rtadvd.c revision 1.67 1 /* $NetBSD: rtadvd.c,v 1.67 2019/01/11 20:41:53 christos Exp $ */
2 /* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $ */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <sys/socket.h>
35 #include <sys/uio.h>
36 #include <sys/time.h>
37 #include <sys/queue.h>
38
39 #include <net/if.h>
40 #include <net/route.h>
41 #include <net/if_dl.h>
42 #include <netinet/in.h>
43 #include <netinet/ip6.h>
44 #include <netinet6/ip6_var.h>
45 #include <netinet/icmp6.h>
46
47 #include <arpa/inet.h>
48
49 #include <time.h>
50 #include <unistd.h>
51 #include <stdio.h>
52 #include <err.h>
53 #include <errno.h>
54 #include <string.h>
55 #include <stdlib.h>
56 #include <syslog.h>
57 #include <stdarg.h>
58 #ifdef __NetBSD__
59 #include <util.h>
60 #endif
61 #include <poll.h>
62 #include <pwd.h>
63
64 #include "rtadvd.h"
65 #include "rrenum.h"
66 #include "advcap.h"
67 #include "timer.h"
68 #include "if.h"
69 #include "config.h"
70 #include "dump.h"
71 #include "logit.h"
72 #include "prog_ops.h"
73 #include "expandm.h"
74
75 struct msghdr rcvmhdr;
76 static unsigned char *rcvcmsgbuf;
77 static size_t rcvcmsgbuflen;
78 static unsigned char *sndcmsgbuf;
79 static size_t sndcmsgbuflen;
80 volatile sig_atomic_t do_dump;
81 volatile sig_atomic_t do_reconf;
82 volatile sig_atomic_t do_die;
83 struct msghdr sndmhdr;
84 struct iovec rcviov[2];
85 struct iovec sndiov[2];
86 struct sockaddr_in6 rcvfrom;
87 static const char *dumpfilename = "/var/run/rtadvd.dump"; /* XXX configurable */
88 static char *mcastif;
89 int sock;
90 int rtsock = -1;
91 int accept_rr = 0;
92 int dflag = 0, sflag = 0, Dflag;
93
94 static char **if_argv;
95 static int if_argc;
96
97 char *conffile = NULL;
98
99 struct ralist_head_t ralist = TAILQ_HEAD_INITIALIZER(ralist);
100
101 struct nd_optlist {
102 TAILQ_ENTRY(nd_optlist) next;
103 struct nd_opt_hdr *opt;
104 };
105 union nd_opts {
106 struct nd_opt_hdr *nd_opt_array[9];
107 struct {
108 struct nd_opt_hdr *zero;
109 struct nd_opt_hdr *src_lladdr;
110 struct nd_opt_hdr *tgt_lladdr;
111 struct nd_opt_prefix_info *pi;
112 struct nd_opt_rd_hdr *rh;
113 struct nd_opt_mtu *mtu;
114 TAILQ_HEAD(, nd_optlist) list;
115 } nd_opt_each;
116 };
117 #define nd_opts_src_lladdr nd_opt_each.src_lladdr
118 #define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr
119 #define nd_opts_pi nd_opt_each.pi
120 #define nd_opts_rh nd_opt_each.rh
121 #define nd_opts_mtu nd_opt_each.mtu
122 #define nd_opts_list nd_opt_each.list
123
124 #define NDOPT_FLAG_SRCLINKADDR (1 << 0)
125 #define NDOPT_FLAG_TGTLINKADDR (1 << 1)
126 #define NDOPT_FLAG_PREFIXINFO (1 << 2)
127 #define NDOPT_FLAG_RDHDR (1 << 3)
128 #define NDOPT_FLAG_MTU (1 << 4)
129 #define NDOPT_FLAG_RDNSS (1 << 5)
130 #define NDOPT_FLAG_DNSSL (1 << 6)
131
132 uint32_t ndopt_flags[] = {
133 [ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR,
134 [ND_OPT_TARGET_LINKADDR] = NDOPT_FLAG_TGTLINKADDR,
135 [ND_OPT_PREFIX_INFORMATION] = NDOPT_FLAG_PREFIXINFO,
136 [ND_OPT_REDIRECTED_HEADER] = NDOPT_FLAG_RDHDR,
137 [ND_OPT_MTU] = NDOPT_FLAG_MTU,
138 [ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS,
139 [ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL,
140 };
141
142 struct sockaddr_in6 sin6_linklocal_allnodes = {
143 .sin6_len = sizeof(sin6_linklocal_allnodes),
144 .sin6_family = AF_INET6,
145 .sin6_addr = IN6ADDR_LINKLOCAL_ALLNODES_INIT,
146 };
147 #ifdef notdef
148 struct sockaddr_in6 sin6_linklocal_allrouters = {
149 .sin6_len = sizeof(sin6_linklocal_allrouters),
150 .sin6_family = AF_INET6,
151 .sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT,
152 };
153 #endif
154 struct sockaddr_in6 sin6_sitelocal_allrouters = {
155 .sin6_len = sizeof(sin6_sitelocal_allrouters),
156 .sin6_family = AF_INET6,
157 .sin6_addr = IN6ADDR_SITELOCAL_ALLROUTERS_INIT,
158 };
159
160 static void set_die(int);
161 static void die(void);
162 static void set_reconf(int);
163 static void sock_open(void);
164 static void rtsock_open(void);
165 static void rtadvd_input(void);
166 static void rs_input(int, struct nd_router_solicit *,
167 struct in6_pktinfo *, struct sockaddr_in6 *);
168 static void ra_input(int, struct nd_router_advert *,
169 struct in6_pktinfo *, struct sockaddr_in6 *);
170 static struct rainfo *ra_output(struct rainfo *, bool);
171 static int prefix_check(struct nd_opt_prefix_info *, struct rainfo *,
172 struct sockaddr_in6 *);
173 static int nd6_options(struct nd_opt_hdr *, int, union nd_opts *, uint32_t);
174 static void free_ndopts(union nd_opts *);
175 static void rtmsg_input(void);
176 static void rtadvd_set_dump_file(int);
177
178 int
179 main(int argc, char *argv[])
180 {
181 struct pollfd set[2];
182 struct timespec *timeout;
183 int i, ch;
184 int fflag = 0, logopt;
185 struct passwd *pw;
186 const char *pidfilepath = NULL;
187 pid_t pid;
188
189 /* get command line options and arguments */
190 #define OPTIONS "c:dDfM:p:Rs"
191 while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
192 #undef OPTIONS
193 switch (ch) {
194 case 'c':
195 conffile = optarg;
196 break;
197 case 'd':
198 dflag++;
199 break;
200 case 'D':
201 Dflag++;
202 break;
203 case 'f':
204 fflag = 1;
205 break;
206 case 'M':
207 mcastif = optarg;
208 break;
209 case 'p':
210 pidfilepath = optarg;
211 break;
212 case 'R':
213 fprintf(stderr, "rtadvd: "
214 "the -R option is currently ignored.\n");
215 /* accept_rr = 1; */
216 /* run anyway... */
217 break;
218 case 's':
219 sflag = 1;
220 break;
221 }
222 }
223 argc -= optind;
224 argv += optind;
225 if (argc == 0) {
226 fprintf(stderr, "Ysage: %s [-DdfRs] [-c conffile]"
227 " [-M ifname] [-p pidfile] interface ...\n", getprogname());
228 return EXIT_FAILURE;
229 }
230
231 if ((pid = pidfile_lock(pidfilepath)) != 0) {
232 if (pid == -1)
233 logit(LOG_ERR, "pidfile_lock: %m");
234 /* Continue */
235 else {
236 logit(LOG_ERR, "Another instance of `%s' is running "
237 "(pid %d); exiting.", getprogname(), pid);
238 return EXIT_FAILURE;
239 }
240 }
241
242 if (prog_init && prog_init() == -1)
243 err(EXIT_FAILURE, "init failed");
244
245 logopt = LOG_NDELAY | LOG_PID;
246 if (fflag)
247 logopt |= LOG_PERROR;
248 openlog("rtadvd", logopt, LOG_DAEMON);
249
250 /* set log level */
251 if (dflag == 0)
252 (void)setlogmask(LOG_UPTO(LOG_ERR));
253 if (dflag == 1)
254 (void)setlogmask(LOG_UPTO(LOG_INFO));
255
256 errno = 0; /* Ensure errno is 0 so we know if getpwnam errors or not */
257 if ((pw = getpwnam(RTADVD_USER)) == NULL) {
258 if (errno == 0)
259 logit(LOG_ERR,
260 "user %s does not exist, aborting",
261 RTADVD_USER);
262 else
263 logit(LOG_ERR, "getpwnam: %s: %m", RTADVD_USER);
264 return EXIT_FAILURE;
265 }
266
267 /* timer initialization */
268 rtadvd_timer_init();
269
270 if_argc = argc;
271 if_argv = argv;
272 while (argc--)
273 getconfig(*argv++, 1);
274
275 if (!fflag) {
276 prog_daemon(1, 0);
277 if (pidfile_lock(pidfilepath) != 0)
278 logit(LOG_ERR, " pidfile_lock: %m");
279 }
280
281 sock_open();
282
283 set[0].fd = sock;
284 set[0].events = POLLIN;
285 if (sflag == 0) {
286 rtsock_open();
287 set[1].fd = rtsock;
288 set[1].events = POLLIN;
289 } else
290 set[1].fd = -1;
291
292 logit(LOG_INFO, "dropping privileges to %s", RTADVD_USER);
293 if (prog_chroot(pw->pw_dir) == -1) {
294 logit(LOG_ERR, "chroot: %s: %m", pw->pw_dir);
295 return EXIT_FAILURE;
296 }
297 if (prog_chdir("/") == -1) {
298 logit(LOG_ERR, "chdir: /: %m");
299 return EXIT_FAILURE;
300 }
301 if (prog_setgroups(1, &pw->pw_gid) == -1 ||
302 prog_setgid(pw->pw_gid) == -1 ||
303 prog_setuid(pw->pw_uid) == -1)
304 {
305 logit(LOG_ERR, "failed to drop privileges: %m");
306 return EXIT_FAILURE;
307 }
308
309 signal(SIGINT, set_die);
310 signal(SIGTERM, set_die);
311 signal(SIGHUP, set_reconf);
312 signal(SIGUSR1, rtadvd_set_dump_file);
313
314 for (;;) {
315 if (do_dump) { /* SIGUSR1 */
316 do_dump = 0;
317 rtadvd_dump_file(dumpfilename);
318 }
319
320 if (do_reconf) { /* SIGHUP */
321 do_reconf = 0;
322 logit(LOG_INFO, "%s: reloading config on SIGHUP",
323 __func__);
324 argc = if_argc;
325 argv = if_argv;
326 while (argc--)
327 getconfig(*argv++, 0);
328 }
329
330 /* timer expiration check and reset the timer */
331 timeout = rtadvd_check_timer();
332
333 if (do_die) {
334 die();
335 /*NOTREACHED*/
336 }
337
338 if (timeout != NULL) {
339 logit(LOG_DEBUG,
340 "%s: set timer to %jd:%jd. waiting for "
341 "inputs or timeout", __func__,
342 (intmax_t)timeout->tv_sec,
343 (intmax_t)timeout->tv_nsec);
344 } else {
345 logit(LOG_DEBUG,
346 "%s: there's no timer. waiting for inputs",
347 __func__);
348 }
349
350 if ((i = prog_poll(set, 2, timeout ? (timeout->tv_sec * 1000 +
351 (timeout->tv_nsec + 999999) / 1000000) : INFTIM)) == -1)
352 {
353 /* EINTR would occur upon SIGUSR1 for status dump */
354 if (errno == EINTR)
355 continue;
356
357 logit(LOG_ERR, "%s: poll: %m", __func__);
358 if (Dflag)
359 exit(1);
360 }
361 if (i == 0) /* timeout */
362 continue;
363 if (rtsock != -1 && set[1].revents & POLLIN)
364 rtmsg_input();
365 if (set[0].revents & POLLIN)
366 rtadvd_input();
367 }
368 return EXIT_SUCCESS; /* NOTREACHED */
369 }
370
371 static void
372 rtadvd_set_dump_file(__unused int sig)
373 {
374
375 do_dump = 1;
376 }
377
378 static void
379 set_reconf(__unused int sig)
380 {
381
382 do_reconf = 1;
383 }
384
385 static void
386 set_die(__unused int sig)
387 {
388
389 do_die = 1;
390 }
391
392 static void
393 die(void)
394 {
395 static int waiting;
396 struct rainfo *rai, *ran;
397 struct rdnss *rdnss;
398 struct dnssl *dnssl;
399
400 if (waiting) {
401 if (TAILQ_FIRST(&ralist)) {
402 logit(LOG_INFO,
403 "%s: waiting for expiration of all RA timers",
404 __func__);
405 return;
406 }
407 logit(LOG_NOTICE, "%s: gracefully terminated", __func__);
408 free(rcvcmsgbuf);
409 free(sndcmsgbuf);
410 exit(EXIT_SUCCESS);
411 /* NOT REACHED */
412 }
413
414 if (TAILQ_FIRST(&ralist) == NULL) {
415 logit(LOG_NOTICE, "%s: gracefully terminated", __func__);
416 exit(EXIT_SUCCESS);
417 /* NOT REACHED */
418 }
419
420 waiting = 1;
421 logit(LOG_NOTICE, "%s: final RA transmission started", __func__);
422
423 TAILQ_FOREACH_SAFE(rai, &ralist, next, ran) {
424 if (rai->leaving) {
425 TAILQ_REMOVE(&ralist, rai, next);
426 TAILQ_INSERT_HEAD(&ralist, rai->leaving, next);
427 rai->leaving->leaving = rai->leaving;
428 rai->leaving->leaving_for = rai->leaving;
429 free_rainfo(rai);
430 continue;
431 }
432 rai->lifetime = 0;
433 TAILQ_FOREACH(rdnss, &rai->rdnss, next)
434 rdnss->lifetime = 0;
435 TAILQ_FOREACH(dnssl, &rai->dnssl, next)
436 dnssl->lifetime = 0;
437 make_packet(rai);
438 rai->leaving = rai;
439 rai->leaving_for = rai;
440 rai->initcounter = MAX_INITIAL_RTR_ADVERTISEMENTS;
441 rai->mininterval = MIN_DELAY_BETWEEN_RAS;
442 rai->maxinterval = MIN_DELAY_BETWEEN_RAS;
443 rai->leaving_adv = MAX_FINAL_RTR_ADVERTISEMENTS;
444 ra_output(rai, false);
445 ra_timer_update(rai, &rai->timer->tm);
446 rtadvd_set_timer(&rai->timer->tm, rai->timer);
447 }
448 }
449
450 static void
451 rtmsg_input(void)
452 {
453 int n, type, ifindex = 0, plen;
454 size_t len;
455 union rt_msghdr_buf {
456 struct rt_msghdr rt_msghdr;
457 char data[2048];
458 } buffer;
459 char *msg, *next, *lim, **argv;
460 char ifname[IF_NAMESIZE];
461 struct prefix *prefix;
462 struct rainfo *rai;
463 struct in6_addr *addr;
464 char addrbuf[INET6_ADDRSTRLEN];
465 int prefixchange = 0, argc;
466
467 memset(&buffer, 0, sizeof(buffer));
468 n = prog_read(rtsock, &buffer, sizeof(buffer));
469
470 /* We read the buffer first to clear the FD */
471 if (do_die)
472 return;
473
474 msg = buffer.data;
475 if (dflag > 1) {
476 logit(LOG_DEBUG, "%s: received a routing message "
477 "(type = %d, len = %d)", __func__, rtmsg_type(msg),
478 rtmsg_len(msg));
479 }
480 if (n > rtmsg_len(msg)) {
481 /*
482 * This usually won't happen for messages received on
483 * a routing socket.
484 */
485 if (dflag > 1)
486 logit(LOG_DEBUG,
487 "%s: received data length is larger than "
488 "1st routing message len. multiple messages? "
489 "read %d bytes, but 1st msg len = %d",
490 __func__, n, rtmsg_len(msg));
491 #if 0
492 /* adjust length */
493 n = rtmsg_len(msg);
494 #endif
495 }
496
497 lim = msg + n;
498 for (next = msg; next < lim; next += len) {
499 int oldifflags;
500
501 next = get_next_msg(next, lim, 0, &len,
502 RTADV_TYPE2BITMASK(RTM_ADD) |
503 RTADV_TYPE2BITMASK(RTM_DELETE) |
504 RTADV_TYPE2BITMASK(RTM_NEWADDR) |
505 RTADV_TYPE2BITMASK(RTM_DELADDR) |
506 #ifdef RTM_IFANNOUNCE
507 RTADV_TYPE2BITMASK(RTM_IFANNOUNCE) |
508 #endif
509 RTADV_TYPE2BITMASK(RTM_IFINFO));
510 if (len == 0)
511 break;
512 type = rtmsg_type(next);
513 switch (type) {
514 case RTM_ADD:
515 case RTM_DELETE:
516 ifindex = get_rtm_ifindex(next);
517 break;
518 case RTM_NEWADDR:
519 case RTM_DELADDR:
520 ifindex = get_ifam_ifindex(next);
521 break;
522 #ifdef RTM_IFANNOUNCE
523 case RTM_IFANNOUNCE:
524 ifindex = get_ifan_ifindex(next);
525 if (get_ifan_what(next) == IFAN_ARRIVAL) {
526 logit(LOG_DEBUG,
527 "%s: interface %s arrived",
528 __func__,
529 if_indextoname(ifindex, ifname));
530 if (if_argc == 0) {
531 getconfig(ifname, 0);
532 continue;
533 }
534 argc = if_argc;
535 argv = if_argv;
536 while (argc--) {
537 if (strcmp(ifname, *argv++) == 0) {
538 getconfig(ifname, 0);
539 break;
540 }
541 }
542 continue;
543 }
544 break;
545 #endif
546 case RTM_IFINFO:
547 ifindex = get_ifm_ifindex(next);
548 break;
549 default:
550 /* should not reach here */
551 if (dflag > 1) {
552 logit(LOG_DEBUG, "%s: unknown rtmsg %d on %s",
553 __func__, type,
554 if_indextoname(ifindex, ifname));
555 }
556 continue;
557 }
558
559 if ((rai = if_indextorainfo(ifindex)) == NULL) {
560 if (dflag > 1) {
561 logit(LOG_DEBUG,
562 "%s: route changed on "
563 "non advertising interface %s (%d)",
564 __func__,
565 if_indextoname(ifindex, ifname),
566 ifindex);
567 }
568 continue;
569 }
570 oldifflags = rai->ifflags;
571
572 switch (type) {
573 case RTM_ADD:
574 /* init ifflags because it may have changed */
575 rai->ifflags = if_getflags(ifindex, rai->ifflags);
576
577 if (sflag)
578 break; /* we aren't interested in prefixes */
579
580 addr = get_addr(msg);
581 plen = get_prefixlen(msg);
582 /* sanity check for plen */
583 /* as RFC2373, prefixlen is at least 4 */
584 if (plen < 4 || plen > 127) {
585 logit(LOG_INFO, "%s: new interface route's"
586 "plen %d is invalid for a prefix",
587 __func__, plen);
588 break;
589 }
590 prefix = find_prefix(rai, addr, plen);
591 if (prefix) {
592 if (prefix->timer) {
593 /*
594 * If the prefix has been invalidated,
595 * make it available again.
596 */
597 update_prefix(prefix);
598 prefixchange = 1;
599 } else if (dflag > 1) {
600 logit(LOG_DEBUG,
601 "%s: new prefix(%s/%d) "
602 "added on %s, "
603 "but it was already in list",
604 __func__,
605 inet_ntop(AF_INET6, addr,
606 (char *)addrbuf, INET6_ADDRSTRLEN),
607 plen, rai->ifname);
608 }
609 break;
610 }
611 make_prefix(rai, ifindex, addr, plen);
612 prefixchange = 1;
613 break;
614 case RTM_DELETE:
615 /* init ifflags because it may have changed */
616 rai->ifflags = if_getflags(ifindex, rai->ifflags);
617
618 if (sflag)
619 break;
620
621 addr = get_addr(msg);
622 plen = get_prefixlen(msg);
623 /* sanity check for plen */
624 /* as RFC2373, prefixlen is at least 4 */
625 if (plen < 4 || plen > 127) {
626 logit(LOG_INFO,
627 "%s: deleted interface route's "
628 "plen %d is invalid for a prefix",
629 __func__, plen);
630 break;
631 }
632 prefix = find_prefix(rai, addr, plen);
633 if (prefix == NULL) {
634 if (dflag > 1) {
635 logit(LOG_DEBUG,
636 "%s: prefix(%s/%d) was "
637 "deleted on %s, "
638 "but it was not in list",
639 __func__,
640 inet_ntop(AF_INET6, addr,
641 (char *)addrbuf, INET6_ADDRSTRLEN),
642 plen, rai->ifname);
643 }
644 break;
645 }
646 invalidate_prefix(prefix);
647 prefixchange = 1;
648 break;
649 case RTM_NEWADDR:
650 case RTM_DELADDR:
651 /* init ifflags because it may have changed */
652 rai->ifflags = if_getflags(ifindex, rai->ifflags);
653 break;
654 case RTM_IFINFO:
655 rai->ifflags = get_ifm_flags(next);
656 break;
657 #ifdef RTM_IFANNOUNCE
658 case RTM_IFANNOUNCE:
659 if (get_ifan_what(next) == IFAN_DEPARTURE) {
660 logit(LOG_DEBUG,
661 "%s: interface %s departed",
662 __func__, rai->ifname);
663 TAILQ_REMOVE(&ralist, rai, next);
664 if (rai->leaving)
665 free_rainfo(rai->leaving);
666 free_rainfo(rai);
667 continue;
668 }
669 break;
670 #endif
671 default:
672 /* should not reach here */
673 if (dflag > 1) {
674 logit(LOG_DEBUG,
675 "%s: unknown rtmsg %d on %s",
676 __func__, type,
677 if_indextoname(ifindex, ifname));
678 }
679 return;
680 }
681
682 /* check if an interface flag is changed */
683 if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */
684 (rai->ifflags & IFF_UP) == 0) {
685 logit(LOG_INFO,
686 "%s: interface %s becomes down. stop timer.",
687 __func__, rai->ifname);
688 rtadvd_remove_timer(&rai->timer);
689 } else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */
690 (rai->ifflags & IFF_UP) != 0) {
691 logit(LOG_INFO,
692 "%s: interface %s becomes up. restart timer.",
693 __func__, rai->ifname);
694
695 rai->initcounter = 0; /* reset the counter */
696 rai->waiting = 0; /* XXX */
697 rtadvd_remove_timer(&rai->timer);
698 rai->timer = rtadvd_add_timer(ra_timeout,
699 ra_timer_update, rai, rai);
700 ra_timer_update(rai, &rai->timer->tm);
701 rtadvd_set_timer(&rai->timer->tm, rai->timer);
702 rtadvd_remove_timer(&rai->timer_sol);
703 rai->timer_sol = rtadvd_add_timer(ra_timeout_sol,
704 NULL, rai, NULL);
705 } else if (prefixchange && rai->ifflags & IFF_UP) {
706 /*
707 * An advertised prefix has been added or invalidated.
708 * Will notice the change in a short delay.
709 */
710 rai->initcounter = 0;
711 ra_timer_set_short_delay(rai, rai->timer);
712 }
713 }
714
715 return;
716 }
717
718 void
719 rtadvd_input(void)
720 {
721 ssize_t i;
722 int *hlimp = NULL;
723 struct icmp6_hdr *icp;
724 int ifindex = 0;
725 struct cmsghdr *cm;
726 struct in6_pktinfo *pi = NULL;
727 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
728 struct in6_addr dst = in6addr_any;
729 struct rainfo *rai;
730
731 /*
732 * Get message. We reset msg_controllen since the field could
733 * be modified if we had received a message before setting
734 * receive options.
735 */
736 rcvmhdr.msg_controllen = rcvcmsgbuflen;
737 if ((i = prog_recvmsg(sock, &rcvmhdr, 0)) == -1)
738 return;
739
740 /* We read the buffer first to clear the FD */
741 if (do_die)
742 return;
743
744 /* extract optional information via Advanced API */
745 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr);
746 cm;
747 cm = (struct cmsghdr *)CMSG_NXTHDR(&rcvmhdr, cm)) {
748 if (cm->cmsg_level == IPPROTO_IPV6 &&
749 cm->cmsg_type == IPV6_PKTINFO &&
750 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
751 pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
752 ifindex = pi->ipi6_ifindex;
753 dst = pi->ipi6_addr;
754 }
755 if (cm->cmsg_level == IPPROTO_IPV6 &&
756 cm->cmsg_type == IPV6_HOPLIMIT &&
757 cm->cmsg_len == CMSG_LEN(sizeof(int)))
758 hlimp = (int *)CMSG_DATA(cm);
759 }
760 if (ifindex == 0) {
761 logit(LOG_ERR,
762 "%s: failed to get receiving interface",
763 __func__);
764 return;
765 }
766 if (hlimp == NULL) {
767 logit(LOG_ERR,
768 "%s: failed to get receiving hop limit",
769 __func__);
770 return;
771 }
772
773 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == NULL) {
774 if (dflag > 1) {
775 logit(LOG_DEBUG,
776 "%s: received data for non advertising "
777 "interface (%s)",
778 __func__,
779 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
780 }
781 return;
782 }
783 /*
784 * If we happen to receive data on an interface which is now down,
785 * just discard the data.
786 */
787 if ((rai->ifflags & IFF_UP) == 0) {
788 logit(LOG_INFO,
789 "%s: received data on a disabled interface (%s)",
790 __func__,
791 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
792 return;
793 }
794
795 if ((size_t)i < sizeof(struct icmp6_hdr)) {
796 logit(LOG_ERR,
797 "%s: packet size(%zd) is too short",
798 __func__, i);
799 return;
800 }
801
802 icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base;
803
804 switch (icp->icmp6_type) {
805 case ND_ROUTER_SOLICIT:
806 /*
807 * Message verification - RFC-2461 6.1.1
808 * XXX: these checks must be done in the kernel as well,
809 * but we can't completely rely on them.
810 */
811 if (*hlimp != 255) {
812 logit(LOG_NOTICE,
813 "%s: RS with invalid hop limit(%d) "
814 "received from %s on %s",
815 __func__, *hlimp,
816 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
817 INET6_ADDRSTRLEN),
818 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
819 return;
820 }
821 if (icp->icmp6_code) {
822 logit(LOG_NOTICE,
823 "%s: RS with invalid ICMP6 code(%d) "
824 "received from %s on %s",
825 __func__, icp->icmp6_code,
826 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
827 INET6_ADDRSTRLEN),
828 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
829 return;
830 }
831 if ((size_t)i < sizeof(struct nd_router_solicit)) {
832 logit(LOG_NOTICE,
833 "%s: RS from %s on %s does not have enough "
834 "length (len = %zd)",
835 __func__,
836 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
837 INET6_ADDRSTRLEN),
838 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
839 return;
840 }
841 rs_input(i, (struct nd_router_solicit *)icp, pi, &rcvfrom);
842 break;
843 case ND_ROUTER_ADVERT:
844 /*
845 * Message verification - RFC-2461 6.1.2
846 * XXX: there's a same dilemma as above...
847 */
848 if (*hlimp != 255) {
849 logit(LOG_NOTICE,
850 "%s: RA with invalid hop limit(%d) "
851 "received from %s on %s",
852 __func__, *hlimp,
853 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
854 INET6_ADDRSTRLEN),
855 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
856 return;
857 }
858 if (icp->icmp6_code) {
859 logit(LOG_NOTICE,
860 "%s: RA with invalid ICMP6 code(%d) "
861 "received from %s on %s",
862 __func__, icp->icmp6_code,
863 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
864 INET6_ADDRSTRLEN),
865 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
866 return;
867 }
868 if ((size_t)i < sizeof(struct nd_router_advert)) {
869 logit(LOG_NOTICE,
870 "%s: RA from %s on %s does not have enough "
871 "length (len = %zd)",
872 __func__,
873 inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
874 INET6_ADDRSTRLEN),
875 if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
876 return;
877 }
878 ra_input(i, (struct nd_router_advert *)icp, pi, &rcvfrom);
879 break;
880 case ICMP6_ROUTER_RENUMBERING:
881 if (accept_rr == 0) {
882 logit(LOG_ERR, "%s: received a router renumbering "
883 "message, but not allowed to be accepted",
884 __func__);
885 break;
886 }
887 rr_input(i, (struct icmp6_router_renum *)icp, pi, &rcvfrom,
888 &dst);
889 break;
890 default:
891 /*
892 * Note that this case is POSSIBLE, especially just
893 * after invocation of the daemon. This is because we
894 * could receive message after opening the socket and
895 * before setting ICMP6 type filter(see sock_open()).
896 */
897 logit(LOG_ERR, "%s: invalid icmp type(%d)",
898 __func__, icp->icmp6_type);
899 return;
900 }
901 }
902
903 static void
904 rs_input(int len, struct nd_router_solicit *rs,
905 struct in6_pktinfo *pi, struct sockaddr_in6 *from)
906 {
907 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
908 union nd_opts ndopts;
909 struct rainfo *rai;
910 struct soliciter *sol;
911
912 logit(LOG_DEBUG,
913 "%s: RS received from %s on %s",
914 __func__,
915 inet_ntop(AF_INET6, &from->sin6_addr,
916 ntopbuf, INET6_ADDRSTRLEN),
917 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
918
919 /* ND option check */
920 memset(&ndopts, 0, sizeof(ndopts));
921 TAILQ_INIT(&ndopts.nd_opts_list);
922 if (nd6_options((struct nd_opt_hdr *)(rs + 1),
923 len - sizeof(struct nd_router_solicit),
924 &ndopts, NDOPT_FLAG_SRCLINKADDR)) {
925 logit(LOG_INFO,
926 "%s: ND option check failed for an RS from %s on %s",
927 __func__,
928 inet_ntop(AF_INET6, &from->sin6_addr,
929 ntopbuf, INET6_ADDRSTRLEN),
930 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
931 return;
932 }
933
934 /*
935 * If the IP source address is the unspecified address, there
936 * must be no source link-layer address option in the message.
937 * (RFC-2461 6.1.1)
938 */
939 if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) &&
940 ndopts.nd_opts_src_lladdr) {
941 logit(LOG_INFO,
942 "%s: RS from unspecified src on %s has a link-layer"
943 " address option",
944 __func__,
945 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
946 goto done;
947 }
948
949 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == NULL) {
950 logit(LOG_INFO,
951 "%s: RS received on non advertising interface(%s)",
952 __func__,
953 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
954 goto done;
955 }
956
957 if (rai->leaving) {
958 logit(LOG_INFO,
959 "%s: RS received on reconfiguring advertising interface(%s)",
960 __func__, rai->ifname);
961 goto done;
962 }
963
964 rai->rsinput++; /* increment statistics */
965
966 /*
967 * Decide whether to send RA according to the rate-limit
968 * consideration.
969 */
970
971 /* record sockaddr waiting for RA, if possible */
972 TAILQ_FOREACH(sol, &rai->soliciter, next) {
973 if (IN6_ARE_ADDR_EQUAL(&sol->addr.sin6_addr, &from->sin6_addr))
974 break;
975 }
976 if (sol == NULL) {
977 sol = malloc(sizeof(*sol));
978 if (sol == NULL) {
979 logit(LOG_ERR, "%s: malloc: %m", __func__);
980 } else {
981 sol->addr = *from;
982 /* XXX RFC2553 need clarification on flowinfo */
983 sol->addr.sin6_flowinfo = 0;
984 TAILQ_INSERT_TAIL(&rai->soliciter, sol, next);
985 }
986 }
987
988 /*
989 * If there is already a waiting RS packet, don't
990 * update the timer.
991 */
992 if (rai->waiting++)
993 goto done;
994
995 ra_timer_set_short_delay(rai, rai->timer_sol);
996
997 done:
998 free_ndopts(&ndopts);
999 }
1000
1001 void
1002 ra_timer_set_short_delay(struct rainfo *rai, struct rtadvd_timer *timer)
1003 {
1004 long delay; /* must not be greater than 1000000 */
1005 struct timespec interval, now, min_delay, tm_tmp, *rest;
1006
1007 /*
1008 * Compute a random delay. If the computed value
1009 * corresponds to a time later than the time the next
1010 * multicast RA is scheduled to be sent, ignore the random
1011 * delay and send the advertisement at the
1012 * already-scheduled time. RFC2461 6.2.6
1013 */
1014 delay = arc4random() % MAX_RA_DELAY_TIME;
1015 interval.tv_sec = 0;
1016 interval.tv_nsec = delay;
1017 rest = rtadvd_timer_rest(rai->timer);
1018 if (timespeccmp(rest, &interval, <)) {
1019 logit(LOG_DEBUG, "%s: random delay is larger than "
1020 "the rest of current timer", __func__);
1021 interval = *rest;
1022 }
1023
1024 /*
1025 * If we sent a multicast Router Advertisement within
1026 * the last MIN_DELAY_BETWEEN_RAS seconds, schedule
1027 * the advertisement to be sent at a time corresponding to
1028 * MIN_DELAY_BETWEEN_RAS plus the random value after the
1029 * previous advertisement was sent.
1030 */
1031 prog_clock_gettime(CLOCK_MONOTONIC, &now);
1032 timespecsub(&now, &rai->lastsent, &tm_tmp);
1033 min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
1034 min_delay.tv_nsec = 0;
1035 if (timespeccmp(&tm_tmp, &min_delay, <)) {
1036 timespecsub(&min_delay, &tm_tmp, &min_delay);
1037 timespecadd(&min_delay, &interval, &interval);
1038 }
1039 rtadvd_set_timer(&interval, timer);
1040 }
1041
1042 static void
1043 ra_input(int len, struct nd_router_advert *ra,
1044 struct in6_pktinfo *pi, struct sockaddr_in6 *from)
1045 {
1046 struct rainfo *rai;
1047 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
1048 union nd_opts ndopts;
1049 const char *on_off[] = {"OFF", "ON"};
1050 uint32_t reachabletime, retranstimer, mtu;
1051 struct nd_optlist *optp;
1052 int inconsistent = 0;
1053
1054 logit(LOG_DEBUG,
1055 "%s: RA received from %s on %s",
1056 __func__,
1057 inet_ntop(AF_INET6, &from->sin6_addr,
1058 ntopbuf, INET6_ADDRSTRLEN),
1059 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
1060
1061 /* ND option check */
1062 memset(&ndopts, 0, sizeof(ndopts));
1063 TAILQ_INIT(&ndopts.nd_opts_list);
1064 if (nd6_options((struct nd_opt_hdr *)(ra + 1),
1065 len - sizeof(struct nd_router_advert),
1066 &ndopts, NDOPT_FLAG_SRCLINKADDR |
1067 NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
1068 NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL))
1069 {
1070 logit(LOG_INFO,
1071 "%s: ND option check failed for an RA from %s on %s",
1072 __func__,
1073 inet_ntop(AF_INET6, &from->sin6_addr,
1074 ntopbuf, INET6_ADDRSTRLEN),
1075 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
1076 return;
1077 }
1078
1079 /*
1080 * RA consistency check according to RFC-2461 6.2.7
1081 */
1082 if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == 0) {
1083 logit(LOG_INFO,
1084 "%s: received RA from %s on non-advertising"
1085 " interface(%s)",
1086 __func__,
1087 inet_ntop(AF_INET6, &from->sin6_addr,
1088 ntopbuf, INET6_ADDRSTRLEN),
1089 if_indextoname(pi->ipi6_ifindex, ifnamebuf));
1090 goto done;
1091 }
1092 if (rai->leaving) {
1093 logit(LOG_DEBUG,
1094 "%s: received RA on re-configuring interface (%s)",
1095 __func__, rai->ifname);
1096 goto done;
1097 }
1098 rai->rainput++; /* increment statistics */
1099
1100 /* Cur Hop Limit value */
1101 if (ra->nd_ra_curhoplimit && rai->hoplimit &&
1102 ra->nd_ra_curhoplimit != rai->hoplimit) {
1103 logit(LOG_INFO,
1104 "%s: CurHopLimit inconsistent on %s:"
1105 " %d from %s, %d from us",
1106 __func__,
1107 rai->ifname,
1108 ra->nd_ra_curhoplimit,
1109 inet_ntop(AF_INET6, &from->sin6_addr,
1110 ntopbuf, INET6_ADDRSTRLEN),
1111 rai->hoplimit);
1112 inconsistent++;
1113 }
1114 /* M flag */
1115 if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) !=
1116 rai->managedflg) {
1117 logit(LOG_INFO,
1118 "%s: M flag inconsistent on %s:"
1119 " %s from %s, %s from us",
1120 __func__,
1121 rai->ifname,
1122 on_off[!rai->managedflg],
1123 inet_ntop(AF_INET6, &from->sin6_addr,
1124 ntopbuf, INET6_ADDRSTRLEN),
1125 on_off[rai->managedflg]);
1126 inconsistent++;
1127 }
1128 /* O flag */
1129 if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) !=
1130 rai->otherflg) {
1131 logit(LOG_INFO,
1132 "%s: O flag inconsistent on %s:"
1133 " %s from %s, %s from us",
1134 __func__,
1135 rai->ifname,
1136 on_off[!rai->otherflg],
1137 inet_ntop(AF_INET6, &from->sin6_addr,
1138 ntopbuf, INET6_ADDRSTRLEN),
1139 on_off[rai->otherflg]);
1140 inconsistent++;
1141 }
1142 /* Reachable Time */
1143 reachabletime = ntohl(ra->nd_ra_reachable);
1144 if (reachabletime && rai->reachabletime &&
1145 reachabletime != rai->reachabletime) {
1146 logit(LOG_INFO,
1147 "%s: ReachableTime inconsistent on %s:"
1148 " %d from %s, %d from us",
1149 __func__,
1150 rai->ifname,
1151 reachabletime,
1152 inet_ntop(AF_INET6, &from->sin6_addr,
1153 ntopbuf, INET6_ADDRSTRLEN),
1154 rai->reachabletime);
1155 inconsistent++;
1156 }
1157 /* Retrans Timer */
1158 retranstimer = ntohl(ra->nd_ra_retransmit);
1159 if (retranstimer && rai->retranstimer &&
1160 retranstimer != rai->retranstimer) {
1161 logit(LOG_INFO,
1162 "%s: RetranceTimer inconsistent on %s:"
1163 " %d from %s, %d from us",
1164 __func__,
1165 rai->ifname,
1166 retranstimer,
1167 inet_ntop(AF_INET6, &from->sin6_addr,
1168 ntopbuf, INET6_ADDRSTRLEN),
1169 rai->retranstimer);
1170 inconsistent++;
1171 }
1172 /* Values in the MTU options */
1173 if (ndopts.nd_opts_mtu) {
1174 mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu);
1175 if (mtu && rai->linkmtu && mtu != rai->linkmtu) {
1176 logit(LOG_INFO,
1177 "%s: MTU option value inconsistent on %s:"
1178 " %d from %s, %d from us",
1179 __func__,
1180 rai->ifname, mtu,
1181 inet_ntop(AF_INET6, &from->sin6_addr,
1182 ntopbuf, INET6_ADDRSTRLEN),
1183 rai->linkmtu);
1184 inconsistent++;
1185 }
1186 }
1187 /* Preferred and Valid Lifetimes for prefixes */
1188 if (ndopts.nd_opts_pi)
1189 if (prefix_check(ndopts.nd_opts_pi, rai, from))
1190 inconsistent++;
1191 TAILQ_FOREACH(optp, &ndopts.nd_opts_list, next)
1192 if (prefix_check((struct nd_opt_prefix_info *)optp->opt,
1193 rai, from))
1194 inconsistent++;
1195
1196 if (inconsistent)
1197 rai->rainconsistent++;
1198
1199 done:
1200 free_ndopts(&ndopts);
1201 }
1202
1203 /* return a non-zero value if the received prefix is inconsitent with ours */
1204 static int
1205 prefix_check(struct nd_opt_prefix_info *pinfo,
1206 struct rainfo *rai, struct sockaddr_in6 *from)
1207 {
1208 uint32_t preferred_time, valid_time;
1209 struct prefix *pp;
1210 int inconsistent = 0;
1211 char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN];
1212 struct timespec now;
1213 struct in6_addr prefix;
1214
1215 #if 0 /* impossible */
1216 if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION)
1217 return 0;
1218 #endif
1219
1220 memcpy(&prefix, &pinfo->nd_opt_pi_prefix, sizeof(prefix));
1221
1222 /*
1223 * log if the adveritsed prefix has link-local scope(sanity check?)
1224 */
1225 if (IN6_IS_ADDR_LINKLOCAL(&prefix)) {
1226 logit(LOG_INFO,
1227 "%s: link-local prefix %s/%d is advertised "
1228 "from %s on %s",
1229 __func__,
1230 inet_ntop(AF_INET6, &prefix,
1231 prefixbuf, INET6_ADDRSTRLEN),
1232 pinfo->nd_opt_pi_prefix_len,
1233 inet_ntop(AF_INET6, &from->sin6_addr,
1234 ntopbuf, INET6_ADDRSTRLEN),
1235 rai->ifname);
1236 }
1237
1238 if ((pp = find_prefix(rai, &prefix,
1239 pinfo->nd_opt_pi_prefix_len)) == NULL) {
1240 logit(LOG_INFO,
1241 "%s: prefix %s/%d from %s on %s is not in our list",
1242 __func__,
1243 inet_ntop(AF_INET6, &prefix,
1244 prefixbuf, INET6_ADDRSTRLEN),
1245 pinfo->nd_opt_pi_prefix_len,
1246 inet_ntop(AF_INET6, &from->sin6_addr,
1247 ntopbuf, INET6_ADDRSTRLEN),
1248 rai->ifname);
1249 return 0;
1250 }
1251
1252 preferred_time = ntohl(pinfo->nd_opt_pi_preferred_time);
1253 if (pp->pltimeexpire) {
1254 /*
1255 * The lifetime is decremented in real time, so we should
1256 * compare the expiration time.
1257 * (RFC 2461 Section 6.2.7.)
1258 * XXX: can we really expect that all routers on the link
1259 * have synchronized clocks?
1260 */
1261 prog_clock_gettime(CLOCK_MONOTONIC, &now);
1262 preferred_time += now.tv_sec;
1263
1264 if (!pp->timer && rai->clockskew &&
1265 llabs((long long)preferred_time - pp->pltimeexpire) > rai->clockskew) {
1266 logit(LOG_INFO,
1267 "%s: preferred lifetime for %s/%d"
1268 " (decr. in real time) inconsistent on %s:"
1269 " %d from %s, %ld from us",
1270 __func__,
1271 inet_ntop(AF_INET6, &prefix,
1272 prefixbuf, INET6_ADDRSTRLEN),
1273 pinfo->nd_opt_pi_prefix_len,
1274 rai->ifname, preferred_time,
1275 inet_ntop(AF_INET6, &from->sin6_addr,
1276 ntopbuf, INET6_ADDRSTRLEN),
1277 pp->pltimeexpire);
1278 inconsistent++;
1279 }
1280 } else if (!pp->timer && preferred_time != pp->preflifetime) {
1281 logit(LOG_INFO,
1282 "%s: preferred lifetime for %s/%d"
1283 " inconsistent on %s:"
1284 " %d from %s, %d from us",
1285 __func__,
1286 inet_ntop(AF_INET6, &prefix,
1287 prefixbuf, INET6_ADDRSTRLEN),
1288 pinfo->nd_opt_pi_prefix_len,
1289 rai->ifname, preferred_time,
1290 inet_ntop(AF_INET6, &from->sin6_addr,
1291 ntopbuf, INET6_ADDRSTRLEN),
1292 pp->preflifetime);
1293 }
1294
1295 valid_time = ntohl(pinfo->nd_opt_pi_valid_time);
1296 if (pp->vltimeexpire) {
1297 prog_clock_gettime(CLOCK_MONOTONIC, &now);
1298 valid_time += now.tv_sec;
1299
1300 if (!pp->timer && rai->clockskew &&
1301 llabs((long long)valid_time - pp->vltimeexpire) > rai->clockskew) {
1302 logit(LOG_INFO,
1303 "%s: valid lifetime for %s/%d"
1304 " (decr. in real time) inconsistent on %s:"
1305 " %d from %s, %ld from us",
1306 __func__,
1307 inet_ntop(AF_INET6, &prefix,
1308 prefixbuf, INET6_ADDRSTRLEN),
1309 pinfo->nd_opt_pi_prefix_len,
1310 rai->ifname, preferred_time,
1311 inet_ntop(AF_INET6, &from->sin6_addr,
1312 ntopbuf, INET6_ADDRSTRLEN),
1313 pp->vltimeexpire);
1314 inconsistent++;
1315 }
1316 } else if (!pp->timer && valid_time != pp->validlifetime) {
1317 logit(LOG_INFO,
1318 "%s: valid lifetime for %s/%d"
1319 " inconsistent on %s:"
1320 " %d from %s, %d from us",
1321 __func__,
1322 inet_ntop(AF_INET6, &prefix,
1323 prefixbuf, INET6_ADDRSTRLEN),
1324 pinfo->nd_opt_pi_prefix_len,
1325 rai->ifname, valid_time,
1326 inet_ntop(AF_INET6, &from->sin6_addr,
1327 ntopbuf, INET6_ADDRSTRLEN),
1328 pp->validlifetime);
1329 inconsistent++;
1330 }
1331
1332 return inconsistent;
1333 }
1334
1335 struct prefix *
1336 find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen)
1337 {
1338 struct prefix *pp;
1339 int bytelen, bitlen;
1340 unsigned char bitmask;
1341
1342 TAILQ_FOREACH(pp, &rai->prefix, next) {
1343 if (plen != pp->prefixlen)
1344 continue;
1345 bytelen = plen / 8;
1346 bitlen = plen % 8;
1347 bitmask = 0xff << (8 - bitlen);
1348 if (memcmp(prefix, &pp->prefix, bytelen))
1349 continue;
1350 if (bitlen == 0 ||
1351 ((prefix->s6_addr[bytelen] & bitmask) ==
1352 (pp->prefix.s6_addr[bytelen] & bitmask))) {
1353 return pp;
1354 }
1355 }
1356
1357 return NULL;
1358 }
1359
1360 /* check if p0/plen0 matches p1/plen1; return 1 if matches, otherwise 0. */
1361 int
1362 prefix_match(struct in6_addr *p0, int plen0,
1363 struct in6_addr *p1, int plen1)
1364 {
1365 int bytelen, bitlen;
1366 unsigned char bitmask;
1367
1368 if (plen0 < plen1)
1369 return 0;
1370 bytelen = plen1 / 8;
1371 bitlen = plen1 % 8;
1372 bitmask = 0xff << (8 - bitlen);
1373 if (memcmp(p0, p1, bytelen))
1374 return 0;
1375 if (bitlen == 0 ||
1376 ((p0->s6_addr[bytelen] & bitmask) ==
1377 (p1->s6_addr[bytelen] & bitmask))) {
1378 return 1;
1379 }
1380
1381 return 0;
1382 }
1383
1384 static int
1385 nd6_options(struct nd_opt_hdr *hdr, int limit,
1386 union nd_opts *ndopts, uint32_t optflags)
1387 {
1388 int optlen = 0;
1389
1390 for (; limit > 0; limit -= optlen) {
1391 if ((size_t)limit < sizeof(struct nd_opt_hdr)) {
1392 logit(LOG_INFO, "%s: short option header", __func__);
1393 goto bad;
1394 }
1395
1396 hdr = (struct nd_opt_hdr *)((char *)hdr + optlen);
1397 if (hdr->nd_opt_len == 0) {
1398 logit(LOG_INFO,
1399 "%s: bad ND option length(0) (type = %d)",
1400 __func__, hdr->nd_opt_type);
1401 goto bad;
1402 }
1403 optlen = hdr->nd_opt_len << 3;
1404 if (optlen > limit) {
1405 logit(LOG_INFO, "%s: short option", __func__);
1406 goto bad;
1407 }
1408
1409 if (hdr->nd_opt_type > ND_OPT_MTU &&
1410 hdr->nd_opt_type != ND_OPT_RDNSS &&
1411 hdr->nd_opt_type != ND_OPT_DNSSL)
1412 {
1413 logit(LOG_INFO, "%s: unknown ND option(type %d)",
1414 __func__, hdr->nd_opt_type);
1415 continue;
1416 }
1417
1418 if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) {
1419 logit(LOG_INFO, "%s: unexpected ND option(type %d)",
1420 __func__, hdr->nd_opt_type);
1421 continue;
1422 }
1423
1424 /*
1425 * Option length check. Do it here for all fixed-length
1426 * options.
1427 */
1428 if ((hdr->nd_opt_type == ND_OPT_MTU &&
1429 (optlen != sizeof(struct nd_opt_mtu))) ||
1430 ((hdr->nd_opt_type == ND_OPT_PREFIX_INFORMATION &&
1431 optlen != sizeof(struct nd_opt_prefix_info))) ||
1432 (hdr->nd_opt_type == ND_OPT_RDNSS &&
1433 ((optlen < (int)sizeof(struct nd_opt_rdnss) ||
1434 (optlen - sizeof(struct nd_opt_rdnss)) % 16 != 0))) ||
1435 (hdr->nd_opt_type == ND_OPT_DNSSL &&
1436 optlen < (int)sizeof(struct nd_opt_dnssl)))
1437 {
1438 logit(LOG_INFO, "%s: invalid option length",
1439 __func__);
1440 continue;
1441 }
1442
1443 switch (hdr->nd_opt_type) {
1444 case ND_OPT_TARGET_LINKADDR:
1445 case ND_OPT_REDIRECTED_HEADER:
1446 case ND_OPT_RDNSS:
1447 case ND_OPT_DNSSL:
1448 break; /* we don't care about these options */
1449 case ND_OPT_SOURCE_LINKADDR:
1450 case ND_OPT_MTU:
1451 if (ndopts->nd_opt_array[hdr->nd_opt_type]) {
1452 logit(LOG_INFO,
1453 "%s: duplicated ND option (type = %d)",
1454 __func__, hdr->nd_opt_type);
1455 }
1456 ndopts->nd_opt_array[hdr->nd_opt_type] = hdr;
1457 break;
1458 case ND_OPT_PREFIX_INFORMATION:
1459 {
1460 struct nd_optlist *pfxlist;
1461
1462 if (ndopts->nd_opts_pi == 0) {
1463 ndopts->nd_opts_pi =
1464 (struct nd_opt_prefix_info *)hdr;
1465 continue;
1466 }
1467 if ((pfxlist = malloc(sizeof(*pfxlist))) == NULL) {
1468 logit(LOG_ERR, "%s: can't allocate memory",
1469 __func__);
1470 goto bad;
1471 }
1472 pfxlist->opt = hdr;
1473 TAILQ_INSERT_TAIL(&ndopts->nd_opts_list, pfxlist, next);
1474
1475 break;
1476 }
1477 default: /* impossible */
1478 break;
1479 }
1480 }
1481
1482 return 0;
1483
1484 bad:
1485 free_ndopts(ndopts);
1486 return -1;
1487 }
1488
1489 static void
1490 free_ndopts(union nd_opts *ndopts)
1491 {
1492 struct nd_optlist *opt;
1493
1494 while ((opt = TAILQ_FIRST(&ndopts->nd_opts_list)) != NULL) {
1495 TAILQ_REMOVE(&ndopts->nd_opts_list, opt, next);
1496 free(opt);
1497 }
1498 }
1499
1500 void
1501 sock_open(void)
1502 {
1503 struct icmp6_filter filt;
1504 struct ipv6_mreq mreq;
1505 struct rainfo *ra;
1506 int on;
1507 /* XXX: should be max MTU attached to the node */
1508 static unsigned char answer[1500];
1509
1510 rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1511 CMSG_SPACE(sizeof(int));
1512 rcvcmsgbuf = malloc(rcvcmsgbuflen);
1513 if (rcvcmsgbuf == NULL) {
1514 logit(LOG_ERR, "%s: malloc: %m", __func__);
1515 exit(EXIT_FAILURE);
1516 }
1517
1518 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo));
1519 sndcmsgbuf = malloc(sndcmsgbuflen);
1520 if (sndcmsgbuf == NULL) {
1521 logit(LOG_ERR, "%s: malloc: %m", __func__);
1522 exit(EXIT_FAILURE);
1523 }
1524
1525 if ((sock = prog_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) {
1526 logit(LOG_ERR, "%s: socket: %m", __func__);
1527 exit(EXIT_FAILURE);
1528 }
1529
1530 /* RFC 4861 Section 4.2 */
1531 on = 255;
1532 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &on,
1533 sizeof(on)) == -1) {
1534 logit(LOG_ERR, "%s: IPV6_MULTICAST_HOPS: %m", __func__);
1535 exit(EXIT_FAILURE);
1536 }
1537 on = 255;
1538 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &on,
1539 sizeof(on)) == -1) {
1540 logit(LOG_ERR, "%s: IPV6_UNICAST_HOPS: %m", __func__);
1541 exit(EXIT_FAILURE);
1542 }
1543
1544 /* specify to tell receiving interface */
1545 on = 1;
1546 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
1547 sizeof(on)) == -1) {
1548 logit(LOG_ERR, "%s: IPV6_RECVPKTINFO: %m", __func__);
1549 exit(EXIT_FAILURE);
1550 }
1551
1552 on = 1;
1553 /* specify to tell value of hoplimit field of received IP6 hdr */
1554 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
1555 sizeof(on)) == -1) {
1556 logit(LOG_ERR, "%s: IPV6_RECVHOPLIMIT: %m", __func__);
1557 exit(EXIT_FAILURE);
1558 }
1559
1560 ICMP6_FILTER_SETBLOCKALL(&filt);
1561 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt);
1562 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
1563 if (accept_rr)
1564 ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt);
1565 if (prog_setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
1566 sizeof(filt)) == -1) {
1567 logit(LOG_ERR, "%s: IICMP6_FILTER: %m", __func__);
1568 exit(EXIT_FAILURE);
1569 }
1570
1571 /*
1572 * join all routers multicast address on each advertising interface.
1573 */
1574 if (inet_pton(AF_INET6, ALLROUTERS_LINK,
1575 mreq.ipv6mr_multiaddr.s6_addr) != 1)
1576 {
1577 logit(LOG_ERR, "%s: inet_pton failed(library bug?)",
1578 __func__);
1579 exit(EXIT_FAILURE);
1580 }
1581 TAILQ_FOREACH(ra, &ralist, next) {
1582 mreq.ipv6mr_interface = ra->ifindex;
1583 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq,
1584 sizeof(mreq)) == -1) {
1585 logit(LOG_ERR, "%s: IPV6_JOIN_GROUP(link) on %s: %m",
1586 __func__, ra->ifname);
1587 continue;
1588 }
1589 }
1590
1591 /*
1592 * When attending router renumbering, join all-routers site-local
1593 * multicast group.
1594 */
1595 if (accept_rr) {
1596 if (inet_pton(AF_INET6, ALLROUTERS_SITE,
1597 mreq.ipv6mr_multiaddr.s6_addr) != 1)
1598 {
1599 logit(LOG_ERR, "%s: inet_pton failed(library bug?)",
1600 __func__);
1601 exit(EXIT_FAILURE);
1602 }
1603 ra = TAILQ_FIRST(&ralist);
1604 if (mcastif) {
1605 if ((mreq.ipv6mr_interface = if_nametoindex(mcastif))
1606 == 0) {
1607 logit(LOG_ERR,
1608 "%s: invalid interface: %s",
1609 __func__, mcastif);
1610 exit(EXIT_FAILURE);
1611 }
1612 } else
1613 mreq.ipv6mr_interface = ra->ifindex;
1614 if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1615 &mreq, sizeof(mreq)) == -1) {
1616 logit(LOG_ERR,
1617 "%s: IPV6_JOIN_GROUP(site) on %s: %m",
1618 __func__,
1619 mcastif ? mcastif : ra->ifname);
1620 exit(EXIT_FAILURE);
1621 }
1622 }
1623
1624 /* initialize msghdr for receiving packets */
1625 rcviov[0].iov_base = answer;
1626 rcviov[0].iov_len = sizeof(answer);
1627 rcvmhdr.msg_name = &rcvfrom;
1628 rcvmhdr.msg_namelen = sizeof(rcvfrom);
1629 rcvmhdr.msg_iov = rcviov;
1630 rcvmhdr.msg_iovlen = 1;
1631 rcvmhdr.msg_control = rcvcmsgbuf;
1632 rcvmhdr.msg_controllen = rcvcmsgbuflen;
1633
1634 /* initialize msghdr for sending packets */
1635 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
1636 sndmhdr.msg_iov = sndiov;
1637 sndmhdr.msg_iovlen = 1;
1638 sndmhdr.msg_control = sndcmsgbuf;
1639 sndmhdr.msg_controllen = sndcmsgbuflen;
1640 }
1641
1642 /* open a routing socket to watch the routing table */
1643 static void
1644 rtsock_open(void)
1645 {
1646 #ifdef RO_MSGFILTER
1647 unsigned char msgfilter[] = {
1648 RTM_ADD, RTM_DELETE,
1649 RTM_NEWADDR, RTM_DELADDR,
1650 #ifdef RTM_IFANNOUNCE
1651 RTM_IFANNOUNCE,
1652 #endif
1653 RTM_IFINFO,
1654 };
1655 #endif
1656
1657 if ((rtsock = prog_socket(PF_ROUTE, SOCK_RAW, 0)) == -1) {
1658 logit(LOG_ERR, "%s: socket: %m", __func__);
1659 exit(EXIT_FAILURE);
1660 }
1661 #ifdef RO_MSGFILTER
1662 if (setsockopt(rtsock, PF_ROUTE, RO_MSGFILTER,
1663 &msgfilter, sizeof(msgfilter) == -1))
1664 logit(LOG_ERR, "%s: RO_MSGFILTER: %m", __func__);
1665 #endif
1666 }
1667
1668 struct rainfo *
1669 if_indextorainfo(unsigned int idx)
1670 {
1671 struct rainfo *rai;
1672
1673 TAILQ_FOREACH(rai, &ralist, next) {
1674 if (rai->ifindex == idx)
1675 return rai;
1676 }
1677
1678 return NULL; /* search failed */
1679 }
1680
1681 struct rainfo *
1682 ra_output(struct rainfo *rai, bool solicited)
1683 {
1684 int i;
1685 struct cmsghdr *cm;
1686 struct in6_pktinfo *pi;
1687 struct soliciter *sol;
1688
1689 if ((rai->ifflags & IFF_UP) == 0) {
1690 logit(LOG_DEBUG, "%s: %s is not up, skip sending RA",
1691 __func__, rai->ifname);
1692 return NULL;
1693 }
1694
1695 make_packet(rai); /* XXX: inefficient */
1696
1697 sndmhdr.msg_name = (void *)&sin6_linklocal_allnodes;
1698 sndmhdr.msg_iov[0].iov_base = (void *)rai->ra_data;
1699 sndmhdr.msg_iov[0].iov_len = rai->ra_datalen;
1700
1701 /* specify the outgoing interface */
1702 cm = CMSG_FIRSTHDR(&sndmhdr);
1703 cm->cmsg_level = IPPROTO_IPV6;
1704 cm->cmsg_type = IPV6_PKTINFO;
1705 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
1706 pi = (struct in6_pktinfo *)CMSG_DATA(cm);
1707 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/
1708 pi->ipi6_ifindex = rai->ifindex;
1709
1710 logit(LOG_DEBUG,
1711 "%s: send RA on %s, # of waitings = %d",
1712 __func__, rai->ifname, rai->waiting);
1713
1714 if (solicited) {
1715 /* unicast solicited RA's as per RFC 7772 */
1716 while ((sol = TAILQ_FIRST(&rai->soliciter)) != NULL) {
1717 sndmhdr.msg_name = (void *)&sol->addr;
1718 i = prog_sendmsg(sock, &sndmhdr, 0);
1719 if (i < 0 || (size_t)i != rai->ra_datalen) {
1720 if (i < 0) {
1721 logit(LOG_ERR,
1722 "%s: unicast sendmsg on %s: %m",
1723 __func__, rai->ifname);
1724 }
1725 }
1726 TAILQ_REMOVE(&rai->soliciter, sol, next);
1727 free(sol);
1728 }
1729
1730 /* reset waiting conter */
1731 rai->waiting = 0;
1732
1733 /* disable timer */
1734 rai->timer_sol->enabled = false;
1735
1736 return rai;
1737 }
1738
1739 i = prog_sendmsg(sock, &sndmhdr, 0);
1740 if (i < 0 || (size_t)i != rai->ra_datalen) {
1741 if (i < 0) {
1742 logit(LOG_ERR, "%s: sendmsg on %s: %m",
1743 __func__, rai->ifname);
1744 }
1745 }
1746
1747 if (rai->leaving_adv > 0) {
1748 if (--(rai->leaving_adv) == 0) {
1749 /* leaving for ourself means we're shutting down */
1750 if (rai->leaving_for == rai) {
1751 TAILQ_REMOVE(&ralist, rai, next);
1752 free_rainfo(rai);
1753 return NULL;
1754 }
1755 logit(LOG_DEBUG,
1756 "%s: expired RA,"
1757 " new config active for interface (%s)",
1758 __func__, rai->ifname);
1759 rai->leaving_for->timer = rtadvd_add_timer(ra_timeout,
1760 ra_timer_update,
1761 rai->leaving_for, rai->leaving_for);
1762 ra_timer_set_short_delay(rai->leaving_for, rai->timer);
1763 rai->leaving_for->leaving = NULL;
1764 free_rainfo(rai);
1765 return NULL;
1766 }
1767 }
1768
1769 /* update counter */
1770 if (rai->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS)
1771 rai->initcounter++;
1772 rai->raoutput++;
1773
1774 /* update timestamp */
1775 prog_clock_gettime(CLOCK_MONOTONIC, &rai->lastsent);
1776 return rai;
1777 }
1778
1779 /* process unsolicited RA timer */
1780 struct rtadvd_timer *
1781 ra_timeout(void *data)
1782 {
1783 struct rainfo *rai = (struct rainfo *)data;
1784
1785 logit(LOG_DEBUG,
1786 "%s: unsolicited RA timer on %s is expired",
1787 __func__, rai->ifname);
1788
1789 if (ra_output(rai, false))
1790 return rai->timer;
1791 return NULL;
1792 }
1793
1794 /* process solicited RA timer */
1795 struct rtadvd_timer *
1796 ra_timeout_sol(void *data)
1797 {
1798 struct rainfo *rai = (struct rainfo *)data;
1799
1800 logit(LOG_DEBUG,
1801 "%s: solicited RA timer on %s is expired",
1802 __func__, rai->ifname);
1803
1804 if (ra_output(rai, true))
1805 return rai->timer_sol;
1806 return NULL;
1807 }
1808
1809 /* update RA timer */
1810 void
1811 ra_timer_update(void *data, struct timespec *tm)
1812 {
1813 struct rainfo *rai = (struct rainfo *)data;
1814 long interval;
1815
1816 /*
1817 * Whenever a multicast advertisement is sent from an interface,
1818 * the timer is reset to a uniformly-distributed random value
1819 * between the interface's configured MinRtrAdvInterval and
1820 * MaxRtrAdvInterval (RFC2461 6.2.4).
1821 */
1822 interval = rai->mininterval;
1823 if (rai->mininterval != rai->maxinterval)
1824 interval += arc4random() % (rai->maxinterval-rai->mininterval);
1825
1826 /*
1827 * For the first few advertisements (up to
1828 * MAX_INITIAL_RTR_ADVERTISEMENTS), if the randomly chosen interval
1829 * is greater than MAX_INITIAL_RTR_ADVERT_INTERVAL, the timer
1830 * SHOULD be set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead.
1831 * (RFC-2461 6.2.4)
1832 */
1833 if (rai->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS &&
1834 interval > MAX_INITIAL_RTR_ADVERT_INTERVAL)
1835 interval = MAX_INITIAL_RTR_ADVERT_INTERVAL;
1836
1837 tm->tv_sec = interval;
1838 tm->tv_nsec = 0;
1839
1840 logit(LOG_DEBUG,
1841 "%s: RA timer on %s is set to %jd:%jd",
1842 __func__, rai->ifname,
1843 (intmax_t)tm->tv_sec, (intmax_t)tm->tv_nsec);
1844 }
1845
1846 void
1847 logit(int level, const char *fmt, ...)
1848 {
1849 va_list ap;
1850 char *buf;
1851
1852 va_start(ap, fmt);
1853 if (!Dflag) {
1854 vsyslog(level, fmt, ap);
1855 va_end(ap);
1856 return;
1857 }
1858
1859 vfprintf(stderr, buf = expandm(fmt, "\n"), ap);
1860 if (buf != fmt)
1861 free(buf);
1862 va_end(ap);
1863 }
1864