diff options
| author | martti <martti@NetBSD.org> | 2006-04-04 16:17:18 +0000 |
|---|---|---|
| committer | martti <martti@NetBSD.org> | 2006-04-04 16:17:18 +0000 |
| commit | 9ea58d54bc33aec41259ffe6552f8969375b59aa (patch) | |
| tree | 6d48ac3be198557f26f11a90f3b256d9c84c45de | |
| parent | 983a2072cee4b5033319b848ebc04ea4d5ce62b6 (diff) | |
Upgraded IPFilter to 4.1.13
77 files changed, 2288 insertions, 1458 deletions
diff --git a/dist/ipf/HISTORY b/dist/ipf/HISTORY index 9b93e8309ca..996f883501f 100644 --- a/dist/ipf/HISTORY +++ b/dist/ipf/HISTORY @@ -10,6 +10,167 @@ # and especially those who have found the time to port IP Filter to new # platforms. # +4.1.13 - Released 4 April 2006 + +fix bug where null pointers introduced by proxies could cause a crash + +pass out the rule flags with SIOCAUTHW + +force loading NAT rules with bad proxy labels to cause an error + +nat_state is used unsafely in calls to fr_addstate + +make return-rst and return-icmp* work with auth rules + +4.1.12 - Released 28 March 2006 + +poll support on FreeBSD/NetBSD needs to use selrecord/selwakeup + +make the fastroute code used by ipftest invoke state/NAT + +move verbose/debug macros out of fil.c and into ip_fil.h (for wider use) + +remove unused code in fr_fastroute + +fix NAT with rules that specify forward and reverise interfaces + +add missing ipfsync_canread() and ipfsync_canwrite() + +behaviour of \ on the end of a line in ipf.conf does not match older behaviour + +remove duplicate statistics line output with "ipfstat -s" +4.1.11 - Released 19 March 2006 + +Patch for NAT with ipfsync from N. Ersen (SESCI) - www.enderunix.org + +NetBSD coverity report fixes (from run 5) + +Possible to reacquire ipf_auth without releasing it in some circumstances + +Locking in FreeBSD's iplioctl for ipf_global isn't present like it shoudl be + +Add poll support for platforms I can build on: NetBSD, FreeBSD, Solaris, Linux + +Using auth rules to return "keep state" got broken with pushing fr_addstate +call into fr_firewall + +all use of '!' in map/rdr rules to match use in ipf configs + +add -L command line option to ipmon to set the default syslog facility + +looking up a port number is more complex than needed in ipft_tx.c + +allow lib/getport to work when neither tcp or udp are specified in a rule + +remove some dead code from lib/addicmpc, lib/facpri.c, lib/icmpcode.c + +program in some more cases where TCP packets fail an initial in-window +check but should be allowed to match + +filter rule added with NAT/state handling of SIOCSTPUT doesn't properly +initialise all fields, making it possible to panic + +simplify NAT ICMP error handling where it updates checksums + +rename "min" variables to "xmin" on NetBSD to avoid problems with the +macro "min" + +#ifdef's for NetBSD compile incorrect for pfil interface + +support select/poll on NetBSD + +copying out a packet with an auth rule fails (EFAULT) because the wrong +pointer is passed to copyoutptr + +ip_len/ip_off where byte swapped twice instead of once for packets +going to be stored on the auth queue + +change timeout queue manipulation functions to make fewer mutex calls + +fix use of skip rules with groups +fix coding problems discovered by the coverity project for FreeBSD + +update BPF program validation with FreeBSD changes + +4.1.10 - Released 6 December 2005 + +Expand regression testing to cover more features + +Add "coverage" build target for BSD + +Fix building 64bit sparc target for Solaris + +Add IPv6 mobility header to list of accepted keywords for V6 headers + +Resolve locking problems on Solaris when sending RST/icmp packets + +#ifdef's for IPFILTER_BPF need to check if words are defined before +using them in comparisons + +Add checking for SACK permitted option in TCP SYN packets + +Fix loading anonymous pools from inline rule configuration groups + +Add -C command line option to ipftest + +Include extra "const" from NetBSD + +Don't require SIOCKSTLCK for SIOCSTPUT + +Fix some use of "sticky" on NAT rules + +Fix statistical counting of deleting state for TCP connections + +Fix compile problems caused by changes to is_opt/is_optmsk in ip_sync.c + +Fix TCP out-of-window (OOW) problems: +- window scaling turned off if one chose for its scale factor +- Microsoft Windows TCP sends the "next packet" to the right of the window + when using SACK and filling in a hole + +4.1.9 - Released 13 August 2005 + +make ipfilter fix IPv4 header checksums for outgoing packets if BRIDGE_IPF +is defined when compiled. + +move the definition of SIOCPROXY from ip_nat.h to ip_proxy.h + +make the BSD/upgrade script more instructive about the requiements for +ip_rules.[ch] when it is run + +register for interface events on FreeBSD (>5.2.1) and NetBSD so that +"ipf -y" is not not requried to tell ipfilter about interface changes. + +for "quick" rules that do "keep state", move the state adding into the rule +evaluation so that we can detect it failing as rules are evaluated and +continue on to the next rather than wait until we're done and it's too late +to recover for more rule processing. + +mark ICMP packets advertising an MTU that's too small as being bad + +rework ipv6 header parsing to get better code reuse and fix logic errors +in dealing with ipv6 packets containing fragment headers. Also, where a +protocol handler was doing both v4 & v6, make a seperate function for each. + +build for both amd64 and i86pc (32bit) on Solaris10 and later, if possible + +include start of work to get IPFilter working on AIX 5.3 + +Use FI_ICMPERR flag rather than try to compute its equivalent all the time + +Rewrork IPv6 extension header parsing to get better code reuse + +Add missing timeout on Linux + +Fix for locking when reading from ipsync (Frank Volf) + +Fix insertion/appending of rules that use a collection number + +Somehow turning up the spl knob to splnet disappeared on platforms that still +use the spl interface. + +fix problems with "ipf -T" not listing multiple variables properly + 4.1.8 - Released 29 March 2005 include path from Phil Dibowitz for sorting ipfstat -t output by source or diff --git a/dist/ipf/Makefile b/dist/ipf/Makefile index c54e1db1b86..2a4c69d55d2 100644 --- a/dist/ipf/Makefile +++ b/dist/ipf/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.76.2.13 2004/11/08 18:42:40 darrenr Exp +# Id: Makefile,v 2.76.2.19 2006/03/17 10:38:38 darrenr Exp # SHELL=/bin/sh BINDEST=/usr/local/bin @@ -134,6 +134,7 @@ all: @echo "freebsd3 - compile for FreeBSD-3.x" @echo "freebsd4 - compile for FreeBSD-4.x" @echo "freebsd5 - compile for FreeBSD-5.x" + @echo "freebsd6 - compile for FreeBSD-6.x" @echo "bsd - compile for generic 4.4BSD systems" @echo "bsdi - compile for BSD/OS" @echo "irix - compile for SGI IRIX" @@ -186,12 +187,21 @@ freebsd22: include fi make freebsd20 -freebsd5: include +freebsd5 freebsd6: include if [ x$(INET6) = x ] ; then \ echo "#undef INET6" > opt_inet6.h; \ else \ echo "#define INET6" > opt_inet6.h; \ fi + if [ "x$(IPFBPF)" = "x" ] ; then \ + echo "#undef NBPF" > opt_bpf.h; \ + echo "#undef NBPFILTER" > opt_bpf.h; \ + echo "#undef DEV_BPF" > opt_bpf.h; \ + else \ + echo "#define NBPF" > opt_bpf.h; \ + echo "#define NBPFILTER" > opt_bpf.h; \ + echo "#define DEV_BPF" > opt_bpf.h; \ + fi if [ x$(ENABLE_PFIL) = x ] ; then \ echo "#undef PFIL_HOOKS" > opt_pfil.h; \ else \ @@ -237,6 +247,11 @@ osf tru64: null include (cd OSF/`OSF/cpurev`; make build TRU64=`uname -v` TOP=../.. "DEBUG=-g" $(MFLAGS) "MACHASSERT=$(MACHASSERT)" "OSREV=`../cpurev`"; cd ..) (cd OSF/`OSF/cpurev`; make -f Makefile.ipsend build TRU64=`uname -v` TOP=../.. $(MFLAGS) "OSREV=`../cpurev`"; cd ..) +aix: null include + make setup "TARGOS=AIX" "CPUDIR=`AIX/cpurev`" + (cd AIX/`AIX/cpurev`; make build AIX=`uname -v` TOP=../.. "DEBUG=-g" $(MFLAGS) "OSREV=`../cpurev`" BITS=`../bootbits.sh`; cd ..) +# (cd AIX/`AIX/cpurev`; make -f Makefile.ipsend build AIX=`uname -v` TOP=../.. $(MFLAGS) "OSREV=`../cpurev`"; cd ..) + bsd: include make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)" (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c" "MLR=mln_rule.o"; cd ..) @@ -277,6 +292,7 @@ clean: clean-include (cd HPUX; $(MAKE) BITS=32 TOP=.. clean) (cd Linux; $(MAKE) TOP=.. clean) (cd OSF; $(MAKE) TOP=.. clean) + (cd AIX; $(MAKE) TOP=.. clean) if [ "`uname -s`" = "IRIX" ]; then (cd IRIX; $(MAKE) clean); fi [ -d test ] && (cd test; $(MAKE) clean) (cd ipsend; $(MAKE) clean) @@ -295,6 +311,9 @@ clean-hpux: clean-include clean-osf: clean-include (cd OSF; make clean) +clean-aix: clean-include + (cd AIX; make clean) + clean-linux: clean-include (cd Linux; make clean) @@ -347,6 +366,10 @@ install-sunos4: solaris install-sunos5: solaris null (cd SunOS5; $(MAKE) CPU=$(CPU) TOP=.. install) +install-aix: + (cd AIX/`AIX/cpurev`; make install "TOP=../.." $(MFLAGS); cd ..) +# (cd AIX/`AIX/cpurev`; make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..) + install-hpux: hpux (cd HPUX/`HPUX/cpurev`; $(MAKE) CPU=$(CPU) TOP=../.. "BITS=`getconf KERNEL_BITS`" install) @@ -355,7 +378,6 @@ install-irix: irix install-osf install-tru64: (cd OSF/`OSF/cpurev`; make install "TOP=../.." $(MFLAGS); cd ..) - (cd OSF/`OSF/cpurev`; make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..) do-cvs: find . -type d -name CVS -print | xargs /bin/rm -rf @@ -378,3 +400,4 @@ mdb: -DIPFILTER_SCAN -DIPFILTER_LKM -DSOLARIS2=10 -n ipf_mdb -k \ -I/home/dr146992/pfil -I/home/dr146992/ipf -f \ /usr/include/netinet/in_systm.h,/usr/include/sys/ethernet.h,/usr/include/netinet/in.h,/usr/include/netinet/ip.h,/usr/include/netinet/ip_var.h,/usr/include/netinet/tcp.h,/usr/include/netinet/tcpip.h,/usr/include/netinet/ip_icmp.h,/usr/include/netinet/udp.h,ip_compat.h,ip_fil.h,ip_nat.h,ip_state.h,ip_proxy.h,ip_scan.h + diff --git a/dist/ipf/ip_fil.c b/dist/ipf/ip_fil.c index d9aa8cdd6d1..c211f5148eb 100644 --- a/dist/ipf/ip_fil.c +++ b/dist/ipf/ip_fil.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_fil.c,v 1.6 2005/02/08 07:01:52 martti Exp $ */ +/* $NetBSD: ip_fil.c,v 1.7 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -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.133.2.9 2005/01/08 14:22:18 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.133.2.11 2006/03/25 11:15:30 darrenr Exp"; #endif #ifndef SOLARIS @@ -138,7 +138,7 @@ struct rtentry; #include "md5.h" -#if !defined(__osf__) +#if !defined(__osf__) && !defined(__linux__) extern struct protosw inetsw[]; #endif @@ -718,13 +718,45 @@ frdest_t *fdp; { struct ifnet *ifp = fdp->fd_ifp; ip_t *ip = fin->fin_ip; + int error = 0; + frentry_t *fr; + void *sifp; if (!ifp) return 0; /* no routing table out here */ - ip->ip_len = htons((u_short)ip->ip_len); - ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); + fr = fin->fin_fr; ip->ip_sum = 0; + + if (fin->fin_out == 0) { + sifp = fin->fin_ifp; + fin->fin_ifp = ifp; + fin->fin_out = 1; + (void) fr_acctpkt(fin, NULL); + fin->fin_fr = NULL; + if (!fr || !(fr->fr_flags & FR_RETMASK)) { + u_32_t pass; + + (void) fr_checkstate(fin, &pass); + } + + switch (fr_checknatout(fin, NULL)) + { + case 0 : + break; + case 1 : + ip->ip_sum = 0; + break; + case -1 : + error = -1; + goto done; + break; + } + + fin->fin_ifp = sifp; + fin->fin_out = 0; + } + #if defined(__sgi) && (IRIX < 60500) (*ifp->if_output)(ifp, (void *)ip, NULL); # if TRU64 >= 1885 @@ -733,7 +765,8 @@ frdest_t *fdp; (*ifp->if_output)(ifp, (void *)m, NULL, 0); # endif #endif - return 0; +done: + return error; } diff --git a/dist/ipf/ipf.h b/dist/ipf/ipf.h index e02150d225f..a2e58d7a77b 100644 --- a/dist/ipf/ipf.h +++ b/dist/ipf/ipf.h @@ -1,4 +1,4 @@ -/* $NetBSD: ipf.h,v 1.10 2005/04/03 15:05:30 martti Exp $ */ +/* $NetBSD: ipf.h,v 1.11 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -6,7 +6,7 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ipf.h 1.12 6/5/96 - * Id: ipf.h,v 2.71.2.6 2005/02/21 05:05:29 darrenr Exp + * Id: ipf.h,v 2.71.2.8 2005/12/30 07:03:21 darrenr Exp */ #ifndef __IPF_H__ @@ -184,7 +184,6 @@ extern struct ipopt_names v6ionames[]; extern int addicmp __P((char ***, struct frentry *, int)); extern int addipopt __P((char *, struct ipopt_names *, int, char *)); extern int addkeep __P((char ***, struct frentry *, int)); -extern int bcopywrap __P((void *, void *, size_t)); extern void binprint __P((void *, size_t)); extern void initparse __P((void)); extern u_32_t buildopts __P((char *, char *, int)); @@ -265,6 +264,7 @@ extern void printpacket6 __P((struct ip *)); extern struct ip_pool_s *printpool __P((struct ip_pool_s *, copyfunc_t, char *, int)); extern struct ip_pool_node *printpoolnode __P((struct ip_pool_node *, int)); +extern void printproto __P((struct protoent *, int, struct ipnat *)); extern void printportcmp __P((int, struct frpcmp *)); extern void optprint __P((u_short *, u_long, u_long)); #ifdef USE_INET6 diff --git a/dist/ipf/iplang/iplang_y.y b/dist/ipf/iplang/iplang_y.y index 76bad060592..45cb5f3d948 100644 --- a/dist/ipf/iplang/iplang_y.y +++ b/dist/ipf/iplang/iplang_y.y @@ -1,4 +1,4 @@ -/* $NetBSD: iplang_y.y,v 1.8 2005/09/27 12:22:27 martti Exp $ */ +/* $NetBSD: iplang_y.y,v 1.9 2006/04/04 16:17:18 martti Exp $ */ %{ /* @@ -6,7 +6,7 @@ * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: iplang_y.y,v 2.9.2.2 2004/12/09 19:41:10 darrenr Exp + * Id: iplang_y.y,v 2.9.2.4 2006/03/17 12:11:29 darrenr Exp */ #include <stdio.h> @@ -1291,8 +1291,9 @@ void prep_packet() ifp->if_fd = initdevice(ifp->if_name, 5); gwip = sending.snd_gw; if (!gwip.s_addr) { - if (!aniphead) { - fprintf(stderr, "no destination address defined for sending!\n"); + if (aniphead == NULL) { + fprintf(stderr, + "no destination address defined for sending\n"); return; } gwip = aniphead->ah_ip->ip_dst; @@ -1647,7 +1648,7 @@ void *ptr; for (sto = toipopts; sto->sto_st; sto++) if (sto->sto_st == state) break; - if (!sto || !sto->sto_st) { + if (!sto->sto_st) { fprintf(stderr, "No mapping for state %d to IP option\n", state); return; diff --git a/dist/ipf/ipsd/sbpf.c b/dist/ipf/ipsd/sbpf.c index 8c1a3f7b25d..44a44dd56a9 100644 --- a/dist/ipf/ipsd/sbpf.c +++ b/dist/ipf/ipsd/sbpf.c @@ -1,4 +1,4 @@ -/* $NetBSD: sbpf.c,v 1.3 2004/12/01 23:51:36 christos Exp $ */ +/* $NetBSD: sbpf.c,v 1.4 2006/04/04 16:17:18 martti Exp $ */ /* * (C)opyright 1995-1998 Darren Reed. (from tcplog) @@ -11,7 +11,9 @@ #include <ctype.h> #include <signal.h> #include <errno.h> -#include <paths.h> +#ifdef __NetBSD__ +# include <paths.h> +#endif #include <sys/types.h> #include <sys/param.h> #include <sys/mbuf.h> @@ -125,17 +127,17 @@ int tout; struct timeval to; struct ifreq ifr; #ifdef _PATH_BPF - int fd; - const char *bpfname = _PATH_BPF; + char *bpfname = _PATH_BPF; + int fd; + if ((fd = open(bpfname, O_RDWR)) < 0) { - fprintf(stderr, "no bpf devices available (%s)\n", - strerror(errno)); + fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); return -1; } #else char bpfname[16]; - int fd = 0, i; + int fd = -1, i; for (i = 0; i < 16; i++) { diff --git a/dist/ipf/ipsend/arp.c b/dist/ipf/ipsend/arp.c index bfb8f06c227..1a8d9ed0c19 100644 --- a/dist/ipf/ipsend/arp.c +++ b/dist/ipf/ipsend/arp.c @@ -1,4 +1,4 @@ -/* $NetBSD: arp.c,v 1.4 2004/03/28 09:00:55 martti Exp $ */ +/* $NetBSD: arp.c,v 1.5 2006/04/04 16:17:18 martti Exp $ */ /* * arp.c (C) 1995-1998 Darren Reed @@ -7,11 +7,11 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: arp.c,v 2.8 2003/12/01 02:01:15 darrenr Exp"; +static const char rcsid[] = "@(#)Id: arp.c,v 2.8.2.1 2005/06/12 07:18:38 darrenr Exp"; #endif #include <sys/types.h> #include <sys/socket.h> -#if !defined(ultrix) && !defined(hpux) && !defined(__hpux) && !defined(__osf__) +#if !defined(ultrix) && !defined(hpux) && !defined(__hpux) && !defined(__osf__) && !defined(_AIX51) #include <sys/sockio.h> #endif #include <sys/ioctl.h> diff --git a/dist/ipf/ipsend/ipsend.c b/dist/ipf/ipsend/ipsend.c index 256e47baaf1..b83464cec5a 100644 --- a/dist/ipf/ipsend/ipsend.c +++ b/dist/ipf/ipsend/ipsend.c @@ -1,4 +1,4 @@ -/* $NetBSD: ipsend.c,v 1.13 2005/02/08 07:01:53 martti Exp $ */ +/* $NetBSD: ipsend.c,v 1.14 2006/04/04 16:17:18 martti Exp $ */ /* * ipsend.c (C) 1995-1998 Darren Reed @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: ipsend.c,v 2.8.2.2 2004/11/13 16:50:10 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ipsend.c,v 2.8.2.3 2006/03/17 13:45:34 darrenr Exp"; #endif #include <sys/param.h> #include <sys/types.h> @@ -156,6 +156,8 @@ struct in_addr gwip; int wfd; wfd = initdevice(dev, 5); + if (wfd == -1) + return -1; return send_packet(wfd, mtu, ip, gwip); } diff --git a/dist/ipf/ipsend/iptests.c b/dist/ipf/ipsend/iptests.c index 89ec5f31c02..7c04a2ccdea 100644 --- a/dist/ipf/ipsend/iptests.c +++ b/dist/ipf/ipsend/iptests.c @@ -1,4 +1,4 @@ -/* $NetBSD: iptests.c,v 1.8 2006/03/07 18:18:06 he Exp $ */ +/* $NetBSD: iptests.c,v 1.9 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. @@ -8,17 +8,17 @@ */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: iptests.c,v 2.8.2.3 2004/04/16 23:33:04 darrenr Exp"; +static const char rcsid[] = "@(#)Id: iptests.c,v 2.8.2.7 2006/03/21 16:10:55 darrenr Exp"; #endif #include <sys/param.h> #include <sys/types.h> #if defined(__NetBSD__) && defined(__vax__) -/* +/* * XXX need to declare boolean_t for _KERNEL <sys/files.h> * which ends up including <sys/device.h> for vax. See PR#32907 * for further details. */ -typedef int boolean_t; +typedef int boolean_t; #endif #include <sys/time.h> #if !defined(__osf__) @@ -40,7 +40,7 @@ typedef int boolean_t; # include <sys/proc.h> #endif #if !defined(ultrix) && !defined(hpux) && !defined(linux) && \ - !defined(__sgi) && !defined(__osf__) + !defined(__sgi) && !defined(__osf__) && !defined(_AIX51) # include <kvm.h> #endif #ifndef ultrix @@ -144,7 +144,10 @@ int ptest; u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = sizeof(*ip) + ntohs(u->uh_ulen); len = ip->ip_len; + nfd = initdevice(dev, 1); + if (nfd == -1) + return; if (!ptest || (ptest == 1)) { /* @@ -478,11 +481,14 @@ int ptest; int nfd; u_char *s; - s = (u_char *)(ip + 1); + nfd = initdevice(dev, 1); + if (nfd == -1) + return; IP_HL_A(ip, 6); ip->ip_len = IP_HL(ip) << 2; + s = (u_char *)(ip + 1); s[IPOPT_OPTVAL] = IPOPT_NOP; s++; if (!ptest || (ptest == 1)) { @@ -582,7 +588,10 @@ int ptest; ip->ip_sum = 0; ip->ip_len = sizeof(*ip) + sizeof(*icp); icp = (struct icmp *)((char *)ip + (IP_HL(ip) << 2)); + nfd = initdevice(dev, 1); + if (nfd == -1) + return; if (!ptest || (ptest == 1)) { /* @@ -781,7 +790,10 @@ int ptest; u->uh_sport = htons(1); u->uh_dport = htons(1); u->uh_ulen = htons(sizeof(*u) + 4); + nfd = initdevice(dev, 1); + if (nfd == -1) + return; if (!ptest || (ptest == 1)) { /* @@ -944,7 +956,10 @@ int ptest; t->th_seq = htonl(1); t->th_ack = 0; ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); + nfd = initdevice(dev, 1); + if (nfd == -1) + return; if (!ptest || (ptest == 1)) { /* @@ -1289,6 +1304,9 @@ int ptest; u->uh_sum = 0; nfd = initdevice(dev, 1); + if (nfd == -1) + return; + u->uh_ulen = htons(7168); printf("6. Exhaustive mbuf test.\n"); @@ -1358,6 +1376,9 @@ int ptest; u_char *s; nfd = initdevice(dev, 1); + if (nfd == -1) + return; + pip = (ip_t *)tbuf; srand(time(NULL) ^ (getpid() * getppid())); diff --git a/dist/ipf/ipsend/lsock.c b/dist/ipf/ipsend/lsock.c index 9ff16a9d093..c6d0f906066 100644 --- a/dist/ipf/ipsend/lsock.c +++ b/dist/ipf/ipsend/lsock.c @@ -1,4 +1,4 @@ -/* $NetBSD: lsock.c,v 1.4 2004/03/28 09:00:56 martti Exp $ */ +/* $NetBSD: lsock.c,v 1.5 2006/04/04 16:17:18 martti Exp $ */ /* * lsock.c (C) 1995-1998 Darren Reed @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: lsock.c,v 2.3 2001/06/09 17:09:26 darrenr Exp"; +static const char rcsid[] = "@(#)Id: lsock.c,v 2.3.4.1 2006/03/17 13:45:34 darrenr Exp"; #endif #include <stdio.h> #include <unistd.h> @@ -227,6 +227,8 @@ struct in_addr gwip; ti->ti_sport = lsin.sin_port; printf("sport %d\n", ntohs(lsin.sin_port)); nfd = initdevice(dev, 0); + if (nfd == -1) + return -1; if (!(s = find_tcp(fd, ti))) return -1; diff --git a/dist/ipf/ipsend/resend.c b/dist/ipf/ipsend/resend.c index ce7be6a0464..dba81c2a483 100644 --- a/dist/ipf/ipsend/resend.c +++ b/dist/ipf/ipsend/resend.c @@ -1,4 +1,4 @@ -/* $NetBSD: resend.c,v 1.6 2004/03/28 09:00:56 martti Exp $ */ +/* $NetBSD: resend.c,v 1.7 2006/04/04 16:17:18 martti Exp $ */ /* * resend.c (C) 1995-1998 Darren Reed @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: resend.c,v 2.8 2004/01/08 13:34:31 darrenr Exp"; +static const char rcsid[] = "@(#)Id: resend.c,v 2.8.2.2 2006/03/17 13:45:34 darrenr Exp"; #endif #include <sys/param.h> #include <sys/types.h> @@ -81,6 +81,9 @@ char *datain; ip_t *ip; int fd, wfd = initdevice(dev, 5), len, i; + if (wfd == -1) + return -1; + if (datain) fd = (*r->r_open)(datain); else @@ -101,6 +104,7 @@ char *datain; if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1)) { perror("arp"); + free(eh); return -2; } @@ -137,5 +141,6 @@ char *datain; } } (*r->r_close)(); + free(eh); return 0; } diff --git a/dist/ipf/ipsend/sbpf.c b/dist/ipf/ipsend/sbpf.c index b474d58eea3..bc0436601db 100644 --- a/dist/ipf/ipsend/sbpf.c +++ b/dist/ipf/ipsend/sbpf.c @@ -1,4 +1,4 @@ -/* $NetBSD: sbpf.c,v 1.6 2005/01/04 12:36:02 martti Exp $ */ +/* $NetBSD: sbpf.c,v 1.7 2006/04/04 16:17:18 martti Exp $ */ /* * (C)opyright 1995-1998 Darren Reed. (from tcplog) @@ -38,7 +38,9 @@ #include <string.h> #include <unistd.h> #include <stdlib.h> -#include <paths.h> +#ifdef __NetBSD__ +# include <paths.h> +#endif #include <ctype.h> #include <signal.h> #include <errno.h> @@ -47,7 +49,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: sbpf.c,v 2.5 2002/02/24 07:30:03 darrenr Exp"; +static const char rcsid[] = "@(#)Id: sbpf.c,v 2.5.4.1 2006/03/21 16:32:58 darrenr Exp"; #endif /* @@ -64,21 +66,18 @@ int tout; struct bpf_version bv; struct timeval to; struct ifreq ifr; - #ifdef _PATH_BPF - const char *bpfname = _PATH_BPF; - int fd; + char *bpfname = _PATH_BPF; + int fd; - if ((fd = open(bpfname, O_RDWR)) < 0) + if ((fd = open(bpfname, O_RDWR)) < 0) { - fprintf(stderr, "no bpf devices available (%s)\n", - strerror(errno)); + fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); return -1; } #else - int fd = 0; char bpfname[16]; - int i; + int fd = 0, i; for (i = 0; i < 16; i++) { diff --git a/dist/ipf/ipsend/sock.c b/dist/ipf/ipsend/sock.c index 317d1c9a3b8..5317f7d416e 100644 --- a/dist/ipf/ipsend/sock.c +++ b/dist/ipf/ipsend/sock.c @@ -1,4 +1,4 @@ -/* $NetBSD: sock.c,v 1.7 2006/03/07 18:18:06 he Exp $ */ +/* $NetBSD: sock.c,v 1.8 2006/04/04 16:17:18 martti Exp $ */ /* * sock.c (C) 1995-1998 Darren Reed @@ -8,19 +8,19 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: sock.c,v 2.8.4.1 2004/03/23 12:58:06 darrenr Exp"; +static const char rcsid[] = "@(#)Id: sock.c,v 2.8.4.4 2006/03/21 16:10:56 darrenr Exp"; #endif #include <sys/param.h> #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> #if defined(__NetBSD__) && defined(__vax__) -/* +/* * XXX need to declare boolean_t for _KERNEL <sys/files.h> * which ends up including <sys/device.h> for vax. See PR#32907 * for further details. */ -typedef int boolean_t; +typedef int boolean_t; #endif #ifndef ultrix #include <fcntl.h> @@ -311,19 +311,25 @@ struct tcpiphdr *ti; } #endif + o = NULL; + f = NULL; + s = NULL; + i = NULL; + t = NULL; + o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); - return NULL; + goto finderror; } f = (struct file *)calloc(1, sizeof(*f)); if (KMCPY(f, o[tfd], sizeof(*f)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); - return NULL; + goto finderror; } s = (struct socket *)calloc(1, sizeof(*s)); @@ -331,7 +337,7 @@ struct tcpiphdr *ti; { fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); - return NULL; + goto finderror; } i = (struct inpcb *)calloc(1, sizeof(*i)); @@ -339,7 +345,7 @@ struct tcpiphdr *ti; { fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); - return NULL; + goto finderror; } t = (struct tcpcb *)calloc(1, sizeof(*t)); @@ -347,9 +353,22 @@ struct tcpiphdr *ti; { fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); - return NULL; + goto finderror; } return (struct tcpcb *)i->inp_ppcb; + +finderror: + if (o != NULL) + free(o); + if (f != NULL) + free(f); + if (s != NULL) + free(s); + if (i != NULL) + free(i); + if (t != NULL) + free(t); + return NULL; } #endif /* BSD < 199301 */ @@ -391,7 +410,10 @@ struct in_addr gwip; (void) getsockname(fd, (struct sockaddr *)&lsin, &len); ti->ti_sport = lsin.sin_port; printf("sport %d\n", ntohs(lsin.sin_port)); + nfd = initdevice(dev, 1); + if (nfd == -1) + return -1; if (!(t = find_tcp(fd, ti))) return -1; diff --git a/dist/ipf/ipt.h b/dist/ipf/ipt.h index ab065a48f64..7caef4e31b3 100644 --- a/dist/ipf/ipt.h +++ b/dist/ipf/ipt.h @@ -1,11 +1,11 @@ -/* $NetBSD: ipt.h,v 1.5 2004/03/28 09:00:54 martti Exp $ */ +/* $NetBSD: ipt.h,v 1.6 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ipt.h,v 2.6 2003/02/16 02:33:09 darrenr Exp + * Id: ipt.h,v 2.6.4.2 2006/03/26 23:42:04 darrenr Exp */ #ifndef __IPT_H__ diff --git a/dist/ipf/lib/addicmp.c b/dist/ipf/lib/addicmp.c index 7c376955c39..f54d08123e0 100644 --- a/dist/ipf/lib/addicmp.c +++ b/dist/ipf/lib/addicmp.c @@ -1,11 +1,11 @@ -/* $NetBSD: addicmp.c,v 1.7 2005/05/18 00:54:14 christos Exp $ */ +/* $NetBSD: addicmp.c,v 1.8 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: addicmp.c,v 1.10.2.1 2004/12/09 19:41:16 darrenr Exp + * Id: addicmp.c,v 1.10.2.4 2006/02/25 17:41:57 darrenr Exp */ #include <ctype.h> @@ -19,76 +19,3 @@ char *icmptypes[MAX_ICMPTYPE + 1] = { "routersol", "timex", "paramprob", "timest", "timestrep", "inforeq", "inforep", "maskreq", "maskrep", "END" }; - -/* - * set the icmp field to the correct type if "icmp" word is found - */ -int addicmp(cp, fp, linenum) -char ***cp; -struct frentry *fp; -int linenum; -{ - char **t; - int i; - - (*cp)++; - if (!**cp) - return -1; - if (!fp->fr_proto) /* to catch lusers */ - fp->fr_proto = IPPROTO_ICMP; - if (ISDIGIT(***cp)) { - if (!ratoi(**cp, &i, 0, 255)) { - fprintf(stderr, - "%d: Invalid icmp-type (%s) specified\n", - linenum, **cp); - return -1; - } - } else { - for (t = icmptypes, i = 0; ; t++, i++) { - if (!*t) - continue; - if (!strcasecmp("END", *t)) { - i = -1; - break; - } - if (!strcasecmp(*t, **cp)) - break; - } - if (i == -1) { - fprintf(stderr, - "%d: Unknown icmp-type (%s) specified\n", - linenum, **cp); - return -1; - } - } - fp->fr_icmp = (u_short)(i << 8); - fp->fr_icmpm = (u_short)0xff00; - (*cp)++; - if (!**cp) - return 0; - - if (**cp && strcasecmp("code", **cp)) - return 0; - (*cp)++; - if (ISDIGIT(***cp)) { - if (!ratoi(**cp, &i, 0, 255)) { - fprintf(stderr, - "%d: Invalid icmp code (%s) specified\n", - linenum, **cp); - return -1; - } - } else { - i = icmpcode(**cp); - if (i == -1) { - fprintf(stderr, - "%d: Unknown icmp code (%s) specified\n", - linenum, **cp); - return -1; - } - } - i &= 0xff; - fp->fr_icmp |= (u_short)i; - fp->fr_icmpm = (u_short)0xffff; - (*cp)++; - return 0; -} diff --git a/dist/ipf/lib/addkeep.c b/dist/ipf/lib/addkeep.c deleted file mode 100644 index abd9c566519..00000000000 --- a/dist/ipf/lib/addkeep.c +++ /dev/null @@ -1,86 +0,0 @@ -/* $NetBSD: addkeep.c,v 1.1.1.1 2004/03/28 08:56:18 martti Exp $ */ - -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: addkeep.c,v 1.12 2003/12/01 01:59:42 darrenr Exp - */ - -#include "ipf.h" - - -/* - * Parses "keep state" and "keep frags" stuff on the end of a line. - */ -int addkeep(cp, fp, linenum) -char ***cp; -struct frentry *fp; -int linenum; -{ - char *s; - - (*cp)++; - if (!**cp) { - fprintf(stderr, "%d: Missing state/frag after keep\n", - linenum); - return -1; - } - - if (!strcasecmp(**cp, "state")) { - fp->fr_flags |= FR_KEEPSTATE; - (*cp)++; - if (**cp && !strcasecmp(**cp, "limit")) { - (*cp)++; - fp->fr_statemax = atoi(**cp); - (*cp)++; - } - if (**cp && !strcasecmp(**cp, "scan")) { - (*cp)++; - if (!strcmp(**cp, "*")) { - fp->fr_isc = NULL; - fp->fr_isctag[0] = '\0'; - } else { - strncpy(fp->fr_isctag, **cp, - sizeof(fp->fr_isctag)); - fp->fr_isctag[sizeof(fp->fr_isctag)-1] = '\0'; - fp->fr_isc = NULL; - } - (*cp)++; - } else - fp->fr_isc = (struct ipscan *)-1; - } else if (!strncasecmp(**cp, "frag", 4)) { - fp->fr_flags |= FR_KEEPFRAG; - (*cp)++; - } else if (!strcasecmp(**cp, "state-age")) { - if (fp->fr_ip.fi_p == IPPROTO_TCP) { - fprintf(stderr, "%d: cannot use state-age with tcp\n", - linenum); - return -1; - } - if ((fp->fr_flags & FR_KEEPSTATE) == 0) { - fprintf(stderr, "%d: state-age with no 'keep state'\n", - linenum); - return -1; - } - (*cp)++; - if (!**cp) { - fprintf(stderr, "%d: state-age with no arg\n", - linenum); - return -1; - } - fp->fr_age[0] = atoi(**cp); - s = strchr(**cp, '/'); - if (s != NULL) { - s++; - fp->fr_age[1] = atoi(s); - } else - fp->fr_age[1] = fp->fr_age[0]; - } else { - fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n", - linenum, **cp); - return -1; - } - return 0; -} diff --git a/dist/ipf/lib/facpri.c b/dist/ipf/lib/facpri.c index 0b38def2a8a..d6fc8d6b8fd 100644 --- a/dist/ipf/lib/facpri.c +++ b/dist/ipf/lib/facpri.c @@ -1,11 +1,11 @@ -/* $NetBSD: facpri.c,v 1.2 2006/03/18 04:12:52 elad Exp $ */ +/* $NetBSD: facpri.c,v 1.3 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp + * Id: facpri.c,v 1.6.2.4 2006/03/17 22:28:41 darrenr Exp */ #include <stdio.h> @@ -22,7 +22,7 @@ #include "facpri.h" #if !defined(lint) -static const char rcsid[] = "@(#)Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp"; +static const char rcsid[] = "@(#)Id: facpri.c,v 1.6.2.4 2006/03/17 22:28:41 darrenr Exp"; #endif @@ -42,10 +42,10 @@ table_t facs[] = { #else { "cron", LOG_CRON1 }, #endif -#ifdef LOG_FTP +#ifdef LOG_FTP { "ftp", LOG_FTP }, #endif -#ifdef LOG_AUTHPRIV +#ifdef LOG_AUTHPRIV { "authpriv", LOG_AUTHPRIV }, #endif #ifdef LOG_AUDIT @@ -84,10 +84,10 @@ fac_toname(facpri) if (j < (sizeof(facs)/sizeof(facs[0]))) { if (facs[j].value == fac) return facs[j].name; - for (i = 0; facs[i].name; i++) - if (fac == facs[i].value) - return facs[i].name; } + for (i = 0; facs[i].name; i++) + if (fac == facs[i].value) + return facs[i].name; return NULL; } @@ -96,11 +96,11 @@ fac_toname(facpri) /* * map a facility name to its number */ -int +int fac_findname(name) char *name; { - int i; + int i; for (i = 0; facs[i].name; i++) if (!strcmp(facs[i].name, name)) @@ -119,22 +119,6 @@ table_t pris[] = { /* - * map a priority name to its number - */ -int -pri_findname(name) - char *name; -{ - int i; - - for (i = 0; pris[i].name; i++) - if (!strcmp(pris[i].name, name)) - return pris[i].value; - return -1; -} - - -/* * map a priority number to its name */ char * diff --git a/dist/ipf/lib/getport.c b/dist/ipf/lib/getport.c index 03fcd179f6d..bb14fb30068 100644 --- a/dist/ipf/lib/getport.c +++ b/dist/ipf/lib/getport.c @@ -18,6 +18,33 @@ u_short *port; return -1; } + /* + * Some people will use port names in rules without specifying + * either TCP or UDP because it is implied by the group head. + * If we don't know the protocol, then the best we can do here is + * to take either only the TCP or UDP mapping (if one or the other + * is missing) or make sure both of them agree. + */ + if (fr->fr_proto == 0) { + s = getservbyname(name, "tcp"); + if (s != NULL) + p1 = s->s_port; + else + p1 = 0; + s = getservbyname(name, "udp"); + if (s != NULL) { + if (p1 != s->s_port) + return -1; + } + if ((p1 == 0) && (s == NULL)) + return -1; + if (p1) + *port = p1; + else + *port = s->s_port; + return 0; + } + if ((fr->fr_flx & FI_TCPUDP) != 0) { /* * If a rule is "tcp/udp" then check that both TCP and UDP diff --git a/dist/ipf/lib/getproto.c b/dist/ipf/lib/getproto.c index bb6ff4d050b..06022d37392 100644 --- a/dist/ipf/lib/getproto.c +++ b/dist/ipf/lib/getproto.c @@ -1,4 +1,4 @@ -/* $NetBSD: getproto.c,v 1.2 2004/11/13 19:16:10 he Exp $ */ +/* $NetBSD: getproto.c,v 1.3 2006/04/04 16:17:18 martti Exp $ */ #include "ipf.h" @@ -14,6 +14,14 @@ char *name; if (*s == '\0') return atoi(name); +#ifdef _AIX51 + /* + * For some bogus reason, "ip" is 252 in /etc/protocols on AIX 5 + */ + if (!strcasecmp(name, "ip")) + return 0; +#endif + p = getprotobyname(name); if (p != NULL) return p->p_proto; diff --git a/dist/ipf/lib/icmpcode.c b/dist/ipf/lib/icmpcode.c index f5aadbfecea..895b5cbedc9 100644 --- a/dist/ipf/lib/icmpcode.c +++ b/dist/ipf/lib/icmpcode.c @@ -1,11 +1,11 @@ -/* $NetBSD: icmpcode.c,v 1.5 2005/02/08 07:01:53 martti Exp $ */ +/* $NetBSD: icmpcode.c,v 1.6 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: icmpcode.c,v 1.7.2.1 2004/12/09 19:41:20 darrenr Exp + * Id: icmpcode.c,v 1.7.2.4 2006/02/25 17:40:22 darrenr Exp */ #include <ctype.h> @@ -22,28 +22,3 @@ char *icmpcodes[MAX_ICMPCODE + 1] = { "net-unk", "host-unk", "isolate", "net-prohib", "host-prohib", "net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff", NULL }; - -/* - * Return the number for the associated ICMP unreachable code. - */ -int icmpcode(str) -char *str; -{ - char *s; - int i, len; - - if ((s = strrchr(str, ')'))) - *s = '\0'; - if (ISDIGIT(*str)) { - if (!ratoi(str, &i, 0, 255)) - return -1; - else - return i; - } - len = strlen(str); - for (i = 0; icmpcodes[i]; i++) - if (!strncasecmp(str, icmpcodes[i], MIN(len, - strlen(icmpcodes[i])) )) - return i; - return -1; -} diff --git a/dist/ipf/lib/ipf_dotuning.c b/dist/ipf/lib/ipf_dotuning.c index 06e17c7ac85..ad0df594e10 100644 --- a/dist/ipf/lib/ipf_dotuning.c +++ b/dist/ipf/lib/ipf_dotuning.c @@ -1,7 +1,7 @@ -/* $NetBSD: ipf_dotuning.c,v 1.2 2005/06/11 12:31:40 darrenr Exp $ */ +/* $NetBSD: ipf_dotuning.c,v 1.3 2006/04/04 16:17:18 martti Exp $ */ #include "ipf.h" -#include "ipl.h" +#include "netinet/ipl.h" #include <sys/ioctl.h> void ipf_dotuning(fd, tuneargs, iocfn) diff --git a/dist/ipf/lib/ipft_hx.c b/dist/ipf/lib/ipft_hx.c index 0a55c90fe42..6fc83a83d2a 100644 --- a/dist/ipf/lib/ipft_hx.c +++ b/dist/ipf/lib/ipft_hx.c @@ -1,4 +1,4 @@ -/* $NetBSD: ipft_hx.c,v 1.5 2005/02/08 07:01:53 martti Exp $ */ +/* $NetBSD: ipft_hx.c,v 1.6 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1995-2001 by Darren Reed. @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed"; -static const char rcsid[] = "@(#)Id: ipft_hx.c,v 1.11.4.1 2004/12/09 19:41:20 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ipft_hx.c,v 1.11.4.3 2005/12/04 10:07:21 darrenr Exp"; #endif #include <ctype.h> @@ -83,7 +83,7 @@ int cnt, *dir; *s = '\0'; if (!*line) continue; - if (!(opts & OPT_BRIEF)) { + if ((opts & OPT_DEBUG) != 0) { printf("input: %s", line); } @@ -108,7 +108,7 @@ int cnt, *dir; s = line; t = (char *)ip; ip = (ip_t *)readhex(s, (char *)ip); - if (!(opts & OPT_BRIEF)) { + if ((opts & OPT_DEBUG) != 0) { if (opts & OPT_ASCII) { if (t < (char *)ip) putchar('\t'); @@ -124,6 +124,8 @@ int cnt, *dir; fflush(stdout); } } + if (feof(tfp)) + return 0; return -1; } diff --git a/dist/ipf/lib/ipft_tx.c b/dist/ipf/lib/ipft_tx.c index b3baacff633..f0dbe5c24e0 100644 --- a/dist/ipf/lib/ipft_tx.c +++ b/dist/ipf/lib/ipft_tx.c @@ -1,15 +1,15 @@ -/* $NetBSD: ipft_tx.c,v 1.5 2005/02/08 07:01:53 martti Exp $ */ +/* $NetBSD: ipft_tx.c,v 1.6 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1995-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ipft_tx.c,v 1.15.2.2 2004/12/09 19:41:21 darrenr Exp + * Id: ipft_tx.c,v 1.15.2.7 2005/12/18 14:53:39 darrenr Exp */ #if !defined(lint) static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)Id: ipft_tx.c,v 1.15.2.2 2004/12/09 19:41:21 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ipft_tx.c,v 1.15.2.7 2005/12/18 14:53:39 darrenr Exp"; #endif #include <ctype.h> @@ -31,8 +31,8 @@ static int text_open __P((char *)), text_close __P((void)); static int text_readip __P((char *, int, char **, int *)); static int parseline __P((char *, ip_t *, char **, int *)); -static char _tcp_flagset[] = "FSRPAUEC"; -static u_char _tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, +static char myflagset[] = "FSRPAUEC"; +static u_char myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG, TH_ECN, TH_CWR }; struct ipread iptext = { text_open, text_close, text_readip, R_DO_CKSUM }; @@ -75,36 +75,15 @@ int *resolved; static u_short tx_portnum(name) char *name; { - struct servent *sp, *sp2; - u_short p1 = 0; + struct servent *sp; if (ISDIGIT(*name)) return (u_short)atoi(name); - if (!tx_proto) - tx_proto = "tcp/udp"; - if (strcasecmp(tx_proto, "tcp/udp")) { - sp = getservbyname(name, tx_proto); - if (sp) - return ntohs(sp->s_port); - (void) fprintf(stderr, "unknown service \"%s\".\n", name); - return 0; - } - sp = getservbyname(name, "tcp"); + sp = getservbyname(name, tx_proto); if (sp) - p1 = sp->s_port; - sp2 = getservbyname(name, "udp"); - if (!sp || !sp2) { - (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n", - name); - return 0; - } - if (p1 != sp2->s_port) { - (void) fprintf(stderr, "%s %d/tcp is a different port to ", - name, p1); - (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port); - return 0; - } - return ntohs(p1); + return ntohs(sp->s_port); + (void) fprintf(stderr, "unknown service \"%s\".\n", name); + return 0; } @@ -161,7 +140,7 @@ int cnt, *dir; *s = '\0'; if (!*line) continue; - if (!(opts & OPT_BRIEF)) + if ((opts & OPT_DEBUG) != 0) printf("input: %s\n", line); *ifn = NULL; *dir = 0; @@ -172,6 +151,8 @@ int cnt, *dir; return sizeof(ip_t); #endif } + if (feof(tfp)) + return 0; return -1; } @@ -280,14 +261,12 @@ int *out; ip->ip_dst.s_addr = tx_hostnum(*cpp, &r); cpp++; if (*cpp && ip->ip_p == IPPROTO_TCP) { - extern char _tcp_flagset[]; - extern u_char _tcp_flags[]; char *s, *t; tcp->th_flags = 0; for (s = *cpp; *s; s++) - if ((t = strchr(_tcp_flagset, *s))) - tcp->th_flags |= _tcp_flags[t - _tcp_flagset]; + if ((t = strchr(myflagset, *s))) + tcp->th_flags |= myflags[t - myflagset]; if (tcp->th_flags) cpp++; if (tcp->th_flags == 0) @@ -299,15 +278,22 @@ int *out; char **s, *t; int i; + t = strchr(*cpp, ','); + if (t != NULL) + *t = '\0'; + for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END"); - s++, i++) - if (*s && !strncasecmp(*cpp, *s, strlen(*s))) { + s++, i++) { + if (*s && !strcasecmp(*cpp, *s)) { ic->icmp_type = i; - if ((t = strchr(*cpp, ','))) - ic->icmp_code = atoi(t+1); + if (t != NULL) + ic->icmp_code = atoi(t + 1); cpp++; break; } + } + if (t != NULL) + *t = ','; } if (*cpp && !strcasecmp(*cpp, "opt")) { diff --git a/dist/ipf/lib/kmem.c b/dist/ipf/lib/kmem.c index d5f5fb10b2f..5c31db4dc51 100644 --- a/dist/ipf/lib/kmem.c +++ b/dist/ipf/lib/kmem.c @@ -1,4 +1,4 @@ -/* $NetBSD: kmem.c,v 1.3 2004/07/23 05:39:03 martti Exp $ */ +/* $NetBSD: kmem.c,v 1.4 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -18,7 +18,7 @@ #include <string.h> #include <fcntl.h> #include <sys/file.h> -#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51) #include <kvm.h> #endif #include <fcntl.h> @@ -44,12 +44,13 @@ #if !defined(lint) static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; -static const char rcsid[] = "@(#)Id: kmem.c,v 1.16.2.1 2004/06/20 10:25:58 darrenr Exp"; +static const char rcsid[] = "@(#)Id: kmem.c,v 1.16.2.2 2005/06/12 07:18:41 darrenr Exp"; #endif -#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \ + !defined(linux) && !defined(_AIX51) /* * For all platforms where there is a libkvm and a kvm_t, we use that... */ diff --git a/dist/ipf/lib/make_range.c b/dist/ipf/lib/make_range.c deleted file mode 100644 index 82e6ce34bc2..00000000000 --- a/dist/ipf/lib/make_range.c +++ /dev/null @@ -1,26 +0,0 @@ -/* $NetBSD: make_range.c,v 1.1.1.1 2004/03/28 08:56:19 martti Exp $ */ - -/* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: make_range.c,v 1.2 2002/05/18 07:27:52 darrenr Exp - */ -#include "ipf.h" - - -alist_t *make_range(not, a1, a2) -int not; -struct in_addr a1, a2; -{ - alist_t *a; - - a = (alist_t *)calloc(1, sizeof(*a)); - if (a != NULL) { - a->al_1 = a1.s_addr; - a->al_2 = a2.s_addr; - a->al_not = not; - } - return a; -} diff --git a/dist/ipf/lib/v6ionames.c b/dist/ipf/lib/v6ionames.c index ec42a508f26..653efee835d 100644 --- a/dist/ipf/lib/v6ionames.c +++ b/dist/ipf/lib/v6ionames.c @@ -1,11 +1,11 @@ -/* $NetBSD: v6ionames.c,v 1.4 2005/02/08 07:01:54 martti Exp $ */ +/* $NetBSD: v6ionames.c,v 1.5 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: v6ionames.c,v 1.1.4.1 2005/01/02 13:08:49 darrenr Exp + * Id: v6ionames.c,v 1.1.4.2 2005/10/17 18:31:09 darrenr Exp */ #include "ipf.h" @@ -21,6 +21,7 @@ struct ipopt_names v6ionames[] ={ { IPPROTO_AH, 0x000020, 0, "ah" }, { IPPROTO_NONE, 0x000040, 0, "none" }, { IPPROTO_DSTOPTS, 0x000080, 0, "dstopts" }, + { IPPROTO_MOBILITY, 0x000100, 0, "mobility" }, { 0, 0, 0, (char *)NULL } }; diff --git a/dist/ipf/man/ipf.5 b/dist/ipf/man/ipf.5 index c5f112ceaef..6ce07fd6ea3 100644 --- a/dist/ipf/man/ipf.5 +++ b/dist/ipf/man/ipf.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: ipf.5,v 1.10 2004/03/28 09:00:56 martti Exp $ +.\" $NetBSD: ipf.5,v 1.11 2006/04/04 16:17:18 martti Exp $ .\" .TH IPF 5 .SH NAME @@ -58,8 +58,8 @@ port-range = "port" port-num range port-num . flags = "flags" flag { flag } [ "/" flag { flag } ] . with = "with" | "and" . icmp = "icmp-type" icmp-type [ "code" decnumber ] . -return-code = "("icmp-code")" . -keep = "keep" "state" | "keep" "frags" . +return-code = "(" icmp-code ")" . +keep = "keep" "state" [ "(" state-options ")" ] | "keep" "frags" . loglevel = facility"."priority | priority . nummask = host-name [ "/" decnumber ] . @@ -67,7 +67,10 @@ host-name = ipaddr | hostname | "any" . ipaddr = host-num "." host-num "." host-num "." host-num . host-num = digit [ digit [ digit ] ] . port-num = service-name | decnumber . +state-options = state-opts [ "," state-options ] . +state-opts = "age" decnumber [ "/" decnumber ] | "strict" | + "no-icmp-err" | "limit" decnumber | "newisn" | "sync" . withopt = [ "not" | "no" ] opttype [ withopt ] . opttype = "ipopts" | "short" | "frag" | "opt" optname . optname = ipopts [ "," optname ] . diff --git a/dist/ipf/man/ipftest.1 b/dist/ipf/man/ipftest.1 index 99dd33ee2d7..89f1a1ce43c 100644 --- a/dist/ipf/man/ipftest.1 +++ b/dist/ipf/man/ipftest.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: ipftest.1,v 1.6 2005/02/08 07:01:54 martti Exp $ +.\" $NetBSD: ipftest.1,v 1.7 2006/04/04 16:17:18 martti Exp $ .\" .TH ipftest 1 .SH NAME @@ -6,7 +6,7 @@ ipftest \- test packet filter rules with arbitrary input. .SH SYNOPSIS .B ipftest [ -.B \-6bdDoRvx +.B \-6bCdDoRvx ] [ .B \-F input-format @@ -29,6 +29,9 @@ interface .B \-r <filename> ] [ +.B \-S +<ip_address> +] [ .B \-T <optionlist> ] @@ -58,6 +61,11 @@ Cause the output to be a brief summary (one-word) of the result of passing the packet through the filter; either "pass", "block" or "nomatch". This is used in the regression testing. .TP +.B \-C +Force the checksums to be (re)calculated for all packets being input into +\fBipftest\fP. This may be necessary if pcap files from tcpdump are being +fed in where there are partial checksums present due to hardware offloading. +.TP .B \-d Turn on filter rule debugging. Currently, this only shows you what caused the rule to not match in the IP header checking (addresses/netmasks, etc). @@ -169,6 +177,14 @@ Specify the filename from which to read filter rules in \fBipf\fP(5) format. .B \-R Don't attempt to convert IP addresses to hostnames. .TP +.BR \-S \0<ip_address> +The IP address specifived with this option is used by ipftest to determine +whether a packet should be treated as "input" or "output". If the source +address in an IP packet matches then it is considered to be inbound. If it +does not match then it is considered to be outbound. This is primarily +for use with tcpdump (pcap) files where there is no in/out information +saved with each packet. +.TP .BR \-T \0<optionlist> This option simulates the run-time changing of IPFilter kernel variables available with the \fB\-T\fP option of \fBipf\fP. diff --git a/dist/ipf/man/ipmon.8 b/dist/ipf/man/ipmon.8 index 22953edeb77..49e2fdce63c 100644 --- a/dist/ipf/man/ipmon.8 +++ b/dist/ipf/man/ipmon.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: ipmon.8,v 1.16 2005/04/20 19:53:04 reed Exp $ +.\" $NetBSD: ipmon.8,v 1.17 2006/04/04 16:17:18 martti Exp $ .\" .TH ipmon 8 .SH NAME @@ -6,10 +6,12 @@ ipmon \- monitors /dev/ipl for logged packets .SH SYNOPSIS .B ipmon [ -.B \-abDFhnpstvxX +.B \-abBDFhnpstvxX ] [ .B "\-N <device>" ] [ +.B "\-L <facility>" +] [ .B "\-o [NSI]" ] [ .B "\-O [NSI]" @@ -86,6 +88,11 @@ are displayed to the same output 'device' (stderr or syslog). For rules which log the body of a packet, generate hex output representing the packet contents after the headers. .TP +.B \-B <binarylogfilename> +Enable logging of the raw, unformatted binary data to the specified +\fI<binarylogfilename>\fP file. This can be read, later, using \fBipmon\fP +with the \fB-f\fP option. +.TP .B \-D Cause ipmon to turn itself into a daemon. Using subshells or backgrounding of ipmon is not required to turn it into an orphan so it can run indefinitely. @@ -98,6 +105,9 @@ for normal IP Filter log records. Flush the current packet log buffer. The number of bytes flushed is displayed, even should the result be zero. .TP +.B \-L <facility> +Using this option allows you to change the default syslog facility that +ipmon uses for syslog messages. The default is local0. .B \-n IP addresses and port numbers will be mapped, where possible, back into hostnames and service names. diff --git a/dist/ipf/man/ipnat.5 b/dist/ipf/man/ipnat.5 index 46a10dfaf4d..a96e2647f62 100644 --- a/dist/ipf/man/ipnat.5 +++ b/dist/ipf/man/ipnat.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: ipnat.5,v 1.18 2005/12/04 23:37:27 rpaulo Exp $ +.\" $NetBSD: ipnat.5,v 1.19 2006/04/04 16:17:18 martti Exp $ .\" .TH IPNAT 5 .SH NAME @@ -12,9 +12,10 @@ ipmap :: = mapblock | redir | map . map ::= mapit ifname lhs "->" dstipmask [ mapicmp | mapport | mapproxy ] mapoptions . mapblock ::= "map-block" ifname lhs "->" ipmask [ ports ] mapoptions . -redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] rdrport rdroptions . +redir ::= "rdr" ifname rlhs "->" ip [ "," ip ] rdrport rdroptions . lhs ::= ipmask | fromto . +rlhs ::= ipmask dport | fromto . dport ::= "port" portnum [ "-" portnum ] . ports ::= "ports" numports | "auto" . rdrport ::= "port" portnum . diff --git a/dist/ipf/man/ipnat.8 b/dist/ipf/man/ipnat.8 index 47845b36bf8..22b6612199c 100644 --- a/dist/ipf/man/ipnat.8 +++ b/dist/ipf/man/ipnat.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: ipnat.8,v 1.8 2005/01/21 15:10:16 wiz Exp $ +.\" $NetBSD: ipnat.8,v 1.9 2006/04/04 16:17:18 martti Exp $ .\" .TH IPNAT 8 .SH NAME @@ -58,7 +58,7 @@ This flag (no-change) prevents \fBipf\fP from actually making any ioctl calls or doing anything which would alter the currently running kernel. .TP .B \-r -Remove matching NAT rules rather than add them to the internal lists +Remove matching NAT rules rather than add them to the internal lists. .TP .B \-s Retrieve and display NAT statistics. diff --git a/dist/ipf/radix.c b/dist/ipf/radix.c index f93fd81d83e..f1bd88c434c 100644 --- a/dist/ipf/radix.c +++ b/dist/ipf/radix.c @@ -1,4 +1,4 @@ -/* $NetBSD: radix.c,v 1.3 2006/02/25 01:58:39 wiz Exp $ */ +/* $NetBSD: radix.c,v 1.4 2006/04/04 16:17:18 martti Exp $ */ /* * Copyright (c) 1988, 1989, 1993 @@ -103,6 +103,12 @@ static int rn_lexobetter __P((void *, void *)); static struct radix_mask *rn_new_radix_mask __P((struct radix_node *, struct radix_mask *)); static int rn_freenode __P((struct radix_node *, void *)); +#if defined(AIX) && !defined(_KERNEL) +struct radix_node *rn_match __P((void *, struct radix_node_head *)); +struct radix_node *rn_addmask __P((int, int, void *)); +#define FreeS(x, y) KFREES(x, y) +#define Bcopy(x, y, z) bcopy(x, y, z) +#endif /* * The data structure for the keys is a radix tree with one way diff --git a/dist/ipf/samples/proxy.c b/dist/ipf/samples/proxy.c index 1e001682e61..7e2ba2c0bcb 100644 --- a/dist/ipf/samples/proxy.c +++ b/dist/ipf/samples/proxy.c @@ -1,4 +1,4 @@ -/* $NetBSD: proxy.c,v 1.6 2005/04/03 15:05:30 martti Exp $ */ +/* $NetBSD: proxy.c,v 1.7 2006/04/04 16:17:18 martti Exp $ */ /* * Sample transparent proxy program. @@ -57,7 +57,6 @@ char *argv[]; struct sockaddr_in sin, sloc, sout; ipfobj_t obj; natlookup_t natlook; - natlookup_t *natlookp = &natlook; char buffer[512]; int namelen, fd, n; @@ -94,8 +93,8 @@ char *argv[]; natlook.nl_outip = sin.sin_addr; natlook.nl_inip = sloc.sin_addr; natlook.nl_flags = IPN_TCP; - natlook.nl_outport = ntohs(sin.sin_port); - natlook.nl_inport = ntohs(sloc.sin_port); + natlook.nl_outport = sin.sin_port; + natlook.nl_inport = sloc.sin_port; /* * Open the NAT device and lookup the mapping pair. diff --git a/dist/ipf/tools/ipf_y.y b/dist/ipf/tools/ipf_y.y index 1d37e516eba..d03887c4c6e 100644 --- a/dist/ipf/tools/ipf_y.y +++ b/dist/ipf/tools/ipf_y.y @@ -3,7 +3,8 @@ #include <sys/ioctl.h> #include <syslog.h> #ifdef IPFILTER_BPF -# include <pcap-bpf.h> +# include "pcap-bpf.h" +# define _NET_BPF_H_ # include <pcap.h> #endif #include "netinet/ip_pool.h" @@ -56,7 +57,7 @@ static struct wordtab icmpcodewords[17]; static struct wordtab icmptypewords[16]; static struct wordtab ipv4optwords[25]; static struct wordtab ipv4secwords[9]; -static struct wordtab ipv6optwords[8]; +static struct wordtab ipv6optwords[9]; static struct wordtab logwords[33]; %} @@ -78,6 +79,10 @@ static struct wordtab logwords[33]; union i6addr m; } ipp; union i6addr ip6; + struct { + char *if1; + char *if2; + } ifs; }; %type <port> portnum @@ -90,6 +95,7 @@ static struct wordtab logwords[33]; %type <str> servicename name interfacename %type <pc> portrange portcomp %type <alist> addrlist poollist +%type <ifs> onname %token <num> YY_NUMBER YY_HEX %token <str> YY_STR @@ -98,7 +104,7 @@ static struct wordtab logwords[33]; %token YY_RANGE_OUT YY_RANGE_IN %token <ip6> YY_IPV6 -%token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL +%token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL IPFY_NOMATCH %token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST %token IPFY_IN IPFY_OUT %token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA @@ -133,6 +139,7 @@ static struct wordtab logwords[33]; %token IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS %token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING +%token IPFY_IPV6OPT_MOBILITY IPFY_IPV6OPT_ESP IPFY_IPV6OPT_FRAG %token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH %token IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST @@ -174,7 +181,7 @@ line: xx rule { while ((fr = frtop) != NULL) { | YY_COMMENT ; -xx: { newrule(); } +xx: { newrule(); } ; assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); @@ -253,6 +260,7 @@ collection: action: block | IPFY_PASS { fr->fr_flags |= FR_PASS; } + | IPFY_NOMATCH { fr->fr_flags |= FR_NOMATCH; } | log | IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; } | auth @@ -282,7 +290,7 @@ log: IPFY_LOG { fr->fr_flags |= FR_LOG; } ; auth: IPFY_AUTH { fr->fr_flags |= FR_AUTH; } - | IPFY_AUTH IPFY_RETRST { fr->fr_flags |= (FR_AUTH|FR_RETRST);} + | IPFY_AUTH blockreturn { fr->fr_flags |= FR_AUTH;} | IPFY_PREAUTH { fr->fr_flags |= FR_PREAUTH; } ; @@ -463,18 +471,41 @@ quick: ; on: IPFY_ON onname + | IPFY_ON lstart onlist lend | IPFY_ON onname IPFY_INVIA vianame | IPFY_ON onname IPFY_OUTVIA vianame ; +onlist: onname { DOREM(strncpy(fr->fr_ifnames[0], $1.if1, \ + sizeof(fr->fr_ifnames[0])); \ + if ($1.if2 != NULL) { \ + strncpy(fr->fr_ifnames[1], \ + $1.if2, \ + sizeof(fr->fr_ifnames[1]));\ + } \ + ) } + | onlist lmore onname { DOREM(strncpy(fr->fr_ifnames[0], $3.if1, \ + sizeof(fr->fr_ifnames[0])); \ + if ($3.if2 != NULL) { \ + strncpy(fr->fr_ifnames[1], \ + $3.if2, \ + sizeof(fr->fr_ifnames[1]));\ + } \ + ) } + ; + onname: interfacename { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0])); + $$.if1 = fr->fr_ifnames[0]; + $$.if2 = NULL; free($1); } | interfacename ',' interfacename { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0])); + $$.if1 = fr->fr_ifnames[0]; free($1); strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1])); + $$.if1 = fr->fr_ifnames[1]; free($3); } ; @@ -1023,7 +1054,8 @@ codelist: icmpcode { DOREM(fr->fr_icmp |= htons($1); fr->fr_icmpm |= htons(0xff);) } | codelist lmore icmpcode - { DOREM(fr->fr_icmp |= htons($3); fr->fr_icmpm |= htons(0xff);) } + { DOREM(fr->fr_icmp &= htons(0xff00); fr->fr_icmp |= htons($3); \ + fr->fr_icmpm |= htons(0xff);) } ; age: | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ @@ -1083,6 +1115,11 @@ stateopt: | IPFY_NOICMPERR { DOALL(fr->fr_flags |= FR_NOICMPERR;) } | IPFY_SYNC { DOALL(fr->fr_flags |= FR_STATESYNC;) } + | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ + fr->fr_age[1] = $2;) } + | IPFY_AGE YY_NUMBER '/' YY_NUMBER + { DOALL(fr->fr_age[0] = $2; \ + fr->fr_age[1] = $4;) } ; portnum: @@ -1099,15 +1136,14 @@ portnum: ; withlist: - withopt - | withlist withopt - | withlist ',' withopt + withopt { nowith = 0; } + | withlist withopt { nowith = 0; } + | withlist ',' withopt { nowith = 0; } ; withopt: opttype { DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) } - | notwith opttype - { DOALL(fr->fr_mflx |= $2;) } + | notwith opttype { DOALL(fr->fr_mflx |= $2;) } | ipopt ipopts { yyresetdict(); } | notwith ipopt ipopts { yyresetdict(); } | startv6hdrs ipv6hdrs { yyresetdict(); } @@ -1265,12 +1301,13 @@ setsecclass: ipv6hdr: IPFY_AH { $$ = getv6optbyvalue(IPPROTO_AH); } | IPFY_IPV6OPT_DSTOPTS { $$ = getv6optbyvalue(IPPROTO_DSTOPTS); } - | IPFY_ESP { $$ = getv6optbyvalue(IPPROTO_ESP); } + | IPFY_IPV6OPT_ESP { $$ = getv6optbyvalue(IPPROTO_ESP); } | IPFY_IPV6OPT_HOPOPTS { $$ = getv6optbyvalue(IPPROTO_HOPOPTS); } | IPFY_IPV6OPT_IPV6 { $$ = getv6optbyvalue(IPPROTO_IPV6); } | IPFY_IPV6OPT_NONE { $$ = getv6optbyvalue(IPPROTO_NONE); } | IPFY_IPV6OPT_ROUTING { $$ = getv6optbyvalue(IPPROTO_ROUTING); } - | IPFY_FRAG { $$ = getv6optbyvalue(IPPROTO_FRAGMENT); } + | IPFY_IPV6OPT_FRAG { $$ = getv6optbyvalue(IPPROTO_FRAGMENT); } + | IPFY_IPV6OPT_MOBILITY { $$ = getv6optbyvalue(IPPROTO_MOBILITY); } ; level: IPFY_LEVEL { setsyslog(); } @@ -1432,6 +1469,7 @@ static struct wordtab ipfwords[95] = { { "mask", IPFY_MASK }, { "match-tag", IPFY_MATCHTAG }, { "mbcast", IPFY_MBCAST }, + { "mcast", IPFY_MULTICAST }, { "multicast", IPFY_MULTICAST }, { "nat", IPFY_NAT }, { "ne", YY_CMP_NE }, @@ -1439,6 +1477,7 @@ static struct wordtab ipfwords[95] = { { "newisn", IPFY_NEWISN }, { "no", IPFY_NO }, { "no-icmp-err", IPFY_NOICMPERR }, + { "nomatch", IPFY_NOMATCH }, { "now", IPFY_NOW }, { "not", IPFY_NOT }, { "oow", IPFY_OOW }, @@ -1571,12 +1610,13 @@ static struct wordtab ipv4secwords[9] = { { NULL, 0 }, }; -static struct wordtab ipv6optwords[8] = { +static struct wordtab ipv6optwords[9] = { { "dstopts", IPFY_IPV6OPT_DSTOPTS }, - { "esp", IPFY_ESP }, - { "frag", IPFY_FRAG }, + { "esp", IPFY_IPV6OPT_ESP }, + { "frag", IPFY_IPV6OPT_FRAG }, { "hopopts", IPFY_IPV6OPT_HOPOPTS }, { "ipv6", IPFY_IPV6OPT_IPV6 }, + { "mobility", IPFY_IPV6OPT_MOBILITY }, { "none", IPFY_IPV6OPT_NONE }, { "routing", IPFY_IPV6OPT_ROUTING }, { NULL, 0 }, @@ -1746,18 +1786,6 @@ static frentry_t *addrule() ; count = nrules; - if (count == 0) { - f = (frentry_t *)calloc(sizeof(*f), 1); - added++; - f2->fr_next = f; - bcopy(f2, f, sizeof(*f)); - if (f2->fr_caddr != NULL) { - f->fr_caddr = malloc(f->fr_dsize); - bcopy(f2->fr_caddr, f->fr_caddr, f->fr_dsize); - } - f->fr_next = NULL; - return f; - } f = f2; for (f1 = frc; count > 0; count--, f1 = f1->fr_next) { f->fr_next = (frentry_t *)calloc(sizeof(*f), 1); @@ -1823,8 +1851,7 @@ char *phrase; fr->fr_v = v; fr->fr_type = FR_T_BPFOPC; - if (!strncmp(phrase, "\"0x", 2)) { - phrase++; + if (!strncmp(phrase, "0x", 2)) { fb = malloc(sizeof(fakebpf_t)); for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL; @@ -2029,7 +2056,7 @@ void *ptr; del = SIOCRMAFR; } - if (fr && (opts & OPT_OUTQUE)) + if ((opts & OPT_OUTQUE) != 0) fr->fr_flags |= FR_OUTQUE; if (fr->fr_hits) fr->fr_hits--; diff --git a/dist/ipf/tools/ipfs.c b/dist/ipf/tools/ipfs.c index 7489ff7f6c7..5ccc28a29c3 100644 --- a/dist/ipf/tools/ipfs.c +++ b/dist/ipf/tools/ipfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: ipfs.c,v 1.6 2005/04/03 15:05:30 martti Exp $ */ +/* $NetBSD: ipfs.c,v 1.7 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1999-2001, 2003 by Darren Reed. @@ -41,7 +41,7 @@ #include <arpa/nameser.h> #include <resolv.h> #include "ipf.h" -#include "ipl.h" +#include "netinet/ipl.h" #if !defined(lint) static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp"; @@ -460,21 +460,19 @@ char *file; i = read(sfd, &ips, sizeof(ips)); if (i == -1) { perror("read"); - close(sfd); - return 1; + goto freeipshead; } if (i == 0) break; if (i != sizeof(ips)) { fprintf(stderr, "state:incomplete read: %d != %d\n", i, (int)sizeof(ips)); - close(sfd); - return 1; + goto freeipshead; } is = (ipstate_save_t *)malloc(sizeof(*is)); - if(!is) { + if (is == NULL) { fprintf(stderr, "malloc failed\n"); - return 1; + goto freeipshead; } bcopy((char *)&ips, (char *)is, sizeof(ips)); @@ -512,7 +510,7 @@ char *file; obj.ipfo_size = sizeof(*is); obj.ipfo_type = IPFOBJ_STATESAVE; - for (is = ipshead; is; is = is->ips_next) { + while ((is = ipshead) != NULL) { if (opts & OPT_VERBOSE) printf("Loading new state table entry\n"); if (is->ips_is.is_flags & SI_NEWFR) { @@ -524,7 +522,7 @@ char *file; if (!(opts & OPT_DONOTHING)) if (ioctl(fd, SIOCSTPUT, &obj)) { perror("SIOCSTPUT"); - return 1; + goto freeipshead; } if (is->ips_is.is_flags & SI_NEWFR) { @@ -534,9 +532,21 @@ char *file; if (is1->ips_rule == (frentry_t *)&is->ips_rule) is1->ips_rule = is->ips_rule; } + + ipshead = is->ips_next; + free(is); } return 0; + +freeipshead: + while ((is = ipshead) != NULL) { + ipshead = is->ips_next; + free(is); + } + if (sfd != -1) + close(sfd); + return 1; } @@ -575,21 +585,21 @@ char *file; i = read(nfd, &ipn, sizeof(ipn)); if (i == -1) { perror("read"); - close(nfd); - return 1; + goto freenathead; } if (i == 0) break; if (i != sizeof(ipn)) { fprintf(stderr, "nat:incomplete read: %d != %d\n", i, (int)sizeof(ipn)); - close(nfd); - return 1; + goto freenathead; } in = (nat_save_t *)malloc(ipn.ipn_dsize); - if (!in) - break; + if (in == NULL) { + fprintf(stderr, "nat:cannot malloc nat save atruct\n"); + goto freenathead; + } if (ipn.ipn_dsize > sizeof(ipn)) { n = ipn.ipn_dsize - sizeof(ipn); @@ -602,8 +612,7 @@ char *file; fprintf(stderr, "nat:incomplete read: %d != %d\n", i, n); - close(nfd); - return 1; + goto freenathead; } } } @@ -645,7 +654,7 @@ char *file; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_NATSAVE; - for (in = ipnhead; in; in = in->ipn_next) { + while ((in = ipnhead) != NULL) { if (opts & OPT_VERBOSE) printf("Loading new NAT table entry\n"); nat = &in->ipn_nat; @@ -670,9 +679,21 @@ char *file; if (in1->ipn_rule == &in->ipn_fr) in1->ipn_rule = nat->nat_fr; } + + ipnhead = in->ipn_next; + free(in); } return 0; + +freenathead: + while ((in = ipnhead) != NULL) { + ipnhead = in->ipn_next; + free(in); + } + if (nfd != -1) + close(nfd); + return 1; } diff --git a/dist/ipf/tools/ipfstat.c b/dist/ipf/tools/ipfstat.c index 15b02f4d9b4..f9678fdf246 100644 --- a/dist/ipf/tools/ipfstat.c +++ b/dist/ipf/tools/ipfstat.c @@ -1,4 +1,4 @@ -/* $NetBSD: ipfstat.c,v 1.11 2005/06/02 09:53:00 lukem Exp $ */ +/* $NetBSD: ipfstat.c,v 1.12 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -70,7 +70,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: ipfstat.c,v 1.44.2.11 2005/03/30 14:09:57 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ipfstat.c,v 1.44.2.14 2006/03/21 16:09:58 darrenr Exp"; #endif #ifdef __hpux @@ -925,8 +925,6 @@ ips_stat_t *ipsp; ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp); PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, ipsp->iss_miss); - PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu max bucket\n", - ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_bucketfull); PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\n", ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse); PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n", @@ -1008,11 +1006,11 @@ int topclosed; { char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; - int i, j, winy, tsentry, maxx, maxy, redraw = 0; - int len, srclen, dstlen, forward = 1, c = 0, ret = 0; - const char *errstr = NULL; + int i, j, winy, tsentry, maxx, maxy, redraw = 0, ret = 0; + int len, srclen, dstlen, forward = 1, c = 0; ips_stat_t ipsst, *ipsstp = &ipsst; statetop_t *tstable = NULL, *tp; + const char *errstr = ""; ipstate_t ips; ipfobj_t ipfo; struct timeval selecttimeout; @@ -1421,14 +1419,12 @@ int topclosed; out: printw("\n"); curs_set(1); - nocbreak(); + /* nocbreak(); XXX - endwin() should make this redundant */ endwin(); free(tstable); - if (ret != 0) { + if (ret != 0) perror(errstr); - exit(ret); - } } #endif diff --git a/dist/ipf/tools/ipmon.c b/dist/ipf/tools/ipmon.c index 09342792e9a..6210630f3be 100644 --- a/dist/ipf/tools/ipmon.c +++ b/dist/ipf/tools/ipmon.c @@ -1,4 +1,4 @@ -/* $NetBSD: ipmon.c,v 1.6 2005/02/08 07:01:54 martti Exp $ */ +/* $NetBSD: ipmon.c,v 1.7 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -78,7 +78,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 1.33.2.8 2004/12/09 19:41:26 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ipmon.c,v 1.33.2.15 2006/03/18 06:59:39 darrenr Exp"; #endif @@ -191,6 +191,7 @@ static char *conf_file = NULL; #ifndef LOGFAC #define LOGFAC LOG_LOCAL0 #endif +int logfac = LOGFAC; static icmp_subtype_t icmpunreachnames[] = { @@ -420,6 +421,14 @@ static void init_tabs() p->p_name != NULL && protocols[p->p_proto] == NULL) protocols[p->p_proto] = strdup(p->p_name); endprotoent(); +#if defined(_AIX51) + if (protocols[0]) + free(protocols[0]); + if (protocols[252]) + free(protocols[252]); + protocols[0] = "ip"; + protocols[252] = NULL; +#endif } if (udp_ports != NULL) { @@ -642,10 +651,10 @@ int len; if (j && !(j & 0xf)) { *t++ = '\n'; *t = '\0'; - if (!(dopts & OPT_SYSLOG)) - fputs(hline, log); - else + if ((dopts & OPT_SYSLOG)) syslog(LOG_INFO, "%s", hline); + else if (log != NULL) + fputs(hline, log); t = (u_char *)hline; *t = '\0'; } @@ -678,11 +687,12 @@ int len; *t++ = '\n'; *t = '\0'; } - if (!(dopts & OPT_SYSLOG)) { + if ((dopts & OPT_SYSLOG) != 0) + syslog(LOG_INFO, "%s", hline); + else if (log != NULL) { fputs(hline, log); fflush(log); - } else - syslog(LOG_INFO, "%s", hline); + } } @@ -776,7 +786,7 @@ int blen; *t++ = '\0'; if (opts & OPT_SYSLOG) syslog(LOG_INFO, "%s", line); - else + else if (log != NULL) (void) fprintf(log, "%s", line); } @@ -893,7 +903,7 @@ int blen; *t++ = '\0'; if (opts & OPT_SYSLOG) syslog(LOG_INFO, "%s", line); - else + else if (log != NULL) (void) fprintf(log, "%s", line); } @@ -1294,8 +1304,9 @@ printipflog: if (defaction == 0) { if (opts & OPT_SYSLOG) syslog(lvl, "%s", line); - else + else if (log != NULL) (void) fprintf(log, "%s", line); + if (opts & OPT_HEXHDR) dumphex(log, opts, buf, sizeof(iplog_t) + sizeof(*ipf)); @@ -1358,11 +1369,12 @@ FILE *log; (void) close(fd); if (flushed) { - if (opts & OPT_SYSLOG) + if (opts & OPT_SYSLOG) { syslog(LOG_INFO, "%d bytes flushed from log\n", flushed); - else if (log != stdout) + } else if ((log != stdout) && (log != NULL)) { fprintf(log, "%d bytes flushed from log\n", flushed); + } } } @@ -1420,7 +1432,8 @@ char *argv[]; iplfile[1] = IPNAT_NAME; iplfile[2] = IPSTATE_NAME; - while ((c = getopt(argc, argv, "?abB:C:Df:FhnN:o:O:pP:sS:tvxX")) != -1) + while ((c = getopt(argc, argv, + "?abB:C:Df:FhL:nN:o:O:pP:sS:tvxX")) != -1) switch (c) { case 'a' : @@ -1452,6 +1465,15 @@ char *argv[]; flushlogs(iplfile[1], log); flushlogs(iplfile[2], log); break; + case 'L' : + logfac = fac_findname(optarg); + if (logfac == -1) { + fprintf(stderr, + "Unknown syslog facility '%s'\n", + optarg); + exit(1); + } + break; case 'n' : opts |= OPT_RESOLVE; break; @@ -1482,7 +1504,7 @@ char *argv[]; s = argv[0]; else s++; - openlog(s, LOG_NDELAY|LOG_PID, LOGFAC); + openlog(s, LOG_NDELAY|LOG_PID, logfac); s = NULL; opts |= OPT_SYSLOG; log = NULL; @@ -1577,8 +1599,8 @@ char *argv[]; #endif /* !BSD */ close(0); close(1); + write_pid(pidfile); } - write_pid(pidfile); signal(SIGHUP, handlehup); @@ -1614,7 +1636,8 @@ char *argv[]; fclose(log); log = fp; } - if (binarylogfile && (fp = fopen(binarylogfile, "a"))) { + if (binarylogfile && + (fp = fopen(binarylogfile, "a"))) { fclose(binarylog); binarylog = fp; } @@ -1636,7 +1659,7 @@ char *argv[]; case 1 : if (opts & OPT_SYSLOG) syslog(LOG_CRIT, "aborting logging\n"); - else + else if (log != NULL) fprintf(log, "aborting logging\n"); doread = 0; break; diff --git a/dist/ipf/tools/ipnat_y.y b/dist/ipf/tools/ipnat_y.y index 86457fc98a5..28fe6ed3de2 100644 --- a/dist/ipf/tools/ipnat_y.y +++ b/dist/ipf/tools/ipnat_y.y @@ -1,4 +1,4 @@ -/* $NetBSD: ipnat_y.y,v 1.13 2005/04/03 15:05:30 martti Exp $ */ +/* $NetBSD: ipnat_y.y,v 1.14 2006/04/04 16:17:19 martti Exp $ */ %{ #ifdef __FreeBSD__ @@ -54,6 +54,7 @@ static ipnat_t *nat = NULL; static int natfd = -1; static ioctlfunc_t natioctlfunc = NULL; static addfunc_t nataddfunc = NULL; +static int suggest_port = 0; static void newnatrule __P((void)); static void setnatproto __P((int)); @@ -160,8 +161,6 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions strncpy(nat->in_ifnames[1], nat->in_ifnames[0], sizeof(nat->in_ifnames[0])); - if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0) - setnatproto(nat->in_p); if (((nat->in_redir & NAT_MAPBLK) != 0) || ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) nat_setgroupmap(nat); @@ -174,6 +173,9 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions strncpy(nat->in_ifnames[1], nat->in_ifnames[0], sizeof(nat->in_ifnames[0])); + if ((suggest_port == 1) && + (nat->in_flags & IPN_TCPUDP) == 0) + nat->in_flags |= IPN_TCPUDP; if ((nat->in_flags & IPN_TCPUDP) == 0) setnatproto(nat->in_p); if (((nat->in_redir & NAT_MAPBLK) != 0) || @@ -188,8 +190,9 @@ map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions strncpy(nat->in_ifnames[1], nat->in_ifnames[0], sizeof(nat->in_ifnames[0])); - if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0) - setnatproto(nat->in_p); + if ((suggest_port == 1) && + (nat->in_flags & IPN_TCPUDP) == 0) + nat->in_flags |= IPN_TCPUDP; if (((nat->in_redir & NAT_MAPBLK) != 0) || ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) nat_setgroupmap(nat); @@ -228,7 +231,7 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions (nat->in_pmin != 0 || nat->in_pmax != 0 || nat->in_pnext != 0)) - setnatproto(IPPROTO_TCP); + setnatproto(IPPROTO_TCP); } | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions { nat->in_v = 4; @@ -238,6 +241,9 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions nat->in_pmax != 0 || nat->in_pnext != 0)) setnatproto(IPPROTO_TCP); + if ((suggest_port == 1) && + (nat->in_flags & IPN_TCPUDP) == 0) + nat->in_flags |= IPN_TCPUDP; if (nat->in_ifnames[1][0] == '\0') strncpy(nat->in_ifnames[1], nat->in_ifnames[0], @@ -252,9 +258,19 @@ redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions nat->in_ifnames[0], sizeof(nat->in_ifnames[0])); } + | rdrit ifnames rdrfrom IPNY_TLATE dip setproto rdroptions + { nat->in_v = 4; + if ((suggest_port == 1) && + (nat->in_flags & IPN_TCPUDP) == 0) + nat->in_flags |= IPN_TCPUDP; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + } ; -proxy: | IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto +proxy: | IPNY_PROXY port portspec YY_STR '/' proto { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); if (nat->in_dcmp == 0) { nat->in_dport = htons($3); @@ -264,7 +280,7 @@ proxy: | IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto setnatproto($6); free($4); } - | IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto + | IPNY_PROXY port YY_STR YY_STR '/' proto { int pnum; strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); pnum = getportproto($3, $6); @@ -306,11 +322,19 @@ rhaddr: addr { $$.a = $1.a; $$.m = $1.m; } dip: hostname { nat->in_inip = $1.s_addr; nat->in_inmsk = 0xffffffff; } + | hostname '/' YY_NUMBER { if ($3 != 0 || $1.s_addr != 0) + yyerror("Only 0/0 supported"); + nat->in_inip = 0; + nat->in_inmsk = 0; + } | hostname ',' hostname { nat->in_flags |= IPN_SPLIT; nat->in_inip = $1.s_addr; nat->in_inmsk = $3.s_addr; } ; +port: IPNY_PORT { suggest_port = 1; } + ; + portspec: YY_NUMBER { if ($1 > 65535) /* Unsigned */ yyerror("invalid port number"); @@ -323,16 +347,16 @@ portspec: } ; -dport: | IPNY_PORT portspec { nat->in_pmin = htons($2); +dport: | port portspec { nat->in_pmin = htons($2); nat->in_pmax = htons($2); } - | IPNY_PORT portspec '-' portspec { nat->in_pmin = htons($2); + | port portspec '-' portspec { nat->in_pmin = htons($2); nat->in_pmax = htons($4); } - | IPNY_PORT portspec ':' portspec { nat->in_pmin = htons($2); + | port portspec ':' portspec { nat->in_pmin = htons($2); nat->in_pmax = htons($4); } ; -nport: IPNY_PORT portspec { nat->in_pnext = htons($2); } - | IPNY_PORT '=' portspec { nat->in_pnext = htons($3); +nport: port portspec { nat->in_pnext = htons($2); } + | port '=' portspec { nat->in_pnext = htons($3); nat->in_flags |= IPN_FIXEDDPORT; } ; @@ -356,12 +380,16 @@ mapfrom: from sobject IPNY_TO dobject | from sobject '!' IPNY_TO dobject { nat->in_flags |= IPN_NOTDST; } + | from sobject IPNY_TO '!' dobject + { nat->in_flags |= IPN_NOTDST; } ; rdrfrom: from sobject IPNY_TO dobject | '!' from sobject IPNY_TO dobject { nat->in_flags |= IPN_NOTSRC; } + | from '!' sobject IPNY_TO dobject + { nat->in_flags |= IPN_NOTSRC; } ; from: IPNY_FROM { nat->in_flags |= IPN_FILTER; } @@ -414,7 +442,7 @@ mapport: sobject: saddr - | saddr IPNY_PORT portstuff { nat->in_sport = $3.p1; + | saddr port portstuff { nat->in_sport = $3.p1; nat->in_stop = $3.p2; nat->in_scmp = $3.pc; } ; @@ -431,7 +459,7 @@ saddr: addr { if (nat->in_redir == NAT_REDIRECT) { dobject: daddr - | daddr IPNY_PORT portstuff { nat->in_dport = $3.p1; + | daddr port portstuff { nat->in_dport = $3.p1; nat->in_dtop = $3.p2; nat->in_dcmp = $3.pc; if (nat->in_redir == NAT_REDIRECT) @@ -454,11 +482,11 @@ addr: IPNY_ANY { $$.a.s_addr = 0; $$.m.s_addr = 0; } $$.a.s_addr &= $$.m.s_addr; } | hostname '/' ipv4 { $$.a = $1; $$.m = $3; $$.a.s_addr &= $$.m.s_addr; } - | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = $3; + | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = htonl($3); $$.a.s_addr &= $$.m.s_addr; } | hostname IPNY_MASK ipv4 { $$.a = $1; $$.m = $3; $$.a.s_addr &= $$.m.s_addr; } - | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = $3; + | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = htonl($3); $$.a.s_addr &= $$.m.s_addr; } ; @@ -471,7 +499,7 @@ nummask: portstuff: compare portspec { $$.pc = $1; $$.p1 = $2; } - | portspec range portspec { $$.pc = $2; $$.p1 = $1; $$.p1 = $3; } + | portspec range portspec { $$.pc = $2; $$.p1 = $1; $$.p2 = $3; } ; mapoptions: @@ -536,10 +564,18 @@ rdrproxy: } ; -proto: YY_NUMBER { $$ = $1; } +proto: YY_NUMBER { $$ = $1; + if ($$ != IPPROTO_TCP && + $$ != IPPROTO_UDP) + suggest_port = 0; + } | IPNY_TCP { $$ = IPPROTO_TCP; } | IPNY_UDP { $$ = IPPROTO_UDP; } - | YY_STR { $$ = getproto($1); free($1); } + | YY_STR { $$ = getproto($1); free($1); + if ($$ != IPPROTO_TCP && + $$ != IPPROTO_UDP) + suggest_port = 0; + } ; hexnumber: @@ -707,6 +743,8 @@ static void newnatrule() nat->in_next = n; nat = n; } + + suggest_port = 0; } @@ -783,7 +821,7 @@ void *ptr; del = SIOCRMNAT; } - if (ipn && (opts & OPT_VERBOSE)) + if ((opts & OPT_VERBOSE) != 0) printnat(ipn, opts); if (opts & OPT_DEBUG) diff --git a/regress/sys/kern/ipf/Makefile b/regress/sys/kern/ipf/Makefile index e829648998b..059f359d461 100644 --- a/regress/sys/kern/ipf/Makefile +++ b/regress/sys/kern/ipf/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.10 2005/04/03 15:05:30 martti Exp $ +# $NetBSD: Makefile,v 1.11 2006/04/04 16:17:19 martti Exp $ # # (C)opyright 1993-1996 by Darren Reed. # @@ -21,14 +21,16 @@ first: -mkdir -p results # Filtering tests -ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 +ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 # Rule parsing tests -ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 +ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 \ + i20 i21 -ntests: n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 +ntests: n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 -nitests: ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 ni16 +nitests: ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 \ + ni16 ni19 ni20 ni21 intests: in1 in2 in3 in4 in5 in6 @@ -40,27 +42,27 @@ ipv6: ipv6.1 ipv6.2 ipv6.3 bpf: bpf1 bpf-f1 -f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14: +f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f19: @${HOST_SH} ${.CURDIR}/dotest ${.CURDIR} \ `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` -f15 f16 f17: +f15 f16 f17 f18 f20: @${HOST_SH} ${.CURDIR}/mtest ${.CURDIR} \ `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` -i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 bpf1: +i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 bpf1: @${HOST_SH} ${.CURDIR}/itest ${.CURDIR} \ `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` -n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12: +n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14: @${HOST_SH} ${.CURDIR}/nattest ${.CURDIR} \ `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` -ni1 ni2 ni3 ni4 ni5 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 ni16: +ni1 ni2 ni3 ni4 ni5 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 ni16 ni19 ni20: @${HOST_SH} ${.CURDIR}/natipftest ${.CURDIR} single \ `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` -ni6: +ni6 ni21: @${HOST_SH} ${.CURDIR}/natipftest ${.CURDIR} multi \ `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` @@ -89,11 +91,11 @@ bpf-f1: `${AWK} "/^$@ / { print; } " ${.CURDIR}/test.format` clean: - /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 - /bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 - /bin/rm -f n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 + /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 + /bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 + /bin/rm -f n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 /bin/rm -f ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 - /bin/rm -f ni10 ni11 ni12 ni13 ni14 ni15 ni16 + /bin/rm -f ni10 ni11 ni12 ni13 ni14 ni15 ni16 ni19 ni20 ni21 /bin/rm -f in1 in2 in3 in4 in5 in6 /bin/rm -f p1 p2 p3 ip1 /bin/rm -f l1 diff --git a/regress/sys/kern/ipf/dotest b/regress/sys/kern/ipf/dotest index 43035add0b9..574ef9e694a 100644 --- a/regress/sys/kern/ipf/dotest +++ b/regress/sys/kern/ipf/dotest @@ -1,11 +1,14 @@ #!/bin/sh # -# $NetBSD: dotest,v 1.3 2004/07/23 05:39:04 martti Exp $ +# $NetBSD: dotest,v 1.4 2006/04/04 16:17:19 martti Exp $ # TESTDIR=$1 shift +thistest=$1 format=$2 +output=$3 +tuning=$4 if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -17,18 +20,21 @@ else fi fi fi -echo "$1..."; -/bin/cp /dev/null results/$1 +if [ "$tuning" != "" ] ; then + tuning="-T $tuning" +fi +echo "${thistest}..."; +/bin/cp /dev/null results/${thistest} ( while read rule; do - echo "$rule" | ipftest -F $format -Rbr - -i ${TESTDIR}/input/$1 >> results/$1; + echo "$rule" | ipftest -F $format -Rbr - -i ${TESTDIR}/input/${thistest} $tuning>> results/${thistest}; if [ $? -ne 0 ] ; then exit 1; fi - echo "--------" >> results/$1 -done ) < ${TESTDIR}/regress/$1 -cmp ${TESTDIR}/expected/$1 results/$1 + echo "--------" >> results/${thistest} +done ) < ${TESTDIR}/regress/${thistest} +cmp ${TESTDIR}/expected/${thistest} results/${thistest} status=$? if [ $status = 0 ] ; then - $TOUCH $1 + $TOUCH ${thistest} fi exit $status diff --git a/regress/sys/kern/ipf/expected/i12 b/regress/sys/kern/ipf/expected/i12 index 22a348871bf..e21724c7a25 100644 --- a/regress/sys/kern/ipf/expected/i12 +++ b/regress/sys/kern/ipf/expected/i12 @@ -13,14 +13,14 @@ pass in from 2.2.2.0/24 to 5.5.5.5/32 port = 25 pass in from 3.3.3.3/32 to 5.5.5.5/32 port = 25 pass in from 2.2.2.0/24 to 6.6.6.6/32 port = 25 pass in from 3.3.3.3/32 to 6.6.6.6/32 port = 25 -pass in proto tcp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 -pass in proto tcp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 -pass in proto tcp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 -pass in proto tcp from 3.3.3.3/32 to 6.6.6.6/32 port = 53 -pass in proto tcp from 2.2.2.0/24 to 5.5.5.5/32 port = 9 -pass in proto tcp from 3.3.3.3/32 to 5.5.5.5/32 port = 9 -pass in proto tcp from 2.2.2.0/24 to 6.6.6.6/32 port = 9 -pass in proto tcp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 +pass in proto tcp from 2.2.2.0/24 port = 53 to 5.5.5.5/32 +pass in proto tcp from 3.3.3.3/32 port = 53 to 5.5.5.5/32 +pass in proto tcp from 2.2.2.0/24 port = 9 to 5.5.5.5/32 +pass in proto tcp from 3.3.3.3/32 port = 9 to 5.5.5.5/32 +pass in proto tcp from 2.2.2.0/24 port = 53 to 6.6.6.6/32 +pass in proto tcp from 3.3.3.3/32 port = 53 to 6.6.6.6/32 +pass in proto tcp from 2.2.2.0/24 port = 9 to 6.6.6.6/32 +pass in proto tcp from 3.3.3.3/32 port = 9 to 6.6.6.6/32 pass in proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 pass in proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 pass in proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 @@ -32,3 +32,8 @@ pass in proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 pass in from 10.10.10.10/32 to 11.11.11.11/32 pass in from pool/101(!) to hash/202(!) pass in from hash/303(!) to pool/404(!) +table role = ipf type = tree number = + { ! 1.1.1.1/32; 2.2.2.2/32; ! 2.2.0.0/16; }; +table role = ipf type = tree number = + { 1.1.0.0/16; }; +pass in from pool/0(!) to pool/0(!) diff --git a/regress/sys/kern/ipf/expected/in1 b/regress/sys/kern/ipf/expected/in1 index ce5a61003ec..8c47a929e54 100644 --- a/regress/sys/kern/ipf/expected/in1 +++ b/regress/sys/kern/ipf/expected/in1 @@ -3,6 +3,8 @@ map le0 0.0.0.1/32 -> 0.0.0.1/32 map le0 128.0.0.0/1 -> 0.0.0.0/0 map le0 10.0.0.0/8 -> 1.2.3.0/24 map le0 10.0.0.0/8 -> 1.2.3.0/24 +map le0 10.0.0.0/8 -> 1.2.3.0/24 +map le0 0.0.0.5/0.0.0.255 -> 1.2.3.0/24 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap udp 20000:29999 @@ -25,3 +27,4 @@ map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 frag age 30/30 map fxp0 from 192.168.0.0/18 to any port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp map thisisalonginte 0.0.0.0/0 -> 0.0.0.0/32 mssclamp 1452 tag freddyliveshere map bar0 0.0.0.0/0 -> 0.0.0.0/32 icmpidmap icmp 1000:2000 +map ppp0,adsl0 0.0.0.0/0 -> 0.0.0.0/32 diff --git a/regress/sys/kern/ipf/itest b/regress/sys/kern/ipf/itest index da3cfa46cdf..341a7d46111 100644 --- a/regress/sys/kern/ipf/itest +++ b/regress/sys/kern/ipf/itest @@ -1,6 +1,6 @@ #!/bin/sh # -# $NetBSD: itest,v 1.3 2004/07/23 05:39:04 martti Exp $ +# $NetBSD: itest,v 1.4 2006/04/04 16:17:19 martti Exp $ # TESTDIR=$1 shift @@ -19,7 +19,14 @@ else fi echo "$1..."; /bin/cp /dev/null results/$1 -ipf -Rnvf ${TESTDIR}/regress/$1 2>/dev/null > results/$1 +case $3 in +ipf) + ipf -Rnvf ${TESTDIR}/regress/$1 2>/dev/null > results/$1 + ;; +ipftest) + ipftest -D -r ${TESTDIR}/regress/$1 -i /dev/null > results/$1 + ;; +esac cmp ${TESTDIR}/expected/$1 results/$1 status=$? if [ $status = 0 ] ; then diff --git a/regress/sys/kern/ipf/natipftest b/regress/sys/kern/ipf/natipftest index 8bb96fddbd0..0d0a064b54f 100644 --- a/regress/sys/kern/ipf/natipftest +++ b/regress/sys/kern/ipf/natipftest @@ -1,6 +1,6 @@ #!/bin/sh # -# $NetBSD: natipftest,v 1.3 2004/07/23 05:39:04 martti Exp $ +# $NetBSD: natipftest,v 1.4 2006/04/04 16:17:19 martti Exp $ # TESTDIR=$1 shift @@ -33,7 +33,7 @@ single) echo "$1..."; /bin/cp /dev/null results/$1 ( while read rule; do - echo "$rule" | ipftest -R $format -bx -r ${TESTDIR}/regress/$1.ipf -N - -i ${TESTDIR}/input/$1 >> \ + echo "$rule" | ipftest -R $format -b -r ${TESTDIR}/regress/$1.ipf -N - -i ${TESTDIR}/input/$1 >> \ results/$1; if [ $? -ne 0 ] ; then exit 1; @@ -49,7 +49,7 @@ single) multi) echo "$1..."; /bin/cp /dev/null results/$1 - ipftest -R $format -bx -r ${TESTDIR}/regress/$1.ipf -N ${TESTDIR}/regress/$1.nat \ + ipftest -R $format -b -r ${TESTDIR}/regress/$1.ipf -N ${TESTDIR}/regress/$1.nat \ -i ${TESTDIR}/input/$1 >> results/$1; if [ $? -ne 0 ] ; then exit 2; diff --git a/regress/sys/kern/ipf/regress/i12 b/regress/sys/kern/ipf/regress/i12 index b8b2f3ea418..5342702353e 100644 --- a/regress/sys/kern/ipf/regress/i12 +++ b/regress/sys/kern/ipf/regress/i12 @@ -2,8 +2,9 @@ pass in from 1.1.1.1/32 to 2.2.2.2/32 pass in from (2.2.2.2/24,3.3.3.3/32) to 4.4.4.4/32 pass in from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) pass in from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (22,25) -pass in proto tcp from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (53,9) +pass in proto tcp from (2.2.2.2/24,3.3.3.3/32) port = (53,9) to (5.5.5.5/32,6.6.6.6/32) pass in proto udp from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (53,9) pass in from 10.10.10.10 to 11.11.11.11 pass in from pool/101 to hash/202 pass in from hash/303 to pool/404 +pass in from pool=(!1.1.1.1,2.2.2.2,!2.2.0.0/16) to pool = ( 1.1.0.0/16 ) diff --git a/sys/dist/ipf/netinet/fil.c b/sys/dist/ipf/netinet/fil.c index 1946d7b4a30..197ba8d9f71 100644 --- a/sys/dist/ipf/netinet/fil.c +++ b/sys/dist/ipf/netinet/fil.c @@ -1,4 +1,4 @@ -/* $NetBSD: fil.c,v 1.21 2005/12/28 09:29:48 christos Exp $ */ +/* $NetBSD: fil.c,v 1.22 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2003 by Darren Reed. @@ -34,7 +34,9 @@ #else # include <sys/ioctl.h> #endif -#include <sys/fcntl.h> +#if !defined(_AIX51) +# include <sys/fcntl.h> +#endif #if defined(_KERNEL) # include <sys/systm.h> # include <sys/file.h> @@ -74,6 +76,9 @@ struct file; # include <net/af.h> #endif #if !defined(_KERNEL) && defined(__FreeBSD__) +# if (__FreeBSD_version >= 504000) +# undef _RADIX_H_ +# endif # include "radix_ipf.h" #endif #include <net/route.h> @@ -88,7 +93,7 @@ struct file; # include <netinet/in_var.h> #endif #include <netinet/tcp.h> -#if !defined(__sgi) || defined(_KERNEL) +#if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL) # include <netinet/udp.h> # include <netinet/ip_icmp.h> #endif @@ -135,10 +140,10 @@ struct file; #if !defined(lint) #if defined(__NetBSD__) #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.21 2005/12/28 09:29:48 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.22 2006/04/04 16:17:19 martti Exp $"); #else 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.243.2.57 2005/03/28 10:47:50 darrenr Exp"; +static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp"; #endif #endif @@ -147,12 +152,6 @@ static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darr # include "ipt.h" # include "bpf-ipf.h" extern int opts; - -# define FR_VERBOSE(verb_pr) verbose verb_pr -# define FR_DEBUG(verb_pr) debug verb_pr -#else /* #ifndef _KERNEL */ -# define FR_VERBOSE(verb_pr) -# define FR_DEBUG(verb_pr) #endif /* _KERNEL */ @@ -178,6 +177,7 @@ int fr_update_ipid = 0; u_short fr_ip_id = 0; int fr_chksrc = 0; /* causes a system crash if enabled */ int fr_minttl = 4; +int fr_icmpminfragmtu = 68; u_long fr_frouteok[2] = {0, 0}; u_long fr_userifqs = 0; u_long fr_badcoalesces[2] = {0, 0}; @@ -223,6 +223,7 @@ static int frflushlist __P((int, minor_t, int *, frentry_t **)); static ipfunc_t fr_findfunc __P((ipfunc_t)); static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *)); static int fr_funcinit __P((frentry_t *fr)); +static INLINE void frpr_ah __P((fr_info_t *)); static INLINE void frpr_esp __P((fr_info_t *)); static INLINE void frpr_gre __P((fr_info_t *)); static INLINE void frpr_udp __P((fr_info_t *)); @@ -231,9 +232,9 @@ static INLINE void frpr_icmp __P((fr_info_t *)); static INLINE void frpr_ipv4hdr __P((fr_info_t *)); static INLINE int frpr_pullup __P((fr_info_t *, int)); static INLINE void frpr_short __P((fr_info_t *, int)); -static INLINE void frpr_tcpcommon __P((fr_info_t *)); -static INLINE void frpr_udpcommon __P((fr_info_t *)); -static INLINE int fr_updateipid __P((fr_info_t *)); +static INLINE int frpr_tcpcommon __P((fr_info_t *)); +static INLINE int frpr_udpcommon __P((fr_info_t *)); +static int fr_updateipid __P((fr_info_t *)); #ifdef IPFILTER_LOOKUP static int fr_grpmapinit __P((frentry_t *fr)); static INLINE void *fr_resolvelookup __P((u_int, u_int, lookupfunc_t *)); @@ -282,6 +283,7 @@ struct optlist ip6exthdr[] = { { IPPROTO_AH, 0x000020 }, { IPPROTO_NONE, 0x000040 }, { IPPROTO_DSTOPTS, 0x000080 }, + { IPPROTO_MOBILITY, 0x000100 }, { 0, 0 } }; #endif @@ -333,15 +335,20 @@ static ipfunc_resolve_t fr_availfuncs[] = { * adding more code to a growing switch statement. */ #ifdef USE_INET6 +static INLINE int frpr_ah6 __P((fr_info_t *)); +static INLINE void frpr_esp6 __P((fr_info_t *)); +static INLINE void frpr_gre6 __P((fr_info_t *)); static INLINE void frpr_udp6 __P((fr_info_t *)); static INLINE void frpr_tcp6 __P((fr_info_t *)); static INLINE void frpr_icmp6 __P((fr_info_t *)); -static INLINE void frpr_ipv6hdr __P((fr_info_t *)); +static INLINE int frpr_ipv6hdr __P((fr_info_t *)); static INLINE void frpr_short6 __P((fr_info_t *, int)); static INLINE int frpr_hopopts6 __P((fr_info_t *)); +static INLINE int frpr_mobility6 __P((fr_info_t *)); static INLINE int frpr_routing6 __P((fr_info_t *)); static INLINE int frpr_dstopts6 __P((fr_info_t *)); -static INLINE int frpr_fragment6 __P((fr_info_t *)); +static INLINE void frpr_fragment6 __P((fr_info_t *)); +static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int)); /* ------------------------------------------------------------------------ */ @@ -358,33 +365,28 @@ static INLINE void frpr_short6(fin, xmin) fr_info_t *fin; int xmin; { - fr_ip_t *fi = &fin->fin_fi; - int off; - off = fin->fin_off; - if (off == 0) { - if (fin->fin_plen < fin->fin_hlen + xmin) - fi->fi_flx |= FI_SHORT; - } else if (off < xmin) { - fi->fi_flx |= FI_SHORT; - } + if (fin->fin_dlen < xmin) + fin->fin_flx |= FI_SHORT; } /* ------------------------------------------------------------------------ */ /* Function: frpr_ipv6hdr */ -/* Returns: void */ +/* Returns: int - 0 = IPv6 packet intact, -1 = packet lost */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ /* Copy values from the IPv6 header into the fr_info_t struct and call the */ -/* per-protocol analyzer if it exists. */ +/* per-protocol analyzer if it exists. In validating the packet, a protocol*/ +/* analyzer may pullup or free the packet itself so we need to be vigiliant */ +/* of that possibility arising. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_ipv6hdr(fin) +static INLINE int frpr_ipv6hdr(fin) fr_info_t *fin; { - int p, go = 1, i, hdrcount, coalesced; ip6_t *ip6 = (ip6_t *)fin->fin_ip; + int p, go = 1, i, hdrcount; fr_ip_t *fi = &fin->fin_fi; fin->fin_off = 0; @@ -394,7 +396,6 @@ fr_info_t *fin; fi->fi_secmsk = 0; fi->fi_auth = 0; - coalesced = (fin->fin_flx & FI_COALESCE) ? 1 : 0; p = ip6->ip6_nxt; fi->fi_ttl = ip6->ip6_hlim; fi->fi_src.in6 = ip6->ip6_src; @@ -421,48 +422,35 @@ fr_info_t *fin; break; case IPPROTO_GRE : - frpr_gre(fin); + frpr_gre6(fin); go = 0; break; case IPPROTO_HOPOPTS : - /* - * Actually, hop by hop header is only allowed right - * after IPv6 header! - */ - if (hdrcount != 0) - fin->fin_flx |= FI_BAD; - - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } p = frpr_hopopts6(fin); break; + case IPPROTO_MOBILITY : + p = frpr_mobility6(fin); + break; + case IPPROTO_DSTOPTS : - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } p = frpr_dstopts6(fin); break; case IPPROTO_ROUTING : - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } p = frpr_routing6(fin); break; - case IPPROTO_ESP : - frpr_esp(fin); - /*FALLTHROUGH*/ case IPPROTO_AH : + p = frpr_ah6(fin); + break; + + case IPPROTO_ESP : + frpr_esp6(fin); + go = 0; + break; + case IPPROTO_IPV6 : for (i = 0; ip6exthdr[i].ol_bit != 0; i++) if (ip6exthdr[i].ol_val == p) { @@ -477,12 +465,8 @@ fr_info_t *fin; break; case IPPROTO_FRAGMENT : - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } - p = frpr_fragment6(fin); + frpr_fragment6(fin); + go = 0; break; default : @@ -496,9 +480,9 @@ fr_info_t *fin; * extension headers (go != 0), the entire header may not have * been pulled up when the code gets to this point. This is * only done for "go != 0" because the other header handlers - * will all pullup their complete header and the other - * indicator of an incomplete header is that this eas just an - * extension header. + * will all pullup their complete header. The other indicator + * of an incomplete packet is that this was just an extension + * header. */ if ((go != 0) && (p != IPPROTO_NONE) && (frpr_pullup(fin, 0) == -1)) { @@ -507,19 +491,32 @@ fr_info_t *fin; } } fi->fi_p = p; + + /* + * Some of the above functions, like frpr_esp6(), can call fr_pullup + * and destroy whatever packet was here. The caller of this function + * expects us to return -1 if there is a problem with fr_pullup. + */ + if (fin->fin_m == NULL) + return -1; + + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_hopopts6 */ +/* Function: frpr_ipv6exthdr */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ -/* Parameters: fin(I) - pointer to packet information */ +/* Parameters: fin(I) - pointer to packet information */ +/* multiple(I) - flag indicating yes/no if multiple occurances */ +/* of this extension header are allowed. */ +/* proto(I) - protocol number for this extension header */ /* */ /* IPv6 Only */ -/* This is function checks pending hop by hop options extension header */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_hopopts6(fin) +static INLINE int frpr_ipv6exthdr(fin, multiple, proto) fr_info_t *fin; +int multiple, proto; { struct ip6_ext *hdr; u_short shift; @@ -544,8 +541,15 @@ fr_info_t *fin; } for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_HOPOPTS) { - fin->fin_optmsk |= ip6exthdr[i].ol_bit; + if (ip6exthdr[i].ol_val == proto) { + /* + * Most IPv6 extension headers are only allowed once. + */ + if ((multiple == 0) && + ((fin->fin_optmsk & ip6exthdr[i].ol_bit) != 0)) + fin->fin_flx |= FI_BAD; + else + fin->fin_optmsk |= ip6exthdr[i].ol_bit; break; } @@ -557,6 +561,36 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ +/* Function: frpr_hopopts6 */ +/* Returns: int - value of the next header or IPPROTO_NONE if error */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* IPv6 Only */ +/* This is function checks pending hop by hop options extension header */ +/* ------------------------------------------------------------------------ */ +static INLINE int frpr_hopopts6(fin) +fr_info_t *fin; +{ + return frpr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: frpr_mobility6 */ +/* Returns: int - value of the next header or IPPROTO_NONE if error */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* IPv6 Only */ +/* This is function checks the IPv6 mobility extension header */ +/* ------------------------------------------------------------------------ */ +static INLINE int frpr_mobility6(fin) +fr_info_t *fin; +{ + return frpr_ipv6exthdr(fin, 0, IPPROTO_MOBILITY); +} + + +/* ------------------------------------------------------------------------ */ /* Function: frpr_routing6 */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ @@ -568,100 +602,67 @@ static INLINE int frpr_routing6(fin) fr_info_t *fin; { struct ip6_ext *hdr; - u_short shift; - int i; - - fin->fin_flx |= FI_V6EXTHDR; + int shift; - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; + if (frpr_ipv6exthdr(fin, 0, IPPROTO_ROUTING) == IPPROTO_NONE) return IPPROTO_NONE; - } - if (frpr_pullup(fin, 8) == -1) - return IPPROTO_NONE; hdr = fin->fin_dp; - shift = 8 + (hdr->ip6e_len << 3); /* * Nasty extension header length? */ - if ((shift > fin->fin_dlen) || (shift < sizeof(struct ip6_hdr)) || + if ((shift < sizeof(struct ip6_hdr)) || ((shift - sizeof(struct ip6_hdr)) & 15)) { fin->fin_flx |= FI_BAD; + /* + * Compensate for the changes made in frpr_ipv6exthdr() + */ + fin->fin_dlen += shift; + fin->fin_dp = (char *)fin->fin_dp - shift; return IPPROTO_NONE; } - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_ROUTING) { - fin->fin_optmsk |= ip6exthdr[i].ol_bit; - break; - } - - fin->fin_dp = (char *)fin->fin_dp + shift; - fin->fin_dlen -= shift; - return hdr->ip6e_nxt; } /* ------------------------------------------------------------------------ */ /* Function: frpr_fragment6 */ -/* Returns: int - value of the next header or IPPROTO_NONE if error */ +/* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ /* Examine the IPv6 fragment header and extract fragment offset information.*/ +/* */ +/* We don't know where the transport layer header (or whatever is next is), */ +/* as it could be behind destination options (amongst others). Because */ +/* there is no fragment cache, there is no knowledge about whether or not an*/ +/* upper layer header has been seen (or where it ends) and thus we are not */ +/* able to continue processing beyond this header with any confidence. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_fragment6(fin) +static INLINE void frpr_fragment6(fin) fr_info_t *fin; { struct ip6_frag *frag; - struct ip6_ext *hdr; - int i; - - fin->fin_flx |= (FI_FRAG|FI_V6EXTHDR); - - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - /* - * Only one frgament header is allowed per IPv6 packet but it need - * not be the first nor last (not possible in some cases.) - */ - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_FRAGMENT) - break; - if (fin->fin_optmsk & ip6exthdr[i].ol_bit) { - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } + fin->fin_flx |= FI_FRAG; - fin->fin_optmsk |= ip6exthdr[i].ol_bit; + if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE) + return; if (frpr_pullup(fin, sizeof(*frag)) == -1) - return IPPROTO_NONE; - hdr = fin->fin_dp; + return; + frag = fin->fin_dp; /* - * Length must be zero, i.e. it has no length. + * Fragment but no fragmentation info set? Bad packet... */ - if (hdr->ip6e_len != 0) { + if (frag->ip6f_offlg == 0) { fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - if ((int)(fin->fin_dlen - sizeof(*frag)) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; + return; } - frag = fin->fin_dp; fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK; fin->fin_off <<= 3; if (fin->fin_off != 0) @@ -669,8 +670,6 @@ fr_info_t *fin; fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag); fin->fin_dlen -= sizeof(*frag); - - return frag->ip6f_nxt; } @@ -686,34 +685,7 @@ fr_info_t *fin; static INLINE int frpr_dstopts6(fin) fr_info_t *fin; { - struct ip6_ext *hdr; - u_short shift; - int i; - - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - if (frpr_pullup(fin, 8) == -1) - return IPPROTO_NONE; - hdr = fin->fin_dp; - - shift = 8 + (hdr->ip6e_len << 3); - if (shift > fin->fin_dlen) { /* Nasty extension header length? */ - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_DSTOPTS) - break; - fin->fin_optmsk |= ip6exthdr[i].ol_bit; - fin->fin_dp = (char *)fin->fin_dp + shift; - fin->fin_dlen -= shift; - - return hdr->ip6e_nxt; + return frpr_ipv6exthdr(fin, 1, IPPROTO_DSTOPTS); } @@ -763,7 +735,7 @@ fr_info_t *fin; } } - frpr_short(fin, minicmpsz); + frpr_short6(fin, minicmpsz); } @@ -774,16 +746,16 @@ fr_info_t *fin; /* */ /* IPv6 Only */ /* Analyse the packet for IPv6/UDP properties. */ +/* Is not expected to be called for fragmented packets. */ /* ------------------------------------------------------------------------ */ static INLINE void frpr_udp6(fin) fr_info_t *fin; { - fr_checkv6sum(fin); - - frpr_short(fin, sizeof(struct udphdr)); + frpr_short6(fin, sizeof(struct udphdr)); - frpr_udpcommon(fin); + if (frpr_udpcommon(fin) == 0) + fr_checkv6sum(fin); } @@ -794,16 +766,86 @@ fr_info_t *fin; /* */ /* IPv6 Only */ /* Analyse the packet for IPv6/TCP properties. */ +/* Is not expected to be called for fragmented packets. */ /* ------------------------------------------------------------------------ */ static INLINE void frpr_tcp6(fin) fr_info_t *fin; { - fr_checkv6sum(fin); + frpr_short6(fin, sizeof(struct tcphdr)); + + if (frpr_tcpcommon(fin) == 0) + fr_checkv6sum(fin); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: frpr_esp6 */ +/* Returns: void */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* IPv6 Only */ +/* Analyse the packet for ESP properties. */ +/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */ +/* even though the newer ESP packets must also have a sequence number that */ +/* is 32bits as well, it is not possible(?) to determine the version from a */ +/* simple packet header. */ +/* ------------------------------------------------------------------------ */ +static INLINE void frpr_esp6(fin) +fr_info_t *fin; +{ - frpr_short(fin, sizeof(struct tcphdr)); + frpr_short6(fin, sizeof(grehdr_t)); - frpr_tcpcommon(fin); + (void) frpr_pullup(fin, 8); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: frpr_ah6 */ +/* Returns: void */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* IPv6 Only */ +/* Analyse the packet for AH properties. */ +/* The minimum length is taken to be the combination of all fields in the */ +/* header being present and no authentication data (null algorithm used.) */ +/* ------------------------------------------------------------------------ */ +static INLINE int frpr_ah6(fin) +fr_info_t *fin; +{ + authhdr_t *ah; + + frpr_short6(fin, 12); + + if (frpr_pullup(fin, sizeof(*ah)) == -1) + return IPPROTO_NONE; + + ah = (authhdr_t *)fin->fin_dp; + return ah->ah_next; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: frpr_gre6 */ +/* Returns: void */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* Analyse the packet for GRE properties. */ +/* ------------------------------------------------------------------------ */ +static INLINE void frpr_gre6(fin) +fr_info_t *fin; +{ + grehdr_t *gre; + + frpr_short6(fin, sizeof(grehdr_t)); + + if (frpr_pullup(fin, sizeof(grehdr_t)) == -1) + return; + + gre = fin->fin_dp; + if (GRE_REV(gre->gr_flags) == 1) + fin->fin_data[0] = gre->gr_call; } #endif /* USE_INET6 */ @@ -841,10 +883,10 @@ int plen; /* ------------------------------------------------------------------------ */ /* Function: frpr_short */ /* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* min(I) - minimum header size */ +/* Parameters: fin(I) - pointer to packet information */ +/* xmin(I) - minimum header size */ /* */ -/* Check if a packet is "short" as defined by min. The rule we are */ +/* Check if a packet is "short" as defined by xmin. The rule we are */ /* applying here is that the packet must not be fragmented within the layer */ /* 4 header. That is, it must not be a fragment that has its offset set to */ /* start within the layer 4 header (hdrmin) or if it is at offset 0, the */ @@ -854,15 +896,12 @@ static INLINE void frpr_short(fin, xmin) fr_info_t *fin; int xmin; { - fr_ip_t *fi = &fin->fin_fi; - int off; - off = fin->fin_off; - if (off == 0) { - if (fin->fin_plen < fin->fin_hlen + xmin) - fi->fi_flx |= FI_SHORT; - } else if (off < xmin) { - fi->fi_flx |= FI_SHORT; + if (fin->fin_off == 0) { + if (fin->fin_dlen < xmin) + fin->fin_flx |= FI_SHORT; + } else if (fin->fin_off < xmin) { + fin->fin_flx |= FI_SHORT; } } @@ -875,7 +914,7 @@ int xmin; /* IPv4 Only */ /* Do a sanity check on the packet for ICMP (v4). In nearly all cases, */ /* except extrememly bad packets, both type and code will be present. */ -/* The expected minimum size of an ICMP packet is very much dependant on */ +/* The expected minimum size of an ICMP packet is very much dependent on */ /* the type of it. */ /* */ /* XXX - other ICMP sanity checks? */ @@ -885,6 +924,7 @@ fr_info_t *fin; { int minicmpsz = sizeof(struct icmp); icmphdr_t *icmp; + ip_t *oip; if (fin->fin_off != 0) { frpr_short(fin, ICMPERR_ICMPHLEN); @@ -894,8 +934,6 @@ fr_info_t *fin; if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1) return; - fr_checkv4sum(fin); - if (fin->fin_dlen > 1) { icmp = fin->fin_dp; @@ -930,13 +968,27 @@ fr_info_t *fin; * type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+) */ case ICMP_UNREACH : +#ifdef icmp_nextmtu + if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) { + if (icmp->icmp_nextmtu < fr_icmpminfragmtu) + fin->fin_flx |= FI_BAD; + } +#endif case ICMP_SOURCEQUENCH : case ICMP_REDIRECT : case ICMP_TIMXCEED : case ICMP_PARAMPROB : + fin->fin_flx |= FI_ICMPERR; if (fr_coalesce(fin) != 1) return; - fin->fin_flx |= FI_ICMPERR; + /* + * ICMP error packets should not be generated for IP + * packets that are a fragment that isn't the first + * fragment. + */ + oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN); + if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0) + fin->fin_flx |= FI_BAD; break; default : break; @@ -947,12 +999,14 @@ fr_info_t *fin; } frpr_short(fin, minicmpsz); + + fr_checkv4sum(fin); } /* ------------------------------------------------------------------------ */ /* Function: frpr_tcpcommon */ -/* Returns: void */ +/* Returns: int - 0 = header ok, 1 = bad packet, -1 = buffer error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* TCP header sanity checking. Look for bad combinations of TCP flags, */ @@ -960,20 +1014,18 @@ fr_info_t *fin; /* If compiled with IPFILTER_CKSUM, check to see if the TCP checksum is */ /* valid and mark the packet as bad if not. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_tcpcommon(fin) +static INLINE int frpr_tcpcommon(fin) fr_info_t *fin; { int flags, tlen; tcphdr_t *tcp; - fr_ip_t *fi; - fi = &fin->fin_fi; - fi->fi_flx |= FI_TCPUDP; + fin->fin_flx |= FI_TCPUDP; if (fin->fin_off != 0) - return; + return 0; if (frpr_pullup(fin, sizeof(*tcp)) == -1) - return; + return -1; tcp = fin->fin_dp; if (fin->fin_dlen > 3) { @@ -981,8 +1033,8 @@ fr_info_t *fin; fin->fin_dport = ntohs(tcp->th_dport); } - if ((fi->fi_flx & FI_SHORT) != 0) - return; + if ((fin->fin_flx & FI_SHORT) != 0) + return 1; /* * Use of the TCP data offset *must* result in a value that is at @@ -991,7 +1043,7 @@ fr_info_t *fin; tlen = TCP_OFF(tcp) << 2; if (tlen < sizeof(tcphdr_t)) { fin->fin_flx |= FI_BAD; - return; + return 1; } flags = tcp->th_flags; @@ -1045,10 +1097,10 @@ fr_info_t *fin; * then that might add some weight to adding this... */ if (tlen == sizeof(tcphdr_t)) - return; + return 0; if (frpr_pullup(fin, tlen) == -1) - return; + return -1; #if 0 ip = fin->fin_ip; @@ -1087,31 +1139,31 @@ fr_info_t *fin; s += ol; } #endif /* 0 */ + + return 0; } /* ------------------------------------------------------------------------ */ /* Function: frpr_udpcommon */ -/* Returns: void */ +/* Returns: int - 0 = header ok, 1 = bad packet */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Extract the UDP source and destination ports, if present. If compiled */ /* with IPFILTER_CKSUM, check to see if the UDP checksum is valid. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_udpcommon(fin) +static INLINE int frpr_udpcommon(fin) fr_info_t *fin; { udphdr_t *udp; - fr_ip_t *fi; - fi = &fin->fin_fi; - fi->fi_flx |= FI_TCPUDP; + fin->fin_flx |= FI_TCPUDP; if (!fin->fin_off && (fin->fin_dlen > 3)) { if (frpr_pullup(fin, sizeof(*udp)) == -1) { - fi->fi_flx |= FI_SHORT; - return; + fin->fin_flx |= FI_SHORT; + return 1; } udp = fin->fin_dp; @@ -1119,6 +1171,8 @@ fr_info_t *fin; fin->fin_sport = ntohs(udp->uh_sport); fin->fin_dport = ntohs(udp->uh_dport); } + + return 0; } @@ -1134,11 +1188,10 @@ static INLINE void frpr_tcp(fin) fr_info_t *fin; { - fr_checkv4sum(fin); - frpr_short(fin, sizeof(tcphdr_t)); - frpr_tcpcommon(fin); + if (frpr_tcpcommon(fin) == 0) + fr_checkv4sum(fin); } @@ -1154,11 +1207,10 @@ static INLINE void frpr_udp(fin) fr_info_t *fin; { - fr_checkv4sum(fin); - frpr_short(fin, sizeof(udphdr_t)); - frpr_udpcommon(fin); + if (frpr_udpcommon(fin) == 0) + fr_checkv4sum(fin); } @@ -1176,15 +1228,42 @@ fr_info_t *fin; static INLINE void frpr_esp(fin) fr_info_t *fin; { - if (fin->fin_off == 0 && frpr_pullup(fin, 8) == -1) - return; - if (fin->fin_v == 4) + if (fin->fin_off == 0) { frpr_short(fin, 8); -#ifdef USE_INET6 - else if (fin->fin_v == 6) - frpr_short6(fin, sizeof(grehdr_t)); -#endif + (void) frpr_pullup(fin, 8); + } + +} + + +/* ------------------------------------------------------------------------ */ +/* Function: frpr_ah */ +/* Returns: void */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* Analyse the packet for AH properties. */ +/* The minimum length is taken to be the combination of all fields in the */ +/* header being present and no authentication data (null algorithm used.) */ +/* ------------------------------------------------------------------------ */ +static INLINE void frpr_ah(fin) +fr_info_t *fin; +{ + authhdr_t *ah; + int len; + + frpr_short(fin, sizeof(*ah)); + + if (((fin->fin_flx & FI_SHORT) != 0) || (fin->fin_off != 0)) + return; + + if (frpr_pullup(fin, sizeof(*ah)) == -1) + return; + + ah = (authhdr_t *)fin->fin_dp; + + len = (ah->ah_plen + 2) << 2; + frpr_short(fin, len); } @@ -1200,20 +1279,19 @@ fr_info_t *fin; { grehdr_t *gre; - if (fin->fin_off == 0 && frpr_pullup(fin, sizeof(grehdr_t)) == -1) + frpr_short(fin, sizeof(*gre)); + + if (fin->fin_off != 0) + return; + + if (frpr_pullup(fin, sizeof(*gre)) == -1) return; - if (fin->fin_v == 4) - frpr_short(fin, sizeof(grehdr_t)); -#ifdef USE_INET6 - else if (fin->fin_v == 6) - frpr_short6(fin, sizeof(grehdr_t)); -#endif - if (fin->fin_off == 0 ) { + if (fin->fin_off == 0) { gre = fin->fin_dp; if (GRE_REV(gre->gr_flags) == 1) fin->fin_data[0] = gre->gr_call; - } + } } @@ -1269,12 +1347,6 @@ fr_info_t *fin; * set packet attribute flags based on the offset and * calculate the byte offset that it represents. */ - if ((off & IP_MF) != 0) { - fi->fi_flx |= FI_FRAG; - if (fin->fin_dlen == 0) - fi->fi_flx |= FI_BAD; - } - off &= IP_MF|IP_OFFMASK; if (off != 0) { fi->fi_flx |= FI_FRAG; @@ -1282,7 +1354,17 @@ fr_info_t *fin; if (off != 0) { fin->fin_flx |= FI_FRAGBODY; off <<= 3; - if (off + fin->fin_dlen > 0xffff) { + if ((off + fin->fin_dlen > 65535) || + (fin->fin_dlen == 0) || (fin->fin_dlen & 7)) { + /* + * The length of the packet, starting at its + * offset cannot exceed 65535 (0xffff) as the + * length of an IP packet is only 16 bits. + * + * Any fragment that isn't the last fragment + * must have a length greater than 0 and it + * must be an even multiple of 8. + */ fi->fi_flx |= FI_BAD; } } @@ -1303,6 +1385,9 @@ fr_info_t *fin; case IPPROTO_ICMP : frpr_icmp(fin); break; + case IPPROTO_AH : + frpr_ah(fin); + break; case IPPROTO_ESP : frpr_esp(fin); break; @@ -1431,8 +1516,10 @@ fr_info_t *fin; if (v == 4) frpr_ipv4hdr(fin); #ifdef USE_INET6 - else if (v == 6) - frpr_ipv6hdr(fin); + else if (v == 6) { + if (frpr_ipv6hdr(fin) == -1) + return -1; + } #endif if (fin->fin_ip == NULL) return -1; @@ -1560,6 +1647,7 @@ frtuc_t *ft; } + /* ------------------------------------------------------------------------ */ /* Function: fr_ipfcheck */ /* Returns: int - 0 == match, 1 == no match */ @@ -1765,7 +1853,7 @@ u_32_t pass; { int rulen, portcmp, off, logged, skip; struct frentry *fr, *fnext; - u_32_t passt; + u_32_t passt, passo; /* * Do not allow nesting deeper than 16 levels. @@ -1833,15 +1921,13 @@ u_32_t pass; case FR_T_BPFOPC|FR_T_BUILTIN : { u_char *mc; - int wlen; if (*fin->fin_mp == NULL) continue; if (fin->fin_v != fr->fr_v) continue; mc = (u_char *)fin->fin_m; - wlen = fin->fin_dlen + fin->fin_hlen; - if (!bpf_filter(fr->fr_data, mc, wlen, 0)) + if (!bpf_filter(fr->fr_data, mc, fin->fin_plen, 0)) continue; break; } @@ -1887,24 +1973,23 @@ u_32_t pass; * it, except for increasing the hit counter. */ if ((passt & FR_CALLNOW) != 0) { + frentry_t *frs; + ATOMIC_INC64(fr->fr_hits); if ((fr->fr_func != NULL) && - (fr->fr_func != (ipfunc_t)-1)) { - frentry_t *frs; + (fr->fr_func == (ipfunc_t)-1)) + continue; - frs = fin->fin_fr; - fin->fin_fr = fr; - fr = (*fr->fr_func)(fin, &passt); - if (fr == NULL) { - fin->fin_fr = frs; - continue; - } - passt = fr->fr_flags; - fin->fin_fr = fr; - } - } else { + frs = fin->fin_fr; fin->fin_fr = fr; + fr = (*fr->fr_func)(fin, &passt); + if (fr == NULL) { + fin->fin_fr = frs; + continue; + } + passt = fr->fr_flags; } + fin->fin_fr = fr; #ifdef IPFILTER_LOG /* @@ -1923,6 +2008,7 @@ u_32_t pass; } #endif /* IPFILTER_LOG */ fr->fr_bytes += (U_QUAD_T)fin->fin_plen; + passo = pass; if (FR_ISSKIP(passt)) skip = fr->fr_arg; else if ((passt & FR_LOGMASK) != FR_LOG) @@ -1935,18 +2021,42 @@ u_32_t pass; (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); if (fr->fr_grp != NULL) { fin->fin_fr = *fr->fr_grp; - pass = fr_scanlist(fin, pass); + passt = fr_scanlist(fin, pass); if (fin->fin_fr == NULL) { fin->fin_rule = rulen; (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); fin->fin_fr = fr; + passt = pass; } if (fin->fin_flx & FI_DONTCACHE) logged = 1; + pass = passt; } - if (pass & FR_QUICK) + + if (passt & FR_QUICK) { + /* + * Finally, if we've asked to track state for this + * packet, set it up. Add state for "quick" rules + * here so that if the action fails we can consider + * the rule to "not match" and keep on processing + * filter rules. + */ + if ((pass & FR_KEEPSTATE) && + !(fin->fin_flx & FI_STATE)) { + int out = fin->fin_out; + + fin->fin_fr = fr; + if (fr_addstate(fin, NULL, 0) != NULL) { + ATOMIC_INCL(frstats[out].fr_ads); + } else { + ATOMIC_INCL(frstats[out].fr_bads); + pass = passo; + continue; + } + } break; + } } if (logged) fin->fin_flx |= FI_DONTCACHE; @@ -2031,18 +2141,22 @@ u_32_t *passp; * the result as if it were from the ACL's. */ fc = &frcache[out][CACHE_HASH(fin)]; + READ_ENTER(&ipf_frcache); if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) { /* - * copy cached data so we can unlock the mutex - * earlier. + * copy cached data so we can unlock the mutexes earlier. */ bcopy((char *)fc, (char *)fin, FI_COPYSIZE); + RWLOCK_EXIT(&ipf_frcache); ATOMIC_INCL(frstats[out].fr_chit); + if ((fr = fin->fin_fr) != NULL) { ATOMIC_INC64(fr->fr_hits); pass = fr->fr_flags; } } else { + RWLOCK_EXIT(&ipf_frcache); + #ifdef USE_INET6 if (fin->fin_v == 6) fin->fin_fr = ipfilter6[out][fr_active]; @@ -2051,9 +2165,13 @@ u_32_t *passp; fin->fin_fr = ipfilter[out][fr_active]; if (fin->fin_fr != NULL) pass = fr_scanlist(fin, fr_pass); + if (((pass & FR_KEEPSTATE) == 0) && - ((fin->fin_flx & FI_DONTCACHE) == 0)) + ((fin->fin_flx & FI_DONTCACHE) == 0)) { + WRITE_ENTER(&ipf_frcache); bcopy((char *)fin, (char *)fc, FI_COPYSIZE); + RWLOCK_EXIT(&ipf_frcache); + } if ((pass & FR_NOMATCH)) { ATOMIC_INCL(frstats[out].fr_nom); } @@ -2078,7 +2196,8 @@ u_32_t *passp; if (FR_ISAUTH(pass)) { if (fr_newauth(fin->fin_m, fin) != 0) { #ifdef _KERNEL - fin->fin_m = *fin->fin_mp = NULL; + if ((pass & FR_RETMASK) == 0) + fin->fin_m = *fin->fin_mp = NULL; #else ; #endif @@ -2118,30 +2237,6 @@ u_32_t *passp; } } - /* - * Finally, if we've asked to track state for this packet, set it up. - */ - if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) { - if (fr_addstate(fin, NULL, 0) != NULL) { - ATOMIC_INCL(frstats[out].fr_ads); - } else { -#ifdef notdef - /* - * This blocks ICMP messages (eg. ICMP_UNREACH_NEEDFRAG) - * fr_addstate returning NULL is not necessary a bad - * thing because there is no state to be added on some - * packets, eg. icmp packets. XXX: but for others this - * is wrong. - */ - ATOMIC_INCL(frstats[out].fr_bads); - if (FR_ISPASS(pass)) { - pass &= ~FR_CMDMASK; - pass |= FR_BLOCK; - } -#endif - } - } - fr = fin->fin_fr; if (passp != NULL) @@ -2157,7 +2252,7 @@ u_32_t *passp; /* User space: */ /* -1 == packet blocked */ /* 1 == packet not matched */ -/* -2 == requires authantication */ +/* -2 == requires authentication */ /* Kernel: */ /* > 0 == filter error # for packet */ /* Parameters: ip(I) - pointer to start of IPv4/6 packet */ @@ -2207,8 +2302,6 @@ int out; #ifdef USE_INET6 ip6_t *ip6; #endif - SPL_INT(s); - /* * The first part of fr_check() deals with making sure that what goes * into the filtering engine makes some sense. Information about the @@ -2222,6 +2315,8 @@ int out; if ((u_int)ip & 0x3) return 2; +# else + SPL_INT(s); # endif READ_ENTER(&ipf_global); @@ -2247,6 +2342,10 @@ int out; if ((m->m_flags & M_MCAST) != 0) fin->fin_flx |= FI_MBCAST|FI_MULTICAST; # endif +# if defined(M_MLOOP) + if ((m->m_flags & M_MLOOP) != 0) + fin->fin_flx |= FI_MBCAST|FI_MULTICAST; +# endif # if defined(M_BCAST) if ((m->m_flags & M_BCAST) != 0) fin->fin_flx |= FI_MBCAST|FI_BROADCAST; @@ -2283,7 +2382,7 @@ int out; fin->fin_out = out; fin->fin_ifp = ifp; fin->fin_error = ENETUNREACH; - fin->fin_hlen = (u_short )hlen; + fin->fin_hlen = (u_short)hlen; fin->fin_dp = (char *)ip + hlen; fin->fin_ipoff = (char *)ip - MTOD(m, char *); @@ -2302,7 +2401,7 @@ int out; fin->fin_plen = ntohs(ip6->ip6_plen); if (fin->fin_plen == 0) { pass = FR_BLOCK|FR_NOMATCH; - goto filtered; + goto finished; } fin->fin_plen += sizeof(ip6_t); } else @@ -2315,8 +2414,10 @@ int out; fin->fin_plen = ip->ip_len; } - if (fr_makefrip(hlen, ip, fin) == -1) + if (fr_makefrip(hlen, ip, fin) == -1) { + pass = FR_BLOCK|FR_NOMATCH; goto finished; + } /* * For at least IPv6 packets, if a m_pullup() fails then this pointer @@ -2381,6 +2482,23 @@ int out; if ((pass & FR_NOMATCH) || (fr == NULL)) fr = fr_firewall(fin, &pass); + /* + * If we've asked to track state for this packet, set it up. + * Here rather than fr_firewall because fr_checkauth may decide + * to return a packet for "keep state" + */ + if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) { + if (fr_addstate(fin, NULL, 0) != NULL) { + ATOMIC_INCL(frstats[out].fr_ads); + } else { + ATOMIC_INCL(frstats[out].fr_bads); + if (FR_ISPASS(pass)) { + pass &= ~FR_CMDMASK; + pass |= FR_BLOCK; + } + } + } + fin->fin_fr = fr; /* @@ -2410,23 +2528,32 @@ int out; } #endif - if (fin->fin_state != NULL) + if (fin->fin_state != NULL) { fr_statederef(fin, (ipstate_t **)&fin->fin_state); + fin->fin_state = NULL; + } - if (fin->fin_nat != NULL) + if (fin->fin_nat != NULL) { fr_natderef((nat_t **)&fin->fin_nat); + fin->fin_nat = NULL; + } /* - * Only allow FR_DUP to work if a rule matched - it makes no sense to - * set FR_DUP as a "default" as there are no instructions about where - * to send the packet. Use fin_m here because it may have changed - * (without an update of 'm') in prior processing. + * Up the reference on fr_lock and exit ipf_mutex. fr_fastroute + * only frees up the lock on ipf_global and the generation of a + * packet below could cause a recursive call into IPFilter. + * Hang onto the filter rule just in case someone decides to remove + * or flush it in the meantime. */ - if ((fr != NULL) && (pass & FR_DUP)) { - mc = M_DUPLICATE(fin->fin_m); + if (fr != NULL) { + MUTEX_ENTER(&fr->fr_lock); + fr->fr_ref++; + MUTEX_EXIT(&fr->fr_lock); } - if (pass & (FR_RETRST|FR_RETICMP)) { + RWLOCK_EXIT(&ipf_mutex); + + if ((pass & FR_RETMASK) != 0) { /* * Should we return an ICMP packet to indicate error * status passing through the packet filter ? @@ -2447,10 +2574,19 @@ int out; ATOMIC_INCL(frstats[0].fr_ret); } else if (((pass & FR_RETMASK) == FR_RETRST) && !(fin->fin_flx & FI_SHORT)) { - if (fr_send_reset(fin) == 0) { + if (((fin->fin_flx & FI_OOW) != 0) || + (fr_send_reset(fin) == 0)) { ATOMIC_INCL(frstats[1].fr_ret); } } + + /* + * When using return-* with auth rules, the auth code + * takes over disposing of this packet. + */ + if (FR_ISAUTH(pass) && (fin->fin_m != NULL)) { + fin->fin_m = *fin->fin_mp = NULL; + } } else { if (pass & FR_RETRST) fin->fin_error = ECONNRESET; @@ -2463,13 +2599,7 @@ int out; * instructions about what to do with a packet. * Once we're finished return to our caller, freeing the packet if * we are dropping it (* BSD ONLY *). - * Reassign m from fin_m as we may have a new buffer, now. */ -#if defined(USE_INET6) || (defined(__sgi) && defined(_KERNEL)) -filtered: -#endif - m = fin->fin_m; - if (fr != NULL) { frdest_t *fdp; @@ -2480,26 +2610,26 @@ filtered: * For fastroute rule, no destioation interface defined * so pass NULL as the frdest_t parameter */ - (void) fr_fastroute(m, mp, fin, NULL); + (void) fr_fastroute(fin->fin_m, mp, fin, NULL); m = *mp = NULL; } else if ((fdp->fd_ifp != NULL) && (fdp->fd_ifp != (struct ifnet *)-1)) { /* this is for to rules: */ - (void) fr_fastroute(m, mp, fin, fdp); + (void) fr_fastroute(fin->fin_m, mp, fin, fdp); m = *mp = NULL; } /* * Generate a duplicated packet. */ - if (mc != NULL) - (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif); - } + if ((pass & FR_DUP) != 0) { + mc = M_DUPLICATE(fin->fin_m); + if (mc != NULL) + (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif); + } - /* - * This late because the likes of fr_fastroute() use fin_fr. - */ - RWLOCK_EXIT(&ipf_mutex); + (void) fr_derefrule(&fr); + } finished: if (!FR_ISPASS(pass)) { @@ -2513,7 +2643,7 @@ finished: #if defined(_KERNEL) && defined(__sgi) if ((fin->fin_hbuf != NULL) && (mtod(fin->fin_m, struct ip *) != fin->fin_ip)) { - COPYBACK(m, 0, fin->fin_plen, fin->fin_hbuf); + COPYBACK(fin->fin_m, 0, fin->fin_plen, fin->fin_hbuf); } #endif } @@ -2522,7 +2652,7 @@ finished: RWLOCK_EXIT(&ipf_global); #ifdef _KERNEL -# if OpenBSD >= 200311 +# if OpenBSD >= 200311 if (FR_ISPASS(pass) && (v == 4)) { ip = fin->fin_ip; ip->ip_len = ntohs(ip->ip_len); @@ -2671,10 +2801,10 @@ int len; /* Expects ip_len to be in host byte order when called. */ /* ------------------------------------------------------------------------ */ #ifdef INET -u_short fr_cksum(m, ip, l4proto, l4hdr) +u_short fr_cksum(m, ip, l4proto, l4hdr, l3len) mb_t *m; ip_t *ip; -int l4proto; +int l4proto, l3len; void *l4hdr; { u_short *sp, slen, sumsave, l4hlen, *csump; @@ -2699,7 +2829,7 @@ void *l4hdr; if (IP_V(ip) == 4) { #endif hlen = IP_HL(ip) << 2; - slen = ip->ip_len - hlen; + slen = l3len - hlen; sum = htons((u_short)l4proto); sum += htons(slen); sp = (u_short *)&ip->ip_src; @@ -2711,9 +2841,9 @@ void *l4hdr; } else if (IP_V(ip) == 6) { ip6 = (ip6_t *)ip; hlen = sizeof(*ip6); - slen = ntohs(ip6->ip6_plen); + slen = ntohs(l3len); sum = htons((u_short)l4proto); - sum += htons(slen); + sum += slen; sp = (u_short *)&ip6->ip6_src; sum += *sp++; /* ip6_src */ sum += *sp++; @@ -2915,7 +3045,7 @@ nodata: #if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \ - defined(__sgi) ) && !defined(linux) + defined(__sgi) ) && !defined(linux) && !defined(_AIX51) /* * Copyright (c) 1982, 1986, 1988, 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -2945,7 +3075,7 @@ nodata: * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp + * Id: fil.c,v 2.243.2.78 2006/03/29 11:19:54 darrenr Exp */ /* * Copy data from an mbuf chain starting "off" bytes from the beginning, @@ -3014,7 +3144,7 @@ m_copyback(m0, off, len, cp) m = m->m_next; } while (len > 0) { - mlen = min (m->m_len - off, len); + mlen = min(m->m_len - off, len); bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen); cp += mlen; len -= mlen; @@ -3063,7 +3193,7 @@ frgroup_t ***fgpp; frgroup_t *fg, **fgp; /* - * Which list of groups to search in is dependant on which list of + * Which list of groups to search in is dependent on which list of * rules are being operated on. */ fgp = &ipfgroups[unit][set]; @@ -3646,13 +3776,7 @@ size_t size; caddr_t ca; int err; -# if SOLARIS - err = COPYIN(dst, (caddr_t)&ca, sizeof(ca)); - if (err != 0) - return err; -# else bcopy(dst, (caddr_t)&ca, sizeof(ca)); -# endif err = COPYOUT(src, ca, size); return err; } @@ -4024,10 +4148,15 @@ caddr_t data; fprev = &fg->fg_start; } - for (f = *fprev; (f = *fprev) != NULL; fprev = &f->fr_next) - if (fp->fr_collect <= f->fr_collect) - break; ftail = fprev; + for (f = *ftail; (f = *ftail) != NULL; ftail = &f->fr_next) { + if (fp->fr_collect <= f->fr_collect) { + ftail = fprev; + f = NULL; + break; + } + fprev = ftail; + } /* * Copy in extra data for the rule. @@ -4126,7 +4255,6 @@ caddr_t data; break; #endif default : - break; } break; @@ -4166,14 +4294,17 @@ caddr_t data; WRITE_ENTER(&ipf_mutex); bzero((char *)frcache, sizeof(frcache)); - for (; (f = *ftail) != NULL; ftail = &f->fr_next) - if ((fp->fr_cksum == f->fr_cksum) && - (f->fr_dsize == fp->fr_dsize) && - !bcmp((char *)&f->fr_func, - (char *)&fp->fr_func, FR_CMPSIZ) && - (!ptr || !f->fr_data || + for (; (f = *ftail) != NULL; ftail = &f->fr_next) { + if ((fp->fr_cksum != f->fr_cksum) || + (f->fr_dsize != fp->fr_dsize)) + continue; + if (bcmp((char *)&f->fr_func, (char *)&fp->fr_func, FR_CMPSIZ)) + continue; + if ((!ptr && !f->fr_data) || + (ptr && f->fr_data && !bcmp((char *)ptr, (char *)f->fr_data, f->fr_dsize))) break; + } /* * If zero'ing statistics, copy current to caller and zero. @@ -4219,12 +4350,40 @@ caddr_t data; } if (!f) { - if (req == (ioctlcmd_t)SIOCINAFR || - req == (ioctlcmd_t)SIOCINIFR) { + /* + * At the end of this, ftail must point to the place where the + * new rule is to be saved/inserted/added. + * For SIOCAD*FR, this should be the last rule in the group of + * rules that have equal fr_collect fields. + * For SIOCIN*FR, ... + */ + if (req == (ioctlcmd_t)SIOCADAFR || + req == (ioctlcmd_t)SIOCADIFR) { + + for (ftail = fprev; (f = *ftail) != NULL; ) { + if (f->fr_collect > fp->fr_collect) + break; + ftail = &f->fr_next; + } + f = NULL; + ptr = NULL; + error = 0; + } else if (req == (ioctlcmd_t)SIOCINAFR || + req == (ioctlcmd_t)SIOCINIFR) { + while ((f = *fprev) != NULL) { + if (f->fr_collect >= fp->fr_collect) + break; + fprev = &f->fr_next; + } ftail = fprev; if (fp->fr_hits != 0) { - while (--fp->fr_hits && (f = *ftail)) + while (fp->fr_hits && (f = *ftail)) { + if (f->fr_collect != fp->fr_collect) + break; + fprev = ftail; ftail = &f->fr_next; + fp->fr_hits--; + } } f = NULL; ptr = NULL; @@ -4269,7 +4428,7 @@ caddr_t data; } if (*f->fr_grhead != '\0') fr_delgroup(f->fr_grhead, unit, set); - fr_fixskip(fprev, f, -1); + fr_fixskip(ftail, f, -1); *ftail = f->fr_next; f->fr_next = NULL; (void)fr_derefrule(&f); @@ -4290,7 +4449,7 @@ caddr_t data; } else f = fp; if (f != NULL) { - if (fg != NULL && fg->fg_head!= NULL ) + if (fg != NULL && fg->fg_head != NULL) fg->fg_head->fr_ref++; if (fp != f) bcopy((char *)fp, (char *)f, @@ -4309,7 +4468,7 @@ caddr_t data; *ftail = f; if (req == (ioctlcmd_t)SIOCINIFR || req == (ioctlcmd_t)SIOCINAFR) - fr_fixskip(fprev, f, 1); + fr_fixskip(ftail, f, 1); f->fr_grp = NULL; group = f->fr_grhead; if (*group != '\0') { @@ -4737,7 +4896,7 @@ ipftq_t *ifq; ifq->ifq_next->ifq_pnext = ifq->ifq_pnext; MUTEX_DESTROY(&ifq->ifq_lock); - fr_userifqs--; + ATOMIC_DEC(fr_userifqs); KFREE(ifq); } @@ -4759,8 +4918,6 @@ ipftqent_t *tqe; ipftq_t *ifq; ifq = tqe->tqe_ifq; - if (ifq == NULL) - return; MUTEX_ENTER(&ifq->ifq_lock); @@ -4832,24 +4989,21 @@ ipftqent_t *tqe; tqe->tqe_die = fr_ticks + ifq->ifq_ttl; MUTEX_ENTER(&ifq->ifq_lock); - if (tqe->tqe_next == NULL) { /* at the end already ? */ - MUTEX_EXIT(&ifq->ifq_lock); - return; - } - - /* - * Remove from list - */ - *tqe->tqe_pnext = tqe->tqe_next; - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; + if (tqe->tqe_next != NULL) { /* at the end already ? */ + /* + * Remove from list + */ + *tqe->tqe_pnext = tqe->tqe_next; + tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - /* - * Make it the last entry. - */ - tqe->tqe_next = NULL; - tqe->tqe_pnext = ifq->ifq_tail; - *ifq->ifq_tail = tqe; - ifq->ifq_tail = &tqe->tqe_next; + /* + * Make it the last entry. + */ + tqe->tqe_next = NULL; + tqe->tqe_pnext = ifq->ifq_tail; + *ifq->ifq_tail = tqe; + ifq->ifq_tail = &tqe->tqe_next; + } MUTEX_EXIT(&ifq->ifq_lock); } @@ -4901,46 +5055,44 @@ ipftq_t *oifq, *nifq; * Is the operation here going to be a no-op ? */ MUTEX_ENTER(&oifq->ifq_lock); - if (oifq == nifq && *oifq->ifq_tail == tqe) { - MUTEX_EXIT(&oifq->ifq_lock); - return; - } + if ((oifq != nifq) || (*oifq->ifq_tail != tqe)) { + /* + * Remove from the old queue + */ + *tqe->tqe_pnext = tqe->tqe_next; + if (tqe->tqe_next) + tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; + else + oifq->ifq_tail = tqe->tqe_pnext; + tqe->tqe_next = NULL; - /* - * Remove from the old queue - */ - *tqe->tqe_pnext = tqe->tqe_next; - if (tqe->tqe_next) - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - else - oifq->ifq_tail = tqe->tqe_pnext; - tqe->tqe_next = NULL; + /* + * If we're moving from one queue to another, release the + * lock on the old queue and get a lock on the new queue. + * For user defined queues, if we're moving off it, call + * delete in case it can now be freed. + */ + if (oifq != nifq) { + tqe->tqe_ifq = NULL; - /* - * If we're moving from one queue to another, release the lock on the - * old queue and get a lock on the new queue. For user defined queues, - * if we're moving off it, call delete in case it can now be freed. - */ - if (oifq != nifq) { - tqe->tqe_ifq = NULL; + (void) fr_deletetimeoutqueue(oifq); - (void) fr_deletetimeoutqueue(oifq); + MUTEX_EXIT(&oifq->ifq_lock); - MUTEX_EXIT(&oifq->ifq_lock); + MUTEX_ENTER(&nifq->ifq_lock); - MUTEX_ENTER(&nifq->ifq_lock); + tqe->tqe_ifq = nifq; + nifq->ifq_ref++; + } - tqe->tqe_ifq = nifq; - nifq->ifq_ref++; + /* + * Add to the bottom of the new queue + */ + tqe->tqe_die = fr_ticks + nifq->ifq_ttl; + tqe->tqe_pnext = nifq->ifq_tail; + *nifq->ifq_tail = tqe; + nifq->ifq_tail = &tqe->tqe_next; } - - /* - * Add to the bottom of the new queue - */ - tqe->tqe_die = fr_ticks + nifq->ifq_ttl; - tqe->tqe_pnext = nifq->ifq_tail; - *nifq->ifq_tail = tqe; - nifq->ifq_tail = &tqe->tqe_next; MUTEX_EXIT(&nifq->ifq_lock); } @@ -4957,7 +5109,7 @@ ipftq_t *oifq, *nifq; /* the fragment cache for non-leading fragments. If a non-leading fragment */ /* has no match in the cache, return an error. */ /* ------------------------------------------------------------------------ */ -static INLINE int fr_updateipid(fin) +static int fr_updateipid(fin) fr_info_t *fin; { u_short id, ido, sums; @@ -5009,7 +5161,7 @@ char *buffer; { static char namebuf[LIFNAMSIZ]; # if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \ - defined(__sgi) || defined(linux) || \ + defined(__sgi) || defined(linux) || defined(_AIX51) || \ (defined(sun) && !defined(__SVR4) && !defined(__svr4__)) int unit, space; char temp[20]; @@ -5021,7 +5173,7 @@ char *buffer; (void) strncpy(buffer, ifp->if_name, LIFNAMSIZ); buffer[LIFNAMSIZ - 1] = '\0'; # if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \ - defined(__sgi) || \ + defined(__sgi) || defined(_AIX51) || \ (defined(sun) && !defined(__SVR4) && !defined(__svr4__)) for (s = buffer; *s; s++) ; @@ -5425,7 +5577,7 @@ fr_info_t *fin; if (dosum) #ifdef INET sum = fr_cksum(fin->fin_m, fin->fin_ip, - fin->fin_p, fin->fin_dp); + fin->fin_p, fin->fin_dp, fin->fin_plen); #else return 1; #endif @@ -5638,6 +5790,10 @@ ipftuneable_t ipf_tuneables[] = { sizeof(fr_update_ipid), 0 }, { { &fr_chksrc }, "fr_chksrc", 0, 1, sizeof(fr_chksrc), 0 }, + { { &fr_minttl }, "fr_minttl", 0, 1, + sizeof(fr_minttl), 0 }, + { { &fr_icmpminfragmtu }, "fr_icmpminfragmtu", 0, 1, + sizeof(fr_icmpminfragmtu), 0 }, { { &fr_pass }, "fr_pass", 0, 0xffffffff, sizeof(fr_pass), 0 }, /* state */ @@ -6175,31 +6331,6 @@ int v; /* ------------------------------------------------------------------------ */ -/* Function: fr_icmp4errortype */ -/* Returns: int - 1 == success, 0 == failure */ -/* Parameters: icmptype(I) - ICMP type number */ -/* */ -/* Tests to see if the ICMP type number passed is an error type or not. */ -/* ------------------------------------------------------------------------ */ -int fr_icmp4errortype(icmptype) -int icmptype; -{ - - switch (icmptype) - { - case ICMP_SOURCEQUENCH : - case ICMP_PARAMPROB : - case ICMP_REDIRECT : - case ICMP_TIMXCEED : - case ICMP_UNREACH : - return 1; - default: - return 0; - } -} - - -/* ------------------------------------------------------------------------ */ /* Function: fr_resolvenic */ /* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */ /* pointer to interface structure for NIC */ diff --git a/sys/dist/ipf/netinet/ip_auth.c b/sys/dist/ipf/netinet/ip_auth.c index 75855e93b9d..e0c15c5926d 100644 --- a/sys/dist/ipf/netinet/ip_auth.c +++ b/sys/dist/ipf/netinet/ip_auth.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_auth.c,v 1.4 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_auth.c,v 1.5 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij. @@ -121,15 +121,16 @@ extern struct ifqueue ipintrq; /* ip packet input queue */ #if !defined(lint) #if defined(__NetBSD__) #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_auth.c,v 1.4 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_auth.c,v 1.5 2006/04/04 16:17:19 martti Exp $"); #else -static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.13 2006/03/29 11:19:55 darrenr Exp"; #endif #endif -#if SOLARIS +#if SOLARIS && defined(_KERNEL) extern kcondvar_t ipfauthwait; +extern struct pollhead iplpollhead[IPL_LOGSIZE]; #endif /* SOLARIS */ #if defined(linux) && defined(_KERNEL) wait_queue_head_t fr_authnext_linux; @@ -324,7 +325,7 @@ fr_info_t *fin; fra = fr_auth + i; fra->fra_index = i; - fra->fra_pass = 0; + fra->fra_pass = fin->fin_fr->fr_flags; fra->fra_age = fr_defaultauthage; bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin)); #if !defined(sparc) && !defined(m68k) @@ -346,17 +347,15 @@ fr_info_t *fin; } #endif #if SOLARIS && defined(_KERNEL) + COPYIFNAME(fin->fin_ifp, fra->fra_info.fin_ifname); m->b_rptr -= qpi->qpi_off; fr_authpkts[i] = *(mblk_t **)fin->fin_mp; fra->fra_q = qpi->qpi_q; /* The queue can disappear! */ + fra->fra_m = *fin->fin_mp; + fra->fra_info.fin_mp = &fra->fra_m; cv_signal(&ipfauthwait); + pollwakeup(&iplpollhead[IPL_LOGAUTH], POLLIN|POLLRDNORM); #else -# if defined(BSD) && !defined(sparc) && (BSD >= 199306) - if (!fin->fin_out) { - ip->ip_len = htons(ip->ip_len); - ip->ip_off = htons(ip->ip_off); - } -# endif fr_authpkts[i] = m; WAKEUP(&fr_authnext,0); #endif @@ -369,19 +368,15 @@ caddr_t data; ioctlcmd_t cmd; int mode; { + frauth_t auth, *au = &auth, *fra; + int i, error = 0, len; + char *t; mb_t *m; #if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \ (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000)) -#ifdef INET struct ifqueue *ifq; + SPL_INT(s); #endif -# ifdef USE_SPL - int s; -# endif /* USE_SPL */ -#endif - frauth_t auth, *au = &auth, *fra; - int i, error = 0, len; - char *t; switch (cmd) { @@ -410,10 +405,14 @@ int mode; case SIOCAUTHW: fr_authioctlloop: error = fr_inobj(data, au, IPFOBJ_FRAUTH); + if (error != 0) + break; READ_ENTER(&ipf_auth); if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) { error = fr_outobj(data, &fr_auth[fr_authnext], IPFOBJ_FRAUTH); + if (error != 0) + break; if (auth.fra_len != 0 && auth.fra_buf != NULL) { /* * Copy packet contents out to user space if @@ -427,11 +426,12 @@ fr_authioctlloop: for (t = auth.fra_buf; m && (len > 0); ) { i = MIN(M_LEN(m), len); error = copyoutptr(MTOD(m, char *), - t, i); + &t, i); len -= i; t += i; if (error != 0) break; + m = m->m_next; } } RWLOCK_EXIT(&ipf_auth); @@ -484,10 +484,8 @@ fr_authioctlloop: #endif MUTEX_EXIT(&ipf_authmx); READ_ENTER(&ipf_global); - if (error == 0) { - READ_ENTER(&ipf_auth); + if (error == 0) goto fr_authioctlloop; - } break; case SIOCAUTHR: @@ -498,6 +496,7 @@ fr_authioctlloop: WRITE_ENTER(&ipf_auth); i = au->fra_index; fra = fr_auth + i; + error = 0; if ((i < 0) || (i >= fr_authsize) || (fra->fra_info.fin_id != au->fra_info.fin_id)) { RWLOCK_EXIT(&ipf_auth); @@ -513,12 +512,16 @@ fr_authioctlloop: if ((m != NULL) && (au->fra_info.fin_out != 0)) { #ifdef INET # ifdef MENTAT - error = !putq(fra->fra_q, m); + error = ipf_inject(&fra->fra_info); + if (error != 0) { + FREE_MB_T(m); + error = ENOBUFS; + } # else /* MENTAT */ -# ifdef linux +# if defined(linux) || defined(AIX) # else # if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \ - (defined(__sgi) && (IRIX >= 60500) || \ + (defined(__sgi) && (IRIX >= 60500) || defined(AIX) || \ (defined(__FreeBSD__) && (__FreeBSD_version >= 470102))) error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); @@ -535,14 +538,18 @@ fr_authioctlloop: } else if (m) { #ifdef INET # ifdef MENTAT - error = !putq(fra->fra_q, m); + error = ipf_inject(&fra->fra_info); + if (error != 0) { + FREE_MB_T(m); + error = ENOBUFS; + } # else /* MENTAT */ -# ifdef linux +# if defined(linux) || defined(AIX) # else -# if __FreeBSD_version >= 501000 +# if (__FreeBSD_version >= 501000) netisr_dispatch(NETISR_IP, m); # else -# if IRIX >= 60516 +# if (IRIX >= 60516) ifq = &((struct ifnet *)fra->fra_info.fin_ifp)->if_snd; # else ifq = &ipintrq; @@ -567,10 +574,6 @@ fr_authioctlloop: fr_authstats.fas_queok++; } else error = EINVAL; -# ifdef MENTAT - if (error != 0) - error = EINVAL; -# else /* MENTAT */ /* * If we experience an error which will result in the packet * not being processed, make sure we advance to the next one. @@ -594,7 +597,6 @@ fr_authioctlloop: } } } -# endif /* MENTAT */ #endif /* _KERNEL */ SPL_X(s); break; @@ -674,9 +676,7 @@ void fr_authexpire() register frauthent_t *fae, **faep; register frentry_t *fr, **frp; mb_t *m; -# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL) - int s; -# endif + SPL_INT(s); if (fr_auth_lock) return; @@ -725,9 +725,7 @@ frentry_t *fr, **frptr; { frauthent_t *fae, **faep; int error = 0; -# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL) - int s; -#endif + SPL_INT(s); if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) return EIO; @@ -813,3 +811,9 @@ int fr_authflush() return num_flushed; } + + +int fr_auth_waiting() +{ + return (fr_authnext != fr_authend) && fr_authpkts[fr_authnext]; +} diff --git a/sys/dist/ipf/netinet/ip_auth.h b/sys/dist/ipf/netinet/ip_auth.h index 60131223a64..0d826dd5159 100644 --- a/sys/dist/ipf/netinet/ip_auth.h +++ b/sys/dist/ipf/netinet/ip_auth.h @@ -1,11 +1,11 @@ -/* $NetBSD: ip_auth.h,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_auth.h,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1997-2001 by Darren Reed & Guido Van Rooij. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp + * Id: ip_auth.h,v 2.16.2.2 2006/03/16 06:45:49 darrenr Exp * */ #ifndef _NETINET_IP_AUTH_H_ @@ -22,6 +22,7 @@ typedef struct frauth { char *fra_buf; #ifdef MENTAT queue_t *fra_q; + mb_t *fra_m; #endif } frauth_t; @@ -62,5 +63,6 @@ extern mb_t **fr_authpkts; extern int fr_newauth __P((mb_t *, fr_info_t *)); extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_t **)); extern int fr_auth_ioctl __P((caddr_t, ioctlcmd_t, int)); +extern int fr_auth_waiting __P((void)); #endif /* __IP_AUTH_H__ */ diff --git a/sys/dist/ipf/netinet/ip_compat.h b/sys/dist/ipf/netinet/ip_compat.h index 116551df281..80c84b7b995 100644 --- a/sys/dist/ipf/netinet/ip_compat.h +++ b/sys/dist/ipf/netinet/ip_compat.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_compat.h,v 1.9 2006/03/17 23:29:07 christos Exp $ */ +/* $NetBSD: ip_compat.h,v 1.10 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -6,7 +6,7 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_compat.h 1.8 1/14/96 - * Id: ip_compat.h,v 2.142.2.25 2005/03/28 09:33:36 darrenr Exp + * Id: ip_compat.h,v 2.142.2.36 2006/03/26 05:50:29 darrenr Exp */ #ifndef _NETINET_IP_COMPAT_H_ @@ -443,6 +443,7 @@ extern void *get_unit __P((char *, int)); wakeup(id + x); \ spinunlock(_l); \ } +# define POLLWAKEUP(x) ; # define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT) # define KMALLOCS(a, b, c) (a) = (b)malloc((c), M_IOSYS, M_NOWAIT) # define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) @@ -580,6 +581,7 @@ typedef struct { # define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) # define SLEEP(id, n) sleep((id), PZERO+1) # define WAKEUP(id,x) wakeup(id+x) +# define POLLWAKEUP(x) ; # define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) # define KFREES(x,s) kmem_free((char *)(x), (s)) # define GETIFP(n,v) ifunit(n) @@ -661,6 +663,7 @@ typedef struct mbuf mb_t; # define GETIFP(n, v) ifunit(n) # define GET_MINOR getminor # define WAKEUP(id,x) wakeup(id + x) +# define POLLWAKEUP(x) ; # define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) # define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) # define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) @@ -768,7 +771,7 @@ typedef u_int32_t u_32_t; /* F R E E B S D */ /* ----------------------------------------------------------------------- */ #ifdef __FreeBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) && !defined(KLD_MODULE) +# if defined(_KERNEL) # if (__FreeBSD_version >= 500000) # include "opt_bpf.h" # else @@ -1031,6 +1034,7 @@ typedef u_int32_t u_32_t; # define KFREES(x,s) kmem_free((char *)(x), (s)) # define SLEEP(id, n) sleep((id), PZERO+1) # define WAKEUP(id,x) wakeup(id + x) +# define POLLWAKEUP(x) ; # define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) # define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } @@ -1076,6 +1080,7 @@ struct ip6_ext { # define FREE_MB_T(m) kfree_skb(m) # define GETKTIME(x) do_gettimeofday((struct timeval *)x) # define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux) +# define POLLWAKEUP(x) ; # define WAKEUP(x,y) wake_up(x##_linux + y) # define UIOMOVE(a,b,c,d) uiomove(a,b,c,d) # define USE_MUTEXES @@ -1122,6 +1127,7 @@ extern mb_t *m_pullup __P((mb_t *, int)); # define mbuf sk_buff # define mtod(m, t) ((t)(m)->data) +# define m_data data # define m_len len # define m_next next # define M_DUPLICATE(m) skb_clone((m), in_interrupt() ? GFP_ATOMIC : \ @@ -1206,6 +1212,116 @@ typedef u_int32_t u_32_t; #endif +/* ----------------------------------------------------------------------- */ +/* A I X */ +/* ----------------------------------------------------------------------- */ +#if defined(_AIX51) +# undef MENTAT + +# include <sys/lock.h> +# include <sys/sysmacros.h> + +# ifdef _KERNEL +# define rw_read_locked(x) 0 +# include <net/net_globals.h> +# include <net/net_malloc.h> +# define KMUTEX_T simple_lock_t +# define KRWLOCK_T complex_lock_t +# define USE_MUTEXES 1 +# define USE_SPL 1 +# define READ_ENTER(x) lock_read((x)->ipf_lk) +# define WRITE_ENTER(x) lock_write((x)->ipf_lk) +# define MUTEX_DOWNGRADE(x) lock_write_to_read((x)->ipf_lk) +# define RWLOCK_INIT(x, y) lock_alloc(&(x)->ipf_lk, \ + LOCK_ALLOC_PIN, \ + (u_short)y, 0); \ + lock_init((x)->ipf_lk, TRUE) +# define RWLOCK_EXIT(x) lock_done((x)->ipf_lk) +# define RW_DESTROY(x) lock_free(&(x)->ipf_lk) +# define MUTEX_ENTER(x) simple_lock((x)->ipf_lk) +# define MUTEX_INIT(x, y) lock_alloc(&(x)->ipf_lk, \ + LOCK_ALLOC_PIN, \ + (u_short)y, 0); \ + simple_lock_init((x)->ipf_lk) +# define MUTEX_DESTROY(x) lock_free(&(x)->ipf_lk) +# define MUTEX_EXIT(x) simple_unlock((x)->ipf_lk) +# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk)) +# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ + MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ + MUTEX_EXIT(&ipf_rw); } +# define SPL_NET(x) x = splnet() +# define SPL_IMP(x) x = splimp() +# undef SPL_X +# define SPL_X(x) splx(x) +# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) +extern void* getifp __P((char *, int)); +# define GETIFP(n, v) getifp(n, v) +# define GET_MINOR minor +# define SLEEP(id, n) sleepx((id), PZERO+1, 0) +# define WAKEUP(id,x) wakeup(id) +# define POLLWAKEUP(x) ; +# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) +# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) +# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) +# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) +# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT) +# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, \ + ((c) > 4096) ? M_WAITOK : M_NOWAIT) +# define KFREE(x) FREE((x), M_TEMP) +# define KFREES(x,s) FREE((x), M_TEMP) +# define MSGDSIZE(x) mbufchainlen(x) +# define M_LEN(x) (x)->m_len +# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) +# define GETKTIME(x) +# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ + ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) +# define IPF_PANIC(x,y) +typedef struct mbuf mb_t; +# endif /* _KERNEL */ + +/* + * These are from's Solaris' #defines for little endian. + */ +#if !defined(IP6F_MORE_FRAG) +# define IP6F_MORE_FRAG 0x0100 +#endif +#if !defined(IP6F_RESERVED_MASK) +# define IP6F_RESERVED_MASK 0x0600 +#endif +#if !defined(IP6F_OFF_MASK) +# define IP6F_OFF_MASK 0xf8ff +#endif + +struct ip6_ext { + u_char ip6e_nxt; + u_char ip6e_len; +}; + +typedef int ioctlcmd_t; +typedef int minor_t; +/* + * Really, any arch where sizeof(long) != sizeof(int). + */ +typedef unsigned int u_32_t; +# define U_32_T 1 + +# define OS_RECOGNISED 1 +#endif /* _AIX51 */ + + #ifndef OS_RECOGNISED #error ip_compat.h does not recognise this platform/OS. #endif @@ -1221,8 +1337,11 @@ typedef u_int32_t u_32_t; * For BSD kernels, if bpf is in the kernel, enable ipfilter to use bpf in * filter rules. */ -#if !defined(IPFILTER_BPF) && ((NBPF > 0) || (NBPFILTER > 0)) -# define IPFILTER_BPF +#if !defined(IPFILTER_BPF) +# if (defined(NBPF) && (NBPF > 0)) || (defined(DEV_BPF) && (DEV_BPF > 0)) || \ + (defined(NBPFILTER) && (NBPFILTER > 0)) +# define IPFILTER_BPF +# endif #endif /* @@ -1290,10 +1409,10 @@ typedef union { #endif #if defined(linux) && defined(_KERNEL) -extern INLINE void ipf_read_enter __P((ipfrwlock_t *)); -extern INLINE void ipf_write_enter __P((ipfrwlock_t *)); -extern INLINE void ipf_rw_exit __P((ipfrwlock_t *)); -extern INLINE void ipf_rw_downgrade __P((ipfrwlock_t *)); +extern void ipf_read_enter __P((ipfrwlock_t *)); +extern void ipf_write_enter __P((ipfrwlock_t *)); +extern void ipf_rw_exit __P((ipfrwlock_t *)); +extern void ipf_rw_downgrade __P((ipfrwlock_t *)); #endif /* @@ -1313,10 +1432,12 @@ typedef struct mb_s { # define M_LEN(x) (x)->mb_len # define M_DUPLICATE(x) (x) # define GETKTIME(x) gettimeofday((struct timeval *)(x), NULL) +# undef MTOD # define MTOD(m, t) ((t)(m)->mb_buf) # define FREE_MB_T(x) # define SLEEP(x,y) 1; # define WAKEUP(x,y) ; +# define POLLWAKEUP(y) ; # define IPF_PANIC(x,y) ; # define PANIC(x,y) ; # define SPL_NET(x) ; @@ -1327,8 +1448,8 @@ typedef struct mb_s { # define KFREE(x) free(x) # define KFREES(x,s) free(x) # define GETIFP(x, v) get_unit(x,v) -# define COPYIN(a,b,c) (bcopy((a), (b), (c)), 0) -# define COPYOUT(a,b,c) (bcopy((a), (b), (c)), 0) +# define COPYIN(a,b,c) bcopywrap((a), (b), (c)) +# define COPYOUT(a,b,c) bcopywrap((a), (b), (c)) # define BCOPYIN(a,b,c) (bcopy((a), (b), (c)), 0) # define BCOPYOUT(a,b,c) (bcopy((a), (b), (c)), 0) # define COPYDATA(m, o, l, b) bcopy(MTOD((mb_t *)m, char *) + (o), \ @@ -1339,6 +1460,7 @@ typedef struct mb_s { # define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d) extern void m_copydata __P((mb_t *, int, int, caddr_t)); extern int ipfuiomove __P((caddr_t, int, int, struct uio *)); +extern int bcopywrap __P((void *, void *, size_t)); # ifndef CACHE_HASH # define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) @@ -1417,6 +1539,9 @@ typedef struct ip6_hdr ip6_t; #endif #if defined(_KERNEL) +# ifdef BSD +extern struct selinfo ipfselwait[]; +# endif # ifdef MENTAT # define COPYDATA mb_copydata # define COPYBACK mb_copyback @@ -1466,6 +1591,7 @@ MALLOC_DECLARE(M_IPFILTER); # define UIOMOVE(a,b,c,d) uiomove(a,b,d) # define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0) # define WAKEUP(id,x) wakeup(id+x) +# define POLLWAKEUP(x) selwakeup(ipfselwait+x) # define GETIFP(n, v) ifunit(n) # endif /* (Free)BSD */ @@ -2043,9 +2169,10 @@ typedef struct tcpiphdr tcpiphdr_t; #ifndef IPPROTO_DSTOPTS # define IPPROTO_DSTOPTS 60 #endif -#ifndef IPPROTO_FRAGMENT -# define IPPROTO_FRAGMENT 44 +#ifndef IPPROTO_MOBILITY +# define IPPROTO_MOBILITY 135 #endif + #ifndef ICMP_ROUTERADVERT # define ICMP_ROUTERADVERT 9 #endif @@ -2279,7 +2406,7 @@ typedef struct tcpiphdr tcpiphdr_t; /* * ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data, * another IP header and then 64 bits of data, totalling 56. Of course, - * the last 64 bits is dependant on that being available. + * the last 64 bits is dependent on that being available. */ #define ICMPERR_ICMPHLEN 8 #define ICMPERR_IPICMPHLEN (20 + 8) @@ -2298,4 +2425,8 @@ typedef struct tcpiphdr tcpiphdr_t; # define DPRINT(x) #endif -#endif /* _NETINET_IP_COMPAT_H_ */ +#ifdef RESCUE +# undef IPFILTER_BPF +#endif + +#endif /* __IP_COMPAT_H__ */ diff --git a/sys/dist/ipf/netinet/ip_fil.h b/sys/dist/ipf/netinet/ip_fil.h index 3d8b29ea197..d6a6c5f8e92 100644 --- a/sys/dist/ipf/netinet/ip_fil.h +++ b/sys/dist/ipf/netinet/ip_fil.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_fil.h,v 1.5 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_fil.h,v 1.6 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -6,12 +6,14 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 - * Id: ip_fil.h,v 2.170.2.18 2005/03/28 10:47:52 darrenr Exp + * Id: ip_fil.h,v 2.170.2.29 2006/03/29 11:19:55 darrenr Exp */ #ifndef _NETINET_IP_FIL_H_ #define _NETINET_IP_FIL_H_ +#include "netinet/ip_compat.h" + #ifndef SOLARIS # define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) #endif @@ -24,7 +26,7 @@ # endif #endif -#if defined(__STDC__) || defined(__GNUC__) +#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) # define SIOCADAFR _IOW('r', 60, struct ipfobj) # define SIOCRMAFR _IOW('r', 61, struct ipfobj) # define SIOCSETFF _IOW('r', 62, u_int) @@ -305,6 +307,7 @@ typedef struct fr_info { #ifdef MENTAT mb_t *fin_qfm; /* pointer to mblk where pkt starts */ void *fin_qpi; + char fin_ifname[LIFNAMSIZ]; #endif #ifdef __sgi void *fin_hbuf; @@ -904,6 +907,7 @@ typedef struct tcpdata { #define TCP_WSCALE_SEEN 0x00000001 #define TCP_WSCALE_FIRST 0x00000002 +#define TCP_SACK_PERMIT 0x00000004 typedef struct tcpinfo { @@ -913,6 +917,9 @@ typedef struct tcpinfo { } tcpinfo_t; +/* + * Structures to define a GRE header as seen in a packet. + */ struct grebits { u_32_t grb_C:1; u_32_t grb_R:1; @@ -947,7 +954,9 @@ typedef struct grehdr { #define gr_A gr_bits.grb_A #define gr_ver gr_bits.grb_ver - +/* + * GRE information tracked by "keep state" + */ typedef struct greinfo { u_short gs_call[2]; u_short gs_flags; @@ -958,6 +967,20 @@ typedef struct greinfo { /* + * Format of an Authentication header + */ +typedef struct authhdr { + u_char ah_next; + u_char ah_plen; + u_short ah_reserved; + u_32_t ah_spi; + u_32_t ah_seq; + /* Following the sequence number field is 0 or more bytes of */ + /* authentication data, as specified by ah_plen - RFC 2402. */ +} authhdr_t; + + +/* * Timeout tail queue list member */ typedef struct ipftqent { @@ -1113,6 +1136,17 @@ typedef struct ipftune { # endif #endif +#ifdef _KERNEL +# define FR_VERBOSE(verb_pr) +# define FR_DEBUG(verb_pr) +#else +extern void debug __P((char *, ...)); +extern void verbose __P((char *, ...)); +# define FR_VERBOSE(verb_pr) verbose verb_pr +# define FR_DEBUG(verb_pr) debug verb_pr +#endif + + #ifndef _KERNEL extern int fr_check __P((struct ip *, int, void *, int, mb_t **)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **)); @@ -1128,6 +1162,7 @@ extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int)); extern int iplopen __P((dev_t, int)); extern int iplclose __P((dev_t, int)); extern void m_freem __P((mb_t *)); +extern int bcopywrap __P((void *, void *, size_t)); #else /* #ifndef _KERNEL */ # if defined(__NetBSD__) && defined(PFIL_HOOKS) extern void ipfilterattach __P((int)); @@ -1237,6 +1272,7 @@ extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap; extern ipfmutex_t ipf_timeoutlock, ipf_stinsert, ipf_natio, ipf_nat_new; extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag; extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; +extern ipfrwlock_t ipf_frcache; extern char *memstr __P((const char *, char *, size_t, size_t)); extern int count4bits __P((u_32_t)); @@ -1295,6 +1331,7 @@ extern void fr_delgroup __P((char *, minor_t, int)); extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***)); extern int fr_loginit __P((void)); +extern int ipflog_canread __P((int)); extern int ipflog_clear __P((minor_t)); extern int ipflog_read __P((minor_t, uio_t *)); extern int ipflog __P((fr_info_t *, u_int)); @@ -1303,7 +1340,7 @@ extern void fr_logunload __P((void)); extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *)); extern int fr_copytolog __P((int, char *, int)); -extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *)); +extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *, int)); extern void fr_deinitialise __P((void)); extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *)); extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *)); @@ -1311,7 +1348,6 @@ extern void fr_fixskip __P((frentry_t **, frentry_t *, int)); extern void fr_forgetifp __P((void *)); extern frentry_t *fr_getrulen __P((int, char *, u_32_t)); extern void fr_getstat __P((struct friostat *)); -extern int fr_icmp4errortype __P((int)); extern int fr_ifpaddr __P((int, int, void *, struct in_addr *, struct in_addr *)); extern int fr_initialise __P((void)); diff --git a/sys/dist/ipf/netinet/ip_fil_netbsd.c b/sys/dist/ipf/netinet/ip_fil_netbsd.c index e9d13423875..cd484c3855a 100644 --- a/sys/dist/ipf/netinet/ip_fil_netbsd.c +++ b/sys/dist/ipf/netinet/ip_fil_netbsd.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_fil_netbsd.c,v 1.18 2005/12/28 09:29:48 christos Exp $ */ +/* $NetBSD: ip_fil_netbsd.c,v 1.19 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2003 by Darren Reed. @@ -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_netbsd.c,v 2.55.2.27 2005/02/21 22:51:08 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_fil_netbsd.c,v 2.55.2.38 2006/03/25 13:03:02 darrenr Exp"; #endif #if defined(KERNEL) || defined(_KERNEL) @@ -36,6 +36,7 @@ static const char rcsid[] = "@(#)Id: ip_fil_netbsd.c,v 2.55.2.27 2005/02/21 22:5 #include <sys/mbuf.h> #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/poll.h> #include <net/if.h> #include <net/route.h> @@ -92,10 +93,6 @@ extern struct protosw inetsw[]; static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **)); static int fr_send_ip __P((fr_info_t *, mb_t *, mb_t **)); -#ifdef KMUTEX_T -extern ipfmutex_t ipf_rw; -extern ipfrwlock_t ipf_mutex; -#endif #ifdef USE_INET6 static int ipfr_fastroute6 __P((struct mbuf *, struct mbuf **, fr_info_t *, frdest_t *)); @@ -116,9 +113,19 @@ int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp)); #endif /* NETBSD_PF */ #if (__NetBSD_Version__ >= 106080000) && defined(_KERNEL) +# include <sys/select.h> + +# if (__NetBSD_Version__ >= 399001400) +int iplpoll __P((dev_t dev, int events, struct lwp *p)); +# else +int iplpoll __P((dev_t dev, int events, struct proc *p)); +# endif + +struct selinfo ipfselwait[IPL_LOGSIZE]; + const struct cdevsw ipl_cdevsw = { iplopen, iplclose, iplread, nowrite, iplioctl, - nostop, notty, nopoll, nommap, + nostop, notty, iplpoll, nommap, }; #endif @@ -207,7 +214,7 @@ struct ifnet *ifp; int dir; { #if defined(INET6) -#if defined(M_CSUM_TCPv6) +# if defined(M_CSUM_TCPv6) && (__NetBSD_Version__ > 200000000) /* * If the packet is out-bound, we can't delay checksums * here. For in-bound, the checksum has already been @@ -216,17 +223,40 @@ int dir; if (dir == PFIL_OUT) { if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) { in6_delayed_cksum(*mp); - (*mp)->m_pkthdr.csum_flags &= - ~(M_CSUM_TCPv6|M_CSUM_UDPv6); + (*mp)->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv6| + M_CSUM_UDPv6); } } -#endif /* M_CSUM_TCPv6 */ +# endif #endif /* INET6 */ return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp)); } # endif + + +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) +static int ipf_pfilsync(void *, struct mbuf **, struct ifnet *, int); + +static int ipf_pfilsync(hdr, mp, ifp, dir) +void *hdr; +struct mbuf **mp; +struct ifnet *ifp; +int dir; +{ + /* + * The interface pointer is useless for create (we have nothing to + * compare it to) and at detach, the interface name is still in the + * list of active NICs (albeit, down, but that's not any real + * indicator) and doing ifunit() on the name will still return the + * pointer, so it's not much use then, either. + */ + frsync(NULL); + return 0; +} +# endif + #endif /* __NetBSD_Version__ >= 105110000 */ @@ -267,6 +297,9 @@ int iplattach() # ifdef USE_INET6 struct pfil_head *ph_inet6; # endif +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) + struct pfil_head *ph_ifsync; +# endif # endif #endif @@ -289,10 +322,17 @@ int iplattach() # ifdef USE_INET6 ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); # endif +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) + ph_ifsync = pfil_head_get(PFIL_TYPE_IFNET, 0); +# endif + if (ph_inet == NULL # ifdef USE_INET6 && ph_inet6 == NULL # endif +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) + && ph_ifsync == NULL +# endif ) { printf("pfil_head_get failed\n"); return ENODEV; @@ -303,22 +343,16 @@ int iplattach() PFIL_IN|PFIL_OUT, ph_inet); else error = 0; -# else +# else error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif - if (error) { -# ifdef USE_INET6 - goto pfil_error; -# else - fr_deinitialise(); - SPL_X(s); - return error; # endif - } + if (error) + goto pfil_error; # else pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT); # endif + # ifdef USE_INET6 # if __NetBSD_Version__ >= 105110000 if (ph_inet6 != NULL) @@ -329,21 +363,27 @@ int iplattach() if (error) { pfil_remove_hook((void *)fr_check_wrapper6, NULL, PFIL_IN|PFIL_OUT, ph_inet6); + goto pfil_error; + } # else error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); if (error) { pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif -pfil_error: - fr_deinitialise(); - SPL_X(s); - return error; + goto pfil_error; } +# endif +# endif + +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) + if (ph_ifsync != NULL) + (void) pfil_add_hook((void *)ipf_pfilsync, NULL, + PFIL_IFNET, ph_ifsync); # endif #endif + bzero((char *)ipfselwait, sizeof(ipfselwait)); bzero((char *)frcache, sizeof(frcache)); fr_savep = fr_checkp; fr_checkp = fr_check; @@ -363,6 +403,13 @@ pfil_error: timeout(fr_slowtimer, NULL, (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); #endif return 0; + +#if __NetBSD_Version__ >= 105110000 +pfil_error: + fr_deinitialise(); + SPL_X(s); + return error; +#endif } @@ -380,6 +427,9 @@ int ipldetach() # ifdef USE_INET6 struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); # endif +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) + struct pfil_head *ph_ifsync = pfil_head_get(PFIL_TYPE_IFNET, 0); +# endif # endif #endif @@ -403,6 +453,11 @@ int ipldetach() #ifdef NETBSD_PF # if (__NetBSD_Version__ >= 104200000) # if __NetBSD_Version__ >= 105110000 +# if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET) + (void) pfil_remove_hook((void *)ipf_pfilsync, NULL, + PFIL_IFNET, ph_ifsync); +# endif + if (ph_inet != NULL) error = pfil_remove_hook((void *)fr_check_wrapper, NULL, PFIL_IN|PFIL_OUT, ph_inet); @@ -444,8 +499,12 @@ int ipldetach() */ int iplioctl(dev, cmd, data, mode #if (NetBSD >= 199511) -, l) -struct lwp *l; +, p) +# if (__NetBSD_Version__ >= 399001400) +struct lwp *p; +# else +struct proc *p; +# endif #else ) #endif @@ -667,9 +726,13 @@ void *ifp; */ int iplopen(dev, flags #if (NetBSD >= 199511) -, devtype, l) +, devtype, p) int devtype; -struct lwp *l; +# if (__NetBSD_Version__ >= 399001400) +struct lwp *p; +# else +struct proc *p; +# endif #else ) #endif @@ -688,9 +751,13 @@ int flags; int iplclose(dev, flags #if (NetBSD >= 199511) -, devtype, l) +, devtype, p) int devtype; -struct lwp *l; +# if (__NetBSD_Version__ >= 399001400) +struct lwp *p; +# else +struct proc *p; +# endif #else ) #endif @@ -1175,18 +1242,8 @@ frdest_t *fdp; goto bad; } - /* - * In case we're here due to "to <if>" being used with "keep state", - * check that we're going in the correct direction. - */ - if ((fr != NULL) && (fin->fin_rev != 0)) { - if ((ifp != NULL) && (fdp == &fr->fr_tif)) - return -1; - } - if (fdp != NULL) { - if (fdp->fd_ip.s_addr != 0) - dst->sin_addr = fdp->fd_ip; - } + if ((fdp != NULL) && (fdp->fd_ip.s_addr != 0)) + dst->sin_addr = fdp->fd_ip; dst->sin_len = sizeof(*dst); rtalloc(ro); @@ -1410,8 +1467,9 @@ frdest_t *fdp; struct ifnet *ifp; frentry_t *fr; u_long mtu; - int error = 0; + int error; + error = 0; ro = &ip6route; fr = fin->fin_fr; bzero((caddr_t)ro, sizeof(*ro)); @@ -1791,7 +1849,7 @@ struct mbuf *m0; /* not been called. Both fin_ip and fin_dp are updated before exiting _IF_ */ /* and ONLY if the pullup succeeds. */ /* */ -/* We assume that 'min' is a pointer to a buffer that is part of the chain */ +/* We assume that 'xmin' is a pointer to a buffer that is part of the chain */ /* of buffers that starts at *fin->fin_mp. */ /* ------------------------------------------------------------------------ */ void *fr_pullup(xmin, fin, len) @@ -1857,3 +1915,52 @@ int len; fin->fin_flx |= FI_COALESCE; return ip; } + + +int iplpoll(dev, events, p) +dev_t dev; +int events; +#if (__NetBSD_Version__ >= 399001400) +struct lwp *p; +#else +struct proc *p; +#endif +{ + u_int xmin = GET_MINOR(dev); + int revents = 0; + + if (IPL_LOGMAX < xmin) + return ENXIO; + + switch (xmin) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : +#ifdef IPFILTER_LOG + if ((events & (POLLIN | POLLRDNORM)) && ipflog_canread(xmin)) + revents |= events & (POLLIN | POLLRDNORM); +#endif + break; + case IPL_LOGAUTH : + if ((events & (POLLIN | POLLRDNORM)) && fr_auth_waiting()) + revents |= events & (POLLIN | POLLRDNORM); + break; + case IPL_LOGSYNC : +#ifdef IPFILTER_SYNC + if ((events & (POLLIN | POLLRDNORM)) && ipfsync_canread()) + revents |= events & (POLLIN | POLLRDNORM); + if ((events & (POLLOUT | POLLWRNORM)) && ipfsync_canwrite()) + revents |= events & (POLLOUT | POLLOUTNORM); +#endif + break; + case IPL_LOGSCAN : + case IPL_LOGLOOKUP : + default : + break; + } + + if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) + selrecord(p, &ipfselwait[xmin]); + return revents; +} diff --git a/sys/dist/ipf/netinet/ip_frag.c b/sys/dist/ipf/netinet/ip_frag.c index 07e9cfad097..1b2755b5095 100644 --- a/sys/dist/ipf/netinet/ip_frag.c +++ b/sys/dist/ipf/netinet/ip_frag.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_frag.c,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_frag.c,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2003 by Darren Reed. @@ -47,7 +47,7 @@ struct file; # endif #endif #if !defined(__SVR4) && !defined(__svr4__) -# if defined(_KERNEL) && !defined(__sgi) +# if defined(_KERNEL) && !defined(__sgi) && !defined(AIX) # include <sys/kernel.h> # endif #else @@ -103,10 +103,10 @@ extern struct timeout fr_slowtimer_ch; #if !defined(lint) #if defined(__NetBSD__) #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.2 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.3 2006/04/04 16:17:19 martti Exp $"); #else static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77 2004/01/27 00:24:54 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77.2.5 2006/02/26 08:26:54 darrenr Exp"; #endif #endif @@ -231,6 +231,7 @@ ipfr_t *table[]; { ipfr_t *fra, frag; u_int idx, off; + frentry_t *fr; ip_t *ip; if (ipfr_inuse >= IPFT_SIZE) @@ -242,7 +243,7 @@ ipfr_t *table[]; ip = fin->fin_ip; if (pass & FR_FRSTRICT) - if ((ip->ip_off & IP_OFFMASK) != 0) + if (fin->fin_off != 0) return NULL; frag.ipfr_p = ip->ip_p; @@ -282,8 +283,13 @@ ipfr_t *table[]; return NULL; } - if ((fra->ipfr_rule = fin->fin_fr) != NULL) - fin->fin_fr->fr_ref++; + fr = fin->fin_fr; + fra->ipfr_rule = fr; + if (fr != NULL) { + MUTEX_ENTER(&fr->fr_lock); + fr->fr_ref++; + MUTEX_EXIT(&fr->fr_lock); + } /* * Insert the fragment into the fragment table, copy the struct used @@ -751,9 +757,7 @@ void fr_fragexpire() { ipfr_t **fp, *fra; nat_t *nat; -#if defined(USE_SPL) && defined(_KERNEL) - int s; -#endif + SPL_INT(s); if (fr_frag_lock) return; @@ -819,7 +823,7 @@ void fr_fragexpire() /* expectation of this being called twice per second. */ /* ------------------------------------------------------------------------ */ #if !defined(_KERNEL) || (!SOLARIS && !defined(__hpux) && !defined(__sgi) && \ - !defined(__osf__)) + !defined(__osf__) && !defined(linux)) # if defined(_KERNEL) && ((BSD >= 199103) || defined(__sgi)) void fr_slowtimer __P((void *ptr)) # else diff --git a/sys/dist/ipf/netinet/ip_frag.h b/sys/dist/ipf/netinet/ip_frag.h index ded607d7b34..ba58cdbf685 100644 --- a/sys/dist/ipf/netinet/ip_frag.h +++ b/sys/dist/ipf/netinet/ip_frag.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_frag.h,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_frag.h,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -6,7 +6,7 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_frag.h 1.5 3/24/96 - * Id: ip_frag.h,v 2.23.2.1 2004/03/29 16:21:56 darrenr Exp + * Id: ip_frag.h,v 2.23.2.2 2005/06/10 18:02:37 darrenr Exp */ #ifndef _NETINET_IP_FRAG_H_ @@ -80,7 +80,11 @@ extern void fr_slowtimer __P((void)); extern void fr_slowtimer __P((void *)); # endif #else +# if defined(linux) && defined(_KERNEL) +extern void fr_slowtimer __P((long)); +# else extern int fr_slowtimer __P((void)); +# endif #endif #endif /* _NETINET_IP_FRAG_H_ */ diff --git a/sys/dist/ipf/netinet/ip_ftp_pxy.c b/sys/dist/ipf/netinet/ip_ftp_pxy.c index db57630202e..514c79bbafc 100644 --- a/sys/dist/ipf/netinet/ip_ftp_pxy.c +++ b/sys/dist/ipf/netinet/ip_ftp_pxy.c @@ -1,7 +1,7 @@ -/* $NetBSD: ip_ftp_pxy.c,v 1.9 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_ftp_pxy.c,v 1.10 2006/04/04 16:17:19 martti Exp $ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: ip_ftp_pxy.c,v 1.9 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ip_ftp_pxy.c,v 1.10 2006/04/04 16:17:19 martti Exp $"); /* * Copyright (C) 1997-2003 by Darren Reed @@ -11,7 +11,7 @@ __KERNEL_RCSID(1, "$NetBSD: ip_ftp_pxy.c,v 1.9 2005/12/11 12:24:21 christos Exp * Simple FTP transparent proxy for in-kernel use. For use with the NAT * code. * - * Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp + * Id: ip_ftp_pxy.c,v 2.88.2.19 2006/04/01 10:14:53 darrenr Exp */ #define IPF_FTP_PROXY @@ -371,7 +371,7 @@ int dlen; fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; ip->ip_dst = nat->nat_inip; } - (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT); + (void) fr_addstate(&fi, NULL, SI_W_DPORT); if (fi.fin_state != NULL) fr_statederef(&fi, (ipstate_t **)&fi.fin_state); } @@ -476,10 +476,10 @@ int dlen; { u_int a1, a2, a3, a4, data_ip; char newbuf[IPF_FTPBUFSZ]; - char *s; const char *brackets[2]; u_short a5, a6; ftpside_t *f; + char *s; if (ippr_ftp_forcepasv != 0 && ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) { @@ -733,7 +733,7 @@ u_int data_ip; fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; ip->ip_dst = nat->nat_inip; } - (void) fr_addstate(&fi, &nat2->nat_state, sflags); + (void) fr_addstate(&fi, NULL, sflags); if (fi.fin_state != NULL) fr_statederef(&fi, (ipstate_t **)&fi.fin_state); } @@ -1032,13 +1032,14 @@ int rv; if (ippr_ftp_debug > 4) printf("ippr_ftp_process: mlen %d\n", mlen); - if (mlen <= 0) { - if ((tcp->th_flags & TH_OPENING) == TH_OPENING) { - f->ftps_seq[0] = thseq + 1; - t->ftps_seq[0] = thack; - } + if ((mlen == 0) && ((tcp->th_flags & TH_OPENING) == TH_OPENING)) { + f->ftps_seq[0] = thseq + 1; + t->ftps_seq[0] = thack; + return 0; + } else if (mlen < 0) { return 0; } + aps = nat->nat_aps; sel = aps->aps_sel[1 - rv]; @@ -1428,7 +1429,7 @@ int dlen; ap += *s++ - '0'; } - if (!s) + if (!*s) return 0; if (*s == '|') diff --git a/sys/dist/ipf/netinet/ip_h323_pxy.c b/sys/dist/ipf/netinet/ip_h323_pxy.c index a92caa817e6..33af6446924 100644 --- a/sys/dist/ipf/netinet/ip_h323_pxy.c +++ b/sys/dist/ipf/netinet/ip_h323_pxy.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_h323_pxy.c,v 1.3 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_h323_pxy.c,v 1.4 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright 2001, QNX Software Systems Ltd. All Rights Reserved @@ -34,7 +34,7 @@ #include "opt_ipfilter.h" #endif -__KERNEL_RCSID(1, "$NetBSD: ip_h323_pxy.c,v 1.3 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ip_h323_pxy.c,v 1.4 2006/04/04 16:17:19 martti Exp $"); #define IPF_H323_PROXY @@ -254,7 +254,7 @@ nat_t *nat; tcp = (tcphdr_t *)fin->fin_dp; ipaddr = nat->nat_inip.s_addr; data = (caddr_t)tcp + (TCP_OFF(tcp) << 2); - datlen = ip->ip_len - fin->fin_hlen - (TCP_OFF(tcp) << 2); + datlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); if (find_port(ipaddr, data, datlen, &off, &port) == 0) { fr_info_t fi; nat_t *nat2; diff --git a/sys/dist/ipf/netinet/ip_htable.c b/sys/dist/ipf/netinet/ip_htable.c index 01fd84f67e6..285a4a5f98c 100644 --- a/sys/dist/ipf/netinet/ip_htable.c +++ b/sys/dist/ipf/netinet/ip_htable.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_htable.c,v 1.3 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_htable.c,v 1.4 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -53,7 +53,7 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_htable.c,v 2.34.2.2 2004/10/17 15:49:15 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_htable.c,v 2.34.2.4 2005/11/13 15:38:37 darrenr Exp"; #endif #ifdef IPFILTER_LOOKUP @@ -104,8 +104,10 @@ iplookupop_t *op; int err, i, unit; KMALLOC(iph, iphtable_t *); - if (iph == NULL) + if (iph == NULL) { + ipht_nomem[op->iplo_unit]++; return ENOMEM; + } err = COPYIN(op->iplo_struct, iph, sizeof(*iph)); if (err != 0) { @@ -139,12 +141,9 @@ iplookupop_t *op; sizeof(oiph->iph_name)) == 0) break; } while (oiph != NULL); + (void)strncpy(iph->iph_name, name, sizeof(iph->iph_name)); - err = COPYOUT(iph, op->iplo_struct, sizeof(*iph)); - if (err != 0) { - KFREE(iph); - return EFAULT; - } + (void)strncpy(op->iplo_name, name, sizeof(op->iplo_name)); iph->iph_type |= IPHASH_ANON; } diff --git a/sys/dist/ipf/netinet/ip_ipsec_pxy.c b/sys/dist/ipf/netinet/ip_ipsec_pxy.c index 314b163fd46..310938b2b6b 100644 --- a/sys/dist/ipf/netinet/ip_ipsec_pxy.c +++ b/sys/dist/ipf/netinet/ip_ipsec_pxy.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_ipsec_pxy.c,v 1.4 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_ipsec_pxy.c,v 1.5 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 2001-2003 by Darren Reed @@ -8,11 +8,11 @@ * Simple ISAKMP transparent proxy for in-kernel use. For use with the NAT * code. * - * Id: ip_ipsec_pxy.c,v 2.20.2.6 2005/03/28 10:47:53 darrenr Exp + * Id: ip_ipsec_pxy.c,v 2.20.2.7 2005/08/20 13:48:22 darrenr Exp * */ -__KERNEL_RCSID(1, "$NetBSD: ip_ipsec_pxy.c,v 1.4 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ip_ipsec_pxy.c,v 1.5 2006/04/04 16:17:19 martti Exp $"); #define IPF_IPSEC_PROXY @@ -99,8 +99,8 @@ nat_t *nat; mb_t *m; ip_t *ip; + off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff; bzero(ipsec_buffer, sizeof(ipsec_buffer)); - off = fin->fin_hlen + sizeof(udphdr_t); ip = fin->fin_ip; m = fin->fin_m; @@ -290,8 +290,8 @@ nat_t *nat; if ((fin->fin_dlen < sizeof(cookies)) || (fin->fin_flx & FI_FRAG)) return -1; + off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff; ipsec = aps->aps_data; - off = fin->fin_hlen + sizeof(udphdr_t); m = fin->fin_m; COPYDATA(m, off, sizeof(cookies), (char *)cookies); diff --git a/sys/dist/ipf/netinet/ip_irc_pxy.c b/sys/dist/ipf/netinet/ip_irc_pxy.c index 3690a97b94f..b9234c1dab0 100644 --- a/sys/dist/ipf/netinet/ip_irc_pxy.c +++ b/sys/dist/ipf/netinet/ip_irc_pxy.c @@ -1,11 +1,11 @@ -/* $NetBSD: ip_irc_pxy.c,v 1.6 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_irc_pxy.c,v 1.7 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 2000-2003 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp + * Id: ip_irc_pxy.c,v 2.39.2.5 2005/12/04 23:39:27 darrenr Exp */ #define IPF_IRC_PROXY diff --git a/sys/dist/ipf/netinet/ip_log.c b/sys/dist/ipf/netinet/ip_log.c index a574401bae3..55e333b1ff8 100644 --- a/sys/dist/ipf/netinet/ip_log.c +++ b/sys/dist/ipf/netinet/ip_log.c @@ -1,15 +1,15 @@ -/* $NetBSD: ip_log.c,v 1.4 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_log.c,v 1.5 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1997-2003 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ip_log.c,v 2.75.2.6 2004/10/16 07:59:27 darrenr Exp + * Id: ip_log.c,v 2.75.2.11 2006/03/26 13:50:47 darrenr Exp */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_log.c,v 1.4 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_log.c,v 1.5 2006/04/04 16:17:19 martti Exp $"); #include <sys/param.h> #if defined(KERNEL) || defined(_KERNEL) @@ -71,6 +71,10 @@ struct file; # include <sys/dir.h> # endif # include <sys/mbuf.h> +# include <sys/select.h> +# if __FreeBSD_version >= 500000 +# include <sys/selinfo.h> +# endif #else # if !defined(__hpux) && defined(_KERNEL) # include <sys/filio.h> @@ -151,6 +155,7 @@ wait_queue_head_t iplh_linux[IPL_LOGSIZE]; # endif # if SOLARIS extern kcondvar_t iplwait; +extern struct pollhead iplpollhead[IPL_LOGSIZE]; # endif iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE]; @@ -420,9 +425,7 @@ int *types, cnt; iplog_t *ipl; size_t len; int i; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif + SPL_INT(s); /* * Check to see if this log record has a CRC which matches the last @@ -511,9 +514,11 @@ int *types, cnt; # if SOLARIS && defined(_KERNEL) cv_signal(&iplwait); MUTEX_EXIT(&ipl_mutex); + pollwakeup(&iplpollhead[dev], POLLRDNORM); # else MUTEX_EXIT(&ipl_mutex); - WAKEUP(iplh,dev); + WAKEUP(iplh, dev); + POLLWAKEUP(dev); # endif SPL_X(s); # ifdef IPL_SELECT @@ -542,9 +547,7 @@ struct uio *uio; size_t dlen, copied; int error = 0; iplog_t *ipl; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif + SPL_INT(s); /* * Sanity checks. Make sure the minor # is valid and we're copying @@ -656,9 +659,7 @@ minor_t unit; { iplog_t *ipl; int used; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif + SPL_INT(s); SPL_NET(s); MUTEX_ENTER(&ipl_mutex); @@ -675,4 +676,19 @@ minor_t unit; SPL_X(s); return used; } + + +/* ------------------------------------------------------------------------ */ +/* Function: ipflog_canread */ +/* Returns: int - 0 == no data to read, 1 = data present */ +/* Parameters: unit(I) - device we are reading from */ +/* */ +/* Returns an indication of whether or not there is data present in the */ +/* current buffer for the selected ipf device. */ +/* ------------------------------------------------------------------------ */ +int ipflog_canread(unit) +int unit; +{ + return iplt[unit] != NULL; +} #endif /* IPFILTER_LOG */ diff --git a/sys/dist/ipf/netinet/ip_lookup.c b/sys/dist/ipf/netinet/ip_lookup.c index f666f4b59a1..06d8cacf3c2 100644 --- a/sys/dist/ipf/netinet/ip_lookup.c +++ b/sys/dist/ipf/netinet/ip_lookup.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_lookup.c,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_lookup.c,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 2002-2003 by Darren Reed. @@ -35,7 +35,7 @@ struct file; # undef _KERNEL #endif #include <sys/socket.h> -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) +#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) # ifdef __osf__ # include <net/radix.h> # endif @@ -63,7 +63,7 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.5 2004/07/06 11:16:25 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.8 2005/11/13 15:35:45 darrenr Exp"; #endif #ifdef IPFILTER_LOOKUP @@ -137,9 +137,7 @@ ioctlcmd_t cmd; int mode; { int err; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif + SPL_INT(s); mode = mode; /* LINT */ @@ -370,6 +368,15 @@ caddr_t data; err = EINVAL; break; } + + /* + * For anonymous pools, copy back the operation struct because in the + * case of success it will contain the new table's name. + */ + if ((err == 0) && ((op.iplo_arg & IPOOL_ANON) != 0)) { + BCOPYOUT(&op, data, sizeof(op)); + } + return err; } diff --git a/sys/dist/ipf/netinet/ip_lookup.h b/sys/dist/ipf/netinet/ip_lookup.h index 9d32c4b48c2..899759a53bc 100644 --- a/sys/dist/ipf/netinet/ip_lookup.h +++ b/sys/dist/ipf/netinet/ip_lookup.h @@ -1,10 +1,10 @@ -/* $NetBSD: ip_lookup.h,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_lookup.h,v 1.3 2006/04/04 16:17:19 martti Exp $ */ #ifndef __IP_LOOKUP_H__ #define __IP_LOOKUP_H__ -#if defined(__STDC__) || defined(__GNUC__) +#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) # define SIOCLOOKUPADDTABLE _IOWR('r', 60, struct iplookupop) # define SIOCLOOKUPDELTABLE _IOWR('r', 61, struct iplookupop) # define SIOCLOOKUPSTAT _IOWR('r', 64, struct iplookupop) diff --git a/sys/dist/ipf/netinet/ip_nat.c b/sys/dist/ipf/netinet/ip_nat.c index 063deb5e09c..c40105850b8 100644 --- a/sys/dist/ipf/netinet/ip_nat.c +++ b/sys/dist/ipf/netinet/ip_nat.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_nat.c,v 1.8 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_nat.c,v 1.9 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1995-2003 by Darren Reed. @@ -37,7 +37,9 @@ struct file; #else # include <sys/ioctl.h> #endif -#include <sys/fcntl.h> +#if !defined(AIX) +# include <sys/fcntl.h> +#endif #if !defined(linux) # include <sys/protosw.h> #endif @@ -107,7 +109,7 @@ extern struct ifnet vpnif; #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.195.2.38 2005/03/28 11:09:54 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.56 2006/04/01 10:15:34 darrenr Exp"; #endif @@ -186,15 +188,15 @@ static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr, struct in_addr, struct in_addr, u_32_t)); static void nat_hostmapdel __P((struct hostmap *)); -static INLINE int nat_icmpquerytype4 __P((int)); +static int nat_icmpquerytype4 __P((int)); static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int)); static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int)); -static INLINE int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, +static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, tcphdr_t *, nat_t **, int)); -static void nat_resolverule __P((ipnat_t *)); +static int nat_resolverule __P((ipnat_t *)); static nat_t *fr_natclone __P((fr_info_t *, nat_t *)); static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *)); -static INLINE int nat_wildok __P((nat_t *, int, int, int, int)); +static int nat_wildok __P((nat_t *, int, int, int, int)); /* ------------------------------------------------------------------------ */ @@ -799,10 +801,14 @@ int mode; error = appr_ioctl(data, cmd, mode); break; case SIOCSTLCK : - fr_lock(data, &fr_nat_lock); + if (!(mode & FWRITE)) { + error = EPERM; + } else { + fr_lock(data, &fr_nat_lock); + } break; case SIOCSTPUT : - if (fr_nat_lock) { + if ((mode & FWRITE) != 0) { error = fr_natputent(data, getlock); } else { error = EACCES; @@ -861,11 +867,8 @@ int getlock; { int error = 0, i, j; - nat_resolverule(n); - if (n->in_plabel[0] != '\0') { - if (n->in_apr == NULL) - return ENOENT; - } + if (nat_resolverule(n) != 0) + return ENOENT; if ((n->in_age[0] == 0) && (n->in_age[1] != 0)) return EINVAL; @@ -990,7 +993,7 @@ int getlock; /* from information passed to the kernel, then add it to the appropriate */ /* NAT rule table(s). */ /* ------------------------------------------------------------------------ */ -static void nat_resolverule(n) +static int nat_resolverule(n) ipnat_t *n; { n->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; @@ -1001,12 +1004,15 @@ ipnat_t *n; (void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ); n->in_ifps[1] = n->in_ifps[0]; } else { - n->in_ifps[1] = fr_resolvenic(n->in_ifnames[0], 4); + n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4); } if (n->in_plabel[0] != '\0') { n->in_apr = appr_lookup(n->in_p, n->in_plabel); + if (n->in_apr == NULL) + return -1; } + return 0; } @@ -1334,29 +1340,50 @@ int getlock; ATOMIC_INC(nat_stats.ns_rules); - nat_resolverule(in); + if (nat_resolverule(in) != 0) { + error = ESRCH; + goto junkput; + } } /* * Check that the NAT entry doesn't already exist in the kernel. + * + * For NAT_OUTBOUND, we're lookup for a duplicate MAP entry. To do + * this, we check to see if the inbound combination of addresses and + * ports is already known. Similar logic is applied for NAT_INBOUND. + * */ bzero((char *)&fin, sizeof(fin)); fin.fin_p = nat->nat_p; + fin.fin_ifp = nat->nat_ifps[0]; if (nat->nat_dir == NAT_OUTBOUND) { fin.fin_data[0] = ntohs(nat->nat_oport); fin.fin_data[1] = ntohs(nat->nat_outport); - fin.fin_ifp = nat->nat_ifps[1]; - if (nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip, - nat->nat_inip) != NULL) { + if (getlock) { + READ_ENTER(&ipf_nat); + } + n = nat_inlookup(&fin, nat->nat_flags, fin.fin_p, + nat->nat_oip, nat->nat_inip); + if (getlock) { + RWLOCK_EXIT(&ipf_nat); + } + if (n != NULL) { error = EEXIST; goto junkput; } } else if (nat->nat_dir == NAT_INBOUND) { fin.fin_data[0] = ntohs(nat->nat_outport); fin.fin_data[1] = ntohs(nat->nat_oport); - fin.fin_ifp = nat->nat_ifps[0]; - if (nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip, - nat->nat_oip) != NULL) { + if (getlock) { + READ_ENTER(&ipf_nat); + } + n = nat_outlookup(&fin, nat->nat_flags, fin.fin_p, + nat->nat_outip, nat->nat_oip); + if (getlock) { + RWLOCK_EXIT(&ipf_nat); + } + if (n != NULL) { error = EEXIST; goto junkput; } @@ -1417,10 +1444,18 @@ int getlock; fr->fr_ref = 1; (void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE); bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr)); + + fr->fr_ref = 1; + fr->fr_dsize = 0; + fr->fr_data = NULL; + fr->fr_type = FR_T_NONE; + MUTEX_NUKE(&fr->fr_lock); MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock"); } else { - READ_ENTER(&ipf_nat); + if (getlock) { + READ_ENTER(&ipf_nat); + } for (n = nat_instances; n; n = n->nat_next) if (n->nat_fr == fr) break; @@ -1430,7 +1465,9 @@ int getlock; fr->fr_ref++; MUTEX_EXIT(&fr->fr_lock); } - RWLOCK_EXIT(&ipf_nat); + if (getlock) { + RWLOCK_EXIT(&ipf_nat); + } if (!n) { error = ESRCH; @@ -1552,6 +1589,9 @@ int logtype; MUTEX_EXIT(&ipf_nat_new); return; } + /* + * At this point, nat_ref can be either 0 or -1 + */ #ifdef IPFILTER_SYNC if (nat->nat_sync) @@ -1981,8 +2021,8 @@ natinfo_t *ni; * packet might match a different one to the previous connection but * we want the same destination to be used. */ - if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == - (IPN_ROUNDR|IPN_STICKY)) { + if (((np->in_flags & (IPN_ROUNDR|IPN_SPLIT)) != 0) && + ((np->in_flags & IPN_STICKY) != 0)) { hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in, (u_32_t)dport); if (hm != NULL) { @@ -2003,7 +2043,7 @@ natinfo_t *ni; in.s_addr = np->in_nip; if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == IPN_STICKY) { - hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, + hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in, (u_32_t)dport); if (hm != NULL) { in.s_addr = hm->hm_mapip.s_addr; @@ -2076,6 +2116,9 @@ natinfo_t *ni; nat->nat_inip.s_addr = htonl(in.s_addr); nat->nat_outip = fin->fin_dst; nat->nat_oip = fin->fin_src; + if ((nat->nat_hm == NULL) && ((np->in_flags & IPN_STICKY) != 0)) + nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, in, + (u_32_t)dport); ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport); ni->nai_sum2 = LONG_SUM(in.s_addr) + ntohs(nport); @@ -2127,6 +2170,9 @@ natinfo_t *ni; /* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */ /* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */ /* and (3) building that structure and putting it into the NAT table(s). */ +/* */ +/* NOTE: natsave should NOT be used top point back to an ipstate_t struct */ +/* as it can result in memory being corrupted. */ /* ------------------------------------------------------------------------ */ nat_t *nat_new(fin, np, natsave, flags, direction) fr_info_t *fin; @@ -2220,6 +2266,7 @@ int direction; natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p, fin->fin_src, fin->fin_dst); if (natl != NULL) { + KFREE(nat); nat = natl; goto done; } @@ -2237,6 +2284,7 @@ int direction; natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p, fin->fin_src, fin->fin_dst); if (natl != NULL) { + KFREE(nat); nat = natl; goto done; } @@ -2337,7 +2385,7 @@ done: /* for both IPv4 and IPv6. */ /* ------------------------------------------------------------------------ */ /*ARGSUSED*/ -static INLINE int nat_finalise(fin, nat, ni, tcp, natsave, direction) +static int nat_finalise(fin, nat, ni, tcp, natsave, direction) fr_info_t *fin; nat_t *nat; natinfo_t *ni; @@ -2350,7 +2398,12 @@ int direction; np = ni->nai_np; - COPYIFNAME(fin->fin_ifp, nat->nat_ifnames[0]); + if (np->in_ifps[0] != NULL) { + COPYIFNAME(np->in_ifps[0], nat->nat_ifnames[0]); + } + if (np->in_ifps[1] != NULL) { + COPYIFNAME(np->in_ifps[1], nat->nat_ifnames[1]); + } #ifdef IPFILTER_SYNC if ((nat->nat_flags & SI_CLONE) == 0) nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat); @@ -2358,12 +2411,11 @@ int direction; nat->nat_me = natsave; nat->nat_dir = direction; - nat->nat_ifps[0] = fin->fin_ifp; + nat->nat_ifps[0] = np->in_ifps[0]; + nat->nat_ifps[1] = np->in_ifps[1]; nat->nat_ptr = np; nat->nat_p = fin->fin_p; nat->nat_mssclamp = np->in_mssclamp; - fr = fin->fin_fr; - nat->nat_fr = fr; if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0)) if (appr_new(fin, nat) == -1) @@ -2373,6 +2425,8 @@ int direction; if (nat_logging) nat_log(nat, (u_int)np->in_redir); np->in_use++; + fr = fin->fin_fr; + nat->nat_fr = fr; if (fr != NULL) { MUTEX_ENTER(&fr->fr_lock); fr->fr_ref++; @@ -2445,7 +2499,7 @@ int rev; nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0'; nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4); - if (nat->nat_ifnames[1][0] !='\0') { + if (nat->nat_ifnames[1][0] != '\0') { nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4); } else { @@ -2514,8 +2568,7 @@ int dir; * Only a basic IP header (no options) should be with an ICMP error * header. Also, if it's not an error type, then return. */ - if ((fin->fin_hlen != sizeof(ip_t)) || - !fr_icmp4errortype(type)) + if ((fin->fin_hlen != sizeof(ip_t)) || !(fin->fin_flx & FI_ICMPERR)) return NULL; /* @@ -2794,8 +2847,9 @@ int dir; * * Since the port fields are part of the TCP/UDP checksum * of the offending IP packet, you need to adjust that checksum - * as well... but, if you change, you must change the icmp - * checksum *again*, to reflect that change. + * as well... except that the change in the port numbers should + * be offset by the checksum change, so we only need to change + * the ICMP checksum if we only change the ports. * * To further complicate: the TCP checksum is not in the first * 8 bytes of the offending ip packet, so it most likely is not @@ -2830,21 +2884,14 @@ int dir; * The UDP checksum is optional, only adjust it if * it has been set. */ - if ((oip->ip_p == IPPROTO_UDP) && - (dlen >= 8) && (*csump != 0)) { + if (oip->ip_p == IPPROTO_UDP) { sumd = sum1 - sum2; - sumd2 += sumd; - - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - /* - * Fix ICMP checksum to compenstate - * UDP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; + if ((dlen >= 8) && (*csump != 0)) { + fix_datacksum(csump, sumd); + } else { + sumd2 += sumd; + } } /* @@ -2853,20 +2900,10 @@ int dir; * the other direction compared to the ICMP message. */ if (oip->ip_p == IPPROTO_TCP) { - if (dlen >= 18) { - sumd = sum1 - sum2; - sumd2 += sumd; + sumd = sum1 - sum2; - sum1 = ntohs(*csump); + if (dlen >= 18) { fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate - * TCP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; } else { sumd = sum2 - sum1 + 1; sumd2 += sumd; @@ -2886,21 +2923,14 @@ int dir; * The UDP checksum is optional, only adjust * it if it has been set. */ - if ((oip->ip_p == IPPROTO_UDP) && - (dlen >= 8) && (*csump != 0)) { + if (oip->ip_p == IPPROTO_UDP) { sumd = sum1 - sum2; - sumd2 += sumd; - - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - /* - * Fix ICMP checksum to compensate - * UDP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; + if ((dlen >= 8) && (*csump != 0)) { + fix_datacksum(csump, sumd); + } else { + sumd2 += sumd; + } } /* @@ -2909,20 +2939,10 @@ int dir; * the other direction compared to the ICMP message. */ if (oip->ip_p == IPPROTO_TCP) { - if (dlen >= 18) { - sumd = sum1 - sum2; - sumd2 += sumd; + sumd = sum1 - sum2; - sum1 = ntohs(*csump); + if (dlen >= 18) { fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate - * TCP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; } else { if (nat->nat_dir == NAT_INBOUND) sumd = sum2 - sum1; @@ -3015,10 +3035,7 @@ struct in_addr src , mapdst; void *ifp; u_int hv; - if (fin != NULL) - ifp = fin->fin_ifp; - else - ifp = NULL; + ifp = fin->fin_ifp; sport = 0; dport = 0; gre = NULL; @@ -3050,17 +3067,13 @@ struct in_addr src , mapdst; hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz); nat = nat_table[1][hv]; for (; nat; nat = nat->nat_hnext[1]) { - nflags = nat->nat_flags; + if (nat->nat_ifps[0] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[0])) + continue; + } else if (ifp != NULL) + nat->nat_ifps[0] = ifp; - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[0]) - continue; - } else { - if (ifp != nat->nat_ifps[1]) - continue; - } - } + nflags = nat->nat_flags; if (nat->nat_oip.s_addr == src.s_addr && nat->nat_outip.s_addr == dst && @@ -3125,15 +3138,11 @@ find_in_wild_ports: nat = nat_table[1][hv]; for (; nat; nat = nat->nat_hnext[1]) { - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[0]) - continue; - } else { - if (ifp != nat->nat_ifps[1]) - continue; - } - } + if (nat->nat_ifps[0] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[0])) + continue; + } else if (ifp != NULL) + nat->nat_ifps[0] = ifp; if (nat->nat_p != fin->fin_p) continue; @@ -3300,17 +3309,13 @@ struct in_addr src , dst; hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz); nat = nat_table[0][hv]; for (; nat; nat = nat->nat_hnext[0]) { - nflags = nat->nat_flags; + if (nat->nat_ifps[1] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[1])) + continue; + } else if (ifp != NULL) + nat->nat_ifps[1] = ifp; - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[1]) - continue; - } else { - if (ifp != nat->nat_ifps[0]) - continue; - } - } + nflags = nat->nat_flags; if (nat->nat_inip.s_addr == srcip && nat->nat_oip.s_addr == dst.s_addr && @@ -3365,15 +3370,11 @@ find_out_wild_ports: nat = nat_table[0][hv]; for (; nat; nat = nat->nat_hnext[0]) { - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[1]) - continue; - } else { - if (ifp != nat->nat_ifps[0]) - continue; - } - } + if (nat->nat_ifps[1] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[1])) + continue; + } else if (ifp != NULL) + nat->nat_ifps[1] = ifp; if (nat->nat_p != fin->fin_p) continue; @@ -3422,6 +3423,16 @@ find_out_wild_ports: /* entry for. */ /* */ /* Lookup the NAT tables to search for a matching redirect */ +/* The contents of natlookup_t should imitate those found in a packet that */ +/* would be translated - ie a packet coming in for RDR or going out for MAP.*/ +/* We can do the lookup in one of two ways, imitating an inbound or */ +/* outbound packet. By default we assume outbound, unless IPN_IN is set. */ +/* For IN, the fields are set as follows: */ +/* nl_real* = source information */ +/* nl_out* = destination information (translated) */ +/* For an out packet, the fields are set like this: */ +/* nl_in* = source information (untranslated) */ +/* nl_out* = destination information (translated) */ /* ------------------------------------------------------------------------ */ nat_t *nat_lookupredir(np) natlookup_t *np; @@ -3683,7 +3694,7 @@ maskloop: hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz); for (np = nat_rules[hv]; np; np = np->in_mnext) { - if ((np->in_ifps[0] && (np->in_ifps[0] != ifp))) + if ((np->in_ifps[1] && (np->in_ifps[1] != ifp))) continue; if (np->in_v != fin->fin_v) continue; @@ -3805,8 +3816,15 @@ u_32_t nflags; CALC_SUMD(s1, s2, sumd); fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd); } -#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || defined(linux) +#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ + defined(linux) || defined(BRIDGE_IPF) else { + /* + * Strictly speaking, this isn't necessary on BSD + * kernels because they do checksum calculation after + * this code has run BUT if ipfilter is being used + * to do NAT as a bridge, that code doesn't exist. + */ if (nat->nat_dir == NAT_OUTBOUND) fix_outcksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd); @@ -4315,10 +4333,8 @@ void fr_natexpire() { ipftq_t *ifq, *ifqnext; ipftqent_t *tqe, *tqn; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif int i; + SPL_INT(s); SPL_NET(s); WRITE_ENTER(&ipf_nat); @@ -4372,9 +4388,7 @@ void *ifp; ipnat_t *n; nat_t *nat; void *ifp2; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif + SPL_INT(s); if (fr_running <= 0) return; @@ -4456,7 +4470,7 @@ void *ifp; /* Tests to see if the ICMP type number passed is a query/response type or */ /* not. */ /* ------------------------------------------------------------------------ */ -static INLINE int nat_icmpquerytype4(icmptype) +static int nat_icmpquerytype4(icmptype) int icmptype; { @@ -4609,9 +4623,20 @@ nat_t *nat; MUTEX_NUKE(&clone->nat_lock); + clone->nat_aps = NULL; + /* + * Initialize all these so that nat_delete() doesn't cause a crash. + */ + clone->nat_tqe.tqe_pnext = NULL; + clone->nat_tqe.tqe_next = NULL; + clone->nat_tqe.tqe_ifq = NULL; + clone->nat_tqe.tqe_parent = clone; + clone->nat_flags &= ~SI_CLONE; clone->nat_flags |= SI_CLONED; + if (clone->nat_hm) + clone->nat_hm->hm_ref++; if (nat_insert(clone, fin->fin_rev) == -1) { KFREE(clone); @@ -4630,14 +4655,13 @@ nat_t *nat; MUTEX_EXIT(&fr->fr_lock); } - /* * Because the clone is created outside the normal loop of things and * TCP has special needs in terms of state, initialise the timeout * state of the new NAT from here. */ if (clone->nat_p == IPPROTO_TCP) { - (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, \ + (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, clone->nat_flags); } #ifdef IPFILTER_SYNC @@ -4662,7 +4686,7 @@ nat_t *nat; /* Use NAT entry and packet direction to determine which combination of */ /* wildcard flags should be used. */ /* ------------------------------------------------------------------------ */ -static INLINE int nat_wildok(nat, sport, dport, flags, dir) +static int nat_wildok(nat, sport, dport, flags, dir) nat_t *nat; int sport; int dport; diff --git a/sys/dist/ipf/netinet/ip_nat.h b/sys/dist/ipf/netinet/ip_nat.h index c6dc0645fa8..6a5f6ab4f22 100644 --- a/sys/dist/ipf/netinet/ip_nat.h +++ b/sys/dist/ipf/netinet/ip_nat.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_nat.h,v 1.6 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_nat.h,v 1.7 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1995-2001, 2003 by Darren Reed. @@ -6,7 +6,7 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_nat.h 1.5 2/4/96 - * Id: ip_nat.h,v 2.90.2.9 2005/03/28 11:09:55 darrenr Exp + * Id: ip_nat.h,v 2.90.2.11 2005/06/18 02:41:32 darrenr Exp */ #ifndef __IP_NAT_H__ @@ -16,18 +16,16 @@ #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) #endif -#if defined(__STDC__) || defined(__GNUC__) +#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) #define SIOCADNAT _IOW('r', 60, struct ipfobj) #define SIOCRMNAT _IOW('r', 61, struct ipfobj) #define SIOCGNATS _IOWR('r', 62, struct ipfobj) #define SIOCGNATL _IOWR('r', 63, struct ipfobj) -#define SIOCPROXY _IOWR('r', 64, struct ap_control) #else #define SIOCADNAT _IOW(r, 60, struct ipfobj) #define SIOCRMNAT _IOW(r, 61, struct ipfobj) #define SIOCGNATS _IOWR(r, 62, struct ipfobj) #define SIOCGNATL _IOWR(r, 63, struct ipfobj) -#define SIOCPROXY _IOWR(r, 64, struct ap_control) #endif #undef LARGE_NAT /* define this if you're setting up a system to NAT @@ -297,6 +295,7 @@ typedef struct natget { } natget_t; +#undef tr_flags typedef struct nattrpnt { struct in_addr tr_dstip; /* real destination IP# */ struct in_addr tr_srcip; /* real source IP# */ diff --git a/sys/dist/ipf/netinet/ip_netbios_pxy.c b/sys/dist/ipf/netinet/ip_netbios_pxy.c index 211c5df3efc..36eac7c7135 100644 --- a/sys/dist/ipf/netinet/ip_netbios_pxy.c +++ b/sys/dist/ipf/netinet/ip_netbios_pxy.c @@ -1,9 +1,9 @@ -/* $NetBSD: ip_netbios_pxy.c,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_netbios_pxy.c,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Simple netbios-dgm transparent proxy for in-kernel use. * For use with the NAT code. - * Id: ip_netbios_pxy.c,v 2.8 2003/12/01 02:52:16 darrenr Exp + * Id: ip_netbios_pxy.c,v 2.8.2.1 2005/08/20 13:48:23 darrenr Exp */ /*- @@ -31,10 +31,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Id: ip_netbios_pxy.c,v 2.8 2003/12/01 02:52:16 darrenr Exp + * Id: ip_netbios_pxy.c,v 2.8.2.1 2005/08/20 13:48:23 darrenr Exp */ -__KERNEL_RCSID(1, "$NetBSD: ip_netbios_pxy.c,v 1.2 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ip_netbios_pxy.c,v 1.3 2006/04/04 16:17:19 martti Exp $"); #define IPF_NETBIOS_PROXY @@ -84,19 +84,17 @@ nat_t *nat; aps = aps; /* LINT */ nat = nat; /* LINT */ - ip = fin->fin_ip; - m = *(mb_t **)fin->fin_mp; - off = fin->fin_hlen + sizeof(udphdr_t); - dlen = M_LEN(m); - dlen -= off; - + m = fin->fin_m; + dlen = fin->fin_dlen - sizeof(*udp); /* * no net bios datagram could possibly be shorter than this */ if (dlen < 11) return 0; + ip = fin->fin_ip; udp = (udphdr_t *)fin->fin_dp; + off = (char *)udp - (char *)ip + sizeof(*udp) + fin->fin_ipoff; /* * move past the diff --git a/sys/dist/ipf/netinet/ip_pool.c b/sys/dist/ipf/netinet/ip_pool.c index 1d3521e806d..0133af34016 100644 --- a/sys/dist/ipf/netinet/ip_pool.c +++ b/sys/dist/ipf/netinet/ip_pool.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_pool.c,v 1.4 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_pool.c,v 1.5 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -55,7 +55,8 @@ struct file; # include <sys/malloc.h> #endif -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) +#if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \ + defined(__hpux) || defined(__sgi)) # ifdef __osf__ # include <net/radix.h> # endif @@ -79,7 +80,7 @@ static int rn_freenode __P((struct radix_node *, void *)); #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_pool.c,v 2.55.2.12 2005/02/01 04:04:46 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_pool.c,v 2.55.2.15 2005/11/13 15:38:37 darrenr Exp"; #endif #ifdef IPFILTER_LOOKUP @@ -356,11 +357,9 @@ ip_pool_t *ipo; addrfamily_t *addr, *mask; { struct radix_node *n; -#ifdef USE_SPL - int s; + SPL_INT(s); SPL_NET(s); -#endif RADIX_NODE_HEAD_LOCK(ipo->ipo_head); n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head); RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); @@ -550,6 +549,7 @@ iplookupop_t *op; } (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name)); + (void)strncpy(op->iplo_name, name, sizeof(op->iplo_name)); } else { (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); } diff --git a/sys/dist/ipf/netinet/ip_pool.h b/sys/dist/ipf/netinet/ip_pool.h index 66815b0f7ce..20c40ef0a3b 100644 --- a/sys/dist/ipf/netinet/ip_pool.h +++ b/sys/dist/ipf/netinet/ip_pool.h @@ -1,18 +1,18 @@ -/* $NetBSD: ip_pool.h,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_pool.h,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ip_pool.h,v 2.26.2.2 2004/03/23 12:44:34 darrenr Exp + * Id: ip_pool.h,v 2.26.2.3 2005/06/12 07:18:27 darrenr Exp */ #ifndef __IP_POOL_H__ #define __IP_POOL_H__ #if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \ - !defined(linux) && !defined(sun) + !defined(linux) && !defined(sun) && !defined(AIX) # include <net/radix.h> extern void rn_freehead __P((struct radix_node_head *)); # define FreeS(p, z) KFREES(p, z) diff --git a/sys/dist/ipf/netinet/ip_pptp_pxy.c b/sys/dist/ipf/netinet/ip_pptp_pxy.c index 84fe70408e2..887851f548e 100644 --- a/sys/dist/ipf/netinet/ip_pptp_pxy.c +++ b/sys/dist/ipf/netinet/ip_pptp_pxy.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_pptp_pxy.c,v 1.5 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_pptp_pxy.c,v 1.6 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 2002-2003 by Darren Reed @@ -6,7 +6,7 @@ * Simple PPTP transparent proxy for in-kernel use. For use with the NAT * code. * - * Id: ip_pptp_pxy.c,v 2.10.2.9 2005/03/16 18:17:34 darrenr Exp + * Id: ip_pptp_pxy.c,v 2.10.2.13 2006/03/17 10:40:05 darrenr Exp * */ #define IPF_PPTP_PROXY @@ -89,15 +89,14 @@ nat_t *nat; pptp_pxy_t *pptp; ipnat_t *ipn; ip_t *ip; - int off; ip = fin->fin_ip; - off = fin->fin_hlen + sizeof(udphdr_t); if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip, ip->ip_dst) != NULL) { if (ippr_pptp_debug > 0) - printf("ippr_pptp_new: GRE session already exists\n"); + printf("ippr_pptp_new: GRE session %s\n", + "already exists"); return -1; } @@ -105,7 +104,8 @@ nat_t *nat; KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp)); if (aps->aps_data == NULL) { if (ippr_pptp_debug > 0) - printf("ippr_pptp_new: malloc for aps_data failed\n"); + printf("ippr_pptp_new: malloc for aps_data %s\n", + "failed"); return -1; } @@ -212,10 +212,12 @@ pptp_pxy_t *pptp; RWLOCK_EXIT(&ipf_state); } else { RWLOCK_EXIT(&ipf_state); - if (nat->nat_dir == NAT_INBOUND) - fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; - else - fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; + if (nat2 != NULL) { + if (nat->nat_dir == NAT_INBOUND) + fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; + else + fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; + } fi.fin_ifp = NULL; pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, 0); diff --git a/sys/dist/ipf/netinet/ip_proxy.c b/sys/dist/ipf/netinet/ip_proxy.c index 48b8a76119a..f009b299d1e 100644 --- a/sys/dist/ipf/netinet/ip_proxy.c +++ b/sys/dist/ipf/netinet/ip_proxy.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_proxy.c,v 1.8 2005/12/28 09:29:48 christos Exp $ */ +/* $NetBSD: ip_proxy.c,v 1.9 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1997-2003 by Darren Reed. @@ -16,7 +16,9 @@ #include <sys/param.h> #include <sys/time.h> #include <sys/file.h> -#include <sys/fcntl.h> +#if !defined(AIX) +# include <sys/fcntl.h> +#endif #if !defined(_KERNEL) && !defined(__KERNEL__) # include <stdio.h> # include <string.h> @@ -35,7 +37,8 @@ struct file; #include <sys/socket.h> #if defined(_KERNEL) # if !defined(__NetBSD__) && !defined(sun) && !defined(__osf__) && \ - !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) + !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) && \ + !defined(AIX) # include <sys/ctype.h> # endif # include <sys/systm.h> @@ -94,9 +97,6 @@ struct file; # include "netinet/ip_irc_pxy.c" # include "netinet/ip_raudio_pxy.c" # include "netinet/ip_h323_pxy.c" -# ifdef IPFILTER_PRO -# include "netinet/ip_msnrpc_pxy.c" -# endif # include "netinet/ip_netbios_pxy.c" #endif #include "netinet/ip_ipsec_pxy.c" @@ -105,7 +105,7 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.62.2.12 2005/03/03 14:28:24 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.62.2.16 2006/03/29 11:19:56 darrenr Exp"; #endif #ifdef INET @@ -327,8 +327,7 @@ int mode; if (error == 0) error = appr_ctl(&ctl); - if ((ctl.apc_dsize > 0) && (ptr != NULL) && - (ctl.apc_data == ptr)) { + if (ptr != NULL) { KFREES(ptr, ctl.apc_dsize); } break; @@ -567,8 +566,8 @@ nat_t *nat; if (err != 0) { short adjlen = err & 0xffff; - s1 = LONG_SUM(ip->ip_len - adjlen); - s2 = LONG_SUM(ip->ip_len); + s1 = LONG_SUM(fin->fin_plen - adjlen); + s2 = LONG_SUM(fin->fin_plen); CALC_SUMD(s1, s2, sd); fix_outcksum(fin, &ip->ip_sum, sd); } @@ -589,19 +588,23 @@ nat_t *nat; #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) if (dosum) tcp->th_sum = fr_cksum(fin->fin_qfm, ip, - IPPROTO_TCP, tcp); + IPPROTO_TCP, tcp, + fin->fin_plen); #else tcp->th_sum = fr_cksum(fin->fin_m, ip, - IPPROTO_TCP, tcp); + IPPROTO_TCP, tcp, + fin->fin_plen); #endif } else if ((udp != NULL) && (udp->uh_sum != 0)) { #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) if (dosum) udp->uh_sum = fr_cksum(fin->fin_qfm, ip, - IPPROTO_UDP, udp); + IPPROTO_UDP, udp, + fin->fin_plen); #else udp->uh_sum = fr_cksum(fin->fin_m, ip, - IPPROTO_UDP, udp); + IPPROTO_UDP, udp, + fin->fin_plen); #endif } #endif @@ -694,9 +697,9 @@ int inc; tcp = (tcphdr_t *)fin->fin_dp; out = fin->fin_out; /* - * ip_len has already been adjusted by 'inc'. + * fin->fin_plen has already been adjusted by 'inc'. */ - nlen = ip->ip_len; + nlen = fin->fin_plen; nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2); inc2 = inc; diff --git a/sys/dist/ipf/netinet/ip_proxy.h b/sys/dist/ipf/netinet/ip_proxy.h index 86ec63b7b08..280f352b3f8 100644 --- a/sys/dist/ipf/netinet/ip_proxy.h +++ b/sys/dist/ipf/netinet/ip_proxy.h @@ -1,11 +1,11 @@ -/* $NetBSD: ip_proxy.h,v 1.3 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_proxy.h,v 1.4 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1997-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ip_proxy.h,v 2.31.2.2 2005/03/12 19:33:48 darrenr Exp + * Id: ip_proxy.h,v 2.31.2.3 2005/06/18 02:41:33 darrenr Exp */ #ifndef _NETINET_IP_PROXY_H_ @@ -15,6 +15,12 @@ #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) #endif +#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) +#define SIOCPROXY _IOWR('r', 64, struct ap_control) +#else +#define SIOCPROXY _IOWR(r, 64, struct ap_control) +#endif + #ifndef APR_LABELLEN #define APR_LABELLEN 16 #endif @@ -22,15 +28,16 @@ struct nat; struct ipnat; +struct ipstate; typedef struct ap_tcp { u_short apt_sport; /* source port */ u_short apt_dport; /* destination port */ short apt_sel[2]; /* {seq,ack}{off,min} set selector */ short apt_seqoff[2]; /* sequence # difference */ - tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */ + u_32_t apt_seqmin[2]; /* don't change seq-off until after this */ short apt_ackoff[2]; /* sequence # difference */ - tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */ + u_32_t apt_ackmin[2]; /* don't change seq-off until after this */ u_char apt_state[2]; /* connection state */ } ap_tcp_t; @@ -197,7 +204,7 @@ typedef struct raudio_s { u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have * been filled */ - tcp_seq rap_sseq; + u_32_t rap_sseq; } raudio_t; #define RA_ID_END 0 @@ -233,7 +240,7 @@ typedef struct ipsec_pxy { int ipsc_rckset; ipnat_t ipsc_rule; nat_t *ipsc_nat; - ipstate_t *ipsc_state; + struct ipstate *ipsc_state; } ipsec_pxy_t; /* @@ -253,7 +260,7 @@ typedef struct pptp_side { typedef struct pptp_pxy { ipnat_t pptp_rule; nat_t *pptp_nat; - ipstate_t *pptp_state; + struct ipstate *pptp_state; u_short pptp_call[2]; pptp_side_t pptp_side[2]; } pptp_pxy_t; diff --git a/sys/dist/ipf/netinet/ip_rcmd_pxy.c b/sys/dist/ipf/netinet/ip_rcmd_pxy.c index 30d5a48af8d..086c7f40590 100644 --- a/sys/dist/ipf/netinet/ip_rcmd_pxy.c +++ b/sys/dist/ipf/netinet/ip_rcmd_pxy.c @@ -1,14 +1,14 @@ -/* $NetBSD: ip_rcmd_pxy.c,v 1.7 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_rcmd_pxy.c,v 1.8 2006/04/04 16:17:19 martti Exp $ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: ip_rcmd_pxy.c,v 1.7 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ip_rcmd_pxy.c,v 1.8 2006/04/04 16:17:19 martti Exp $"); /* * Copyright (C) 1998-2003 by Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * - * Id: ip_rcmd_pxy.c,v 1.41.2.4 2005/02/04 10:22:55 darrenr Exp + * Id: ip_rcmd_pxy.c,v 1.41.2.6 2006/04/01 10:14:54 darrenr Exp * * Simple RCMD transparent proxy for in-kernel use. For use with the NAT * code. @@ -156,6 +156,8 @@ nat_t *nat; * other way. */ bcopy((char *)fin, (char *)&fi, sizeof(fi)); + fi.fin_state = NULL; + fi.fin_nat = NULL; fi.fin_flx |= FI_IGNORE; fi.fin_data[0] = sp; fi.fin_data[1] = 0; @@ -205,7 +207,7 @@ nat_t *nat; fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; ip->ip_dst = nat->nat_inip; } - (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT); + (void) fr_addstate(&fi, NULL, SI_W_DPORT); if (fi.fin_state != NULL) fr_statederef(&fi, (ipstate_t **)&fi.fin_state); } diff --git a/sys/dist/ipf/netinet/ip_scan.c b/sys/dist/ipf/netinet/ip_scan.c index 70797ef1e49..721fd6de269 100644 --- a/sys/dist/ipf/netinet/ip_scan.c +++ b/sys/dist/ipf/netinet/ip_scan.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_scan.c,v 1.5 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_scan.c,v 1.6 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1995-2001 by Darren Reed. @@ -34,7 +34,7 @@ struct file; # endif #endif #include <sys/socket.h> -#if !defined(__hpux) && !defined(__osf__) && !defined(linux) +#if !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(AIX) # include <sys/ioccom.h> #endif #ifdef __FreeBSD__ @@ -60,7 +60,7 @@ struct file; #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_scan.c,v 2.40.2.2 2005/01/18 10:13:16 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_scan.c,v 2.40.2.6 2006/03/26 23:06:49 darrenr Exp"; #endif #ifdef IPFILTER_SCAN /* endif at bottom of file */ @@ -86,18 +86,23 @@ int ipsc_matchstr __P((sinfo_t *, char *, int)); int ipsc_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *)); int ipsc_match __P((ipstate_t *)); +static int ipsc_inited = 0; int ipsc_init() { RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock"); + ipsc_inited = 1; return 0; } void fr_scanunload() { - RW_DESTROY(&ipsc_rwlock); + if (ipsc_inited == 1) { + RW_DESTROY(&ipsc_rwlock); + ipsc_inited = 0; + } } @@ -433,6 +438,8 @@ ipstate_t *is; } if (k == 1) isc = lm; + if (isc == NULL) + return 0; /* * No matches or partial matches, so reset the respective @@ -539,8 +546,8 @@ ipstate_t *is; j = 0xffff >> (16 - dlen); i = (0xffff & j) << off; #ifdef _KERNEL - COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_hlen + thoff, dlen, - (caddr_t)is->is_sbuf[rv] + off); + COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_plen - fin->fin_dlen + thoff, + dlen, (caddr_t)is->is_sbuf[rv] + off); #endif is->is_smsk[rv] |= i; for (j = 0, i = is->is_smsk[rv]; i & 1; i >>= 1) diff --git a/sys/dist/ipf/netinet/ip_scan.h b/sys/dist/ipf/netinet/ip_scan.h index 1b6b5fdc758..5204b140c54 100644 --- a/sys/dist/ipf/netinet/ip_scan.h +++ b/sys/dist/ipf/netinet/ip_scan.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_scan.h,v 1.2 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_scan.h,v 1.3 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -6,7 +6,7 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 - * Id: ip_scan.h,v 2.9 2003/07/25 22:05:01 darrenr Exp + * Id: ip_scan.h,v 2.9.2.1 2005/06/12 07:18:29 darrenr Exp */ #ifndef __IP_SCAN_H__ @@ -27,7 +27,7 @@ struct ip; struct ipstate; -#if defined(__STDC__) || defined(__GNUC__) +#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) # define SIOCADSCA _IOWR('r', 60, struct ipscan *) # define SIOCRMSCA _IOWR('r', 61, struct ipscan *) # define SIOCGSCST _IOWR('r', 62, struct ipscan *) diff --git a/sys/dist/ipf/netinet/ip_state.c b/sys/dist/ipf/netinet/ip_state.c index 46482f3858b..409207647c3 100644 --- a/sys/dist/ipf/netinet/ip_state.c +++ b/sys/dist/ipf/netinet/ip_state.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_state.c,v 1.8 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_state.c,v 1.9 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1995-2003 by Darren Reed. @@ -110,10 +110,10 @@ struct file; #if !defined(lint) #if defined(__NetBSD__) #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.8 2005/12/11 12:24:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.9 2006/04/04 16:17:19 martti Exp $"); #else 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.186.2.29 2005/03/28 10:47:54 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_state.c,v 2.186.2.41 2006/04/01 10:16:28 darrenr Exp"; #endif #endif @@ -512,13 +512,17 @@ int mode; * means no packets match). */ case SIOCSTLCK : - fr_lock(data, &fr_state_lock); + if (!(mode & FWRITE)) { + error = EPERM; + } else { + fr_lock(data, &fr_state_lock); + } break; /* * Add an entry to the current state table. */ case SIOCSTPUT : - if (!fr_state_lock) { + if (!fr_state_lock || !(mode &FWRITE)) { error = EACCES; break; } @@ -640,6 +644,7 @@ caddr_t data; if (fr == NULL) { READ_ENTER(&ipf_state); fr_stinsert(isn, 0); + MUTEX_EXIT(&isn->is_lock); RWLOCK_EXIT(&ipf_state); return 0; } @@ -670,6 +675,7 @@ caddr_t data; fr->fr_ref = 0; fr->fr_dsize = 0; fr->fr_data = NULL; + fr->fr_type = FR_T_NONE; fr_resolvedest(&fr->fr_tif, fr->fr_v); fr_resolvedest(&fr->fr_dif, fr->fr_v); @@ -687,6 +693,7 @@ caddr_t data; } READ_ENTER(&ipf_state); fr_stinsert(isn, 0); + MUTEX_EXIT(&isn->is_lock); RWLOCK_EXIT(&ipf_state); } else { @@ -694,6 +701,7 @@ caddr_t data; for (is = ips_list; is; is = is->is_next) if (is->is_rule == fr) { fr_stinsert(isn, 0); + MUTEX_EXIT(&isn->is_lock); break; } @@ -721,6 +729,7 @@ caddr_t data; /* to pointers and adjusts running stats for the hash table as appropriate. */ /* */ /* Locking: it is assumed that some kind of lock on ipf_state is held. */ +/* Exits with is_lock initialised and held. */ /* ------------------------------------------------------------------------ */ void fr_stinsert(is, rev) ipstate_t *is; @@ -785,7 +794,6 @@ int rev; MUTEX_EXIT(&ipf_stinsert); fr_setstatequeue(is, rev); - MUTEX_EXIT(&is->is_lock); } @@ -801,6 +809,11 @@ int rev; /* Inserts it into the state table and appends to the bottom of the active */ /* list. If the capacity of the table has reached the maximum allowed then */ /* the call will fail and a flush is scheduled for the next timeout call. */ +/* */ +/* NOTE: The use of stsave to point to nat_state will result in memory */ +/* corruption. It should only be used to point to objects that will */ +/* either outlive this (not expired) or will deref the ip_state_t */ +/* when they are deleted. */ /* ------------------------------------------------------------------------ */ ipstate_t *fr_addstate(fin, stsave, flags) fr_info_t *fin; @@ -823,24 +836,29 @@ u_int flags; if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN)) return NULL; - fr = fin->fin_fr; - if ((fr->fr_statemax == 0) && (ips_num == fr_statemax)) { - ATOMIC_INCL(ips_stats.iss_max); - fr_state_doflush = 1; - return NULL; - } - /* * If a "keep state" rule has reached the maximum number of references * to it, then schedule an automatic flush in case we can clear out - * some "dead old wood". + * some "dead old wood". Note that because the lock isn't held on + * fr it is possible that we could overflow. The cost of overflowing + * is being ignored here as the number by which it can overflow is + * a product of the number of simultaneous threads that could be + * executing in here, so a limit of 100 won't result in 200, but could + * result in 101 or 102. */ - if ((fr != NULL) && (fr->fr_statemax != 0) && - (fr->fr_statecnt >= fr->fr_statemax)) { - MUTEX_EXIT(&fr->fr_lock); - ATOMIC_INCL(ips_stats.iss_maxref); - fr_state_doflush = 1; - return NULL; + fr = fin->fin_fr; + if (fr != NULL) { + if ((ips_num == fr_statemax) && (fr->fr_statemax == 0)) { + ATOMIC_INCL(ips_stats.iss_max); + fr_state_doflush = 1; + return NULL; + } + if ((fr->fr_statemax != 0) && + (fr->fr_statecnt >= fr->fr_statemax)) { + ATOMIC_INCL(ips_stats.iss_maxref); + fr_state_doflush = 1; + return NULL; + } } pass = (fr == NULL) ? 0 : fr->fr_flags; @@ -984,9 +1002,9 @@ u_int flags; TH_SYN && (TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) { if (fr_tcpoptions(fin, tcp, - &is->is_tcp.ts_data[0])) - is->is_swinflags = TCP_WSCALE_SEEN| - TCP_WSCALE_FIRST; + &is->is_tcp.ts_data[0]) == -1) { + fin->fin_flx |= FI_BAD; + } } if ((fin->fin_out != 0) && (pass & FR_NEWISN) != 0) { @@ -1129,8 +1147,15 @@ u_int flags; * this may change. */ is->is_v = fin->fin_v; - is->is_opt = fin->fin_optmsk; - is->is_optmsk = 0xffffffff; + is->is_opt[0] = fin->fin_optmsk; + is->is_optmsk[0] = 0xffffffff; + is->is_optmsk[1] = 0xffffffff; + if (is->is_v == 6) { + is->is_opt[0] &= ~0x8; + is->is_optmsk[0] &= ~0x8; + is->is_optmsk[1] &= ~0x8; + } + is->is_me = stsave; is->is_sec = fin->fin_secmsk; is->is_secmsk = 0xffff; is->is_auth = fin->fin_auth; @@ -1145,7 +1170,6 @@ u_int flags; is->is_pass &= ~(FR_LOGFIRST|FR_LOG); READ_ENTER(&ipf_state); - is->is_me = stsave; fr_stinsert(is, fin->fin_rev); @@ -1155,13 +1179,14 @@ u_int flags; * timer on it as we'll never see an error if it fails to * connect. */ - MUTEX_ENTER(&is->is_lock); (void) fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags); MUTEX_EXIT(&is->is_lock); #ifdef IPFILTER_SCAN if ((is->is_flags & SI_CLONE) == 0) (void) ipsc_attachis(is); #endif + } else { + MUTEX_EXIT(&is->is_lock); } #ifdef IPFILTER_SYNC if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0)) @@ -1183,7 +1208,8 @@ u_int flags; /* ------------------------------------------------------------------------ */ /* Function: fr_tcpoptions */ -/* Returns: int - 1 == packet matches state entry, 0 == it does not */ +/* Returns: int - 1 == packet matches state entry, 0 == it does not, */ +/* -1 == packet has bad TCP options data */ /* Parameters: fin(I) - pointer to packet information */ /* tcp(I) - pointer to TCP packet header */ /* td(I) - pointer to TCP data held as part of the state */ @@ -1200,13 +1226,14 @@ tcpdata_t *td; char buf[64], *s, opt; mb_t *m = NULL; - off = fin->fin_hlen + sizeof(*tcp); - len = (TCP_OFF(tcp) << 2) - sizeof(*tcp); - if (fin->fin_plen < off + len) + len = (TCP_OFF(tcp) << 2); + if (fin->fin_dlen < len) return 0; + len -= sizeof(*tcp); + + off = fin->fin_plen - fin->fin_dlen + sizeof(*tcp) + fin->fin_ipoff; m = fin->fin_m; - off += fin->fin_ipoff; mlen = MSGDSIZE(m) - off; if (len > mlen) { len = mlen; @@ -1244,7 +1271,10 @@ tcpdata_t *td; else if (i < 0) i = 0; td->td_winscale = i; - } + td->td_winflags |= TCP_WSCALE_SEEN| + TCP_WSCALE_FIRST; + } else + retval = -1; break; case TCPOPT_MAXSEG : /* @@ -1256,7 +1286,14 @@ tcpdata_t *td; i <<= 8; i += (int)*(s + 3); td->td_maxseg = i; - } + } else + retval = -1; + break; + case TCPOPT_SACK_PERMITTED : + if (ol == TCPOLEN_SACK_PERMITTED) + td->td_winflags |= TCP_SACK_PERMIT; + else + retval = -1; break; } } @@ -1327,24 +1364,22 @@ ipstate_t *is; is->is_s0[source] = ntohl(tcp->th_ack); is->is_s0[!source] = ntohl(tcp->th_seq) + 1; if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2)) && - tdata->td_winscale) { - if (fr_tcpoptions(fin, tcp, fdata)) { - fdata->td_winflags = TCP_WSCALE_SEEN| - TCP_WSCALE_FIRST; - } else { - if (!fdata->td_winscale) - tdata->td_winscale = 0; + (tdata->td_winflags & TCP_WSCALE_SEEN)) { + if (fr_tcpoptions(fin, tcp, fdata) == -1) + fin->fin_flx |= FI_BAD; + if (!(fdata->td_winflags & TCP_WSCALE_SEEN)) { + fdata->td_winscale = 0; + tdata->td_winscale = 0; } } if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN)) fr_checknewisn(fin, is); } else if (flags == TH_SYN) { is->is_s0[source] = ntohl(tcp->th_seq) + 1; - if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) - if (fr_tcpoptions(fin, tcp, tdata)) { - tdata->td_winflags = TCP_WSCALE_SEEN| - TCP_WSCALE_FIRST; - } + if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) { + if (fr_tcpoptions(fin, tcp, tdata) == -1) + fin->fin_flx |= FI_BAD; + } if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN)) fr_checknewisn(fin, is); @@ -1416,6 +1451,7 @@ int flags; tcp_seq seq, ack, end; int ackskew, tcpflags; u_32_t win, maxwin; + int dsize, inseq; /* * Find difference between last checked packet and this packet. @@ -1427,9 +1463,16 @@ int flags; win = ntohs(tcp->th_win); else win = ntohs(tcp->th_win) << fdata->td_winscale; + + /* + * A window of 0 produces undesirable behaviour from this function. + */ if (win == 0) win = 1; + dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) + + ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0); + /* * if window scaling is present, the scaling is only allowed * for windows not in the first SYN packet. In that packet the @@ -1447,14 +1490,15 @@ int flags; fdata->td_maxwin = win; } else { fdata->td_winscale = 0; - fdata->td_winflags = 0; + fdata->td_winflags &= ~(TCP_WSCALE_FIRST| + TCP_WSCALE_SEEN); tdata->td_winscale = 0; - tdata->td_winflags = 0; + tdata->td_winflags &= ~(TCP_WSCALE_FIRST| + TCP_WSCALE_SEEN); } } - end = seq + fin->fin_dlen - (TCP_OFF(tcp) << 2) + - ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0); + end = seq + dsize; if ((fdata->td_end == 0) && (!(flags & IS_TCPFSM) || @@ -1462,7 +1506,7 @@ int flags; /* * Must be a (outgoing) SYN-ACK in reply to a SYN. */ - fdata->td_end = end; + fdata->td_end = end - 1; fdata->td_maxwin = 1; fdata->td_maxend = end + win; } @@ -1475,9 +1519,6 @@ int flags; ack = tdata->td_end; } - if (seq == end) - seq = end = fdata->td_end; - maxwin = tdata->td_maxwin; ackskew = tdata->td_end - ack; @@ -1492,16 +1533,58 @@ int flags; #define SEQ_GE(a,b) ((int)((a) - (b)) >= 0) #define SEQ_GT(a,b) ((int)((a) - (b)) > 0) - if ( -#if defined(_KERNEL) - (SEQ_GE(fdata->td_maxend, end)) && + inseq = 0; + if ((SEQ_GE(fdata->td_maxend, end)) && (SEQ_GE(seq, fdata->td_end - maxwin)) && -#endif /* XXX what about big packets */ #define MAXACKWINDOW 66000 (-ackskew <= (MAXACKWINDOW << fdata->td_winscale)) && ( ackskew <= (MAXACKWINDOW << fdata->td_winscale))) { + inseq = 1; + /* + * Microsoft Windows will send the next packet to the right of the + * window if SACK is in use. + */ + } else if ((seq == fdata->td_maxend) && (ackskew == 0) && + (fdata->td_winflags & TCP_SACK_PERMIT) && + (tdata->td_winflags & TCP_SACK_PERMIT)) { + inseq = 1; + /* + * Sometimes a TCP RST will be generated with only the ACK field + * set to non-zero. + */ + } else if ((seq == 0) && (tcpflags == (TH_RST|TH_ACK)) && + (ackskew >= -1) && (ackskew <= 1)) { + inseq = 1; + } else if (!(flags & IS_TCPFSM)) { + int i; + + i = (fin->fin_rev << 1) + fin->fin_out; +#if 0 + if (is_pkts[i]0 == 0) { + /* + * Picking up a connection in the middle, the "next" + * packet seen from a direction that is new should be + * accepted, even if it appears out of sequence. + */ + inseq = 1; + } else +#endif + if (!(fdata->td_winflags & + (TCP_WSCALE_SEEN|TCP_WSCALE_FIRST))) { + /* + * No TCPFSM and no window scaling, so make some + * extra guesses. + */ + if ((seq == fdata->td_maxend) && (ackskew == 0)) + inseq = 1; + else if (SEQ_GE(seq + maxwin, fdata->td_end - maxwin)) + inseq = 1; + } + } + + if (inseq) { /* if ackskew < 0 then this should be due to fragmented * packets. There is no way to know the length of the * total packet in advance. @@ -1593,8 +1676,7 @@ ipstate_t *is; clone->is_flags &= ~SI_CLONE; clone->is_flags |= SI_CLONED; fr_stinsert(clone, fin->fin_rev); - MUTEX_ENTER(&clone->is_lock); - clone->is_ref = 1; + clone->is_ref = 2; if (clone->is_p == IPPROTO_TCP) { (void) fr_tcp_age(&clone->is_sti, fin, ips_tqtqb, clone->is_flags); @@ -1779,7 +1861,7 @@ u_32_t cmask; * Match up any flags set from IP options. */ if ((cflx && (flx != (cflx & cmask))) || - ((fin->fin_optmsk & is->is_optmsk) != is->is_opt) || + ((fin->fin_optmsk & is->is_optmsk[rev]) != is->is_opt[rev]) || ((fin->fin_secmsk & is->is_secmsk) != is->is_sec) || ((fin->fin_auth & is->is_authmsk) != is->is_auth)) return NULL; @@ -1796,9 +1878,12 @@ u_32_t cmask; if ((flags & (SI_W_SPORT|SI_W_DPORT))) { if ((flags & SI_CLONE) != 0) { - is = fr_stclone(fin, tcp, is); - if (is == NULL) + ipstate_t *clone; + + clone = fr_stclone(fin, tcp, is); + if (clone == NULL) return NULL; + is = clone; } else { ATOMIC_DECL(ips_stats.iss_wild); } @@ -1829,8 +1914,14 @@ u_32_t cmask; ret = -1; - if (is->is_flx[out][rev] == 0) + if (is->is_flx[out][rev] == 0) { is->is_flx[out][rev] = flx; + is->is_opt[rev] = fin->fin_optmsk; + if (is->is_v == 6) { + is->is_opt[rev] &= ~0x8; + is->is_optmsk[rev] &= ~0x8; + } + } /* * Check if the interface name for this "direction" is set and if not, @@ -1876,21 +1967,16 @@ fr_info_t *fin; /* * Does it at least have the return (basic) IP header ? + * Is it an actual recognised ICMP error type? * Only a basic IP header (no options) should be with * an ICMP error header. */ if ((fin->fin_v != 4) || (fin->fin_hlen != sizeof(ip_t)) || - (fin->fin_plen < ICMPERR_MINPKTLEN)) + (fin->fin_plen < ICMPERR_MINPKTLEN) || + !(fin->fin_flx & FI_ICMPERR)) return NULL; ic = fin->fin_dp; type = ic->icmp_type; - /* - * If it's not an error type, then return - */ - if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) && - (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) && - (type != ICMP_PARAMPROB)) - return NULL; oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN); /* @@ -1953,7 +2039,7 @@ fr_info_t *fin; */ savelen = oip->ip_len; oip->ip_len = len; - oip->ip_off = htons(oip->ip_off); + oip->ip_off = ntohs(oip->ip_off); ofin.fin_flx = FI_NOCKSUM; ofin.fin_v = 4; @@ -1981,8 +2067,6 @@ fr_info_t *fin; switch (oip->ip_p) { case IPPROTO_ICMP : - icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - /* * an ICMP error can only be generated as a result of an * ICMP query, not as the response on an ICMP error @@ -1990,15 +2074,13 @@ fr_info_t *fin; * XXX theoretically ICMP_ECHOREP and the other reply's are * ICMP query's as well, but adding them here seems strange XXX */ - if ((icmp->icmp_type != ICMP_ECHO) && - (icmp->icmp_type != ICMP_TSTAMP) && - (icmp->icmp_type != ICMP_IREQ) && - (icmp->icmp_type != ICMP_MASKREQ)) + if ((ofin.fin_flx & FI_ICMPERR) != 0) return NULL; /* * perform a lookup of the ICMP packet in the state table */ + icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2)); hv = (pr = oip->ip_p); src.in4 = oip->ip_src; hv += src.in4.s_addr; @@ -2017,10 +2099,6 @@ fr_info_t *fin; is = fr_matchsrcdst(&ofin, is, &src, &dst, NULL, FI_ICMPCMP); if (is != NULL) { - if ((is->is_pass & FR_NOICMPERR) != 0) { - RWLOCK_EXIT(&ipf_state); - return NULL; - } /* * i : the index of this packet (the icmp * unreachable) @@ -2293,7 +2371,8 @@ icmp6again: if ((is->is_p != pr) || (is->is_v != v)) continue; is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); - if (is != NULL && + if ((is != NULL) && + (ic->icmp_id == is->is_icmp.ici_id) && fr_matchicmpqueryreply(v, &is->is_icmp, ic, fin->fin_rev)) { if (fin->fin_rev) @@ -2386,11 +2465,13 @@ retry_tcpudp: break; } - if ((is != NULL) && ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) && - (is->is_tqehead[fin->fin_rev] != NULL)) - ifq = is->is_tqehead[fin->fin_rev]; - if (ifq != NULL && ifqp != NULL) - *ifqp = ifq; + if (is != NULL) { + if (((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) && + (is->is_tqehead[fin->fin_rev] != NULL)) + ifq = is->is_tqehead[fin->fin_rev]; + if (ifq != NULL && ifqp != NULL) + *ifqp = ifq; + } return is; } @@ -2783,6 +2864,11 @@ int why; if (ipstate_logging != 0 && why != 0) ipstate_log(is, why); + if (is->is_p == IPPROTO_TCP) + ips_stats.iss_fin++; + else + ips_stats.iss_expire++; + if (is->is_rule != NULL) { is->is_rule->fr_statecnt--; (void)fr_derefrule(&is->is_rule); @@ -2809,9 +2895,7 @@ void fr_timeoutstate() ipftq_t *ifq, *ifqnext; ipftqent_t *tqe, *tqn; ipstate_t *is; -#if defined(USE_SPL) && defined(_KERNEL) - int s; -#endif + SPL_INT(s); SPL_NET(s); WRITE_ENTER(&ipf_state); @@ -2881,9 +2965,7 @@ int which, proto; int delete, removed; long try, maxtick; u_long interval; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif + SPL_INT(s); removed = 0; @@ -2912,10 +2994,6 @@ int which, proto; } if (delete) { - if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; - else - ips_stats.iss_expire++; fr_delstate(is, ISL_FLUSH); removed++; } else @@ -3051,7 +3129,7 @@ int flags; rval = 0; dir = fin->fin_rev; tcpflags = tcp->th_flags; - dlen = fin->fin_plen - fin->fin_hlen - (TCP_OFF(tcp) << 2); + dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); if (tcpflags & TH_RST) { if (!(tcpflags & TH_PUSH) && !dlen) @@ -3189,13 +3267,34 @@ int flags; break; case IPF_TCPS_HALF_ESTAB: /* 4 */ - if (ostate >= IPF_TCPS_HALF_ESTAB) { - if ((tcpflags & TH_ACKMASK) == TH_ACK) { + if (tcpflags & TH_FIN) { + nstate = IPF_TCPS_FIN_WAIT_1; + rval = 1; + } else if ((tcpflags & TH_ACKMASK) == TH_ACK) { + /* + * If we've picked up a connection in mid + * flight, we could be looking at a follow on + * packet from the same direction as the one + * that created this state. Recognise it but + * do not advance the entire connection's + * state. + */ + switch (ostate) + { + case IPF_TCPS_CLOSED : + case IPF_TCPS_SYN_SENT : + case IPF_TCPS_SYN_RECEIVED : + rval = 1; + break; + case IPF_TCPS_HALF_ESTAB : + case IPF_TCPS_ESTABLISHED : nstate = IPF_TCPS_ESTABLISHED; rval = 1; + break; + default : + break; } } - break; case IPF_TCPS_ESTABLISHED: /* 5 */ @@ -3325,9 +3424,6 @@ int flags; (u_long)tcp, tcpflags, (u_long)tqe, nstate, ostate); # endif -# ifdef DIAGNOSTIC - panic("invalid TCP state"); -# endif #else abort(); #endif @@ -3451,20 +3547,16 @@ fr_info_t *fin; /* * Does it at least have the return (basic) IP header ? + * Is it an actual recognised ICMP error type? * Only a basic IP header (no options) should be with * an ICMP error header. */ - if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN)) + if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN) || + !(fin->fin_flx & FI_ICMPERR)) return NULL; ic6 = fin->fin_dp; type = ic6->icmp6_type; - /* - * If it's not an error type, then return - */ - if ((type != ICMP6_DST_UNREACH) && (type != ICMP6_PACKET_TOO_BIG) && - (type != ICMP6_TIME_EXCEEDED) && (type != ICMP6_PARAM_PROB)) - return NULL; oip6 = (ip6_t *)((char *)ic6 + ICMPERR_ICMPHLEN); if (fin->fin_plen < sizeof(*oip6)) diff --git a/sys/dist/ipf/netinet/ip_state.h b/sys/dist/ipf/netinet/ip_state.h index a858ae20209..9a13f21a25b 100644 --- a/sys/dist/ipf/netinet/ip_state.h +++ b/sys/dist/ipf/netinet/ip_state.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_state.h,v 1.4 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_state.h,v 1.5 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1995-2001 by Darren Reed. @@ -6,12 +6,12 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed - * Id: ip_state.h,v 2.68.2.3 2005/03/03 14:24:11 darrenr Exp + * Id: ip_state.h,v 2.68.2.5 2005/08/20 13:48:25 darrenr Exp */ #ifndef _NETINET_IP_STATE_H_ #define _NETINET_IP_STATE_H_ -#if defined(__STDC__) || defined(__GNUC__) +#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) # define SIOCDELST _IOW('r', 61, struct ipfobj) #else # define SIOCDELST _IOW(r, 61, struct ipfobj) @@ -60,8 +60,8 @@ typedef struct ipstate { u_char is_v; u_32_t is_hv; u_32_t is_tag; - u_32_t is_opt; /* packet options set */ - u_32_t is_optmsk; /* " " mask */ + u_32_t is_opt[2]; /* packet options set */ + u_32_t is_optmsk[2]; /* " " mask */ u_short is_sec; /* security options set */ u_short is_secmsk; /* " " mask */ u_short is_auth; /* authentication options set */ diff --git a/sys/dist/ipf/netinet/ip_sync.c b/sys/dist/ipf/netinet/ip_sync.c index 9168a8942fb..47bc1c8c3c4 100644 --- a/sys/dist/ipf/netinet/ip_sync.c +++ b/sys/dist/ipf/netinet/ip_sync.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_sync.c,v 1.4 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_sync.c,v 1.5 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1995-1998 by Darren Reed. @@ -98,7 +98,7 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.3 2005/02/18 13:06:29 darrenr Exp"; +static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.7 2006/03/19 14:59:39 darrenr Exp"; #endif #define SYNC_STATETABSZ 256 @@ -231,8 +231,10 @@ ipstate_t *ips; ips->is_die = htonl(ips->is_die); ips->is_pass = htonl(ips->is_pass); ips->is_flags = htonl(ips->is_flags); - ips->is_opt = htonl(ips->is_opt); - ips->is_optmsk = htonl(ips->is_optmsk); + ips->is_opt[0] = htonl(ips->is_opt[0]); + ips->is_opt[1] = htonl(ips->is_opt[1]); + ips->is_optmsk[0] = htonl(ips->is_optmsk[0]); + ips->is_optmsk[1] = htonl(ips->is_optmsk[1]); ips->is_sec = htons(ips->is_sec); ips->is_secmsk = htons(ips->is_secmsk); ips->is_auth = htons(ips->is_auth); @@ -246,8 +248,10 @@ ipstate_t *ips; ips->is_die = ntohl(ips->is_die); ips->is_pass = ntohl(ips->is_pass); ips->is_flags = ntohl(ips->is_flags); - ips->is_opt = ntohl(ips->is_opt); - ips->is_optmsk = ntohl(ips->is_optmsk); + ips->is_opt[0] = ntohl(ips->is_opt[0]); + ips->is_opt[1] = ntohl(ips->is_opt[1]); + ips->is_optmsk[0] = ntohl(ips->is_optmsk[0]); + ips->is_optmsk[1] = ntohl(ips->is_optmsk[1]); ips->is_sec = ntohs(ips->is_sec); ips->is_secmsk = ntohs(ips->is_secmsk); ips->is_auth = ntohs(ips->is_auth); @@ -442,21 +446,26 @@ struct uio *uio; l = get_sleep_lock(&sl_tail); err = sleep(&sl_tail, PZERO+1); + if (err) { + MUTEX_EXIT(&ipsl_mutex); + return EINTR; + } spinunlock(l); } # else /* __hpux */ # ifdef __osf__ err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0, &ipsl_mutex, MS_LOCK_SIMPLE); + if (err) + return EINTR; # else MUTEX_EXIT(&ipsl_mutex); err = SLEEP(&sl_tail, "ipl sleep"); + if (err) + return EINTR; + MUTEX_ENTER(&ipsl_mutex); # endif /* __osf__ */ # endif /* __hpux */ - if (err) { - MUTEX_EXIT(&ipsl_mutex); - return err; - } # endif /* SOLARIS */ } MUTEX_EXIT(&ipsl_mutex); @@ -695,7 +704,6 @@ int ipfsync_nat(sp, data) synchdr_t *sp; void *data; { - synclogent_t sle; syncupdent_t su; nat_t *n, *nat; synclist_t *sl; @@ -707,8 +715,6 @@ void *data; switch (sp->sm_cmd) { case SMC_CREATE : - bcopy(data, &sle, sizeof(sle)); - KMALLOC(n, nat_t *); if (n == NULL) { err = ENOMEM; @@ -722,9 +728,7 @@ void *data; break; } - WRITE_ENTER(&ipf_nat); - - nat = &sle.sle_un.sleu_ipn; + nat = (nat_t *)data; bzero((char *)n, offsetof(nat_t, nat_age)); bcopy((char *)&nat->nat_age, (char *)&n->nat_age, sizeof(*n) - offsetof(nat_t, nat_age)); @@ -734,6 +738,8 @@ void *data; sl->sl_idx = -1; sl->sl_ipn = n; sl->sl_num = ntohl(sp->sm_num); + + WRITE_ENTER(&ipf_nat); sl->sl_pnext = syncstatetab + hv; sl->sl_next = syncstatetab[hv]; if (syncstatetab[hv] != NULL) @@ -998,4 +1004,16 @@ int mode; { return EINVAL; } + + +int ipfsync_canread() +{ + return !((sl_tail == sl_idx) && (su_tail == su_idx)); +} + + +int ipfsync_canwrite() +{ + return 1; +} #endif /* IPFILTER_SYNC */ diff --git a/sys/dist/ipf/netinet/ip_sync.h b/sys/dist/ipf/netinet/ip_sync.h index 37fac196418..d97ac5be58a 100644 --- a/sys/dist/ipf/netinet/ip_sync.h +++ b/sys/dist/ipf/netinet/ip_sync.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_sync.h,v 1.3 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ip_sync.h,v 1.4 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001 by Darren Reed. @@ -6,7 +6,7 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 - * Id: ip_sync.h,v 2.11.2.2 2004/11/04 19:29:07 darrenr Exp + * Id: ip_sync.h,v 2.11.2.3 2006/03/19 14:59:39 darrenr Exp */ #ifndef __IP_SYNC_H__ @@ -113,5 +113,7 @@ extern int ipfsync_nat __P((synchdr_t *sp, void *data)); extern int ipfsync_state __P((synchdr_t *sp, void *data)); extern int ipfsync_read __P((struct uio *uio)); extern int ipfsync_write __P((struct uio *uio)); +extern int ipfsync_canread __P((void)); +extern int ipfsync_canwrite __P((void)); #endif /* IP_SYNC */ diff --git a/sys/dist/ipf/netinet/ipl.h b/sys/dist/ipf/netinet/ipl.h index 4b48e45f36d..387f03ccdae 100644 --- a/sys/dist/ipf/netinet/ipl.h +++ b/sys/dist/ipf/netinet/ipl.h @@ -1,4 +1,4 @@ -/* $NetBSD: ipl.h,v 1.5 2005/12/11 12:24:21 christos Exp $ */ +/* $NetBSD: ipl.h,v 1.6 2006/04/04 16:17:19 martti Exp $ */ /* * Copyright (C) 1993-2001, 2003 by Darren Reed. @@ -6,14 +6,14 @@ * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ipl.h 1.21 6/5/96 - * Id: ipl.h,v 2.52.2.9 2005/03/30 14:14:05 darrenr Exp + * Id: ipl.h,v 2.52.2.14 2006/04/01 20:09:42 darrenr Exp */ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter: v4.1.8" +#define IPL_VERSION "IP Filter: v4.1.13" -#define IPFILTER_VERSION 4010800 +#define IPFILTER_VERSION 4011300 #endif |
