Update DragonFly's IPFilter to version 3.4.35:

	o Vendor's ChangeLog available in src/contrib/ipfilter/HISTORY

	o Cast interface numbers to u_int instead of u_char, so that
	  big numbered units don't get truncated. More information on
	  this problem can be found at FreeBSD GNATS, PR kern/64584.

	o Compile INET6 support into ipfilter unless NOINET6 is defined
	  as Make variable.

	o Update $FreeBSD$ CVS ID tags.

	o Adjust minor style(9) changes, like prototypes, etc.

Index: contrib/ipfilter/HISTORY
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/HISTORY,v
retrieving revision 1.1
diff -u -p -u -r1.1 HISTORY
--- contrib/ipfilter/HISTORY	17 Jun 2003 02:44:50 -0000	1.1
+++ contrib/ipfilter/HISTORY	17 Jul 2004 04:55:54 -0000
@@ -22,6 +22,87 @@
 # and especially those who have found the time to port IP Filter to new
 # platforms.
 #
+3.4.35 21/6/2004 - Released
+
+some cases of ICMP checksum alteration were wrong
+
+block packets that fail to create state table entries
+
+correctly handle all return values from ip_natout() when fastrouting
+
+ipmon was not correctly calculating the length of the IPv6 packet (excluded
+ipv6 header length)
+
+3.4.34 20/4/2004 - Released
+
+correct the ICMP packet checksum fixing up when processing ICMP errors for NAT
+
+various changes to ipsend for sending packets with ipv4 options
+
+look for ipmon's pidfile in /var/run and /etc/opt/ipf in Solaris' init script
+
+only allow non-fragmented packets to influence whether or not a logged
+packet is the same as the one logged before.
+
+make "ipfstat -f" output more informative
+
+compatibility for openbsd byte order changes to ip_off/ip_len
+
+disallow "freebsd" as a make target (encourages people to do the wrong thing)
+
+3.4.33	15/12/2003 - Released
+
+pass on messages moving through ipfilter when it is unloading itself on Solaris
+
+add disabling of auto-detach when the module attaches on Solaris
+
+compatibility patches for 'struct ifnet' changes on FreeBSD
+
+implement a maximum for the number of entries in the NAT table (NAT_TABLE_MAX
+and ipf_nattable_max)
+
+fix ipfstat -A
+
+frsynclist() wasn't paying attention to all the places where interface
+names are, like it should.
+
+fix where packet header pointers are pointing to after doing an ipf_pullup
+
+fix comparing ICMP packets with established TCP state where only 8 bytes
+of header are returned in the ICMP error.
+
+3.4.32	18/6/2003 - Released
+
+fix up the behaviour of ipfs
+
+make parsing errors in ipf/ipnat return an error rather than return
+indicating success.
+
+window scaling patch
+
+make ipfstat work as a set{g,u}id thing - gave up privs before opening
+/dev/ipl
+
+checksum adjustment corrections for ICMP & NAT
+
+attempt to always get an mbuf full of data through pullup if possible
+
+Fix bug with NAT and fragments causing system to crash
+
+Add patches for OpenBSD 3.3
+
+stop LKM locking up the machine on modern NetBSD(?)
+
+allow timeouts in NAT rules to over-ride fr_defnatage if LARGE_NAT is defined
+
+Locking patches for IRIX 6.5 from SGI.
+ 
+fix bug in synchronising state sessions where all interfaces were invalidated
+
+fix bug in openbsd 3.2 bridge diffs
+
+fix bug parsing port comparisons in proxy rules
+
 3.4.31	7/12/2002 - Released
 
 Solaris 10 compatibility
Index: contrib/ipfilter/Makefile
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/Makefile,v
retrieving revision 1.1
diff -u -p -u -r1.1 Makefile
--- contrib/ipfilter/Makefile	17 Jun 2003 02:44:50 -0000	1.1
+++ contrib/ipfilter/Makefile	17 Jul 2004 04:55:54 -0000
@@ -84,7 +84,7 @@ all:
 	@echo "solaris	- auto-selects SunOS4.1.x/Solaris 2.3-6/Solaris2.4-6x86"
 	@echo "netbsd	- compile for NetBSD"
 	@echo "openbsd	- compile for OpenBSD"
-	@echo "freebsd	- compile for FreeBSD 2.0, 2.1 or earlier"
+	@echo "freebsd20	- compile for FreeBSD 2.0, 2.1 or earlier"
 	@echo "freebsd22	- compile for FreeBSD-2.2 or greater"
 	@echo "freebsd3	- compile for FreeBSD-3.x"
 	@echo "freebsd4	- compile for FreeBSD-4.x"
@@ -123,7 +123,7 @@ freebsd22: include
 	else \
 		ln -s `uname -v|sed -e 's@^.*:\(/[^: ]*\).*@\1@'`/ioconf.h BSD/$(CPU) ; \
 	fi
-	make freebsd
+	make freebsd20
 
 freebsd4: include
 	if [ x$INET6 = x ] ; then \
@@ -150,7 +150,7 @@ openbsd openbsd21: include
 	(cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c"; cd ..)
 	(cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
 
-freebsd freebsd20 freebsd21: include
+freebsd20 freebsd21: include
 	make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
 	(cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlf_ipl.c"; cd ..)
 	(cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
@@ -288,3 +288,27 @@ null:
 		exit 1; \
 	fi
 	-@echo make ok
+
+test-solaris test-sunos4 test-sunos5: solaris
+	(cd test && make clean && make)
+
+test-freebsd: freebsd
+	(cd test && make clean && make)
+
+test-freebsd22: freebsd22
+	(cd test && make clean && make)
+
+test-freebsd3: freebsd3
+	(cd test && make clean && make)
+
+test-freebsd4: freebsd4
+	(cd test && make clean && make)
+
+test-netbsd: netbsd
+	(cd test && make clean && make)
+
+test-openbsd: openbsd
+	(cd test && make clean && make)
+
+test-irix: irix
+	(cd test && make clean && make)
Index: contrib/ipfilter/common.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/common.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 common.c
--- contrib/ipfilter/common.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/common.c	17 Jul 2004 04:55:54 -0000
@@ -263,7 +263,19 @@ int     linenum;
 		return 0;
 	if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) {
 		(*seg)++;
-		if (isalnum(***seg) && *(*seg + 2)) {
+		if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq"))
+			comp = FR_EQUAL;
+		else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne"))
+			comp = FR_NEQUAL;
+		else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt"))
+			comp = FR_LESST;
+		else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt"))
+			comp = FR_GREATERT;
+		else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le"))
+			comp = FR_LESSTE;
+		else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge"))
+			comp = FR_GREATERTE;
+		else if (isalnum(***seg) && *(*seg + 2)) {
 			if (portnum(**seg, pp, linenum) == 0)
 				return -1;
 			(*seg)++;
@@ -285,19 +297,7 @@ int     linenum;
 			}
 			if (portnum(**seg, tp, linenum) == 0)
 				return -1;
-		} else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq"))
-			comp = FR_EQUAL;
-		else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne"))
-			comp = FR_NEQUAL;
-		else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt"))
-			comp = FR_LESST;
-		else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt"))
-			comp = FR_GREATERT;
-		else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le"))
-			comp = FR_LESSTE;
-		else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge"))
-			comp = FR_GREATERTE;
-		else {
+		} else {
 			fprintf(stderr, "%d: unknown comparator (%s)\n",
 					linenum, **seg);
 			return -1;
Index: contrib/ipfilter/fil.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/fil.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 fil.c
--- contrib/ipfilter/fil.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/fil.c	17 Jul 2004 06:05:18 -0000
@@ -42,6 +42,7 @@
 #  include <sys/mbuf.h>
 # endif
 #else
+# include <sys/cmn_err.h>
 # include <sys/byteorder.h>
 # if SOLARIS2 < 5
 #  include <sys/dditypes.h>
@@ -97,7 +98,7 @@
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)fil.c	1.36 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fil.c,v 2.35.2.67 2002/12/06 13:28:05 darrenr Exp $";
+static const char rcsid[] = "@(#)$FreeBSD: src/contrib/ipfilter/Attic/fil.c,v 1.1.1.10.2.9 2004/07/05 06:02:35 darrenr Exp $";
 #endif
 
 #ifndef	_KERNEL
@@ -146,6 +147,9 @@ static	int	frflushlist __P((int, minor_t
 static	void	frsynclist __P((frentry_t *));
 #endif
 
+# ifndef __sgi
+static  void    *ipf_pullup (mb_t *, fr_info_t *, int, void *);
+# endif
 
 /*
  * bit values for identifying presence of individual IP options
@@ -192,19 +196,27 @@ struct	optlist	secopt[8] = {
  * compact the IP header into a structure which contains just the info.
  * which is useful for comparing IP headers with.
  */
-void	fr_makefrip(hlen, ip, fin)
+int	fr_makefrip(hlen, ip, fin)
 int hlen;
 ip_t *ip;
 fr_info_t *fin;
 {
 	u_short optmsk = 0, secmsk = 0, auth = 0;
 	int i, mv, ol, off, p, plen, v;
+#if defined(_KERNEL)
+# if SOLARIS
+	mb_t *m = fin->fin_qfm;
+# else
+	mb_t *m = fin->fin_mp ? *fin->fin_mp : NULL;
+# endif
+#endif
 	fr_ip_t *fi = &fin->fin_fi;
 	struct optlist *op;
 	u_char *s, opt;
 	tcphdr_t *tcp;
 
 	fin->fin_rev = 0;
+	fin->fin_dp = NULL;
 	fin->fin_fr = NULL;
 	fin->fin_tcpf = 0;
 	fin->fin_data[0] = 0;
@@ -218,8 +230,10 @@ fr_info_t *fin;
 	if (v == 4) {
 		fin->fin_id = ip->ip_id;
 		fi->fi_tos = ip->ip_tos;
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+		ip->ip_off = ntohs(ip->ip_off);
+#endif
 		off = (ip->ip_off & IP_OFFMASK);
-		tcp = (tcphdr_t *)((char *)ip + hlen);
 		(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
 		fi->fi_src.i6[1] = 0;
 		fi->fi_src.i6[2] = 0;
@@ -233,6 +247,9 @@ fr_info_t *fin;
 		fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
 		if (ip->ip_off & (IP_MF|IP_OFFMASK))
 			fi->fi_fl |= FI_FRAG;
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+		ip->ip_len = ntohs(ip->ip_len);
+#endif
 		plen = ip->ip_len;
 		fin->fin_dlen = plen - hlen;
 	}
@@ -244,7 +261,6 @@ fr_info_t *fin;
 		p = ip6->ip6_nxt;
 		fi->fi_p = p;
 		fi->fi_ttl = ip6->ip6_hlim;
-		tcp = (tcphdr_t *)(ip6 + 1);
 		fi->fi_src.in6 = ip6->ip6_src;
 		fi->fi_dst.in6 = ip6->ip6_dst;
 		fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
@@ -256,14 +272,23 @@ fr_info_t *fin;
 	}
 #endif
 	else
-		return;
+		return -1;
 
 	fin->fin_off = off;
 	fin->fin_plen = plen;
-	fin->fin_dp = (char *)tcp;
+	tcp = (tcphdr_t *)((char *)ip + hlen);
 	fin->fin_misc = 0;
 	off <<= 3;
 
+	/*
+	 * For both ICMPV6 & ICMP, we attempt to pullup the entire packet into
+	 * a single buffer for recognised error return packets.  Why?  Because 
+	 * the entire data section of the ICMP payload is considered to be of
+	 * significance and maybe required in NAT/state processing, so rather
+	 * than be careful later, attempt to get it all in one buffeer first.
+	 * For TCP we just make sure the _entire_ TCP header is in the first
+	 * buffer for convienience.
+	 */
 	switch (p)
 	{
 #ifdef USE_INET6
@@ -272,7 +297,7 @@ fr_info_t *fin;
 		int minicmpsz = sizeof(struct icmp6_hdr);
 		struct icmp6_hdr *icmp6;
 
-		if (fin->fin_dlen > 1) {
+		if (!(fin->fin_fl & FI_SHORT) && (fin->fin_dlen > 1)) {
 			fin->fin_data[0] = *(u_short *)tcp;
 
 			icmp6 = (struct icmp6_hdr *)tcp;
@@ -287,6 +312,14 @@ fr_info_t *fin;
 			case ICMP6_PACKET_TOO_BIG :
 			case ICMP6_TIME_EXCEEDED :
 			case ICMP6_PARAM_PROB :
+# if defined(KERNEL) && !defined(__sgi)
+				if ((m != NULL) && (M_BLEN(m) < plen)) {
+					ip = ipf_pullup(m, fin, plen, ip);
+					if (ip == NULL)
+						return -1;
+					tcp = (tcphdr_t *)((char *)ip + hlen);
+				}
+# endif /* KERNEL && !__sgi */
 				minicmpsz = ICMP6ERR_IPICMPHLEN;
 				break;
 			default :
@@ -294,22 +327,27 @@ fr_info_t *fin;
 			}
 		}
 
-		if (!(plen >= minicmpsz))
+		if (!(fin->fin_dlen >= minicmpsz))
 			fi->fi_fl |= FI_SHORT;
 
 		break;
 	}
-#endif
+#endif /* USE_INET6 */
+
 	case IPPROTO_ICMP :
 	{
 		int minicmpsz = sizeof(struct icmp);
 		icmphdr_t *icmp;
 
-		if (!off && (fin->fin_dlen > 1)) {
+		if (!off && (fin->fin_dlen > 1) && !(fin->fin_fl & FI_SHORT)) {
 			fin->fin_data[0] = *(u_short *)tcp;
 
 			icmp = (icmphdr_t *)tcp;
 
+			/*
+			 * Minimum ICMP packet is type(1) code(1) cksum(2)
+			 * plus 4 bytes following, totalling 8 bytes.
+			 */
 			switch (icmp->icmp_type)
 			{
 			case ICMP_ECHOREPLY :
@@ -325,7 +363,7 @@ fr_info_t *fin;
 			 */
 			case ICMP_TSTAMP :
 			case ICMP_TSTAMPREPLY :
-				minicmpsz = 20;
+				minicmpsz = ICMP_MINLEN + 12;
 				break;
 			/*
 			 * type(1) + code(1) + cksum(2) + id(2) seq(2) +
@@ -333,9 +371,28 @@ fr_info_t *fin;
 			 */
 			case ICMP_MASKREQ :
 			case ICMP_MASKREPLY :
-				minicmpsz = 12;
+				minicmpsz = ICMP_MINLEN + 4;
+				break;
+			/*
+			 * type(1) + code(1) + cksum(2) + arg(4) ip(20+)
+			 */
+			case ICMP_UNREACH :
+			case ICMP_SOURCEQUENCH :
+			case ICMP_REDIRECT :
+			case ICMP_TIMXCEED :
+			case ICMP_PARAMPROB :
+#if defined(KERNEL) && !defined(__sgi)
+				if ((m != NULL) && (M_BLEN(m) < plen)) {
+					ip = ipf_pullup(m, fin, plen, ip);
+					if (ip == NULL)
+						return -1;
+					tcp = (tcphdr_t *)((char *)ip + hlen);
+				}
+#endif /* KERNEL && !__sgi */
+				minicmpsz = ICMPERR_MINPKTLEN - sizeof(ip_t);
 				break;
 			default :
+				minicmpsz = ICMP_MINLEN;
 				break;
 			}
 		}
@@ -343,9 +400,9 @@ fr_info_t *fin;
 		if ((!(plen >= hlen + minicmpsz) && !off) ||
 		    (off && off < sizeof(struct icmp)))
 			fi->fi_fl |= FI_SHORT;
-
 		break;
 	}
+
 	case IPPROTO_TCP :
 		fi->fi_fl |= FI_TCPUDP;
 #ifdef	USE_INET6
@@ -359,6 +416,20 @@ fr_info_t *fin;
 			     (off && off < sizeof(struct tcphdr)))
 				fi->fi_fl |= FI_SHORT;
 		}
+
+#if defined(KERNEL) && !defined(__sgi)
+		if (!off && !(fi->fi_fl & FI_SHORT)) {
+			int tlen = hlen + (tcp->th_off << 2);
+
+			if ((m != NULL) && (M_BLEN(m) < tlen)) {
+				ip = ipf_pullup(m, fin, tlen, ip);
+				if (ip == NULL)
+					return -1;
+				tcp = (tcphdr_t *)((char *)ip + hlen);
+			}
+		}
+#endif /* _KERNEL && !_sgi */
+
 		if (!(fi->fi_fl & FI_SHORT) && !off)
 			fin->fin_tcpf = tcp->th_flags;
 		goto getports;
@@ -398,12 +469,14 @@ getports:
 		break;
 	}
 
+	fin->fin_dp = (char *)tcp;
+
 #ifdef	USE_INET6
 	if (v == 6) {
 		fi->fi_optmsk = 0;
 		fi->fi_secmsk = 0;
 		fi->fi_auth = 0;
-		return;
+		return 0;
 	}
 #endif
 
@@ -460,6 +533,7 @@ getports:
 	fi->fi_optmsk = optmsk;
 	fi->fi_secmsk = secmsk;
 	fi->fi_auth = auth;
+	return 0;
 }
 
 
@@ -747,7 +821,7 @@ void *m;
 #endif /* IPFILTER_LOG */
 		ATOMIC_INCL(fr->fr_hits);
 		if (passt & FR_ACCOUNT)
-			fr->fr_bytes += (U_QUAD_T)ip->ip_len;
+			fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
 		else
 			fin->fin_icode = fr->fr_icode;
 		fin->fin_rule = rulen;
@@ -810,12 +884,17 @@ int out;
 	int p, len, drop = 0, logit = 0;
 	mb_t *mc = NULL;
 # if !defined(__SVR4) && !defined(__svr4__)
+   /*
+    * We don't do this section for Solaris because fr_precheck() does a
+    * pullupmsg() instead, effectively achieving the same result as here
+    * so no need to duplicate it.
+    */
 #  ifdef __sgi
 	char hbuf[128];
 #  endif
 	int up;
 
-#  if !SOLARIS && !defined(NETBSD_PF) && \
+#  if !defined(NETBSD_PF) && \
       ((defined(__FreeBSD__) && (__FreeBSD_version < 500011)) || \
        defined(__OpenBSD__) || defined(_BSDI_VERSION))
 	if (fr_checkp != fr_check && fr_running > 0) {
@@ -853,7 +932,7 @@ int out;
 	}
 #  endif /* CSUM_DELAY_DATA */
 
-# ifdef	USE_INET6
+#  ifdef	USE_INET6
 	if (v == 6) {
 		len = ntohs(((ip6_t*)ip)->ip6_plen);
 		if (!len)
@@ -861,17 +940,20 @@ int out;
 		len += sizeof(ip6_t);
 		p = ((ip6_t *)ip)->ip6_nxt;
 	} else
-# endif
+#  endif
 	{
 		p = ip->ip_p;
 		len = ip->ip_len;
 	}
 
+	fin->fin_mp = mp;
+	fin->fin_out = out;
+
 	if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
 	    (v == 4 && p == IPPROTO_ICMP)
-# ifdef USE_INET6
+#  ifdef USE_INET6
 	    || (v == 6 && p == IPPROTO_ICMPV6)
-# endif
+#  endif
 	   )) {
 		int plen = 0;
 
@@ -891,7 +973,7 @@ int out;
 			case IPPROTO_ESP:
 				plen = 8;
 				break;
-# ifdef USE_INET6
+#  ifdef USE_INET6
 	    		case IPPROTO_ICMPV6 :
 				/*
 				 * XXX does not take intermediate header
@@ -899,8 +981,10 @@ int out;
 				 */
 				plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
 				break;
-# endif
+#  endif
 			}
+		if ((plen > 0) && (len < hlen + plen))
+			fin->fin_fl |= FI_SHORT;
 		up = MIN(hlen + plen, len);
 
 		if (up > m->m_len) {
@@ -915,14 +999,34 @@ int out;
 			ip = (ip_t *)hbuf;
 #  else /* __ sgi */
 #   ifndef linux
-			if ((*mp = m_pullup(m, up)) == 0) {
-				ATOMIC_INCL(frstats[out].fr_pull[1]);
+			/*
+			 * Having determined that we need to pullup some data,
+			 * try to bring as much of the packet up into a single
+			 * buffer with the first pullup.  This hopefully means
+			 * less need for doing futher pullups.  Not needed for
+			 * Solaris because fr_precheck() does it anyway.
+			 *
+			 * The main potential for trouble here is if MLEN/MHLEN
+			 * become quite small, lets say < 64 bytes...but if
+			 * that did happen, BSD networking as a whole would be
+			 * slow/inefficient.
+			 */
+#    ifdef MHLEN
+			/*
+			 * Assume that M_PKTHDR is set and just work with what
+			 * is left rather than check..  Should not make any
+			 * real difference, anyway.
+			 */
+			if ((MHLEN > up) && (len > up))
+				up = MIN(len, MHLEN);
+#    else
+			if ((MLEN > up) && (len > up))
+				up = MIN(len, MLEN);
+#    endif
+			ip = ipf_pullup(m, fin, up, ip);
+			if (ip == NULL)
 				return -1;
-			} else {
-				ATOMIC_INCL(frstats[out].fr_pull[0]);
-				m = *mp;
-				ip = mtod(m, ip_t *);
-			}
+			m = *mp;
 #   endif /* !linux */
 #  endif /* __sgi */
 		} else
@@ -935,17 +1039,21 @@ int out;
 
 	if ((u_int)ip & 0x3)
 		return 2;
+	fin->fin_mp = mp;
+	fin->fin_out = out;
 	fin->fin_qfm = m;
 	fin->fin_qif = qif;
 # endif
+#else
+	fin->fin_mp = mp;
+	fin->fin_out = out;
 #endif /* _KERNEL */
 	
 	changed = 0;
-	fin->fin_ifp = ifp;
 	fin->fin_v = v;
-	fin->fin_out = out;
-	fin->fin_mp = mp;
-	fr_makefrip(hlen, ip, fin);
+	fin->fin_ifp = ifp;
+	if (fr_makefrip(hlen, ip, fin) == -1)
+		return -1;
 
 #ifdef _KERNEL
 # ifdef	USE_INET6
@@ -1109,6 +1217,10 @@ int out;
 		if (pass & FR_KEEPSTATE) {
 			if (fr_addstate(ip, fin, NULL, 0) == NULL) {
 				ATOMIC_INCL(frstats[out].fr_bads);
+				if (pass & FR_PASS) {
+					pass &= ~FR_PASS;
+					pass |= FR_BLOCK;
+				}
 			} else {
 				ATOMIC_INCL(frstats[out].fr_ads);
 			}
@@ -1290,6 +1402,12 @@ logit:
 			(void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
 	}
 # endif /* !SOLARIS */
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+	if (pass & FR_PASS) {
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
+	}
+#endif
 	return (pass & FR_PASS) ? 0 : error;
 #else /* _KERNEL */
 	if (pass & FR_NOMATCH)
@@ -1387,10 +1505,10 @@ tcphdr_t *tcp;
 	/*
 	 * Both sum and sum2 are partial sums, so combine them together.
 	 */
-	sum = (sum & 0xffff) + (sum >> 16);
-	sum = ~sum & 0xffff;
-	sum2 += sum;
-	sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+	sum += ~sum2 & 0xffff;
+	while (sum > 0xffff)
+		sum = (sum & 0xffff) + (sum >> 16);
+	sum2 = ~sum & 0xffff;
 #  else /* defined(BSD) || defined(sun) */
 {
 	union {
@@ -1531,7 +1649,7 @@ nodata:
  * SUCH DAMAGE.
  *
  *	@(#)uipc_mbuf.c	8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.67 2002/12/06 13:28:05 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.82 2004/06/20 10:27:47 darrenr Exp $
  */
 /*
  * Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1963,12 +2081,40 @@ struct in_addr *inp;
 static void frsynclist(fr)
 register frentry_t *fr;
 {
+	frdest_t *fdp;
+	int i;
+
 	for (; fr; fr = fr->fr_next) {
-		if (fr->fr_ifa != NULL) {
-			fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_ip.fi_v);
-			if (fr->fr_ifa == NULL)
-				fr->fr_ifa = (void *)-1;
+		for (i = 0; i < 4; i++) {
+			if ((fr->fr_ifnames[i][1] == '\0') &&
+			    ((fr->fr_ifnames[i][0] == '-') ||
+			     (fr->fr_ifnames[i][0] == '*'))) {
+				fr->fr_ifas[i] = NULL;
+			} else if (*fr->fr_ifnames[i]) {
+				fr->fr_ifas[i] = GETUNIT(fr->fr_ifnames[i],
+							 fr->fr_v);
+				if (!fr->fr_ifas[i])
+					fr->fr_ifas[i] = (void *)-1;
+			}
+		}
+
+		fdp = &fr->fr_dif;
+		fr->fr_flags &= ~FR_DUP;
+		if (*fdp->fd_ifname) {
+			fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
+			if (!fdp->fd_ifp)
+				fdp->fd_ifp = (struct ifnet *)-1;
+			else
+				fr->fr_flags |= FR_DUP;
 		}
+
+		fdp = &fr->fr_tif;
+		if (*fdp->fd_ifname) {
+			fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
+			if (!fdp->fd_ifp)
+				fdp->fd_ifp = (struct ifnet *)-1;
+		}
+
 		if (fr->fr_grp)
 			frsynclist(fr->fr_grp);
 	}
@@ -2223,3 +2369,64 @@ mb_t *buf;
 	return ip->ip_len;
 }
 #endif
+
+
+#if defined(_KERNEL) && !defined(__sgi)
+void *ipf_pullup(m, fin, len, ipin)
+mb_t *m;
+fr_info_t *fin;
+int len;
+void *ipin;
+{
+# if SOLARIS
+	qif_t *qf = fin->fin_qif;
+# endif
+	int out = fin->fin_out, dpoff, ipoff;
+	char *ip;
+
+	if (m == NULL)
+		return NULL;
+
+	ipoff = (char *)ipin - MTOD(m, char *);
+	if (fin->fin_dp != NULL)
+		dpoff = (char *)fin->fin_dp - (char *)ipin;
+	else
+		dpoff = 0;
+
+	if (M_BLEN(m) < len) {
+# if SOLARIS
+		qif_t *qf = fin->fin_qif;
+		int inc = 0;
+
+		if (ipoff > 0) {
+			if ((ipoff & 3) != 0) {
+				inc = 4 - (ipoff & 3);
+				if (m->b_rptr - inc >= m->b_datap->db_base)
+					m->b_rptr -= inc;
+				else
+					inc = 0;
+			}
+		}
+		if (!pullupmsg(m, len + ipoff + inc)) {
+			ATOMIC_INCL(frstats[out].fr_pull[1]);
+			return NULL;
+		}
+		m->b_rptr += inc;
+		ATOMIC_INCL(frstats[out].fr_pull[0]);
+		qf->qf_data = MTOD(m, char *) + ipoff;
+# else
+		m = m_pullup(m, len);
+		*fin->fin_mp = m;
+		if (m == NULL) {
+			ATOMIC_INCL(frstats[out].fr_pull[1]);
+			return NULL;
+		}
+		ATOMIC_INCL(frstats[out].fr_pull[0]);
+# endif /* SOLARIS */
+	}
+	ip = MTOD(m, char *) + ipoff;
+	if (fin->fin_dp != NULL)
+		fin->fin_dp = (char *)ip + dpoff;
+	return ip;
+}
+#endif /* _KERNEL */
Index: contrib/ipfilter/fils.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/fils.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 fils.c
--- contrib/ipfilter/fils.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/fils.c	17 Jul 2004 04:55:54 -0000
@@ -99,7 +99,7 @@
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)fils.c	1.21 4/20/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.40 2002/12/06 11:40:20 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.45 2004/04/10 11:45:48 darrenr Exp $";
 #endif
 
 extern	char	*optarg;
@@ -117,6 +117,9 @@ static	char	*filters[4] = { "ipfilter(in
 int	opts = 0;
 int	use_inet6 = 0;
 int	live_kernel = 1;
+int	state_fd = -1;
+int	auth_fd = -1;
+int	ipf_fd = -1;
 
 #ifdef STATETOP
 #define	STSTRSIZE 	80
@@ -236,6 +239,21 @@ char *argv[];
 		}
 	optind = myoptind;
 
+	if (live_kernel == 1) {
+		if ((state_fd = open(IPL_STATE, O_RDONLY)) == -1) {
+			perror("open");
+			exit(-1);
+		}
+		if ((auth_fd = open(IPL_AUTH, O_RDONLY)) == -1) {
+			perror("open");
+			exit(-1);
+		}
+		if ((ipf_fd = open(device, O_RDONLY)) == -1) {
+			perror("open");
+			exit(-1);
+		}
+	}
+
 	if (kern != NULL || memf != NULL)
 	{
 		(void)setuid(getuid());
@@ -404,32 +422,20 @@ ipfrstat_t **ifrstpp;
 fr_authstat_t **frauthstpp;
 u_32_t *frfp;
 {
-	int fd;
-
-	if ((fd = open(device, O_RDONLY)) < 0) {
-		perror("open");
-		exit(-1);
-	}
 
-	if (!(opts & OPT_AUTHSTATS) && ioctl(fd, SIOCGETFS, fiopp) == -1) {
+	if (!(opts & OPT_AUTHSTATS) && ioctl(ipf_fd, SIOCGETFS, fiopp) == -1) {
 		perror("ioctl(ipf:SIOCGETFS)");
 		exit(-1);
 	}
 
 	if ((opts & OPT_IPSTATES)) {
-		int	sfd = open(IPL_STATE, O_RDONLY);
-
-		if (sfd == -1) {
-			perror("open");
-			exit(-1);
-		}
-		if ((ioctl(sfd, SIOCGETFS, ipsstpp) == -1)) {
+		if ((ioctl(state_fd, SIOCGETFS, ipsstpp) == -1)) {
 			perror("ioctl(state:SIOCGETFS)");
 			exit(-1);
 		}
-		close(sfd);
 	}
-	if ((opts & OPT_FRSTATES) && (ioctl(fd, SIOCGFRST, ifrstpp) == -1)) {
+	if ((opts & OPT_FRSTATES) &&
+	    (ioctl(ipf_fd, SIOCGFRST, ifrstpp) == -1)) {
 		perror("ioctl(SIOCGFRST)");
 		exit(-1);
 	}
@@ -438,15 +444,15 @@ u_32_t *frfp;
 		PRINTF("opts %#x name %s\n", opts, device);
 
 	if ((opts & OPT_AUTHSTATS) &&
-	    (ioctl(fd, SIOCATHST, frauthstpp) == -1)) {
+	    (ioctl(auth_fd, SIOCATHST, frauthstpp) == -1)) {
 		perror("ioctl(SIOCATHST)");
 		exit(-1);
 	}
 
-	if (ioctl(fd, SIOCGETFF, frfp) == -1)
+	if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1)
 		perror("ioctl(SIOCGETFF)");
 
-	return fd;
+	return ipf_fd;
 }
 
 
@@ -691,10 +697,10 @@ u_32_t frf;
 			fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl);
 	PRINTF(" log failures:\t\tinput %lu output %lu\n",
 			fp->f_st[0].fr_skip, fp->f_st[1].fr_skip);
-	PRINTF("fragment state(in):\tkept %lu\tlost %lu\n",
-			fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr);
-	PRINTF("fragment state(out):\tkept %lu\tlost %lu\n",
-			fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr);
+	PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n",
+			fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr, fp->f_st[0].fr_cfr);
+	PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n",
+			fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr, fp->f_st[1].fr_cfr);
 	PRINTF("packet state(in):\tkept %lu\tlost %lu\n",
 			fp->f_st[0].fr_ads, fp->f_st[0].fr_bads);
 	PRINTF("packet state(out):\tkept %lu\tlost %lu\n",
@@ -849,6 +855,8 @@ ips_stat_t *ipsp;
 			ipsp->iss_miss);
 		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 logged\n\t%lu log failures\n",
+			ipsp->iss_logged, ipsp->iss_logfail);
 		PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n",
 			ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin);
 		return;
@@ -875,7 +883,7 @@ void showqiflist(kern)
 char *kern;
 {
 	struct nlist qifnlist[2] = {
-		{ "qif_head" },
+		{ "_qif_head" },
 		{ NULL }
 	};
 	qif_t qif, *qf;
@@ -926,7 +934,7 @@ int topclosed;
 {
 	char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE];
 	int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT;
-	int i, j, sfd, winx, tsentry, maxx, maxy, redraw = 0;
+	int i, j, winx, tsentry, maxx, maxy, redraw = 0;
 	ipstate_t *istab[IPSTATE_SIZE], ips;
 	ips_stat_t ipsst, *ipsstp = &ipsst;
 	statetop_t *tstable = NULL, *tp;
@@ -941,12 +949,6 @@ int topclosed;
 	fd_set readfd;
 #endif
 
-	/* open state device */
-	if ((sfd = open(IPL_STATE, O_RDONLY)) == -1) {
-		perror("open");
-		exit(-1);
-	}
-
 	/* init ncurses stuff */
   	initscr();
   	cbreak();
@@ -961,7 +963,7 @@ int topclosed;
 
 		/* get state table */
 		bzero((char *)&ipsst, sizeof(&ipsst));
-		if ((ioctl(sfd, SIOCGETFS, &ipsstp) == -1)) {
+		if ((ioctl(state_fd, SIOCGETFS, &ipsstp) == -1)) {
 			perror("ioctl(SIOCGETFS)");
 			exit(-1);
 		}
@@ -1246,8 +1248,6 @@ int topclosed;
 		}
 	} /* while */
 
-	close(sfd);
-
 	printw("\n");
 	nocbreak();
 	endwin();
@@ -1279,6 +1279,7 @@ ipfrstat_t *ifsp;
 	/*
 	 * Print out the contents (if any) of the fragment cache table.
 	 */
+	PRINTF("\n");
 	for (i = 0; i < IPFT_SIZE; i++)
 		while (ipfrtab[i]) {
 			if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i],
@@ -1287,11 +1288,11 @@ ipfrstat_t *ifsp;
 			PRINTF("%s -> ", hostname(4, &ifr.ipfr_src));
 			if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule,
 				    sizeof(fr)) == -1)
-				break;
-			PRINTF("%s %d %d %d %#02x = %#x\n",
-				hostname(4, &ifr.ipfr_dst), ifr.ipfr_id,
-				ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos,
-				fr.fr_flags);
+				break; 
+			PRINTF("%s id %d ttl %d pr %d seen0 %d ifp %p tos %#02x = fl %#x\n",
+				hostname(4, &ifr.ipfr_dst), ntohs(ifr.ipfr_id),
+				ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_seen0, 
+				ifr.ipfr_ifp, ifr.ipfr_tos, fr.fr_flags);
 			ipfrtab[i] = ifr.ipfr_next;
 		}
 	if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab)))
Index: contrib/ipfilter/ip_fil.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_fil.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 ip_fil.c
--- contrib/ipfilter/ip_fil.c	6 Jan 2004 03:17:19 -0000	1.2
+++ contrib/ipfilter/ip_fil.c	17 Jul 2004 06:26:31 -0000
@@ -1020,8 +1020,8 @@ caddr_t data;
 			while ((f = *ftail))
 				ftail = &f->fr_next;
 		else {
+			ftail = fprev;
 			if (fp->fr_hits) {
-				ftail = fprev;
 				while (--fp->fr_hits && (f = *ftail))
 					ftail = &f->fr_next;
 			}
@@ -1275,7 +1275,7 @@ struct mbuf **mp;
 	frn.fin_ifp = fin->fin_ifp;
 	frn.fin_v = fin->fin_v;
 	frn.fin_out = fin->fin_out;
-	frn.fin_mp = fin->fin_mp;
+	frn.fin_mp = mp;
 
 	ip = mtod(m, ip_t *);
 	hlen = sizeof(*ip);
@@ -1319,9 +1319,11 @@ struct mbuf **mp;
 	m->m_pkthdr.rcvif = NULL;
 # endif
 
-	fr_makefrip(hlen, ip, &frn);
+	if (fr_makefrip(hlen, ip, &frn) == 0)
+		error = ipfr_fastroute(m, mp, &frn, NULL);
+	else
+		error = EINVAL;
 
-	error = ipfr_fastroute(m, mp, &frn, NULL);
 	return error;
 }
 
@@ -1454,7 +1456,13 @@ int dst;
 #endif
 
 	if (avail) {
+		slen = oip->ip_len;
+		oip->ip_len = htons(oip->ip_len);
+		soff = oip->ip_off;
+		oip->ip_off = htons(oip->ip_off);
 		bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
+		oip->ip_len = slen;
+		oip->ip_off = soff;
 		avail -= MIN(ohlen, avail);
 	}
 
@@ -1475,10 +1483,6 @@ int dst;
 	} else
 #endif
 	{
-		slen = oip->ip_len;
-		oip->ip_len = htons(oip->ip_len);
-		soff = oip->ip_off;
-		oip->ip_off = htons(ip->ip_off);
 
 		ip->ip_src.s_addr = dst4.s_addr;
 		ip->ip_dst.s_addr = oip->ip_src.s_addr;
@@ -1498,13 +1502,7 @@ int dst;
 	fin->fin_hlen = hlen;
 	err = send_ip(oip, fin, &m);
 	fin->fin_hlen = shlen;
-#ifdef	USE_INET6
-	if (fin->fin_v == 4)
-#endif
-	{
-		oip->ip_len = slen;
-		oip->ip_off = soff;
-	}
+
 	return err;
 }
 
@@ -1562,7 +1560,7 @@ frdest_t *fdp;
 	register struct ip *ip, *mhip;
 	register struct mbuf *m = m0;
 	register struct route *ro;
-	int len, off, error = 0, hlen, code;
+	int len, off, error = 0, hlen, code, sout;
 	struct ifnet *ifp, *sifp;
 	struct sockaddr_in *dst;
 	struct route iproute;
@@ -1628,7 +1626,7 @@ frdest_t *fdp;
 	/*
 	 * Route packet.
 	 */
-#if defined(__sgi) && (IRIX >= 605)
+#if (defined(IRIX) && (IRIX >= 605))
 	ROUTE_RDLOCK();
 #endif
 	bzero((caddr_t)ro, sizeof (*ro));
@@ -1647,8 +1645,12 @@ frdest_t *fdp;
 	 * check that we're going in the correct direction.
 	 */
 	if ((fr != NULL) && (fin->fin_rev != 0)) {
-		if ((ifp != NULL) && (fdp == &fr->fr_tif))
+		if ((ifp != NULL) && (fdp == &fr->fr_tif)) {
+# if (defined(IRIX) && (IRIX >= 605))
+			ROUTE_UNLOCK();
+# endif
 			return 0;
+		}
 	} else if (fdp != NULL) {
 		if (fdp->fd_ip.s_addr != 0)
 			dst->sin_addr = fdp->fd_ip;
@@ -1668,13 +1670,12 @@ frdest_t *fdp;
 	rtalloc(ro);
 # endif
 
-#if defined(__sgi) && (IRIX > 602)
-	ROUTE_UNLOCK();
-#endif
-
 	if (!ifp) {
 		if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
 			error = -2;
+# if (defined(IRIX) && (IRIX >= 605))
+			ROUTE_UNLOCK();
+# endif
 			goto bad;
 		}
 	}
