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