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