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