Index: head/sys/netinet6/dest6.c =================================================================== --- head/sys/netinet6/dest6.c +++ head/sys/netinet6/dest6.c @@ -72,25 +72,23 @@ m = *mp; off = *offp; - /* validation of the length of the header */ -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(*dstopts), IPPROTO_DONE); + /* Validation of the length of the header. */ + m = m_pullup(m, off + sizeof(*dstopts)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; + return (IPPROTO_DONE); + } dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, sizeof(*dstopts)); - if (dstopts == NULL) - return IPPROTO_DONE; -#endif dstoptlen = (dstopts->ip6d_len + 1) << 3; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, dstoptlen, IPPROTO_DONE); + m = m_pullup(m, off + dstoptlen); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; + return (IPPROTO_DONE); + } dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, dstoptlen); - if (dstopts == NULL) - return IPPROTO_DONE; -#endif off += dstoptlen; dstoptlen -= sizeof(struct ip6_dest); opt = (u_int8_t *)dstopts + sizeof(struct ip6_dest); Index: head/sys/netinet6/frag6.c =================================================================== --- head/sys/netinet6/frag6.c +++ head/sys/netinet6/frag6.c @@ -218,30 +218,22 @@ * Remove the IPv6 fragmentation header from the mbuf. */ int -ip6_deletefraghdr(struct mbuf *m, int offset, int wait) +ip6_deletefraghdr(struct mbuf *m, int offset, int wait __unused) { struct ip6_hdr *ip6; - struct mbuf *t; - /* Delete frag6 header. */ - if (m->m_len >= offset + sizeof(struct ip6_frag)) { + KASSERT(m->m_len >= offset + sizeof(struct ip6_frag), + ("%s: ext headers not contigous in mbuf %p m_len %d >= " + "offset %d + %zu\n", __func__, m, m->m_len, offset, + sizeof(struct ip6_frag))); - /* This is the only possible case with !PULLDOWN_TEST. */ - ip6 = mtod(m, struct ip6_hdr *); - bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag), - offset); - m->m_data += sizeof(struct ip6_frag); - m->m_len -= sizeof(struct ip6_frag); - } else { - - /* This comes with no copy if the boundary is on cluster. */ - if ((t = m_split(m, offset, wait)) == NULL) - return (ENOMEM); - m_adj(t, sizeof(struct ip6_frag)); - m_cat(m, t); - } - + /* Delete frag6 header. */ + ip6 = mtod(m, struct ip6_hdr *); + bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag), offset); + m->m_data += sizeof(struct ip6_frag); + m->m_len -= sizeof(struct ip6_frag); m->m_flags |= M_FRAGMENTED; + return (0); } @@ -397,15 +389,13 @@ M_ASSERTPKTHDR(m); - ip6 = mtod(m, struct ip6_hdr *); -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE); - ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset); -#else - IP6_EXTHDR_GET(ip6f, struct ip6_frag *, m, offset, sizeof(*ip6f)); - if (ip6f == NULL) + m = m_pullup(m, offset + sizeof(struct ip6_frag)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = NULL; return (IPPROTO_DONE); -#endif + } + ip6 = mtod(m, struct ip6_hdr *); dstifp = NULL; /* Find the destination interface of the packet. */ @@ -429,6 +419,7 @@ * sizeof(struct ip6_frag) == 8 * sizeof(struct ip6_hdr) = 40 */ + ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset); if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) && (((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) { icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, @@ -833,15 +824,7 @@ V_ip6qb[bucket].count--; atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag); - if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0) { -#ifdef MAC - mac_ip6q_destroy(q6); -#endif - free(q6, M_FRAG6); - atomic_subtract_int(&V_frag6_nfragpackets, 1); - - goto dropfrag; - } + ip6_deletefraghdr(m, offset, M_NOWAIT); /* Set nxt(-hdr field value) to the original value. */ m_copyback(m, ip6_get_prevhdr(m, offset), sizeof(uint8_t), Index: head/sys/netinet6/icmp6.c =================================================================== --- head/sys/netinet6/icmp6.c +++ head/sys/netinet6/icmp6.c @@ -232,16 +232,13 @@ if (ifp == NULL) return; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), ); -#else if (m->m_len < sizeof(struct ip6_hdr)) { m = m_pullup(m, sizeof(struct ip6_hdr)); - if (m == NULL) + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; + } } -#endif - ip6 = mtod(m, struct ip6_hdr *); if (in6_setscope(&ip6->ip6_src, ifp, NULL) != 0) @@ -276,15 +273,13 @@ } #endif -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), ); -#else if (m->m_len < sizeof(struct ip6_hdr)) { m = m_pullup(m, sizeof(struct ip6_hdr)); - if (m == NULL) + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; + } } -#endif oip6 = mtod(m, struct ip6_hdr *); /* @@ -322,17 +317,14 @@ if (off >= 0 && nxt == IPPROTO_ICMPV6) { struct icmp6_hdr *icp; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, off + sizeof(struct icmp6_hdr), ); - icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off, - sizeof(*icp)); - if (icp == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, off + sizeof(struct icmp6_hdr)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; } -#endif + oip6 = mtod(m, struct ip6_hdr *); + icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); + if (icp->icmp6_type < ICMP6_ECHO_REQUEST || icp->icmp6_type == ND_REDIRECT) { /* @@ -349,8 +341,6 @@ /* non-ICMPv6 - send the error */ } - oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */ - /* Finally, do rate limitation check. */ if (icmp6_ratelimit(&oip6->ip6_src, type, code)) { ICMP6STAT_INC(icp6s_toofreq); @@ -411,10 +401,12 @@ m = *mp; off = *offp; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE); - /* m might change if M_LOOP. So, call mtod after this */ -#endif + m = m_pullup(m, off + sizeof(struct icmp6_hdr)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; + return (IPPROTO_DONE); + } /* * Locate icmp6 structure in mbuf, and check @@ -445,17 +437,8 @@ } /* Calculate the checksum. */ -#ifndef PULLDOWN_TEST icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); - if (icmp6 == NULL) { - ICMP6STAT_INC(icp6s_tooshort); - return IPPROTO_DONE; - } -#endif code = icmp6->icmp6_code; - if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { nd6log((LOG_ERR, "ICMP6 checksum error(%d|%x) %s\n", @@ -583,8 +566,12 @@ n->m_pkthdr.len = n0len + (noff - off); n->m_next = n0; } else { - IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off, - sizeof(*nicmp6)); + n = m_pullup(n, off + sizeof(*nicmp6)); + if (n == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + break; + } + nicmp6 = (struct icmp6_hdr *)(mtod(n, caddr_t) + off); noff = off; } if (n) { @@ -648,10 +635,12 @@ if (pr == NULL) pr = curthread->td_ucred->cr_prison; if (mode == FQDN) { -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo), - IPPROTO_DONE); -#endif + m = m_pullup(m, off + sizeof(struct icmp6_nodeinfo)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; + return (IPPROTO_DONE); + } n = m_copym(m, 0, M_COPYALL, M_NOWAIT); if (n) n = ni6_input(n, off, pr); @@ -736,7 +725,12 @@ if (icmp6len < sizeof(struct nd_router_solicit)) goto badlen; if (send_sendso_input_hook != NULL) { - IP6_EXTHDR_CHECK(m, off, icmp6len, IPPROTO_DONE); + m = m_pullup(m, off + icmp6len); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = NULL; + return (IPPROTO_DONE); + } error = send_sendso_input_hook(m, ifp, SND_IN, ip6len); if (error == 0) { m = NULL; @@ -896,18 +890,14 @@ ICMP6STAT_INC(icp6s_tooshort); goto freeit; } -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, - sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr), -1); - icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, - sizeof(*icmp6) + sizeof(struct ip6_hdr)); - if (icmp6 == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + + m = m_pullup(m, off + sizeof(*icmp6) + sizeof(struct ip6_hdr)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; return (-1); } -#endif + icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); eip6 = (struct ip6_hdr *)(icmp6 + 1); /* Detect the upper level protocol */ @@ -931,19 +921,14 @@ case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_AH: -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, - eoff + sizeof(struct ip6_ext), -1); - eh = (struct ip6_ext *)(mtod(m, caddr_t) + eoff); -#else - IP6_EXTHDR_GET(eh, struct ip6_ext *, m, - eoff, sizeof(*eh)); - if (eh == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, eoff + sizeof(struct ip6_ext)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; return (-1); } -#endif - + eh = (struct ip6_ext *) + (mtod(m, caddr_t) + eoff); if (nxt == IPPROTO_AH) eoff += (eh->ip6e_len + 2) << 2; else @@ -959,18 +944,14 @@ * information that depends on the final * destination (e.g. path MTU). */ -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, eoff + sizeof(*rth), -1); - rth = (struct ip6_rthdr *) - (mtod(m, caddr_t) + eoff); -#else - IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m, - eoff, sizeof(*rth)); - if (rth == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, eoff + sizeof(*rth)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; return (-1); } -#endif + rth = (struct ip6_rthdr *) + (mtod(m, caddr_t) + eoff); rthlen = (rth->ip6r_len + 1) << 3; /* * XXX: currently there is no @@ -984,19 +965,14 @@ rth->ip6r_type == IPV6_RTHDR_TYPE_0) { int hops; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, eoff + rthlen, -1); - rth0 = (struct ip6_rthdr0 *) - (mtod(m, caddr_t) + eoff); -#else - IP6_EXTHDR_GET(rth0, - struct ip6_rthdr0 *, m, - eoff, rthlen); - if (rth0 == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, eoff + rthlen); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; return (-1); } -#endif + rth0 = (struct ip6_rthdr0 *) + (mtod(m, caddr_t) + eoff); /* just ignore a bogus header */ if ((rth0->ip6r0_len % 2) == 0 && (hops = rth0->ip6r0_len/2)) @@ -1006,19 +982,14 @@ nxt = rth->ip6r_nxt; break; case IPPROTO_FRAGMENT: -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, 0, eoff + - sizeof(struct ip6_frag), -1); - fh = (struct ip6_frag *)(mtod(m, caddr_t) + - eoff); -#else - IP6_EXTHDR_GET(fh, struct ip6_frag *, m, - eoff, sizeof(*fh)); - if (fh == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, eoff + sizeof(struct ip6_frag)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = m; return (-1); } -#endif + fh = (struct ip6_frag *)(mtod(m, caddr_t) + + eoff); /* * Data after a fragment header is meaningless * unless it is the first fragment, but @@ -1044,16 +1015,7 @@ } } notify: -#ifndef PULLDOWN_TEST icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, - sizeof(*icmp6) + sizeof(struct ip6_hdr)); - if (icmp6 == NULL) { - ICMP6STAT_INC(icp6s_tooshort); - return (-1); - } -#endif /* * retrieve parameters from the inner IPv6 header, and convert @@ -1198,15 +1160,7 @@ struct in6_ifaddr *ia6 = NULL; ip6 = mtod(m, struct ip6_hdr *); -#ifndef PULLDOWN_TEST ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6)); - if (ni6 == NULL) { - /* m is already reclaimed */ - return (NULL); - } -#endif /* * Validate IPv6 source address. @@ -1303,7 +1257,6 @@ * * We do not do proxy at this moment. */ - /* m_pulldown instead of copy? */ m_copydata(m, off + sizeof(struct icmp6_nodeinfo), subjlen, (caddr_t)&in6_subj); if (in6_setscope(&in6_subj, m->m_pkthdr.rcvif, NULL)) @@ -1342,10 +1295,16 @@ mtx_unlock(&pr->pr_mtx); if (!n || n->m_next || n->m_len == 0) goto bad; - IP6_EXTHDR_GET(subj, char *, m, - off + sizeof(struct icmp6_nodeinfo), subjlen); - if (subj == NULL) + m = m_pullup(m, off + sizeof(struct icmp6_nodeinfo) + + subjlen); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); goto bad; + } + /* ip6 possibly invalid but not used after. */ + ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off); + subj = (char *)(mtod(m, caddr_t) + off + + sizeof(struct icmp6_nodeinfo)); if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *), n->m_len)) { goto bad; @@ -1903,16 +1862,8 @@ NET_EPOCH_ASSERT(); -#ifndef PULLDOWN_TEST - /* this is assumed to be safe. */ + /* This is assumed to be safe; icmp6_input() does a pullup. */ icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); - if (icmp6 == NULL) { - /* m is already reclaimed */ - return (IPPROTO_DONE); - } -#endif /* * XXX: the address may have embedded scope zone ID, which should be @@ -2229,9 +2180,7 @@ struct ifnet *ifp; struct ip6_hdr *ip6; struct nd_redirect *nd_rd; - struct in6_addr src6; - struct in6_addr redtgt6; - struct in6_addr reddst6; + struct in6_addr src6, redtgt6, reddst6; union nd_opts ndopts; char ip6buf[INET6_ADDRSTRLEN]; char *lladdr; @@ -2252,16 +2201,13 @@ ip6 = mtod(m, struct ip6_hdr *); icmp6len = ntohs(ip6->ip6_plen); -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, icmp6len,); - nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len); - if (nd_rd == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, off + icmp6len); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; } -#endif + ip6 = mtod(m, struct ip6_hdr *); + nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off); ifp = m->m_pkthdr.rcvif; redtgt6 = nd_rd->nd_rd_target; Index: head/sys/netinet6/ip6_input.c =================================================================== --- head/sys/netinet6/ip6_input.c +++ head/sys/netinet6/ip6_input.c @@ -203,9 +203,6 @@ RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); -#ifdef PULLDOWN_TEST -static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); -#endif /* * IP6 initialization: fill in IP6 protocol switch table. @@ -441,17 +438,8 @@ (caddr_t)&ip6->ip6_plen - (caddr_t)ip6); goto out; } -#ifndef PULLDOWN_TEST /* ip6_hopopts_input() ensures that mbuf is contiguous */ hbh = (struct ip6_hbh *)(ip6 + 1); -#else - IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), - sizeof(struct ip6_hbh)); - if (hbh == NULL) { - IP6STAT_INC(ip6s_tooshort); - goto out; - } -#endif *nxt = hbh->ip6h_nxt; /* @@ -602,7 +590,6 @@ in6_ifstat_inc(rcvif, ifs6_in_receive); IP6STAT_INC(ip6s_total); -#ifndef PULLDOWN_TEST /* * L2 bridge code and some other code can return mbuf chain * that does not conform to KAME requirement. too bad. @@ -624,9 +611,6 @@ m_freem(m); m = n; } - IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /* nothing */); -#endif - if (m->m_len < sizeof(struct ip6_hdr)) { if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { IP6STAT_INC(ip6s_toosmall); @@ -985,28 +969,22 @@ struct ip6_hbh *hbh; /* validation of the length of the header */ -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1); + m = m_pullup(m, off + sizeof(*hbh)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = NULL; + return (-1); + } hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); hbhlen = (hbh->ip6h_len + 1) << 3; - IP6_EXTHDR_CHECK(m, off, hbhlen, -1); - hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); -#else - IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, - sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); - if (hbh == NULL) { - IP6STAT_INC(ip6s_tooshort); - return -1; + m = m_pullup(m, off + hbhlen); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = NULL; + return (-1); } - hbhlen = (hbh->ip6h_len + 1) << 3; - IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), - hbhlen); - if (hbh == NULL) { - IP6STAT_INC(ip6s_tooshort); - return -1; - } -#endif + hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); off += hbhlen; hbhlen -= sizeof(struct ip6_hbh); if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), @@ -1198,10 +1176,9 @@ * Create the "control" list for this pcb. * These functions will not modify mbuf chain at all. * - * With KAME mbuf chain restriction: * The routine will be called from upper layer handlers like tcp6_input(). * Thus the routine assumes that the caller (tcp6_input) have already - * called IP6_EXTHDR_CHECK() and all the extension headers are located in the + * called m_pullup() and all the extension headers are located in the * very first mbuf on the mbuf chain. * * ip6_savecontrol_v4 will handle those options that are possible to be @@ -1436,29 +1413,10 @@ */ if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { struct ip6_hbh *hbh; - int hbhlen = 0; -#ifdef PULLDOWN_TEST - struct mbuf *ext; -#endif + int hbhlen; -#ifndef PULLDOWN_TEST hbh = (struct ip6_hbh *)(ip6 + 1); hbhlen = (hbh->ip6h_len + 1) << 3; -#else - ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr), - ip6->ip6_nxt); - if (ext == NULL) { - IP6STAT_INC(ip6s_tooshort); - return; - } - hbh = mtod(ext, struct ip6_hbh *); - hbhlen = (hbh->ip6h_len + 1) << 3; - if (hbhlen != ext->m_len) { - m_freem(ext); - IP6STAT_INC(ip6s_tooshort); - return; - } -#endif /* * XXX: We copy the whole header even if a @@ -1472,9 +1430,6 @@ IPPROTO_IPV6); if (*mp) mp = &(*mp)->m_next; -#ifdef PULLDOWN_TEST - m_freem(ext); -#endif } } @@ -1491,9 +1446,6 @@ while (1) { /* is explicit loop prevention necessary? */ struct ip6_ext *ip6e = NULL; int elen; -#ifdef PULLDOWN_TEST - struct mbuf *ext = NULL; -#endif /* * if it is not an extension header, don't try to @@ -1509,7 +1461,6 @@ goto loopend; } -#ifndef PULLDOWN_TEST if (off + sizeof(*ip6e) > m->m_len) goto loopend; ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off); @@ -1519,23 +1470,6 @@ elen = (ip6e->ip6e_len + 1) << 3; if (off + elen > m->m_len) goto loopend; -#else - ext = ip6_pullexthdr(m, off, nxt); - if (ext == NULL) { - IP6STAT_INC(ip6s_tooshort); - return; - } - ip6e = mtod(ext, struct ip6_ext *); - if (nxt == IPPROTO_AH) - elen = (ip6e->ip6e_len + 2) << 2; - else - elen = (ip6e->ip6e_len + 1) << 3; - if (elen != ext->m_len) { - m_freem(ext); - IP6STAT_INC(ip6s_tooshort); - return; - } -#endif switch (nxt) { case IPPROTO_DSTOPTS: @@ -1570,9 +1504,6 @@ * the code just in case (nxt overwritten or * other cases). */ -#ifdef PULLDOWN_TEST - m_freem(ext); -#endif goto loopend; } @@ -1581,10 +1512,6 @@ off += elen; nxt = ip6e->ip6e_nxt; ip6e = NULL; -#ifdef PULLDOWN_TEST - m_freem(ext); - ext = NULL; -#endif } loopend: ; @@ -1669,49 +1596,6 @@ } else sorwakeup(so); } - -#ifdef PULLDOWN_TEST -/* - * pull single extension header from mbuf chain. returns single mbuf that - * contains the result, or NULL on error. - */ -static struct mbuf * -ip6_pullexthdr(struct mbuf *m, size_t off, int nxt) -{ - struct ip6_ext ip6e; - size_t elen; - struct mbuf *n; - -#ifdef DIAGNOSTIC - switch (nxt) { - case IPPROTO_DSTOPTS: - case IPPROTO_ROUTING: - case IPPROTO_HOPOPTS: - case IPPROTO_AH: /* is it possible? */ - break; - default: - printf("ip6_pullexthdr: invalid nxt=%d\n", nxt); - } -#endif - - m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); - if (nxt == IPPROTO_AH) - elen = (ip6e.ip6e_len + 2) << 2; - else - elen = (ip6e.ip6e_len + 1) << 3; - - if (elen > MLEN) - n = m_getcl(M_NOWAIT, MT_DATA, 0); - else - n = m_get(M_NOWAIT, MT_DATA); - if (n == NULL) - return NULL; - - m_copydata(m, off, elen, mtod(n, caddr_t)); - n->m_len = elen; - return n; -} -#endif /* * Get pointer to the previous header followed by the header Index: head/sys/netinet6/ip6_mroute.c =================================================================== --- head/sys/netinet6/ip6_mroute.c +++ head/sys/netinet6/ip6_mroute.c @@ -1745,20 +1745,13 @@ * Make sure that the IP6 and PIM headers in contiguous memory, and * possibly the PIM REGISTER header */ -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, minlen, IPPROTO_DONE); - /* adjust pointer */ - ip6 = mtod(m, struct ip6_hdr *); - - /* adjust mbuf to point to the PIM header */ - pim = (struct pim *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(pim, struct pim *, m, off, minlen); - if (pim == NULL) { - PIM6STAT_INC(pim6s_rcv_tooshort); + m = m_pullup(m, off + minlen); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return (IPPROTO_DONE); } -#endif + ip6 = mtod(m, struct ip6_hdr *); + pim = (struct pim *)((caddr_t)ip6 + off); #define PIM6_CHECKSUM #ifdef PIM6_CHECKSUM Index: head/sys/netinet6/mld6.c =================================================================== --- head/sys/netinet6/mld6.c +++ head/sys/netinet6/mld6.c @@ -1261,6 +1261,11 @@ ifp = m->m_pkthdr.rcvif; /* Pullup to appropriate size. */ + m = m_pullup(m, off + sizeof(*mld)); + if (m == NULL) { + ICMP6STAT_INC(icp6s_badlen); + return (IPPROTO_DONE); + } mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off); if (mld->mld_type == MLD_LISTENER_QUERY && icmp6len >= sizeof(struct mldv2_query)) { @@ -1268,12 +1273,13 @@ } else { mldlen = sizeof(struct mld_hdr); } - IP6_EXTHDR_GET(mld, struct mld_hdr *, m, off, mldlen); - if (mld == NULL) { + m = m_pullup(m, off + mldlen); + if (m == NULL) { ICMP6STAT_INC(icp6s_badlen); return (IPPROTO_DONE); } ip6 = mtod(m, struct ip6_hdr *); + mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off); /* * Userland needs to see all of this traffic for implementing Index: head/sys/netinet6/nd6_nbr.c =================================================================== --- head/sys/netinet6/nd6_nbr.c +++ head/sys/netinet6/nd6_nbr.c @@ -148,17 +148,13 @@ goto bads; } -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, icmp6len,); - nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len); - if (nd_ns == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, off + icmp6len); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; } -#endif - ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */ + ip6 = mtod(m, struct ip6_hdr *); + nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off); saddr6 = ip6->ip6_src; daddr6 = ip6->ip6_dst; @@ -656,16 +652,13 @@ goto bad; } -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, icmp6len,); - nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len); - if (nd_na == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, off + icmp6len); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; } -#endif + ip6 = mtod(m, struct ip6_hdr *); + nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off); flags = nd_na->nd_na_flags_reserved; is_router = ((flags & ND_NA_FLAG_ROUTER) != 0); Index: head/sys/netinet6/nd6_rtr.c =================================================================== --- head/sys/netinet6/nd6_rtr.c +++ head/sys/netinet6/nd6_rtr.c @@ -202,16 +202,13 @@ if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) goto freeit; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, icmp6len,); - nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len); - if (nd_rs == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, off + icmp6len); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; } -#endif + ip6 = mtod(m, struct ip6_hdr *); + nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off); icmp6len -= sizeof(*nd_rs); nd6_option_init(nd_rs + 1, icmp6len, &ndopts); @@ -403,16 +400,13 @@ goto bad; } -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, icmp6len,); - nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len); - if (nd_ra == NULL) { - ICMP6STAT_INC(icp6s_tooshort); + m = m_pullup(m, off + icmp6len); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); return; } -#endif + ip6 = mtod(m, struct ip6_hdr *); + nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off); icmp6len -= sizeof(*nd_ra); nd6_option_init(nd_ra + 1, icmp6len, &ndopts); Index: head/sys/netinet6/route6.c =================================================================== --- head/sys/netinet6/route6.c +++ head/sys/netinet6/route6.c @@ -83,18 +83,14 @@ } #endif -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE); + m = m_pullup(m, off + sizeof(*rh)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = NULL; + return (IPPROTO_DONE); + } ip6 = mtod(m, struct ip6_hdr *); rh = (struct ip6_rthdr *)((caddr_t)ip6 + off); -#else - ip6 = mtod(m, struct ip6_hdr *); - IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh)); - if (rh == NULL) { - IP6STAT_INC(ip6s_tooshort); - return IPPROTO_DONE; - } -#endif /* * While this switch may look gratuitous, leave it in Index: head/sys/netinet6/udp6_usrreq.c =================================================================== --- head/sys/netinet6/udp6_usrreq.c +++ head/sys/netinet6/udp6_usrreq.c @@ -223,16 +223,14 @@ ifp = m->m_pkthdr.rcvif; -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE); - ip6 = mtod(m, struct ip6_hdr *); - uh = (struct udphdr *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(*uh)); - if (!uh) + m = m_pullup(m, off + sizeof(struct udphdr)); + if (m == NULL) { + IP6STAT_INC(ip6s_exthdrtoolong); + *mp = NULL; return (IPPROTO_DONE); + } ip6 = mtod(m, struct ip6_hdr *); -#endif + uh = (struct udphdr *)((caddr_t)ip6 + off); UDPSTAT_INC(udps_ipackets);