summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ipsec.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2005-07-25 12:31:43 +0000
committerume <ume@FreeBSD.org>2005-07-25 12:31:43 +0000
commitda2cf62b280b8450d5f8e0d810e810cdcc59a8c0 (patch)
tree5a678f63b25976c30f74f3bad9edb6f708c52930 /sys/netinet6/ipsec.c
parent59bc7b0da19f008a39ee92249e92f8246f04394e (diff)
downloadFreeBSD-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.c26
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);
OpenPOWER on IntegriCloud