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