This patch affects both kernel and userland. Make sure you have both
kenel and userland sources before applying this patch.

Apply by doing:
	# cd /usr/src
	# patch -p0 < 001_ipf.patch

	now, build a kernel. Eg, for GENERIC:

	# cd sys/arch/i386/conf
	# config GENERIC
	# cd ../compile/GENERIC
	# make clean && make depend && make
	# cp /bsd /bsd.old
	# cp bsd /bsd

	Export headers to userland

	# cd /usr/src
	# make includes
	
	And now rebuild userland

	# cd /usr/src/sbin/ipf
	# make obj && make cleandir && make && make install
	# cd /usr/src/sbin/ipnat
	# make obj && make cleandir && make && make install
	# cd /usr/src/sbin/ipfstat
	# make obj && make cleandir && make && make install
	# cd /usr/src/usr.sbin/ipmon
	# make obj && make cleandir && make && make install
	# cd /usr/src/usr.sbin/ipftest
	# make obj && make cleandir && make && make install

Reboot to activate the new ipf. To check that all was successful, do:
	
	# ipf -V

You should see something like:

	ipf: IP Filter: v3.3.16 (184)
	Kernel: IP Filter: v3.3.16
	Running: yes
	Log Flags: 0 = none set
	Default: pass all, Logging: available
	Active list: 0

Index: sys/netinet/ipl.h
===================================================================
RCS file: /cvs/src/sys/netinet/ipl.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- sys/netinet/ipl.h	2000/05/10 20:40:53	1.10
+++ sys/netinet/ipl.h	2000/05/24 21:59:11	1.11
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ipl.h,v 1.10 2000/05/10 20:40:53 deraadt Exp $	*/
+/*	$OpenBSD: ipl.h,v 1.11 2000/05/24 21:59:11 kjell Exp $	*/
 
 /*
  * Copyright (C) 1993-1999 by Darren Reed.
@@ -13,6 +13,6 @@
 #ifndef	__IPL_H__
 #define	__IPL_H__
 
-#define	IPL_VERSION	"IP Filter: v3.3.14"
+#define	IPL_VERSION	"IP Filter: v3.3.16"
 
 #endif
Index: sys/netinet/fil.c
===================================================================
RCS file: /cvs/src/sys/netinet/fil.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- sys/netinet/fil.c	2000/05/10 20:40:52	1.24
+++ sys/netinet/fil.c	2000/05/24 21:59:10	1.25
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fil.c,v 1.24 2000/05/10 20:40:52 deraadt Exp $	*/
+/*	$OpenBSD: fil.c,v 1.25 2000/05/24 21:59:10 kjell Exp $	*/
 
 /*
  * Copyright (C) 1993-1998 by Darren Reed.
@@ -9,7 +9,7 @@
  */
 #if !defined(lint)
 static const char sccsid[] = "@(#)fil.c	1.36 6/5/96 (C) 1993-1996 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: fil.c,v 2.3.2.18 2000/04/25 16:21:09 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: fil.c,v 2.3.2.20 2000/05/22 06:57:42 darrenr Exp $";
 #endif
 
 #include <sys/errno.h>
@@ -99,9 +99,7 @@
 							  second; }
 # define	FR_VERBOSE(verb_pr)			verbose verb_pr
 # define	FR_DEBUG(verb_pr)			debug verb_pr
-# define	SEND_RESET(ip, qif, if, m, fin)		send_reset(ip, if)
 # define	IPLLOG(a, c, d, e)		ipllog()
-# define	FR_NEWAUTH(m, fi, ip, qif)	fr_newauth((mb_t *)m, fi, ip)
 #else /* #ifndef _KERNEL */
 # define	FR_IFVERBOSE(ex,second,verb_pr)	;
 # define	FR_IFDEBUG(ex,second,verb_pr)	;
@@ -111,23 +109,6 @@
 # if SOLARIS || defined(__sgi)
 extern	KRWLOCK_T	ipf_mutex, ipf_auth, ipf_nat;
 extern	kmutex_t	ipf_rw;
