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