summaryrefslogtreecommitdiff
path: root/sys/netinet6/in6_pcb.c
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-06-13 10:12:02 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-06-13 10:12:02 +0000
commit2a1a93444daf975435e69cd08e072311261d6354 (patch)
treee24d1167c9ba5ddb40875ccc4cb13b25338966fb /sys/netinet6/in6_pcb.c
parentf43a60883364695d1eb6ee3d262e4313aa44ff4f (diff)
allow link-local IPv6 addres in in6_pcbbind.
Diffstat (limited to 'sys/netinet6/in6_pcb.c')
-rw-r--r--sys/netinet6/in6_pcb.c50
1 files changed, 18 insertions, 32 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 5db6a39a412..ba6e7fb3834 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_pcb.c,v 1.14 2000/06/03 13:04:39 itojun Exp $ */
+/* $OpenBSD: in6_pcb.c,v 1.15 2000/06/13 10:12:01 itojun Exp $ */
/*
%%% copyright-nrl-95
@@ -153,6 +153,13 @@ in6_pcbbind(inp, nam)
*/
if (sin6->sin6_family != AF_INET6)
return EAFNOSUPPORT;
+
+ /* KAME hack: embed scopeid */
+ if (in6_embedscope(&sin6->sin6_addr, sin6, inp, NULL) != 0)
+ return EINVAL;
+ /* this must be cleared for ifa_ifwithaddr() */
+ sin6->sin6_scope_id = 0;
+
lport = sin6->sin6_port;
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
@@ -383,10 +390,10 @@ in6_pcbconnect(inp, nam)
{
struct in6_addr *in6a = NULL;
struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *);
- struct in6_pktinfo *pi;
struct ifnet *ifp = NULL; /* outgoing interface */
int error = 0;
struct in6_addr mapped;
+ struct sockaddr_in6 tmp;
(void)&in6a; /* XXX fool gcc */
@@ -408,36 +415,15 @@ in6_pcbconnect(inp, nam)
return EINVAL;
}
- /*
- * If the scope of the destination is link-local, embed the interface
- * index in the address.
- */
- if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
- /* XXX boundary check is assumed to be already done. */
- /* XXX sin6_scope_id is weaker than advanced-api. */
- if (inp->inp_outputopts6 &&
- (pi = inp->inp_outputopts6->ip6po_pktinfo) &&
- pi->ipi6_ifindex) {
- sin6->sin6_addr.s6_addr16[1] = htons(pi->ipi6_ifindex);
- ifp = ifindex2ifnet[pi->ipi6_ifindex];
- }
- else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
- inp->inp_moptions6 &&
- inp->inp_moptions6->im6o_multicast_ifp) {
- sin6->sin6_addr.s6_addr16[1] =
- htons(inp->inp_moptions6->im6o_multicast_ifp->if_index);
- ifp = ifindex2ifnet[inp->inp_moptions6->im6o_multicast_ifp->if_index];
- } else if (sin6->sin6_scope_id) {
- /* boundary check */
- if (sin6->sin6_scope_id < 0
- || if_index < sin6->sin6_scope_id) {
- return ENXIO; /* XXX EINVAL? */
- }
- sin6->sin6_addr.s6_addr16[1]
- = htons(sin6->sin6_scope_id & 0xffff);/*XXX*/
- ifp = ifindex2ifnet[sin6->sin6_scope_id];
- }
- }
+ /* protect *sin6 from overwrites */
+ tmp = *sin6;
+ sin6 = &tmp;
+
+ /* KAME hack: embed scopeid */
+ if (in6_embedscope(&sin6->sin6_addr, sin6, inp, &ifp) != 0)
+ return EINVAL;
+ /* this must be cleared for ifa_ifwithaddr() */
+ sin6->sin6_scope_id = 0;
/* Source address selection. */
if (IN6_IS_ADDR_V4MAPPED(&inp->inp_laddr6)