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