From: florian Date: Mon, 23 Jul 2018 12:04:46 +0000 (+0000) Subject: Remove rtadvd(8), it's time to switch to rad(8). X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=796506dc8a6f6f1ff0d23d75aeec927eaed77039;p=openbsd Remove rtadvd(8), it's time to switch to rad(8). --- diff --git a/usr.sbin/rtadvd/Makefile b/usr.sbin/rtadvd/Makefile deleted file mode 100644 index 53c34328445..00000000000 --- a/usr.sbin/rtadvd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $OpenBSD: Makefile,v 1.9 2016/08/02 17:00:09 jca Exp $ - -PROG= rtadvd -SRCS= rtadvd.c advcap.c if.c config.c dump.c log.c - -CFLAGS+=-Wall -MAN= rtadvd.8 rtadvd.conf.5 - -LDADD= -levent -DPADD+= ${LIBEVENT} - -.include diff --git a/usr.sbin/rtadvd/advcap.c b/usr.sbin/rtadvd/advcap.c deleted file mode 100644 index ace81f4fa7c..00000000000 --- a/usr.sbin/rtadvd/advcap.c +++ /dev/null @@ -1,438 +0,0 @@ -/* $OpenBSD: advcap.c,v 1.18 2017/12/08 17:04:15 deraadt Exp $ */ -/* $KAME: advcap.c,v 1.9 2002/05/29 14:28:35 itojun 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. - * 3. 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include "pathnames.h" -#include "log.h" - -#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 */ - -static char *remotefile; - -extern char *conffile; - -int tgetent(char *, char *); -int getent(char *, char *, 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) -{ - char *cp; - - remotefile = cp = conffile ? conffile : _PATH_RTADVDCONF; - return (getent(bp, name, cp)); -} - -int -getent(char *bp, char *name, char *cp) -{ - int c; - int i = 0, cnt = 0; - char ibuf[BUFSIZ]; - 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 (cp && *cp) { - tf = open(cp, O_RDONLY); - } - if (tf < 0) { - log_warn("open(\"%s\")", cp); - 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) { - dprintf(STDERR_FILENO, "Remcap entry too long\n"); - 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) { - dprintf(STDERR_FILENO, "Bad remcap entry\n"); - 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) { - dprintf(STDERR_FILENO, "Infinite tc= loop\n"); - return (0); - } - if (getent(tcbuf, tcname, remotefile) != 1) { - log_warnx("Could not parse %s: " - "Unresolvable reference to %s.", remotefile, tcname); - return (0); - } - for (q = tcbuf; *q++ != ':'; ) - ; - l = p - holdtbuf + strlen(q); - if (l > BUFSIZ) { - dprintf(STDERR_FILENO, "Remcap entry too long\n"); - q[BUFSIZ - (p-holdtbuf)] = 0; - } - strlcpy(p, q, holdtbuf + BUFSIZ - p); - 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((unsigned char)*bp)) { - while (isdigit((unsigned char)*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((unsigned char)*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; - 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((unsigned char)c)) { - c -= '0', i = 2; - do - c <<= 3, c |= *str++ - '0'; - while (--i && isdigit((unsigned char)*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 db45c200e30..00000000000 --- a/usr.sbin/rtadvd/advcap.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $OpenBSD: advcap.h,v 1.7 2012/12/05 23:20:26 deraadt Exp $ */ -/* $KAME: advcap.h,v 1.4 2001/06/08 04:46:19 jinmei 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_ - -__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 497fedbf562..00000000000 --- a/usr.sbin/rtadvd/config.c +++ /dev/null @@ -1,881 +0,0 @@ -/* $OpenBSD: config.c,v 1.62 2017/08/08 09:03:02 jca Exp $ */ -/* $KAME: config.c,v 1.62 2002/05/29 10:13:10 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 -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtadvd.h" -#include "advcap.h" -#include "if.h" -#include "config.h" -#include "log.h" - -static void makeentry(char *, size_t, int, char *); -static int getinet6sysctl(int); - -extern struct ralist ralist; - -void -getconfig(char *intface) -{ - int stat, i; - char tbuf[BUFSIZ]; - struct rainfo *tmp; - long val; - int64_t val64; - char buf[BUFSIZ]; - char *bp = buf; - char *addr; - static int forwarding = -1; - -#define MUSTHAVE(var, cap) \ - do { \ - int64_t t; \ - if ((t = agetnum(cap)) < 0) { \ - fatalx("need %s for interface %s", \ - cap, intface); \ - } \ - var = t; \ - } while (0) -#define MAYHAVE(var, cap, def) \ - do { \ - if ((var = agetnum(cap)) < 0) \ - var = def; \ - } while (0) - - if ((stat = agetent(tbuf, intface)) <= 0) { - memset(tbuf, 0, sizeof(tbuf)); - log_info("Could not parse configuration file for %s" - " or the configuration file doesn't exist." - " Treat it as default", intface); - } - - if ((tmp = calloc(1, sizeof(*tmp))) == NULL) - fatal(NULL); - - TAILQ_INIT(&tmp->prefixes); - TAILQ_INIT(&tmp->rtinfos); - TAILQ_INIT(&tmp->rdnsss); - TAILQ_INIT(&tmp->dnssls); - - /* check if we are allowed to forward packets (if not determined) */ - if (forwarding < 0) { - if ((forwarding = getinet6sysctl(IPV6CTL_FORWARDING)) < 0) - exit(1); - } - - /* make sure that the user-specified interface name fits */ - if (strlcpy(tmp->ifname, intface, - sizeof(tmp->ifname)) >= sizeof(tmp->ifname)) - fatalx("invalid interface name"); - - /* get interface information */ - if (agetflag("nolladdr")) - tmp->advlinkopt = 0; - else - tmp->advlinkopt = 1; - if (tmp->advlinkopt) { - if ((tmp->sdl = if_nametosdl(intface)) == NULL) - fatalx("can't get information of %s", intface); - - tmp->ifindex = tmp->sdl->sdl_index; - } else - tmp->ifindex = if_nametoindex(intface); - if ((tmp->phymtu = if_getmtu(intface)) == 0) { - tmp->phymtu = IPV6_MMTU; - log_warn("can't get interface mtu of %s. Treat as %d", - intface, IPV6_MMTU); - } - - /* - * set router configuration variables. - */ - MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL); - if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) - fatalx("maxinterval (%ld) on %s is invalid " - "(must be between %u and %u)", val, - intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL); - - tmp->maxinterval = (u_int)val; - MAYHAVE(val, "mininterval", tmp->maxinterval/3); - if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) - fatalx("mininterval (%ld) on %s is invalid " - "(must be between %u and %u)", - val, intface, MIN_MININTERVAL, (tmp->maxinterval * 3) / 4); - - tmp->mininterval = (u_int)val; - - MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT); - tmp->hoplimit = val & 0xff; - - MAYHAVE(val, "raflags", 0); - tmp->managedflg = val & ND_RA_FLAG_MANAGED; - tmp->otherflg = val & ND_RA_FLAG_OTHER; - tmp->rtpref = val & ND_RA_FLAG_RTPREF_MASK; - if (tmp->rtpref == ND_RA_FLAG_RTPREF_RSV) - fatalx("invalid router preference (%02x) on %s", - tmp->rtpref, intface); - - MAYHAVE(val, "rltime", tmp->maxinterval * 3); - if (val && (val < tmp->maxinterval || val > MAX_ROUTERLIFETIME)) - fatalx("router lifetime (%ld) on %s is invalid " - "(must be 0 or between %d and %d)", - val, intface, - tmp->maxinterval, MAX_ROUTERLIFETIME); - - /* - * Basically, hosts MUST NOT send Router Advertisement messages at any - * time (RFC 2461, 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 - * explicitely set to zero. (see also the above section) - */ - if (val && forwarding == 0) - fatalx("non zero router lifetime is specified for %s, " - "which must not be allowed for hosts. you must " - "change router lifetime or enable IPv6 forwarding.", - intface); - - tmp->lifetime = val & 0xffff; - - MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME); - if (val < 0 || val > MAX_REACHABLETIME) - log_warnx("reachable time (%ld) on %s is invalid" - " (must be no greater than %d)", - val, intface, MAX_REACHABLETIME); - - tmp->reachabletime = (u_int32_t)val; - - MAYHAVE(val64, "retrans", DEF_ADVRETRANSTIMER); - if (val64 < 0 || val64 > 0xffffffff) - fatalx("retrans time (%lld) on %s out of range", - (long long)val64, intface); - - tmp->retranstimer = (u_int32_t)val64; - - if (agetnum("hapref") != -1 || agetnum("hatime") != -1) - fatalx("mobile-ip6 configuration not supported"); - - /* 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); - tmp->clockskew = val; - - tmp->pfxs = 0; - for (i = -1; i < MAXPREFIX; i++) { - struct prefix *pfx; - char entbuf[256]; - - makeentry(entbuf, sizeof(entbuf), i, "addr"); - addr = agetstr(entbuf, &bp); - if (addr == NULL) - continue; - - /* allocate memory to store prefix information */ - if ((pfx = calloc(1, sizeof(*pfx))) == NULL) - fatal(NULL); - - /* link into chain */ - TAILQ_INSERT_TAIL(&tmp->prefixes, pfx, entry); - tmp->pfxs++; - - pfx->origin = PREFIX_FROM_CONFIG; - - if (inet_pton(AF_INET6, addr, &pfx->prefix) != 1) - fatal("inet_pton failed for %s", addr); - - if (IN6_IS_ADDR_MULTICAST(&pfx->prefix)) - fatalx("multicast prefix (%s) must" - " not be advertised on %s", - addr, intface); - - if (IN6_IS_ADDR_LINKLOCAL(&pfx->prefix)) - log_info("link-local prefix (%s) will be" - " advertised on %s", - addr, intface); - - makeentry(entbuf, sizeof(entbuf), i, "prefixlen"); - MAYHAVE(val, entbuf, 64); - if (val < 0 || val > 128) - fatalx("prefixlen (%ld) for %s " - "on %s out of range", - val, addr, intface); - - pfx->prefixlen = (int)val; - - makeentry(entbuf, sizeof(entbuf), i, "pinfoflags"); - MAYHAVE(val, entbuf, - (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO)); - pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK; - pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO; - - makeentry(entbuf, sizeof(entbuf), i, "vltime"); - MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME); - if (val64 < 0 || val64 > 0xffffffff) - fatalx("vltime (%lld) for" - " %s/%d on %s is out of range", - (long long)val64, - addr, pfx->prefixlen, intface); - - pfx->validlifetime = (u_int32_t)val64; - - makeentry(entbuf, sizeof(entbuf), i, "vltimedecr"); - if (agetflag(entbuf)) { - struct timeval now; - gettimeofday(&now, 0); - pfx->vltimeexpire = - now.tv_sec + pfx->validlifetime; - } - - makeentry(entbuf, sizeof(entbuf), i, "pltime"); - MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME); - if (val64 < 0 || val64 > 0xffffffff) - fatalx("pltime (%lld) for %s/%d on %s" - " is out of range", - (long long)val64, - addr, pfx->prefixlen, intface); - - pfx->preflifetime = (u_int32_t)val64; - - makeentry(entbuf, sizeof(entbuf), i, "pltimedecr"); - if (agetflag(entbuf)) { - struct timeval now; - gettimeofday(&now, 0); - pfx->pltimeexpire = - now.tv_sec + pfx->preflifetime; - } - } - if (tmp->pfxs == 0 && !agetflag("noifprefix")) - get_prefix(tmp); - - for (i = -1; i < MAXRTINFO; i++) { - struct rtinfo *rti; - char entbuf[256]; - const char *flagstr; - - makeentry(entbuf, sizeof(entbuf), i, "rtprefix"); - addr = agetstr(entbuf, &bp); - if (addr == NULL) - continue; - - rti = malloc(sizeof(struct rtinfo)); - if (rti == NULL) - fatal(NULL); - - if (inet_pton(AF_INET6, addr, &rti->prefix) != 1) - fatal("inet_pton failed for %s", addr); - - makeentry(entbuf, sizeof(entbuf), i, "rtplen"); - MAYHAVE(val, entbuf, 64); - if (val < 0 || val > 128) - fatalx("route prefixlen (%ld) for %s " - "on %s out of range", - val, addr, intface); - - rti->prefixlen = (int)val; - - makeentry(entbuf, sizeof(entbuf), i, "rtflags"); - if ((flagstr = 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) - fatalx("the \'h\' and \'l\'" - " route preferences are" - " exclusive"); - - val |= ND_RA_FLAG_RTPREF_LOW; - } - } else - MAYHAVE(val, entbuf, 0); - - rti->rtpref = val & ND_RA_FLAG_RTPREF_MASK; - if (rti->rtpref == ND_RA_FLAG_RTPREF_RSV) - fatalx("invalid route preference (%02x)" - " for %s/%d on %s", - rti->rtpref, addr, rti->prefixlen, intface); - - makeentry(entbuf, sizeof(entbuf), i, "rtltime"); - MAYHAVE(val64, entbuf, -1); - if (val64 == -1) - val64 = tmp->lifetime; - if (val64 < 0 || val64 >= 0xffffffff) - fatalx("route lifetime (%d) " - " for %s/%d on %s out of range", - rti->rtpref, addr, rti->prefixlen, intface); - - rti->lifetime = (uint32_t)val64; - - TAILQ_INSERT_TAIL(&tmp->rtinfos, rti, entry); - } - - for (i = -1; i < MAXRDNSS; ++i) { - struct rdnss *rds; - char entbuf[256]; - char *tmpaddr; - - makeentry(entbuf, sizeof(entbuf), i, "rdnss"); - addr = agetstr(entbuf, &bp); - if (addr == NULL) - continue; - - /* servers are separated by commas in the config file */ - val = 1; - tmpaddr = addr; - while (*tmpaddr++) - if (*tmpaddr == ',') - ++val; - - rds = malloc(sizeof(struct rdnss) + val * sizeof(struct in6_addr)); - if (rds == NULL) - fatal(NULL); - - TAILQ_INSERT_TAIL(&tmp->rdnsss, rds, entry); - - rds->servercnt = val; - - makeentry(entbuf, sizeof(entbuf), i, "rdnssltime"); - MAYHAVE(val, entbuf, (tmp->maxinterval * 3) / 2); - if (val < tmp->maxinterval || val > tmp->maxinterval * 2) { - log_warnx("%s (%ld) on %s is invalid " - "(should be between %d and %d)", - entbuf, val, intface, tmp->maxinterval, - tmp->maxinterval * 2); - } - rds->lifetime = val; - - val = 0; - while ((tmpaddr = strsep(&addr, ","))) { - if (inet_pton(AF_INET6, tmpaddr, &rds->servers[val]) != - 1) - fatal("inet_pton failed for %s", tmpaddr); - - val++; - } - } - - for (i = -1; i < MAXDNSSL; ++i) { - struct dnssl *dsl; - char entbuf[256]; - char *tmpsl; - - makeentry(entbuf, sizeof(entbuf), i, "dnssl"); - addr = agetstr(entbuf, &bp); - if (addr == NULL) - continue; - - dsl = malloc(sizeof(struct dnssl)); - if (dsl == NULL) - fatal(NULL); - - TAILQ_INIT(&dsl->dnssldoms); - - while ((tmpsl = strsep(&addr, ","))) { - struct dnssldom *dnsd; - size_t len; - - len = strlen(tmpsl); - - /* if the domain is not "dot-terminated", add it */ - if (tmpsl[len - 1] != '.') - len += 1; - - dnsd = malloc(sizeof(struct dnssldom) + len + 1); - if (dnsd == NULL) - fatal(NULL); - - dnsd->length = len; - strlcpy(dnsd->domain, tmpsl, len + 1); - dnsd->domain[len - 1] = '.'; - dnsd->domain[len] = '\0'; - - TAILQ_INSERT_TAIL(&dsl->dnssldoms, dnsd, entry); - } - - TAILQ_INSERT_TAIL(&tmp->dnssls, dsl, entry); - - makeentry(entbuf, sizeof(entbuf), i, "dnsslltime"); - MAYHAVE(val, entbuf, (tmp->maxinterval * 3) / 2); - if (val < tmp->maxinterval || val > tmp->maxinterval * 2) { - log_warnx("%s (%ld) on %s is invalid " - "(should be between %d and %d)", - entbuf, val, intface, tmp->maxinterval, - tmp->maxinterval * 2); - } - dsl->lifetime = val; - } - - MAYHAVE(val, "mtu", 0); - if (val < 0 || val > 0xffffffff) - fatalx("mtu (%ld) on %s out of range", val, intface); - - tmp->linkmtu = (u_int32_t)val; - if (tmp->linkmtu == 0) { - char *mtustr; - - if ((mtustr = agetstr("mtu", &bp)) && - strcmp(mtustr, "auto") == 0) - tmp->linkmtu = tmp->phymtu; - } else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) - fatalx("advertised link mtu (%u) on %s is invalid (must" - " be between least MTU (%d) and physical link MTU (%d)", - tmp->linkmtu, intface, IPV6_MMTU, tmp->phymtu); - - /* route information */ - MAYHAVE(val, "routes", -1); - if (val != -1) - log_info("route information option is not available"); - - /* okey */ - SLIST_INSERT_HEAD(&ralist, tmp, entry); - - /* construct the sending packet */ - make_packet(tmp); - - /* set timer */ - ra_timer_update(tmp); -} - -void -get_prefix(struct rainfo *rai) -{ - struct ifaddrs *ifap, *ifa; - struct prefix *pp; - struct in6_addr *a; - u_char *p, *ep, *m, *lim; - u_char ntopbuf[INET6_ADDRSTRLEN]; - - if (getifaddrs(&ifap) < 0) - fatal("can't get interface addresses"); - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - int plen; - - if (strcmp(ifa->ifa_name, rai->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 = (u_char *)&((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; - lim = (u_char *)(ifa->ifa_netmask) + ifa->ifa_netmask->sa_len; - plen = prefixlen(m, lim); - if (plen <= 0 || plen > 128) - fatalx("failed to get prefixlen or prefix is invalid"); - if (plen == 128) /* XXX */ - continue; - if (find_prefix(rai, a, plen)) { - /* ignore a duplicated prefix. */ - continue; - } - - /* allocate memory to store prefix info. */ - if ((pp = calloc(1, sizeof(*pp))) == NULL) - fatal(NULL); - - /* set prefix, sweep bits outside of prefixlen */ - pp->prefixlen = plen; - memcpy(&pp->prefix, a, sizeof(*a)); - if (1) - { - p = (u_char *)&pp->prefix; - ep = (u_char *)(&pp->prefix + 1); - while (m < lim && p < ep) - *p++ &= *m++; - while (p < ep) - *p++ = 0x00; - } - if (!inet_ntop(AF_INET6, &pp->prefix, ntopbuf, - sizeof(ntopbuf))) - fatal("inet_ntop failed"); - log_debug("add %s/%d to prefix list on %s", - ntopbuf, pp->prefixlen, rai->ifname); - - /* set other fields with protocol defaults */ - pp->validlifetime = DEF_ADVVALIDLIFETIME; - pp->preflifetime = DEF_ADVPREFERREDLIFETIME; - pp->onlinkflg = 1; - pp->autoconfflg = 1; - pp->origin = PREFIX_FROM_KERNEL; - - /* link into chain */ - TAILQ_INSERT_TAIL(&rai->prefixes, pp, entry); - - /* counter increment */ - rai->pfxs++; - } - - freeifaddrs(ifap); -} - -static void -makeentry(char *buf, size_t len, int id, 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) ought - * to be specified. - */ -void -make_prefix(struct rainfo *rai, int ifindex, struct in6_addr *addr, int plen) -{ - struct prefix *prefix; - u_char ntopbuf[INET6_ADDRSTRLEN]; - - if ((prefix = calloc(1, sizeof(*prefix))) == NULL) { - log_warn(NULL); - return; /* XXX: error or exit? */ - } - prefix->prefix = *addr; - prefix->prefixlen = plen; - prefix->validlifetime = DEF_ADVVALIDLIFETIME; - prefix->preflifetime = DEF_ADVPREFERREDLIFETIME; - prefix->onlinkflg = 1; - prefix->autoconfflg = 1; - prefix->origin = PREFIX_FROM_DYNAMIC; - - TAILQ_INSERT_TAIL(&rai->prefixes, prefix, entry); - - log_debug("new prefix %s/%d was added on %s", - inet_ntop(AF_INET6, &prefix->prefix, - ntopbuf, INET6_ADDRSTRLEN), - prefix->prefixlen, rai->ifname); - - /* free the previous packet */ - free(rai->ra_data); - rai->ra_data = NULL; - - /* reconstruct the packet */ - rai->pfxs++; - make_packet(rai); - - /* - * reset the timer so that the new prefix will be advertised quickly. - */ - rai->initcounter = 0; - ra_timer_update(rai); - evtimer_add(&rai->timer.ev, &rai->timer.tm); -} - -/* - * 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 rainfo *rai, struct prefix *prefix) -{ - u_char ntopbuf[INET6_ADDRSTRLEN]; - - TAILQ_REMOVE(&rai->prefixes, prefix, entry); - log_debug("prefix %s/%d was deleted on %s", - inet_ntop(AF_INET6, &prefix->prefix, ntopbuf, INET6_ADDRSTRLEN), - prefix->prefixlen, rai->ifname); - free(prefix); - rai->pfxs--; - make_packet(rai); -} - -void -make_packet(struct rainfo *rainfo) -{ - 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 nd_opt_rdnss *ndopt_rdnss; - struct nd_opt_dnssl *ndopt_dnssl; - struct prefix *pfx; - struct rtinfo *rti; - struct rdnss *rds; - struct dnssl *dsl; - struct dnssldom *dnsd; - - /* calculate total length */ - packlen = sizeof(struct nd_router_advert); - if (rainfo->advlinkopt) { - if ((lladdroptlen = lladdropt_length(rainfo->sdl)) == 0) { - log_info("link-layer address option has" - " null length on %s. Treat as not included.", - rainfo->ifname); - rainfo->advlinkopt = 0; - } - packlen += lladdroptlen; - } - if (rainfo->pfxs) - packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs; - if (rainfo->linkmtu) - packlen += sizeof(struct nd_opt_mtu); - TAILQ_FOREACH(rti, &rainfo->rtinfos, entry) - packlen += sizeof(struct nd_opt_route_info) + - ((rti->prefixlen + 0x3f) >> 6) * 8; - TAILQ_FOREACH(rds, &rainfo->rdnsss, entry) - packlen += sizeof(struct nd_opt_rdnss) + 16 * rds->servercnt; - TAILQ_FOREACH(dsl, &rainfo->dnssls, entry) { - size_t domains_size = 0; - - packlen += sizeof(struct nd_opt_dnssl); - - /* - * Each domain in the packet ends with a null byte. Account for - * that here. - */ - TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry) - domains_size += dnsd->length + 1; - - domains_size = (domains_size + 7) & ~7; - - packlen += domains_size; - } - - /* allocate memory for the packet */ - if ((buf = malloc(packlen)) == NULL) - fatal(NULL); - /* free the previous packet */ - free(rainfo->ra_data); - rainfo->ra_data = buf; - /* XXX: what if packlen > 576? */ - rainfo->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 = (u_int8_t)(0xff & rainfo->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 & rainfo->rtpref; - ra->nd_ra_flags_reserved |= - rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0; - ra->nd_ra_flags_reserved |= - rainfo->otherflg ? ND_RA_FLAG_OTHER : 0; - ra->nd_ra_router_lifetime = htons(rainfo->lifetime); - ra->nd_ra_reachable = htonl(rainfo->reachabletime); - ra->nd_ra_retransmit = htonl(rainfo->retranstimer); - buf += sizeof(*ra); - - if (rainfo->advlinkopt) { - lladdropt_fill(rainfo->sdl, (struct nd_opt_hdr *)buf); - buf += lladdroptlen; - } - - if (rainfo->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(rainfo->linkmtu); - buf += sizeof(struct nd_opt_mtu); - } - - TAILQ_FOREACH(pfx, &rainfo->prefixes, entry) { - u_int32_t vltime, pltime; - struct timeval 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->prefixlen; - ndopt_pi->nd_opt_pi_flags_reserved = 0; - if (pfx->onlinkflg) - ndopt_pi->nd_opt_pi_flags_reserved |= - ND_OPT_PI_FLAG_ONLINK; - if (pfx->autoconfflg) - ndopt_pi->nd_opt_pi_flags_reserved |= - ND_OPT_PI_FLAG_AUTO; - if (pfx->vltimeexpire || pfx->pltimeexpire) - gettimeofday(&now, NULL); - if (pfx->vltimeexpire == 0) - vltime = pfx->validlifetime; - else - vltime = (u_int32_t)(pfx->vltimeexpire > now.tv_sec ? - pfx->vltimeexpire - now.tv_sec : 0); - if (pfx->pltimeexpire == 0) - pltime = pfx->preflifetime; - else - pltime = (u_int32_t)(pfx->pltimeexpire > now.tv_sec ? - pfx->pltimeexpire - now.tv_sec : 0); - if (vltime < pltime) { - /* - * this can happen if vltime is decremented 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->prefix; - - buf += sizeof(struct nd_opt_prefix_info); - } - - TAILQ_FOREACH(rti, &rainfo->rtinfos, entry) { - uint8_t psize = (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->prefixlen; - ndopt_rti->nd_opt_rti_flags = 0xff & rti->rtpref; - ndopt_rti->nd_opt_rti_lifetime = htonl(rti->lifetime); - memcpy(ndopt_rti + 1, &rti->prefix, psize * 8); - buf += sizeof(struct nd_opt_route_info) + psize * 8; - } - - TAILQ_FOREACH(rds, &rainfo->rdnsss, entry) { - ndopt_rdnss = (struct nd_opt_rdnss *)buf; - ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS; - /* - * An IPv6 address is 16 bytes, so multiply the number of - * addresses by two to get a size in units of 8 bytes. - */ - ndopt_rdnss->nd_opt_rdnss_len = 1 + rds->servercnt * 2; - ndopt_rdnss->nd_opt_rdnss_reserved = 0; - ndopt_rdnss->nd_opt_rdnss_lifetime = htonl(rds->lifetime); - - buf += sizeof(struct nd_opt_rdnss); - - memcpy(buf, rds->servers, rds->servercnt * 16); - buf += rds->servercnt * 16; - } - - TAILQ_FOREACH(dsl, &rainfo->dnssls, entry) { - u_int32_t size; - - ndopt_dnssl = (struct nd_opt_dnssl *)buf; - ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL; - ndopt_dnssl->nd_opt_dnssl_reserved = 0; - ndopt_dnssl->nd_opt_dnssl_lifetime = htonl(dsl->lifetime); - - size = 0; - TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry) - size += dnsd->length + 1; - /* align size on the next 8 byte boundary */ - size = (size + 7) & ~7; - ndopt_dnssl->nd_opt_dnssl_len = 1 + size / 8; - - buf += sizeof(struct nd_opt_dnssl); - - TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry) { - char *curlabel_begin; - char *curlabel_end; - - curlabel_begin = dnsd->domain; - while ((curlabel_end = strchr(curlabel_begin, '.')) - != NULL && curlabel_end > curlabel_begin) - { - size_t curlabel_size; - - curlabel_size = curlabel_end - curlabel_begin; - *buf++ = curlabel_size; - memcpy(buf, curlabel_begin, curlabel_size); - buf += curlabel_size; - curlabel_begin = curlabel_end + 1; - } - - /* null-terminate the current domain */ - *buf++ = '\0'; - } - - /* zero out the end of the current option */ - while (((uintptr_t)buf) % 8 != 0) - *buf++ = '\0'; - } -} - -static 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) { - log_warn("failed to get ip6 sysctl(%d)", code); - return(-1); - } else - return(value); -} diff --git a/usr.sbin/rtadvd/config.h b/usr.sbin/rtadvd/config.h deleted file mode 100644 index be5a29a1c5c..00000000000 --- a/usr.sbin/rtadvd/config.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $OpenBSD: config.h,v 1.10 2016/02/08 23:19:00 jca Exp $ */ -/* $KAME: config.h,v 1.3 2000/05/16 13:34:13 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 void getconfig(char *); -extern void delete_prefix(struct rainfo *, 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, rdnss or dnssl information options, - * so it should be okay to limit it - */ -#define MAXPREFIX 100 -#define MAXRTINFO 100 -#define MAXRDNSS 100 -#define MAXDNSSL 100 diff --git a/usr.sbin/rtadvd/dump.c b/usr.sbin/rtadvd/dump.c deleted file mode 100644 index bccfad7a3fb..00000000000 --- a/usr.sbin/rtadvd/dump.c +++ /dev/null @@ -1,251 +0,0 @@ -/* $OpenBSD: dump.c,v 1.23 2017/04/05 13:38:18 jca Exp $ */ -/* $KAME: dump.c,v 1.27 2002/05/29 14:23:55 itojun Exp $ */ - -/* - * Copyright (C) 2000 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 -#include -#include - -#include -#include - -#include - -/* XXX: the following two are non-standard include files */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtadvd.h" -#include "if.h" -#include "log.h" -#include "dump.h" - -extern struct ralist ralist; - -static char *ether_str(struct sockaddr_dl *); -char *lifetime(int); - -static char *rtpref_str[] = { - "medium", /* 00 */ - "high", /* 01 */ - "rsv", /* 10 */ - "low" /* 11 */ -}; - -static char * -ether_str(struct sockaddr_dl *sdl) -{ - static char hbuf[NI_MAXHOST]; - u_char *cp; - - if (sdl->sdl_alen) { - cp = (u_char *)LLADDR(sdl); - snprintf(hbuf, sizeof(hbuf), "%02x:%02x:%02x:%02x:%02x:%02x", - cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); - } else - snprintf(hbuf, sizeof(hbuf), "NONE"); - - return(hbuf); -} - -char * -lifetime(int lt) -{ - char *str; - - if (lt == ND6_INFINITE_LIFETIME) { - if (asprintf(&str, "infinity") < 0) - return (NULL); - } else { - if (asprintf(&str, "%ld", (long)lt) < 0) - return (NULL); - } - return str; -} - -void -rtadvd_dump(void) -{ - struct rainfo *rai; - struct prefix *pfx; - struct rdnss *rds; - struct dnssl *dsl; - struct dnssldom *dnsd; - char prefixbuf[INET6_ADDRSTRLEN]; - int first; - struct timeval now, next; - char *origin, *vltime, *pltime, *flags; - char *vltimexpire, *pltimexpire; - char ctimebuf[26]; - - gettimeofday(&now, NULL); - SLIST_FOREACH(rai, &ralist, entry) { - log_info("%s:", rai->ifname); - - log_info(" Status: %s", - (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : "DOWN"); - - /* control information */ - if (rai->lastsent.tv_sec) { - time_t t = rai->lastsent.tv_sec; - (void)strlcpy(ctimebuf, ctime(&t), sizeof(ctimebuf)); - ctimebuf[strcspn(ctimebuf, "\n")] = '\0'; - log_info(" Last RA sent: %s", ctimebuf); - } - if (evtimer_pending(&rai->timer.ev, &next)) { - time_t t = next.tv_sec; - (void)strlcpy(ctimebuf, ctime(&t), sizeof(ctimebuf)); - ctimebuf[strcspn(ctimebuf, "\n")] = '\0'; - log_info(" Next RA will be sent: %s", ctimebuf); - } else - log_info(" RA timer is stopped"); - log_info(" waits: %u, initcount: %u", - rai->waiting, rai->initcounter); - - /* statistics */ - log_info(" statistics: RA(out/in/inconsistent): " - "%llu/%llu/%llu, RS(input): %llu", - (unsigned long long)rai->raoutput, - (unsigned long long)rai->rainput, - (unsigned long long)rai->rainconsistent, - (unsigned long long)rai->rsinput); - - /* interface information */ - if (rai->advlinkopt) - log_info(" Link-layer address: %s", - ether_str(rai->sdl)); - log_info(" MTU: %d", rai->phymtu); - - /* Router configuration variables */ - log_info(" DefaultLifetime: %d, MaxAdvInterval: %d, " - "MinAdvInterval: %d, " - "Flags: %s%s, Preference: %s, MTU: %d", - rai->lifetime, rai->maxinterval, rai->mininterval, - rai->managedflg ? "M" : "-", rai->otherflg ? "O" : "-", - rtpref_str[(rai->rtpref >> 3) & 0xff], rai->linkmtu); - log_info(" ReachableTime: %d, RetransTimer: %d, " - "CurHopLimit: %d", rai->reachabletime, - rai->retranstimer, rai->hoplimit); - if (rai->clockskew) - log_info(" Clock skew: %ldsec", - rai->clockskew); - first = 1; - TAILQ_FOREACH(pfx, &rai->prefixes, entry) { - if (first) { - log_info(" Prefixes:"); - first = 0; - } - switch (pfx->origin) { - case PREFIX_FROM_KERNEL: - origin = "KERNEL"; - break; - case PREFIX_FROM_CONFIG: - origin = "CONFIG"; - break; - case PREFIX_FROM_DYNAMIC: - origin = "DYNAMIC"; - break; - default: - origin = ""; - } - if (pfx->vltimeexpire != 0) { - /* truncate to onwire value */ - if (asprintf(&vltimexpire, "(decr,expire %u)", - (u_int32_t)(pfx->vltimeexpire > now.tv_sec ? - pfx->vltimeexpire - now.tv_sec : 0)) == -1) - vltimexpire = NULL; - } else - vltimexpire = NULL; - - if (pfx->pltimeexpire != 0) { - /* truncate to onwire value */ - if (asprintf(&pltimexpire, "(decr,expire %u)", - (u_int32_t)(pfx->pltimeexpire > now.tv_sec ? - pfx->pltimeexpire - now.tv_sec : 0)) == -1) - pltimexpire = NULL; - } else - pltimexpire = NULL; - - vltime = lifetime(pfx->validlifetime); - pltime = lifetime(pfx->preflifetime); - asprintf(&flags, "%s%s", - pfx->onlinkflg ? "L" : "-", - pfx->autoconfflg ? "A" : "-"); - log_info(" %s/%d(%s, vltime: %s%s, " - "pltime: %s%s, flags: %s)", - inet_ntop(AF_INET6, &pfx->prefix, prefixbuf, - sizeof(prefixbuf)), pfx->prefixlen, origin, - vltime, (vltimexpire)? vltimexpire : "", - pltime, (pltimexpire)? pltimexpire : "", flags); - - free(vltimexpire); - vltimexpire = NULL; - free(pltimexpire); - pltimexpire = NULL; - free(vltime); - free(pltime); - free(flags); - } - - if (!TAILQ_EMPTY(&rai->rdnsss)) - log_info(" Recursive DNS servers:"); - TAILQ_FOREACH(rds, &rai->rdnsss, entry) { - log_info(" Servers:"); - for (first = 0; first < rds->servercnt; ++first) { - inet_ntop(AF_INET6, &rds->servers[first], - prefixbuf, sizeof(prefixbuf)); - log_info(" %s", prefixbuf); - } - log_info(" Lifetime: %u", rds->lifetime); - } - - if (!TAILQ_EMPTY(&rai->dnssls)) - log_info(" DNS search lists:"); - TAILQ_FOREACH(dsl, &rai->dnssls, entry) { - log_info(" Domains:"); - - TAILQ_FOREACH(dnsd, &dsl->dnssldoms, entry) - log_info(" %s", dnsd->domain); - - log_info(" Lifetime: %u", dsl->lifetime); - } - } -} diff --git a/usr.sbin/rtadvd/dump.h b/usr.sbin/rtadvd/dump.h deleted file mode 100644 index b577ca1c70d..00000000000 --- a/usr.sbin/rtadvd/dump.h +++ /dev/null @@ -1,33 +0,0 @@ -/* $OpenBSD: dump.h,v 1.5 2016/02/08 23:19:00 jca Exp $ */ -/* $KAME: dump.h,v 1.1 2000/05/23 11:31:26 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 rtadvd_dump(void); diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c deleted file mode 100644 index cc1edb37059..00000000000 --- a/usr.sbin/rtadvd/if.c +++ /dev/null @@ -1,466 +0,0 @@ -/* $OpenBSD: if.c,v 1.46 2017/08/12 07:38:26 florian Exp $ */ -/* $KAME: if.c,v 1.17 2001/01/21 15:27:30 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtadvd.h" -#include "if.h" -#include "log.h" - -#define ROUNDUP(a, size) \ - (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) - -#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ - ((char *)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\ - sizeof(u_long)) :\ - sizeof(u_long))) - -struct if_msghdr **iflist; -static void get_iflist(char **buf, size_t *size); -static void parse_iflist(struct if_msghdr ***ifmlist_p, char *buf, - size_t bufsize); - -extern int ioctl_sock; - -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; - } -} - -struct sockaddr_dl * -if_nametosdl(char *name) -{ - struct ifaddrs *ifap, *ifa; - struct sockaddr_dl *sdl; - - if (getifaddrs(&ifap) != 0) - return (NULL); - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (strcmp(ifa->ifa_name, name) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_LINK) - continue; - - sdl = malloc(ifa->ifa_addr->sa_len); - if (!sdl) - continue; /*XXX*/ - - memcpy(sdl, ifa->ifa_addr, ifa->ifa_addr->sa_len); - freeifaddrs(ifap); - return (sdl); - } - - freeifaddrs(ifap); - return (NULL); -} - -int -if_getmtu(char *name) -{ - struct ifreq ifr; - u_long mtu = 0; - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_addr.sa_family = AF_INET6; - if (strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)) >= - sizeof(ifr.ifr_name)) - fatalx("strlcpy"); - if (ioctl(ioctl_sock, SIOCGIFMTU, (char *)&ifr) >= 0) - mtu = ifr.ifr_mtu; - else - log_warn("s: %d", ioctl_sock); - return (mtu); -} - -/* give interface index and its old flags, then new flags returned */ -int -if_getflags(int ifindex, int oifflags) -{ - struct ifreq ifr; - - if_indextoname(ifindex, ifr.ifr_name); - if (ioctl(ioctl_sock, SIOCGIFFLAGS, (char *)&ifr) < 0) { - log_warn("ioctl:SIOCGIFFLAGS: failed for %s", ifr.ifr_name); - return (oifflags & ~IFF_UP); - } - return (ifr.ifr_flags); -} - -#define ROUNDUP8(a) (1 + (((a) - 1) | 7)) -int -lladdropt_length(struct sockaddr_dl *sdl) -{ - switch (sdl->sdl_type) { - case IFT_CARP: - 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_CARP: - 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: - fatalx("unsupported link type(%d)", sdl->sdl_type); - } -} - -#define SIN6(s) ((struct sockaddr_in6 *)(s)) -int -validate_msg(char *buf) -{ - struct rt_msghdr *rtm = (struct rt_msghdr *)buf; - struct ifa_msghdr *ifam; - struct sockaddr *sa, *dst, *ifa, *rti_info[RTAX_MAX]; - - /* just for safety */ - if (!rtm->rtm_msglen) { - log_warnx("rtm_msglen is 0 (rtm=%p)", rtm); - return -1; - } - if (rtm->rtm_version != RTM_VERSION) - return -1; - - switch (rtm->rtm_type) { - case RTM_ADD: - case RTM_DELETE: - if (rtm->rtm_tableid != 0) - return -1; - - /* address related checks */ - sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen); - get_rtaddrs(rtm->rtm_addrs, sa, rti_info); - if ((dst = rti_info[RTAX_DST]) == NULL || - dst->sa_family != AF_INET6) - return -1; - - if (IN6_IS_ADDR_LINKLOCAL(&SIN6(dst)->sin6_addr) || - IN6_IS_ADDR_MULTICAST(&SIN6(dst)->sin6_addr)) - return -1; - - if (rti_info[RTAX_NETMASK] == NULL) - return -1; - - /* found */ - return 0; - /* NOTREACHED */ - case RTM_NEWADDR: - case RTM_DELADDR: - ifam = (struct ifa_msghdr *)rtm; - - /* address related checks */ - sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen); - 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)) - return -1; - - if (ifa->sa_family == AF_INET6 && - (IN6_IS_ADDR_LINKLOCAL(&SIN6(ifa)->sin6_addr) || - IN6_IS_ADDR_MULTICAST(&SIN6(ifa)->sin6_addr))) - return -1; - - /* found */ - return 0; - /* NOTREACHED */ - case RTM_IFINFO: - /* found */ - return 0; - /* NOTREACHED */ - } - return -1; -} - -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 *)(buf + rtm->rtm_hdrlen); - 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; - - return rtm->rtm_index; -} - -int -get_ifm_ifindex(char *buf) -{ - struct if_msghdr *ifm = (struct if_msghdr *)buf; - - return ((int)ifm->ifm_index); -} - -int -get_ifam_ifindex(char *buf) -{ - struct ifa_msghdr *ifam = (struct ifa_msghdr *)buf; - - return ((int)ifam->ifam_index); -} - -int -get_ifm_flags(char *buf) -{ - struct if_msghdr *ifm = (struct if_msghdr *)buf; - - return (ifm->ifm_flags); -} - -int -get_prefixlen(char *buf) -{ - struct rt_msghdr *rtm = (struct rt_msghdr *)buf; - struct sockaddr *sa, *rti_info[RTAX_MAX]; - u_char *p, *lim; - - sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen); - get_rtaddrs(rtm->rtm_addrs, sa, rti_info); - sa = rti_info[RTAX_NETMASK]; - - p = (u_char *)(&SIN6(sa)->sin6_addr); - lim = (u_char *)sa + sa->sa_len; - return prefixlen(p, lim); -} - -int -prefixlen(u_char *p, u_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); -} - -int -rtmsg_type(char *buf) -{ - struct rt_msghdr *rtm = (struct rt_msghdr *)buf; - - return(rtm->rtm_type); -} - -int -rtmsg_len(char *buf) -{ - struct rt_msghdr *rtm = (struct rt_msghdr *)buf; - - return(rtm->rtm_msglen); -} - -/* - * alloc buffer and get if_msghdrs block from kernel, - * and put them into the buffer - */ -static void -get_iflist(char **buf, size_t *size) -{ - int mib[6]; - - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = AF_INET6; - mib[4] = NET_RT_IFLIST; - mib[5] = 0; - while (1) { - if (sysctl(mib, 6, NULL, size, NULL, 0) == -1) - fatal("sysctl: iflist size get failed"); - if (*size == 0) - break; - if ((*buf = realloc(*buf, *size)) == NULL) - fatal(NULL); - if (sysctl(mib, 6, *buf, size, NULL, 0) == -1) { - if (errno == ENOMEM) - continue; - fatal("sysctl: iflist get failed"); - } - break; - } -} - -/* - * alloc buffer and parse if_msghdrs block passed as arg, - * and init the buffer as list of pointers ot each of the if_msghdr. - */ -static void -parse_iflist(struct if_msghdr ***ifmlist_p, char *buf, size_t bufsize) -{ - int iflentry_size, malloc_size; - struct if_msghdr *ifm; - struct ifa_msghdr *ifam; - char *lim; - - /* - * Estimate least size of an iflist entry, to be obtained from kernel. - * Should add sizeof(sockaddr) ?? - */ - iflentry_size = sizeof(struct if_msghdr); - /* roughly estimate max list size of pointers to each if_msghdr */ - malloc_size = (bufsize/iflentry_size) * sizeof(size_t); - if ((*ifmlist_p = malloc(malloc_size)) == NULL) - fatal(NULL); - - lim = buf + bufsize; - for (ifm = (struct if_msghdr *)buf; ifm < (struct if_msghdr *)lim;) { - if (ifm->ifm_msglen == 0) { - log_warnx("ifm_msglen is 0 (buf=%p lim=%p ifm=%p)", - buf, lim, ifm); - return; - } - if (ifm->ifm_type == RTM_IFINFO) { - if (ifm->ifm_version == RTM_VERSION) - (*ifmlist_p)[ifm->ifm_index] = ifm; - } else { - fatalx("out of sync parsing NET_RT_IFLIST," - " expected %d, got %d, msglen = %d," - " buf:%p, ifm:%p, lim:%p", - RTM_IFINFO, ifm->ifm_type, ifm->ifm_msglen, - buf, ifm, lim); - } - for (ifam = (struct ifa_msghdr *) - ((char *)ifm + ifm->ifm_msglen); - ifam < (struct ifa_msghdr *)lim; - ifam = (struct ifa_msghdr *) - ((char *)ifam + ifam->ifam_msglen)) { - /* just for safety */ - if (!ifam->ifam_msglen) { - log_warnx("ifa_msglen is 0 " - "(buf=%p lim=%p ifam=%p)", - buf, lim, ifam); - return; - } - if (ifam->ifam_type != RTM_NEWADDR) - break; - } - ifm = (struct if_msghdr *)ifam; - } -} - -void -init_iflist(void) -{ - static size_t ifblock_size; - static char *ifblock; - - if (ifblock) { - free(ifblock); - ifblock_size = 0; - } - free(iflist); - /* get iflist block from kernel */ - get_iflist(&ifblock, &ifblock_size); - - /* make list of pointers to each if_msghdr */ - parse_iflist(&iflist, ifblock, ifblock_size); -} diff --git a/usr.sbin/rtadvd/if.h b/usr.sbin/rtadvd/if.h deleted file mode 100644 index 9b621e13f52..00000000000 --- a/usr.sbin/rtadvd/if.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $OpenBSD: if.h,v 1.14 2017/08/10 19:07:14 jca Exp $ */ -/* $KAME: if.h,v 1.6 2001/01/21 15:37:14 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. - */ - -#define RTADV_TYPE2BITMASK(type) (0x1 << type) - -extern struct if_msghdr **iflist; - -struct nd_opt_hdr; -struct sockaddr_dl *if_nametosdl(char *); -int if_getmtu(char *); -int if_getflags(int, int); -int lladdropt_length(struct sockaddr_dl *); -void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *); -int validate_msg(char *); -struct in6_addr *get_addr(char *); -int get_rtm_ifindex(char *); -int get_ifm_ifindex(char *); -int get_ifam_ifindex(char *); -int get_ifm_flags(char *); -int get_prefixlen(char *); -int prefixlen(u_char *, u_char *); -int rtmsg_type(char *); -int ifmsg_type(char *); -int rtmsg_len(char *); -void init_iflist(void); diff --git a/usr.sbin/rtadvd/log.c b/usr.sbin/rtadvd/log.c deleted file mode 100644 index e5d62856fb6..00000000000 --- a/usr.sbin/rtadvd/log.c +++ /dev/null @@ -1,178 +0,0 @@ -/* $OpenBSD: log.c,v 1.4 2017/07/12 06:09:59 florian Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" - -int debug; -int verbose; -const char *log_procname; - -void -log_init(int n_debug) -{ - extern char *__progname; - - debug = n_debug; - - if (!debug) - openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); - - tzset(); -} - -void -log_verbose(int v) -{ - verbose = v; -} - -void -logit(int pri, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(pri, fmt, ap); - va_end(ap); -} - -void -vlog(int pri, const char *fmt, va_list ap) -{ - char *nfmt; - - if (debug) { - /* best effort in out of mem situations */ - if (asprintf(&nfmt, "%s\n", fmt) == -1) { - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } else { - vfprintf(stderr, nfmt, ap); - free(nfmt); - } - fflush(stderr); - } else - vsyslog(pri, fmt, ap); -} - -void -log_warn(const char *emsg, ...) -{ - char *nfmt; - va_list ap; - - /* best effort to even work in out of memory situations */ - if (emsg == NULL) - logit(LOG_ERR, "%s", strerror(errno)); - else { - va_start(ap, emsg); - - if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) { - /* we tried it... */ - vlog(LOG_ERR, emsg, ap); - logit(LOG_ERR, "%s", strerror(errno)); - } else { - vlog(LOG_ERR, nfmt, ap); - free(nfmt); - } - va_end(ap); - } -} - -void -log_warnx(const char *emsg, ...) -{ - va_list ap; - - va_start(ap, emsg); - vlog(LOG_ERR, emsg, ap); - va_end(ap); -} - -void -log_info(const char *emsg, ...) -{ - va_list ap; - - va_start(ap, emsg); - vlog(LOG_INFO, emsg, ap); - va_end(ap); -} - -void -log_debug(const char *emsg, ...) -{ - va_list ap; - - if (verbose) { - va_start(ap, emsg); - vlog(LOG_DEBUG, emsg, ap); - va_end(ap); - } -} - -static void -vfatalc(int code, const char *emsg, va_list ap) -{ - static char s[BUFSIZ]; - const char *sep; - - if (emsg != NULL) { - (void)vsnprintf(s, sizeof(s), emsg, ap); - sep = ": "; - } else { - s[0] = '\0'; - sep = ""; - } - if (code) - logit(LOG_CRIT, "fatal in %s: %s%s%s", - log_procname, s, sep, strerror(code)); - else - logit(LOG_CRIT, "fatal in %s%s%s", log_procname, sep, s); -} - -void -fatal(const char *emsg, ...) -{ - va_list ap; - - va_start(ap, emsg); - vfatalc(errno, emsg, ap); - va_end(ap); - exit(1); -} - -void -fatalx(const char *emsg, ...) -{ - va_list ap; - - va_start(ap, emsg); - vfatalc(0, emsg, ap); - va_end(ap); - exit(1); -} diff --git a/usr.sbin/rtadvd/log.h b/usr.sbin/rtadvd/log.h deleted file mode 100644 index 7d65207ef9f..00000000000 --- a/usr.sbin/rtadvd/log.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $OpenBSD: log.h,v 1.4 2017/07/12 06:09:59 florian Exp $ */ - -/* - * Copyright (c) 2003, 2004 Henning Brauer - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef LOG_H -#define LOG_H - -#include - -extern const char *log_procname; - -void log_init(int); -void log_verbose(int); -void logit(int, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void vlog(int, const char *, va_list) - __attribute__((__format__ (printf, 2, 0))); -void log_warn(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -void log_warnx(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -void log_info(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -void log_debug(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -__dead void fatal(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -__dead void fatalx(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); - -#endif /* LOG_H */ diff --git a/usr.sbin/rtadvd/pathnames.h b/usr.sbin/rtadvd/pathnames.h deleted file mode 100644 index 8f53945b733..00000000000 --- a/usr.sbin/rtadvd/pathnames.h +++ /dev/null @@ -1,4 +0,0 @@ -/* $OpenBSD: pathnames.h,v 1.4 2000/05/23 11:23:23 itojun Exp $ */ -/* $KAME: pathnames.h,v 1.2 2000/05/16 13:34:13 itojun Exp $ */ - -#define _PATH_RTADVDCONF "/etc/rtadvd.conf" diff --git a/usr.sbin/rtadvd/rtadvd.8 b/usr.sbin/rtadvd/rtadvd.8 deleted file mode 100644 index bacfc927d7b..00000000000 --- a/usr.sbin/rtadvd/rtadvd.8 +++ /dev/null @@ -1,149 +0,0 @@ -.\" $OpenBSD: rtadvd.8,v 1.35 2017/09/14 12:56:36 sthen Exp $ -.\" $KAME: rtadvd.8,v 1.18 2002/04/28 10:43:02 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. -.\" -.Dd $Mdocdate: September 14 2017 $ -.Dt RTADVD 8 -.Os -.Sh NAME -.Nm rtadvd -.Nd router advertisement daemon -.Sh SYNOPSIS -.Nm -.Op Fl ds -.Op Fl c Ar configfile -.Ar interface ... -.Sh DESCRIPTION -.Nm -sends router advertisement packets to the specified interfaces. -.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 at all, -.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. -By default, if an interface direct route is -added/deleted on an advertising interface and no static prefixes are -specified by the configuration file, -.Nm -adds/deletes the corresponding prefix to/from its advertising list, -respectively. -The -.Fl s -option may be used to disable this behavior. -Moreover, if the status of an advertising interface changes, -.Nm -will start or stop sending router advertisements according -to the latest status. -.Pp -Basically, hosts MUST NOT send Router Advertisement messages at any -time (RFC 4861, Section 6.2.4). -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 to zero on every -advertising interface. -.Pp -The command line options are: -.Bl -tag -width indent -.\" -.It Fl c Ar configfile -Specify an alternate location, -.Ar configfile , -for the configuration file. -By default, -.Pa /etc/rtadvd.conf -is used. -.It Fl d -Do not daemonize. -If this option is specified, -.Nm -will run in the foreground and log to -.Em stderr . -.It Fl s -Do not add or delete prefixes dynamically. -Only statically configured prefixes, if any, will be advertised. -.El -.Pp -Upon receipt of signal -.Dv SIGUSR1 , -.Nm -will dump the current internal state into -.Xr syslog 3 . -.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 "/etc/rtadvd.conf" -compact -.It Pa /etc/rtadvd.conf -The default configuration file. -.El -.Sh EXIT STATUS -.Ex -std rtadvd -.Sh SEE ALSO -.Xr rtadvd.conf 5 , -.Xr slaacd 8 , -.Xr syslogd 8 -.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 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 ba15e31f1dc..00000000000 --- a/usr.sbin/rtadvd/rtadvd.c +++ /dev/null @@ -1,1333 +0,0 @@ -/* $OpenBSD: rtadvd.c,v 1.92 2018/07/16 07:56:04 claudio Exp $ */ -/* $KAME: rtadvd.c,v 1.66 2002/05/29 14:18:36 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtadvd.h" -#include "advcap.h" -#include "if.h" -#include "config.h" -#include "dump.h" -#include "log.h" - -struct msghdr rcvmhdr; -static u_char *rcvcmsgbuf; -static size_t rcvcmsgbuflen; -static u_char *sndcmsgbuf = NULL; -static size_t sndcmsgbuflen; -struct msghdr sndmhdr; -struct iovec rcviov[2]; -struct iovec sndiov[2]; -static char *rtsockbuf; -static size_t rtsockbuflen; -struct sockaddr_in6 from; -struct sockaddr_in6 sin6_allnodes = {sizeof(sin6_allnodes), AF_INET6}; -int sock; -int rtsock = -1; -int ioctl_sock; -int dflag = 0, sflag = 0; - -u_char *conffile = NULL; - -struct ralist ralist; - -struct nd_opt { - SLIST_ENTRY(nd_opt) entry; - struct nd_opt_hdr *opt; -}; - -union nd_opts { - struct nd_opt_hdr *nd_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; - SLIST_HEAD(nd_optlist, nd_opt) list; - } nd_opt_each; -}; -#define nd_opts_src_lladdr nd_opt_each.src_lladdr -#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr -#define nd_opts_pi nd_opt_each.pi -#define nd_opts_rh nd_opt_each.rh -#define nd_opts_mtu nd_opt_each.mtu -#define nd_opts_list nd_opt_each.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) -#define NDOPT_FLAG_ROUTE_INFO (1 << 7) - -u_int32_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_ROUTE_INFO] = NDOPT_FLAG_ROUTE_INFO, - [ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS, - [ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL, -}; - -static __dead void usage(void); -static void sock_open(void); -static void rtsock_open(void); -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_opts *, u_int32_t); -static void free_ndopts(union nd_opts *); -static void ra_output(struct rainfo *, struct sockaddr_in6 *); -static struct rainfo *if_indextorainfo(int); -static int rdaemon(int); - -static void dump_cb(int, short, void *); -static void die_cb(int, short, void *); -static void rtsock_cb(int, short, void *); -static void sock_cb(int, short, void *); -static void timer_cb(int, short, void *); - -int -main(int argc, char *argv[]) -{ - struct passwd *pw; - int ch; - int devnull = -1; - struct event ev_sock; - struct event ev_rtsock; - struct event ev_sigterm; - struct event ev_sigusr1; - struct rainfo *rai; - - log_procname = getprogname(); - log_init(1); /* log to stderr until daemonized */ - - closefrom(3); - - /* get command line options and arguments */ - while ((ch = getopt(argc, argv, "c:ds")) != -1) { - switch (ch) { - case 'c': - conffile = optarg; - break; - case 'd': - dflag = 1; - break; - case 's': - sflag = 1; - break; - default: - usage(); - } - } - argc -= optind; - argv += optind; - if (argc == 0) - usage(); - - if (!dflag) { - devnull = open(_PATH_DEVNULL, O_RDWR, 0); - if (devnull == -1) - fatal("open(\"" _PATH_DEVNULL "\")"); - } else - log_verbose(1); - - SLIST_INIT(&ralist); - - /* get iflist block from kernel */ - init_iflist(); - - if (conffile == NULL) - log_init(dflag); - - if ((ioctl_sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) - fatal("socket"); - - while (argc--) - getconfig(*argv++); - - if (inet_pton(AF_INET6, ALLNODES, &sin6_allnodes.sin6_addr) != 1) - fatal("inet_pton failed"); - - sock_open(); - - if (sflag == 0) - rtsock_open(); - - if ((pw = getpwnam(RTADVD_USER)) == NULL) - fatal("getpwnam(" RTADVD_USER ")"); - if (chroot(pw->pw_dir) == -1) - fatal("chroot"); - if (chdir("/") == -1) - fatal("chdir(\"/\")"); - if (setgroups(1, &pw->pw_gid) == -1 || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) - fatal("cannot drop privileges"); - - if (!dflag) { - if (rdaemon(devnull) == -1) - fatal("rdaemon"); - } - - if (conffile != NULL) - log_init(dflag); - - if (pledge("stdio inet route", NULL) == -1) - err(1, "pledge"); - - event_init(); - - signal_set(&ev_sigterm, SIGTERM, die_cb, NULL); - signal_add(&ev_sigterm, NULL); - signal_set(&ev_sigusr1, SIGUSR1, dump_cb, NULL); - signal_add(&ev_sigusr1, NULL); - - event_set(&ev_sock, sock, EV_READ|EV_PERSIST, sock_cb, NULL); - event_add(&ev_sock, NULL); - if (rtsock != -1) { - event_set(&ev_rtsock, rtsock, EV_READ|EV_PERSIST, rtsock_cb, - NULL); - event_add(&ev_rtsock, NULL); - } - - SLIST_FOREACH(rai, &ralist, entry) { - evtimer_set(&rai->timer.ev, timer_cb, rai); - evtimer_add(&rai->timer.ev, &rai->timer.tm); - } - - event_dispatch(); - - log_warn("event_dispatch returned"); - - return 1; -} - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-ds] [-c configfile] interface ...\n", - getprogname()); - exit(1); -} - -static void -dump_cb(int sig, short event, void *arg) -{ - rtadvd_dump(); -} - -static void -die_cb(int sig, short event, void *arg) -{ - struct rainfo *ra; - int i; - const int retrans = MAX_FINAL_RTR_ADVERTISEMENTS; - - log_debug("cease to be an advertising router"); - - SLIST_FOREACH(ra, &ralist, entry) { - ra->lifetime = 0; - make_packet(ra); - } - for (i = 0; i < retrans; i++) { - SLIST_FOREACH(ra, &ralist, entry) - ra_output(ra, &sin6_allnodes); - sleep(MIN_DELAY_BETWEEN_RAS); - } - exit(0); - /*NOTREACHED*/ -} - -static void -rtsock_cb(int fd, short event, void *arg) -{ - int n, type, ifindex = 0, oldifflags, plen; - char *rtm; - u_char ifname[IF_NAMESIZE]; - struct prefix *prefix; - struct rainfo *rai; - struct in6_addr *addr; - char addrbuf[INET6_ADDRSTRLEN]; - - n = read(rtsock, rtsockbuf, rtsockbuflen); - log_debug("received a routing message " - "(type = %d, len = %d)", rtmsg_type(rtsockbuf), n); - - rtm = rtsockbuf; - if (validate_msg(rtm) == -1) - return; - - type = rtmsg_type(rtm); - switch (type) { - case RTM_ADD: - case RTM_DELETE: - ifindex = get_rtm_ifindex(rtm); - break; - case RTM_NEWADDR: - case RTM_DELADDR: - ifindex = get_ifam_ifindex(rtm); - break; - case RTM_IFINFO: - ifindex = get_ifm_ifindex(rtm); - break; - default: - /* should not reach here */ - log_debug("unknown rtmsg %d on %s", - type, if_indextoname(ifindex, ifname)); - return; - } - - if ((rai = if_indextorainfo(ifindex)) == NULL) { - log_debug("route changed on " - "non advertising interface(%s)", - if_indextoname(ifindex, ifname)); - return; - } - oldifflags = iflist[ifindex]->ifm_flags; - - switch (type) { - case RTM_ADD: - /* init ifflags because it may have changed */ - iflist[ifindex]->ifm_flags = - if_getflags(ifindex, iflist[ifindex]->ifm_flags); - - if (sflag) - break; /* we aren't interested in prefixes */ - - addr = get_addr(rtm); - plen = get_prefixlen(rtm); - /* sanity check for plen */ - /* as RFC2373, prefixlen is at least 4 */ - if (plen < 4 || plen > 127) { - log_info("new interface route's" - " plen %d is invalid for a prefix", plen); - break; - } - prefix = find_prefix(rai, addr, plen); - if (prefix) { - log_debug("new prefix(%s/%d) " - "added on %s, " - "but it was already in list", - inet_ntop(AF_INET6, addr, - addrbuf, INET6_ADDRSTRLEN), - plen, rai->ifname); - break; - } - make_prefix(rai, ifindex, addr, plen); - break; - case RTM_DELETE: - /* init ifflags because it may have changed */ - iflist[ifindex]->ifm_flags = - if_getflags(ifindex, iflist[ifindex]->ifm_flags); - - if (sflag) - break; - - addr = get_addr(rtm); - plen = get_prefixlen(rtm); - /* sanity check for plen */ - /* as RFC2373, prefixlen is at least 4 */ - if (plen < 4 || plen > 127) { - log_info("deleted interface route's " - "plen %d is invalid for a prefix", plen); - break; - } - prefix = find_prefix(rai, addr, plen); - if (prefix == NULL) { - log_debug("prefix(%s/%d) was " - "deleted on %s, " - "but it was not in list", - inet_ntop(AF_INET6, addr, - addrbuf, INET6_ADDRSTRLEN), - plen, rai->ifname); - break; - } - delete_prefix(rai, prefix); - break; - case RTM_NEWADDR: - case RTM_DELADDR: - /* init ifflags because it may have changed */ - iflist[ifindex]->ifm_flags = - if_getflags(ifindex, iflist[ifindex]->ifm_flags); - break; - case RTM_IFINFO: - iflist[ifindex]->ifm_flags = get_ifm_flags(rtm); - break; - default: - /* should not reach here */ - log_debug("unknown rtmsg %d on %s", - type, if_indextoname(ifindex, ifname)); - return; - } - - /* check if an interface flag is changed */ - if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */ - (iflist[ifindex]->ifm_flags & IFF_UP) == 0) { - log_info("interface %s becomes down. stop timer.", - rai->ifname); - evtimer_del(&rai->timer.ev); - } else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */ - (iflist[ifindex]->ifm_flags & IFF_UP) != 0) { - log_info("interface %s becomes up. restart timer.", - rai->ifname); - - rai->initcounter = 0; /* reset the counter */ - rai->waiting = 0; /* XXX */ - ra_timer_update(rai); - evtimer_add(&rai->timer.ev, &rai->timer.tm); - } -} - -void -sock_cb(int fd, short event, void *arg) -{ - ssize_t len; - int *hlimp = NULL; - struct icmp6_hdr *icp; - int ifindex = 0; - struct cmsghdr *cm; - struct in6_pktinfo *pi = NULL; - u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; - struct in6_addr dst = in6addr_any; - - /* - * 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 ((len = recvmsg(sock, &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) { - log_warnx("failed to get receiving interface"); - return; - } - if (hlimp == NULL) { - log_warnx("failed to get receiving hop limit"); - return; - } - - /* - * If we happen to receive data on an interface which is now down, - * just discard the data. - */ - if ((iflist[pi->ipi6_ifindex]->ifm_flags & IFF_UP) == 0) { - log_info("received data on a disabled interface (%s)", - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - if (len < sizeof(struct icmp6_hdr)) { - log_warnx("packet size(%zd) is too short", len); - return; - } - - icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base; - - switch (icp->icmp6_type) { - case ND_ROUTER_SOLICIT: - /* - * Message verification - RFC-2461 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) { - log_info("RS with invalid hop limit(%d) " - "received from %s on %s", - *hlimp, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - if (icp->icmp6_code) { - log_info("RS with invalid ICMP6 code(%d) " - "received from %s on %s", - icp->icmp6_code, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - if (len < sizeof(struct nd_router_solicit)) { - log_info("RS from %s on %s too short (len = %zd)", - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf), len); - return; - } - rs_input(len, (struct nd_router_solicit *)icp, pi, &from); - break; - case ND_ROUTER_ADVERT: - /* - * Message verification - RFC-2461 6.1.2 - * XXX: there's a same dilemma as above... - */ - if (*hlimp != 255) { - log_info("RA with invalid hop limit(%d) " - "received from %s on %s", - *hlimp, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - if (icp->icmp6_code) { - log_info("RA with invalid ICMP6 code(%d) " - "received from %s on %s", - icp->icmp6_code, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - if (len < sizeof(struct nd_router_advert)) { - log_info("RA from %s on %s too short (len = %zd)", - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf), len); - return; - } - ra_input(len, (struct nd_router_advert *)icp, pi, &from); - 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()). - */ - log_warnx("invalid icmp type(%d)", icp->icmp6_type); - } -} - -static void -rs_input(int len, struct nd_router_solicit *rs, - struct in6_pktinfo *pi, struct sockaddr_in6 *from) -{ - u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; - union nd_opts ndopts; - struct rainfo *ra; - - log_debug("RS received from %s on %s", - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - - /* ND option check */ - memset(&ndopts, 0, sizeof(ndopts)); - SLIST_INIT(&ndopts.nd_opts_list); - if (nd6_options((struct nd_opt_hdr *)(rs + 1), - len - sizeof(struct nd_router_solicit), - &ndopts, NDOPT_FLAG_SRCLINKADDR)) { - log_debug("ND option check failed for an RS from %s on %s", - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - 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-2461 6.1.1) - */ - if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) && - ndopts.nd_opts_src_lladdr) { - log_warnx("RS from unspecified src on %s has a link-layer" - " address option", - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - goto done; - } - - SLIST_FOREACH(ra, &ralist, entry) { - if (pi->ipi6_ifindex == ra->ifindex) - break; - } - if (ra == NULL) { - log_info("RS received on non advertising interface(%s)", - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - goto done; - } - - ra->rsinput++; /* increment statistics */ - - if (ndopts.nd_opts_src_lladdr) - ra_output(ra, from); - else { - /* - * Decide whether to send RA according to the rate-limit - * consideration. - */ - long delay; /* must not be greater than 1000000 */ - struct timeval interval, now, min_delay, tm_tmp, next, - computed; - - /* - * If there is already a waiting RS packet, don't - * update the timer. - */ - if (ra->waiting++) - goto done; - - gettimeofday(&now, NULL); - - /* - * 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-2461 6.2.6 - */ - delay = arc4random_uniform(MAX_RA_DELAY_TIME); - interval.tv_sec = 0; - interval.tv_usec = delay; - /* - * Could happen if an interface has transitioned from DOWN to - * UP and we haven't re-enabled the timer yet. - */ - if (!evtimer_pending(&ra->timer.ev, &next)) - goto done; - timeradd(&now, &interval, &computed); - if (timercmp(&computed, &next, >)) { - log_debug("random delay is larger than " - "the rest of normal timer"); - goto done; - } - - /* - * 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. - */ - min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS; - min_delay.tv_usec = 0; - timeradd(&ra->lastsent, &min_delay, &tm_tmp); - if (timercmp(&computed, &tm_tmp, <)) - computed = tm_tmp; - timersub(&computed, &now, &computed); - evtimer_add(&ra->timer.ev, &computed); - } - - done: - free_ndopts(&ndopts); -} - -static void -ra_input(int len, struct nd_router_advert *ra, - struct in6_pktinfo *pi, struct sockaddr_in6 *from) -{ - struct rainfo *rai; - u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; - union nd_opts ndopts; - char *on_off[] = {"OFF", "ON"}; - u_int32_t reachabletime, retranstimer, mtu; - int inconsistent = 0; - - log_debug("RA received from %s on %s", - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - - /* ND option check */ - memset(&ndopts, 0, sizeof(ndopts)); - SLIST_INIT(&ndopts.nd_opts_list); - if (nd6_options((struct nd_opt_hdr *)(ra + 1), - len - sizeof(struct nd_router_advert), - &ndopts, NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO - | NDOPT_FLAG_MTU | NDOPT_FLAG_ROUTE_INFO - | NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL)) { - log_warnx("ND option check failed for an RA from %s on %s", - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - /* - * RA consistency check according to RFC-2461 6.2.7 - */ - if ((rai = if_indextorainfo(pi->ipi6_ifindex)) == NULL) - goto done; /* not our interface */ - - rai->rainput++; /* increment statistics */ - - /* Cur Hop Limit value */ - if (ra->nd_ra_curhoplimit && rai->hoplimit && - ra->nd_ra_curhoplimit != rai->hoplimit) { - log_info("CurHopLimit inconsistent on %s: %d from %s," - " %d from us", - rai->ifname, - ra->nd_ra_curhoplimit, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - rai->hoplimit); - inconsistent++; - } - /* M flag */ - if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) != - rai->managedflg) { - log_info("M flag inconsistent on %s: %s from %s, %s from us", - rai->ifname, on_off[rai->managedflg ? 0 : 1], - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - on_off[rai->managedflg ? 1 : 0]); - inconsistent++; - } - /* O flag */ - if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) != - rai->otherflg) { - log_info("O flag inconsistent on %s: %s from %s, %s from us", - rai->ifname, on_off[rai->otherflg ? 0 : 1], - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - on_off[rai->otherflg ? 1 : 0]); - inconsistent++; - } - /* Reachable Time */ - reachabletime = ntohl(ra->nd_ra_reachable); - if (reachabletime && rai->reachabletime && - reachabletime != rai->reachabletime) { - log_info("ReachableTime inconsistent on %s:" - " %d from %s, %d from us", - rai->ifname, reachabletime, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - rai->reachabletime); - inconsistent++; - } - /* Retrans Timer */ - retranstimer = ntohl(ra->nd_ra_retransmit); - if (retranstimer && rai->retranstimer && - retranstimer != rai->retranstimer) { - log_info("RetransTimer inconsistent on %s:" - " %d from %s, %d from us", - rai->ifname, retranstimer, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - rai->retranstimer); - inconsistent++; - } - /* Values in the MTU options */ - if (ndopts.nd_opts_mtu) { - mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu); - if (mtu && rai->linkmtu && mtu != rai->linkmtu) { - log_info("MTU option value inconsistent on %s:" - " %d from %s, %d from us", - rai->ifname, mtu, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - rai->linkmtu); - inconsistent++; - } - } - /* Preferred and Valid Lifetimes for prefixes */ - { - struct nd_opt *optp; - - if (ndopts.nd_opts_pi) - if (prefix_check(ndopts.nd_opts_pi, rai, from)) - inconsistent++; - SLIST_FOREACH(optp, &ndopts.nd_opts_list, entry) { - if (prefix_check((struct nd_opt_prefix_info *)optp->opt, - rai, from)) - inconsistent++; - } - } - - if (inconsistent) - rai->rainconsistent++; - - done: - free_ndopts(&ndopts); -} - -/* 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) -{ - time_t preferred_time, valid_time; - struct prefix *pp; - int inconsistent = 0; - u_char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN]; - struct timeval now; - - /* - * log if the advertised prefix has link-local scope(sanity check?) - */ - if (IN6_IS_ADDR_LINKLOCAL(&pinfo->nd_opt_pi_prefix)) - log_info("link-local prefix %s/%d is advertised " - "from %s on %s", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - prefixbuf, INET6_ADDRSTRLEN), - pinfo->nd_opt_pi_prefix_len, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - rai->ifname); - - if ((pp = find_prefix(rai, &pinfo->nd_opt_pi_prefix, - pinfo->nd_opt_pi_prefix_len)) == NULL) { - log_info("prefix %s/%d from %s on %s is not in our list", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - prefixbuf, INET6_ADDRSTRLEN), - pinfo->nd_opt_pi_prefix_len, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - rai->ifname); - return(0); - } - - preferred_time = ntohl(pinfo->nd_opt_pi_preferred_time); - if (pp->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? - */ - gettimeofday(&now, NULL); - preferred_time += now.tv_sec; - - if (rai->clockskew && - llabs(preferred_time - pp->pltimeexpire) > rai->clockskew) { - log_info("preferred lifetime for %s/%d" - " (decr. in real time) inconsistent on %s:" - " %lld from %s, %lld from us", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - prefixbuf, INET6_ADDRSTRLEN), - pinfo->nd_opt_pi_prefix_len, - rai->ifname, (long long)preferred_time, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - (long long)pp->pltimeexpire); - inconsistent++; - } - } else if (preferred_time != pp->preflifetime) - log_info("preferred lifetime for %s/%d" - " inconsistent on %s:" - " %lld from %s, %d from us", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - prefixbuf, INET6_ADDRSTRLEN), - pinfo->nd_opt_pi_prefix_len, - rai->ifname, (long long)preferred_time, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - pp->preflifetime); - - valid_time = ntohl(pinfo->nd_opt_pi_valid_time); - if (pp->vltimeexpire) { - gettimeofday(&now, NULL); - valid_time += now.tv_sec; - - if (rai->clockskew && - llabs(valid_time - pp->vltimeexpire) > rai->clockskew) { - log_info("valid lifetime for %s/%d" - " (decr. in real time) inconsistent on %s:" - " %lld from %s, %lld from us", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - prefixbuf, INET6_ADDRSTRLEN), - pinfo->nd_opt_pi_prefix_len, - rai->ifname, (long long)preferred_time, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - (long long)pp->vltimeexpire); - inconsistent++; - } - } else if (valid_time != pp->validlifetime) { - log_info("valid lifetime for %s/%d" - " inconsistent on %s:" - " %lld from %s, %d from us", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - prefixbuf, INET6_ADDRSTRLEN), - pinfo->nd_opt_pi_prefix_len, - rai->ifname, (long long)valid_time, - inet_ntop(AF_INET6, &from->sin6_addr, - ntopbuf, INET6_ADDRSTRLEN), - pp->validlifetime); - inconsistent++; - } - - return(inconsistent); -} - -struct prefix * -find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen) -{ - struct prefix *pp; - int bytelen, bitlen; - u_char bitmask; - - TAILQ_FOREACH(pp, &rai->prefixes, entry) { - if (plen != pp->prefixlen) - continue; - bytelen = plen / 8; - bitlen = plen % 8; - bitmask = 0xff << (8 - bitlen); - if (memcmp(prefix, &pp->prefix, bytelen)) - continue; - if (bitlen == 0 || - ((prefix->s6_addr[bytelen] & bitmask) == - (pp->prefix.s6_addr[bytelen] & bitmask))) { - return(pp); - } - } - - return(NULL); -} - -static int -nd6_options(struct nd_opt_hdr *hdr, int limit, - union nd_opts *ndopts, u_int32_t optflags) -{ - int optlen = 0; - - for (; limit > 0; limit -= optlen) { - if (limit < sizeof(struct nd_opt_hdr)) { - log_info("short option header"); - goto bad; - } - - hdr = (struct nd_opt_hdr *)((char *)hdr + optlen); - if (hdr->nd_opt_len == 0) { - log_warnx("bad ND option length(0) (type = %d)", - hdr->nd_opt_type); - goto bad; - } - optlen = hdr->nd_opt_len << 3; - if (optlen > limit) { - log_info("short option"); - goto bad; - } - - if (hdr->nd_opt_type > ND_OPT_MTU && - hdr->nd_opt_type != ND_OPT_ROUTE_INFO && - hdr->nd_opt_type != ND_OPT_RDNSS && - hdr->nd_opt_type != ND_OPT_DNSSL) - { - log_info("unknown ND option(type %d)", - hdr->nd_opt_type); - continue; - } - - if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) { - log_info("unexpected ND option(type %d)", - hdr->nd_opt_type); - continue; - } - - /* - * Option length check. Do it here for all fixed-length - * options. - */ - if ((hdr->nd_opt_type == ND_OPT_RDNSS && (optlen < 24 || - ((optlen - sizeof(struct nd_opt_rdnss)) % 16 != 0))) || - (hdr->nd_opt_type == ND_OPT_DNSSL && optlen < 16) || - (hdr->nd_opt_type == ND_OPT_MTU && - (optlen != sizeof(struct nd_opt_mtu))) || - ((hdr->nd_opt_type == ND_OPT_PREFIX_INFORMATION && - optlen != sizeof(struct nd_opt_prefix_info)))) { - log_info("invalid option length"); - continue; - } - - switch (hdr->nd_opt_type) { - case ND_OPT_SOURCE_LINKADDR: - ndopts->nd_opt_array[hdr->nd_opt_type] = hdr; - break; - case ND_OPT_TARGET_LINKADDR: - case ND_OPT_REDIRECTED_HEADER: - case ND_OPT_ROUTE_INFO: - case ND_OPT_RDNSS: - case ND_OPT_DNSSL: - break; /* we don't care about these options */ - case ND_OPT_MTU: - if (ndopts->nd_opt_array[hdr->nd_opt_type]) { - log_info("duplicated ND option (type = %d)", - hdr->nd_opt_type); - } - ndopts->nd_opt_array[hdr->nd_opt_type] = hdr; - break; - case ND_OPT_PREFIX_INFORMATION: - { - struct nd_opt *pfx; - - if (ndopts->nd_opts_pi == 0) { - ndopts->nd_opts_pi = - (struct nd_opt_prefix_info *)hdr; - continue; - } - if ((pfx = malloc(sizeof(*pfx))) == NULL) { - log_warn(NULL); - goto bad; - } - - pfx->opt = hdr; - SLIST_INSERT_HEAD(&ndopts->nd_opts_list, pfx, entry); - - break; - } - default: /* impossible */ - break; - } - } - - return(0); - - bad: - free_ndopts(ndopts); - - return(-1); -} - -static void -free_ndopts(union nd_opts *ndopts) -{ - struct nd_opt *opt; - - while (!SLIST_EMPTY(&ndopts->nd_opts_list)) { - opt = SLIST_FIRST(&ndopts->nd_opts_list); - SLIST_REMOVE_HEAD(&ndopts->nd_opts_list, entry); - free(opt); - } -} - -static void -sock_open(void) -{ - struct rainfo *ra; - struct icmp6_filter filt; - struct ipv6_mreq mreq; - int on; - /* XXX: should be max MTU attached to the node */ - static u_char answer[1500]; - - rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int)); - rcvcmsgbuf = malloc(rcvcmsgbuflen); - if (rcvcmsgbuf == NULL) - fatal(NULL); - - sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int)); - sndcmsgbuf = malloc(sndcmsgbuflen); - if (sndcmsgbuf == NULL) - fatal(NULL); - - if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) - fatal("socket"); - - /* specify to tell receiving interface */ - on = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) - < 0) - fatal("IPV6_RECVPKTINFO"); - - on = 1; - /* specify to tell value of hoplimit field of received IP6 hdr */ - if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)) - < 0) - fatal("IPV6_RECVHOPLIMIT"); - - ICMP6_FILTER_SETBLOCKALL(&filt); - ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt); - ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); - if (setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) - < 0) - fatal("ICMP6_FILTER"); - - /* - * join all routers multicast address on each advertising interface. - */ - if (inet_pton(AF_INET6, ALLROUTERS_LINK, &mreq.ipv6mr_multiaddr.s6_addr) - != 1) - fatal("inet_pton"); - SLIST_FOREACH(ra, &ralist, entry) { - mreq.ipv6mr_interface = ra->ifindex; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, - sizeof(mreq)) < 0) - fatal("IPV6_JOIN_GROUP(link) on %s", ra->ifname); - } - - /* initialize msghdr for receiving packets */ - rcviov[0].iov_base = answer; - rcviov[0].iov_len = sizeof(answer); - rcvmhdr.msg_name = &from; - rcvmhdr.msg_namelen = sizeof(from); - rcvmhdr.msg_iov = rcviov; - rcvmhdr.msg_iovlen = 1; - rcvmhdr.msg_control = 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 = sndcmsgbuf; - sndmhdr.msg_controllen = sndcmsgbuflen; -} - -/* open a routing socket to watch the routing table */ -static void -rtsock_open(void) -{ - unsigned int rtfilter; - - if ((rtsock = socket(PF_ROUTE, SOCK_RAW, AF_INET6)) < 0) - fatal("socket"); - - rtfilter = - ROUTE_FILTER(RTM_ADD) | - ROUTE_FILTER(RTM_DELETE) | - ROUTE_FILTER(RTM_NEWADDR) | - ROUTE_FILTER(RTM_DELADDR) | - ROUTE_FILTER(RTM_IFINFO); - - if (setsockopt(rtsock, PF_ROUTE, ROUTE_MSGFILTER, - &rtfilter, sizeof(rtfilter)) == -1) - fatal("setsockopt(ROUTE_MSGFILTER)"); - - rtsockbuflen = 2048; - rtsockbuf = malloc(rtsockbuflen); - if (rtsockbuf == NULL) - fatal(NULL); -} - -static struct rainfo * -if_indextorainfo(int index) -{ - struct rainfo *rai; - - SLIST_FOREACH(rai, &ralist, entry) { - if (rai->ifindex == index) - return(rai); - } - - return(NULL); /* search failed */ -} - -static void -ra_output(struct rainfo *rainfo, struct sockaddr_in6 *to) -{ - struct cmsghdr *cm; - struct in6_pktinfo *pi; - ssize_t len; - - if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) { - log_debug("%s is not up, skip sending RA", rainfo->ifname); - return; - } - - make_packet(rainfo); /* XXX: inefficient */ - - sndmhdr.msg_name = to; - sndmhdr.msg_iov[0].iov_base = rainfo->ra_data; - sndmhdr.msg_iov[0].iov_len = rainfo->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 = rainfo->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)); - } - - log_debug("send RA on %s, # of waitings = %u", - rainfo->ifname, rainfo->waiting); - - len = sendmsg(sock, &sndmhdr, 0); - if (len < 0) { - log_warn("sendmsg on %s", rainfo->ifname); - return; - } - - rainfo->raoutput++; - - if (memcmp(to, &sin6_allnodes, sizeof(sin6_allnodes)) == 0) { - /* update counter */ - if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS) - rainfo->initcounter++; - /* update timestamp */ - gettimeofday(&rainfo->lastsent, NULL); - - /* reset waiting counter */ - rainfo->waiting = 0; - } -} - -/* process RA timer */ -void -timer_cb(int fd, short event, void *data) -{ - struct rainfo *rai = (struct rainfo *)data; - - log_debug("RA timer on %s is expired", rai->ifname); - - ra_output(rai, &sin6_allnodes); - - ra_timer_update(rai); - evtimer_add(&rai->timer.ev, &rai->timer.tm); -} - -/* update RA timer */ -void -ra_timer_update(struct rainfo *rai) -{ - struct timeval *tm = &rai->timer.tm; - long interval; - - /* - * 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 (RFC2461 6.2.4). - */ - interval = rai->mininterval; - interval += arc4random_uniform(rai->maxinterval - rai->mininterval); - - /* - * 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-2461 6.2.4) - */ - if (rai->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS && - interval > MAX_INITIAL_RTR_ADVERT_INTERVAL) - interval = MAX_INITIAL_RTR_ADVERT_INTERVAL; - - tm->tv_sec = interval; - tm->tv_usec = 0; - - log_debug("RA timer on %s set to %lld.%lds", rai->ifname, - (long long)tm->tv_sec, tm->tv_usec); -} - -int -rdaemon(int devnull) -{ - if (devnull == -1) { - errno = EBADF; - return (-1); - } - if (fcntl(devnull, F_GETFL) == -1) - return (-1); - - switch (fork()) { - case -1: - return (-1); - case 0: - break; - default: - _exit(0); - } - - if (setsid() == -1) - return (-1); - - (void)dup2(devnull, STDIN_FILENO); - (void)dup2(devnull, STDOUT_FILENO); - (void)dup2(devnull, STDERR_FILENO); - if (devnull > 2) - (void)close(devnull); - - return (0); -} diff --git a/usr.sbin/rtadvd/rtadvd.conf b/usr.sbin/rtadvd/rtadvd.conf deleted file mode 100644 index d610925bfae..00000000000 --- a/usr.sbin/rtadvd/rtadvd.conf +++ /dev/null @@ -1,23 +0,0 @@ -# $OpenBSD: rtadvd.conf,v 1.8 2013/06/01 01:30:54 brad Exp $ -# $KAME: rtadvd.conf,v 1.12 2001/01/21 14:56:38 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:\ -# :rtprefix="2001:db8:ffff:1001::":\ -# :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 7811924e470..00000000000 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ /dev/null @@ -1,412 +0,0 @@ -.\" $OpenBSD: rtadvd.conf.5,v 1.40 2018/06/13 14:18:26 florian Exp $ -.\" $KAME: rtadvd.conf.5,v 1.46 2003/06/17 08:26:35 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. -.\" -.Dd $Mdocdate: June 13 2018 $ -.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 infamous -.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 one third of the 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 -(num) Flags field in router advertisement message header. -Bit 7 -.Pq 0x80 -means Managed address configuration flag bit, -and Bit 6 -.Pq 0x40 -means Other stateful configuration flag bit. -Bit 4 -.Pq 0x10 -and -Bit 3 -.Pq 0x08 -are used to encode the route preference for the route as follows: -.Pp -.Bl -tag -width "0x08XXX" -offset indent -compact -.It 0x08 -High -.It 0x00 -Medium (the default) -.It 0x18 -Low -.El -.Pp -The default value is 0. -.It Cm \&rltime -(num) Router lifetime field -.Pq unit: seconds . -Its value must be no greater than 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, unless the -.Cm noifprefix -flag is specified. -Keywords other than -.Cm clockskew -can be augmented with a number, like -.Dq Li prefix2 , -to specify multiple prefixes. -.Bl -tag -width indent -.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 -(num) Flags field in prefix information option. -Bit 7 -.Pq 0x80 -means On-link flag bit, -and Bit 6 -.Pq 0x40 -means Autonomous address-configuration flag bit. -The default value is 0xc0, i.e., both bits are set. -.It Cm \&addr -(str) The address filled into Prefix field. -Since -.Dq \&: -is used for the -.Xr termcap 5 -file format as well as IPv6 numeric addresses, the field MUST be quoted -using double quotes. -.It Cm \&noifprefix -(bool) Specifies whether -.Nm rtadvd -should gather prefix information from the interface if no -.Cm addr -is specified. -If no -.Cm addr -is given, and -.Cm noifprefix -is set, -.Nm rtadvd -will send RA packets with no prefix information. -.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 items are for ICMPv6 route information option, -which will be attached to router advertisement header. -These items are optional. -Each item can be augmented with a 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 for those is the same as that of the raflags field. -.It Cm \&rtltime -(num) route lifetime field in route information option. -.Pq unit: seconds . -The default value is same as router lifetime. -.El -.Pp -The following items are for ICMPv6 RDNSS option, used to give a list of -recursive DNS servers to hosts. -If this item is omitted, no information about DNS servers will be advertised. -.Bl -tag -width indent -.It Cm \&rdnss -(str) The list of advertised recursive DNS servers, separated by commas. -.It Cm \&rdnssltime -(num) Validity of the list of DNS servers -.Pq unit: seconds . -The default value is 1.5 * the value of maxinterval. -.El -.Pp -The following items are used for ICMPv6 DNSSL option which specifies a -list of DNS suffixes advertised to hosts. -If this option is not specified, no DNS suffix will be sent to hosts. -.Bl -tag -width indent -.It Cm \&dnssl -(str) The list of advertised DNS suffixes, separated by commas. -.It Cm \&dnsslltime -(num) Validity of the list of DNS suffixes -.Pq unit: seconds . -The default value is 1.5 * the value of maxinterval. -.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 -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:\e - :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:\e - :addr="2001:db8:ffff:1000::":prefixlen#64: -.Ed -.Pp -The following example configures two recursive DNS servers for the -.Li em0 -interface and sets the DNS search suffix to -.Do -example.com -.Dc . -.Bd -literal -offset indent -em0:\e - :rdnss="2001:db8:ffff:1000::1,2001:db8:ffff:1000::2":\e - :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:\e - :chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\e - :pinfoflags#192:vltime#2592000:pltime#604800:mtu#0: -ef0:\e - :addr="2001:db8:ffff:1000::":prefixlen#64:tc=default: -.Ed -.Sh SEE ALSO -.Xr termcap 5 , -.Xr rtadvd 8 -.Sh STANDARDS -.Rs -.%A R. Draves -.%A D. Thaler -.%D 2005 -.%R RFC 4191 -.%T Default Router Preferences and More-Specific Routes -.Re -.Pp -.Rs -.%A T. Narten -.%A E. Nordmark -.%A W. Simpson -.%A H. Soliman -.%D 2007 -.%R RFC 4861 -.%T Neighbor Discovery for IP version 6 (IPv6) -.Re -.Pp -.Rs -.%A J. Jeong -.%A S. Park -.%A L. Beloeil -.%A S. Madanapalli -.%D 2017 -.%R RFC 8106 -.%T IPv6 Router Advertisement Options for DNS Configuration -.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 18f532b9436..00000000000 --- a/usr.sbin/rtadvd/rtadvd.h +++ /dev/null @@ -1,171 +0,0 @@ -/* $OpenBSD: rtadvd.h,v 1.29 2016/09/25 13:54:39 florian Exp $ */ -/* $KAME: rtadvd.h,v 1.20 2002/05/29 10:13:10 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. - */ - -#define RTADVD_USER "_rtadvd" - -#define ALLNODES "ff02::1" -#define ALLROUTERS_LINK "ff02::2" - -/* 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 MAX_ROUTERLIFETIME 9000 -#define MIN_MAXINTERVAL 4 -#define MAX_MAXINTERVAL 1800 -#define MIN_MININTERVAL 3 -#define MAX_REACHABLETIME 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 rtadvd_timer { - struct event ev; - struct timeval tm; -}; - -struct prefix { - TAILQ_ENTRY(prefix) entry; - - u_int32_t validlifetime; /* AdvValidLifetime */ - time_t vltimeexpire; /* expiration of vltime; decrement case only */ - u_int32_t preflifetime; /* AdvPreferredLifetime */ - time_t pltimeexpire; /* expiration of pltime; decrement case only */ - u_int onlinkflg; /* bool: AdvOnLinkFlag */ - u_int autoconfflg; /* bool: AdvAutonomousFlag */ - int prefixlen; - int origin; /* from kernel or config */ - struct in6_addr prefix; -}; - -struct rtinfo { - TAILQ_ENTRY(rtinfo) entry; - - uint32_t lifetime; - int rtpref; - int prefixlen; - struct in6_addr prefix; -}; - -/* - * `struct rdnss` may contain an arbitrary number of `servers` and `struct - * dnssldom` will contain a variable-sized `domain`. Space required for these - * elements will be dynamically allocated. We do not use flexible array members - * here because this breaks compile on some architectures using gcc2. Instead, - * we just have an array with a single (unused) element. - */ - -struct rdnss { - TAILQ_ENTRY(rdnss) entry; - - u_int32_t lifetime; - int servercnt; - struct in6_addr servers[1]; -}; - -struct dnssldom { - TAILQ_ENTRY(dnssldom) entry; - - u_int32_t length; - char domain[1]; -}; - -struct dnssl { - TAILQ_ENTRY(dnssl) entry; - - u_int32_t lifetime; - TAILQ_HEAD(dnssldomlist, dnssldom) dnssldoms; -}; - -struct rainfo { - /* pointer for list */ - SLIST_ENTRY(rainfo) entry; - - /* timer related parameters */ - struct rtadvd_timer timer; - unsigned int initcounter; /* counter for the first few advertisements */ - struct timeval lastsent; /* timestamp when the latest RA was sent */ - unsigned int waiting; /* number of RS waiting for RA */ - - /* interface information */ - int ifindex; - int advlinkopt; /* bool: whether include link-layer addr opt */ - struct sockaddr_dl *sdl; - char ifname[IF_NAMESIZE]; - int phymtu; /* mtu of the physical interface */ - - /* Router configuration variables */ - u_short lifetime; /* AdvDefaultLifetime */ - u_int maxinterval; /* MaxRtrAdvInterval */ - u_int mininterval; /* MinRtrAdvInterval */ - int managedflg; /* AdvManagedFlag */ - int otherflg; /* AdvOtherConfigFlag */ - int rtpref; /* router preference */ - u_int32_t linkmtu; /* AdvLinkMTU */ - u_int32_t reachabletime; /* AdvReachableTime */ - u_int32_t retranstimer; /* AdvRetransTimer */ - u_int hoplimit; /* AdvCurHopLimit */ - TAILQ_HEAD(prefixlist, prefix) prefixes; /* AdvPrefixList(link head) */ - int pfxs; /* number of prefixes */ - TAILQ_HEAD(rtinfolist, rtinfo) rtinfos; - TAILQ_HEAD(rdnsslist, rdnss) rdnsss; /* advertised recursive dns servers */ - TAILQ_HEAD(dnssllist, dnssl) dnssls; - long clockskew; /* used for consistency check of lifetimes */ - - - /* actual RA packet data and its length */ - size_t ra_datalen; - u_char *ra_data; - - /* statistics */ - uint64_t raoutput; /* number of RAs sent */ - uint64_t rainput; /* number of RAs received */ - uint64_t rainconsistent; /* number of RAs inconsistent with ours */ - uint64_t rsinput; /* number of RSs received */ -}; -SLIST_HEAD(ralist, rainfo); - -void ra_timer_update(struct rainfo *); - -struct prefix *find_prefix(struct rainfo *, struct in6_addr *, int);