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