1 /* 2 * dhcpcd - IPv6 ND handling 3 * Copyright (c) 2006-2018 Roy Marples <roy@marples.name> 4 * All rights reserved 5 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/ioctl.h> 29 #include <sys/param.h> 30 #include <sys/socket.h> 31 #include <net/if.h> 32 #include <net/route.h> 33 #include <netinet/in.h> 34 #include <netinet/ip6.h> 35 #include <netinet/icmp6.h> 36 37 #include <errno.h> 38 #include <fcntl.h> 39 #include <stddef.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 #define ELOOP_QUEUE 3 45 #include "common.h" 46 #include "dhcpcd.h" 47 #include "dhcp6.h" 48 #include "eloop.h" 49 #include "if.h" 50 #include "ipv6.h" 51 #include "ipv6nd.h" 52 #include "logerr.h" 53 #include "route.h" 54 #include "script.h" 55 56 /* Debugging Router Solicitations is a lot of spam, so disable it */ 57 //#define DEBUG_RS 58 59 #ifndef ND_OPT_RDNSS 60 #define ND_OPT_RDNSS 25 61 struct nd_opt_rdnss { /* RDNSS option RFC 6106 */ 62 uint8_t nd_opt_rdnss_type; 63 uint8_t nd_opt_rdnss_len; 64 uint16_t nd_opt_rdnss_reserved; 65 uint32_t nd_opt_rdnss_lifetime; 66 /* followed by list of IP prefixes */ 67 }; 68 __CTASSERT(sizeof(struct nd_opt_rdnss) == 8); 69 #endif 70 71 #ifndef ND_OPT_DNSSL 72 #define ND_OPT_DNSSL 31 73 struct nd_opt_dnssl { /* DNSSL option RFC 6106 */ 74 uint8_t nd_opt_dnssl_type; 75 uint8_t nd_opt_dnssl_len; 76 uint16_t nd_opt_dnssl_reserved; 77 uint32_t nd_opt_dnssl_lifetime; 78 /* followed by list of DNS servers */ 79 }; 80 __CTASSERT(sizeof(struct nd_opt_rdnss) == 8); 81 #endif 82 83 /* Impossible options, so we can easily add extras */ 84 #define _ND_OPT_PREFIX_ADDR 255 + 1 85 86 /* Minimal IPv6 MTU */ 87 #ifndef IPV6_MMTU 88 #define IPV6_MMTU 1280 89 #endif 90 91 #ifndef ND_RA_FLAG_RTPREF_HIGH 92 #define ND_RA_FLAG_RTPREF_MASK 0x18 93 #define ND_RA_FLAG_RTPREF_HIGH 0x08 94 #define ND_RA_FLAG_RTPREF_MEDIUM 0x00 95 #define ND_RA_FLAG_RTPREF_LOW 0x18 96 #define ND_RA_FLAG_RTPREF_RSV 0x10 97 #endif 98 99 /* RTPREF_MEDIUM has to be 0! */ 100 #define RTPREF_HIGH 1 101 #define RTPREF_MEDIUM 0 102 #define RTPREF_LOW (-1) 103 #define RTPREF_RESERVED (-2) 104 #define RTPREF_INVALID (-3) /* internal */ 105 106 #define MIN_RANDOM_FACTOR 500 /* millisecs */ 107 #define MAX_RANDOM_FACTOR 1500 /* millisecs */ 108 #define MIN_RANDOM_FACTOR_U MIN_RANDOM_FACTOR * 1000 /* usecs */ 109 #define MAX_RANDOM_FACTOR_U MAX_RANDOM_FACTOR * 1000 /* usecs */ 110 111 #if BYTE_ORDER == BIG_ENDIAN 112 #define IPV6_ADDR_INT32_ONE 1 113 #define IPV6_ADDR_INT16_MLL 0xff02 114 #elif BYTE_ORDER == LITTLE_ENDIAN 115 #define IPV6_ADDR_INT32_ONE 0x01000000 116 #define IPV6_ADDR_INT16_MLL 0x02ff 117 #endif 118 119 /* Debugging Neighbor Solicitations is a lot of spam, so disable it */ 120 //#define DEBUG_NS 121 // 122 123 static void ipv6nd_handledata(void *); 124 125 /* 126 * Android ships buggy ICMP6 filter headers. 127 * Supply our own until they fix their shit. 128 * References: 129 * https://android-review.googlesource.com/#/c/58438/ 130 * http://code.google.com/p/android/issues/original?id=32621&seq=24 131 */ 132 #ifdef __ANDROID__ 133 #undef ICMP6_FILTER_WILLPASS 134 #undef ICMP6_FILTER_WILLBLOCK 135 #undef ICMP6_FILTER_SETPASS 136 #undef ICMP6_FILTER_SETBLOCK 137 #undef ICMP6_FILTER_SETPASSALL 138 #undef ICMP6_FILTER_SETBLOCKALL 139 #define ICMP6_FILTER_WILLPASS(type, filterp) \ 140 ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) 141 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ 142 ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0) 143 #define ICMP6_FILTER_SETPASS(type, filterp) \ 144 ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))) 145 #define ICMP6_FILTER_SETBLOCK(type, filterp) \ 146 ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))) 147 #define ICMP6_FILTER_SETPASSALL(filterp) \ 148 memset(filterp, 0, sizeof(struct icmp6_filter)); 149 #define ICMP6_FILTER_SETBLOCKALL(filterp) \ 150 memset(filterp, 0xff, sizeof(struct icmp6_filter)); 151 #endif 152 153 /* Support older systems with different defines */ 154 #if !defined(IPV6_RECVHOPLIMIT) && defined(IPV6_HOPLIMIT) 155 #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT 156 #endif 157 #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO) 158 #define IPV6_RECVPKTINFO IPV6_PKTINFO 159 #endif 160 161 /* Handy defines */ 162 #define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra), 0) 163 #define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra), 1) 164 165 void 166 ipv6nd_printoptions(const struct dhcpcd_ctx *ctx, 167 const struct dhcp_opt *opts, size_t opts_len) 168 { 169 size_t i, j; 170 const struct dhcp_opt *opt, *opt2; 171 int cols; 172 173 for (i = 0, opt = ctx->nd_opts; 174 i < ctx->nd_opts_len; i++, opt++) 175 { 176 for (j = 0, opt2 = opts; j < opts_len; j++, opt2++) 177 if (opt2->option == opt->option) 178 break; 179 if (j == opts_len) { 180 cols = printf("%03d %s", opt->option, opt->var); 181 dhcp_print_option_encoding(opt, cols); 182 } 183 } 184 for (i = 0, opt = opts; i < opts_len; i++, opt++) { 185 cols = printf("%03d %s", opt->option, opt->var); 186 dhcp_print_option_encoding(opt, cols); 187 } 188 } 189 190 static int 191 ipv6nd_open(struct dhcpcd_ctx *ctx) 192 { 193 int on; 194 struct icmp6_filter filt; 195 196 if (ctx->nd_fd != -1) 197 return ctx->nd_fd; 198 #define SOCK_FLAGS SOCK_CLOEXEC | SOCK_NONBLOCK 199 ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW | SOCK_FLAGS, IPPROTO_ICMPV6); 200 #undef SOCK_FLAGS 201 if (ctx->nd_fd == -1) 202 return -1; 203 204 /* RFC4861 4.1 */ 205 on = 255; 206 if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 207 &on, sizeof(on)) == -1) 208 goto eexit; 209 210 on = 1; 211 if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 212 &on, sizeof(on)) == -1) 213 goto eexit; 214 215 on = 1; 216 if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, 217 &on, sizeof(on)) == -1) 218 goto eexit; 219 220 ICMP6_FILTER_SETBLOCKALL(&filt); 221 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt); 222 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); 223 if (setsockopt(ctx->nd_fd, IPPROTO_ICMPV6, ICMP6_FILTER, 224 &filt, sizeof(filt)) == -1) 225 goto eexit; 226 227 eloop_event_add(ctx->eloop, ctx->nd_fd, ipv6nd_handledata, ctx); 228 return ctx->nd_fd; 229 230 eexit: 231 if (ctx->nd_fd != -1) { 232 eloop_event_delete(ctx->eloop, ctx->nd_fd); 233 close(ctx->nd_fd); 234 ctx->nd_fd = -1; 235 } 236 return -1; 237 } 238 239 static int 240 ipv6nd_makersprobe(struct interface *ifp) 241 { 242 struct rs_state *state; 243 struct nd_router_solicit *rs; 244 245 state = RS_STATE(ifp); 246 free(state->rs); 247 state->rslen = sizeof(*rs); 248 if (ifp->hwlen != 0) 249 state->rslen += (size_t)ROUNDUP8(ifp->hwlen + 2); 250 state->rs = calloc(1, state->rslen); 251 if (state->rs == NULL) 252 return -1; 253 rs = state->rs; 254 rs->nd_rs_type = ND_ROUTER_SOLICIT; 255 //rs->nd_rs_code = 0; 256 //rs->nd_rs_cksum = 0; 257 //rs->nd_rs_reserved = 0; 258 259 if (ifp->hwlen != 0) { 260 struct nd_opt_hdr *nd; 261 262 nd = (struct nd_opt_hdr *)(state->rs + 1); 263 nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR; 264 nd->nd_opt_len = (uint8_t)((ROUNDUP8(ifp->hwlen + 2)) >> 3); 265 memcpy(nd + 1, ifp->hwaddr, ifp->hwlen); 266 } 267 return 0; 268 } 269 270 static void 271 ipv6nd_sendrsprobe(void *arg) 272 { 273 struct interface *ifp = arg; 274 struct dhcpcd_ctx *ctx; 275 struct rs_state *state; 276 struct sockaddr_in6 dst; 277 struct cmsghdr *cm; 278 struct in6_pktinfo pi; 279 280 if (ipv6_linklocal(ifp) == NULL) { 281 logdebugx("%s: delaying Router Solicitation for LL address", 282 ifp->name); 283 ipv6_addlinklocalcallback(ifp, ipv6nd_sendrsprobe, ifp); 284 return; 285 } 286 287 memset(&dst, 0, sizeof(dst)); 288 dst.sin6_family = AF_INET6; 289 #ifdef HAVE_SA_LEN 290 dst.sin6_len = sizeof(dst); 291 #endif 292 dst.sin6_scope_id = ifp->index; 293 if (inet_pton(AF_INET6, ALLROUTERS, &dst.sin6_addr) != 1) { 294 logerr(__func__); 295 return; 296 } 297 298 state = RS_STATE(ifp); 299 ctx = ifp->ctx; 300 ctx->sndhdr.msg_name = (void *)&dst; 301 ctx->sndhdr.msg_iov[0].iov_base = state->rs; 302 ctx->sndhdr.msg_iov[0].iov_len = state->rslen; 303 304 /* Set the outbound interface */ 305 cm = CMSG_FIRSTHDR(&ctx->sndhdr); 306 if (cm == NULL) /* unlikely */ 307 return; 308 cm->cmsg_level = IPPROTO_IPV6; 309 cm->cmsg_type = IPV6_PKTINFO; 310 cm->cmsg_len = CMSG_LEN(sizeof(pi)); 311 memset(&pi, 0, sizeof(pi)); 312 pi.ipi6_ifindex = ifp->index; 313 memcpy(CMSG_DATA(cm), &pi, sizeof(pi)); 314 315 logdebugx("%s: sending Router Solicitation", ifp->name); 316 if (sendmsg(ctx->nd_fd, &ctx->sndhdr, 0) == -1) { 317 logerr(__func__); 318 /* Allow IPv6ND to continue .... at most a few errors 319 * would be logged. 320 * Generally the error is ENOBUFS when struggling to 321 * associate with an access point. */ 322 } 323 324 if (state->rsprobes++ < MAX_RTR_SOLICITATIONS) 325 eloop_timeout_add_sec(ifp->ctx->eloop, 326 RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp); 327 else { 328 logwarnx("%s: no IPv6 Routers available", ifp->name); 329 ipv6nd_drop(ifp); 330 dhcp6_dropnondelegates(ifp); 331 } 332 } 333 334 void 335 ipv6nd_expire(struct interface *ifp, uint32_t seconds) 336 { 337 struct ra *rap; 338 struct timespec now; 339 uint32_t vltime = seconds; 340 uint32_t pltime = seconds / 2; 341 342 if (ifp->ctx->ra_routers == NULL) 343 return; 344 345 clock_gettime(CLOCK_MONOTONIC, &now); 346 347 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { 348 if (rap->iface == ifp) { 349 rap->acquired = now; 350 rap->expired = seconds ? 0 : 1; 351 if (seconds) { 352 struct ipv6_addr *ia; 353 354 rap->lifetime = seconds; 355 TAILQ_FOREACH(ia, &rap->addrs, next) { 356 if (ia->prefix_pltime > pltime || 357 ia->prefix_vltime > vltime) 358 { 359 ia->acquired = now; 360 if (ia->prefix_pltime != 0) 361 ia->prefix_pltime = 362 pltime; 363 ia->prefix_vltime = vltime; 364 } 365 } 366 ipv6_addaddrs(&rap->addrs); 367 } 368 } 369 } 370 if (seconds) 371 ipv6nd_expirera(ifp); 372 else 373 rt_build(ifp->ctx, AF_INET6); 374 } 375 376 static void 377 ipv6nd_reachable(struct ra *rap, int flags) 378 { 379 380 if (rap->lifetime == 0) 381 return; 382 383 if (flags & IPV6ND_REACHABLE) { 384 if (rap->expired == 0) 385 return; 386 loginfox("%s: %s is reachable again", 387 rap->iface->name, rap->sfrom); 388 rap->expired = 0; 389 } else { 390 if (rap->expired != 0) 391 return; 392 logwarnx("%s: %s is unreachable, expiring it", 393 rap->iface->name, rap->sfrom); 394 rap->expired = 1; 395 } 396 397 rt_build(rap->iface->ctx, AF_INET6); 398 /* XXX Not really an RA */ 399 script_runreason(rap->iface, "ROUTERADVERT"); 400 } 401 402 void 403 ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags) 404 { 405 struct ra *rap; 406 407 if (ctx->ra_routers) { 408 TAILQ_FOREACH(rap, ctx->ra_routers, next) { 409 if (IN6_ARE_ADDR_EQUAL(&rap->from, addr)) { 410 ipv6nd_reachable(rap, flags); 411 break; 412 } 413 } 414 } 415 } 416 417 const struct ipv6_addr * 418 ipv6nd_iffindaddr(const struct interface *ifp, const struct in6_addr *addr, 419 unsigned int flags) 420 { 421 struct ra *rap; 422 struct ipv6_addr *ap; 423 424 if (ifp->ctx->ra_routers == NULL) 425 return NULL; 426 427 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { 428 if (rap->iface != ifp) 429 continue; 430 TAILQ_FOREACH(ap, &rap->addrs, next) { 431 if (ipv6_findaddrmatch(ap, addr, flags)) 432 return ap; 433 } 434 } 435 return NULL; 436 } 437 438 struct ipv6_addr * 439 ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr, 440 unsigned int flags) 441 { 442 struct ra *rap; 443 struct ipv6_addr *ap; 444 445 if (ctx->ra_routers == NULL) 446 return NULL; 447 448 TAILQ_FOREACH(rap, ctx->ra_routers, next) { 449 TAILQ_FOREACH(ap, &rap->addrs, next) { 450 if (ipv6_findaddrmatch(ap, addr, flags)) 451 return ap; 452 } 453 } 454 return NULL; 455 } 456 457 static void 458 ipv6nd_removefreedrop_ra(struct ra *rap, int remove_ra, int drop_ra) 459 { 460 461 eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap->iface); 462 eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap); 463 if (remove_ra) 464 TAILQ_REMOVE(rap->iface->ctx->ra_routers, rap, next); 465 ipv6_freedrop_addrs(&rap->addrs, drop_ra, NULL); 466 free(rap->data); 467 free(rap); 468 } 469 470 static void 471 ipv6nd_freedrop_ra(struct ra *rap, int drop) 472 { 473 474 ipv6nd_removefreedrop_ra(rap, 1, drop); 475 } 476 477 ssize_t 478 ipv6nd_free(struct interface *ifp) 479 { 480 struct rs_state *state; 481 struct ra *rap, *ran; 482 struct dhcpcd_ctx *ctx; 483 ssize_t n; 484 485 state = RS_STATE(ifp); 486 if (state == NULL) 487 return 0; 488 489 free(state->rs); 490 free(state); 491 ifp->if_data[IF_DATA_IPV6ND] = NULL; 492 n = 0; 493 TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) { 494 if (rap->iface == ifp) { 495 ipv6nd_free_ra(rap); 496 n++; 497 } 498 } 499 500 /* If we don't have any more IPv6 enabled interfaces, 501 * close the global socket and release resources */ 502 ctx = ifp->ctx; 503 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 504 if (RS_STATE(ifp)) 505 break; 506 } 507 if (ifp == NULL) { 508 if (ctx->nd_fd != -1) { 509 eloop_event_delete(ctx->eloop, ctx->nd_fd); 510 close(ctx->nd_fd); 511 ctx->nd_fd = -1; 512 } 513 } 514 515 return n; 516 } 517 518 static int 519 rtpref(struct ra *rap) 520 { 521 522 switch (rap->flags & ND_RA_FLAG_RTPREF_MASK) { 523 case ND_RA_FLAG_RTPREF_HIGH: 524 return (RTPREF_HIGH); 525 case ND_RA_FLAG_RTPREF_MEDIUM: 526 case ND_RA_FLAG_RTPREF_RSV: 527 return (RTPREF_MEDIUM); 528 case ND_RA_FLAG_RTPREF_LOW: 529 return (RTPREF_LOW); 530 default: 531 logerrx("rtpref: impossible RA flag %x", rap->flags); 532 return (RTPREF_INVALID); 533 } 534 /* NOTREACHED */ 535 } 536 537 static void 538 add_router(struct dhcpcd_ctx *ctx, struct ra *router) 539 { 540 struct ra *rap; 541 542 TAILQ_FOREACH(rap, ctx->ra_routers, next) { 543 if (router->iface->metric < rap->iface->metric || 544 (router->iface->metric == rap->iface->metric && 545 rtpref(router) > rtpref(rap))) 546 { 547 TAILQ_INSERT_BEFORE(rap, router, next); 548 return; 549 } 550 } 551 TAILQ_INSERT_TAIL(ctx->ra_routers, router, next); 552 } 553 554 static int 555 ipv6nd_scriptrun(struct ra *rap) 556 { 557 int hasdns, hasaddress, pid; 558 struct ipv6_addr *ap; 559 560 hasaddress = 0; 561 /* If all addresses have completed DAD run the script */ 562 TAILQ_FOREACH(ap, &rap->addrs, next) { 563 if ((ap->flags & (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) == 564 (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) 565 { 566 hasaddress = 1; 567 if (!(ap->flags & IPV6_AF_DADCOMPLETED) && 568 ipv6_iffindaddr(ap->iface, &ap->addr, 569 IN6_IFF_TENTATIVE)) 570 ap->flags |= IPV6_AF_DADCOMPLETED; 571 if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) { 572 logdebugx("%s: waiting for Router Advertisement" 573 " DAD to complete", 574 rap->iface->name); 575 return 0; 576 } 577 } 578 } 579 580 /* If we don't require RDNSS then set hasdns = 1 so we fork */ 581 if (!(rap->iface->options->options & DHCPCD_IPV6RA_REQRDNSS)) 582 hasdns = 1; 583 else { 584 hasdns = rap->hasdns; 585 } 586 587 script_runreason(rap->iface, "ROUTERADVERT"); 588 pid = 0; 589 if (hasdns && (hasaddress || 590 !(rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)))) 591 pid = dhcpcd_daemonise(rap->iface->ctx); 592 #if 0 593 else if (options & DHCPCD_DAEMONISE && 594 !(options & DHCPCD_DAEMONISED) && new_data) 595 logwarnx("%s: did not fork due to an absent" 596 " RDNSS option in the RA", 597 ifp->name); 598 } 599 #endif 600 return pid; 601 } 602 603 static void 604 ipv6nd_addaddr(void *arg) 605 { 606 struct ipv6_addr *ap = arg; 607 608 ipv6_addaddr(ap, NULL); 609 } 610 611 int 612 ipv6nd_dadcompleted(const struct interface *ifp) 613 { 614 const struct ra *rap; 615 const struct ipv6_addr *ap; 616 617 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { 618 if (rap->iface != ifp) 619 continue; 620 TAILQ_FOREACH(ap, &rap->addrs, next) { 621 if (ap->flags & IPV6_AF_AUTOCONF && 622 ap->flags & IPV6_AF_ADDED && 623 !(ap->flags & IPV6_AF_DADCOMPLETED)) 624 return 0; 625 } 626 } 627 return 1; 628 } 629 630 static void 631 ipv6nd_dadcallback(void *arg) 632 { 633 struct ipv6_addr *ia = arg, *rapap; 634 struct interface *ifp; 635 struct ra *rap; 636 int wascompleted, found; 637 struct timespec tv; 638 char buf[INET6_ADDRSTRLEN]; 639 const char *p; 640 int dadcounter; 641 642 ifp = ia->iface; 643 wascompleted = (ia->flags & IPV6_AF_DADCOMPLETED); 644 ia->flags |= IPV6_AF_DADCOMPLETED; 645 if (ia->flags & IPV6_AF_DUPLICATED) { 646 ia->dadcounter++; 647 logwarnx("%s: DAD detected %s", ifp->name, ia->saddr); 648 649 /* Try and make another stable private address. 650 * Because ap->dadcounter is always increamented, 651 * a different address is generated. */ 652 /* XXX Cache DAD counter per prefix/id/ssid? */ 653 if (ifp->options->options & DHCPCD_SLAACPRIVATE) { 654 if (ia->dadcounter >= IDGEN_RETRIES) { 655 logerrx("%s: unable to obtain a" 656 " stable private address", 657 ifp->name); 658 goto try_script; 659 } 660 loginfox("%s: deleting address %s", 661 ifp->name, ia->saddr); 662 if (if_address6(RTM_DELADDR, ia) == -1 && 663 errno != EADDRNOTAVAIL && errno != ENXIO) 664 logerr(__func__); 665 dadcounter = ia->dadcounter; 666 if (ipv6_makestableprivate(&ia->addr, 667 &ia->prefix, ia->prefix_len, 668 ifp, &dadcounter) == -1) 669 { 670 logerr("ipv6_makestableprivate"); 671 return; 672 } 673 ia->dadcounter = dadcounter; 674 ia->flags &= ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED); 675 ia->flags |= IPV6_AF_NEW; 676 p = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf)); 677 if (p) 678 snprintf(ia->saddr, 679 sizeof(ia->saddr), 680 "%s/%d", 681 p, ia->prefix_len); 682 else 683 ia->saddr[0] = '\0'; 684 tv.tv_sec = 0; 685 tv.tv_nsec = (suseconds_t) 686 arc4random_uniform(IDGEN_DELAY * NSEC_PER_SEC); 687 timespecnorm(&tv); 688 eloop_timeout_add_tv(ifp->ctx->eloop, &tv, 689 ipv6nd_addaddr, ia); 690 return; 691 } 692 } 693 694 try_script: 695 if (!wascompleted) { 696 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { 697 if (rap->iface != ifp) 698 continue; 699 wascompleted = 1; 700 found = 0; 701 TAILQ_FOREACH(rapap, &rap->addrs, next) { 702 if (rapap->flags & IPV6_AF_AUTOCONF && 703 rapap->flags & IPV6_AF_ADDED && 704 (rapap->flags & IPV6_AF_DADCOMPLETED) == 0) 705 { 706 wascompleted = 0; 707 break; 708 } 709 if (rapap == ia) 710 found = 1; 711 } 712 713 if (wascompleted && found) { 714 logdebugx("%s: Router Advertisement DAD " 715 "completed", 716 rap->iface->name); 717 if (ipv6nd_scriptrun(rap)) 718 return; 719 } 720 } 721 } 722 } 723 724 #ifndef DHCP6 725 /* If DHCPv6 is compiled out, supply a shim to provide an error message 726 * if IPv6RA requests DHCPv6. */ 727 #undef dhcp6_start 728 static int 729 dhcp6_start(__unused struct interface *ifp, __unused enum DH6S init_state) 730 { 731 732 errno = ENOTSUP; 733 return -1; 734 } 735 #endif 736 737 static void 738 ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp, 739 struct icmp6_hdr *icp, size_t len, int hoplimit) 740 { 741 size_t i, olen; 742 struct nd_router_advert *nd_ra; 743 struct nd_opt_hdr ndo; 744 struct nd_opt_prefix_info pi; 745 struct nd_opt_mtu mtu; 746 struct nd_opt_rdnss rdnss; 747 uint8_t *p; 748 struct ra *rap; 749 struct in6_addr pi_prefix; 750 struct ipv6_addr *ap; 751 struct dhcp_opt *dho; 752 bool new_rap, new_data; 753 uint32_t old_lifetime; 754 __printflike(1, 2) void (*logfunc)(const char *, ...); 755 #ifdef IPV6_MANAGETEMPADDR 756 uint8_t new_ap; 757 #endif 758 759 if (ifp == NULL) { 760 #ifdef DEBUG_RS 761 logdebugx("RA for unexpected interface from %s", 762 ctx->sfrom); 763 #endif 764 return; 765 } 766 767 if (len < sizeof(struct nd_router_advert)) { 768 logerrx("IPv6 RA packet too short from %s", ctx->sfrom); 769 return; 770 } 771 772 /* RFC 4861 7.1.2 */ 773 if (hoplimit != 255) { 774 logerrx("invalid hoplimit(%d) in RA from %s", 775 hoplimit, ctx->sfrom); 776 return; 777 } 778 779 if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) { 780 logerrx("RA from non local address %s", ctx->sfrom); 781 return; 782 } 783 784 if (!(ifp->options->options & DHCPCD_IPV6RS)) { 785 #ifdef DEBUG_RS 786 logerrx("%s: unexpected RA from %s", 787 ifp->name, ctx->sfrom); 788 #endif 789 return; 790 } 791 792 /* We could receive a RA before we sent a RS*/ 793 if (ipv6_linklocal(ifp) == NULL) { 794 #ifdef DEBUG_RS 795 logdebugx("%s: received RA from %s (no link-local)", 796 ifp->name, ctx->sfrom); 797 #endif 798 return; 799 } 800 801 if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr, IN6_IFF_TENTATIVE)) { 802 logdebugx("%s: ignoring RA from ourself %s", 803 ifp->name, ctx->sfrom); 804 return; 805 } 806 807 TAILQ_FOREACH(rap, ctx->ra_routers, next) { 808 if (ifp == rap->iface && 809 IN6_ARE_ADDR_EQUAL(&rap->from, &ctx->from.sin6_addr)) 810 break; 811 } 812 813 nd_ra = (struct nd_router_advert *)icp; 814 815 /* We don't want to spam the log with the fact we got an RA every 816 * 30 seconds or so, so only spam the log if it's different. */ 817 if (rap == NULL || (rap->data_len != len || 818 memcmp(rap->data, (unsigned char *)icp, rap->data_len) != 0)) 819 { 820 if (rap) { 821 free(rap->data); 822 rap->data_len = 0; 823 } 824 new_data = true; 825 } else 826 new_data = false; 827 if (rap == NULL) { 828 rap = calloc(1, sizeof(*rap)); 829 if (rap == NULL) { 830 logerr(__func__); 831 return; 832 } 833 rap->iface = ifp; 834 rap->from = ctx->from.sin6_addr; 835 strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom)); 836 TAILQ_INIT(&rap->addrs); 837 new_rap = true; 838 } else 839 new_rap = false; 840 if (rap->data_len == 0) { 841 rap->data = malloc(len); 842 if (rap->data == NULL) { 843 logerr(__func__); 844 if (new_rap) 845 free(rap); 846 return; 847 } 848 memcpy(rap->data, icp, len); 849 rap->data_len = len; 850 } 851 852 /* We could change the debug level based on new_data, but some 853 * routers like to decrease the advertised valid and preferred times 854 * in accordance with the own prefix times which would result in too 855 * much needless log spam. */ 856 logfunc = new_rap ? loginfox : logdebugx, 857 logfunc("%s: Router Advertisement from %s", 858 ifp->name, ctx->sfrom); 859 860 clock_gettime(CLOCK_MONOTONIC, &rap->acquired); 861 rap->flags = nd_ra->nd_ra_flags_reserved; 862 old_lifetime = rap->lifetime; 863 rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime); 864 if (!new_rap && rap->lifetime == 0 && old_lifetime != 0) 865 logwarnx("%s: %s: no longer a default router", 866 ifp->name, rap->sfrom); 867 if (nd_ra->nd_ra_reachable) { 868 rap->reachable = ntohl(nd_ra->nd_ra_reachable); 869 if (rap->reachable > MAX_REACHABLE_TIME) 870 rap->reachable = 0; 871 } 872 if (nd_ra->nd_ra_retransmit) 873 rap->retrans = ntohl(nd_ra->nd_ra_retransmit); 874 if (rap->lifetime) 875 rap->expired = 0; 876 rap->hasdns = 0; 877 878 #ifdef IPV6_AF_TEMPORARY 879 ipv6_markaddrsstale(ifp, IPV6_AF_TEMPORARY); 880 #endif 881 TAILQ_FOREACH(ap, &rap->addrs, next) { 882 ap->flags |= IPV6_AF_STALE; 883 } 884 885 len -= sizeof(struct nd_router_advert); 886 p = ((uint8_t *)icp) + sizeof(struct nd_router_advert); 887 for (; len > 0; p += olen, len -= olen) { 888 if (len < sizeof(ndo)) { 889 logerrx("%s: short option", ifp->name); 890 break; 891 } 892 memcpy(&ndo, p, sizeof(ndo)); 893 olen = (size_t)ndo.nd_opt_len * 8; 894 if (olen == 0) { 895 logerrx("%s: zero length option", ifp->name); 896 break; 897 } 898 if (olen > len) { 899 logerrx("%s: option length exceeds message", 900 ifp->name); 901 break; 902 } 903 904 if (has_option_mask(ifp->options->rejectmasknd, 905 ndo.nd_opt_type)) 906 { 907 for (i = 0, dho = ctx->nd_opts; 908 i < ctx->nd_opts_len; 909 i++, dho++) 910 { 911 if (dho->option == ndo.nd_opt_type) 912 break; 913 } 914 if (dho != NULL) 915 logwarnx("%s: reject RA (option %s) from %s", 916 ifp->name, dho->var, ctx->sfrom); 917 else 918 logwarnx("%s: reject RA (option %d) from %s", 919 ifp->name, ndo.nd_opt_type, ctx->sfrom); 920 if (new_rap) 921 ipv6nd_removefreedrop_ra(rap, 0, 0); 922 else 923 ipv6nd_free_ra(rap); 924 return; 925 } 926 927 if (has_option_mask(ifp->options->nomasknd, ndo.nd_opt_type)) 928 continue; 929 930 switch (ndo.nd_opt_type) { 931 case ND_OPT_PREFIX_INFORMATION: 932 logfunc = new_data ? logerrx : logdebugx; 933 if (ndo.nd_opt_len != 4) { 934 logfunc("%s: invalid option len for prefix", 935 ifp->name); 936 continue; 937 } 938 memcpy(&pi, p, sizeof(pi)); 939 if (pi.nd_opt_pi_prefix_len > 128) { 940 logfunc("%s: invalid prefix len", ifp->name); 941 continue; 942 } 943 /* nd_opt_pi_prefix is not aligned. */ 944 memcpy(&pi_prefix, &pi.nd_opt_pi_prefix, 945 sizeof(pi_prefix)); 946 if (IN6_IS_ADDR_MULTICAST(&pi_prefix) || 947 IN6_IS_ADDR_LINKLOCAL(&pi_prefix)) 948 { 949 logfunc("%s: invalid prefix in RA", ifp->name); 950 continue; 951 } 952 if (ntohl(pi.nd_opt_pi_preferred_time) > 953 ntohl(pi.nd_opt_pi_valid_time)) 954 { 955 logfunc("%s: pltime > vltime", ifp->name); 956 continue; 957 } 958 TAILQ_FOREACH(ap, &rap->addrs, next) 959 if (ap->prefix_len ==pi.nd_opt_pi_prefix_len && 960 IN6_ARE_ADDR_EQUAL(&ap->prefix, &pi_prefix)) 961 break; 962 if (ap == NULL) { 963 unsigned int flags; 964 965 if (!(pi.nd_opt_pi_flags_reserved & 966 ND_OPT_PI_FLAG_AUTO) && 967 !(pi.nd_opt_pi_flags_reserved & 968 ND_OPT_PI_FLAG_ONLINK)) 969 continue; 970 971 flags = IPV6_AF_RAPFX; 972 if (pi.nd_opt_pi_flags_reserved & 973 ND_OPT_PI_FLAG_AUTO && 974 rap->iface->options->options & 975 DHCPCD_IPV6RA_AUTOCONF) 976 flags |= IPV6_AF_AUTOCONF; 977 978 ap = ipv6_newaddr(rap->iface, 979 &pi_prefix, pi.nd_opt_pi_prefix_len, flags); 980 if (ap == NULL) 981 break; 982 ap->prefix = pi_prefix; 983 ap->dadcallback = ipv6nd_dadcallback; 984 ap->created = ap->acquired = rap->acquired; 985 TAILQ_INSERT_TAIL(&rap->addrs, ap, next); 986 987 #ifdef IPV6_MANAGETEMPADDR 988 /* New address to dhcpcd RA handling. 989 * If the address already exists and a valid 990 * temporary address also exists then 991 * extend the existing one rather than 992 * create a new one */ 993 if (ipv6_iffindaddr(ifp, &ap->addr, 994 IN6_IFF_NOTUSEABLE) && 995 ipv6_settemptime(ap, 0)) 996 new_ap = 0; 997 else 998 new_ap = 1; 999 #endif 1000 } else { 1001 #ifdef IPV6_MANAGETEMPADDR 1002 new_ap = 0; 1003 #endif 1004 ap->flags &= ~IPV6_AF_STALE; 1005 ap->acquired = rap->acquired; 1006 } 1007 if (pi.nd_opt_pi_flags_reserved & 1008 ND_OPT_PI_FLAG_ONLINK) 1009 ap->flags |= IPV6_AF_ONLINK; 1010 ap->prefix_vltime = 1011 ntohl(pi.nd_opt_pi_valid_time); 1012 ap->prefix_pltime = 1013 ntohl(pi.nd_opt_pi_preferred_time); 1014 1015 #ifdef IPV6_MANAGETEMPADDR 1016 /* RFC4941 Section 3.3.3 */ 1017 if (ap->flags & IPV6_AF_AUTOCONF && 1018 ip6_use_tempaddr(ap->iface->name)) 1019 { 1020 if (!new_ap) { 1021 if (ipv6_settemptime(ap, 1) == NULL) 1022 new_ap = 1; 1023 } 1024 if (new_ap && ap->prefix_pltime) { 1025 if (ipv6_createtempaddr(ap, 1026 &ap->acquired) == NULL) 1027 logerr("ipv6_createtempaddr"); 1028 } 1029 } 1030 #endif 1031 break; 1032 1033 case ND_OPT_MTU: 1034 memcpy(&mtu, p, sizeof(mtu)); 1035 mtu.nd_opt_mtu_mtu = ntohl(mtu.nd_opt_mtu_mtu); 1036 if (mtu.nd_opt_mtu_mtu < IPV6_MMTU) { 1037 logerrx("%s: invalid MTU %d", 1038 ifp->name, mtu.nd_opt_mtu_mtu); 1039 break; 1040 } 1041 rap->mtu = mtu.nd_opt_mtu_mtu; 1042 break; 1043 1044 case ND_OPT_RDNSS: 1045 memcpy(&rdnss, p, sizeof(rdnss)); 1046 if (rdnss.nd_opt_rdnss_lifetime && 1047 rdnss.nd_opt_rdnss_len > 1) 1048 rap->hasdns = 1; 1049 break; 1050 default: 1051 continue; 1052 } 1053 } 1054 1055 for (i = 0, dho = ctx->nd_opts; 1056 i < ctx->nd_opts_len; 1057 i++, dho++) 1058 { 1059 if (has_option_mask(ifp->options->requiremasknd, 1060 dho->option)) 1061 { 1062 logwarnx("%s: reject RA (no option %s) from %s", 1063 ifp->name, dho->var, ctx->sfrom); 1064 if (new_rap) 1065 ipv6nd_removefreedrop_ra(rap, 0, 0); 1066 else 1067 ipv6nd_free_ra(rap); 1068 return; 1069 } 1070 } 1071 1072 if (new_rap) 1073 add_router(ifp->ctx, rap); 1074 1075 if (ifp->ctx->options & DHCPCD_TEST) { 1076 script_runreason(ifp, "TEST"); 1077 goto handle_flag; 1078 } 1079 ipv6_addaddrs(&rap->addrs); 1080 #ifdef IPV6_MANAGETEMPADDR 1081 ipv6_addtempaddrs(ifp, &rap->acquired); 1082 #endif 1083 1084 /* Find any freshly added routes, such as the subnet route. 1085 * We do this because we cannot rely on recieving the kernel 1086 * notification right now via our link socket. */ 1087 if_initrt(ifp->ctx, AF_INET6); 1088 1089 rt_build(ifp->ctx, AF_INET6); 1090 if (ipv6nd_scriptrun(rap)) 1091 return; 1092 1093 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 1094 eloop_timeout_delete(ifp->ctx->eloop, NULL, rap); /* reachable timer */ 1095 1096 handle_flag: 1097 if (!(ifp->options->options & DHCPCD_DHCP6)) 1098 goto nodhcp6; 1099 /* Only log a DHCPv6 start error if compiled in or debugging is enabled. */ 1100 #ifdef DHCP6 1101 #define LOG_DHCP6 logerr 1102 #else 1103 #define LOG_DHCP6 logdebug 1104 #endif 1105 if (rap->flags & ND_RA_FLAG_MANAGED) { 1106 if (new_data && dhcp6_start(ifp, DH6S_REQUEST) == -1) 1107 LOG_DHCP6("dhcp6_start: %s", ifp->name); 1108 } else if (rap->flags & ND_RA_FLAG_OTHER) { 1109 if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1) 1110 LOG_DHCP6("dhcp6_start: %s", ifp->name); 1111 } else { 1112 if (new_data) 1113 logdebugx("%s: No DHCPv6 instruction in RA", ifp->name); 1114 nodhcp6: 1115 if (ifp->ctx->options & DHCPCD_TEST) { 1116 eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS); 1117 return; 1118 } 1119 } 1120 1121 /* Expire should be called last as the rap object could be destroyed */ 1122 ipv6nd_expirera(ifp); 1123 } 1124 1125 int 1126 ipv6nd_hasra(const struct interface *ifp) 1127 { 1128 const struct ra *rap; 1129 1130 if (ifp->ctx->ra_routers) { 1131 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) 1132 if (rap->iface == ifp && !rap->expired) 1133 return 1; 1134 } 1135 return 0; 1136 } 1137 1138 int 1139 ipv6nd_hasradhcp(const struct interface *ifp) 1140 { 1141 const struct ra *rap; 1142 1143 if (ifp->ctx->ra_routers) { 1144 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { 1145 if (rap->iface == ifp && 1146 !rap->expired && 1147 (rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))) 1148 return 1; 1149 } 1150 } 1151 return 0; 1152 } 1153 1154 static const uint8_t * 1155 ipv6nd_getoption(struct dhcpcd_ctx *ctx, 1156 size_t *os, unsigned int *code, size_t *len, 1157 const uint8_t *od, size_t ol, struct dhcp_opt **oopt) 1158 { 1159 struct nd_opt_hdr ndo; 1160 size_t i; 1161 struct dhcp_opt *opt; 1162 1163 if (od) { 1164 *os = sizeof(ndo); 1165 if (ol < *os) { 1166 errno = EINVAL; 1167 return NULL; 1168 } 1169 memcpy(&ndo, od, sizeof(ndo)); 1170 i = (size_t)(ndo.nd_opt_len * 8); 1171 if (i > ol) { 1172 errno = EINVAL; 1173 return NULL; 1174 } 1175 *len = i; 1176 *code = ndo.nd_opt_type; 1177 } 1178 1179 for (i = 0, opt = ctx->nd_opts; 1180 i < ctx->nd_opts_len; i++, opt++) 1181 { 1182 if (opt->option == *code) { 1183 *oopt = opt; 1184 break; 1185 } 1186 } 1187 1188 if (od) 1189 return od + sizeof(ndo); 1190 return NULL; 1191 } 1192 1193 ssize_t 1194 ipv6nd_env(char **env, const char *prefix, const struct interface *ifp) 1195 { 1196 size_t i, j, n, len, olen; 1197 struct ra *rap; 1198 char ndprefix[32], abuf[24]; 1199 struct dhcp_opt *opt; 1200 uint8_t *p; 1201 struct nd_opt_hdr ndo; 1202 struct ipv6_addr *ia; 1203 struct timespec now; 1204 1205 clock_gettime(CLOCK_MONOTONIC, &now); 1206 i = n = 0; 1207 TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { 1208 if (rap->iface != ifp) 1209 continue; 1210 i++; 1211 if (prefix != NULL) 1212 snprintf(ndprefix, sizeof(ndprefix), 1213 "%s_nd%zu", prefix, i); 1214 else 1215 snprintf(ndprefix, sizeof(ndprefix), 1216 "nd%zu", i); 1217 if (env) 1218 setvar(&env[n], ndprefix, "from", rap->sfrom); 1219 n++; 1220 if (env) 1221 setvard(&env[n], ndprefix, "acquired", 1222 (size_t)rap->acquired.tv_sec); 1223 n++; 1224 if (env) 1225 setvard(&env[n], ndprefix, "now", (size_t)now.tv_sec); 1226 n++; 1227 1228 /* Zero our indexes */ 1229 if (env) { 1230 for (j = 0, opt = rap->iface->ctx->nd_opts; 1231 j < rap->iface->ctx->nd_opts_len; 1232 j++, opt++) 1233 dhcp_zero_index(opt); 1234 for (j = 0, opt = rap->iface->options->nd_override; 1235 j < rap->iface->options->nd_override_len; 1236 j++, opt++) 1237 dhcp_zero_index(opt); 1238 } 1239 1240 /* Unlike DHCP, ND6 options *may* occur more than once. 1241 * There is also no provision for option concatenation 1242 * unlike DHCP. */ 1243 len = rap->data_len - sizeof(struct nd_router_advert); 1244 for (p = rap->data + sizeof(struct nd_router_advert); 1245 len >= sizeof(ndo); 1246 p += olen, len -= olen) 1247 { 1248 memcpy(&ndo, p, sizeof(ndo)); 1249 olen = (size_t)(ndo.nd_opt_len * 8); 1250 if (olen > len) { 1251 errno = EINVAL; 1252 break; 1253 } 1254 if (has_option_mask(rap->iface->options->nomasknd, 1255 ndo.nd_opt_type)) 1256 continue; 1257 for (j = 0, opt = rap->iface->options->nd_override; 1258 j < rap->iface->options->nd_override_len; 1259 j++, opt++) 1260 if (opt->option == ndo.nd_opt_type) 1261 break; 1262 if (j == rap->iface->options->nd_override_len) { 1263 for (j = 0, opt = rap->iface->ctx->nd_opts; 1264 j < rap->iface->ctx->nd_opts_len; 1265 j++, opt++) 1266 if (opt->option == ndo.nd_opt_type) 1267 break; 1268 if (j == rap->iface->ctx->nd_opts_len) 1269 opt = NULL; 1270 } 1271 if (opt) { 1272 n += dhcp_envoption(rap->iface->ctx, 1273 env == NULL ? NULL : &env[n], 1274 ndprefix, rap->iface->name, 1275 opt, ipv6nd_getoption, 1276 p + sizeof(ndo), olen - sizeof(ndo)); 1277 } 1278 } 1279 1280 /* We need to output the addresses we actually made 1281 * from the prefix information options as well. */ 1282 j = 0; 1283 TAILQ_FOREACH(ia, &rap->addrs, next) { 1284 if (!(ia->flags & IPV6_AF_AUTOCONF) 1285 #ifdef IPV6_AF_TEMPORARY 1286 || ia->flags & IPV6_AF_TEMPORARY 1287 #endif 1288 ) 1289 continue; 1290 j++; 1291 if (env) { 1292 snprintf(abuf, sizeof(abuf), "addr%zu", j); 1293 setvar(&env[n], ndprefix, abuf, ia->saddr); 1294 } 1295 n++; 1296 } 1297 } 1298 return (ssize_t)n; 1299 } 1300 1301 void 1302 ipv6nd_handleifa(int cmd, struct ipv6_addr *addr, pid_t pid) 1303 { 1304 struct ra *rap; 1305 1306 /* IPv6 init may not have happened yet if we are learning 1307 * existing addresses when dhcpcd starts. */ 1308 if (addr->iface->ctx->ra_routers == NULL) 1309 return; 1310 1311 TAILQ_FOREACH(rap, addr->iface->ctx->ra_routers, next) { 1312 if (rap->iface != addr->iface) 1313 continue; 1314 ipv6_handleifa_addrs(cmd, &rap->addrs, addr, pid); 1315 } 1316 } 1317 1318 void 1319 ipv6nd_expirera(void *arg) 1320 { 1321 struct interface *ifp; 1322 struct ra *rap, *ran; 1323 struct timespec now, lt, expire, next; 1324 uint8_t expired, anyvalid, valid, validone; 1325 struct ipv6_addr *ia; 1326 1327 ifp = arg; 1328 clock_gettime(CLOCK_MONOTONIC, &now); 1329 expired = 0; 1330 timespecclear(&next); 1331 1332 anyvalid = 0; 1333 TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) { 1334 if (rap->iface != ifp) 1335 continue; 1336 valid = validone = 0; 1337 if (rap->lifetime) { 1338 lt.tv_sec = (time_t)rap->lifetime; 1339 lt.tv_nsec = 0; 1340 timespecadd(&rap->acquired, <, &expire); 1341 if (rap->lifetime == 0 || timespeccmp(&now, &expire, >)) 1342 { 1343 if (!rap->expired) { 1344 logwarnx("%s: %s: router expired", 1345 ifp->name, rap->sfrom); 1346 rap->expired = expired = 1; 1347 rap->lifetime = 0; 1348 } 1349 } else { 1350 valid = 1; 1351 timespecsub(&expire, &now, <); 1352 if (!timespecisset(&next) || 1353 timespeccmp(&next, <, >)) 1354 next = lt; 1355 } 1356 } 1357 1358 /* Not every prefix is tied to an address which 1359 * the kernel can expire, so we need to handle it ourself. 1360 * Also, some OS don't support address lifetimes (Solaris). */ 1361 TAILQ_FOREACH(ia, &rap->addrs, next) { 1362 if (ia->prefix_vltime == 0) 1363 continue; 1364 if (ia->prefix_vltime == ND6_INFINITE_LIFETIME) { 1365 validone = 1; 1366 continue; 1367 } 1368 lt.tv_sec = (time_t)ia->prefix_vltime; 1369 lt.tv_nsec = 0; 1370 timespecadd(&ia->acquired, <, &expire); 1371 if (timespeccmp(&now, &expire, >)) { 1372 if (ia->flags & IPV6_AF_ADDED) { 1373 logwarnx("%s: expired address %s", 1374 ia->iface->name, ia->saddr); 1375 if (if_address6(RTM_DELADDR, ia)== -1 && 1376 errno != EADDRNOTAVAIL && 1377 errno != ENXIO) 1378 logerr(__func__); 1379 } 1380 ia->prefix_vltime = ia->prefix_pltime = 0; 1381 ia->flags &= 1382 ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED); 1383 expired = 1; 1384 } else { 1385 timespecsub(&expire, &now, <); 1386 if (!timespecisset(&next) || 1387 timespeccmp(&next, <, >)) 1388 next = lt; 1389 validone = 1; 1390 } 1391 } 1392 1393 /* XXX FixMe! 1394 * We need to extract the lifetime from each option and check 1395 * if that has expired or not. 1396 * If it has, zero the option out in the returned data. */ 1397 1398 /* No valid lifetimes are left on the RA, so we might 1399 * as well punt it. */ 1400 if (!valid && !validone) 1401 ipv6nd_free_ra(rap); 1402 else 1403 anyvalid = 1; 1404 } 1405 1406 if (timespecisset(&next)) 1407 eloop_timeout_add_tv(ifp->ctx->eloop, 1408 &next, ipv6nd_expirera, ifp); 1409 if (expired) { 1410 rt_build(ifp->ctx, AF_INET6); 1411 script_runreason(ifp, "ROUTERADVERT"); 1412 } 1413 1414 /* No valid routers? Kill any DHCPv6. */ 1415 if (!anyvalid) 1416 dhcp6_dropnondelegates(ifp); 1417 } 1418 1419 void 1420 ipv6nd_drop(struct interface *ifp) 1421 { 1422 struct ra *rap, *ran; 1423 uint8_t expired = 0; 1424 1425 if (ifp->ctx->ra_routers == NULL) 1426 return; 1427 1428 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 1429 TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) { 1430 if (rap->iface == ifp) { 1431 rap->expired = expired = 1; 1432 ipv6nd_drop_ra(rap); 1433 } 1434 } 1435 if (expired) { 1436 rt_build(ifp->ctx, AF_INET6); 1437 if ((ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) 1438 script_runreason(ifp, "ROUTERADVERT"); 1439 } 1440 } 1441 1442 static void 1443 ipv6nd_handlena(struct dhcpcd_ctx *ctx, struct interface *ifp, 1444 struct icmp6_hdr *icp, size_t len, int hoplimit) 1445 { 1446 struct nd_neighbor_advert *nd_na; 1447 struct in6_addr nd_na_target; 1448 struct ra *rap; 1449 uint32_t is_router, is_solicited; 1450 char buf[INET6_ADDRSTRLEN]; 1451 const char *taddr; 1452 1453 if (ifp == NULL) { 1454 #ifdef DEBUG_NS 1455 logdebugx("NA for unexpected interface from %s", 1456 ctx->sfrom); 1457 #endif 1458 return; 1459 } 1460 1461 if ((size_t)len < sizeof(struct nd_neighbor_advert)) { 1462 logerrx("%s: IPv6 NA too short from %s", 1463 ifp->name, ctx->sfrom); 1464 return; 1465 } 1466 1467 /* RFC 4861 7.1.2 */ 1468 if (hoplimit != 255) { 1469 logerrx("invalid hoplimit(%d) in NA from %s", 1470 hoplimit, ctx->sfrom); 1471 return; 1472 } 1473 1474 nd_na = (struct nd_neighbor_advert *)icp; 1475 is_router = nd_na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER; 1476 is_solicited = nd_na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED; 1477 taddr = inet_ntop(AF_INET6, &nd_na->nd_na_target, 1478 buf, INET6_ADDRSTRLEN); 1479 1480 /* nd_na->nd_na_target is not aligned. */ 1481 memcpy(&nd_na_target, &nd_na->nd_na_target, sizeof(nd_na_target)); 1482 if (IN6_IS_ADDR_MULTICAST(&nd_na_target)) { 1483 logerrx("%s: NA multicast address %s (%s)", 1484 ifp->name, taddr, ctx->sfrom); 1485 return; 1486 } 1487 1488 TAILQ_FOREACH(rap, ctx->ra_routers, next) { 1489 if (rap->iface == ifp && 1490 IN6_ARE_ADDR_EQUAL(&rap->from, &nd_na_target)) 1491 break; 1492 } 1493 if (rap == NULL) { 1494 #ifdef DEBUG_NS 1495 logdebugx("%s: unexpected NA from %s for %s", 1496 ifp->name, ctx->sfrom, taddr); 1497 #endif 1498 return; 1499 } 1500 1501 #ifdef DEBUG_NS 1502 logdebugx("%s: %sNA for %s from %s", 1503 ifp->name, is_solicited ? "solicited " : "", taddr, ctx->sfrom); 1504 #endif 1505 1506 /* Node is no longer a router, so remove it from consideration */ 1507 if (!is_router && !rap->expired) { 1508 loginfox("%s: %s not a router (%s)", 1509 ifp->name, taddr, ctx->sfrom); 1510 rap->expired = 1; 1511 rt_build(ifp->ctx, AF_INET6); 1512 script_runreason(ifp, "ROUTERADVERT"); 1513 return; 1514 } 1515 1516 if (is_solicited && is_router && rap->lifetime) 1517 ipv6nd_reachable(rap, IPV6ND_REACHABLE); 1518 } 1519 1520 static void 1521 ipv6nd_handledata(void *arg) 1522 { 1523 struct dhcpcd_ctx *ctx; 1524 ssize_t len; 1525 struct cmsghdr *cm; 1526 int hoplimit; 1527 struct in6_pktinfo pkt; 1528 struct icmp6_hdr *icp; 1529 struct interface *ifp; 1530 1531 ctx = arg; 1532 ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 1533 CMSG_SPACE(sizeof(int)); 1534 len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0); 1535 if (len == -1) { 1536 logerr(__func__); 1537 return; 1538 } 1539 ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr, 1540 ctx->ntopbuf, INET6_ADDRSTRLEN); 1541 if ((size_t)len < sizeof(struct icmp6_hdr)) { 1542 logerrx("IPv6 ICMP packet too short from %s", ctx->sfrom); 1543 return; 1544 } 1545 1546 pkt.ipi6_ifindex = 0; 1547 hoplimit = 0; 1548 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&ctx->rcvhdr); 1549 cm; 1550 cm = (struct cmsghdr *)CMSG_NXTHDR(&ctx->rcvhdr, cm)) 1551 { 1552 if (cm->cmsg_level != IPPROTO_IPV6) 1553 continue; 1554 switch(cm->cmsg_type) { 1555 case IPV6_PKTINFO: 1556 if (cm->cmsg_len == CMSG_LEN(sizeof(pkt))) 1557 memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt)); 1558 break; 1559 case IPV6_HOPLIMIT: 1560 if (cm->cmsg_len == CMSG_LEN(sizeof(int))) 1561 memcpy(&hoplimit, CMSG_DATA(cm), sizeof(int)); 1562 break; 1563 } 1564 } 1565 1566 if (pkt.ipi6_ifindex == 0) { 1567 logerrx("IPv6 RA/NA did not contain index from %s", ctx->sfrom); 1568 return; 1569 } 1570 1571 /* Find the receiving interface */ 1572 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1573 if (ifp->index == (unsigned int)pkt.ipi6_ifindex) 1574 break; 1575 } 1576 1577 /* Don't do anything if the user hasn't configured it. */ 1578 if (ifp != NULL && 1579 (ifp->active != IF_ACTIVE_USER || 1580 !(ifp->options->options & DHCPCD_IPV6))) 1581 return; 1582 1583 icp = (struct icmp6_hdr *)ctx->rcvhdr.msg_iov[0].iov_base; 1584 if (icp->icmp6_code == 0) { 1585 switch(icp->icmp6_type) { 1586 case ND_NEIGHBOR_ADVERT: 1587 ipv6nd_handlena(ctx, ifp, icp, (size_t)len, 1588 hoplimit); 1589 return; 1590 case ND_ROUTER_ADVERT: 1591 ipv6nd_handlera(ctx, ifp, icp, (size_t)len, 1592 hoplimit); 1593 return; 1594 } 1595 } 1596 1597 logerrx("invalid IPv6 type %d or code %d from %s", 1598 icp->icmp6_type, icp->icmp6_code, ctx->sfrom); 1599 } 1600 1601 static void 1602 ipv6nd_startrs1(void *arg) 1603 { 1604 struct interface *ifp = arg; 1605 struct rs_state *state; 1606 1607 loginfox("%s: soliciting an IPv6 router", ifp->name); 1608 if (ipv6nd_open(ifp->ctx) == -1) { 1609 logerr(__func__); 1610 return; 1611 } 1612 1613 state = RS_STATE(ifp); 1614 if (state == NULL) { 1615 ifp->if_data[IF_DATA_IPV6ND] = calloc(1, sizeof(*state)); 1616 state = RS_STATE(ifp); 1617 if (state == NULL) { 1618 logerr(__func__); 1619 return; 1620 } 1621 } 1622 1623 /* Always make a new probe as the underlying hardware 1624 * address could have changed. */ 1625 ipv6nd_makersprobe(ifp); 1626 if (state->rs == NULL) { 1627 logerr(__func__); 1628 return; 1629 } 1630 1631 state->rsprobes = 0; 1632 ipv6nd_sendrsprobe(ifp); 1633 } 1634 1635 void 1636 ipv6nd_startrs(struct interface *ifp) 1637 { 1638 struct timespec tv; 1639 1640 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); 1641 if (!(ifp->options->options & DHCPCD_INITIAL_DELAY)) { 1642 ipv6nd_startrs1(ifp); 1643 return; 1644 } 1645 1646 tv.tv_sec = 0; 1647 tv.tv_nsec = (suseconds_t)arc4random_uniform( 1648 MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC); 1649 timespecnorm(&tv); 1650 logdebugx("%s: delaying IPv6 router solicitation for %0.1f seconds", 1651 ifp->name, timespec_to_double(&tv)); 1652 eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp); 1653 return; 1654 } 1655