Apply by doing:
	cd /usr/src
	patch -p0 < 027_ipf-frag.patch
And then rebuild your kernel.

Index: sys/netinet/ip_frag.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_frag.c,v
retrieving revision 1.19
diff -u -r1.19 ip_frag.c
--- sys/netinet/ip_frag.c	2000/09/07 19:45:04	1.19
+++ sys/netinet/ip_frag.c	2001/04/23 21:35:14
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_frag.c,v 1.19 2000/09/07 19:45:04 art Exp $	*/
+/*	$OpenBSD: ip_frag.c,v 1.19.2.1 2001/04/18 01:02:44 jason Exp $	*/
 
 /*
  * Copyright (C) 1993-1998 by Darren Reed.
@@ -141,11 +141,14 @@
 ipfr_t *table[];
 {
 	ipfr_t	**fp, *fra, frag;
-	u_int	idx;
+	u_int	idx, off;
 
 	if (ipfr_inuse >= IPFT_SIZE)
 		return NULL;
 
+	if (!(fin->fin_fi.fi_fl & FI_FRAG))
+		return NULL;
+
 	frag.ipfr_p = ip->ip_p;
 	idx = ip->ip_p;
 	frag.ipfr_id = ip->ip_id;
@@ -198,7 +201,10 @@
 	/*
 	 * Compute the offset of the expected start of the next packet.
 	 */
-	fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
+	off = ip->ip_off & IP_OFFMASK;
+	if (!off)
+		fra->ipfr_seen0 = 1;
+	fra->ipfr_off = off + (fin->fin_dlen >> 3);
 	ATOMIC_INC(ipfr_stats.ifs_new);
 	ATOMIC_INC(ipfr_inuse);
 	return fra;
@@ -250,6 +256,9 @@
 	ipfr_t	*f, frag;
 	u_int	idx;
 
+	if (!(fin->fin_fi.fi_fl & FI_FRAG))
+		return NULL;
+
 	/*
 	 * For fragments, we record protocol, packet id, TOS and both IP#'s
 	 * (these should all be the same for all fragments of a packet).
@@ -276,6 +285,19 @@
 			  IPFR_CMPSZ)) {
 			u_short	atoff, off;
 
+			/*
+			 * XXX - We really need to be guarding against the
+			 * retransmission of (src,dst,id,offset-range) here
+			 * because a fragmented packet is never resent with
+			 * the same IP ID#.
+			 */
+			off = ip->ip_off & IP_OFFMASK;
+			if (f->ipfr_seen0) {
+				if (!off || (fin->fin_fi.fi_fl & FI_SHORT))
+					continue;
+			} else if (!off)
+				f->ipfr_seen0 = 1;
+
 			if (f != table[idx]) {
 				/*
 				 * move fragment info. to the top of the list
@@ -288,7 +310,6 @@
 				f->ipfr_prev = NULL;
 				table[idx] = f;
 			}
-			off = ip->ip_off & IP_OFFMASK;
 			atoff = off + (fin->fin_dlen >> 3);
 			/*
 			 * If we've follwed the fragments, and this is the
Index: sys/netinet/ip_frag.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_frag.h,v
retrieving revision 1.12
diff -u -r1.12 ip_frag.h
--- sys/netinet/ip_frag.h	2000/03/13 23:40:18	1.12
+++ sys/netinet/ip_frag.h	2001/04/23 21:35:14
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_frag.h,v 1.12 2000/03/13 23:40:18 kjell Exp $	*/
+/*	$OpenBSD: ip_frag.h,v 1.12.4.1 2001/04/18 01:02:44 jason Exp $	*/
 
 /*
  * Copyright (C) 1993-1998 by Darren Reed.
@@ -25,7 +25,8 @@
 	u_char	ipfr_p;
 	u_char	ipfr_tos;
 	u_short	ipfr_off;
-	u_short	ipfr_ttl;
+	u_char	ipfr_ttl;
+	u_char	ipfr_seen0;
 	frentry_t *ipfr_rule;
 } ipfr_t;
 
@@ -41,7 +42,8 @@
 	struct	ipfr	**ifs_nattab;
 } ipfrstat_t;
 
-#define	IPFR_CMPSZ	(4 + 4 + 2 + 1 + 1)
+#define	IPFR_CMPSZ	(offsetof(ipfr_t, ipfr_off) - \
+			offsetof(ipfr_t, ipfr_src))
 
 extern	int	fr_ipfrttl;
 extern	ipfrstat_t	*ipfr_fragstats __P((void));
Index: sys/netinet/ip_state.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_state.c,v
retrieving revision 1.23
diff -u -r1.23 ip_state.c
--- sys/netinet/ip_state.c	2000/08/10 05:50:26	1.23
+++ sys/netinet/ip_state.c	2001/04/23 21:35:15
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_state.c,v 1.23 2000/08/10 05:50:26 kjell Exp $	*/
+/*	$OpenBSD: ip_state.c,v 1.23.2.1 2001/04/18 01:02:45 jason Exp $	*/
 
 /*
  * Copyright (C) 1995-1998 by Darren Reed.
@@ -429,7 +429,7 @@
 #endif
 	RWLOCK_EXIT(&ipf_state);
 	fin->fin_rev = (is->is_dst.s_addr != ip->ip_dst.s_addr);
-	if (fin->fin_fi.fi_fl & FI_FRAG)
+	if ((fin->fin_fi.fi_fl & FI_FRAG) && (pass & FR_KEEPFRAG))
 		ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
 	return is;
 }
@@ -1023,7 +1023,7 @@
 		fr_delstate(is);
 #endif
 	RWLOCK_EXIT(&ipf_state);
-	if (fin->fin_fi.fi_fl & FI_FRAG)
+	if ((fin->fin_fi.fi_fl & FI_FRAG) && (pass & FR_KEEPFRAG))
 		ipfr_newfrag(ip, fin, pass ^ FR_KEEPSTATE);
 	return fr;
 }

