This is version two of this patch.

To apply:
    cd /usr/src/sys/netinet
    patch -p0 < maxqueue.patch

Recompile your kernel.

Index: in.h
===================================================================
RCS file: /cvs/src/sys/netinet/in.h,v
retrieving revision 1.12
diff -u -r1.12 in.h
--- in.h	1998/02/11 03:58:31	1.12
+++ in.h	1999/02/18 04:33:56
@@ -1,4 +1,4 @@
-/*	$OpenBSD: in.h,v 1.12 1998/02/11 03:58:31 deraadt Exp $	*/
+/*	$OpenBSD: in.h,v 1.18 1999/02/17 23:51:12 deraadt Exp $	*/
 /*	$NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $	*/
 
 /*
@@ -325,7 +325,8 @@
 #define IPCTL_IPPORT_LASTAUTO	8
 #define IPCTL_IPPORT_HIFIRSTAUTO 9
 #define IPCTL_IPPORT_HILASTAUTO	10
-#define	IPCTL_MAXID		11
+#define	IPCTL_IPPORT_MAXQUEUE	11
+#define	IPCTL_MAXID		12
 
 #define	IPCTL_NAMES { \
 	{ 0, 0 }, \
@@ -339,6 +340,7 @@
 	{ "portlast", CTLTYPE_INT }, \
 	{ "porthifirst", CTLTYPE_INT }, \
 	{ "porthilast", CTLTYPE_INT }, \
+	{ "maxqueue", CTLTYPE_INT }, \
 }
 
 #ifndef _KERNEL
Index: ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.30
diff -u -r1.30 ip_input.c
--- ip_input.c	1998/02/14 18:50:36	1.30
+++ ip_input.c	1999/02/18 04:33:56
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_input.c,v 1.30 1998/02/14 18:50:36 mickey Exp $	*/
+/*	$OpenBSD: ip_input.c,v 1.35 1999/02/17 23:51:12 deraadt Exp $	*/
 /*	$NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $	*/
 
 /*
@@ -99,6 +99,10 @@
 u_char  ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT;
 u_char  ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT;
 
+/* Keep track of memory used for reassembly */
+int	ip_maxqueue = 300;
+int	ip_frags = 0;
+
 /* from in_pcb.c */
 extern int ipport_firstauto;
 extern int ipport_lastauto;
@@ -117,7 +121,6 @@
 			  struct mbuf **));
 #endif
 
-
 char *
 inet_ntoa(ina)
 	struct in_addr ina;
@@ -279,10 +282,10 @@
 	}
 
 #if defined(IPFILTER) || defined(IPFILTER_LKM)
-       /*
-	* Check if we want to allow this packet to be processed.
-	* Consider it to be bad if not.
-	*/
+	 /*
+	 * Check if we want to allow this packet to be processed.
+	 * Consider it to be bad if not.
+	 */
 	{
 		struct mbuf *m0 = m;
 		if (fr_checkp && (*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m0))
@@ -433,12 +436,19 @@
 		 */
 		if (mff || ip->ip_off) {
 			ipstat.ips_fragments++;
+			if (ip_frags + 1 > ip_maxqueue) {
+				ip_flush();
+				ipstat.ips_rcvmemdrop++;
+				goto bad;
+			}
+			    
 			MALLOC(ipqe, struct ipqent *, sizeof (struct ipqent),
 			    M_IPQ, M_NOWAIT);
 			if (ipqe == NULL) {
 				ipstat.ips_rcvmemdrop++;
 				goto bad;
 			}
+			ip_frags++;
 			ipqe->ipqe_mff = mff;
 			ipqe->ipqe_ip = ip;
 			ip = ip_reass(ipqe, fp);
@@ -580,6 +590,7 @@
 		m_freem(dtom(q->ipqe_ip));
 		LIST_REMOVE(q, ipqe_q);
 		FREE(q, M_IPQ);
+		ip_frags--;
 	}
 
 insert:
@@ -619,10 +630,12 @@
 	m_cat(m, t);
 	nq = q->ipqe_q.le_next;
 	FREE(q, M_IPQ);
+	ip_frags--;
 	for (q = nq; q != NULL; q = nq) {
 		t = dtom(q->ipqe_ip);
 		nq = q->ipqe_q.le_next;
 		FREE(q, M_IPQ);
+		ip_frags--;
 		m_cat(m, t);
 	}
 
@@ -652,6 +665,7 @@
 	ipstat.ips_fragdropped++;
 	m_freem(m);
 	FREE(ipqe, M_IPQ);
+	ip_frags--;
 	return (0);
 }
 
