netinet6: Remove PULLDOWN_TESTs.
Remove the KAME introduced PULLDOWN_TESTs which did not even have a compile-time option in sys/conf to turn them on for a custom kernel build. They made the code a lot harder to read or more complicated in a few cases. Convert the IP6_EXTHDR_CHECK() calls into FreeBSD looking code. Rather than throwing the packet away if it would not fit the KAME mbuf expectations, convert the macros to m_pullup() calls. Do not do any extra manual conditional checks upfront as to whether the m_len would suffice (*), simply let m_pullup() do its work (incl. an early check). Remove extra m_pullup() calls where earlier in the function or the only caller has already done the pullup. Discussed with: rwatson (*) Reviewed by: ae MFC after: 8 weeks Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D22334
This commit is contained in:
parent
5a2899ac85
commit
a61b5cfbbf
@ -72,25 +72,23 @@ dest6_input(struct mbuf **mp, int *offp, int proto)
|
||||
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);
|
||||
|
@ -218,30 +218,22 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGBUCKETSIZE, maxfragbucketsize,
|
||||
* 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;
|
||||
|
||||
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)));
|
||||
|
||||
/* Delete frag6 header. */
|
||||
if (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);
|
||||
}
|
||||
|
||||
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 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
|
||||
|
||||
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 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
|
||||
* 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 @@ postinsert:
|
||||
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),
|
||||
|
@ -232,16 +232,13 @@ icmp6_error2(struct mbuf *m, int type, int code, int param,
|
||||
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 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
|
||||
}
|
||||
#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 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
|
||||
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 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
|
||||
/* 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 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
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 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
}
|
||||
|
||||
/* 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 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
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 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
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 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
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 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
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 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
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 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
* 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 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
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 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
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 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
|
||||
}
|
||||
}
|
||||
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 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
|
||||
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 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
|
||||
*
|
||||
* 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 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
|
||||
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 @@ icmp6_rip6_input(struct mbuf **mp, int off)
|
||||
|
||||
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 @@ icmp6_redirect_input(struct mbuf *m, int off)
|
||||
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 @@ icmp6_redirect_input(struct mbuf *m, int off)
|
||||
|
||||
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;
|
||||
|
@ -203,9 +203,6 @@ struct rmlock in6_ifaddr_lock;
|
||||
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 @@ ip6_input_hbh(struct mbuf **mp, uint32_t *plen, uint32_t *rtalert, int *off,
|
||||
(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 @@ ip6_input(struct mbuf *m)
|
||||
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 @@ ip6_input(struct mbuf *m)
|
||||
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 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
|
||||
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);
|
||||
m = m_pullup(m, off + hbhlen);
|
||||
if (m == NULL) {
|
||||
IP6STAT_INC(ip6s_exthdrtoolong);
|
||||
*mp = NULL;
|
||||
return (-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;
|
||||
}
|
||||
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
|
||||
off += hbhlen;
|
||||
hbhlen -= sizeof(struct ip6_hbh);
|
||||
if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
|
||||
@ -1198,10 +1176,9 @@ ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
|
||||
* 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 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
*/
|
||||
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 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
IPPROTO_IPV6);
|
||||
if (*mp)
|
||||
mp = &(*mp)->m_next;
|
||||
#ifdef PULLDOWN_TEST
|
||||
m_freem(ext);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1491,9 +1446,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
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 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
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 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
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 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
* the code just in case (nxt overwritten or
|
||||
* other cases).
|
||||
*/
|
||||
#ifdef PULLDOWN_TEST
|
||||
m_freem(ext);
|
||||
#endif
|
||||
goto loopend;
|
||||
|
||||
}
|
||||
@ -1581,10 +1512,6 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
|
||||
off += elen;
|
||||
nxt = ip6e->ip6e_nxt;
|
||||
ip6e = NULL;
|
||||
#ifdef PULLDOWN_TEST
|
||||
m_freem(ext);
|
||||
ext = NULL;
|
||||
#endif
|
||||
}
|
||||
loopend:
|
||||
;
|
||||
@ -1670,49 +1597,6 @@ ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6 *dst, u_int32_t mtu)
|
||||
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
|
||||
* currently processed.
|
||||
|
@ -1745,20 +1745,13 @@ pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
|
||||
* 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
|
||||
|
@ -1261,6 +1261,11 @@ mld_input(struct mbuf *m, int off, int icmp6len)
|
||||
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 @@ mld_input(struct mbuf *m, int off, int icmp6len)
|
||||
} 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
|
||||
|
@ -148,17 +148,13 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
|
||||
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 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
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);
|
||||
|
@ -202,16 +202,13 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
|
||||
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 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
|
||||
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);
|
||||
|
@ -83,18 +83,14 @@ route6_input(struct mbuf **mp, int *offp, int proto)
|
||||
}
|
||||
#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
|
||||
|
@ -223,16 +223,14 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
|
||||
ifp = m->m_pkthdr.rcvif;
|
||||
|
||||
#ifndef PULLDOWN_TEST
|
||||
IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
|
||||
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 *);
|
||||
uh = (struct udphdr *)((caddr_t)ip6 + off);
|
||||
#else
|
||||
IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(*uh));
|
||||
if (!uh)
|
||||
return (IPPROTO_DONE);
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
#endif
|
||||
|
||||
UDPSTAT_INC(udps_ipackets);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user