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