@@ -1687,11 +1688,14 @@ frdest_t *fdp;
 			error = EHOSTUNREACH;
 		else
 			error = ENETUNREACH;
+# if (defined(IRIX) && (IRIX >= 605))
+			ROUTE_UNLOCK();
+# endif
 		goto bad;
 	}
 
 	if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
-#if BSD >= 199306
+#if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
 		dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
 #else
 		dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
@@ -1699,6 +1703,10 @@ frdest_t *fdp;
 	}
 	ro->ro_rt->rt_use++;
 
+#if (defined(IRIX) && (IRIX > 602))
+	ROUTE_UNLOCK();
+#endif
+
 	/*
 	 * For input packets which are being "fastrouted", they won't
 	 * go back through output filtering and miss their chance to get
@@ -1706,6 +1714,7 @@ frdest_t *fdp;
 	 */
 	if (fin->fin_out == 0) {
 		sifp = fin->fin_ifp;
+		sout = fin->fin_out;
 		fin->fin_ifp = ifp;
 		fin->fin_out = 1;
 		if ((fin->fin_fr = ipacct[1][fr_active]) &&
@@ -1715,10 +1724,25 @@ frdest_t *fdp;
 		fin->fin_fr = NULL;
 		if (!fr || !(fr->fr_flags & FR_RETMASK))
 			(void) fr_checkstate(ip, fin);
-		(void) ip_natout(ip, fin);
+
+		switch (ip_natout(ip, fin))
+		{
+		case 0 :
+			break;
+		case 1 :
+			ip->ip_sum = 0;
+			break;
+		case -1 :
+			error = EINVAL;
+			goto done;
+			break;
+		}
+
 		fin->fin_ifp = sifp;
+		fin->fin_out = sout;
 	} else
 		ip->ip_sum = 0;
+
 	/*
 	 * If small enough for interface, can just send directly.
 	 */
@@ -1748,8 +1772,14 @@ frdest_t *fdp;
 			ip->ip_sum = in_cksum(m, hlen);
 # endif /* __NetBSD__ && M_CSUM_IPv4 */
 # if	(BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
+#  ifdef IRIX
+		IFNET_UPPERLOCK(ifp);
+#  endif
 		error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
 					  ro->ro_rt);
+#  ifdef IRIX
+		IFNET_UPPERUNLOCK(ifp);
+#  endif
 # else
 		error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
 # endif
@@ -1895,7 +1925,7 @@ void *ifp;
 	dst->sin_family = AF_INET;
 	dst->sin_addr = ipa;
 # if    (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
-        !defined(__OpenBSD__)
+	!defined(__OpenBSD__)
 #  ifdef        RTF_CLONING
 	rtalloc_ign(&iproute, RTF_CLONING);
 #  else
@@ -1947,17 +1977,18 @@ frdest_t *fdp;
 	u_long mtu;
 	int error;
 
-	ifp = NULL;
 	ro = &ip6route;
 	fr = fin->fin_fr;
 	bzero((caddr_t)ro, sizeof(*ro));
 	dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
 	dst6->sin6_family = AF_INET6;
 	dst6->sin6_len = sizeof(struct sockaddr_in6);
-	dst6->sin6_addr = fin->fin_fi.fi_src.in6;
+	dst6->sin6_addr = fin->fin_fi.fi_dst.in6;
 
 	if (fdp != NULL)
 		ifp = fdp->fd_ifp;
+	else
+		ifp = fin->fin_ifp;
 
 	if ((fr != NULL) && (fin->fin_rev != 0)) {
 		if ((ifp != NULL) && (fdp == &fr->fr_tif))
@@ -1966,9 +1997,14 @@ frdest_t *fdp;
 		if (IP6_NOTZERO(&fdp->fd_ip6))
 			dst6->sin6_addr = fdp->fd_ip6.in6;
 	}
-	if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
+	if (ifp == NULL)
 		return -2;
 
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
+	/* KAME */
+	if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr))
+		dst6->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+#endif
 	rtalloc((struct route *)ro);
 
 	if ((ifp == NULL) && (ro->ro_rt != NULL))
Index: contrib/ipfilter/ip_frag.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_frag.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_frag.c
--- contrib/ipfilter/ip_frag.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_frag.c	17 Jul 2004 06:16:23 -0000
@@ -149,7 +149,7 @@ ipfr_t *table[];
 	if (ipfr_inuse >= IPFT_SIZE)
 		return NULL;
 
-	if (!(fin->fin_fl & FI_FRAG))
+	if (!(fin->fin_fi.fi_fl & FI_FRAG))
 		return NULL;
 
 	frag.ipfr_p = ip->ip_p;
@@ -195,7 +195,7 @@ ipfr_t *table[];
 
 
 	/*
-	 * Instert the fragment into the fragment table, copy the struct used
+	 * Insert the fragment into the fragment table, copy the struct used
 	 * in the search using bcopy rather than reassign each field.
 	 * Set the ttl to the default.
 	 */
@@ -276,8 +276,8 @@ fr_info_t *fin;
 ipfr_t *table[];
 {
 	ipfr_t	*f, frag;
-	u_int idx;
- 
+	u_int	idx;
+
 	/*
 	 * For fragments, we record protocol, packet id, TOS and both IP#'s
 	 * (these should all be the same for all fragments of a packet).
@@ -423,7 +423,26 @@ fr_info_t *fin;
 /*
  * forget any references to this external object.
  */
-void ipfr_forget(nat)
+void ipfr_forget(ptr)
+void *ptr;
+{
+	ipfr_t	*fr;
+	int	idx;
+
+	WRITE_ENTER(&ipf_frag);
+	for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
+		for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+			if (fr->ipfr_data == ptr)
+				fr->ipfr_data = NULL;
+
+	RWLOCK_EXIT(&ipf_frag);
+}
+
+
+/*
+ * forget any references to this external object.
+ */
+void ipfr_forgetnat(nat)
 void *nat;
 {
 	ipfr_t	*fr;
@@ -431,7 +450,7 @@ void *nat;
 
 	WRITE_ENTER(&ipf_natfrag);
 	for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
-		for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+		for (fr = ipfr_nattab[idx]; fr; fr = fr->ipfr_next)
 			if (fr->ipfr_data == nat)
 				fr->ipfr_data = NULL;
 
Index: contrib/ipfilter/ip_ftp_pxy.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_ftp_pxy.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_ftp_pxy.c
--- contrib/ipfilter/ip_ftp_pxy.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_ftp_pxy.c	17 Jul 2004 06:16:23 -0000
@@ -1,8 +1,7 @@
 /*
  * Simple FTP transparent proxy for in-kernel use.  For use with the NAT
  * code.
- *
- * $Id: ip_ftp_pxy.c,v 2.7.2.42 2002/11/25 21:42:35 darrenr Exp $
+ * $FreeBSD: src/contrib/ipfilter/Attic/ip_ftp_pxy.c,v 1.1.1.5.2.9 2004/07/05 17:06:31 darrenr Exp $
  */
 #if SOLARIS && defined(_KERNEL)
 extern	kmutex_t	ipf_rw;
@@ -121,7 +120,7 @@ int dlen;
 	int inc, off;
 	nat_t *ipn;
 	mb_t *m;
-#if	SOLARIS
+#if	SOLARIS && defined(_KERNEL)
 	mb_t *m1;
 #endif
 
@@ -207,8 +206,13 @@ int dlen;
 	a1 >>= 24;
 	olen = s - f->ftps_rptr;
 	/* DO NOT change this to snprintf! */
+#if defined(OpenBSD) && (200311 >= 200311)
+	(void) snprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
+		        "PORT", a1, a2, a3, a4, a5, a6);
+#else
 	(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
 		       "PORT", a1, a2, a3, a4, a5, a6);
+#endif
 
 	nlen = strlen(newbuf);
 	inc = nlen - olen;
@@ -221,7 +225,7 @@ int dlen;
 	}
 
 #if !defined(_KERNEL)
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	bcopy(newbuf, (char *)m + off, nlen);
 #else
 # if SOLARIS
@@ -251,7 +255,7 @@ int dlen;
 	}
 	copyin_mblk(m, off, nlen, newbuf);
 # else
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	if (inc < 0)
 		m_adj(m, inc);
 	/* the mbuf chain will be extended if necessary by m_copyback() */
@@ -263,7 +267,7 @@ int dlen;
 # endif
 #endif
 	if (inc != 0) {
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
 		register u_32_t	sum1, sum2;
 
 		sum1 = ip->ip_len;
@@ -542,7 +546,7 @@ int dlen;
 		return 0;
 
 #if !defined(_KERNEL)
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	m_copyback(m, off, nlen, newbuf);
 #else
 # if SOLARIS
@@ -569,7 +573,7 @@ int dlen;
 	}
 	/*copyin_mblk(m, off, nlen, newbuf);*/
 # else /* SOLARIS */
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	if (inc < 0)
 		m_adj(m, inc);
 	/* the mbuf chain will be extended if necessary by m_copyback() */
@@ -577,7 +581,7 @@ int dlen;
 # endif /* SOLARIS */
 #endif /* _KERNEL */
 	if (inc != 0) {
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
 		register u_32_t	sum1, sum2;
 
 		sum1 = ip->ip_len;
@@ -714,7 +718,8 @@ size_t len;
 
 	if (i < 5) {
 #if !defined(_KERNEL) && !defined(KERNEL)
-		fprintf(stdout, "ippr_ftp_client_valid:i(%d) < 5\n", i);
+		fprintf(stdout, "ippr_ftp_client_valid:i(%lu) < 5\n",
+			(u_long)i);
 #endif
 		return 2;
 	}
@@ -750,8 +755,8 @@ size_t len;
 bad_client_command:
 #if !defined(_KERNEL) && !defined(KERNEL)
 		fprintf(stdout,
-			"ippr_ftp_client_valid:bad cmd:len %d i %d c 0x%x\n",
-			i, len, c);
+			"ippr_ftp_client_valid:bad cmd:len %lu i %lu c 0x%x\n",
+			(u_long)i, (u_long)len, c);
 #endif
 		return 1;
 	}
@@ -812,8 +817,8 @@ size_t len;
 bad_server_command:
 #if !defined(_KERNEL) && !defined(KERNEL)
 		fprintf(stdout,
-			"ippr_ftp_server_valid:bad cmd:len %d i %d c 0x%x\n",
-			i, len, c);
+			"ippr_ftp_server_valid:bad cmd:len %lu i %lu c 0x%x\n",
+			(u_long)i, (u_long)len, c);
 #endif
 		return 1;
 	}
@@ -875,7 +880,7 @@ int rv;
 #if	SOLARIS && defined(_KERNEL)
 	m = fin->fin_qfm;
 #else
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 #endif
 
 #ifndef	_KERNEL
@@ -1025,9 +1030,9 @@ int rv;
 		printf("inc %d sel %d rv %d\n", inc, sel, rv);
 		printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0],
 			f->ftps_seq[1]);
-		printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
+		printf("ackmin %x ackoff %d\n", (u_int)aps->aps_ackmin[sel],
 			aps->aps_ackoff[sel]);
-		printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
+		printf("seqmin %x seqoff %d\n", (u_int)aps->aps_seqmin[sel],
 			aps->aps_seqoff[sel]);
 #endif
 
Index: contrib/ipfilter/ip_log.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_log.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 ip_log.c
--- contrib/ipfilter/ip_log.c	6 Jan 2004 03:17:19 -0000	1.2
+++ contrib/ipfilter/ip_log.c	17 Jul 2004 06:16:23 -0000
@@ -14,9 +14,14 @@
 # include "opt_ipfilter_log.h"
 #endif
 #ifdef  __FreeBSD__
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-#  if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
-#   include "opt_ipfilter.h"
+# if defined(IPFILTER_LKM) || defined(_KERNEL)
+#  if !defined(__FreeBSD_version) 
+#   include <sys/osreldate.h>
+#  endif
+#  if !defined(IPFILTER_LKM)
+#   if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
+#    include "opt_ipfilter.h"
+#   endif
 #  endif
 # else
 #  ifdef KLD_MODULE
@@ -30,7 +35,7 @@
 #  endif
 # endif
 #endif
-#ifdef	IPFILTER_LOG
+#ifdef  IPFILTER_LOG
 # ifndef SOLARIS
 #  define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
 # endif
@@ -241,7 +246,7 @@ mb_t *m;
 	 */
 	bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
 # if SOLARIS && defined(_KERNEL)
-	ipfl.fl_unit = (u_char)ifp->ill_ppa;
+	ipfl.fl_unit = (u_int)ifp->ill_ppa;
 	bcopy(ifp->ill_name, ipfl.fl_ifname,
 	      MIN(ifp->ill_name_length, sizeof(ipfl.fl_ifname)));
 	mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
@@ -250,7 +255,7 @@ mb_t *m;
 	(defined(OpenBSD) && (OpenBSD >= 199603)) || defined(__DragonFly__)
 	strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
 #  else
-	ipfl.fl_unit = (u_char)ifp->if_unit;
+	ipfl.fl_unit = (u_int)ifp->if_unit;
 	strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
 						  sizeof(ifp->if_name)));
 #  endif
@@ -312,7 +317,7 @@ int *types, cnt;
 	 * rather than create a new one.
 	 */
 	MUTEX_ENTER(&ipl_mutex);
