diff options
author | ume <ume@FreeBSD.org> | 2005-07-25 12:31:43 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2005-07-25 12:31:43 +0000 |
commit | da2cf62b280b8450d5f8e0d810e810cdcc59a8c0 (patch) | |
tree | 5a678f63b25976c30f74f3bad9edb6f708c52930 /sys/netinet6/ipsec.c | |
parent | 59bc7b0da19f008a39ee92249e92f8246f04394e (diff) | |
download | FreeBSD-src-da2cf62b280b8450d5f8e0d810e810cdcc59a8c0.zip FreeBSD-src-da2cf62b280b8450d5f8e0d810e810cdcc59a8c0.tar.gz |
scope cleanup. with this change
- most of the kernel code will not care about the actual encoding of
scope zone IDs and won't touch "s6_addr16[1]" directly.
- similarly, most of the kernel code will not care about link-local
scoped addresses as a special case.
- scope boundary check will be stricter. For example, the current
*BSD code allows a packet with src=::1 and dst=(some global IPv6
address) to be sent outside of the node, if the application do:
s = socket(AF_INET6);
bind(s, "::1");
sendto(s, some_global_IPv6_addr);
This is clearly wrong, since ::1 is only meaningful within a single
node, but the current implementation of the *BSD kernel cannot
reject this attempt.
Submitted by: JINMEI Tatuya <jinmei__at__isl.rdc.toshiba.co.jp>
Obtained from: KAME
Diffstat (limited to 'sys/netinet6/ipsec.c')
-rw-r--r-- | sys/netinet6/ipsec.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c index 63e02d0..aa710a2 100644 --- a/sys/netinet6/ipsec.c +++ b/sys/netinet6/ipsec.c @@ -73,6 +73,7 @@ #include <netinet/ip6.h> #ifdef INET6 #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #endif #include <netinet/in_pcb.h> #ifdef INET6 @@ -1143,14 +1144,14 @@ ipsec6_setspidx_ipaddr(m, spidx) bzero(sin6, sizeof(*sin6)); sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); - in6_recoverscope(sin6, &ip6->ip6_src, NULL); + sin6->sin6_addr = ip6->ip6_src; spidx->prefs = sizeof(struct in6_addr) << 3; sin6 = (struct sockaddr_in6 *)&spidx->dst; bzero(sin6, sizeof(*sin6)); sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); - in6_recoverscope(sin6, &ip6->ip6_dst, NULL); + sin6->sin6_addr = ip6->ip6_dst; spidx->prefd = sizeof(struct in6_addr) << 3; return 0; @@ -2177,9 +2178,11 @@ ipsec6_encapsulate(m, sav) struct mbuf *m; struct secasvar *sav; { + struct sockaddr_in6 sa6; struct ip6_hdr *oip6; struct ip6_hdr *ip6; size_t plen; + int error; /* can't tunnel between different AFs */ if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family @@ -2237,10 +2240,17 @@ ipsec6_encapsulate(m, sav) /* ip6->ip6_plen will be updated in ip6_output() */ } ip6->ip6_nxt = IPPROTO_IPV6; - in6_embedscope(&ip6->ip6_src, - (struct sockaddr_in6 *)&sav->sah->saidx.src, NULL, NULL); - in6_embedscope(&ip6->ip6_dst, - (struct sockaddr_in6 *)&sav->sah->saidx.dst, NULL, NULL); + + sa6 = *(struct sockaddr_in6 *)&sav->sah->saidx.src; + if ((error = sa6_embedscope(&sa6, 0)) != 0) + return (error); + ip6->ip6_src = sa6.sin6_addr; + + sa6 = *(struct sockaddr_in6 *)&sav->sah->saidx.dst; + if ((error = sa6_embedscope(&sa6, 0)) != 0) + return (error); + ip6->ip6_dst = sa6.sin6_addr; + ip6->ip6_hlim = IPV6_DEFHLIM; /* XXX Should ip6_src be updated later ? */ @@ -2833,14 +2843,14 @@ ipsec6_checksa(isr, state, tunnel) sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; sin6->sin6_port = IPSEC_PORT_ANY; - in6_recoverscope(sin6, &ip6->ip6_src, NULL); + sin6->sin6_addr = ip6->ip6_src; } sin6 = (struct sockaddr_in6 *)&saidx.dst; if (sin6->sin6_len == 0 || tunnel) { sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; sin6->sin6_port = IPSEC_PORT_ANY; - in6_recoverscope(sin6, &ip6->ip6_dst, NULL); + sin6->sin6_addr = ip6->ip6_dst; } return key_checkrequest(isr, &saidx); |