diff options
Diffstat (limited to 'sys/netinet6/in6_cksum.c')
-rw-r--r-- | sys/netinet6/in6_cksum.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/sys/netinet6/in6_cksum.c b/sys/netinet6/in6_cksum.c index 50e14bf..1fd9451 100644 --- a/sys/netinet6/in6_cksum.c +++ b/sys/netinet6/in6_cksum.c @@ -66,6 +66,7 @@ #include <sys/systm.h> #include <netinet/in.h> #include <netinet/ip6.h> +#include <netinet6/scope6_var.h> #include <net/net_osdep.h> @@ -97,6 +98,7 @@ in6_cksum(m, nxt, off, len) int mlen = 0; int byte_swapped = 0; struct ip6_hdr *ip6; + struct in6_addr in6; union { u_int16_t phs[4]; struct { @@ -126,22 +128,27 @@ in6_cksum(m, nxt, off, len) * First create IP6 pseudo header and calculate a summary. */ ip6 = mtod(m, struct ip6_hdr *); - w = (u_int16_t *)&ip6->ip6_src; uph.ph.ph_len = htonl(len); uph.ph.ph_nxt = nxt; - /* IPv6 source address */ - sum += w[0]; - if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) - sum += w[1]; - sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5]; - sum += w[6]; sum += w[7]; + /* + * IPv6 source address. + * XXX: we'd like to avoid copying the address, but we can't due to + * the possibly embedded scope zone ID. + */ + in6 = ip6->ip6_src; + in6_clearscope(&in6); + w = (u_int16_t *)&in6; + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; + /* IPv6 destination address */ - sum += w[8]; - if (!IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) - sum += w[9]; - sum += w[10]; sum += w[11]; sum += w[12]; sum += w[13]; - sum += w[14]; sum += w[15]; + in6 = ip6->ip6_dst; + in6_clearscope(&in6); + w = (u_int16_t *)&in6; + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; + /* Payload length and upper layer identifier */ sum += uph.phs[0]; sum += uph.phs[1]; sum += uph.phs[2]; sum += uph.phs[3]; |