-	if (fin != NULL) {
+	if ((fin != NULL) && (fin->fin_off == 0)) {
 		if ((ipll[dev] != NULL) &&
 		    bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
 			ipll[dev]->ipl_count++;
@@ -428,7 +433,7 @@ struct uio *uio;
 	SPL_NET(s);
 	MUTEX_ENTER(&ipl_mutex);
 
-	while (!iplused[unit] || !iplt[unit]) {
+	while (iplt[unit] == NULL) {
 # if SOLARIS && defined(_KERNEL)
 		if (!cv_wait_sig(&iplwait, &ipl_mutex)) {
 			MUTEX_EXIT(&ipl_mutex);
Index: contrib/ipfilter/ip_nat.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_nat.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_nat.c
--- contrib/ipfilter/ip_nat.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_nat.c	17 Jul 2004 06:16:23 -0000
@@ -115,6 +115,7 @@ static const char rcsid[] = "@(#)$Id: ip
 nat_t	**nat_table[2] = { NULL, NULL },
 	*nat_instances = NULL;
 ipnat_t	*nat_list = NULL;
+u_int	ipf_nattable_max = NAT_TABLE_MAX;
 u_int	ipf_nattable_sz = NAT_TABLE_SZ;
 u_int	ipf_natrules_sz = NAT_SIZE;
 u_int	ipf_rdrrules_sz = RDR_SIZE;
@@ -431,7 +432,7 @@ int mode;
 	u_32_t i, j;
 
 #if (BSD >= 199306) && defined(_KERNEL)
-	if ((securelevel >= 2) && (mode & FWRITE))
+	if ((securelevel >= 3) && (mode & FWRITE))
 		return EPERM;
 #endif
 
@@ -778,6 +779,8 @@ caddr_t data;
 	if ((aps != NULL) && (aps->aps_data != 0)) {
 		ng.ng_sz += sizeof(ap_session_t);
 		ng.ng_sz += aps->aps_psiz;
+		if (aps->aps_psiz > 4)	/* XXX - sizeof(ipn_data) */
+			ng.ng_sz -= 4;
 	}
 
 	error = IWCOPY((caddr_t)&ng, data, sizeof(ng));
@@ -793,6 +796,7 @@ caddr_t data;
 	nat_save_t ipn, *ipnp, *ipnn = NULL;
 	register nat_t *n, *nat;
 	ap_session_t *aps;
+	size_t dsz;
 	int error;
 
 	error = IRCOPY(data, (caddr_t)&ipnp, sizeof(ipnp));
@@ -824,7 +828,6 @@ caddr_t data;
 	}
 
 	ipn.ipn_next = nat->nat_next;
-	ipn.ipn_dsize = 0;
 	bcopy((char *)nat, (char *)&ipn.ipn_nat, sizeof(ipn.ipn_nat));
 	ipn.ipn_nat.nat_data = NULL;
 
@@ -838,10 +841,13 @@ caddr_t data;
 		      sizeof(ipn.ipn_rule));
 
 	if ((aps = nat->nat_aps)) {
-		ipn.ipn_dsize = sizeof(*aps);
+		dsz = sizeof(*aps);
 		if (aps->aps_data)
-			ipn.ipn_dsize += aps->aps_psiz;
-		KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
+			dsz += aps->aps_psiz;
+		ipn.ipn_dsize = dsz;
+		if (dsz > sizeof(ipn.ipn_data))
+			dsz -= sizeof(ipn.ipn_data);
+		KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + dsz);
 		if (ipnn == NULL)
 			return ENOMEM;
 		bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
@@ -850,14 +856,14 @@ caddr_t data;
 		if (aps->aps_data) {
 			bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
 			      aps->aps_psiz);
-			ipnn->ipn_dsize += aps->aps_psiz;
 		}
 		error = IWCOPY((caddr_t)ipnn, ipnp,
-			       sizeof(ipn) + ipn.ipn_dsize);
+			       sizeof(ipn) + dsz);
 		if (error)
 			error = EFAULT;
-		KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize);
+		KFREES(ipnn, sizeof(*ipnn) + dsz);
 	} else {
+		ipn.ipn_dsize = 0;
 		error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
 		if (error)
 			error = EFAULT;
@@ -885,12 +891,12 @@ caddr_t data;
 		return EFAULT;
 	nat = NULL;
 	if (ipn.ipn_dsize) {
-		KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize);
+		KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
 		if (ipnn == NULL)
 			return ENOMEM;
 		bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
-		error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data,
-			       ipn.ipn_dsize);
+		error = IRCOPY((caddr_t)ipnp + offsetof(nat_save_t, ipn_data),
+			       (caddr_t)ipnn->ipn_data, ipn.ipn_dsize);
 		if (error) {
 			error = EFAULT;
 			goto junkput;
@@ -1065,7 +1071,7 @@ struct nat *natd;
 	 * If there's a fragment table entry too for this nat entry, then
 	 * dereference that as well.
 	 */
-	ipfr_forget((void *)natd);
+	ipfr_forgetnat((void *)natd);
 	aps_free(natd->nat_aps);
 	nat_stats.ns_inuse--;
 	KFREE(natd);
@@ -1163,6 +1169,11 @@ int direction;
 	qif_t *qf = fin->fin_qif;
 #endif
 
+	if (nat_stats.ns_inuse >= ipf_nattable_max) {
+		nat_stats.ns_memfail++;
+		return NULL;
+	}
+
 	nflags = flags & np->in_flags;
 	if (flags & IPN_TCPUDP) {
 		tcp = (tcphdr_t *)fin->fin_dp;
@@ -1174,6 +1185,17 @@ int direction;
 	KMALLOC(nat, nat_t *);
 	if (nat == NULL) {
 		nat_stats.ns_memfail++;
+		/*
+		 * Try to automatically tune the max # of entries in the
+		 * table allowed to be less than what will cause kmem_alloc()
+		 * to fail and try to eliminate panics due to out of memory
+		 * conditions arising.
+		 */
+		if (ipf_nattable_max > ipf_nattable_sz) {
+			ipf_nattable_max = nat_stats.ns_inuse - 100;
+			printf("ipf_nattable_max reduced to %d\n",
+				ipf_nattable_max);
+		}
 		return NULL;
 	}
 
@@ -1430,7 +1452,7 @@ int direction;
 	CALC_SUMD(sum1, sum2, sumd);
 	nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
 #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
-	if ((flags & IPN_TCPUDP) && dohwcksum &&
+	if ((flags & IPN_TCP) && dohwcksum &&
 	    (qf->qf_ill->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
 		if (direction == NAT_OUTBOUND)
 			sum1 = LONG_SUM(ntohl(in.s_addr));
@@ -1682,6 +1704,7 @@ int dir;
 		return NULL;
 
 	flags = 0;
+	sumd2 = 0;
 	*nflags = IPN_ICMPERR;
 	icmp = (icmphdr_t *)fin->fin_dp;
 	oip = (ip_t *)&icmp->icmp_ip;
@@ -1735,137 +1758,75 @@ int dir;
 
 	CALC_SUMD(sum1, sum2, sumd);
 
-	if (nat->nat_dir == NAT_OUTBOUND) {
-		/*
-		 * Fix IP checksum of the offending IP packet to adjust for
-		 * the change in the IP address.
-		 *
-		 * Normally, you would expect that the ICMP checksum of the 
-		 * ICMP error message needs to be adjusted as well for the
-		 * IP address change in oip.
-		 * However, this is a NOP, because the ICMP checksum is 
-		 * calculated over the complete ICMP packet, which includes the
-		 * changed oip IP addresses and oip->ip_sum. However, these 
-		 * two changes cancel each other out (if the delta for
-		 * the IP address is x, then the delta for ip_sum is minus x), 
-		 * so no change in the icmp_cksum is necessary.
-		 *
-		 * Be careful that nat_dir refers to the direction of the
-		 * offending IP packet (oip), not to its ICMP response (icmp)
-		 */
-		fix_datacksum(&oip->ip_sum, sumd);
+	/*
+	 * Fix IP checksum of the offending IP packet to adjust for
+	 * the change in the IP address.
+	 *
+	 * Normally, you would expect that the ICMP checksum of the 
+	 * ICMP error message needs to be adjusted as well for the
+	 * IP address change in oip.
+	 * However, this is a NOP, because the ICMP checksum is 
+	 * calculated over the complete ICMP packet, which includes the
+	 * changed oip IP addresses and oip->ip_sum. However, these 
+	 * two changes cancel each other out (if the delta for
+	 * the IP address is x, then the delta for ip_sum is minus x), 
+	 * so no change in the icmp_cksum is necessary.
+	 *
+	 * Be careful that nat_dir refers to the direction of the
+	 * offending IP packet (oip), not to its ICMP response (icmp)
+	 */
+	fix_datacksum(&oip->ip_sum, sumd);
+	/* Fix icmp cksum : IP Addr + Cksum */
 
+	/*
+	 * Fix UDP pseudo header checksum to compensate for the
+	 * IP address change.
+	 */
+	if ((oip->ip_p == IPPROTO_UDP) && (dlen >= 8) && udp->uh_sum) {
 		/*
-		 * Fix UDP pseudo header checksum to compensate for the
-		 * IP address change.
+		 * The UDP checksum is optional, only adjust it 
+		 * if it has been set.
 		 */
-		if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-			/*
-			 * The UDP checksum is optional, only adjust it 
-			 * if it has been set.
-			 */
-			sum1 = ntohs(udp->uh_sum);
-			fix_datacksum(&udp->uh_sum, sumd);
-			sum2 = ntohs(udp->uh_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the UDP 
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
+		sum1 = ntohs(udp->uh_sum);
+		fix_datacksum(&udp->uh_sum, sumd);
+		sum2 = ntohs(udp->uh_sum);
 
 		/*
-		 * Fix TCP pseudo header checksum to compensate for the 
-		 * IP address change. Before we can do the change, we
-		 * must make sure that oip is sufficient large to hold
-		 * the TCP checksum (normally it does not!).
+		 * Fix ICMP checksum to compensate the UDP 
+		 * checksum adjustment.
 		 */
-		if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-		
-			sum1 = ntohs(tcp->th_sum);
-			fix_datacksum(&tcp->th_sum, sumd);
-			sum2 = ntohs(tcp->th_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the TCP 
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
-	} else {
+		sumd2 = sumd << 1;
+		CALC_SUMD(sum1, sum2, sumd);
+		sumd2 += sumd;
+	}
 
-		/*
-		 * Fix IP checksum of the offending IP packet to adjust for
-		 * the change in the IP address.
-		 *
-		 * Normally, you would expect that the ICMP checksum of the 
-		 * ICMP error message needs to be adjusted as well for the
-		 * IP address change in oip.
-		 * However, this is a NOP, because the ICMP checksum is 
-		 * calculated over the complete ICMP packet, which includes the
-		 * changed oip IP addresses and oip->ip_sum. However, these 
-		 * two changes cancel each other out (if the delta for
-		 * the IP address is x, then the delta for ip_sum is minus x), 
-		 * so no change in the icmp_cksum is necessary.
-		 *
-		 * Be careful that nat_dir refers to the direction of the
-		 * offending IP packet (oip), not to its ICMP response (icmp)
-		 */
-		fix_datacksum(&oip->ip_sum, sumd);
+	/*
+	 * Fix TCP pseudo header checksum to compensate for the 
+	 * IP address change. Before we can do the change, we
+	 * must make sure that oip is sufficient large to hold
+	 * the TCP checksum (normally it does not!).
+	 */
+	else if ((oip->ip_p == IPPROTO_TCP) && (dlen >= 18)) {
+		sum1 = ntohs(tcp->th_sum);
+		fix_datacksum(&tcp->th_sum, sumd);
+		sum2 = ntohs(tcp->th_sum);
 
-/* XXX FV : without having looked at Solaris source code, it seems unlikely
- * that SOLARIS would compensate this in the kernel (a body of an IP packet 
- * in the data section of an ICMP packet). I have the feeling that this should
- * be unconditional, but I'm not in a position to check.
- */
-#if !SOLARIS && !defined(__sgi)
 		/*
-		 * Fix UDP pseudo header checksum to compensate for the
-		 * IP address change.
+		 * Fix ICMP checksum to compensate the TCP 
+		 * checksum adjustment.
 		 */
-		if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-			/*
-			 * The UDP checksum is optional, only adjust it 
-			 * if it has been set 
-			 */
-			sum1 = ntohs(udp->uh_sum);
-			fix_datacksum(&udp->uh_sum, sumd);
-			sum2 = ntohs(udp->uh_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the UDP 
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
-		
-		/* 
-		 * Fix TCP pseudo header checksum to compensate for the 
-		 * IP address change. Before we can do the change, we
-		 * must make sure that oip is sufficient large to hold
-		 * the TCP checksum (normally it does not!).
-		 */
-		if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-		
-			sum1 = ntohs(tcp->th_sum);
-			fix_datacksum(&tcp->th_sum, sumd);
-			sum2 = ntohs(tcp->th_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the TCP
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
-#endif
+		sumd2 = sumd << 1;
+		CALC_SUMD(sum1, sum2, sumd);
+		sumd2 += sumd;
+	} else {
+		sumd2 = (sumd >> 16); 
+		if (nat->nat_dir == NAT_OUTBOUND)
+			sumd2 = ~sumd2;
+		else
+			sumd2 = ~sumd2 + 1;
 	}
 
-	if ((flags & IPN_TCPUDP) != 0) {
+	if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) {
 		/*
 		 * Step 2 :
 		 * For offending TCP/UDP IP packets, translate the ports as
@@ -1885,17 +1846,14 @@ int dir;
 		 * include the TCP checksum. So we have to check if the
 		 * ip->ip_len actually holds the TCP checksum of the oip!
 		 */
-
 		if (nat->nat_oport == tcp->th_dport) {
 			if (tcp->th_sport != nat->nat_inport) {
 				/*
 				 * Fix ICMP checksum to compensate port
 				 * adjustment.
 				 */
-				sum1 = ntohs(tcp->th_sport);
-				sum2 = ntohs(nat->nat_inport);
-				CALC_SUMD(sum1, sum2, sumd);
-				sumd2 += sumd;
+				sum1 = ntohs(nat->nat_inport);
+				sum2 = ntohs(tcp->th_sport);
 				tcp->th_sport = nat->nat_inport;
 
 				/*
@@ -1907,16 +1865,18 @@ int dir;
 				 * The UDP checksum is optional, only adjust
 				 * it if it has been set.
 				 */
-				if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
+				if ((oip->ip_p == IPPROTO_UDP) &&
+				    (dlen >= 8) && udp->uh_sum) {
+					sumd = sum1 - sum2;
+					sumd2 += sumd;
 
 					sum1 = ntohs(udp->uh_sum);
 					fix_datacksum(&udp->uh_sum, sumd);
 					sum2 = ntohs(udp->uh_sum);
 
 					/*
-					 * Fix ICMP checksum to 
-					 * compensate UDP checksum 
-					 * adjustment.
+					 * Fix ICMP checksum to compensate
+					 * UDP checksum adjustment.
 					 */
 					CALC_SUMD(sum1, sum2, sumd);
 					sumd2 += sumd;
@@ -1928,63 +1888,73 @@ int dir;
 				 * packet flows the other direction compared to
 				 * the ICMP message.
 				 */
-				if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-
-					sum1 = ntohs(tcp->th_sum);
-					fix_datacksum(&tcp->th_sum, sumd);
-					sum2 = ntohs(tcp->th_sum);
-
-					/*
-					 * Fix ICMP checksum to 
-					 * compensate TCP checksum 
-					 * adjustment.
-					 */
-					CALC_SUMD(sum1, sum2, sumd);
-					sumd2 += sumd;
+				if (oip->ip_p == IPPROTO_TCP) {
+					if (dlen >= 18) {
+						sumd = sum1 - sum2;
+						sumd2 += sumd;
+
+						sum1 = ntohs(tcp->th_sum);
+						fix_datacksum(&tcp->th_sum,
+							      sumd);
+						sum2 = ntohs(tcp->th_sum);
+
+						/*
+						 * Fix ICMP checksum to 
+						 * compensate TCP checksum 
+						 * adjustment.
+						 */
+						CALC_SUMD(sum1, sum2, sumd);
+						sumd2 += sumd;
+					} else {
+						sumd = sum2 - sum1 + 1;
+						sumd2 += sumd;
+					}
 				}
 			}
-		} else {
-			if (tcp->th_dport != nat->nat_outport) {
-				/*
-				 * Fix ICMP checksum to compensate port
-				 * adjustment.
-				 */
-				sum1 = ntohs(tcp->th_dport);
-				sum2 = ntohs(nat->nat_outport);
-				CALC_SUMD(sum1, sum2, sumd);
+		} else if (tcp->th_dport != nat->nat_outport) {
+			/*
+			 * Fix ICMP checksum to compensate port
+			 * adjustment.
+			 */
+			sum1 = ntohs(nat->nat_outport);
+			sum2 = ntohs(tcp->th_dport);
+			tcp->th_dport = nat->nat_outport;
+
+			/*
+			 * Fix udp checksum to compensate port
+			 * adjustment.   NOTE : the offending IP
+			 * packet flows the other direction compared
+			 * to the ICMP message.
+			 *
+			 * The UDP checksum is optional, only adjust
+			 * it if it has been set.
+			 */
+			if ((oip->ip_p == IPPROTO_UDP) &&
+			    (dlen >= 8) && udp->uh_sum) {
+				sumd = sum1 - sum2;
 				sumd2 += sumd;
-				tcp->th_dport = nat->nat_outport;
+
+				sum1 = ntohs(udp->uh_sum);
+				fix_datacksum(&udp->uh_sum, sumd);
+				sum2 = ntohs(udp->uh_sum);
 
 				/*
-				 * Fix udp checksum to compensate port
-				 * adjustment.   NOTE : the offending IP
-				 * packet flows the other direction compared
-				 * to the ICMP message.
-				 *
-				 * The UDP checksum is optional, only adjust
-				 * it if it has been set.
+				 * Fix ICMP checksum to compensate
+				 * UDP checksum adjustment.
 				 */
-				if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-
-					sum1 = ntohs(udp->uh_sum);
-					fix_datacksum(&udp->uh_sum, sumd);
-					sum2 = ntohs(udp->uh_sum);
+				CALC_SUMD(sum1, sum2, sumd);
+			}
 
-					/*
-					 * Fix ICMP checksum to compensate
-					 * UDP checksum adjustment.
-					 */
-					CALC_SUMD(sum1, sum2, sumd);
+			/*
+			 * Fix tcp checksum (if present) to compensate
+			 * port adjustment. NOTE : the offending IP
+			 * packet flows the other direction compared to
+			 * the ICMP message.
+			 */
+			if (oip->ip_p == IPPROTO_TCP) {
+				if (dlen >= 18) {
+					sumd = sum1 - sum2;
 					sumd2 += sumd;
-				}
-
-				/*
-				 * Fix tcp checksum (if present) to compensate
-				 * port adjustment. NOTE : the offending IP
-				 * packet flows the other direction compared to
-				 * the ICMP message.
-				 */
-				if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
 
 					sum1 = ntohs(tcp->th_sum);
 					fix_datacksum(&tcp->th_sum, sumd);
@@ -1995,18 +1965,18 @@ int dir;
 					 * UDP checksum adjustment.
 					 */
 					CALC_SUMD(sum1, sum2, sumd);
-					sumd2 += sumd;
+				} else {
+					sumd = sum2 - sum1;
+					if (nat->nat_dir == NAT_OUTBOUND)
+						sumd++;
 				}
 			}
+			sumd2 += sumd;
 		}
 		if (sumd2) {
 			sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
 			sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
-			if (nat->nat_dir == NAT_OUTBOUND) {
-				fix_outcksum(fin, &icmp->icmp_cksum, sumd2);
-			} else {
-				fix_incksum(fin, &icmp->icmp_cksum, sumd2);
-			}
+			fix_incksum(fin, &icmp->icmp_cksum, sumd2);
 		}
 	}
 	if (oip->ip_p == IPPROTO_ICMP)
@@ -2476,13 +2446,9 @@ maskloop:
 			s1 = LONG_SUM(ntohl(fin->fin_saddr));
 			s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
 			CALC_SUMD(s1, s2, sumd);
-
-			if (nat->nat_dir == NAT_OUTBOUND)
-				fix_outcksum(fin, &ip->ip_sum, sumd);
-			else
-				fix_incksum(fin, &ip->ip_sum, sumd);
+			fix_outcksum(fin, &ip->ip_sum, sumd);
 		}
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) || !defined(_KERNEL)
 		else {
 			if (nat->nat_dir == NAT_OUTBOUND)
 				fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
@@ -2510,7 +2476,8 @@ maskloop:
 				if (nat->nat_age < fr_defnaticmpage)
 					nat->nat_age = fr_defnaticmpage;
 #ifdef LARGE_NAT
-				else if (nat->nat_age > fr_defnatage)
+				else if ((!np || !np->in_age[1]) &&
+				         (nat->nat_age > fr_defnatage))
 					nat->nat_age = fr_defnatage;
 #endif
 				/*
@@ -2703,19 +2670,19 @@ maskloop:
 		nat->nat_bytes += ip->ip_len;
 		nat->nat_pkts++;
 		MUTEX_EXIT(&nat->nat_lock);
-		ip->ip_dst = nat->nat_inip;
-		fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
 
 		/*
 		 * Fix up checksums, not by recalculating them, but
 		 * simply computing adjustments.
 		 */
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
 		if (nat->nat_dir == NAT_OUTBOUND)
 			fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
 		else
 			fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
-#endif
+
+		ip->ip_dst = nat->nat_inip;
+		fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
+
 		if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
 
 			if ((nat->nat_inport != 0) && (tcp != NULL)) {
@@ -2731,7 +2698,8 @@ maskloop:
 				if (nat->nat_age < fr_defnaticmpage)
 					nat->nat_age = fr_defnaticmpage;
 #ifdef LARGE_NAT
-				else if (nat->nat_age > fr_defnatage)
+				else if ((!np || !np->in_age[0]) &&
+					 (nat->nat_age > fr_defnatage))
 					nat->nat_age = fr_defnatage;
 #endif
 				/*
@@ -2983,7 +2951,7 @@ u_short *csump;
 			if (&cp[1] >= ep)
 				break;
 			advance = cp[1];
-			if (&cp[advance] >= ep)
+			if (&cp[advance] > ep)
 				break;
 			switch (opt) {
 			case TCPOPT_MAXSEG:
Index: contrib/ipfilter/ip_raudio_pxy.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_raudio_pxy.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_raudio_pxy.c
--- contrib/ipfilter/ip_raudio_pxy.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_raudio_pxy.c	17 Jul 2004 06:16:23 -0000
@@ -66,9 +66,6 @@ nat_t *nat;
 	tcphdr_t *tcp;
 	int len = 0;
 	mb_t *m;
-#if	SOLARIS
-	mb_t *m1;
-#endif
 
 	/*
 	 * If we've already processed the start messages, then nothing left
@@ -181,9 +178,6 @@ nat_t *nat;
 	nat_t *ipn;
 	u_char swp;
 	mb_t *m;
-#if	SOLARIS
-	mb_t *m1;
-#endif
 
 	/*
 	 * Wait until we've seen the end of the start messages and even then
Index: contrib/ipfilter/ip_rcmd_pxy.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_rcmd_pxy.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_rcmd_pxy.c
--- contrib/ipfilter/ip_rcmd_pxy.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_rcmd_pxy.c	17 Jul 2004 06:16:23 -0000
@@ -88,9 +88,6 @@ nat_t *nat;
 	u_short sp;
 	nat_t *ipn;
 	mb_t *m;
-#if	SOLARIS
-	mb_t *m1;
-#endif
 
 	tcp = (tcphdr_t *)fin->fin_dp;
 
Index: contrib/ipfilter/ip_sfil.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_sfil.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_sfil.c
--- contrib/ipfilter/ip_sfil.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_sfil.c	17 Jul 2004 04:55:54 -0000
@@ -7,7 +7,7 @@
  */
 #if !defined(lint)
 static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.24 2002/12/06 11:42:22 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.27 2003/06/12 16:03:14 darrenr Exp $";
 #endif
 
 #include <sys/types.h>
@@ -623,8 +623,8 @@ caddr_t data;
 			while ((f = *ftail))
 				ftail = &f->fr_next;
 		else {
+			ftail = fprev;
 			if (fp->fr_hits) {
-				ftail = fprev;
 				while (--fp->fr_hits && (f = *ftail))
 					ftail = &f->fr_next;
 			}
@@ -785,15 +785,14 @@ fr_info_t *fin;
 	tcp2->th_sport = tcp->th_dport;
 	if (tcp->th_flags & TH_ACK) {
 		tcp2->th_seq = tcp->th_ack;
-		tcp2->th_flags = TH_RST|TH_ACK;
+		tcp2->th_flags = TH_RST;
 	} else {
 		tcp2->th_ack = ntohl(tcp->th_seq);
 		tcp2->th_ack += tlen;
 		tcp2->th_ack = htonl(tcp2->th_ack);
-		tcp2->th_flags = TH_RST;
+		tcp2->th_flags = TH_RST|TH_ACK;
 	}
 	tcp2->th_off = sizeof(struct tcphdr) >> 2;
-	tcp2->th_flags = TH_RST|TH_ACK;
 
 	/*
 	 * This is to get around a bug in the Solaris 2.4/2.5 TCP checksum
Index: contrib/ipfilter/ip_state.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ip_state.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ip_state.c
--- contrib/ipfilter/ip_state.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ip_state.c	17 Jul 2004 06:16:23 -0000
@@ -3,6 +3,7 @@
  *
  * See the IPFILTER.LICENCE file for details on licencing.
  */
+
 #if defined(__sgi) && (IRIX > 602)
 # include <sys/ptimers.h>
 #endif
@@ -921,7 +922,8 @@ tcphdr_t *tcp;
 		fdata->td_wscale = wscale;
 	else if (wscale == -2)
 		fdata->td_wscale = tdata->td_wscale = 0;
-	win <<= fdata->td_wscale;
+	if (!(tcp->th_flags & TH_SYN))
+		win <<= fdata->td_wscale;
 
 	if ((fdata->td_end == 0) &&
 	    (!is->is_fsm || ((tcp->th_flags & TH_OPENING) == TH_OPENING))) {
@@ -955,14 +957,15 @@ tcphdr_t *tcp;
 	    (SEQ_GE(seq, fdata->td_end - maxwin)) &&
 /* XXX what about big packets */
 #define MAXACKWINDOW 66000
-	    (ackskew >= -MAXACKWINDOW) &&
-	    (ackskew <= MAXACKWINDOW)) {
-		/* if ackskew < 0 then this should be due to fragented
+	    (-ackskew <= (MAXACKWINDOW << tdata->td_wscale)) &&
+	    ( ackskew <= (MAXACKWINDOW << tdata->td_wscale))) {
+
+		/* 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.
 		 * We do know the total length from the fragment cache though.
 		 * Note however that there might be more sessions with
-		 * exactly the same source and destination paramters in the
+		 * exactly the same source and destination parameters in the
 		 * state cache (and source and destination is the only stuff
 		 * that is saved in the fragment cache). Note further that
 		 * some TCP connections in the state cache are hashed with
@@ -1208,6 +1211,10 @@ fr_info_t *fin;
 
 	oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
 	ohlen = oip->ip_hl << 2;
+	/*
+	 * Check if the at least the old IP header (with options) and
+	 * 8 bytes of payload is present.
+	 */
 	if (fin->fin_plen < ICMPERR_MAXPKTLEN + ohlen - sizeof(*oip))
 		return NULL;
 
@@ -1224,7 +1231,7 @@ fr_info_t *fin;
 	 * may be too big to be in this buffer but not so big that it's
 	 * outside the ICMP packet, leading to TCP deref's causing problems.
 	 * This is possible because we don't know how big oip_hl is when we
-	 * do the pullup early in fr_check() and thus can't gaurantee it is
+	 * do the pullup early in fr_check() and thus can't guarantee it is
 	 * all here now.
 	 */
 #ifdef  _KERNEL
@@ -1251,9 +1258,43 @@ fr_info_t *fin;
 	bzero((char *)&src, sizeof(src));
 	bzero((char *)&dst, sizeof(dst));
 	bzero((char *)&ofin, sizeof(ofin));
+	/*
+	 * We make an fin entry to be able to feed it to
+	 * matchsrcdst.  Note that not all fields are encessary
+	 * but this is the cleanest way. Note further that we
+	 * fill in fin_mp such that if someone uses it we'll get
+	 * a kernel panic. fr_matchsrcdst does not use this.
+	 */
 	ofin.fin_ifp = fin->fin_ifp;
 	ofin.fin_out = !fin->fin_out;
+	ofin.fin_mp = NULL;
 	ofin.fin_v = 4;
+	/*
+	 * watch out here, as ip is in host order and oip in network
+	 * order. Any change we make must be undone afterwards, like
+	 * oip->ip_off - it is still in network byte order so fix it.
+	 */
+	savelen = oip->ip_len;
+	oip->ip_len = len;
+	oip->ip_off = ntohs(oip->ip_off);
+	(void) fr_makefrip(ohlen, oip, &ofin);
+	/*
+	 * Reset the short flag here because in fr_matchsrcdst() the flags
+	 * for the current packet (fin_fl) are compared against * those for
+	 * the existing session.
+	 */
+	ofin.fin_fl &= ~FI_SHORT;
+
+	/*
+	 * Put old values of ip_len and ip_off back as we don't know
+	 * if we have to forward the packet (or process it again.
+	 */
+	oip->ip_len = savelen;
+	oip->ip_off = htons(oip->ip_off);
+
+#if SOLARIS
+	ofin.fin_qfm = NULL;
+#endif
 	fr = NULL;
 
 	switch (oip->ip_p)
@@ -1262,7 +1303,7 @@ fr_info_t *fin;
 		icmp = (icmphdr_t *)((char *)oip + ohlen);
 
 		/*
-		 * a ICMP error can only be generated as a result of an
+		 * an ICMP error can only be generated as a result of an
 		 * ICMP query, not as the response on an ICMP error
 		 *
 		 * XXX theoretically ICMP_ECHOREP and the other reply's are
@@ -1286,18 +1327,15 @@ fr_info_t *fin;
 		hv += icmp->icmp_seq;
 		hv %= fr_statesize;
 
-		savelen = oip->ip_len;
-		oip->ip_len = len;
-		fr_makefrip(ohlen, oip, &ofin);
-		oip->ip_len = savelen;
-
 		READ_ENTER(&ipf_state);
 		for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
 			if ((is->is_p == pr) && (is->is_v == 4) &&
+			    (is->is_icmppkts < is->is_pkts) &&
 			    fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
-			    fr_matchicmpqueryreply(is->is_v, is, icmp, fin->fin_rev)) {
+			    fr_matchicmpqueryreply(is->is_v, is, icmp,
+						   fin->fin_rev)) {
 				ips_stats.iss_hits++;
-				is->is_pkts++;
+				is->is_icmppkts++;
 				is->is_bytes += ip->ip_len;
 				fr = is->is_rule;
 				break;
@@ -1326,20 +1364,7 @@ fr_info_t *fin;
 	hv += dport;
 	hv += sport;
 	hv %= fr_statesize;
-	/*
-	 * we make an fin entry to be able to feed it to
-	 * matchsrcdst note that not all fields are encessary
-	 * but this is the cleanest way. Note further we fill
-	 * in fin_mp such that if someone uses it we'll get
-	 * a kernel panic. fr_matchsrcdst does not use this.
-	 *
-	 * watch out here, as ip is in host order and oip in network
-	 * order. Any change we make must be undone afterwards.
-	 */
-	savelen = oip->ip_len;
-	oip->ip_len = len;
-	fr_makefrip(ohlen, oip, &ofin);
-	oip->ip_len = savelen;
+
 	READ_ENTER(&ipf_state);
 	for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
 		/*
@@ -1347,13 +1372,16 @@ fr_info_t *fin;
 		 * encapsulated packet was allowed through the
 		 * other way around. Note that the minimal amount
 		 * of info present does not allow for checking against
-		 * tcp internals such as seq and ack numbers.
+		 * tcp internals such as seq and ack numbers.  Only the
+		 * ports are known to be present and can be even if the
+		 * short flag is set.
 		 */
 		if ((is->is_p == pr) && (is->is_v == 4) &&
+		    (is->is_icmppkts < is->is_pkts) &&
 		    fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
 			fr = is->is_rule;
 			ips_stats.iss_hits++;
-			is->is_pkts++;
+			is->is_icmppkts++;
 			is->is_bytes += fin->fin_plen;
 			/*
 			 * we deliberately do not touch the timeouts
@@ -1675,8 +1703,8 @@ void *ifp;
 	for (is = ips_list; is; is = is->is_next) {
 		for (i = 0; i < 4; i++) {
 			if (is->is_ifp[i] == ifp) {
-				is->is_ifpin = GETUNIT(is->is_ifname[i],
-						       is->is_v);
+				is->is_ifp[i] = GETUNIT(is->is_ifname[i],
+							is->is_v);
 				if (!is->is_ifp[i])
 					is->is_ifp[i] = (void *)-1;
 			}
@@ -1843,17 +1871,41 @@ int dir, fsm;
 			state[dir] = TCPS_SYN_SENT;
 			newage = fr_tcptimeout;
 		}
+		
+		/* 
+		 * It is apparently possible that a hosts sends two syncs
+		 * before the remote party is able to respond with a SA. In
+		 * such a case the remote server sometimes ACK's the second
+		 * sync, and then responds with a SA. The following code
+		 * is used to prevent this ack from being blocked.
+		 *
+		 * We do not reset the timeout here to fr_tcptimeout because
+		 * a connection connect timeout does not renew after every
+		 * packet that is sent.  We need to set newage to something
+		 * to indicate the packet has passed the check for its flags
+		 * being valid in the TCP FSM.
+		 */
+		else if ((ostate == TCPS_SYN_SENT) &&
+		         ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK)) {
+			newage = *age;
+		}
+
 		/*
 		 * The next piece of code makes it possible to get
 		 * already established connections into the state table
 		 * after a restart or reload of the filter rules; this
 		 * does not work when a strict 'flags S keep state' is
-		 * used for tcp connections of course
+		 * used for tcp connections of course, however, use a
+		 * lower time-out so the state disappears quickly if
+		 * the other side does not pick it up.
 		 */
-		if (!fsm && (flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
+		else if (!fsm &&
+			 (flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
 			/* we saw an A, guess 'dir' is in ESTABLISHED mode */
-			if (state[1 - dir] == TCPS_CLOSED ||
-			    state[1 - dir] == TCPS_ESTABLISHED) {
+			if (ostate == TCPS_CLOSED) {
+				state[dir] = TCPS_ESTABLISHED;
+				newage = fr_tcptimeout;
+			} else if (ostate == TCPS_ESTABLISHED) {
 				state[dir] = TCPS_ESTABLISHED;
 				newage = fr_tcpidletimeout;
 			}
@@ -2056,7 +2108,7 @@ u_int type;
 	int types[1];
 
 	ipsl.isl_type = type;
-	ipsl.isl_pkts = is->is_pkts;
+	ipsl.isl_pkts = is->is_pkts + is->is_icmppkts;
 	ipsl.isl_bytes = is->is_bytes;
 	ipsl.isl_src = is->is_src;
 	ipsl.isl_dst = is->is_dst;
@@ -2084,7 +2136,11 @@ u_int type;
 	sizes[0] = sizeof(ipsl);
 	types[0] = 0;
 
-	(void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1);
+	if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) {
+		ATOMIC_INCL(ips_stats.iss_logged);
+	} else {
+		ATOMIC_INCL(ips_stats.iss_logfail);
+	}
 }
 #endif
 
@@ -2134,12 +2190,30 @@ fr_info_t *fin;
 	bzero((char *)&ofin, sizeof(ofin));
 	ofin.fin_out = !fin->fin_out;
 	ofin.fin_ifp = fin->fin_ifp;
+	ofin.fin_mp = NULL;
 	ofin.fin_v = 6;
+#if SOLARIS
+	ofin.fin_qfm = NULL;
+#endif
+	/*
+	 * We make a fin entry to be able to feed it to
+	 * matchsrcdst. Note that not all fields are necessary
+	 * but this is the cleanest way. Note further we fill
+	 * in fin_mp such that if someone uses it we'll get
+	 * a kernel panic. fr_matchsrcdst does not use this.
+	 *
+	 * watch out here, as ip is in host order and oip in network
+	 * order. Any change we make must be undone afterwards.
+	 */
+	savelen = oip->ip6_plen;
+	oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
+	fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
+	oip->ip6_plen = savelen;
 
 	if (oip->ip6_nxt == IPPROTO_ICMPV6) {
 		oic = (struct icmp6_hdr *)(oip + 1);
 		/*
-		 * a ICMP error can only be generated as a result of an
+		 * an ICMP error can only be generated as a result of an
 		 * ICMP query, not as the response on an ICMP error
 		 *
 		 * XXX theoretically ICMP_ECHOREP and the other reply's are
@@ -2160,10 +2234,6 @@ fr_info_t *fin;
 		hv += oic->icmp6_seq;
 		hv %= fr_statesize;
 
-		oip->ip6_plen = ntohs(oip->ip6_plen);
-		fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
-		oip->ip6_plen = htons(oip->ip6_plen);
-
 		READ_ENTER(&ipf_state);
 		for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
 			if ((is->is_p == pr) &&
@@ -2207,20 +2277,7 @@ fr_info_t *fin;
 	hv += dport;
 	hv += sport;
 	hv %= fr_statesize;
-	/*
-	 * we make an fin entry to be able to feed it to
-	 * matchsrcdst note that not all fields are encessary
-	 * but this is the cleanest way. Note further we fill
-	 * in fin_mp such that if someone uses it we'll get
-	 * a kernel panic. fr_matchsrcdst does not use this.
-	 *
-	 * watch out here, as ip is in host order and oip in network
-	 * order. Any change we make must be undone afterwards.
-	 */
-	savelen = oip->ip6_plen;
-	oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
-	fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
-	oip->ip6_plen = savelen;
+
 	READ_ENTER(&ipf_state);
 	for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
 		/*
Index: contrib/ipfilter/ipf.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipf.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipf.c
--- contrib/ipfilter/ipf.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ipf.c	17 Jul 2004 04:55:54 -0000
@@ -50,7 +50,7 @@
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)ipf.c	1.23 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.19 2002/12/06 11:41:13 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.23 2003/06/27 14:39:13 darrenr Exp $";
 #endif
 
 #if	SOLARIS
@@ -61,6 +61,7 @@ extern	char	*index __P((const char *, in
 #endif
 
 extern	char	*optarg;
+extern	int	optind;
 
 void	frsync __P((void));
 void	zerostats __P((void));
@@ -72,15 +73,16 @@ int	use_inet6 = 0;
 static	int	fd = -1;
 
 static	void	procfile __P((char *, char *)), flushfilter __P((char *));
-static	void	set_state __P((u_int)), showstats __P((friostat_t *));
+static	int	set_state __P((u_int));
+static	void	showstats __P((friostat_t *));
 static	void	packetlogon __P((char *)), swapactive __P((void));
 static	int	opendevice __P((char *));
 static	void	closedevice __P((void));
 static	char	*getline __P((char *, size_t, FILE *, int *));
 static	char	*ipfname = IPL_NAME;
-static	void	usage __P((void));
+static	void	usage __P((char *));
 static	int	showversion __P((void));
-static	int	get_flags __P((void));
+static	int	get_flags __P((int *));
 
 
 #if SOLARIS
@@ -89,9 +91,10 @@ static	int	get_flags __P((void));
 # define	OPTS	"6AdDEf:F:Il:noPrsvVyzZ"
 #endif
 
-static void usage()
+static void usage(name)
+char *name;
 {
-	fprintf(stderr, "usage: ipf [-%s] %s %s %s\n", OPTS,
+	fprintf(stderr, "usage: %s [-%s] %s %s %s\n", name, OPTS,
 		"[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]");
 	exit(1);
 }
@@ -103,6 +106,9 @@ char *argv[];
 {
 	int c;
 
+	if (argc < 2)
+		usage(argv[0]);
+
 	while ((c = getopt(argc, argv, OPTS)) != -1) {
 		switch (c)
 		{
@@ -113,10 +119,12 @@ char *argv[];
 			opts &= ~OPT_INACTIVE;
 			break;
 		case 'E' :
-			set_state((u_int)1);
+			if (set_state((u_int)1))
+				exit(1);
 			break;
 		case 'D' :
-			set_state((u_int)0);
+			if (set_state((u_int)0))
+				exit(1);
 			break;
 		case 'd' :
 			opts |= OPT_DEBUG;
@@ -168,12 +176,16 @@ char *argv[];
 		case 'Z' :
 			zerostats();
 			break;
+		case '?' :
 		default :
-			usage();
+			usage(argv[0]);
 			break;
 		}
 	}
 
+	if (optind < 2)
+		usage(argv[0]);
+
 	if (fd != -1)
 		(void) close(fd);
 
@@ -186,53 +198,82 @@ static int opendevice(ipfdev)
 char *ipfdev;
 {
 	if (opts & OPT_DONOTHING)
-		return -2;
+		return 0;
 
 	if (!ipfdev)
 		ipfdev = ipfname;
 
-	if (!(opts & OPT_DONOTHING) && fd == -1)
-		if ((fd = open(ipfdev, O_RDWR)) == -1)
-			if ((fd = open(ipfdev, O_RDONLY)) == -1) {
-				perror("open device");
-				if (errno == ENODEV)
-					fprintf(stderr, "IPFilter enabled?\n");
-			}
-	return fd;
+	/*
+	 * shouldn't we really be testing for fd < 0 here and below?
+	 */
+
+	if (fd != -1)
+		return 0;
+
+	if ((fd = open(ipfdev, O_RDWR)) == -1) {
+		if ((fd = open(ipfdev, O_RDONLY)) == -1) {
+			perror("open device");
+			if (errno == ENODEV)
+				fprintf(stderr, "IPFilter enabled?\n");
+			return -1;
+		}
+	}
+
+	return 0;
 }
 
 
 static void closedevice()
 {
-	close(fd);
+	if (fd != -1)
+		close(fd);
 	fd = -1;
 }
 
 
-static	int	get_flags()
+/*
+ * Return codes:
+ *	0	Success
+ *	!0	Failure (and an error message has already been printed)
+ */
+static	int	get_flags(i)
+int	*i;
 {
-	int i;
 
-	if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) {
-		perror("SIOCGETFF");
+	if (opts & OPT_DONOTHING)
 		return 0;
+
+	if (opendevice(ipfname) < 0)
+		return -1;
+
+	if (ioctl(fd, SIOCGETFF, i) == -1) {
+		perror("SIOCGETFF");
+		return -1;
 	}
-	return i;
+	return 0;
 }
 
 
-static	void	set_state(enable)
+static	int	set_state(enable)
 u_int	enable;
 {
-	if (opendevice(ipfname) != -2)
-		if (ioctl(fd, SIOCFRENB, &enable) == -1) {
-			if (errno == EBUSY)
-				fprintf(stderr,
-					"IP Filter: already initialized\n");
-			else
-				perror("SIOCFRENB");
+	if (opts & OPT_DONOTHING)
+		return 0;
+
+	if (opendevice(ipfname))
+		return -1;
+
+	if (ioctl(fd, SIOCFRENB, &enable) == -1) {
+		if (errno == EBUSY)
+			/* Not really an error */
+			fprintf(stderr,
+				"IP Filter: already initialized\n");
+		else {
+			perror("SIOCFRENB");
+			return -1;
 		}
-	return;
+	}
+	return 0;
 }
 
 static	void	procfile(name, file)
@@ -243,8 +284,10 @@ char	*name, *file;
 	struct	frentry	*fr;
 	u_int	add, del;
 	int     linenum = 0;
+	int	parsestatus;
 
-	(void) opendevice(ipfname);
+	if (opendevice(ipfname) == -1)
+		exit(1);
 
 	if (opts & OPT_INACTIVE) {
 		add = SIOCADIFR;
@@ -284,9 +327,18 @@ char	*name, *file;
 		if (opts & OPT_VERBOSE)
 			(void)fprintf(stderr, "[%s]\n", line);
 
-		fr = parse(line, linenum);
+		parsestatus = 1;
+		fr = parse(line, linenum, &parsestatus);
 		(void)fflush(stdout);
 
+		if (parsestatus != 0) {
+			fprintf(stderr, "%s: %s: %s error (%d), quitting\n",
+			    name, file,
+			    ((parsestatus < 0)? "parse": "internal"),
+			    parsestatus);
+			exit(1);
+		}
+
 		if (fr) {
 			if (opts & OPT_ZERORULEST)
 				add = SIOCZRLST;
@@ -311,6 +363,7 @@ char	*name, *file;
 				if (ioctl(fd, add, &fr) == -1) {
 					fprintf(stderr, "%d:", linenum);
 					perror("ioctl(SIOCZRLST)");
+					exit(1);
 				} else {
 #ifdef	USE_QUAD_T
 					printf("hits %qd bytes %qd ",
@@ -327,11 +380,13 @@ char	*name, *file;
 				if (ioctl(fd, del, &fr) == -1) {
 					fprintf(stderr, "%d:", linenum);
 					perror("ioctl(delete rule)");
+					exit(1);
 				}
 			} else if (!(opts & OPT_DONOTHING)) {
 				if (ioctl(fd, add, &fr) == -1) {
 					fprintf(stderr, "%d:", linenum);
 					perror("ioctl(add/insert rule)");
+					exit(1);
 				}
 			}
 		}
@@ -346,7 +401,7 @@ char	*name, *file;
 
 /*
  * Similar to fgets(3) but can handle '\\' and NL is converted to NUL.
- * Returns NULL if error occured, EOF encounterd or input line is too long.
+ * Returns NULL if error occurred, EOF encounterd or input line is too long.
  */
 static char *getline(str, size, file, linenum)
 register char	*str;
@@ -360,7 +415,7 @@ int	*linenum;
 	do {
 		for (p = str, s = size;; p += (len - 1), s -= (len - 1)) {
 			/*
-			 * if an error occured, EOF was encounterd, or there
+			 * if an error occurred, EOF was encounterd, or there
 			 * was no room to put NUL, return NULL.
 			 */
 			if (fgets(p, s, file) == NULL)
@@ -391,7 +446,9 @@ char	*opt;
 {
 	int	flag;
 
-	flag = get_flags();
+	if (get_flags(&flag))
+		exit(1);
+
 	if (flag != 0) {
 		if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
 			printf("log flag is currently %#x\n", flag);
@@ -415,11 +472,27 @@ char	*opt;
 			printf("set log flag: block\n");
 	}
 
-	if (opendevice(ipfname) != -2 && (ioctl(fd, SIOCSETFF, &flag) != 0))
-		perror("ioctl(SIOCSETFF)");
+	if (opendevice(ipfname) == -1) {
+		exit(1);
+	}
+
+	if (!(opts & OPT_DONOTHING)) {
+		if (ioctl(fd, SIOCSETFF, &flag) != 0) {
+			perror("ioctl(SIOCSETFF)");
+			exit(1);
+		}
+	}
 
 	if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
-		flag = get_flags();
+		/*
+		 * Even though the ioctls above succeeded, it
+		 * is possible that a calling script/program
+		 * relies on the following verbose mode string.
+		 * Thus, we still take an error exit if get_flags
+		 * fails here.
+		 */
+		if (get_flags(&flag))
+			exit(1);
 		printf("log flag is now %#x\n", flag);
 	}
 }
@@ -430,8 +503,11 @@ char	*arg;
 {
 	int	fl = 0, rem;
 
-	if (!arg || !*arg)
-		return;
+	if (!arg || !*arg) {
+		fprintf(stderr, "-F: no filter specified\n");
+		exit(1);
+	}
+
 	if (!strcmp(arg, "s") || !strcmp(arg, "S")) {
 		if (*arg == 'S')
 			fl = 0;
@@ -440,13 +516,22 @@ char	*arg;
 		rem = fl;
 
 		closedevice();
-		if (opendevice(IPL_STATE) != -2) {
+
+		if (opendevice(IPL_STATE) == -1) {
+			exit(1);
+		}
+
+		if (!(opts & OPT_DONOTHING)) {
 			if (use_inet6) {
-				if (ioctl(fd, SIOCIPFL6, &fl) == -1)
+				if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
 					perror("ioctl(SIOCIPFL6)");
+					exit(1);
+				}
 			} else {
-				if (ioctl(fd, SIOCIPFFL, &fl) == -1)
+				if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
 					perror("ioctl(SIOCIPFFL)");
+					exit(1);
+				}
 			}
 		}
 		if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
@@ -465,13 +550,21 @@ char	*arg;
 	fl |= (opts & FR_INACTIVE);
 	rem = fl;
 
-	if (opendevice(ipfname) != -2) {
+	if (opendevice(ipfname) == -1) {
+		exit(1);
+	}
+
+	if (!(opts & OPT_DONOTHING)) {
 		if (use_inet6) {
-			if (ioctl(fd, SIOCIPFL6, &fl) == -1)
+			if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
 				perror("ioctl(SIOCIPFL6)");
+				exit(1);
+			}
 		} else {
-			if (ioctl(fd, SIOCIPFFL, &fl) == -1)
+			if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
 				perror("ioctl(SIOCIPFFL)");
+				exit(1);
+			}
 		}
 	}
 	if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
@@ -487,10 +580,18 @@ static void swapactive()
 {
 	int in = 2;
 
-	if (opendevice(ipfname) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
-		perror("ioctl(SIOCSWAPA)");
-	else
-		printf("Set %d now inactive\n", in);
+	if (opendevice(ipfname) == -1) {
+		exit(1);
+	}
+
+
+	if (!(opts & OPT_DONOTHING)) {
+		if (ioctl(fd, SIOCSWAPA, &in) == -1) {
+			perror("ioctl(SIOCSWAPA)");
+			exit(1);
+		}
+	}
+	printf("Set %d now inactive\n", in);
 }
 
 
@@ -498,10 +599,16 @@ void frsync()
 {
 	int frsyn = 0;
 
-	if (opendevice(ipfname) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1)
-		perror("SIOCFRSYN");
-	else
-		printf("filter sync'd\n");
+	if (opendevice(ipfname) == -1)
+		exit(1);
+
+	if (!(opts & OPT_DONOTHING)) {
+		if (ioctl(fd, SIOCFRSYN, &frsyn) == -1) {
+			perror("SIOCFRSYN");
+			exit(1);
+		}
+	}
+	printf("filter sync'd\n");
 }
 
 
@@ -510,7 +617,10 @@ void zerostats()
 	friostat_t	fio;
 	friostat_t	*fiop = &fio;
 
-	if (opendevice(ipfname) != -2) {
+	if (opendevice(ipfname) == -1)
+		exit(1);
+
+	if (!(opts & OPT_DONOTHING)) {
 		if (ioctl(fd, SIOCFRZST, &fiop) == -1) {
 			perror("ioctl(SIOCFRZST)");
 			exit(-1);
@@ -522,7 +632,7 @@ void zerostats()
 
 
 /*
- * read the kernel stats for packets blocked and passed
+ * Read the kernel stats for packets blocked and passed
  */
 static void showstats(fp)
 friostat_t	*fp;
@@ -556,19 +666,26 @@ friostat_t	*fp;
 #if SOLARIS
 static void blockunknown()
 {
-	u_32_t	flag;
+	int	flag;
 
 	if (opendevice(ipfname) == -1)
-		return;
+		exit(1);
+
+	if (get_flags(&flag))
+		exit(1);
 
-	flag = get_flags();
 	if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
 		printf("log flag is currently %#x\n", flag);
 
 	flag ^= FF_BLOCKNONIP;
 
-	if (opendevice(ipfname) != -2 && ioctl(fd, SIOCSETFF, &flag))
-		perror("ioctl(SIOCSETFF)");
+	if (opendevice(ipfname) == -1)
+		exit(1);
+
+	if (!(opts & OPT_DONOTHING)) {
+		if (ioctl(fd, SIOCSETFF, &flag))
+			perror("ioctl(SIOCSETFF)");
+	}
 
 	if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
 		if (ioctl(fd, SIOCGETFF, &flag))
@@ -580,13 +697,15 @@ static void blockunknown()
 #endif
 
 
+/*
+ * nonzero return value means caller should exit with error
+ */
 static int showversion()
 {
 	struct friostat fio;
 	struct friostat *fiop=&fio;
-	u_32_t flags;
+	int flags, vfd;
 	char *s;
-	int vfd;
 
 	printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
 
@@ -601,11 +720,14 @@ static int showversion()
 		return 1;
 	}
 	close(vfd);
-	flags = get_flags();
 
 	printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
 		(int)sizeof(fio.f_version), fio.f_version);
 	printf("Running: %s\n", fio.f_running ? "yes" : "no");
+
+	if (get_flags(&flags)) {
+		return 1;
+	}
 	printf("Log Flags: %#x = ", flags);
 	s = "";
 	if (flags & FF_LOGPASS) {
Index: contrib/ipfilter/ipf.h
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipf.h,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipf.h
--- contrib/ipfilter/ipf.h	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ipf.h	17 Jul 2004 04:55:54 -0000
@@ -4,7 +4,7 @@
  * See the IPFILTER.LICENCE file for details on licencing.
  *
  * @(#)ipf.h	1.12 6/5/96
- * $Id: ipf.h,v 2.9.2.6 2002/01/03 08:00:12 darrenr Exp $
+ * $Id: ipf.h,v 2.9.2.7 2003/05/15 17:45:33 darrenr Exp $
  */
 
 #ifndef	__IPF_H__
@@ -62,7 +62,7 @@ struct nat;
 extern	char	*strdup __P((char *));
 #endif
 
-extern	struct	frentry	*parse __P((char *, int));
+extern	struct	frentry	*parse __P((char *, int, int *));
 
 extern	void	printfr __P((struct frentry *));
 extern	void	binprint __P((struct frentry *)), initparse __P((void));
Index: contrib/ipfilter/ipfs.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipfs.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipfs.c
--- contrib/ipfilter/ipfs.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ipfs.c	17 Jul 2004 04:55:54 -0000
@@ -45,7 +45,7 @@
 #include "ipf.h"
 
 #if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.12 2002/09/26 12:25:19 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.15 2003/05/31 02:12:21 darrenr Exp $";
 #endif
 
 #ifndef	IPF_SAVEDIR
@@ -63,6 +63,7 @@ extern	char	*index __P((const char *, in
 #endif
 
 extern	char	*optarg;
+extern	int	optind;
 
 int	main __P((int, char *[]));
 void	usage __P((void));
@@ -80,22 +81,24 @@ int	writenat __P((int, char *));
 char	*concat __P((char *, char *));
 
 int	opts = 0;
+char	*progname;
 
 
 void usage()
 {
 	fprintf(stderr, "\
-usage: ipfs [-nv] -l\n\
-usage: ipfs [-nv] -u\n\
-usage: ipfs [-nv] [-d <dir>] -R\n\
-usage: ipfs [-nv] [-d <dir>] -W\n\
-usage: ipfs [-nv] -N [-f <file> | -d <dir>] -r\n\
-usage: ipfs [-nv] -S [-f <file> | -d <dir>] -r\n\
-usage: ipfs [-nv] -N [-f <file> | -d <dir>] -w\n\
-usage: ipfs [-nv] -S [-f <file> | -d <dir>] -w\n\
-usage: ipfs [-nv] -N [-f <filename> | -d <dir> ] -i <if1>,<if2>\n\
-usage: ipfs [-nv] -S [-f <filename> | -d <dir> ] -i <if1>,<if2>\n\
-");
+usage: %s [-nv] -l\n\
+usage: %s [-nv] -u\n\
+usage: %s [-nv] [-d <dir>] -R\n\
+usage: %s [-nv] [-d <dir>] -W\n\
+usage: %s [-nv] -N [-f <file> | -d <dir>] -r\n\
+usage: %s [-nv] -S [-f <file> | -d <dir>] -r\n\
+usage: %s [-nv] -N [-f <file> | -d <dir>] -w\n\
+usage: %s [-nv] -S [-f <file> | -d <dir>] -w\n\
+usage: %s [-nv] -N [-f <filename> | -d <dir> ] -i <if1>,<if2>\n\
+usage: %s [-nv] -S [-f <filename> | -d <dir> ] -i <if1>,<if2>\n\
+", progname, progname, progname, progname, progname, progname,
+		progname, progname, progname, progname);
 	exit(1);
 }
 
@@ -214,6 +217,8 @@ char *argv[];
 	int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0;
 	char *dirname = NULL, *filename = NULL, *ifs = NULL;
 
+	progname = argv[0];
+
 	while ((c = getopt(argc, argv, "d:f:i:lNnSRruvWw")) != -1)
 		switch (c)
 		{
@@ -287,10 +292,14 @@ char *argv[];
 			rw = 3;
 			set = 1;
 			break;
+		case '?' :
 		default :
 			usage();
 		}
 
+	if (optind < 2)
+		usage();
+
 	if (filename == NULL) {
 		if (ns == 0) {
 			if (dirname == NULL)
@@ -560,9 +569,11 @@ int readnat(fd, file)
 int fd;
 char *file;
 {
-	nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL, *ipnp;
+	nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL;
 	int nfd = -1, i;
 	nat_t *nat;
+	char *s;
+	int n;
 
 	if (!file)
 		file = IPF_NATFILE;
@@ -575,7 +586,6 @@ char *file;
 	}
 
 	bzero((char *)&ipn, sizeof(ipn));
-	ipnp = &ipn;
 
 	/*
 	 * 1. Read all state information in.
@@ -597,30 +607,35 @@ char *file;
 		}
 
 		if (ipn.ipn_dsize > 0) {
-			char *s = ipnp->ipn_data;
-			int n = ipnp->ipn_dsize;
+			n = ipn.ipn_dsize;
 
-			n -= sizeof(ipnp->ipn_data);
+			if (n > sizeof(ipn.ipn_data))
+				n -= sizeof(ipn.ipn_data);
+			else
+				n = 0;
 			in = malloc(sizeof(*in) + n);
 			if (!in)
 				break;
 
-			s += sizeof(ipnp->ipn_data);
-			i = read(nfd, s, n);
-			if (i == 0)
-				break;
-			if (i != n) {
-				fprintf(stderr, "incomplete read: %d != %d\n",
-					i, n);
-				close(nfd);
-				return 1;
+			if (n > 0) {
+				s = in->ipn_data + sizeof(in->ipn_data);
+				i = read(nfd, s, n);
+				if (i == 0)
+					break;
+				if (i != n) {
+					fprintf(stderr,
+						"incomplete read: %d != %d\n",
+						i, n);
+					close(nfd);
+					return 1;
+				}
 			}
 		} else
 			in = (nat_save_t *)malloc(sizeof(*in));
-		bcopy((char *)ipnp, (char *)in, sizeof(ipn));
+		bcopy((char *)&ipn, (char *)in, sizeof(ipn));
 
 		/*
-		 * Check to see if this is the first state entry that will
+		 * Check to see if this is the first NAT entry that will
 		 * reference a particular rule and if so, flag it as such
 		 * else just adjust the rule pointer to become a pointer to
 		 * the other.  We do this so we have a means later for tracking
@@ -650,6 +665,7 @@ char *file;
 	} while (1);
 
 	close(nfd);
+	nfd = -1;
 
 	for (in = ipnhead; in; in = in->ipn_next) {
 		if (opts & OPT_VERBOSE)
@@ -758,6 +774,7 @@ char *dirname;
 		dirname = IPF_SAVEDIR;
 
 	if (chdir(dirname)) {
+		fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname);
 		perror("chdir(IPF_SAVEDIR)");
 		return 1;
 	}
Index: contrib/ipfilter/ipft_ef.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipft_ef.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipft_ef.c
--- contrib/ipfilter/ipft_ef.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ipft_ef.c	17 Jul 2004 04:55:54 -0000
@@ -52,7 +52,7 @@ etherfind -n -t
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)ipft_ef.c	1.6 2/4/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.4 2002/12/06 11:40:25 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.5 2003/05/19 12:02:35 darrenr Exp $";
 #endif
 
 static	int	etherf_open __P((char *));
@@ -108,9 +108,9 @@ int	cnt, *dir;
 
 	bzero(&pkt, sizeof(pkt));
 
-	if (sscanf(lbuf, "%s %s %s %s %s %s", len, prot, src, dst,
+	if (sscanf(lbuf, "%7s %7s %15s %15s %15s %15s", len, prot, src, dst,
 		   sprt, dprt) != 6)
-		if (sscanf(lbuf, "%s %s %s %s %s %s %s", time,
+		if (sscanf(lbuf, "%7s %7s %7s %15s %15s %15s %15s", time,
 			   len, prot, src, dst, sprt, dprt) != 7)
 			return -1;
 
Index: contrib/ipfilter/ipft_td.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipft_td.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipft_td.c
--- contrib/ipfilter/ipft_td.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ipft_td.c	17 Jul 2004 04:55:54 -0000
@@ -61,7 +61,7 @@ tcpdump -nqte
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)ipft_td.c	1.8 2/4/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2.2.4 2002/12/06 11:40:26 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2.2.6 2003/05/31 02:13:04 darrenr Exp $";
 #endif
 
 static	int	tcpd_open __P((char *));
@@ -131,12 +131,13 @@ int	cnt, *dir;
 
 	bzero(&pkt, sizeof(pkt));
 
-	if ((n = sscanf(lbuf, "%s > %s: %s", src, dst, misc)) != 3)
-		if ((n = sscanf(lbuf, "%s %s > %s: %s",
+	if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3)
+		if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s",
 				time, src, dst, misc)) != 4)
-			if ((n = sscanf(lbuf, "%s %s: %s > %s: %s",
+			if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s",
 					link1, link2, src, dst, misc)) != 5) {
-				n = sscanf(lbuf, "%s %s %s: %s > %s: %s",
+				n = sscanf(lbuf,
+					   "%31s %31s %31s: %31s > %31s: %255s",
 					   time, link1, link2, src, dst, misc);
 				if (n != 6)
 					return -1;
Index: contrib/ipfilter/ipmon.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipmon.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipmon.c
--- contrib/ipfilter/ipmon.c	17 Jun 2003 04:24:02 -0000	1.2
+++ contrib/ipfilter/ipmon.c	17 Jul 2004 04:55:54 -0000
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/contrib/ipfilter/ipmon.c,v 1.5.2.7 2003/03/01 03:55:51 darrenr Exp $ */
-/* $DragonFly: src/contrib/ipfilter/ipmon.c,v 1.2 2003/06/17 04:24:02 dillon Exp $ */
+/* $FreeBSD: src/contrib/ipfilter/ipmon.c,v 1.5.2.8 2004/07/04 09:24:39 darrenr Exp $ */
 /*
  * Copyright (C) 1993-2002 by Darren Reed.
  *
@@ -993,7 +993,7 @@ int	blen;
 		p = (u_short)ip6->ip6_nxt;
 		s = (u_32_t *)&ip6->ip6_src;
 		d = (u_32_t *)&ip6->ip6_dst;
-		plen = ntohs(ip6->ip6_plen);
+		plen = hl + ntohs(ip6->ip6_plen);
 #else
 		sprintf(t, "ipv6");
 		goto printipflog;
@@ -1107,11 +1107,12 @@ int	blen;
 					ipc->ip_hl << 2, i);
 				t += strlen(t);
 				if (ipoff & IP_OFFMASK) {
-					(void) sprintf(t, " frag %s%s%hu@%hu",
-						ipoff & IP_MF ? "+" : "",
-						ipoff & IP_DF ? "-" : "",
+					(void) sprintf(t, " (frag %d:%hu@%hu%s%s)",
+						ntohs(ipc->ip_id),
 						i - (ipc->ip_hl<<2),
-						(ipoff & IP_OFFMASK) << 3);
+						(ipoff & IP_OFFMASK) << 3,
+						ipoff & IP_MF ? "+" : "",
+						ipoff & IP_DF ? "-" : "");
 				}
 			}
 		}
@@ -1122,10 +1123,11 @@ int	blen;
 			hostname(res, v, d), proto, hl, plen);
 		t += strlen(t);
 		if (off & IP_OFFMASK)
-			(void) sprintf(t, " frag %s%s%hu@%hu",
+			(void) sprintf(t, " (frag %d:%hu@%hu%s%s)",
+				ntohs(ip->ip_id),
+				plen - hl, (off & IP_OFFMASK) << 3,
 				ipoff & IP_MF ? "+" : "",
-				ipoff & IP_DF ? "-" : "",
-				plen - hl, (off & IP_OFFMASK) << 3);
+				ipoff & IP_DF ? "-" : "");
 	}
 	t += strlen(t);
 
Index: contrib/ipfilter/ipnat.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipnat.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipnat.c
--- contrib/ipfilter/ipnat.c	17 Jun 2003 02:44:51 -0000	1.1
+++ contrib/ipfilter/ipnat.c	17 Jul 2004 04:55:54 -0000
@@ -60,7 +60,7 @@ extern	char	*sys_errlist[];
 
 #if !defined(lint)
 static const char sccsid[] ="@(#)ipnat.c	1.9 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.22 2002/12/06 11:40:26 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.25 2003/06/05 14:00:28 darrenr Exp $";
 #endif
 
 
@@ -71,27 +71,31 @@ int	use_inet6 = 0;
 char	thishost[MAXHOSTNAMELEN];
 
 extern	char	*optarg;
+extern	int	optind;
+#if 0
 extern	ipnat_t	*natparse __P((char *, int));
+#endif
 extern	void	natparsefile __P((int, char *, int));
 extern	void	printnat __P((ipnat_t *, int));
 extern	void	printactivenat __P((nat_t *, int));
 extern	void	printhostmap __P((hostmap_t *, u_int));
 extern	char	*getsumd __P((u_32_t));
 
-void	dostats __P((natstat_t *, int)), flushtable __P((int, int));
+static int	dostats __P((natstat_t *, int));
+static int	flushtable __P((int, int));
 void	usage __P((char *));
 int	countbits __P((u_32_t));
 char	*getnattype __P((ipnat_t *));
 int	main __P((int, char*[]));
 void	printaps __P((ap_session_t *, int));
-void	showhostmap __P((natstat_t *nsp));
-void	natstat_dead __P((natstat_t *, char *));
+static int	showhostmap __P((natstat_t *nsp));
+static int	natstat_dead __P((natstat_t *, char *));
 
 
 void usage(name)
 char *name;
 {
-	fprintf(stderr, "%s: [-CFhlnrsv] [-f filename]\n", name);
+	fprintf(stderr, "Usage: %s [-CFhlnrsv] [-f filename]\n", name);
 	exit(1);
 }
 
@@ -153,10 +157,14 @@ char *argv[];
 		case 'v' :
 			opts |= OPT_VERBOSE;
 			break;
+		case '?' :
 		default :
 			usage(argv[0]);
 		}
 
+	if (optind < 2)
+		usage(argv[0]);
+
 	if ((kernel != NULL) || (core != NULL)) {
 		(void) setgid(getgid());
 		(void) setuid(getuid());
@@ -189,27 +197,36 @@ char *argv[];
 		if (openkmem(kernel, core) == -1)
 			exit(1);
 
-		natstat_dead(nsp, kernel);
-		if (opts & (OPT_LIST|OPT_STAT))
-			dostats(nsp, opts);
+		if (natstat_dead(nsp, kernel))
+			exit(1);
+		if (opts & (OPT_LIST|OPT_STAT)) {
+			if (dostats(nsp, opts))
+				exit(1);
+		}
 		exit(0);
 	}
 
 	if (opts & (OPT_FLUSH|OPT_CLEAR))
-		flushtable(fd, opts);
-	if (file)
+		if (flushtable(fd, opts))
+		    exit(1);
+	if (file) {
+		/* NB natparsefile exits with nonzero in case of error */
 		natparsefile(fd, file, opts);
+	}
 	if (opts & (OPT_LIST|OPT_STAT))
-		dostats(nsp, opts);
+		if (dostats(nsp, opts))
+			exit(1);
+
+	/* TBD why not exit(0)? */
 	return 0;
 }
 
 
 /*
- * Read nat statistic information in using a symbol table and memory file
+ * Read NAT statistic information in using a symbol table and memory file
  * rather than doing ioctl's.
  */
-void natstat_dead(nsp, kernel)
+static int natstat_dead(nsp, kernel)
 natstat_t *nsp;
 char *kernel;
 {
@@ -229,12 +246,12 @@ char *kernel;
 
 	if (nlist(kernel, nat_nlist) == -1) {
 		fprintf(stderr, "nlist error\n");
-		return;
+		return -1;
 	}
 
 	/*
 	 * Normally the ioctl copies all of these values into the structure
-	 * for us, before returning it to useland, so here we must copy each
+	 * for us, before returning it to userland, so here we must copy each
 	 * one in individually.
 	 */
 	kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
@@ -257,18 +274,21 @@ char *kernel;
 		sizeof(nsp->ns_instances));
 	kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
 		sizeof(nsp->ns_apslist));
+
+	return 0;
 }
 
 
 /*
  * Display NAT statistics.
  */
-void dostats(nsp, opts)
+static int dostats(nsp, opts)
 natstat_t *nsp;
 int opts;
 {
 	nat_t **nt[2], *np, nat;
 	ipnat_t	ipn;
+	int rc = 0;
 
 	/*
 	 * Show statistics ?
@@ -297,6 +317,7 @@ int opts;
 			if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
 				    sizeof(ipn))) {
 				perror("kmemcpy");
+				rc = -1;
 				break;
 			}
 			if (opts & OPT_HITS)
@@ -309,28 +330,40 @@ int opts;
 		if (kmemcpy((char *)nt[0], (long)nsp->ns_table[0],
 			    sizeof(**nt) * NAT_SIZE)) {
 			perror("kmemcpy");
-			return;
+			rc = -1;
+		}
+		if (rc) {
+			free(nt[0]);
+			return rc;
 		}
 
 		printf("\nList of active sessions:\n");
 
 		for (np = nsp->ns_instances; np; np = nat.nat_next) {
-			if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
+			if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) {
+				/* TBD Is this an error? If so, return -1 */
 				break;
+			}
 			printactivenat(&nat, opts);
 		}
 
-		if (opts & OPT_VERBOSE)
-			showhostmap(nsp);
+		if (opts & OPT_VERBOSE) {
+			if (showhostmap(nsp)) {
+				free(nt[0]);
+				return -1;
+			}
+		}
+
 		free(nt[0]);
 	}
+	return 0;
 }
 
 
 /*
- * display the active host mapping table.
+ * Display the active host mapping table.
  */
-void showhostmap(nsp)
+static int showhostmap(nsp)
 natstat_t *nsp;
 {
 	hostmap_t hm, *hmp, **maptable;
@@ -343,7 +376,8 @@ natstat_t *nsp;
 	if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable,
 		    sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) {
 		perror("kmemcpy (maptable)");
-		return;
+		free(maptable);
+		return -1;
 	}
 
 	for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) {
@@ -352,7 +386,8 @@ natstat_t *nsp;
 		while (hmp) {
 			if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) {
 				perror("kmemcpy (hostmap)");
-				return;
+				free(maptable);
+				return -1;
 			}
 
 			printhostmap(&hm, hv);
@@ -360,6 +395,7 @@ natstat_t *nsp;
 		}
 	}
 	free(maptable);
+	return 0;
 }
 
 
@@ -367,24 +403,31 @@ natstat_t *nsp;
  * Issue an ioctl to flush either the NAT rules table or the active mapping
  * table or both.
  */
-void flushtable(fd, opts)
+static int flushtable(fd, opts)
 int fd, opts;
 {
 	int n = 0;
+	int rc = 0;
 
 	if (opts & OPT_FLUSH) {
 		n = 0;
-		if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
+		if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1) {
 			perror("ioctl(SIOCFLNAT)");
-		else
+			rc = -1;
+		} else {
 			printf("%d entries flushed from NAT table\n", n);
+		}
 	}
 
 	if (opts & OPT_CLEAR) {
 		n = 1;
-		if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
+		if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1) {
 			perror("ioctl(SIOCCNATL)");
-		else
+			rc = -1;
+		} else {
 			printf("%d entries flushed from NAT list\n", n);
+		}
 	}
+
+	return rc;
 }
Index: contrib/ipfilter/ipt.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipt.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipt.c
--- contrib/ipfilter/ipt.c	6 Jan 2004 03:17:19 -0000	1.2
+++ contrib/ipfilter/ipt.c	17 Jul 2004 04:55:54 -0000
@@ -64,7 +64,7 @@
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)ipt.c	1.19 6/3/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.24 2002/12/06 11:40:26 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.26 2003/11/09 17:22:21 darrenr Exp $";
 #endif
 
 extern	char	*optarg;
@@ -72,7 +72,7 @@ extern	struct frentry	*ipfilter[2][2];
 extern	struct ipread	snoop, etherf, tcpd, pcap, iptext, iphex;
 extern	struct ifnet	*get_unit __P((char *, int));
 extern	void	init_ifp __P((void));
-extern	ipnat_t	*natparse __P((char *, int));
+extern	ipnat_t	*natparse __P((char *, int, int *));
 extern	int	fr_running;
 
 int	opts = 0;
@@ -310,6 +310,7 @@ char *file;
 	int     linenum, i;
 	void	*fr;
 	FILE	*fp;
+	int	parsestatus;
 
 	if (!strcmp(file, "-"))
 		fp = stdin;
@@ -346,7 +347,21 @@ char *file;
 		/* fake an `ioctl' call :) */
 
 		if ((opts & OPT_NAT) != 0) {
-			if (!(fr = natparse(line, linenum)))
+			parsestatus = 1;
+			fr = natparse(line, linenum, &parsestatus);
+			if (parsestatus != 0) {
+				if (*line) {
+					fprintf(stderr,
+					    "%d: syntax error in \"%s\"\n",
+					    linenum, line);
+				}
+				fprintf(stderr, "%s: %s error (%d), quitting\n",
+				    file,
+				    ((parsestatus < 0)? "parse": "internal"),
+				    parsestatus);
+				exit(1);
+			}
+			if (!fr)
 				continue;
 
 			if (rremove == 0) {
@@ -367,8 +382,19 @@ char *file;
 						fr, i);
 			}
 		} else {
-			if (!(fr = parse(line, linenum)))
+			fr = parse(line, linenum, &parsestatus);
+
+			if (parsestatus != 0) {
+			    fprintf(stderr, "%s: %s error (%d), quitting\n",
+				file,
+				((parsestatus < 0)? "parse": "internal"),
+				parsestatus);
+			    exit(1);
+			}
+
+			if (!fr) {
 				continue;
+			}
 
 			if (rremove == 0) {
 				i = IPL_EXTERN(ioctl)(0, SIOCADAFR,
Index: contrib/ipfilter/kmem.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/kmem.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 kmem.c
--- contrib/ipfilter/kmem.c	6 Jan 2004 03:17:19 -0000	1.2
+++ contrib/ipfilter/kmem.c	17 Jul 2004 04:55:54 -0000
@@ -46,14 +46,14 @@
 
 #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 2.2.2.16 2002/12/06 11:40:27 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2.2.18 2003/11/09 17:22:22 darrenr Exp $";
 #endif
 
 #ifdef	__sgi
 typedef	int 	kvm_t;
 
 static	int	kvm_fd = -1;
-static	char	*kvm_errstr;
+static	char	*kvm_errstr = NULL;
 
 kvm_t *kvm_open(kernel, core, swap, mode, errstr)
 char *kernel, *core, *swap;
@@ -79,8 +79,10 @@ size_t size;
 	int r;
 
 	if (lseek(*kvm, pos, 0) == -1) {
-		fprintf(stderr, "%s", kvm_errstr);
-		perror("lseek");
+		if (kvm_errstr != NULL) {
+			fprintf(stderr, "%s:", kvm_errstr);
+			perror("lseek");
+		}
 		return -1;
 	}
 
@@ -103,7 +105,7 @@ char	*kern, *core;
 		kvm_t *uk;
 	} k;
 
-	kvm_f = kvm_open(kern, core, NULL, O_RDONLY, "");
+	kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL);
 	if (kvm_f == NULL)
 	    {
 		perror("openkmem:open");
Index: contrib/ipfilter/mln_ipl.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/mln_ipl.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 mln_ipl.c
--- contrib/ipfilter/mln_ipl.c	17 Jun 2003 02:44:52 -0000	1.1
+++ contrib/ipfilter/mln_ipl.c	17 Jul 2004 04:55:54 -0000
@@ -220,7 +220,9 @@ static int ipl_remove()
 #ifdef OpenBSD
 		VOP_LOCK(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc);
 #else
+# if !defined(__NetBSD_Version__) || (__NetBSD_Version__ < 106000000)
 		vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
+# endif
 #endif
 		VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
 		(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
Index: contrib/ipfilter/natparse.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/natparse.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 natparse.c
--- contrib/ipfilter/natparse.c	17 Jun 2003 02:44:52 -0000	1.1
+++ contrib/ipfilter/natparse.c	17 Jul 2004 04:55:54 -0000
@@ -56,7 +56,7 @@ extern	char	*sys_errlist[];
 
 #if !defined(lint)
 static const char sccsid[] ="@(#)ipnat.c	1.9 6/5/96 (C) 1993 Darren Reed";
-static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.27 2002/12/06 11:40:27 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.29 2003/05/15 17:45:34 darrenr Exp $";
 #endif
 
 
@@ -68,7 +68,7 @@ extern	void	printnat __P((ipnat_t *, int
 extern	int	countbits __P((u_32_t));
 extern	char	*proto;
 
-ipnat_t	*natparse __P((char *, int));
+ipnat_t	*natparse __P((char *, int, int *));
 void	natparsefile __P((int, char *, int));
 void	nat_setgroupmap __P((struct ipnat *));
 
@@ -98,10 +98,16 @@ ipnat_t *n;
 
 /*
  * Parse a line of input from the ipnat configuration file
+ *
+ * status:
+ *	< 0	error
+ *	= 0	OK
+ *	> 0	programmer error
  */
-ipnat_t *natparse(line, linenum)
+ipnat_t *natparse(line, linenum, status)
 char *line;
 int linenum;
+int *status;
 {
 	static ipnat_t ipn;
 	struct protoent *pr;
@@ -110,6 +116,7 @@ int linenum;
 	int i, cnt;
 	char *port1a = NULL, *port1b = NULL, *port2a = NULL;
 
+	*status = 100;		/* default to error */
 	proto = NULL;
 
 	/*
@@ -121,8 +128,10 @@ int linenum;
 		*s = '\0';
 	while (*line && isspace(*line))
 		line++;
-	if (!*line)
+	if (!*line) {
+		*status = 0;
 		return NULL;
+	}
 
 	bzero((char *)&ipn, sizeof(ipn));
 	cnt = 0;
@@ -137,6 +146,7 @@ int linenum;
 
 	if (cnt < 3) {
 		fprintf(stderr, "%d: not enough segments in line\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 
@@ -156,6 +166,7 @@ int linenum;
 	else {
 		fprintf(stderr, "%d: unknown mapping: \"%s\"\n",
 			linenum, *cpp);
+		*status = -1;
 		return NULL;
 	}
 
@@ -174,12 +185,14 @@ int linenum;
 			cpp++;
 			if (strcasecmp(*cpp, "from")) {
 				fprintf(stderr, "Missing from after !\n");
+				*status = -1;
 				return NULL;
 			}
 			ipn.in_flags |= IPN_NOTSRC;
 		} else if (**cpp == '!') {
 			if (strcasecmp(*cpp + 1, "from")) {
 				fprintf(stderr, "Missing from after !\n");
+				*status = -1;
 				return NULL;
 			}
 			ipn.in_flags |= IPN_NOTSRC;
@@ -187,6 +200,7 @@ int linenum;
 		if ((ipn.in_flags & IPN_NOTSRC) &&
 		    (ipn.in_redir & (NAT_MAP|NAT_MAPBLK))) {
 			fprintf(stderr, "Cannot use '! from' with map\n");
+			*status = -1;
 			return NULL;
 		}
 
@@ -196,12 +210,14 @@ int linenum;
 			if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
 				     (u_32_t *)&ipn.in_srcmsk, &ipn.in_sport,
 				     &ipn.in_scmp, &ipn.in_stop, linenum)) {
+				*status = -1;
 				return NULL;
 			}
 		} else {
 			if (hostmask(&cpp, (u_32_t *)&ipn.in_inip,
 				     (u_32_t *)&ipn.in_inmsk, &ipn.in_sport,
 				     &ipn.in_scmp, &ipn.in_stop, linenum)) {
+				*status = -1;
 				return NULL;
 			}
 		}
@@ -217,22 +233,26 @@ int linenum;
 		if (strcasecmp(*cpp, "to")) {
 			fprintf(stderr, "%d: unexpected keyword (%s) - to\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		if ((ipn.in_flags & IPN_NOTDST) &&
 		    (ipn.in_redir & (NAT_REDIRECT))) {
 			fprintf(stderr, "Cannot use '! to' with rdr\n");
+			*status = -1;
 			return NULL;
 		}
 
 		if (!*++cpp) {
 			fprintf(stderr, "%d: missing host after to\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (ipn.in_redir == NAT_REDIRECT) {
 			if (hostmask(&cpp, (u_32_t *)&ipn.in_outip,
 				     (u_32_t *)&ipn.in_outmsk, &ipn.in_dport,
 				     &ipn.in_dcmp, &ipn.in_dtop, linenum)) {
+				*status = -1;
 				return NULL;
 			}
 			ipn.in_pmin = htons(ipn.in_dport);
@@ -240,6 +260,7 @@ int linenum;
 			if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip,
 				     (u_32_t *)&ipn.in_srcmsk, &ipn.in_dport,
 				     &ipn.in_dcmp, &ipn.in_dtop, linenum)) {
+				*status = -1;
 				return NULL;
 			}
 		}
@@ -247,30 +268,39 @@ int linenum;
 		s = *cpp;
 		if (!s) {
 			fprintf(stderr, "%d: short line\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		t = strchr(s, '/');
 		if (!t) {
 			fprintf(stderr, "%d: no netmask on LHS\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		*t++ = '\0';
 		if (ipn.in_redir == NAT_REDIRECT) {
-			if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1)
+			if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1){
+				*status = -1;
 				return NULL;
+			}
 			if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) {
+				*status = -1;
 				return NULL;
 			}
 		} else {
-			if (hostnum((u_32_t *)&ipn.in_inip, s, linenum) == -1)
+			if (hostnum((u_32_t *)&ipn.in_inip, s, linenum) == -1) {
+				*status = -1;
 				return NULL;
+			}
 			if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) {
+				*status = -1;
 				return NULL;
 			}
 		}
 		cpp++;
 		if (!*cpp) {
 			fprintf(stderr, "%d: short line\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 	}
@@ -283,6 +313,7 @@ int linenum;
 		if (strcasecmp(*cpp, "port")) {
 			fprintf(stderr, "%d: missing fields - 1st port\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -292,6 +323,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: missing fields (destination port)\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -319,10 +351,12 @@ int linenum;
 	 */
 	if (!*cpp) {
 		fprintf(stderr, "%d: missing fields (->)\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 	if (strcmp(*cpp, "->")) {
 		fprintf(stderr, "%d: missing ->\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 	cpp++;
@@ -330,6 +364,7 @@ int linenum;
 	if (!*cpp) {
 		fprintf(stderr, "%d: missing fields (%s)\n",
 			linenum, ipn.in_redir ? "destination" : "target");
+		*status = -1;
 		return NULL;
 	}
 
@@ -341,6 +376,7 @@ int linenum;
 				fprintf(stderr, "%d: missing fields (%s)\n",
 					linenum,
 					ipn.in_redir ? "destination":"target");
+				*status = -1;
 				return NULL;
 			}
 		}
@@ -358,6 +394,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: desination range not specified\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 	} else if (ipn.in_redir != NAT_REDIRECT) {
@@ -371,6 +408,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: missing fields (dest netmask)\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (*dnetm == '/')
@@ -383,20 +421,25 @@ int linenum;
 			ipn.in_flags |= IPN_SPLIT;
 			*dnetm++ = '\0';
 		}
-		if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1)
+		if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1) {
+			*status = -1;
 			return NULL;
+		}
 #if SOLARIS
 		if (ntohl(ipn.in_inip) == INADDR_LOOPBACK) {
 			fprintf(stderr,
 				"localhost as destination not supported\n");
+			*status = -1;
 			return NULL;
 		}
 #endif
 	} else {
 		if (!strcmp(*cpp, ipn.in_ifname))
 			*cpp = "0";
-		if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1)
+		if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1) {
+			*status = -1;
 			return NULL;
+		}
 	}
 	cpp++;
 
@@ -406,6 +449,7 @@ int linenum;
 				fprintf(stderr,
 					"%d: expected \"ports\" - got \"%s\"\n",
 					linenum, *cpp);
+				*status = -1;
 				return NULL;
 			}
 			cpp++;
@@ -413,6 +457,7 @@ int linenum;
 				fprintf(stderr,
 					"%d: missing argument to \"ports\"\n",
 					linenum);
+				*status = -1;
 				return NULL;
 			}
 			if (!strcasecmp(*cpp, "auto"))
@@ -426,12 +471,14 @@ int linenum;
 		if (*cpp && (strrchr(*cpp, '/') != NULL)) {
 			fprintf(stderr, "%d: No netmask supported in %s\n",
 				linenum, "destination host for redirect");
+			*status = -1;
 			return NULL;
 		}
 
 		if (!*cpp) {
 			fprintf(stderr, "%d: Missing destination port %s\n",
 				linenum, "in redirect");
+			*status = -1;
 			return NULL;
 		}
 
@@ -440,6 +487,7 @@ int linenum;
 		if (strcasecmp(*cpp, "port")) {
 			fprintf(stderr, "%d: missing fields - 2nd port (%s)\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		cpp++;
@@ -447,6 +495,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: missing fields (destination port)\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -458,17 +507,25 @@ int linenum;
 	if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) {
 		if (ipn.in_flags & IPN_IPRANGE) {
 			if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm,
-				    linenum) == -1)
+				    linenum) == -1) {
+				*status = -1;
 				return NULL;
-		} else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk))
+			}
+		} else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk)) {
+			*status = -1;
 			return NULL;
+		}
 	} else {
 		if (ipn.in_flags & IPN_SPLIT) {
 			if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm,
-				    linenum) == -1)
+				    linenum) == -1) {
+				*status = -1;
 				return NULL;
-		} else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk))
+			}
+		} else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk)){
+			*status = -1;
 			return NULL;
+		}
 		if (!*cpp) {
 			ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */
 			proto = "tcp";
@@ -494,6 +551,7 @@ int linenum;
 						fprintf(stderr,
 						"%d: Unknown protocol %s\n",
 							linenum, proto);
+						*status = -1;
 						return NULL;
 					} else
 						ipn.in_p = atoi(proto);