-# endif
-# if SOLARIS
-#  define	FR_NEWAUTH(m, fi, ip, qif)	fr_newauth((mb_t *)m, fi, \
-							   ip, qif)
-#  define	SEND_RESET(ip, qif, if, fin)	send_reset(fin, ip, qif)
-#  define	ICMP_ERROR(b, ip, t, c, if, dst) \
-			icmp_error(ip, t, c, if, dst)
-# else /* SOLARIS */
-#  define	FR_NEWAUTH(m, fi, ip, qif)	fr_newauth((mb_t *)m, fi, ip)
-#  ifdef linux
-#   define	SEND_RESET(ip, qif, if, fin)	send_reset(ip, ifp)
-#   define	ICMP_ERROR(b, ip, t, c, if, dst) 	icmp_send(b,t,c,0,if)
-#  else
-#   define	SEND_RESET(ip, qif, if, fin)	send_reset(fin, ip)
-#   define	ICMP_ERROR(b, ip, t, c, if, dst) \
-		send_icmp_err(ip, t, c, if, dst)
-#  endif /* linux */
 # endif /* SOLARIS || __sgi */
 #endif /* _KERNEL */
 
@@ -247,12 +228,17 @@
 		if (!off && (icmp->icmp_type == ICMP_ECHOREPLY ||
 		     icmp->icmp_type == ICMP_ECHO))
 			minicmpsz = ICMP_MINLEN;
+
 		if (!off && (icmp->icmp_type == ICMP_TSTAMP ||
 		     icmp->icmp_type == ICMP_TSTAMPREPLY))
-			minicmpsz = 20; /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + 3*timestamp(3*4) */
+			minicmpsz = 20;
+/* type(1) + code(1) + cksum(2) + id(2) + seq(2) + 3*timestamp(3*4) */
+
 		if (!off && (icmp->icmp_type == ICMP_MASKREQ ||
 		     icmp->icmp_type == ICMP_MASKREPLY))
-			minicmpsz = 12; /* type(1) + code(1) + cksum(2) + id(2) + seq(2) + mask(4) */
+			minicmpsz = 12;
+/* type(1) + code(1) + cksum(2) + id(2) + seq(2) + mask(4) */
+
 		if ((!(ip->ip_len >= hlen + minicmpsz) && !off) ||
 		    (off && off < sizeof(struct icmp)))
 			fi->fi_fl |= FI_SHORT;
@@ -632,6 +618,16 @@
 	 */
 	m->m_flags &= ~M_CANFASTFWD;
 #  endif /* M_CANFASTFWD */
+#  ifdef CSUM_DELAY_DATA
+	/*
+	 * disable delayed checksums.
+	 */
+	if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+		in_delayed_cksum(m);
+		m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+	}
+#  endif /* CSUM_DELAY_DATA */
+
 
 	if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ||
 	     ip->ip_p == IPPROTO_ICMP)) {
@@ -764,7 +760,7 @@
 		 * then pretend we've dropped it already.
 		 */
 		if ((pass & FR_AUTH))
-			if (FR_NEWAUTH(m, fin, ip, qif) != 0)
+			if (fr_newauth((mb_t *)m, fin, ip) != 0)
 #ifdef	_KERNEL
 				m = *mp = NULL;
 #else
@@ -894,17 +890,11 @@
 					dst = ip->ip_dst;
 				else
 					dst.s_addr = 0;
-# if SOLARIS
-				ICMP_ERROR(q, ip, ICMP_UNREACH, fin->fin_icode,
-					   qif, dst);
-# else
-				ICMP_ERROR(m, ip, ICMP_UNREACH, fin->fin_icode,
-					   ifp, dst);
-# endif
+				send_icmp_err(ip, ICMP_UNREACH, fin, dst);
 				ATOMIC_INC(frstats[0].fr_ret);
 			} else if (((pass & FR_RETMASK) == FR_RETRST) &&
 				   !(fin->fin_fi.fi_fl & FI_SHORT)) {
-				if (SEND_RESET(ip, qif, ifp, fin) == 0) {
+				if (send_reset(ip, fin) == 0) {
 					ATOMIC_INC(frstats[1].fr_ret);
 				}
 			}
@@ -1197,7 +1187,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)uipc_mbuf.c	8.2 (Berkeley) 1/4/94
- * $IPFilter: fil.c,v 2.3.2.18 2000/04/25 16:21:09 darrenr Exp $
+ * $IPFilter: fil.c,v 2.3.2.20 2000/05/22 06:57:42 darrenr Exp $
  */
 /*
  * Copy data from an mbuf chain starting "off" bytes from the beginning,
Index: sys/netinet/ip_auth.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_auth.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- sys/netinet/ip_auth.c	2000/05/01 06:16:47	1.13
+++ sys/netinet/ip_auth.c	2000/05/24 21:59:10	1.14
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_auth.c,v 1.13 2000/05/01 06:16:47 kjell Exp $	*/
+/*	$OpenBSD: ip_auth.c,v 1.14 2000/05/24 21:59:10 kjell Exp $	*/
 
 /*
  * Copyright (C) 1998 by Darren Reed & Guido van Rooij.
@@ -8,7 +8,7 @@
  * to the original author and the contributors.
  */
 #if !defined(lint)
