From 54a215376523c9828e0092de33f29614fca24281 Mon Sep 17 00:00:00 2001 From: darrenr Date: Sun, 13 Aug 2000 04:58:02 +0000 Subject: Import base ipfilter 3.4.9 into contrib dir. --- contrib/ipfilter/HISTORY | 26 ++++ contrib/ipfilter/Makefile | 13 +- contrib/ipfilter/fil.c | 49 +++--- contrib/ipfilter/fils.c | 5 +- contrib/ipfilter/ip_auth.c | 4 +- contrib/ipfilter/ip_compat.h | 6 +- contrib/ipfilter/ip_fil.c | 6 +- contrib/ipfilter/ip_ftp_pxy.c | 6 +- contrib/ipfilter/ip_log.c | 4 +- contrib/ipfilter/ip_nat.c | 88 ++++++++--- contrib/ipfilter/ip_sfil.c | 25 +++- contrib/ipfilter/ip_state.c | 298 ++++++++++++++++++++++++++++++------- contrib/ipfilter/ipf.c | 12 +- contrib/ipfilter/ipl.h | 4 +- contrib/ipfilter/iplang/iplang_y.y | 5 +- contrib/ipfilter/ipmon.c | 64 ++++++-- contrib/ipfilter/ipnat.c | 9 +- contrib/ipfilter/ipsend/ipsend.1 | 2 +- contrib/ipfilter/ipsend/ipsend.5 | 2 +- contrib/ipfilter/mlfk_ipl.c | 4 +- contrib/ipfilter/opt_inet6.h | 1 + contrib/ipfilter/perl/plog | 40 ++--- contrib/ipfilter/solaris.c | 5 +- 23 files changed, 510 insertions(+), 168 deletions(-) create mode 100644 contrib/ipfilter/opt_inet6.h (limited to 'contrib') diff --git a/contrib/ipfilter/HISTORY b/contrib/ipfilter/HISTORY index b794c9a..da1594d 100644 --- a/contrib/ipfilter/HISTORY +++ b/contrib/ipfilter/HISTORY @@ -20,6 +20,32 @@ # and especially those who have found the time to port IP Filter to new # platforms. # +3.4.9 08/08/2000 - Released + +implement new aging mechanism in fr_tcp_age() + +fix icmp state checking bug + +revamp buildsunos script and build both sparcv7/sparcv9 for Solaris +if on an Ultra with a 64bit system & compiler (Caseper Dik) + +open ipfilter device read only if we know we can + +print out better information for ICMP packets in ipmon + +move checking for source spoofed packets to a point where we can generate +logs of them + +return EFAULT from ircopyptr/iwcopyptr + +don't do ioctl(SIOCGETFS) for auth stats + +fix up freeing mbufs for post-4.3BSD + +fix returning of inc from ftp proxy + +fix bugs with ipfs -R/-W (Caseper Dik) + 3.4.8 19/07/2000 - Released create fake opt_inet6.h for FreeBSD-4 compile as LKM diff --git a/contrib/ipfilter/Makefile b/contrib/ipfilter/Makefile index cb4199e..947c3b6 100644 --- a/contrib/ipfilter/Makefile +++ b/contrib/ipfilter/Makefile @@ -5,7 +5,7 @@ # provided that this notice is preserved and due credit is given # to the original author and the contributors. # -# $Id: Makefile,v 2.11.2.2 2000/07/18 13:58:10 darrenr Exp $ +# $Id: Makefile,v 2.11.2.3 2000/08/05 14:50:00 darrenr Exp $ # BINDEST=/usr/local/bin SBINDEST=/sbin @@ -15,6 +15,7 @@ CC=gcc -Wstrict-prototypes -Wmissing-prototypes #CC=gcc #CC=cc -Dconst= DEBUG=-g +TOP=../.. CFLAGS=-I$$(TOP) -g CPU=`uname -m` CPUDIR=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m` @@ -63,7 +64,8 @@ MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6)' \ "IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \ "SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \ "CPUDIR=$(CPUDIR)" 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' \ - 'STATETOP_INC=$(STATETOP_INC)' 'STATETOP_LIB=$(STATETOP_LIB)' + 'STATETOP_INC=$(STATETOP_INC)' 'STATETOP_LIB=$(STATETOP_LIB)' \ + "BITS=$(BITS)" "OBJ=$(OBJ)" DEST="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" MFLAGS=$(MFLAGS1) "IPFLKM=$(IPFLKM)" # @@ -105,7 +107,7 @@ include: fi sunos solaris: include - ./buildsunos + ./buildsunos $(MFLAGS) freebsd22: include make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)" @@ -132,7 +134,7 @@ freebsd4: include echo "#define INET6" > opt_inet6.h; \ fi make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)" - (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko" "DLKM=-DKLD_MODULE"; cd ..) + (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko" "DLKM=-DKLD_MODULE -I/sys"; cd ..) (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS1); cd ..) freebsd3 freebsd30: include @@ -186,7 +188,8 @@ setup: clean: clean-include ${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \ - vnode_if.h $(LKM) *~ opt_inet6.h + vnode_if.h $(LKM) *~ + ${RM} -rf sparcv7 sparcv9 (cd SunOS4; make clean) (cd SunOS5; make clean) (cd BSD; make clean) diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c index 623e84e..91b5108 100644 --- a/contrib/ipfilter/fil.c +++ b/contrib/ipfilter/fil.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.18 2000/07/19 13:13:40 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.20 2000/08/13 04:15:43 darrenr Exp $"; #endif #include @@ -820,18 +820,6 @@ int out; fin->fin_qfm = m; fin->fin_qif = qif; # endif -# ifdef USE_INET6 - if (v == 6) { - ATOMIC_INCL(frstats[0].fr_ipv6[out]); - } else -# endif - if (!out && fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) { - ATOMIC_INCL(frstats[0].fr_badsrc); -# if !SOLARIS - m_freem(m); -# endif - return error; - } #endif /* _KERNEL */ /* @@ -847,8 +835,29 @@ int out; fin->fin_out = out; fin->fin_mp = mp; fr_makefrip(hlen, ip, fin); - pass = fr_pass; +#ifdef _KERNEL +# ifdef USE_INET6 + if (v == 6) { + ATOMIC_INCL(frstats[0].fr_ipv6[out]); + } else +# endif + if (!out && fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) { + ATOMIC_INCL(frstats[0].fr_badsrc); +# ifdef IPFILTER_LOG + if (fr_chksrc == 2) { + fin->fin_group = -2; + pass = FR_INQUE|FR_NOMATCH|FR_LOGB; + (void) IPLLOG(pass, ip, fin, m); + } +# endif +# if !SOLARIS + m_freem(m); +# endif + return error; + } +#endif + pass = fr_pass; if (fin->fin_fi.fi_fl & FI_SHORT) { ATOMIC_INCL(frstats[out].fr_short); } @@ -1367,7 +1376,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.35.2.18 2000/07/19 13:13:40 darrenr Exp $ + * $Id: fil.c,v 2.35.2.20 2000/08/13 04:15:43 darrenr Exp $ */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -1846,11 +1855,14 @@ size_t c; int err; #if SOLARIS - copyin(a, &ca, sizeof(ca)); + if (copyin(a, &ca, sizeof(ca))) + return EFAULT; #else bcopy(a, &ca, sizeof(ca)); #endif err = copyin(ca, b, c); + if (err) + err = EFAULT; return err; } @@ -1863,11 +1875,14 @@ size_t c; int err; #if SOLARIS - copyin(b, &ca, sizeof(ca)); + if (copyin(b, &ca, sizeof(ca))) + return EFAULT; #else bcopy(b, &ca, sizeof(ca)); #endif err = copyout(a, ca, c); + if (err) + err = EFAULT; return err; } diff --git a/contrib/ipfilter/fils.c b/contrib/ipfilter/fils.c index 761f905..6a4cf67 100644 --- a/contrib/ipfilter/fils.c +++ b/contrib/ipfilter/fils.c @@ -65,7 +65,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.4 2000/05/22 12:47:38 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.5 2000/07/20 14:13:30 darrenr Exp $"; #endif extern char *optarg; @@ -209,6 +209,7 @@ char *argv[]; opts |= OPT_ACCNT|OPT_SHOWLIST; break; case 'A' : + device = IPAUTH_NAME; opts |= OPT_AUTHSTATS; break; case 'C' : @@ -297,7 +298,7 @@ char *argv[]; bzero((char *)&ipsst, sizeof(ipsst)); bzero((char *)&ifrst, sizeof(ifrst)); - if (ioctl(fd, SIOCGETFS, &fiop) == -1) { + if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, &fiop) == -1) { perror("ioctl(ipf:SIOCGETFS)"); exit(-1); } diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c index 9fa24d6..d737b9c 100644 --- a/contrib/ipfilter/ip_auth.c +++ b/contrib/ipfilter/ip_auth.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.3 2000/06/17 06:24:31 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.4 2000/08/05 14:48:50 darrenr Exp $"; #endif #include @@ -46,7 +46,7 @@ static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.3 2000/06/17 06:24:31 d # include # include #endif -#if (_BSDI_VERSION >= 199802) || (__FreeBSD_Version >= 400000) +#if (_BSDI_VERSION >= 199802) || (__FreeBSD_version >= 400000) # include #endif #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi) diff --git a/contrib/ipfilter/ip_compat.h b/contrib/ipfilter/ip_compat.h index 9b7cddf..ba9e014 100644 --- a/contrib/ipfilter/ip_compat.h +++ b/contrib/ipfilter/ip_compat.h @@ -6,7 +6,7 @@ * to the original author and the contributors. * * @(#)ip_compat.h 1.8 1/14/96 - * $Id: ip_compat.h,v 2.26.2.3 2000/04/28 14:56:49 darrenr Exp $ + * $Id: ip_compat.h,v 2.26.2.4 2000/08/13 03:51:03 darrenr Exp $ */ #ifndef __IP_COMPAT_H__ @@ -126,6 +126,10 @@ typedef int minor_t; #endif /* SOLARIS */ #define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h))) +#if defined(__FreeBSD__) && (__FreeBSD__ >= 5) && defined(_KERNEL) +# include +#endif + #ifndef IP_OFFMASK #define IP_OFFMASK 0x1fff #endif diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c index fe6af66..2e8af26 100644 --- a/contrib/ipfilter/ip_fil.c +++ b/contrib/ipfilter/ip_fil.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.14 2000/07/18 13:57:55 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.42.2.15 2000/08/05 14:49:08 darrenr Exp $"; #endif #ifndef SOLARIS @@ -1139,8 +1139,10 @@ int dst; return ENOBUFS; MCLGET(m, M_DONTWAIT); - if (!m) + if ((m->m_flags & M_EXT) == 0) { + m_freem(m); return ENOBUFS; + } avail = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN; xtra = MIN(ntohs(oip6->ip6_plen) + sizeof(ip6_t), avail - hlen - sizeof(*icmp) - max_linkhdr); diff --git a/contrib/ipfilter/ip_ftp_pxy.c b/contrib/ipfilter/ip_ftp_pxy.c index 5ea94a1..84dc8b9 100644 --- a/contrib/ipfilter/ip_ftp_pxy.c +++ b/contrib/ipfilter/ip_ftp_pxy.c @@ -2,7 +2,7 @@ * Simple FTP transparent proxy for in-kernel use. For use with the NAT * code. * - * $Id: ip_ftp_pxy.c,v 2.7.2.12 2000/07/19 13:06:13 darrenr Exp $ + * $Id: ip_ftp_pxy.c,v 2.7.2.13 2000/08/07 12:35:27 darrenr Exp $ */ #if SOLARIS && defined(_KERNEL) extern kmutex_t ipf_rw; @@ -263,7 +263,7 @@ int dlen; ip->ip_len = slen; ip->ip_src = swip; } - return inc; + return APR_INC(inc); } @@ -703,7 +703,7 @@ int rv; t->ftps_seq = ntohl(tcp->th_ack); f->ftps_rptr = rptr; f->ftps_wptr = wptr; - return inc; + return APR_INC(inc); } diff --git a/contrib/ipfilter/ip_log.c b/contrib/ipfilter/ip_log.c index 08073bb..8adc410 100644 --- a/contrib/ipfilter/ip_log.c +++ b/contrib/ipfilter/ip_log.c @@ -5,7 +5,7 @@ * provided that this notice is preserved and due credit is given * to the original author and the contributors. * - * $Id: ip_log.c,v 2.5.2.1 2000/07/19 13:11:47 darrenr Exp $ + * $Id: ip_log.c,v 2.5.2.2 2000/08/13 03:50:41 darrenr Exp $ */ #include #if defined(KERNEL) && !defined(_KERNEL) @@ -21,8 +21,6 @@ # endif # else # ifdef KLD_MODULE -# include -# else # include # endif # endif diff --git a/contrib/ipfilter/ip_nat.c b/contrib/ipfilter/ip_nat.c index d25f3f7..bbcff77 100644 --- a/contrib/ipfilter/ip_nat.c +++ b/contrib/ipfilter/ip_nat.c @@ -9,7 +9,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.16 2000/07/18 13:57:40 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.21 2000/08/12 07:32:40 darrenr Exp $"; #endif #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) @@ -126,7 +126,7 @@ hostmap_t **maptable = NULL; u_long fr_defnatage = DEF_NAT_AGE, fr_defnaticmpage = 6; /* 3 seconds */ -static natstat_t nat_stats; +natstat_t nat_stats; int fr_nat_lock = 0; #if (SOLARIS || defined(__sgi)) && defined(_KERNEL) extern kmutex_t ipf_rw, ipf_hostmap; @@ -403,8 +403,11 @@ int mode; KMALLOC(nt, ipnat_t *); if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) error = IRCOPYPTR(data, (char *)&natd, sizeof(natd)); - else if (cmd == SIOCIPFFL) /* SIOCFLNAT & SIOCCNATL */ + else if (cmd == SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */ error = IRCOPY(data, (char *)&arg, sizeof(arg)); + if (error) + error = EFAULT; + } if (error) goto done; @@ -498,7 +501,7 @@ int mode; * mapping range. In all cases, the range is inclusive of * the start and ending IP addresses. * If to a CIDR address, lose 2: broadcast + network address - * (so subtract 1) + * (so subtract 1) * If to a range, add one. * If to a single IP address, set to 1. */ @@ -641,7 +644,8 @@ int mode; sizeof(fr_nat_lock)); if (!error) fr_nat_lock = arg; - } + } else + error = EFAULT; break; case SIOCSTPUT : if (fr_nat_lock) @@ -666,6 +670,8 @@ int mode; MUTEX_DOWNGRADE(&ipf_nat); error = IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data, sizeof(iplused[IPL_LOGNAT])); + if (error) + error = EFAULT; #endif break; default : @@ -732,7 +738,7 @@ caddr_t data; static int fr_natgetent(data) caddr_t data; { - nat_save_t ipn, *ipnp, *ipnn; + nat_save_t ipn, *ipnp, *ipnn = NULL; register nat_t *n, *nat; ap_session_t *aps; int error; @@ -785,33 +791,33 @@ caddr_t data; ipn.ipn_dsize += aps->aps_psiz; KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize); if (ipnn == NULL) - return NULL; + return ENOMEM; bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn)); - bcopy((char *)aps, ipn.ipn_data, sizeof(*aps)); + bcopy((char *)aps, ipnn->ipn_data, sizeof(*aps)); if (aps->aps_data) { - bcopy(aps->aps_data, ipn.ipn_data + sizeof(*aps), + bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps), aps->aps_psiz); - ipn.ipn_dsize += aps->aps_psiz; + ipnn->ipn_dsize += aps->aps_psiz; } error = IWCOPY((caddr_t)ipnn, ipnp, sizeof(ipn) + ipn.ipn_dsize); if (error) - return EFAULT; + error = EFAULT; KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize); } else { error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn)); if (error) - return EFAULT; + error = EFAULT; } - return 0; + return error; } static int fr_natputent(data) caddr_t data; { - nat_save_t ipn, *ipnp, *ipnn; + nat_save_t ipn, *ipnp, *ipnn = NULL; register nat_t *n, *nat; ap_session_t *aps; frentry_t *fr; @@ -825,6 +831,7 @@ caddr_t data; error = IRCOPY((caddr_t)ipnp, (caddr_t)&ipn, sizeof(ipn)); if (error) return EFAULT; + nat = NULL; if (ipn.ipn_dsize) { KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize); if (ipnn == NULL) @@ -832,14 +839,18 @@ caddr_t data; bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn)); error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data, ipn.ipn_dsize); - if (error) - return EFAULT; + if (error) { + error = EFAULT; + goto junkput; + } } else ipnn = NULL; KMALLOC(nat, nat_t *); - if (nat == NULL) - return ENOMEM; + if (nat == NULL) { + error = EFAULT; + goto junkput; + } bcopy((char *)&ipn.ipn_nat, (char *)nat, sizeof(*nat)); /* @@ -1458,7 +1469,7 @@ int dir; icmphdr_t *icmp; tcphdr_t *tcp = NULL; ip_t *oip; - int flags = 0, type; + int flags = 0, type, minlen; icmp = (icmphdr_t *)fin->fin_dp; /* @@ -1478,13 +1489,45 @@ int dir; return NULL; oip = (ip_t *)((char *)fin->fin_dp + 8); - if (ip->ip_len < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2)) + minlen = (oip->ip_hl << 2); + if (minlen < sizeof(ip_t)) return NULL; + if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen) + return NULL; + /* + * Is the buffer big enough for all of it ? It's the size of the IP + * header claimed in the encapsulated part which is of concern. It + * may be too big to be in this buffer but not so big that it's + * outside the ICMP packet, leading to TCP deref's causing problems. + * This is possible because we don't know how big oip_hl is when we + * do the pullup early in fr_check() and thus can't gaurantee it is + * all here now. + */ +#ifdef _KERNEL + { + mb_t *m; + +# if SOLARIS + m = fin->fin_qfm; + if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > (char *)m->b_wptr) + return NULL; +# else + m = *(mb_t **)fin->fin_mp; + if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > + (char *)ip + m->m_len) + return NULL; +# endif + } +#endif + if (oip->ip_p == IPPROTO_TCP) flags = IPN_TCP; else if (oip->ip_p == IPPROTO_UDP) flags = IPN_UDP; if (flags & IPN_TCPUDP) { + minlen += 8; /* + 64bits of data to get ports */ + if (ip->ip_len < ICMPERR_IPICMPHLEN + minlen) + return NULL; tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2)); if (dir == NAT_INBOUND) return nat_inlookup(fin->fin_ifp, flags, @@ -1576,7 +1619,10 @@ int dir; if ((flags & IPN_TCPUDP) != 0) { tcphdr_t *tcp; - /* XXX - what if this is bogus hl and we go off the end ? */ + /* + * XXX - what if this is bogus hl and we go off the end ? + * In this case, nat_icmpinlookup() will have returned NULL. + */ tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2))); if (nat->nat_dir == NAT_OUTBOUND) { diff --git a/contrib/ipfilter/ip_sfil.c b/contrib/ipfilter/ip_sfil.c index 615e57f..38e5e3e 100644 --- a/contrib/ipfilter/ip_sfil.c +++ b/contrib/ipfilter/ip_sfil.c @@ -9,7 +9,7 @@ */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.3 2000/07/08 02:20:14 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.6 2000/08/07 12:36:19 darrenr Exp $"; #endif #include @@ -50,6 +50,7 @@ static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.3 2000/07/08 02:20:14 d #include "ip_nat.h" #include "ip_frag.h" #include "ip_auth.h" +#include "ip_proxy.h" #include #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -64,6 +65,7 @@ u_long ipl_frouteok[2] = {0, 0}; static int frzerostats __P((caddr_t)); static int frrequest __P((minor_t, int, caddr_t, int)); +static int send_ip __P((fr_info_t *fin, mblk_t *m)); kmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap; KRWLOCK_T ipf_mutex, ipfs_mutex, ipf_solaris; KRWLOCK_T ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; @@ -148,7 +150,7 @@ caddr_t data; fr_getstat(&fio); error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio)); if (error) - return EFAULT; + return error; bzero((char *)frstats, sizeof(*frstats) * 2); @@ -227,6 +229,8 @@ int *rp; case SIOCGETFF : error = IWCOPY((caddr_t)&fr_flags, (caddr_t)data, sizeof(fr_flags)); + if (error) + error = EFAULT; break; case SIOCINAFR : case SIOCRMAFR : @@ -254,6 +258,8 @@ int *rp; bzero((char *)frcache, sizeof(frcache[0]) * 2); error = IWCOPY((caddr_t)&fr_active, (caddr_t)data, sizeof(fr_active)); + if (error) + error = EFAULT; fr_active = 1 - fr_active; RWLOCK_EXIT(&ipf_mutex); } @@ -286,6 +292,8 @@ int *rp; tmp = frflush(unit, tmp); error = IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp)); + if (error) + error = EFAULT; } } break; @@ -307,6 +315,8 @@ int *rp; tmp = ipflog_clear(unit); error = IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp)); + if (error) + error = EFAULT; } break; #endif /* IPFILTER_LOG */ @@ -319,8 +329,6 @@ int *rp; case SIOCGFRST : error = IWCOPYPTR((caddr_t)ipfr_fragstats(), (caddr_t)data, sizeof(ipfrstat_t)); - if (error) - error = EFAULT; break; case FIONREAD : { @@ -328,6 +336,8 @@ int *rp; int copy = (int)iplused[IPL_LOGIPF]; error = IWCOPY((caddr_t)©, (caddr_t)data, sizeof(copy)); + if (error) + error = EFAULT; #endif break; } @@ -533,10 +543,8 @@ caddr_t data; } MUTEX_DOWNGRADE(&ipf_mutex); error = IWCOPYPTR((caddr_t)f, data, sizeof(*f)); - if (error) { - error = EFAULT; + if (error) goto out; - } f->fr_hits = 0; f->fr_bytes = 0; goto out; @@ -741,7 +749,7 @@ fr_info_t *fin; } -int send_ip(fin, m) +int static send_ip(fin, m) fr_info_t *fin; mblk_t *m; { @@ -749,6 +757,7 @@ mblk_t *m; RWLOCK_EXIT(&ipf_solaris); #ifdef USE_INET6 if (fin->fin_v == 6) { + extern void ip_wput_v6 __P((queue_t *, mblk_t *)); ip6_t *ip6; ip6 = (ip6_t *)m->b_rptr; diff --git a/contrib/ipfilter/ip_state.c b/contrib/ipfilter/ip_state.c index fa8e050..f05c887 100644 --- a/contrib/ipfilter/ip_state.c +++ b/contrib/ipfilter/ip_state.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.12 2000/06/19 02:38:37 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.30.2.17 2000/08/08 16:01:03 darrenr Exp $"; #endif #include @@ -180,7 +180,7 @@ static ips_stat_t *fr_statetstats() * flush state tables. two actions currently defined: * which == 0 : flush all state table entries * which == 1 : flush TCP connections which have started to close but are - * stuck for some reason. + * stuck for some reason. */ static int fr_state_flush(which) int which; @@ -371,8 +371,8 @@ caddr_t data; sizeof(ips.ips_fr)); error = IWCOPY((caddr_t)&ips, ipsp, sizeof(ips)); if (error) - return EFAULT; - return 0; + error = EFAULT; + return error; } @@ -477,6 +477,7 @@ register ipstate_t *is; is->is_phnext = ips_table + hv; is->is_hnext = ips_table[hv]; ips_table[hv] = is; + ips_num++; } @@ -557,7 +558,6 @@ u_int flags; case ND_NEIGHBOR_SOLICIT : is->is_icmp.ics_type = ic->icmp_type + 1; break; - break; #endif case ICMP_ECHO : case ICMP_TSTAMP : @@ -669,11 +669,10 @@ u_int flags; if (pass & FR_LOGFIRST) is->is_pass &= ~(FR_LOGFIRST|FR_LOG); fr_stinsert(is); - ips_num++; if (is->is_p == IPPROTO_TCP) { MUTEX_ENTER(&is->is_lock); fr_tcp_age(&is->is_age, is->is_state, fin, - tcp->th_sport == is->is_sport); + 0); /* 0 = packet from the source */ MUTEX_EXIT(&is->is_lock); } #ifdef IPFILTER_LOG @@ -785,7 +784,8 @@ tcphdr_t *tcp; * Nearing end of connection, start timeout. */ MUTEX_ENTER(&is->is_lock); - fr_tcp_age(&is->is_age, is->is_state, fin, source); + /* source ? 0 : 1 -> !source */ + fr_tcp_age(&is->is_age, is->is_state, fin, !source); MUTEX_EXIT(&is->is_lock); ret = 1; } @@ -970,12 +970,12 @@ fr_info_t *fin; union i6addr dst, src; struct icmp *ic; u_short savelen; + icmphdr_t *icmp; fr_info_t ofin; + int type, len; tcphdr_t *tcp; - icmphdr_t *icmp; frentry_t *fr; ip_t *oip; - int type; u_int hv; /* @@ -1000,6 +1000,46 @@ fr_info_t *fin; if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((oip->ip_hl - 5) << 2)) return NULL; + /* + * Sanity checks. + */ + len = fin->fin_dlen - ICMPERR_ICMPHLEN; + if ((len <= 0) || ((oip->ip_hl << 2) > len)) + return NULL; + + /* + * Is the buffer big enough for all of it ? It's the size of the IP + * header claimed in the encapsulated part which is of concern. It + * may be too big to be in this buffer but not so big that it's + * outside the ICMP packet, leading to TCP deref's causing problems. + * This is possible because we don't know how big oip_hl is when we + * do the pullup early in fr_check() and thus can't gaurantee it is + * all here now. + */ +#ifdef _KERNEL + { + mb_t *m; + +# if SOLARIS + m = fin->fin_qfm; + if ((char *)oip + len > (char *)m->b_wptr) + return NULL; +# else + m = *(mb_t **)fin->fin_mp; + if ((char *)oip + len > (char *)ip + m->m_len) + return NULL; +# endif + } +#endif + + /* + * in the IPv4 case we must zero the i6addr union otherwise + * the IP6EQ and IP6NEQ macros produce the wrong results because + * of the 'junk' in the unused part of the union + */ + bzero(&src, sizeof(src)); + bzero(&dst, sizeof(dst)); + if (oip->ip_p == IPPROTO_ICMP) { icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2)); @@ -1028,9 +1068,11 @@ fr_info_t *fin; hv += icmp->icmp_seq; hv %= fr_statesize; - oip->ip_len = ntohs(oip->ip_len); + savelen = oip->ip_len; + oip->ip_len = len; + ofin.fin_v = 4; fr_makefrip(oip->ip_hl << 2, oip, &ofin); - oip->ip_len = htons(oip->ip_len); + oip->ip_len = savelen; ofin.fin_ifp = fin->fin_ifp; ofin.fin_out = !fin->fin_out; ofin.fin_mp = NULL; /* if dereferenced, panic XXX */ @@ -1077,7 +1119,8 @@ fr_info_t *fin; * order. Any change we make must be undone afterwards. */ savelen = oip->ip_len; - oip->ip_len = ip->ip_len - (ip->ip_hl << 2) - ICMPERR_ICMPHLEN; + oip->ip_len = len; + ofin.fin_v = 4; fr_makefrip(oip->ip_hl << 2, oip, &ofin); oip->ip_len = savelen; ofin.fin_ifp = fin->fin_ifp; @@ -1198,7 +1241,15 @@ fr_info_t *fin; case IPPROTO_TCP : { register u_short dport = tcp->th_dport, sport = tcp->th_sport; + register int i; + i = tcp->th_flags; + /* + * Just plain ignore RST flag set with either FIN or SYN. + */ + if ((i & TH_RST) && + ((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST)) + break; tryagain = 0; retry_tcp: hvm = hv % fr_statesize; @@ -1384,6 +1435,27 @@ void fr_timeoutstate() /* * Original idea freom Pradeep Krishnan for use primarily with NAT code. * (pkrishna@netcom.com) + * + * Rewritten by Arjan de Vet , 2000-07-29: + * + * - (try to) base state transitions on real evidence only, + * i.e. packets that are sent and have been received by ipfilter; + * diagram 18.12 of TCP/IP volume 1 by W. Richard Stevens was used. + * + * - deal with half-closed connections correctly; + * + * - store the state of the source in state[0] such that ipfstat + * displays the state as source/dest instead of dest/source; the calls + * to fr_tcp_age have been changed accordingly. + * + * Parameters: + * + * state[0] = state of source (host that initiated connection) + * state[1] = state of dest (host that accepted the connection) + * + * dir == 0 : a packet from source to dest + * dir == 1 : a packet from dest to source + * */ void fr_tcp_age(age, state, fin, dir) u_long *age; @@ -1410,67 +1482,192 @@ int dir; return; } - *age = fr_tcptimeout; /* 1 min */ + *age = fr_tcptimeout; /* default 4 mins */ switch(state[dir]) { - case TCPS_CLOSED: + case TCPS_CLOSED: /* 0 */ + if ((flags & TH_OPENING) == TH_OPENING) { + /* + * 'dir' received an S and sends SA in response, + * CLOSED -> SYN_RECEIVED + */ + state[dir] = TCPS_SYN_RECEIVED; + *age = fr_tcptimeout; + } else if ((flags & (TH_SYN|TH_ACK)) == TH_SYN) { + /* 'dir' sent S, CLOSED -> SYN_SENT */ + state[dir] = TCPS_SYN_SENT; + *age = fr_tcptimeout; + } + /* + * The next piece of code makes it possible to get + * already established connections into the state table + * after a restart or reload of the filter rules; this + * does not work when a strict 'flags S keep state' is + * used for tcp connections of course + */ if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) { + /* we saw an A, guess 'dir' is in ESTABLISHED mode */ state[dir] = TCPS_ESTABLISHED; *age = fr_tcpidletimeout; } - case TCPS_FIN_WAIT_2: - if ((flags & TH_OPENING) == TH_OPENING) + /* + * TODO: besides regular ACK packets we can have other + * packets as well; it is yet to be determined how we + * should initialize the states in those cases + */ + break; + + case TCPS_LISTEN: /* 1 */ + /* NOT USED */ + break; + + case TCPS_SYN_SENT: /* 2 */ + if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) { + /* + * We see an A from 'dir' which is in SYN_SENT + * state: 'dir' sent an A in response to an SA + * which it received, SYN_SENT -> ESTABLISHED + */ + state[dir] = TCPS_ESTABLISHED; + *age = fr_tcpidletimeout; + } else if (flags & TH_FIN) { + /* + * We see an F from 'dir' which is in SYN_SENT + * state and wants to close its side of the + * connection; SYN_SENT -> FIN_WAIT_1 + */ + state[dir] = TCPS_FIN_WAIT_1; + *age = fr_tcpidletimeout; /* or fr_tcptimeout? */ + } else if ((flags & TH_OPENING) == TH_OPENING) { + /* + * We see an SA from 'dir' which is already in + * SYN_SENT state, this means we have a + * simultaneous open; SYN_SENT -> SYN_RECEIVED + */ state[dir] = TCPS_SYN_RECEIVED; - else if (flags & TH_SYN) - state[dir] = TCPS_SYN_SENT; + *age = fr_tcptimeout; + } break; - case TCPS_SYN_RECEIVED: - case TCPS_SYN_SENT: - if ((flags & (TH_FIN|TH_ACK)) == TH_ACK) { + + case TCPS_SYN_RECEIVED: /* 3 */ + if ((flags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) { + /* + * We see an A from 'dir' which was in SYN_RECEIVED + * state so it must now be in established state, + * SYN_RECEIVED -> ESTABLISHED + */ state[dir] = TCPS_ESTABLISHED; *age = fr_tcpidletimeout; - } else if ((flags & (TH_FIN|TH_ACK)) == (TH_FIN|TH_ACK)) { - state[dir] = TCPS_CLOSE_WAIT; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) - *age = fr_tcplastack; - else - *age = fr_tcpclosewait; + } else if (flags & TH_FIN) { + /* + * We see an F from 'dir' which is in SYN_RECEIVED + * state and wants to close its side of the connection; + * SYN_RECEIVED -> FIN_WAIT_1 + */ + state[dir] = TCPS_FIN_WAIT_1; + *age = fr_tcpidletimeout; /* or fr_tcptimeout? */ } break; - case TCPS_ESTABLISHED: + + case TCPS_ESTABLISHED: /* 4 */ if (flags & TH_FIN) { - state[dir] = TCPS_CLOSE_WAIT; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) - *age = fr_tcplastack; - else - *age = fr_tcpclosewait; - } else { - if (ostate < TCPS_CLOSE_WAIT) + /* + * 'dir' closed its side of the connection; this + * gives us a half-closed connection; + * ESTABLISHED -> FIN_WAIT_1 + */ + state[dir] = TCPS_FIN_WAIT_1; + *age = fr_tcpidletimeout; + } else if (flags & TH_ACK) { + /* an ACK, should we exclude other flags here? */ + if (ostate == TCPS_FIN_WAIT_1) { + /* + * We know the other side did an active close, + * so we are ACKing the recvd FIN packet (does + * the window matching code guarantee this?) + * and go into CLOSE_WAIT state; this gives us + * a half-closed connection + */ + state[dir] = TCPS_CLOSE_WAIT; + *age = fr_tcpidletimeout; + } else if (ostate < TCPS_CLOSE_WAIT) + /* + * Still a fully established connection, + * reset timeout + */ *age = fr_tcpidletimeout; } break; - case TCPS_CLOSE_WAIT: - if ((flags & TH_FIN) && !(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) { + + case TCPS_CLOSE_WAIT: /* 5 */ + if (flags & TH_FIN) { + /* + * Application closed and 'dir' sent a FIN, we're now + * going into LAST_ACK state + */ *age = fr_tcplastack; state[dir] = TCPS_LAST_ACK; + } else { + /* + * We remain in CLOSE_WAIT because the other side has + * closed already and we did not close our side yet; + * reset timeout + */ + *age = fr_tcpidletimeout; + } + break; + + case TCPS_FIN_WAIT_1: /* 6 */ + if ((flags & TH_ACK) && ostate > TCPS_CLOSE_WAIT) { + /* + * If the other side is not active anymore it has sent + * us a FIN packet that we are ack'ing now with an ACK; + * this means both sides have now closed the connection + * and we go into TIME_WAIT + */ + /* + * XXX: how do we know we really are ACKing the FIN + * packet here? does the window code guarantee that? + */ + state[dir] = TCPS_TIME_WAIT; + *age = fr_tcptimeout; } else - *age = fr_tcpclosewait; + /* + * We closed our side of the connection already but the + * other side is still active (ESTABLISHED/CLOSE_WAIT); + * continue with this half-closed connection + */ + *age = fr_tcpidletimeout; + break; + + case TCPS_CLOSING: /* 7 */ + /* NOT USED */ break; - case TCPS_LAST_ACK: + + case TCPS_LAST_ACK: /* 8 */ if (flags & TH_ACK) { - state[dir] = TCPS_FIN_WAIT_2; - if (!(flags & TH_PUSH) && !dlen && - ostate > TCPS_ESTABLISHED) + if ((flags & TH_PUSH) || dlen) + /* + * There is still data to be delivered, reset + * timeout + */ *age = fr_tcplastack; - else { - *age = fr_tcpclosewait; - state[dir] = TCPS_CLOSE_WAIT; - } } + /* + * We cannot detect when we go out of LAST_ACK state to CLOSED + * because that is based on the reception of ACK packets; + * ipfilter can only detect that a packet has been sent by a + * host + */ + break; + + case TCPS_FIN_WAIT_2: /* 9 */ + /* NOT USED */ + break; + + case TCPS_TIME_WAIT: /* 10 */ + /* we're in 2MSL timeout now */ break; } } @@ -1579,6 +1776,7 @@ fr_info_t *fin; hv %= fr_statesize; oip->ip6_plen = ntohs(oip->ip6_plen); + ofin.fin_v = 6; fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin); oip->ip6_plen = htons(oip->ip6_plen); ofin.fin_ifp = fin->fin_ifp; diff --git a/contrib/ipfilter/ipf.c b/contrib/ipfilter/ipf.c index a1a0bfc..36448b4 100644 --- a/contrib/ipfilter/ipf.c +++ b/contrib/ipfilter/ipf.c @@ -43,7 +43,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.1 2000/07/08 02:19:46 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.3 2000/08/07 14:54:05 darrenr Exp $"; #endif #if SOLARIS @@ -558,13 +558,21 @@ static void showversion() struct friostat *fiop=&fio; u_32_t flags; char *s; + int vfd; printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t)); - if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fiop)) { + if ((vfd = open(ipfname, O_RDONLY)) == -1) { + perror("open device"); + return; + } + + if (ioctl(vfd, SIOCGETFS, &fiop)) { perror("ioctl(SIOCGETFS"); + close(vfd); return; } + close(vfd); flags = get_flags(); printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version), diff --git a/contrib/ipfilter/ipl.h b/contrib/ipfilter/ipl.h index bb2523d..866d34d 100644 --- a/contrib/ipfilter/ipl.h +++ b/contrib/ipfilter/ipl.h @@ -6,12 +6,12 @@ * to the original author and the contributors. * * @(#)ipl.h 1.21 6/5/96 - * $Id: ipl.h,v 2.15.2.9 2000/07/19 13:40:04 darrenr Exp $ + * $Id: ipl.h,v 2.15.2.10 2000/08/07 15:10:09 darrenr Exp $ */ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter: v3.4.8" +#define IPL_VERSION "IP Filter: v3.4.9" #endif diff --git a/contrib/ipfilter/iplang/iplang_y.y b/contrib/ipfilter/iplang/iplang_y.y index 95f3419..56d705b 100644 --- a/contrib/ipfilter/iplang/iplang_y.y +++ b/contrib/ipfilter/iplang/iplang_y.y @@ -6,7 +6,7 @@ * provided that this notice is preserved and due credit is given * to the original author and the contributors. * - * $Id: iplang_y.y,v 2.2 1999/12/04 03:37:04 darrenr Exp $ + * $Id: iplang_y.y,v 2.2.2.1 2000/08/05 14:43:39 darrenr Exp $ */ #include @@ -48,7 +48,8 @@ #include "ipf.h" #include "iplang.h" -#ifndef __NetBSD__ +#if !defined(__NetBSD__) && (!defined(__FreeBSD_version) && \ + __FreeBSD_version < 400020) extern struct ether_addr *ether_aton __P((char *)); #endif diff --git a/contrib/ipfilter/ipmon.c b/contrib/ipfilter/ipmon.c index 858c40c..bb7e75f 100644 --- a/contrib/ipfilter/ipmon.c +++ b/contrib/ipfilter/ipmon.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.2 2000/07/15 14:50:06 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.4 2000/08/07 12:32:22 darrenr Exp $"; #endif #ifndef SOLARIS @@ -336,7 +336,7 @@ int len; t += 2; if (!((j + 1) & 0xf)) { s -= 15; - sprintf((char *)t, " "); + sprintf((char *)t, " "); t += 8; for (k = 16; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); @@ -581,6 +581,7 @@ int blen; { tcphdr_t *tp; struct icmp *ic; + struct icmp *icmp; struct tm *tm; char *t, *proto; int i, v, lvl, res, len, off, plen, ipoff; @@ -742,19 +743,56 @@ int blen; ic->icmp_type == ICMP_REDIRECT || ic->icmp_type == ICMP_TIMXCEED) { ipc = &ic->icmp_ip; - tp = (tcphdr_t *)((char *)ipc + hl); - + i = ntohs(ipc->ip_len); + ipoff = ntohs(ipc->ip_off); proto = getproto(ipc->ip_p); - t += strlen(t); - (void) sprintf(t, " for %s,%s -", - HOSTNAME_V4(res, ipc->ip_src), - portname(res, proto, (u_int)tp->th_sport)); - t += strlen(t); - (void) sprintf(t, " %s,%s PR %s len %hu %hu", - HOSTNAME_V4(res, ipc->ip_dst), - portname(res, proto, (u_int)tp->th_dport), - proto, ipc->ip_hl << 2, ipc->ip_len); + if (!(ipoff & IP_OFFMASK) && + ((ipc->ip_p == IPPROTO_TCP) || + (ipc->ip_p == IPPROTO_UDP))) { + tp = (tcphdr_t *)((char *)ipc + hl); + t += strlen(t); + (void) sprintf(t, " for %s,%s -", + HOSTNAME_V4(res, ipc->ip_src), + portname(res, proto, + (u_int)tp->th_sport)); + t += strlen(t); + (void) sprintf(t, " %s,%s PR %s len %hu %hu", + HOSTNAME_V4(res, ipc->ip_dst), + portname(res, proto, + (u_int)tp->th_dport), + proto, ipc->ip_hl << 2, i); + } else if (!(ipoff & IP_OFFMASK) && + (ipc->ip_p == IPPROTO_ICMP)) { + icmp = (icmphdr_t *)((char *)ipc + hl); + + t += strlen(t); + (void) sprintf(t, " for %s -", + HOSTNAME_V4(res, ipc->ip_src)); + t += strlen(t); + (void) sprintf(t, + " %s PR icmp len %hu %hu icmp %d/%d", + HOSTNAME_V4(res, ipc->ip_dst), + ipc->ip_hl << 2, i, + icmp->icmp_type, icmp->icmp_code); + + } else { + t += strlen(t); + (void) sprintf(t, " for %s -", + HOSTNAME_V4(res, ipc->ip_src)); + t += strlen(t); + (void) sprintf(t, " %s PR %s len %hu (%hu)", + HOSTNAME_V4(res, ipc->ip_dst), proto, + ipc->ip_hl << 2, i); + t += strlen(t); + if (ipoff & IP_OFFMASK) { + (void) sprintf(t, " frag %s%s%hu@%hu", + ipoff & IP_MF ? "+" : "", + ipoff & IP_DF ? "-" : "", + i - (ipc->ip_hl<<2), + (ipoff & IP_OFFMASK) << 3); + } + } } } else { (void) sprintf(t, "%s -> ", hostname(res, v, s)); diff --git a/contrib/ipfilter/ipnat.c b/contrib/ipfilter/ipnat.c index 9e1ef34..d1f8ed3 100644 --- a/contrib/ipfilter/ipnat.c +++ b/contrib/ipfilter/ipnat.c @@ -57,7 +57,7 @@ extern char *sys_errlist[]; #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.2 2000/05/15 06:54:18 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.3 2000/07/27 13:07:13 darrenr Exp $"; #endif @@ -111,7 +111,7 @@ int argc; char *argv[]; { char *file = NULL; - int fd = -1, opts = 0, c; + int fd = -1, opts = 0, c, mode = O_RDWR; while ((c = getopt(argc, argv, "CdFf:hlnrsv")) != -1) switch (c) @@ -133,15 +133,18 @@ char *argv[]; break; case 'l' : opts |= OPT_LIST; + mode = O_RDONLY; break; case 'n' : opts |= OPT_NODO; + mode = O_RDONLY; break; case 'r' : opts |= OPT_REMOVE; break; case 's' : opts |= OPT_STAT; + mode = O_RDONLY; break; case 'v' : opts |= OPT_VERBOSE; @@ -153,7 +156,7 @@ char *argv[]; gethostname(thishost, sizeof(thishost)); thishost[sizeof(thishost) - 1] = '\0'; - if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, O_RDWR)) == -1) && + if (!(opts & OPT_NODO) && ((fd = open(IPL_NAT, mode)) == -1) && ((fd = open(IPL_NAT, O_RDONLY)) == -1)) { (void) fprintf(stderr, "%s: open: %s\n", IPL_NAT, STRERROR(errno)); diff --git a/contrib/ipfilter/ipsend/ipsend.1 b/contrib/ipfilter/ipsend/ipsend.1 index 6554e58..04d895d 100644 --- a/contrib/ipfilter/ipsend/ipsend.1 +++ b/contrib/ipfilter/ipsend/ipsend.1 @@ -96,7 +96,7 @@ Set the protocol to TCP. .B \-U Set the protocol to UDP. .TP -.BR \-d +.BR \-v enable verbose mode. .DT .SH SEE ALSO diff --git a/contrib/ipfilter/ipsend/ipsend.5 b/contrib/ipfilter/ipsend/ipsend.5 index 9fa4593..1e4e82e 100644 --- a/contrib/ipfilter/ipsend/ipsend.5 +++ b/contrib/ipfilter/ipsend/ipsend.5 @@ -323,7 +323,7 @@ If the new total length would exceed 64k, an error will be reported. .SH "ICMP TYPES" .TP .B echorep -Eecho Reply. +Echo Reply. .TP .B "unreach [ unreachable-code ]" Generic Unreachable error. This is used to indicate that an error has diff --git a/contrib/ipfilter/mlfk_ipl.c b/contrib/ipfilter/mlfk_ipl.c index 4412960..f869149 100644 --- a/contrib/ipfilter/mlfk_ipl.c +++ b/contrib/ipfilter/mlfk_ipl.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mlfk_ipl.c,v 2.1.2.1 2000/04/26 12:17:24 darrenr Exp $ + * $Id: mlfk_ipl.c,v 2.1.2.3 2000/08/13 03:42:42 darrenr Exp $ */ @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -82,6 +83,7 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, &fr_authused, 0, ""); SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, &fr_defaultauthage, 0, ""); +SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); #define CDEV_MAJOR 79 static struct cdevsw ipl_cdevsw = { diff --git a/contrib/ipfilter/opt_inet6.h b/contrib/ipfilter/opt_inet6.h new file mode 100644 index 0000000..43e7657 --- /dev/null +++ b/contrib/ipfilter/opt_inet6.h @@ -0,0 +1 @@ +#define INET6 diff --git a/contrib/ipfilter/perl/plog b/contrib/ipfilter/perl/plog index 75c733b..b251b0c 100644 --- a/contrib/ipfilter/perl/plog +++ b/contrib/ipfilter/perl/plog @@ -320,8 +320,7 @@ while (defined ($_ = shift)) defined ($arg) || &usage (1, qq{-$flag requires an argument}); if ($flag eq 's') { - defined ($services) && &usage (1, qq{too many service maps} -); + defined ($services) && &usage (1, qq{too many service maps}); $services = $arg; } elsif ($flag eq 'A') @@ -433,8 +432,7 @@ while () # dd/mm/yyyy (no y2k problem here!). Both formats then have a packet # timestamp and the log info. my ($log); - if (s/^\w+\s+\d+\s+\d+:\d+:\d+\s+(?:\d\w:)?[\w\.\-]+\s+\S*ipmon\[\d+\]:\s+( -?:\[ID\s+\d+\s+[\w\.]+\]\s+)?\d+:\d+:\d+\.\d+\s+//) + if (s/^\w+\s+\d+\s+\d+:\d+:\d+\s+(?:\d\w:)?[\w\.\-]+\s+\S*ipmon\[\d+\]:\s+(?:\[ID\s+\d+\s+[\w\.]+\]\s+)?\d+:\d+:\d+\.\d+\s+//) { $log = $_; } @@ -457,15 +455,13 @@ while () # number, "PR", a protocol name or number, "len", a header length, a # packet length (which will be in parentheses for protocols other than # TCP, UDP, or ICMP), and maybe some additional info. - my @fields = ($log =~ /^(?:(\d+)x)?\s*(\w+)\s+@(\d+):(\d+)\s+(\w)\s+([\w\-\ -..,]+)\s+->\s+([\w\-\.,]+)\s+PR\s+(\w+)\s+len\s+(\d+)\s+\(?(\d+)\)?\s*(.*)$/ox); + my @fields = ($log =~ /^(?:(\d+)x)?\s*(\w+)\s+@(\d+):(\d+)\s+(\w)\s+([\w\-\..,]+)\s+->\s+([\w\-\.,]+)\s+PR\s+(\w+)\s+len\s+(\d+)\s+\(?(\d+)\)?\s*(.*)$/ox); unless (scalar (@fields)) { print STDERR "$me:$.: cannot parse: $_\n"; next; } - my ($count, $if, $group, $rule, $act, $src, $dest, $proto, $hlen, $len, $mo -re) = @fields; + my ($count, $if, $group, $rule, $act, $src, $dest, $proto, $hlen, $len, $more) = @fields; # Skip actions we're not interested in. next unless (exists ($selectActs{$act})); @@ -530,8 +526,7 @@ re) = @fields; $dest = $x; # Skip hosts we're not interested in. - next if ($selectHosts && !(exists ($selectHosts{$src}) || exists ($selectHo -sts{$dest}))); + next if ($selectHosts && !(exists ($selectHosts{$src}) || exists ($selectHosts{$dest}))); # Convert proto to proto number. $proto = &protoNumber ($proto); @@ -566,12 +561,10 @@ sts{$dest}))); } # Count the packet as outgoing traffic from the source address. - &countPacket ($src, 's', $dest, $proto, $count, "$sport:$dport:$if:$act") i -f ($sTable); + &countPacket ($src, 's', $dest, $proto, $count, "$sport:$dport:$if:$act") if ($sTable); # Count the packet as incoming traffic to the destination address. - &countPacket ($dest, 'd', $src, $proto, $count, "$dport:$sport:$if:$act") i -f ($dTable); + &countPacket ($dest, 'd', $src, $proto, $count, "$dport:$sport:$if:$act") if ($dTable); } my $dir; @@ -588,16 +581,14 @@ foreach $dir (@dirs) { my @a = split (/\./, $a); my @b = split (/\./, $b); - $a[0] <=> $b[0] || $a[1] <=> $b[1] || $a[2] <=> $b[2] || $a[3] <=> $b[3 -]; + $a[0] <=> $b[0] || $a[1] <=> $b[1] || $a[2] <=> $b[2] || $a[3] <=> $b[3]; } sub packetSort { my ($asport, $adport, $aif, $aact) = split (/:/, $a); my ($bsport, $bdport, $bif, $bact) = split (/:/, $b); - $bact cmp $aact || $aif cmp $bif || $asport <=> $bsport || $adport <=> -$bdport; + $bact cmp $aact || $aif cmp $bif || $asport <=> $bsport || $adport <=> $bdport; } my $host; @@ -636,19 +627,15 @@ $bdport; $act = '?' unless (defined ($act = $acts{$act})); if (($protoName eq 'tcp') || ($protoName eq 'udp')) { - printf (" %-6s %7s %4d %4s %16s %2s %s.%s\n", $if, $ -act, $count, $protoName, &portName ($sport, $protoName), $arrow, $peerName, &po -rtName ($dport, $protoName)); + printf (" %-6s %7s %4d %4s %16s %2s %s.%s\n", $if, $act, $count, $protoName, &portName ($sport, $protoName), $arrow, $peerName, &portName ($dport, $protoName)); } elsif ($protoName eq 'icmp') { - printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act -, $count, $protoName, &icmpType ($sport), $arrow, $peerName); + printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act, $count, $protoName, &icmpType ($sport), $arrow, $peerName); } else { - printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act -, $count, $protoName, '', $arrow, $peerName); + printf (" %-6s %7s %4d %4s %16s %2s %s\n", $if, $act, $count, $protoName, '', $arrow, $peerName); } } } @@ -672,8 +659,7 @@ sub portName unless (exists ($pn{$pname})) { my $name = getservbyport ($port, $proto); - $pn{$pname} = (defined ($name) ? $name : ($port <= 1023 ? $port : '')); + $pn{$pname} = (defined ($name) ? $name : ($port <= 1023 ? $port : '')); } return $pn{$pname}; } diff --git a/contrib/ipfilter/solaris.c b/contrib/ipfilter/solaris.c index ce25337..c32f250 100644 --- a/contrib/ipfilter/solaris.c +++ b/contrib/ipfilter/solaris.c @@ -6,7 +6,7 @@ * to the original author and the contributors. */ /* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ -#pragma ident "@(#)$Id: solaris.c,v 2.15.2.6 2000/07/18 13:56:33 darrenr Exp $" +#pragma ident "@(#)$Id: solaris.c,v 2.15.2.7 2000/08/05 14:50:30 darrenr Exp $" #include #include @@ -51,6 +51,7 @@ #include "ipl.h" #include "ip_fil.h" #include "ip_nat.h" +#include "ip_state.h" char _depends_on[] = "drv/ip"; @@ -683,7 +684,7 @@ fixalign: s = m->b_rptr; } *mp = m2; - MTYPE(m2) = MTYPE(mt); + MTYPE(m2) = M_DATA; freemsg(mt); mt = m2; -- cgit v1.1