1 /* $OpenBSD: frontend.c,v 1.39 2021/01/19 16:54:48 florian Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Florian Obser <florian@openbsd.org> 5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 24 * All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions 28 * are met: 29 * 1. Redistributions of source code must retain the above copyright 30 * notice, this list of conditions and the following disclaimer. 31 * 2. Redistributions in binary form must reproduce the above copyright 32 * notice, this list of conditions and the following disclaimer in the 33 * documentation and/or other materials provided with the distribution. 34 * 3. Neither the name of the project nor the names of its contributors 35 * may be used to endorse or promote products derived from this software 36 * without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 */ 50 51 #include <sys/types.h> 52 #include <sys/ioctl.h> 53 #include <sys/queue.h> 54 #include <sys/socket.h> 55 #include <sys/syslog.h> 56 #include <sys/uio.h> 57 58 #include <net/if.h> 59 #include <net/if_types.h> 60 #include <net/route.h> 61 62 #include <arpa/inet.h> 63 64 #include <netinet/in.h> 65 #include <netinet/if_ether.h> 66 #include <netinet6/nd6.h> 67 #include <netinet6/in6_var.h> 68 #include <netinet/ip6.h> 69 #include <netinet6/ip6_var.h> 70 #include <netinet/icmp6.h> 71 72 #include <ctype.h> 73 #include <errno.h> 74 #include <event.h> 75 #include <ifaddrs.h> 76 #include <imsg.h> 77 #include <pwd.h> 78 #include <signal.h> 79 #include <stdio.h> 80 #include <stdlib.h> 81 #include <string.h> 82 #include <unistd.h> 83 84 #include "log.h" 85 #include "rad.h" 86 #include "frontend.h" 87 #include "control.h" 88 89 #define RA_MAX_SIZE 1500 90 #define ROUTE_SOCKET_BUF_SIZE 16384 91 92 struct icmp6_ev { 93 struct event ev; 94 uint8_t answer[1500]; 95 struct msghdr rcvmhdr; 96 struct iovec rcviov[1]; 97 struct sockaddr_in6 from; 98 int refcnt; 99 }; 100 101 struct ra_iface { 102 TAILQ_ENTRY(ra_iface) entry; 103 struct icmp6_ev *icmp6ev; 104 struct ra_prefix_conf_head prefixes; 105 char name[IF_NAMESIZE]; 106 char conf_name[IF_NAMESIZE]; 107 uint32_t if_index; 108 int rdomain; 109 int removed; 110 int link_state; 111 int prefix_count; 112 size_t datalen; 113 uint8_t data[RA_MAX_SIZE]; 114 }; 115 116 TAILQ_HEAD(, ra_iface) ra_interfaces; 117 118 __dead void frontend_shutdown(void); 119 void frontend_sig_handler(int, short, void *); 120 void frontend_startup(void); 121 void icmp6_receive(int, short, void *); 122 void join_all_routers_mcast_group(struct ra_iface *); 123 void leave_all_routers_mcast_group(struct ra_iface *); 124 int get_link_state(char *); 125 int get_ifrdomain(char *); 126 void merge_ra_interface(char *, char *); 127 void merge_ra_interfaces(void); 128 struct ra_iface *find_ra_iface_by_id(uint32_t); 129 struct ra_iface *find_ra_iface_by_name(char *); 130 struct ra_iface_conf *find_ra_iface_conf(struct ra_iface_conf_head *, 131 char *); 132 struct ra_prefix_conf *find_ra_prefix_conf(struct ra_prefix_conf_head*, 133 struct in6_addr *, int); 134 struct icmp6_ev *get_icmp6ev_by_rdomain(int); 135 void unref_icmp6ev(struct ra_iface *); 136 void set_icmp6sock(int, int); 137 void add_new_prefix_to_ra_iface(struct ra_iface *r, 138 struct in6_addr *, int, struct ra_prefix_conf *); 139 void free_ra_iface(struct ra_iface *); 140 int in6_mask2prefixlen(struct in6_addr *); 141 void get_interface_prefixes(struct ra_iface *, 142 struct ra_prefix_conf *); 143 int interface_has_linklocal_address(char *); 144 void build_packet(struct ra_iface *); 145 void build_leaving_packet(struct ra_iface *); 146 void ra_output(struct ra_iface *, struct sockaddr_in6 *); 147 void get_rtaddrs(int, struct sockaddr *, 148 struct sockaddr **); 149 void route_receive(int, short, void *); 150 void handle_route_message(struct rt_msghdr *, 151 struct sockaddr **); 152 153 struct rad_conf *frontend_conf; 154 static struct imsgev *iev_main; 155 static struct imsgev *iev_engine; 156 struct event ev_route; 157 int ioctlsock = -1, routesock = -1; 158 struct ipv6_mreq all_routers; 159 struct msghdr sndmhdr; 160 struct iovec sndiov[2]; 161 162 void 163 frontend_sig_handler(int sig, short event, void *bula) 164 { 165 /* 166 * Normal signal handler rules don't apply because libevent 167 * decouples for us. 168 */ 169 170 switch (sig) { 171 case SIGINT: 172 case SIGTERM: 173 frontend_shutdown(); 174 default: 175 fatalx("unexpected signal"); 176 } 177 } 178 179 void 180 frontend(int debug, int verbose) 181 { 182 struct event ev_sigint, ev_sigterm; 183 struct passwd *pw; 184 size_t sndcmsgbuflen; 185 uint8_t *sndcmsgbuf = NULL; 186 187 frontend_conf = config_new_empty(); 188 189 log_init(debug, LOG_DAEMON); 190 log_setverbose(verbose); 191 192 if ((pw = getpwnam(RAD_USER)) == NULL) 193 fatal("getpwnam"); 194 195 if (chroot(pw->pw_dir) == -1) 196 fatal("chroot"); 197 if (chdir("/") == -1) 198 fatal("chdir(\"/\")"); 199 200 setproctitle("%s", "frontend"); 201 log_procinit("frontend"); 202 203 if (setgroups(1, &pw->pw_gid) || 204 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 205 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 206 fatal("can't drop privileges"); 207 208 /* XXX pass in from main */ 209 if ((ioctlsock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == -1) 210 fatal("socket"); 211 212 if (pledge("stdio inet unix recvfd route mcast", NULL) == -1) 213 fatal("pledge"); 214 215 event_init(); 216 217 /* Setup signal handler. */ 218 signal_set(&ev_sigint, SIGINT, frontend_sig_handler, NULL); 219 signal_set(&ev_sigterm, SIGTERM, frontend_sig_handler, NULL); 220 signal_add(&ev_sigint, NULL); 221 signal_add(&ev_sigterm, NULL); 222 signal(SIGPIPE, SIG_IGN); 223 signal(SIGHUP, SIG_IGN); 224 225 /* Setup pipe and event handler to the parent process. */ 226 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL) 227 fatal(NULL); 228 imsg_init(&iev_main->ibuf, 3); 229 iev_main->handler = frontend_dispatch_main; 230 iev_main->events = EV_READ; 231 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 232 iev_main->handler, iev_main); 233 event_add(&iev_main->ev, NULL); 234 235 if (inet_pton(AF_INET6, "ff02::2", 236 &all_routers.ipv6mr_multiaddr.s6_addr) == -1) 237 fatal("inet_pton"); 238 239 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 240 CMSG_SPACE(sizeof(int)); 241 if ((sndcmsgbuf = malloc(sndcmsgbuflen)) == NULL) 242 fatal("%s", __func__); 243 244 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); 245 sndmhdr.msg_iov = sndiov; 246 sndmhdr.msg_iovlen = 1; 247 sndmhdr.msg_control = sndcmsgbuf; 248 sndmhdr.msg_controllen = sndcmsgbuflen; 249 250 TAILQ_INIT(&ra_interfaces); 251 252 event_dispatch(); 253 254 frontend_shutdown(); 255 } 256 257 __dead void 258 frontend_shutdown(void) 259 { 260 /* Close pipes. */ 261 msgbuf_write(&iev_engine->ibuf.w); 262 msgbuf_clear(&iev_engine->ibuf.w); 263 close(iev_engine->ibuf.fd); 264 msgbuf_write(&iev_main->ibuf.w); 265 msgbuf_clear(&iev_main->ibuf.w); 266 close(iev_main->ibuf.fd); 267 268 config_clear(frontend_conf); 269 270 free(iev_engine); 271 free(iev_main); 272 273 log_info("frontend exiting"); 274 exit(0); 275 } 276 277 int 278 frontend_imsg_compose_main(int type, pid_t pid, void *data, uint16_t datalen) 279 { 280 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, 281 datalen)); 282 } 283 284 int 285 frontend_imsg_compose_engine(int type, pid_t pid, void *data, uint16_t datalen) 286 { 287 return (imsg_compose_event(iev_engine, type, 0, pid, -1, data, 288 datalen)); 289 } 290 291 void 292 frontend_dispatch_main(int fd, short event, void *bula) 293 { 294 static struct rad_conf *nconf; 295 static struct ra_iface_conf *ra_iface_conf; 296 static struct ra_options_conf *ra_options; 297 struct imsg imsg; 298 struct imsgev *iev = bula; 299 struct imsgbuf *ibuf = &iev->ibuf; 300 struct ra_prefix_conf *ra_prefix_conf; 301 struct ra_rdnss_conf *ra_rdnss_conf; 302 struct ra_dnssl_conf *ra_dnssl_conf; 303 int n, shut = 0, icmp6sock, rdomain; 304 305 if (event & EV_READ) { 306 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 307 fatal("imsg_read error"); 308 if (n == 0) /* Connection closed. */ 309 shut = 1; 310 } 311 if (event & EV_WRITE) { 312 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 313 fatal("msgbuf_write"); 314 if (n == 0) /* Connection closed. */ 315 shut = 1; 316 } 317 318 for (;;) { 319 if ((n = imsg_get(ibuf, &imsg)) == -1) 320 fatal("%s: imsg_get error", __func__); 321 if (n == 0) /* No more messages. */ 322 break; 323 324 switch (imsg.hdr.type) { 325 case IMSG_SOCKET_IPC: 326 /* 327 * Setup pipe and event handler to the engine 328 * process. 329 */ 330 if (iev_engine) 331 fatalx("%s: received unexpected imsg fd to " 332 "frontend", __func__); 333 if ((fd = imsg.fd) == -1) 334 fatalx("%s: expected to receive imsg fd to " 335 "frontend but didn't receive any", 336 __func__); 337 338 iev_engine = malloc(sizeof(struct imsgev)); 339 if (iev_engine == NULL) 340 fatal(NULL); 341 342 imsg_init(&iev_engine->ibuf, fd); 343 iev_engine->handler = frontend_dispatch_engine; 344 iev_engine->events = EV_READ; 345 346 event_set(&iev_engine->ev, iev_engine->ibuf.fd, 347 iev_engine->events, iev_engine->handler, iev_engine); 348 event_add(&iev_engine->ev, NULL); 349 break; 350 case IMSG_RECONF_CONF: 351 if (nconf != NULL) 352 fatalx("%s: IMSG_RECONF_CONF already in " 353 "progress", __func__); 354 if (IMSG_DATA_SIZE(imsg) != sizeof(struct rad_conf)) 355 fatalx("%s: IMSG_RECONF_CONF wrong length: %lu", 356 __func__, IMSG_DATA_SIZE(imsg)); 357 if ((nconf = malloc(sizeof(struct rad_conf))) == 358 NULL) 359 fatal(NULL); 360 memcpy(nconf, imsg.data, sizeof(struct rad_conf)); 361 SIMPLEQ_INIT(&nconf->ra_iface_list); 362 SIMPLEQ_INIT(&nconf->ra_options.ra_rdnss_list); 363 SIMPLEQ_INIT(&nconf->ra_options.ra_dnssl_list); 364 ra_options = &nconf->ra_options; 365 break; 366 case IMSG_RECONF_RA_IFACE: 367 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 368 ra_iface_conf)) 369 fatalx("%s: IMSG_RECONF_RA_IFACE wrong length: " 370 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 371 if ((ra_iface_conf = malloc(sizeof(struct 372 ra_iface_conf))) == NULL) 373 fatal(NULL); 374 memcpy(ra_iface_conf, imsg.data, sizeof(struct 375 ra_iface_conf)); 376 ra_iface_conf->autoprefix = NULL; 377 SIMPLEQ_INIT(&ra_iface_conf->ra_prefix_list); 378 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_rdnss_list); 379 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_dnssl_list); 380 SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list, 381 ra_iface_conf, entry); 382 ra_options = &ra_iface_conf->ra_options; 383 break; 384 case IMSG_RECONF_RA_AUTOPREFIX: 385 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 386 ra_prefix_conf)) 387 fatalx("%s: IMSG_RECONF_RA_AUTOPREFIX wrong " 388 "length: %lu", __func__, 389 IMSG_DATA_SIZE(imsg)); 390 if ((ra_iface_conf->autoprefix = malloc(sizeof(struct 391 ra_prefix_conf))) == NULL) 392 fatal(NULL); 393 memcpy(ra_iface_conf->autoprefix, imsg.data, 394 sizeof(struct ra_prefix_conf)); 395 break; 396 case IMSG_RECONF_RA_PREFIX: 397 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 398 ra_prefix_conf)) 399 fatalx("%s: IMSG_RECONF_RA_PREFIX wrong " 400 "length: %lu", __func__, 401 IMSG_DATA_SIZE(imsg)); 402 if ((ra_prefix_conf = malloc(sizeof(struct 403 ra_prefix_conf))) == NULL) 404 fatal(NULL); 405 memcpy(ra_prefix_conf, imsg.data, 406 sizeof(struct ra_prefix_conf)); 407 SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_prefix_list, 408 ra_prefix_conf, entry); 409 break; 410 case IMSG_RECONF_RA_RDNSS: 411 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 412 ra_rdnss_conf)) 413 fatalx("%s: IMSG_RECONF_RA_RDNSS wrong length: " 414 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 415 if ((ra_rdnss_conf = malloc(sizeof(struct 416 ra_rdnss_conf))) == NULL) 417 fatal(NULL); 418 memcpy(ra_rdnss_conf, imsg.data, sizeof(struct 419 ra_rdnss_conf)); 420 SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list, 421 ra_rdnss_conf, entry); 422 break; 423 case IMSG_RECONF_RA_DNSSL: 424 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 425 ra_dnssl_conf)) 426 fatalx("%s: IMSG_RECONF_RA_DNSSL wrong length: " 427 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 428 if ((ra_dnssl_conf = malloc(sizeof(struct 429 ra_dnssl_conf))) == NULL) 430 fatal(NULL); 431 memcpy(ra_dnssl_conf, imsg.data, sizeof(struct 432 ra_dnssl_conf)); 433 SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list, 434 ra_dnssl_conf, entry); 435 break; 436 case IMSG_RECONF_END: 437 if (nconf == NULL) 438 fatalx("%s: IMSG_RECONF_END without " 439 "IMSG_RECONF_CONF", __func__); 440 merge_config(frontend_conf, nconf); 441 merge_ra_interfaces(); 442 nconf = NULL; 443 break; 444 case IMSG_ICMP6SOCK: 445 if ((icmp6sock = imsg.fd) == -1) 446 fatalx("%s: expected to receive imsg " 447 "ICMPv6 fd but didn't receive any", 448 __func__); 449 if (IMSG_DATA_SIZE(imsg) != sizeof(rdomain)) 450 fatalx("%s: IMSG_ICMP6SOCK wrong length: " 451 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 452 memcpy(&rdomain, imsg.data, sizeof(rdomain)); 453 set_icmp6sock(icmp6sock, rdomain); 454 break; 455 case IMSG_ROUTESOCK: 456 if (routesock != -1) 457 fatalx("%s: received unexpected routesock fd", 458 __func__); 459 if ((routesock = imsg.fd) == -1) 460 fatalx("%s: expected to receive imsg " 461 "routesocket fd but didn't receive any", 462 __func__); 463 event_set(&ev_route, routesock, EV_READ | EV_PERSIST, 464 route_receive, NULL); 465 break; 466 case IMSG_STARTUP: 467 frontend_startup(); 468 break; 469 case IMSG_CONTROLFD: 470 if ((fd = imsg.fd) == -1) 471 fatalx("%s: expected to receive imsg " 472 "control fd but didn't receive any", 473 __func__); 474 /* Listen on control socket. */ 475 control_listen(fd); 476 break; 477 default: 478 log_debug("%s: error handling imsg %d", __func__, 479 imsg.hdr.type); 480 break; 481 } 482 imsg_free(&imsg); 483 } 484 if (!shut) 485 imsg_event_add(iev); 486 else { 487 /* This pipe is dead. Remove its event handler. */ 488 event_del(&iev->ev); 489 event_loopexit(NULL); 490 } 491 } 492 493 void 494 frontend_dispatch_engine(int fd, short event, void *bula) 495 { 496 struct imsgev *iev = bula; 497 struct imsgbuf *ibuf = &iev->ibuf; 498 struct imsg imsg; 499 struct imsg_send_ra send_ra; 500 struct ra_iface *ra_iface; 501 uint32_t if_index; 502 int n, shut = 0; 503 504 if (event & EV_READ) { 505 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 506 fatal("imsg_read error"); 507 if (n == 0) /* Connection closed. */ 508 shut = 1; 509 } 510 if (event & EV_WRITE) { 511 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 512 fatal("msgbuf_write"); 513 if (n == 0) /* Connection closed. */ 514 shut = 1; 515 } 516 517 for (;;) { 518 if ((n = imsg_get(ibuf, &imsg)) == -1) 519 fatal("%s: imsg_get error", __func__); 520 if (n == 0) /* No more messages. */ 521 break; 522 523 switch (imsg.hdr.type) { 524 case IMSG_SEND_RA: 525 if (IMSG_DATA_SIZE(imsg) != sizeof(send_ra)) 526 fatalx("%s: IMSG_SEND_RA wrong length: %lu", 527 __func__, IMSG_DATA_SIZE(imsg)); 528 memcpy(&send_ra, imsg.data, sizeof(send_ra)); 529 ra_iface = find_ra_iface_by_id(send_ra.if_index); 530 if (ra_iface) 531 ra_output(ra_iface, &send_ra.to); 532 break; 533 case IMSG_REMOVE_IF: 534 if (IMSG_DATA_SIZE(imsg) != sizeof(if_index)) 535 fatalx("%s: IMSG_REMOVE_IF wrong length: %lu", 536 __func__, IMSG_DATA_SIZE(imsg)); 537 memcpy(&if_index, imsg.data, sizeof(if_index)); 538 ra_iface = find_ra_iface_by_id(if_index); 539 if (ra_iface) { 540 TAILQ_REMOVE(&ra_interfaces, ra_iface, entry); 541 free_ra_iface(ra_iface); 542 } 543 break; 544 default: 545 log_debug("%s: error handling imsg %d", __func__, 546 imsg.hdr.type); 547 break; 548 } 549 imsg_free(&imsg); 550 } 551 if (!shut) 552 imsg_event_add(iev); 553 else { 554 /* This pipe is dead. Remove its event handler. */ 555 event_del(&iev->ev); 556 event_loopexit(NULL); 557 } 558 } 559 560 void 561 frontend_startup(void) 562 { 563 if (!event_initialized(&ev_route)) 564 fatalx("%s: did not receive a route socket from the main " 565 "process", __func__); 566 567 event_add(&ev_route, NULL); 568 } 569 570 571 void 572 icmp6_receive(int fd, short events, void *arg) 573 { 574 struct icmp6_ev *icmp6ev; 575 struct icmp6_hdr *icmp6_hdr; 576 struct imsg_ra_rs ra_rs; 577 struct in6_pktinfo *pi = NULL; 578 struct cmsghdr *cm; 579 ssize_t len; 580 int if_index = 0, *hlimp = NULL; 581 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 582 583 icmp6ev = arg; 584 if ((len = recvmsg(fd, &icmp6ev->rcvmhdr, 0)) == -1) { 585 log_warn("recvmsg"); 586 return; 587 } 588 589 if ((size_t)len < sizeof(struct icmp6_hdr)) 590 return; 591 592 icmp6_hdr = (struct icmp6_hdr *)icmp6ev->answer; 593 if (icmp6_hdr->icmp6_type != ND_ROUTER_ADVERT && 594 icmp6_hdr->icmp6_type != ND_ROUTER_SOLICIT) 595 return; 596 597 /* extract optional information via Advanced API */ 598 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&icmp6ev->rcvmhdr); cm; 599 cm = (struct cmsghdr *)CMSG_NXTHDR(&icmp6ev->rcvmhdr, cm)) { 600 if (cm->cmsg_level == IPPROTO_IPV6 && 601 cm->cmsg_type == IPV6_PKTINFO && 602 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { 603 pi = (struct in6_pktinfo *)(CMSG_DATA(cm)); 604 if_index = pi->ipi6_ifindex; 605 } 606 if (cm->cmsg_level == IPPROTO_IPV6 && 607 cm->cmsg_type == IPV6_HOPLIMIT && 608 cm->cmsg_len == CMSG_LEN(sizeof(int))) 609 hlimp = (int *)CMSG_DATA(cm); 610 } 611 612 if (if_index == 0) { 613 log_warnx("failed to get receiving interface"); 614 return; 615 } 616 617 if (hlimp == NULL) { 618 log_warnx("failed to get receiving hop limit"); 619 return; 620 } 621 622 if (*hlimp != 255) { 623 log_warnx("invalid RA or RS with hop limit of %d from %s on %s", 624 *hlimp, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr, 625 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index, 626 ifnamebuf)); 627 return; 628 } 629 630 log_debug("RA or RS with hop limit of %d from %s on %s", 631 *hlimp, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr, 632 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index, 633 ifnamebuf)); 634 635 if ((size_t)len > sizeof(ra_rs.packet)) { 636 log_warnx("invalid RA or RS with size %ld from %s on %s", 637 len, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr, 638 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index, 639 ifnamebuf)); 640 return; 641 } 642 643 ra_rs.if_index = if_index; 644 memcpy(&ra_rs.from, &icmp6ev->from, sizeof(ra_rs.from)); 645 ra_rs.len = len; 646 memcpy(ra_rs.packet, icmp6ev->answer, len); 647 648 frontend_imsg_compose_engine(IMSG_RA_RS, 0, &ra_rs, sizeof(ra_rs)); 649 } 650 651 void 652 join_all_routers_mcast_group(struct ra_iface *ra_iface) 653 { 654 if (!event_initialized(&ra_iface->icmp6ev->ev)) 655 return; 656 log_debug("joining multicast group on %s", ra_iface->name); 657 all_routers.ipv6mr_interface = ra_iface->if_index; 658 if (setsockopt(EVENT_FD(&ra_iface->icmp6ev->ev), IPPROTO_IPV6, 659 IPV6_JOIN_GROUP, &all_routers, sizeof(all_routers)) == -1) 660 fatal("IPV6_JOIN_GROUP(%s)", ra_iface->name); 661 } 662 663 void 664 leave_all_routers_mcast_group(struct ra_iface *ra_iface) 665 { 666 if (!event_initialized(&ra_iface->icmp6ev->ev)) 667 return; 668 log_debug("leaving multicast group on %s", ra_iface->name); 669 all_routers.ipv6mr_interface = ra_iface->if_index; 670 setsockopt(EVENT_FD(&ra_iface->icmp6ev->ev), IPPROTO_IPV6, 671 IPV6_LEAVE_GROUP, &all_routers, sizeof(all_routers)); 672 } 673 674 struct ra_iface* 675 find_ra_iface_by_id(uint32_t if_index) 676 { 677 struct ra_iface *ra_iface; 678 679 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) { 680 if (ra_iface->if_index == if_index) 681 return ra_iface; 682 } 683 return (NULL); 684 } 685 686 struct ra_iface* 687 find_ra_iface_by_name(char *if_name) 688 { 689 struct ra_iface *ra_iface; 690 691 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) { 692 if (strcmp(ra_iface->name, if_name) == 0) 693 return ra_iface; 694 } 695 return (NULL); 696 } 697 698 struct ra_iface_conf* 699 find_ra_iface_conf(struct ra_iface_conf_head *head, char *if_name) 700 { 701 struct ra_iface_conf *ra_iface_conf; 702 703 SIMPLEQ_FOREACH(ra_iface_conf, head, entry) { 704 if (strcmp(ra_iface_conf->name, if_name) == 0) 705 return ra_iface_conf; 706 } 707 return (NULL); 708 } 709 710 int 711 get_link_state(char *if_name) 712 { 713 struct ifaddrs *ifap, *ifa; 714 int ls = LINK_STATE_UNKNOWN; 715 716 if (getifaddrs(&ifap) != 0) { 717 log_warn("getifaddrs"); 718 return LINK_STATE_UNKNOWN; 719 } 720 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 721 if (ifa->ifa_addr == NULL || 722 ifa->ifa_addr->sa_family != AF_LINK) 723 continue; 724 if (strcmp(if_name, ifa->ifa_name) != 0) 725 continue; 726 727 ls = ((struct if_data*)ifa->ifa_data)->ifi_link_state; 728 break; 729 } 730 freeifaddrs(ifap); 731 return ls; 732 } 733 734 int 735 get_ifrdomain(char *if_name) 736 { 737 struct ifreq ifr; 738 739 strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); 740 if (ioctl(ioctlsock, SIOCGIFRDOMAIN, (caddr_t)&ifr) == -1) { 741 log_warn("SIOCGIFRDOMAIN"); 742 return -1; 743 } 744 return ifr.ifr_rdomainid; 745 } 746 747 void 748 merge_ra_interface(char *name, char *conf_name) 749 { 750 struct ra_iface *ra_iface; 751 uint32_t if_index; 752 int link_state, has_linklocal, ifrdomain; 753 754 link_state = get_link_state(name); 755 has_linklocal = interface_has_linklocal_address(name); 756 ifrdomain = get_ifrdomain(name); 757 758 if ((ra_iface = find_ra_iface_by_name(name)) != NULL) { 759 ra_iface->link_state = link_state; 760 if (!LINK_STATE_IS_UP(link_state)) { 761 log_debug("%s down, removing", name); 762 ra_iface->removed = 1; 763 } else if (!has_linklocal) { 764 log_debug("%s has no IPv6 link-local address, " 765 "removing", name); 766 ra_iface->removed = 1; 767 } else if (ifrdomain == -1) { 768 log_debug("can't get rdomain for %s, removing", name); 769 ra_iface->removed = 1; 770 } else if (ra_iface->rdomain != ifrdomain) { 771 leave_all_routers_mcast_group(ra_iface); 772 unref_icmp6ev(ra_iface); 773 ra_iface->rdomain = ifrdomain; 774 ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain); 775 join_all_routers_mcast_group(ra_iface); 776 ra_iface->removed = 0; 777 } else { 778 log_debug("keeping interface %s", name); 779 ra_iface->removed = 0; 780 } 781 return; 782 } 783 784 if (!LINK_STATE_IS_UP(link_state)) { 785 log_debug("%s down, ignoring", name); 786 return; 787 } 788 789 if (!has_linklocal) { 790 log_debug("%s has no IPv6 link-local address, ignoring", name); 791 return; 792 } 793 794 log_debug("new interface %s", name); 795 if ((if_index = if_nametoindex(name)) == 0) 796 return; 797 798 log_debug("adding interface %s", name); 799 if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL) 800 fatal("%s", __func__); 801 802 strlcpy(ra_iface->name, name, sizeof(ra_iface->name)); 803 strlcpy(ra_iface->conf_name, conf_name, 804 sizeof(ra_iface->conf_name)); 805 806 ra_iface->if_index = if_index; 807 ra_iface->rdomain = ifrdomain; 808 809 SIMPLEQ_INIT(&ra_iface->prefixes); 810 811 ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain); 812 join_all_routers_mcast_group(ra_iface); 813 TAILQ_INSERT_TAIL(&ra_interfaces, ra_iface, entry); 814 } 815 816 void 817 merge_ra_interfaces(void) 818 { 819 struct ra_iface_conf *ra_iface_conf; 820 struct ra_prefix_conf *ra_prefix_conf; 821 struct ra_iface *ra_iface; 822 struct ifgroupreq ifgr; 823 struct ifg_req *ifg; 824 char *conf_name; 825 unsigned int len; 826 827 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) 828 ra_iface->removed = 1; 829 830 SIMPLEQ_FOREACH(ra_iface_conf, &frontend_conf->ra_iface_list, entry) { 831 conf_name = ra_iface_conf->name; 832 833 /* check if network interface or group */ 834 if (isdigit((unsigned char)conf_name[strlen(conf_name) - 1])) { 835 merge_ra_interface(conf_name, conf_name); 836 } else { 837 log_debug("interface group %s", conf_name); 838 839 memset(&ifgr, 0, sizeof(ifgr)); 840 strlcpy(ifgr.ifgr_name, conf_name, 841 sizeof(ifgr.ifgr_name)); 842 if (ioctl(ioctlsock, SIOCGIFGMEMB, 843 (caddr_t)&ifgr) == -1) 844 continue; 845 846 len = ifgr.ifgr_len; 847 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 848 fatal("%s: calloc", __func__); 849 if (ioctl(ioctlsock, SIOCGIFGMEMB, 850 (caddr_t)&ifgr) == -1) { 851 log_debug("group %s without members", 852 conf_name); 853 free(ifgr.ifgr_groups); 854 continue; 855 } 856 857 for (ifg = ifgr.ifgr_groups; 858 (ifg != NULL) && (len >= sizeof(struct ifg_req)); 859 ifg++) { 860 len -= sizeof(struct ifg_req); 861 merge_ra_interface(ifg->ifgrq_member, 862 conf_name); 863 } 864 free(ifgr.ifgr_groups); 865 } 866 } 867 868 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) { 869 while ((ra_prefix_conf = SIMPLEQ_FIRST(&ra_iface->prefixes)) 870 != NULL) { 871 SIMPLEQ_REMOVE_HEAD(&ra_iface->prefixes, 872 entry); 873 free(ra_prefix_conf); 874 } 875 ra_iface->prefix_count = 0; 876 877 if (ra_iface->removed) { 878 log_debug("iface removed: %s", ra_iface->name); 879 build_leaving_packet(ra_iface); 880 frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 881 &ra_iface->if_index, sizeof(ra_iface->if_index)); 882 continue; 883 } 884 885 ra_iface_conf = find_ra_iface_conf( 886 &frontend_conf->ra_iface_list, ra_iface->conf_name); 887 888 log_debug("add static prefixes for %s", ra_iface->name); 889 890 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface_conf->ra_prefix_list, 891 entry) { 892 add_new_prefix_to_ra_iface(ra_iface, 893 &ra_prefix_conf->prefix, 894 ra_prefix_conf->prefixlen, ra_prefix_conf); 895 } 896 897 if (ra_iface_conf->autoprefix) 898 get_interface_prefixes(ra_iface, 899 ra_iface_conf->autoprefix); 900 901 build_packet(ra_iface); 902 } 903 } 904 905 void 906 free_ra_iface(struct ra_iface *ra_iface) 907 { 908 struct ra_prefix_conf *prefix; 909 910 leave_all_routers_mcast_group(ra_iface); 911 912 while ((prefix = SIMPLEQ_FIRST(&ra_iface->prefixes)) != NULL) { 913 SIMPLEQ_REMOVE_HEAD(&ra_iface->prefixes, entry); 914 free(prefix); 915 } 916 917 unref_icmp6ev(ra_iface); 918 free(ra_iface); 919 } 920 921 /* from kame via ifconfig, where it's called prefix() */ 922 int 923 in6_mask2prefixlen(struct in6_addr *in6) 924 { 925 u_char *nam = (u_char *)in6; 926 int byte, bit, plen = 0, size = sizeof(struct in6_addr); 927 928 for (byte = 0; byte < size; byte++, plen += 8) 929 if (nam[byte] != 0xff) 930 break; 931 if (byte == size) 932 return (plen); 933 for (bit = 7; bit != 0; bit--, plen++) 934 if (!(nam[byte] & (1 << bit))) 935 break; 936 for (; bit != 0; bit--) 937 if (nam[byte] & (1 << bit)) 938 return (0); 939 byte++; 940 for (; byte < size; byte++) 941 if (nam[byte]) 942 return (0); 943 return (plen); 944 } 945 946 int 947 interface_has_linklocal_address(char *name) 948 { 949 struct ifaddrs *ifap, *ifa; 950 struct sockaddr_in6 *sin6; 951 struct in6_ifreq ifr6; 952 int ret = 0; 953 954 if (getifaddrs(&ifap) != 0) 955 fatal("getifaddrs"); 956 957 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 958 if (strcmp(name, ifa->ifa_name) != 0) 959 continue; 960 if (ifa->ifa_addr == NULL || 961 ifa->ifa_addr->sa_family != AF_INET6) 962 continue; 963 964 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 965 966 if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 967 continue; 968 969 memset(&ifr6, 0, sizeof(ifr6)); 970 strlcpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name)); 971 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); 972 if (ioctl(ioctlsock, SIOCGIFAFLAG_IN6, (caddr_t)&ifr6) == -1) { 973 log_warn("SIOCGIFAFLAG_IN6"); 974 continue; 975 } 976 977 if (ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_TENTATIVE | 978 IN6_IFF_DUPLICATED)) 979 continue; 980 981 ret = 1; 982 break; 983 } 984 freeifaddrs(ifap); 985 return (ret); 986 } 987 988 void 989 get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf 990 *autoprefix) 991 { 992 struct in6_ifreq ifr6; 993 struct ifaddrs *ifap, *ifa; 994 struct sockaddr_in6 *sin6; 995 int prefixlen; 996 997 log_debug("%s: %s", __func__, ra_iface->name); 998 999 if (getifaddrs(&ifap) != 0) 1000 fatal("getifaddrs"); 1001 1002 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 1003 if (strcmp(ra_iface->name, ifa->ifa_name) != 0) 1004 continue; 1005 if (ifa->ifa_addr == NULL || 1006 ifa->ifa_addr->sa_family != AF_INET6) 1007 continue; 1008 1009 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1010 1011 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 1012 continue; 1013 1014 memset(&ifr6, 0, sizeof(ifr6)); 1015 strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name)); 1016 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); 1017 1018 if (ioctl(ioctlsock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) == -1) 1019 continue; /* addr got deleted while we were looking */ 1020 1021 prefixlen = in6_mask2prefixlen(&((struct sockaddr_in6 *) 1022 &ifr6.ifr_addr)->sin6_addr); 1023 1024 if (prefixlen == 128) 1025 continue; 1026 1027 mask_prefix(&sin6->sin6_addr, prefixlen); 1028 1029 add_new_prefix_to_ra_iface(ra_iface, &sin6->sin6_addr, 1030 prefixlen, autoprefix); 1031 } 1032 freeifaddrs(ifap); 1033 } 1034 1035 struct ra_prefix_conf* 1036 find_ra_prefix_conf(struct ra_prefix_conf_head* head, struct in6_addr *prefix, 1037 int prefixlen) 1038 { 1039 struct ra_prefix_conf *ra_prefix_conf; 1040 1041 SIMPLEQ_FOREACH(ra_prefix_conf, head, entry) { 1042 if (ra_prefix_conf->prefixlen == prefixlen && 1043 memcmp(&ra_prefix_conf->prefix, prefix, sizeof(*prefix)) == 1044 0) 1045 return (ra_prefix_conf); 1046 } 1047 return (NULL); 1048 } 1049 1050 void 1051 add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr *addr, 1052 int prefixlen, struct ra_prefix_conf *ra_prefix_conf) 1053 { 1054 struct ra_prefix_conf *new_ra_prefix_conf; 1055 1056 if (find_ra_prefix_conf(&ra_iface->prefixes, addr, prefixlen)) { 1057 log_debug("ignoring duplicate %s/%d prefix", 1058 in6_to_str(addr), prefixlen); 1059 return; 1060 } 1061 1062 log_debug("adding %s/%d prefix", in6_to_str(addr), prefixlen); 1063 1064 if ((new_ra_prefix_conf = calloc(1, sizeof(*ra_prefix_conf))) == NULL) 1065 fatal("%s", __func__); 1066 new_ra_prefix_conf->prefix = *addr; 1067 new_ra_prefix_conf->prefixlen = prefixlen; 1068 new_ra_prefix_conf->vltime = ra_prefix_conf->vltime; 1069 new_ra_prefix_conf->pltime = ra_prefix_conf->pltime; 1070 new_ra_prefix_conf->aflag = ra_prefix_conf->aflag; 1071 new_ra_prefix_conf->lflag = ra_prefix_conf->lflag; 1072 SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry); 1073 ra_iface->prefix_count++; 1074 } 1075 1076 void 1077 build_packet(struct ra_iface *ra_iface) 1078 { 1079 struct nd_router_advert *ra; 1080 struct nd_opt_mtu *ndopt_mtu; 1081 struct nd_opt_prefix_info *ndopt_pi; 1082 struct ra_iface_conf *ra_iface_conf; 1083 struct ra_options_conf *ra_options_conf; 1084 struct ra_prefix_conf *ra_prefix_conf; 1085 struct nd_opt_rdnss *ndopt_rdnss; 1086 struct nd_opt_dnssl *ndopt_dnssl; 1087 struct ra_rdnss_conf *ra_rdnss; 1088 struct ra_dnssl_conf *ra_dnssl; 1089 size_t len, label_len; 1090 uint8_t *p, buf[RA_MAX_SIZE]; 1091 char *label_start, *label_end; 1092 1093 ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list, 1094 ra_iface->conf_name); 1095 ra_options_conf = &ra_iface_conf->ra_options; 1096 1097 len = sizeof(*ra); 1098 if (ra_options_conf->mtu > 0) 1099 len += sizeof(*ndopt_mtu); 1100 len += sizeof(*ndopt_pi) * ra_iface->prefix_count; 1101 if (ra_iface_conf->ra_options.rdnss_count > 0) 1102 len += sizeof(*ndopt_rdnss) + 1103 ra_iface_conf->ra_options.rdnss_count * 1104 sizeof(struct in6_addr); 1105 1106 if (ra_iface_conf->ra_options.dnssl_len > 0) 1107 /* round up to 8 byte boundary */ 1108 len += sizeof(*ndopt_dnssl) + 1109 ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7); 1110 1111 if (len > sizeof(ra_iface->data)) 1112 fatalx("%s: packet too big", __func__); /* XXX send multiple */ 1113 1114 p = buf; 1115 1116 ra = (struct nd_router_advert *)p; 1117 1118 memset(ra, 0, sizeof(*ra)); 1119 1120 ra->nd_ra_type = ND_ROUTER_ADVERT; 1121 ra->nd_ra_curhoplimit = ra_options_conf->cur_hl; 1122 if (ra_options_conf->m_flag) 1123 ra->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; 1124 if (ra_options_conf->o_flag) 1125 ra->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; 1126 if (ra_iface->removed) 1127 /* tell clients that we are no longer a default router */ 1128 ra->nd_ra_router_lifetime = 0; 1129 else if (ra_options_conf->dfr) { 1130 ra->nd_ra_router_lifetime = 1131 htons(ra_options_conf->router_lifetime); 1132 } 1133 ra->nd_ra_reachable = htonl(ra_options_conf->reachable_time); 1134 ra->nd_ra_retransmit = htonl(ra_options_conf->retrans_timer); 1135 p += sizeof(*ra); 1136 1137 if (ra_options_conf->mtu > 0) { 1138 ndopt_mtu = (struct nd_opt_mtu *)p; 1139 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU; 1140 ndopt_mtu->nd_opt_mtu_len = 1; 1141 ndopt_mtu->nd_opt_mtu_reserved = 0; 1142 ndopt_mtu->nd_opt_mtu_mtu = htonl(ra_options_conf->mtu); 1143 p += sizeof(*ndopt_mtu); 1144 } 1145 1146 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface->prefixes, entry) { 1147 ndopt_pi = (struct nd_opt_prefix_info *)p; 1148 memset(ndopt_pi, 0, sizeof(*ndopt_pi)); 1149 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; 1150 ndopt_pi->nd_opt_pi_len = 4; 1151 ndopt_pi->nd_opt_pi_prefix_len = ra_prefix_conf->prefixlen; 1152 if (ra_prefix_conf->lflag) 1153 ndopt_pi->nd_opt_pi_flags_reserved |= 1154 ND_OPT_PI_FLAG_ONLINK; 1155 if (ra_prefix_conf->aflag) 1156 ndopt_pi->nd_opt_pi_flags_reserved |= 1157 ND_OPT_PI_FLAG_AUTO; 1158 ndopt_pi->nd_opt_pi_valid_time = htonl(ra_prefix_conf->vltime); 1159 ndopt_pi->nd_opt_pi_preferred_time = 1160 htonl(ra_prefix_conf->pltime); 1161 ndopt_pi->nd_opt_pi_prefix = ra_prefix_conf->prefix; 1162 1163 p += sizeof(*ndopt_pi); 1164 } 1165 1166 if (ra_iface_conf->ra_options.rdnss_count > 0) { 1167 ndopt_rdnss = (struct nd_opt_rdnss *)p; 1168 ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS; 1169 ndopt_rdnss->nd_opt_rdnss_len = 1 + 1170 ra_iface_conf->ra_options.rdnss_count * 2; 1171 ndopt_rdnss->nd_opt_rdnss_reserved = 0; 1172 ndopt_rdnss->nd_opt_rdnss_lifetime = 1173 htonl(ra_iface_conf->ra_options.rdns_lifetime); 1174 p += sizeof(struct nd_opt_rdnss); 1175 SIMPLEQ_FOREACH(ra_rdnss, 1176 &ra_iface_conf->ra_options.ra_rdnss_list, entry) { 1177 memcpy(p, &ra_rdnss->rdnss, sizeof(ra_rdnss->rdnss)); 1178 p += sizeof(ra_rdnss->rdnss); 1179 } 1180 } 1181 1182 if (ra_iface_conf->ra_options.dnssl_len > 0) { 1183 ndopt_dnssl = (struct nd_opt_dnssl *)p; 1184 ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL; 1185 /* round up to 8 byte boundary */ 1186 ndopt_dnssl->nd_opt_dnssl_len = 1 + 1187 ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7) / 8; 1188 ndopt_dnssl->nd_opt_dnssl_reserved = 0; 1189 ndopt_dnssl->nd_opt_dnssl_lifetime = 1190 htonl(ra_iface_conf->ra_options.rdns_lifetime); 1191 p += sizeof(struct nd_opt_dnssl); 1192 1193 SIMPLEQ_FOREACH(ra_dnssl, 1194 &ra_iface_conf->ra_options.ra_dnssl_list, entry) { 1195 label_start = ra_dnssl->search; 1196 while ((label_end = strchr(label_start, '.')) != NULL) { 1197 label_len = label_end - label_start; 1198 *p++ = label_len; 1199 memcpy(p, label_start, label_len); 1200 p += label_len; 1201 label_start = label_end + 1; 1202 } 1203 *p++ = '\0'; /* last dot */ 1204 } 1205 /* zero pad */ 1206 while (((uintptr_t)p) % 8 != 0) 1207 *p++ = '\0'; 1208 } 1209 1210 if (len != ra_iface->datalen || memcmp(buf, ra_iface->data, len) 1211 != 0) { 1212 memcpy(ra_iface->data, buf, len); 1213 ra_iface->datalen = len; 1214 /* packet changed; tell engine to send new advertisments */ 1215 if (event_initialized(&ra_iface->icmp6ev->ev)) 1216 frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, 1217 &ra_iface->if_index, sizeof(ra_iface->if_index)); 1218 } 1219 } 1220 1221 void 1222 build_leaving_packet(struct ra_iface *ra_iface) 1223 { 1224 struct nd_router_advert ra; 1225 size_t len; 1226 1227 len = sizeof(ra); 1228 1229 memset(&ra, 0, sizeof(ra)); 1230 1231 ra.nd_ra_type = ND_ROUTER_ADVERT; 1232 1233 memcpy(ra_iface->data, &ra, sizeof(ra)); 1234 ra_iface->datalen = sizeof(ra); 1235 } 1236 1237 void 1238 ra_output(struct ra_iface *ra_iface, struct sockaddr_in6 *to) 1239 { 1240 1241 struct cmsghdr *cm; 1242 struct in6_pktinfo *pi; 1243 ssize_t len; 1244 int hoplimit = 255; 1245 1246 if (!LINK_STATE_IS_UP(ra_iface->link_state)) 1247 return; 1248 1249 sndmhdr.msg_name = to; 1250 sndmhdr.msg_iov[0].iov_base = ra_iface->data; 1251 sndmhdr.msg_iov[0].iov_len = ra_iface->datalen; 1252 1253 cm = CMSG_FIRSTHDR(&sndmhdr); 1254 /* specify the outgoing interface */ 1255 cm->cmsg_level = IPPROTO_IPV6; 1256 cm->cmsg_type = IPV6_PKTINFO; 1257 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 1258 pi = (struct in6_pktinfo *)CMSG_DATA(cm); 1259 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); 1260 pi->ipi6_ifindex = ra_iface->if_index; 1261 1262 /* specify the hop limit of the packet */ 1263 cm = CMSG_NXTHDR(&sndmhdr, cm); 1264 cm->cmsg_level = IPPROTO_IPV6; 1265 cm->cmsg_type = IPV6_HOPLIMIT; 1266 cm->cmsg_len = CMSG_LEN(sizeof(int)); 1267 memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); 1268 1269 log_debug("send RA on %s", ra_iface->name); 1270 1271 len = sendmsg(EVENT_FD(&ra_iface->icmp6ev->ev), &sndmhdr, 0); 1272 if (len == -1) 1273 log_warn("sendmsg on %s", ra_iface->name); 1274 1275 } 1276 1277 #define ROUNDUP(a) \ 1278 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 1279 1280 void 1281 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 1282 { 1283 int i; 1284 1285 for (i = 0; i < RTAX_MAX; i++) { 1286 if (addrs & (1 << i)) { 1287 rti_info[i] = sa; 1288 sa = (struct sockaddr *)((char *)(sa) + 1289 ROUNDUP(sa->sa_len)); 1290 } else 1291 rti_info[i] = NULL; 1292 } 1293 } 1294 1295 void 1296 route_receive(int fd, short events, void *arg) 1297 { 1298 static uint8_t *buf; 1299 1300 struct rt_msghdr *rtm; 1301 struct sockaddr *sa, *rti_info[RTAX_MAX]; 1302 ssize_t n; 1303 1304 if (buf == NULL) { 1305 buf = malloc(ROUTE_SOCKET_BUF_SIZE); 1306 if (buf == NULL) 1307 fatal("malloc"); 1308 } 1309 rtm = (struct rt_msghdr *)buf; 1310 if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) { 1311 if (errno == EAGAIN || errno == EINTR) 1312 return; 1313 log_warn("dispatch_rtmsg: read error"); 1314 return; 1315 } 1316 1317 if (n == 0) 1318 fatal("routing socket closed"); 1319 1320 if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) { 1321 log_warnx("partial rtm of %zd in buffer", n); 1322 return; 1323 } 1324 1325 if (rtm->rtm_version != RTM_VERSION) 1326 return; 1327 1328 sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen); 1329 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); 1330 1331 handle_route_message(rtm, rti_info); 1332 } 1333 1334 void 1335 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) 1336 { 1337 switch (rtm->rtm_type) { 1338 case RTM_IFINFO: 1339 case RTM_NEWADDR: 1340 case RTM_DELADDR: 1341 case RTM_CHGADDRATTR: 1342 /* 1343 * do the same thing as after a config reload when interfaces 1344 * change or IPv6 addresses show up / disappear 1345 */ 1346 merge_ra_interfaces(); 1347 break; 1348 default: 1349 log_debug("unexpected RTM: %d", rtm->rtm_type); 1350 break; 1351 } 1352 } 1353 1354 struct icmp6_ev* 1355 get_icmp6ev_by_rdomain(int rdomain) 1356 { 1357 struct ra_iface *ra_iface; 1358 struct icmp6_ev *icmp6ev = NULL; 1359 1360 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) { 1361 if (ra_iface->rdomain == rdomain) { 1362 icmp6ev = ra_iface->icmp6ev; 1363 break; 1364 } 1365 } 1366 1367 if (icmp6ev == NULL) { 1368 if ((icmp6ev = calloc(1, sizeof(*icmp6ev))) == NULL) 1369 fatal("calloc"); 1370 1371 icmp6ev->rcviov[0].iov_base = (caddr_t)icmp6ev->answer; 1372 icmp6ev->rcviov[0].iov_len = sizeof(icmp6ev->answer); 1373 icmp6ev->rcvmhdr.msg_name = (caddr_t)&icmp6ev->from; 1374 icmp6ev->rcvmhdr.msg_namelen = sizeof(icmp6ev->from); 1375 icmp6ev->rcvmhdr.msg_iov = icmp6ev->rcviov; 1376 icmp6ev->rcvmhdr.msg_iovlen = 1; 1377 icmp6ev->rcvmhdr.msg_controllen = 1378 CMSG_SPACE(sizeof(struct in6_pktinfo)) + 1379 CMSG_SPACE(sizeof(int)); 1380 if ((icmp6ev->rcvmhdr.msg_control = malloc(icmp6ev-> 1381 rcvmhdr.msg_controllen)) == NULL) 1382 fatal("malloc"); 1383 frontend_imsg_compose_main(IMSG_OPEN_ICMP6SOCK, 0, 1384 &rdomain, sizeof(rdomain)); 1385 } 1386 1387 icmp6ev->refcnt++; 1388 return (icmp6ev); 1389 } 1390 1391 void 1392 unref_icmp6ev(struct ra_iface *ra_iface) 1393 { 1394 struct icmp6_ev *icmp6ev = ra_iface->icmp6ev; 1395 1396 ra_iface->icmp6ev = NULL; 1397 1398 if (icmp6ev != NULL) { 1399 icmp6ev->refcnt--; 1400 if (icmp6ev->refcnt == 0) { 1401 event_del(&icmp6ev->ev); 1402 close(EVENT_FD(&icmp6ev->ev)); 1403 free(icmp6ev); 1404 } 1405 } 1406 } 1407 1408 void 1409 set_icmp6sock(int icmp6sock, int rdomain) 1410 { 1411 struct ra_iface *ra_iface; 1412 1413 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) { 1414 if (!event_initialized(&ra_iface->icmp6ev->ev) && 1415 ra_iface->rdomain == rdomain) { 1416 event_set(&ra_iface->icmp6ev->ev, icmp6sock, EV_READ | 1417 EV_PERSIST, icmp6_receive, ra_iface->icmp6ev); 1418 event_add(&ra_iface->icmp6ev->ev, NULL); 1419 icmp6sock = -1; 1420 break; 1421 } 1422 } 1423 1424 if (icmp6sock != -1) { 1425 /* 1426 * The interface disappeared or changed rdomain while we were 1427 * waiting for the parent process to open the raw socket. 1428 */ 1429 close(icmp6sock); 1430 return; 1431 } 1432 1433 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) { 1434 if (ra_iface->rdomain == rdomain) { 1435 join_all_routers_mcast_group(ra_iface); 1436 frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, 1437 &ra_iface->if_index, sizeof(ra_iface->if_index)); 1438 } 1439 } 1440 } 1441