-static const char rcsid[] = "@(#)$IPFilter: ip_auth.c,v 2.1.2.3 2000/04/25 16:21:12 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: ip_auth.c,v 2.1.2.4 2000/05/22 06:57:45 darrenr Exp $";
 #endif
 
 #include <sys/errno.h>
@@ -198,17 +198,14 @@
  * If we do, store it and wake up any user programs which are waiting to
  * hear about these events.
  */
-int fr_newauth(m, fin, ip
-#if defined(_KERNEL) && SOLARIS
-, qif)
-qif_t *qif;
-#else
-)
-#endif
+int fr_newauth(m, fin, ip)
 mb_t *m;
 fr_info_t *fin;
 ip_t *ip;
 {
+#if defined(_KERNEL) && SOLARIS
+	qif_t *qif = fin->fin_qif;
+#endif
 	int i;
 
 	WRITE_ENTER(&ipf_auth);
Index: sys/netinet/ip_auth.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_auth.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- sys/netinet/ip_auth.h	2000/03/13 23:40:17	1.7
+++ sys/netinet/ip_auth.h	2000/05/24 21:59:11	1.8
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_auth.h,v 1.7 2000/03/13 23:40:17 kjell Exp $	*/
+/*	$OpenBSD: ip_auth.h,v 1.8 2000/05/24 21:59:11 kjell Exp $	*/
 
 /*
  * Copyright (C) 1997-1998 by Darren Reed & Guido Van Rooij.
@@ -7,7 +7,7 @@
  * provided that this notice is preserved and due credit is given
  * to the original author and the contributors.
  *
- * $IPFilter: ip_auth.h,v 2.1 1999/08/04 17:29:54 darrenr Exp $
+ * $IPFilter: ip_auth.h,v 2.1.2.1 2000/05/22 06:57:47 darrenr Exp $
  *
  */
 #ifndef	__IP_AUTH_H__
@@ -56,11 +56,7 @@
 extern	void	fr_authexpire __P((void));
 extern	void	fr_authunload __P((void));
 extern	mb_t	*fr_authpkts[];
-#if defined(_KERNEL) && SOLARIS
-extern	int	fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *));
-#else
 extern	int	fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
-#endif
 #if defined(__NetBSD__) || defined(__OpenBSD__)
 extern	int	fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **));
 #else
Index: sys/netinet/ip_fil.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_fil.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- sys/netinet/ip_fil.h	2000/05/10 20:40:53	1.19
+++ sys/netinet/ip_fil.h	2000/05/24 21:59:11	1.20
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_fil.h,v 1.19 2000/05/10 20:40:53 deraadt Exp $	*/
+/*	$OpenBSD: ip_fil.h,v 1.20 2000/05/24 21:59:11 kjell Exp $	*/
 
 /*
  * Copyright (C) 1993-1998 by Darren Reed.
@@ -8,7 +8,7 @@
  * to the original author and the contributors.
  *
  * @(#)ip_fil.h	1.35 6/5/96
- * $IPFilter: ip_fil.h,v 2.3.2.9 2000/03/08 11:43:30 darrenr Exp $
+ * $IPFilter: ip_fil.h,v 2.3.2.11 2000/05/22 06:57:50 darrenr Exp $
  */
 
 #ifndef	__IP_FIL_H__
@@ -459,11 +459,12 @@
 extern	int	ipflog_read __P((minor_t, struct uio *));
 extern	int	ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
 extern	int	ipllog __P((int, fr_info_t *, void **, size_t *, int *, int));
