Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-4]: src/sys/netinet Pull up revisions 1.131, 1.133 (via patch, r...



details:   https://anonhg.NetBSD.org/src/rev/487550260127
branches:  netbsd-1-4
changeset: 471300:487550260127
user:      he <he%NetBSD.org@localhost>
date:      Wed May 30 09:44:09 2001 +0000

description:
Pull up revisions 1.131,1.133 (via patch, requested by he):
  Introduce net.inet.ip.maxfragpackets, which controls the maximum
  number of IPv4 fragment reassembly queue entries.  Defends against
  certain DoS attacks.  Fixes SA#2001-006.

diffstat:

 sys/netinet/ip_input.c |  33 ++++++++++++++++++++++++++++++++-
 1 files changed, 32 insertions(+), 1 deletions(-)

diffs (82 lines):

diff -r dd79f3c17866 -r 487550260127 sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c    Wed May 30 09:43:49 2001 +0000
+++ b/sys/netinet/ip_input.c    Wed May 30 09:44:09 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_input.c,v 1.82.2.6 2000/05/06 16:43:25 he Exp $     */
+/*     $NetBSD: ip_input.c,v 1.82.2.7 2001/05/30 09:44:09 he Exp $     */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -167,6 +167,8 @@
 
 struct ipqhead ipq;
 int    ipq_locked;
+int    ip_nfragpackets = 0;
+int    ip_maxfragpackets = 200;
 
 static __inline int ipq_lock_try __P((void));
 static __inline void ipq_unlock __P((void));
@@ -641,6 +643,17 @@
         * 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)
+                       ;
+               else if (ip_nfragpackets >= ip_maxfragpackets)
+                       goto dropfrag;
+               ip_nfragpackets++;
                MALLOC(fp, struct ipq *, sizeof (struct ipq),
                    M_FTABLE, M_NOWAIT);
                if (fp == NULL)
@@ -756,6 +769,7 @@
        ip->ip_dst = fp->ipq_dst;
        LIST_REMOVE(fp, ipq_q);
        FREE(fp, M_FTABLE);
+       ip_nfragpackets--;
        m->m_len += (ip->ip_hl << 2);
        m->m_data -= (ip->ip_hl << 2);
        /* some debugging cruft by sklower, below, will go away soon */
@@ -794,6 +808,7 @@
        }
        LIST_REMOVE(fp, ipq_q);
        FREE(fp, M_FTABLE);
+       ip_nfragpackets--;
 }
 
 /*
@@ -815,6 +830,17 @@
                        ip_freef(fp);
                }
        }
+       /*
+        * 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.
+        */
+       if (ip_maxfragpackets < 0)
+               ;
+       else {
+               while (ip_nfragpackets > ip_maxfragpackets && ipq.lh_first)
+                       ip_freef(ipq.lh_first);
+       }
        IPQ_UNLOCK();
 #ifdef GATEWAY
        ipflow_slowtimo();
@@ -1522,6 +1548,11 @@
                return (error);
            }
 #endif
+
+       case IPCTL_MAXFRAGPACKETS:
+               return (sysctl_int(oldp, oldlenp, newp, newlen,
+                   &ip_maxfragpackets));
+
        default:
                return (EOPNOTSUPP);
        }



Home | Main Index | Thread Index | Old Index