Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/Darwin/System/xnu/bsd/netinet/ip_input.c,v
retrieving revision 1.1.1.9
diff -u -d -b -w -r1.1.1.9 ip_input.c
--- ip_input.c  2001/08/01 20:56:03     1.1.1.9
+++ ip_input.c  2001/08/07 04:28:15
@@ -206,6 +206,12 @@
 ip_nat_ctl_t *ip_nat_ctl_ptr;
 #endif
 
+static int     ip_nfragpackets = 0;
+static int     ip_maxfragpackets;      /* initialized in ip_init() */
+SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragpackets, CTLFLAG_RW,
+       &ip_maxfragpackets, 0,
+       "Maximum number of IPv4 fragment reassembly queue entries");
+
 /*
  * We need to save the IP options in case a protocol wants to respond
  * to an incoming packet over the same route if the packet got here
@@ -289,6 +295,7 @@
                    ipq[i].next = ipq[i].prev = &ipq[i];
 
                maxnipq = nmbclusters/4;
+               ip_maxfragpackets = nmbclusters / 4;
 
                ip_id = time_second & 0xffff;
                ipintrq.ifq_maxlen = ipqmaxlen;
@@ -908,6 +915,15 @@
         * If first fragment to arrive, create a reassembly queue.
         */
        if (fp == 0) {
+               /*
+                * Enforce upper bound on number of fragmented packets
+                * for which we attempt reassembly;
+                * If maxfrag is 0, never accept fragments.
+                * If maxfrag is -1, accept all fragments without limitation.
+                */
+               if ((ip_maxfragpackets >= 0) && (ip_nfragpackets >= ip_maxfragpackets))
+                       goto dropfrag;
+               ip_nfragpackets++;
                if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
                        goto dropfrag;
                fp = mtod(t, struct ipq *);
@@ -1058,6 +1074,7 @@
        remque((void *) fp);
        nipq--;
        (void) m_free(dtom(fp));
+       ip_nfragpackets--;
        m->m_len += (IP_VHL_HL(ip->ip_vhl) << 2);
        m->m_data -= (IP_VHL_HL(ip->ip_vhl) << 2);
        /* some debugging cruft by sklower, below, will go away soon */
@@ -1098,6 +1115,7 @@
        }
        remque((void *) fp);
        (void) m_free(dtom(fp));
+       ip_nfragpackets--;
        nipq--;
 }
 
@@ -1123,6 +1141,20 @@
                        if (fp->prev->ipq_ttl == 0) {
                                ipstat.ips_fragtimeout++;
                                ip_freef(fp->prev);
+                       }
+               }
+       }
+       /*
+        * If we are over the maximum number of fragments
+        * (due to the limit being lowered), drain off
+        * enough to get down to the new limit.
+        */
+       for (i = 0; i < IPREASS_NHASH; i++) {
+               if (ip_maxfragpackets >= 0) {
+                       while ((ip_nfragpackets > ip_maxfragpackets) &&
+                               (ipq[i].next != &ipq[i])) {
+                               ipstat.ips_fragdropped++;
+                               ip_freef(ipq[i].next);
                        }
                }
        }
cvs server: Diffing netinet6
Index: netinet6/frag6.c
===================================================================
RCS file: /cvs/Darwin/System/xnu/bsd/netinet6/frag6.c,v
retrieving revision 1.1.1.3
diff -u -d -b -w -r1.1.1.3 frag6.c
--- frag6.c     2001/04/05 01:08:43     1.1.1.3
+++ frag6.c     2001/08/07 04:28:15
@@ -90,6 +90,8 @@
 {
        struct timeval tv;
 
+       ip6_maxfragpackets = nmbclusters / 4;
+
        /*
         * in many cases, random() here does NOT return random number
         * as initialization during bootstrap time occur in fixed order.
Index: netinet6/in6_proto.c
===================================================================
RCS file: /cvs/Darwin/System/xnu/bsd/netinet6/in6_proto.c,v
retrieving revision 1.1.1.1
diff -u -d -b -w -r1.1.1.1 in6_proto.c
--- in6_proto.c 2000/11/30 00:47:21     1.1.1.1
+++ in6_proto.c 2001/08/07 04:28:15
@@ -328,7 +328,7 @@
 int    ip6_defhlim = IPV6_DEFHLIM;
 int    ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS;
 int    ip6_accept_rtadv = 0;   /* "IPV6FORWARDING ? 0 : 1" is dangerous */
-int    ip6_maxfragpackets = 200;
+int    ip6_maxfragpackets;     /* initialized in frag6.c:frag6_init() */
 int    ip6_log_interval = 5;
 int    ip6_hdrnestlimit = 50;  /* appropriate? */
 int    ip6_dad_count = 1;      /* DupAddrDetectionTransmits */
