diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index 1650fcbdc7a2..63b96a85761c 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 0568bd748105..eb9c1ad85517 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 1b27a7fc0965..848325b75a0b 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 54a66b6930ca..5083f6ff3ff6 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 291ef9a961f5..7d070fdae3a6 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 08c2f6e1b4d2..3be64b19fc49 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 a91062bfa017..0341207174ca 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 2576cf566cd5..9a4a6829213b 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 91fcad6a5713..722879b7442b 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