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