@@ -520,6 +578,7 @@ int linenum;
 					fprintf(stderr,
 						"%d: age with no parameters\n",
 						linenum);
+					*status = -1;
 					return NULL;
 				}
 
@@ -541,6 +600,7 @@ int linenum;
 					fprintf(stderr,
 					   "%d: mssclamp with no parameters\n",
 						linenum);
+					*status = -1;
 					return NULL;
 				}
 			}
@@ -549,26 +609,33 @@ int linenum;
 				fprintf(stderr,
 				"%d: extra junk at the end of the line: %s\n",
 					linenum, *cpp);
+				*status = -1;
 				return NULL;
 			}
 		}
 	}
 
 	if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) {
-		if (!portnum(port1a, &ipn.in_pmin, linenum))
+		if (!portnum(port1a, &ipn.in_pmin, linenum)) {
+			*status = -1;
 			return NULL;
+		}
 		ipn.in_pmin = htons(ipn.in_pmin);
 		if (port1b != NULL) {
-			if (!portnum(port1b, &ipn.in_pmax, linenum))
+			if (!portnum(port1b, &ipn.in_pmax, linenum)) {
+				*status = -1;
 				return NULL;
+			}
 			ipn.in_pmax = htons(ipn.in_pmax);
 		} else
 			ipn.in_pmax = ipn.in_pmin;
 	}
 
 	if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) {
-		if (!portnum(port2a, &ipn.in_pnext, linenum))
+		if (!portnum(port2a, &ipn.in_pnext, linenum)) {
+			*status = -1;
 			return NULL;
+		}
 		ipn.in_pnext = htons(ipn.in_pnext);
 	}
 
@@ -586,13 +653,18 @@ int linenum;
 		ipn.in_flags |= IPN_FRAG;
 	}
 
-	if (!*cpp)
+	if (!*cpp) {
+		*status = 0;
 		return &ipn;
+	}
 
 	if (ipn.in_redir != NAT_BIMAP && !strcasecmp(*cpp, "proxy")) {
+		u_short pport;
+
 		if (ipn.in_redir == NAT_BIMAP) {
 			fprintf(stderr, "%d: cannot use proxy with bimap\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		cpp++;
@@ -600,6 +672,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: missing parameter for \"proxy\"\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		dport = NULL;
@@ -610,6 +683,7 @@ int linenum;
 				fprintf(stderr,
 					"%d: missing parameter for \"port\"\n",
 					linenum);
+				*status = -1;
 				return NULL;
 			}
 
@@ -620,11 +694,13 @@ int linenum;
 				fprintf(stderr,
 					"%d: missing parameter for \"proxy\"\n",
 					linenum);
+				*status = -1;
 				return NULL;
 			}
 		} else {
 			fprintf(stderr,
 				"%d: missing keyword \"port\"\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -637,9 +713,17 @@ int linenum;
 		} else
 			ipn.in_p = 0;
 
-		if (dport && !portnum(dport, &ipn.in_dport, linenum))
+		if (dport && !portnum(dport, &pport, linenum))
 			return NULL;
-		ipn.in_dport = htons(ipn.in_dport);
+		if (ipn.in_dcmp != 0) {
+			if (pport != ipn.in_dport) {
+				fprintf(stderr,
+					"%d: mismatch in port numbers\n",
+					linenum);
+				return NULL;
+			}
+		} else
+			ipn.in_dport = htons(pport);
 
 		(void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel));
 		cpp++;
