Do not reduce ip_len by size of IP header in the ip_input()

before passing a packet to protocol input routines.
  For several protocols this mean that now protocol needs to
do subtraction itself, and for another half this means that
we do not need to add header length back to the packet.

  Make ip_stripoptions() to adjust ip_len, since now we enter
this function with a packet header whose ip_len does represent
length of entire packet, not payload only.
This commit is contained in:
Gleb Smirnoff 2012-10-23 08:33:13 +00:00
parent d2bffb140e
commit 8ad458a471
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241923
9 changed files with 10 additions and 24 deletions

View File

@ -1442,7 +1442,7 @@ igmp_input(struct mbuf *m, int off)
ip = mtod(m, struct ip *);
iphlen = off;
igmplen = ntohs(ip->ip_len);
igmplen = ntohs(ip->ip_len) - off;
/*
* Validate lengths.

View File

@ -359,7 +359,7 @@ icmp_input(struct mbuf *m, int off)
struct ip *ip = mtod(m, struct ip *);
struct sockaddr_in icmpsrc, icmpdst, icmpgw;
int hlen = off;
int icmplen = ntohs(ip->ip_len);
int icmplen = ntohs(ip->ip_len) - off;
int i, code;
void (*ctlfunc)(int, struct sockaddr *, void *);
int fibnum;
@ -592,8 +592,6 @@ icmp_input(struct mbuf *m, int off)
}
ifa_free(&ia->ia_ifa);
reflect:
/* Since ip_input() deducts this. */
ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
ICMPSTAT_INC(icps_reflect);
ICMPSTAT_INC(icps_outhist[icp->icmp_type]);
icmp_reflect(m);

View File

@ -731,12 +731,6 @@ ip_input(struct mbuf *m)
ip_len = ntohs(ip->ip_len);
}
/*
* Further protocols expect the packet length to be w/o the
* IP header.
*/
ip->ip_len = htons(ip_len - hlen);
#ifdef IPSEC
/*
* enforce IPsec policy checking if we are seeing last header.

View File

@ -470,7 +470,7 @@ ip_stripoptions(struct mbuf *m)
m->m_len -= olen;
if (m->m_flags & M_PKTHDR)
m->m_pkthdr.len -= olen;
ip->ip_v = IPVERSION;
ip->ip_len = htons(ntohs(ip->ip_len) - olen);
ip->ip_hl = sizeof(struct ip) >> 2;
}

View File

@ -287,12 +287,9 @@ rip_input(struct mbuf *m, int off)
ifp = m->m_pkthdr.rcvif;
/*
* Add back the IP header length which was
* removed by ip_input(). Raw sockets do
* not modify the packet except for some
* byte order swaps.
* Applications on raw sockets expect host byte order.
*/
ip->ip_len = ntohs(ip->ip_len) + off;
ip->ip_len = ntohs(ip->ip_len);
ip->ip_off = ntohs(ip->ip_off);
hash = INP_PCBHASH_RAW(proto, ip->ip_src.s_addr,
@ -506,7 +503,8 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
ip->ip_id = ip_newid();
/*
* Applications on raw sockets expect host byte order.
* Applications on raw sockets pass us packets
* in host byte order.
*/
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);

View File

@ -6038,7 +6038,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
dst.sin_len = sizeof(struct sockaddr_in);
dst.sin_port = sh->dest_port;
dst.sin_addr = ip->ip_dst;
length = ntohs(ip->ip_len) + iphlen;
length = ntohs(ip->ip_len);
/* Validate mbuf chain length with IP payload length. */
if (SCTP_HEADER_LEN(m) != length) {
SCTPDBG(SCTP_DEBUG_INPUT1,

View File

@ -641,7 +641,7 @@ tcp_input(struct mbuf *m, int off0)
}
ip = mtod(m, struct ip *);
th = (struct tcphdr *)((caddr_t)ip + off0);
tlen = ntohs(ip->ip_len);
tlen = ntohs(ip->ip_len) - off0;
if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)

View File

@ -392,7 +392,7 @@ udp_input(struct mbuf *m, int off)
* reflect UDP length, drop.
*/
len = ntohs((u_short)uh->uh_ulen);
ip_len = ntohs(ip->ip_len);
ip_len = ntohs(ip->ip_len) - iphlen;
if (ip_len != len) {
if (len > ip_len || len < sizeof(struct udphdr)) {
UDPSTAT_INC(udps_badlen);
@ -601,7 +601,6 @@ udp_input(struct mbuf *m, int off)
if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0)
goto badunlocked;
*ip = save_ip;
ip->ip_len = htons(ip_len + iphlen);
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
return;
}

View File

@ -305,9 +305,6 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
ip->ip_ttl = 0;
ip->ip_sum = 0;
if (!out)
ip->ip_len = htons(ntohs(ip->ip_len) + skip);
if (alg == CRYPTO_MD5_KPDK || alg == CRYPTO_SHA1_KPDK)
ip->ip_off &= htons(IP_DF);
else