ifo->options |= DHCPCD_SLAACPRIVATE;
else
ifo->options &= ~DHCPCD_SLAACPRIVATE;
+ if (strcmp(arg, "token") == 0) {
+ if (np == NULL) {
+ logerrx("slaac token: no token specified");
+ return -1;
+ }
+ arg = np;
+ np = strwhite(np);
+ if (np != NULL) {
+ *np++ = '\0';
+ np = strskipwhite(np);
+ }
+ if (inet_pton(AF_INET6, arg, &ifo->token) != 1) {
+ logerrx("slaac token: invalid token");
+ return -1;
+ }
+ }
if (np != NULL &&
(strcmp(np, "temp") == 0 || strcmp(np, "temporary") == 0))
ifo->options |= DHCPCD_SLAACTEMP;
}
#endif
-int
-ipv6_makeaddr(struct in6_addr *addr, struct interface *ifp,
- const struct in6_addr *prefix, int prefix_len, unsigned int flags)
-{
- const struct ipv6_addr *ap;
- int dad;
-
- if (prefix_len < 0 || prefix_len > 120) {
- errno = EINVAL;
- return -1;
- }
-
-#ifdef IPV6_AF_TEMPORARY
- if (flags & IPV6_AF_TEMPORARY)
- return ipv6_maketemporaryaddress(addr, prefix, prefix_len, ifp);
-#else
- UNUSED(flags);
-#endif
-
- if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
- dad = 0;
- if (ipv6_makestableprivate(addr,
- prefix, prefix_len, ifp, &dad) == -1)
- return -1;
- return dad;
- }
-
- if (prefix_len > 64) {
- errno = EINVAL;
- return -1;
- }
- if ((ap = ipv6_linklocal(ifp)) == NULL) {
- /* We delay a few functions until we get a local-link address
- * so this should never be hit. */
- errno = ENOENT;
- return -1;
- }
-
- /* Make the address from the first local-link address */
- memcpy(addr, prefix, sizeof(*prefix));
- addr->s6_addr32[2] = ap->addr.s6_addr32[2];
- addr->s6_addr32[3] = ap->addr.s6_addr32[3];
- return 0;
-}
-
static int
ipv6_makeprefix(struct in6_addr *prefix, const struct in6_addr *addr, int len)
{
return (uint8_t)(x * NBBY + y);
}
+int
+ipv6_makeaddr(struct in6_addr *addr, struct interface *ifp,
+ const struct in6_addr *prefix, int prefix_len, unsigned int flags)
+{
+ const struct ipv6_addr *ap;
+ const struct if_options *ifo = ifp->options;
+ int dad;
+
+ if (prefix_len < 0 || prefix_len > 120) {
+ errno = EINVAL;
+ return -1;
+ }
+
+#ifdef IPV6_AF_TEMPORARY
+ if (flags & IPV6_AF_TEMPORARY)
+ return ipv6_maketemporaryaddress(addr, prefix, prefix_len, ifp);
+#else
+ UNUSED(flags);
+#endif
+
+ if (ifo->options & DHCPCD_SLAACPRIVATE) {
+ dad = 0;
+ if (ipv6_makestableprivate(addr,
+ prefix, prefix_len, ifp, &dad) == -1)
+ return -1;
+ return dad;
+ } else if (!IN6_IS_ADDR_UNSPECIFIED(&ifo->token)) {
+ *addr = ifo->token;
+ return ipv6_makeprefix(addr, prefix, prefix_len);
+ }
+
+ if (prefix_len > 64) {
+ errno = EINVAL;
+ return -1;
+ }
+ if ((ap = ipv6_linklocal(ifp)) == NULL) {
+ /* We delay a few functions until we get a local-link address
+ * so this should never be hit. */
+ errno = ENOENT;
+ return -1;
+ }
+
+ /* Make the address from the first local-link address */
+ memcpy(addr, prefix, sizeof(*prefix));
+ addr->s6_addr32[2] = ap->addr.s6_addr32[2];
+ addr->s6_addr32[3] = ap->addr.s6_addr32[3];
+ return 0;
+}
+
static void
in6_to_h64(uint64_t *vhigh, uint64_t *vlow, const struct in6_addr *addr)
{