summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtadvd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/rtadvd')
-rw-r--r--usr.sbin/rtadvd/Makefile26
-rw-r--r--usr.sbin/rtadvd/Makefile.depend20
-rw-r--r--usr.sbin/rtadvd/advcap.c436
-rw-r--r--usr.sbin/rtadvd/advcap.h46
-rw-r--r--usr.sbin/rtadvd/config.c1541
-rw-r--r--usr.sbin/rtadvd/config.h53
-rw-r--r--usr.sbin/rtadvd/control.c492
-rw-r--r--usr.sbin/rtadvd/control.h74
-rw-r--r--usr.sbin/rtadvd/control_client.c133
-rw-r--r--usr.sbin/rtadvd/control_client.h30
-rw-r--r--usr.sbin/rtadvd/control_server.c752
-rw-r--r--usr.sbin/rtadvd/control_server.h42
-rw-r--r--usr.sbin/rtadvd/if.c748
-rw-r--r--usr.sbin/rtadvd/if.h61
-rw-r--r--usr.sbin/rtadvd/pathnames.h6
-rw-r--r--usr.sbin/rtadvd/rrenum.c502
-rw-r--r--usr.sbin/rtadvd/rrenum.h34
-rw-r--r--usr.sbin/rtadvd/rtadvd.8242
-rw-r--r--usr.sbin/rtadvd/rtadvd.c1914
-rw-r--r--usr.sbin/rtadvd/rtadvd.conf22
-rw-r--r--usr.sbin/rtadvd/rtadvd.conf.5530
-rw-r--r--usr.sbin/rtadvd/rtadvd.h298
-rw-r--r--usr.sbin/rtadvd/timer.c199
-rw-r--r--usr.sbin/rtadvd/timer.h52
-rw-r--r--usr.sbin/rtadvd/timer_subr.c91
-rw-r--r--usr.sbin/rtadvd/timer_subr.h59
26 files changed, 0 insertions, 8403 deletions
diff --git a/usr.sbin/rtadvd/Makefile b/usr.sbin/rtadvd/Makefile
deleted file mode 100644
index 5d627e5..0000000
--- a/usr.sbin/rtadvd/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) 1996 WIDE Project. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modifications, are permitted provided that the above copyright notice
-# and this paragraph are duplicated in all such forms and that any
-# documentation, advertising materials, and other materials related to
-# such distribution and use acknowledge that the software was developed
-# by the WIDE Project, Japan. The name of the Project may not be used to
-# endorse or promote products derived from this software without
-# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
-# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
-# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE.
-#
-# $FreeBSD$
-
-PROG= rtadvd
-MAN= rtadvd.conf.5 rtadvd.8
-SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c timer_subr.c \
- control.c control_server.c
-
-LIBADD= util
-
-WARNS?= 1
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/rtadvd/Makefile.depend b/usr.sbin/rtadvd/Makefile.depend
deleted file mode 100644
index 7de116d..0000000
--- a/usr.sbin/rtadvd/Makefile.depend
+++ /dev/null
@@ -1,20 +0,0 @@
-# $FreeBSD$
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- gnu/lib/csu \
- gnu/lib/libgcc \
- include \
- include/arpa \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
- lib/libcompiler_rt \
- lib/libutil \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.sbin/rtadvd/advcap.c b/usr.sbin/rtadvd/advcap.c
deleted file mode 100644
index 542e066..0000000
--- a/usr.sbin/rtadvd/advcap.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: advcap.c,v 1.11 2003/05/19 09:46:50 keiichi Exp $ */
-
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * remcap - routines for dealing with the remote host data base
- *
- * derived from termcap
- */
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include "pathnames.h"
-
-#ifndef BUFSIZ
-#define BUFSIZ 1024
-#endif
-#define MAXHOP 32 /* max number of tc= indirections */
-
-#define tgetent agetent
-#define tnchktc anchktc
-#define tnamatch anamatch
-#define tgetnum agetnum
-#define tgetflag agetflag
-#define tgetstr agetstr
-
-#if 0
-#define V_TERMCAP "REMOTE"
-#define V_TERM "HOST"
-#endif
-
-/*
- * termcap - routines for dealing with the terminal capability data base
- *
- * BUG: Should use a "last" pointer in tbuf, so that searching
- * for capabilities alphabetically would not be a n**2/2
- * process when large numbers of capabilities are given.
- * Note: If we add a last pointer now we will screw up the
- * tc capability. We really should compile termcap.
- *
- * Essentially all the work here is scanning and decoding escapes
- * in string capabilities. We don't use stdio because the editor
- * doesn't, and because living w/o it is not hard.
- */
-
-static char *tbuf;
-static int hopcount; /* detect infinite loops in termcap, init 0 */
-
-extern const char *conffile;
-
-int tgetent(char *, char *);
-int getent(char *, char *, const char *);
-int tnchktc(void);
-int tnamatch(char *);
-static char *tskip(char *);
-int64_t tgetnum(char *);
-int tgetflag(char *);
-char *tgetstr(char *, char **);
-static char *tdecode(char *, char **);
-
-/*
- * Get an entry for terminal name in buffer bp,
- * from the termcap file. Parse is very rudimentary;
- * we just notice escaped newlines.
- */
-int
-tgetent(char *bp, char *name)
-{
- return (getent(bp, name, conffile));
-}
-
-int
-getent(char *bp, char *name, const char *cfile)
-{
- int c;
- int i = 0, cnt = 0;
- char ibuf[BUFSIZ];
- char *cp;
- int tf;
-
- tbuf = bp;
- tf = 0;
- /*
- * TERMCAP can have one of two things in it. It can be the
- * name of a file to use instead of /etc/termcap. In this
- * case it better start with a "/". Or it can be an entry to
- * use so we don't have to read the file. In this case it
- * has to already have the newlines crunched out.
- */
- if (cfile && *cfile)
- tf = open(cfile, O_RDONLY);
-
- if (tf < 0) {
- syslog(LOG_INFO,
- "<%s> open: %s", __func__, strerror(errno));
- return (-2);
- }
- for (;;) {
- cp = bp;
- for (;;) {
- if (i == cnt) {
- cnt = read(tf, ibuf, BUFSIZ);
- if (cnt <= 0) {
- close(tf);
- return (0);
- }
- i = 0;
- }
- c = ibuf[i++];
- if (c == '\n') {
- if (cp > bp && cp[-1] == '\\') {
- cp--;
- continue;
- }
- break;
- }
- if (cp >= bp + BUFSIZ - 1) {
- write(STDERR_FILENO, "Remcap entry too long\n",
- 22);
- break;
- } else
- *cp++ = c;
- }
- *cp = 0;
-
- /*
- * The real work for the match.
- */
- if (tnamatch(name)) {
- close(tf);
- return (tnchktc());
- }
- }
-}
-
-/*
- * tnchktc: check the last entry, see if it's tc=xxx. If so,
- * recursively find xxx and append that entry (minus the names)
- * to take the place of the tc=xxx entry. This allows termcap
- * entries to say "like an HP2621 but doesn't turn on the labels".
- * Note that this works because of the left to right scan.
- */
-int
-tnchktc(void)
-{
- char *p, *q;
- char tcname[16]; /* name of similar terminal */
- char tcbuf[BUFSIZ];
- char *holdtbuf = tbuf;
- int l;
-
- p = tbuf + strlen(tbuf) - 2; /* before the last colon */
- while (*--p != ':')
- if (p < tbuf) {
- write(STDERR_FILENO, "Bad remcap entry\n", 18);
- return (0);
- }
- p++;
- /* p now points to beginning of last field */
- if (p[0] != 't' || p[1] != 'c')
- return (1);
- strlcpy(tcname, p + 3, sizeof tcname);
- q = tcname;
- while (*q && *q != ':')
- q++;
- *q = 0;
- if (++hopcount > MAXHOP) {
- write(STDERR_FILENO, "Infinite tc= loop\n", 18);
- return (0);
- }
- if (getent(tcbuf, tcname, conffile) != 1) {
- return (0);
- }
- for (q = tcbuf; *q++ != ':'; )
- ;
- l = p - holdtbuf + strlen(q);
- if (l > BUFSIZ) {
- write(STDERR_FILENO, "Remcap entry too long\n", 23);
- q[BUFSIZ - (p-holdtbuf)] = 0;
- }
- strcpy(p, q);
- tbuf = holdtbuf;
- return (1);
-}
-
-/*
- * Tnamatch deals with name matching. The first field of the termcap
- * entry is a sequence of names separated by |'s, so we compare
- * against each such name. The normal : terminator after the last
- * name (before the first field) stops us.
- */
-int
-tnamatch(char *np)
-{
- char *Np, *Bp;
-
- Bp = tbuf;
- if (*Bp == '#')
- return (0);
- for (;;) {
- for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
- continue;
- if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
- return (1);
- while (*Bp && *Bp != ':' && *Bp != '|')
- Bp++;
- if (*Bp == 0 || *Bp == ':')
- return (0);
- Bp++;
- }
-}
-
-/*
- * Skip to the next field. Notice that this is very dumb, not
- * knowing about \: escapes or any such. If necessary, :'s can be put
- * into the termcap file in octal.
- */
-static char *
-tskip(char *bp)
-{
- int dquote;
-
- dquote = 0;
- while (*bp) {
- switch (*bp) {
- case ':':
- if (!dquote)
- goto breakbreak;
- else
- bp++;
- break;
- case '\\':
- bp++;
- if (isdigit(*bp)) {
- while (isdigit(*bp++))
- ;
- } else
- bp++;
- case '"':
- dquote = (dquote ? 1 : 0);
- bp++;
- break;
- default:
- bp++;
- break;
- }
- }
-breakbreak:
- if (*bp == ':')
- bp++;
- return (bp);
-}
-
-/*
- * Return the (numeric) option id.
- * Numeric options look like
- * li#80
- * i.e. the option string is separated from the numeric value by
- * a # character. If the option is not found we return -1.
- * Note that we handle octal numbers beginning with 0.
- */
-int64_t
-tgetnum(char *id)
-{
- int64_t i;
- int base;
- char *bp = tbuf;
-
- for (;;) {
- bp = tskip(bp);
- if (*bp == 0)
- return (-1);
- if (strncmp(bp, id, strlen(id)) != 0)
- continue;
- bp += strlen(id);
- if (*bp == '@')
- return (-1);
- if (*bp != '#')
- continue;
- bp++;
- base = 10;
- if (*bp == '0')
- base = 8;
- i = 0;
- while (isdigit(*bp))
- i *= base, i += *bp++ - '0';
- return (i);
- }
-}
-
-/*
- * Handle a flag option.
- * Flag options are given "naked", i.e. followed by a : or the end
- * of the buffer. Return 1 if we find the option, or 0 if it is
- * not given.
- */
-int
-tgetflag(char *id)
-{
- char *bp = tbuf;
-
- for (;;) {
- bp = tskip(bp);
- if (!*bp)
- return (0);
- if (strncmp(bp, id, strlen(id)) == 0) {
- bp += strlen(id);
- if (!*bp || *bp == ':')
- return (1);
- else if (*bp == '@')
- return (0);
- }
- }
-}
-
-/*
- * Get a string valued option.
- * These are given as
- * cl=^Z
- * Much decoding is done on the strings, and the strings are
- * placed in area, which is a ref parameter which is updated.
- * No checking on area overflow.
- */
-char *
-tgetstr(char *id, char **area)
-{
- char *bp = tbuf;
-
- for (;;) {
- bp = tskip(bp);
- if (!*bp)
- return (0);
- if (strncmp(bp, id, strlen(id)) != 0)
- continue;
- bp += strlen(id);
- if (*bp == '@')
- return (0);
- if (*bp != '=')
- continue;
- bp++;
- return (tdecode(bp, area));
- }
-}
-
-/*
- * Tdecode does the grung work to decode the
- * string capability escapes.
- */
-static char *
-tdecode(char *str, char **area)
-{
- char *cp;
- int c;
- const char *dp;
- int i;
- char term;
-
- term = ':';
- cp = *area;
-again:
- if (*str == '"') {
- term = '"';
- str++;
- }
- while ((c = *str++) && c != term) {
- switch (c) {
-
- case '^':
- c = *str++ & 037;
- break;
-
- case '\\':
- dp = "E\033^^\\\\::n\nr\rt\tb\bf\f\"\"";
- c = *str++;
-nextc:
- if (*dp++ == c) {
- c = *dp++;
- break;
- }
- dp++;
- if (*dp)
- goto nextc;
- if (isdigit(c)) {
- c -= '0', i = 2;
- do
- c <<= 3, c |= *str++ - '0';
- while (--i && isdigit(*str));
- }
- break;
- }
- *cp++ = c;
- }
- if (c == term && term != ':') {
- term = ':';
- goto again;
- }
- *cp++ = 0;
- str = *area;
- *area = cp;
- return (str);
-}
diff --git a/usr.sbin/rtadvd/advcap.h b/usr.sbin/rtadvd/advcap.h
deleted file mode 100644
index 3cc124a..0000000
--- a/usr.sbin/rtadvd/advcap.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: advcap.h,v 1.5 2003/06/09 05:40:54 t-momose Exp $ */
-
-/*
- * Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* Based on Id: termcap.h,v 1.8 1996/09/10 12:42:10 peter Exp */
-
-#ifndef _ADVCAP_H_
-#define _ADVCAP_H_
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-extern int agetent(char *, const char *);
-extern int agetflag(const char *);
-extern int64_t agetnum(const char *);
-extern char *agetstr(const char *, char **);
-
-__END_DECLS
-
-#endif /* _ADVCAP_H_ */
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c
deleted file mode 100644
index db16e33..0000000
--- a/usr.sbin/rtadvd/config.c
+++ /dev/null
@@ -1,1541 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: config.c,v 1.84 2003/08/05 12:34:23 itojun Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/route.h>
-#include <net/if_dl.h>
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
-#include <netinet6/nd6.h>
-
-#include <arpa/inet.h>
-
-#include <stdio.h>
-#include <syslog.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <netdb.h>
-#include <string.h>
-#include <search.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#include <ifaddrs.h>
-
-#include "rtadvd.h"
-#include "advcap.h"
-#include "timer.h"
-#include "if.h"
-#include "config.h"
-
-/* label of tcapcode + number + domain name + zero octet */
-static char entbuf[10 + 3 + NI_MAXHOST + 1];
-static char oentbuf[10 + 3 + NI_MAXHOST + 1];
-static char abuf[DNAME_LABELENC_MAXLEN];
-
-static time_t prefix_timo = (60 * 120); /* 2 hours.
- * XXX: should be configurable. */
-
-static struct rtadvd_timer *prefix_timeout(void *);
-static void makeentry(char *, size_t, int, const char *);
-static ssize_t dname_labelenc(char *, const char *);
-
-/* Encode domain name label encoding in RFC 1035 Section 3.1 */
-static ssize_t
-dname_labelenc(char *dst, const char *src)
-{
- char *dst_origin;
- char *p;
- size_t len;
-
- dst_origin = dst;
- len = strlen(src);
-
- if (len + len / 64 + 1 + 1 > DNAME_LABELENC_MAXLEN)
- return (-1);
- /* Length fields per 63 octets + '\0' (<= DNAME_LABELENC_MAXLEN) */
- memset(dst, 0, len + len / 64 + 1 + 1);
-
- syslog(LOG_DEBUG, "<%s> labelenc = %s", __func__, src);
- while (src && (len = strlen(src)) != 0) {
- /* Put a length field with 63 octet limitation first. */
- p = strchr(src, '.');
- if (p == NULL)
- *dst = len = MIN(63, len);
- else
- *dst = len = MIN(63, p - src);
- if (dst + 1 + len < dst_origin + DNAME_LABELENC_MAXLEN)
- dst++;
- else
- return (-1);
- /* Copy 63 octets at most. */
- memcpy(dst, src, len);
- dst += len;
- if (p == NULL) /* the last label */
- break;
- src = p + 1;
- }
- /* Always need a 0-length label at the tail. */
- *dst++ = '\0';
-
- syslog(LOG_DEBUG, "<%s> labellen = %td", __func__, dst - dst_origin);
- return (dst - dst_origin);
-}
-
-#define MUSTHAVE(var, cap) \
- do { \
- int64_t t; \
- if ((t = agetnum(cap)) < 0) { \
- fprintf(stderr, "rtadvd: need %s for interface %s\n", \
- cap, intface); \
- exit(1); \
- } \
- var = t; \
- } while (0)
-
-#define MAYHAVE(var, cap, def) \
- do { \
- if ((var = agetnum(cap)) < 0) \
- var = def; \
- } while (0)
-
-int
-loadconfig_index(int idx)
-{
- char ifname[IFNAMSIZ];
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (if_indextoname(idx, ifname) != NULL)
- return (loadconfig_ifname(ifname));
- else
- return (1);
-}
-
-int
-loadconfig_ifname(char *ifname)
-{
- struct ifinfo *ifi;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- update_ifinfo(&ifilist, UPDATE_IFINFO_ALL);
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- /* NULL means all IFs will be processed. */
- if (ifname != NULL &&
- strcmp(ifi->ifi_ifname, ifname) != 0)
- continue;
-
- if (!ifi->ifi_persist) {
- syslog(LOG_INFO,
- "<%s> %s is not a target interface. "
- "Ignored at this moment.", __func__,
- ifi->ifi_ifname);
- continue;
-
- }
- if (ifi->ifi_ifindex == 0) {
- syslog(LOG_ERR,
- "<%s> %s not found. "
- "Ignored at this moment.", __func__,
- ifi->ifi_ifname);
- continue;
- }
- if (getconfig(ifi) == NULL) {
- syslog(LOG_ERR,
- "<%s> invalid configuration for %s. "
- "Ignored at this moment.", __func__,
- ifi->ifi_ifname);
- continue;
- }
- }
- return (0);
-}
-
-int
-rm_ifinfo_index(int idx)
-{
- struct ifinfo *ifi;
-
- ifi = if_indextoifinfo(idx);
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s>: ifinfo not found (idx=%d)",
- __func__, idx);
- return (-1);
- }
-
- return (rm_ifinfo(ifi));
-}
-
-int
-rm_ifinfo(struct ifinfo *ifi)
-{
- int error;
-
- syslog(LOG_DEBUG, "<%s> enter (%s).", __func__, ifi->ifi_ifname);
- switch (ifi->ifi_state) {
- case IFI_STATE_UNCONFIGURED:
- return (0);
- break;
- default:
- ifi->ifi_state = IFI_STATE_UNCONFIGURED;
- syslog(LOG_DEBUG,
- "<%s> ifname=%s marked as UNCONFIGURED.",
- __func__, ifi->ifi_ifname);
-
- /* XXX: No MC leaving here because index is disappeared */
-
- /* Inactivate timer */
- rtadvd_remove_timer(ifi->ifi_ra_timer);
- ifi->ifi_ra_timer = NULL;
- break;
- }
-
- /* clean up ifi */
- if (!ifi->ifi_persist) {
- TAILQ_REMOVE(&ifilist, ifi, ifi_next);
- syslog(LOG_DEBUG, "<%s>: ifinfo (idx=%d) removed.",
- __func__, ifi->ifi_ifindex);
- } else {
- /* recreate an empty entry */
- update_persist_ifinfo(&ifilist, ifi->ifi_ifname);
- syslog(LOG_DEBUG, "<%s>: ifname=%s is persistent.",
- __func__, ifi->ifi_ifname);
- }
-
- /* clean up rai if any */
- switch (ifi->ifi_state) {
- case IFI_STATE_CONFIGURED:
- if (ifi->ifi_rainfo != NULL) {
- error = rm_rainfo(ifi->ifi_rainfo);
- if (error)
- return (error);
- ifi->ifi_rainfo = NULL;
- }
- break;
- case IFI_STATE_TRANSITIVE:
- if (ifi->ifi_rainfo == ifi->ifi_rainfo_trans) {
- if (ifi->ifi_rainfo != NULL) {
- error = rm_rainfo(ifi->ifi_rainfo);
- if (error)
- return (error);
- ifi->ifi_rainfo = NULL;
- ifi->ifi_rainfo_trans = NULL;
- }
- } else {
- if (ifi->ifi_rainfo != NULL) {
- error = rm_rainfo(ifi->ifi_rainfo);
- if (error)
- return (error);
- ifi->ifi_rainfo = NULL;
- }
- if (ifi->ifi_rainfo_trans != NULL) {
- error = rm_rainfo(ifi->ifi_rainfo_trans);
- if (error)
- return (error);
- ifi->ifi_rainfo_trans = NULL;
- }
- }
- }
-
- syslog(LOG_DEBUG, "<%s> leave (%s).", __func__, ifi->ifi_ifname);
- if (!ifi->ifi_persist)
- free(ifi);
- return (0);
-}
-
-int
-rm_rainfo(struct rainfo *rai)
-{
- struct prefix *pfx;
- struct soliciter *sol;
- struct rdnss *rdn;
- struct rdnss_addr *rdna;
- struct dnssl *dns;
- struct rtinfo *rti;
-
- syslog(LOG_DEBUG, "<%s>: enter", __func__);
-
- TAILQ_REMOVE(&railist, rai, rai_next);
- if (rai->rai_ifinfo != NULL)
- syslog(LOG_DEBUG, "<%s>: rainfo (idx=%d) removed.",
- __func__, rai->rai_ifinfo->ifi_ifindex);
-
- if (rai->rai_ra_data != NULL)
- free(rai->rai_ra_data);
-
- while ((pfx = TAILQ_FIRST(&rai->rai_prefix)) != NULL)
- delete_prefix(pfx);
- while ((sol = TAILQ_FIRST(&rai->rai_soliciter)) != NULL) {
- TAILQ_REMOVE(&rai->rai_soliciter, sol, sol_next);
- free(sol);
- }
- while ((rdn = TAILQ_FIRST(&rai->rai_rdnss)) != NULL) {
- TAILQ_REMOVE(&rai->rai_rdnss, rdn, rd_next);
- while ((rdna = TAILQ_FIRST(&rdn->rd_list)) != NULL) {
- TAILQ_REMOVE(&rdn->rd_list, rdna, ra_next);
- free(rdna);
- }
- free(rdn);
- }
- while ((dns = TAILQ_FIRST(&rai->rai_dnssl)) != NULL) {
- TAILQ_REMOVE(&rai->rai_dnssl, dns, dn_next);
- free(dns);
- }
- while ((rti = TAILQ_FIRST(&rai->rai_route)) != NULL) {
- TAILQ_REMOVE(&rai->rai_route, rti, rti_next);
- free(rti);
- }
- free(rai);
- syslog(LOG_DEBUG, "<%s>: leave", __func__);
-
- return (0);
-}
-
-struct ifinfo *
-getconfig(struct ifinfo *ifi)
-{
- int stat, i;
- int error;
- char tbuf[BUFSIZ];
- struct rainfo *rai;
- struct rainfo *rai_old;
- int32_t val;
- int64_t val64;
- char buf[BUFSIZ];
- char *bp = buf;
- char *addr, *flagstr;
-
- if (ifi == NULL) /* if does not exist */
- return (NULL);
-
- if (ifi->ifi_state == IFI_STATE_TRANSITIVE &&
- ifi->ifi_rainfo == NULL) {
- syslog(LOG_INFO, "<%s> %s is shutting down. Skipped.",
- __func__, ifi->ifi_ifname);
- return (NULL);
- }
-
- if ((stat = agetent(tbuf, ifi->ifi_ifname)) <= 0) {
- memset(tbuf, 0, sizeof(tbuf));
- syslog(LOG_INFO,
- "<%s> %s isn't defined in the configuration file"
- " or the configuration file doesn't exist."
- " Treat it as default",
- __func__, ifi->ifi_ifname);
- }
-
- ELM_MALLOC(rai, exit(1));
- TAILQ_INIT(&rai->rai_prefix);
- TAILQ_INIT(&rai->rai_route);
- TAILQ_INIT(&rai->rai_rdnss);
- TAILQ_INIT(&rai->rai_dnssl);
- TAILQ_INIT(&rai->rai_soliciter);
- rai->rai_ifinfo = ifi;
-
- /* gather on-link prefixes from the network interfaces. */
- if (agetflag("noifprefix"))
- rai->rai_advifprefix = 0;
- else
- rai->rai_advifprefix = 1;
-
- /* get interface information */
- if (agetflag("nolladdr"))
- rai->rai_advlinkopt = 0;
- else
- rai->rai_advlinkopt = 1;
- if (rai->rai_advlinkopt) {
- if (ifi->ifi_sdl.sdl_type == 0) {
- syslog(LOG_ERR,
- "<%s> can't get information of %s",
- __func__, ifi->ifi_ifname);
- goto getconfig_free_rai;
- }
- }
-
- /*
- * set router configuration variables.
- */
- MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL);
- if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) {
- syslog(LOG_ERR,
- "<%s> maxinterval (%" PRIu32 ") on %s is invalid "
- "(must be between %u and %u)", __func__, val,
- ifi->ifi_ifname, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
- goto getconfig_free_rai;
- }
- rai->rai_maxinterval = (uint16_t)val;
-
- MAYHAVE(val, "mininterval", rai->rai_maxinterval/3);
- if ((uint16_t)val < MIN_MININTERVAL ||
- (uint16_t)val > (rai->rai_maxinterval * 3) / 4) {
- syslog(LOG_ERR,
- "<%s> mininterval (%" PRIu32 ") on %s is invalid "
- "(must be between %d and %d)",
- __func__, val, ifi->ifi_ifname, MIN_MININTERVAL,
- (rai->rai_maxinterval * 3) / 4);
- goto getconfig_free_rai;
- }
- rai->rai_mininterval = (uint16_t)val;
-
- MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
- rai->rai_hoplimit = val & 0xff;
-
- if ((flagstr = (char *)agetstr("raflags", &bp))) {
- val = 0;
- if (strchr(flagstr, 'm'))
- val |= ND_RA_FLAG_MANAGED;
- if (strchr(flagstr, 'o'))
- val |= ND_RA_FLAG_OTHER;
- if (strchr(flagstr, 'h'))
- val |= ND_RA_FLAG_RTPREF_HIGH;
- if (strchr(flagstr, 'l')) {
- if ((val & ND_RA_FLAG_RTPREF_HIGH)) {
- syslog(LOG_ERR, "<%s> the \'h\' and \'l\'"
- " router flags are exclusive", __func__);
- goto getconfig_free_rai;
- }
- val |= ND_RA_FLAG_RTPREF_LOW;
- }
- } else
- MAYHAVE(val, "raflags", 0);
-
- rai->rai_managedflg = val & ND_RA_FLAG_MANAGED;
- rai->rai_otherflg = val & ND_RA_FLAG_OTHER;
-#ifndef ND_RA_FLAG_RTPREF_MASK
-#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
-#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
-#endif
- rai->rai_rtpref = val & ND_RA_FLAG_RTPREF_MASK;
- if (rai->rai_rtpref == ND_RA_FLAG_RTPREF_RSV) {
- syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s",
- __func__, rai->rai_rtpref, ifi->ifi_ifname);
- goto getconfig_free_rai;
- }
-
- MAYHAVE(val, "rltime", rai->rai_maxinterval * 3);
- if ((uint16_t)val && ((uint16_t)val < rai->rai_maxinterval ||
- (uint16_t)val > MAXROUTERLIFETIME)) {
- syslog(LOG_ERR,
- "<%s> router lifetime (%" PRIu32 ") on %s is invalid "
- "(must be 0 or between %d and %d)",
- __func__, val, ifi->ifi_ifname, rai->rai_maxinterval,
- MAXROUTERLIFETIME);
- goto getconfig_free_rai;
- }
- rai->rai_lifetime = val & 0xffff;
-
- MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME);
- if (val < 0 || val > MAXREACHABLETIME) {
- syslog(LOG_ERR,
- "<%s> reachable time (%" PRIu32 ") on %s is invalid "
- "(must be no greater than %d)",
- __func__, val, ifi->ifi_ifname, MAXREACHABLETIME);
- goto getconfig_free_rai;
- }
- rai->rai_reachabletime = (uint32_t)val;
-
- MAYHAVE(val64, "retrans", DEF_ADVRETRANSTIMER);
- if (val64 < 0 || val64 > 0xffffffff) {
- syslog(LOG_ERR, "<%s> retrans time (%" PRIu64 ") on %s out of range",
- __func__, val64, ifi->ifi_ifname);
- goto getconfig_free_rai;
- }
- rai->rai_retranstimer = (uint32_t)val64;
-
- if (agetnum("hapref") != -1 || agetnum("hatime") != -1) {
- syslog(LOG_ERR,
- "<%s> mobile-ip6 configuration not supported",
- __func__);
- goto getconfig_free_rai;
- }
- /* prefix information */
-
- /*
- * This is an implementation specific parameter to consider
- * link propagation delays and poorly synchronized clocks when
- * checking consistency of advertised lifetimes.
- */
- MAYHAVE(val, "clockskew", 0);
- rai->rai_clockskew = val;
-
- rai->rai_pfxs = 0;
- for (i = -1; i < MAXPREFIX; i++) {
- struct prefix *pfx;
-
- makeentry(entbuf, sizeof(entbuf), i, "addr");
- addr = (char *)agetstr(entbuf, &bp);
- if (addr == NULL)
- continue;
-
- /* allocate memory to store prefix information */
- ELM_MALLOC(pfx, exit(1));
- pfx->pfx_rainfo = rai;
- pfx->pfx_origin = PREFIX_FROM_CONFIG;
-
- if (inet_pton(AF_INET6, addr, &pfx->pfx_prefix) != 1) {
- syslog(LOG_ERR,
- "<%s> inet_pton failed for %s",
- __func__, addr);
- goto getconfig_free_pfx;
- }
- if (IN6_IS_ADDR_MULTICAST(&pfx->pfx_prefix)) {
- syslog(LOG_ERR,
- "<%s> multicast prefix (%s) must "
- "not be advertised on %s",
- __func__, addr, ifi->ifi_ifname);
- goto getconfig_free_pfx;
- }
- if (IN6_IS_ADDR_LINKLOCAL(&pfx->pfx_prefix))
- syslog(LOG_NOTICE,
- "<%s> link-local prefix (%s) will be"
- " advertised on %s",
- __func__, addr, ifi->ifi_ifname);
-
- makeentry(entbuf, sizeof(entbuf), i, "prefixlen");
- MAYHAVE(val, entbuf, 64);
- if (val < 0 || val > 128) {
- syslog(LOG_ERR, "<%s> prefixlen (%" PRIu32 ") for %s "
- "on %s out of range",
- __func__, val, addr, ifi->ifi_ifname);
- goto getconfig_free_pfx;
- }
- pfx->pfx_prefixlen = (int)val;
-
- makeentry(entbuf, sizeof(entbuf), i, "pinfoflags");
- if ((flagstr = (char *)agetstr(entbuf, &bp))) {
- val = 0;
- if (strchr(flagstr, 'l'))
- val |= ND_OPT_PI_FLAG_ONLINK;
- if (strchr(flagstr, 'a'))
- val |= ND_OPT_PI_FLAG_AUTO;
- } else {
- MAYHAVE(val, entbuf,
- (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO));
- }
- pfx->pfx_onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
- pfx->pfx_autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
-
- makeentry(entbuf, sizeof(entbuf), i, "vltime");
- MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
- if (val64 < 0 || val64 > 0xffffffff) {
- syslog(LOG_ERR, "<%s> vltime (%" PRIu64 ") for "
- "%s/%d on %s is out of range",
- __func__, val64,
- addr, pfx->pfx_prefixlen, ifi->ifi_ifname);
- goto getconfig_free_pfx;
- }
- pfx->pfx_validlifetime = (uint32_t)val64;
-
- makeentry(entbuf, sizeof(entbuf), i, "vltimedecr");
- if (agetflag(entbuf)) {
- struct timespec now;
-
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- pfx->pfx_vltimeexpire =
- now.tv_sec + pfx->pfx_validlifetime;
- }
-
- makeentry(entbuf, sizeof(entbuf), i, "pltime");
- MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME);
- if (val64 < 0 || val64 > 0xffffffff) {
- syslog(LOG_ERR,
- "<%s> pltime (%" PRIu64 ") for %s/%d on %s "
- "is out of range",
- __func__, val64,
- addr, pfx->pfx_prefixlen, ifi->ifi_ifname);
- goto getconfig_free_pfx;
- }
- pfx->pfx_preflifetime = (uint32_t)val64;
-
- makeentry(entbuf, sizeof(entbuf), i, "pltimedecr");
- if (agetflag(entbuf)) {
- struct timespec now;
-
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- pfx->pfx_pltimeexpire =
- now.tv_sec + pfx->pfx_preflifetime;
- }
- /* link into chain */
- TAILQ_INSERT_TAIL(&rai->rai_prefix, pfx, pfx_next);
- rai->rai_pfxs++;
- continue;
-getconfig_free_pfx:
- free(pfx);
- }
- if (rai->rai_advifprefix && rai->rai_pfxs == 0)
- get_prefix(rai);
-
- MAYHAVE(val64, "mtu", 0);
- if (val < 0 || val64 > 0xffffffff) {
- syslog(LOG_ERR,
- "<%s> mtu (%" PRIu64 ") on %s out of range",
- __func__, val64, ifi->ifi_ifname);
- goto getconfig_free_rai;
- }
- rai->rai_linkmtu = (uint32_t)val64;
- if (rai->rai_linkmtu == 0) {
- char *mtustr;
-
- if ((mtustr = (char *)agetstr("mtu", &bp)) &&
- strcmp(mtustr, "auto") == 0)
- rai->rai_linkmtu = ifi->ifi_phymtu;
- }
- else if (rai->rai_linkmtu < IPV6_MMTU ||
- rai->rai_linkmtu > ifi->ifi_phymtu) {
- syslog(LOG_ERR,
- "<%s> advertised link mtu (%" PRIu32 ") on %s is invalid (must "
- "be between least MTU (%d) and physical link MTU (%d)",
- __func__, rai->rai_linkmtu, ifi->ifi_ifname,
- IPV6_MMTU, ifi->ifi_phymtu);
- goto getconfig_free_rai;
- }
-
-#ifdef SIOCSIFINFO_IN6
- {
- struct in6_ndireq ndi;
- int s;
-
- if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "<%s> socket: %s", __func__,
- strerror(errno));
- exit(1);
- }
- memset(&ndi, 0, sizeof(ndi));
- strlcpy(ndi.ifname, ifi->ifi_ifname, sizeof(ndi.ifname));
- if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&ndi) < 0)
- syslog(LOG_INFO, "<%s> ioctl:SIOCGIFINFO_IN6 at %s: %s",
- __func__, ifi->ifi_ifname, strerror(errno));
-
- /* reflect the RA info to the host variables in kernel */
- ndi.ndi.chlim = rai->rai_hoplimit;
- ndi.ndi.retrans = rai->rai_retranstimer;
- ndi.ndi.basereachable = rai->rai_reachabletime;
- if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&ndi) < 0)
- syslog(LOG_INFO, "<%s> ioctl:SIOCSIFINFO_IN6 at %s: %s",
- __func__, ifi->ifi_ifname, strerror(errno));
-
- close(s);
- }
-#endif
-
- /* route information */
- rai->rai_routes = 0;
- for (i = -1; i < MAXROUTE; i++) {
- struct rtinfo *rti;
-
- makeentry(entbuf, sizeof(entbuf), i, "rtprefix");
- addr = (char *)agetstr(entbuf, &bp);
- if (addr == NULL) {
- makeentry(oentbuf, sizeof(oentbuf), i, "rtrprefix");
- addr = (char *)agetstr(oentbuf, &bp);
- if (addr)
- fprintf(stderr, "%s was obsoleted. Use %s.\n",
- oentbuf, entbuf);
- }
- if (addr == NULL)
- continue;
-
- /* allocate memory to store prefix information */
- ELM_MALLOC(rti, exit(1));
-
- if (inet_pton(AF_INET6, addr, &rti->rti_prefix) != 1) {
- syslog(LOG_ERR, "<%s> inet_pton failed for %s",
- __func__, addr);
- goto getconfig_free_rti;
- }
-#if 0
- /*
- * XXX: currently there's no restriction in route information
- * prefix according to
- * draft-ietf-ipngwg-router-selection-00.txt.
- * However, I think the similar restriction be necessary.
- */
- MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
- if (IN6_IS_ADDR_MULTICAST(&rti->prefix)) {
- syslog(LOG_ERR,
- "<%s> multicast route (%s) must "
- "not be advertised on %s",
- __func__, addr, ifi->ifi_ifname);
- goto getconfig_free_rti;
- }
- if (IN6_IS_ADDR_LINKLOCAL(&rti->prefix)) {
- syslog(LOG_NOTICE,
- "<%s> link-local route (%s) will "
- "be advertised on %s",
- __func__, addr, ifi->ifi_ifname);
- goto getconfig_free_rti;
- }
-#endif
-
- makeentry(entbuf, sizeof(entbuf), i, "rtplen");
- /* XXX: 256 is a magic number for compatibility check. */
- MAYHAVE(val, entbuf, 256);
- if (val == 256) {
- makeentry(oentbuf, sizeof(oentbuf), i, "rtrplen");
- MAYHAVE(val, oentbuf, 256);
- if (val != 256)
- fprintf(stderr, "%s was obsoleted. Use %s.\n",
- oentbuf, entbuf);
- else
- val = 64;
- }
- if (val < 0 || val > 128) {
- syslog(LOG_ERR, "<%s> prefixlen (%" PRIu32 ") for %s on %s "
- "out of range",
- __func__, val, addr, ifi->ifi_ifname);
- goto getconfig_free_rti;
- }
- rti->rti_prefixlen = (int)val;
-
- makeentry(entbuf, sizeof(entbuf), i, "rtflags");
- if ((flagstr = (char *)agetstr(entbuf, &bp))) {
- val = 0;
- if (strchr(flagstr, 'h'))
- val |= ND_RA_FLAG_RTPREF_HIGH;
- if (strchr(flagstr, 'l')) {
- if ((val & ND_RA_FLAG_RTPREF_HIGH)) {
- syslog(LOG_ERR,
- "<%s> the \'h\' and \'l\' route"
- " preferences are exclusive",
- __func__);
- goto getconfig_free_rti;
- }
- val |= ND_RA_FLAG_RTPREF_LOW;
- }
- } else
- MAYHAVE(val, entbuf, 256); /* XXX */
- if (val == 256) {
- makeentry(oentbuf, sizeof(oentbuf), i, "rtrflags");
- MAYHAVE(val, oentbuf, 256);
- if (val != 256) {
- fprintf(stderr, "%s was obsoleted. Use %s.\n",
- oentbuf, entbuf);
- } else
- val = 0;
- }
- rti->rti_rtpref = val & ND_RA_FLAG_RTPREF_MASK;
- if (rti->rti_rtpref == ND_RA_FLAG_RTPREF_RSV) {
- syslog(LOG_ERR, "<%s> invalid route preference (%02x) "
- "for %s/%d on %s",
- __func__, rti->rti_rtpref, addr,
- rti->rti_prefixlen, ifi->ifi_ifname);
- goto getconfig_free_rti;
- }
-
- /*
- * Since the spec does not a default value, we should make
- * this entry mandatory. However, FreeBSD 4.4 has shipped
- * with this field being optional, we use the router lifetime
- * as an ad-hoc default value with a warning message.
- */
- makeentry(entbuf, sizeof(entbuf), i, "rtltime");
- MAYHAVE(val64, entbuf, -1);
- if (val64 == -1) {
- makeentry(oentbuf, sizeof(oentbuf), i, "rtrltime");
- MAYHAVE(val64, oentbuf, -1);
- if (val64 != -1)
- fprintf(stderr, "%s was obsoleted. Use %s.\n",
- oentbuf, entbuf);
- else {
- fprintf(stderr, "%s should be specified "
- "for interface %s.\n", entbuf,
- ifi->ifi_ifname);
- val64 = rai->rai_lifetime;
- }
- }
- if (val64 < 0 || val64 > 0xffffffff) {
- syslog(LOG_ERR, "<%s> route lifetime (%" PRIu64 ") for "
- "%s/%d on %s out of range", __func__,
- val64, addr, rti->rti_prefixlen,
- ifi->ifi_ifname);
- goto getconfig_free_rti;
- }
- rti->rti_ltime = (uint32_t)val64;
-
- /* link into chain */
- TAILQ_INSERT_TAIL(&rai->rai_route, rti, rti_next);
- rai->rai_routes++;
- continue;
-getconfig_free_rti:
- free(rti);
- }
-
- /* DNS server and DNS search list information */
- for (i = -1; i < MAXRDNSSENT ; i++) {
- struct rdnss *rdn;
- struct rdnss_addr *rdna;
- char *ap;
- int c;
-
- makeentry(entbuf, sizeof(entbuf), i, "rdnss");
- addr = (char *)agetstr(entbuf, &bp);
- if (addr == NULL)
- continue;
- ELM_MALLOC(rdn, exit(1));
-
- TAILQ_INIT(&rdn->rd_list);
-
- for (ap = addr; ap - addr < (ssize_t)strlen(addr); ap += c+1) {
- c = strcspn(ap, ",");
- strncpy(abuf, ap, c);
- abuf[c] = '\0';
- ELM_MALLOC(rdna, goto getconfig_free_rdn);
- if (inet_pton(AF_INET6, abuf, &rdna->ra_dns) != 1) {
- syslog(LOG_ERR, "<%s> inet_pton failed for %s",
- __func__, abuf);
- free(rdna);
- goto getconfig_free_rdn;
- }
- TAILQ_INSERT_TAIL(&rdn->rd_list, rdna, ra_next);
- }
-
- makeentry(entbuf, sizeof(entbuf), i, "rdnssltime");
- MAYHAVE(val, entbuf, (rai->rai_maxinterval * 3 / 2));
- if ((uint16_t)val < rai->rai_maxinterval ||
- (uint16_t)val > rai->rai_maxinterval * 2) {
- syslog(LOG_ERR, "%s (%" PRIu16 ") on %s is invalid "
- "(must be between %d and %d)",
- entbuf, val, ifi->ifi_ifname, rai->rai_maxinterval,
- rai->rai_maxinterval * 2);
- goto getconfig_free_rdn;
- }
- rdn->rd_ltime = val;
-
- /* link into chain */
- TAILQ_INSERT_TAIL(&rai->rai_rdnss, rdn, rd_next);
- continue;
-getconfig_free_rdn:
- while ((rdna = TAILQ_FIRST(&rdn->rd_list)) != NULL) {
- TAILQ_REMOVE(&rdn->rd_list, rdna, ra_next);
- free(rdna);
- }
- free(rdn);
- }
-
- for (i = -1; i < MAXDNSSLENT ; i++) {
- struct dnssl *dns;
- struct dnssl_addr *dnsa;
- char *ap;
- int c;
-
- makeentry(entbuf, sizeof(entbuf), i, "dnssl");
- addr = (char *)agetstr(entbuf, &bp);
- if (addr == NULL)
- continue;
-
- ELM_MALLOC(dns, exit(1));
-
- TAILQ_INIT(&dns->dn_list);
-
- for (ap = addr; ap - addr < (ssize_t)strlen(addr); ap += c+1) {
- c = strcspn(ap, ",");
- strncpy(abuf, ap, c);
- abuf[c] = '\0';
- ELM_MALLOC(dnsa, goto getconfig_free_dns);
- dnsa->da_len = dname_labelenc(dnsa->da_dom, abuf);
- if (dnsa->da_len < 0) {
- syslog(LOG_ERR, "Invalid dnssl entry: %s",
- abuf);
- goto getconfig_free_dns;
- }
- syslog(LOG_DEBUG, "<%s>: dnsa->da_len = %d", __func__,
- dnsa->da_len);
- TAILQ_INSERT_TAIL(&dns->dn_list, dnsa, da_next);
- }
-
- makeentry(entbuf, sizeof(entbuf), i, "dnsslltime");
- MAYHAVE(val, entbuf, (rai->rai_maxinterval * 3 / 2));
- if ((uint16_t)val < rai->rai_maxinterval ||
- (uint16_t)val > rai->rai_maxinterval * 2) {
- syslog(LOG_ERR, "%s (%" PRIu16 ") on %s is invalid "
- "(must be between %d and %d)",
- entbuf, val, ifi->ifi_ifname, rai->rai_maxinterval,
- rai->rai_maxinterval * 2);
- goto getconfig_free_dns;
- }
- dns->dn_ltime = val;
-
- /* link into chain */
- TAILQ_INSERT_TAIL(&rai->rai_dnssl, dns, dn_next);
- continue;
-getconfig_free_dns:
- while ((dnsa = TAILQ_FIRST(&dns->dn_list)) != NULL) {
- TAILQ_REMOVE(&dns->dn_list, dnsa, da_next);
- free(dnsa);
- }
- free(dns);
- }
- /* construct the sending packet */
- make_packet(rai);
-
- /*
- * If an entry with the same ifindex exists, remove it first.
- * Before the removal, RDNSS and DNSSL options with
- * zero-lifetime will be sent.
- */
- switch (ifi->ifi_state) {
- case IFI_STATE_UNCONFIGURED:
- /* UNCONFIGURED -> TRANSITIVE */
-
- error = sock_mc_join(&sock, ifi->ifi_ifindex);
- if (error)
- exit(1);
-
- ifi->ifi_state = IFI_STATE_TRANSITIVE;
- ifi->ifi_burstcount = MAX_INITIAL_RTR_ADVERTISEMENTS;
- ifi->ifi_burstinterval = MAX_INITIAL_RTR_ADVERT_INTERVAL;
-
- /* The same two rai mean initial burst */
- ifi->ifi_rainfo = rai;
- ifi->ifi_rainfo_trans = rai;
- TAILQ_INSERT_TAIL(&railist, rai, rai_next);
-
- if (ifi->ifi_ra_timer == NULL)
- ifi->ifi_ra_timer = rtadvd_add_timer(ra_timeout,
- ra_timer_update, ifi, ifi);
- ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
- rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
- ifi->ifi_ra_timer);
-
- syslog(LOG_DEBUG,
- "<%s> ifname=%s marked as TRANSITIVE (initial burst).",
- __func__, ifi->ifi_ifname);
- break;
- case IFI_STATE_CONFIGURED:
- /* CONFIGURED -> TRANSITIVE */
- rai_old = ifi->ifi_rainfo;
- if (rai_old == NULL) {
- syslog(LOG_ERR,
- "<%s> ifi_rainfo is NULL"
- " in IFI_STATE_CONFIGURED.", __func__);
- ifi = NULL;
- break;
- } else {
- struct rdnss *rdn;
- struct dnssl *dns;
-
- rai_old->rai_lifetime = 0;
- TAILQ_FOREACH(rdn, &rai_old->rai_rdnss, rd_next)
- rdn->rd_ltime = 0;
- TAILQ_FOREACH(dns, &rai_old->rai_dnssl, dn_next)
- dns->dn_ltime = 0;
-
- ifi->ifi_rainfo_trans = rai_old;
- ifi->ifi_state = IFI_STATE_TRANSITIVE;
- ifi->ifi_burstcount = MAX_FINAL_RTR_ADVERTISEMENTS;
- ifi->ifi_burstinterval = MIN_DELAY_BETWEEN_RAS;
-
- ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
- rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
- ifi->ifi_ra_timer);
-
- syslog(LOG_DEBUG,
- "<%s> ifname=%s marked as TRANSITIVE"
- " (transitional burst)",
- __func__, ifi->ifi_ifname);
- }
- ifi->ifi_rainfo = rai;
- TAILQ_INSERT_TAIL(&railist, rai, rai_next);
- break;
- case IFI_STATE_TRANSITIVE:
- if (ifi->ifi_rainfo != NULL) {
- if (ifi->ifi_rainfo == ifi->ifi_rainfo_trans) {
- /* Reinitialize initial burst */
- rm_rainfo(ifi->ifi_rainfo);
- ifi->ifi_rainfo = rai;
- ifi->ifi_rainfo_trans = rai;
- ifi->ifi_burstcount =
- MAX_INITIAL_RTR_ADVERTISEMENTS;
- ifi->ifi_burstinterval =
- MAX_INITIAL_RTR_ADVERT_INTERVAL;
- } else {
- /* Replace ifi_rainfo with the new one */
- rm_rainfo(ifi->ifi_rainfo);
- ifi->ifi_rainfo = rai;
- }
- TAILQ_INSERT_TAIL(&railist, rai, rai_next);
-
- ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
- rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
- ifi->ifi_ra_timer);
- } else {
- /* XXX: NOTREACHED. Being shut down. */
- syslog(LOG_ERR,
- "<%s> %s is shutting down. Skipped.",
- __func__, ifi->ifi_ifname);
- rm_rainfo(rai);
-
- return (NULL);
- }
- break;
- }
-
- return (ifi);
-
-getconfig_free_rai:
- free(rai);
- return (NULL);
-}
-
-void
-get_prefix(struct rainfo *rai)
-{
- struct ifaddrs *ifap, *ifa;
- struct prefix *pfx;
- struct in6_addr *a;
- struct ifinfo *ifi;
- char *p, *ep, *m, *lim;
- char ntopbuf[INET6_ADDRSTRLEN];
-
- if (getifaddrs(&ifap) < 0) {
- syslog(LOG_ERR,
- "<%s> can't get interface addresses",
- __func__);
- exit(1);
- }
- ifi = rai->rai_ifinfo;
-
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- int plen;
-
- if (strcmp(ifa->ifa_name, ifi->ifi_ifname) != 0)
- continue;
- if (ifa->ifa_addr->sa_family != AF_INET6)
- continue;
- a = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
- if (IN6_IS_ADDR_LINKLOCAL(a))
- continue;
-
- /* get prefix length */
- m = (char *)&((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
- lim = (char *)(ifa->ifa_netmask) + ifa->ifa_netmask->sa_len;
- plen = prefixlen(m, lim);
- if (plen <= 0 || plen > 128) {
- syslog(LOG_ERR, "<%s> failed to get prefixlen "
- "or prefix is invalid",
- __func__);
- exit(1);
- }
- if (plen == 128) /* XXX */
- continue;
- if (find_prefix(rai, a, plen)) {
- /* ignore a duplicated prefix. */
- continue;
- }
-
- /* allocate memory to store prefix info. */
- ELM_MALLOC(pfx, exit(1));
-
- /* set prefix, sweep bits outside of prefixlen */
- pfx->pfx_prefixlen = plen;
- memcpy(&pfx->pfx_prefix, a, sizeof(*a));
- p = (char *)&pfx->pfx_prefix;
- ep = (char *)(&pfx->pfx_prefix + 1);
- while (m < lim && p < ep)
- *p++ &= *m++;
- while (p < ep)
- *p++ = 0x00;
- if (!inet_ntop(AF_INET6, &pfx->pfx_prefix, ntopbuf,
- sizeof(ntopbuf))) {
- syslog(LOG_ERR, "<%s> inet_ntop failed", __func__);
- exit(1);
- }
- syslog(LOG_DEBUG,
- "<%s> add %s/%d to prefix list on %s",
- __func__, ntopbuf, pfx->pfx_prefixlen, ifi->ifi_ifname);
-
- /* set other fields with protocol defaults */
- pfx->pfx_validlifetime = DEF_ADVVALIDLIFETIME;
- pfx->pfx_preflifetime = DEF_ADVPREFERREDLIFETIME;
- pfx->pfx_onlinkflg = 1;
- pfx->pfx_autoconfflg = 1;
- pfx->pfx_origin = PREFIX_FROM_KERNEL;
- pfx->pfx_rainfo = rai;
-
- /* link into chain */
- TAILQ_INSERT_TAIL(&rai->rai_prefix, pfx, pfx_next);
-
- /* counter increment */
- rai->rai_pfxs++;
- }
-
- freeifaddrs(ifap);
-}
-
-static void
-makeentry(char *buf, size_t len, int id, const char *string)
-{
-
- if (id < 0)
- strlcpy(buf, string, len);
- else
- snprintf(buf, len, "%s%d", string, id);
-}
-
-/*
- * Add a prefix to the list of specified interface and reconstruct
- * the outgoing packet.
- * The prefix must not be in the list.
- * XXX: other parameters of the prefix (e.g. lifetime) should be
- * able to be specified.
- */
-static void
-add_prefix(struct rainfo *rai, struct in6_prefixreq *ipr)
-{
- struct prefix *pfx;
- struct ifinfo *ifi;
- char ntopbuf[INET6_ADDRSTRLEN];
-
- ifi = rai->rai_ifinfo;
- ELM_MALLOC(pfx, return);
- pfx->pfx_prefix = ipr->ipr_prefix.sin6_addr;
- pfx->pfx_prefixlen = ipr->ipr_plen;
- pfx->pfx_validlifetime = ipr->ipr_vltime;
- pfx->pfx_preflifetime = ipr->ipr_pltime;
- pfx->pfx_onlinkflg = ipr->ipr_raf_onlink;
- pfx->pfx_autoconfflg = ipr->ipr_raf_auto;
- pfx->pfx_origin = PREFIX_FROM_DYNAMIC;
- pfx->pfx_rainfo = rai;
-
- TAILQ_INSERT_TAIL(&rai->rai_prefix, pfx, pfx_next);
-
- syslog(LOG_DEBUG, "<%s> new prefix %s/%d was added on %s",
- __func__,
- inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr, ntopbuf,
- sizeof(ntopbuf)), ipr->ipr_plen, ifi->ifi_ifname);
-
- rai->rai_pfxs++;
-}
-
-/*
- * Delete a prefix to the list of specified interface and reconstruct
- * the outgoing packet.
- * The prefix must be in the list.
- */
-void
-delete_prefix(struct prefix *pfx)
-{
- struct rainfo *rai;
- struct ifinfo *ifi;
- char ntopbuf[INET6_ADDRSTRLEN];
-
- rai = pfx->pfx_rainfo;
- ifi = rai->rai_ifinfo;
- TAILQ_REMOVE(&rai->rai_prefix, pfx, pfx_next);
- syslog(LOG_DEBUG, "<%s> prefix %s/%d was deleted on %s",
- __func__,
- inet_ntop(AF_INET6, &pfx->pfx_prefix, ntopbuf,
- sizeof(ntopbuf)), pfx->pfx_prefixlen, ifi->ifi_ifname);
- if (pfx->pfx_timer)
- rtadvd_remove_timer(pfx->pfx_timer);
- free(pfx);
-
- rai->rai_pfxs--;
-}
-
-void
-invalidate_prefix(struct prefix *pfx)
-{
- struct timespec timo;
- struct rainfo *rai;
- struct ifinfo *ifi;
- char ntopbuf[INET6_ADDRSTRLEN];
-
- rai = pfx->pfx_rainfo;
- ifi = rai->rai_ifinfo;
- if (pfx->pfx_timer) { /* sanity check */
- syslog(LOG_ERR,
- "<%s> assumption failure: timer already exists",
- __func__);
- exit(1);
- }
-
- syslog(LOG_DEBUG, "<%s> prefix %s/%d was invalidated on %s, "
- "will expire in %ld seconds", __func__,
- inet_ntop(AF_INET6, &pfx->pfx_prefix, ntopbuf, sizeof(ntopbuf)),
- pfx->pfx_prefixlen, ifi->ifi_ifname, (long)prefix_timo);
-
- /* set the expiration timer */
- pfx->pfx_timer = rtadvd_add_timer(prefix_timeout, NULL, pfx, NULL);
- if (pfx->pfx_timer == NULL) {
- syslog(LOG_ERR, "<%s> failed to add a timer for a prefix. "
- "remove the prefix", __func__);
- delete_prefix(pfx);
- }
- timo.tv_sec = prefix_timo;
- timo.tv_nsec = 0;
- rtadvd_set_timer(&timo, pfx->pfx_timer);
-}
-
-static struct rtadvd_timer *
-prefix_timeout(void *arg)
-{
-
- delete_prefix((struct prefix *)arg);
-
- return (NULL);
-}
-
-void
-update_prefix(struct prefix *pfx)
-{
- struct rainfo *rai;
- struct ifinfo *ifi;
- char ntopbuf[INET6_ADDRSTRLEN];
-
- rai = pfx->pfx_rainfo;
- ifi = rai->rai_ifinfo;
- if (pfx->pfx_timer == NULL) { /* sanity check */
- syslog(LOG_ERR,
- "<%s> assumption failure: timer does not exist",
- __func__);
- exit(1);
- }
-
- syslog(LOG_DEBUG, "<%s> prefix %s/%d was re-enabled on %s",
- __func__, inet_ntop(AF_INET6, &pfx->pfx_prefix, ntopbuf,
- sizeof(ntopbuf)), pfx->pfx_prefixlen, ifi->ifi_ifname);
-
- /* stop the expiration timer */
- rtadvd_remove_timer(pfx->pfx_timer);
- pfx->pfx_timer = NULL;
-}
-
-/*
- * Try to get an in6_prefixreq contents for a prefix which matches
- * ipr->ipr_prefix and ipr->ipr_plen and belongs to
- * the interface whose name is ipr->ipr_name[].
- */
-static int
-init_prefix(struct in6_prefixreq *ipr)
-{
-#if 0
- int s;
-
- if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "<%s> socket: %s", __func__,
- strerror(errno));
- exit(1);
- }
-
- if (ioctl(s, SIOCGIFPREFIX_IN6, (caddr_t)ipr) < 0) {
- syslog(LOG_INFO, "<%s> ioctl:SIOCGIFPREFIX %s", __func__,
- strerror(errno));
-
- ipr->ipr_vltime = DEF_ADVVALIDLIFETIME;
- ipr->ipr_pltime = DEF_ADVPREFERREDLIFETIME;
- ipr->ipr_raf_onlink = 1;
- ipr->ipr_raf_auto = 1;
- /* omit other field initialization */
- }
- else if (ipr->ipr_origin < PR_ORIG_RR) {
- char ntopbuf[INET6_ADDRSTRLEN];
-
- syslog(LOG_WARNING, "<%s> Added prefix(%s)'s origin %d is"
- "lower than PR_ORIG_RR(router renumbering)."
- "This should not happen if I am router", __func__,
- inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr, ntopbuf,
- sizeof(ntopbuf)), ipr->ipr_origin);
- close(s);
- return (1);
- }
-
- close(s);
- return (0);
-#else
- ipr->ipr_vltime = DEF_ADVVALIDLIFETIME;
- ipr->ipr_pltime = DEF_ADVPREFERREDLIFETIME;
- ipr->ipr_raf_onlink = 1;
- ipr->ipr_raf_auto = 1;
- return (0);
-#endif
-}
-
-void
-make_prefix(struct rainfo *rai, int ifindex, struct in6_addr *addr, int plen)
-{
- struct in6_prefixreq ipr;
-
- memset(&ipr, 0, sizeof(ipr));
- if (if_indextoname(ifindex, ipr.ipr_name) == NULL) {
- syslog(LOG_ERR, "<%s> Prefix added interface No.%d doesn't "
- "exist. This should not happen! %s", __func__,
- ifindex, strerror(errno));
- exit(1);
- }
- ipr.ipr_prefix.sin6_len = sizeof(ipr.ipr_prefix);
- ipr.ipr_prefix.sin6_family = AF_INET6;
- ipr.ipr_prefix.sin6_addr = *addr;
- ipr.ipr_plen = plen;
-
- if (init_prefix(&ipr))
- return; /* init failed by some error */
- add_prefix(rai, &ipr);
-}
-
-void
-make_packet(struct rainfo *rai)
-{
- size_t packlen, lladdroptlen = 0;
- char *buf;
- struct nd_router_advert *ra;
- struct nd_opt_prefix_info *ndopt_pi;
- struct nd_opt_mtu *ndopt_mtu;
- struct nd_opt_route_info *ndopt_rti;
- struct rtinfo *rti;
- struct nd_opt_rdnss *ndopt_rdnss;
- struct rdnss *rdn;
- struct nd_opt_dnssl *ndopt_dnssl;
- struct dnssl *dns;
- size_t len;
- struct prefix *pfx;
- struct ifinfo *ifi;
-
- ifi = rai->rai_ifinfo;
- /* calculate total length */
- packlen = sizeof(struct nd_router_advert);
- if (rai->rai_advlinkopt) {
- if ((lladdroptlen = lladdropt_length(&ifi->ifi_sdl)) == 0) {
- syslog(LOG_INFO,
- "<%s> link-layer address option has"
- " null length on %s. Treat as not included.",
- __func__, ifi->ifi_ifname);
- rai->rai_advlinkopt = 0;
- }
- packlen += lladdroptlen;
- }
- if (rai->rai_pfxs)
- packlen += sizeof(struct nd_opt_prefix_info) * rai->rai_pfxs;
- if (rai->rai_linkmtu)
- packlen += sizeof(struct nd_opt_mtu);
-
- TAILQ_FOREACH(rti, &rai->rai_route, rti_next)
- packlen += sizeof(struct nd_opt_route_info) +
- ((rti->rti_prefixlen + 0x3f) >> 6) * 8;
-
- TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next) {
- struct rdnss_addr *rdna;
-
- packlen += sizeof(struct nd_opt_rdnss);
- TAILQ_FOREACH(rdna, &rdn->rd_list, ra_next)
- packlen += sizeof(rdna->ra_dns);
- }
- TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next) {
- struct dnssl_addr *dnsa;
-
- packlen += sizeof(struct nd_opt_dnssl);
- len = 0;
- TAILQ_FOREACH(dnsa, &dns->dn_list, da_next)
- len += dnsa->da_len;
-
- /* A zero octet and 8 octet boundary */
- len++;
- len += (len % 8) ? 8 - len % 8 : 0;
-
- packlen += len;
- }
- /* allocate memory for the packet */
- if ((buf = malloc(packlen)) == NULL) {
- syslog(LOG_ERR,
- "<%s> can't get enough memory for an RA packet",
- __func__);
- exit(1);
- }
- memset(buf, 0, packlen);
- if (rai->rai_ra_data) /* Free old data if any. */
- free(rai->rai_ra_data);
- rai->rai_ra_data = buf;
- /* XXX: what if packlen > 576? */
- rai->rai_ra_datalen = packlen;
-
- /*
- * construct the packet
- */
- ra = (struct nd_router_advert *)buf;
- ra->nd_ra_type = ND_ROUTER_ADVERT;
- ra->nd_ra_code = 0;
- ra->nd_ra_cksum = 0;
- ra->nd_ra_curhoplimit = (uint8_t)(0xff & rai->rai_hoplimit);
- ra->nd_ra_flags_reserved = 0; /* just in case */
- /*
- * XXX: the router preference field, which is a 2-bit field, should be
- * initialized before other fields.
- */
- ra->nd_ra_flags_reserved = 0xff & rai->rai_rtpref;
- ra->nd_ra_flags_reserved |=
- rai->rai_managedflg ? ND_RA_FLAG_MANAGED : 0;
- ra->nd_ra_flags_reserved |=
- rai->rai_otherflg ? ND_RA_FLAG_OTHER : 0;
- ra->nd_ra_router_lifetime = htons(rai->rai_lifetime);
- ra->nd_ra_reachable = htonl(rai->rai_reachabletime);
- ra->nd_ra_retransmit = htonl(rai->rai_retranstimer);
- buf += sizeof(*ra);
-
- if (rai->rai_advlinkopt) {
- lladdropt_fill(&ifi->ifi_sdl, (struct nd_opt_hdr *)buf);
- buf += lladdroptlen;
- }
-
- if (rai->rai_linkmtu) {
- ndopt_mtu = (struct nd_opt_mtu *)buf;
- ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU;
- ndopt_mtu->nd_opt_mtu_len = 1;
- ndopt_mtu->nd_opt_mtu_reserved = 0;
- ndopt_mtu->nd_opt_mtu_mtu = htonl(rai->rai_linkmtu);
- buf += sizeof(struct nd_opt_mtu);
- }
-
- TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
- uint32_t vltime, pltime;
- struct timespec now;
-
- ndopt_pi = (struct nd_opt_prefix_info *)buf;
- ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
- ndopt_pi->nd_opt_pi_len = 4;
- ndopt_pi->nd_opt_pi_prefix_len = pfx->pfx_prefixlen;
- ndopt_pi->nd_opt_pi_flags_reserved = 0;
- if (pfx->pfx_onlinkflg)
- ndopt_pi->nd_opt_pi_flags_reserved |=
- ND_OPT_PI_FLAG_ONLINK;
- if (pfx->pfx_autoconfflg)
- ndopt_pi->nd_opt_pi_flags_reserved |=
- ND_OPT_PI_FLAG_AUTO;
- if (pfx->pfx_timer)
- vltime = 0;
- else {
- if (pfx->pfx_vltimeexpire || pfx->pfx_pltimeexpire)
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- if (pfx->pfx_vltimeexpire == 0)
- vltime = pfx->pfx_validlifetime;
- else
- vltime = ((time_t)pfx->pfx_vltimeexpire > now.tv_sec) ?
- pfx->pfx_vltimeexpire - now.tv_sec : 0;
- }
- if (pfx->pfx_timer)
- pltime = 0;
- else {
- if (pfx->pfx_pltimeexpire == 0)
- pltime = pfx->pfx_preflifetime;
- else
- pltime = ((time_t)pfx->pfx_pltimeexpire > now.tv_sec) ?
- pfx->pfx_pltimeexpire - now.tv_sec : 0;
- }
- if (vltime < pltime) {
- /*
- * this can happen if vltime is decrement but pltime
- * is not.
- */
- pltime = vltime;
- }
- ndopt_pi->nd_opt_pi_valid_time = htonl(vltime);
- ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime);
- ndopt_pi->nd_opt_pi_reserved2 = 0;
- ndopt_pi->nd_opt_pi_prefix = pfx->pfx_prefix;
-
- buf += sizeof(struct nd_opt_prefix_info);
- }
-
- TAILQ_FOREACH(rti, &rai->rai_route, rti_next) {
- uint8_t psize = (rti->rti_prefixlen + 0x3f) >> 6;
-
- ndopt_rti = (struct nd_opt_route_info *)buf;
- ndopt_rti->nd_opt_rti_type = ND_OPT_ROUTE_INFO;
- ndopt_rti->nd_opt_rti_len = 1 + psize;
- ndopt_rti->nd_opt_rti_prefixlen = rti->rti_prefixlen;
- ndopt_rti->nd_opt_rti_flags = 0xff & rti->rti_rtpref;
- ndopt_rti->nd_opt_rti_lifetime = htonl(rti->rti_ltime);
- memcpy(ndopt_rti + 1, &rti->rti_prefix, psize * 8);
- buf += sizeof(struct nd_opt_route_info) + psize * 8;
- }
-
- TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next) {
- struct rdnss_addr *rdna;
-
- ndopt_rdnss = (struct nd_opt_rdnss *)buf;
- ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS;
- ndopt_rdnss->nd_opt_rdnss_len = 0;
- ndopt_rdnss->nd_opt_rdnss_reserved = 0;
- ndopt_rdnss->nd_opt_rdnss_lifetime = htonl(rdn->rd_ltime);
- buf += sizeof(struct nd_opt_rdnss);
-
- TAILQ_FOREACH(rdna, &rdn->rd_list, ra_next) {
- memcpy(buf, &rdna->ra_dns, sizeof(rdna->ra_dns));
- buf += sizeof(rdna->ra_dns);
- }
- /* Length field should be in 8 octets */
- ndopt_rdnss->nd_opt_rdnss_len = (buf - (char *)ndopt_rdnss) / 8;
-
- syslog(LOG_DEBUG, "<%s>: nd_opt_dnss_len = %d", __func__,
- ndopt_rdnss->nd_opt_rdnss_len);
- }
-
- TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next) {
- struct dnssl_addr *dnsa;
-
- ndopt_dnssl = (struct nd_opt_dnssl *)buf;
- ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL;
- ndopt_dnssl->nd_opt_dnssl_len = 0;
- ndopt_dnssl->nd_opt_dnssl_reserved = 0;
- ndopt_dnssl->nd_opt_dnssl_lifetime = htonl(dns->dn_ltime);
- buf += sizeof(*ndopt_dnssl);
-
- TAILQ_FOREACH(dnsa, &dns->dn_list, da_next) {
- memcpy(buf, dnsa->da_dom, dnsa->da_len);
- buf += dnsa->da_len;
- }
-
- /* A zero octet after encoded DNS server list. */
- *buf++ = '\0';
-
- /* Padding to next 8 octets boundary */
- len = buf - (char *)ndopt_dnssl;
- len += (len % 8) ? 8 - len % 8 : 0;
- buf = (char *)ndopt_dnssl + len;
-
- /* Length field must be in 8 octets */
- ndopt_dnssl->nd_opt_dnssl_len = len / 8;
-
- syslog(LOG_DEBUG, "<%s>: nd_opt_dnssl_len = %d", __func__,
- ndopt_dnssl->nd_opt_dnssl_len);
- }
- return;
-}
diff --git a/usr.sbin/rtadvd/config.h b/usr.sbin/rtadvd/config.h
deleted file mode 100644
index 219390b..0000000
--- a/usr.sbin/rtadvd/config.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: config.h,v 1.8 2003/06/17 08:26:22 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-extern struct ifinfo *getconfig(struct ifinfo *);
-extern int rm_ifinfo(struct ifinfo *);
-extern int rm_ifinfo_index(int);
-extern int rm_rainfo(struct rainfo *);
-extern int loadconfig_ifname(char *);
-extern int loadconfig_index(int);
-extern void delete_prefix(struct prefix *);
-extern void invalidate_prefix(struct prefix *);
-extern void update_prefix(struct prefix *);
-extern void make_prefix(struct rainfo *, int, struct in6_addr *, int);
-extern void make_packet(struct rainfo *);
-extern void get_prefix(struct rainfo *);
-
-/*
- * it is highly unlikely to have 100 prefix information options,
- * so it should be okay to limit it
- */
-#define MAXPREFIX 100
-#define MAXROUTE 100
-#define MAXRDNSSENT 100
-#define MAXDNSSLENT 100
diff --git a/usr.sbin/rtadvd/control.c b/usr.sbin/rtadvd/control.c
deleted file mode 100644
index fc6d536..0000000
--- a/usr.sbin/rtadvd/control.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*-
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <sys/uio.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <poll.h>
-#include <signal.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-
-#include "rtadvd.h"
-#include "if.h"
-#include "pathnames.h"
-#include "control.h"
-
-#define CM_RECV_TIMEOUT 30
-
-int
-cm_recv(int fd, char *buf)
-{
- ssize_t n;
- struct ctrl_msg_hdr *cm;
- char *msg;
- struct pollfd pfds[1];
- int i;
-
- syslog(LOG_DEBUG, "<%s> enter, fd=%d", __func__, fd);
-
- memset(buf, 0, CM_MSG_MAXLEN);
- cm = (struct ctrl_msg_hdr *)buf;
- msg = (char *)buf + sizeof(*cm);
-
- pfds[0].fd = fd;
- pfds[0].events = POLLIN;
-
- for (;;) {
- i = poll(pfds, sizeof(pfds)/sizeof(pfds[0]),
- CM_RECV_TIMEOUT);
-
- if (i == 0)
- continue;
-
- if (i < 0) {
- syslog(LOG_ERR, "<%s> poll error: %s",
- __func__, strerror(errno));
- continue;
- }
-
- if (pfds[0].revents & POLLIN) {
- n = read(fd, cm, sizeof(*cm));
- if (n < 0 && errno == EAGAIN) {
- syslog(LOG_DEBUG,
- "<%s> waiting...", __func__);
- continue;
- }
- break;
- }
- }
-
- if (n != (ssize_t)sizeof(*cm)) {
- syslog(LOG_WARNING,
- "<%s> received a too small message.", __func__);
- goto cm_recv_err;
- }
- if (cm->cm_len > CM_MSG_MAXLEN) {
- syslog(LOG_WARNING,
- "<%s> received a too large message.", __func__);
- goto cm_recv_err;
- }
- if (cm->cm_version != CM_VERSION) {
- syslog(LOG_WARNING,
- "<%s> version mismatch", __func__);
- goto cm_recv_err;
- }
- if (cm->cm_type >= CM_TYPE_MAX) {
- syslog(LOG_WARNING,
- "<%s> invalid msg type.", __func__);
- goto cm_recv_err;
- }
-
- syslog(LOG_DEBUG,
- "<%s> ctrl msg received: type=%d", __func__,
- cm->cm_type);
-
- if (cm->cm_len > sizeof(*cm)) {
- size_t msglen = cm->cm_len - sizeof(*cm);
-
- syslog(LOG_DEBUG,
- "<%s> ctrl msg has payload (len=%zu)", __func__,
- msglen);
-
- for (;;) {
- i = poll(pfds, sizeof(pfds)/sizeof(pfds[0]),
- CM_RECV_TIMEOUT);
-
- if (i == 0)
- continue;
-
- if (i < 0) {
- syslog(LOG_ERR, "<%s> poll error: %s",
- __func__, strerror(errno));
- continue;
- }
-
- if (pfds[0].revents & POLLIN) {
- n = read(fd, msg, msglen);
- if (n < 0 && errno == EAGAIN) {
- syslog(LOG_DEBUG,
- "<%s> waiting...", __func__);
- continue;
- }
- }
- break;
- }
- if (n != (ssize_t)msglen) {
- syslog(LOG_WARNING,
- "<%s> payload size mismatch.", __func__);
- goto cm_recv_err;
- }
- buf[CM_MSG_MAXLEN - 1] = '\0';
- }
-
- return (0);
-
-cm_recv_err:
- close(fd);
- return (-1);
-}
-
-int
-cm_send(int fd, char *buf)
-{
- struct iovec iov[2];
- int iovcnt;
- ssize_t len;
- ssize_t iov_len_total;
- struct ctrl_msg_hdr *cm;
- char *msg;
-
- cm = (struct ctrl_msg_hdr *)buf;
- msg = (char *)buf + sizeof(*cm);
-
- iovcnt = 1;
- iov[0].iov_base = cm;
- iov[0].iov_len = sizeof(*cm);
- iov_len_total = iov[0].iov_len;
- if (cm->cm_len > sizeof(*cm)) {
- iovcnt++;
- iov[1].iov_base = msg;
- iov[1].iov_len = cm->cm_len - iov[0].iov_len;
- iov_len_total += iov[1].iov_len;
- }
-
- syslog(LOG_DEBUG,
- "<%s> ctrl msg send: type=%d, count=%d, total_len=%zd", __func__,
- cm->cm_type, iovcnt, iov_len_total);
-
- len = writev(fd, iov, iovcnt);
- syslog(LOG_DEBUG,
- "<%s> ctrl msg send: length=%zd", __func__, len);
-
- if (len == -1) {
- syslog(LOG_DEBUG,
- "<%s> write failed: (%d)%s", __func__, errno,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- syslog(LOG_DEBUG,
- "<%s> write length = %zd (actual)", __func__, len);
- syslog(LOG_DEBUG,
- "<%s> write length = %zd (expected)", __func__, iov_len_total);
-
- if (len != iov_len_total) {
- close(fd);
- return (-1);
- }
-
- return (0);
-}
-
-int
-csock_accept(struct sockinfo *s)
-{
- struct sockaddr_un sun;
- int flags;
- int fd;
-
- sun.sun_len = sizeof(sun);
- if ((fd = accept(s->si_fd, (struct sockaddr *)&sun,
- (socklen_t *)&sun.sun_len)) == -1) {
- if (errno != EWOULDBLOCK && errno != EINTR)
- syslog(LOG_WARNING, "<%s> accept ", __func__);
- syslog(LOG_WARNING, "<%s> Xaccept: %s", __func__, strerror(errno));
- return (-1);
- }
- if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
- syslog(LOG_WARNING, "<%s> fcntl F_GETFL", __func__);
- close(s->si_fd);
- return (-1);
- }
- if ((flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1) {
- syslog(LOG_WARNING, "<%s> fcntl F_SETFL", __func__);
- return (-1);
- }
- syslog(LOG_DEBUG, "<%s> accept connfd=%d, listenfd=%d", __func__,
- fd, s->si_fd);
-
- return (fd);
-}
-
-int
-csock_close(struct sockinfo *s)
-{
- close(s->si_fd);
- unlink(s->si_name);
- syslog(LOG_DEBUG, "<%s> remove %s", __func__, s->si_name);
- return (0);
-}
-
-int
-csock_listen(struct sockinfo *s)
-{
- if (s->si_fd == -1) {
- syslog(LOG_ERR, "<%s> listen failed", __func__);
- return (-1);
- }
- if (listen(s->si_fd, SOCK_BACKLOG) == -1) {
- syslog(LOG_ERR, "<%s> listen failed", __func__);
- return (-1);
- }
-
- return (0);
-}
-
-int
-csock_open(struct sockinfo *s, mode_t mode)
-{
- int flags;
- struct sockaddr_un sun;
- mode_t old_umask;
-
- if (s == NULL) {
- syslog(LOG_ERR, "<%s> internal error.", __func__);
- exit(1);
- }
- if (s->si_name == NULL)
- s->si_name = _PATH_CTRL_SOCK;
-
- if ((s->si_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
- syslog(LOG_ERR,
- "<%s> cannot open control socket", __func__);
- return (-1);
- }
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- sun.sun_len = sizeof(sun);
- strlcpy(sun.sun_path, s->si_name, sizeof(sun.sun_path));
-
- if (unlink(s->si_name) == -1)
- if (errno != ENOENT) {
- syslog(LOG_ERR,
- "<%s> unlink %s", __func__, s->si_name);
- close(s->si_fd);
- return (-1);
- }
- old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- if (bind(s->si_fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
- syslog(LOG_ERR,
- "<%s> bind failed: %s", __func__, s->si_name);
- close(s->si_fd);
- umask(old_umask);
- return (-1);
- }
- umask(old_umask);
- if (chmod(s->si_name, mode) == -1) {
- syslog(LOG_ERR,
- "<%s> chmod failed: %s", __func__, s->si_name);
- goto csock_open_err;
- }
- if ((flags = fcntl(s->si_fd, F_GETFL, 0)) == -1) {
- syslog(LOG_ERR,
- "<%s> fcntl F_GETFL failed: %s", __func__, s->si_name);
- goto csock_open_err;
- }
- if ((flags = fcntl(s->si_fd, F_SETFL, flags | O_NONBLOCK)) == -1) {
- syslog(LOG_ERR,
- "<%s> fcntl F_SETFL failed: %s", __func__, s->si_name);
- goto csock_open_err;
- }
-
- return (s->si_fd);
-
-csock_open_err:
- close(s->si_fd);
- unlink(s->si_name);
- return (-1);
-}
-
-struct ctrl_msg_pl *
-cm_bin2pl(char *str, struct ctrl_msg_pl *cp)
-{
- size_t len;
- size_t *lenp;
- char *p;
-
- memset(cp, 0, sizeof(*cp));
-
- p = str;
-
- lenp = (size_t *)p;
- len = *lenp++;
- p = (char *)lenp;
- syslog(LOG_DEBUG, "<%s> len(ifname) = %zu", __func__, len);
- if (len > 0) {
- cp->cp_ifname = malloc(len + 1);
- if (cp->cp_ifname == NULL) {
- syslog(LOG_ERR, "<%s> malloc", __func__);
- exit(1);
- }
- memcpy(cp->cp_ifname, p, len);
- cp->cp_ifname[len] = '\0';
- p += len;
- }
-
- lenp = (size_t *)p;
- len = *lenp++;
- p = (char *)lenp;
- syslog(LOG_DEBUG, "<%s> len(key) = %zu", __func__, len);
- if (len > 0) {
- cp->cp_key = malloc(len + 1);
- if (cp->cp_key == NULL) {
- syslog(LOG_ERR, "<%s> malloc", __func__);
- exit(1);
- }
- memcpy(cp->cp_key, p, len);
- cp->cp_key[len] = '\0';
- p += len;
- }
-
- lenp = (size_t *)p;
- len = *lenp++;
- p = (char *)lenp;
- syslog(LOG_DEBUG, "<%s> len(val) = %zu", __func__, len);
- if (len > 0) {
- cp->cp_val = malloc(len + 1);
- if (cp->cp_val == NULL) {
- syslog(LOG_ERR, "<%s> malloc", __func__);
- exit(1);
- }
- memcpy(cp->cp_val, p, len);
- cp->cp_val[len] = '\0';
- cp->cp_val_len = len;
- } else
- cp->cp_val_len = 0;
-
- return (cp);
-}
-
-size_t
-cm_pl2bin(char *str, struct ctrl_msg_pl *cp)
-{
- size_t len;
- size_t *lenp;
- char *p;
- struct ctrl_msg_hdr *cm;
-
- len = sizeof(size_t);
- if (cp->cp_ifname != NULL)
- len += strlen(cp->cp_ifname);
- len += sizeof(size_t);
- if (cp->cp_key != NULL)
- len += strlen(cp->cp_key);
- len += sizeof(size_t);
- if (cp->cp_val != NULL && cp->cp_val_len > 0)
- len += cp->cp_val_len;
-
- if (len > CM_MSG_MAXLEN - sizeof(*cm)) {
- syslog(LOG_DEBUG, "<%s> msg too long (len=%zu)",
- __func__, len);
- return (0);
- }
- syslog(LOG_DEBUG, "<%s> msglen=%zu", __func__, len);
- memset(str, 0, len);
- p = str;
- lenp = (size_t *)p;
-
- if (cp->cp_ifname != NULL) {
- *lenp++ = strlen(cp->cp_ifname);
- p = (char *)lenp;
- memcpy(p, cp->cp_ifname, strlen(cp->cp_ifname));
- p += strlen(cp->cp_ifname);
- } else {
- *lenp++ = '\0';
- p = (char *)lenp;
- }
-
- lenp = (size_t *)p;
- if (cp->cp_key != NULL) {
- *lenp++ = strlen(cp->cp_key);
- p = (char *)lenp;
- memcpy(p, cp->cp_key, strlen(cp->cp_key));
- p += strlen(cp->cp_key);
- } else {
- *lenp++ = '\0';
- p = (char *)lenp;
- }
-
- lenp = (size_t *)p;
- if (cp->cp_val != NULL && cp->cp_val_len > 0) {
- *lenp++ = cp->cp_val_len;
- p = (char *)lenp;
- memcpy(p, cp->cp_val, cp->cp_val_len);
- p += cp->cp_val_len;
- } else {
- *lenp++ = '\0';
- p = (char *)lenp;
- }
-
- return (len);
-}
-
-size_t
-cm_str2bin(char *bin, void *str, size_t len)
-{
- struct ctrl_msg_hdr *cm;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (len > CM_MSG_MAXLEN - sizeof(*cm)) {
- syslog(LOG_DEBUG, "<%s> msg too long (len=%zu)",
- __func__, len);
- return (0);
- }
- syslog(LOG_DEBUG, "<%s> msglen=%zu", __func__, len);
- memcpy(bin, (char *)str, len);
-
- return (len);
-}
-
-void *
-cm_bin2str(char *bin, void *str, size_t len)
-{
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- memcpy((char *)str, bin, len);
-
- return (str);
-}
diff --git a/usr.sbin/rtadvd/control.h b/usr.sbin/rtadvd/control.h
deleted file mode 100644
index 2168302..0000000
--- a/usr.sbin/rtadvd/control.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*-
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#define SOCK_BACKLOG 5
-
-#define CM_MSG_MAXLEN 8192
-#define CM_VERSION 1
-#define CM_VERSION_STR "1.0"
-
-#define CM_TYPE_EOM 0
-#define CM_TYPE_ACK 1
-#define CM_TYPE_ERR 2
-#define CM_TYPE_NUL 3
-#define CM_TYPE_REQ_SET_PROP 4
-#define CM_TYPE_REQ_GET_PROP 5
-#define CM_TYPE_MAX 6
-
-#define CM_STATE_EOM 0
-#define CM_STATE_INIT 1
-#define CM_STATE_MSG_DISPATCH 2
-#define CM_STATE_MSG_RECV 3
-#define CM_STATE_ACK_WAIT 4
-
-struct ctrl_msg_hdr {
- int cm_version;
- size_t cm_len;
- int cm_type;
-};
-
-struct ctrl_msg_pl {
- char *cp_ifname;
- char *cp_key;
-
- size_t cp_val_len;
- char *cp_val;
-};
-
-int csock_open(struct sockinfo *, mode_t);
-int csock_close(struct sockinfo *);
-int csock_listen(struct sockinfo *);
-int csock_accept(struct sockinfo *);
-int cm_send(int, char *);
-int cm_recv(int, char *);
-
-size_t cm_pl2bin(char *, struct ctrl_msg_pl *);
-struct ctrl_msg_pl *cm_bin2pl(char *, struct ctrl_msg_pl *);
-size_t cm_str2bin(char *, void *, size_t);
-void *cm_bin2str(char *, void *, size_t);
diff --git a/usr.sbin/rtadvd/control_client.c b/usr.sbin/rtadvd/control_client.c
deleted file mode 100644
index ca5cb68..0000000
--- a/usr.sbin/rtadvd/control_client.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <sys/uio.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-
-#include "pathnames.h"
-#include "rtadvd.h"
-#include "if.h"
-#include "control.h"
-#include "control_client.h"
-
-int
-cm_handler_client(int fd, int state, char *buf_orig)
-{
- char buf[CM_MSG_MAXLEN];
- struct ctrl_msg_hdr *cm;
- struct ctrl_msg_hdr *cm_orig;
- int error;
- char *msg;
- char *msg_orig;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- memset(buf, 0, sizeof(buf));
- cm = (struct ctrl_msg_hdr *)buf;
- cm_orig = (struct ctrl_msg_hdr *)buf_orig;
- msg = (char *)buf + sizeof(*cm);
- msg_orig = (char *)buf_orig + sizeof(*cm_orig);
-
- if (cm_orig->cm_len > CM_MSG_MAXLEN) {
- syslog(LOG_DEBUG, "<%s> msg too long", __func__);
- close(fd);
- return (-1);
- }
- cm->cm_type = cm_orig->cm_type;
- if (cm_orig->cm_len > sizeof(*cm_orig)) {
- memcpy(msg, msg_orig, cm_orig->cm_len - sizeof(*cm));
- cm->cm_len = cm_orig->cm_len;
- }
- while (state != CM_STATE_EOM) {
- syslog(LOG_DEBUG, "<%s> state = %d", __func__, state);
-
- switch (state) {
- case CM_STATE_INIT:
- state = CM_STATE_EOM;
- break;
- case CM_STATE_MSG_DISPATCH:
- cm->cm_version = CM_VERSION;
- error = cm_send(fd, buf);
- if (error) {
- syslog(LOG_WARNING,
- "<%s> cm_send()", __func__);
- return (-1);
- }
- state = CM_STATE_ACK_WAIT;
- break;
- case CM_STATE_ACK_WAIT:
- error = cm_recv(fd, buf);
- if (error) {
- syslog(LOG_ERR,
- "<%s> cm_recv()", __func__);
- close(fd);
- return (-1);
- }
- switch (cm->cm_type) {
- case CM_TYPE_ACK:
- syslog(LOG_DEBUG,
- "<%s> CM_TYPE_ACK", __func__);
- break;
- case CM_TYPE_ERR:
- syslog(LOG_DEBUG,
- "<%s> CM_TYPE_ERR", __func__);
- close(fd);
- return (-1);
- default:
- syslog(LOG_DEBUG,
- "<%s> unknown status", __func__);
- close(fd);
- return (-1);
- }
- memcpy(buf_orig, buf, cm->cm_len);
- state = CM_STATE_EOM;
- break;
- }
- }
- close(fd);
- return (0);
-}
diff --git a/usr.sbin/rtadvd/control_client.h b/usr.sbin/rtadvd/control_client.h
deleted file mode 100644
index 2f50f17..0000000
--- a/usr.sbin/rtadvd/control_client.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-int cm_handler_client(int, int, char *);
diff --git a/usr.sbin/rtadvd/control_server.c b/usr.sbin/rtadvd/control_server.c
deleted file mode 100644
index 76ca541..0000000
--- a/usr.sbin/rtadvd/control_server.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*-
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <sys/uio.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-
-#include "pathnames.h"
-#include "rtadvd.h"
-#include "if.h"
-#include "config.h"
-#include "control.h"
-#include "control_server.h"
-#include "timer.h"
-
-static char *do_reload_ifname;
-static int do_reload;
-static int do_shutdown;
-
-void set_do_reload(int sig __unused) { do_reload = 1; }
-void set_do_reload_ifname(char *ifname){ do_reload_ifname = ifname; }
-void set_do_shutdown(int sig __unused) { do_shutdown = 1; }
-void reset_do_reload(void) { do_reload = 0; do_reload_ifname = NULL; }
-void reset_do_shutdown(void) { do_shutdown = 0; }
-int is_do_reload(void) { return (do_reload); }
-int is_do_shutdown(void) { return (do_shutdown); }
-char *reload_ifname(void) { return (do_reload_ifname); }
-
-#define DEF_PL_HANDLER(key) { #key, cm_getprop_##key }
-
-static int cm_getprop_echo(struct ctrl_msg_pl *);
-static int cm_getprop_version(struct ctrl_msg_pl *);
-static int cm_getprop_ifilist(struct ctrl_msg_pl *);
-static int cm_getprop_ifi(struct ctrl_msg_pl *);
-static int cm_getprop_ifi_ra_timer(struct ctrl_msg_pl *);
-static int cm_getprop_rai(struct ctrl_msg_pl *);
-static int cm_getprop_pfx(struct ctrl_msg_pl *);
-static int cm_getprop_rdnss(struct ctrl_msg_pl *);
-static int cm_getprop_dnssl(struct ctrl_msg_pl *);
-static int cm_getprop_rti(struct ctrl_msg_pl *);
-
-static int cm_setprop_reload(struct ctrl_msg_pl *);
-static int cm_setprop_enable(struct ctrl_msg_pl *);
-static int cm_setprop_disable(struct ctrl_msg_pl *);
-
-static struct dispatch_table {
- const char *dt_comm;
- int (*dt_act)(struct ctrl_msg_pl *cp);
-} getprop_dtable[] = {
- { "", cm_getprop_echo },
- DEF_PL_HANDLER(echo),
- DEF_PL_HANDLER(version),
- DEF_PL_HANDLER(ifilist),
- DEF_PL_HANDLER(ifi),
- DEF_PL_HANDLER(ifi_ra_timer),
- DEF_PL_HANDLER(rai),
- DEF_PL_HANDLER(rti),
- DEF_PL_HANDLER(pfx),
- DEF_PL_HANDLER(rdnss),
- DEF_PL_HANDLER(dnssl),
-};
-
-static int
-cm_getprop_echo(struct ctrl_msg_pl *cp)
-{
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
- cp->cp_val = strdup("");
- cp->cp_val_len = strlen(cp->cp_val) + 1;
-
- return (0);
-}
-
-static int
-cm_getprop_version(struct ctrl_msg_pl *cp)
-{
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
- cp->cp_val = strdup(CM_VERSION_STR);
- cp->cp_val_len = strlen(cp->cp_val) + 1;
-
- return (0);
-}
-
-static int
-cm_getprop_ifilist(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- char *p;
- size_t len;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- len = 0;
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- len += strlen(ifi->ifi_ifname) + 1;
- }
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- p = malloc(len);
- if (p == NULL)
- exit(1);
- memset(p, 0, len);
- cp->cp_val = p;
-
- if (len > 0)
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- syslog(LOG_DEBUG, "<%s> add ifname=%s(%d)",
- __func__, ifi->ifi_ifname, ifi->ifi_ifindex);
- strcpy(p, ifi->ifi_ifname);
- p += strlen(ifi->ifi_ifname) + 1;
- }
- cp->cp_val_len = p - cp->cp_val;
-
- return (0);
-}
-
-static int
-cm_getprop_ifi(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- char *p;
- size_t len;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
-
- p = malloc(sizeof(*ifi));
- if (p == NULL)
- exit(1);
- len = cm_str2bin(p, ifi, sizeof(*ifi));
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- if (len == 0)
- return (1);
-
- cp->cp_val = p;
- cp->cp_val_len = len;
-
- return (0);
-}
-
-static int
-cm_getprop_rai(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- char *p;
- size_t len;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
- if ((rai = ifi->ifi_rainfo) == NULL) {
- syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
- cp->cp_ifname);
- return (1);
- }
-
- p = malloc(sizeof(*rai));
- if (p == NULL)
- exit(1);
- len = cm_str2bin(p, rai, sizeof(*rai));
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- if (len == 0)
- return (1);
-
- cp->cp_val = p;
- cp->cp_val_len = len;
-
- return (0);
-}
-
-static int
-cm_getprop_ifi_ra_timer(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- struct rtadvd_timer *rtimer;
- char *p;
- size_t len;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
- if ((rai = ifi->ifi_rainfo) == NULL) {
- syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
- cp->cp_ifname);
- return (1);
- }
- if ((rtimer = ifi->ifi_ra_timer) == NULL) {
- syslog(LOG_ERR, "<%s> %s has no ifi_ra_timer", __func__,
- cp->cp_ifname);
- return (1);
- }
- p = malloc(sizeof(*rtimer));
- if (p == NULL)
- exit(1);
- len = cm_str2bin(p, rtimer, sizeof(*rtimer));
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- if (len == 0)
- return (1);
-
- cp->cp_val = p;
- cp->cp_val_len = len;
-
- return (0);
-}
-
-static int
-cm_getprop_rti(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- struct rtinfo *rti;
- char *p;
- size_t len;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- len = 0;
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
- if (ifi->ifi_rainfo == NULL) {
- syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
- cp->cp_ifname);
- return (1);
- }
- rai = ifi->ifi_rainfo;
- TAILQ_FOREACH(rti, &rai->rai_route, rti_next) {
- len += sizeof(*rti);
- }
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- p = malloc(len);
- if (p == NULL)
- exit(1);
- memset(p, 0, len);
- cp->cp_val = p;
-
- if (len > 0)
- TAILQ_FOREACH(rti, &rai->rai_route, rti_next) {
- memcpy(p, rti, sizeof(*rti));
- p += sizeof(*rti);
- }
- cp->cp_val_len = p - cp->cp_val;
-
- return (0);
-}
-
-static int
-cm_getprop_pfx(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- struct prefix *pfx;
- char *p;
- size_t len;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- len = 0;
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
- if (ifi->ifi_rainfo == NULL) {
- syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
- cp->cp_ifname);
- return (1);
- }
- rai = ifi->ifi_rainfo;
- TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
- len += sizeof(*pfx);
- }
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- p = malloc(len);
- if (p == NULL)
- exit(1);
- memset(p, 0, len);
- cp->cp_val = p;
-
- if (len > 0)
- TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
- memcpy(p, pfx, sizeof(*pfx));
- p += sizeof(*pfx);
- }
- cp->cp_val_len = p - cp->cp_val;
-
- return (0);
-}
-
-static int
-cm_getprop_rdnss(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- struct rdnss *rdn;
- struct rdnss_addr *rda;
- char *p;
- size_t len;
- uint16_t *rdn_cnt;
- uint16_t *rda_cnt;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- len = 0;
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
- if (ifi->ifi_rainfo == NULL) {
- syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
- cp->cp_ifname);
- return (1);
- }
- rai = ifi->ifi_rainfo;
-
- len = sizeof(*rdn_cnt);
- TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next) {
- len += sizeof(*rdn);
- len += sizeof(*rda_cnt);
- TAILQ_FOREACH(rda, &rdn->rd_list, ra_next) {
- len += sizeof(*rda);
- }
- }
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- p = malloc(len);
- if (p == NULL)
- exit(1);
- memset(p, 0, len);
- cp->cp_val = p;
-
- rdn_cnt = (uint16_t *)p;
- p += sizeof(*rdn_cnt);
- TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next) {
- *rdn_cnt += 1;
- memcpy(p, rdn, sizeof(*rdn));
- p += sizeof(*rdn);
-
- rda_cnt = (uint16_t *)p;
- p += sizeof(*rda_cnt);
- TAILQ_FOREACH(rda, &rdn->rd_list, ra_next) {
- *rda_cnt += 1;
- memcpy(p, rda, sizeof(*rda));
- p += sizeof(*rda);
- }
- }
- syslog(LOG_DEBUG, "<%s> rdn_cnt = %d", __func__, *rdn_cnt);
- cp->cp_val_len = p - cp->cp_val;
-
- return (0);
-}
-
-static int
-cm_getprop_dnssl(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- struct dnssl *dns;
- struct dnssl_addr *dna;
- char *p;
- size_t len;
- uint16_t *dns_cnt;
- uint16_t *dna_cnt;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- len = 0;
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
- if (ifi->ifi_rainfo == NULL) {
- syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
- cp->cp_ifname);
- return (1);
- }
- rai = ifi->ifi_rainfo;
-
- len = sizeof(*dns_cnt);
- TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next) {
- len += sizeof(*dns);
- len += sizeof(*dna_cnt);
- TAILQ_FOREACH(dna, &dns->dn_list, da_next) {
- len += sizeof(*dna);
- }
- }
-
- syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
-
- p = malloc(len);
- if (p == NULL)
- exit(1);
- memset(p, 0, len);
- cp->cp_val = p;
-
- dns_cnt = (uint16_t *)cp->cp_val;
- p += sizeof(*dns_cnt);
- TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next) {
- (*dns_cnt)++;
- memcpy(p, dns, sizeof(*dns));
- p += sizeof(*dns);
-
- dna_cnt = (uint16_t *)p;
- p += sizeof(*dna_cnt);
- TAILQ_FOREACH(dna, &dns->dn_list, da_next) {
- (*dna_cnt)++;
- memcpy(p, dna, sizeof(*dna));
- p += sizeof(*dna);
- }
- }
- cp->cp_val_len = p - cp->cp_val;
-
- return (0);
-}
-
-int
-cm_getprop(struct ctrl_msg_pl *cp)
-{
- size_t i;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (cp == NULL)
- return (1);
-
- for (i = 0;
- i < sizeof(getprop_dtable) / sizeof(getprop_dtable[0]);
- i++) {
- if (strcmp(cp->cp_key, getprop_dtable[i].dt_comm) == 0)
- return (getprop_dtable[i].dt_act(cp));
- }
- return (1);
-}
-
-int
-cm_setprop(struct ctrl_msg_pl *cp)
-{
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (cp == NULL || cp->cp_key == NULL)
- return (1);
-
- if (strncmp(cp->cp_key, "reload", sizeof("reload")) == 0)
- cm_setprop_reload(cp);
- else if (strncmp(cp->cp_key, "shutdown", sizeof("shutdown")) == 0)
- set_do_shutdown(0);
- else if (strncmp(cp->cp_key, "enable", sizeof("enable")) == 0)
- cm_setprop_enable(cp);
- else if (strncmp(cp->cp_key, "disable", sizeof("disable")) == 0)
- cm_setprop_disable(cp);
- else if (strncmp(cp->cp_key, "echo", 8) == 0)
- ; /* do nothing */
- else
- return (1);
-
- return (0);
-}
-
-static int
-cm_setprop_reload(struct ctrl_msg_pl *cp)
-{
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- set_do_reload_ifname(cp->cp_ifname);
- set_do_reload(1);
-
- return (0);
-}
-
-static int
-cm_setprop_enable(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
-
- ifi->ifi_persist = 1;
- set_do_reload_ifname(ifi->ifi_ifname);
- set_do_reload(0);
-
- return (0);
-}
-
-static int
-cm_setprop_disable(struct ctrl_msg_pl *cp)
-{
- struct ifinfo *ifi;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> %s not found", __func__,
- cp->cp_ifname);
- return (1);
- }
-
- if (ifi->ifi_persist == 1) {
- ifi->ifi_persist = 0;
- rm_ifinfo(ifi);
-
- /* MC leaving needed here */
- sock_mc_leave(&sock, ifi->ifi_ifindex);
-
- set_do_reload_ifname(ifi->ifi_ifname);
- set_do_reload(0);
- }
-
- return (0);
-}
-
-int
-cm_handler_server(int fd)
-{
- int state;
- char *msg;
- struct ctrl_msg_hdr *cm;
- struct ctrl_msg_pl cp;
- char buf[CM_MSG_MAXLEN];
- char pbuf[CM_MSG_MAXLEN];
- int error;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- memset(buf, 0, sizeof(buf));
- memset(pbuf, 0, sizeof(pbuf));
- cm = (struct ctrl_msg_hdr *)buf;
- msg = (char *)buf + sizeof(*cm);
-
- state = CM_STATE_INIT;
- while (state != CM_STATE_EOM) {
- syslog(LOG_DEBUG, "<%s> state = %d", __func__, state);
-
- switch (state) {
- case CM_STATE_INIT:
- state = CM_STATE_MSG_RECV;
- break;
- case CM_STATE_MSG_DISPATCH:
- cm->cm_version = CM_VERSION;
- error = cm_send(fd, buf);
- if (error)
- syslog(LOG_WARNING,
- "<%s> cm_send()", __func__);
- state = CM_STATE_EOM;
- break;
- case CM_STATE_ACK_WAIT:
- error = cm_recv(fd, buf);
- if (error) {
- syslog(LOG_ERR,
- "<%s> cm_recv()", __func__);
- close(fd);
- return (-1);
- }
-
- switch (cm->cm_type) {
- case CM_TYPE_ACK:
- break;
- case CM_TYPE_ERR:
- syslog(LOG_DEBUG,
- "<%s> CM_TYPE_ERR", __func__);
- close(fd);
- return (-1);
- default:
- syslog(LOG_DEBUG,
- "<%s> unknown status", __func__);
- close(fd);
- return (-1);
- }
- state = CM_STATE_EOM;
- break;
- case CM_STATE_MSG_RECV:
- error = cm_recv(fd, buf);
-
- if (error) {
- syslog(LOG_ERR,
- "<%s> cm_recv()", __func__);
- close(fd);
- return (-1);
- }
- memset(&cp, 0, sizeof(cp));
-
- syslog(LOG_DEBUG,
- "<%s> cm->cm_type = %d", __func__, cm->cm_type);
- syslog(LOG_DEBUG,
- "<%s> cm->cm_len = %zu", __func__, cm->cm_len);
-
- switch (cm->cm_type) {
- case CM_TYPE_EOM:
- state = CM_STATE_EOM;
- case CM_TYPE_NUL:
- cm->cm_type = CM_TYPE_ACK;
- cm->cm_len = sizeof(*cm);
- break;
- case CM_TYPE_REQ_GET_PROP:
- cm_bin2pl(msg, &cp);
- error = cm_getprop(&cp);
- if (error) {
- cm->cm_type = CM_TYPE_ERR;
- cm->cm_len = sizeof(*cm);
- } else {
- cm->cm_type = CM_TYPE_ACK;
- cm->cm_len = sizeof(*cm);
- cm->cm_len += cm_pl2bin(msg, &cp);
- }
- if (cp.cp_val != NULL)
- free(cp.cp_val);
- break;
- case CM_TYPE_REQ_SET_PROP:
- cm_bin2pl(msg, &cp);
- error = cm_setprop(&cp);
- if (error) {
- cm->cm_type = CM_TYPE_ERR;
- cm->cm_len = sizeof(*cm);
- } else {
- cm->cm_type = CM_TYPE_ACK;
- cm->cm_len = sizeof(*cm);
- }
- break;
- default:
- cm->cm_type = CM_TYPE_ERR;
- cm->cm_len = sizeof(*cm);
- }
-
- switch (cm->cm_type) {
- case CM_TYPE_ERR:
- case CM_TYPE_ACK:
- state = CM_STATE_MSG_DISPATCH;
- break;
- }
- }
- }
- syslog(LOG_DEBUG, "<%s> leave", __func__);
-
- return (0);
-}
diff --git a/usr.sbin/rtadvd/control_server.h b/usr.sbin/rtadvd/control_server.h
deleted file mode 100644
index 76fe9cd..0000000
--- a/usr.sbin/rtadvd/control_server.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-int cm_getprop(struct ctrl_msg_pl *);
-int cm_setprop(struct ctrl_msg_pl *);
-
-int cm_handler_server(int);
-
-void set_do_reload(int);
-void set_do_reload_ifname(char *);
-void set_do_shutdown(int);
-void reset_do_reload(void);
-void reset_do_shutdown(void);
-int is_do_reload(void);
-char *reload_ifname(void);
-int is_do_shutdown(void);
diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c
deleted file mode 100644
index dc6ac8e..0000000
--- a/usr.sbin/rtadvd/if.c
+++ /dev/null
@@ -1,748 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: if.c,v 1.17 2001/01/21 15:27:30 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-#include <net/ethernet.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <netinet6/nd6.h>
-#include <unistd.h>
-#include <errno.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "pathnames.h"
-#include "rtadvd.h"
-#include "if.h"
-
-#define ROUNDUP(a, size) \
- (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
-
-#define NEXT_SA(ap) \
- (ap) = (struct sockaddr *)((caddr_t)(ap) + \
- ((ap)->sa_len ? ROUNDUP((ap)->sa_len, sizeof(u_long)) : \
- sizeof(u_long)))
-
-struct sockaddr_in6 sin6_linklocal_allnodes = {
- .sin6_len = sizeof(sin6_linklocal_allnodes),
- .sin6_family = AF_INET6,
- .sin6_addr = IN6ADDR_LINKLOCAL_ALLNODES_INIT,
-};
-
-struct sockaddr_in6 sin6_linklocal_allrouters = {
- .sin6_len = sizeof(sin6_linklocal_allrouters),
- .sin6_family = AF_INET6,
- .sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT,
-};
-
-struct sockaddr_in6 sin6_sitelocal_allrouters = {
- .sin6_len = sizeof(sin6_sitelocal_allrouters),
- .sin6_family = AF_INET6,
- .sin6_addr = IN6ADDR_SITELOCAL_ALLROUTERS_INIT,
-};
-
-struct sockinfo sock = { .si_fd = -1, .si_name = NULL };
-struct sockinfo rtsock = { .si_fd = -1, .si_name = NULL };
-struct sockinfo ctrlsock = { .si_fd = -1, .si_name = _PATH_CTRL_SOCK };
-
-char *mcastif;
-
-static void get_rtaddrs(int, struct sockaddr *,
- struct sockaddr **);
-static struct if_msghdr *get_next_msghdr(struct if_msghdr *,
- struct if_msghdr *);
-
-static void
-get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
-{
- int i;
-
- for (i = 0; i < RTAX_MAX; i++) {
- if (addrs & (1 << i)) {
- rti_info[i] = sa;
- NEXT_SA(sa);
- }
- else
- rti_info[i] = NULL;
- }
-}
-
-#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
-int
-lladdropt_length(struct sockaddr_dl *sdl)
-{
- switch (sdl->sdl_type) {
- case IFT_ETHER:
- return (ROUNDUP8(ETHER_ADDR_LEN + 2));
- default:
- return (0);
- }
-}
-
-void
-lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)
-{
- char *addr;
-
- ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */
-
- switch (sdl->sdl_type) {
- case IFT_ETHER:
- ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3;
- addr = (char *)(ndopt + 1);
- memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN);
- break;
- default:
- syslog(LOG_ERR, "<%s> unsupported link type(%d)",
- __func__, sdl->sdl_type);
- exit(1);
- }
-
- return;
-}
-
-int
-rtbuf_len(void)
-{
- size_t len;
- int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET6, NET_RT_DUMP, 0};
-
- if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
- return (-1);
-
- return (len);
-}
-
-#define FILTER_MATCH(type, filter) ((0x1 << type) & filter)
-#define SIN6(s) ((struct sockaddr_in6 *)(s))
-#define SDL(s) ((struct sockaddr_dl *)(s))
-char *
-get_next_msg(char *buf, char *lim, int ifindex, size_t *lenp, int filter)
-{
- struct rt_msghdr *rtm;
- struct ifa_msghdr *ifam;
- struct sockaddr *sa, *dst, *gw, *ifa, *rti_info[RTAX_MAX];
-
- *lenp = 0;
- for (rtm = (struct rt_msghdr *)buf;
- rtm < (struct rt_msghdr *)lim;
- rtm = (struct rt_msghdr *)(((char *)rtm) + rtm->rtm_msglen)) {
- /* just for safety */
- if (!rtm->rtm_msglen) {
- syslog(LOG_WARNING, "<%s> rtm_msglen is 0 "
- "(buf=%p lim=%p rtm=%p)", __func__,
- buf, lim, rtm);
- break;
- }
- if (((struct rt_msghdr *)buf)->rtm_version != RTM_VERSION) {
- syslog(LOG_WARNING,
- "<%s> routing message version mismatch "
- "(buf=%p lim=%p rtm=%p)", __func__,
- buf, lim, rtm);
- continue;
- }
-
- if (FILTER_MATCH(rtm->rtm_type, filter) == 0)
- continue;
-
- switch (rtm->rtm_type) {
- case RTM_GET:
- case RTM_ADD:
- case RTM_DELETE:
- /* address related checks */
- sa = (struct sockaddr *)(rtm + 1);
- get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
- if ((dst = rti_info[RTAX_DST]) == NULL ||
- dst->sa_family != AF_INET6)
- continue;
-
- if (IN6_IS_ADDR_LINKLOCAL(&SIN6(dst)->sin6_addr) ||
- IN6_IS_ADDR_MULTICAST(&SIN6(dst)->sin6_addr))
- continue;
-
- if ((gw = rti_info[RTAX_GATEWAY]) == NULL ||
- gw->sa_family != AF_LINK)
- continue;
- if (ifindex && SDL(gw)->sdl_index != ifindex)
- continue;
-
- if (rti_info[RTAX_NETMASK] == NULL)
- continue;
-
- /* found */
- *lenp = rtm->rtm_msglen;
- return (char *)rtm;
- /* NOTREACHED */
- case RTM_NEWADDR:
- case RTM_DELADDR:
- ifam = (struct ifa_msghdr *)rtm;
-
- /* address related checks */
- sa = (struct sockaddr *)(ifam + 1);
- get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
- if ((ifa = rti_info[RTAX_IFA]) == NULL ||
- (ifa->sa_family != AF_INET &&
- ifa->sa_family != AF_INET6))
- continue;
-
- if (ifa->sa_family == AF_INET6 &&
- (IN6_IS_ADDR_LINKLOCAL(&SIN6(ifa)->sin6_addr) ||
- IN6_IS_ADDR_MULTICAST(&SIN6(ifa)->sin6_addr)))
- continue;
-
- if (ifindex && ifam->ifam_index != ifindex)
- continue;
-
- /* found */
- *lenp = ifam->ifam_msglen;
- return (char *)rtm;
- /* NOTREACHED */
- case RTM_IFINFO:
- case RTM_IFANNOUNCE:
- /* found */
- *lenp = rtm->rtm_msglen;
- return (char *)rtm;
- /* NOTREACHED */
- }
- }
-
- return ((char *)rtm);
-}
-#undef FILTER_MATCH
-
-struct in6_addr *
-get_addr(char *buf)
-{
- struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
-
- sa = (struct sockaddr *)(rtm + 1);
- get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
-
- return (&SIN6(rti_info[RTAX_DST])->sin6_addr);
-}
-
-int
-get_rtm_ifindex(char *buf)
-{
- struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
-
- sa = (struct sockaddr *)(rtm + 1);
- get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
-
- return (((struct sockaddr_dl *)rti_info[RTAX_GATEWAY])->sdl_index);
-}
-
-int
-get_prefixlen(char *buf)
-{
- struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
- char *p, *lim;
-
- sa = (struct sockaddr *)(rtm + 1);
- get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
- sa = rti_info[RTAX_NETMASK];
-
- p = (char *)(&SIN6(sa)->sin6_addr);
- lim = (char *)sa + sa->sa_len;
- return prefixlen(p, lim);
-}
-
-int
-prefixlen(unsigned char *p, unsigned char *lim)
-{
- int masklen;
-
- for (masklen = 0; p < lim; p++) {
- switch (*p) {
- case 0xff:
- masklen += 8;
- break;
- case 0xfe:
- masklen += 7;
- break;
- case 0xfc:
- masklen += 6;
- break;
- case 0xf8:
- masklen += 5;
- break;
- case 0xf0:
- masklen += 4;
- break;
- case 0xe0:
- masklen += 3;
- break;
- case 0xc0:
- masklen += 2;
- break;
- case 0x80:
- masklen += 1;
- break;
- case 0x00:
- break;
- default:
- return (-1);
- }
- }
-
- return (masklen);
-}
-
-struct ifinfo *
-update_persist_ifinfo(struct ifilist_head_t *ifi_head, const char *ifname)
-{
- struct ifinfo *ifi;
- int ifindex;
-
- ifi = NULL;
- ifindex = if_nametoindex(ifname);
- TAILQ_FOREACH(ifi, ifi_head, ifi_next) {
- if (ifindex != 0) {
- if (ifindex == ifi->ifi_ifindex)
- break;
- } else {
- if (strncmp(ifname, ifi->ifi_ifname,
- sizeof(ifi->ifi_ifname)) == 0)
- break;
- }
- }
-
- if (ifi == NULL) {
- /* A new ifinfo element is needed. */
- syslog(LOG_DEBUG, "<%s> new entry: %s", __func__,
- ifname);
-
- ELM_MALLOC(ifi, exit(1));
- ifi->ifi_ifindex = 0;
- strlcpy(ifi->ifi_ifname, ifname, sizeof(ifi->ifi_ifname));
- ifi->ifi_rainfo = NULL;
- ifi->ifi_state = IFI_STATE_UNCONFIGURED;
- TAILQ_INSERT_TAIL(ifi_head, ifi, ifi_next);
- }
-
- ifi->ifi_persist = 1;
-
- syslog(LOG_DEBUG, "<%s> %s is marked PERSIST", __func__,
- ifi->ifi_ifname);
- syslog(LOG_DEBUG, "<%s> %s is state = %d", __func__,
- ifi->ifi_ifname, ifi->ifi_state);
- return (ifi);
-}
-
-int
-update_ifinfo_nd_flags(struct ifinfo *ifi)
-{
- struct in6_ndireq nd;
- int s;
- int error;
-
- if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR,
- "<%s> socket() failed.", __func__);
- return (1);
- }
- /* ND flags */
- memset(&nd, 0, sizeof(nd));
- strlcpy(nd.ifname, ifi->ifi_ifname,
- sizeof(nd.ifname));
- error = ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd);
- if (error) {
- close(s);
- if (errno != EPFNOSUPPORT)
- syslog(LOG_ERR, "<%s> ioctl() failed.", __func__);
- return (1);
- }
- ifi->ifi_nd_flags = nd.ndi.flags;
- close(s);
-
- return (0);
-}
-
-struct ifinfo *
-update_ifinfo(struct ifilist_head_t *ifi_head, int ifindex)
-{
- struct if_msghdr *ifm;
- struct ifinfo *ifi = NULL;
- struct sockaddr *sa;
- struct sockaddr *rti_info[RTAX_MAX];
- char *msg;
- size_t len;
- char *lim;
- int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_IFLIST, 0 };
- int error;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), NULL, &len, NULL, 0) <
- 0) {
- syslog(LOG_ERR,
- "<%s> sysctl: NET_RT_IFLIST size get failed", __func__);
- exit(1);
- }
- if ((msg = malloc(len)) == NULL) {
- syslog(LOG_ERR, "<%s> malloc failed", __func__);
- exit(1);
- }
- if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), msg, &len, NULL, 0) <
- 0) {
- syslog(LOG_ERR,
- "<%s> sysctl: NET_RT_IFLIST get failed", __func__);
- exit(1);
- }
-
- lim = msg + len;
- for (ifm = (struct if_msghdr *)msg;
- ifm != NULL && ifm < (struct if_msghdr *)lim;
- ifm = get_next_msghdr(ifm,(struct if_msghdr *)lim)) {
- int ifi_new;
-
- syslog(LOG_DEBUG, "<%s> ifm = %p, lim = %p, diff = %zu",
- __func__, ifm, lim, (char *)lim - (char *)ifm);
-
- if (ifm->ifm_version != RTM_VERSION) {
- syslog(LOG_ERR,
- "<%s> ifm_vesrion mismatch", __func__);
- exit(1);
- }
- if (ifm->ifm_msglen == 0) {
- syslog(LOG_WARNING,
- "<%s> ifm_msglen is 0", __func__);
- free(msg);
- return (NULL);
- }
-
- ifi_new = 0;
- if (ifm->ifm_type == RTM_IFINFO) {
- struct ifreq ifr;
- int s;
- char ifname[IFNAMSIZ];
-
- syslog(LOG_DEBUG, "<%s> RTM_IFINFO found. "
- "ifm_index = %d, ifindex = %d",
- __func__, ifm->ifm_index, ifindex);
-
- /* when ifindex is specified */
- if (ifindex != UPDATE_IFINFO_ALL &&
- ifindex != ifm->ifm_index)
- continue;
-
- /* lookup an entry with the same ifindex */
- TAILQ_FOREACH(ifi, ifi_head, ifi_next) {
- if (ifm->ifm_index == ifi->ifi_ifindex)
- break;
- if_indextoname(ifm->ifm_index, ifname);
- if (strncmp(ifname, ifi->ifi_ifname,
- sizeof(ifname)) == 0)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_DEBUG,
- "<%s> new entry for idx=%d",
- __func__, ifm->ifm_index);
- ELM_MALLOC(ifi, exit(1));
- ifi->ifi_rainfo = NULL;
- ifi->ifi_state = IFI_STATE_UNCONFIGURED;
- ifi->ifi_persist = 0;
- ifi_new = 1;
- }
- /* ifindex */
- ifi->ifi_ifindex = ifm->ifm_index;
-
- /* ifname */
- if_indextoname(ifm->ifm_index, ifi->ifi_ifname);
- if (ifi->ifi_ifname == NULL) {
- syslog(LOG_WARNING,
- "<%s> ifname not found (idx=%d)",
- __func__, ifm->ifm_index);
- if (ifi_new)
- free(ifi);
- continue;
- }
-
- if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR,
- "<%s> socket() failed.", __func__);
- if (ifi_new)
- free(ifi);
- continue;
- }
-
- /* MTU */
- ifi->ifi_phymtu = ifm->ifm_data.ifi_mtu;
- if (ifi->ifi_phymtu == 0) {
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_addr.sa_family = AF_INET6;
- strlcpy(ifr.ifr_name, ifi->ifi_ifname,
- sizeof(ifr.ifr_name));
- error = ioctl(s, SIOCGIFMTU, (caddr_t)&ifr);
- if (error) {
- close(s);
- syslog(LOG_ERR,
- "<%s> ioctl() failed.",
- __func__);
- if (ifi_new)
- free(ifi);
- continue;
- }
- ifi->ifi_phymtu = ifr.ifr_mtu;
- if (ifi->ifi_phymtu == 0) {
- syslog(LOG_WARNING,
- "<%s> no interface mtu info"
- " on %s. %d will be used.",
- __func__, ifi->ifi_ifname,
- IPV6_MMTU);
- ifi->ifi_phymtu = IPV6_MMTU;
- }
- }
- close(s);
-
- /* ND flags */
- error = update_ifinfo_nd_flags(ifi);
- if (error) {
- if (ifi_new)
- free(ifi);
- continue;
- }
-
- /* SDL */
- sa = (struct sockaddr *)(ifm + 1);
- get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
- if ((sa = rti_info[RTAX_IFP]) != NULL) {
- if (sa->sa_family == AF_LINK) {
- memcpy(&ifi->ifi_sdl,
- (struct sockaddr_dl *)sa,
- sizeof(ifi->ifi_sdl));
- }
- } else
- memset(&ifi->ifi_sdl, 0,
- sizeof(ifi->ifi_sdl));
-
- /* flags */
- ifi->ifi_flags = ifm->ifm_flags;
-
- /* type */
- ifi->ifi_type = ifm->ifm_type;
- } else {
- syslog(LOG_ERR,
- "out of sync parsing NET_RT_IFLIST\n"
- "expected %d, got %d\n msglen = %d\n",
- RTM_IFINFO, ifm->ifm_type, ifm->ifm_msglen);
- exit(1);
- }
-
- if (ifi_new) {
- syslog(LOG_DEBUG,
- "<%s> adding %s(idx=%d) to ifilist",
- __func__, ifi->ifi_ifname, ifi->ifi_ifindex);
- TAILQ_INSERT_TAIL(ifi_head, ifi, ifi_next);
- }
- }
- free(msg);
-
- if (mcastif != NULL) {
- error = sock_mc_rr_update(&sock, mcastif);
- if (error)
- exit(1);
- }
-
- return (ifi);
-}
-
-static struct if_msghdr *
-get_next_msghdr(struct if_msghdr *ifm, struct if_msghdr *lim)
-{
- struct ifa_msghdr *ifam;
-
- for (ifam = (struct ifa_msghdr *)((char *)ifm + ifm->ifm_msglen);
- ifam < (struct ifa_msghdr *)lim;
- ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen)) {
- if (!ifam->ifam_msglen) {
- syslog(LOG_WARNING,
- "<%s> ifa_msglen is 0", __func__);
- return (NULL);
- }
- if (ifam->ifam_type != RTM_NEWADDR)
- break;
- }
-
- return ((struct if_msghdr *)ifam);
-}
-
-int
-getinet6sysctl(int code)
-{
- int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 };
- int value;
- size_t size;
-
- mib[3] = code;
- size = sizeof(value);
- if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0)
- < 0) {
- syslog(LOG_ERR, "<%s>: failed to get ip6 sysctl(%d): %s",
- __func__, code,
- strerror(errno));
- return (-1);
- }
- else
- return (value);
-}
-
-
-int
-sock_mc_join(struct sockinfo *s, int ifindex)
-{
- struct ipv6_mreq mreq;
- char ifname[IFNAMSIZ];
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (ifindex == 0)
- return (1);
-
- /*
- * join all routers multicast address on each advertising
- * interface.
- */
- memset(&mreq, 0, sizeof(mreq));
- /* XXX */
- memcpy(&mreq.ipv6mr_multiaddr.s6_addr,
- &sin6_linklocal_allrouters.sin6_addr,
- sizeof(mreq.ipv6mr_multiaddr.s6_addr));
-
- mreq.ipv6mr_interface = ifindex;
- if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq,
- sizeof(mreq)) < 0) {
- syslog(LOG_ERR,
- "<%s> IPV6_JOIN_GROUP(link) on %s: %s",
- __func__, if_indextoname(ifindex, ifname),
- strerror(errno));
- return (1);
- }
- syslog(LOG_DEBUG,
- "<%s> %s: join link-local all-routers MC group",
- __func__, if_indextoname(ifindex, ifname));
-
- return (0);
-}
-
-int
-sock_mc_leave(struct sockinfo *s, int ifindex)
-{
- struct ipv6_mreq mreq;
- char ifname[IFNAMSIZ];
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (ifindex == 0)
- return (1);
-
- /*
- * join all routers multicast address on each advertising
- * interface.
- */
-
- memset(&mreq, 0, sizeof(mreq));
- /* XXX */
- memcpy(&mreq.ipv6mr_multiaddr.s6_addr,
- &sin6_linklocal_allrouters.sin6_addr,
- sizeof(mreq.ipv6mr_multiaddr.s6_addr));
-
- mreq.ipv6mr_interface = ifindex;
- if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq,
- sizeof(mreq)) < 0) {
- syslog(LOG_ERR,
- "<%s> IPV6_JOIN_LEAVE(link) on %s: %s",
- __func__, if_indextoname(ifindex, ifname),
- strerror(errno));
- return (1);
- }
- syslog(LOG_DEBUG,
- "<%s> %s: leave link-local all-routers MC group",
- __func__, if_indextoname(ifindex, ifname));
-
- return (0);
-}
-
-int
-sock_mc_rr_update(struct sockinfo *s, char *mif)
-{
- struct ipv6_mreq mreq;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (mif == NULL)
- return (1);
- /*
- * When attending router renumbering, join all-routers site-local
- * multicast group.
- */
- /* XXX */
- memcpy(&mreq.ipv6mr_multiaddr.s6_addr,
- &sin6_sitelocal_allrouters.sin6_addr,
- sizeof(mreq.ipv6mr_multiaddr.s6_addr));
- if ((mreq.ipv6mr_interface = if_nametoindex(mif)) == 0) {
- syslog(LOG_ERR,
- "<%s> invalid interface: %s",
- __func__, mif);
- return (1);
- }
-
- if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
- &mreq, sizeof(mreq)) < 0) {
- syslog(LOG_ERR,
- "<%s> IPV6_JOIN_GROUP(site) on %s: %s",
- __func__, mif, strerror(errno));
- return (1);
- }
-
- syslog(LOG_DEBUG,
- "<%s> %s: join site-local all-routers MC group",
- __func__, mif);
-
- return (0);
-}
diff --git a/usr.sbin/rtadvd/if.h b/usr.sbin/rtadvd/if.h
deleted file mode 100644
index 6efdd56..0000000
--- a/usr.sbin/rtadvd/if.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: if.h,v 1.10 2003/02/24 11:29:10 ono Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define UPDATE_IFINFO_ALL 0
-
-struct sockinfo {
- int si_fd;
- const char *si_name;
-};
-
-extern struct sockinfo sock;
-extern struct sockinfo rtsock;
-extern struct sockinfo ctrlsock;
-
-int lladdropt_length(struct sockaddr_dl *);
-void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *);
-int rtbuf_len(void);
-char *get_next_msg(char *, char *, int, size_t *, int);
-struct in6_addr *get_addr(char *);
-int get_rtm_ifindex(char *);
-int get_prefixlen(char *);
-int prefixlen(unsigned char *, unsigned char *);
-
-struct ifinfo *update_ifinfo(struct ifilist_head_t *, int);
-int update_ifinfo_nd_flags(struct ifinfo *);
-struct ifinfo *update_persist_ifinfo(struct ifilist_head_t *,
- const char *);
-
-int sock_mc_join(struct sockinfo *, int);
-int sock_mc_leave(struct sockinfo *, int);
-int sock_mc_rr_update(struct sockinfo *, char *);
-int getinet6sysctl(int);
diff --git a/usr.sbin/rtadvd/pathnames.h b/usr.sbin/rtadvd/pathnames.h
deleted file mode 100644
index 248ee19..0000000
--- a/usr.sbin/rtadvd/pathnames.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* $KAME: pathnames.h,v 1.2 2000/05/16 13:34:13 itojun Exp $ */
-/* $FreeBSD$ */
-
-#define _PATH_RTADVDCONF "/etc/rtadvd.conf"
-#define _PATH_RTADVDPID "/var/run/rtadvd.pid"
-#define _PATH_CTRL_SOCK "/var/run/rtadvd.sock"
diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c
deleted file mode 100644
index eede4b6..0000000
--- a/usr.sbin/rtadvd/rrenum.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: rrenum.c,v 1.12 2002/06/10 19:59:47 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/icmp6.h>
-
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <syslog.h>
-#include "rtadvd.h"
-#include "rrenum.h"
-#include "if.h"
-
-#define RR_ISSET_SEGNUM(segnum_bits, segnum) \
- ((((segnum_bits)[(segnum) >> 5]) & (1 << ((segnum) & 31))) != 0)
-#define RR_SET_SEGNUM(segnum_bits, segnum) \
- (((segnum_bits)[(segnum) >> 5]) |= (1 << ((segnum) & 31)))
-
-struct rr_operation {
- u_long rro_seqnum;
- u_long rro_segnum_bits[8];
-};
-
-static struct rr_operation rro;
-static int rr_rcvifindex;
-static int rrcmd2pco[RPM_PCO_MAX] = {
- 0,
- SIOCAIFPREFIX_IN6,
- SIOCCIFPREFIX_IN6,
- SIOCSGIFPREFIX_IN6
-};
-static int s = -1;
-
-/*
- * Check validity of a Prefix Control Operation(PCO).
- * return 0 on success, 1 on failure.
- */
-static int
-rr_pco_check(int len, struct rr_pco_match *rpm)
-{
- struct rr_pco_use *rpu, *rpulim;
- int checklen;
-
- /* rpm->rpm_len must be (4N * 3) as router-renum-05.txt */
- if ((rpm->rpm_len - 3) < 0 || /* must be at least 3 */
- (rpm->rpm_len - 3) & 0x3) { /* must be multiple of 4 */
- syslog(LOG_WARNING, "<%s> rpm_len %d is not 4N * 3",
- __func__, rpm->rpm_len);
- return (1);
- }
- /* rpm->rpm_code must be valid value */
- switch (rpm->rpm_code) {
- case RPM_PCO_ADD:
- case RPM_PCO_CHANGE:
- case RPM_PCO_SETGLOBAL:
- break;
- default:
- syslog(LOG_WARNING, "<%s> unknown rpm_code %d", __func__,
- rpm->rpm_code);
- return (1);
- }
- /* rpm->rpm_matchlen must be 0 to 128 inclusive */
- if (rpm->rpm_matchlen > 128) {
- syslog(LOG_WARNING, "<%s> rpm_matchlen %d is over 128",
- __func__, rpm->rpm_matchlen);
- return (1);
- }
-
- /*
- * rpu->rpu_uselen, rpu->rpu_keeplen, and sum of them must be
- * between 0 and 128 inclusive
- */
- for (rpu = (struct rr_pco_use *)(rpm + 1),
- rpulim = (struct rr_pco_use *)((char *)rpm + len);
- rpu < rpulim;
- rpu += 1) {
- checklen = rpu->rpu_uselen;
- checklen += rpu->rpu_keeplen;
- /*
- * omit these check, because either of rpu_uselen
- * and rpu_keeplen is unsigned char
- * (128 > rpu_uselen > 0)
- * (128 > rpu_keeplen > 0)
- * (rpu_uselen + rpu_keeplen > 0)
- */
- if (checklen > 128) {
- syslog(LOG_WARNING, "<%s> sum of rpu_uselen %d and"
- " rpu_keeplen %d is %d(over 128)",
- __func__, rpu->rpu_uselen, rpu->rpu_keeplen,
- rpu->rpu_uselen + rpu->rpu_keeplen);
- return (1);
- }
- }
- return (0);
-}
-
-static void
-do_use_prefix(int len, struct rr_pco_match *rpm,
- struct in6_rrenumreq *irr, int ifindex)
-{
- struct rr_pco_use *rpu, *rpulim;
- struct rainfo *rai;
- struct ifinfo *ifi;
- struct prefix *pfx;
-
- rpu = (struct rr_pco_use *)(rpm + 1);
- rpulim = (struct rr_pco_use *)((char *)rpm + len);
-
- if (rpu == rpulim) { /* no use prefix */
- if (rpm->rpm_code == RPM_PCO_ADD)
- return;
-
- irr->irr_u_uselen = 0;
- irr->irr_u_keeplen = 0;
- irr->irr_raf_mask_onlink = 0;
- irr->irr_raf_mask_auto = 0;
- irr->irr_vltime = 0;
- irr->irr_pltime = 0;
- memset(&irr->irr_flags, 0, sizeof(irr->irr_flags));
- irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */
- irr->irr_useprefix.sin6_family = 0;
- irr->irr_useprefix.sin6_addr = in6addr_any;
- if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 &&
- errno != EADDRNOTAVAIL)
- syslog(LOG_ERR, "<%s> ioctl: %s", __func__,
- strerror(errno));
- return;
- }
-
- for (rpu = (struct rr_pco_use *)(rpm + 1),
- rpulim = (struct rr_pco_use *)((char *)rpm + len);
- rpu < rpulim;
- rpu += 1) {
- /* init in6_rrenumreq fields */
- irr->irr_u_uselen = rpu->rpu_uselen;
- irr->irr_u_keeplen = rpu->rpu_keeplen;
- irr->irr_raf_mask_onlink =
- !!(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK);
- irr->irr_raf_mask_auto =
- !!(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_AUTO);
- irr->irr_vltime = ntohl(rpu->rpu_vltime);
- irr->irr_pltime = ntohl(rpu->rpu_pltime);
- irr->irr_raf_onlink =
- (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK) == 0 ?
- 0 : 1;
- irr->irr_raf_auto =
- (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO) == 0 ?
- 0 : 1;
- irr->irr_rrf_decrvalid =
- (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME) == 0 ?
- 0 : 1;
- irr->irr_rrf_decrprefd =
- (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) == 0 ?
- 0 : 1;
- irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix);
- irr->irr_useprefix.sin6_family = AF_INET6;
- irr->irr_useprefix.sin6_addr = rpu->rpu_prefix;
-
- if (ioctl(s, rrcmd2pco[rpm->rpm_code], (caddr_t)irr) < 0 &&
- errno != EADDRNOTAVAIL)
- syslog(LOG_ERR, "<%s> ioctl: %s", __func__,
- strerror(errno));
-
- /* very adhoc: should be rewritten */
- if (rpm->rpm_code == RPM_PCO_CHANGE &&
- IN6_ARE_ADDR_EQUAL(&rpm->rpm_prefix, &rpu->rpu_prefix) &&
- rpm->rpm_matchlen == rpu->rpu_uselen &&
- rpu->rpu_uselen == rpu->rpu_keeplen) {
- ifi = if_indextoifinfo(ifindex);
- if (ifi == NULL || ifi->ifi_rainfo == NULL)
- continue; /* non-advertising IF */
- rai = ifi->ifi_rainfo;
-
- TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
- struct timespec now;
-
- if (prefix_match(&pfx->pfx_prefix,
- pfx->pfx_prefixlen, &rpm->rpm_prefix,
- rpm->rpm_matchlen)) {
- /* change parameters */
- pfx->pfx_validlifetime =
- ntohl(rpu->rpu_vltime);
- pfx->pfx_preflifetime =
- ntohl(rpu->rpu_pltime);
- if (irr->irr_rrf_decrvalid) {
- clock_gettime(CLOCK_MONOTONIC_FAST,
- &now);
- pfx->pfx_vltimeexpire =
- now.tv_sec +
- pfx->pfx_validlifetime;
- } else
- pfx->pfx_vltimeexpire = 0;
- if (irr->irr_rrf_decrprefd) {
- clock_gettime(CLOCK_MONOTONIC_FAST,
- &now);
- pfx->pfx_pltimeexpire =
- now.tv_sec +
- pfx->pfx_preflifetime;
- } else
- pfx->pfx_pltimeexpire = 0;
- }
- }
- }
- }
-}
-
-/*
- * process a Prefix Control Operation(PCO).
- * return 0 on success, 1 on failure
- */
-static int
-do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm)
-{
- int ifindex = 0;
- struct in6_rrenumreq irr;
- struct ifinfo *ifi;
-
- if ((rr_pco_check(len, rpm) != 0))
- return (1);
-
- if (s == -1 && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "<%s> socket: %s", __func__,
- strerror(errno));
- exit(1);
- }
-
- memset(&irr, 0, sizeof(irr));
- irr.irr_origin = PR_ORIG_RR;
- irr.irr_m_len = rpm->rpm_matchlen;
- irr.irr_m_minlen = rpm->rpm_minlen;
- irr.irr_m_maxlen = rpm->rpm_maxlen;
- irr.irr_matchprefix.sin6_len = sizeof(irr.irr_matchprefix);
- irr.irr_matchprefix.sin6_family = AF_INET6;
- irr.irr_matchprefix.sin6_addr = rpm->rpm_prefix;
-
- while (if_indextoname(++ifindex, irr.irr_name)) {
- ifi = if_indextoifinfo(ifindex);
- if (ifi == NULL) {
- syslog(LOG_ERR, "<%s> ifindex not found.",
- __func__);
- return (1);
- }
- /*
- * if ICMP6_RR_FLAGS_FORCEAPPLY(A flag) is 0 and
- * IFF_UP is off, the interface is not applied
- */
- if ((rr->rr_flags & ICMP6_RR_FLAGS_FORCEAPPLY) == 0 &&
- (ifi->ifi_flags & IFF_UP) == 0)
- continue;
- /* TODO: interface scope check */
- do_use_prefix(len, rpm, &irr, ifindex);
- }
- if (errno == ENXIO)
- return (0);
- else if (errno) {
- syslog(LOG_ERR, "<%s> if_indextoname: %s", __func__,
- strerror(errno));
- return (1);
- }
- return (0);
-}
-
-/*
- * call do_pco() for each Prefix Control Operations(PCOs) in a received
- * Router Renumbering Command packet.
- * return 0 on success, 1 on failure
- */
-static int
-do_rr(int len, struct icmp6_router_renum *rr)
-{
- struct rr_pco_match *rpm;
- char *cp, *lim;
-
- lim = (char *)rr + len;
- cp = (char *)(rr + 1);
- len -= sizeof(struct icmp6_router_renum);
-
- update_ifinfo(&ifilist, UPDATE_IFINFO_ALL);
-
- while (cp < lim) {
- int rpmlen;
-
- rpm = (struct rr_pco_match *)cp;
- if ((size_t)len < sizeof(struct rr_pco_match)) {
- tooshort:
- syslog(LOG_ERR, "<%s> pkt too short. left len = %d. "
- "garbage at end of pkt?", __func__, len);
- return (1);
- }
- rpmlen = rpm->rpm_len << 3;
- if (len < rpmlen)
- goto tooshort;
-
- if (do_pco(rr, rpmlen, rpm)) {
- syslog(LOG_WARNING, "<%s> invalid PCO", __func__);
- goto next;
- }
-
- next:
- cp += rpmlen;
- len -= rpmlen;
- }
-
- return (0);
-}
-
-/*
- * check validity of a router renumbering command packet
- * return 0 on success, 1 on failure
- */
-static int
-rr_command_check(int len, struct icmp6_router_renum *rr, struct in6_addr *from,
- struct in6_addr *dst)
-{
- u_char ntopbuf[INET6_ADDRSTRLEN];
-
- /* omit rr minimal length check. hope kernel have done it. */
- /* rr_command length check */
- if ((size_t)len < (sizeof(struct icmp6_router_renum) +
- sizeof(struct rr_pco_match))) {
- syslog(LOG_ERR, "<%s> rr_command len %d is too short",
- __func__, len);
- return (1);
- }
-
- /* destination check. only for multicast. omit unicast check. */
- if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) &&
- !IN6_IS_ADDR_MC_SITELOCAL(dst)) {
- syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal",
- __func__,
- inet_ntop(AF_INET6, dst, ntopbuf, sizeof(ntopbuf)));
- return (1);
- }
-
- /* seqnum and segnum check */
- if (rro.rro_seqnum > rr->rr_seqnum) {
- syslog(LOG_WARNING,
- "<%s> rcvd old seqnum %d from %s",
- __func__, (u_int32_t)ntohl(rr->rr_seqnum),
- inet_ntop(AF_INET6, from, ntopbuf, sizeof(ntopbuf)));
- return (1);
- }
- if (rro.rro_seqnum == rr->rr_seqnum &&
- (rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 &&
- RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) {
- if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0)
- syslog(LOG_WARNING,
- "<%s> rcvd duped segnum %d from %s",
- __func__, rr->rr_segnum, inet_ntop(AF_INET6, from,
- ntopbuf, sizeof(ntopbuf)));
- return (0);
- }
-
- /* update seqnum */
- if (rro.rro_seqnum != rr->rr_seqnum) {
- /* then must be "<" */
-
- /* init rro_segnum_bits */
- memset(rro.rro_segnum_bits, 0,
- sizeof(rro.rro_segnum_bits));
- }
- rro.rro_seqnum = rr->rr_seqnum;
-
- return (0);
-}
-
-static void
-rr_command_input(int len, struct icmp6_router_renum *rr,
- struct in6_addr *from, struct in6_addr *dst)
-{
- /* rr_command validity check */
- if (rr_command_check(len, rr, from, dst))
- goto failed;
- if ((rr->rr_flags & (ICMP6_RR_FLAGS_TEST|ICMP6_RR_FLAGS_REQRESULT)) ==
- ICMP6_RR_FLAGS_TEST)
- return;
-
- /* do router renumbering */
- if (do_rr(len, rr))
- goto failed;
-
- /* update segnum */
- RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum);
-
- return;
-
- failed:
- syslog(LOG_ERR, "<%s> received RR was invalid", __func__);
- return;
-}
-
-void
-rr_input(int len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi,
- struct sockaddr_in6 *from, struct in6_addr *dst)
-{
- u_char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
-
- syslog(LOG_DEBUG,
- "<%s> RR received from %s to %s on %s",
- __func__,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf[0] ,sizeof(ntopbuf[0])),
- inet_ntop(AF_INET6, &dst, ntopbuf[1], sizeof(ntopbuf[1])),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
-
- /* packet validation based on Section 4.1 of RFC2894 */
- if ((size_t)len < sizeof(struct icmp6_router_renum)) {
- syslog(LOG_NOTICE,
- "<%s>: RR short message (size %d) from %s to %s on %s",
- __func__, len,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf[0],
- sizeof(ntopbuf[0])),
- inet_ntop(AF_INET6, &dst, ntopbuf[1], sizeof(ntopbuf[1])),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
-
- /*
- * If the IPv6 destination address is neither an All Routers multicast
- * address [AARCH] nor one of the receiving router's unicast addresses,
- * the message MUST be discarded and SHOULD be logged to network
- * management.
- * We rely on the kernel input routine for unicast addresses, and thus
- * check multicast destinations only.
- */
- if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) && !IN6_ARE_ADDR_EQUAL(
- &sin6_sitelocal_allrouters.sin6_addr, &pi->ipi6_addr)) {
- syslog(LOG_NOTICE,
- "<%s>: RR message with invalid destination (%s) "
- "from %s on %s",
- __func__,
- inet_ntop(AF_INET6, &dst, ntopbuf[0], sizeof(ntopbuf[0])),
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf[1],
- sizeof(ntopbuf[1])),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
-
- rr_rcvifindex = pi->ipi6_ifindex;
-
- switch (rr->rr_code) {
- case ICMP6_ROUTER_RENUMBERING_COMMAND:
- rr_command_input(len, rr, &from->sin6_addr, dst);
- /* TODO: send reply msg */
- break;
- case ICMP6_ROUTER_RENUMBERING_RESULT:
- /* RESULT will be processed by rrenumd */
- break;
- case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:
- /* TODO: sequence number reset */
- break;
- default:
- syslog(LOG_ERR, "<%s> received unknown code %d",
- __func__, rr->rr_code);
- break;
-
- }
-
- return;
-}
diff --git a/usr.sbin/rtadvd/rrenum.h b/usr.sbin/rtadvd/rrenum.h
deleted file mode 100644
index 2b20d59..0000000
--- a/usr.sbin/rtadvd/rrenum.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: rrenum.h,v 1.3 2001/01/21 15:37:14 itojun Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-void rr_input(int, struct icmp6_router_renum *, struct in6_pktinfo *,
- struct sockaddr_in6 *, struct in6_addr *);
diff --git a/usr.sbin/rtadvd/rtadvd.8 b/usr.sbin/rtadvd/rtadvd.8
deleted file mode 100644
index fcb46fe..0000000
--- a/usr.sbin/rtadvd/rtadvd.8
+++ /dev/null
@@ -1,242 +0,0 @@
-.\" $KAME: rtadvd.8,v 1.24 2002/05/31 16:16:08 jinmei Exp $
-.\"
-.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the project nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd February 25, 2013
-.Dt RTADVD 8
-.Os
-.Sh NAME
-.Nm rtadvd
-.Nd router advertisement daemon
-.Sh SYNOPSIS
-.Nm
-.Op Fl dDfRs
-.Op Fl c Ar configfile
-.Op Fl C Ar ctlsock
-.Op Fl M Ar ifname
-.Op Fl p Ar pidfile
-.Op Ar interface ...
-.Sh DESCRIPTION
-.Nm
-sends router advertisement packets to the specified
-.Ar interfaces .
-If no interfaces are specified,
-.Nm
-will still run, but will not advertise any routes until interfaces are
-added using
-.Xr rtadvctl 8 .
-.Pp
-The program will daemonize itself on invocation.
-It will then send router advertisement packets periodically, as well
-as in response to router solicitation messages sent by end hosts.
-.Pp
-Router advertisements can be configured on a per-interface basis, as
-described in
-.Xr rtadvd.conf 5 .
-.Pp
-If there is no configuration file entry for an interface,
-or if the configuration file does not exist altogether,
-.Nm
-sets all the parameters to their default values.
-In particular,
-.Nm
-reads all the interface routes from the routing table and advertises
-them as on-link prefixes.
-.Pp
-.Nm
-also watches the routing table.
-If an interface direct route is
-added on an advertising interface and no static prefixes are
-specified by the configuration file,
-.Nm
-adds the corresponding prefix to its advertising list.
-.Pp
-Similarly, when an interface direct route is deleted,
-.Nm
-will start advertising the prefixes with zero valid and preferred
-lifetimes to help the receiving hosts switch to a new prefix when
-renumbering.
-Note, however, that the zero valid lifetime cannot invalidate the
-autoconfigured addresses at a receiving host immediately.
-According to the specification, the host will retain the address
-for a certain period, which will typically be two hours.
-The zero lifetimes rather intend to make the address deprecated,
-indicating that a new non-deprecated address should be used as the
-source address of a new connection.
-This behavior will last for two hours.
-Then
-.Nm
-will completely remove the prefix from the advertising list,
-and succeeding advertisements will not contain the prefix information.
-.Pp
-Moreover, if the status of an advertising interface changes,
-.Nm
-will start or stop sending router advertisements according
-to the latest status.
-.Pp
-The
-.Fl s
-option may be used to disable this behavior;
-.Nm
-will not watch the routing table and the whole functionality described
-above will be suppressed.
-.Pp
-Basically, hosts MUST NOT send Router Advertisement messages at any
-time (RFC 4861, Section 6.2.3).
-However, it would sometimes be useful to allow hosts to advertise some
-parameters such as prefix information and link MTU.
-Thus,
-.Nm
-can be invoked if router lifetime is explicitly set zero on every
-advertising interface.
-.Pp
-The command line options are:
-.Bl -tag -width indent
-.\"
-.It Fl c
-Specify an alternate location,
-.Ar configfile ,
-for the configuration file.
-By default,
-.Pa /etc/rtadvd.conf
-is used.
-.It Fl C
-Specify an alternate location for the control socket used by
-.Xr rtadvctl 8 .
-The default is
-.Pa /var/run/rtadvd.sock .
-.It Fl d
-Print debugging information.
-.It Fl D
-Even more debugging information is printed.
-.It Fl f
-Foreground mode (useful when debugging).
-Log messages will be dumped to stderr when this option is specified.
-.It Fl M
-Specify an interface to join the all-routers site-local multicast group.
-By default,
-.Nm
-tries to join the first advertising interface appearing on the command
-line.
-This option has meaning only with the
-.Fl R
-option, which enables routing renumbering protocol support.
-.It Fl p
-Specify an alternative file in which to store the process ID.
-The default is
-.Pa /var/run/rtadvd.pid .
-.It Fl R
-Accept router renumbering requests.
-If you enable it, certain IPsec setup is suggested for security reasons.
-This option is currently disabled, and is ignored by
-.Nm
-with a warning message.
-.It Fl s
-Do not add or delete prefixes dynamically.
-Only statically configured prefixes, if any, will be advertised.
-.El
-.Pp
-Use
-.Dv SIGHUP
-to reload the configuration file
-.Pa /etc/rtadvd.conf .
-If an invalid parameter is found in the configuration file upon the reload,
-the entry will be ignored and the old configuration will be used.
-When parameters in an existing entry are updated,
-.Nm
-will send Router Advertisement messages with the old configuration but
-zero router lifetime to the interface first, and then start to send a new
-message.
-.Pp
-Use
-.Dv SIGTERM
-to kill
-.Nm
-gracefully.
-In this case,
-.Nm
-will transmit router advertisement with router lifetime 0
-to all the interfaces
-.Pq in accordance with RFC 4861 6.2.5 .
-.Sh FILES
-.Bl -tag -width Pa -compact
-.It Pa /etc/rtadvd.conf
-The default configuration file.
-.It Pa /var/run/rtadvd.pid
-The default process ID file.
-.El
-.Sh EXIT STATUS
-.Ex -std
-.Sh SEE ALSO
-.Xr rtadvd.conf 5 ,
-.Xr rtadvctl 8 ,
-.Xr rtsol 8
-.Rs
-.%A Thomas Narten
-.%A Erik Nordmark
-.%A W. A. Simpson
-.%A Hesham Soliman
-.%T Neighbor Discovery for IP version 6 (IPv6)
-.%R RFC 4861
-.Re
-.Rs
-.%A Thomas Narten
-.%A Erik Nordmark
-.%A W. A. Simpson
-.%T Neighbor Discovery for IP version 6 (IPv6)
-.%R RFC 2461 (obsoleted by RFC 4861)
-.Re
-.Rs
-.%A Richard Draves
-.%T Default Router Preferences and More-Specific Routes
-.%R draft-ietf-ipngwg-router-selection-xx.txt
-.Re
-.Rs
-.%A J. Jeong
-.%A S. Park
-.%A L. Beloeil
-.%A S. Madanapalli
-.%T IPv6 Router Advertisement Options for DNS Configuration
-.%R RFC 6106
-.Re
-.Sh HISTORY
-The
-.Nm
-command first appeared in the WIDE Hydrangea IPv6 protocol stack kit.
-.Sh BUGS
-There used to be some text that recommended users not to let
-.Nm
-advertise Router Advertisement messages on an upstream link to avoid
-undesirable
-.Xr icmp6 4
-redirect messages.
-However, based on the later discussion in the IETF ipng working group,
-all routers should rather advertise the messages regardless of
-the network topology, in order to ensure reachability.
diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c
deleted file mode 100644
index 9976c78..0000000
--- a/usr.sbin/rtadvd/rtadvd.c
+++ /dev/null
@@ -1,1914 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: rtadvd.c,v 1.82 2003/08/05 12:34:23 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_media.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
-
-#include <arpa/inet.h>
-
-#include <netinet/in_var.h>
-#include <netinet6/nd6.h>
-
-#include <time.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <err.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <libutil.h>
-#include <netdb.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <poll.h>
-
-#include "pathnames.h"
-#include "rtadvd.h"
-#include "if.h"
-#include "rrenum.h"
-#include "advcap.h"
-#include "timer_subr.h"
-#include "timer.h"
-#include "config.h"
-#include "control.h"
-#include "control_server.h"
-
-#define RTADV_TYPE2BITMASK(type) (0x1 << type)
-
-struct msghdr rcvmhdr;
-static char *rcvcmsgbuf;
-static size_t rcvcmsgbuflen;
-static char *sndcmsgbuf = NULL;
-static size_t sndcmsgbuflen;
-struct msghdr sndmhdr;
-struct iovec rcviov[2];
-struct iovec sndiov[2];
-struct sockaddr_in6 rcvfrom;
-static const char *pidfilename = _PATH_RTADVDPID;
-const char *conffile = _PATH_RTADVDCONF;
-static struct pidfh *pfh;
-static int dflag, sflag;
-static int wait_shutdown;
-
-#define PFD_RAWSOCK 0
-#define PFD_RTSOCK 1
-#define PFD_CSOCK 2
-#define PFD_MAX 3
-
-struct railist_head_t railist =
- TAILQ_HEAD_INITIALIZER(railist);
-struct ifilist_head_t ifilist =
- TAILQ_HEAD_INITIALIZER(ifilist);
-
-struct nd_optlist {
- TAILQ_ENTRY(nd_optlist) nol_next;
- struct nd_opt_hdr *nol_opt;
-};
-union nd_opt {
- struct nd_opt_hdr *opt_array[9];
- struct {
- struct nd_opt_hdr *zero;
- struct nd_opt_hdr *src_lladdr;
- struct nd_opt_hdr *tgt_lladdr;
- struct nd_opt_prefix_info *pi;
- struct nd_opt_rd_hdr *rh;
- struct nd_opt_mtu *mtu;
- TAILQ_HEAD(, nd_optlist) opt_list;
- } nd_opt_each;
-};
-#define opt_src_lladdr nd_opt_each.src_lladdr
-#define opt_tgt_lladdr nd_opt_each.tgt_lladdr
-#define opt_pi nd_opt_each.pi
-#define opt_rh nd_opt_each.rh
-#define opt_mtu nd_opt_each.mtu
-#define opt_list nd_opt_each.opt_list
-
-#define NDOPT_FLAG_SRCLINKADDR (1 << 0)
-#define NDOPT_FLAG_TGTLINKADDR (1 << 1)
-#define NDOPT_FLAG_PREFIXINFO (1 << 2)
-#define NDOPT_FLAG_RDHDR (1 << 3)
-#define NDOPT_FLAG_MTU (1 << 4)
-#define NDOPT_FLAG_RDNSS (1 << 5)
-#define NDOPT_FLAG_DNSSL (1 << 6)
-
-static uint32_t ndopt_flags[] = {
- [ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR,
- [ND_OPT_TARGET_LINKADDR] = NDOPT_FLAG_TGTLINKADDR,
- [ND_OPT_PREFIX_INFORMATION] = NDOPT_FLAG_PREFIXINFO,
- [ND_OPT_REDIRECTED_HEADER] = NDOPT_FLAG_RDHDR,
- [ND_OPT_MTU] = NDOPT_FLAG_MTU,
- [ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS,
- [ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL,
-};
-
-static void rtadvd_shutdown(void);
-static void sock_open(struct sockinfo *);
-static void rtsock_open(struct sockinfo *);
-static void rtadvd_input(struct sockinfo *);
-static void rs_input(int, struct nd_router_solicit *,
- struct in6_pktinfo *, struct sockaddr_in6 *);
-static void ra_input(int, struct nd_router_advert *,
- struct in6_pktinfo *, struct sockaddr_in6 *);
-static int prefix_check(struct nd_opt_prefix_info *, struct rainfo *,
- struct sockaddr_in6 *);
-static int nd6_options(struct nd_opt_hdr *, int,
- union nd_opt *, uint32_t);
-static void free_ndopts(union nd_opt *);
-static void rtmsg_input(struct sockinfo *);
-static void set_short_delay(struct ifinfo *);
-static int check_accept_rtadv(int);
-
-static void
-usage(void)
-{
-
- fprintf(stderr, "usage: rtadvd [-dDfRs] "
- "[-c configfile] [-C ctlsock] [-M ifname] [-p pidfile]\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- struct pollfd set[PFD_MAX];
- struct timespec *timeout;
- int i, ch;
- int fflag = 0, logopt;
- int error;
- pid_t pid, otherpid;
-
- /* get command line options and arguments */
- while ((ch = getopt(argc, argv, "c:C:dDfhM:p:Rs")) != -1) {
- switch (ch) {
- case 'c':
- conffile = optarg;
- break;
- case 'C':
- ctrlsock.si_name = optarg;
- break;
- case 'd':
- dflag++;
- break;
- case 'D':
- dflag += 3;
- break;
- case 'f':
- fflag = 1;
- break;
- case 'M':
- mcastif = optarg;
- break;
- case 'R':
- fprintf(stderr, "rtadvd: "
- "the -R option is currently ignored.\n");
- /* accept_rr = 1; */
- /* run anyway... */
- break;
- case 's':
- sflag = 1;
- break;
- case 'p':
- pidfilename = optarg;
- break;
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- logopt = LOG_NDELAY | LOG_PID;
- if (fflag)
- logopt |= LOG_PERROR;
- openlog("rtadvd", logopt, LOG_DAEMON);
-
- /* set log level */
- if (dflag > 2)
- (void)setlogmask(LOG_UPTO(LOG_DEBUG));
- else if (dflag > 1)
- (void)setlogmask(LOG_UPTO(LOG_INFO));
- else if (dflag > 0)
- (void)setlogmask(LOG_UPTO(LOG_NOTICE));
- else
- (void)setlogmask(LOG_UPTO(LOG_ERR));
-
- /* timer initialization */
- rtadvd_timer_init();
-
- pfh = pidfile_open(pidfilename, 0600, &otherpid);
- if (pfh == NULL) {
- if (errno == EEXIST)
- errx(1, "%s already running, pid: %d",
- getprogname(), otherpid);
- syslog(LOG_ERR,
- "failed to open the pid file %s, run anyway.",
- pidfilename);
- }
- if (!fflag)
- daemon(1, 0);
-
- sock_open(&sock);
-
- update_ifinfo(&ifilist, UPDATE_IFINFO_ALL);
- for (i = 0; i < argc; i++)
- update_persist_ifinfo(&ifilist, argv[i]);
-
- csock_open(&ctrlsock, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (ctrlsock.si_fd == -1) {
- syslog(LOG_ERR, "cannot open control socket: %s",
- strerror(errno));
- exit(1);
- }
-
- /* record the current PID */
- pid = getpid();
- pidfile_write(pfh);
-
- set[PFD_RAWSOCK].fd = sock.si_fd;
- set[PFD_RAWSOCK].events = POLLIN;
- if (sflag == 0) {
- rtsock_open(&rtsock);
- set[PFD_RTSOCK].fd = rtsock.si_fd;
- set[PFD_RTSOCK].events = POLLIN;
- } else
- set[PFD_RTSOCK].fd = -1;
- set[PFD_CSOCK].fd = ctrlsock.si_fd;
- set[PFD_CSOCK].events = POLLIN;
- signal(SIGTERM, set_do_shutdown);
- signal(SIGINT, set_do_shutdown);
- signal(SIGHUP, set_do_reload);
-
- error = csock_listen(&ctrlsock);
- if (error) {
- syslog(LOG_ERR, "cannot listen control socket: %s",
- strerror(errno));
- exit(1);
- }
-
- /* load configuration file */
- set_do_reload(0);
-
- while (1) {
- if (is_do_shutdown())
- rtadvd_shutdown();
-
- if (is_do_reload()) {
- loadconfig_ifname(reload_ifname());
- if (reload_ifname() == NULL)
- syslog(LOG_INFO,
- "configuration file reloaded.");
- else
- syslog(LOG_INFO,
- "configuration file for %s reloaded.",
- reload_ifname());
- reset_do_reload();
- }
-
- /* timeout handler update for active interfaces */
- rtadvd_update_timeout_handler();
-
- /* timer expiration check and reset the timer */
- timeout = rtadvd_check_timer();
-
- if (timeout != NULL) {
- syslog(LOG_DEBUG,
- "<%s> set timer to %ld:%ld. waiting for "
- "inputs or timeout", __func__,
- (long int)timeout->tv_sec,
- (long int)timeout->tv_nsec / 1000);
- } else {
- syslog(LOG_DEBUG,
- "<%s> there's no timer. waiting for inputs",
- __func__);
- }
- if ((i = poll(set, sizeof(set)/sizeof(set[0]),
- timeout ? (timeout->tv_sec * 1000 +
- timeout->tv_nsec / 1000 / 1000) : INFTIM)) < 0) {
-
- /* EINTR would occur if a signal was delivered */
- if (errno != EINTR)
- syslog(LOG_ERR, "poll() failed: %s",
- strerror(errno));
- continue;
- }
- if (i == 0) /* timeout */
- continue;
- if (rtsock.si_fd != -1 && set[PFD_RTSOCK].revents & POLLIN)
- rtmsg_input(&rtsock);
-
- if (set[PFD_RAWSOCK].revents & POLLIN)
- rtadvd_input(&sock);
-
- if (set[PFD_CSOCK].revents & POLLIN) {
- int fd;
-
- fd = csock_accept(&ctrlsock);
- if (fd == -1)
- syslog(LOG_ERR,
- "cannot accept() control socket: %s",
- strerror(errno));
- else {
- cm_handler_server(fd);
- close(fd);
- }
- }
- }
- exit(0); /* NOTREACHED */
-}
-
-static void
-rtadvd_shutdown(void)
-{
- struct ifinfo *ifi;
- struct rainfo *rai;
- struct rdnss *rdn;
- struct dnssl *dns;
-
- if (wait_shutdown) {
- syslog(LOG_INFO,
- "waiting expiration of the all RA timers.");
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- /*
- * Ignore !IFF_UP interfaces in waiting for shutdown.
- */
- if (!(ifi->ifi_flags & IFF_UP) &&
- ifi->ifi_ra_timer != NULL) {
- ifi->ifi_state = IFI_STATE_UNCONFIGURED;
- rtadvd_remove_timer(ifi->ifi_ra_timer);
- ifi->ifi_ra_timer = NULL;
- syslog(LOG_DEBUG, "<%s> %s(idx=%d) is down. "
- "Timer removed and marked as UNCONFIGURED.",
- __func__, ifi->ifi_ifname,
- ifi->ifi_ifindex);
- }
- }
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (ifi->ifi_ra_timer != NULL)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_NOTICE, "gracefully terminated.");
- exit(0);
- }
-
- sleep(1);
- return;
- }
-
- syslog(LOG_DEBUG, "<%s> cease to be an advertising router",
- __func__);
-
- wait_shutdown = 1;
-
- TAILQ_FOREACH(rai, &railist, rai_next) {
- rai->rai_lifetime = 0;
- TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next)
- rdn->rd_ltime = 0;
- TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next)
- dns->dn_ltime = 0;
- }
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (!ifi->ifi_persist)
- continue;
- if (ifi->ifi_state == IFI_STATE_UNCONFIGURED)
- continue;
- if (ifi->ifi_ra_timer == NULL)
- continue;
- if (ifi->ifi_ra_lastsent.tv_sec == 0 &&
- ifi->ifi_ra_lastsent.tv_nsec == 0 &&
- ifi->ifi_ra_timer != NULL) {
- /*
- * When RA configured but never sent,
- * ignore the IF immediately.
- */
- rtadvd_remove_timer(ifi->ifi_ra_timer);
- ifi->ifi_ra_timer = NULL;
- ifi->ifi_state = IFI_STATE_UNCONFIGURED;
- continue;
- }
-
- ifi->ifi_state = IFI_STATE_TRANSITIVE;
-
- /* Mark as the shut-down state. */
- ifi->ifi_rainfo_trans = ifi->ifi_rainfo;
- ifi->ifi_rainfo = NULL;
-
- ifi->ifi_burstcount = MAX_FINAL_RTR_ADVERTISEMENTS;
- ifi->ifi_burstinterval = MIN_DELAY_BETWEEN_RAS;
-
- ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
- rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
- ifi->ifi_ra_timer);
- }
- syslog(LOG_NOTICE, "final RA transmission started.");
-
- pidfile_remove(pfh);
- csock_close(&ctrlsock);
-}
-
-static void
-rtmsg_input(struct sockinfo *s)
-{
- int n, type, ifindex = 0, plen;
- size_t len;
- char msg[2048], *next, *lim;
- char ifname[IFNAMSIZ];
- struct if_announcemsghdr *ifan;
- struct rt_msghdr *rtm;
- struct prefix *pfx;
- struct rainfo *rai;
- struct in6_addr *addr;
- struct ifinfo *ifi;
- char addrbuf[INET6_ADDRSTRLEN];
- int prefixchange = 0;
-
- if (s == NULL) {
- syslog(LOG_ERR, "<%s> internal error", __func__);
- exit(1);
- }
- n = read(s->si_fd, msg, sizeof(msg));
- rtm = (struct rt_msghdr *)msg;
- syslog(LOG_DEBUG, "<%s> received a routing message "
- "(type = %d, len = %d)", __func__, rtm->rtm_type, n);
-
- if (n > rtm->rtm_msglen) {
- /*
- * This usually won't happen for messages received on
- * a routing socket.
- */
- syslog(LOG_DEBUG,
- "<%s> received data length is larger than "
- "1st routing message len. multiple messages? "
- "read %d bytes, but 1st msg len = %d",
- __func__, n, rtm->rtm_msglen);
-#if 0
- /* adjust length */
- n = rtm->rtm_msglen;
-#endif
- }
-
- lim = msg + n;
- for (next = msg; next < lim; next += len) {
- int oldifflags;
-
- next = get_next_msg(next, lim, 0, &len,
- RTADV_TYPE2BITMASK(RTM_ADD) |
- RTADV_TYPE2BITMASK(RTM_DELETE) |
- RTADV_TYPE2BITMASK(RTM_NEWADDR) |
- RTADV_TYPE2BITMASK(RTM_DELADDR) |
- RTADV_TYPE2BITMASK(RTM_IFINFO) |
- RTADV_TYPE2BITMASK(RTM_IFANNOUNCE));
- if (len == 0)
- break;
- type = ((struct rt_msghdr *)next)->rtm_type;
- switch (type) {
- case RTM_ADD:
- case RTM_DELETE:
- ifindex = get_rtm_ifindex(next);
- break;
- case RTM_NEWADDR:
- case RTM_DELADDR:
- ifindex = (int)((struct ifa_msghdr *)next)->ifam_index;
- break;
- case RTM_IFINFO:
- ifindex = (int)((struct if_msghdr *)next)->ifm_index;
- break;
- case RTM_IFANNOUNCE:
- ifan = (struct if_announcemsghdr *)next;
- switch (ifan->ifan_what) {
- case IFAN_ARRIVAL:
- case IFAN_DEPARTURE:
- break;
- default:
- syslog(LOG_DEBUG,
- "<%s:%d> unknown ifan msg (ifan_what=%d)",
- __func__, __LINE__, ifan->ifan_what);
- continue;
- }
-
- syslog(LOG_DEBUG, "<%s>: if_announcemsg (idx=%d:%d)",
- __func__, ifan->ifan_index, ifan->ifan_what);
- switch (ifan->ifan_what) {
- case IFAN_ARRIVAL:
- syslog(LOG_NOTICE,
- "interface added (idx=%d)",
- ifan->ifan_index);
- update_ifinfo(&ifilist, ifan->ifan_index);
- loadconfig_index(ifan->ifan_index);
- break;
- case IFAN_DEPARTURE:
- syslog(LOG_NOTICE,
- "interface removed (idx=%d)",
- ifan->ifan_index);
- rm_ifinfo_index(ifan->ifan_index);
-
- /* Clear ifi_ifindex */
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (ifi->ifi_ifindex
- == ifan->ifan_index) {
- ifi->ifi_ifindex = 0;
- break;
- }
- }
- update_ifinfo(&ifilist, ifan->ifan_index);
- break;
- }
- continue;
- default:
- /* should not reach here */
- syslog(LOG_DEBUG,
- "<%s:%d> unknown rtmsg %d on %s",
- __func__, __LINE__, type,
- if_indextoname(ifindex, ifname));
- continue;
- }
- ifi = if_indextoifinfo(ifindex);
- if (ifi == NULL) {
- syslog(LOG_DEBUG,
- "<%s> ifinfo not found for idx=%d. Why?",
- __func__, ifindex);
- continue;
- }
- rai = ifi->ifi_rainfo;
- if (rai == NULL) {
- syslog(LOG_DEBUG,
- "<%s> route changed on "
- "non advertising interface(%s)",
- __func__, ifi->ifi_ifname);
- continue;
- }
-
- oldifflags = ifi->ifi_flags;
- /* init ifflags because it may have changed */
- update_ifinfo(&ifilist, ifindex);
-
- switch (type) {
- case RTM_ADD:
- if (sflag)
- break; /* we aren't interested in prefixes */
-
- addr = get_addr(msg);
- plen = get_prefixlen(msg);
- /* sanity check for plen */
- /* as RFC2373, prefixlen is at least 4 */
- if (plen < 4 || plen > 127) {
- syslog(LOG_INFO, "<%s> new interface route's"
- "plen %d is invalid for a prefix",
- __func__, plen);
- break;
- }
- pfx = find_prefix(rai, addr, plen);
- if (pfx) {
- if (pfx->pfx_timer) {
- /*
- * If the prefix has been invalidated,
- * make it available again.
- */
- update_prefix(pfx);
- prefixchange = 1;
- } else
- syslog(LOG_DEBUG,
- "<%s> new prefix(%s/%d) "
- "added on %s, "
- "but it was already in list",
- __func__,
- inet_ntop(AF_INET6, addr,
- (char *)addrbuf,
- sizeof(addrbuf)),
- plen, ifi->ifi_ifname);
- break;
- }
- make_prefix(rai, ifindex, addr, plen);
- prefixchange = 1;
- break;
- case RTM_DELETE:
- if (sflag)
- break;
-
- addr = get_addr(msg);
- plen = get_prefixlen(msg);
- /* sanity check for plen */
- /* as RFC2373, prefixlen is at least 4 */
- if (plen < 4 || plen > 127) {
- syslog(LOG_INFO,
- "<%s> deleted interface route's "
- "plen %d is invalid for a prefix",
- __func__, plen);
- break;
- }
- pfx = find_prefix(rai, addr, plen);
- if (pfx == NULL) {
- syslog(LOG_DEBUG,
- "<%s> prefix(%s/%d) was deleted on %s, "
- "but it was not in list",
- __func__, inet_ntop(AF_INET6, addr,
- (char *)addrbuf, sizeof(addrbuf)),
- plen, ifi->ifi_ifname);
- break;
- }
- invalidate_prefix(pfx);
- prefixchange = 1;
- break;
- case RTM_NEWADDR:
- case RTM_DELADDR:
- case RTM_IFINFO:
- break;
- default:
- /* should not reach here */
- syslog(LOG_DEBUG,
- "<%s:%d> unknown rtmsg %d on %s",
- __func__, __LINE__, type,
- if_indextoname(ifindex, ifname));
- return;
- }
-
- /* check if an interface flag is changed */
- if ((oldifflags & IFF_UP) && /* UP to DOWN */
- !(ifi->ifi_flags & IFF_UP)) {
- syslog(LOG_NOTICE,
- "<interface %s becomes down. stop timer.",
- ifi->ifi_ifname);
- rtadvd_remove_timer(ifi->ifi_ra_timer);
- ifi->ifi_ra_timer = NULL;
- } else if (!(oldifflags & IFF_UP) && /* DOWN to UP */
- (ifi->ifi_flags & IFF_UP)) {
- syslog(LOG_NOTICE,
- "interface %s becomes up. restart timer.",
- ifi->ifi_ifname);
-
- ifi->ifi_state = IFI_STATE_TRANSITIVE;
- ifi->ifi_burstcount =
- MAX_INITIAL_RTR_ADVERTISEMENTS;
- ifi->ifi_burstinterval =
- MAX_INITIAL_RTR_ADVERT_INTERVAL;
-
- ifi->ifi_ra_timer = rtadvd_add_timer(ra_timeout,
- ra_timer_update, ifi, ifi);
- ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
- rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
- ifi->ifi_ra_timer);
- } else if (prefixchange &&
- (ifi->ifi_flags & IFF_UP)) {
- /*
- * An advertised prefix has been added or invalidated.
- * Will notice the change in a short delay.
- */
- set_short_delay(ifi);
- }
- }
-
- return;
-}
-
-void
-rtadvd_input(struct sockinfo *s)
-{
- ssize_t i;
- int *hlimp = NULL;
-#ifdef OLDRAWSOCKET
- struct ip6_hdr *ip;
-#endif
- struct icmp6_hdr *icp;
- int ifindex = 0;
- struct cmsghdr *cm;
- struct in6_pktinfo *pi = NULL;
- char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
- struct in6_addr dst = in6addr_any;
- struct ifinfo *ifi;
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (s == NULL) {
- syslog(LOG_ERR, "<%s> internal error", __func__);
- exit(1);
- }
- /*
- * Get message. We reset msg_controllen since the field could
- * be modified if we had received a message before setting
- * receive options.
- */
- rcvmhdr.msg_controllen = rcvcmsgbuflen;
- if ((i = recvmsg(s->si_fd, &rcvmhdr, 0)) < 0)
- return;
-
- /* extract optional information via Advanced API */
- for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr);
- cm;
- cm = (struct cmsghdr *)CMSG_NXTHDR(&rcvmhdr, cm)) {
- if (cm->cmsg_level == IPPROTO_IPV6 &&
- cm->cmsg_type == IPV6_PKTINFO &&
- cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
- pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
- ifindex = pi->ipi6_ifindex;
- dst = pi->ipi6_addr;
- }
- if (cm->cmsg_level == IPPROTO_IPV6 &&
- cm->cmsg_type == IPV6_HOPLIMIT &&
- cm->cmsg_len == CMSG_LEN(sizeof(int)))
- hlimp = (int *)CMSG_DATA(cm);
- }
- if (ifindex == 0) {
- syslog(LOG_ERR, "failed to get receiving interface");
- return;
- }
- if (hlimp == NULL) {
- syslog(LOG_ERR, "failed to get receiving hop limit");
- return;
- }
-
- /*
- * If we happen to receive data on an interface which is now gone
- * or down, just discard the data.
- */
- ifi = if_indextoifinfo(pi->ipi6_ifindex);
- if (ifi == NULL || !(ifi->ifi_flags & IFF_UP)) {
- syslog(LOG_INFO,
- "<%s> received data on a disabled interface (%s)",
- __func__,
- (ifi == NULL) ? "[gone]" : ifi->ifi_ifname);
- return;
- }
-
-#ifdef OLDRAWSOCKET
- if ((size_t)i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) {
- syslog(LOG_ERR,
- "packet size(%d) is too short", i);
- return;
- }
-
- ip = (struct ip6_hdr *)rcvmhdr.msg_iov[0].iov_base;
- icp = (struct icmp6_hdr *)(ip + 1); /* XXX: ext. hdr? */
-#else
- if ((size_t)i < sizeof(struct icmp6_hdr)) {
- syslog(LOG_ERR, "packet size(%zd) is too short", i);
- return;
- }
-
- icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base;
-#endif
-
- switch (icp->icmp6_type) {
- case ND_ROUTER_SOLICIT:
- /*
- * Message verification - RFC 4861 6.1.1
- * XXX: these checks must be done in the kernel as well,
- * but we can't completely rely on them.
- */
- if (*hlimp != 255) {
- syslog(LOG_NOTICE,
- "RS with invalid hop limit(%d) "
- "received from %s on %s",
- *hlimp,
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
- if (icp->icmp6_code) {
- syslog(LOG_NOTICE,
- "RS with invalid ICMP6 code(%d) "
- "received from %s on %s",
- icp->icmp6_code,
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
- if ((size_t)i < sizeof(struct nd_router_solicit)) {
- syslog(LOG_NOTICE,
- "RS from %s on %s does not have enough "
- "length (len = %zd)",
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
- return;
- }
- rs_input(i, (struct nd_router_solicit *)icp, pi, &rcvfrom);
- break;
- case ND_ROUTER_ADVERT:
- /*
- * Message verification - RFC 4861 6.1.2
- * XXX: there's the same dilemma as above...
- */
- if (!IN6_IS_ADDR_LINKLOCAL(&rcvfrom.sin6_addr)) {
- syslog(LOG_NOTICE,
- "RA with non-linklocal source address "
- "received from %s on %s",
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr,
- ntopbuf, sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
- if (*hlimp != 255) {
- syslog(LOG_NOTICE,
- "RA with invalid hop limit(%d) "
- "received from %s on %s",
- *hlimp,
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
- if (icp->icmp6_code) {
- syslog(LOG_NOTICE,
- "RA with invalid ICMP6 code(%d) "
- "received from %s on %s",
- icp->icmp6_code,
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
- if ((size_t)i < sizeof(struct nd_router_advert)) {
- syslog(LOG_NOTICE,
- "RA from %s on %s does not have enough "
- "length (len = %zd)",
- inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
- return;
- }
- ra_input(i, (struct nd_router_advert *)icp, pi, &rcvfrom);
- break;
- case ICMP6_ROUTER_RENUMBERING:
- if (mcastif == NULL) {
- syslog(LOG_ERR, "received a router renumbering "
- "message, but not allowed to be accepted");
- break;
- }
- rr_input(i, (struct icmp6_router_renum *)icp, pi, &rcvfrom,
- &dst);
- break;
- default:
- /*
- * Note that this case is POSSIBLE, especially just
- * after invocation of the daemon. This is because we
- * could receive message after opening the socket and
- * before setting ICMP6 type filter(see sock_open()).
- */
- syslog(LOG_ERR, "invalid icmp type(%d)", icp->icmp6_type);
- return;
- }
-
- return;
-}
-
-static void
-rs_input(int len, struct nd_router_solicit *rs,
- struct in6_pktinfo *pi, struct sockaddr_in6 *from)
-{
- char ntopbuf[INET6_ADDRSTRLEN];
- char ifnamebuf[IFNAMSIZ];
- union nd_opt ndopts;
- struct rainfo *rai;
- struct ifinfo *ifi;
- struct soliciter *sol;
-
- syslog(LOG_DEBUG,
- "<%s> RS received from %s on %s",
- __func__,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
-
- /* ND option check */
- memset(&ndopts, 0, sizeof(ndopts));
- TAILQ_INIT(&ndopts.opt_list);
- if (nd6_options((struct nd_opt_hdr *)(rs + 1),
- len - sizeof(struct nd_router_solicit),
- &ndopts, NDOPT_FLAG_SRCLINKADDR)) {
- syslog(LOG_INFO,
- "<%s> ND option check failed for an RS from %s on %s",
- __func__,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- return;
- }
-
- /*
- * If the IP source address is the unspecified address, there
- * must be no source link-layer address option in the message.
- * (RFC 4861 6.1.1)
- */
- if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) &&
- ndopts.opt_src_lladdr) {
- syslog(LOG_INFO,
- "<%s> RS from unspecified src on %s has a link-layer"
- " address option",
- __func__, if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- goto done;
- }
-
- ifi = if_indextoifinfo(pi->ipi6_ifindex);
- if (ifi == NULL) {
- syslog(LOG_INFO,
- "<%s> if (idx=%d) not found. Why?",
- __func__, pi->ipi6_ifindex);
- goto done;
- }
- rai = ifi->ifi_rainfo;
- if (rai == NULL) {
- syslog(LOG_INFO,
- "<%s> RS received on non advertising interface(%s)",
- __func__,
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
- goto done;
- }
-
- rai->rai_ifinfo->ifi_rsinput++;
-
- /*
- * Decide whether to send RA according to the rate-limit
- * consideration.
- */
-
- /* record sockaddr waiting for RA, if possible */
- sol = (struct soliciter *)malloc(sizeof(*sol));
- if (sol) {
- sol->sol_addr = *from;
- /* XXX RFC 2553 need clarification on flowinfo */
- sol->sol_addr.sin6_flowinfo = 0;
- TAILQ_INSERT_TAIL(&rai->rai_soliciter, sol, sol_next);
- }
-
- /*
- * If there is already a waiting RS packet, don't
- * update the timer.
- */
- if (ifi->ifi_rs_waitcount++)
- goto done;
-
- set_short_delay(ifi);
-
- done:
- free_ndopts(&ndopts);
- return;
-}
-
-static void
-set_short_delay(struct ifinfo *ifi)
-{
- long delay; /* must not be greater than 1000000 */
- struct timespec interval, now, min_delay, tm_tmp, *rest;
-
- if (ifi->ifi_ra_timer == NULL)
- return;
- /*
- * Compute a random delay. If the computed value
- * corresponds to a time later than the time the next
- * multicast RA is scheduled to be sent, ignore the random
- * delay and send the advertisement at the
- * already-scheduled time. RFC 4861 6.2.6
- */
- delay = arc4random_uniform(MAX_RA_DELAY_TIME);
- interval.tv_sec = 0;
- interval.tv_nsec = delay * 1000;
- rest = rtadvd_timer_rest(ifi->ifi_ra_timer);
- if (TS_CMP(rest, &interval, <)) {
- syslog(LOG_DEBUG, "<%s> random delay is larger than "
- "the rest of the current timer", __func__);
- interval = *rest;
- }
-
- /*
- * If we sent a multicast Router Advertisement within
- * the last MIN_DELAY_BETWEEN_RAS seconds, schedule
- * the advertisement to be sent at a time corresponding to
- * MIN_DELAY_BETWEEN_RAS plus the random value after the
- * previous advertisement was sent.
- */
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- TS_SUB(&now, &ifi->ifi_ra_lastsent, &tm_tmp);
- min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
- min_delay.tv_nsec = 0;
- if (TS_CMP(&tm_tmp, &min_delay, <)) {
- TS_SUB(&min_delay, &tm_tmp, &min_delay);
- TS_ADD(&min_delay, &interval, &interval);
- }
- rtadvd_set_timer(&interval, ifi->ifi_ra_timer);
-}
-
-static int
-check_accept_rtadv(int idx)
-{
- struct ifinfo *ifi;
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (ifi->ifi_ifindex == idx)
- break;
- }
- if (ifi == NULL) {
- syslog(LOG_DEBUG,
- "<%s> if (idx=%d) not found. Why?",
- __func__, idx);
- return (0);
- }
-#if (__FreeBSD_version < 900000)
- /*
- * RA_RECV: !ip6.forwarding && ip6.accept_rtadv
- * RA_SEND: ip6.forwarding
- */
- return ((getinet6sysctl(IPV6CTL_FORWARDING) == 0) &&
- (getinet6sysctl(IPV6CTL_ACCEPT_RTADV) == 1));
-#else
- /*
- * RA_RECV: ND6_IFF_ACCEPT_RTADV
- * RA_SEND: ip6.forwarding
- */
- if (update_ifinfo_nd_flags(ifi) != 0) {
- syslog(LOG_ERR, "cannot get nd6 flags (idx=%d)", idx);
- return (0);
- }
-
- return (ifi->ifi_nd_flags & ND6_IFF_ACCEPT_RTADV);
-#endif
-}
-
-static void
-ra_input(int len, struct nd_router_advert *nra,
- struct in6_pktinfo *pi, struct sockaddr_in6 *from)
-{
- struct rainfo *rai;
- struct ifinfo *ifi;
- char ntopbuf[INET6_ADDRSTRLEN];
- char ifnamebuf[IFNAMSIZ];
- union nd_opt ndopts;
- const char *on_off[] = {"OFF", "ON"};
- uint32_t reachabletime, retranstimer, mtu;
- int inconsistent = 0;
- int error;
-
- syslog(LOG_DEBUG, "<%s> RA received from %s on %s", __func__,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, sizeof(ntopbuf)),
- if_indextoname(pi->ipi6_ifindex, ifnamebuf));
-
- /* ND option check */
- memset(&ndopts, 0, sizeof(ndopts));
- TAILQ_INIT(&ndopts.opt_list);
- error = nd6_options((struct nd_opt_hdr *)(nra + 1),
- len - sizeof(struct nd_router_advert), &ndopts,
- NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
- NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL);
- if (error) {
- syslog(LOG_INFO,
- "<%s> ND option check failed for an RA from %s on %s",
- __func__,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex,
- ifnamebuf));
- return;
- }
-
- /*
- * RA consistency check according to RFC 4861 6.2.7
- */
- ifi = if_indextoifinfo(pi->ipi6_ifindex);
- if (ifi->ifi_rainfo == NULL) {
- syslog(LOG_INFO,
- "<%s> received RA from %s on non-advertising"
- " interface(%s)",
- __func__,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex,
- ifnamebuf));
- goto done;
- }
- rai = ifi->ifi_rainfo;
- ifi->ifi_rainput++;
- syslog(LOG_DEBUG, "<%s> ifi->ifi_rainput = %" PRIu64, __func__,
- ifi->ifi_rainput);
-
- /* Cur Hop Limit value */
- if (nra->nd_ra_curhoplimit && rai->rai_hoplimit &&
- nra->nd_ra_curhoplimit != rai->rai_hoplimit) {
- syslog(LOG_NOTICE,
- "CurHopLimit inconsistent on %s:"
- " %d from %s, %d from us",
- ifi->ifi_ifname, nra->nd_ra_curhoplimit,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), rai->rai_hoplimit);
- inconsistent++;
- }
- /* M flag */
- if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) !=
- rai->rai_managedflg) {
- syslog(LOG_NOTICE,
- "M flag inconsistent on %s:"
- " %s from %s, %s from us",
- ifi->ifi_ifname, on_off[!rai->rai_managedflg],
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), on_off[rai->rai_managedflg]);
- inconsistent++;
- }
- /* O flag */
- if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) !=
- rai->rai_otherflg) {
- syslog(LOG_NOTICE,
- "O flag inconsistent on %s:"
- " %s from %s, %s from us",
- ifi->ifi_ifname, on_off[!rai->rai_otherflg],
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), on_off[rai->rai_otherflg]);
- inconsistent++;
- }
- /* Reachable Time */
- reachabletime = ntohl(nra->nd_ra_reachable);
- if (reachabletime && rai->rai_reachabletime &&
- reachabletime != rai->rai_reachabletime) {
- syslog(LOG_NOTICE,
- "ReachableTime inconsistent on %s:"
- " %d from %s, %d from us",
- ifi->ifi_ifname, reachabletime,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), rai->rai_reachabletime);
- inconsistent++;
- }
- /* Retrans Timer */
- retranstimer = ntohl(nra->nd_ra_retransmit);
- if (retranstimer && rai->rai_retranstimer &&
- retranstimer != rai->rai_retranstimer) {
- syslog(LOG_NOTICE,
- "RetranceTimer inconsistent on %s:"
- " %d from %s, %d from us",
- ifi->ifi_ifname, retranstimer,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), rai->rai_retranstimer);
- inconsistent++;
- }
- /* Values in the MTU options */
- if (ndopts.opt_mtu) {
- mtu = ntohl(ndopts.opt_mtu->nd_opt_mtu_mtu);
- if (mtu && rai->rai_linkmtu && mtu != rai->rai_linkmtu) {
- syslog(LOG_NOTICE,
- "MTU option value inconsistent on %s:"
- " %d from %s, %d from us",
- ifi->ifi_ifname, mtu,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), rai->rai_linkmtu);
- inconsistent++;
- }
- }
- /* Preferred and Valid Lifetimes for prefixes */
- {
- struct nd_optlist *nol;
-
- if (ndopts.opt_pi)
- if (prefix_check(ndopts.opt_pi, rai, from))
- inconsistent++;
-
- TAILQ_FOREACH(nol, &ndopts.opt_list, nol_next)
- if (prefix_check((struct nd_opt_prefix_info *)nol->nol_opt,
- rai, from))
- inconsistent++;
- }
-
- if (inconsistent)
- ifi->ifi_rainconsistent++;
-
- done:
- free_ndopts(&ndopts);
- return;
-}
-
-static uint32_t
-udiff(uint32_t u, uint32_t v)
-{
- return (u >= v ? u - v : v - u);
-}
-
-/* return a non-zero value if the received prefix is inconsistent with ours */
-static int
-prefix_check(struct nd_opt_prefix_info *pinfo,
- struct rainfo *rai, struct sockaddr_in6 *from)
-{
- struct ifinfo *ifi;
- uint32_t preferred_time, valid_time;
- struct prefix *pfx;
- int inconsistent = 0;
- char ntopbuf[INET6_ADDRSTRLEN];
- char prefixbuf[INET6_ADDRSTRLEN];
- struct timespec now;
-
-#if 0 /* impossible */
- if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION)
- return (0);
-#endif
- ifi = rai->rai_ifinfo;
- /*
- * log if the adveritsed prefix has link-local scope(sanity check?)
- */
- if (IN6_IS_ADDR_LINKLOCAL(&pinfo->nd_opt_pi_prefix))
- syslog(LOG_INFO,
- "<%s> link-local prefix %s/%d is advertised "
- "from %s on %s",
- __func__,
- inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
- sizeof(prefixbuf)),
- pinfo->nd_opt_pi_prefix_len,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), ifi->ifi_ifname);
-
- if ((pfx = find_prefix(rai, &pinfo->nd_opt_pi_prefix,
- pinfo->nd_opt_pi_prefix_len)) == NULL) {
- syslog(LOG_INFO,
- "<%s> prefix %s/%d from %s on %s is not in our list",
- __func__,
- inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
- sizeof(prefixbuf)),
- pinfo->nd_opt_pi_prefix_len,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), ifi->ifi_ifname);
- return (0);
- }
-
- preferred_time = ntohl(pinfo->nd_opt_pi_preferred_time);
- if (pfx->pfx_pltimeexpire) {
- /*
- * The lifetime is decremented in real time, so we should
- * compare the expiration time.
- * (RFC 2461 Section 6.2.7.)
- * XXX: can we really expect that all routers on the link
- * have synchronized clocks?
- */
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- preferred_time += now.tv_sec;
-
- if (!pfx->pfx_timer && rai->rai_clockskew &&
- udiff(preferred_time, pfx->pfx_pltimeexpire) > rai->rai_clockskew) {
- syslog(LOG_INFO,
- "<%s> preferred lifetime for %s/%d"
- " (decr. in real time) inconsistent on %s:"
- " %" PRIu32 " from %s, %" PRIu32 " from us",
- __func__,
- inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
- sizeof(prefixbuf)),
- pinfo->nd_opt_pi_prefix_len,
- ifi->ifi_ifname, preferred_time,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), pfx->pfx_pltimeexpire);
- inconsistent++;
- }
- } else if (!pfx->pfx_timer && preferred_time != pfx->pfx_preflifetime)
- syslog(LOG_INFO,
- "<%s> preferred lifetime for %s/%d"
- " inconsistent on %s:"
- " %d from %s, %d from us",
- __func__,
- inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
- sizeof(prefixbuf)),
- pinfo->nd_opt_pi_prefix_len,
- ifi->ifi_ifname, preferred_time,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), pfx->pfx_preflifetime);
-
- valid_time = ntohl(pinfo->nd_opt_pi_valid_time);
- if (pfx->pfx_vltimeexpire) {
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- valid_time += now.tv_sec;
-
- if (!pfx->pfx_timer && rai->rai_clockskew &&
- udiff(valid_time, pfx->pfx_vltimeexpire) > rai->rai_clockskew) {
- syslog(LOG_INFO,
- "<%s> valid lifetime for %s/%d"
- " (decr. in real time) inconsistent on %s:"
- " %d from %s, %" PRIu32 " from us",
- __func__,
- inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
- sizeof(prefixbuf)),
- pinfo->nd_opt_pi_prefix_len,
- ifi->ifi_ifname, preferred_time,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), pfx->pfx_vltimeexpire);
- inconsistent++;
- }
- } else if (!pfx->pfx_timer && valid_time != pfx->pfx_validlifetime) {
- syslog(LOG_INFO,
- "<%s> valid lifetime for %s/%d"
- " inconsistent on %s:"
- " %d from %s, %d from us",
- __func__,
- inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
- sizeof(prefixbuf)),
- pinfo->nd_opt_pi_prefix_len,
- ifi->ifi_ifname, valid_time,
- inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
- sizeof(ntopbuf)), pfx->pfx_validlifetime);
- inconsistent++;
- }
-
- return (inconsistent);
-}
-
-struct prefix *
-find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen)
-{
- struct prefix *pfx;
- int bytelen, bitlen;
- char bitmask;
-
- TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
- if (plen != pfx->pfx_prefixlen)
- continue;
-
- bytelen = plen / 8;
- bitlen = plen % 8;
- bitmask = 0xff << (8 - bitlen);
-
- if (memcmp((void *)prefix, (void *)&pfx->pfx_prefix, bytelen))
- continue;
-
- if (bitlen == 0 ||
- ((prefix->s6_addr[bytelen] & bitmask) ==
- (pfx->pfx_prefix.s6_addr[bytelen] & bitmask))) {
- return (pfx);
- }
- }
-
- return (NULL);
-}
-
-/* check if p0/plen0 matches p1/plen1; return 1 if matches, otherwise 0. */
-int
-prefix_match(struct in6_addr *p0, int plen0,
- struct in6_addr *p1, int plen1)
-{
- int bytelen, bitlen;
- char bitmask;
-
- if (plen0 < plen1)
- return (0);
-
- bytelen = plen1 / 8;
- bitlen = plen1 % 8;
- bitmask = 0xff << (8 - bitlen);
-
- if (memcmp((void *)p0, (void *)p1, bytelen))
- return (0);
-
- if (bitlen == 0 ||
- ((p0->s6_addr[bytelen] & bitmask) ==
- (p1->s6_addr[bytelen] & bitmask))) {
- return (1);
- }
-
- return (0);
-}
-
-static int
-nd6_options(struct nd_opt_hdr *hdr, int limit,
- union nd_opt *ndopts, uint32_t optflags)
-{
- int optlen = 0;
-
- for (; limit > 0; limit -= optlen) {
- if ((size_t)limit < sizeof(struct nd_opt_hdr)) {
- syslog(LOG_INFO, "<%s> short option header", __func__);
- goto bad;
- }
-
- hdr = (struct nd_opt_hdr *)((caddr_t)hdr + optlen);
- if (hdr->nd_opt_len == 0) {
- syslog(LOG_INFO,
- "<%s> bad ND option length(0) (type = %d)",
- __func__, hdr->nd_opt_type);
- goto bad;
- }
- optlen = hdr->nd_opt_len << 3;
- if (optlen > limit) {
- syslog(LOG_INFO, "<%s> short option", __func__);
- goto bad;
- }
-
- if (hdr->nd_opt_type > ND_OPT_MTU &&
- hdr->nd_opt_type != ND_OPT_RDNSS &&
- hdr->nd_opt_type != ND_OPT_DNSSL) {
- syslog(LOG_INFO, "<%s> unknown ND option(type %d)",
- __func__, hdr->nd_opt_type);
- continue;
- }
-
- if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) {
- syslog(LOG_INFO, "<%s> unexpected ND option(type %d)",
- __func__, hdr->nd_opt_type);
- continue;
- }
-
- /*
- * Option length check. Do it here for all fixed-length
- * options.
- */
- switch (hdr->nd_opt_type) {
- case ND_OPT_MTU:
- if (optlen == sizeof(struct nd_opt_mtu))
- break;
- goto skip;
- case ND_OPT_RDNSS:
- if (optlen >= 24 &&
- (optlen - sizeof(struct nd_opt_rdnss)) % 16 == 0)
- break;
- goto skip;
- case ND_OPT_DNSSL:
- if (optlen >= 16 &&
- (optlen - sizeof(struct nd_opt_dnssl)) % 8 == 0)
- break;
- goto skip;
- case ND_OPT_PREFIX_INFORMATION:
- if (optlen == sizeof(struct nd_opt_prefix_info))
- break;
-skip:
- syslog(LOG_INFO, "<%s> invalid option length",
- __func__);
- continue;
- }
-
- switch (hdr->nd_opt_type) {
- case ND_OPT_TARGET_LINKADDR:
- case ND_OPT_REDIRECTED_HEADER:
- case ND_OPT_RDNSS:
- case ND_OPT_DNSSL:
- break; /* we don't care about these options */
- case ND_OPT_SOURCE_LINKADDR:
- case ND_OPT_MTU:
- if (ndopts->opt_array[hdr->nd_opt_type]) {
- syslog(LOG_INFO,
- "<%s> duplicated ND option (type = %d)",
- __func__, hdr->nd_opt_type);
- }
- ndopts->opt_array[hdr->nd_opt_type] = hdr;
- break;
- case ND_OPT_PREFIX_INFORMATION:
- {
- struct nd_optlist *nol;
-
- if (ndopts->opt_pi == 0) {
- ndopts->opt_pi =
- (struct nd_opt_prefix_info *)hdr;
- continue;
- }
- nol = malloc(sizeof(*nol));
- if (nol == NULL) {
- syslog(LOG_ERR, "<%s> can't allocate memory",
- __func__);
- goto bad;
- }
- nol->nol_opt = hdr;
- TAILQ_INSERT_TAIL(&(ndopts->opt_list), nol, nol_next);
-
- break;
- }
- default: /* impossible */
- break;
- }
- }
-
- return (0);
-
- bad:
- free_ndopts(ndopts);
-
- return (-1);
-}
-
-static void
-free_ndopts(union nd_opt *ndopts)
-{
- struct nd_optlist *nol;
-
- while ((nol = TAILQ_FIRST(&ndopts->opt_list)) != NULL) {
- TAILQ_REMOVE(&ndopts->opt_list, nol, nol_next);
- free(nol);
- }
-}
-
-void
-sock_open(struct sockinfo *s)
-{
- struct icmp6_filter filt;
- int on;
- /* XXX: should be max MTU attached to the node */
- static char answer[1500];
-
- syslog(LOG_DEBUG, "<%s> enter", __func__);
-
- if (s == NULL) {
- syslog(LOG_ERR, "<%s> internal error", __func__);
- exit(1);
- }
- rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
- CMSG_SPACE(sizeof(int));
- rcvcmsgbuf = (char *)malloc(rcvcmsgbuflen);
- if (rcvcmsgbuf == NULL) {
- syslog(LOG_ERR, "<%s> not enough core", __func__);
- exit(1);
- }
-
- sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
- CMSG_SPACE(sizeof(int));
- sndcmsgbuf = (char *)malloc(sndcmsgbuflen);
- if (sndcmsgbuf == NULL) {
- syslog(LOG_ERR, "<%s> not enough core", __func__);
- exit(1);
- }
-
- if ((s->si_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
- syslog(LOG_ERR, "<%s> socket: %s", __func__, strerror(errno));
- exit(1);
- }
- /* specify to tell receiving interface */
- on = 1;
- if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
- sizeof(on)) < 0) {
- syslog(LOG_ERR, "<%s> IPV6_RECVPKTINFO: %s", __func__,
- strerror(errno));
- exit(1);
- }
- on = 1;
- /* specify to tell value of hoplimit field of received IP6 hdr */
- if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
- sizeof(on)) < 0) {
- syslog(LOG_ERR, "<%s> IPV6_RECVHOPLIMIT: %s", __func__,
- strerror(errno));
- exit(1);
- }
- ICMP6_FILTER_SETBLOCKALL(&filt);
- ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
- if (mcastif != NULL)
- ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt);
-
- if (setsockopt(s->si_fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
- sizeof(filt)) < 0) {
- syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s",
- __func__, strerror(errno));
- exit(1);
- }
-
- /* initialize msghdr for receiving packets */
- rcviov[0].iov_base = (caddr_t)answer;
- rcviov[0].iov_len = sizeof(answer);
- rcvmhdr.msg_name = (caddr_t)&rcvfrom;
- rcvmhdr.msg_namelen = sizeof(rcvfrom);
- rcvmhdr.msg_iov = rcviov;
- rcvmhdr.msg_iovlen = 1;
- rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
- rcvmhdr.msg_controllen = rcvcmsgbuflen;
-
- /* initialize msghdr for sending packets */
- sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
- sndmhdr.msg_iov = sndiov;
- sndmhdr.msg_iovlen = 1;
- sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
- sndmhdr.msg_controllen = sndcmsgbuflen;
-
- return;
-}
-
-/* open a routing socket to watch the routing table */
-static void
-rtsock_open(struct sockinfo *s)
-{
- if (s == NULL) {
- syslog(LOG_ERR, "<%s> internal error", __func__);
- exit(1);
- }
- if ((s->si_fd = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
- syslog(LOG_ERR,
- "<%s> socket: %s", __func__, strerror(errno));
- exit(1);
- }
-}
-
-struct ifinfo *
-if_indextoifinfo(int idx)
-{
- struct ifinfo *ifi;
- char *name, name0[IFNAMSIZ];
-
- /* Check if the interface has a valid name or not. */
- if (if_indextoname(idx, name0) == NULL)
- return (NULL);
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- if (ifi->ifi_ifindex == idx)
- return (ifi);
- }
-
- if (ifi != NULL)
- syslog(LOG_DEBUG, "<%s> ifi found (idx=%d)",
- __func__, idx);
- else
- syslog(LOG_DEBUG, "<%s> ifi not found (idx=%d)",
- __func__, idx);
-
- return (NULL); /* search failed */
-}
-
-void
-ra_output(struct ifinfo *ifi)
-{
- int i;
- struct cmsghdr *cm;
- struct in6_pktinfo *pi;
- struct soliciter *sol;
- struct rainfo *rai;
-
- switch (ifi->ifi_state) {
- case IFI_STATE_CONFIGURED:
- rai = ifi->ifi_rainfo;
- break;
- case IFI_STATE_TRANSITIVE:
- rai = ifi->ifi_rainfo_trans;
- break;
- case IFI_STATE_UNCONFIGURED:
- syslog(LOG_DEBUG, "<%s> %s is unconfigured. "
- "Skip sending RAs.",
- __func__, ifi->ifi_ifname);
- return;
- default:
- rai = NULL;
- }
- if (rai == NULL) {
- syslog(LOG_DEBUG, "<%s> rainfo is NULL on %s."
- "Skip sending RAs.",
- __func__, ifi->ifi_ifname);
- return;
- }
- if (!(ifi->ifi_flags & IFF_UP)) {
- syslog(LOG_DEBUG, "<%s> %s is not up. "
- "Skip sending RAs.",
- __func__, ifi->ifi_ifname);
- return;
- }
- /*
- * Check lifetime, ACCEPT_RTADV flag, and ip6.forwarding.
- *
- * (lifetime == 0) = output
- * (lifetime != 0 && (check_accept_rtadv()) = no output
- *
- * Basically, hosts MUST NOT send Router Advertisement
- * messages at any time (RFC 4861, Section 6.2.3). However, it
- * would sometimes be useful to allow hosts to advertise some
- * parameters such as prefix information and link MTU. Thus,
- * we allow hosts to invoke rtadvd only when router lifetime
- * (on every advertising interface) is explicitly set
- * zero. (see also the above section)
- */
- syslog(LOG_DEBUG,
- "<%s> check lifetime=%d, ACCEPT_RTADV=%d, ip6.forwarding=%d "
- "on %s", __func__,
- rai->rai_lifetime,
- check_accept_rtadv(ifi->ifi_ifindex),
- getinet6sysctl(IPV6CTL_FORWARDING),
- ifi->ifi_ifname);
-
- if (rai->rai_lifetime != 0) {
- if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) {
- syslog(LOG_ERR,
- "non-zero lifetime RA "
- "but net.inet6.ip6.forwarding=0. "
- "Ignored.");
- return;
- }
- if (check_accept_rtadv(ifi->ifi_ifindex)) {
- syslog(LOG_ERR,
- "non-zero lifetime RA "
- "on RA receiving interface %s."
- " Ignored.", ifi->ifi_ifname);
- return;
- }
- }
-
- make_packet(rai); /* XXX: inefficient */
-
- sndmhdr.msg_name = (caddr_t)&sin6_linklocal_allnodes;
- sndmhdr.msg_iov[0].iov_base = (caddr_t)rai->rai_ra_data;
- sndmhdr.msg_iov[0].iov_len = rai->rai_ra_datalen;
-
- cm = CMSG_FIRSTHDR(&sndmhdr);
- /* specify the outgoing interface */
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_PKTINFO;
- cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- pi = (struct in6_pktinfo *)CMSG_DATA(cm);
- memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/
- pi->ipi6_ifindex = ifi->ifi_ifindex;
-
- /* specify the hop limit of the packet */
- {
- int hoplimit = 255;
-
- cm = CMSG_NXTHDR(&sndmhdr, cm);
- cm->cmsg_level = IPPROTO_IPV6;
- cm->cmsg_type = IPV6_HOPLIMIT;
- cm->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
- }
-
- syslog(LOG_DEBUG,
- "<%s> send RA on %s, # of RS waitings = %d",
- __func__, ifi->ifi_ifname, ifi->ifi_rs_waitcount);
-
- i = sendmsg(sock.si_fd, &sndmhdr, 0);
-
- if (i < 0 || (size_t)i != rai->rai_ra_datalen) {
- if (i < 0) {
- syslog(LOG_ERR, "<%s> sendmsg on %s: %s",
- __func__, ifi->ifi_ifname,
- strerror(errno));
- }
- }
-
- /*
- * unicast advertisements
- * XXX commented out. reason: though spec does not forbit it, unicast
- * advert does not really help
- */
- while ((sol = TAILQ_FIRST(&rai->rai_soliciter)) != NULL) {
- TAILQ_REMOVE(&rai->rai_soliciter, sol, sol_next);
- free(sol);
- }
-
- /* update timestamp */
- clock_gettime(CLOCK_MONOTONIC_FAST, &ifi->ifi_ra_lastsent);
-
- /* update counter */
- ifi->ifi_rs_waitcount = 0;
- ifi->ifi_raoutput++;
-
- switch (ifi->ifi_state) {
- case IFI_STATE_CONFIGURED:
- if (ifi->ifi_burstcount > 0)
- ifi->ifi_burstcount--;
- break;
- case IFI_STATE_TRANSITIVE:
- ifi->ifi_burstcount--;
- if (ifi->ifi_burstcount == 0) {
- if (ifi->ifi_rainfo == ifi->ifi_rainfo_trans) {
- /* Initial burst finished. */
- if (ifi->ifi_rainfo_trans != NULL)
- ifi->ifi_rainfo_trans = NULL;
- }
-
- /* Remove burst RA information */
- if (ifi->ifi_rainfo_trans != NULL) {
- rm_rainfo(ifi->ifi_rainfo_trans);
- ifi->ifi_rainfo_trans = NULL;
- }
-
- if (ifi->ifi_rainfo != NULL) {
- /*
- * TRANSITIVE -> CONFIGURED
- *
- * After initial burst or transition from
- * one configuration to another,
- * ifi_rainfo always points to the next RA
- * information.
- */
- ifi->ifi_state = IFI_STATE_CONFIGURED;
- syslog(LOG_DEBUG,
- "<%s> ifname=%s marked as "
- "CONFIGURED.", __func__,
- ifi->ifi_ifname);
- } else {
- /*
- * TRANSITIVE -> UNCONFIGURED
- *
- * If ifi_rainfo points to NULL, this
- * interface is shutting down.
- *
- */
- int error;
-
- ifi->ifi_state = IFI_STATE_UNCONFIGURED;
- syslog(LOG_DEBUG,
- "<%s> ifname=%s marked as "
- "UNCONFIGURED.", __func__,
- ifi->ifi_ifname);
- error = sock_mc_leave(&sock,
- ifi->ifi_ifindex);
- if (error)
- exit(1);
- }
- }
- break;
- }
-}
-
-/* process RA timer */
-struct rtadvd_timer *
-ra_timeout(void *arg)
-{
- struct ifinfo *ifi;
-
- ifi = (struct ifinfo *)arg;
- syslog(LOG_DEBUG, "<%s> RA timer on %s is expired",
- __func__, ifi->ifi_ifname);
-
- ra_output(ifi);
-
- return (ifi->ifi_ra_timer);
-}
-
-/* update RA timer */
-void
-ra_timer_update(void *arg, struct timespec *tm)
-{
- uint16_t interval;
- struct rainfo *rai;
- struct ifinfo *ifi;
-
- ifi = (struct ifinfo *)arg;
- rai = ifi->ifi_rainfo;
- interval = 0;
-
- switch (ifi->ifi_state) {
- case IFI_STATE_UNCONFIGURED:
- return;
- break;
- case IFI_STATE_CONFIGURED:
- /*
- * Whenever a multicast advertisement is sent from
- * an interface, the timer is reset to a
- * uniformly-distributed random value between the
- * interface's configured MinRtrAdvInterval and
- * MaxRtrAdvInterval (RFC4861 6.2.4).
- */
- interval = rai->rai_mininterval;
- interval += arc4random_uniform(rai->rai_maxinterval -
- rai->rai_mininterval);
- break;
- case IFI_STATE_TRANSITIVE:
- /*
- * For the first few advertisements (up to
- * MAX_INITIAL_RTR_ADVERTISEMENTS), if the randomly chosen
- * interval is greater than
- * MAX_INITIAL_RTR_ADVERT_INTERVAL, the timer SHOULD be
- * set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead. (RFC
- * 4861 6.2.4)
- *
- * In such cases, the router SHOULD transmit one or more
- * (but not more than MAX_FINAL_RTR_ADVERTISEMENTS) final
- * multicast Router Advertisements on the interface with a
- * Router Lifetime field of zero. (RFC 4861 6.2.5)
- */
- interval = ifi->ifi_burstinterval;
- break;
- }
-
- tm->tv_sec = interval;
- tm->tv_nsec = 0;
-
- syslog(LOG_DEBUG,
- "<%s> RA timer on %s is set to %ld:%ld",
- __func__, ifi->ifi_ifname,
- (long int)tm->tv_sec, (long int)tm->tv_nsec / 1000);
-
- return;
-}
diff --git a/usr.sbin/rtadvd/rtadvd.conf b/usr.sbin/rtadvd/rtadvd.conf
deleted file mode 100644
index 1e42c75..0000000
--- a/usr.sbin/rtadvd/rtadvd.conf
+++ /dev/null
@@ -1,22 +0,0 @@
-# $FreeBSD$
-# $KAME: rtadvd.conf,v 1.13 2003/06/25 03:45:21 itojun Exp $
-#
-# Note: All of the following parameters have default values defined
-# in specifications, and hence you usually do not have to set them
-# by hand unless you need special non-default values.
-#
-# You even do not need to create the configuration file. rtadvd
-# would usually work well without a configuration file.
-# See also: rtadvd(8)
-
-# per-interface definitions.
-# Mainly IPv6 prefixes are configured in this part. However, rtadvd
-# automatically learns appropriate prefixes from the kernel's routing
-# table, and advertises the prefixes, so you don't have to configure
-# this part, either.
-# If you don't want the automatic advertisement, (uncomment and) configure
-# this part by hand, and then invoke rtadvd with the -s option.
-
-#ef0:\
-# :addr="2001:db8:ffff:1000::":prefixlen#64:\
-# :rdnss="2001:db8:ffff:1000::1":dnssl="example.com":
diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5
deleted file mode 100644
index d4a0c02..0000000
--- a/usr.sbin/rtadvd/rtadvd.conf.5
+++ /dev/null
@@ -1,530 +0,0 @@
-.\" $KAME: rtadvd.conf.5,v 1.50 2005/01/14 05:30:59 jinmei Exp $
-.\"
-.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the project nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd June 4, 2011
-.Dt RTADVD.CONF 5
-.Os
-.Sh NAME
-.Nm rtadvd.conf
-.Nd config file for router advertisement daemon
-.Sh DESCRIPTION
-This file describes how the router advertisement packets must be constructed
-for each of the interfaces.
-.Pp
-As described in
-.Xr rtadvd 8 ,
-you do not have to set this configuration file up at all,
-unless you need some special configurations.
-You may even omit the file as a whole.
-In such cases, the
-.Nm rtadvd
-daemon will automatically configure itself using default values
-specified in the specification.
-.Pp
-It obeys the famous
-.Xr termcap 5
-file format.
-Each line in the file describes a network interface.
-Fields are separated by a colon
-.Pq Sq \&: ,
-and each field contains one capability description.
-Lines may be concatenated by the
-.Sq \e
-character.
-The comment marker is the
-.Sq \&#
-character.
-.Sh CAPABILITIES
-Capabilities describe the value to be filled into ICMPv6 router
-advertisement messages and to control
-.Xr rtadvd 8
-behavior.
-Therefore, you are encouraged to read IETF neighbor discovery documents
-if you would like to modify the sample configuration file.
-.Pp
-Note that almost all items have default values.
-If you omit an item, the default value of the item will be used.
-.Pp
-There are two items which control the interval of sending router advertisements.
-These items can be omitted, then
-.Nm rtadvd
-will use the default values.
-.Bl -tag -width indent
-.It Cm \&maxinterval
-(num) The maximum time allowed between sending unsolicited
-multicast router advertisements
-.Pq unit: seconds .
-The default value is 600.
-Its value must be no less than 4 seconds
-and no greater than 1800 seconds.
-.It Cm \&mininterval
-(num) The minimum time allowed between sending unsolicited multicast
-router advertisements
-.Pq unit: seconds .
-The default value is the one third of value of
-.Cm maxinterval .
-Its value must be no less than 3 seconds and no greater than .75 *
-the value of
-.Cm maxinterval .
-.El
-.Pp
-The following items are for ICMPv6 router advertisement message
-header.
-These items can be omitted, then
-.Nm rtadvd
-will use the default values.
-.Bl -tag -width indent
-.It Cm \&chlim
-(num) The value for Cur Hop Limit field.
-The default value is 64.
-.It Cm \&raflags
-(str or num) A 8-bit flags field in router advertisement message header.
-This field can be specified either as a case-sensitive string or as an
-integer.
-A string consists of characters each of which corresponds to a
-particular flag bit(s).
-An integer should be the logical OR of all enabled bits.
-Bit 7
-.Po
-.Li 'm' or 0x80
-.Pc
-means Managed address configuration flag bit,
-and Bit 6
-.Po
-.Li 'o' or 0x40
-.Pc
-means Other stateful configuration flag bit.
-Bit 4
-.Po
-.Li 0x10
-.Pc
-and Bit 3
-.Po
-.Li 0x08
-.Pc
-are used to encode router preference.
-Bits 01
-.Po
-or 'h'
-.Pc
-means high, 00 means medium, and 11
-.Po
-or 'l'
-.Pc
-means low.
-Bits 10 is reserved, and must not be specified.
-There is no character to specify the medium preference explicitly.
-The default value of the entire flag is 0
-.Po
-or a null string,
-.Pc
-which means no additional
-configuration methods, and the medium router preference.
-.It Cm \&rltime
-(num) Router lifetime field
-.Pq unit: seconds .
-The value must be either zero or between
-the value of
-.Cm maxinterval
-and 9000.
-When
-.Nm rtadvd
-runs on a host, this value must explicitly set 0 on all the
-advertising interfaces as described in
-.Xr rtadvd 8 .
-The default value is 1800.
-.It Cm \&rtime
-(num) Reachable time field
-.Pq unit: milliseconds .
-The default value is 0, which means unspecified by this router.
-.It Cm \&retrans
-(num) Retrans Timer field
-.Pq unit: milliseconds .
-The default value is 0, which means unspecified by this router.
-.El
-.Pp
-The following items are for ICMPv6 prefix information option,
-which will be attached to router advertisement header.
-These items can be omitted, then
-.Nm rtadvd
-will automatically get appropriate prefixes from the kernel's routing table,
-and advertise the prefixes with the default parameters.
-Keywords other than
-.Cm clockskew
-and
-.Cm noifprefix
-can be augmented with a number, like
-.Dq Li prefix2 ,
-to specify multiple prefixes.
-.Bl -tag -width indent
-.It Cm \&noifprefix
-(bool) Specifies no prefix on the network interfaces will be advertised.
-By default
-.Nm rtadvd
-automatically gathers on-link prefixes from all of the network interfaces
-and advertise them.
-The
-.Cm noifprefix
-disables that behavior.
-If this is specified and no
-.Cm addr
-keyword is specified, no prefix information option will be included in the
-message.
-.It Cm \&clockskew
-(num) Time skew to adjust link propagation delays and clock skews
-between routers on the link
-.Pq unit: seconds .
-This value is used in consistency check for locally-configured and
-advertised prefix lifetimes, and has its meaning when the local router
-configures a prefix on the link with a lifetime that decrements in
-real time.
-If the value is 0, it means the consistency check will be skipped
-for such prefixes.
-The default value is 0.
-.It Cm \&prefixlen
-(num) Prefix length field.
-The default value is 64.
-.It Cm \&pinfoflags
-(str or num) A 8-bit flags field in prefix information option.
-This field can be specified either as a case-sensitive string or as an
-integer.
-A string consists of characters each of which corresponds to a
-particular flag bit(s).
-An integer should be the logical OR of all enabled bits.
-Bit 7
-.Po
-.Li 'l' or 0x80
-.Pc
-means On-link flag bit,
-and Bit 6
-.Po
-.Li 'a' or 0x40
-.Pc
-means Autonomous address-configuration flag bit.
-The default value is "la" or 0xc0, i.e., both bits are set.
-.It Cm \&addr
-(str) The address filled into Prefix field.
-Since
-.Dq \&:
-is used for
-.Xr termcap 5
-file format as well as IPv6 numeric address, the field MUST be quoted by
-doublequote character.
-.It Cm \&vltime
-(num) Valid lifetime field
-.Pq unit: seconds .
-The default value is 2592000 (30 days).
-.It Cm \&vltimedecr
-(bool) This item means the advertised valid lifetime will decrement
-in real time, which is disabled by default.
-.It Cm \&pltime
-(num) Preferred lifetime field
-.Pq unit: seconds .
-The default value is 604800 (7 days).
-.It Cm \&pltimedecr
-(bool) This item means the advertised preferred lifetime will decrement
-in real time, which is disabled by default.
-.El
-.Pp
-The following item is for ICMPv6 MTU option,
-which will be attached to router advertisement header.
-This item can be omitted, then
-.Nm rtadvd
-will use the default value.
-.Bl -tag -width indent
-.It Cm \&mtu
-(num or str) MTU (maximum transmission unit) field.
-If 0 is specified, it means that the option will not be included.
-The default value is 0.
-If the special string
-.Dq auto
-is specified for this item, MTU option will be included and its value
-will be set to the interface MTU automatically.
-.El
-.Pp
-The following item controls ICMPv6 source link-layer address option,
-which will be attached to router advertisement header.
-As noted above, you can just omit the item, then
-.Nm rtadvd
-will use the default value.
-.Bl -tag -width indent
-.It Cm \&nolladdr
-(bool) By default
-.Po
-if
-.Cm \&nolladdr
-is not specified
-.Pc ,
-.Xr rtadvd 8
-will try to get link-layer address for the interface from the kernel,
-and attach that in source link-layer address option.
-If this capability exists,
-.Xr rtadvd 8
-will not attach source link-layer address option to
-router advertisement packets.
-.El
-.Pp
-The following item controls ICMPv6 home agent information option,
-which was defined with mobile IPv6 support.
-It will be attached to router advertisement header just like other options do.
-.Bl -tag -width indent
-.It Cm \&hapref
-(num) Specifies home agent preference.
-If set to non-zero,
-.Cm \&hatime
-must be present as well.
-.It Cm \&hatime
-(num) Specifies home agent lifetime.
-.El
-.Pp
-When mobile IPv6 support is turned on for
-.Xr rtadvd 8 ,
-advertisement interval option will be attached to router advertisement
-packet, by configuring
-.Cm \&maxinterval
-explicitly.
-.Pp
-The following items are for ICMPv6 route information option,
-which will be attached to router advertisement header.
-These items are optional.
-Each items can be augmented with number, like
-.Dq Li rtplen2 ,
-to specify multiple routes.
-.Bl -tag -width indent
-.It Cm \&rtprefix
-(str) The prefix filled into the Prefix field of route information option.
-Since
-.Dq \&:
-is used for
-.Xr termcap 5
-file format as well as IPv6 numeric address, the field MUST be quoted by
-doublequote character.
-.It Cm \&rtplen
-(num) Prefix length field in route information option.
-The default value is 64.
-.It Cm \&rtflags
-(str or num) A 8-bit flags field in route information option.
-Currently only the preference values are defined.
-The notation is same as that of the raflags field.
-Bit 4
-.Po
-.Li 0x10
-.Pc
-and
-Bit 3
-.Po
-.Li 0x08
-.Pc
-are used to encode the route preference for the route.
-The default value is 0x00, i.e., medium preference.
-.It Cm \&rtltime
-(num) route lifetime field in route information option.
-.Pq unit: seconds .
-Since the specification does not define the default value of this
-item, the value for this item should be specified by hand.
-However,
-.Nm rtadvd
-allows this item to be unspecified, and uses the router lifetime
-as the default value in such a case, just for compatibility with an
-old version of the program.
-.El
-.Pp
-In the above list, each keyword beginning with
-.Dq Li rt
-could be replaced with the one beginning with
-.Dq Li rtr
-for backward compatibility reason.
-For example,
-.Cm rtrplen
-is accepted instead of
-.Cm rtplen .
-However, keywords that start with
-.Dq Li rtr
-have basically been obsoleted, and should not be used any more.
-.Pp
-The following items are for ICMPv6 Recursive DNS Server Option and
-DNS Search List Option
-.Pq RFC 6106 ,
-which will be attached to router advertisement header.
-These items are optional.
-.Bl -tag -width indent
-.It Cm \&rdnss
-(str) The IPv6 address of one or more recursive DNS servers.
-The argument must be inside double quotes.
-Multiple DNS servers can be specified in a comma-separated string.
-If different lifetimes are needed for different servers,
-separate entries can be given by using
-.Cm rdnss ,
-.Cm rdnss0 ,
-.Cm rdnss1 ,
-.Cm rdnss2 ...
-options with corresponding
-.Cm rdnssltime ,
-.Cm rdnssltime0 ,
-.Cm rdnssltime1 ,
-.Cm rdnssltime2 ...
-entries.
-Note that the maximum number of servers depends on the receiver side.
-See also
-.Xr resolver 5
-manual page for resolver implementation in
-.Fx .
-.It Cm \&rdnssltime
-The lifetime of the
-.Cm rdnss
-DNS server entries.
-The default value is 3/2 of the interval time.
-.It Cm \&dnssl
-(str) One or more domain names in a comma-separated string.
-These domain names will be used when making DNS queries on a
-non-fully-qualified domain name.
-If different lifetimes are needed for different domains, separate entries
-can be given by using
-.Cm dnssl ,
-.Cm dnssl0 ,
-.Cm dnssl1 ,
-.Cm dnssl2 ...
-options with corresponding
-.Cm dnsslltime ,
-.Cm dnsslltime0 ,
-.Cm dnsslltime1 ,
-.Cm dnsslltime2 ...
-entries.
-Note that the maximum number of names depends on the receiver side.
-See also
-.Xr resolver 5
-manual page for resolver implementation in
-.Fx .
-.It Cm \&dnsslltime
-The lifetime of the
-.Cm dnssl
-DNS search list entries.
-The default value is 3/2 of the interval time.
-.El
-.Pp
-You can also refer one line from another by using
-.Cm tc
-capability.
-See
-.Xr termcap 5
-for details on the capability.
-.Sh EXAMPLES
-As presented above, all of the advertised parameters have default values
-defined in specifications, and hence you usually do not have to set them
-by hand, unless you need special non-default values.
-It can cause interoperability problem if you use an ill-configured
-parameter.
-.Pp
-To override a configuration parameter, you can specify the parameter alone.
-With the following configuration,
-.Xr rtadvd 8
-overrides the router lifetime parameter for the
-.Li ne0
-interface.
-.Bd -literal -offset indent
-ne0:\\
- :rltime#0:
-.Ed
-.Pp
-The following example manually configures prefixes advertised from the
-.Li ef0
-interface.
-The configuration must be used with the
-.Fl s
-option to
-.Xr rtadvd 8 .
-.Bd -literal -offset indent
-ef0:\\
- :addr="2001:db8:ffff:1000::":prefixlen#64:
-.Ed
-.Pp
-The following example configures the
-.Li wlan0
-interface and adds two DNS servers and a DNS domain search options
-using the default option lifetime values.
-.Bd -literal -offset indent
-wlan0:\\
- :addr="2001:db8:ffff:1000::":prefixlen#64:\\
- :rdnss="2001:db8:ffff::10,2001:db8:ffff::2:43":\\
- :dnssl="example.com":
-.Ed
-.Pp
-The following example presents the default values in an explicit manner.
-The configuration is provided just for reference purposes;
-YOU DO NOT NEED TO HAVE IT AT ALL.
-.Bd -literal -offset indent
-default:\\
- :chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\\
- :pinfoflags="la":vltime#2592000:pltime#604800:mtu#0:
-ef0:\\
- :addr="2001:db8:ffff:1000::":prefixlen#64:tc=default:
-.Ed
-.Sh SEE ALSO
-.Xr resolver 5 ,
-.Xr termcap 5 ,
-.Xr rtadvd 8 ,
-.Xr rtsol 8
-.Rs
-.%A Thomas Narten
-.%A Erik Nordmark
-.%A W. A. Simpson
-.%A Hesham Soliman
-.%T Neighbor Discovery for IP version 6 (IPv6)
-.%R RFC 4861
-.Re
-.Rs
-.%A Thomas Narten
-.%A Erik Nordmark
-.%A W. A. Simpson
-.%T Neighbor Discovery for IP version 6 (IPv6)
-.%R RFC 2461 (obsoleted by RFC 4861)
-.Re
-.Rs
-.%A Richard Draves
-.%T Default Router Preferences and More-Specific Routes
-.%R draft-ietf-ipngwg-router-selection-xx.txt
-.Re
-.Rs
-.%A J. Jeong
-.%A S. Park
-.%A L. Beloeil
-.%A S. Madanapalli
-.%T IPv6 Router Advertisement Options for DNS Configuration
-.%R RFC 6106
-.Re
-.Sh HISTORY
-The
-.Xr rtadvd 8
-and the configuration file
-.Nm
-first appeared in WIDE Hydrangea IPv6 protocol stack kit.
-.\" .Sh BUGS
-.\" (to be written)
diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h
deleted file mode 100644
index e7ed87f..0000000
--- a/usr.sbin/rtadvd/rtadvd.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: rtadvd.h,v 1.26 2003/08/05 12:34:23 itojun Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define ELM_MALLOC(p,error_action) \
- do { \
- p = malloc(sizeof(*p)); \
- if (p == NULL) { \
- syslog(LOG_ERR, "<%s> malloc failed: %s", \
- __func__, strerror(errno)); \
- error_action; \
- } \
- memset(p, 0, sizeof(*p)); \
- } while(0)
-
-#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
- {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
-
-#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
- {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
-
-#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT \
- {{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
-
-extern struct sockaddr_in6 sin6_linklocal_allnodes;
-extern struct sockaddr_in6 sin6_linklocal_allrouters;
-extern struct sockaddr_in6 sin6_sitelocal_allrouters;
-
-/*
- * RFC 3542 API deprecates IPV6_PKTINFO in favor of
- * IPV6_RECVPKTINFO
- */
-#ifndef IPV6_RECVPKTINFO
-#ifdef IPV6_PKTINFO
-#define IPV6_RECVPKTINFO IPV6_PKTINFO
-#endif
-#endif
-
-/*
- * RFC 3542 API deprecates IPV6_HOPLIMIT in favor of
- * IPV6_RECVHOPLIMIT
- */
-#ifndef IPV6_RECVHOPLIMIT
-#ifdef IPV6_HOPLIMIT
-#define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
-#endif
-#endif
-
-/* protocol constants and default values */
-#define DEF_MAXRTRADVINTERVAL 600
-#define DEF_ADVLINKMTU 0
-#define DEF_ADVREACHABLETIME 0
-#define DEF_ADVRETRANSTIMER 0
-#define DEF_ADVCURHOPLIMIT 64
-#define DEF_ADVVALIDLIFETIME 2592000
-#define DEF_ADVPREFERREDLIFETIME 604800
-
-#define MAXROUTERLIFETIME 9000
-#define MIN_MAXINTERVAL 4
-#define MAX_MAXINTERVAL 1800
-#define MIN_MININTERVAL 3
-#define MAXREACHABLETIME 3600000
-
-#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16
-#define MAX_INITIAL_RTR_ADVERTISEMENTS 3
-#define MAX_FINAL_RTR_ADVERTISEMENTS 3
-#define MIN_DELAY_BETWEEN_RAS 3
-#define MAX_RA_DELAY_TIME 500000 /* usec */
-
-#define PREFIX_FROM_KERNEL 1
-#define PREFIX_FROM_CONFIG 2
-#define PREFIX_FROM_DYNAMIC 3
-
-struct prefix {
- TAILQ_ENTRY(prefix) pfx_next;
-
- struct rainfo *pfx_rainfo; /* back pointer to the interface */
- /*
- * Expiration timer. This is used when a prefix derived from
- * the kernel is deleted.
- */
- struct rtadvd_timer *pfx_timer;
-
- uint32_t pfx_validlifetime; /* AdvValidLifetime */
- uint32_t pfx_vltimeexpire; /* Expiration of vltime */
- uint32_t pfx_preflifetime; /* AdvPreferredLifetime */
- uint32_t pfx_pltimeexpire; /* Expiration of pltime */
- int pfx_onlinkflg; /* bool: AdvOnLinkFlag */
- int pfx_autoconfflg; /* bool: AdvAutonomousFlag */
- int pfx_prefixlen;
- int pfx_origin; /* From kernel or config */
-
- struct in6_addr pfx_prefix;
-};
-
-struct rtinfo {
- TAILQ_ENTRY(rtinfo) rti_next;
-
- uint32_t rti_ltime; /* route lifetime */
- int rti_rtpref; /* route preference */
- int rti_prefixlen;
- struct in6_addr rti_prefix;
-};
-
-struct rdnss_addr {
- TAILQ_ENTRY(rdnss_addr) ra_next;
-
- struct in6_addr ra_dns; /* DNS server entry */
-};
-
-struct rdnss {
- TAILQ_ENTRY(rdnss) rd_next;
-
- TAILQ_HEAD(, rdnss_addr) rd_list; /* list of DNS servers */
- uint32_t rd_ltime; /* number of seconds valid */
-};
-
-/*
- * The maximum length of a domain name in a DNS search list is calculated
- * by a domain name + length fields per 63 octets + a zero octet at
- * the tail and adding 8 octet boundary padding.
- */
-#define _DNAME_LABELENC_MAXLEN \
- (NI_MAXHOST + (NI_MAXHOST / 64 + 1) + 1)
-
-#define DNAME_LABELENC_MAXLEN \
- (_DNAME_LABELENC_MAXLEN + 8 - _DNAME_LABELENC_MAXLEN % 8)
-
-struct dnssl_addr {
- TAILQ_ENTRY(dnssl_addr) da_next;
-
- int da_len; /* length of entry */
- char da_dom[DNAME_LABELENC_MAXLEN]; /* search domain name entry */
-};
-
-struct dnssl {
- TAILQ_ENTRY(dnssl) dn_next;
-
- TAILQ_HEAD(, dnssl_addr) dn_list; /* list of search domains */
- uint32_t dn_ltime; /* number of seconds valid */
-};
-
-struct soliciter {
- TAILQ_ENTRY(soliciter) sol_next;
-
- struct sockaddr_in6 sol_addr;
-};
-
-struct rainfo {
- /* pointer for list */
- TAILQ_ENTRY(rainfo) rai_next;
-
- /* interface information */
- struct ifinfo *rai_ifinfo;
-
- int rai_advlinkopt; /* bool: whether include link-layer addr opt */
- int rai_advifprefix; /* bool: gather IF prefixes? */
-
- /* Router configuration variables */
- uint16_t rai_lifetime; /* AdvDefaultLifetime */
- uint16_t rai_maxinterval; /* MaxRtrAdvInterval */
- uint16_t rai_mininterval; /* MinRtrAdvInterval */
- int rai_managedflg; /* AdvManagedFlag */
- int rai_otherflg; /* AdvOtherConfigFlag */
-
- int rai_rtpref; /* router preference */
- uint32_t rai_linkmtu; /* AdvLinkMTU */
- uint32_t rai_reachabletime; /* AdvReachableTime */
- uint32_t rai_retranstimer; /* AdvRetransTimer */
- uint8_t rai_hoplimit; /* AdvCurHopLimit */
-
- TAILQ_HEAD(, prefix) rai_prefix;/* AdvPrefixList(link head) */
- int rai_pfxs; /* number of prefixes */
-
- uint16_t rai_clockskew; /* used for consisitency check of lifetimes */
-
- TAILQ_HEAD(, rdnss) rai_rdnss; /* DNS server list */
- TAILQ_HEAD(, dnssl) rai_dnssl; /* search domain list */
- TAILQ_HEAD(, rtinfo) rai_route; /* route information option (link head) */
- int rai_routes; /* number of route information options */
- /* actual RA packet data and its length */
- size_t rai_ra_datalen;
- char *rai_ra_data;
-
- /* info about soliciter */
- TAILQ_HEAD(, soliciter) rai_soliciter; /* recent solication source */
-};
-
-/* RA information list */
-extern TAILQ_HEAD(railist_head_t, rainfo) railist;
-
-/*
- * ifi_state:
- *
- * (INIT)
- * |
- * | update_ifinfo()
- * | update_persist_ifinfo()
- * v
- * UNCONFIGURED
- * | ^
- * loadconfig()| |rm_ifinfo(), ra_output()
- * (MC join)| |(MC leave)
- * | |
- * | |
- * v |
- * TRANSITIVE
- * | ^
- * ra_output()| |getconfig()
- * | |
- * | |
- * | |
- * v |
- * CONFIGURED
- *
- *
- */
-#define IFI_STATE_UNCONFIGURED 0
-#define IFI_STATE_CONFIGURED 1
-#define IFI_STATE_TRANSITIVE 2
-
-struct ifinfo {
- TAILQ_ENTRY(ifinfo) ifi_next;
-
- uint16_t ifi_state;
- uint16_t ifi_persist;
- uint16_t ifi_ifindex;
- char ifi_ifname[IFNAMSIZ];
- uint8_t ifi_type;
- uint16_t ifi_flags;
- uint32_t ifi_nd_flags;
- uint32_t ifi_phymtu;
- struct sockaddr_dl ifi_sdl;
-
- struct rainfo *ifi_rainfo;
- struct rainfo *ifi_rainfo_trans;
- uint16_t ifi_burstcount;
- uint32_t ifi_burstinterval;
- struct rtadvd_timer *ifi_ra_timer;
- /* timestamp when the latest RA was sent */
- struct timespec ifi_ra_lastsent;
- uint16_t ifi_rs_waitcount;
-
- /* statistics */
- uint64_t ifi_raoutput; /* # of RAs sent */
- uint64_t ifi_rainput; /* # of RAs received */
- uint64_t ifi_rainconsistent; /* # of inconsistent recv'd RAs */
- uint64_t ifi_rsinput; /* # of RSs received */
-};
-
-/* Interface list */
-extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
-
-extern char *mcastif;
-
-struct rtadvd_timer *ra_timeout(void *);
-void ra_timer_update(void *, struct timespec *);
-void ra_output(struct ifinfo *);
-
-int prefix_match(struct in6_addr *, int,
- struct in6_addr *, int);
-struct ifinfo *if_indextoifinfo(int);
-struct prefix *find_prefix(struct rainfo *,
- struct in6_addr *, int);
-void rtadvd_set_reload(int);
-void rtadvd_set_shutdown(int);
diff --git a/usr.sbin/rtadvd/timer.c b/usr.sbin/rtadvd/timer.c
deleted file mode 100644
index 452add4..0000000
--- a/usr.sbin/rtadvd/timer.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: timer.c,v 1.9 2002/06/10 19:59:47 itojun Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <netinet/in.h>
-
-#include <unistd.h>
-#include <syslog.h>
-#include <stdlib.h>
-#include <string.h>
-#include <search.h>
-#include <time.h>
-#include <netdb.h>
-
-#include "rtadvd.h"
-#include "timer_subr.h"
-#include "timer.h"
-
-struct rtadvd_timer_head_t ra_timer =
- TAILQ_HEAD_INITIALIZER(ra_timer);
-static struct timespec tm_limit;
-static struct timespec tm_max;
-
-void
-rtadvd_timer_init(void)
-{
- /* Generate maximum time in timespec. */
- tm_limit.tv_sec = (-1) & ~((time_t)1 << ((sizeof(tm_max.tv_sec) * 8) - 1));
- tm_limit.tv_nsec = (-1) & ~((long)1 << ((sizeof(tm_max.tv_nsec) * 8) - 1));
- tm_max = tm_limit;
- TAILQ_INIT(&ra_timer);
-}
-
-void
-rtadvd_update_timeout_handler(void)
-{
- struct ifinfo *ifi;
-
- TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
- switch (ifi->ifi_state) {
- case IFI_STATE_CONFIGURED:
- case IFI_STATE_TRANSITIVE:
- if (ifi->ifi_ra_timer != NULL)
- continue;
-
- syslog(LOG_DEBUG, "<%s> add timer for %s (idx=%d)",
- __func__, ifi->ifi_ifname, ifi->ifi_ifindex);
- ifi->ifi_ra_timer = rtadvd_add_timer(ra_timeout,
- ra_timer_update, ifi, ifi);
- ra_timer_update((void *)ifi,
- &ifi->ifi_ra_timer->rat_tm);
- rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
- ifi->ifi_ra_timer);
- break;
- case IFI_STATE_UNCONFIGURED:
- if (ifi->ifi_ra_timer == NULL)
- continue;
-
- syslog(LOG_DEBUG,
- "<%s> remove timer for %s (idx=%d)", __func__,
- ifi->ifi_ifname, ifi->ifi_ifindex);
- rtadvd_remove_timer(ifi->ifi_ra_timer);
- ifi->ifi_ra_timer = NULL;
- break;
- }
- }
-
- return;
-}
-
-struct rtadvd_timer *
-rtadvd_add_timer(struct rtadvd_timer *(*timeout)(void *),
- void (*update)(void *, struct timespec *),
- void *timeodata, void *updatedata)
-{
- struct rtadvd_timer *rat;
-
- if (timeout == NULL) {
- syslog(LOG_ERR,
- "<%s> timeout function unspecified", __func__);
- exit(1);
- }
-
- rat = malloc(sizeof(*rat));
- if (rat == NULL) {
- syslog(LOG_ERR,
- "<%s> can't allocate memory", __func__);
- exit(1);
- }
- memset(rat, 0, sizeof(*rat));
-
- rat->rat_expire = timeout;
- rat->rat_update = update;
- rat->rat_expire_data = timeodata;
- rat->rat_update_data = updatedata;
- rat->rat_tm = tm_max;
-
- /* link into chain */
- TAILQ_INSERT_TAIL(&ra_timer, rat, rat_next);
-
- return (rat);
-}
-
-void
-rtadvd_remove_timer(struct rtadvd_timer *rat)
-{
-
- if (rat == NULL)
- return;
-
- TAILQ_REMOVE(&ra_timer, rat, rat_next);
- free(rat);
-}
-
-/*
- * Check expiration for each timer. If a timer expires,
- * call the expire function for the timer and update the timer.
- * Return the next interval for select() call.
- */
-struct timespec *
-rtadvd_check_timer(void)
-{
- static struct timespec returnval;
- struct timespec now;
- struct rtadvd_timer *rat;
-
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- tm_max = tm_limit;
- TAILQ_FOREACH(rat, &ra_timer, rat_next) {
- if (TS_CMP(&rat->rat_tm, &now, <=)) {
- if (((*rat->rat_expire)(rat->rat_expire_data) == NULL))
- continue; /* the timer was removed */
- if (rat->rat_update)
- (*rat->rat_update)(rat->rat_update_data, &rat->rat_tm);
- TS_ADD(&rat->rat_tm, &now, &rat->rat_tm);
- }
- if (TS_CMP(&rat->rat_tm, &tm_max, <))
- tm_max = rat->rat_tm;
- }
- if (TS_CMP(&tm_max, &tm_limit, ==)) {
- /* no need to timeout */
- return (NULL);
- } else if (TS_CMP(&tm_max, &now, <)) {
- /* this may occur when the interval is too small */
- returnval.tv_sec = returnval.tv_nsec = 0;
- } else
- TS_SUB(&tm_max, &now, &returnval);
- return (&returnval);
-}
-
-void
-rtadvd_set_timer(struct timespec *tm, struct rtadvd_timer *rat)
-{
- struct timespec now;
-
- /* reset the timer */
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- TS_ADD(&now, tm, &rat->rat_tm);
-
- /* update the next expiration time */
- if (TS_CMP(&rat->rat_tm, &tm_max, <))
- tm_max = rat->rat_tm;
-
- return;
-}
diff --git a/usr.sbin/rtadvd/timer.h b/usr.sbin/rtadvd/timer.h
deleted file mode 100644
index 4498aaf..0000000
--- a/usr.sbin/rtadvd/timer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: timer.h,v 1.5 2002/05/31 13:30:38 jinmei Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-extern TAILQ_HEAD(rtadvd_timer_head_t, rtadvd_timer) ra_timer;
-struct rtadvd_timer {
- TAILQ_ENTRY(rtadvd_timer) rat_next;
-
- struct rainfo *rat_rai;
- struct timespec rat_tm;
- struct rtadvd_timer *(*rat_expire)(void *);
- void *rat_expire_data;
- void (*rat_update)(void *, struct timespec *);
- void *rat_update_data;
-};
-
-void rtadvd_timer_init(void);
-void rtadvd_update_timeout_handler(void);
-struct rtadvd_timer *rtadvd_add_timer(struct rtadvd_timer *(*)(void *),
- void (*)(void *, struct timespec *), void *, void *);
-void rtadvd_set_timer(struct timespec *,
- struct rtadvd_timer *);
-void rtadvd_remove_timer(struct rtadvd_timer *);
-struct timespec *rtadvd_check_timer(void);
diff --git a/usr.sbin/rtadvd/timer_subr.c b/usr.sbin/rtadvd/timer_subr.c
deleted file mode 100644
index 0ddf0a4..0000000
--- a/usr.sbin/rtadvd/timer_subr.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: timer.c,v 1.9 2002/06/10 19:59:47 itojun Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <syslog.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <time.h>
-
-#include "timer.h"
-#include "timer_subr.h"
-
-struct timespec *
-rtadvd_timer_rest(struct rtadvd_timer *rat)
-{
- static struct timespec returnval, now;
-
- clock_gettime(CLOCK_MONOTONIC_FAST, &now);
- if (TS_CMP(&rat->rat_tm, &now, <=)) {
- syslog(LOG_DEBUG,
- "<%s> a timer must be expired, but not yet",
- __func__);
- returnval.tv_sec = returnval.tv_nsec = 0;
- }
- else
- TS_SUB(&rat->rat_tm, &now, &returnval);
-
- return (&returnval);
-}
-
-char *
-sec2str(uint32_t s, char *buf)
-{
- uint32_t day;
- uint32_t hour;
- uint32_t min;
- uint32_t sec;
- char *p;
-
- min = s / 60;
- sec = s % 60;
-
- hour = min / 60;
- min = min % 60;
-
- day = hour / 24;
- hour = hour % 24;
-
- p = buf;
- if (day > 0)
- p += sprintf(p, "%" PRIu32 "d", day);
- if (hour > 0)
- p += sprintf(p, "%" PRIu32 "h", hour);
- if (min > 0)
- p += sprintf(p, "%" PRIu32 "m", min);
-
- if ((p == buf) || (sec > 0 && p > buf))
- sprintf(p, "%" PRIu32 "s", sec);
-
- return (buf);
-}
diff --git a/usr.sbin/rtadvd/timer_subr.h b/usr.sbin/rtadvd/timer_subr.h
deleted file mode 100644
index 32e1bb1..0000000
--- a/usr.sbin/rtadvd/timer_subr.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: timer.h,v 1.5 2002/05/31 13:30:38 jinmei Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define SSBUFLEN 1024
-
-#define TS_CMP(tsp, usp, cmp) \
- (((tsp)->tv_sec == (usp)->tv_sec) ? \
- ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
- ((tsp)->tv_sec cmp (usp)->tv_sec))
-#define TS_ADD(tsp, usp, vsp) \
- do { \
- (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
- (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
- if ((vsp)->tv_nsec >= 1000000000L) { \
- (vsp)->tv_sec++; \
- (vsp)->tv_nsec -= 1000000000L; \
- } \
- } while (0)
-#define TS_SUB(tsp, usp, vsp) \
- do { \
- (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
- (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
- if ((vsp)->tv_nsec < 0) { \
- (vsp)->tv_sec--; \
- (vsp)->tv_nsec += 1000000000L; \
- } \
- } while (0)
-
-struct timespec *rtadvd_timer_rest(struct rtadvd_timer *);
-char *sec2str(uint32_t, char *buf);
OpenPOWER on IntegriCloud