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