@@ -670,6 +684,7 @@
 		m_freem(dtom(q->ipqe_ip));
 		LIST_REMOVE(q, ipqe_q);
 		FREE(q, M_IPQ);
+		ip_frags--;
 	}
 	LIST_REMOVE(fp, ipq_q);
 	(void) m_free(dtom(fp));
@@ -710,6 +725,19 @@
 }
 
 /*
+ * Flush a bunch of datagram fragments, till we are down to 75%.
+ */
+void
+ip_flush()
+{
+
+	while (ipq.lh_first != NULL && ip_frags > ip_maxqueue * 3 / 4) {
+		ipstat.ips_fragdropped++;
+		ip_freef(ipq.lh_first);
+	}
+}
+
+/*
  * Do option processing on a datagram,
  * possibly discarding it if bad options are encountered,
  * or forwarding it if source-routed.
@@ -973,9 +1001,9 @@
  */
 static int
 ip_weadvertise(addr)
-        u_int32_t addr;
+	u_int32_t addr;
 {
-        register struct rtentry *rt;
+	register struct rtentry *rt;
 	register struct ifnet *ifp;
 	register struct ifaddr *ifa;
 	struct sockaddr_inarp sin;
@@ -990,21 +1018,21 @@
 	
 	RTFREE(rt);
 	
-	if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 
-	    || rt->rt_gateway->sa_family != AF_LINK)
+	if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
+	    rt->rt_gateway->sa_family != AF_LINK)
 	  return 0;
 
 	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
-          for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) 
-	  {
-		if (ifa->ifa_addr->sa_family != rt->rt_gateway->sa_family)
-		  continue;
-
-		if (!bcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr), 
-			  LLADDR((struct sockaddr_dl *)rt->rt_gateway),
-			  ETHER_ADDR_LEN))
-		  return 1;
-	  }
+		for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
+		    ifa = ifa->ifa_list.tqe_next) {
+			if (ifa->ifa_addr->sa_family != rt->rt_gateway->sa_family)
+				continue;
+
+			if (!bcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr), 
+			    LLADDR((struct sockaddr_dl *)rt->rt_gateway),
+			    ETHER_ADDR_LEN))
+				return 1;
+		}
 
 	return 0;
 }
@@ -1313,6 +1341,9 @@
 	case IPCTL_IPPORT_HILASTAUTO:
 		return (sysctl_int(oldp, oldlenp, newp, newlen,
 		    &ipport_hilastauto));
+	case IPCTL_IPPORT_MAXQUEUE:
+		return (sysctl_int(oldp, oldlenp, newp, newlen,
+		    &ip_maxqueue));
 	default:
 		return (EOPNOTSUPP);
 	}
Index: ip_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_var.h,v
retrieving revision 1.8
diff -u -r1.8 ip_var.h
--- ip_var.h	1998/02/14 18:50:36	1.8
+++ ip_var.h	1999/02/18 04:33:56
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ip_var.h,v 1.8 1998/02/14 18:50:36 mickey Exp $	*/
+/*	$OpenBSD: ip_var.h,v 1.11 1999/02/17 23:51:12 deraadt Exp $	*/
 /*	$NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $	*/
 
 /*
@@ -166,6 +166,7 @@
 int	 ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
 int	 ip_dooptions __P((struct mbuf *));
 void	 ip_drain __P((void));
+void	 ip_flush __P((void));
 void	 ip_forward __P((struct mbuf *, int));
 void	 ip_freef __P((struct ipq *));
 void	 ip_freemoptions __P((struct ip_moptions *));
