summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-10-23 08:33:13 +0000
committerglebius <glebius@FreeBSD.org>2012-10-23 08:33:13 +0000
commitfea857f2a843cb039f3757ef79ba28b083d7a0c3 (patch)
tree3f8a671ee4ada31ed0990132b9e47b3cd8a49bc2
parent6a485e417ac3a2996d760532faaf5a48a890d223 (diff)
downloadFreeBSD-src-fea857f2a843cb039f3757ef79ba28b083d7a0c3.zip
FreeBSD-src-fea857f2a843cb039f3757ef79ba28b083d7a0c3.tar.gz
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.
-rw-r--r--sys/netinet/igmp.c2
-rw-r--r--sys/netinet/ip_icmp.c4
-rw-r--r--sys/netinet/ip_input.c6
-rw-r--r--sys/netinet/ip_options.c2
-rw-r--r--sys/netinet/raw_ip.c10
-rw-r--r--sys/netinet/sctp_input.c2
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/udp_usrreq.c3
-rw-r--r--sys/netipsec/xform_ah.c3
9 files changed, 10 insertions, 24 deletions
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index 1650fcb..63b96a8 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -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.
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 0568bd7..eb9c1ad 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -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);
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 1b27a7f..848325b 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -731,12 +731,6 @@ ours:
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.
diff --git a/sys/netinet/ip_options.c b/sys/netinet/ip_options.c
index 54a66b6..5083f6f 100644
--- a/sys/netinet/ip_options.c
+++ b/sys/netinet/ip_options.c
@@ -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;
}
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 291ef9a..7d070fd 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -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);
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 08c2f6e..3be64b1 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -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,
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index a91062b..0341207 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -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)
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 2576cf5..9a4a682 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -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;
}
diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c
index 91fcad6..722879b 100644
--- a/sys/netipsec/xform_ah.c
+++ b/sys/netipsec/xform_ah.c
@@ -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
OpenPOWER on IntegriCloud