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