Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Oct 2012 21:09:04 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241913 - in head: . sys/net sys/netgraph sys/netinet sys/netinet6 sys/netipsec sys/netpfil/ipfw sys/netpfil/pf sys/sys
Message-ID:  <201210222109.q9ML94e7007834@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Mon Oct 22 21:09:03 2012
New Revision: 241913
URL: http://svn.freebsd.org/changeset/base/241913

Log:
    Switch the entire IPv4 stack to keep the IP packet header
  in network byte order. Any host byte order processing is
  done in local variables and host byte order values are
  never[1] written to a packet.
  
    After this change a packet processed by the stack isn't
  modified at all[2] except for TTL.
  
    After this change a network stack hacker doesn't need to
  scratch his head trying to figure out what is the byte order
  at the given place in the stack.
  
  [1] One exception still remains. The raw sockets convert host
  byte order before pass a packet to an application. Probably
  this would remain for ages for compatibility.
  
  [2] The ip_input() still subtructs header len from ip->ip_len,
  but this is planned to be fixed soon.
  
  Reviewed by:	luigi, Maxim Dounin <mdounin mdounin.ru>
  Tested by:	ray, Olivier Cochard-Labbe <olivier cochard.me>

Modified:
  head/UPDATING
  head/sys/net/if_gre.c
  head/sys/net/if_stf.c
  head/sys/netgraph/ng_ipfw.c
  head/sys/netinet/igmp.c
  head/sys/netinet/in.h
  head/sys/netinet/in_gif.c
  head/sys/netinet/ip_carp.c
  head/sys/netinet/ip_divert.c
  head/sys/netinet/ip_gre.c
  head/sys/netinet/ip_icmp.c
  head/sys/netinet/ip_input.c
  head/sys/netinet/ip_ipsec.c
  head/sys/netinet/ip_mroute.c
  head/sys/netinet/ip_options.c
  head/sys/netinet/ip_output.c
  head/sys/netinet/raw_ip.c
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctputil.c
  head/sys/netinet/siftr.c
  head/sys/netinet/tcp_debug.c
  head/sys/netinet/tcp_input.c
  head/sys/netinet/tcp_output.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/tcp_syncache.c
  head/sys/netinet/tcp_timewait.c
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet6/ip6_ipsec.c
  head/sys/netipsec/ipsec.c
  head/sys/netpfil/ipfw/ip_dn_io.c
  head/sys/netpfil/ipfw/ip_fw2.c
  head/sys/netpfil/ipfw/ip_fw_dynamic.c
  head/sys/netpfil/ipfw/ip_fw_pfil.c
  head/sys/netpfil/pf/if_pfsync.c
  head/sys/netpfil/pf/pf.c
  head/sys/sys/param.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/UPDATING	Mon Oct 22 21:09:03 2012	(r241913)
@@ -24,6 +24,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10
 	disable the most expensive debugging functionality run
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
 
+20121023:
+	The IPv4 network stack has been converted to network byte
+	order. The following modules need to be recompiled together
+	with kernel: carp(4), divert(4), gif(4), siftr(4), gre(4),
+	pf(4), ipfw(4), ng_ipfw(4), stf(4).
+
 20121022:
 	Support for non-MPSAFE filesystems was removed from VFS. The
 	VFS_VERSION was bumped, all filesystem modules shall be

