1 /* $OpenBSD: rad.c,v 1.38 2024/11/21 13:38:15 claudio 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 #include <sys/types.h> 22 #include <sys/queue.h> 23 #include <sys/socket.h> 24 #include <sys/syslog.h> 25 #include <sys/uio.h> 26 #include <sys/wait.h> 27 28 #include <netinet/in.h> 29 #include <net/if.h> 30 #include <net/route.h> 31 #include <netinet/if_ether.h> 32 #include <netinet6/in6_var.h> 33 #include <netinet/icmp6.h> 34 35 #include <err.h> 36 #include <errno.h> 37 #include <event.h> 38 #include <fcntl.h> 39 #include <imsg.h> 40 #include <netdb.h> 41 #include <pwd.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <signal.h> 46 #include <unistd.h> 47 48 #include "log.h" 49 #include "rad.h" 50 #include "frontend.h" 51 #include "engine.h" 52 #include "control.h" 53 54 enum rad_process { 55 PROC_MAIN, 56 PROC_ENGINE, 57 PROC_FRONTEND 58 }; 59 60 __dead void usage(void); 61 __dead void main_shutdown(void); 62 63 void main_sig_handler(int, short, void *); 64 65 static pid_t start_child(enum rad_process, char *, int, int, int); 66 67 void main_dispatch_frontend(int, short, void *); 68 void main_dispatch_engine(int, short, void *); 69 void open_icmp6sock(int); 70 71 static int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *); 72 static int main_imsg_send_config(struct rad_conf *); 73 74 int main_reload(void); 75 int main_sendboth(enum imsg_type, void *, uint16_t); 76 77 struct rad_conf *main_conf; 78 static struct imsgev *iev_frontend; 79 static struct imsgev *iev_engine; 80 char *conffile; 81 pid_t frontend_pid; 82 pid_t engine_pid; 83 uint32_t cmd_opts; 84 85 void 86 main_sig_handler(int sig, short event, void *arg) 87 { 88 /* 89 * Normal signal handler rules don't apply because libevent 90 * decouples for us. 91 */ 92 93 switch (sig) { 94 case SIGTERM: 95 case SIGINT: 96 main_shutdown(); 97 break; 98 case SIGHUP: 99 if (main_reload() == -1) 100 log_warnx("configuration reload failed"); 101 else 102 log_debug("configuration reloaded"); 103 break; 104 default: 105 fatalx("unexpected signal"); 106 } 107 } 108 109 __dead void 110 usage(void) 111 { 112 extern char *__progname; 113 114 fprintf(stderr, "usage: %s [-dnv] [-f file] [-s socket]\n", 115 __progname); 116 exit(1); 117 } 118 119 int 120 main(int argc, char *argv[]) 121 { 122 struct event ev_sigint, ev_sigterm, ev_sighup; 123 int ch; 124 int debug = 0, engine_flag = 0, frontend_flag = 0; 125 char *saved_argv0; 126 int pipe_main2frontend[2]; 127 int pipe_main2engine[2]; 128 int frontend_routesock, rtfilter; 129 int rtable_any = RTABLE_ANY; 130 int control_fd; 131 char *csock; 132 133 conffile = _PATH_CONF_FILE; 134 csock = _PATH_RAD_SOCKET; 135 136 log_init(1, LOG_DAEMON); /* Log to stderr until daemonized. */ 137 log_setverbose(1); 138 139 saved_argv0 = argv[0]; 140 if (saved_argv0 == NULL) 141 saved_argv0 = "rad"; 142 143 while ((ch = getopt(argc, argv, "dEFf:ns:v")) != -1) { 144 switch (ch) { 145 case 'd': 146 debug = 1; 147 break; 148 case 'E': 149 engine_flag = 1; 150 break; 151 case 'F': 152 frontend_flag = 1; 153 break; 154 case 'f': 155 conffile = optarg; 156 break; 157 case 'n': 158 cmd_opts |= OPT_NOACTION; 159 break; 160 case 's': 161 csock = optarg; 162 break; 163 case 'v': 164 if (cmd_opts & OPT_VERBOSE) 165 cmd_opts |= OPT_VERBOSE2; 166 cmd_opts |= OPT_VERBOSE; 167 break; 168 default: 169 usage(); 170 } 171 } 172 173 argc -= optind; 174 argv += optind; 175 if (argc > 0 || (engine_flag && frontend_flag)) 176 usage(); 177 178 if (engine_flag) 179 engine(debug, cmd_opts & OPT_VERBOSE); 180 else if (frontend_flag) 181 frontend(debug, cmd_opts & OPT_VERBOSE); 182 183 /* parse config file */ 184 if ((main_conf = parse_config(conffile)) == NULL) { 185 exit(1); 186 } 187 188 if (cmd_opts & OPT_NOACTION) { 189 if (cmd_opts & OPT_VERBOSE) 190 print_config(main_conf); 191 else 192 fprintf(stderr, "configuration OK\n"); 193 exit(0); 194 } 195 196 /* Check for root privileges. */ 197 if (geteuid()) 198 errx(1, "need root privileges"); 199 200 /* Check for assigned daemon user */ 201 if (getpwnam(RAD_USER) == NULL) 202 errx(1, "unknown user %s", RAD_USER); 203 204 log_init(debug, LOG_DAEMON); 205 log_setverbose(cmd_opts & OPT_VERBOSE); 206 207 if (!debug) 208 daemon(1, 0); 209 210 log_info("startup"); 211 212 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 213 PF_UNSPEC, pipe_main2frontend) == -1) 214 fatal("main2frontend socketpair"); 215 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 216 PF_UNSPEC, pipe_main2engine) == -1) 217 fatal("main2engine socketpair"); 218 219 /* Start children. */ 220 engine_pid = start_child(PROC_ENGINE, saved_argv0, pipe_main2engine[1], 221 debug, cmd_opts & OPT_VERBOSE); 222 frontend_pid = start_child(PROC_FRONTEND, saved_argv0, 223 pipe_main2frontend[1], debug, cmd_opts & OPT_VERBOSE); 224 225 log_procinit("main"); 226 227 event_init(); 228 229 /* Setup signal handler. */ 230 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); 231 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); 232 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); 233 signal_add(&ev_sigint, NULL); 234 signal_add(&ev_sigterm, NULL); 235 signal_add(&ev_sighup, NULL); 236 signal(SIGPIPE, SIG_IGN); 237 238 /* Setup pipes to children. */ 239 240 if ((iev_frontend = malloc(sizeof(struct imsgev))) == NULL || 241 (iev_engine = malloc(sizeof(struct imsgev))) == NULL) 242 fatal(NULL); 243 if (imsgbuf_init(&iev_frontend->ibuf, pipe_main2frontend[0]) == -1) 244 fatal(NULL); 245 imsgbuf_allow_fdpass(&iev_frontend->ibuf); 246 iev_frontend->handler = main_dispatch_frontend; 247 if (imsgbuf_init(&iev_engine->ibuf, pipe_main2engine[0]) == -1) 248 fatal(NULL); 249 imsgbuf_allow_fdpass(&iev_engine->ibuf); 250 iev_engine->handler = main_dispatch_engine; 251 252 /* Setup event handlers for pipes to engine & frontend. */ 253 iev_frontend->events = EV_READ; 254 event_set(&iev_frontend->ev, iev_frontend->ibuf.fd, 255 iev_frontend->events, iev_frontend->handler, iev_frontend); 256 event_add(&iev_frontend->ev, NULL); 257 258 iev_engine->events = EV_READ; 259 event_set(&iev_engine->ev, iev_engine->ibuf.fd, iev_engine->events, 260 iev_engine->handler, iev_engine); 261 event_add(&iev_engine->ev, NULL); 262 263 if (main_imsg_send_ipc_sockets(&iev_frontend->ibuf, &iev_engine->ibuf)) 264 fatal("could not establish imsg links"); 265 266 if ((frontend_routesock = socket(AF_ROUTE, SOCK_RAW | SOCK_CLOEXEC, 267 AF_INET6)) == -1) 268 fatal("route socket"); 269 270 rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) | 271 ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_CHGADDRATTR); 272 if (setsockopt(frontend_routesock, AF_ROUTE, ROUTE_MSGFILTER, 273 &rtfilter, sizeof(rtfilter)) == -1) 274 fatal("setsockopt(ROUTE_MSGFILTER)"); 275 if (setsockopt(frontend_routesock, AF_ROUTE, ROUTE_TABLEFILTER, 276 &rtable_any, sizeof(rtable_any)) == -1) 277 fatal("setsockopt(ROUTE_TABLEFILTER)"); 278 279 if ((control_fd = control_init(csock)) == -1) 280 fatalx("control socket setup failed"); 281 282 main_imsg_compose_frontend(IMSG_ROUTESOCK, frontend_routesock, 283 NULL, 0); 284 main_imsg_compose_frontend(IMSG_CONTROLFD, control_fd, NULL, 0); 285 main_imsg_send_config(main_conf); 286 287 if (pledge("stdio inet rpath sendfd mcast wroute", NULL) == -1) 288 fatal("pledge"); 289 290 main_imsg_compose_frontend(IMSG_STARTUP, -1, NULL, 0); 291 292 event_dispatch(); 293 294 main_shutdown(); 295 return (0); 296 } 297 298 __dead void 299 main_shutdown(void) 300 { 301 pid_t pid; 302 int status; 303 304 /* Close pipes. */ 305 imsgbuf_clear(&iev_frontend->ibuf); 306 close(iev_frontend->ibuf.fd); 307 imsgbuf_clear(&iev_engine->ibuf); 308 close(iev_engine->ibuf.fd); 309 310 config_clear(main_conf); 311 312 log_debug("waiting for children to terminate"); 313 do { 314 pid = wait(&status); 315 if (pid == -1) { 316 if (errno != EINTR && errno != ECHILD) 317 fatal("wait"); 318 } else if (WIFSIGNALED(status)) 319 log_warnx("%s terminated; signal %d", 320 (pid == engine_pid) ? "engine" : 321 "frontend", WTERMSIG(status)); 322 } while (pid != -1 || (pid == -1 && errno == EINTR)); 323 324 free(iev_frontend); 325 free(iev_engine); 326 327 log_info("terminating"); 328 exit(0); 329 } 330 331 static pid_t 332 start_child(enum rad_process p, char *argv0, int fd, int debug, int verbose) 333 { 334 char *argv[6]; 335 int argc = 0; 336 pid_t pid; 337 338 switch (pid = fork()) { 339 case -1: 340 fatal("cannot fork"); 341 case 0: 342 break; 343 default: 344 close(fd); 345 return (pid); 346 } 347 348 if (fd != 3) { 349 if (dup2(fd, 3) == -1) 350 fatal("cannot setup imsg fd"); 351 } else if (fcntl(fd, F_SETFD, 0) == -1) 352 fatal("cannot setup imsg fd"); 353 354 argv[argc++] = argv0; 355 switch (p) { 356 case PROC_MAIN: 357 fatalx("Can not start main process"); 358 case PROC_ENGINE: 359 argv[argc++] = "-E"; 360 break; 361 case PROC_FRONTEND: 362 argv[argc++] = "-F"; 363 break; 364 } 365 if (debug) 366 argv[argc++] = "-d"; 367 if (verbose) 368 argv[argc++] = "-v"; 369 argv[argc++] = NULL; 370 371 execvp(argv0, argv); 372 fatal("execvp"); 373 } 374 375 void 376 main_dispatch_frontend(int fd, short event, void *bula) 377 { 378 struct imsgev *iev = bula; 379 struct imsgbuf *ibuf; 380 struct imsg imsg; 381 ssize_t n; 382 int shut = 0, verbose; 383 int rdomain; 384 385 ibuf = &iev->ibuf; 386 387 if (event & EV_READ) { 388 if ((n = imsgbuf_read(ibuf)) == -1) 389 fatal("imsgbuf_read error"); 390 if (n == 0) /* Connection closed. */ 391 shut = 1; 392 } 393 if (event & EV_WRITE) { 394 if (imsgbuf_write(ibuf) == -1) { 395 if (errno == EPIPE) /* connection closed */ 396 shut = 1; 397 else 398 fatal("imsgbuf_write"); 399 } 400 } 401 402 for (;;) { 403 if ((n = imsg_get(ibuf, &imsg)) == -1) 404 fatal("imsg_get"); 405 if (n == 0) /* No more messages. */ 406 break; 407 408 switch (imsg.hdr.type) { 409 case IMSG_OPEN_ICMP6SOCK: 410 log_debug("IMSG_OPEN_ICMP6SOCK"); 411 if (IMSG_DATA_SIZE(imsg) != sizeof(rdomain)) 412 fatalx("%s: IMSG_OPEN_ICMP6SOCK wrong length: " 413 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 414 memcpy(&rdomain, imsg.data, sizeof(rdomain)); 415 open_icmp6sock(rdomain); 416 break; 417 case IMSG_CTL_RELOAD: 418 if (main_reload() == -1) 419 log_warnx("configuration reload failed"); 420 else 421 log_warnx("configuration reloaded"); 422 break; 423 case IMSG_CTL_LOG_VERBOSE: 424 if (IMSG_DATA_SIZE(imsg) != sizeof(verbose)) 425 fatalx("%s: IMSG_CTL_LOG_VERBOSE wrong length: " 426 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 427 memcpy(&verbose, imsg.data, sizeof(verbose)); 428 log_setverbose(verbose); 429 break; 430 default: 431 log_debug("%s: error handling imsg %d", __func__, 432 imsg.hdr.type); 433 break; 434 } 435 imsg_free(&imsg); 436 } 437 if (!shut) 438 imsg_event_add(iev); 439 else { 440 /* This pipe is dead. Remove its event handler */ 441 event_del(&iev->ev); 442 event_loopexit(NULL); 443 } 444 } 445 446 void 447 main_dispatch_engine(int fd, short event, void *bula) 448 { 449 struct imsgev *iev = bula; 450 struct imsgbuf *ibuf; 451 struct imsg imsg; 452 ssize_t n; 453 int shut = 0; 454 455 ibuf = &iev->ibuf; 456 457 if (event & EV_READ) { 458 if ((n = imsgbuf_read(ibuf)) == -1) 459 fatal("imsgbuf_read error"); 460 if (n == 0) /* Connection closed. */ 461 shut = 1; 462 } 463 if (event & EV_WRITE) { 464 if (imsgbuf_write(ibuf) == -1) { 465 if (errno == EPIPE) /* connection closed */ 466 shut = 1; 467 else 468 fatal("imsgbuf_write"); 469 } 470 } 471 472 for (;;) { 473 if ((n = imsg_get(ibuf, &imsg)) == -1) 474 fatal("imsg_get"); 475 if (n == 0) /* No more messages. */ 476 break; 477 478 switch (imsg.hdr.type) { 479 default: 480 log_debug("%s: error handling imsg %d", __func__, 481 imsg.hdr.type); 482 break; 483 } 484 imsg_free(&imsg); 485 } 486 if (!shut) 487 imsg_event_add(iev); 488 else { 489 /* This pipe is dead. Remove its event handler. */ 490 event_del(&iev->ev); 491 event_loopexit(NULL); 492 } 493 } 494 495 int 496 main_imsg_compose_frontend(int type, int fd, void *data, uint16_t datalen) 497 { 498 if (iev_frontend) 499 return (imsg_compose_event(iev_frontend, type, 0, 0, fd, data, 500 datalen)); 501 else 502 return (-1); 503 } 504 505 void 506 main_imsg_compose_engine(int type, pid_t pid, void *data, uint16_t datalen) 507 { 508 if (iev_engine) 509 imsg_compose_event(iev_engine, type, 0, pid, -1, data, 510 datalen); 511 } 512 513 void 514 imsg_event_add(struct imsgev *iev) 515 { 516 iev->events = EV_READ; 517 if (imsgbuf_queuelen(&iev->ibuf) > 0) 518 iev->events |= EV_WRITE; 519 520 event_del(&iev->ev); 521 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 522 event_add(&iev->ev, NULL); 523 } 524 525 int 526 imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid, 527 pid_t pid, int fd, void *data, uint16_t datalen) 528 { 529 int ret; 530 531 if ((ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, 532 datalen)) != -1) 533 imsg_event_add(iev); 534 535 return (ret); 536 } 537 538 static int 539 main_imsg_send_ipc_sockets(struct imsgbuf *frontend_buf, 540 struct imsgbuf *engine_buf) 541 { 542 int pipe_frontend2engine[2]; 543 544 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 545 PF_UNSPEC, pipe_frontend2engine) == -1) 546 return (-1); 547 548 if (imsg_compose(frontend_buf, IMSG_SOCKET_IPC, 0, 0, 549 pipe_frontend2engine[0], NULL, 0) == -1) 550 return (-1); 551 if (imsg_compose(engine_buf, IMSG_SOCKET_IPC, 0, 0, 552 pipe_frontend2engine[1], NULL, 0) == -1) 553 return (-1); 554 555 return (0); 556 } 557 558 int 559 main_reload(void) 560 { 561 struct rad_conf *xconf; 562 563 if ((xconf = parse_config(conffile)) == NULL) 564 return (-1); 565 566 if (main_imsg_send_config(xconf) == -1) 567 return (-1); 568 569 merge_config(main_conf, xconf); 570 571 return (0); 572 } 573 574 int 575 main_imsg_send_config(struct rad_conf *xconf) 576 { 577 struct ra_iface_conf *ra_iface_conf; 578 struct ra_prefix_conf *ra_prefix_conf; 579 struct ra_rdnss_conf *ra_rdnss_conf; 580 struct ra_dnssl_conf *ra_dnssl_conf; 581 struct ra_pref64_conf *pref64; 582 583 /* Send fixed part of config to children. */ 584 if (main_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1) 585 return (-1); 586 587 /* send global dns options to children */ 588 SIMPLEQ_FOREACH(ra_rdnss_conf, &xconf->ra_options.ra_rdnss_list, 589 entry) { 590 if (main_sendboth(IMSG_RECONF_RA_RDNSS, ra_rdnss_conf, 591 sizeof(*ra_rdnss_conf)) == -1) 592 return (-1); 593 } 594 SIMPLEQ_FOREACH(ra_dnssl_conf, &xconf->ra_options.ra_dnssl_list, 595 entry) { 596 if (main_sendboth(IMSG_RECONF_RA_DNSSL, ra_dnssl_conf, 597 sizeof(*ra_dnssl_conf)) == -1) 598 return (-1); 599 } 600 601 /* send global pref64 list to children */ 602 SIMPLEQ_FOREACH(pref64, &xconf->ra_options.ra_pref64_list, 603 entry) { 604 if (main_sendboth(IMSG_RECONF_RA_PREF64, pref64, 605 sizeof(*pref64)) == -1) 606 return (-1); 607 } 608 609 /* Send the interface list to children. */ 610 SIMPLEQ_FOREACH(ra_iface_conf, &xconf->ra_iface_list, entry) { 611 if (main_sendboth(IMSG_RECONF_RA_IFACE, ra_iface_conf, 612 sizeof(*ra_iface_conf)) == -1) 613 return (-1); 614 if (ra_iface_conf->autoprefix) { 615 if (main_sendboth(IMSG_RECONF_RA_AUTOPREFIX, 616 ra_iface_conf->autoprefix, 617 sizeof(*ra_iface_conf->autoprefix)) == -1) 618 return (-1); 619 } 620 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface_conf->ra_prefix_list, 621 entry) { 622 if (main_sendboth(IMSG_RECONF_RA_PREFIX, 623 ra_prefix_conf, sizeof(*ra_prefix_conf)) == -1) 624 return (-1); 625 } 626 SIMPLEQ_FOREACH(ra_rdnss_conf, 627 &ra_iface_conf->ra_options.ra_rdnss_list, entry) { 628 if (main_sendboth(IMSG_RECONF_RA_RDNSS, ra_rdnss_conf, 629 sizeof(*ra_rdnss_conf)) == -1) 630 return (-1); 631 } 632 SIMPLEQ_FOREACH(ra_dnssl_conf, 633 &ra_iface_conf->ra_options.ra_dnssl_list, entry) { 634 if (main_sendboth(IMSG_RECONF_RA_DNSSL, ra_dnssl_conf, 635 sizeof(*ra_dnssl_conf)) == -1) 636 return (-1); 637 } 638 SIMPLEQ_FOREACH(pref64, 639 &ra_iface_conf->ra_options.ra_pref64_list, entry) { 640 if (main_sendboth(IMSG_RECONF_RA_PREF64, pref64, 641 sizeof(*pref64)) == -1) 642 return (-1); 643 } 644 } 645 646 /* Tell children the revised config is now complete. */ 647 if (main_sendboth(IMSG_RECONF_END, NULL, 0) == -1) 648 return (-1); 649 650 return (0); 651 } 652 653 int 654 main_sendboth(enum imsg_type type, void *buf, uint16_t len) 655 { 656 if (imsg_compose_event(iev_frontend, type, 0, 0, -1, buf, len) == -1) 657 return (-1); 658 if (imsg_compose_event(iev_engine, type, 0, 0, -1, buf, len) == -1) 659 return (-1); 660 return (0); 661 } 662 663 void 664 free_ra_iface_conf(struct ra_iface_conf *ra_iface_conf) 665 { 666 struct ra_prefix_conf *prefix; 667 struct ra_pref64_conf *pref64; 668 669 if (!ra_iface_conf) 670 return; 671 672 free(ra_iface_conf->autoprefix); 673 674 while ((prefix = SIMPLEQ_FIRST(&ra_iface_conf->ra_prefix_list)) != 675 NULL) { 676 SIMPLEQ_REMOVE_HEAD(&ra_iface_conf->ra_prefix_list, entry); 677 free(prefix); 678 } 679 680 free_dns_options(&ra_iface_conf->ra_options); 681 682 while ((pref64 = 683 SIMPLEQ_FIRST(&ra_iface_conf->ra_options.ra_pref64_list)) != NULL) { 684 SIMPLEQ_REMOVE_HEAD(&ra_iface_conf->ra_options.ra_pref64_list, 685 entry); 686 free(pref64); 687 } 688 689 free(ra_iface_conf); 690 } 691 692 void 693 free_dns_options(struct ra_options_conf *ra_options) 694 { 695 struct ra_rdnss_conf *ra_rdnss; 696 struct ra_dnssl_conf *ra_dnssl; 697 698 while ((ra_rdnss = SIMPLEQ_FIRST(&ra_options->ra_rdnss_list)) != NULL) { 699 SIMPLEQ_REMOVE_HEAD(&ra_options->ra_rdnss_list, entry); 700 free(ra_rdnss); 701 } 702 ra_options->rdnss_count = 0; 703 704 while ((ra_dnssl = SIMPLEQ_FIRST(&ra_options->ra_dnssl_list)) != NULL) { 705 SIMPLEQ_REMOVE_HEAD(&ra_options->ra_dnssl_list, entry); 706 free(ra_dnssl); 707 } 708 ra_options->dnssl_len = 0; 709 } 710 711 void 712 merge_config(struct rad_conf *conf, struct rad_conf *xconf) 713 { 714 struct ra_iface_conf *ra_iface_conf; 715 struct ra_pref64_conf *pref64; 716 717 /* Remove & discard existing interfaces. */ 718 while ((ra_iface_conf = SIMPLEQ_FIRST(&conf->ra_iface_list)) != NULL) { 719 SIMPLEQ_REMOVE_HEAD(&conf->ra_iface_list, entry); 720 free_ra_iface_conf(ra_iface_conf); 721 } 722 free_dns_options(&conf->ra_options); 723 724 while ((pref64 = SIMPLEQ_FIRST(&conf->ra_options.ra_pref64_list)) 725 != NULL) { 726 SIMPLEQ_REMOVE_HEAD(&conf->ra_options.ra_pref64_list, entry); 727 free(pref64); 728 } 729 730 conf->ra_options = xconf->ra_options; 731 SIMPLEQ_INIT(&conf->ra_options.ra_rdnss_list); 732 SIMPLEQ_INIT(&conf->ra_options.ra_dnssl_list); 733 SIMPLEQ_INIT(&conf->ra_options.ra_pref64_list); 734 735 /* Add new interfaces. */ 736 SIMPLEQ_CONCAT(&conf->ra_iface_list, &xconf->ra_iface_list); 737 738 /* Add dns options */ 739 SIMPLEQ_CONCAT(&conf->ra_options.ra_rdnss_list, 740 &xconf->ra_options.ra_rdnss_list); 741 SIMPLEQ_CONCAT(&conf->ra_options.ra_dnssl_list, 742 &xconf->ra_options.ra_dnssl_list); 743 SIMPLEQ_CONCAT(&conf->ra_options.ra_pref64_list, 744 &xconf->ra_options.ra_pref64_list); 745 free(xconf); 746 } 747 748 struct rad_conf * 749 config_new_empty(void) 750 { 751 struct rad_conf *xconf; 752 753 xconf = calloc(1, sizeof(*xconf)); 754 if (xconf == NULL) 755 fatal(NULL); 756 757 SIMPLEQ_INIT(&xconf->ra_iface_list); 758 759 xconf->ra_options.dfr = 1; 760 xconf->ra_options.cur_hl = 0; 761 xconf->ra_options.m_flag = 0; 762 xconf->ra_options.o_flag = 0; 763 xconf->ra_options.router_lifetime = ADV_DEFAULT_LIFETIME; 764 xconf->ra_options.reachable_time = 0; 765 xconf->ra_options.retrans_timer = 0; 766 xconf->ra_options.source_link_addr = 1; 767 xconf->ra_options.mtu = 0; 768 xconf->ra_options.rdns_lifetime = DEFAULT_RDNS_LIFETIME; 769 SIMPLEQ_INIT(&xconf->ra_options.ra_rdnss_list); 770 SIMPLEQ_INIT(&xconf->ra_options.ra_dnssl_list); 771 SIMPLEQ_INIT(&xconf->ra_options.ra_pref64_list); 772 773 return (xconf); 774 } 775 776 void 777 config_clear(struct rad_conf *conf) 778 { 779 struct rad_conf *xconf; 780 781 /* Merge current config with an empty config. */ 782 xconf = config_new_empty(); 783 merge_config(conf, xconf); 784 785 free(conf); 786 } 787 788 void 789 mask_prefix(struct in6_addr* in6, int len) 790 { 791 uint8_t bitmask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; 792 int i, skip; 793 794 if (len < 0 || len > 128) 795 fatalx("invalid prefix length: %d", len); 796 797 skip = len / 8; 798 799 if (skip < 16) 800 in6->s6_addr[skip] &= bitmask[len % 8]; 801 802 for (i = skip + 1; i < 16; i++) 803 in6->s6_addr[i] = 0; 804 } 805 806 const char* 807 sin6_to_str(struct sockaddr_in6 *sin6) 808 { 809 static char hbuf[NI_MAXHOST]; 810 int error; 811 812 error = getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, hbuf, 813 sizeof(hbuf), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); 814 if (error) { 815 log_warnx("%s", gai_strerror(error)); 816 strlcpy(hbuf, "unknown", sizeof(hbuf)); 817 } 818 return hbuf; 819 } 820 821 const char* 822 in6_to_str(struct in6_addr *in6) 823 { 824 825 struct sockaddr_in6 sin6; 826 827 memset(&sin6, 0, sizeof(sin6)); 828 sin6.sin6_len = sizeof(sin6); 829 sin6.sin6_family = AF_INET6; 830 sin6.sin6_addr = *in6; 831 832 return (sin6_to_str(&sin6)); 833 } 834 835 void 836 open_icmp6sock(int rdomain) 837 { 838 int icmp6sock, on = 1, off = 0; 839 840 log_debug("%s: %d", __func__, rdomain); 841 842 if ((icmp6sock = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, 843 IPPROTO_ICMPV6)) == -1) 844 fatal("ICMPv6 socket"); 845 846 if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, 847 sizeof(on)) == -1) 848 fatal("IPV6_RECVPKTINFO"); 849 850 if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, 851 sizeof(on)) == -1) 852 fatal("IPV6_RECVHOPLIMIT"); 853 854 if (setsockopt(icmp6sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, 855 sizeof(off)) == -1) 856 fatal("IPV6_RECVHOPLIMIT"); 857 858 if (setsockopt(icmp6sock, SOL_SOCKET, SO_RTABLE, &rdomain, 859 sizeof(rdomain)) == -1) { 860 /* we might race against removal of the rdomain */ 861 log_warn("setsockopt SO_RTABLE"); 862 close(icmp6sock); 863 return; 864 } 865 866 main_imsg_compose_frontend(IMSG_ICMP6SOCK, icmp6sock, &rdomain, 867 sizeof(rdomain)); 868 } 869