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