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