Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_input.c
Show First 20 Lines • Show All 470 Lines • ▼ Show 20 Lines | if (m->m_flags & M_FASTFWD_OURS) { | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
hlen = ip->ip_hl << 2; | hlen = ip->ip_hl << 2; | ||||
ip_len = ntohs(ip->ip_len); | ip_len = ntohs(ip->ip_len); | ||||
goto ours; | goto ours; | ||||
} | } | ||||
IPSTAT_INC(ips_total); | IPSTAT_INC(ips_total); | ||||
if (m->m_pkthdr.len < sizeof(struct ip)) | if (__predict_false(m->m_pkthdr.len < sizeof(struct ip))) | ||||
goto tooshort; | goto tooshort; | ||||
if (m->m_len < sizeof (struct ip) && | if (m->m_len < sizeof(struct ip)) { | ||||
(m = m_pullup(m, sizeof (struct ip))) == NULL) { | m = m_pullup(m, sizeof(struct ip)); | ||||
if (__predict_false(m == NULL)) { | |||||
IPSTAT_INC(ips_toosmall); | IPSTAT_INC(ips_toosmall); | ||||
return; | return; | ||||
} | } | ||||
} | |||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
if (ip->ip_v != IPVERSION) { | if (__predict_false(ip->ip_v != IPVERSION)) { | ||||
IPSTAT_INC(ips_badvers); | IPSTAT_INC(ips_badvers); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
hlen = ip->ip_hl << 2; | hlen = ip->ip_hl << 2; | ||||
if (hlen < sizeof(struct ip)) { /* minimum header length */ | if (__predict_false(hlen < sizeof(struct ip))) { /* minimum header length */ | ||||
IPSTAT_INC(ips_badhlen); | IPSTAT_INC(ips_badhlen); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
if (hlen > m->m_len) { | if (hlen > m->m_len) { | ||||
if ((m = m_pullup(m, hlen)) == NULL) { | m = m_pullup(m, hlen); | ||||
if (__predict_false(m == NULL)) { | |||||
IPSTAT_INC(ips_badhlen); | IPSTAT_INC(ips_badhlen); | ||||
return; | return; | ||||
} | } | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
} | } | ||||
IP_PROBE(receive, NULL, NULL, ip, m->m_pkthdr.rcvif, ip, NULL); | IP_PROBE(receive, NULL, NULL, ip, m->m_pkthdr.rcvif, ip, NULL); | ||||
Show All 11 Lines | if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { | ||||
sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); | sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); | ||||
} else { | } else { | ||||
if (hlen == sizeof(struct ip)) { | if (hlen == sizeof(struct ip)) { | ||||
sum = in_cksum_hdr(ip); | sum = in_cksum_hdr(ip); | ||||
} else { | } else { | ||||
sum = in_cksum(m, hlen); | sum = in_cksum(m, hlen); | ||||
} | } | ||||
} | } | ||||
if (sum) { | if (__predict_false(sum)) { | ||||
IPSTAT_INC(ips_badsum); | IPSTAT_INC(ips_badsum); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
#ifdef ALTQ | #ifdef ALTQ | ||||
if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0) | if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0) | ||||
/* packet is dropped by traffic conditioner */ | /* packet is dropped by traffic conditioner */ | ||||
return; | return; | ||||
#endif | #endif | ||||
ip_len = ntohs(ip->ip_len); | ip_len = ntohs(ip->ip_len); | ||||
if (ip_len < hlen) { | if (__predict_false(ip_len < hlen)) { | ||||
IPSTAT_INC(ips_badlen); | IPSTAT_INC(ips_badlen); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
/* | /* | ||||
* Check that the amount of data in the buffers | * Check that the amount of data in the buffers | ||||
* is as at least much as the IP header would have us expect. | * is as at least much as the IP header would have us expect. | ||||
* Trim mbufs if longer than we expect. | * Trim mbufs if longer than we expect. | ||||
* Drop packet if shorter than we expect. | * Drop packet if shorter than we expect. | ||||
*/ | */ | ||||
if (m->m_pkthdr.len < ip_len) { | if (__predict_false(m->m_pkthdr.len < ip_len)) { | ||||
tooshort: | tooshort: | ||||
IPSTAT_INC(ips_tooshort); | IPSTAT_INC(ips_tooshort); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
if (m->m_pkthdr.len > ip_len) { | if (m->m_pkthdr.len > ip_len) { | ||||
if (m->m_len == m->m_pkthdr.len) { | if (m->m_len == m->m_pkthdr.len) { | ||||
m->m_len = ip_len; | m->m_len = ip_len; | ||||
m->m_pkthdr.len = ip_len; | m->m_pkthdr.len = ip_len; | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | if (hlen > sizeof (struct ip) && ip_dooptions(m, 0)) | ||||
return; | return; | ||||
/* greedy RSVP, snatches any PATH packet of the RSVP protocol and no | /* greedy RSVP, snatches any PATH packet of the RSVP protocol and no | ||||
* matter if it is destined to another node, or whether it is | * matter if it is destined to another node, or whether it is | ||||
* a multicast one, RSVP wants it! and prevents it from being forwarded | * a multicast one, RSVP wants it! and prevents it from being forwarded | ||||
* anywhere else. Also checks if the rsvp daemon is running before | * anywhere else. Also checks if the rsvp daemon is running before | ||||
* grabbing the packet. | * grabbing the packet. | ||||
*/ | */ | ||||
if (V_rsvp_on && ip->ip_p==IPPROTO_RSVP) | if (ip->ip_p == IPPROTO_RSVP && V_rsvp_on) | ||||
goto ours; | goto ours; | ||||
/* | /* | ||||
* Check our list of addresses, to see if the packet is for us. | * Check our list of addresses, to see if the packet is for us. | ||||
* If we don't have any addresses, assume any unicast packet | * If we don't have any addresses, assume any unicast packet | ||||
* we receive might be for us (and let the upper layers deal | * we receive might be for us (and let the upper layers deal | ||||
* with it). | * with it). | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 774 Lines • Show Last 20 Lines |