summaryrefslogtreecommitdiffstats
path: root/src/ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipv6.c')
-rw-r--r--src/ipv6.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/ipv6.c b/src/ipv6.c
index 8ecdf622..4ea61019 100644
--- a/src/ipv6.c
+++ b/src/ipv6.c
@@ -1532,6 +1532,44 @@ ipv6_tryaddlinklocal(struct interface *ifp)
return ipv6_addlinklocal(ifp);
}
+void
+ipv6_setscope(struct sockaddr_in6 *sin, unsigned int ifindex)
+{
+
+#ifdef __KAME__
+ /* KAME based systems want to store the scope inside the sin6_addr
+ * for link local addresses */
+ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) {
+ uint16_t scope = htons((uint16_t)ifindex);
+ memcpy(&sin->sin6_addr.s6_addr[2], &scope,
+ sizeof(scope));
+ }
+ sin->sin6_scope_id = 0;
+#else
+ if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
+ sin->sin6_scope_id = ifindex;
+ else
+ sin->sin6_scope_id = 0;
+#endif
+}
+
+unsigned int
+ipv6_getscope(const struct sockaddr_in6 *sin)
+{
+#ifdef __KAME__
+ uint16_t scope;
+#endif
+
+ if (!IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
+ return 0;
+#ifdef __KAME__
+ memcpy(&scope, &sin->sin6_addr.s6_addr[2], sizeof(scope));
+ return (unsigned int)ntohs(scope);
+#else
+ return (unsigned int)sin->sin6_scope_id;
+#endif
+}
+
struct ipv6_addr *
ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
uint8_t prefix_len, unsigned int flags)