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