summaryrefslogtreecommitdiffstats
path: root/src/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-05-07 14:29:44 +0100
committerRoy Marples <roy@marples.name>2020-05-07 14:29:44 +0100
commit060f5a9e936bddea5bca2eb082f8fe6f32629e61 (patch)
tree5e027c6885bf8dbbeb524bcf5ee11bb55b8e59bd /src/ipv6.c
parent36a65e2c921742085d89afc4d2eecd9466fe5abc (diff)
downloaddhcpcd-060f5a9e936bddea5bca2eb082f8fe6f32629e61.tar.xz
inet6: Move BSD get/set scope function to ipv6 for general use
It seems that FreeBSD doesn't allow binding to scoped addresses, so let's use our functions everwhere rather than directly setting scope.
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)