diff options
author | Lawrence Teo <lteo@cvs.openbsd.org> | 2013-10-25 18:44:37 +0000 |
---|---|---|
committer | Lawrence Teo <lteo@cvs.openbsd.org> | 2013-10-25 18:44:37 +0000 |
commit | bee20e9a4e2f481f6762d7a8ccc33627df1c9893 (patch) | |
tree | b5d78f92ba7ca17d1bce6b0d9b92f4bc4e1f01b8 /sys/netinet | |
parent | 5eec9bb66b1c00f80fd4a94af33885eb2bc5762b (diff) |
Don't let in_proto_cksum_out() assume that the ICMP checksum field is
always in the first mbuf of an mbuf chain.
Thanks to henning@ and bluhm@ for their work on checksums at b2k13,
which allowed this fix to be very straightforward compared to earlier
versions.
help/feedback bluhm@ henning@
OK henning@ naddy@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_output.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 0da7d4a9cf2..9a2372f22e1 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.249 2013/10/20 13:44:23 henning Exp $ */ +/* $OpenBSD: ip_output.c,v 1.250 2013/10/25 18:44:36 lteo Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -2070,6 +2070,10 @@ in_delayed_cksum(struct mbuf *m) offset += offsetof(struct udphdr, uh_sum); break; + case IPPROTO_ICMP: + offset += offsetof(struct icmp, icmp_cksum); + break; + default: return; } @@ -2115,14 +2119,7 @@ in_proto_cksum_out(struct mbuf *m, struct ifnet *ifp) m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */ } } else if (m->m_pkthdr.csum_flags & M_ICMP_CSUM_OUT) { - struct ip *ip = mtod(m, struct ip *); - int hlen; - struct icmp *icp; - - hlen = ip->ip_hl << 2; - icp = (struct icmp *)(mtod(m, caddr_t) + hlen); - icp->icmp_cksum = in4_cksum(m, 0, hlen, - ntohs(ip->ip_len) - hlen); + in_delayed_cksum(m); m->m_pkthdr.csum_flags &= ~M_ICMP_CSUM_OUT; /* Clear */ } } |