summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartti <martti@NetBSD.org>2006-04-04 16:17:18 +0000
committermartti <martti@NetBSD.org>2006-04-04 16:17:18 +0000
commit9ea58d54bc33aec41259ffe6552f8969375b59aa (patch)
tree6d48ac3be198557f26f11a90f3b256d9c84c45de
parent983a2072cee4b5033319b848ebc04ea4d5ce62b6 (diff)
Upgraded IPFilter to 4.1.13
-rw-r--r--dist/ipf/HISTORY161
-rw-r--r--dist/ipf/Makefile29
-rw-r--r--dist/ipf/ip_fil.c45
-rw-r--r--dist/ipf/ipf.h6
-rw-r--r--dist/ipf/iplang/iplang_y.y11
-rw-r--r--dist/ipf/ipsd/sbpf.c16
-rw-r--r--dist/ipf/ipsend/arp.c6
-rw-r--r--dist/ipf/ipsend/ipsend.c6
-rw-r--r--dist/ipf/ipsend/iptests.c33
-rw-r--r--dist/ipf/ipsend/lsock.c6
-rw-r--r--dist/ipf/ipsend/resend.c9
-rw-r--r--dist/ipf/ipsend/sbpf.c21
-rw-r--r--dist/ipf/ipsend/sock.c40
-rw-r--r--dist/ipf/ipt.h4
-rw-r--r--dist/ipf/lib/addicmp.c77
-rw-r--r--dist/ipf/lib/addkeep.c86
-rw-r--r--dist/ipf/lib/facpri.c36
-rw-r--r--dist/ipf/lib/getport.c27
-rw-r--r--dist/ipf/lib/getproto.c10
-rw-r--r--dist/ipf/lib/icmpcode.c29
-rw-r--r--dist/ipf/lib/ipf_dotuning.c4
-rw-r--r--dist/ipf/lib/ipft_hx.c10
-rw-r--r--dist/ipf/lib/ipft_tx.c66
-rw-r--r--dist/ipf/lib/kmem.c9
-rw-r--r--dist/ipf/lib/make_range.c26
-rw-r--r--dist/ipf/lib/v6ionames.c5
-rw-r--r--dist/ipf/man/ipf.59
-rw-r--r--dist/ipf/man/ipftest.120
-rw-r--r--dist/ipf/man/ipmon.814
-rw-r--r--dist/ipf/man/ipnat.55
-rw-r--r--dist/ipf/man/ipnat.84
-rw-r--r--dist/ipf/radix.c8
-rw-r--r--dist/ipf/samples/proxy.c7
-rw-r--r--dist/ipf/tools/ipf_y.y89
-rw-r--r--dist/ipf/tools/ipfs.c59
-rw-r--r--dist/ipf/tools/ipfstat.c18
-rw-r--r--dist/ipf/tools/ipmon.c59
-rw-r--r--dist/ipf/tools/ipnat_y.y80
-rw-r--r--regress/sys/kern/ipf/Makefile32
-rw-r--r--regress/sys/kern/ipf/dotest22
-rw-r--r--regress/sys/kern/ipf/expected/i1221
-rw-r--r--regress/sys/kern/ipf/expected/in13
-rw-r--r--regress/sys/kern/ipf/itest11
-rw-r--r--regress/sys/kern/ipf/natipftest6
-rw-r--r--regress/sys/kern/ipf/regress/i123
-rw-r--r--sys/dist/ipf/netinet/fil.c979
-rw-r--r--sys/dist/ipf/netinet/ip_auth.c86
-rw-r--r--sys/dist/ipf/netinet/ip_auth.h6
-rw-r--r--sys/dist/ipf/netinet/ip_compat.h161
-rw-r--r--sys/dist/ipf/netinet/ip_fil.h48
-rw-r--r--sys/dist/ipf/netinet/ip_fil_netbsd.c199
-rw-r--r--sys/dist/ipf/netinet/ip_frag.c26
-rw-r--r--sys/dist/ipf/netinet/ip_frag.h8
-rw-r--r--sys/dist/ipf/netinet/ip_ftp_pxy.c25
-rw-r--r--sys/dist/ipf/netinet/ip_h323_pxy.c6
-rw-r--r--sys/dist/ipf/netinet/ip_htable.c15
-rw-r--r--sys/dist/ipf/netinet/ip_ipsec_pxy.c10
-rw-r--r--sys/dist/ipf/netinet/ip_irc_pxy.c4
-rw-r--r--sys/dist/ipf/netinet/ip_log.c42
-rw-r--r--sys/dist/ipf/netinet/ip_lookup.c19
-rw-r--r--sys/dist/ipf/netinet/ip_lookup.h4
-rw-r--r--sys/dist/ipf/netinet/ip_nat.c308
-rw-r--r--sys/dist/ipf/netinet/ip_nat.h9
-rw-r--r--sys/dist/ipf/netinet/ip_netbios_pxy.c18
-rw-r--r--sys/dist/ipf/netinet/ip_pool.c12
-rw-r--r--sys/dist/ipf/netinet/ip_pool.h6
-rw-r--r--sys/dist/ipf/netinet/ip_pptp_pxy.c22
-rw-r--r--sys/dist/ipf/netinet/ip_proxy.c37
-rw-r--r--sys/dist/ipf/netinet/ip_proxy.h21
-rw-r--r--sys/dist/ipf/netinet/ip_rcmd_pxy.c10
-rw-r--r--sys/dist/ipf/netinet/ip_scan.c19
-rw-r--r--sys/dist/ipf/netinet/ip_scan.h6
-rw-r--r--sys/dist/ipf/netinet/ip_state.c318
-rw-r--r--sys/dist/ipf/netinet/ip_state.h10
-rw-r--r--sys/dist/ipf/netinet/ip_sync.c50
-rw-r--r--sys/dist/ipf/netinet/ip_sync.h6
-rw-r--r--sys/dist/ipf/netinet/ipl.h8
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