+extern	int	send_icmp_err __P((ip_t *, int, fr_info_t *, struct in_addr));
+extern	int	send_reset __P((ip_t *, fr_info_t *));
 # if	SOLARIS
 extern	int	fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **));
 extern	int	(*fr_checkp) __P((ip_t *, int, void *,
 				  int, qif_t *, mb_t **));
-extern	int	icmp_error __P((ip_t *, int, int, qif_t *, struct in_addr));
 #  if SOLARIS2 >= 7
 extern	int	iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
 #  else
@@ -472,7 +473,6 @@
 extern	int	iplopen __P((dev_t *, int, int, cred_t *));
 extern	int	iplclose __P((dev_t, int, int, cred_t *));
 extern	int	ipfsync __P((void));
-extern	int	send_reset __P((fr_info_t *, ip_t *, qif_t *));
 extern	int	ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **,
 				   fr_info_t *, frdest_t *));
 extern	void	copyin_mblk __P((mblk_t *, size_t, size_t, char *));
@@ -485,12 +485,6 @@
 # else /* SOLARIS */
 extern	int	fr_check __P((ip_t *, int, void *, int, mb_t **));
 extern	int	(*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
-#  ifdef	linux
-extern	int	send_reset __P((tcpiphdr_t *, struct ifnet *));
-#  else
-extern	int	send_reset __P((fr_info_t *, struct ip *));
-extern	int	send_icmp_err __P((ip_t *, int, int, void *, struct in_addr));
-#  endif
 extern	int	ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
 extern	size_t	mbufchainlen __P((mb_t *));
 #  ifdef	__sgi
Index: sys/netinet/ip_fil.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_fil.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- sys/netinet/ip_fil.c	2000/05/01 06:16:47	1.34
+++ sys/netinet/ip_fil.c	2000/05/24 21:59:11	1.35
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_fil.c,v 1.34 2000/05/01 06:16:47 kjell Exp $	*/
+/*	$OpenBSD: ip_fil.c,v 1.35 2000/05/24 21:59:11 kjell Exp $	*/
 
 /*
  * Copyright (C) 1993-1998 by Darren Reed.
@@ -9,7 +9,7 @@
  */
 #if !defined(lint)
 static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-1995 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: ip_fil.c,v 2.4.2.20 2000/04/18 16:31:27 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: ip_fil.c,v 2.4.2.21 2000/05/22 06:57:47 darrenr Exp $";
 #endif
 
 #ifndef	SOLARIS
@@ -144,7 +144,7 @@
 #endif
 #ifdef	_KERNEL
 static	int	(*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
-static	int	send_ip __P((struct mbuf *, ip_t *));
+static	int	send_ip __P((ip_t *, fr_info_t *, struct mbuf *));
 # ifdef	__sgi
 extern  kmutex_t        ipf_rw;
 extern	KRWLOCK_T	ipf_mutex;
@@ -914,12 +914,11 @@
  * send_reset - this could conceivably be a call to tcp_respond(), but that
  * requires a large amount of setting up and isn't any more efficient.
  */
-int send_reset(fin, oip)
-fr_info_t *fin;
+int send_reset(oip, fin)
 struct ip *oip;
+fr_info_t *fin;
 {
 	struct tcphdr *tcp, *tcp2;
-	struct tcpiphdr *tp;
 	struct mbuf *m;
 	int tlen = 0;
 	ip_t *ip;
@@ -942,13 +941,12 @@
 	m->m_len = sizeof(*tcp2) + sizeof(*ip);
 # if	BSD >= 199306
 	m->m_data += max_linkhdr;
-	m->m_pkthdr.len = m->m_len;
+	m->m_pkthdr.len = sizeof(*tcp2) + sizeof(*ip);
 	m->m_pkthdr.rcvif = (struct ifnet *)0;
 # endif
-	bzero(mtod(m, char *), sizeof(struct tcpiphdr));
 	ip = mtod(m, struct ip *);
-	tp = mtod(m, struct tcpiphdr *);
-	tcp2 = (struct tcphdr *)((char *)ip + sizeof(*ip));
+	bzero((char *)ip, sizeof(*tcp2) + sizeof(*ip));
+	tcp2 = (struct tcphdr *)(ip + 1);
 
 	ip->ip_src.s_addr = oip->ip_dst.s_addr;
 	ip->ip_dst.s_addr = oip->ip_src.s_addr;
@@ -959,27 +957,25 @@
 	tcp2->th_ack = htonl(tcp2->th_ack);
 	tcp2->th_off = sizeof(*tcp2) >> 2;
 	tcp2->th_flags = TH_RST|TH_ACK;
-	tp->ti_pr = oip->ip_p;
-	tp->ti_len = htons(sizeof(struct tcphdr));
+	ip->ip_p = IPPROTO_TCP;
+	ip->ip_len = htons(sizeof(struct tcphdr));
 	tcp2->th_sum = in_cksum(m, sizeof(*ip) + sizeof(*tcp2));
 
+	ip->ip_id = oip->ip_id;
 	ip->ip_tos = oip->ip_tos;
-	ip->ip_p = oip->ip_p;
 	ip->ip_len = sizeof(*ip) + sizeof(*tcp2);
 
-	return send_ip(m, ip);
+	return send_ip(ip, fin, m);
 }
 
 
-static int send_ip(m, ip)
+static int send_ip(ip, fin, m)
+fr_info_t *fin;
 struct mbuf *m;
 ip_t *ip;
 {
-# if (defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) || \
-     (defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802))
-	struct route ro;
-# endif
-
+	ip->ip_v = IPVERSION;
+	ip->ip_hl = (sizeof(*ip) >> 2);
 # if (BSD < 199306) || defined(__sgi)
 	ip->ip_ttl = tcp_ttl;
 # else
@@ -988,44 +984,35 @@
 
 # ifdef	IPSEC
 	m->m_pkthdr.rcvif = NULL;
-# endif
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
-	{
-	int err;
-
-	bzero((char *)&ro, sizeof(ro));
-	err = ip_output(m, (struct mbuf *)0, &ro, 0, 0);
-	if (ro.ro_rt)
-		RTFREE(ro.ro_rt);
-	return err;
-	}
-# else
-	/*
-	 * extra 0 in case of multicast
-	 */
-#  if _BSDI_VERSION >= 199802
-	return ip_output(m, (struct mbuf *)0, &ro, 0, 0, NULL);
-#  else
-#   if	defined(__OpenBSD__)
-	return ip_output(m, (struct mbuf *)0, 0, 0, 0, NULL);
-#   else
-	return ip_output(m, (struct mbuf *)0, 0, 0, 0);
-#   endif
-#  endif
 # endif
+	return ipfr_fastroute(m, fin, NULL);
 }
 
 
-int send_icmp_err(oip, type, code, ifp, dst)
+int send_icmp_err(oip, type, fin, dst)
 ip_t *oip;
-int type, code;
-void *ifp;
+int type;
+fr_info_t *fin;
 struct in_addr dst;
 {
 	struct icmp *icmp;
 	struct mbuf *m;
 	ip_t *nip;
+	int code;
 
+	if ((oip->ip_p == IPPROTO_ICMP) && !(fin->fin_fi.fi_fl & FI_SHORT))
+		switch (ntohs(fin->fin_data[0]) >> 8)
+		{
+		case ICMP_ECHO :
+		case ICMP_TSTAMP :
+		case ICMP_IREQ :
+		case ICMP_MASKREQ :
+			break;
+		default :
+			return 0;
+		}
+
+	code = fin->fin_icode;
 # if	(BSD < 199306) || defined(__sgi)
 	m = m_get(M_DONTWAIT, MT_HEADER);
 # else
@@ -1044,8 +1031,6 @@
 	nip = mtod(m, ip_t *);
 	icmp = (struct icmp *)(nip + 1);
 
-	nip->ip_v = IPVERSION;
-	nip->ip_hl = (sizeof(*nip) >> 2);
 	nip->ip_p = IPPROTO_ICMP;
 	nip->ip_id = oip->ip_id;
 	nip->ip_sum = 0;
@@ -1053,7 +1038,7 @@
 	nip->ip_tos = oip->ip_tos;
 	nip->ip_len = sizeof(*nip) + sizeof(*icmp) + 8;
 	if (dst.s_addr == 0) {
-		if (fr_ifpaddr(ifp, &dst) == -1)
+		if (fr_ifpaddr(fin->fin_ifp, &dst) == -1)
 			return -1;
 	}
 	nip->ip_src = dst;
@@ -1077,7 +1062,7 @@
 	}
 # endif
 	icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8);
