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