diff options
author | ru <ru@FreeBSD.org> | 2000-09-01 12:33:03 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2000-09-01 12:33:03 +0000 |
commit | 326b00612baa3c05ca8f66d72ca7e5269d299815 (patch) | |
tree | 26cc2393e38f3564148847d7f4c5ac5ea7bf2e82 /sys/netinet/ip_icmp.c | |
parent | 5b3f190e28307c0d57ae5574c15bd27e3ef1a3f1 (diff) | |
download | FreeBSD-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_icmp.c')
-rw-r--r-- | sys/netinet/ip_icmp.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 58a4915..91c0bc0 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -191,7 +191,13 @@ icmp_error(n, type, code, dest, destifp) icp->icmp_code = code; bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen); nip = &icp->icmp_ip; - nip->ip_len = htons((u_short)(nip->ip_len + oiplen)); + + /* + * Convert fields to network representation. + */ + HTONS(nip->ip_len); + HTONS(nip->ip_id); + HTONS(nip->ip_off); /* * Now, copy old ip header (without options) |