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