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