Modified: head/sys/net/if_gre.c
==============================================================================
--- head/sys/net/if_gre.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/net/if_gre.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -356,7 +356,7 @@ gre_output(struct ifnet *ifp, struct mbu
 			 * RFC2004 specifies that fragmented diagrams shouldn't
 			 * be encapsulated.
 			 */
-			if (ip->ip_off & (IP_MF | IP_OFFMASK)) {
+			if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) {
 				_IF_DROP(&ifp->if_snd);
 				m_freem(m);
 				error = EINVAL;    /* is there better errno? */
@@ -410,7 +410,7 @@ gre_output(struct ifnet *ifp, struct mbu
 			}
 			ip = mtod(m, struct ip *);
 			memcpy((caddr_t)(ip + 1), &mob_h, (unsigned)msiz);
-			ip->ip_len = ntohs(ip->ip_len) + msiz;
+			ip->ip_len = htons(ntohs(ip->ip_len) + msiz);
 		} else {  /* AF_INET */
 			_IF_DROP(&ifp->if_snd);
 			m_freem(m);
@@ -493,7 +493,7 @@ gre_output(struct ifnet *ifp, struct mbu
 		((struct ip*)gh)->ip_ttl = GRE_TTL;
 		((struct ip*)gh)->ip_tos = gre_ip_tos;
 		((struct ip*)gh)->ip_id = gre_ip_id;
-		gh->gi_len = m->m_pkthdr.len;
+		gh->gi_len = htons(m->m_pkthdr.len);
 	}
 
 	ifp->if_opackets++;

Modified: head/sys/net/if_stf.c
==============================================================================
--- head/sys/net/if_stf.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/net/if_stf.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -524,7 +524,7 @@ stf_output(ifp, m, dst, ro)
 	bcopy(&in4, &ip->ip_dst, sizeof(ip->ip_dst));
 	ip->ip_p = IPPROTO_IPV6;
 	ip->ip_ttl = ip_stf_ttl;
-	ip->ip_len = m->m_pkthdr.len;	/*host order*/
+	ip->ip_len = htons(m->m_pkthdr.len);
 	if (ifp->if_flags & IFF_LINK1)
 		ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos);
 	else

Modified: head/sys/netgraph/ng_ipfw.c
==============================================================================
--- head/sys/netgraph/ng_ipfw.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netgraph/ng_ipfw.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -265,7 +265,6 @@ ng_ipfw_rcvdata(hook_p hook, item_p item
 		switch (ip->ip_v) {
 #ifdef INET
 		case IPVERSION:
-			SET_HOST_IPLEN(ip);
 			return (ip_output(m, NULL, NULL, IP_FORWARDING,
 			    NULL, NULL));
 #endif

Modified: head/sys/netinet/igmp.c
==============================================================================
--- head/sys/netinet/igmp.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/igmp.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -1442,7 +1442,7 @@ igmp_input(struct mbuf *m, int off)
 
 	ip = mtod(m, struct ip *);
 	iphlen = off;
-	igmplen = ip->ip_len;
+	igmplen = ntohs(ip->ip_len);
 
 	/*
 	 * Validate lengths.
@@ -2225,7 +2225,7 @@ igmp_v1v2_queue_report(struct in_multi *
 
 	ip = mtod(m, struct ip *);
 	ip->ip_tos = 0;
-	ip->ip_len = sizeof(struct ip) + sizeof(struct igmp);
+	ip->ip_len = htons(sizeof(struct ip) + sizeof(struct igmp));
 	ip->ip_off = 0;
 	ip->ip_p = IPPROTO_IGMP;
 	ip->ip_src.s_addr = INADDR_ANY;
@@ -3522,8 +3522,8 @@ igmp_v3_encap_report(struct ifnet *ifp, 
 
 	ip = mtod(m, struct ip *);
 	ip->ip_tos = IPTOS_PREC_INTERNETCONTROL;
-	ip->ip_len = hdrlen + igmpreclen;
-	ip->ip_off = IP_DF;
+	ip->ip_len = htons(hdrlen + igmpreclen);
+	ip->ip_off = htons(IP_DF);
 	ip->ip_p = IPPROTO_IGMP;
 	ip->ip_sum = 0;
 

Modified: head/sys/netinet/in.h
==============================================================================
--- head/sys/netinet/in.h	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/in.h	Mon Oct 22 21:09:03 2012	(r241913)
@@ -741,33 +741,6 @@ void	 in_ifdetach(struct ifnet *);
 #define	satosin(sa)	((struct sockaddr_in *)(sa))
 #define	sintosa(sin)	((struct sockaddr *)(sin))
 #define	ifatoia(ifa)	((struct in_ifaddr *)(ifa))
-
-/*
- * Historically, BSD keeps ip_len and ip_off in host format
- * when doing layer 3 processing, and this often requires
- * to translate the format back and forth.
- * To make the process explicit, we define a couple of macros
- * that also take into account the fact that at some point
- * we may want to keep those fields always in net format.
- */
-
-#if (BYTE_ORDER == BIG_ENDIAN) || defined(HAVE_NET_IPLEN)
-#define SET_NET_IPLEN(p)	do {} while (0)
-#define SET_HOST_IPLEN(p)	do {} while (0)
-#else
-#define SET_NET_IPLEN(p)	do {		\
-	struct ip *h_ip = (p);			\
-	h_ip->ip_len = htons(h_ip->ip_len);	\
-	h_ip->ip_off = htons(h_ip->ip_off);	\
-	} while (0)
-
-#define SET_HOST_IPLEN(p)	do {		\
-	struct ip *h_ip = (p);			\
-	h_ip->ip_len = ntohs(h_ip->ip_len);	\
-	h_ip->ip_off = ntohs(h_ip->ip_off);	\
-	} while (0)
-#endif /* !HAVE_NET_IPLEN */
-
 #endif /* _KERNEL */
 
 /* INET6 stuff */

Modified: head/sys/netinet/in_gif.c
==============================================================================
--- head/sys/netinet/in_gif.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/in_gif.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -192,7 +192,7 @@ in_gif_output(struct ifnet *ifp, int fam
 	iphdr.ip_p = proto;
 	/* version will be set in ip_output() */
 	iphdr.ip_ttl = V_ip_gif_ttl;
-	iphdr.ip_len = m->m_pkthdr.len + sizeof(struct ip);
+	iphdr.ip_len = htons(m->m_pkthdr.len + sizeof(struct ip));
 	ip_ecn_ingress((ifp->if_flags & IFF_LINK1) ? ECN_ALLOWED : ECN_NOCARE,
 		       &iphdr.ip_tos, &tos);
 

Modified: head/sys/netinet/ip_carp.c
==============================================================================
--- head/sys/netinet/ip_carp.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_carp.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -783,9 +783,9 @@ carp_send_ad_locked(struct carp_softc *s
 		ip->ip_v = IPVERSION;
 		ip->ip_hl = sizeof(*ip) >> 2;
 		ip->ip_tos = IPTOS_LOWDELAY;
-		ip->ip_len = len;
+		ip->ip_len = htons(len);
 		ip->ip_id = ip_newid();
-		ip->ip_off = IP_DF;
+		ip->ip_off = htons(IP_DF);
 		ip->ip_ttl = CARP_DFLTTL;
 		ip->ip_p = IPPROTO_CARP;
 		ip->ip_sum = 0;

Modified: head/sys/netinet/ip_divert.c
==============================================================================
--- head/sys/netinet/ip_divert.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_divert.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -386,10 +386,6 @@ div_output(struct socket *so, struct mbu
 				INP_RUNLOCK(inp);
 				goto cantsend;
 			}
-
-			/* Convert fields to host order for ip_output() */
-			ip->ip_len = ntohs(ip->ip_len);
-			ip->ip_off = ntohs(ip->ip_off);
 			break;
 #ifdef INET6
 		case IPV6_VERSION >> 4:

Modified: head/sys/netinet/ip_gre.c
==============================================================================
--- head/sys/netinet/ip_gre.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_gre.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -274,12 +274,10 @@ gre_mobile_input(struct mbuf *m, int hle
 
 	/*
 	 * On FreeBSD, rip_input() supplies us with ip->ip_len
-	 * already converted into host byteorder and also decreases
-	 * it by the lengh of IP header, however, ip_input() expects
-	 * that this field is in the original format (network byteorder
-	 * and full size of IP packet), so that adjust accordingly.
+	 * decreased by the lengh of IP header, however, ip_input()
+	 * expects it to be full size of IP packet, so adjust accordingly.
 	 */
-	ip->ip_len = htons(ip->ip_len + sizeof(struct ip) - msiz);
+	ip->ip_len = htons(ntohs(ip->ip_len) + sizeof(struct ip) - msiz);
 
 	ip->ip_sum = 0;
 	ip->ip_sum = in_cksum(m, (ip->ip_hl << 2));

Modified: head/sys/netinet/ip_icmp.c
==============================================================================
--- head/sys/netinet/ip_icmp.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_icmp.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -229,7 +229,7 @@ icmp_error(struct mbuf *n, int type, int
 	 */
 	if (n->m_flags & M_DECRYPTED)
 		goto freeit;
-	if (oip->ip_off & ~(IP_MF|IP_DF))
+	if (oip->ip_off & htons(~(IP_MF|IP_DF)))
 		goto freeit;
 	if (n->m_flags & (M_BCAST|M_MCAST))
 		goto freeit;
@@ -263,16 +263,17 @@ icmp_error(struct mbuf *n, int type, int
 		tcphlen = th->th_off << 2;
 		if (tcphlen < sizeof(struct tcphdr))
 			goto freeit;
-		if (oip->ip_len < oiphlen + tcphlen)
+		if (ntohs(oip->ip_len) < oiphlen + tcphlen)
 			goto freeit;
 		if (oiphlen + tcphlen > n->m_len && n->m_next == NULL)
 			goto stdreply;
 		if (n->m_len < oiphlen + tcphlen && 
 		    ((n = m_pullup(n, oiphlen + tcphlen)) == NULL))
 			goto freeit;
-		icmpelen = max(tcphlen, min(V_icmp_quotelen, oip->ip_len - oiphlen));
+		icmpelen = max(tcphlen, min(V_icmp_quotelen,
+		    ntohs(oip->ip_len) - oiphlen));
 	} else
-stdreply:	icmpelen = max(8, min(V_icmp_quotelen, oip->ip_len - oiphlen));
+stdreply:	icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
 
 	icmplen = min(oiphlen + icmpelen, nlen);
 	if (icmplen < sizeof(struct ip))
@@ -322,8 +323,6 @@ stdreply:	icmpelen = max(8, min(V_icmp_q
 	 */
 	m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
 	nip = &icp->icmp_ip;
-	nip->ip_len = htons(nip->ip_len);
-	nip->ip_off = htons(nip->ip_off);
 
 	/*
 	 * Set up ICMP message mbuf and copy old IP header (without options
@@ -338,7 +337,7 @@ stdreply:	icmpelen = max(8, min(V_icmp_q
 	m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
 	nip = mtod(m, struct ip *);
 	bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip));
-	nip->ip_len = m->m_len;
+	nip->ip_len = htons(m->m_len);
 	nip->ip_v = IPVERSION;
 	nip->ip_hl = 5;
 	nip->ip_p = IPPROTO_ICMP;
@@ -360,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 = ip->ip_len;
+	int icmplen = ntohs(ip->ip_len);
 	int i, code;
 	void (*ctlfunc)(int, struct sockaddr *, void *);
 	int fibnum;
@@ -501,7 +500,6 @@ icmp_input(struct mbuf *m, int off)
 			ICMPSTAT_INC(icps_badlen);
 			goto freeit;
 		}
-		icp->icmp_ip.ip_len = ntohs(icp->icmp_ip.ip_len);
 		/* Discard ICMP's in response to multicast packets */
 		if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
 			goto badcode;
@@ -594,7 +592,8 @@ icmp_input(struct mbuf *m, int off)
 		}
 		ifa_free(&ia->ia_ifa);
 reflect:
-		ip->ip_len += hlen;	/* since ip_input deducts this */
+		/* 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);
@@ -864,7 +863,7 @@ match:
 		 * Now strip out original options by copying rest of first
 		 * mbuf's data back, and adjust the IP length.
 		 */
-		ip->ip_len -= optlen;
+		ip->ip_len = htons(ntohs(ip->ip_len) - optlen);
 		ip->ip_v = IPVERSION;
 		ip->ip_hl = 5;
 		m->m_len -= optlen;
@@ -898,7 +897,7 @@ icmp_send(struct mbuf *m, struct mbuf *o
 	m->m_len -= hlen;
 	icp = mtod(m, struct icmp *);
 	icp->icmp_cksum = 0;
-	icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
+	icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen);
 	m->m_data -= hlen;
 	m->m_len += hlen;
 	m->m_pkthdr.rcvif = (struct ifnet *)0;

Modified: head/sys/netinet/ip_input.c
==============================================================================
--- head/sys/netinet/ip_input.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_input.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -390,9 +390,8 @@ ip_input(struct mbuf *m)
 		m->m_flags &= ~M_FASTFWD_OURS;
 		/* Set up some basics that will be used later. */
 		ip = mtod(m, struct ip *);
-		ip->ip_len = ntohs(ip->ip_len);
-		ip->ip_off = ntohs(ip->ip_off);
 		hlen = ip->ip_hl << 2;
+		ip_len = ntohs(ip->ip_len);
 		goto ours;
 	}
 
@@ -513,8 +512,6 @@ tooshort:
 #ifdef IPFIREWALL_FORWARD
 	if (m->m_flags & M_FASTFWD_OURS) {
 		m->m_flags &= ~M_FASTFWD_OURS;
-		ip->ip_len = ntohs(ip->ip_len);
-		ip->ip_off = ntohs(ip->ip_off);
 		goto ours;
 	}
 	if ((dchg = (m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL)) != 0) {
@@ -523,20 +520,12 @@ tooshort:
 		 * packets originally destined to us to some other directly
 		 * connected host.
 		 */
-		ip->ip_len = ntohs(ip->ip_len);
-		ip->ip_off = ntohs(ip->ip_off);
 		ip_forward(m, dchg);
 		return;
 	}
 #endif /* IPFIREWALL_FORWARD */
 
 passin:
-	/*
-	 *  From now and up to output pfil(9) processing in ip_output()
-	 *  the header is in host byte order.
-	 */
-	ip->ip_len = ntohs(ip->ip_len);
-	ip->ip_off = ntohs(ip->ip_off);
 
 	/*
 	 * Process options and, if not destined for us,
@@ -732,20 +721,21 @@ ours:
 	 * Attempt reassembly; if it succeeds, proceed.
 	 * ip_reass() will return a different mbuf.
 	 */
-	if (ip->ip_off & (IP_MF | IP_OFFMASK)) {
+	if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) {
 		m = ip_reass(m);
 		if (m == NULL)
 			return;
 		ip = mtod(m, struct ip *);
 		/* Get the header length of the reassembled packet */
 		hlen = ip->ip_hl << 2;
+		ip_len = ntohs(ip->ip_len);
 	}
 
 	/*
 	 * Further protocols expect the packet length to be w/o the
 	 * IP header.
 	 */
-	ip->ip_len -= hlen;
+	ip->ip_len = htons(ip_len - hlen);
 
 #ifdef IPSEC
 	/*
@@ -914,21 +904,20 @@ found:
 	 * Adjust ip_len to not reflect header,
 	 * convert offset of this to bytes.
 	 */
-	ip->ip_len -= hlen;
-	if (ip->ip_off & IP_MF) {
+	ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
+	if (ip->ip_off & htons(IP_MF)) {
 		/*
 		 * Make sure that fragments have a data length
 		 * that's a non-zero multiple of 8 bytes.
 		 */
-		if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {
+		if (ntohs(ip->ip_len) == 0 || (ntohs(ip->ip_len & 0x7) != 0)) {
 			IPSTAT_INC(ips_toosmall); /* XXX */
 			goto dropfrag;
 		}
 		m->m_flags |= M_FRAG;
 	} else
 		m->m_flags &= ~M_FRAG;
-	ip->ip_off <<= 3;
-
+	ip->ip_off = htons(ntohs(ip->ip_off) << 3);
 
 	/*
 	 * Attempt reassembly; if it succeeds, proceed.
@@ -1000,7 +989,7 @@ found:
 	 * Find a segment which begins after this one does.
 	 */
 	for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt)
-		if (GETIP(q)->ip_off > ip->ip_off)
+		if (ntohs(GETIP(q)->ip_off) > ntohs(ip->ip_off))
 			break;
 
 	/*
@@ -1013,14 +1002,15 @@ found:
 	 * segment, then it's checksum is invalidated.
 	 */
 	if (p) {
-		i = GETIP(p)->ip_off + GETIP(p)->ip_len - ip->ip_off;
+		i = ntohs(GETIP(p)->ip_off) + ntohs(GETIP(p)->ip_len) -
+		    ntohs(ip->ip_off);
 		if (i > 0) {
-			if (i >= ip->ip_len)
+			if (i >= ntohs(ip->ip_len))
 				goto dropfrag;
 			m_adj(m, i);
 			m->m_pkthdr.csum_flags = 0;
-			ip->ip_off += i;
-			ip->ip_len -= i;
+			ip->ip_off = htons(ntohs(ip->ip_off) + i);
+			ip->ip_len = htons(ntohs(ip->ip_len) - i);
 		}
 		m->m_nextpkt = p->m_nextpkt;
 		p->m_nextpkt = m;
@@ -1033,12 +1023,13 @@ found:
 	 * While we overlap succeeding segments trim them or,
 	 * if they are completely covered, dequeue them.
 	 */
-	for (; q != NULL && ip->ip_off + ip->ip_len > GETIP(q)->ip_off;
-	     q = nq) {
-		i = (ip->ip_off + ip->ip_len) - GETIP(q)->ip_off;
-		if (i < GETIP(q)->ip_len) {
-			GETIP(q)->ip_len -= i;
-			GETIP(q)->ip_off += i;
+	for (; q != NULL && ntohs(ip->ip_off) + ntohs(ip->ip_len) >
+	    ntohs(GETIP(q)->ip_off); q = nq) {
+		i = (ntohs(ip->ip_off) + ntohs(ip->ip_len)) -
+		    ntohs(GETIP(q)->ip_off);
+		if (i < ntohs(GETIP(q)->ip_len)) {
+			GETIP(q)->ip_len = htons(ntohs(GETIP(q)->ip_len) - i);
+			GETIP(q)->ip_off = htons(ntohs(GETIP(q)->ip_off) + i);
 			m_adj(q, i);
 			q->m_pkthdr.csum_flags = 0;
 			break;
@@ -1062,14 +1053,14 @@ found:
 	 */
 	next = 0;
 	for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt) {
-		if (GETIP(q)->ip_off != next) {
+		if (ntohs(GETIP(q)->ip_off) != next) {
 			if (fp->ipq_nfrags > V_maxfragsperpacket) {
 				IPSTAT_ADD(ips_fragdropped, fp->ipq_nfrags);
 				ip_freef(head, fp);
 			}
 			goto done;
 		}
-		next += GETIP(q)->ip_len;
+		next += ntohs(GETIP(q)->ip_len);
 	}
 	/* Make sure the last packet didn't have the IP_MF flag */
 	if (p->m_flags & M_FRAG) {
@@ -1125,7 +1116,7 @@ found:
 	 * packet;  dequeue and discard fragment reassembly header.
 	 * Make header visible.
 	 */
-	ip->ip_len = (ip->ip_hl << 2) + next;
+	ip->ip_len = htons((ip->ip_hl << 2) + next);
 	ip->ip_src = fp->ipq_src;
 	ip->ip_dst = fp->ipq_dst;
 	TAILQ_REMOVE(head, fp, ipq_list);
@@ -1365,8 +1356,6 @@ u_char inetctlerrmap[PRC_NCMDS] = {
  *
  * The srcrt parameter indicates whether the packet is being forwarded
  * via a source route.
- *
- * IP header in host byte order.
  */
 void
 ip_forward(struct mbuf *m, int srcrt)
@@ -1436,7 +1425,7 @@ ip_forward(struct mbuf *m, int srcrt)
 		mcopy = NULL;
 	}
 	if (mcopy != NULL) {
-		mcopy->m_len = min(ip->ip_len, M_TRAILINGSPACE(mcopy));
+		mcopy->m_len = min(ntohs(ip->ip_len), M_TRAILINGSPACE(mcopy));
 		mcopy->m_pkthdr.len = mcopy->m_len;
 		m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
 	}
@@ -1564,7 +1553,7 @@ ip_forward(struct mbuf *m, int srcrt)
 			if (ia != NULL)
 				mtu = ia->ia_ifp->if_mtu;
 			else
-				mtu = ip_next_mtu(ip->ip_len, 0);
+				mtu = ip_next_mtu(ntohs(ip->ip_len), 0);
 		}
 		IPSTAT_INC(ips_cantfrag);
 		break;

Modified: head/sys/netinet/ip_ipsec.c
==============================================================================
--- head/sys/netinet/ip_ipsec.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_ipsec.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -259,7 +259,6 @@ ip_ipsec_output(struct mbuf **m, struct 
 {
 #ifdef IPSEC
 	struct secpolicy *sp = NULL;
-	struct ip *ip = mtod(*m, struct ip *);
 	struct tdb_ident *tdbi;
 	struct m_tag *mtag;
 	/*
@@ -324,9 +323,6 @@ ip_ipsec_output(struct mbuf **m, struct 
 			}
 		}
 
-		ip->ip_len = htons(ip->ip_len);
-		ip->ip_off = htons(ip->ip_off);
-
 		/*
 		 * Do delayed checksums now because we send before
 		 * this is done in the normal processing path.
@@ -337,6 +333,8 @@ ip_ipsec_output(struct mbuf **m, struct 
 		}
 #ifdef SCTP
 		if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) {
+			struct ip *ip = mtod(*m, struct ip *);
+
 			sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2));
 			(*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
 		}
@@ -351,8 +349,6 @@ ip_ipsec_output(struct mbuf **m, struct 
 			 * IPsec processing and return without error.
 			 */
 			*error = 0;
-			ip->ip_len = ntohs(ip->ip_len);
-			ip->ip_off = ntohs(ip->ip_off);
 			goto done;
 		}
 		/*

Modified: head/sys/netinet/ip_mroute.c
==============================================================================
--- head/sys/netinet/ip_mroute.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_mroute.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -1493,7 +1493,7 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp
 {
     struct ip  *ip = mtod(m, struct ip *);
     vifi_t vifi;
-    int plen = ip->ip_len;
+    int plen = ntohs(ip->ip_len);
 
     VIF_LOCK_ASSERT();
 
@@ -2376,10 +2376,7 @@ pim_register_prepare(struct ip *ip, stru
 
     /* Take care of delayed checksums */
     if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
-	/* XXX: in_delayed_cksum() expects net byte order */
-	ip->ip_len = htons(ip->ip_len);
 	in_delayed_cksum(m);
-	ip->ip_len = ntohs(ip->ip_len);
 	m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
     }
 
@@ -2401,10 +2398,8 @@ pim_register_prepare(struct ip *ip, stru
     /* Compute the MTU after the PIM Register encapsulation */
     mtu = 0xffff - sizeof(pim_encap_iphdr) - sizeof(pim_encap_pimhdr);
 
-    if (ip->ip_len <= mtu) {
+    if (ntohs(ip->ip_len) <= mtu) {
 	/* Turn the IP header into a valid one */
-	ip->ip_len = htons(ip->ip_len);
-	ip->ip_off = htons(ip->ip_off);
 	ip->ip_sum = 0;
 	ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2);
     } else {
@@ -2509,7 +2504,8 @@ pim_register_send_rp(struct ip *ip, stru
     ip_outer = mtod(mb_first, struct ip *);
     *ip_outer = pim_encap_iphdr;
     ip_outer->ip_id = ip_newid();
-    ip_outer->ip_len = len + sizeof(pim_encap_iphdr) + sizeof(pim_encap_pimhdr);
+    ip_outer->ip_len = htons(len + sizeof(pim_encap_iphdr) +
+	sizeof(pim_encap_pimhdr));
     ip_outer->ip_src = V_viftable[vifi].v_lcl_addr;
     ip_outer->ip_dst = rt->mfc_rp;
     /*
@@ -2517,8 +2513,8 @@ pim_register_send_rp(struct ip *ip, stru
      * IP_DF bit.
      */
     ip_outer->ip_tos = ip->ip_tos;
-    if (ntohs(ip->ip_off) & IP_DF)
-	ip_outer->ip_off |= IP_DF;
+    if (ip->ip_off & htons(IP_DF))
+	ip_outer->ip_off |= htons(IP_DF);
     pimhdr = (struct pim_encap_pimhdr *)((caddr_t)ip_outer
 					 + sizeof(pim_encap_iphdr));
     *pimhdr = pim_encap_pimhdr;
@@ -2571,7 +2567,7 @@ pim_input(struct mbuf *m, int off)
     struct ip *ip = mtod(m, struct ip *);
     struct pim *pim;
     int minlen;
-    int datalen = ip->ip_len;
+    int datalen = ntohs(ip->ip_len);
     int ip_tos;
     int iphlen = off;
 

Modified: head/sys/netinet/ip_options.c
==============================================================================
--- head/sys/netinet/ip_options.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_options.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -490,7 +490,7 @@ ip_insertoptions(struct mbuf *m, struct 
 	unsigned optlen;
 
 	optlen = opt->m_len - sizeof(p->ipopt_dst);
-	if (optlen + ip->ip_len > IP_MAXPACKET) {
+	if (optlen + ntohs(ip->ip_len) > IP_MAXPACKET) {
 		*phlen = 0;
 		return (m);		/* XXX should fail */
 	}
@@ -523,7 +523,7 @@ ip_insertoptions(struct mbuf *m, struct 
 	*phlen = sizeof(struct ip) + optlen;
 	ip->ip_v = IPVERSION;
 	ip->ip_hl = *phlen >> 2;
-	ip->ip_len += optlen;
+	ip->ip_len = htons(ntohs(ip->ip_len) + optlen);
 	return (m);
 }
 

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/ip_output.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -102,7 +102,6 @@ extern	struct protosw inetsw[];
 /*
  * IP output.  The packet in mbuf chain m contains a skeletal IP
  * header (with len, off, ttl, proto, tos, src, dst).
- * ip_len and ip_off are in host format.
  * The mbuf chain containing the packet will be freed.
  * The mbuf opt, if present, will not be freed.
  * If route ro is present and has ro_rt initialized, route lookup would be
@@ -175,6 +174,8 @@ ip_output(struct mbuf *m, struct mbuf *o
 			hlen = len; /* ip->ip_hl is updated above */
 	}
 	ip = mtod(m, struct ip *);
+	ip_len = ntohs(ip->ip_len);
+	ip_off = ntohs(ip->ip_off);
 
 	/*
 	 * Fill in IP header.  If we are not allowing fragmentation,
@@ -442,7 +443,7 @@ again:
 	 * packet or packet fragments, unless ALTQ is enabled on the given
 	 * interface in which case packetdrop should be done by queueing.
 	 */
-	n = ip->ip_len / mtu + 1; /* how many fragments ? */
+	n = ip_len / mtu + 1; /* how many fragments ? */
 	if (
 #ifdef ALTQ
 	    (!ALTQ_IS_ENABLED(&ifp->if_snd)) &&
@@ -469,7 +470,7 @@ again:
 			goto bad;
 		}
 		/* don't allow broadcast messages to be fragmented */
-		if (ip->ip_len > mtu) {
+		if (ip_len > mtu) {
 			error = EMSGSIZE;
 			goto bad;
 		}
@@ -502,12 +503,6 @@ sendit:
 	hlen = ip->ip_hl << 2;
 #endif /* IPSEC */
 
-	/*
-	 * To network byte order. pfil(9) hooks and ip_fragment() expect this.
-	 */
-	ip->ip_len = htons(ip->ip_len);
-	ip->ip_off = htons(ip->ip_off);
-
 	/* Jump over all PFIL processing if hooks are not active. */
 	if (!PFIL_HOOKED(&V_inet_pfil_hook))
 		goto passout;
@@ -544,8 +539,6 @@ sendit:
 		} else {
 			if (ia != NULL)
 				ifa_free(&ia->ia_ifa);
-			ip->ip_len = ntohs(ip->ip_len);
-			ip->ip_off = ntohs(ip->ip_off);
 			goto again;	/* Redo the routing table lookup. */
 		}
 	}
@@ -579,16 +572,11 @@ sendit:
 		m_tag_delete(m, fwd_tag);
 		if (ia != NULL)
 			ifa_free(&ia->ia_ifa);
-		ip->ip_len = ntohs(ip->ip_len);
-		ip->ip_off = ntohs(ip->ip_off);
 		goto again;
 	}
 #endif /* IPFIREWALL_FORWARD */
 
 passout:
-	ip_len = ntohs(ip->ip_len);
-	ip_off = ntohs(ip->ip_off);
-
 	/* 127/8 must not appear on wire - RFC1122. */
 	if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
 	    (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
@@ -1295,8 +1283,6 @@ ip_ctloutput(struct socket *so, struct s
  * calls the output routine of the loopback "driver", but with an interface
  * pointer that might NOT be a loopback interface -- evil, but easier than
  * replicating that code here.
- *
- * IP header in host byte order.
  */
 static void
 ip_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in *dst,
@@ -1313,9 +1299,6 @@ ip_mloopback(struct ifnet *ifp, struct m
 	if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
 		copym = m_pullup(copym, hlen);
 	if (copym != NULL) {
-		ip = mtod(copym, struct ip *);
-		ip->ip_len = htons(ip->ip_len);
-		ip->ip_off = htons(ip->ip_off);
 		/* If needed, compute the checksum and mark it as valid. */
 		if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
 			in_delayed_cksum(copym);
@@ -1328,6 +1311,7 @@ ip_mloopback(struct ifnet *ifp, struct m
 		 * We don't bother to fragment if the IP length is greater
 		 * than the interface's MTU.  Can this possibly matter?
 		 */
+		ip = mtod(copym, struct ip *);
 		ip->ip_sum = 0;
 		ip->ip_sum = in_cksum(copym, hlen);
 #if 1 /* XXX */

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/raw_ip.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -292,7 +292,8 @@ rip_input(struct mbuf *m, int off)
 	 * not modify the packet except for some
 	 * byte order swaps.
 	 */
-	ip->ip_len += off;
+	ip->ip_len = ntohs(ip->ip_len) + off;
+	ip->ip_off = ntohs(ip->ip_off);
 
 	hash = INP_PCBHASH_RAW(proto, ip->ip_src.s_addr,
 	    ip->ip_dst.s_addr, V_ripcbinfo.ipi_hashmask);
@@ -449,11 +450,11 @@ rip_output(struct mbuf *m, struct socket
 		ip = mtod(m, struct ip *);
 		ip->ip_tos = inp->inp_ip_tos;
 		if (inp->inp_flags & INP_DONTFRAG)
-			ip->ip_off = IP_DF;
+			ip->ip_off = htons(IP_DF);
 		else
-			ip->ip_off = 0;
+			ip->ip_off = htons(0);
 		ip->ip_p = inp->inp_ip_p;
-		ip->ip_len = m->m_pkthdr.len;
+		ip->ip_len = htons(m->m_pkthdr.len);
 		ip->ip_src = inp->inp_laddr;
 		if (jailed(inp->inp_cred)) {
 			/*
@@ -505,6 +506,12 @@ rip_output(struct mbuf *m, struct socket
 			ip->ip_id = ip_newid();
 
 		/*
+		 * Applications on raw sockets expect host byte order.
+		 */
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
+
+		/*
 		 * XXX prevent ip_output from overwriting header fields.
 		 */
 		flags |= IP_RAWOUTPUT;

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/sctp_input.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -6038,7 +6038,7 @@ sctp_input_with_port(struct mbuf *i_pak,
 	dst.sin_len = sizeof(struct sockaddr_in);
 	dst.sin_port = sh->dest_port;
 	dst.sin_addr = ip->ip_dst;
-	length = ip->ip_len + iphlen;
+	length = ntohs(ip->ip_len) + iphlen;
 	/* Validate mbuf chain length with IP payload length. */
 	if (SCTP_HEADER_LEN(m) != length) {
 		SCTPDBG(SCTP_DEBUG_INPUT1,

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/sctp_output.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -3980,15 +3980,15 @@ sctp_lowlevel_chunk_output(struct sctp_i
 				tos_value |= sctp_get_ect(stcb);
 			}
 			if ((nofragment_flag) && (port == 0)) {
-				ip->ip_off = IP_DF;
+				ip->ip_off = htons(IP_DF);
 			} else
-				ip->ip_off = 0;
+				ip->ip_off = htons(0);
 
 			/* FreeBSD has a function for ip_id's */
 			ip->ip_id = ip_newid();
 
 			ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
-			ip->ip_len = packet_length;
+			ip->ip_len = htons(packet_length);
 			ip->ip_tos = tos_value;
 			if (port) {
 				ip->ip_p = IPPROTO_UDP;
@@ -10991,7 +10991,7 @@ sctp_send_resp_msg(struct sockaddr *src,
 				udp->uh_sum = 0;
 			}
 		}
-		ip->ip_len = len;
+		ip->ip_len = htons(len);
 		if (port) {
 #if defined(SCTP_WITH_NO_CSUM)
 			SCTP_STAT_INCR(sctps_sendnocrc);

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/sctp_usrreq.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -180,7 +180,7 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
 		SCTP_TCB_UNLOCK(stcb);
 		return;
 	}
-	totsz = ip->ip_len;
+	totsz = ntohs(ip->ip_len);
 
 	nxtsz = ntohs(icmph->icmp_nextmtu);
 	if (nxtsz == 0) {

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/sctputil.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -6821,7 +6821,7 @@ sctp_recv_udp_tunneled_packet(struct mbu
 	switch (iph->ip_v) {
 #ifdef INET
 	case IPVERSION:
-		iph->ip_len -= sizeof(struct udphdr);
+		iph->ip_len = ntohs(htons(iph->ip_len) - sizeof(struct udphdr));
 		sctp_input_with_port(m, off, port);
 		break;
 #endif

Modified: head/sys/netinet/siftr.c
==============================================================================
--- head/sys/netinet/siftr.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/siftr.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -952,7 +952,8 @@ siftr_chkpkt(void *arg, struct mbuf **m,
 			 * the mbuf cluster "at" at offset "offset" bytes from
 			 * the beginning of the "at" mbuf's data pointer.
 			 */
-			th->th_sum = in_cksum_skip(*m, ip->ip_len, ip_hl);
+			th->th_sum = in_cksum_skip(*m, ntohs(ip->ip_len),
+			    ip_hl);
 		}
 
 		/*

Modified: head/sys/netinet/tcp_debug.c
==============================================================================
--- head/sys/netinet/tcp_debug.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/tcp_debug.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -175,11 +175,10 @@ tcp_trace(short act, short ostate, struc
 #ifdef INET6
 		    isipv6 ? ntohs(((struct ip6_hdr *)ipgen)->ip6_plen) :
 #endif
-		    ((struct ip *)ipgen)->ip_len;
+		    ntohs(((struct ip *)ipgen)->ip_len);
 		if (act == TA_OUTPUT) {
 			seq = ntohl(seq);
 			ack = ntohl(ack);
-			len = ntohs((u_short)len);
 		}
 		if (act == TA_OUTPUT)
 			len -= sizeof (struct tcphdr);

Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/tcp_input.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -528,9 +528,6 @@ tcp_input(struct mbuf *m, int off0)
 {
 	struct tcphdr *th = NULL;
 	struct ip *ip = NULL;
-#ifdef INET
-	struct ipovly *ipov;
-#endif
 	struct inpcb *inp = NULL;
 	struct tcpcb *tp = NULL;
 	struct socket *so = NULL;
@@ -643,32 +640,27 @@ tcp_input(struct mbuf *m, int off0)
 			}
 		}
 		ip = mtod(m, struct ip *);
-		ipov = (struct ipovly *)ip;
 		th = (struct tcphdr *)((caddr_t)ip + off0);
-		tlen = ip->ip_len;
+		tlen = ntohs(ip->ip_len);
 
 		if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
 			if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
 				th->th_sum = m->m_pkthdr.csum_data;
 			else
 				th->th_sum = in_pseudo(ip->ip_src.s_addr,
-						ip->ip_dst.s_addr,
-						htonl(m->m_pkthdr.csum_data +
-							ip->ip_len +
-							IPPROTO_TCP));
+				    ip->ip_dst.s_addr,
+				    htonl(m->m_pkthdr.csum_data + tlen +
+				    IPPROTO_TCP));
 			th->th_sum ^= 0xffff;
-#ifdef TCPDEBUG
-			ipov->ih_len = (u_short)tlen;
-			ipov->ih_len = htons(ipov->ih_len);
-#endif
 		} else {
+			struct ipovly *ipov = (struct ipovly *)ip;
+
 			/*
 			 * Checksum extended TCP header and data.
 			 */
-			len = sizeof (struct ip) + tlen;
+			len = off0 + tlen;
 			bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
-			ipov->ih_len = (u_short)tlen;
-			ipov->ih_len = htons(ipov->ih_len);
+			ipov->ih_len = htons(tlen);
 			th->th_sum = in_cksum(m, len);
 		}
 		if (th->th_sum) {
@@ -721,7 +713,6 @@ tcp_input(struct mbuf *m, int off0)
 					return;
 				}
 				ip = mtod(m, struct ip *);
-				ipov = (struct ipovly *)ip;
 				th = (struct tcphdr *)((caddr_t)ip + off0);
 			}
 		}

Modified: head/sys/netinet/tcp_output.c
==============================================================================
--- head/sys/netinet/tcp_output.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/tcp_output.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -1239,7 +1239,7 @@ timer:
 	struct route ro;
 
 	bzero(&ro, sizeof(ro));
-	ip->ip_len = m->m_pkthdr.len;
+	ip->ip_len = htons(m->m_pkthdr.len);
 #ifdef INET6
 	if (tp->t_inpcb->inp_vflag & INP_IPV6PROTO)
 		ip->ip_ttl = in6_selecthlim(tp->t_inpcb, NULL);
@@ -1253,7 +1253,7 @@ timer:
 	 * NB: Don't set DF on small MTU/MSS to have a safe fallback.
 	 */
 	if (V_path_mtu_discovery && tp->t_maxopd > V_tcp_minmss)
-		ip->ip_off |= IP_DF;
+		ip->ip_off |= htons(IP_DF);
 
 	error = ip_output(m, tp->t_inpcb->inp_options, &ro,
 	    ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0,

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/tcp_subr.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -584,10 +584,10 @@ tcp_respond(struct tcpcb *tp, void *ipge
 #ifdef INET
 	{
 		tlen += sizeof (struct tcpiphdr);
-		ip->ip_len = tlen;
+		ip->ip_len = htons(tlen);
 		ip->ip_ttl = V_ip_defttl;
 		if (V_path_mtu_discovery)
-			ip->ip_off |= IP_DF;
+			ip->ip_off |= htons(IP_DF);
 	}
 #endif
 	m->m_len = tlen;
@@ -1398,12 +1398,11 @@ tcp_ctlinput(int cmd, struct sockaddr *s
 					    /*
 					     * If no alternative MTU was
 					     * proposed, try the next smaller
-					     * one.  ip->ip_len has already
-					     * been swapped in icmp_input().
+					     * one.
 					     */
 					    if (!mtu)
-						mtu = ip_next_mtu(ip->ip_len,
-						 1);
+						mtu = ip_next_mtu(
+						 ntohs(ip->ip_len), 1);
 					    if (mtu < V_tcp_minmss
 						 + sizeof(struct tcpiphdr))
 						mtu = V_tcp_minmss

Modified: head/sys/netinet/tcp_syncache.c
==============================================================================
--- head/sys/netinet/tcp_syncache.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/tcp_syncache.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -1395,7 +1395,7 @@ syncache_respond(struct syncache *sc)
 		ip = mtod(m, struct ip *);
 		ip->ip_v = IPVERSION;
 		ip->ip_hl = sizeof(struct ip) >> 2;
-		ip->ip_len = tlen;
+		ip->ip_len = htons(tlen);
 		ip->ip_id = 0;
 		ip->ip_off = 0;
 		ip->ip_sum = 0;
@@ -1413,7 +1413,7 @@ syncache_respond(struct syncache *sc)
 		 *	2) the SCF_UNREACH flag has been set
 		 */
 		if (V_path_mtu_discovery && ((sc->sc_flags & SCF_UNREACH) == 0))
-		       ip->ip_off |= IP_DF;
+		       ip->ip_off |= htons(IP_DF);
 
 		th = (struct tcphdr *)(ip + 1);
 	}
@@ -1473,7 +1473,7 @@ syncache_respond(struct syncache *sc)
 			ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) + optlen);
 		else
 #endif
-			ip->ip_len += optlen;
+			ip->ip_len = htons(ntohs(ip->ip_len) + optlen);
 	} else
 		optlen = 0;
 

Modified: head/sys/netinet/tcp_timewait.c
==============================================================================
--- head/sys/netinet/tcp_timewait.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/tcp_timewait.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -593,9 +593,9 @@ tcp_twrespond(struct tcptw *tw, int flag
 		m->m_pkthdr.csum_flags = CSUM_TCP;
 		th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
 		    htons(sizeof(struct tcphdr) + optlen + IPPROTO_TCP));
-		ip->ip_len = m->m_pkthdr.len;
+		ip->ip_len = htons(m->m_pkthdr.len);
 		if (V_path_mtu_discovery)
-			ip->ip_off |= IP_DF;
+			ip->ip_off |= htons(IP_DF);
 		error = ip_output(m, inp->inp_options, NULL,
 		    ((tw->tw_so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0),
 		    NULL, inp);

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Mon Oct 22 20:17:58 2012	(r241912)
+++ head/sys/netinet/udp_usrreq.c	Mon Oct 22 21:09:03 2012	(r241913)
@@ -338,7 +338,7 @@ udp_input(struct mbuf *m, int off)
 	struct udphdr *uh;
 	struct ifnet *ifp;
 	struct inpcb *inp;
-	int len;
+	uint16_t len, ip_len;
 	struct ip save_ip;
 	struct sockaddr_in udp_in;
 #ifdef IPFIREWALL_FORWARD
@@ -392,13 +392,13 @@ udp_input(struct mbuf *m, int off)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210222109.q9ML94e7007834>