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