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