diff options
-rw-r--r-- | sys/netinet6/frag6.c | 53 | ||||
-rw-r--r-- | sys/netinet6/in6.h | 23 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 3 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 4 |
5 files changed, 65 insertions, 22 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 83ff8d1a0ca..6d180787d85 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -1,5 +1,5 @@ -/* $OpenBSD: frag6.c,v 1.15 2002/05/27 19:48:27 deraadt Exp $ */ -/* $KAME: frag6.c,v 1.31 2001/05/17 13:45:34 jinmei Exp $ */ +/* $OpenBSD: frag6.c,v 1.16 2002/05/28 03:04:38 itojun Exp $ */ +/* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -70,6 +70,7 @@ static void frag6_freef(struct ip6q *); static int ip6q_locked; u_int frag6_nfragpackets; +u_int frag6_nfrags; struct ip6q ip6q; /* ip6 reassemble queue */ static __inline int ip6q_lock_try(void); @@ -240,9 +241,8 @@ frag6_input(mp, offp, proto) */ if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) && (((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) { - icmp6_error(m, ICMP6_PARAM_PROB, - ICMP6_PARAMPROB_HEADER, - offsetof(struct ip6_hdr, ip6_plen)); + icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, + offsetof(struct ip6_hdr, ip6_plen)); in6_ifstat_inc(dstifp, ifs6_reass_fail); return IPPROTO_DONE; } @@ -255,6 +255,16 @@ frag6_input(mp, offp, proto) IP6Q_LOCK(); + /* + * Enforce upper bound on number of fragments. + * If maxfrag is 0, never accept fragments. + * If maxfrag is -1, accept all fragments without limitation. + */ + if (ip6_maxfrags < 0) + ; + else if (frag6_nfrags >= (u_int)ip6_maxfrags) + goto dropfrag; + for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next) if (ip6f->ip6f_ident == q6->ip6q_ident && IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) && @@ -270,8 +280,9 @@ frag6_input(mp, offp, proto) /* * 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 maxfragpackets is 0, never accept fragments. + * If maxfragpackets is -1, accept all fragments without + * limitation. */ if (ip6_maxfragpackets < 0) ; @@ -279,7 +290,7 @@ frag6_input(mp, offp, proto) goto dropfrag; frag6_nfragpackets++; q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE, - M_DONTWAIT); + M_DONTWAIT); if (q6 == NULL) goto dropfrag; bzero(q6, sizeof(*q6)); @@ -297,6 +308,8 @@ frag6_input(mp, offp, proto) q6->ip6q_src = ip6->ip6_src; q6->ip6q_dst = ip6->ip6_dst; q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */ + + q6->ip6q_nfrag = 0; } /* @@ -305,8 +318,8 @@ frag6_input(mp, offp, proto) */ fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK); if (fragoff == 0) { - q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) - - sizeof(struct ip6_frag); + q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) - + sizeof(struct ip6_frag); q6->ip6q_nxt = ip6f->ip6f_nxt; } @@ -320,13 +333,12 @@ frag6_input(mp, offp, proto) /* The 1st fragment has already arrived. */ if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) { icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, - offset - sizeof(struct ip6_frag) + - offsetof(struct ip6_frag, ip6f_offlg)); + offset - sizeof(struct ip6_frag) + + offsetof(struct ip6_frag, ip6f_offlg)); IP6Q_UNLOCK(); return(IPPROTO_DONE); } - } - else if (fragoff + frgpartlen > IPV6_MAXPACKET) { + } else if (fragoff + frgpartlen > IPV6_MAXPACKET) { icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset - sizeof(struct ip6_frag) + offsetof(struct ip6_frag, ip6f_offlg)); @@ -363,9 +375,9 @@ frag6_input(mp, offp, proto) ip6err->ip6_dst = q6->ip6q_dst; icmp6_error(merr, ICMP6_PARAM_PROB, - ICMP6_PARAMPROB_HEADER, - erroff - sizeof(struct ip6_frag) + - offsetof(struct ip6_frag, ip6f_offlg)); + ICMP6_PARAMPROB_HEADER, + erroff - sizeof(struct ip6_frag) + + offsetof(struct ip6_frag, ip6f_offlg)); } } } @@ -458,6 +470,8 @@ frag6_input(mp, offp, proto) * If the incoming framgent overlaps some existing fragments in * the reassembly queue, drop it, since it is dangerous to override * existing fragments from a security point of view. + * We don't know which fragment is the bad guy - here we trust + * fragment that came in earlier, with no real reason. */ if (af6->ip6af_up != (struct ip6asfrag *)q6) { i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen @@ -495,6 +509,8 @@ insert: * the most recently active fragmented packet. */ frag6_enq(ip6af, af6->ip6af_up); + frag6_nfrags++; + q6->ip6q_nfrag++; #if 0 /* xxx */ if (q6 != ip6q.ip6q_next) { frag6_remque(q6); @@ -557,6 +573,7 @@ insert: /* this comes with no copy if the boundary is on cluster */ if ((t = m_split(m, offset, M_DONTWAIT)) == NULL) { frag6_remque(q6); + frag6_nfrags -= q6->ip6q_nfrag; free(q6, M_FTABLE); frag6_nfragpackets--; goto dropfrag; @@ -574,6 +591,7 @@ insert: } frag6_remque(q6); + frag6_nfrags -= q6->ip6q_nfrag; free(q6, M_FTABLE); frag6_nfragpackets--; @@ -645,6 +663,7 @@ frag6_freef(q6) free(af6, M_FTABLE); } frag6_remque(q6); + frag6_nfrags -= q6->ip6q_nfrag; free(q6, M_FTABLE); frag6_nfragpackets--; } diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 40e88198bd0..f19719db76d 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.h,v 1.26 2002/03/14 01:27:11 millert Exp $ */ +/* $OpenBSD: in6.h,v 1.27 2002/05/28 03:04:38 itojun Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -531,9 +531,11 @@ struct in6_pktinfo { #define IPV6CTL_USE_DEPRECATED 21 /* use deprecated addr (RFC2462 5.5.4) */ #define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */ /*#define IPV6CTL_MAPPED_ADDR 23 not for openbsd */ +/* 24 to 40: resrved */ +#define IPV6CTL_MAXFRAGS 41 /* max fragments */ /* New entries should be added here from current IPV6CTL_MAXID value. */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ -#define IPV6CTL_MAXID 24 +#define IPV6CTL_MAXID 42 #define IPV6CTL_NAMES { \ { 0, 0 }, \ @@ -560,6 +562,23 @@ struct in6_pktinfo { { "use_deprecated", CTLTYPE_INT }, \ { "rr_prune", CTLTYPE_INT }, \ { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { "maxfrags", CTLTYPE_INT }, \ } #endif /* !_XOPEN_SOURCE */ diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 5d46a0e2aff..8f1fda7ff09 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_proto.c,v 1.32 2002/01/08 02:29:03 itojun Exp $ */ +/* $OpenBSD: in6_proto.c,v 1.33 2002/05/28 03:04:38 itojun Exp $ */ /* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */ /* @@ -251,6 +251,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_maxfrags = 200; int ip6_log_interval = 5; int ip6_hdrnestlimit = 50; /* appropriate? */ int ip6_dad_count = 1; /* DupAddrDetectionTransmits */ diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index b00665a0e44..2062a97d23a 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.41 2002/03/14 01:27:12 millert Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.42 2002/05/28 03:04:38 itojun Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -1473,6 +1473,8 @@ ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen) &ip6_use_deprecated); case IPV6CTL_RR_PRUNE: return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune); + case IPV6CTL_MAXFRAGS: + return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_maxfrags); default: return EOPNOTSUPP; } diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index a762113b178..4c07d7c694f 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.14 2002/03/14 01:27:12 millert Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.15 2002/05/28 03:04:38 itojun Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -89,6 +89,7 @@ struct ip6q { #ifdef notyet u_char *ip6q_nxtp; #endif + int ip6q_nfrag; /* # of fragments */ }; struct ip6asfrag { @@ -216,6 +217,7 @@ extern int ip6_rr_prune; /* router renumbering prefix extern struct socket *ip6_mrouter; /* multicast routing daemon */ extern int ip6_sendredirects; /* send IP redirects when forwarding? */ extern int ip6_maxfragpackets; /* Maximum packets in reassembly queue */ +extern int ip6_maxfrags; /* Maximum fragments in reassembly queue */ extern int ip6_sourcecheck; /* Verify source interface */ extern int ip6_sourcecheck_interval; /* Interval between log messages */ extern int ip6_accept_rtadv; /* Acts as a host not a router */ |