summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_mroute.c
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2000-09-01 12:33:03 +0000
committerru <ru@FreeBSD.org>2000-09-01 12:33:03 +0000
commit326b00612baa3c05ca8f66d72ca7e5269d299815 (patch)
tree26cc2393e38f3564148847d7f4c5ac5ea7bf2e82 /sys/netinet/ip_mroute.c
parent5b3f190e28307c0d57ae5574c15bd27e3ef1a3f1 (diff)
downloadFreeBSD-src-326b00612baa3c05ca8f66d72ca7e5269d299815.zip
FreeBSD-src-326b00612baa3c05ca8f66d72ca7e5269d299815.tar.gz
Fixed broken ICMP error generation, unified conversion of IP header
fields between host and network byte order. The details: o icmp_error() now does not add IP header length. This fixes the problem when icmp_error() is called from ip_forward(). In this case the ip_len of the original IP datagram returned with ICMP error was wrong. o icmp_error() expects all three fields, ip_len, ip_id and ip_off in host byte order, so DTRT and convert these fields back to network byte order before sending a message. This fixes the problem described in PR 16240 and PR 20877 (ip_id field was returned in host byte order). o ip_ttl decrement operation in ip_forward() was moved down to make sure that it does not corrupt the copy of original IP datagram passed later to icmp_error(). o A copy of original IP datagram in ip_forward() was made a read-write, independent copy. This fixes the problem I first reported to Garrett Wollman and Bill Fenner and later put in audit trail of PR 16240: ip_output() (not always) converts fields of original datagram to network byte order, but because copy (mcopy) and its original (m) most likely share the same mbuf cluster, ip_output()'s manipulations on original also corrupted the copy. o ip_output() now expects all three fields, ip_len, ip_off and (what is significant) ip_id in host byte order. It was a headache for years that ip_id was handled differently. The only compatibility issue here is the raw IP socket interface with IP_HDRINCL socket option set and a non-zero ip_id field, but ip.4 manual page was unclear on whether in this case ip_id field should be in host or network byte order.
Diffstat (limited to 'sys/netinet/ip_mroute.c')
-rw-r--r--sys/netinet/ip_mroute.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 1d165f5..73ab039 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1581,7 +1581,7 @@ encap_send(ip, vifp, m)
*/
ip_copy = mtod(mb_copy, struct ip *);
*ip_copy = multicast_encap_iphdr;
- ip_copy->ip_id = htons(ip_id++);
+ ip_copy->ip_id = ip_id++;
ip_copy->ip_len += len;
ip_copy->ip_src = vifp->v_lcl_addr;
ip_copy->ip_dst = vifp->v_rmt_addr;
@@ -1592,6 +1592,7 @@ encap_send(ip, vifp, m)
ip = (struct ip *)((caddr_t)ip_copy + sizeof(multicast_encap_iphdr));
--ip->ip_ttl;
HTONS(ip->ip_len);
+ HTONS(ip->ip_id);
HTONS(ip->ip_off);
ip->ip_sum = 0;
mb_copy->m_data += sizeof(multicast_encap_iphdr);
OpenPOWER on IntegriCloud