-	return send_ip(m, nip);
+	return send_ip(nip, fin, m);
 }
 
 
@@ -1119,10 +1104,10 @@
 	register struct ip *ip, *mhip;
 	register struct mbuf *m = m0;
 	register struct route *ro;
-	int len, off, error = 0, hlen;
+	int len, off, error = 0, hlen, code;
+	struct ifnet *ifp, *sifp;
 	struct sockaddr_in *dst;
 	struct route iproute;
-	struct ifnet *ifp;
 	frentry_t *fr;
 
 	hlen = fin->fin_hlen;
@@ -1136,7 +1121,13 @@
 	dst->sin_family = AF_INET;
 
 	fr = fin->fin_fr;
-	ifp = fdp->fd_ifp;
+	if (fdp)
+		ifp = fdp->fd_ifp;
+	else {
+		ifp = fin->fin_ifp;
+		dst->sin_addr = ip->ip_dst;
+	}
+
 	/*
 	 * In case we're here due to "to <if>" being used with "keep state",
 	 * check that we're going in the correct direction.
@@ -1145,9 +1136,10 @@
 		if ((ifp != NULL) && (fdp == &fr->fr_tif))
 			return -1;
 		dst->sin_addr = ip->ip_dst;
-	} else
+	} else if (fdp)
 		dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
-# ifdef	__bsdi__
+
+# if BSD >= 199306
 	dst->sin_len = sizeof(*dst);
 # endif
 # if	(BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
@@ -1161,7 +1153,7 @@
 	rtalloc(ro);
 # endif
 	if (!ifp) {
-		if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) {
+		if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
 			error = -2;
 			goto bad;
 		}
@@ -1191,8 +1183,10 @@
 			ATOMIC_INC(frstats[1].fr_acct);
 		}
 		fin->fin_fr = NULL;
-		(void) fr_checkstate(ip, fin);
-		(void) ip_natout(ip, fin);
+		if (!fr || !(fr->fr_flags & FR_RETMASK)) {
+			(void) fr_checkstate(ip, fin);
+			(void) ip_natout(ip, fin);
+		}
 	} else
 		ip->ip_sum = 0;
 	/*
@@ -1316,9 +1310,15 @@
 		RTFREE(ro->ro_rt);
 	return 0;
 bad:
-	if (error == EMSGSIZE)
-		(void) send_icmp_err(ip, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
-				     ifp, ip->ip_dst);
+	if (error == EMSGSIZE) {
+		sifp = fin->fin_ifp;
+		fin->fin_ifp = ifp;
+		code = fin->fin_icode;
+		fin->fin_icode = ICMP_UNREACH_NEEDFRAG;
+		(void) send_icmp_err(ip, ICMP_UNREACH, fin, ip->ip_dst);
+		fin->fin_ifp = sifp;
+		fin->fin_icode = code;
+	}
 	m_freem(m);
 	goto done;
 }
Index: sys/netinet/ip_nat.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_nat.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- sys/netinet/ip_nat.c	2000/05/10 20:40:53	1.31
+++ sys/netinet/ip_nat.c	2000/05/24 21:59:11	1.32
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_nat.c,v 1.31 2000/05/10 20:40:53 deraadt Exp $	*/
+/*	$OpenBSD: ip_nat.c,v 1.32 2000/05/24 21:59:11 kjell Exp $	*/
 
 /*
  * Copyright (C) 1995-1998 by Darren Reed.
@@ -11,7 +11,7 @@
  */
 #if !defined(lint)
 static const char sccsid[] = "@(#)ip_nat.c	1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: ip_nat.c,v 2.2.2.15 2000/04/25 16:21:13 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: ip_nat.c,v 2.2.2.18 2000/05/19 15:52:29 darrenr Exp $";
 #endif
 
 #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@@ -326,11 +326,17 @@
 	{
 #ifdef  IPFILTER_LOG
 	case SIOCIPFFB :
+	{
+		int tmp;
+
 		if (!(mode & FWRITE))
 			error = EPERM;
-		else
-			*(int *)data = ipflog_clear(IPL_LOGNAT);
+		else {
+			tmp = ipflog_clear(IPL_LOGNAT);
+			IWCOPY((char *)&tmp, (char *)data, sizeof(tmp));
+		}
 		break;
+	}
 #endif
 	case SIOCADNAT :
 		if (!(mode & FWRITE)) {
@@ -800,7 +806,7 @@
 					port += MAPBLK_MINPORT;
 					port = htons(port);
 				}
-			} else if (!np->in_nip &&
+			} else if (!np->in_outip &&
 				   (np->in_outmsk == 0xffffffff)) {
 				/*
 				 * 0/32 - use the interface's IP address.
@@ -811,7 +817,7 @@
 					return NULL;
 				}
 				in.s_addr = ntohl(in.s_addr);
-			} else if (!np->in_nip && !np->in_outmsk) {
+			} else if (!np->in_outip && !np->in_outmsk) {
 				/*
 				 * 0/0 - use the original source address/port.
 				 */
Index: sys/netinet/ip_state.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_state.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- sys/netinet/ip_state.c	2000/05/01 06:16:47	1.21
+++ sys/netinet/ip_state.c	2000/05/24 21:59:11	1.22
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_state.c,v 1.21 2000/05/01 06:16:47 kjell Exp $	*/
+/*	$OpenBSD: ip_state.c,v 1.22 2000/05/24 21:59:11 kjell Exp $	*/
 
 /*
  * Copyright (C) 1995-1998 by Darren Reed.
@@ -9,7 +9,7 @@
  */
 #if !defined(lint)
 static const char sccsid[] = "@(#)ip_state.c	1.8 6/5/96 (C) 1993-1995 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: ip_state.c,v 2.3.2.23 2000/04/25 16:21:16 darrenr Exp $";
+static const char rcsid[] = "@(#)$IPFilter: ip_state.c,v 2.3.2.25 2000/05/22 06:57:53 darrenr Exp $";
 #endif
 
 #include <sys/errno.h>
@@ -232,8 +232,12 @@
 	case SIOCIPFFB :
 		if (!(mode & FWRITE))
 			error = EPERM;
-		else
-			*(int *)data = ipflog_clear(IPL_LOGSTATE);
+		else {
+			int tmp;
+
+			tmp = ipflog_clear(IPL_LOGSTATE);
+			IWCOPY((char *)&tmp, data, sizeof(tmp));
+		}
 		break;
 #endif
 	case SIOCGIPST :
@@ -314,6 +318,8 @@
 	    {
 		register tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
 
+		if (tcp->th_flags & TH_RST)
+			return NULL;
 		/*
 		 * The endian of the ports doesn't matter, but the ack and
 		 * sequence numbers do as we do mathematics on them later.
Index: sbin/ipf/HISTORY
===================================================================
RCS file: /cvs/src/sbin/ipf/HISTORY,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- sbin/ipf/HISTORY	2000/05/01 06:16:48	1.7
+++ sbin/ipf/HISTORY	2000/05/24 21:59:11	1.8
@@ -1,4 +1,4 @@
-#	$OpenBSD: HISTORY,v 1.7 2000/05/01 06:16:48 kjell Exp $
+#	$OpenBSD: HISTORY,v 1.8 2000/05/24 21:59:11 kjell Exp $
 #
 # NOTE: Quite a few patches and suggestions come from other sources, to whom
 #       I'm greatly indebted, even if no names are mentioned.
@@ -21,6 +21,27 @@
 # and especially those who have found the time to port IP Filter to new
 # platforms.
 #
+3.3.16	23/05/2000 - Released
+
+don't add TCP state if it is an RST packet and (attempt) to send out
+RST/ICMP packets in a manner that bypasses IP Filter.
+
+add patch to work with 4.0_STABLE delayed checksums
+
+3.3.15	20/05/2000 - Released
+
+fix destination being 0/32 in NAT map rules
+
+fix ipmon -F
+
+3.3.14	10/05/2000 - Released
+
+Fix bug in dealing with "hlen == 1 and opt > 1" - Itojun
+
+ignore previous NAT mappings for 0/0 and 0/32 rules
+
+struct friostat got too big for SunOS4
+
 3.3.13	26/04/2000 - Released
 
 Fix parsing of "range" with "portmap"
