1 /* $NetBSD: rtadvd.c,v 1.66 2018/04/24 18:31:48 roy Exp $ */ 2 /* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/socket.h> 35 #include <sys/uio.h> 36 #include <sys/time.h> 37 #include <sys/queue.h> 38 39 #include <net/if.h> 40 #include <net/route.h> 41 #include <net/if_dl.h> 42 #include <netinet/in.h> 43 #include <netinet/ip6.h> 44 #include <netinet6/ip6_var.h> 45 #include <netinet/icmp6.h> 46 47 #include <arpa/inet.h> 48 49 #include <time.h> 50 #include <unistd.h> 51 #include <stdio.h> 52 #include <err.h> 53 #include <errno.h> 54 #include <string.h> 55 #include <stdlib.h> 56 #include <syslog.h> 57 #include <stdarg.h> 58 #ifdef __NetBSD__ 59 #include <util.h> 60 #endif 61 #include <poll.h> 62 #include <pwd.h> 63 64 #include "rtadvd.h" 65 #include "rrenum.h" 66 #include "advcap.h" 67 #include "timer.h" 68 #include "if.h" 69 #include "config.h" 70 #include "dump.h" 71 #include "logit.h" 72 #include "prog_ops.h" 73 74 struct msghdr rcvmhdr; 75 static unsigned char *rcvcmsgbuf; 76 static size_t rcvcmsgbuflen; 77 static unsigned char *sndcmsgbuf; 78 static size_t sndcmsgbuflen; 79 volatile sig_atomic_t do_dump; 80 volatile sig_atomic_t do_reconf; 81 volatile sig_atomic_t do_die; 82 struct msghdr sndmhdr; 83 struct iovec rcviov[2]; 84 struct iovec sndiov[2]; 85 struct sockaddr_in6 rcvfrom; 86 static const char *dumpfilename = "/var/run/rtadvd.dump"; /* XXX configurable */ 87 static char *mcastif; 88 int sock; 89 int rtsock = -1; 90 int accept_rr = 0; 91 int dflag = 0, sflag = 0, Dflag; 92 93 static char **if_argv; 94 static int if_argc; 95 96 char *conffile = NULL; 97 98 struct ralist_head_t ralist = TAILQ_HEAD_INITIALIZER(ralist); 99 100 struct nd_optlist { 101 TAILQ_ENTRY(nd_optlist) next; 102 struct nd_opt_hdr *opt; 103 }; 104 union nd_opts { 105 struct nd_opt_hdr *nd_opt_array[9]; 106 struct { 107 struct nd_opt_hdr *zero; 108 struct nd_opt_hdr *src_lladdr; 109 struct nd_opt_hdr *tgt_lladdr; 110 struct nd_opt_prefix_info *pi; 111 struct nd_opt_rd_hdr *rh; 112 struct nd_opt_mtu *mtu; 113 TAILQ_HEAD(, nd_optlist) list; 114 } nd_opt_each; 115 }; 116 #define nd_opts_src_lladdr nd_opt_each.src_lladdr 117 #define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr 118 #define nd_opts_pi nd_opt_each.pi 119 #define nd_opts_rh nd_opt_each.rh 120 #define nd_opts_mtu nd_opt_each.mtu 121 #define nd_opts_list nd_opt_each.list 122 123 #define NDOPT_FLAG_SRCLINKADDR (1 << 0) 124 #define NDOPT_FLAG_TGTLINKADDR (1 << 1) 125 #define NDOPT_FLAG_PREFIXINFO (1 << 2) 126 #define NDOPT_FLAG_RDHDR (1 << 3) 127 #define NDOPT_FLAG_MTU (1 << 4) 128 #define NDOPT_FLAG_RDNSS (1 << 5) 129 #define NDOPT_FLAG_DNSSL (1 << 6) 130 131 uint32_t ndopt_flags[] = { 132 [ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR, 133 [ND_OPT_TARGET_LINKADDR] = NDOPT_FLAG_TGTLINKADDR, 134 [ND_OPT_PREFIX_INFORMATION] = NDOPT_FLAG_PREFIXINFO, 135 [ND_OPT_REDIRECTED_HEADER] = NDOPT_FLAG_RDHDR, 136 [ND_OPT_MTU] = NDOPT_FLAG_MTU, 137 [ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS, 138 [ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL, 139 }; 140 141 struct sockaddr_in6 sin6_linklocal_allnodes = { 142 .sin6_len = sizeof(sin6_linklocal_allnodes), 143 .sin6_family = AF_INET6, 144 .sin6_addr = IN6ADDR_LINKLOCAL_ALLNODES_INIT, 145 }; 146 #ifdef notdef 147 struct sockaddr_in6 sin6_linklocal_allrouters = { 148 .sin6_len = sizeof(sin6_linklocal_allrouters), 149 .sin6_family = AF_INET6, 150 .sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT, 151 }; 152 #endif 153 struct sockaddr_in6 sin6_sitelocal_allrouters = { 154 .sin6_len = sizeof(sin6_sitelocal_allrouters), 155 .sin6_family = AF_INET6, 156 .sin6_addr = IN6ADDR_SITELOCAL_ALLROUTERS_INIT, 157 }; 158 159 static void set_die(int); 160 static void die(void); 161 static void set_reconf(int); 162 static void sock_open(void); 163 static void rtsock_open(void); 164 static void rtadvd_input(void); 165 static void rs_input(int, struct nd_router_solicit *, 166 struct in6_pktinfo *, struct sockaddr_in6 *); 167 static void ra_input(int, struct nd_router_advert *, 168 struct in6_pktinfo *, struct sockaddr_in6 *); 169 static struct rainfo *ra_output(struct rainfo *, bool); 170 static int prefix_check(struct nd_opt_prefix_info *, struct rainfo *, 171 struct sockaddr_in6 *); 172 static int nd6_options(struct nd_opt_hdr *, int, union nd_opts *, uint32_t); 173 static void free_ndopts(union nd_opts *); 174 static void rtmsg_input(void); 175 static void rtadvd_set_dump_file(int); 176 177 int 178 main(int argc, char *argv[]) 179 { 180 struct pollfd set[2]; 181 struct timespec *timeout; 182 int i, ch; 183 int fflag = 0, logopt; 184 struct passwd *pw; 185 const char *pidfilepath = NULL; 186 pid_t pid; 187 188 /* get command line options and arguments */ 189 #define OPTIONS "c:dDfM:p:Rs" 190 while ((ch = getopt(argc, argv, OPTIONS)) != -1) { 191 #undef OPTIONS 192 switch (ch) { 193 case 'c': 194 conffile = optarg; 195 break; 196 case 'd': 197 dflag++; 198 break; 199 case 'D': 200 Dflag++; 201 break; 202 case 'f': 203 fflag = 1; 204 break; 205 case 'M': 206 mcastif = optarg; 207 break; 208 case 'p': 209 pidfilepath = optarg; 210 break; 211 case 'R': 212 fprintf(stderr, "rtadvd: " 213 "the -R option is currently ignored.\n"); 214 /* accept_rr = 1; */ 215 /* run anyway... */ 216 break; 217 case 's': 218 sflag = 1; 219 break; 220 } 221 } 222 argc -= optind; 223 argv += optind; 224 if (argc == 0) { 225 fprintf(stderr, "Ysage: %s [-DdfRs] [-c conffile]" 226 " [-M ifname] [-p pidfile] interface ...\n", getprogname()); 227 return EXIT_FAILURE; 228 } 229 230 if ((pid = pidfile_lock(pidfilepath)) != 0) { 231 if (pid == -1) 232 logit(LOG_ERR, "pidfile_lock: %m"); 233 /* Continue */ 234 else { 235 logit(LOG_ERR, "Another instance of `%s' is running " 236 "(pid %d); exiting.", getprogname(), pid); 237 return EXIT_FAILURE; 238 } 239 } 240 241 if (prog_init && prog_init() == -1) 242 err(EXIT_FAILURE, "init failed"); 243 244 logopt = LOG_NDELAY | LOG_PID; 245 if (fflag) 246 logopt |= LOG_PERROR; 247 openlog("rtadvd", logopt, LOG_DAEMON); 248 249 /* set log level */ 250 if (dflag == 0) 251 (void)setlogmask(LOG_UPTO(LOG_ERR)); 252 if (dflag == 1) 253 (void)setlogmask(LOG_UPTO(LOG_INFO)); 254 255 errno = 0; /* Ensure errno is 0 so we know if getpwnam errors or not */ 256 if ((pw = getpwnam(RTADVD_USER)) == NULL) { 257 if (errno == 0) 258 logit(LOG_ERR, 259 "user %s does not exist, aborting", 260 RTADVD_USER); 261 else 262 logit(LOG_ERR, "getpwnam: %s: %m", RTADVD_USER); 263 return EXIT_FAILURE; 264 } 265 266 /* timer initialization */ 267 rtadvd_timer_init(); 268 269 if_argc = argc; 270 if_argv = argv; 271 while (argc--) 272 getconfig(*argv++, 1); 273 274 if (!fflag) { 275 prog_daemon(1, 0); 276 if (pidfile_lock(pidfilepath) != 0) 277 logit(LOG_ERR, " pidfile_lock: %m"); 278 } 279 280 sock_open(); 281 282 set[0].fd = sock; 283 set[0].events = POLLIN; 284 if (sflag == 0) { 285 rtsock_open(); 286 set[1].fd = rtsock; 287 set[1].events = POLLIN; 288 } else 289 set[1].fd = -1; 290 291 logit(LOG_INFO, "dropping privileges to %s", RTADVD_USER); 292 if (prog_chroot(pw->pw_dir) == -1) { 293 logit(LOG_ERR, "chroot: %s: %m", pw->pw_dir); 294 return EXIT_FAILURE; 295 } 296 if (prog_chdir("/") == -1) { 297 logit(LOG_ERR, "chdir: /: %m"); 298 return EXIT_FAILURE; 299 } 300 if (prog_setgroups(1, &pw->pw_gid) == -1 || 301 prog_setgid(pw->pw_gid) == -1 || 302 prog_setuid(pw->pw_uid) == -1) 303 { 304 logit(LOG_ERR, "failed to drop privileges: %m"); 305 return EXIT_FAILURE; 306 } 307 308 signal(SIGINT, set_die); 309 signal(SIGTERM, set_die); 310 signal(SIGHUP, set_reconf); 311 signal(SIGUSR1, rtadvd_set_dump_file); 312 313 for (;;) { 314 if (do_dump) { /* SIGUSR1 */ 315 do_dump = 0; 316 rtadvd_dump_file(dumpfilename); 317 } 318 319 if (do_reconf) { /* SIGHUP */ 320 do_reconf = 0; 321 logit(LOG_INFO, "%s: reloading config on SIGHUP", 322 __func__); 323 argc = if_argc; 324 argv = if_argv; 325 while (argc--) 326 getconfig(*argv++, 0); 327 } 328 329 /* timer expiration check and reset the timer */ 330 timeout = rtadvd_check_timer(); 331 332 if (do_die) { 333 die(); 334 /*NOTREACHED*/ 335 } 336 337 if (timeout != NULL) { 338 logit(LOG_DEBUG, 339 "%s: set timer to %jd:%jd. waiting for " 340 "inputs or timeout", __func__, 341 (intmax_t)timeout->tv_sec, 342 (intmax_t)timeout->tv_nsec); 343 } else { 344 logit(LOG_DEBUG, 345 "%s: there's no timer. waiting for inputs", 346 __func__); 347 } 348 349 if ((i = prog_poll(set, 2, timeout ? (timeout->tv_sec * 1000 + 350 (timeout->tv_nsec + 999999) / 1000000) : INFTIM)) == -1) 351 { 352 /* EINTR would occur upon SIGUSR1 for status dump */ 353 if (errno == EINTR) 354 continue; 355 356 logit(LOG_ERR, "%s: poll: %m", __func__); 357 if (Dflag) 358 exit(1); 359 } 360 if (i == 0) /* timeout */ 361 continue; 362 if (rtsock != -1 && set[1].revents & POLLIN) 363 rtmsg_input(); 364 if (set[0].revents & POLLIN) 365 rtadvd_input(); 366 } 367 return EXIT_SUCCESS; /* NOTREACHED */ 368 } 369 370 static void 371 rtadvd_set_dump_file(__unused int sig) 372 { 373 374 do_dump = 1; 375 } 376 377 static void 378 set_reconf(__unused int sig) 379 { 380 381 do_reconf = 1; 382 } 383 384 static void 385 set_die(__unused int sig) 386 { 387 388 do_die = 1; 389 } 390 391 static void 392 die(void) 393 { 394 static int waiting; 395 struct rainfo *rai, *ran; 396 struct rdnss *rdnss; 397 struct dnssl *dnssl; 398 399 if (waiting) { 400 if (TAILQ_FIRST(&ralist)) { 401 logit(LOG_INFO, 402 "%s: waiting for expiration of all RA timers", 403 __func__); 404 return; 405 } 406 logit(LOG_NOTICE, "%s: gracefully terminated", __func__); 407 free(rcvcmsgbuf); 408 free(sndcmsgbuf); 409 exit(EXIT_SUCCESS); 410 /* NOT REACHED */ 411 } 412 413 if (TAILQ_FIRST(&ralist) == NULL) { 414 logit(LOG_NOTICE, "%s: gracefully terminated", __func__); 415 exit(EXIT_SUCCESS); 416 /* NOT REACHED */ 417 } 418 419 waiting = 1; 420 logit(LOG_NOTICE, "%s: final RA transmission started", __func__); 421 422 TAILQ_FOREACH_SAFE(rai, &ralist, next, ran) { 423 if (rai->leaving) { 424 TAILQ_REMOVE(&ralist, rai, next); 425 TAILQ_INSERT_HEAD(&ralist, rai->leaving, next); 426 rai->leaving->leaving = rai->leaving; 427 rai->leaving->leaving_for = rai->leaving; 428 free_rainfo(rai); 429 continue; 430 } 431 rai->lifetime = 0; 432 TAILQ_FOREACH(rdnss, &rai->rdnss, next) 433 rdnss->lifetime = 0; 434 TAILQ_FOREACH(dnssl, &rai->dnssl, next) 435 dnssl->lifetime = 0; 436 make_packet(rai); 437 rai->leaving = rai; 438 rai->leaving_for = rai; 439 rai->initcounter = MAX_INITIAL_RTR_ADVERTISEMENTS; 440 rai->mininterval = MIN_DELAY_BETWEEN_RAS; 441 rai->maxinterval = MIN_DELAY_BETWEEN_RAS; 442 rai->leaving_adv = MAX_FINAL_RTR_ADVERTISEMENTS; 443 ra_output(rai, false); 444 ra_timer_update(rai, &rai->timer->tm); 445 rtadvd_set_timer(&rai->timer->tm, rai->timer); 446 } 447 } 448 449 static void 450 rtmsg_input(void) 451 { 452 int n, type, ifindex = 0, plen; 453 size_t len; 454 union rt_msghdr_buf { 455 struct rt_msghdr rt_msghdr; 456 char data[2048]; 457 } buffer; 458 char *msg, *next, *lim, **argv; 459 char ifname[IF_NAMESIZE]; 460 struct prefix *prefix; 461 struct rainfo *rai; 462 struct in6_addr *addr; 463 char addrbuf[INET6_ADDRSTRLEN]; 464 int prefixchange = 0, argc; 465 466 memset(&buffer, 0, sizeof(buffer)); 467 n = prog_read(rtsock, &buffer, sizeof(buffer)); 468 469 /* We read the buffer first to clear the FD */ 470 if (do_die) 471 return; 472 473 msg = buffer.data; 474 if (dflag > 1) { 475 logit(LOG_DEBUG, "%s: received a routing message " 476 "(type = %d, len = %d)", __func__, rtmsg_type(msg), 477 rtmsg_len(msg)); 478 } 479 if (n > rtmsg_len(msg)) { 480 /* 481 * This usually won't happen for messages received on 482 * a routing socket. 483 */ 484 if (dflag > 1) 485 logit(LOG_DEBUG, 486 "%s: received data length is larger than " 487 "1st routing message len. multiple messages? " 488 "read %d bytes, but 1st msg len = %d", 489 __func__, n, rtmsg_len(msg)); 490 #if 0 491 /* adjust length */ 492 n = rtmsg_len(msg); 493 #endif 494 } 495 496 lim = msg + n; 497 for (next = msg; next < lim; next += len) { 498 int oldifflags; 499 500 next = get_next_msg(next, lim, 0, &len, 501 RTADV_TYPE2BITMASK(RTM_ADD) | 502 RTADV_TYPE2BITMASK(RTM_DELETE) | 503 RTADV_TYPE2BITMASK(RTM_NEWADDR) | 504 RTADV_TYPE2BITMASK(RTM_DELADDR) | 505 #ifdef RTM_IFANNOUNCE 506 RTADV_TYPE2BITMASK(RTM_IFANNOUNCE) | 507 #endif 508 RTADV_TYPE2BITMASK(RTM_IFINFO)); 509 if (len == 0) 510 break; 511 type = rtmsg_type(next); 512 switch (type) { 513 case RTM_ADD: 514 case RTM_DELETE: 515 ifindex = get_rtm_ifindex(next); 516 break; 517 case RTM_NEWADDR: 518 case RTM_DELADDR: 519 ifindex = get_ifam_ifindex(next); 520 break; 521 #ifdef RTM_IFANNOUNCE 522 case RTM_IFANNOUNCE: 523 ifindex = get_ifan_ifindex(next); 524 if (get_ifan_what(next) == IFAN_ARRIVAL) { 525 logit(LOG_DEBUG, 526 "%s: interface %s arrived", 527 __func__, 528 if_indextoname(ifindex, ifname)); 529 if (if_argc == 0) { 530 getconfig(ifname, 0); 531 continue; 532 } 533 argc = if_argc; 534 argv = if_argv; 535 while (argc--) { 536 if (strcmp(ifname, *argv++) == 0) { 537 getconfig(ifname, 0); 538 break; 539 } 540 } 541 continue; 542 } 543 break; 544 #endif 545 case RTM_IFINFO: 546 ifindex = get_ifm_ifindex(next); 547 break; 548 default: 549 /* should not reach here */ 550 if (dflag > 1) { 551 logit(LOG_DEBUG, "%s: unknown rtmsg %d on %s", 552 __func__, type, 553 if_indextoname(ifindex, ifname)); 554 } 555 continue; 556 } 557 558 if ((rai = if_indextorainfo(ifindex)) == NULL) { 559 if (dflag > 1) { 560 logit(LOG_DEBUG, 561 "%s: route changed on " 562 "non advertising interface %s (%d)", 563 __func__, 564 if_indextoname(ifindex, ifname), 565 ifindex); 566 } 567 continue; 568 } 569 oldifflags = rai->ifflags; 570 571 switch (type) { 572 case RTM_ADD: 573 /* init ifflags because it may have changed */ 574 rai->ifflags = if_getflags(ifindex, rai->ifflags); 575 576 if (sflag) 577 break; /* we aren't interested in prefixes */ 578 579 addr = get_addr(msg); 580 plen = get_prefixlen(msg); 581 /* sanity check for plen */ 582 /* as RFC2373, prefixlen is at least 4 */ 583 if (plen < 4 || plen > 127) { 584 logit(LOG_INFO, "%s: new interface route's" 585 "plen %d is invalid for a prefix", 586 __func__, plen); 587 break; 588 } 589 prefix = find_prefix(rai, addr, plen); 590 if (prefix) { 591 if (prefix->timer) { 592 /* 593 * If the prefix has been invalidated, 594 * make it available again. 595 */ 596 update_prefix(prefix); 597 prefixchange = 1; 598 } else if (dflag > 1) { 599 logit(LOG_DEBUG, 600 "%s: new prefix(%s/%d) " 601 "added on %s, " 602 "but it was already in list", 603 __func__, 604 inet_ntop(AF_INET6, addr, 605 (char *)addrbuf, INET6_ADDRSTRLEN), 606 plen, rai->ifname); 607 } 608 break; 609 } 610 make_prefix(rai, ifindex, addr, plen); 611 prefixchange = 1; 612 break; 613 case RTM_DELETE: 614 /* init ifflags because it may have changed */ 615 rai->ifflags = if_getflags(ifindex, rai->ifflags); 616 617 if (sflag) 618 break; 619 620 addr = get_addr(msg); 621 plen = get_prefixlen(msg); 622 /* sanity check for plen */ 623 /* as RFC2373, prefixlen is at least 4 */ 624 if (plen < 4 || plen > 127) { 625 logit(LOG_INFO, 626 "%s: deleted interface route's " 627 "plen %d is invalid for a prefix", 628 __func__, plen); 629 break; 630 } 631 prefix = find_prefix(rai, addr, plen); 632 if (prefix == NULL) { 633 if (dflag > 1) { 634 logit(LOG_DEBUG, 635 "%s: prefix(%s/%d) was " 636 "deleted on %s, " 637 "but it was not in list", 638 __func__, 639 inet_ntop(AF_INET6, addr, 640 (char *)addrbuf, INET6_ADDRSTRLEN), 641 plen, rai->ifname); 642 } 643 break; 644 } 645 invalidate_prefix(prefix); 646 prefixchange = 1; 647 break; 648 case RTM_NEWADDR: 649 case RTM_DELADDR: 650 /* init ifflags because it may have changed */ 651 rai->ifflags = if_getflags(ifindex, rai->ifflags); 652 break; 653 case RTM_IFINFO: 654 rai->ifflags = get_ifm_flags(next); 655 break; 656 #ifdef RTM_IFANNOUNCE 657 case RTM_IFANNOUNCE: 658 if (get_ifan_what(next) == IFAN_DEPARTURE) { 659 logit(LOG_DEBUG, 660 "%s: interface %s departed", 661 __func__, rai->ifname); 662 TAILQ_REMOVE(&ralist, rai, next); 663 if (rai->leaving) 664 free_rainfo(rai->leaving); 665 free_rainfo(rai); 666 continue; 667 } 668 break; 669 #endif 670 default: 671 /* should not reach here */ 672 if (dflag > 1) { 673 logit(LOG_DEBUG, 674 "%s: unknown rtmsg %d on %s", 675 __func__, type, 676 if_indextoname(ifindex, ifname)); 677 } 678 return; 679 } 680 681 /* check if an interface flag is changed */ 682 if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */ 683 (rai->ifflags & IFF_UP) == 0) { 684 logit(LOG_INFO, 685 "%s: interface %s becomes down. stop timer.", 686 __func__, rai->ifname); 687 rtadvd_remove_timer(&rai->timer); 688 } else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */ 689 (rai->ifflags & IFF_UP) != 0) { 690 logit(LOG_INFO, 691 "%s: interface %s becomes up. restart timer.", 692 __func__, rai->ifname); 693 694 rai->initcounter = 0; /* reset the counter */ 695 rai->waiting = 0; /* XXX */ 696 rtadvd_remove_timer(&rai->timer); 697 rai->timer = rtadvd_add_timer(ra_timeout, 698 ra_timer_update, rai, rai); 699 ra_timer_update(rai, &rai->timer->tm); 700 rtadvd_set_timer(&rai->timer->tm, rai->timer); 701 rtadvd_remove_timer(&rai->timer_sol); 702 rai->timer_sol = rtadvd_add_timer(ra_timeout_sol, 703 NULL, rai, NULL); 704 } else if (prefixchange && rai->ifflags & IFF_UP) { 705 /* 706 * An advertised prefix has been added or invalidated. 707 * Will notice the change in a short delay. 708 */ 709 rai->initcounter = 0; 710 ra_timer_set_short_delay(rai, rai->timer); 711 } 712 } 713 714 return; 715 } 716 717 void 718 rtadvd_input(void) 719 { 720 ssize_t i; 721 int *hlimp = NULL; 722 struct icmp6_hdr *icp; 723 int ifindex = 0; 724 struct cmsghdr *cm; 725 struct in6_pktinfo *pi = NULL; 726 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 727 struct in6_addr dst = in6addr_any; 728 struct rainfo *rai; 729 730 /* 731 * Get message. We reset msg_controllen since the field could 732 * be modified if we had received a message before setting 733 * receive options. 734 */ 735 rcvmhdr.msg_controllen = rcvcmsgbuflen; 736 if ((i = prog_recvmsg(sock, &rcvmhdr, 0)) == -1) 737 return; 738 739 /* We read the buffer first to clear the FD */ 740 if (do_die) 741 return; 742 743 /* extract optional information via Advanced API */ 744 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr); 745 cm; 746 cm = (struct cmsghdr *)CMSG_NXTHDR(&rcvmhdr, cm)) { 747 if (cm->cmsg_level == IPPROTO_IPV6 && 748 cm->cmsg_type == IPV6_PKTINFO && 749 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { 750 pi = (struct in6_pktinfo *)(CMSG_DATA(cm)); 751 ifindex = pi->ipi6_ifindex; 752 dst = pi->ipi6_addr; 753 } 754 if (cm->cmsg_level == IPPROTO_IPV6 && 755 cm->cmsg_type == IPV6_HOPLIMIT && 756 cm->cmsg_len == CMSG_LEN(sizeof(int))) 757 hlimp = (int *)CMSG_DATA(cm); 758 } 759 if (ifindex == 0) { 760 logit(LOG_ERR, 761 "%s: failed to get receiving interface", 762 __func__); 763 return; 764 } 765 if (hlimp == NULL) { 766 logit(LOG_ERR, 767 "%s: failed to get receiving hop limit", 768 __func__); 769 return; 770 } 771 772 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == NULL) { 773 if (dflag > 1) { 774 logit(LOG_DEBUG, 775 "%s: received data for non advertising " 776 "interface (%s)", 777 __func__, 778 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 779 } 780 return; 781 } 782 /* 783 * If we happen to receive data on an interface which is now down, 784 * just discard the data. 785 */ 786 if ((rai->ifflags & IFF_UP) == 0) { 787 logit(LOG_INFO, 788 "%s: received data on a disabled interface (%s)", 789 __func__, 790 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 791 return; 792 } 793 794 if ((size_t)i < sizeof(struct icmp6_hdr)) { 795 logit(LOG_ERR, 796 "%s: packet size(%zd) is too short", 797 __func__, i); 798 return; 799 } 800 801 icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base; 802 803 switch (icp->icmp6_type) { 804 case ND_ROUTER_SOLICIT: 805 /* 806 * Message verification - RFC-2461 6.1.1 807 * XXX: these checks must be done in the kernel as well, 808 * but we can't completely rely on them. 809 */ 810 if (*hlimp != 255) { 811 logit(LOG_NOTICE, 812 "%s: RS with invalid hop limit(%d) " 813 "received from %s on %s", 814 __func__, *hlimp, 815 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 816 INET6_ADDRSTRLEN), 817 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 818 return; 819 } 820 if (icp->icmp6_code) { 821 logit(LOG_NOTICE, 822 "%s: RS with invalid ICMP6 code(%d) " 823 "received from %s on %s", 824 __func__, icp->icmp6_code, 825 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 826 INET6_ADDRSTRLEN), 827 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 828 return; 829 } 830 if ((size_t)i < sizeof(struct nd_router_solicit)) { 831 logit(LOG_NOTICE, 832 "%s: RS from %s on %s does not have enough " 833 "length (len = %zd)", 834 __func__, 835 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 836 INET6_ADDRSTRLEN), 837 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i); 838 return; 839 } 840 rs_input(i, (struct nd_router_solicit *)icp, pi, &rcvfrom); 841 break; 842 case ND_ROUTER_ADVERT: 843 /* 844 * Message verification - RFC-2461 6.1.2 845 * XXX: there's a same dilemma as above... 846 */ 847 if (*hlimp != 255) { 848 logit(LOG_NOTICE, 849 "%s: RA with invalid hop limit(%d) " 850 "received from %s on %s", 851 __func__, *hlimp, 852 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 853 INET6_ADDRSTRLEN), 854 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 855 return; 856 } 857 if (icp->icmp6_code) { 858 logit(LOG_NOTICE, 859 "%s: RA with invalid ICMP6 code(%d) " 860 "received from %s on %s", 861 __func__, icp->icmp6_code, 862 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 863 INET6_ADDRSTRLEN), 864 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 865 return; 866 } 867 if ((size_t)i < sizeof(struct nd_router_advert)) { 868 logit(LOG_NOTICE, 869 "%s: RA from %s on %s does not have enough " 870 "length (len = %zd)", 871 __func__, 872 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf, 873 INET6_ADDRSTRLEN), 874 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i); 875 return; 876 } 877 ra_input(i, (struct nd_router_advert *)icp, pi, &rcvfrom); 878 break; 879 case ICMP6_ROUTER_RENUMBERING: 880 if (accept_rr == 0) { 881 logit(LOG_ERR, "%s: received a router renumbering " 882 "message, but not allowed to be accepted", 883 __func__); 884 break; 885 } 886 rr_input(i, (struct icmp6_router_renum *)icp, pi, &rcvfrom, 887 &dst); 888 break; 889 default: 890 /* 891 * Note that this case is POSSIBLE, especially just 892 * after invocation of the daemon. This is because we 893 * could receive message after opening the socket and 894 * before setting ICMP6 type filter(see sock_open()). 895 */ 896 logit(LOG_ERR, "%s: invalid icmp type(%d)", 897 __func__, icp->icmp6_type); 898 return; 899 } 900 } 901 902 static void 903 rs_input(int len, struct nd_router_solicit *rs, 904 struct in6_pktinfo *pi, struct sockaddr_in6 *from) 905 { 906 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 907 union nd_opts ndopts; 908 struct rainfo *rai; 909 struct soliciter *sol; 910 911 logit(LOG_DEBUG, 912 "%s: RS received from %s on %s", 913 __func__, 914 inet_ntop(AF_INET6, &from->sin6_addr, 915 ntopbuf, INET6_ADDRSTRLEN), 916 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 917 918 /* ND option check */ 919 memset(&ndopts, 0, sizeof(ndopts)); 920 TAILQ_INIT(&ndopts.nd_opts_list); 921 if (nd6_options((struct nd_opt_hdr *)(rs + 1), 922 len - sizeof(struct nd_router_solicit), 923 &ndopts, NDOPT_FLAG_SRCLINKADDR)) { 924 logit(LOG_INFO, 925 "%s: ND option check failed for an RS from %s on %s", 926 __func__, 927 inet_ntop(AF_INET6, &from->sin6_addr, 928 ntopbuf, INET6_ADDRSTRLEN), 929 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 930 return; 931 } 932 933 /* 934 * If the IP source address is the unspecified address, there 935 * must be no source link-layer address option in the message. 936 * (RFC-2461 6.1.1) 937 */ 938 if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) && 939 ndopts.nd_opts_src_lladdr) { 940 logit(LOG_INFO, 941 "%s: RS from unspecified src on %s has a link-layer" 942 " address option", 943 __func__, 944 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 945 goto done; 946 } 947 948 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == NULL) { 949 logit(LOG_INFO, 950 "%s: RS received on non advertising interface(%s)", 951 __func__, 952 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 953 goto done; 954 } 955 956 if (rai->leaving) { 957 logit(LOG_INFO, 958 "%s: RS received on reconfiguring advertising interface(%s)", 959 __func__, rai->ifname); 960 goto done; 961 } 962 963 rai->rsinput++; /* increment statistics */ 964 965 /* 966 * Decide whether to send RA according to the rate-limit 967 * consideration. 968 */ 969 970 /* record sockaddr waiting for RA, if possible */ 971 TAILQ_FOREACH(sol, &rai->soliciter, next) { 972 if (IN6_ARE_ADDR_EQUAL(&sol->addr.sin6_addr, &from->sin6_addr)) 973 break; 974 } 975 if (sol == NULL) { 976 sol = malloc(sizeof(*sol)); 977 if (sol == NULL) { 978 logit(LOG_ERR, "%s: malloc: %m", __func__); 979 } else { 980 sol->addr = *from; 981 /* XXX RFC2553 need clarification on flowinfo */ 982 sol->addr.sin6_flowinfo = 0; 983 TAILQ_INSERT_TAIL(&rai->soliciter, sol, next); 984 } 985 } 986 987 /* 988 * If there is already a waiting RS packet, don't 989 * update the timer. 990 */ 991 if (rai->waiting++) 992 goto done; 993 994 ra_timer_set_short_delay(rai, rai->timer_sol); 995 996 done: 997 free_ndopts(&ndopts); 998 } 999 1000 void 1001 ra_timer_set_short_delay(struct rainfo *rai, struct rtadvd_timer *timer) 1002 { 1003 long delay; /* must not be greater than 1000000 */ 1004 struct timespec interval, now, min_delay, tm_tmp, *rest; 1005 1006 /* 1007 * Compute a random delay. If the computed value 1008 * corresponds to a time later than the time the next 1009 * multicast RA is scheduled to be sent, ignore the random 1010 * delay and send the advertisement at the 1011 * already-scheduled time. RFC2461 6.2.6 1012 */ 1013 delay = arc4random() % MAX_RA_DELAY_TIME; 1014 interval.tv_sec = 0; 1015 interval.tv_nsec = delay; 1016 rest = rtadvd_timer_rest(rai->timer); 1017 if (timespeccmp(rest, &interval, <)) { 1018 logit(LOG_DEBUG, "%s: random delay is larger than " 1019 "the rest of current timer", __func__); 1020 interval = *rest; 1021 } 1022 1023 /* 1024 * If we sent a multicast Router Advertisement within 1025 * the last MIN_DELAY_BETWEEN_RAS seconds, schedule 1026 * the advertisement to be sent at a time corresponding to 1027 * MIN_DELAY_BETWEEN_RAS plus the random value after the 1028 * previous advertisement was sent. 1029 */ 1030 prog_clock_gettime(CLOCK_MONOTONIC, &now); 1031 timespecsub(&now, &rai->lastsent, &tm_tmp); 1032 min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS; 1033 min_delay.tv_nsec = 0; 1034 if (timespeccmp(&tm_tmp, &min_delay, <)) { 1035 timespecsub(&min_delay, &tm_tmp, &min_delay); 1036 timespecadd(&min_delay, &interval, &interval); 1037 } 1038 rtadvd_set_timer(&interval, timer); 1039 } 1040 1041 static void 1042 ra_input(int len, struct nd_router_advert *ra, 1043 struct in6_pktinfo *pi, struct sockaddr_in6 *from) 1044 { 1045 struct rainfo *rai; 1046 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 1047 union nd_opts ndopts; 1048 const char *on_off[] = {"OFF", "ON"}; 1049 uint32_t reachabletime, retranstimer, mtu; 1050 struct nd_optlist *optp; 1051 int inconsistent = 0; 1052 1053 logit(LOG_DEBUG, 1054 "%s: RA received from %s on %s", 1055 __func__, 1056 inet_ntop(AF_INET6, &from->sin6_addr, 1057 ntopbuf, INET6_ADDRSTRLEN), 1058 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 1059 1060 /* ND option check */ 1061 memset(&ndopts, 0, sizeof(ndopts)); 1062 TAILQ_INIT(&ndopts.nd_opts_list); 1063 if (nd6_options((struct nd_opt_hdr *)(ra + 1), 1064 len - sizeof(struct nd_router_advert), 1065 &ndopts, NDOPT_FLAG_SRCLINKADDR | 1066 NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU | 1067 NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL)) 1068 { 1069 logit(LOG_INFO, 1070 "%s: ND option check failed for an RA from %s on %s", 1071 __func__, 1072 inet_ntop(AF_INET6, &from->sin6_addr, 1073 ntopbuf, INET6_ADDRSTRLEN), 1074 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 1075 return; 1076 } 1077 1078 /* 1079 * RA consistency check according to RFC-2461 6.2.7 1080 */ 1081 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == 0) { 1082 logit(LOG_INFO, 1083 "%s: received RA from %s on non-advertising" 1084 " interface(%s)", 1085 __func__, 1086 inet_ntop(AF_INET6, &from->sin6_addr, 1087 ntopbuf, INET6_ADDRSTRLEN), 1088 if_indextoname(pi->ipi6_ifindex, ifnamebuf)); 1089 goto done; 1090 } 1091 if (rai->leaving) { 1092 logit(LOG_DEBUG, 1093 "%s: received RA on re-configuring interface (%s)", 1094 __func__, rai->ifname); 1095 goto done; 1096 } 1097 rai->rainput++; /* increment statistics */ 1098 1099 /* Cur Hop Limit value */ 1100 if (ra->nd_ra_curhoplimit && rai->hoplimit && 1101 ra->nd_ra_curhoplimit != rai->hoplimit) { 1102 logit(LOG_INFO, 1103 "%s: CurHopLimit inconsistent on %s:" 1104 " %d from %s, %d from us", 1105 __func__, 1106 rai->ifname, 1107 ra->nd_ra_curhoplimit, 1108 inet_ntop(AF_INET6, &from->sin6_addr, 1109 ntopbuf, INET6_ADDRSTRLEN), 1110 rai->hoplimit); 1111 inconsistent++; 1112 } 1113 /* M flag */ 1114 if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) != 1115 rai->managedflg) { 1116 logit(LOG_INFO, 1117 "%s: M flag inconsistent on %s:" 1118 " %s from %s, %s from us", 1119 __func__, 1120 rai->ifname, 1121 on_off[!rai->managedflg], 1122 inet_ntop(AF_INET6, &from->sin6_addr, 1123 ntopbuf, INET6_ADDRSTRLEN), 1124 on_off[rai->managedflg]); 1125 inconsistent++; 1126 } 1127 /* O flag */ 1128 if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) != 1129 rai->otherflg) { 1130 logit(LOG_INFO, 1131 "%s: O flag inconsistent on %s:" 1132 " %s from %s, %s from us", 1133 __func__, 1134 rai->ifname, 1135 on_off[!rai->otherflg], 1136 inet_ntop(AF_INET6, &from->sin6_addr, 1137 ntopbuf, INET6_ADDRSTRLEN), 1138 on_off[rai->otherflg]); 1139 inconsistent++; 1140 } 1141 /* Reachable Time */ 1142 reachabletime = ntohl(ra->nd_ra_reachable); 1143 if (reachabletime && rai->reachabletime && 1144 reachabletime != rai->reachabletime) { 1145 logit(LOG_INFO, 1146 "%s: ReachableTime inconsistent on %s:" 1147 " %d from %s, %d from us", 1148 __func__, 1149 rai->ifname, 1150 reachabletime, 1151 inet_ntop(AF_INET6, &from->sin6_addr, 1152 ntopbuf, INET6_ADDRSTRLEN), 1153 rai->reachabletime); 1154 inconsistent++; 1155 } 1156 /* Retrans Timer */ 1157 retranstimer = ntohl(ra->nd_ra_retransmit); 1158 if (retranstimer && rai->retranstimer && 1159 retranstimer != rai->retranstimer) { 1160 logit(LOG_INFO, 1161 "%s: RetranceTimer inconsistent on %s:" 1162 " %d from %s, %d from us", 1163 __func__, 1164 rai->ifname, 1165 retranstimer, 1166 inet_ntop(AF_INET6, &from->sin6_addr, 1167 ntopbuf, INET6_ADDRSTRLEN), 1168 rai->retranstimer); 1169 inconsistent++; 1170 } 1171 /* Values in the MTU options */ 1172 if (ndopts.nd_opts_mtu) { 1173 mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu); 1174 if (mtu && rai->linkmtu && mtu != rai->linkmtu) { 1175 logit(LOG_INFO, 1176 "%s: MTU option value inconsistent on %s:" 1177 " %d from %s, %d from us", 1178 __func__, 1179 rai->ifname, mtu, 1180 inet_ntop(AF_INET6, &from->sin6_addr, 1181 ntopbuf, INET6_ADDRSTRLEN), 1182 rai->linkmtu); 1183 inconsistent++; 1184 } 1185 } 1186 /* Preferred and Valid Lifetimes for prefixes */ 1187 if (ndopts.nd_opts_pi) 1188 if (prefix_check(ndopts.nd_opts_pi, rai, from)) 1189 inconsistent++; 1190 TAILQ_FOREACH(optp, &ndopts.nd_opts_list, next) 1191 if (prefix_check((struct nd_opt_prefix_info *)optp->opt, 1192 rai, from)) 1193 inconsistent++; 1194 1195 if (inconsistent) 1196 rai->rainconsistent++; 1197 1198 done: 1199 free_ndopts(&ndopts); 1200 } 1201 1202 /* return a non-zero value if the received prefix is inconsitent with ours */ 1203 static int 1204 prefix_check(struct nd_opt_prefix_info *pinfo, 1205 struct rainfo *rai, struct sockaddr_in6 *from) 1206 { 1207 uint32_t preferred_time, valid_time; 1208 struct prefix *pp; 1209 int inconsistent = 0; 1210 char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN]; 1211 struct timespec now; 1212 struct in6_addr prefix; 1213 1214 #if 0 /* impossible */ 1215 if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION) 1216 return 0; 1217 #endif 1218 1219 memcpy(&prefix, &pinfo->nd_opt_pi_prefix, sizeof(prefix)); 1220 1221 /* 1222 * log if the adveritsed prefix has link-local scope(sanity check?) 1223 */ 1224 if (IN6_IS_ADDR_LINKLOCAL(&prefix)) { 1225 logit(LOG_INFO, 1226 "%s: link-local prefix %s/%d is advertised " 1227 "from %s on %s", 1228 __func__, 1229 inet_ntop(AF_INET6, &prefix, 1230 prefixbuf, INET6_ADDRSTRLEN), 1231 pinfo->nd_opt_pi_prefix_len, 1232 inet_ntop(AF_INET6, &from->sin6_addr, 1233 ntopbuf, INET6_ADDRSTRLEN), 1234 rai->ifname); 1235 } 1236 1237 if ((pp = find_prefix(rai, &prefix, 1238 pinfo->nd_opt_pi_prefix_len)) == NULL) { 1239 logit(LOG_INFO, 1240 "%s: prefix %s/%d from %s on %s is not in our list", 1241 __func__, 1242 inet_ntop(AF_INET6, &prefix, 1243 prefixbuf, INET6_ADDRSTRLEN), 1244 pinfo->nd_opt_pi_prefix_len, 1245 inet_ntop(AF_INET6, &from->sin6_addr, 1246 ntopbuf, INET6_ADDRSTRLEN), 1247 rai->ifname); 1248 return 0; 1249 } 1250 1251 preferred_time = ntohl(pinfo->nd_opt_pi_preferred_time); 1252 if (pp->pltimeexpire) { 1253 /* 1254 * The lifetime is decremented in real time, so we should 1255 * compare the expiration time. 1256 * (RFC 2461 Section 6.2.7.) 1257 * XXX: can we really expect that all routers on the link 1258 * have synchronized clocks? 1259 */ 1260 prog_clock_gettime(CLOCK_MONOTONIC, &now); 1261 preferred_time += now.tv_sec; 1262 1263 if (!pp->timer && rai->clockskew && 1264 llabs((long long)preferred_time - pp->pltimeexpire) > rai->clockskew) { 1265 logit(LOG_INFO, 1266 "%s: preferred lifetime for %s/%d" 1267 " (decr. in real time) inconsistent on %s:" 1268 " %d from %s, %ld from us", 1269 __func__, 1270 inet_ntop(AF_INET6, &prefix, 1271 prefixbuf, INET6_ADDRSTRLEN), 1272 pinfo->nd_opt_pi_prefix_len, 1273 rai->ifname, preferred_time, 1274 inet_ntop(AF_INET6, &from->sin6_addr, 1275 ntopbuf, INET6_ADDRSTRLEN), 1276 pp->pltimeexpire); 1277 inconsistent++; 1278 } 1279 } else if (!pp->timer && preferred_time != pp->preflifetime) { 1280 logit(LOG_INFO, 1281 "%s: preferred lifetime for %s/%d" 1282 " inconsistent on %s:" 1283 " %d from %s, %d from us", 1284 __func__, 1285 inet_ntop(AF_INET6, &prefix, 1286 prefixbuf, INET6_ADDRSTRLEN), 1287 pinfo->nd_opt_pi_prefix_len, 1288 rai->ifname, preferred_time, 1289 inet_ntop(AF_INET6, &from->sin6_addr, 1290 ntopbuf, INET6_ADDRSTRLEN), 1291 pp->preflifetime); 1292 } 1293 1294 valid_time = ntohl(pinfo->nd_opt_pi_valid_time); 1295 if (pp->vltimeexpire) { 1296 prog_clock_gettime(CLOCK_MONOTONIC, &now); 1297 valid_time += now.tv_sec; 1298 1299 if (!pp->timer && rai->clockskew && 1300 llabs((long long)valid_time - pp->vltimeexpire) > rai->clockskew) { 1301 logit(LOG_INFO, 1302 "%s: valid lifetime for %s/%d" 1303 " (decr. in real time) inconsistent on %s:" 1304 " %d from %s, %ld from us", 1305 __func__, 1306 inet_ntop(AF_INET6, &prefix, 1307 prefixbuf, INET6_ADDRSTRLEN), 1308 pinfo->nd_opt_pi_prefix_len, 1309 rai->ifname, preferred_time, 1310 inet_ntop(AF_INET6, &from->sin6_addr, 1311 ntopbuf, INET6_ADDRSTRLEN), 1312 pp->vltimeexpire); 1313 inconsistent++; 1314 } 1315 } else if (!pp->timer && valid_time != pp->validlifetime) { 1316 logit(LOG_INFO, 1317 "%s: valid lifetime for %s/%d" 1318 " inconsistent on %s:" 1319 " %d from %s, %d from us", 1320 __func__, 1321 inet_ntop(AF_INET6, &prefix, 1322 prefixbuf, INET6_ADDRSTRLEN), 1323 pinfo->nd_opt_pi_prefix_len, 1324 rai->ifname, valid_time, 1325 inet_ntop(AF_INET6, &from->sin6_addr, 1326 ntopbuf, INET6_ADDRSTRLEN), 1327 pp->validlifetime); 1328 inconsistent++; 1329 } 1330 1331 return inconsistent; 1332 } 1333 1334 struct prefix * 1335 find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen) 1336 { 1337 struct prefix *pp; 1338 int bytelen, bitlen; 1339 unsigned char bitmask; 1340 1341 TAILQ_FOREACH(pp, &rai->prefix, next) { 1342 if (plen != pp->prefixlen) 1343 continue; 1344 bytelen = plen / 8; 1345 bitlen = plen % 8; 1346 bitmask = 0xff << (8 - bitlen); 1347 if (memcmp(prefix, &pp->prefix, bytelen)) 1348 continue; 1349 if (bitlen == 0 || 1350 ((prefix->s6_addr[bytelen] & bitmask) == 1351 (pp->prefix.s6_addr[bytelen] & bitmask))) { 1352 return pp; 1353 } 1354 } 1355 1356 return NULL; 1357 } 1358 1359 /* check if p0/plen0 matches p1/plen1; return 1 if matches, otherwise 0. */ 1360 int 1361 prefix_match(struct in6_addr *p0, int plen0, 1362 struct in6_addr *p1, int plen1) 1363 { 1364 int bytelen, bitlen; 1365 unsigned char bitmask; 1366 1367 if (plen0 < plen1) 1368 return 0; 1369 bytelen = plen1 / 8; 1370 bitlen = plen1 % 8; 1371 bitmask = 0xff << (8 - bitlen); 1372 if (memcmp(p0, p1, bytelen)) 1373 return 0; 1374 if (bitlen == 0 || 1375 ((p0->s6_addr[bytelen] & bitmask) == 1376 (p1->s6_addr[bytelen] & bitmask))) { 1377 return 1; 1378 } 1379 1380 return 0; 1381 } 1382 1383 static int 1384 nd6_options(struct nd_opt_hdr *hdr, int limit, 1385 union nd_opts *ndopts, uint32_t optflags) 1386 { 1387 int optlen = 0; 1388 1389 for (; limit > 0; limit -= optlen) { 1390 if ((size_t)limit < sizeof(struct nd_opt_hdr)) { 1391 logit(LOG_INFO, "%s: short option header", __func__); 1392 goto bad; 1393 } 1394 1395 hdr = (struct nd_opt_hdr *)((char *)hdr + optlen); 1396 if (hdr->nd_opt_len == 0) { 1397 logit(LOG_INFO, 1398 "%s: bad ND option length(0) (type = %d)", 1399 __func__, hdr->nd_opt_type); 1400 goto bad; 1401 } 1402 optlen = hdr->nd_opt_len << 3; 1403 if (optlen > limit) { 1404 logit(LOG_INFO, "%s: short option", __func__); 1405 goto bad; 1406 } 1407 1408 if (hdr->nd_opt_type > ND_OPT_MTU && 1409 hdr->nd_opt_type != ND_OPT_RDNSS && 1410 hdr->nd_opt_type != ND_OPT_DNSSL) 1411 { 1412 logit(LOG_INFO, "%s: unknown ND option(type %d)", 1413 __func__, hdr->nd_opt_type); 1414 continue; 1415 } 1416 1417 if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) { 1418 logit(LOG_INFO, "%s: unexpected ND option(type %d)", 1419 __func__, hdr->nd_opt_type); 1420 continue; 1421 } 1422 1423 /* 1424 * Option length check. Do it here for all fixed-length 1425 * options. 1426 */ 1427 if ((hdr->nd_opt_type == ND_OPT_MTU && 1428 (optlen != sizeof(struct nd_opt_mtu))) || 1429 ((hdr->nd_opt_type == ND_OPT_PREFIX_INFORMATION && 1430 optlen != sizeof(struct nd_opt_prefix_info))) || 1431 (hdr->nd_opt_type == ND_OPT_RDNSS && 1432 ((optlen < (int)sizeof(struct nd_opt_rdnss) || 1433 (optlen - sizeof(struct nd_opt_rdnss)) % 16 != 0))) || 1434 (hdr->nd_opt_type == ND_OPT_DNSSL && 1435 optlen < (int)sizeof(struct nd_opt_dnssl))) 1436 { 1437 logit(LOG_INFO, "%s: invalid option length", 1438 __func__); 1439 continue; 1440 } 1441 1442 switch (hdr->nd_opt_type) { 1443 case ND_OPT_TARGET_LINKADDR: 1444 case ND_OPT_REDIRECTED_HEADER: 1445 case ND_OPT_RDNSS: 1446 case ND_OPT_DNSSL: 1447 break; /* we don't care about these options */ 1448 case ND_OPT_SOURCE_LINKADDR: 1449 case ND_OPT_MTU: 1450 if (ndopts->nd_opt_array[hdr->nd_opt_type]) { 1451 logit(LOG_INFO, 1452 "%s: duplicated ND option (type = %d)", 1453 __func__, hdr->nd_opt_type); 1454 } 1455 ndopts->nd_opt_array[hdr->nd_opt_type] = hdr; 1456 break; 1457 case ND_OPT_PREFIX_INFORMATION: 1458 { 1459 struct nd_optlist *pfxlist; 1460 1461 if (ndopts->nd_opts_pi == 0) { 1462 ndopts->nd_opts_pi = 1463 (struct nd_opt_prefix_info *)hdr; 1464 continue; 1465 } 1466 if ((pfxlist = malloc(sizeof(*pfxlist))) == NULL) { 1467 logit(LOG_ERR, "%s: can't allocate memory", 1468 __func__); 1469 goto bad; 1470 } 1471 pfxlist->opt = hdr; 1472 TAILQ_INSERT_TAIL(&ndopts->nd_opts_list, pfxlist, next); 1473 1474 break; 1475 } 1476 default: /* impossible */ 1477 break; 1478 } 1479 } 1480 1481 return 0; 1482 1483 bad: 1484 free_ndopts(ndopts); 1485 return -1; 1486 } 1487 1488 static void 1489 free_ndopts(union nd_opts *ndopts) 1490 { 1491 struct nd_optlist *opt; 1492 1493 while ((opt = TAILQ_FIRST(&ndopts->nd_opts_list)) != NULL) { 1494 TAILQ_REMOVE(&ndopts->nd_opts_list, opt, next); 1495 free(opt); 1496 } 1497 } 1498 1499 void 1500 sock_open(void) 1501 { 1502 struct icmp6_filter filt; 1503 struct ipv6_mreq mreq; 1504 struct rainfo *ra; 1505 int on; 1506 /* XXX: should be max MTU attached to the node */ 1507 static unsigned char answer[1500]; 1508 1509 rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 1510 CMSG_SPACE(sizeof(int)); 1511 rcvcmsgbuf = malloc(rcvcmsgbuflen); 1512 if (rcvcmsgbuf == NULL) { 1513 logit(LOG_ERR, "%s: malloc: %m", __func__); 1514 exit(EXIT_FAILURE); 1515 } 1516 1517 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)); 1518 sndcmsgbuf = malloc(sndcmsgbuflen); 1519 if (sndcmsgbuf == NULL) { 1520 logit(LOG_ERR, "%s: malloc: %m", __func__); 1521 exit(EXIT_FAILURE); 1522 } 1523 1524 if ((sock = prog_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) { 1525 logit(LOG_ERR, "%s: socket: %m", __func__); 1526 exit(EXIT_FAILURE); 1527 } 1528 1529 /* RFC 4861 Section 4.2 */ 1530 on = 255; 1531 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &on, 1532 sizeof(on)) == -1) { 1533 logit(LOG_ERR, "%s: IPV6_MULTICAST_HOPS: %m", __func__); 1534 exit(EXIT_FAILURE); 1535 } 1536 on = 255; 1537 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &on, 1538 sizeof(on)) == -1) { 1539 logit(LOG_ERR, "%s: IPV6_UNICAST_HOPS: %m", __func__); 1540 exit(EXIT_FAILURE); 1541 } 1542 1543 /* specify to tell receiving interface */ 1544 on = 1; 1545 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, 1546 sizeof(on)) == -1) { 1547 logit(LOG_ERR, "%s: IPV6_RECVPKTINFO: %m", __func__); 1548 exit(EXIT_FAILURE); 1549 } 1550 1551 on = 1; 1552 /* specify to tell value of hoplimit field of received IP6 hdr */ 1553 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, 1554 sizeof(on)) == -1) { 1555 logit(LOG_ERR, "%s: IPV6_RECVHOPLIMIT: %m", __func__); 1556 exit(EXIT_FAILURE); 1557 } 1558 1559 ICMP6_FILTER_SETBLOCKALL(&filt); 1560 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt); 1561 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); 1562 if (accept_rr) 1563 ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt); 1564 if (prog_setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 1565 sizeof(filt)) == -1) { 1566 logit(LOG_ERR, "%s: IICMP6_FILTER: %m", __func__); 1567 exit(EXIT_FAILURE); 1568 } 1569 1570 /* 1571 * join all routers multicast address on each advertising interface. 1572 */ 1573 if (inet_pton(AF_INET6, ALLROUTERS_LINK, 1574 mreq.ipv6mr_multiaddr.s6_addr) != 1) 1575 { 1576 logit(LOG_ERR, "%s: inet_pton failed(library bug?)", 1577 __func__); 1578 exit(EXIT_FAILURE); 1579 } 1580 TAILQ_FOREACH(ra, &ralist, next) { 1581 mreq.ipv6mr_interface = ra->ifindex; 1582 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, 1583 sizeof(mreq)) == -1) { 1584 logit(LOG_ERR, "%s: IPV6_JOIN_GROUP(link) on %s: %m", 1585 __func__, ra->ifname); 1586 continue; 1587 } 1588 } 1589 1590 /* 1591 * When attending router renumbering, join all-routers site-local 1592 * multicast group. 1593 */ 1594 if (accept_rr) { 1595 if (inet_pton(AF_INET6, ALLROUTERS_SITE, 1596 mreq.ipv6mr_multiaddr.s6_addr) != 1) 1597 { 1598 logit(LOG_ERR, "%s: inet_pton failed(library bug?)", 1599 __func__); 1600 exit(EXIT_FAILURE); 1601 } 1602 ra = TAILQ_FIRST(&ralist); 1603 if (mcastif) { 1604 if ((mreq.ipv6mr_interface = if_nametoindex(mcastif)) 1605 == 0) { 1606 logit(LOG_ERR, 1607 "%s: invalid interface: %s", 1608 __func__, mcastif); 1609 exit(EXIT_FAILURE); 1610 } 1611 } else 1612 mreq.ipv6mr_interface = ra->ifindex; 1613 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, 1614 &mreq, sizeof(mreq)) == -1) { 1615 logit(LOG_ERR, 1616 "%s: IPV6_JOIN_GROUP(site) on %s: %m", 1617 __func__, 1618 mcastif ? mcastif : ra->ifname); 1619 exit(EXIT_FAILURE); 1620 } 1621 } 1622 1623 /* initialize msghdr for receiving packets */ 1624 rcviov[0].iov_base = answer; 1625 rcviov[0].iov_len = sizeof(answer); 1626 rcvmhdr.msg_name = &rcvfrom; 1627 rcvmhdr.msg_namelen = sizeof(rcvfrom); 1628 rcvmhdr.msg_iov = rcviov; 1629 rcvmhdr.msg_iovlen = 1; 1630 rcvmhdr.msg_control = rcvcmsgbuf; 1631 rcvmhdr.msg_controllen = rcvcmsgbuflen; 1632 1633 /* initialize msghdr for sending packets */ 1634 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); 1635 sndmhdr.msg_iov = sndiov; 1636 sndmhdr.msg_iovlen = 1; 1637 sndmhdr.msg_control = sndcmsgbuf; 1638 sndmhdr.msg_controllen = sndcmsgbuflen; 1639 } 1640 1641 /* open a routing socket to watch the routing table */ 1642 static void 1643 rtsock_open(void) 1644 { 1645 #ifdef RO_MSGFILTER 1646 unsigned char msgfilter[] = { 1647 RTM_ADD, RTM_DELETE, 1648 RTM_NEWADDR, RTM_DELADDR, 1649 #ifdef RTM_IFANNOUNCE 1650 RTM_IFANNOUNCE, 1651 #endif 1652 RTM_IFINFO, 1653 }; 1654 #endif 1655 1656 if ((rtsock = prog_socket(PF_ROUTE, SOCK_RAW, 0)) == -1) { 1657 logit(LOG_ERR, "%s: socket: %m", __func__); 1658 exit(EXIT_FAILURE); 1659 } 1660 #ifdef RO_MSGFILTER 1661 if (setsockopt(rtsock, PF_ROUTE, RO_MSGFILTER, 1662 &msgfilter, sizeof(msgfilter) == -1)) 1663 logit(LOG_ERR, "%s: RO_MSGFILTER: %m", __func__); 1664 #endif 1665 } 1666 1667 struct rainfo * 1668 if_indextorainfo(unsigned int idx) 1669 { 1670 struct rainfo *rai; 1671 1672 TAILQ_FOREACH(rai, &ralist, next) { 1673 if (rai->ifindex == idx) 1674 return rai; 1675 } 1676 1677 return NULL; /* search failed */ 1678 } 1679 1680 struct rainfo * 1681 ra_output(struct rainfo *rai, bool solicited) 1682 { 1683 int i; 1684 struct cmsghdr *cm; 1685 struct in6_pktinfo *pi; 1686 struct soliciter *sol; 1687 1688 if ((rai->ifflags & IFF_UP) == 0) { 1689 logit(LOG_DEBUG, "%s: %s is not up, skip sending RA", 1690 __func__, rai->ifname); 1691 return NULL; 1692 } 1693 1694 make_packet(rai); /* XXX: inefficient */ 1695 1696 sndmhdr.msg_name = (void *)&sin6_linklocal_allnodes; 1697 sndmhdr.msg_iov[0].iov_base = (void *)rai->ra_data; 1698 sndmhdr.msg_iov[0].iov_len = rai->ra_datalen; 1699 1700 /* specify the outgoing interface */ 1701 cm = CMSG_FIRSTHDR(&sndmhdr); 1702 cm->cmsg_level = IPPROTO_IPV6; 1703 cm->cmsg_type = IPV6_PKTINFO; 1704 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 1705 pi = (struct in6_pktinfo *)CMSG_DATA(cm); 1706 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ 1707 pi->ipi6_ifindex = rai->ifindex; 1708 1709 logit(LOG_DEBUG, 1710 "%s: send RA on %s, # of waitings = %d", 1711 __func__, rai->ifname, rai->waiting); 1712 1713 if (solicited) { 1714 /* unicast solicited RA's as per RFC 7772 */ 1715 while ((sol = TAILQ_FIRST(&rai->soliciter)) != NULL) { 1716 sndmhdr.msg_name = (void *)&sol->addr; 1717 i = prog_sendmsg(sock, &sndmhdr, 0); 1718 if (i < 0 || (size_t)i != rai->ra_datalen) { 1719 if (i < 0) { 1720 logit(LOG_ERR, 1721 "%s: unicast sendmsg on %s: %m", 1722 __func__, rai->ifname); 1723 } 1724 } 1725 TAILQ_REMOVE(&rai->soliciter, sol, next); 1726 free(sol); 1727 } 1728 1729 /* reset waiting conter */ 1730 rai->waiting = 0; 1731 1732 /* disable timer */ 1733 rai->timer_sol->enabled = false; 1734 1735 return rai; 1736 } 1737 1738 i = prog_sendmsg(sock, &sndmhdr, 0); 1739 if (i < 0 || (size_t)i != rai->ra_datalen) { 1740 if (i < 0) { 1741 logit(LOG_ERR, "%s: sendmsg on %s: %m", 1742 __func__, rai->ifname); 1743 } 1744 } 1745 1746 if (rai->leaving_adv > 0) { 1747 if (--(rai->leaving_adv) == 0) { 1748 /* leaving for ourself means we're shutting down */ 1749 if (rai->leaving_for == rai) { 1750 TAILQ_REMOVE(&ralist, rai, next); 1751 free_rainfo(rai); 1752 return NULL; 1753 } 1754 logit(LOG_DEBUG, 1755 "%s: expired RA," 1756 " new config active for interface (%s)", 1757 __func__, rai->ifname); 1758 rai->leaving_for->timer = rtadvd_add_timer(ra_timeout, 1759 ra_timer_update, 1760 rai->leaving_for, rai->leaving_for); 1761 ra_timer_set_short_delay(rai->leaving_for, rai->timer); 1762 rai->leaving_for->leaving = NULL; 1763 free_rainfo(rai); 1764 return NULL; 1765 } 1766 } 1767 1768 /* update counter */ 1769 if (rai->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS) 1770 rai->initcounter++; 1771 rai->raoutput++; 1772 1773 /* update timestamp */ 1774 prog_clock_gettime(CLOCK_MONOTONIC, &rai->lastsent); 1775 return rai; 1776 } 1777 1778 /* process unsolicited RA timer */ 1779 struct rtadvd_timer * 1780 ra_timeout(void *data) 1781 { 1782 struct rainfo *rai = (struct rainfo *)data; 1783 1784 logit(LOG_DEBUG, 1785 "%s: unsolicited RA timer on %s is expired", 1786 __func__, rai->ifname); 1787 1788 if (ra_output(rai, false)) 1789 return rai->timer; 1790 return NULL; 1791 } 1792 1793 /* process solicited RA timer */ 1794 struct rtadvd_timer * 1795 ra_timeout_sol(void *data) 1796 { 1797 struct rainfo *rai = (struct rainfo *)data; 1798 1799 logit(LOG_DEBUG, 1800 "%s: solicited RA timer on %s is expired", 1801 __func__, rai->ifname); 1802 1803 if (ra_output(rai, true)) 1804 return rai->timer_sol; 1805 return NULL; 1806 } 1807 1808 /* update RA timer */ 1809 void 1810 ra_timer_update(void *data, struct timespec *tm) 1811 { 1812 struct rainfo *rai = (struct rainfo *)data; 1813 long interval; 1814 1815 /* 1816 * Whenever a multicast advertisement is sent from an interface, 1817 * the timer is reset to a uniformly-distributed random value 1818 * between the interface's configured MinRtrAdvInterval and 1819 * MaxRtrAdvInterval (RFC2461 6.2.4). 1820 */ 1821 interval = rai->mininterval; 1822 if (rai->mininterval != rai->maxinterval) 1823 interval += arc4random() % (rai->maxinterval-rai->mininterval); 1824 1825 /* 1826 * For the first few advertisements (up to 1827 * MAX_INITIAL_RTR_ADVERTISEMENTS), if the randomly chosen interval 1828 * is greater than MAX_INITIAL_RTR_ADVERT_INTERVAL, the timer 1829 * SHOULD be set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead. 1830 * (RFC-2461 6.2.4) 1831 */ 1832 if (rai->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS && 1833 interval > MAX_INITIAL_RTR_ADVERT_INTERVAL) 1834 interval = MAX_INITIAL_RTR_ADVERT_INTERVAL; 1835 1836 tm->tv_sec = interval; 1837 tm->tv_nsec = 0; 1838 1839 logit(LOG_DEBUG, 1840 "%s: RA timer on %s is set to %jd:%jd", 1841 __func__, rai->ifname, 1842 (intmax_t)tm->tv_sec, (intmax_t)tm->tv_nsec); 1843 } 1844 1845 __format_arg(3) 1846 static const char * 1847 expandm(char *buf, size_t len, const char *fmt) 1848 { 1849 char *ptr; 1850 const char *e = strerror(errno); 1851 size_t cur = 0, elen = strlen(e); 1852 1853 *buf = '\0'; 1854 while ((ptr = strstr(fmt, "%m")) != NULL) { 1855 size_t l = (size_t)(ptr - fmt); 1856 if (cur + elen + l + 1 >= len) 1857 return buf; 1858 memcpy(buf + cur, fmt, l); 1859 cur += l; 1860 memcpy(buf + cur, e, elen); 1861 cur += elen; 1862 fmt += l + 2; 1863 buf[cur] = '\0'; 1864 } 1865 strlcat(buf, fmt, len); 1866 strlcat(buf, "\n", len); /* syslog does not need \n, printf does */ 1867 return buf; 1868 } 1869 1870 void 1871 logit(int level, const char *fmt, ...) 1872 { 1873 va_list ap; 1874 char buf[1024]; 1875 1876 va_start(ap, fmt); 1877 if (!Dflag) { 1878 vsyslog(level, fmt, ap); 1879 va_end(ap); 1880 return; 1881 } 1882 1883 vfprintf(stderr, expandm(buf, sizeof(buf), fmt), ap); 1884 va_end(ap); 1885 } 1886