@@ -648,6 +732,7 @@ int linenum;
 		if (ipn.in_redir == NAT_BIMAP) {
 			fprintf(stderr, "%d: cannot use portmap with bimap\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		cpp++;
@@ -655,6 +740,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: missing expression following portmap\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -670,6 +756,7 @@ int linenum;
 			fprintf(stderr,
 				"%d: expected protocol name - got \"%s\"\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		proto = *cpp;
@@ -677,6 +764,7 @@ int linenum;
 
 		if (!*cpp) {
 			fprintf(stderr, "%d: no port range found\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -691,12 +779,15 @@ int linenum;
 				fprintf(stderr,
 					"%d: no port range in \"%s\"\n",
 					linenum, *cpp);
+				*status = -1;
 				return NULL;
 			}
 			*t++ = '\0';
 			if (!portnum(*cpp, &ipn.in_pmin, linenum) ||
-			    !portnum(t, &ipn.in_pmax, linenum))
+			    !portnum(t, &ipn.in_pmax, linenum)) {
+				*status = -1;
 				return NULL;
+			}
 			ipn.in_pmin = htons(ipn.in_pmin);
 			ipn.in_pmax = htons(ipn.in_pmax);
 			cpp++;
@@ -713,6 +804,7 @@ int linenum;
 		if (!*cpp) {
 			fprintf(stderr, "%d: age with no parameters\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		ipn.in_age[0] = atoi(*cpp);
@@ -732,6 +824,7 @@ int linenum;
 		} else {
 			fprintf(stderr, "%d: mssclamp with no parameters\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 	}
@@ -739,8 +832,11 @@ int linenum;
 	if (*cpp) {
 		fprintf(stderr, "%d: extra junk at the end of the line: %s\n",
 			linenum, *cpp);
+		*status = -1;
 		return NULL;
 	}
+
+	*status = 0;
 	return &ipn;
 }
 
@@ -754,6 +850,7 @@ int opts;
 	ipnat_t	*np;
 	FILE	*fp;
 	int	linenum = 0;
+	int	parsestatus;
 
 	if (strcmp(file, "-")) {
 		if (!(fp = fopen(file, "r"))) {
@@ -770,11 +867,20 @@ int opts;
 		if ((s = strchr(line, '\n')))
 			*s = '\0';
 
-		if (!(np = natparse(line, linenum))) {
-			if (*line)
+		parsestatus = 1;
+		np = natparse(line, linenum, &parsestatus);
+		if (parsestatus != 0) {
+			if (*line) {
 				fprintf(stderr, "%d: syntax error in \"%s\"\n",
 					linenum, line);
-		} else {
+			}
+			fprintf(stderr, "%s: %s error (%d), quitting\n",
+			    file,
+			    ((parsestatus < 0)? "parse": "internal"),
+			    parsestatus);
+			exit(1);
+		}
+		if (np) {
 			if ((opts & OPT_VERBOSE) && np)
 				printnat(np, opts);
 			if (!(opts & OPT_NODO)) {
Index: contrib/ipfilter/parse.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/parse.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 parse.c
--- contrib/ipfilter/parse.c	17 Jun 2003 02:44:52 -0000	1.1
+++ contrib/ipfilter/parse.c	17 Jul 2004 04:55:54 -0000
@@ -68,10 +68,16 @@ extern	u_char	flags[];
 /* parse()
  *
  * parse a line read from the input filter rule file
+ *
+ * status:
+ *	< 0	error
+ *	= 0	OK
+ *	> 0	programmer error
  */
-struct	frentry	*parse(line, linenum)
+struct	frentry	*parse(line, linenum, status)
 char	*line;
 int     linenum;
+int	*status;	/* good, bad, or indifferent */
 {
 	static	struct	frentry	fil;
 	char	*cps[31], **cpp, *endptr, *s;
@@ -79,10 +85,14 @@ int     linenum;
 	int	i, cnt = 1, j, ch;
 	u_int	k;
 
+	*status = 100;	/* default to error */
+
 	while (*line && isspace(*line))
 		line++;
-	if (!*line)
+	if (!*line) {
+		*status = 0;
 		return NULL;
+	}
 
 	bzero((char *)&fil, sizeof(fil));
 	fil.fr_mip.fi_v = 0xf;
@@ -100,6 +110,7 @@ int     linenum;
 
 	if (cnt < 3) {
 		fprintf(stderr, "%d: not enough segments in line\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 
@@ -143,6 +154,7 @@ int     linenum;
 					fprintf(stderr,
 					"%d: unrecognised icmp code %s\n",
 						linenum, *cpp + 20);
+					*status = -1;
 					return NULL;
 				}
 				fil.fr_icode = j;
@@ -172,6 +184,7 @@ int     linenum;
 		else {
 			fprintf(stderr, "%d: integer must follow skip\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 	} else if (!strcasecmp("log", *cpp)) {
@@ -190,8 +203,11 @@ int     linenum;
 		}
 		if (!strcasecmp(*(cpp+1), "level")) {
 			cpp++;
-			if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1)
+			if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1) {
+				/* NB loglevel prints its own error message */
+				*status = -1;
 				return NULL;
+			}
 			cpp++;
 		}
 	} else {
@@ -199,10 +215,12 @@ int     linenum;
 		 * Doesn't start with one of the action words
 		 */
 		fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp);
+		*status = -1;
 		return NULL;
 	}
 	if (!*++cpp) {
 		fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 
@@ -218,16 +236,19 @@ int     linenum;
 			fprintf(stderr,
 				"%d: Can only use return-icmp with 'in'\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		} else if (fil.fr_flags & FR_RETRST) {
 			fprintf(stderr,
 				"%d: Can only use return-rst with 'in'\n", 
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 	}
 	if (!*++cpp) {
 		fprintf(stderr, "%d: missing source specification\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 
@@ -235,6 +256,7 @@ int     linenum;
 		if (!*++cpp) {
 			fprintf(stderr, "%d: missing source specification\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (fil.fr_flags & FR_PASS)
@@ -254,14 +276,17 @@ int     linenum;
 				fprintf(stderr,
 					"%d: or-block must be used with pass\n",
 					linenum);
+				*status = -1;
 				return NULL;
 			}
 			fil.fr_flags |= FR_LOGORBLOCK;
 			cpp++;
 		}
 		if (*cpp && !strcasecmp(*cpp, "level")) {
-			if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1)
+			if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1) {
+				*status = -1;
 				return NULL;
+			}
 			cpp++;
 			cpp++;
 		}
@@ -271,6 +296,7 @@ int     linenum;
 		if (fil.fr_skip != 0) {
 			fprintf(stderr, "%d: cannot use skip with quick\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		cpp++;
@@ -287,6 +313,7 @@ int     linenum;
 		if (!*++cpp) {
 			fprintf(stderr, "%d: interface name missing\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -307,28 +334,35 @@ int     linenum;
 				fprintf(stderr,
 					"%d: %s can only be used with TCP\n",
 					linenum, "return-rst");
+				*status = -1;
 				return NULL;
 			}
+			*status = 0;
 			return &fil;
 		}
 
 		if (*cpp) {
 			if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) {
 				cpp++;
-				if (to_interface(&fil.fr_dif, *cpp, linenum))
+				if (to_interface(&fil.fr_dif, *cpp, linenum)) {
+					*status = -1;
 					return NULL;
+				}
 				cpp++;
 			}
 			if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) {
 				cpp++;
-				if (to_interface(&fil.fr_tif, *cpp, linenum))
+				if (to_interface(&fil.fr_tif, *cpp, linenum)) {
+					*status = -1;
 					return NULL;
+				}
 				cpp++;
 			} else if (*cpp && !strcasecmp(*cpp, "fastroute")) {
 				if (!(fil.fr_flags & FR_INQUE)) {
 					fprintf(stderr,
 						"can only use %s with 'in'\n",
 						"fastroute");
+					*status = -1;
 					return NULL;
 				}
 				fil.fr_flags |= FR_FASTROUTE;
@@ -366,6 +400,7 @@ int     linenum;
 	if (*cpp && !strcasecmp(*cpp, "tos")) {
 		if (!*++cpp) {
 			fprintf(stderr, "%d: tos missing value\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		fil.fr_tos = strtol(*cpp, NULL, 0);
@@ -377,6 +412,7 @@ int     linenum;
 		if (!*++cpp) {
 			fprintf(stderr, "%d: ttl missing hopcount value\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (ratoi(*cpp, &i, 0, 255))
@@ -384,6 +420,7 @@ int     linenum;
 		else {
 			fprintf(stderr, "%d: invalid ttl (%s)\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		fil.fr_mip.fi_ttl = 0xff;
@@ -397,6 +434,7 @@ int     linenum;
 	if (*cpp && !strcasecmp(*cpp, "proto")) {
 		if (!*++cpp) {
 			fprintf(stderr, "%d: protocol name missing\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		proto = *cpp++;
@@ -412,6 +450,7 @@ int     linenum;
 				fprintf(stderr,
 					"%d: unknown protocol (%s)\n",
 					linenum, proto);
+				*status = -1;
 				return NULL;
 			}
 			if (p)
@@ -422,6 +461,7 @@ int     linenum;
 					fprintf(stderr,
 						"%d: unknown protocol (%s)\n",
 						linenum, proto);
+					*status = -1;
 					return NULL;		
 				}
 				fil.fr_proto = i;
@@ -433,6 +473,7 @@ int     linenum;
 	    ((fil.fr_flags & FR_RETMASK) == FR_RETRST)) {
 		fprintf(stderr, "%d: %s can only be used with TCP\n",
 			linenum, "return-rst");
+		*status = -1;
 		return NULL;
 	}
 
@@ -442,21 +483,26 @@ int     linenum;
 
 	if (!*cpp) {
 		fprintf(stderr, "%d: missing source specification\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 	if (!strcasecmp(*cpp, "all")) {
 		cpp++;
-		if (!*cpp)
+		if (!*cpp) {
+			*status = 0;
 			return &fil;
+		}
 	} else {
 		if (strcasecmp(*cpp, "from")) {
 			fprintf(stderr, "%d: unexpected keyword (%s) - from\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		if (!*++cpp) {
 			fprintf(stderr, "%d: missing host after from\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (!strcmp(*cpp, "!")) {
@@ -465,6 +511,7 @@ int     linenum;
 				fprintf(stderr,
 					"%d: missing host after from\n",
 					linenum);
+				*status = -1;
 				return NULL;
 			}
 		} else if (**cpp == '!') {
@@ -475,6 +522,7 @@ int     linenum;
 		if (hostmask(&cpp, (u_32_t *)&fil.fr_src,
 			     (u_32_t *)&fil.fr_smsk, &fil.fr_sport, &ch,
 			     &fil.fr_stop, linenum)) {
+			*status = -1;
 			return NULL;
 		}
 
@@ -484,12 +532,14 @@ int     linenum;
 			fprintf(stderr,
 				"%d: cannot use port and neither tcp or udp\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
 		fil.fr_scmp = ch;
 		if (!*cpp) {
 			fprintf(stderr, "%d: missing to fields\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -499,10 +549,12 @@ int     linenum;
 		if (strcasecmp(*cpp, "to")) {
 			fprintf(stderr, "%d: unexpected keyword (%s) - to\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		if (!*++cpp) {
 			fprintf(stderr, "%d: missing host after to\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		ch = 0;
@@ -512,6 +564,7 @@ int     linenum;
 				fprintf(stderr,
 					"%d: missing host after from\n",
 					linenum);
+				*status = -1;
 				return NULL;
 			}
 		} else if (**cpp == '!') {
@@ -521,6 +574,7 @@ int     linenum;
 		if (hostmask(&cpp, (u_32_t *)&fil.fr_dst,
 			     (u_32_t *)&fil.fr_dmsk, &fil.fr_dport, &ch,
 			     &fil.fr_dtop, linenum)) {
+			*status = -1;
 			return NULL;
 		}
 		if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
@@ -529,6 +583,7 @@ int     linenum;
 			fprintf(stderr,
 				"%d: cannot use port and neither tcp or udp\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 
@@ -542,20 +597,25 @@ int     linenum;
 	if (fil.fr_proto && (fil.fr_dcmp || fil.fr_scmp) &&
 	    fil.fr_proto != IPPROTO_TCP && fil.fr_proto != IPPROTO_UDP) {
 		fprintf(stderr, "%d: port operation on non tcp/udp\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 	if (fil.fr_icmp && fil.fr_proto != IPPROTO_ICMP) {
 		fprintf(stderr, "%d: icmp comparisons on wrong protocol\n",
 			linenum);
+		*status = -1;
 		return NULL;
 	}
 
-	if (!*cpp)
+	if (!*cpp) {
+		*status = 0;
 		return &fil;
+	}
 
 	if (*cpp && !strcasecmp(*cpp, "flags")) {
 		if (!*++cpp) {
 			fprintf(stderr, "%d: no flags present\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		fil.fr_tcpf = tcp_flags(*cpp, &fil.fr_tcpfm, linenum);
@@ -567,8 +627,10 @@ int     linenum;
 	 */
 	if ((fil.fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") ||
 	     !strcasecmp(*cpp, "and")))
-		if (extras(&cpp, &fil, linenum))
+		if (extras(&cpp, &fil, linenum)) {
+			*status = -1;
 			return NULL;
+		}
 
 	/*
 	 * icmp types for use with the icmp protocol
@@ -579,10 +641,13 @@ int     linenum;
 			fprintf(stderr,
 				"%d: icmp with wrong protocol (%d)\n",
 				linenum, fil.fr_proto);
+			*status = -1;
 			return NULL;
 		}
-		if (addicmp(&cpp, &fil, linenum))
+		if (addicmp(&cpp, &fil, linenum)) {
+			*status = -1;
 			return NULL;
+		}
 		fil.fr_icmp = htons(fil.fr_icmp);
 		fil.fr_icmpm = htons(fil.fr_icmpm);
 	}
@@ -591,8 +656,10 @@ int     linenum;
 	 * Keep something...
 	 */
 	while (*cpp && !strcasecmp(*cpp, "keep"))
-		if (addkeep(&cpp, &fil, linenum))
+		if (addkeep(&cpp, &fil, linenum)) {
+			*status = -1;
 			return NULL;
+		}
 
 	/*
 	 * This is here to enforce the old interface binding behaviour.
@@ -614,10 +681,12 @@ int     linenum;
 		if (fil.fr_skip != 0) {
 			fprintf(stderr, "%d: cannot use skip with head\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (!*++cpp) {
 			fprintf(stderr, "%d: head without group #\n", linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (ratoui(*cpp, &k, 0, UINT_MAX))
@@ -625,6 +694,7 @@ int     linenum;
 		else {
 			fprintf(stderr, "%d: invalid group (%s)\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		cpp++;
@@ -637,6 +707,7 @@ int     linenum;
 		if (!*++cpp) {
 			fprintf(stderr, "%d: group without group #\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 		if (ratoui(*cpp, &k, 0, UINT_MAX))
@@ -644,6 +715,7 @@ int     linenum;
 		else {
 			fprintf(stderr, "%d: invalid group (%s)\n",
 				linenum, *cpp);
+			*status = -1;
 			return NULL;
 		}
 		cpp++;
@@ -657,6 +729,7 @@ int     linenum;
 		for (; *cpp; cpp++)
 			fprintf(stderr, "%s ", *cpp);
 		fprintf(stderr, "]\n");
+		*status = -1;
 		return NULL;
 	}
 
@@ -665,6 +738,7 @@ int     linenum;
 	 */
 	if ((fil.fr_tcpf || fil.fr_tcpfm) && fil.fr_proto != IPPROTO_TCP) {
 		fprintf(stderr, "%d: TCP protocol not specified\n", linenum);
+		*status = -1;
 		return NULL;
 	}
 	if (!(fil.fr_ip.fi_fl & FI_TCPUDP) && (fil.fr_proto != IPPROTO_TCP) &&
@@ -676,6 +750,7 @@ int     linenum;
 			fprintf(stderr,
 				"%d: port comparisons for non-TCP/UDP\n",
 				linenum);
+			*status = -1;
 			return NULL;
 		}
 	}
@@ -685,9 +760,11 @@ int     linenum;
 		fprintf(stderr,
 			"%d: must use 'with frags' with 'keep frags'\n",
 			linenum);
+		*status = -1;
 		return NULL;
 	}
 */
+	*status = 0;
 	return &fil;
 }
 
Index: contrib/ipfilter/printnat.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/printnat.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 printnat.c
--- contrib/ipfilter/printnat.c	17 Jun 2003 02:44:52 -0000	1.1
+++ contrib/ipfilter/printnat.c	17 Jul 2004 04:55:54 -0000
@@ -58,7 +58,7 @@ extern	char	*sys_errlist[];
 #endif
 
 #if !defined(lint)
-static const char rcsid[] = "@(#)$Id: printnat.c,v 1.1.2.13 2002/12/06 11:40:27 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: printnat.c,v 1.1.2.15 2003/03/22 15:31:49 darrenr Exp $";
 #endif
 
 
@@ -399,7 +399,6 @@ int opts;
 			       np->in_space, np->in_flags,
 			       np->in_pmax, np->in_use);
 	} else {
-		np->in_nextip.s_addr = htonl(np->in_nextip.s_addr);
 		if (!(np->in_flags & IPN_FILTER)) {
 			printf("%s/", inet_ntoa(np->in_in[0]));
 			bits = countbits(np->in_in[1].s_addr);
@@ -422,6 +421,8 @@ int opts;
 		}
 		if (*np->in_plabel) {
 			printf(" proxy port");
+			if (np->in_dcmp != 0)
+				np->in_dport = htons(np->in_dport);
 			if (np->in_dport != 0) {
 				if (pr != NULL)
 					sv = getservbyport(np->in_dport,
@@ -473,8 +474,12 @@ int opts;
 			printf(" age %d/%d", np->in_age[0], np->in_age[1]);
 		printf("\n");
 		if (opts & OPT_DEBUG) {
+			struct in_addr nip;
+
+			nip.s_addr = htonl(np->in_nextip.s_addr);
+
 			printf("\tspace %lu nextip %s pnext %d", np->in_space,
-			       inet_ntoa(np->in_nextip), np->in_pnext);
+			       inet_ntoa(nip), np->in_pnext);
 			printf(" flags %x use %u\n",
 			       np->in_flags, np->in_use);
 		}
Index: contrib/ipfilter/printstate.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/printstate.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 printstate.c
--- contrib/ipfilter/printstate.c	17 Jun 2003 02:44:52 -0000	1.1
+++ contrib/ipfilter/printstate.c	17 Jul 2004 04:55:54 -0000
@@ -47,22 +47,26 @@ int opts;
 #else
 	PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes);
 #endif
-	if (ips.is_p == IPPROTO_TCP)
+	if (ips.is_p == IPPROTO_TCP) {
 #if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
 (__FreeBSD_version >= 220000) || defined(__OpenBSD__)
-		PRINTF("\t%hu -> %hu %x:%x %u<<%d:%u<<%d",
+		PRINTF("\t%hu -> %hu %x:%x (max %x:%x)\n",
 			ntohs(ips.is_sport), ntohs(ips.is_dport),
 			ips.is_send, ips.is_dend,
+			ips.is_maxsend, ips.is_maxdend);
+		PRINTF("\t%u<<%d:%u<<%d",
 			ips.is_maxswin>>ips.is_swscale, ips.is_swscale,
 			ips.is_maxdwin>>ips.is_dwscale, ips.is_dwscale);
 #else
-		PRINTF("\t%hu -> %hu %x:%x %u<<%d:%u<<%d",
+		PRINTF("\t%hu -> %hu %x:%x (max %x:%x)\n",
 			ntohs(ips.is_sport), ntohs(ips.is_dport),
 			ips.is_send, ips.is_dend,
+			ips.is_maxsend, ips.is_maxdend);
+		PRINTF("\t%u<<%d:%u<<%d",
 			ips.is_maxswin>>ips.is_swscale, ips.is_swscale,
 			ips.is_maxdwin>>ips.is_dwscale, ips.is_dwscale);
 #endif
-	else if (ips.is_p == IPPROTO_UDP)
+	} else if (ips.is_p == IPPROTO_UDP)
 		PRINTF(" %hu -> %hu", ntohs(ips.is_sport),
 			ntohs(ips.is_dport));
 	else if (ips.is_p == IPPROTO_ICMP
Index: contrib/ipfilter/BSD/kupgrade
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/BSD/kupgrade,v
retrieving revision 1.1
diff -u -p -u -r1.1 kupgrade
--- contrib/ipfilter/BSD/kupgrade	17 Jun 2003 02:44:52 -0000	1.1
+++ contrib/ipfilter/BSD/kupgrade	17 Jul 2004 04:55:54 -0000
@@ -16,6 +16,9 @@ if [ $os = FreeBSD ] ; then
 		echo "Copying /usr/include/osreldate.h to /sys/sys"
 		cp /usr/include/osreldate.h /sys/sys
 	fi
+	if [ -f /sys/contrib/ipfilter/netinet/mlfk_ipl.c ] ; then
+		/bin/cp mlfk_ipl.c /sys/contrib/ipfilter/netinet/
+	fi
 fi
 archdir="/sys/arch/$karch"
 ipfdir=/sys/netinet
Index: contrib/ipfilter/iplang/iplang_l.l
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/iplang/iplang_l.l,v
retrieving revision 1.1
diff -u -p -u -r1.1 iplang_l.l
--- contrib/ipfilter/iplang/iplang_l.l	17 Jun 2003 02:44:53 -0000	1.1
+++ contrib/ipfilter/iplang/iplang_l.l	17 Jul 2004 04:55:54 -0000
@@ -6,7 +6,7 @@
  * provided that this notice is preserved and due credit is given
  * to the original author and the contributors.
  *
- * $Id: iplang_l.l,v 2.2 2000/02/18 00:18:05 darrenr Exp $
+ * $Id: iplang_l.l,v 2.2.2.1 2003/07/28 01:15:59 darrenr Exp $
  */
 #include <stdio.h>
 #include <string.h>
@@ -318,5 +318,6 @@ void swallow()
 		while ((c != '\n') && (c != EOF))
 			c = input();
 	}
-	unput(c);
+	if (c != EOF)
+		unput(c);
 }
Index: contrib/ipfilter/ipsend/ipsend.1
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipsend/ipsend.1,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipsend.1
--- contrib/ipfilter/ipsend/ipsend.1	17 Jun 2003 02:44:54 -0000	1.1
+++ contrib/ipfilter/ipsend/ipsend.1	17 Jul 2004 04:55:54 -0000
@@ -51,7 +51,7 @@ enable debugging mode.
 .TP
 .BR \-f \0<offset>
 The \fI-f\fP allows the IP offset field in the IP header to be set to an
-arbitrary value, which can be specified in decimal or hexidecimal.
+arbitrary value, which can be specified in decimal or hexadecimal.
 .TP
 .BR \-g \0<gateway>
 Specify the hostname of the gateway through which to route packets.  This
Index: contrib/ipfilter/ipsend/ipsend.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipsend/ipsend.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipsend.c
--- contrib/ipfilter/ipsend/ipsend.c	17 Jun 2003 04:24:02 -0000	1.2
+++ contrib/ipfilter/ipsend/ipsend.c	17 Jul 2004 04:55:54 -0000
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/contrib/ipfilter/ipsend/ipsend.c,v 1.4.2.5 2003/03/01 03:55:53 darrenr Exp $ */
-/* $DragonFly: src/contrib/ipfilter/ipsend/ipsend.c,v 1.2 2003/06/17 04:24:02 dillon Exp $ */
+/* $FreeBSD: src/contrib/ipfilter/ipsend/ipsend.c,v 1.4.2.6 2004/07/04 09:24:40 darrenr Exp $ */
 /*
  * ipsend.c (C) 1995-1998 Darren Reed
  *
@@ -26,8 +26,10 @@
 #include <arpa/inet.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/ip_var.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
+#include <netinet/udp_var.h>
 #include <netinet/ip_icmp.h>
 #ifndef	linux
 #include <netinet/ip_var.h>
@@ -71,6 +73,7 @@ char	default_device[] = "lan0";
 
 static	void	usage __P((char *));
 static	void	do_icmp __P((ip_t *, char *));
+void udpcksum(ip_t *, struct udphdr *, int);
 int	main __P((int, char **));
 
 
@@ -170,6 +173,37 @@ struct in_addr gwip;
 	return send_packet(wfd, mtu, ip, gwip);
 }
 
+void
+udpcksum(ip_t *ip, struct udphdr *udp, int len)
+{
+	union pseudoh {
+		struct hdr {
+			u_short len;
+			u_char ttl;
+			u_char proto;
+			u_32_t src;
+			u_32_t dst;
+		} h;
+		u_short w[6];
+	} ph;
+	u_32_t temp32;
+	u_short cksum, *opts;
+
+	ph.h.len = htons(len);
+	ph.h.ttl = 0;
+	ph.h.proto = IPPROTO_UDP;
+	ph.h.src = ip->ip_src.s_addr;
+	ph.h.dst = ip->ip_dst.s_addr;
+	temp32 = 0;
+	opts = &ph.w[0];
+	temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5];
+	temp32 = (temp32 >> 16) + (temp32 & 65535);
+	temp32 += (temp32 >> 16);
+	udp->uh_sum = temp32 & 65535;
+	udp->uh_sum = chksum((u_short *)udp, len);
+	if (udp->uh_sum == 0)
+		udp->uh_sum = 0xffff;
+}
 
 int main(argc, argv)
 int	argc;
@@ -177,8 +211,10 @@ char	**argv;
 {
 	FILE	*langfile = NULL;
 	struct	tcpiphdr *ti;
+	struct	udpiphdr *ui;
 	struct	in_addr	gwip;
 	tcphdr_t	*tcp;
+	udphdr_t	*udp;
 	ip_t	*ip;
 	char	*name =  argv[0], host[MAXHOSTNAMELEN + 1];
 	char	*gateway = NULL, *dev = NULL;
@@ -190,7 +226,10 @@ char	**argv;
 	 */
 	ip = (ip_t *)calloc(1, 65536);
 	ti = (struct tcpiphdr *)ip;
+	ui = (struct udpiphdr *)ip;
 	tcp = (tcphdr_t *)&ti->ti_sport;
+	udp = (udphdr_t *)&ui->ui_sport;
+	ui->ui_ulen = htons(sizeof(*udp));
 	ip->ip_len = sizeof(*ip);
 	ip->ip_hl = sizeof(*ip) >> 2;
 
@@ -344,27 +383,35 @@ char	**argv;
 		exit(2);
 	    }
 
+	if (ip->ip_p != IPPROTO_TCP && ip->ip_p != IPPROTO_UDP) {
+		fprintf(stderr,"Unsupported protocol %d\n", ip->ip_p);
+		exit(2);
+	}
+
 	if (olen)
 	    {
-		caddr_t	ipo = (caddr_t)ip;
+		int hlen;
+		char *p;
 
 		printf("Options: %d\n", olen);
-		ti = (struct tcpiphdr *)malloc(olen + ip->ip_len);
-		if(!ti)
+		hlen = sizeof(*ip) + olen;
+		ip->ip_hl = hlen >> 2;
+		ip->ip_len += olen;
+		p = (char *)malloc(65536);
+		if(!p)
 		    {
 			fprintf(stderr,"malloc failed\n");
 			exit(2);
 		    } 
-
-		bcopy((char *)ip, (char *)ti, sizeof(*ip));
-		ip = (ip_t *)ti;
-		ip->ip_hl = (olen >> 2);
-		bcopy(options, (char *)(ip + 1), olen);
-		bcopy((char *)tcp, (char *)(ip + 1) + olen, sizeof(*tcp));
-		ip->ip_len += olen;
-		bcopy((char *)ip, (char *)ipo, ip->ip_len);
-		ip = (ip_t *)ipo;
-		tcp = (tcphdr_t *)((char *)(ip + 1) + olen);
+		bcopy(ip, p, sizeof(*ip));
+		bcopy(options, p + sizeof(*ip), olen);
+		bcopy(ip + 1, p + hlen, ip->ip_len - hlen);
+		ip = (ip_t *)p;
+		if (ip->ip_p == IPPROTO_TCP) {
+			tcp = (tcphdr_t *)((char *)ip + hlen);
+		} else {
+			udp = (udphdr_t *)((char *)ip + hlen);
+		}
 	    }
 
 	if (ip->ip_p == IPPROTO_TCP)
@@ -401,9 +448,13 @@ char	**argv;
 		printf("Flags:   %#x\n", tcp->th_flags);
 	printf("mtu:     %d\n", mtu);
 
+	if (ip->ip_p == IPPROTO_UDP) {
+		udp->uh_sum = 0;
+		udpcksum(ip, udp, (ip->ip_len) - (ip->ip_hl << 2));
+	}
 #ifdef	DOSOCKET
-	if (tcp->th_dport)
-		return do_socket(dev, mtu, ti, gwip);
+	if (ip->ip_p == IPPROTO_TCP && tcp->th_dport)
+		return do_socket(dev, mtu, (struct tcpiphdr *)ip, gwip);
 #endif
-	return send_packets(dev, mtu, (ip_t *)ti, gwip);
+	return send_packets(dev, mtu, ip, gwip);
 }
Index: contrib/ipfilter/ipsend/ipsopt.c
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/ipsend/ipsopt.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipsopt.c
--- contrib/ipfilter/ipsend/ipsopt.c	17 Jun 2003 02:44:54 -0000	1.1
+++ contrib/ipfilter/ipsend/ipsopt.c	17 Jul 2004 04:55:54 -0000
@@ -25,7 +25,7 @@
 
 #if !defined(lint)
 static const char sccsid[] = "@(#)ipsopt.c	1.2 1/11/96 (C)1995 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.4 2002/12/06 11:40:35 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.5 2004/04/10 11:50:52 darrenr Exp $";
 #endif
 
 
@@ -98,7 +98,10 @@ char *class;
 			len += val;
 		} else
 			*op++ = io->on_siz;
-		*op++ = IPOPT_MINOFF;
+		if (io->on_value == IPOPT_TS)
+			*op++ = IPOPT_MINOFF + 1;
+		else
+			*op++ = IPOPT_MINOFF;
 
 		while (class && *class) {
 			t = NULL;
Index: contrib/ipfilter/man/ipf.5
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/man/ipf.5,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipf.5
--- contrib/ipfilter/man/ipf.5	17 Jun 2003 04:24:02 -0000	1.2
+++ contrib/ipfilter/man/ipf.5	17 Jul 2004 04:55:54 -0000
@@ -1,12 +1,12 @@
 .\" $FreeBSD: src/contrib/ipfilter/man/ipf.5,v 1.4.2.3 2003/03/01 03:55:53 darrenr Exp $
-.\" $DragonFly: src/contrib/ipfilter/man/ipf.5,v 1.2 2003/06/17 04:24:02 dillon Exp $
+.\" $FreeBSD: src/contrib/ipfilter/man/ipf.5,v 1.4.2.4 2004/07/04 09:24:40 darrenr Exp $
 .TH IPF 5
 .SH NAME
-ipf, ipf.conf \- IP packet filter rule syntax
+ipf, ipf.conf, ipf6.conf \- IP packet filter rule syntax
 .SH DESCRIPTION
 .PP
 A rule file for \fBipf\fP may have any name or even be stdin.  As
-\fBipfstat\fP produces parseable rules as output when displaying the internal
+\fBipfstat\fP produces parsable rules as output when displaying the internal
 kernel filter lists, it is quite plausible to use its output to feed back
 into \fBipf\fP.  Thus, to remove all filters on input packets, the following
 could be done:
@@ -39,7 +39,7 @@ log	= "log" [ "body" ] [ "first" ] [ "or
 call	= "call" [ "now" ] function-name .
 skip	= "skip" decnumber .
 dup	= "dup-to" interface-name[":"ipaddr] .
-froute	= "fastroute" | "to" interface-name .
+froute	= "fastroute" | "to" interface-name[":"ipaddr] .
 protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
 srcdst	= "all" | fromto .
 fromto	= "from" [ "!" ] object "to" [ "!" ] object .
@@ -118,7 +118,7 @@ below).
 Filters are installed by default at the end of the kernel's filter
 lists, prepending the rule with \fB@n\fP will cause it to be inserted
 as the n'th entry in the current list. This is especially useful when
-modifying and testing active filter rulesets. See ipf(1) for more
+modifying and testing active filter rulesets. See ipf(8) for more
 information.
 .SH ACTIONS
 .PP
@@ -138,7 +138,7 @@ with a rule which is being applied to TC
 \fBreturn-icmp\fP or \fBreturn-icmp-as-dest\fP, it is possible to specify
 the actual unreachable `type'.  That is, whether it is a network
 unreachable, port unreachable or even administratively
-prohibitied. This is done by enclosing the ICMP code associated with
+prohibited. This is done by enclosing the ICMP code associated with
 it in parenthesis directly following \fBreturn-icmp\fP or
 \fBreturn-icmp-as-dest\fP as follows:
 .nf
@@ -388,7 +388,7 @@ against, e.g.:
 .TP
 .B icmp-type
 is only effective when used with \fBproto icmp\fP and must NOT be used
-in conjuction with \fBflags\fP.  There are a number of types, which can be
+in conjunction with \fBflags\fP.  There are a number of types, which can be
 referred to by an abbreviation recognised by this language, or the numbers
 with which they are associated can be used.  The most important from
 a security point of view is the ICMP redirect.
@@ -429,7 +429,7 @@ indicates that the rule should be put in
 .PP
 When a packet is logged, with either the \fBlog\fP action or option,
 the headers of the packet are written to the \fBipl\fP packet logging
-psuedo-device. Immediately following the \fBlog\fP keyword, the
+pseudo-device. Immediately following the \fBlog\fP keyword, the
 following qualifiers may be used (in order):
 .TP
 .B body
Index: contrib/ipfilter/man/ipf.8
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/man/ipf.8,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipf.8
--- contrib/ipfilter/man/ipf.8	17 Jun 2003 04:24:02 -0000	1.2
+++ contrib/ipfilter/man/ipf.8	17 Jul 2004 04:55:54 -0000
@@ -1,5 +1,5 @@
 .\" $FreeBSD: src/contrib/ipfilter/man/ipf.8,v 1.3.2.2 2003/03/01 03:55:53 darrenr Exp $
-.\" $DragonFly: src/contrib/ipfilter/man/ipf.8,v 1.2 2003/06/17 04:24:02 dillon Exp $
+.\" $FreeBSD: src/contrib/ipfilter/man/ipf.8,v 1.3.2.3 2004/07/04 09:24:40 darrenr Exp $
 .TH IPF 8
 .SH NAME
 ipf \- alters packet filtering lists for IP packet input and output
@@ -114,7 +114,7 @@ the current interface status list.
 .TP
 .B \-z
 For each rule in the input file, reset the statistics for it to zero and
-display the statistics prior to them being zero'd.
+display the statistics prior to them being zeroed.
 .TP
 .B \-Z
 Zero global statistics held in the kernel for filtering only (this doesn't
Index: contrib/ipfilter/man/ipfstat.8
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/man/ipfstat.8,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipfstat.8
--- contrib/ipfilter/man/ipfstat.8	17 Jun 2003 04:24:02 -0000	1.2
+++ contrib/ipfilter/man/ipfstat.8	17 Jul 2004 04:55:54 -0000
@@ -1,5 +1,5 @@
 .\" $FreeBSD: src/contrib/ipfilter/man/ipfstat.8,v 1.3.2.4 2003/03/01 03:55:53 darrenr Exp $
-.\" $DragonFly: src/contrib/ipfilter/man/ipfstat.8,v 1.2 2003/06/17 04:24:02 dillon Exp $
+.\" $FreeBSD: src/contrib/ipfilter/man/ipfstat.8,v 1.3.2.5 2004/07/04 09:24:40 darrenr Exp $
 .TH ipfstat 8
 .SH NAME
 ipfstat \- reports on packet filter statistics and filter list
@@ -66,7 +66,7 @@ This option is only valid in combination
 display to show only state entries whose destination IP address and port
 match the addport argument. The addrport specification is of the form
 ipaddress[,port].  The ipaddress and port should be either numerical or the
-string "any" (specifying any ip address resp. any port). If the \fB\-D\fP
+string "any" (specifying any IP address resp. any port). If the \fB\-D\fP
 option is not specified, it defaults to "\fB\-D\fP any,any".
 .TP
 .B \-f
@@ -142,7 +142,7 @@ kernel.
 Using the \fB\-t\fP option \fBipfstat\fP will enter the state top mode. In
 this mode the state table is displayed similar to the way \fBtop\fP displays
 the process table. The \fB\-C\fP, \fB\-D\fP, \fB\-P\fP, \fB\-S\fP and \fB\-T\fP 
-commandline options can be used to restrict the state entries that will be 
+command line options can be used to restrict the state entries that will be 
 shown and to specify the frequency of display updates.
 .PP
 In state top mode, the following keys can be used to influence the displayed
Index: contrib/ipfilter/man/ipl.4
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/man/ipl.4,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipl.4
--- contrib/ipfilter/man/ipl.4	17 Jun 2003 02:44:54 -0000	1.1
+++ contrib/ipfilter/man/ipl.4	17 Jul 2004 04:55:54 -0000
@@ -7,7 +7,7 @@ packet headers of packets you wish to lo
 logged, the entire header is logged (including any IP options \- TCP/UDP
 options are not included when it calculates header size) or not at all.
 The packet contents are also logged after the header.  If the log reader
-is busy or otherwise unable to read log records, upto IPLLOGSIZE (8192 is the
+is busy or otherwise unable to read log records, up to IPLLOGSIZE (8192 is the
 default) bytes of data are stored.
 .PP
 Prepending every packet header logged is a structure containing information
Index: contrib/ipfilter/man/ipmon.8
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/man/ipmon.8,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipmon.8
--- contrib/ipfilter/man/ipmon.8	17 Jun 2003 04:24:02 -0000	1.2
+++ contrib/ipfilter/man/ipmon.8	17 Jul 2004 04:55:54 -0000
@@ -1,5 +1,5 @@
 .\" $FreeBSD: src/contrib/ipfilter/man/ipmon.8,v 1.6.2.5 2003/03/01 03:55:53 darrenr Exp $
-.\" $DragonFly: src/contrib/ipfilter/man/ipmon.8,v 1.2 2003/06/17 04:24:02 dillon Exp $
+.\" $FreeBSD: src/contrib/ipfilter/man/ipmon.8,v 1.6.2.6 2004/07/04 09:24:40 darrenr Exp $
 .TH ipmon 8
 .SH NAME
 ipmon \- monitors /dev/ipl for logged packets
@@ -84,11 +84,11 @@ are displayed to the same output 'device
 .TP
 .B \-b
 For rules which log the body of a packet, generate hex output representing
-the packet contents afte the headers.
+the packet contents after the headers.
 .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 indefinately.
+of ipmon is not required to turn it into an orphan so it can run indefinitely.
 .TP
 .B "\-f <device>"
 specify an alternative device/file from which to read the log information
@@ -172,3 +172,5 @@ recorded data.
 .SH SEE ALSO
 ipl(4), ipf(8), ipfstat(8), ipnat(8)
 .\".SH BUGS
+.PP
+If you find any, please send email to me at darrenr@pobox.com
Index: contrib/ipfilter/man/ipnat.5
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/man/ipnat.5,v
retrieving revision 1.1
diff -u -p -u -r1.1 ipnat.5
--- contrib/ipfilter/man/ipnat.5	17 Jun 2003 02:44:55 -0000	1.1
+++ contrib/ipfilter/man/ipnat.5	17 Jul 2004 04:55:54 -0000
@@ -12,16 +12,16 @@ map ::= mapit ifname fromto "->" dstipma
 mapblock ::= "map-block" ifname ipmask "->" ipmask [ ports ] mapoptions.
 redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] rdrport rdroptions .
 
-dport ::= "port" portnum [ "-" portnum ] .
-ports ::= "ports" numports | "auto" .
-rdrport ::= "port" portnum .
+dport ::= "port" number [ "-" number ] .
+ports ::= "ports" number | "auto" .
+rdrport ::= "port" number .
 mapit ::= "map" | "bimap" .
 fromto ::= "from" object "to" object .
 ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask .
 dstipmask ::= ipmask | "range" ip "-" ip .
 mapport ::= "portmap" tcpudp portspec .
 mapoptions ::= [ tcpudp ] [ "frag" ] [ age ] [ clamp ] .
-rdroptions ::= [ tcpudp ] [ rr ] [ "frag" ] [ age ] [ clamp ] .
+rdroptions ::= [ tcpudp | protocol ] [ rr ] [ "frag" ] [ age ] [ clamp ] .
 
 object  :: = addr [ port-comp | port-range ] .
 addr    :: = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
@@ -31,14 +31,14 @@ port-range :: = "port" port-num range po
 rr ::= "round-robin" .
 age ::= "age" decnumber [ "/" decnumber ] .
 clamp ::= "mssclamp" decnumber .
-tcpudp ::= "tcp/udp" | protocol .
+tcpudp ::= "tcp/udp" | "tcp" | "udp" .
 
 protocol ::= protocol-name | decnumber .
-nummask ::= host-name [ "/" decnumber ] .
-portspec ::= "auto" | portnumber ":" portnumber .
-portnumber ::= number { numbers } .
+nummask ::= host-name [ "/" number ] .
+portspec ::= "auto" | number ":" number .
 ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers .
 
+number ::= numbers [ number ] .
 numbers ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
 .fi
 .PP
@@ -134,9 +134,9 @@ If more refined timeouts are required th
 NAT settings, this allows you to set them for \fBnon-TCP\fP use.
 .SH TRANSLATION
 .PP
-To the right of the "->" is the address and port specificaton which will be
+To the right of the "->" is the address and port specification which will be
 written into the packet providing it has already successful matched the
-prior constraints.  The case of redirections (\fBrdr\fP) is the simpliest:
+prior constraints.  The case of redirections (\fBrdr\fP) is the simplest:
 the new destination address is that specified in the rule.  For \fBmap\fP
 rules, the destination address will be one for which the tuple combining
 the new source and destination is known to be unique.  If the packet is
@@ -187,7 +187,7 @@ automatically, as required.  This will n
 using "ipnat -l", only the internal application order.
 .SH EXAMPLES
 .PP
-This section deals with the \fBmap\fP command and it's variations.
+This section deals with the \fBmap\fP command and its variations.
 .PP
 To change IP#'s used internally from network 10 into an ISP provided 8 bit
 subnet at 209.1.2.0 through the ppp0 interface, the following would be used:
@@ -214,7 +214,7 @@ map ppp0 10.0.0.0/8 -> 209.1.2.0/24
 .fi
 .PP
 so that all TCP/UDP packets were port mapped and only other protocols, such as
-ICMP, only have their IP# changed.  In some instaces, it is more appropriate
+ICMP, only have their IP# changed.  In some instances, it is more appropriate
 to use the keyword \fBauto\fP in place of an actual range of port numbers if
 you want to guarantee simultaneous access to all within the given range.
 However, in the above case, it would default to 1 port per IP address, since
@@ -228,7 +228,7 @@ map ppp0 172.192.0.0/16 -> 209.1.2.0/24 
 which would result in each IP address being given a small range of ports to
 use (252).  The problem here is that the \fBmap\fP directive tells the NAT
 code to use the next address/port pair available for an outgoing connection,
-resulting in no easily discernable relation between external addresses/ports
+resulting in no easily discernible relation between external addresses/ports
 and internal ones.  This is overcome by using \fBmap-block\fP as follows:
 .LP
 .nf
Index: contrib/ipfilter/test/Makefile
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/Makefile,v
retrieving revision 1.1
diff -u -p -u -r1.1 Makefile
--- contrib/ipfilter/test/Makefile	17 Jun 2003 02:44:55 -0000	1.1
+++ contrib/ipfilter/test/Makefile	17 Jul 2004 04:55:54 -0000
@@ -51,7 +51,7 @@ i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12:
 n1 n2 n3 n4 n5 n6 n7:
 	@/bin/sh ./nattest $@
 
-ni1 ni2 ni3 ni4 ni5:
+ni1 ni2 ni3 ni4 ni5 ni7 ni8 ni10 ni11:
 	@/bin/sh ./natipftest $@
 
 in1 in2 in3 in4:
Index: contrib/ipfilter/test/expected/in1
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/expected/in1,v
retrieving revision 1.1
diff -u -p -u -r1.1 in1
--- contrib/ipfilter/test/expected/in1	17 Jun 2003 02:44:56 -0000	1.1
+++ contrib/ipfilter/test/expected/in1	17 Jul 2004 04:55:54 -0000
@@ -22,3 +22,4 @@ map ppp0 192.168.0.0/16 -> 0.0.0.0/32 po
 map le0 0.0.0.0/0 -> 0.0.0.0/32 frag age 10/10
 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20
 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 = ftp -> 1.2.3.4/32 proxy port ftp ftp/tcp
Index: contrib/ipfilter/test/expected/ni1
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/expected/ni1,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni1
--- contrib/ipfilter/test/expected/ni1	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/expected/ni1	17 Jul 2004 04:55:54 -0000
@@ -1,3 +1,4 @@
-4500 0028 4706 4000 0111 ced8 0606 0606 0404 0404 afc9 829e 0014 0b2d 0402 0000 3be5 468d 000a cfc3
-4500 0038 809a 0000 ff01 8f31 0303 0303 0202 0202 0b00 a537 0000 0000 4500 0028 4703 4000 0111 ef89 0202 0202 0404 0404 afc9 829e 0014 1d4f
+4500 0028 4706 4000 0111 1eac 0606 0606 0404 0404 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3
+4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0b00 5773 0000 0000 4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 afc9 829e 0014 6b10
+4500 0044 809a 0000 ff01 3115 0303 0303 0202 0202 0b00 0131 0000 0000 4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 afc9 829e 0014 6b10 0402 0000 3be5 468d 000a cfc3
 -------------------------------
Index: contrib/ipfilter/test/expected/ni2
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/expected/ni2,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni2
--- contrib/ipfilter/test/expected/ni2	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/expected/ni2	17 Jul 2004 04:55:54 -0000
@@ -1,10 +1,10 @@
-4510 002c bd0d 4000 3e06 ea1d 0101 0101 c0a8 0133 9c40 0077 a664 2485 0000 0000 6002 4000 2ca8 0000 0204 05b4
-4500 002c ce83 4000 7e06 98b7 c0a8 0133 0a01 0201 0077 05f6 fbdf 1a21 a664 2486 6012 2238 c0a8 0000 0204 05b4
-4510 0028 bd0e 4000 3e06 ea20 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a22 5010 4470 29e3 0000
-4500 005b cf83 4000 7e06 9788 c0a8 0133 0a01 0201 0077 05f6 fbdf 1a22 a664 2486 5018 2238 ce2a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0a
-4510 0028 bd18 4000 3e06 ea16 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5010 4470 29b0 0000
-4510 002e bd1e 4000 3e06 ea0a 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5018 4470 1c98 0000 0000 0000 0d0a
-4500 0048 e383 4000 7e06 839b c0a8 0133 0a01 0201 0077 05f6 fbdf 1a55 a664 248c 5018 2232 d80a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
-4500 05dc e483 4000 7e06 7d07 c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3331 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
-4500 0038 d71d 4000 4001 f0be 0101 0101 c0a8 0133 0304 348b 0000 05a0 4500 05dc e483 4000 7e06 8707 c0a8 0133 0101 0101 0077 9c40 fbdf 1a75
+4510 002c bd0d 4000 3e06 bbd1 0101 0101 c0a8 0133 9c40 0077 a664 2485 0000 0000 6002 4000 2ca8 0000 0204 05b4
+4500 002c ce83 4000 7e06 606b c0a8 0133 0a01 0201 0077 05f6 fbdf 1a21 a664 2486 6012 2238 c0a8 0000 0204 05b4
+4510 0028 bd0e 4000 3e06 bbd4 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a22 5010 4470 29e3 0000
+4500 005b cf83 4000 7e06 5f3c c0a8 0133 0a01 0201 0077 05f6 fbdf 1a22 a664 2486 5018 2238 ce2a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0a
+4510 0028 bd18 4000 3e06 bbca 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5010 4470 29b0 0000
+4510 002e bd1e 4000 3e06 bbbe 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5018 4470 1c98 0000 0000 0000 0d0a
+4500 0048 e383 4000 7e06 4b4f c0a8 0133 0a01 0201 0077 05f6 fbdf 1a55 a664 248c 5018 2232 d80a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
+4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3331 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
+4500 0038 d71d 4000 4001 9fca 0101 0101 c0a8 0133 0304 444f 0000 05a0 4500 05dc e483 4000 7e06 4ebb c0a8 0133 0101 0101 0077 9c40 fbdf 1a75
 -------------------------------
Index: contrib/ipfilter/test/expected/ni3
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/expected/ni3,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni3
--- contrib/ipfilter/test/expected/ni3	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/expected/ni3	17 Jul 2004 04:55:54 -0000
@@ -1,4 +1,4 @@
-4500 003c 4706 4000 ff06 28aa 0606 0606 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
-4500 0038 809a 0000 ff01 3323 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001
-4500 0058 809a 0000 ff01 3303 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
+4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
+4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001
+4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
 -------------------------------
Index: contrib/ipfilter/test/expected/ni4
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/expected/ni4,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni4
--- contrib/ipfilter/test/expected/ni4	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/expected/ni4	17 Jul 2004 04:55:54 -0000
@@ -1,4 +1,4 @@
-4500 003c 4706 4000 ff06 28aa 0606 0606 0404 0404 9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
-4500 0038 809a 0000 ff01 3323 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001
-4500 0058 809a 0000 ff01 3303 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
+4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
+4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001
+4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300
 -------------------------------
Index: contrib/ipfilter/test/expected/ni5
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/expected/ni5,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni5
--- contrib/ipfilter/test/expected/ni5	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/expected/ni5	17 Jul 2004 04:55:54 -0000
@@ -1,28 +1,28 @@
-4500 002c 10c9 4000 ff06 3289 0101 0101 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 f5a2 0000 0204 05b4
+4500 002c 10c9 4000 ff06 f232 0101 0101 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 f5a2 0000 0204 05b4
 4500 002c ffdd 4000 ef06 5374 96cb e002 c0a8 0103 0015 8032 3786 76c4 bd6b c9c9 6012 269c 8369 0000 0204 0584
-4500 0028 10ca 4000 ff06 328c 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 76c5 5010 269c 5aa0 0000
+4500 0028 10ca 4000 ff06 f235 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 76c5 5010 269c 5aa0 0000
 4500 006f ffde 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 76c5 bd6b c9c9 5018 269c 967e 0000 3232 302d 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 7520 4e63 4654 5064 2053 6572 7665 7220 2866 7265 6520 6564 7563 6174 696f 6e61 6c20 6c69 6365 6e73 6529 2072 6561 6479 2e0d 0a
-4500 0028 10cb 4000 ff06 328b 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 770c 5010 269c 5a59 0000
+4500 0028 10cb 4000 ff06 f234 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 770c 5010 269c 5a59 0000
 ippr_ftp_server_valid:junk after cmd[220-Maintained by RSSS and RSPAS IT Staff (previously known as Coombs Comp]
 4500 00c7 ffdf 4000 ef06 52d7 96cb e002 c0a8 0103 0015 8032 3786 770c bd6b c9c9 5018 269c 1087 0000 3232 302d 0d0a 3232 302d 4d61 696e 7461 696e 6564 2062 7920 5253 5353 2061 6e64 2052 5350 4153 2049 5420 5374 6166 6620 2870 7265 7669 6f75 736c 7920 6b6e 6f77 6e20 6173 2043 6f6f 6d62 7320 436f 6d70 7574 696e 6720 556e 6974 290d 0a32 3230 2d41 6e79 2070 726f 626c 656d 7320 636f 6e74 6163 7420 6674 706d 6173 7465 7240 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 750d 0a32 3230 2d0d 0a32 3230 200d 0a
-4500 0028 10cc 4000 ff06 328a 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5010 269c 59ba 0000
-4500 0038 10cd 4000 ff06 3279 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5018 269c d1c5 0000 5553 4552 2061 6e6f 6e79 6d6f 7573 0d0a
+4500 0028 10cc 4000 ff06 f233 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5010 269c 59ba 0000
+4500 0038 10cd 4000 ff06 f222 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5018 269c d1c5 0000 5553 4552 2061 6e6f 6e79 6d6f 7573 0d0a
 4500 0028 ffe0 4000 ef06 5375 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5010 269c 9a00 0000
 4500 006c ffe1 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5018 269c b00f 0000 3333 3120 4775 6573 7420 6c6f 6769 6e20 6f6b 2c20 7365 6e64 2079 6f75 7220 636f 6d70 6c65 7465 2065 2d6d 6169 6c20 6164 6472 6573 7320 6173 2070 6173 7377 6f72 642e 0d0a
-4500 0028 10ce 4000 ff06 3288 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5010 269c 5966 0000
-4500 0036 10cf 4000 ff06 3279 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5018 269c 373f 0000 5041 5353 2061 7661 6c6f 6e40 0d0a
+4500 0028 10ce 4000 ff06 f231 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5010 269c 5966 0000
+4500 0036 10cf 4000 ff06 f222 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5018 269c 373f 0000 5041 5353 2061 7661 6c6f 6e40 0d0a
 4500 005f ffe2 4000 ef06 533c 96cb e002 c0a8 0103 0015 8032 3786 77ef bd6b c9e7 5018 269c 895e 0000 3233 302d 596f 7520 6172 6520 7573 6572 2023 3420 6f66 2035 3020 7369 6d75 6c74 616e 656f 7573 2075 7365 7273 2061 6c6c 6f77 6564 2e0d 0a
-4500 0028 10d0 4000 ff06 3286 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7826 5010 269c 5921 0000
+4500 0028 10d0 4000 ff06 f22f 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7826 5010 269c 5921 0000
 4500 0099 ffe3 4000 ef06 5301 96cb e002 c0a8 0103 0015 8032 3786 7826 bd6b c9e7 5018 269c d399 0000 3233 302d 0d0a 3233 302d 0d0a 3233 302d 4869 2e20 2057 6527 7265 2063 6c65 616e 696e 6720 7570 2e20 2041 6e79 2066 6565 6462 6163 6b20 6d6f 7374 2077 656c 636f 6d65 2e20 3130 2041 7567 2030 300d 0a32 3330 2d0d 0a32 3330 204c 6f67 6765 6420 696e 2061 6e6f 6e79 6d6f 7573 6c79 2e0d 0a
-4500 0028 10d1 4000 ff06 3285 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5010 269c 58b0 0000
-4500 0030 10d2 4000 ff06 327c 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5018 269c 86ae 0000 5459 5045 2049 0d0a
+4500 0028 10d1 4000 ff06 f22e 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5010 269c 58b0 0000
+4500 0030 10d2 4000 ff06 f225 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5018 269c 86ae 0000 5459 5045 2049 0d0a
 4500 0038 ffe4 4000 ef06 5361 96cb e002 c0a8 0103 0015 8032 3786 7897 bd6b c9ef 5018 269c 5fae 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a
-4500 0028 10d3 4000 ff06 3283 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5010 269c 5898 0000
-4500 003d 10d4 4000 ff06 3269 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5018 269c 4b67 0000 504f 5254 2031 2c31 2c31 2c31 2c31 3238 2c35 310d 0a
+4500 0028 10d3 4000 ff06 f22c 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5010 269c 5898 0000
+4500 003d 10d4 4000 ff06 f216 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5018 269c 4b67 0000 504f 5254 2031 2c31 2c31 2c31 2c31 3238 2c35 310d 0a
 4500 0046 ffe5 4000 ef06 5352 96cb e002 c0a8 0103 0015 8032 3786 78a7 bd6b ca0c 5018 269c dbc3 0000 3230 3020 504f 5254 2063 6f6d 6d61 6e64 2073 7563 6365 7373 6675 6c2e 0d0a
-4500 0030 10d5 4000 ff06 3279 0101 0101 96cb e002 8032 0015 bd6b ca04 3786 78c5 5018 269c 866b 0000 5459 5045 2041 0d0a
+4500 0030 10d5 4000 ff06 f222 0101 0101 96cb e002 8032 0015 bd6b ca04 3786 78c5 5018 269c 866b 0000 5459 5045 2041 0d0a
 4500 0038 ffe6 4000 ef06 535f 96cb e002 c0a8 0103 0015 8032 3786 78c5 bd6b ca14 5018 269c 5f5b 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a
-4500 002e 10d6 4000 ff06 327a 0101 0101 96cb e002 8032 0015 bd6b ca0c 3786 78d5 5018 269c a994 0000 4e4c 5354 0d0a
+4500 002e 10d6 4000 ff06 f223 0101 0101 96cb e002 8032 0015 bd6b ca0c 3786 78d5 5018 269c a994 0000 4e4c 5354 0d0a
 4500 002c ffe7 4000 ef06 536a 96cb e002 c0a8 0103 0014 8033 d9f8 11d4 0000 0000 6002 2238 d190 0000 0204 0584
 4500 002c 10d7 4000 ff06 327b c0a8 0103 96cb e002 8033 0014 bd78 5c12 d9f8 11d5 6012 02f8 d734 0000 0204 0584
 4500 0028 ffe8 4000 ef06 536d 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5010 269c cb1d 0000
@@ -34,14 +34,14 @@ ippr_ftp_server_valid:junk after cmd[220
 4500 0028 10da 4000 ff06 327c c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5010 6348 8e35 0000
 4500 0028 10db 4000 ff06 327b c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5011 6348 8e34 0000
 4500 0028 ffec 4000 ef06 5369 96cb e002 c0a8 0103 0014 8033 d9f8 1211 bd78 5c14 5010 269c cae0 0000
-4500 0028 10dc 4000 ff06 327a 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 790a 5010 269c 5812 0000
+4500 0028 10dc 4000 ff06 f223 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 790a 5010 269c 5812 0000
 4500 0040 ffed 4000 ef06 5350 96cb e002 c0a8 0103 0015 8032 3786 790a bd6b ca1a 5018 269c 7c9e 0000 3232 3620 4c69 7374 696e 6720 636f 6d70 6c65 7465 642e 0d0a
-4500 0030 10dd 4000 ff06 3271 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 7922 5018 269c 85f8 0000 5459 5045 2049 0d0a
+4500 0030 10dd 4000 ff06 f21a 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 7922 5018 269c 85f8 0000 5459 5045 2049 0d0a
 4500 0038 ffee 4000 ef06 5357 96cb e002 c0a8 0103 0015 8032 3786 7922 bd6b ca22 5018 269c 5ef0 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a
-4500 0028 10de 4000 ff06 3278 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5010 269c 57e2 0000
-4500 002e 10df 4000 ff06 3271 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5018 269c b020 0000 5155 4954 0d0a
+4500 0028 10de 4000 ff06 f221 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5010 269c 57e2 0000
+4500 002e 10df 4000 ff06 f21a 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5018 269c b020 0000 5155 4954 0d0a
 4500 0036 ffef 4000 ef06 5358 96cb e002 c0a8 0103 0015 8032 3786 7932 bd6b ca28 5018 269c a93c 0000 3232 3120 476f 6f64 6279 652e 0d0a
-4500 0028 10e0 4000 ff06 3276 0101 0101 96cb e002 8032 0015 bd6b ca20 3786 7940 5011 269c 57cd 0000
+4500 0028 10e0 4000 ff06 f21f 0101 0101 96cb e002 8032 0015 bd6b ca20 3786 7940 5011 269c 57cd 0000
 4500 0028 fff0 4000 ef06 5365 96cb e002 c0a8 0103 0015 8032 3786 7940 bd6b ca28 5011 269c 981b 0000
 4500 0028 10e1 4000 ff06 3275 c0a8 0103 96cb e002 8032 0015 bd6b ca25 3786 7941 5010 269c 981e 0000
 4500 0028 fff1 4000 ef06 5364 96cb e002 c0a8 0103 0015 8032 3786 7941 bd6b ca29 5010 269c 981a 0000
Index: contrib/ipfilter/test/input/f13
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/f13,v
retrieving revision 1.1
diff -u -p -u -r1.1 f13
--- contrib/ipfilter/test/input/f13	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/f13	17 Jul 2004 04:55:54 -0000
@@ -1,51 +1,51 @@
 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF,MF,FO=0  SYN
-45 00 0028 0001 4000 3f 06 0000 01010101 02010101
+45 00 0028 0001 4000 3f 06 36cc 01010101 02010101
 0401 0019 00000000 00000000 50 02 2000 0000 0000
 
 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP MF  ACK
-45 00 0024 0002 2000 3f 06 0000 01010101 02010101
+45 00 0024 0002 2000 3f 06 56cf 01010101 02010101
 0401001900000000 0000000050102000
 
 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP FO=2  ACK
-45 00 002c 0002 0002 3f 06 0000 01010101 02010101
+45 00 002c 0002 0002 3f 06 76c5 01010101 02010101
 0000000000010203 0405060708090a0b 0c0d0e0f10111213
 
 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 SYN
-45 00 0028 0003 6000 3f 06 0000 01010101 02010101
+45 00 0028 0003 6000 3f 06 16ca 01010101 02010101
 0401 0019 00000000 00000000 50 10 2000 0000 0000
 
 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0
-45 00 001c 0004 6000 3f 06 0000 01010101 02010101
+45 00 001c 0004 6000 3f 06 16d5 01010101 02010101
 0401 0019 00000000
 
 # 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 SYN
-45 00 001c 0005 6001 3f 06 0000 01010101 02010101
+45 00 001c 0005 6001 3f 06 16d3 01010101 02010101
 00000000 50 10 2000
 
 # 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0
-45 00 0014 0006 6000 3f 11 0000 01010101 02010101
+45 00 0014 0006 6000 3f 11 16d0 01010101 02010101
 
 # 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0
-45 00 0018 0007 2000 3f 11 0000 01010101 02010101
+45 00 0018 0007 2000 3f 11 56cb 01010101 02010101
 0035 0035
 
 # 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0
-45 00 001c 0008 2000 3f 11 0000 01010101 02010101
+45 00 001c 0008 2000 3f 11 56c6 01010101 02010101
 0035003500040000
 
 # 1.1.1.1,53 -> 2.1.1.1,54 TTL=63 UDP MF FO=0 (short)
-45 00 0018 0008 2000 3f 11 0000 01010101 02010101
+45 00 0018 0008 2000 3f 11 56ca 01010101 02010101
 00350036
 
 # 1.1.1.1,21 -> 2.1.1.1,54 TTL=63 UDP MF FO=0
-45 00 001c 0008 2000 3f 11 0000 01010101 02010101
+45 00 001c 0008 2000 3f 11 56c6 01010101 02010101
 0015003600040000
 
 # 1.1.1.1,21 -> 2.1.1.1,54 TTL=63 TCP MF FO=0
-45 00 001c 0008 2000 3f 06 0000 01010101 02010101
+45 00 001c 0008 2000 3f 06 56d1 01010101 02010101
 0015 0036 00000000 00000000 50 02 2000 0000 0000
 
 # 1.1.1.1 -> 2.1.1.1 TTL=63 UDP FO=1
-45 00 001c 0008 0001 3f 11 0000 01010101 02010101
+45 00 001c 0008 0001 3f 11 76c5 01010101 02010101
 0000000000000000
 
Index: contrib/ipfilter/test/input/f17
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/f17,v
retrieving revision 1.1
diff -u -p -u -r1.1 f17
--- contrib/ipfilter/test/input/f17	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/f17	17 Jul 2004 04:55:54 -0000
@@ -1,61 +1,61 @@
 # (1.1.1.1,54076,seq=0xbfd08989) -> (2.2.2.2,25,seq=0) SYN
 [out,ppp0]
-4500 003c 8262 0000 4006 8417 0101 0101
+4500 003c 8262 0000 4006 f254 0101 0101
 0202 0202 d33c 0019 bfd0 8989 0000 0000
-a002 4000 6190 0000 0204 05b4 0103 0300
+a002 4000 cfcd 0000 0204 05b4 0103 0300
 0101 080a 008e 17f7 0000 0000
 
 # (2.2.2.2,25,seq=0x40203436) -> (1.1.1.1,54076,seq=0xbfdfcbc9) ACK
 [in,ppp0]
-4500 003c 8262 0000 1106 b317 0202 0202
+4500 003c 8262 0000 1106 2155 0202 0202
 0101 0101 0019 d33c 4020 3436 bfdf cbc9
-5010 4000 fb0c 0000 0204 0584 0103 0300
+5010 4000 694a 0000 0204 0584 0103 0300
 0101 080a 008e 17f7 0000 0000
 
 # (1.1.1.1,54076,seq=0xbfd08989) -> (2.2.2.2,25,seq=0x0) SYN
 [out,ppp0]
-4500 003c 8265 0000 4006 8414 0101 0101
+4500 003c 8265 0000 4006 f251 0101 0101
 0202 0202 d33c 0019 bfd0 8989 0000 0000
-a002 4000 6185 0000 0204 05b4 0103 0300
+a002 4000 cfc2 0000 0204 05b4 0103 0300
 0101 080a 008e 1802 0000 0000
 
 # (2.2.2.2,25,seq=0xed674d4e) -> (1.1.1.1,54076,seq=0xbfd0898a) SYN-ACK
 [in,ppp0]
-4500 002c 7442 4000 2906 6947 0202 0202
+4500 002c 7442 4000 2906 d784 0202 0202
 0101 0101 0019 d33c ed67 4d4e bfd0 898a
-6012 2118 ab84 0000 0204 0584
+6012 2118 19c2 0000 0204 0584
 
 #
 # (2.2.2.2,25,seq=0xbfd0898a) -> (1.1.1.1,54076,seq=0xed674d4e) ACK
 [out,ppp0]
-4500 002c 8262 0000 4006 8417 0101 0101
+4500 002c 8262 0000 4006 f264 0101 0101
 0202 0202 d33c 0019 bfd0 898a ed67 4d4e
 5010 4000 6190 0000 0000
 
 # (1.1.1.1,54076,seq=0xcfd08989) -> (2.2.2.2,25,seq=0x0) SYN
 [out,ppp0]
-4500 003c 8265 0000 4006 8414 0101 0101
+4500 003c 8265 0000 4006 f251 0101 0101
 0202 0202 d33c 0019 cfd0 8989 0000 0000
-a002 4000 6185 0000 0204 05b4 0103 0300
+a002 4000 bfc2 0000 0204 05b4 0103 0300
 0101 080a 008e 1802 0000 0000
 
 # (1.1.1.1,54076,seq=0xcfd08989) -> (2.2.2.2,25,seq=0x0) SYN
 [out,ppp0]
-4500 003c 8266 0000 4006 8413 0101 0101
+4500 003c 8266 0000 4006 f250 0101 0101
 0202 0202 d33c 0019 cfd0 8989 0000 0000
-a002 4000 6185 0000 0204 05b4 0103 0300
+a002 4000 bfc2 0000 0204 05b4 0103 0300
 0101 080a 008e 1802 0000 0000
 
 # (2.2.2.2,25,seq=0xed674d4e) -> (1.1.1.1,54076,seq=0xcfd0898a) SYN-ACK
 [in,ppp0]
-4500 002c 7442 4000 2906 6947 0202 0202
+4500 002c 7442 4000 2906 d784 0202 0202
 0101 0101 0019 d33c ed67 4d4e cfd0 898a
-6012 2118 ab84 0000 0204 0584
+6012 2118 09c2 0000 0204 0584
 
 #
 # (2.2.2.2,25,seq=0xcfd0898a) -> (1.1.1.1,54076,seq=0xed674d4e) ACK
 [out,ppp0]
-4500 002c 8262 0000 4006 8417 0101 0101
+4500 002c 8262 0000 4006 f264 0101 0101
 0202 0202 d33c 0019 cfd0 898a ed67 4d4e
 5010 4000 6190 0000 0000
 
Index: contrib/ipfilter/test/input/ni1
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/ni1,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni1
--- contrib/ipfilter/test/input/ni1	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/ni1	17 Jul 2004 04:55:54 -0000
@@ -1,6 +1,19 @@
 #v tos len id   off  ttl p sum  src       dst
 # ICMP timeout exceeded in reply to a ICMP packet going out.
-[out,df0] 45 00 0028 4706 4000 01 11 ced8 0202 0202 0404 0404 afc9 829e 0014 1335 0402 0000 3be5 468d 000a cfc3
+[out,df0]
+4500 0028 4706 4000 0111 26b4 0202 0202
+0404 0404 afc9 829e 0014 6b10 0402 0000
+3be5 468d 000a cfc3
 
-[in,df0] 45 00 0038 809a 0000 ff 01 8f31 0303 0303 0101 0101 0b00 ad3f 0000 0000 4500 0028 4703 4000 0111 e781 0606 0606 0404 0404 afc9 829e 0014 1547
+[in,df0]
+4500 0038 809a 0000 ff01 2919 0303 0303
+0606 0606 0b00 5f7b 0000 0000
+4500 0028 4706 4000 0111 1eac 0606 0606 0404 0404
+afc9 829e 0014 6308
+
+[in,df0]
+4500 0044 809a 0000 ff01 290d 0303 0303
+0606 0606 0b00 0939 0000 0000
+4500 0028 4706 4000 0111 1eac 0606 0606 0404 0404
+afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3
 
Index: contrib/ipfilter/test/input/ni2
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/ni2,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni2
--- contrib/ipfilter/test/input/ni2	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/ni2	17 Jul 2004 04:55:54 -0000
@@ -1,27 +1,27 @@
 # Test of fragmentation required coming from the inside.
 [out,xl0]
-4510 002c bd0d 4000 3e06 ea1d
+4510 002c bd0d 4000 3e06 b1d1
 0a01 0201
 c0a8 0133
 05f6 0077 a664 2485 0000 0000
 6002 4000 b8f2 0000 0204 05b4
 
 [in,xl0]
-4500 002c ce83 4000 7e06 98b7
+4500 002c ce83 4000 7e06 606b
 c0a8 0133
 0a01 0201
 0077 05f6 fbdf 1a21 a664 2486
 6012 2238 c0a8 0000 0204 05b4 0000
 
 [out,xl0]
-4510 0028 bd0e 4000 3e06 ea20
+4510 0028 bd0e 4000 3e06 b1d4
 0a01 0201
 c0a8 0133
 05f6 0077 a664 2486 fbdf 1a22
 5010 4470 b62d 0000
 
 [in,xl0]
-4500 005b cf83 4000 7e06 9788
+4500 005b cf83 4000 7e06 5f3c
 c0a8 0133
 0a01 0201
 0077 05f6 fbdf 1a22 a664 2486
@@ -31,21 +31,21 @@ c0a8 0133
 0000 0000 0000 0000 0000 0a
 
 [out,xl0]
-4510 0028 bd18 4000 3e06 ea16
+4510 0028 bd18 4000 3e06 b1ca
 0a01 0201
 c0a8 0133
 05f6 0077 a664 2486 fbdf 1a55
 5010 4470 b5fa 0000
 
 [out,xl0]
-4510 002e bd1e 4000 3e06 ea0a
+4510 002e bd1e 4000 3e06 b1be
 0a01 0201
 c0a8 0133
 05f6 0077 a664 2486 fbdf 1a55
 5018 4470 a8e2 0000 0000 0000 0d0a
 
 [in,xl0]
-4500 0048 e383 4000 7e06 839b
+4500 0048 e383 4000 7e06 4b4f
 c0a8 0133
 0a01 0201
 0077 05f6 fbdf 1a55 a664 248c
@@ -54,7 +54,7 @@ c0a8 0133
 0000 0000 0000 0000
 
 [in,xl0]
-4500 05dc e483 4000 7e06 7d07
+4500 05dc e483 4000 7e06 44bb
 c0a8 0133
 0a01 0201
 0077 05f6 fbdf 1a75 a664 248c
@@ -152,10 +152,10 @@ c0a8 0133
 0000 0000 0000 0000 0000 0000
 
 [out,xl0]
-4500 0038 d71d 4000 4001 ce16
+4500 0038 d71d 4000 4001 7d22
 c0a8 6401
 c0a8 0133
-0304 cad5 0000 05a0 4500 05dc
-e483 4000 7e06 7d07 c0a8 0133 0a01 0201
+0304 da99 0000 05a0 4500 05dc
+e483 4000 7e06 44bb c0a8 0133 0a01 0201
 0077 05f6 fbdf 1a75
 
Index: contrib/ipfilter/test/input/ni3
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/ni3,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni3
--- contrib/ipfilter/test/input/ni3	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/ni3	17 Jul 2004 04:55:54 -0000
@@ -3,8 +3,8 @@
 # going out)
 [out,df0] 45 00 00 3c 47 06 40 00 ff 06 28 aa 02 02 02 02 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d8 e2 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 
 
-[in,df0] 45 00 00 38 80 9a 00 00 ff 01 33 23 03 03 03 03 01 01 01 01 03 03 ac ab 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 50 00 00 50 00 00 00 01
+[in,df0] 45 00 00 38 80 9a 00 00 ff 01 29 19 03 03 03 03 06 06 06 06 03 03 ac ac 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 50 00 00 50 00 00 00 01
 
 # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits)
-[in,df0] 45 00 00 58 80 9a 00 00 ff 01 33 03 03 03 03 03 01 01 01 01 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d0 da 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00
+[in,df0] 45 00 00 58 80 9a 00 00 ff 01 28 f9 03 03 03 03 06 06 06 06 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d0 da 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00
 
Index: contrib/ipfilter/test/input/ni4
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/ni4,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni4
--- contrib/ipfilter/test/input/ni4	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/ni4	17 Jul 2004 04:55:54 -0000
@@ -3,8 +3,8 @@
 # going out)
 [out,df0] 45 00 00 3c 47 06 40 00 ff 06 28 aa 02 02 02 02 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d8 e2 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 
 
-[in,df0] 45 00 00 38 80 9a 00 00 ff 01 33 23 03 03 03 03 01 01 01 01 03 03 60 6b 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 9c 40 00 50 00 00 00 01
+[in,df0] 45 00 00 38 80 9a 00 00 ff 01 29 19 03 03 03 03 06 06 06 06 03 03 60 6c 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 9c 40 00 50 00 00 00 01
 
 # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits)
-[in,df0] 45 00 00 58 80 9a 00 00 ff 01 33 03 03 03 03 03 01 01 01 01 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 9c 40 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 84 9a 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00
+[in,df0] 45 00 00 58 80 9a 00 00 ff 01 28 f9 03 03 03 03 06 06 06 06 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 9c 40 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 84 9a 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00
 
Index: contrib/ipfilter/test/input/ni5
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/input/ni5,v
retrieving revision 1.1
diff -u -p -u -r1.1 ni5
--- contrib/ipfilter/test/input/ni5	17 Jun 2003 02:44:57 -0000	1.1
+++ contrib/ipfilter/test/input/ni5	17 Jul 2004 04:55:54 -0000
@@ -4,7 +4,7 @@
 6002 2238 35f9 0000 0204 05b4
 
 [in,ppp0]
-4500 002c ffdd 4000 ef06 5374 96cb e002
+4500 002c ffdd 4000 ef06 131e 96cb e002
 0101 0101 0015 8032 3786 76c4 bd6b c9c9
 6012 269c 4313 0000 0204 0584
 
@@ -14,7 +14,7 @@
 5010 269c 9af6 0000
 
 [in,ppp0]
-4500 006f ffde 4000 ef06 5330 96cb e002
+4500 006f ffde 4000 ef06 12da 96cb e002
 0101 0101 0015 8032 3786 76c5 bd6b c9c9
 5018 269c 5628 0000 3232 302d 636f 6f6d
 6273 2e61 6e75 2e65 6475 2e61 7520 4e63
@@ -28,7 +28,7 @@
 5010 269c 9aaf 0000
 
 [in,ppp0]
-4500 00c7 ffdf 4000 ef06 52d7 96cb e002
+4500 00c7 ffdf 4000 ef06 1281 96cb e002
 0101 0101 0015 8032 3786 770c bd6b c9c9
 5018 269c d030 0000 3232 302d 0d0a 3232
 302d 4d61 696e 7461 696e 6564 2062 7920
@@ -54,12 +54,12 @@
 6e79 6d6f 7573 0d0a
 
 [in,ppp0]
-4500 0028 ffe0 4000 ef06 5375 96cb e002
+4500 0028 ffe0 4000 ef06 131f 96cb e002
 0101 0101 0015 8032 3786 77ab bd6b c9d9
 5010 269c 59aa 0000
 
 [in,ppp0]
-4500 006c ffe1 4000 ef06 5330 96cb e002
+4500 006c ffe1 4000 ef06 12da 96cb e002
 0101 0101 0015 8032 3786 77ab bd6b c9d9
 5018 269c 6fb9 0000 3333 3120 4775 6573
 7420 6c6f 6769 6e20 6f6b 2c20 7365 6e64
@@ -79,7 +79,7 @@
 6c6f 6e40 0d0a
 
 [in,ppp0]
-4500 005f ffe2 4000 ef06 533c 96cb e002
+4500 005f ffe2 4000 ef06 12e6 96cb e002
 0101 0101 0015 8032 3786 77ef bd6b c9e7
 5018 269c 4908 0000 3233 302d 596f 7520
 6172 6520 7573 6572 2023 3420 6f66 2035
@@ -92,7 +92,7 @@
 5010 269c 9977 0000
 
 [in,ppp0]
-4500 0099 ffe3 4000 ef06 5301 96cb e002
+4500 0099 ffe3 4000 ef06 12ab 96cb e002
 0101 0101 0015 8032 3786 7826 bd6b c9e7
 5018 269c 9343 0000 3233 302d 0d0a 3233
 302d 0d0a 3233 302d 4869 2e20 2057 6527
@@ -114,7 +114,7 @@
 5018 269c c704 0000 5459 5045 2049 0d0a
 
 [in,ppp0]
-4500 0038 ffe4 4000 ef06 5361 96cb e002
+4500 0038 ffe4 4000 ef06 130b 96cb e002
 0101 0101 0015 8032 3786 7897 bd6b c9ef
 5018 269c 1f58 0000 3230 3020 5479 7065
 206f 6b61 792e 0d0a
@@ -132,7 +132,7 @@
 0a
 
 [in,ppp0]
-4500 0046 ffe5 4000 ef06 5352 96cb e002
+4500 0046 ffe5 4000 ef06 12fc 96cb e002
 0101 0101 0015 8032 3786 78a7 bd6b ca08
 5018 269c 9b71 0000 3230 3020 504f 5254
 2063 6f6d 6d61 6e64 2073 7563 6365 7373
@@ -144,7 +144,7 @@
 5018 269c c6bd 0000 5459 5045 2041 0d0a
 
 [in,ppp0]
-4500 0038 ffe6 4000 ef06 535f 96cb e002
+4500 0038 ffe6 4000 ef06 1309 96cb e002
 0101 0101 0015 8032 3786 78c5 bd6b ca10
 5018 269c 1f09 0000 3230 3020 5479 7065
 206f 6b61 792e 0d0a
@@ -155,7 +155,7 @@
 5018 269c e9e6 0000 4e4c 5354 0d0a
 
 [in,ppp0]
-4500 002c ffe7 4000 ef06 536a 96cb e002
+4500 002c ffe7 4000 ef06 1314 96cb e002
 0101 0101 0014 8033 d9f8 11d4 0000 0000
 6002 2238 913a 0000 0204 0584
 
@@ -165,12 +165,12 @@
 6012 02f8 d734 0000 0204 0584
 
 [in,ppp0]
-4500 0028 ffe8 4000 ef06 536d 96cb e002
+4500 0028 ffe8 4000 ef06 1317 96cb e002
 0101 0101 0014 8033 d9f8 11d5 bd78 5c13
 5010 269c 8ac7 0000
 
 [in,ppp0]
-4500 005d ffe9 4000 ef06 5337 96cb e002
+4500 005d ffe9 4000 ef06 12e1 96cb e002
 0101 0101 0015 8032 3786 78d5 bd6b ca16
 5018 269c ae7e 0000 3135 3020 4f70 656e
 696e 6720 4153 4349 4920 6d6f 6465 2064
@@ -183,7 +183,7 @@
 5010 6348 8e71 0000
 
 [in,ppp0]
-4500 0063 ffea 4000 ef06 5330 96cb e002
+4500 0063 ffea 4000 ef06 12da 96cb e002
 0101 0101 0014 8033 d9f8 11d5 bd78 5c13
 5018 269c 62bf 0000 636f 6f6d 6273 7061
 7065 7273 0d0a 6465 7074 730d 0a66 6f75
@@ -197,7 +197,7 @@
 5010 6348 8e36 0000
 
 [in,ppp0]
-4500 0028 ffeb 4000 ef06 536a 96cb e002
+4500 0028 ffeb 4000 ef06 1314 96cb e002
 0101 0101 0014 8033 d9f8 1210 bd78 5c13
 5011 269c 8a8b 0000
 
@@ -212,7 +212,7 @@
 5011 6348 8e34 0000
 
 [in,ppp0]
-4500 0028 ffec 4000 ef06 5369 96cb e002
+4500 0028 ffec 4000 ef06 1313 96cb e002
 0101 0101 0014 8033 d9f8 1211 bd78 5c14
 5010 269c 8a8a 0000
 
@@ -222,7 +222,7 @@
 5010 269c 9864 0000
 
 [in,ppp0]
-4500 0040 ffed 4000 ef06 5350 96cb e002
+4500 0040 ffed 4000 ef06 12fa 96cb e002
 0101 0101 0015 8032 3786 790a bd6b ca16
 5018 269c 3c4c 0000 3232 3620 4c69 7374
 696e 6720 636f 6d70 6c65 7465 642e 0d0a
@@ -233,7 +233,7 @@
 5018 269c c64a 0000 5459 5045 2049 0d0a
 
 [in,ppp0]
-4500 0038 ffee 4000 ef06 5357 96cb e002
+4500 0038 ffee 4000 ef06 1301 96cb e002
 0101 0101 0015 8032 3786 7922 bd6b ca1e
 5018 269c 1e9e 0000 3230 3020 5479 7065
 206f 6b61 792e 0d0a
@@ -249,7 +249,7 @@
 5018 269c f072 0000 5155 4954 0d0a
 
 [in,ppp0]
-4500 0036 ffef 4000 ef06 5358 96cb e002
+4500 0036 ffef 4000 ef06 1302 96cb e002
 0101 0101 0015 8032 3786 7932 bd6b ca24
 5018 269c 68ea 0000 3232 3120 476f 6f64
 6279 652e 0d0a
@@ -260,7 +260,7 @@
 5011 269c 981f 0000
 
 [in,ppp0]
-4500 0028 fff0 4000 ef06 5365 96cb e002
+4500 0028 fff0 4000 ef06 130f 96cb e002
 0101 0101 0015 8032 3786 7940 bd6b ca24
 5011 269c 57c9 0000
 
@@ -270,7 +270,7 @@
 5010 269c 981e 0000
 
 [in,ppp0]
-4500 0028 fff1 4000 ef06 5364 96cb e002
+4500 0028 fff1 4000 ef06 130e 96cb e002
 0101 0101 0015 8032 3786 7941 bd6b ca25
 5010 269c 57c8 0000
 
Index: contrib/ipfilter/test/regress/in1
===================================================================
RCS file: /cvs/DragonFly/src/contrib/ipfilter/test/regress/in1,v
retrieving revision 1.1
diff -u -p -u -r1.1 in1
--- contrib/ipfilter/test/regress/in1	17 Jun 2003 02:44:58 -0000	1.1
+++ contrib/ipfilter/test/regress/in1	17 Jul 2004 04:55:54 -0000
@@ -22,3 +22,4 @@ map ppp0 192.168.0.0/16 -> 0/32 portmap 
 map le0 0/0 -> 0/32 frag age 10
 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20
 map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag age 30
+map fxp0 from 192.168.0.0/18 to 0/0 port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp
Index: sys/contrib/ipfilter/netinet/fil.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/fil.c,v
retrieving revision 1.8
diff -u -p -u -r1.8 fil.c
--- sys/contrib/ipfilter/netinet/fil.c	2 Jun 2004 14:42:48 -0000	1.8
+++ sys/contrib/ipfilter/netinet/fil.c	17 Jul 2004 05:59:34 -0000
@@ -4,7 +4,7 @@
  * See the IPFILTER.LICENCE file for details on licencing.
  *
  * @(#)fil.c        1.36 6/5/96 (C) 1993-2000 Darren Reed
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/fil.c,v 1.23.2.6 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/fil.c,v 1.23.2.7 2004/07/04 09:24:38 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/fil.c,v 1.8 2004/06/02 14:42:48 eirikn Exp $
  */
 #if defined(__sgi) && (IRIX > 602)
@@ -46,6 +46,7 @@
 #  include <sys/mbuf.h>
 # endif
 #else
+# include <sys/cmn_err.h>
 # include <sys/byteorder.h>
 # if SOLARIS2 < 5
 #  include <sys/dditypes.h>
@@ -149,6 +150,9 @@ static	int	frflushlist (int, minor_t, in
 static	void	frsynclist (frentry_t *);
 #endif
 
+# ifndef __sgi
+static  void    *ipf_pullup (mb_t *, fr_info_t *, int, void *);
+# endif
 
 /*
  * bit values for identifying presence of individual IP options
@@ -195,19 +199,27 @@ struct	optlist	secopt[8] = {
  * compact the IP header into a structure which contains just the info.
  * which is useful for comparing IP headers with.
  */
-void	fr_makefrip(hlen, ip, fin)
+int	fr_makefrip(hlen, ip, fin)
 int hlen;
 ip_t *ip;
 fr_info_t *fin;
 {
 	u_short optmsk = 0, secmsk = 0, auth = 0;
 	int i, mv, ol, off, p, plen, v;
+#if defined(_KERNEL)
+# if SOLARIS
+	mb_t *m = fin->fin_qfm;
+# else
+	mb_t *m = fin->fin_mp ? *fin->fin_mp : NULL;
+# endif
+#endif
 	fr_ip_t *fi = &fin->fin_fi;
 	struct optlist *op;
 	u_char *s, opt;
 	tcphdr_t *tcp;
 
 	fin->fin_rev = 0;
+	fin->fin_dp = NULL;
 	fin->fin_fr = NULL;
 	fin->fin_tcpf = 0;
 	fin->fin_data[0] = 0;
@@ -221,8 +233,10 @@ fr_info_t *fin;
 	if (v == 4) {
 		fin->fin_id = ip->ip_id;
 		fi->fi_tos = ip->ip_tos;
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+		ip->ip_off = ntohs(ip->ip_off);
+#endif
 		off = (ip->ip_off & IP_OFFMASK);
-		tcp = (tcphdr_t *)((char *)ip + hlen);
 		(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
 		fi->fi_src.i6[1] = 0;
 		fi->fi_src.i6[2] = 0;
@@ -236,6 +250,9 @@ fr_info_t *fin;
 		fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
 		if (ip->ip_off & (IP_MF|IP_OFFMASK))
 			fi->fi_fl |= FI_FRAG;
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+		ip->ip_len = ntohs(ip->ip_len);
+#endif
 		plen = ip->ip_len;
 		fin->fin_dlen = plen - hlen;
 	}
@@ -247,7 +264,6 @@ fr_info_t *fin;
 		p = ip6->ip6_nxt;
 		fi->fi_p = p;
 		fi->fi_ttl = ip6->ip6_hlim;
-		tcp = (tcphdr_t *)(ip6 + 1);
 		fi->fi_src.in6 = ip6->ip6_src;
 		fi->fi_dst.in6 = ip6->ip6_dst;
 		fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
@@ -259,14 +275,23 @@ fr_info_t *fin;
 	}
 #endif
 	else
-		return;
+		return -1;
 
 	fin->fin_off = off;
 	fin->fin_plen = plen;
-	fin->fin_dp = (char *)tcp;
+	tcp = (tcphdr_t *)((char *)ip + hlen);
 	fin->fin_misc = 0;
 	off <<= 3;
 
+	/*
+	 * For both ICMPV6 & ICMP, we attempt to pullup the entire packet into
+	 * a single buffer for recognised error return packets.  Why?  Because 
+	 * the entire data section of the ICMP payload is considered to be of
+	 * significance and maybe required in NAT/state processing, so rather
+	 * than be careful later, attempt to get it all in one buffeer first.
+	 * For TCP we just make sure the _entire_ TCP header is in the first
+	 * buffer for convienience.
+	 */
 	switch (p)
 	{
 #ifdef USE_INET6
@@ -275,7 +300,7 @@ fr_info_t *fin;
 		int minicmpsz = sizeof(struct icmp6_hdr);
 		struct icmp6_hdr *icmp6;
 
-		if (fin->fin_dlen > 1) {
+		if (!(fin->fin_fl & FI_SHORT) && (fin->fin_dlen > 1)) {
 			fin->fin_data[0] = *(u_short *)tcp;
 
 			icmp6 = (struct icmp6_hdr *)tcp;
@@ -290,6 +315,14 @@ fr_info_t *fin;
 			case ICMP6_PACKET_TOO_BIG :
 			case ICMP6_TIME_EXCEEDED :
 			case ICMP6_PARAM_PROB :
+# if defined(KERNEL) && !defined(__sgi)
+				if ((m != NULL) && (M_BLEN(m) < plen)) {
+					ip = ipf_pullup(m, fin, plen, ip);
+					if (ip == NULL)
+						return -1;
+					tcp = (tcphdr_t *)((char *)ip + hlen);
+				}
+# endif /* KERNEL && !__sgi */
 				minicmpsz = ICMP6ERR_IPICMPHLEN;
 				break;
 			default :
@@ -297,22 +330,27 @@ fr_info_t *fin;
 			}
 		}
 
-		if (!(plen >= minicmpsz))
+		if (!(fin->fin_dlen >= minicmpsz))
 			fi->fi_fl |= FI_SHORT;
 
 		break;
 	}
-#endif
+#endif /* USE_INET6 */
+
 	case IPPROTO_ICMP :
 	{
 		int minicmpsz = sizeof(struct icmp);
 		icmphdr_t *icmp;
 
-		if (!off && (fin->fin_dlen > 1)) {
+		if (!off && (fin->fin_dlen > 1) && !(fin->fin_fl & FI_SHORT)) {
 			fin->fin_data[0] = *(u_short *)tcp;
 
 			icmp = (icmphdr_t *)tcp;
 
+			/*
+			 * Minimum ICMP packet is type(1) code(1) cksum(2)
+			 * plus 4 bytes following, totalling 8 bytes.
+			 */
 			switch (icmp->icmp_type)
 			{
 			case ICMP_ECHOREPLY :
@@ -328,7 +366,7 @@ fr_info_t *fin;
 			 */
 			case ICMP_TSTAMP :
 			case ICMP_TSTAMPREPLY :
-				minicmpsz = 20;
+				minicmpsz = ICMP_MINLEN + 12;
 				break;
 			/*
 			 * type(1) + code(1) + cksum(2) + id(2) seq(2) +
@@ -336,9 +374,28 @@ fr_info_t *fin;
 			 */
 			case ICMP_MASKREQ :
 			case ICMP_MASKREPLY :
-				minicmpsz = 12;
+				minicmpsz = ICMP_MINLEN + 4;
+				break;
+			/*
+			 * type(1) + code(1) + cksum(2) + arg(4) ip(20+)
+			 */
+			case ICMP_UNREACH :
+			case ICMP_SOURCEQUENCH :
+			case ICMP_REDIRECT :
+			case ICMP_TIMXCEED :
+			case ICMP_PARAMPROB :
+#if defined(KERNEL) && !defined(__sgi)
+				if ((m != NULL) && (M_BLEN(m) < plen)) {
+					ip = ipf_pullup(m, fin, plen, ip);
+					if (ip == NULL)
+						return -1;
+					tcp = (tcphdr_t *)((char *)ip + hlen);
+				}
+#endif /* KERNEL && !__sgi */
+				minicmpsz = ICMPERR_MINPKTLEN - sizeof(ip_t);
 				break;
 			default :
+				minicmpsz = ICMP_MINLEN;
 				break;
 			}
 		}
@@ -346,9 +403,9 @@ fr_info_t *fin;
 		if ((!(plen >= hlen + minicmpsz) && !off) ||
 		    (off && off < sizeof(struct icmp)))
 			fi->fi_fl |= FI_SHORT;
-
 		break;
 	}
+
 	case IPPROTO_TCP :
 		fi->fi_fl |= FI_TCPUDP;
 #ifdef	USE_INET6
@@ -362,6 +419,20 @@ fr_info_t *fin;
 			     (off && off < sizeof(struct tcphdr)))
 				fi->fi_fl |= FI_SHORT;
 		}
+
+#if defined(KERNEL) && !defined(__sgi)
+		if (!off && !(fi->fi_fl & FI_SHORT)) {
+			int tlen = hlen + (tcp->th_off << 2);
+
+			if ((m != NULL) && (M_BLEN(m) < tlen)) {
+				ip = ipf_pullup(m, fin, tlen, ip);
+				if (ip == NULL)
+					return -1;
+				tcp = (tcphdr_t *)((char *)ip + hlen);
+			}
+		}
+#endif /* _KERNEL && !_sgi */
+
 		if (!(fi->fi_fl & FI_SHORT) && !off)
 			fin->fin_tcpf = tcp->th_flags;
 		goto getports;
@@ -401,12 +472,14 @@ getports:
 		break;
 	}
 
+	fin->fin_dp = (char *)tcp;
+
 #ifdef	USE_INET6
 	if (v == 6) {
 		fi->fi_optmsk = 0;
 		fi->fi_secmsk = 0;
 		fi->fi_auth = 0;
-		return;
+		return 0;
 	}
 #endif
 
@@ -463,6 +536,7 @@ getports:
 	fi->fi_optmsk = optmsk;
 	fi->fi_secmsk = secmsk;
 	fi->fi_auth = auth;
+	return 0;
 }
 
 
@@ -750,7 +824,7 @@ void *m;
 #endif /* IPFILTER_LOG */
 		ATOMIC_INCL(fr->fr_hits);
 		if (passt & FR_ACCOUNT)
-			fr->fr_bytes += (U_QUAD_T)ip->ip_len;
+			fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
 		else
 			fin->fin_icode = fr->fr_icode;
 		fin->fin_rule = rulen;
@@ -813,12 +887,17 @@ int out;
 	int p, len, drop = 0, logit = 0;
 	mb_t *mc = NULL;
 # if !defined(__SVR4) && !defined(__svr4__)
+   /*
+    * We don't do this section for Solaris because fr_precheck() does a
+    * pullupmsg() instead, effectively achieving the same result as here
+    * so no need to duplicate it.
+    */
 #  ifdef __sgi
 	char hbuf[128];
 #  endif
 	int up;
 
-#  if !SOLARIS && !defined(NETBSD_PF) && \
+#  if !defined(NETBSD_PF) && \
       (defined(__DragonFly__) || (defined(__FreeBSD__) && (__FreeBSD_version < 500011)) || \
        defined(__OpenBSD__) || defined(_BSDI_VERSION))
 	if (fr_checkp != fr_check && fr_running > 0) {
@@ -856,7 +935,7 @@ int out;
 	}
 #  endif /* CSUM_DELAY_DATA */
 
-# ifdef	USE_INET6
+#  ifdef	USE_INET6
 	if (v == 6) {
 		len = ntohs(((ip6_t*)ip)->ip6_plen);
 		if (!len)
@@ -864,17 +943,20 @@ int out;
 		len += sizeof(ip6_t);
 		p = ((ip6_t *)ip)->ip6_nxt;
 	} else
-# endif
+#  endif
 	{
 		p = ip->ip_p;
 		len = ip->ip_len;
 	}
 
+	fin->fin_mp = mp;
+	fin->fin_out = out;
+
 	if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
 	    (v == 4 && p == IPPROTO_ICMP)
-# ifdef USE_INET6
+#  ifdef USE_INET6
 	    || (v == 6 && p == IPPROTO_ICMPV6)
-# endif
+#  endif
 	   )) {
 		int plen = 0;
 
@@ -894,7 +976,7 @@ int out;
 			case IPPROTO_ESP:
 				plen = 8;
 				break;
-# ifdef USE_INET6
+#  ifdef USE_INET6
 	    		case IPPROTO_ICMPV6 :
 				/*
 				 * XXX does not take intermediate header
@@ -902,8 +984,10 @@ int out;
 				 */
 				plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
 				break;
-# endif
+#  endif
 			}
+		if ((plen > 0) && (len < hlen + plen))
+			fin->fin_fl |= FI_SHORT;
 		up = MIN(hlen + plen, len);
 
 		if (up > m->m_len) {
@@ -918,14 +1002,34 @@ int out;
 			ip = (ip_t *)hbuf;
 #  else /* __ sgi */
 #   ifndef linux
-			if ((*mp = m_pullup(m, up)) == 0) {
-				ATOMIC_INCL(frstats[out].fr_pull[1]);
+			/*
+			 * Having determined that we need to pullup some data,
+			 * try to bring as much of the packet up into a single
+			 * buffer with the first pullup.  This hopefully means
+			 * less need for doing futher pullups.  Not needed for
+			 * Solaris because fr_precheck() does it anyway.
+			 *
+			 * The main potential for trouble here is if MLEN/MHLEN
+			 * become quite small, lets say < 64 bytes...but if
+			 * that did happen, BSD networking as a whole would be
+			 * slow/inefficient.
+			 */
+#    ifdef MHLEN
+			/*
+			 * Assume that M_PKTHDR is set and just work with what
+			 * is left rather than check..  Should not make any
+			 * real difference, anyway.
+			 */
+			if ((MHLEN > up) && (len > up))
+				up = MIN(len, MHLEN);
+#    else
+			if ((MLEN > up) && (len > up))
+				up = MIN(len, MLEN);
+#    endif
+			ip = ipf_pullup(m, fin, up, ip);
+			if (ip == NULL)
 				return -1;
-			} else {
-				ATOMIC_INCL(frstats[out].fr_pull[0]);
-				m = *mp;
-				ip = mtod(m, ip_t *);
-			}
+			m = *mp;
 #   endif /* !linux */
 #  endif /* __sgi */
 		} else
@@ -938,17 +1042,21 @@ int out;
 
 	if ((u_int)ip & 0x3)
 		return 2;
+	fin->fin_mp = mp;
+	fin->fin_out = out;
 	fin->fin_qfm = m;
 	fin->fin_qif = qif;
 # endif
+#else
+	fin->fin_mp = mp;
+	fin->fin_out = out;
 #endif /* _KERNEL */
 	
 	changed = 0;
-	fin->fin_ifp = ifp;
 	fin->fin_v = v;
-	fin->fin_out = out;
-	fin->fin_mp = mp;
-	fr_makefrip(hlen, ip, fin);
+	fin->fin_ifp = ifp;
+	if (fr_makefrip(hlen, ip, fin) == -1)
+		return -1;
 
 #ifdef _KERNEL
 # ifdef	USE_INET6
@@ -1112,6 +1220,10 @@ int out;
 		if (pass & FR_KEEPSTATE) {
 			if (fr_addstate(ip, fin, NULL, 0) == NULL) {
 				ATOMIC_INCL(frstats[out].fr_bads);
+				if (pass & FR_PASS) {
+					pass &= ~FR_PASS;
+					pass |= FR_BLOCK;
+				}
 			} else {
 				ATOMIC_INCL(frstats[out].fr_ads);
 			}
@@ -1293,6 +1405,12 @@ logit:
 			(void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
 	}
 # endif /* !SOLARIS */
+#if (OpenBSD >= 200311) && defined(_KERNEL)
+	if (pass & FR_PASS) {
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
+	}
+#endif
 	return (pass & FR_PASS) ? 0 : error;
 #else /* _KERNEL */
 	if (pass & FR_NOMATCH)
@@ -1390,10 +1508,10 @@ tcphdr_t *tcp;
 	/*
 	 * Both sum and sum2 are partial sums, so combine them together.
 	 */
-	sum = (sum & 0xffff) + (sum >> 16);
-	sum = ~sum & 0xffff;
-	sum2 += sum;
-	sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+	sum += ~sum2 & 0xffff;
+	while (sum > 0xffff)
+		sum = (sum & 0xffff) + (sum >> 16);
+	sum2 = ~sum & 0xffff;
 #  else /* defined(BSD) || defined(sun) */
 {
 	union {
@@ -1534,7 +1652,7 @@ nodata:
  * SUCH DAMAGE.
  *
  *	@(#)uipc_mbuf.c	8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.67 2002/12/06 13:28:05 darrenr Exp $
+ * $Id: fil.c,v 2.35.2.82 2004/06/20 10:27:47 darrenr Exp $
  */
 /*
  * Copy data from an mbuf chain starting "off" bytes from the beginning,
@@ -1974,12 +2092,40 @@ struct in_addr *inp;
 static void frsynclist(fr)
 frentry_t *fr;
 {
+	frdest_t *fdp;
+	int i;
+
 	for (; fr; fr = fr->fr_next) {
-		if (fr->fr_ifa != NULL) {
-			fr->fr_ifa = GETUNIT(fr->fr_ifname, fr->fr_ip.fi_v);
-			if (fr->fr_ifa == NULL)
-				fr->fr_ifa = (void *)-1;
+		for (i = 0; i < 4; i++) {
+			if ((fr->fr_ifnames[i][1] == '\0') &&
+			    ((fr->fr_ifnames[i][0] == '-') ||
+			     (fr->fr_ifnames[i][0] == '*'))) {
+				fr->fr_ifas[i] = NULL;
+			} else if (*fr->fr_ifnames[i]) {
+				fr->fr_ifas[i] = GETUNIT(fr->fr_ifnames[i],
+							 fr->fr_v);
+				if (!fr->fr_ifas[i])
+					fr->fr_ifas[i] = (void *)-1;
+			}
+		}
+
+		fdp = &fr->fr_dif;
+		fr->fr_flags &= ~FR_DUP;
+		if (*fdp->fd_ifname) {
+			fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
+			if (!fdp->fd_ifp)
+				fdp->fd_ifp = (struct ifnet *)-1;
+			else
+				fr->fr_flags |= FR_DUP;
+		}
+
+		fdp = &fr->fr_tif;
+		if (*fdp->fd_ifname) {
+			fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
+			if (!fdp->fd_ifp)
+				fdp->fd_ifp = (struct ifnet *)-1;
 		}
+
 		if (fr->fr_grp)
 			frsynclist(fr->fr_grp);
 	}
@@ -2234,3 +2380,64 @@ mb_t *buf;
 	return ip->ip_len;
 }
 #endif
+
+
+#if defined(_KERNEL) && !defined(__sgi)
+void *ipf_pullup(m, fin, len, ipin)
+mb_t *m;
+fr_info_t *fin;
+int len;
+void *ipin;
+{
+# if SOLARIS
+	qif_t *qf = fin->fin_qif;
+# endif
+	int out = fin->fin_out, dpoff, ipoff;
+	char *ip;
+
+	if (m == NULL)
+		return NULL;
+
+	ipoff = (char *)ipin - MTOD(m, char *);
+	if (fin->fin_dp != NULL)
+		dpoff = (char *)fin->fin_dp - (char *)ipin;
+	else
+		dpoff = 0;
+
+	if (M_BLEN(m) < len) {
+# if SOLARIS
+		qif_t *qf = fin->fin_qif;
+		int inc = 0;
+
+		if (ipoff > 0) {
+			if ((ipoff & 3) != 0) {
+				inc = 4 - (ipoff & 3);
+				if (m->b_rptr - inc >= m->b_datap->db_base)
+					m->b_rptr -= inc;
+				else
+					inc = 0;
+			}
+		}
+		if (!pullupmsg(m, len + ipoff + inc)) {
+			ATOMIC_INCL(frstats[out].fr_pull[1]);
+			return NULL;
+		}
+		m->b_rptr += inc;
+		ATOMIC_INCL(frstats[out].fr_pull[0]);
+		qf->qf_data = MTOD(m, char *) + ipoff;
+# else
+		m = m_pullup(m, len);
+		*fin->fin_mp = m;
+		if (m == NULL) {
+			ATOMIC_INCL(frstats[out].fr_pull[1]);
+			return NULL;
+		}
+		ATOMIC_INCL(frstats[out].fr_pull[0]);
+# endif /* SOLARIS */
+	}
+	ip = MTOD(m, char *) + ipoff;
+	if (fin->fin_dp != NULL)
+		fin->fin_dp = (char *)ip + dpoff;
+	return ip;
+}
+#endif /* _KERNEL */
Index: sys/contrib/ipfilter/netinet/ip_compat.h
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_compat.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 ip_compat.h
--- sys/contrib/ipfilter/netinet/ip_compat.h	14 Feb 2004 21:12:38 -0000	1.10
+++ sys/contrib/ipfilter/netinet/ip_compat.h	17 Jul 2004 05:22:02 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_compat.h	1.8 1/14/96
  * $Id: ip_compat.h,v 2.26.2.46 2002/06/27 14:39:40 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_compat.h,v 1.13.2.5 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_compat.h,v 1.13.2.6 2004/07/04 09:24:38 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_compat.h,v 1.10 2004/02/14 21:12:38 dillon Exp $
  */
 
@@ -60,7 +60,7 @@
 
 #if defined(__sgi) || defined(bsdi)
 struct  ether_addr {
-        u_char  ether_addr_octet[6];
+	u_char  ether_addr_octet[6];
 };
 #endif
 
@@ -156,6 +156,7 @@ struct file;
 #   define	V4_PART_OF_V6(v6)	v6.s6_addr32[3]
 #  endif
 # endif
+# define	M_BLEN(m)	((m)->b_wptr - (m)->b_rptr)
 
 typedef	struct	qif	{
 	struct	qif	*qf_next;
@@ -165,6 +166,7 @@ typedef	struct	qif	{
 	void	*qf_optr;
 	queue_t	*qf_in;
 	queue_t	*qf_out;
+	void	*qf_data;	/* layer 3 header pointer */
 	struct	qinit	*qf_wqinfo;
 	struct	qinit	*qf_rqinfo;
 	struct	qinit	qf_wqinit;
@@ -521,6 +523,7 @@ extern	ill_t	*get_unit (char *, int);
 #  ifndef linux
 #   define	FREE_MB_T(m)	m_freem(m)
 #   define	MTOD(m,t)	mtod(m,t)
+#   define	M_BLEN(m)	(m)->m_len
 #   define	IRCOPY(a,b,c)	(bcopy((a), (b), (c)), 0)
 #   define	IWCOPY(a,b,c)	(bcopy((a), (b), (c)), 0)
 #   define	IRCOPYPTR	ircopyptr
@@ -958,7 +961,7 @@ typedef	struct	{
 	__u32	th_seq;
 	__u32	th_ack;
 # if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
-    defined(vax)
+    defined(__vax__)
 	__u8	th_res:4;
 	__u8	th_off:4;
 #else
@@ -980,7 +983,7 @@ typedef	struct	{
 
 typedef	struct	{
 # if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
-    defined(vax)
+    defined(__vax__)
 	__u8	ip_hl:4;
 	__u8	ip_v:4;
 # else
@@ -1204,8 +1207,8 @@ struct	ether_addr	{
 #define	ICMPERR_MINPKTLEN	(20 + 8 + 20)
 #define	ICMPERR_MAXPKTLEN	(20 + 8 + 20 + 8)
 #define	ICMP6_MINLEN		8
-#define	ICMP6ERR_MINPKTLEN	(40 + 8)
-#define	ICMP6ERR_IPICMPHLEN	(40 + 8 + 40)
+#define	ICMP6ERR_IPICMPHLEN	(40 + 8)
+#define	ICMP6ERR_MINPKTLEN	(40 + 8 + 40)
 
 #ifndef	ICMP6_DST_UNREACH
 # define	ICMP6_DST_UNREACH	1
Index: sys/contrib/ipfilter/netinet/ip_fil.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_fil.c,v
retrieving revision 1.12
diff -u -p -u -r1.12 ip_fil.c
--- sys/contrib/ipfilter/netinet/ip_fil.c	24 Jun 2004 08:15:14 -0000	1.12
+++ sys/contrib/ipfilter/netinet/ip_fil.c	17 Jul 2004 06:24:46 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_fil.c     2.41 6/5/96 (C) 1993-2000 Darren Reed
  * @(#)$Id: ip_fil.c,v 2.42.2.60 2002/08/28 12:40:39 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_fil.c,v 1.25.2.6 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_fil.c,v 1.25.2.7 2004/07/04  09:24:38 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_fil.c,v 1.12 2004/06/24 08:15:14 dillon Exp $
  */
 #ifndef	SOLARIS
@@ -537,7 +537,7 @@ int ipldetach()
 # if (__NetBSD_Version__ >= 105150000) || (__DragonFly_version >= 100000)
         struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
 #  ifdef USE_INET6
-        struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+	struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
 #  endif
 # endif
 #endif
@@ -1055,8 +1055,8 @@ caddr_t data;
 			while ((f = *ftail))
 				ftail = &f->fr_next;
 		else {
+			ftail = fprev;
 			if (fp->fr_hits) {
-				ftail = fprev;
 				while (--fp->fr_hits && (f = *ftail))
 					ftail = &f->fr_next;
 			}
@@ -1320,7 +1320,7 @@ struct mbuf **mp;
 	frn.fin_ifp = fin->fin_ifp;
 	frn.fin_v = fin->fin_v;
 	frn.fin_out = fin->fin_out;
-	frn.fin_mp = fin->fin_mp;
+	frn.fin_mp = mp;
 
 	ip = mtod(m, ip_t *);
 	hlen = sizeof(*ip);
@@ -1364,9 +1364,10 @@ struct mbuf **mp;
 	m->m_pkthdr.rcvif = NULL;
 # endif
 
-	fr_makefrip(hlen, ip, &frn);
-
-	error = ipfr_fastroute(m, mp, &frn, NULL);
+	if (fr_makefrip(hlen, ip, &frn) == 0)
+		error = ipfr_fastroute(m, mp, &frn, NULL);
+	else
+		error = EINVAL;
 	return error;
 }
 
@@ -1510,7 +1511,13 @@ int dst;
 #endif
 
 	if (avail) {
+		slen = oip->ip_len;
+		oip->ip_len = htons(oip->ip_len);
+		soff = oip->ip_off;
+		oip->ip_off = htons(oip->ip_off);
 		bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN(ohlen, avail));
+		oip->ip_len = slen;
+		oip->ip_off = soff;
 		avail -= MIN(ohlen, avail);
 	}
 
@@ -1531,10 +1538,6 @@ int dst;
 	} else
 #endif
 	{
-		slen = oip->ip_len;
-		oip->ip_len = htons(oip->ip_len);
-		soff = oip->ip_off;
-		oip->ip_off = htons(ip->ip_off);
 
 		ip->ip_src.s_addr = dst4.s_addr;
 		ip->ip_dst.s_addr = oip->ip_src.s_addr;
@@ -1554,13 +1557,7 @@ int dst;
 	fin->fin_hlen = hlen;
 	err = send_ip(oip, fin, &m);
 	fin->fin_hlen = shlen;
-#ifdef	USE_INET6
-	if (fin->fin_v == 4)
-#endif
-	{
-		oip->ip_len = slen;
-		oip->ip_off = soff;
-	}
+
 	return err;
 }
 
@@ -1618,7 +1615,7 @@ frdest_t *fdp;
 	struct ip *ip, *mhip;
 	struct mbuf *m = m0;
 	struct route *ro;
-	int len, off, error = 0, hlen, code;
+	int len, off, error = 0, hlen, code, sout;
 	struct ifnet *ifp, *sifp;
 	struct sockaddr_in *dst;
 	struct route iproute;
@@ -1688,7 +1685,7 @@ frdest_t *fdp;
 	/*
 	 * Route packet.
 	 */
-#if defined(__sgi) && (IRIX >= 605)
+#if (defined(IRIX) && (IRIX >= 605))
 	ROUTE_RDLOCK();
 #endif
 	bzero((caddr_t)ro, sizeof (*ro));
@@ -1707,8 +1704,12 @@ frdest_t *fdp;
 	 * check that we're going in the correct direction.
 	 */
 	if ((fr != NULL) && (fin->fin_rev != 0)) {
-		if ((ifp != NULL) && (fdp == &fr->fr_tif))
+		if ((ifp != NULL) && (fdp == &fr->fr_tif)) {
+# if (defined(IRIX) && (IRIX >= 605))
+			ROUTE_UNLOCK();
+# endif
 			return 0;
+		}
 	} else if (fdp != NULL) {
 		if (fdp->fd_ip.s_addr != 0)
 			dst->sin_addr = fdp->fd_ip;
@@ -1728,13 +1729,12 @@ frdest_t *fdp;
 	rtalloc(ro);
 # endif
 
-#if defined(__sgi) && (IRIX > 602)
-	ROUTE_UNLOCK();
-#endif
-
 	if (!ifp) {
 		if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
 			error = -2;
+# if (defined(IRIX) && (IRIX >= 605))
+			ROUTE_UNLOCK();
+# endif
 			goto bad;
 		}
 	}
@@ -1747,11 +1747,14 @@ frdest_t *fdp;
 			error = EHOSTUNREACH;
 		else
 			error = ENETUNREACH;
+# if (defined(IRIX) && (IRIX >= 605))
+			ROUTE_UNLOCK();
+# endif
 		goto bad;
 	}
 
 	if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
-#if BSD >= 199306
+#if (BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
 		dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
 #else
 		dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
@@ -1759,6 +1762,10 @@ frdest_t *fdp;
 	}
 	ro->ro_rt->rt_use++;
 
+#if (defined(IRIX) && (IRIX > 602))
+	ROUTE_UNLOCK();
+#endif
+
 	/*
 	 * For input packets which are being "fastrouted", they won't
 	 * go back through output filtering and miss their chance to get
@@ -1766,6 +1773,7 @@ frdest_t *fdp;
 	 */
 	if (fin->fin_out == 0) {
 		sifp = fin->fin_ifp;
+		sout = fin->fin_out;
 		fin->fin_ifp = ifp;
 		fin->fin_out = 1;
 		if ((fin->fin_fr = ipacct[1][fr_active]) &&
@@ -1775,10 +1783,25 @@ frdest_t *fdp;
 		fin->fin_fr = NULL;
 		if (!fr || !(fr->fr_flags & FR_RETMASK))
 			(void) fr_checkstate(ip, fin);
-		(void) ip_natout(ip, fin);
+
+		switch (ip_natout(ip, fin))
+		{
+		case 0 :
+			break;
+		case 1 :
+			ip->ip_sum = 0;
+			break;
+		case -1 :
+			error = EINVAL;
+			goto done;
+			break;
+		}
+
 		fin->fin_ifp = sifp;
+		fin->fin_out = sout;
 	} else
 		ip->ip_sum = 0;
+
 	/*
 	 * If small enough for interface, can just send directly.
 	 */
@@ -1808,8 +1831,14 @@ frdest_t *fdp;
 			ip->ip_sum = in_cksum(m, hlen);
 # endif /* __NetBSD__ && M_CSUM_IPv4 */
 # if	(BSD >= 199306) || (defined(IRIX) && (IRIX >= 605))
+#  ifdef IRIX
+		IFNET_UPPERLOCK(ifp);
+#  endif
 		error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
 					  ro->ro_rt);
+#  ifdef IRIX
+		IFNET_UPPERUNLOCK(ifp);
+#  endif
 # else
 		error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
 # endif
@@ -1957,7 +1986,7 @@ void *ifp;
 	dst->sin_family = AF_INET;
 	dst->sin_addr = ipa;
 # if    (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
-        !defined(__OpenBSD__)
+	!defined(__OpenBSD__)
 #  ifdef        RTF_CLONING
 	rtalloc_ign(&iproute, RTF_CLONING);
 #  else
@@ -2009,17 +2038,18 @@ frdest_t *fdp;
 	u_long mtu;
 	int error;
 
-	ifp = NULL;
 	ro = &ip6route;
 	fr = fin->fin_fr;
 	bzero((caddr_t)ro, sizeof(*ro));
 	dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
 	dst6->sin6_family = AF_INET6;
 	dst6->sin6_len = sizeof(struct sockaddr_in6);
-	dst6->sin6_addr = fin->fin_fi.fi_src.in6;
+	dst6->sin6_addr = fin->fin_fi.fi_dst.in6;
 
 	if (fdp != NULL)
 		ifp = fdp->fd_ifp;
+	else
+		ifp = fin->fin_ifp;
 
 	if ((fr != NULL) && (fin->fin_rev != 0)) {
 		if ((ifp != NULL) && (fdp == &fr->fr_tif))
@@ -2028,9 +2058,14 @@ frdest_t *fdp;
 		if (IP6_NOTZERO(&fdp->fd_ip6))
 			dst6->sin6_addr = fdp->fd_ip6.in6;
 	}
-	if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
+	if (ifp == NULL)
 		return -2;
 
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
+	/* KAME */
+	if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr))
+		dst6->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+#endif
 	rtalloc((struct route *)ro);
 
 	if ((ifp == NULL) && (ro->ro_rt != NULL))
Index: sys/contrib/ipfilter/netinet/ip_fil.h
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_fil.h,v
retrieving revision 1.6
diff -u -p -u -r1.6 ip_fil.h
--- sys/contrib/ipfilter/netinet/ip_fil.h	12 Feb 2004 22:35:47 -0000	1.6
+++ sys/contrib/ipfilter/netinet/ip_fil.h	17 Jul 2004 05:52:00 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_fil.h	1.35 6/5/96
  * $Id: ip_fil.h,v 2.29.2.33 2002/06/04 14:46:28 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_fil.h,v 1.18.2.5 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_fil.h,v 1.18.2.8 2004/07/05 06:02:35 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_fil.h,v 1.6 2004/02/12 22:35:47 joerg Exp $
  */
 
@@ -145,7 +145,7 @@ typedef	struct	fr_info	{
 	u_short	fin_dlen;		/* length of data portion of packet */
 	u_short	fin_id;			/* IP packet id field */
 	u_int	fin_misc;
-	void	*fin_mp;		/* pointer to pointer to mbuf */
+	mb_t	**fin_mp;		/* pointer to pointer to mbuf */
 #if SOLARIS
 	void	*fin_qfm;		/* pointer to mblk where pkt starts */
 	void	*fin_qif;
@@ -629,7 +629,7 @@ extern	void	fr_forgetifp (void *);
 extern	void	fr_getstat (struct friostat *);
 extern	int	fr_ifpaddr (int, void *, struct in_addr *);
 extern	int	fr_lock (caddr_t, int *);
-extern  void	fr_makefrip (int, ip_t *, fr_info_t *);
+extern  int	fr_makefrip (int, ip_t *, fr_info_t *);
 extern	u_short	fr_tcpsum (mb_t *, ip_t *, tcphdr_t *);
 extern	int	fr_scanlist (u_32_t, ip_t *, fr_info_t *, void *);
 extern	int	fr_tcpudpchk (frtuc_t *, fr_info_t *);
Index: sys/contrib/ipfilter/netinet/ip_frag.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_frag.c,v
retrieving revision 1.5
diff -u -p -u -r1.5 ip_frag.c
--- sys/contrib/ipfilter/netinet/ip_frag.c	12 Feb 2004 22:35:47 -0000	1.5
+++ sys/contrib/ipfilter/netinet/ip_frag.c	17 Jul 2004 05:39:49 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_frag.c    1.11 3/24/96 (C) 1993-2000 Darren Reed
  * @(#)$Id: ip_frag.c,v 2.10.2.24 2002/08/28 12:41:04 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_frag.c,v 1.15.2.6 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_frag.c,v 1.15.2.7 2004/07/04 09:24:38 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_frag.c,v 1.5 2004/02/12 22:35:47 joerg Exp $
  */
 #if defined(KERNEL) && !defined(_KERNEL)
@@ -196,7 +196,7 @@ ipfr_t *table[];
 
 
 	/*
-	 * Instert the fragment into the fragment table, copy the struct used
+	 * Insert the fragment into the fragment table, copy the struct used
 	 * in the search using bcopy rather than reassign each field.
 	 * Set the ttl to the default.
 	 */
@@ -424,7 +424,26 @@ fr_info_t *fin;
 /*
  * forget any references to this external object.
  */
-void ipfr_forget(nat)
+void ipfr_forget(ptr)
+void *ptr;
+{
+	ipfr_t	*fr;
+	int	idx;
+
+	WRITE_ENTER(&ipf_frag);
+	for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
+		for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+			if (fr->ipfr_data == ptr)
+				fr->ipfr_data = NULL;
+
+	RWLOCK_EXIT(&ipf_frag);
+}
+
+
+/*
+ * forget any references to this external object.
+ */
+void ipfr_forgetnat(nat)
 void *nat;
 {
 	ipfr_t	*fr;
@@ -432,7 +451,7 @@ void *nat;
 
 	WRITE_ENTER(&ipf_natfrag);
 	for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
-		for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+		for (fr = ipfr_nattab[idx]; fr; fr = fr->ipfr_next)
 			if (fr->ipfr_data == nat)
 				fr->ipfr_data = NULL;
 
Index: sys/contrib/ipfilter/netinet/ip_frag.h
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_frag.h,v
retrieving revision 1.3
diff -u -p -u -r1.3 ip_frag.h
--- sys/contrib/ipfilter/netinet/ip_frag.h	27 Aug 2003 11:02:14 -0000	1.3
+++ sys/contrib/ipfilter/netinet/ip_frag.h	17 Jul 2004 05:38:29 -0000
@@ -55,6 +55,7 @@ extern	int	ipfr_nat_newfrag (ip_t *, fr_
 extern	nat_t	*ipfr_nat_knownfrag (ip_t *, fr_info_t *);
 extern	frentry_t *ipfr_knownfrag (ip_t *, fr_info_t *);
 extern	void	ipfr_forget (void *);
+extern	void	ipfr_forgetnat (void *);
 extern	void	ipfr_unload (void);
 extern	void	ipfr_fragexpire (void);
 
Index: sys/contrib/ipfilter/netinet/ip_ftp_pxy.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 ip_ftp_pxy.c
--- sys/contrib/ipfilter/netinet/ip_ftp_pxy.c	27 Aug 2003 11:02:14 -0000	1.4
+++ sys/contrib/ipfilter/netinet/ip_ftp_pxy.c	17 Jul 2004 05:44:08 -0000
@@ -1,7 +1,7 @@
 /*
  * Simple FTP transparent proxy for in-kernel use.  For use with the NAT
  * code.
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c,v 1.17.2.5 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c,v 1.17.2.6 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c,v 1.4 2003/08/27 11:02:14 rob Exp $
  */
 #if SOLARIS && defined(_KERNEL)
@@ -121,7 +121,7 @@ int dlen;
 	int inc, off;
 	nat_t *ipn;
 	mb_t *m;
-#if	SOLARIS
+#if	SOLARIS && defined(_KERNEL)
 	mb_t *m1;
 #endif
 
@@ -207,8 +207,13 @@ int dlen;
 	a1 >>= 24;
 	olen = s - f->ftps_rptr;
 	/* DO NOT change this to snprintf! */
+#if defined(OpenBSD) && (200311 >= 200311)
+	(void) snprintf(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
+		        "PORT", a1, a2, a3, a4, a5, a6);
+#else
 	(void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
 		       "PORT", a1, a2, a3, a4, a5, a6);
+#endif
 
 	nlen = strlen(newbuf);
 	inc = nlen - olen;
@@ -221,7 +226,7 @@ int dlen;
 	}
 
 #if !defined(_KERNEL)
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	bcopy(newbuf, (char *)m + off, nlen);
 #else
 # if SOLARIS
@@ -251,7 +256,7 @@ int dlen;
 	}
 	copyin_mblk(m, off, nlen, newbuf);
 # else
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	if (inc < 0)
 		m_adj(m, inc);
 	/* the mbuf chain will be extended if necessary by m_copyback() */
@@ -263,7 +268,7 @@ int dlen;
 # endif
 #endif
 	if (inc != 0) {
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
 		u_32_t	sum1, sum2;
 
 		sum1 = ip->ip_len;
@@ -542,7 +547,7 @@ int dlen;
 		return 0;
 
 #if !defined(_KERNEL)
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	m_copyback(m, off, nlen, newbuf);
 #else
 # if SOLARIS
@@ -569,7 +574,7 @@ int dlen;
 	}
 	/*copyin_mblk(m, off, nlen, newbuf);*/
 # else /* SOLARIS */
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 	if (inc < 0)
 		m_adj(m, inc);
 	/* the mbuf chain will be extended if necessary by m_copyback() */
@@ -577,7 +582,7 @@ int dlen;
 # endif /* SOLARIS */
 #endif /* _KERNEL */
 	if (inc != 0) {
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if ((SOLARIS || defined(__sgi)) && defined(_KERNEL)) || !defined(_KERNEL)
 		u_32_t	sum1, sum2;
 
 		sum1 = ip->ip_len;
@@ -714,7 +719,8 @@ size_t len;
 
 	if (i < 5) {
 #if !defined(_KERNEL) && !defined(KERNEL)
-		fprintf(stdout, "ippr_ftp_client_valid:i(%d) < 5\n", i);
+		fprintf(stdout, "ippr_ftp_client_valid:i(%lu) < 5\n",
+			(u_long)i);
 #endif
 		return 2;
 	}
@@ -750,8 +756,8 @@ size_t len;
 bad_client_command:
 #if !defined(_KERNEL) && !defined(KERNEL)
 		fprintf(stdout,
-			"ippr_ftp_client_valid:bad cmd:len %d i %d c 0x%x\n",
-			i, len, c);
+			"ippr_ftp_client_valid:bad cmd:len %lu i %lu c 0x%x\n",
+			(u_long)i, (u_long)len, c);
 #endif
 		return 1;
 	}
@@ -812,8 +818,8 @@ size_t len;
 bad_server_command:
 #if !defined(_KERNEL) && !defined(KERNEL)
 		fprintf(stdout,
-			"ippr_ftp_server_valid:bad cmd:len %d i %d c 0x%x\n",
-			i, len, c);
+			"ippr_ftp_server_valid:bad cmd:len %lu i %lu c 0x%x\n",
+			(u_long)i, (u_long)len, c);
 #endif
 		return 1;
 	}
@@ -875,7 +881,7 @@ int rv;
 #if	SOLARIS && defined(_KERNEL)
 	m = fin->fin_qfm;
 #else
-	m = *((mb_t **)fin->fin_mp);
+	m = *fin->fin_mp;
 #endif
 
 #ifndef	_KERNEL
@@ -1025,9 +1031,9 @@ int rv;
 		printf("inc %d sel %d rv %d\n", inc, sel, rv);
 		printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0],
 			f->ftps_seq[1]);
-		printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
+		printf("ackmin %x ackoff %d\n", (u_int)aps->aps_ackmin[sel],
 			aps->aps_ackoff[sel]);
-		printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
+		printf("seqmin %x seqoff %d\n", (u_int)aps->aps_seqmin[sel],
 			aps->aps_seqoff[sel]);
 #endif
 
Index: sys/contrib/ipfilter/netinet/ip_log.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_log.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 ip_log.c
--- sys/contrib/ipfilter/netinet/ip_log.c	12 Feb 2004 22:35:47 -0000	1.6
+++ sys/contrib/ipfilter/netinet/ip_log.c	17 Jul 2004 06:09:50 -0000
@@ -4,7 +4,7 @@
  * See the IPFILTER.LICENCE file for details on licencing.
  *
  * $Id: ip_log.c,v 2.5.2.1 2000/07/19 13:11:47 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_log.c,v 1.17.2.4 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_log.c,v 1.17.2.6 2004/07/05 16:55:16 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_log.c,v 1.6 2004/02/12 22:35:47 joerg Exp $
  */
 #include <sys/param.h>
@@ -248,7 +248,7 @@ mb_t *m;
 	 */
 	bzero((char *)ipfl.fl_ifname, sizeof(ipfl.fl_ifname));
 # if SOLARIS && defined(_KERNEL)
-	ipfl.fl_unit = (u_char)ifp->ill_ppa;
+	ipfl.fl_unit = (u_int)ifp->ill_ppa;
 	bcopy(ifp->ill_name, ipfl.fl_ifname,
 	      MIN(ifp->ill_name_length, sizeof(ipfl.fl_ifname)));
 	mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
@@ -258,7 +258,7 @@ mb_t *m;
 	(defined(__DragonFly__))
 	strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
 #  else
-	ipfl.fl_unit = (u_char)ifp->if_unit;
+	ipfl.fl_unit = (u_int)ifp->if_unit;
 	strncpy(ipfl.fl_ifname, ifp->if_name, MIN(sizeof(ipfl.fl_ifname),
 						  sizeof(ifp->if_name)));
 #  endif
@@ -320,7 +320,7 @@ int *types, cnt;
 	 * rather than create a new one.
 	 */
 	MUTEX_ENTER(&ipl_mutex);
-	if (fin != NULL) {
+	if ((fin != NULL) && (fin->fin_off == 0)) {
 		if ((ipll[dev] != NULL) &&
 		    bcmp((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE) == 0) {
 			ipll[dev]->ipl_count++;
@@ -436,7 +436,7 @@ struct uio *uio;
 	SPL_NET(s);
 	MUTEX_ENTER(&ipl_mutex);
 
-	while (!iplused[unit] || !iplt[unit]) {
+	while (iplt[unit] == NULL) {
 # if SOLARIS && defined(_KERNEL)
 		if (!cv_wait_sig(&iplwait, &ipl_mutex)) {
 			MUTEX_EXIT(&ipl_mutex);
Index: sys/contrib/ipfilter/netinet/ip_nat.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_nat.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 ip_nat.c
--- sys/contrib/ipfilter/netinet/ip_nat.c	12 Feb 2004 22:35:47 -0000	1.6
+++ sys/contrib/ipfilter/netinet/ip_nat.c	17 Jul 2004 05:46:06 -0000
@@ -7,7 +7,7 @@
  *
  * @(#)ip_nat.c     1.11 6/5/96 (C) 1995 Darren Reed
  * @(#)$Id: ip_nat.c,v 2.37.2.70 2002/08/28 12:45:48 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_nat.c,v 1.22.2.7 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_nat.c,v 1.22.2.8 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_nat.c,v 1.6 2004/02/12 22:35:47 joerg Exp $
  */
 #if (defined(__DragonFly__) || defined(__FreeBSD__)) && defined(KERNEL) && !defined(_KERNEL)
@@ -117,6 +117,7 @@ static const char sccsid[] = "@(#)ip_nat
 nat_t	**nat_table[2] = { NULL, NULL },
 	*nat_instances = NULL;
 ipnat_t	*nat_list = NULL;
+u_int	ipf_nattable_max = NAT_TABLE_MAX;
 u_int	ipf_nattable_sz = NAT_TABLE_SZ;
 u_int	ipf_natrules_sz = NAT_SIZE;
 u_int	ipf_rdrrules_sz = RDR_SIZE;
@@ -780,6 +781,8 @@ caddr_t data;
 	if ((aps != NULL) && (aps->aps_data != 0)) {
 		ng.ng_sz += sizeof(ap_session_t);
 		ng.ng_sz += aps->aps_psiz;
+		if (aps->aps_psiz > 4)	/* XXX - sizeof(ipn_data) */
+			ng.ng_sz -= 4;
 	}
 
 	error = IWCOPY((caddr_t)&ng, data, sizeof(ng));
@@ -795,6 +798,7 @@ caddr_t data;
 	nat_save_t ipn, *ipnp, *ipnn = NULL;
 	nat_t *n, *nat;
 	ap_session_t *aps;
+	size_t dsz;
 	int error;
 
 	error = IRCOPY(data, (caddr_t)&ipnp, sizeof(ipnp));
@@ -826,7 +830,6 @@ caddr_t data;
 	}
 
 	ipn.ipn_next = nat->nat_next;
-	ipn.ipn_dsize = 0;
 	bcopy((char *)nat, (char *)&ipn.ipn_nat, sizeof(ipn.ipn_nat));
 	ipn.ipn_nat.nat_data = NULL;
 
@@ -840,10 +843,13 @@ caddr_t data;
 		      sizeof(ipn.ipn_rule));
 
 	if ((aps = nat->nat_aps)) {
-		ipn.ipn_dsize = sizeof(*aps);
+		dsz = sizeof(*aps);
 		if (aps->aps_data)
-			ipn.ipn_dsize += aps->aps_psiz;
-		KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
+			dsz += aps->aps_psiz;
+		ipn.ipn_dsize = dsz;
+		if (dsz > sizeof(ipn.ipn_data))
+			dsz -= sizeof(ipn.ipn_data);
+		KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + dsz);
 		if (ipnn == NULL)
 			return ENOMEM;
 		bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
@@ -852,14 +858,14 @@ caddr_t data;
 		if (aps->aps_data) {
 			bcopy(aps->aps_data, ipnn->ipn_data + sizeof(*aps),
 			      aps->aps_psiz);
-			ipnn->ipn_dsize += aps->aps_psiz;
 		}
 		error = IWCOPY((caddr_t)ipnn, ipnp,
-			       sizeof(ipn) + ipn.ipn_dsize);
+			       sizeof(ipn) + dsz);
 		if (error)
 			error = EFAULT;
-		KFREES(ipnn, sizeof(*ipnn) + ipn.ipn_dsize);
+		KFREES(ipnn, sizeof(*ipnn) + dsz);
 	} else {
+		ipn.ipn_dsize = 0;
 		error = IWCOPY((caddr_t)&ipn, ipnp, sizeof(ipn));
 		if (error)
 			error = EFAULT;
@@ -887,12 +893,12 @@ caddr_t data;
 		return EFAULT;
 	nat = NULL;
 	if (ipn.ipn_dsize) {
-		KMALLOCS(ipnn, nat_save_t *, sizeof(ipn) + ipn.ipn_dsize);
+		KMALLOCS(ipnn, nat_save_t *, sizeof(*ipnn) + ipn.ipn_dsize);
 		if (ipnn == NULL)
 			return ENOMEM;
 		bcopy((char *)&ipn, (char *)ipnn, sizeof(ipn));
-		error = IRCOPY((caddr_t)ipnp, (caddr_t)ipn.ipn_data,
-			       ipn.ipn_dsize);
+		error = IRCOPY((caddr_t)ipnp + offsetof(nat_save_t, ipn_data),
+			       (caddr_t)ipnn->ipn_data, ipn.ipn_dsize);
 		if (error) {
 			error = EFAULT;
 			goto junkput;
@@ -1067,7 +1073,7 @@ struct nat *natd;
 	 * If there's a fragment table entry too for this nat entry, then
 	 * dereference that as well.
 	 */
-	ipfr_forget((void *)natd);
+	ipfr_forgetnat((void *)natd);
 	aps_free(natd->nat_aps);
 	nat_stats.ns_inuse--;
 	KFREE(natd);
@@ -1165,6 +1171,11 @@ int direction;
 	qif_t *qf = fin->fin_qif;
 #endif
 
+	if (nat_stats.ns_inuse >= ipf_nattable_max) {
+		nat_stats.ns_memfail++;
+		return NULL;
+	}
+
 	nflags = flags & np->in_flags;
 	if (flags & IPN_TCPUDP) {
 		tcp = (tcphdr_t *)fin->fin_dp;
@@ -1176,6 +1187,17 @@ int direction;
 	KMALLOC(nat, nat_t *);
 	if (nat == NULL) {
 		nat_stats.ns_memfail++;
+		/*
+		 * Try to automatically tune the max # of entries in the
+		 * table allowed to be less than what will cause kmem_alloc()
+		 * to fail and try to eliminate panics due to out of memory
+		 * conditions arising.
+		 */
+		if (ipf_nattable_max > ipf_nattable_sz) {
+			ipf_nattable_max = nat_stats.ns_inuse - 100;
+			printf("ipf_nattable_max reduced to %d\n",
+				ipf_nattable_max);
+		}
 		return NULL;
 	}
 
@@ -1432,7 +1454,7 @@ int direction;
 	CALC_SUMD(sum1, sum2, sumd);
 	nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
 #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
-	if ((flags & IPN_TCPUDP) && dohwcksum &&
+	if ((flags & IPN_TCP) && dohwcksum &&
 	    (qf->qf_ill->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) {
 		if (direction == NAT_OUTBOUND)
 			sum1 = LONG_SUM(ntohl(in.s_addr));
@@ -1684,6 +1706,7 @@ int dir;
 		return NULL;
 
 	flags = 0;
+	sumd2 = 0;
 	*nflags = IPN_ICMPERR;
 	icmp = (icmphdr_t *)fin->fin_dp;
 	oip = (ip_t *)&icmp->icmp_ip;
@@ -1737,137 +1760,75 @@ int dir;
 
 	CALC_SUMD(sum1, sum2, sumd);
 
-	if (nat->nat_dir == NAT_OUTBOUND) {
-		/*
-		 * Fix IP checksum of the offending IP packet to adjust for
-		 * the change in the IP address.
-		 *
-		 * Normally, you would expect that the ICMP checksum of the 
-		 * ICMP error message needs to be adjusted as well for the
-		 * IP address change in oip.
-		 * However, this is a NOP, because the ICMP checksum is 
-		 * calculated over the complete ICMP packet, which includes the
-		 * changed oip IP addresses and oip->ip_sum. However, these 
-		 * two changes cancel each other out (if the delta for
-		 * the IP address is x, then the delta for ip_sum is minus x), 
-		 * so no change in the icmp_cksum is necessary.
-		 *
-		 * Be careful that nat_dir refers to the direction of the
-		 * offending IP packet (oip), not to its ICMP response (icmp)
-		 */
-		fix_datacksum(&oip->ip_sum, sumd);
+	/*
+	 * Fix IP checksum of the offending IP packet to adjust for
+	 * the change in the IP address.
+	 *
+	 * Normally, you would expect that the ICMP checksum of the 
+	 * ICMP error message needs to be adjusted as well for the
+	 * IP address change in oip.
+	 * However, this is a NOP, because the ICMP checksum is 
+	 * calculated over the complete ICMP packet, which includes the
+	 * changed oip IP addresses and oip->ip_sum. However, these 
+	 * two changes cancel each other out (if the delta for
+	 * the IP address is x, then the delta for ip_sum is minus x), 
+	 * so no change in the icmp_cksum is necessary.
+	 *
+	 * Be careful that nat_dir refers to the direction of the
+	 * offending IP packet (oip), not to its ICMP response (icmp)
+	 */
+	fix_datacksum(&oip->ip_sum, sumd);
+	/* Fix icmp cksum : IP Addr + Cksum */
 
+	/*
+	 * Fix UDP pseudo header checksum to compensate for the
+	 * IP address change.
+	 */
+	if ((oip->ip_p == IPPROTO_UDP) && (dlen >= 8) && udp->uh_sum) {
 		/*
-		 * Fix UDP pseudo header checksum to compensate for the
-		 * IP address change.
+		 * The UDP checksum is optional, only adjust it 
+		 * if it has been set.
 		 */
-		if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-			/*
-			 * The UDP checksum is optional, only adjust it 
-			 * if it has been set.
-			 */
-			sum1 = ntohs(udp->uh_sum);
-			fix_datacksum(&udp->uh_sum, sumd);
-			sum2 = ntohs(udp->uh_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the UDP 
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
+		sum1 = ntohs(udp->uh_sum);
+		fix_datacksum(&udp->uh_sum, sumd);
+		sum2 = ntohs(udp->uh_sum);
 
 		/*
-		 * Fix TCP pseudo header checksum to compensate for the 
-		 * IP address change. Before we can do the change, we
-		 * must make sure that oip is sufficient large to hold
-		 * the TCP checksum (normally it does not!).
+		 * Fix ICMP checksum to compensate the UDP 
+		 * checksum adjustment.
 		 */
-		if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-		
-			sum1 = ntohs(tcp->th_sum);
-			fix_datacksum(&tcp->th_sum, sumd);
-			sum2 = ntohs(tcp->th_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the TCP 
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
-	} else {
+		sumd2 = sumd << 1;
+		CALC_SUMD(sum1, sum2, sumd);
+		sumd2 += sumd;
+	}
 
-		/*
-		 * Fix IP checksum of the offending IP packet to adjust for
-		 * the change in the IP address.
-		 *
-		 * Normally, you would expect that the ICMP checksum of the 
-		 * ICMP error message needs to be adjusted as well for the
-		 * IP address change in oip.
-		 * However, this is a NOP, because the ICMP checksum is 
-		 * calculated over the complete ICMP packet, which includes the
-		 * changed oip IP addresses and oip->ip_sum. However, these 
-		 * two changes cancel each other out (if the delta for
-		 * the IP address is x, then the delta for ip_sum is minus x), 
-		 * so no change in the icmp_cksum is necessary.
-		 *
-		 * Be careful that nat_dir refers to the direction of the
-		 * offending IP packet (oip), not to its ICMP response (icmp)
-		 */
-		fix_datacksum(&oip->ip_sum, sumd);
+	/*
+	 * Fix TCP pseudo header checksum to compensate for the 
+	 * IP address change. Before we can do the change, we
+	 * must make sure that oip is sufficient large to hold
+	 * the TCP checksum (normally it does not!).
+	 */
+	else if ((oip->ip_p == IPPROTO_TCP) && (dlen >= 18)) {
+		sum1 = ntohs(tcp->th_sum);
+		fix_datacksum(&tcp->th_sum, sumd);
+		sum2 = ntohs(tcp->th_sum);
 
-/* XXX FV : without having looked at Solaris source code, it seems unlikely
- * that SOLARIS would compensate this in the kernel (a body of an IP packet 
- * in the data section of an ICMP packet). I have the feeling that this should
- * be unconditional, but I'm not in a position to check.
- */
-#if !SOLARIS && !defined(__sgi)
 		/*
-		 * Fix UDP pseudo header checksum to compensate for the
-		 * IP address change.
+		 * Fix ICMP checksum to compensate the TCP 
+		 * checksum adjustment.
 		 */
-		if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-			/*
-			 * The UDP checksum is optional, only adjust it 
-			 * if it has been set 
-			 */
-			sum1 = ntohs(udp->uh_sum);
-			fix_datacksum(&udp->uh_sum, sumd);
-			sum2 = ntohs(udp->uh_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the UDP 
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
-		
-		/* 
-		 * Fix TCP pseudo header checksum to compensate for the 
-		 * IP address change. Before we can do the change, we
-		 * must make sure that oip is sufficient large to hold
-		 * the TCP checksum (normally it does not!).
-		 */
-		if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-		
-			sum1 = ntohs(tcp->th_sum);
-			fix_datacksum(&tcp->th_sum, sumd);
-			sum2 = ntohs(tcp->th_sum);
-
-			/*
-			 * Fix ICMP checksum to compensate the TCP
-			 * checksum adjustment.
-			 */
-			CALC_SUMD(sum1, sum2, sumd);
-			sumd2 = sumd;
-		}
-#endif
+		sumd2 = sumd << 1;
+		CALC_SUMD(sum1, sum2, sumd);
+		sumd2 += sumd;
+	} else {
+		sumd2 = (sumd >> 16); 
+		if (nat->nat_dir == NAT_OUTBOUND)
+			sumd2 = ~sumd2;
+		else
+			sumd2 = ~sumd2 + 1;
 	}
 
-	if ((flags & IPN_TCPUDP) != 0) {
+	if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) {
 		/*
 		 * Step 2 :
 		 * For offending TCP/UDP IP packets, translate the ports as
@@ -1887,17 +1848,14 @@ int dir;
 		 * include the TCP checksum. So we have to check if the
 		 * ip->ip_len actually holds the TCP checksum of the oip!
 		 */
-
 		if (nat->nat_oport == tcp->th_dport) {
 			if (tcp->th_sport != nat->nat_inport) {
 				/*
 				 * Fix ICMP checksum to compensate port
 				 * adjustment.
 				 */
-				sum1 = ntohs(tcp->th_sport);
-				sum2 = ntohs(nat->nat_inport);
-				CALC_SUMD(sum1, sum2, sumd);
-				sumd2 += sumd;
+				sum1 = ntohs(nat->nat_inport);
+				sum2 = ntohs(tcp->th_sport);
 				tcp->th_sport = nat->nat_inport;
 
 				/*
@@ -1909,16 +1867,18 @@ int dir;
 				 * The UDP checksum is optional, only adjust
 				 * it if it has been set.
 				 */
-				if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
+				if ((oip->ip_p == IPPROTO_UDP) &&
+				    (dlen >= 8) && udp->uh_sum) {
+					sumd = sum1 - sum2;
+					sumd2 += sumd;
 
 					sum1 = ntohs(udp->uh_sum);
 					fix_datacksum(&udp->uh_sum, sumd);
 					sum2 = ntohs(udp->uh_sum);
 
 					/*
-					 * Fix ICMP checksum to 
-					 * compensate UDP checksum 
-					 * adjustment.
+					 * Fix ICMP checksum to compensate
+					 * UDP checksum adjustment.
 					 */
 					CALC_SUMD(sum1, sum2, sumd);
 					sumd2 += sumd;
@@ -1930,63 +1890,73 @@ int dir;
 				 * packet flows the other direction compared to
 				 * the ICMP message.
 				 */
-				if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
-
-					sum1 = ntohs(tcp->th_sum);
-					fix_datacksum(&tcp->th_sum, sumd);
-					sum2 = ntohs(tcp->th_sum);
-
-					/*
-					 * Fix ICMP checksum to 
-					 * compensate TCP checksum 
-					 * adjustment.
-					 */
-					CALC_SUMD(sum1, sum2, sumd);
-					sumd2 += sumd;
+				if (oip->ip_p == IPPROTO_TCP) {
+					if (dlen >= 18) {
+						sumd = sum1 - sum2;
+						sumd2 += sumd;
+
+						sum1 = ntohs(tcp->th_sum);
+						fix_datacksum(&tcp->th_sum,
+							      sumd);
+						sum2 = ntohs(tcp->th_sum);
+
+						/*
+						 * Fix ICMP checksum to 
+						 * compensate TCP checksum 
+						 * adjustment.
+						 */
+						CALC_SUMD(sum1, sum2, sumd);
+						sumd2 += sumd;
+					} else {
+						sumd = sum2 - sum1 + 1;
+						sumd2 += sumd;
+					}
 				}
 			}
-		} else {
-			if (tcp->th_dport != nat->nat_outport) {
-				/*
-				 * Fix ICMP checksum to compensate port
-				 * adjustment.
-				 */
-				sum1 = ntohs(tcp->th_dport);
-				sum2 = ntohs(nat->nat_outport);
-				CALC_SUMD(sum1, sum2, sumd);
+		} else if (tcp->th_dport != nat->nat_outport) {
+			/*
+			 * Fix ICMP checksum to compensate port
+			 * adjustment.
+			 */
+			sum1 = ntohs(nat->nat_outport);
+			sum2 = ntohs(tcp->th_dport);
+			tcp->th_dport = nat->nat_outport;
+
+			/*
+			 * Fix udp checksum to compensate port
+			 * adjustment.   NOTE : the offending IP
+			 * packet flows the other direction compared
+			 * to the ICMP message.
+			 *
+			 * The UDP checksum is optional, only adjust
+			 * it if it has been set.
+			 */
+			if ((oip->ip_p == IPPROTO_UDP) &&
+			    (dlen >= 8) && udp->uh_sum) {
+				sumd = sum1 - sum2;
 				sumd2 += sumd;
-				tcp->th_dport = nat->nat_outport;
+
+				sum1 = ntohs(udp->uh_sum);
+				fix_datacksum(&udp->uh_sum, sumd);
+				sum2 = ntohs(udp->uh_sum);
 
 				/*
-				 * Fix udp checksum to compensate port
-				 * adjustment.   NOTE : the offending IP
-				 * packet flows the other direction compared
-				 * to the ICMP message.
-				 *
-				 * The UDP checksum is optional, only adjust
-				 * it if it has been set.
+				 * Fix ICMP checksum to compensate
+				 * UDP checksum adjustment.
 				 */
-				if (oip->ip_p == IPPROTO_UDP && udp->uh_sum) {
-
-					sum1 = ntohs(udp->uh_sum);
-					fix_datacksum(&udp->uh_sum, sumd);
-					sum2 = ntohs(udp->uh_sum);
+				CALC_SUMD(sum1, sum2, sumd);
+			}
 
-					/*
-					 * Fix ICMP checksum to compensate
-					 * UDP checksum adjustment.
-					 */
-					CALC_SUMD(sum1, sum2, sumd);
+			/*
+			 * Fix tcp checksum (if present) to compensate
+			 * port adjustment. NOTE : the offending IP
+			 * packet flows the other direction compared to
+			 * the ICMP message.
+			 */
+			if (oip->ip_p == IPPROTO_TCP) {
+				if (dlen >= 18) {
+					sumd = sum1 - sum2;
 					sumd2 += sumd;
-				}
-
-				/*
-				 * Fix tcp checksum (if present) to compensate
-				 * port adjustment. NOTE : the offending IP
-				 * packet flows the other direction compared to
-				 * the ICMP message.
-				 */
-				if (oip->ip_p == IPPROTO_TCP && dlen >= 18) {
 
 					sum1 = ntohs(tcp->th_sum);
 					fix_datacksum(&tcp->th_sum, sumd);
@@ -1997,18 +1967,18 @@ int dir;
 					 * UDP checksum adjustment.
 					 */
 					CALC_SUMD(sum1, sum2, sumd);
-					sumd2 += sumd;
+				} else {
+					sumd = sum2 - sum1;
+					if (nat->nat_dir == NAT_OUTBOUND)
+						sumd++;
 				}
 			}
+			sumd2 += sumd;
 		}
 		if (sumd2) {
 			sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
 			sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
-			if (nat->nat_dir == NAT_OUTBOUND) {
-				fix_outcksum(fin, &icmp->icmp_cksum, sumd2);
-			} else {
-				fix_incksum(fin, &icmp->icmp_cksum, sumd2);
-			}
+			fix_incksum(fin, &icmp->icmp_cksum, sumd2);
 		}
 	}
 	if (oip->ip_p == IPPROTO_ICMP)
@@ -2478,13 +2448,9 @@ maskloop:
 			s1 = LONG_SUM(ntohl(fin->fin_saddr));
 			s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr));
 			CALC_SUMD(s1, s2, sumd);
-
-			if (nat->nat_dir == NAT_OUTBOUND)
-				fix_outcksum(fin, &ip->ip_sum, sumd);
-			else
-				fix_incksum(fin, &ip->ip_sum, sumd);
+			fix_outcksum(fin, &ip->ip_sum, sumd);
 		}
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) || !defined(_KERNEL)
 		else {
 			if (nat->nat_dir == NAT_OUTBOUND)
 				fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
@@ -2512,7 +2478,8 @@ maskloop:
 				if (nat->nat_age < fr_defnaticmpage)
 					nat->nat_age = fr_defnaticmpage;
 #ifdef LARGE_NAT
-				else if (nat->nat_age > fr_defnatage)
+				else if ((!np || !np->in_age[1]) &&
+				         (nat->nat_age > fr_defnatage))
 					nat->nat_age = fr_defnatage;
 #endif
 				/*
@@ -2705,19 +2672,19 @@ maskloop:
 		nat->nat_bytes += ip->ip_len;
 		nat->nat_pkts++;
 		MUTEX_EXIT(&nat->nat_lock);
-		ip->ip_dst = nat->nat_inip;
-		fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
 
 		/*
 		 * Fix up checksums, not by recalculating them, but
 		 * simply computing adjustments.
 		 */
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
 		if (nat->nat_dir == NAT_OUTBOUND)
 			fix_incksum(fin, &ip->ip_sum, nat->nat_ipsumd);
 		else
 			fix_outcksum(fin, &ip->ip_sum, nat->nat_ipsumd);
-#endif
+
+		ip->ip_dst = nat->nat_inip;
+		fin->fin_fi.fi_daddr = nat->nat_inip.s_addr;
+
 		if ((fin->fin_off == 0) && !(fin->fin_fl & FI_SHORT)) {
 
 			if ((nat->nat_inport != 0) && (tcp != NULL)) {
@@ -2733,7 +2700,8 @@ maskloop:
 				if (nat->nat_age < fr_defnaticmpage)
 					nat->nat_age = fr_defnaticmpage;
 #ifdef LARGE_NAT
-				else if (nat->nat_age > fr_defnatage)
+				else if ((!np || !np->in_age[0]) &&
+					 (nat->nat_age > fr_defnatage))
 					nat->nat_age = fr_defnatage;
 #endif
 				/*
@@ -2985,7 +2953,7 @@ u_short *csump;
 			if (&cp[1] >= ep)
 				break;
 			advance = cp[1];
-			if (&cp[advance] >= ep)
+			if (&cp[advance] > ep)
 				break;
 			switch (opt) {
 			case TCPOPT_MAXSEG:
Index: sys/contrib/ipfilter/netinet/ip_nat.h
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_nat.h,v
retrieving revision 1.4
diff -u -p -u -r1.4 ip_nat.h
--- sys/contrib/ipfilter/netinet/ip_nat.h	12 Feb 2004 22:35:47 -0000	1.4
+++ sys/contrib/ipfilter/netinet/ip_nat.h	17 Jul 2004 05:46:24 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_nat.h	1.5 2/4/96
  * $Id: ip_nat.h,v 2.17.2.27 2002/08/28 12:45:51 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_nat.h,v 1.15.2.5 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_nat.h,v 1.15.2.6 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_nat.h,v 1.4 2004/02/12 22:35:47 joerg Exp $
  */
 
@@ -36,26 +36,39 @@
 			 * a setup with 1000-2000 networks to NAT.
 			 */
 #ifndef	NAT_SIZE
-# define	NAT_SIZE	127
+# ifdef	LARGE_NAT
+#  define	NAT_SIZE	2047
+# else
+#  define	NAT_SIZE	127
+# endif
 #endif
 #ifndef	RDR_SIZE
-# define	RDR_SIZE	127
+# ifdef	LARGE_NAT
+#  define	RDR_SIZE	2047
+# else
+#  define	RDR_SIZE	127
+# endif
 #endif
 #ifndef	HOSTMAP_SIZE
-# define	HOSTMAP_SIZE	127
+# ifdef	LARGE_NAT
+#  define	HOSTMAP_SIZE	8191
+# else
+#  define	HOSTMAP_SIZE	2047
+# endif
+#endif
+#ifndef NAT_TABLE_MAX
+# ifdef	LARGE_NAT
+#  define	NAT_TABLE_MAX	180000
+# else
+#  define	NAT_TABLE_MAX	30000
+# endif
 #endif
 #ifndef	NAT_TABLE_SZ
-# define	NAT_TABLE_SZ	127
-#endif
-#ifdef	LARGE_NAT
-#undef	NAT_SIZE
-#undef	RDR_SIZE
-#undef	NAT_TABLE_SZ
-#undef	HOSTMAP_SIZE	127
-#define	NAT_SIZE	2047
-#define	RDR_SIZE	2047
-#define	NAT_TABLE_SZ	16383
-#define	HOSTMAP_SIZE	8191
+# ifdef	LARGE_NAT
+#  define	NAT_TABLE_SZ	16383
+# else
+#  define	NAT_TABLE_SZ	2047
+# endif
 #endif
 #ifndef	APR_LABELLEN
 #define	APR_LABELLEN	16
Index: sys/contrib/ipfilter/netinet/ip_raudio_pxy.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 ip_raudio_pxy.c
--- sys/contrib/ipfilter/netinet/ip_raudio_pxy.c	27 Aug 2003 11:02:14 -0000	1.3
+++ sys/contrib/ipfilter/netinet/ip_raudio_pxy.c	17 Jul 2004 05:47:40 -0000
@@ -1,5 +1,5 @@
 /*
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c,v 1.7.2.3 2002/04/27 17:37:12 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c,v 1.8.2.4 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c,v 1.3 2003/08/27 11:02:14 rob Exp $
  */
 #if SOLARIS && defined(_KERNEL)
@@ -67,9 +67,6 @@ nat_t *nat;
 	tcphdr_t *tcp;
 	int len = 0;
 	mb_t *m;
-#if	SOLARIS
-	mb_t *m1;
-#endif
 
 	/*
 	 * If we've already processed the start messages, then nothing left
@@ -182,9 +179,6 @@ nat_t *nat;
 	nat_t *ipn;
 	u_char swp;
 	mb_t *m;
-#if	SOLARIS
-	mb_t *m1;
-#endif
 
 	/*
 	 * Wait until we've seen the end of the start messages and even then
Index: sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 ip_rcmd_pxy.c
--- sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c	27 Aug 2003 11:02:14 -0000	1.4
+++ sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c	17 Jul 2004 04:55:54 -0000
@@ -90,9 +90,6 @@ nat_t *nat;
 	u_short sp;
 	nat_t *ipn;
 	mb_t *m;
-#if	SOLARIS
-	mb_t *m1;
-#endif
 
 	tcp = (tcphdr_t *)fin->fin_dp;
 
Index: sys/contrib/ipfilter/netinet/ip_state.c
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_state.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 ip_state.c
--- sys/contrib/ipfilter/netinet/ip_state.c	12 Feb 2004 22:35:47 -0000	1.6
+++ sys/contrib/ipfilter/netinet/ip_state.c	17 Jul 2004 05:48:16 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_state.c   1.8 6/5/96 (C) 1993-2000 Darren Reed
  * @(#)$Id: ip_state.c,v 2.30.2.74 2002/07/27 15:58:10 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_state.c,v 1.21.2.5 2003/03/01 03:55:54 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_state.c,v 1.21.2.6 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_state.c,v 1.6 2004/02/12 22:35:47 joerg Exp $
  */
 
@@ -925,7 +925,8 @@ tcphdr_t *tcp;
 		fdata->td_wscale = wscale;
 	else if (wscale == -2)
 		fdata->td_wscale = tdata->td_wscale = 0;
-	win <<= fdata->td_wscale;
+	if (!(tcp->th_flags & TH_SYN))
+		win <<= fdata->td_wscale;
 
 	if ((fdata->td_end == 0) &&
 	    (!is->is_fsm || ((tcp->th_flags & TH_OPENING) == TH_OPENING))) {
@@ -959,14 +960,15 @@ tcphdr_t *tcp;
 	    (SEQ_GE(seq, fdata->td_end - maxwin)) &&
 /* XXX what about big packets */
 #define MAXACKWINDOW 66000
-	    (ackskew >= -MAXACKWINDOW) &&
-	    (ackskew <= MAXACKWINDOW)) {
-		/* if ackskew < 0 then this should be due to fragented
+	    (-ackskew <= (MAXACKWINDOW << tdata->td_wscale)) &&
+	    ( ackskew <= (MAXACKWINDOW << tdata->td_wscale))) {
+
+		/* 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.
 		 * We do know the total length from the fragment cache though.
 		 * Note however that there might be more sessions with
-		 * exactly the same source and destination paramters in the
+		 * exactly the same source and destination parameters in the
 		 * state cache (and source and destination is the only stuff
 		 * that is saved in the fragment cache). Note further that
 		 * some TCP connections in the state cache are hashed with
@@ -1212,6 +1214,10 @@ fr_info_t *fin;
 
 	oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN);
 	ohlen = oip->ip_hl << 2;
+	/*
+	 * Check if the at least the old IP header (with options) and
+	 * 8 bytes of payload is present.
+	 */
 	if (fin->fin_plen < ICMPERR_MAXPKTLEN + ohlen - sizeof(*oip))
 		return NULL;
 
@@ -1228,7 +1234,7 @@ fr_info_t *fin;
 	 * may be too big to be in this buffer but not so big that it's
 	 * outside the ICMP packet, leading to TCP deref's causing problems.
 	 * This is possible because we don't know how big oip_hl is when we
-	 * do the pullup early in fr_check() and thus can't gaurantee it is
+	 * do the pullup early in fr_check() and thus can't guarantee it is
 	 * all here now.
 	 */
 #ifdef  _KERNEL
@@ -1255,9 +1261,43 @@ fr_info_t *fin;
 	bzero((char *)&src, sizeof(src));
 	bzero((char *)&dst, sizeof(dst));
 	bzero((char *)&ofin, sizeof(ofin));
+	/*
+	 * We make an fin entry to be able to feed it to
+	 * matchsrcdst.  Note that not all fields are encessary
+	 * but this is the cleanest way. Note further that we
+	 * fill in fin_mp such that if someone uses it we'll get
+	 * a kernel panic. fr_matchsrcdst does not use this.
+	 */
 	ofin.fin_ifp = fin->fin_ifp;
 	ofin.fin_out = !fin->fin_out;
+	ofin.fin_mp = NULL;
 	ofin.fin_v = 4;
+	/*
+	 * watch out here, as ip is in host order and oip in network
+	 * order. Any change we make must be undone afterwards, like
+	 * oip->ip_off - it is still in network byte order so fix it.
+	 */
+	savelen = oip->ip_len;
+	oip->ip_len = len;
+	oip->ip_off = ntohs(oip->ip_off);
+	(void) fr_makefrip(ohlen, oip, &ofin);
+	/*
+	 * Reset the short flag here because in fr_matchsrcdst() the flags
+	 * for the current packet (fin_fl) are compared against * those for
+	 * the existing session.
+	 */
+	ofin.fin_fl &= ~FI_SHORT;
+
+	/*
+	 * Put old values of ip_len and ip_off back as we don't know
+	 * if we have to forward the packet (or process it again.
+	 */
+	oip->ip_len = savelen;
+	oip->ip_off = htons(oip->ip_off);
+
+#if SOLARIS
+	ofin.fin_qfm = NULL;
+#endif
 	fr = NULL;
 
 	switch (oip->ip_p)
@@ -1266,7 +1306,7 @@ fr_info_t *fin;
 		icmp = (icmphdr_t *)((char *)oip + ohlen);
 
 		/*
-		 * a ICMP error can only be generated as a result of an
+		 * an ICMP error can only be generated as a result of an
 		 * ICMP query, not as the response on an ICMP error
 		 *
 		 * XXX theoretically ICMP_ECHOREP and the other reply's are
@@ -1290,18 +1330,15 @@ fr_info_t *fin;
 		hv += icmp->icmp_seq;
 		hv %= fr_statesize;
 
-		savelen = oip->ip_len;
-		oip->ip_len = len;
-		fr_makefrip(ohlen, oip, &ofin);
-		oip->ip_len = savelen;
-
 		READ_ENTER(&ipf_state);
 		for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
 			if ((is->is_p == pr) && (is->is_v == 4) &&
+			    (is->is_icmppkts < is->is_pkts) &&
 			    fr_matchsrcdst(is, src, dst, &ofin, NULL) &&
-			    fr_matchicmpqueryreply(is->is_v, is, icmp, fin->fin_rev)) {
+			    fr_matchicmpqueryreply(is->is_v, is, icmp,
+						   fin->fin_rev)) {
 				ips_stats.iss_hits++;
-				is->is_pkts++;
+				is->is_icmppkts++;
 				is->is_bytes += ip->ip_len;
 				fr = is->is_rule;
 				break;
@@ -1330,20 +1367,7 @@ fr_info_t *fin;
 	hv += dport;
 	hv += sport;
 	hv %= fr_statesize;
-	/*
-	 * we make an fin entry to be able to feed it to
-	 * matchsrcdst note that not all fields are encessary
-	 * but this is the cleanest way. Note further we fill
-	 * in fin_mp such that if someone uses it we'll get
-	 * a kernel panic. fr_matchsrcdst does not use this.
-	 *
-	 * watch out here, as ip is in host order and oip in network
-	 * order. Any change we make must be undone afterwards.
-	 */
-	savelen = oip->ip_len;
-	oip->ip_len = len;
-	fr_makefrip(ohlen, oip, &ofin);
-	oip->ip_len = savelen;
+
 	READ_ENTER(&ipf_state);
 	for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
 		/*
@@ -1351,13 +1375,16 @@ fr_info_t *fin;
 		 * encapsulated packet was allowed through the
 		 * other way around. Note that the minimal amount
 		 * of info present does not allow for checking against
-		 * tcp internals such as seq and ack numbers.
+		 * tcp internals such as seq and ack numbers.  Only the
+		 * ports are known to be present and can be even if the
+		 * short flag is set.
 		 */
 		if ((is->is_p == pr) && (is->is_v == 4) &&
+		    (is->is_icmppkts < is->is_pkts) &&
 		    fr_matchsrcdst(is, src, dst, &ofin, tcp)) {
 			fr = is->is_rule;
 			ips_stats.iss_hits++;
-			is->is_pkts++;
+			is->is_icmppkts++;
 			is->is_bytes += fin->fin_plen;
 			/*
 			 * we deliberately do not touch the timeouts
@@ -2084,7 +2111,7 @@ u_int type;
 	int types[1];
 
 	ipsl.isl_type = type;
-	ipsl.isl_pkts = is->is_pkts;
+	ipsl.isl_pkts = is->is_pkts + is->is_icmppkts;
 	ipsl.isl_bytes = is->is_bytes;
 	ipsl.isl_src = is->is_src;
 	ipsl.isl_dst = is->is_dst;
@@ -2112,7 +2139,11 @@ u_int type;
 	sizes[0] = sizeof(ipsl);
 	types[0] = 0;
 
-	(void) ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1);
+	if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) {
+		ATOMIC_INCL(ips_stats.iss_logged);
+	} else {
+		ATOMIC_INCL(ips_stats.iss_logfail);
+	}
 }
 #endif
 
@@ -2162,12 +2193,30 @@ fr_info_t *fin;
 	bzero((char *)&ofin, sizeof(ofin));
 	ofin.fin_out = !fin->fin_out;
 	ofin.fin_ifp = fin->fin_ifp;
+	ofin.fin_mp = NULL;
 	ofin.fin_v = 6;
+#if SOLARIS
+	ofin.fin_qfm = NULL;
+#endif
+	/*
+	 * We make a fin entry to be able to feed it to
+	 * matchsrcdst. Note that not all fields are necessary
+	 * but this is the cleanest way. Note further we fill
+	 * in fin_mp such that if someone uses it we'll get
+	 * a kernel panic. fr_matchsrcdst does not use this.
+	 *
+	 * watch out here, as ip is in host order and oip in network
+	 * order. Any change we make must be undone afterwards.
+	 */
+	savelen = oip->ip6_plen;
+	oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
+	fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
+	oip->ip6_plen = savelen;
 
 	if (oip->ip6_nxt == IPPROTO_ICMPV6) {
 		oic = (struct icmp6_hdr *)(oip + 1);
 		/*
-		 * a ICMP error can only be generated as a result of an
+		 * an ICMP error can only be generated as a result of an
 		 * ICMP query, not as the response on an ICMP error
 		 *
 		 * XXX theoretically ICMP_ECHOREP and the other reply's are
@@ -2188,10 +2237,6 @@ fr_info_t *fin;
 		hv += oic->icmp6_seq;
 		hv %= fr_statesize;
 
-		oip->ip6_plen = ntohs(oip->ip6_plen);
-		fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
-		oip->ip6_plen = htons(oip->ip6_plen);
-
 		READ_ENTER(&ipf_state);
 		for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext)
 			if ((is->is_p == pr) &&
@@ -2235,20 +2280,7 @@ fr_info_t *fin;
 	hv += dport;
 	hv += sport;
 	hv %= fr_statesize;
-	/*
-	 * we make an fin entry to be able to feed it to
-	 * matchsrcdst note that not all fields are encessary
-	 * but this is the cleanest way. Note further we fill
-	 * in fin_mp such that if someone uses it we'll get
-	 * a kernel panic. fr_matchsrcdst does not use this.
-	 *
-	 * watch out here, as ip is in host order and oip in network
-	 * order. Any change we make must be undone afterwards.
-	 */
-	savelen = oip->ip6_plen;
-	oip->ip6_plen = ip->ip6_plen - sizeof(*ip) - ICMPERR_ICMPHLEN;
-	fr_makefrip(sizeof(*oip), (ip_t *)oip, &ofin);
-	oip->ip6_plen = savelen;
+
 	READ_ENTER(&ipf_state);
 	for (isp = &ips_table[hv]; (is = *isp); isp = &is->is_hnext) {
 		/*
Index: sys/contrib/ipfilter/netinet/ip_state.h
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ip_state.h,v
retrieving revision 1.3
diff -u -p -u -r1.3 ip_state.h
--- sys/contrib/ipfilter/netinet/ip_state.h	27 Aug 2003 11:02:14 -0000	1.3
+++ sys/contrib/ipfilter/netinet/ip_state.h	17 Jul 2004 05:48:36 -0000
@@ -5,7 +5,7 @@
  *
  * @(#)ip_state.h	1.3 1/12/96 (C) 1995 Darren Reed
  * $Id: ip_state.h,v 2.13.2.13 2002/06/27 14:40:29 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_state.h,v 1.10.2.4 2002/08/31 16:24:52 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_state.h,v 1.10.2.5 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_state.h,v 1.3 2003/08/27 11:02:14 rob Exp $
  */
 #ifndef	__IP_STATE_H__
@@ -64,6 +64,7 @@ typedef struct ipstate {
 	frentry_t	*is_rule;
 	U_QUAD_T	is_pkts;
 	U_QUAD_T	is_bytes;
+	U_QUAD_T	is_icmppkts;
 	union	i6addr	is_src;
 	union	i6addr	is_dst;
 	void	*is_ifp[4];
Index: sys/contrib/ipfilter/netinet/ipl.h
===================================================================
RCS file: /cvs/DragonFly/src/sys/contrib/ipfilter/netinet/ipl.h,v
retrieving revision 1.2
diff -u -p -u -r1.2 ipl.h
--- sys/contrib/ipfilter/netinet/ipl.h	17 Jun 2003 04:28:20 -0000	1.2
+++ sys/contrib/ipfilter/netinet/ipl.h	17 Jul 2004 05:49:09 -0000
@@ -5,13 +5,13 @@
  *
  * @(#)ipl.h	1.21 6/5/96
  * $Id: ipl.h,v 2.15.2.35 2002/08/28 13:00:50 darrenr Exp $
- * $FreeBSD: src/sys/contrib/ipfilter/netinet/ipl.h,v 1.14.2.5 2003/03/01 03:55:55 darrenr Exp $
+ * $FreeBSD: src/sys/contrib/ipfilter/netinet/ipl.h,v 1.14.2.6 2004/07/04 09:24:39 darrenr Exp $
  * $DragonFly: src/sys/contrib/ipfilter/netinet/ipl.h,v 1.2 2003/06/17 04:28:20 dillon Exp $
  */
 
 #ifndef	__IPL_H__
 #define	__IPL_H__
 
-#define	IPL_VERSION	"IP Filter: v3.4.31"
+#define	IPL_VERSION	"IP Filter: v3.4.35"
 
 #endif
Index: sys/net/ipfilter/Makefile
===================================================================
RCS file: /cvs/DragonFly/src/sys/net/ipfilter/Makefile,v
retrieving revision 1.2
diff -u -p -u -r1.2 Makefile
--- sys/net/ipfilter/Makefile	17 Jun 2003 04:28:44 -0000	1.2
+++ sys/net/ipfilter/Makefile	17 Jul 2004 06:08:31 -0000
@@ -6,6 +6,9 @@ KMOD=	ipl
 SRCS=	mlfk_ipl.c ip_nat.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \
 	ip_log.c ip_fil.c fil.c
 NOMAN=
+.if !defined(NOINET6)
+CFLAGS+= -DUSE_INET6
+.endif
 CFLAGS+= -DIPFILTER_LKM -DIPFILTER_LOG
 CFLAGS+=  -I${.CURDIR}/../../contrib/ipfilter
 #
