Import NetBSD rtadvd(8)
Change-Id: I22626843d85c78f0fadefd58d61d7a85d285b2b8
This commit is contained in:
parent
5de448e315
commit
8f957290eb
|
|
@ -160,6 +160,7 @@
|
|||
./etc/rc.d/npf minix-base
|
||||
./etc/rc.d/pwcheck minix-base
|
||||
./etc/rc.d/root minix-base
|
||||
./etc/rc.d/rtadvd minix-base
|
||||
./etc/rc.d/sysctl minix-base
|
||||
./etc/rc.d/sysdb minix-base
|
||||
./etc/rc.d/syslogd minix-base
|
||||
|
|
@ -1133,6 +1134,7 @@
|
|||
./usr/sbin/rdate minix-base
|
||||
./usr/sbin/rndc-confgen minix-base
|
||||
./usr/sbin/rndc minix-base
|
||||
./usr/sbin/rtadvd minix-base use_inet6
|
||||
./usr/sbin/service minix-base
|
||||
./usr/sbin/services_mkdb minix-base
|
||||
./usr/sbin/syslogd minix-base
|
||||
|
|
@ -1258,6 +1260,8 @@
|
|||
./usr/share/examples/openssl/CA.pl minix-base crypto
|
||||
./usr/share/examples/openssl/CA.sh minix-base crypto
|
||||
./usr/share/examples/openssl/openssl.cnf minix-base crypto
|
||||
./usr/share/examples/rtadvd minix-base
|
||||
./usr/share/examples/rtadvd/rtadvd.conf minix-base use_inet6
|
||||
./usr/share/examples/tmux minix-base
|
||||
./usr/share/examples/tmux/screen-keys.conf minix-base
|
||||
./usr/share/i18n minix-base nls
|
||||
|
|
@ -3938,6 +3942,10 @@
|
|||
./var/chroot/named/var/run/lwresd minix-base
|
||||
./var/chroot/named/var/run/named minix-base
|
||||
./var/chroot/named/var/tmp minix-base
|
||||
./var/chroot/rtadvd minix-base
|
||||
./var/chroot/rtadvd/etc minix-base
|
||||
./var/chroot/rtadvd/var minix-base
|
||||
./var/chroot/rtadvd/var/run minix-base
|
||||
./var/chroot/tcpdump minix-base
|
||||
./var/db minix-base
|
||||
./var/db/obsolete minix-base
|
||||
|
|
|
|||
|
|
@ -660,6 +660,7 @@
|
|||
./usr/libdata/debug/usr/sbin/rdate.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/sbin/rndc-confgen.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/sbin/rndc.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/sbin/rtadvd.debug minix-debug use_inet6,debug
|
||||
./usr/libdata/debug/usr/sbin/services_mkdb.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/sbin/syslogd.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/sbin/tcpdump.debug minix-debug debug
|
||||
|
|
|
|||
|
|
@ -3390,6 +3390,7 @@
|
|||
./usr/man/man5/resolver.5 minix-man
|
||||
./usr/man/man5/rhosts.5 minix-man obsolete
|
||||
./usr/man/man5/rndc.conf.5 minix-man
|
||||
./usr/man/man5/rtadvd.conf.5 minix-man use_inet6
|
||||
./usr/man/man5/serv.access.5 minix-man obsolete
|
||||
./usr/man/man5/statvfs.5 minix-man
|
||||
./usr/man/man5/syslog.conf.5 minix-man
|
||||
|
|
@ -3564,6 +3565,7 @@
|
|||
./usr/man/man8/rotate.8 minix-man
|
||||
./usr/man/man8/route.8 minix-man
|
||||
./usr/man/man8/rshd.8 minix-man
|
||||
./usr/man/man8/rtadvd.8 minix-man use_inet6
|
||||
./usr/man/man8/screendump.8 minix-man
|
||||
./usr/man/man8/serial-ip.8 minix-man obsolete
|
||||
./usr/man/man8/service.8 minix-man
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@
|
|||
./usr/share/examples/lua
|
||||
./usr/share/examples/lutok
|
||||
./usr/share/examples/openssl
|
||||
./usr/share/examples/rtadvd
|
||||
./usr/share/examples/tmux
|
||||
./usr/share/games
|
||||
./usr/share/games/fortune
|
||||
|
|
@ -714,6 +715,10 @@
|
|||
./var/chroot/named/var/run/lwresd mode=0775 gname=named
|
||||
./var/chroot/named/var/run/named mode=0775 gname=named
|
||||
./var/chroot/named/var/tmp mode=01775 gname=named
|
||||
./var/chroot/rtadvd type=dir mode=0755
|
||||
./var/chroot/rtadvd/etc type=dir mode=0755
|
||||
./var/chroot/rtadvd/var type=dir mode=0755
|
||||
./var/chroot/rtadvd/var/run type=dir mode=0775 gname=_rtadvd
|
||||
./var/chroot/tcpdump mode=0755
|
||||
./var/db
|
||||
./var/db/obsolete
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ CONFIGFILES=\
|
|||
pwcheck \
|
||||
\
|
||||
\
|
||||
root \
|
||||
root rtadvd \
|
||||
\
|
||||
\
|
||||
sysctl sysdb syslogd \
|
||||
|
|
|
|||
60
etc/rc.d/rtadvd
Executable file
60
etc/rc.d/rtadvd
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: rtadvd,v 1.8 2013/07/09 09:34:58 roy Exp $
|
||||
#
|
||||
|
||||
# PROVIDE: rtadvd
|
||||
# REQUIRE: DAEMON
|
||||
# BEFORE: LOGIN
|
||||
|
||||
$_rc_subr_loaded . /etc/rc.subr
|
||||
|
||||
name=rtadvd
|
||||
rcvar=$name
|
||||
command="/usr/sbin/$name"
|
||||
pidfile="/var/run/$name.pid"
|
||||
extra_commands=reload
|
||||
start_precmd=rtadvd_prestart
|
||||
reload_precmd=rtadvd_prereload
|
||||
|
||||
rtadvd_prereload()
|
||||
{
|
||||
local chdir="$(getent passwd _rtadvd | cut -d: -f6)"
|
||||
local conf=/etc/rtadvd.conf myflags o confdir
|
||||
|
||||
[ -z "$chdir" -o "$chdir" = / ] && return 0
|
||||
|
||||
if [ -n "$flags" ]; then
|
||||
myflags=$flags
|
||||
else
|
||||
eval myflags=\$${name}_flags
|
||||
fi
|
||||
set -- ${myflags}
|
||||
while getopts c:dDfM:Rs o; do
|
||||
case "$1" in
|
||||
-c) conf="$OPTARG";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
confdir=$(dirname "$conf")
|
||||
|
||||
echo "$name: copying $conf to $chdir$conf"
|
||||
cp "$conf" "$chdir$conf"
|
||||
|
||||
# Provide a link to the chrooted dump file
|
||||
ln -snf "$chdir/var/run/$name.dump" /var/run
|
||||
}
|
||||
|
||||
rtadvd_prestart()
|
||||
{
|
||||
if [ "$ip6mode" != router ]; then
|
||||
warn \
|
||||
"${name} cannot be used on IPv6 host, only on an IPv6 router."
|
||||
return 1
|
||||
fi
|
||||
|
||||
rtadvd_prereload
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
||||
|
|
@ -55,7 +55,7 @@ SUBDIR+= mdsetimage
|
|||
SUBDIR+= ndp
|
||||
.endif
|
||||
.if (${USE_INET6} != "no")
|
||||
SUBDIR+= traceroute6
|
||||
SUBDIR+= rtadvd traceroute6
|
||||
.endif
|
||||
|
||||
.if !defined(__MINIX)
|
||||
|
|
|
|||
26
usr.sbin/rtadvd/Makefile
Normal file
26
usr.sbin/rtadvd/Makefile
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# $NetBSD: Makefile,v 1.17 2012/08/10 12:10:30 joerg Exp $
|
||||
|
||||
WARNS?= 4
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?= yes # network server
|
||||
|
||||
PROG= rtadvd
|
||||
SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c
|
||||
|
||||
CPPFLAGS+=-DINET6
|
||||
MAN= rtadvd.8 rtadvd.conf.5
|
||||
LDADD+= -lutil
|
||||
DPADD+= ${LIBUTIL}
|
||||
|
||||
.if ${MKSHARE} != "no"
|
||||
FILESDIR= /usr/share/examples/rtadvd
|
||||
FILES= rtadvd.conf
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
.if defined(HAVE_GCC) || defined(HAVE_LLVM)
|
||||
COPTS.dump.c=-fno-strict-aliasing
|
||||
.endif
|
||||
444
usr.sbin/rtadvd/advcap.c
Normal file
444
usr.sbin/rtadvd/advcap.c
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/* $NetBSD: advcap.c,v 1.15 2015/06/05 15:41:59 roy Exp $ */
|
||||
/* $KAME: advcap.c,v 1.11 2003/05/19 09:46:50 keiichi Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifndef __UNCONST
|
||||
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
|
||||
#endif
|
||||
|
||||
#ifndef BUFSIZ
|
||||
#define BUFSIZ 1024
|
||||
#endif
|
||||
#define MAXHOP 32 /* max number of tc= indirections */
|
||||
|
||||
#define tgetent agetent
|
||||
#define tnchktc anchktc
|
||||
#define tnamatch anamatch
|
||||
#define tgetnum agetnum
|
||||
#define tgetflag agetflag
|
||||
#define tgetstr agetstr
|
||||
|
||||
#if 0
|
||||
#define V_TERMCAP "REMOTE"
|
||||
#define V_TERM "HOST"
|
||||
#endif
|
||||
|
||||
char *RM;
|
||||
|
||||
/*
|
||||
* 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 : __UNCONST(_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(RM = cp, O_RDONLY);
|
||||
}
|
||||
if (tf < 0) {
|
||||
syslog(LOG_INFO, "<%s> open: %m", __func__);
|
||||
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) {
|
||||
write(2,"Remcap entry too long\n", 23);
|
||||
break;
|
||||
} else
|
||||
*cp++ = c;
|
||||
}
|
||||
*cp = 0;
|
||||
|
||||
/*
|
||||
* The real work for the match.
|
||||
*/
|
||||
if (tnamatch(name)) {
|
||||
close(tf);
|
||||
return (tnchktc());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* tnchktc: check the last entry, see if it's tc=xxx. If so,
|
||||
* recursively find xxx and append that entry (minus the names)
|
||||
* to take the place of the tc=xxx entry. This allows termcap
|
||||
* entries to say "like an HP2621 but doesn't turn on the labels".
|
||||
* Note that this works because of the left to right scan.
|
||||
*/
|
||||
int
|
||||
tnchktc(void)
|
||||
{
|
||||
char *p, *q;
|
||||
char tcname[16]; /* name of similar terminal */
|
||||
char tcbuf[BUFSIZ];
|
||||
char *holdtbuf = tbuf;
|
||||
int l;
|
||||
|
||||
p = tbuf + strlen(tbuf) - 2; /* before the last colon */
|
||||
while (*--p != ':')
|
||||
if (p < tbuf) {
|
||||
write(2, "Bad remcap entry\n", 18);
|
||||
return (0);
|
||||
}
|
||||
p++;
|
||||
/* p now points to beginning of last field */
|
||||
if (p[0] != 't' || p[1] != 'c')
|
||||
return (1);
|
||||
strlcpy(tcname, p + 3, sizeof tcname);
|
||||
q = tcname;
|
||||
while (*q && *q != ':')
|
||||
q++;
|
||||
*q = 0;
|
||||
if (++hopcount > MAXHOP) {
|
||||
write(2, "Infinite tc= loop\n", 18);
|
||||
return (0);
|
||||
}
|
||||
if (getent(tcbuf, tcname, remotefile) != 1) {
|
||||
return (0);
|
||||
}
|
||||
for (q = tcbuf; *q++ != ':'; )
|
||||
;
|
||||
l = p - holdtbuf + strlen(q);
|
||||
if (l > BUFSIZ) {
|
||||
write(2, "Remcap entry too long\n", 23);
|
||||
q[BUFSIZ - (p-holdtbuf)] = 0;
|
||||
}
|
||||
strcpy(p, q);
|
||||
tbuf = holdtbuf;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tnamatch deals with name matching. The first field of the termcap
|
||||
* entry is a sequence of names separated by |'s, so we compare
|
||||
* against each such name. The normal : terminator after the last
|
||||
* name (before the first field) stops us.
|
||||
*/
|
||||
int
|
||||
tnamatch(char *np)
|
||||
{
|
||||
char *Np, *Bp;
|
||||
|
||||
Bp = tbuf;
|
||||
if (*Bp == '#')
|
||||
return (0);
|
||||
for (;;) {
|
||||
for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
|
||||
continue;
|
||||
if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
|
||||
return (1);
|
||||
while (*Bp && *Bp != ':' && *Bp != '|')
|
||||
Bp++;
|
||||
if (*Bp == 0 || *Bp == ':')
|
||||
return (0);
|
||||
Bp++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip to the next field. Notice that this is very dumb, not
|
||||
* knowing about \: escapes or any such. If necessary, :'s can be put
|
||||
* into the termcap file in octal.
|
||||
*/
|
||||
static char *
|
||||
tskip(char *bp)
|
||||
{
|
||||
int dquote;
|
||||
|
||||
dquote = 0;
|
||||
while (*bp) {
|
||||
switch (*bp) {
|
||||
case ':':
|
||||
if (!dquote)
|
||||
goto breakbreak;
|
||||
else
|
||||
bp++;
|
||||
break;
|
||||
case '\\':
|
||||
bp++;
|
||||
if (isdigit((unsigned char)*bp)) {
|
||||
while (isdigit((unsigned char)*bp++))
|
||||
;
|
||||
} else
|
||||
bp++;
|
||||
case '"':
|
||||
dquote = (dquote ? 0 : 1);
|
||||
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;
|
||||
const char *dps = "E\033^^\\\\::n\nr\rt\tb\bf\f\"\"", *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 = dps;
|
||||
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);
|
||||
}
|
||||
46
usr.sbin/rtadvd/advcap.h
Normal file
46
usr.sbin/rtadvd/advcap.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* $NetBSD: advcap.h,v 1.7 2011/12/10 19:14:29 roy Exp $ */
|
||||
/* $KAME: advcap.h,v 1.5 2003/06/09 05:40:54 t-momose Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Based on Id: termcap.h,v 1.8 1996/09/10 12:42:10 peter Exp */
|
||||
|
||||
#ifndef _ADVCAP_H_
|
||||
#define _ADVCAP_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern int agetent(char *, const char *);
|
||||
extern int agetflag(const char *);
|
||||
extern int64_t agetnum(const char *);
|
||||
extern char *agetstr(const char *, char **);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _ADVCAP_H_ */
|
||||
1324
usr.sbin/rtadvd/config.c
Normal file
1324
usr.sbin/rtadvd/config.c
Normal file
File diff suppressed because it is too large
Load Diff
49
usr.sbin/rtadvd/config.h
Normal file
49
usr.sbin/rtadvd/config.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/* $NetBSD: config.h,v 1.9 2012/12/13 15:36:36 roy Exp $ */
|
||||
/* $KAME: config.h,v 1.9 2003/08/06 04:19:40 ono Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
extern void free_rainfo(struct rainfo *);
|
||||
extern void getconfig(const char *, int);
|
||||
extern void delete_prefix(struct prefix *);
|
||||
extern void invalidate_prefix(struct prefix *);
|
||||
extern void update_prefix(struct prefix *);
|
||||
extern void make_prefix(struct rainfo *, int, struct in6_addr *, int);
|
||||
extern void make_packet(struct rainfo *);
|
||||
extern void get_prefix(struct rainfo *);
|
||||
|
||||
/*
|
||||
* it is highly unlikely to have 100 information options,
|
||||
* so it should be okay to limit it
|
||||
*/
|
||||
#define MAXPREFIX 100
|
||||
#define MAXROUTE 100
|
||||
#define MAXRDNSS 100
|
||||
#define MAXDNSSL 100
|
||||
280
usr.sbin/rtadvd/dump.c
Normal file
280
usr.sbin/rtadvd/dump.c
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
/* $NetBSD: dump.c,v 1.12 2015/06/05 14:09:20 roy Exp $ */
|
||||
/* $KAME: dump.c,v 1.34 2004/06/14 05:35:59 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 <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/if_var.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* XXX: the following two are non-standard include files */
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "rtadvd.h"
|
||||
#include "timer.h"
|
||||
#include "if.h"
|
||||
#include "dump.h"
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
static char *ether_str(struct sockaddr_dl *);
|
||||
static void if_dump(void);
|
||||
|
||||
static const char *rtpref_str[] = {
|
||||
"medium", /* 00 */
|
||||
"high", /* 01 */
|
||||
"rsv", /* 10 */
|
||||
"low" /* 11 */
|
||||
};
|
||||
|
||||
static char *
|
||||
ether_str(struct sockaddr_dl *sdl)
|
||||
{
|
||||
static char hbuf[NI_MAXHOST];
|
||||
|
||||
if (sdl->sdl_alen) {
|
||||
if (getnameinfo((struct sockaddr *)sdl, sdl->sdl_len,
|
||||
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
snprintf(hbuf, sizeof(hbuf), "<invalid>");
|
||||
} else
|
||||
snprintf(hbuf, sizeof(hbuf), "NONE");
|
||||
|
||||
return(hbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
if_dump(void)
|
||||
{
|
||||
struct rainfo *rai;
|
||||
struct prefix *pfx;
|
||||
struct rtinfo *rti;
|
||||
struct rdnss *rdns;
|
||||
struct rdnss_addr *rdnsa;
|
||||
struct dnssl *dnsl;
|
||||
struct dnssl_domain *dnsd;
|
||||
char *p, len;
|
||||
char prefixbuf[INET6_ADDRSTRLEN];
|
||||
struct timespec now;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now); /* XXX: unused in most cases */
|
||||
TAILQ_FOREACH(rai, &ralist, next) {
|
||||
fprintf(fp, "%s:\n", rai->ifname);
|
||||
|
||||
fprintf(fp, " Status: %s\n",
|
||||
(rai->ifflags & IFF_UP) ? "UP" : "DOWN");
|
||||
|
||||
/* control information */
|
||||
if (rai->lastsent.tv_sec) {
|
||||
/* note that ctime() appends CR by itself */
|
||||
fprintf(fp, " Last RA sent: %s",
|
||||
ctime((time_t *)&rai->lastsent.tv_sec));
|
||||
}
|
||||
if (rai->timer) {
|
||||
fprintf(fp, " Next RA will be sent: %s",
|
||||
ctime((time_t *)&rai->timer->tm.tv_sec));
|
||||
}
|
||||
else
|
||||
fprintf(fp, " RA timer is stopped");
|
||||
fprintf(fp, " waits: %d, initcount: %d\n",
|
||||
rai->waiting, rai->initcounter);
|
||||
|
||||
/* statistics */
|
||||
fprintf(fp, " statistics: RA(out/in/inconsistent): "
|
||||
"%llu/%llu/%llu, ",
|
||||
(unsigned long long)rai->raoutput,
|
||||
(unsigned long long)rai->rainput,
|
||||
(unsigned long long)rai->rainconsistent);
|
||||
fprintf(fp, "RS(input): %llu\n",
|
||||
(unsigned long long)rai->rsinput);
|
||||
|
||||
/* interface information */
|
||||
if (rai->advlinkopt)
|
||||
fprintf(fp, " Link-layer address: %s\n",
|
||||
ether_str(rai->sdl));
|
||||
fprintf(fp, " MTU: %d\n", rai->phymtu);
|
||||
|
||||
/* Router configuration variables */
|
||||
fprintf(fp, " DefaultLifetime: %d, MaxAdvInterval: %d, "
|
||||
"MinAdvInterval: %d\n", rai->lifetime, rai->maxinterval,
|
||||
rai->mininterval);
|
||||
fprintf(fp, " Flags: %s%s%s, ",
|
||||
rai->managedflg ? "M" : "", rai->otherflg ? "O" : "",
|
||||
"");
|
||||
fprintf(fp, "Preference: %s, ",
|
||||
rtpref_str[(rai->rtpref >> 3) & 0xff]);
|
||||
fprintf(fp, "MTU: %d\n", rai->linkmtu);
|
||||
fprintf(fp, " ReachableTime: %d, RetransTimer: %d, "
|
||||
"CurHopLimit: %d\n", rai->reachabletime,
|
||||
rai->retranstimer, rai->hoplimit);
|
||||
if (rai->clockskew)
|
||||
fprintf(fp, " Clock skew: %dsec\n",
|
||||
rai->clockskew);
|
||||
TAILQ_FOREACH(pfx, &rai->prefix, next) {
|
||||
if (pfx == TAILQ_FIRST(&rai->prefix))
|
||||
fprintf(fp, " Prefixes:\n");
|
||||
fprintf(fp, " %s/%d(",
|
||||
inet_ntop(AF_INET6, &pfx->prefix, prefixbuf,
|
||||
sizeof(prefixbuf)), pfx->prefixlen);
|
||||
switch (pfx->origin) {
|
||||
case PREFIX_FROM_KERNEL:
|
||||
fprintf(fp, "KERNEL, ");
|
||||
break;
|
||||
case PREFIX_FROM_CONFIG:
|
||||
fprintf(fp, "CONFIG, ");
|
||||
break;
|
||||
case PREFIX_FROM_DYNAMIC:
|
||||
fprintf(fp, "DYNAMIC, ");
|
||||
break;
|
||||
}
|
||||
if (pfx->validlifetime == ND6_INFINITE_LIFETIME)
|
||||
fprintf(fp, "vltime: infinity");
|
||||
else
|
||||
fprintf(fp, "vltime: %ld",
|
||||
(long)pfx->validlifetime);
|
||||
if (pfx->vltimeexpire != 0)
|
||||
fprintf(fp, "(decr,expire %lld), ", (long long)
|
||||
(pfx->vltimeexpire > now.tv_sec ?
|
||||
pfx->vltimeexpire - now.tv_sec : 0));
|
||||
else
|
||||
fprintf(fp, ", ");
|
||||
if (pfx->preflifetime == ND6_INFINITE_LIFETIME)
|
||||
fprintf(fp, "pltime: infinity");
|
||||
else
|
||||
fprintf(fp, "pltime: %ld",
|
||||
(long)pfx->preflifetime);
|
||||
if (pfx->pltimeexpire != 0)
|
||||
fprintf(fp, "(decr,expire %lld), ", (long long)
|
||||
(pfx->pltimeexpire > now.tv_sec ?
|
||||
pfx->pltimeexpire - now.tv_sec : 0));
|
||||
else
|
||||
fprintf(fp, ", ");
|
||||
fprintf(fp, "flags: %s%s%s",
|
||||
pfx->onlinkflg ? "L" : "",
|
||||
pfx->autoconfflg ? "A" : "",
|
||||
"");
|
||||
if (pfx->timer) {
|
||||
struct timespec *rest;
|
||||
|
||||
rest = rtadvd_timer_rest(pfx->timer);
|
||||
if (rest) { /* XXX: what if not? */
|
||||
fprintf(fp, ", expire in: %ld",
|
||||
(long)rest->tv_sec);
|
||||
}
|
||||
}
|
||||
fprintf(fp, ")\n");
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(rti, &rai->route, next) {
|
||||
if (rti == TAILQ_FIRST(&rai->route))
|
||||
fprintf(fp, " Route Information:\n");
|
||||
fprintf(fp, " %s/%d (",
|
||||
inet_ntop(AF_INET6, &rti->prefix,
|
||||
prefixbuf, sizeof(prefixbuf)),
|
||||
rti->prefixlen);
|
||||
fprintf(fp, "preference: %s, ",
|
||||
rtpref_str[0xff & (rti->rtpref >> 3)]);
|
||||
if (rti->ltime == ND6_INFINITE_LIFETIME)
|
||||
fprintf(fp, "lifetime: infinity");
|
||||
else
|
||||
fprintf(fp, "lifetime: %ld", (long)rti->ltime);
|
||||
fprintf(fp, ")\n");
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(rdns, &rai->rdnss, next) {
|
||||
fprintf(fp, " Recursive DNS Servers:\n");
|
||||
if (rdns->lifetime == ND6_INFINITE_LIFETIME)
|
||||
fprintf(fp, " lifetime: infinity\n");
|
||||
else
|
||||
fprintf(fp, " lifetime: %ld\n",
|
||||
(long)rdns->lifetime);
|
||||
TAILQ_FOREACH(rdnsa, &rdns->list, next)
|
||||
fprintf(fp, " %s\n",
|
||||
inet_ntop(AF_INET6, &rdnsa->addr,
|
||||
prefixbuf, sizeof(prefixbuf)));
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(dnsl, &rai->dnssl, next) {
|
||||
fprintf(fp, " DNS Search List:\n");
|
||||
if (dnsl->lifetime == ND6_INFINITE_LIFETIME)
|
||||
fprintf(fp, " lifetime: infinity\n");
|
||||
else
|
||||
fprintf(fp, " lifetime: %ld\n",
|
||||
(long)dnsl->lifetime);
|
||||
TAILQ_FOREACH(dnsd, &dnsl->list, next) {
|
||||
fprintf(fp, " ");
|
||||
for (p = dnsd->domain, len = *p++;
|
||||
len != 0;
|
||||
len = *p++)
|
||||
{
|
||||
if (p != dnsd->domain)
|
||||
fputc('.', fp);
|
||||
while(len-- != 0)
|
||||
fputc(*p++, fp);
|
||||
}
|
||||
fputc('\n', fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtadvd_dump_file(const char *dumpfile)
|
||||
{
|
||||
syslog(LOG_DEBUG, "<%s> dump current status to %s", __func__,
|
||||
dumpfile);
|
||||
|
||||
if ((fp = fopen(dumpfile, "w")) == NULL) {
|
||||
syslog(LOG_WARNING, "<%s> open a dump file(%s): %m",
|
||||
__func__, dumpfile);
|
||||
return;
|
||||
}
|
||||
|
||||
if_dump();
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
33
usr.sbin/rtadvd/dump.h
Normal file
33
usr.sbin/rtadvd/dump.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* $NetBSD: dump.h,v 1.2 2011/12/10 19:14:29 roy 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.
|
||||
*/
|
||||
|
||||
extern void rtadvd_dump_file(const char *);
|
||||
418
usr.sbin/rtadvd/if.c
Normal file
418
usr.sbin/rtadvd/if.c
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
/* $NetBSD: if.c,v 1.23 2015/06/05 15:41:59 roy Exp $ */
|
||||
/* $KAME: if.c,v 1.36 2004/11/30 22:32:01 suz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <ifaddrs.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/ethernet.h>
|
||||
#else
|
||||
#include <net/if_ether.h>
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "rtadvd.h"
|
||||
#include "if.h"
|
||||
|
||||
#ifndef RT_ROUNDUP
|
||||
#define RT_ROUNDUP(a) \
|
||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
|
||||
#endif
|
||||
|
||||
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;
|
||||
RT_ADVANCE(sa, sa);
|
||||
}
|
||||
else
|
||||
rti_info[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_dl *
|
||||
if_nametosdl(const 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(const char *name)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s, mtu;
|
||||
|
||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
|
||||
return 0;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_addr.sa_family = AF_INET6;
|
||||
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCGIFMTU, &ifr) != -1)
|
||||
mtu = ifr.ifr_mtu;
|
||||
else
|
||||
mtu = 0;
|
||||
close(s);
|
||||
|
||||
return mtu;
|
||||
}
|
||||
|
||||
/* give interface index and its old flags, then new flags returned */
|
||||
int
|
||||
if_getflags(int ifindex, int oifflags)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
syslog(LOG_ERR, "<%s> socket: %m", __func__);
|
||||
return (oifflags & ~IFF_UP);
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
if_indextoname(ifindex, ifr.ifr_name);
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
|
||||
syslog(LOG_ERR, "<%s> ioctl:SIOCGIFFLAGS: failed for %s",
|
||||
__func__, ifr.ifr_name);
|
||||
close(s);
|
||||
return (oifflags & ~IFF_UP);
|
||||
}
|
||||
close(s);
|
||||
return (ifr.ifr_flags);
|
||||
}
|
||||
|
||||
#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
|
||||
int
|
||||
lladdropt_length(struct sockaddr_dl *sdl)
|
||||
{
|
||||
switch (sdl->sdl_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
return(ROUNDUP8(ETHER_ADDR_LEN + 2));
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)
|
||||
{
|
||||
char *addr;
|
||||
|
||||
ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */
|
||||
|
||||
switch (sdl->sdl_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3;
|
||||
addr = (char *)(ndopt + 1);
|
||||
memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "<%s> unsupported link type(%d)",
|
||||
__func__, sdl->sdl_type);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define FILTER_MATCH(type, filter) ((0x1 << type) & filter)
|
||||
#define SIN6(s) ((struct sockaddr_in6 *)(s))
|
||||
#define SDL(s) ((struct sockaddr_dl *)(s))
|
||||
char *
|
||||
get_next_msg(char *buf, char *lim, int ifindex, size_t *lenp, int filter)
|
||||
{
|
||||
struct rt_msghdr *rtm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct sockaddr *sa, *dst, *gw, *ifa, *rti_info[RTAX_MAX];
|
||||
|
||||
*lenp = 0;
|
||||
for (rtm = (struct rt_msghdr *)buf;
|
||||
rtm < (struct rt_msghdr *)lim;
|
||||
rtm = (struct rt_msghdr *)(((char *)rtm) + rtm->rtm_msglen)) {
|
||||
/* just for safety */
|
||||
if (!rtm->rtm_msglen) {
|
||||
syslog(LOG_WARNING, "<%s> rtm_msglen is 0 "
|
||||
"(buf=%p lim=%p rtm=%p)", __func__,
|
||||
buf, lim, rtm);
|
||||
break;
|
||||
}
|
||||
if (FILTER_MATCH(rtm->rtm_type, filter) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (rtm->rtm_type) {
|
||||
case RTM_GET:
|
||||
case RTM_ADD:
|
||||
case RTM_DELETE:
|
||||
/* address related checks */
|
||||
sa = (struct sockaddr *)(rtm + 1);
|
||||
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
|
||||
if ((dst = rti_info[RTAX_DST]) == NULL ||
|
||||
dst->sa_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&SIN6(dst)->sin6_addr) ||
|
||||
IN6_IS_ADDR_MULTICAST(&SIN6(dst)->sin6_addr))
|
||||
continue;
|
||||
|
||||
if ((gw = rti_info[RTAX_GATEWAY]) == NULL ||
|
||||
gw->sa_family != AF_LINK)
|
||||
continue;
|
||||
if (ifindex && SDL(gw)->sdl_index != ifindex)
|
||||
continue;
|
||||
|
||||
if (rti_info[RTAX_NETMASK] == NULL)
|
||||
continue;
|
||||
|
||||
/* found */
|
||||
*lenp = rtm->rtm_msglen;
|
||||
return (char *)rtm;
|
||||
/* NOTREACHED */
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR:
|
||||
ifam = (struct ifa_msghdr *)rtm;
|
||||
|
||||
/* address related checks */
|
||||
sa = (struct sockaddr *)(ifam + 1);
|
||||
get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
|
||||
if ((ifa = rti_info[RTAX_IFA]) == NULL ||
|
||||
(ifa->sa_family != AF_INET &&
|
||||
ifa->sa_family != AF_INET6))
|
||||
continue;
|
||||
|
||||
if (ifa->sa_family == AF_INET6 &&
|
||||
(IN6_IS_ADDR_LINKLOCAL(&SIN6(ifa)->sin6_addr) ||
|
||||
IN6_IS_ADDR_MULTICAST(&SIN6(ifa)->sin6_addr)))
|
||||
continue;
|
||||
|
||||
if (ifindex && ifam->ifam_index != ifindex)
|
||||
continue;
|
||||
|
||||
/* found */
|
||||
*lenp = ifam->ifam_msglen;
|
||||
return (char *)rtm;
|
||||
/* NOTREACHED */
|
||||
#ifdef RTM_IFANNOUNCE
|
||||
case RTM_IFANNOUNCE:
|
||||
#endif
|
||||
case RTM_IFINFO:
|
||||
/* found */
|
||||
*lenp = rtm->rtm_msglen;
|
||||
return (char *)rtm;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
return (char *)rtm;
|
||||
}
|
||||
#undef FILTER_MATCH
|
||||
|
||||
struct in6_addr *
|
||||
get_addr(char *buf)
|
||||
{
|
||||
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
|
||||
struct sockaddr *sa, *rti_info[RTAX_MAX];
|
||||
|
||||
sa = (struct sockaddr *)(rtm + 1);
|
||||
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
|
||||
|
||||
return(&SIN6(rti_info[RTAX_DST])->sin6_addr);
|
||||
}
|
||||
|
||||
int
|
||||
get_rtm_ifindex(char *buf)
|
||||
{
|
||||
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
|
||||
struct sockaddr *sa, *rti_info[RTAX_MAX];
|
||||
|
||||
sa = (struct sockaddr *)(rtm + 1);
|
||||
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
|
||||
|
||||
return(((struct sockaddr_dl *)rti_info[RTAX_GATEWAY])->sdl_index);
|
||||
}
|
||||
|
||||
int
|
||||
get_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);
|
||||
}
|
||||
|
||||
#ifdef RTM_IFANNOUNCE
|
||||
int
|
||||
get_ifan_ifindex(char *buf)
|
||||
{
|
||||
struct if_announcemsghdr *ifan = (struct if_announcemsghdr *)buf;
|
||||
|
||||
return ((int)ifan->ifan_index);
|
||||
}
|
||||
|
||||
int
|
||||
get_ifan_what(char *buf)
|
||||
{
|
||||
struct if_announcemsghdr *ifan = (struct if_announcemsghdr *)buf;
|
||||
|
||||
return ((int)ifan->ifan_what);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
get_prefixlen(char *buf)
|
||||
{
|
||||
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
|
||||
struct sockaddr *sa, *rti_info[RTAX_MAX];
|
||||
unsigned char *p, *lim;
|
||||
|
||||
sa = (struct sockaddr *)(rtm + 1);
|
||||
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
|
||||
sa = rti_info[RTAX_NETMASK];
|
||||
|
||||
p = (unsigned char *)(&SIN6(sa)->sin6_addr);
|
||||
lim = (unsigned char *)sa + sa->sa_len;
|
||||
return prefixlen(p, lim);
|
||||
}
|
||||
|
||||
int
|
||||
prefixlen(const unsigned char *p, const unsigned char *lim)
|
||||
{
|
||||
int masklen;
|
||||
|
||||
for (masklen = 0; p < lim; p++) {
|
||||
switch (*p) {
|
||||
case 0xff:
|
||||
masklen += 8;
|
||||
break;
|
||||
case 0xfe:
|
||||
masklen += 7;
|
||||
break;
|
||||
case 0xfc:
|
||||
masklen += 6;
|
||||
break;
|
||||
case 0xf8:
|
||||
masklen += 5;
|
||||
break;
|
||||
case 0xf0:
|
||||
masklen += 4;
|
||||
break;
|
||||
case 0xe0:
|
||||
masklen += 3;
|
||||
break;
|
||||
case 0xc0:
|
||||
masklen += 2;
|
||||
break;
|
||||
case 0x80:
|
||||
masklen += 1;
|
||||
break;
|
||||
case 0x00:
|
||||
break;
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return(masklen);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
54
usr.sbin/rtadvd/if.h
Normal file
54
usr.sbin/rtadvd/if.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* $NetBSD: if.h,v 1.10 2012/12/13 15:36:36 roy Exp $ */
|
||||
/* $KAME: if.h,v 1.12 2003/09/21 07:17:03 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)
|
||||
|
||||
struct nd_opt_hdr;
|
||||
struct sockaddr_dl *if_nametosdl(const char *);
|
||||
int if_getmtu(const char *);
|
||||
int if_getflags(int, int);
|
||||
int lladdropt_length(struct sockaddr_dl *);
|
||||
void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *);
|
||||
char *get_next_msg(char *, char *, int, size_t *, int);
|
||||
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 *);
|
||||
#ifdef RTM_IFANNOUNCE
|
||||
int get_ifan_ifindex(char *);
|
||||
int get_ifan_what(char *);
|
||||
#endif
|
||||
int get_prefixlen(char *);
|
||||
int prefixlen(const unsigned char *, const unsigned char *);
|
||||
int rtmsg_type(char *);
|
||||
int rtmsg_len(char *);
|
||||
4
usr.sbin/rtadvd/pathnames.h
Normal file
4
usr.sbin/rtadvd/pathnames.h
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/* $NetBSD: pathnames.h,v 1.3 2000/05/23 11:37:59 itojun Exp $ */
|
||||
/* $KAME: pathnames.h,v 1.2 2000/05/16 13:34:13 itojun Exp $ */
|
||||
|
||||
#define _PATH_RTADVDCONF "/etc/rtadvd.conf"
|
||||
488
usr.sbin/rtadvd/rrenum.c
Normal file
488
usr.sbin/rtadvd/rrenum.c
Normal file
|
|
@ -0,0 +1,488 @@
|
|||
/* $NetBSD: rrenum.c,v 1.18 2015/06/05 15:41:59 roy Exp $ */
|
||||
/* $KAME: rrenum.c,v 1.14 2004/06/14 05:36:00 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/if_var.h>
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "rtadvd.h"
|
||||
#include "rrenum.h"
|
||||
#include "if.h"
|
||||
|
||||
#define RR_ISSET_SEGNUM(segnum_bits, segnum) \
|
||||
((((segnum_bits)[(segnum) >> 5]) & (1 << ((segnum) & 31))) != 0)
|
||||
#define RR_SET_SEGNUM(segnum_bits, segnum) \
|
||||
(((segnum_bits)[(segnum) >> 5]) |= (1 << ((segnum) & 31)))
|
||||
|
||||
struct rr_operation {
|
||||
u_long rro_seqnum;
|
||||
u_long rro_segnum_bits[8];
|
||||
};
|
||||
|
||||
static struct rr_operation rro;
|
||||
static int rr_rcvifindex;
|
||||
static int rrcmd2pco[RPM_PCO_MAX] = {
|
||||
0,
|
||||
SIOCAIFPREFIX_IN6,
|
||||
SIOCCIFPREFIX_IN6,
|
||||
SIOCSGIFPREFIX_IN6
|
||||
};
|
||||
static int s = -1;
|
||||
|
||||
/*
|
||||
* Check validity of a Prefix Control Operation(PCO).
|
||||
* Return 0 on success, 1 on failure.
|
||||
*/
|
||||
static int
|
||||
rr_pco_check(int len, struct rr_pco_match *rpm)
|
||||
{
|
||||
struct rr_pco_use *rpu, *rpulim;
|
||||
int checklen;
|
||||
|
||||
/* rpm->rpm_len must be (4N * 3) as router-renum-05.txt */
|
||||
if ((rpm->rpm_len - 3) < 0 || /* must be at least 3 */
|
||||
(rpm->rpm_len - 3) & 0x3) { /* must be multiple of 4 */
|
||||
syslog(LOG_WARNING, "<%s> rpm_len %d is not 4N * 3",
|
||||
__func__, rpm->rpm_len);
|
||||
return 1;
|
||||
}
|
||||
/* rpm->rpm_code must be valid value */
|
||||
switch (rpm->rpm_code) {
|
||||
case RPM_PCO_ADD:
|
||||
case RPM_PCO_CHANGE:
|
||||
case RPM_PCO_SETGLOBAL:
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_WARNING, "<%s> unknown rpm_code %d", __func__,
|
||||
rpm->rpm_code);
|
||||
return 1;
|
||||
}
|
||||
/* rpm->rpm_matchlen must be 0 to 128 inclusive */
|
||||
if (rpm->rpm_matchlen > 128) {
|
||||
syslog(LOG_WARNING, "<%s> rpm_matchlen %d is over 128",
|
||||
__func__, rpm->rpm_matchlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* rpu->rpu_uselen, rpu->rpu_keeplen, and sum of them must be
|
||||
* between 0 and 128 inclusive
|
||||
*/
|
||||
for (rpu = (struct rr_pco_use *)(rpm + 1),
|
||||
rpulim = (struct rr_pco_use *)((char *)rpm + len);
|
||||
rpu < rpulim;
|
||||
rpu += 1) {
|
||||
checklen = rpu->rpu_uselen;
|
||||
checklen += rpu->rpu_keeplen;
|
||||
/*
|
||||
* omit these check, because either of rpu_uselen
|
||||
* and rpu_keeplen is unsigned char
|
||||
* (128 > rpu_uselen > 0)
|
||||
* (128 > rpu_keeplen > 0)
|
||||
* (rpu_uselen + rpu_keeplen > 0)
|
||||
*/
|
||||
if (checklen > 128) {
|
||||
syslog(LOG_WARNING, "<%s> sum of rpu_uselen %d and"
|
||||
" rpu_keeplen %d is %d(over 128)",
|
||||
__func__, rpu->rpu_uselen,
|
||||
rpu->rpu_keeplen,
|
||||
rpu->rpu_uselen + rpu->rpu_keeplen);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_use_prefix(int len, struct rr_pco_match *rpm,
|
||||
struct in6_rrenumreq *irr, int ifindex)
|
||||
{
|
||||
struct rr_pco_use *rpu, *rpulim;
|
||||
struct rainfo *rai;
|
||||
struct prefix *pp;
|
||||
|
||||
rpu = (struct rr_pco_use *)(rpm + 1);
|
||||
rpulim = (struct rr_pco_use *)((char *)rpm + len);
|
||||
|
||||
if (rpu == rpulim) { /* no use prefix */
|
||||
if (rpm->rpm_code == RPM_PCO_ADD)
|
||||
return;
|
||||
|
||||
irr->irr_u_uselen = 0;
|
||||
irr->irr_u_keeplen = 0;
|
||||
irr->irr_raf_mask_onlink = 0;
|
||||
irr->irr_raf_mask_auto = 0;
|
||||
irr->irr_vltime = 0;
|
||||
irr->irr_pltime = 0;
|
||||
memset(&irr->irr_flags, 0, sizeof(irr->irr_flags));
|
||||
irr->irr_useprefix.sin6_len = 0; /* let it mean, no addition */
|
||||
irr->irr_useprefix.sin6_family = 0;
|
||||
irr->irr_useprefix.sin6_addr = in6addr_any;
|
||||
if (ioctl(s, rrcmd2pco[rpm->rpm_code], irr) < 0 &&
|
||||
errno != EADDRNOTAVAIL)
|
||||
syslog(LOG_ERR, "<%s> ioctl: %m", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (rpu = (struct rr_pco_use *)(rpm + 1),
|
||||
rpulim = (struct rr_pco_use *)((char *)rpm + len);
|
||||
rpu < rpulim;
|
||||
rpu += 1) {
|
||||
/* init in6_rrenumreq fields */
|
||||
irr->irr_u_uselen = rpu->rpu_uselen;
|
||||
irr->irr_u_keeplen = rpu->rpu_keeplen;
|
||||
irr->irr_raf_mask_onlink =
|
||||
!!(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK);
|
||||
irr->irr_raf_mask_auto =
|
||||
!!(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_AUTO);
|
||||
irr->irr_vltime = ntohl(rpu->rpu_vltime);
|
||||
irr->irr_pltime = ntohl(rpu->rpu_pltime);
|
||||
irr->irr_raf_onlink =
|
||||
(rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK) == 0 ? 0 : 1;
|
||||
irr->irr_raf_auto =
|
||||
(rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO) == 0 ? 0 : 1;
|
||||
irr->irr_rrf_decrvalid =
|
||||
(rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME) == 0 ? 0 : 1;
|
||||
irr->irr_rrf_decrprefd =
|
||||
(rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME) == 0 ? 0 : 1;
|
||||
irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix);
|
||||
irr->irr_useprefix.sin6_family = AF_INET6;
|
||||
irr->irr_useprefix.sin6_addr = rpu->rpu_prefix;
|
||||
|
||||
if (ioctl(s, rrcmd2pco[rpm->rpm_code], irr) < 0 &&
|
||||
errno != EADDRNOTAVAIL)
|
||||
syslog(LOG_ERR, "<%s> ioctl: %m", __func__);
|
||||
|
||||
/* very adhoc: should be rewritten */
|
||||
if (rpm->rpm_code == RPM_PCO_CHANGE &&
|
||||
IN6_ARE_ADDR_EQUAL(&rpm->rpm_prefix, &rpu->rpu_prefix) &&
|
||||
rpm->rpm_matchlen == rpu->rpu_uselen &&
|
||||
rpu->rpu_uselen == rpu->rpu_keeplen) {
|
||||
if ((rai = if_indextorainfo(ifindex)) == NULL)
|
||||
continue; /* non-advertising IF */
|
||||
|
||||
TAILQ_FOREACH(pp, &rai->prefix, next) {
|
||||
struct timespec now;
|
||||
|
||||
if (prefix_match(&pp->prefix, pp->prefixlen,
|
||||
&rpm->rpm_prefix,
|
||||
rpm->rpm_matchlen)) {
|
||||
/* change parameters */
|
||||
pp->validlifetime = ntohl(rpu->rpu_vltime);
|
||||
pp->preflifetime = ntohl(rpu->rpu_pltime);
|
||||
if (irr->irr_rrf_decrvalid) {
|
||||
clock_gettime(CLOCK_MONOTONIC,
|
||||
&now);
|
||||
pp->vltimeexpire =
|
||||
now.tv_sec + pp->validlifetime;
|
||||
} else
|
||||
pp->vltimeexpire = 0;
|
||||
if (irr->irr_rrf_decrprefd) {
|
||||
clock_gettime(CLOCK_MONOTONIC,
|
||||
&now);
|
||||
pp->pltimeexpire =
|
||||
now.tv_sec + pp->preflifetime;
|
||||
} else
|
||||
pp->pltimeexpire = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* process a Prefix Control Operation(PCO).
|
||||
* return 0 on success, 1 on failure
|
||||
*/
|
||||
static int
|
||||
do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm)
|
||||
{
|
||||
int ifindex = 0;
|
||||
struct in6_rrenumreq irr;
|
||||
struct rainfo *rai;
|
||||
|
||||
if ((rr_pco_check(len, rpm) != 0))
|
||||
return 1;
|
||||
|
||||
if (s == -1 && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
syslog(LOG_ERR, "<%s> socket: %m", __func__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&irr, 0, sizeof(irr));
|
||||
irr.irr_origin = PR_ORIG_RR;
|
||||
irr.irr_m_len = rpm->rpm_matchlen;
|
||||
irr.irr_m_minlen = rpm->rpm_minlen;
|
||||
irr.irr_m_maxlen = rpm->rpm_maxlen;
|
||||
irr.irr_matchprefix.sin6_len = sizeof(irr.irr_matchprefix);
|
||||
irr.irr_matchprefix.sin6_family = AF_INET6;
|
||||
irr.irr_matchprefix.sin6_addr = rpm->rpm_prefix;
|
||||
|
||||
/*
|
||||
* if ICMP6_RR_FLAGS_FORCEAPPLY(A flag) is 0 and IFF_UP is off,
|
||||
* the interface is not applied
|
||||
*/
|
||||
|
||||
if (rr->rr_flags & ICMP6_RR_FLAGS_FORCEAPPLY) {
|
||||
while (if_indextoname(++ifindex, irr.irr_name)) {
|
||||
rai = if_indextorainfo(ifindex);
|
||||
if (rai && (rai->ifflags & IFF_UP)) {
|
||||
/* TODO: interface scope check */
|
||||
do_use_prefix(len, rpm, &irr, ifindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errno == ENXIO)
|
||||
return 0;
|
||||
else if (errno) {
|
||||
syslog(LOG_ERR, "<%s> if_indextoname: %m", __func__);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* call do_pco() for each Prefix Control Operations(PCOs) in a received
|
||||
* Router Renumbering Command packet.
|
||||
* return 0 on success, 1 on failure
|
||||
*/
|
||||
static int
|
||||
do_rr(size_t len, struct icmp6_router_renum *rr)
|
||||
{
|
||||
struct rr_pco_match *rpm;
|
||||
char *cp, *lim;
|
||||
|
||||
lim = (char *)rr + len;
|
||||
cp = (char *)(rr + 1);
|
||||
len -= sizeof(struct icmp6_router_renum);
|
||||
|
||||
while (cp < lim) {
|
||||
size_t rpmlen;
|
||||
|
||||
rpm = (struct rr_pco_match *)cp;
|
||||
if (len < sizeof(struct rr_pco_match)) {
|
||||
tooshort:
|
||||
syslog(LOG_ERR, "<%s> pkt too short. left len = %zd. "
|
||||
"garbage at end of pkt?", __func__, len);
|
||||
return 1;
|
||||
}
|
||||
rpmlen = rpm->rpm_len << 3;
|
||||
if (len < rpmlen)
|
||||
goto tooshort;
|
||||
|
||||
if (do_pco(rr, rpmlen, rpm)) {
|
||||
syslog(LOG_WARNING, "<%s> invalid PCO", __func__);
|
||||
goto next;
|
||||
}
|
||||
|
||||
next:
|
||||
cp += rpmlen;
|
||||
len -= rpmlen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* check validity of a router renumbering command packet
|
||||
* return 0 on success, 1 on failure
|
||||
*/
|
||||
static int
|
||||
rr_command_check(size_t len, struct icmp6_router_renum *rr,
|
||||
struct in6_addr *from, struct in6_addr *dst)
|
||||
{
|
||||
char ntopbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
/* omit rr minimal length check. hope kernel have done it. */
|
||||
/* rr_command length check */
|
||||
if (len < (sizeof(struct icmp6_router_renum) +
|
||||
sizeof(struct rr_pco_match))) {
|
||||
syslog(LOG_ERR, "<%s> rr_command len %zd is too short",
|
||||
__func__, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* destination check. only for multicast. omit unicast check. */
|
||||
if (IN6_IS_ADDR_MULTICAST(dst) && !IN6_IS_ADDR_MC_LINKLOCAL(dst) &&
|
||||
!IN6_IS_ADDR_MC_SITELOCAL(dst)) {
|
||||
syslog(LOG_ERR, "<%s> dst mcast addr %s is illegal",
|
||||
__func__,
|
||||
inet_ntop(AF_INET6, dst, ntopbuf, INET6_ADDRSTRLEN));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* seqnum and segnum check */
|
||||
if (rro.rro_seqnum > rr->rr_seqnum) {
|
||||
syslog(LOG_WARNING,
|
||||
"<%s> rcvd old seqnum %d from %s",
|
||||
__func__, (uint32_t)ntohl(rr->rr_seqnum),
|
||||
inet_ntop(AF_INET6, from, ntopbuf, INET6_ADDRSTRLEN));
|
||||
return 1;
|
||||
}
|
||||
if (rro.rro_seqnum == rr->rr_seqnum &&
|
||||
(rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 &&
|
||||
RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) {
|
||||
if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0)
|
||||
syslog(LOG_WARNING,
|
||||
"<%s> rcvd duped segnum %d from %s",
|
||||
__func__, rr->rr_segnum,
|
||||
inet_ntop(AF_INET6, from, ntopbuf,
|
||||
INET6_ADDRSTRLEN));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* update seqnum */
|
||||
if (rro.rro_seqnum != rr->rr_seqnum) {
|
||||
/* then must be "<" */
|
||||
|
||||
/* init rro_segnum_bits */
|
||||
memset(rro.rro_segnum_bits, 0,
|
||||
sizeof(rro.rro_segnum_bits));
|
||||
}
|
||||
rro.rro_seqnum = rr->rr_seqnum;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
rr_command_input(int len, struct icmp6_router_renum *rr,
|
||||
struct in6_addr *from, struct in6_addr *dst)
|
||||
{
|
||||
/* rr_command validity check */
|
||||
if (rr_command_check(len, rr, from, dst))
|
||||
goto failed;
|
||||
if ((rr->rr_flags & (ICMP6_RR_FLAGS_TEST|ICMP6_RR_FLAGS_REQRESULT)) ==
|
||||
ICMP6_RR_FLAGS_TEST)
|
||||
return;
|
||||
|
||||
/* do router renumbering */
|
||||
if (do_rr(len, rr)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* update segnum */
|
||||
RR_SET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum);
|
||||
|
||||
return;
|
||||
|
||||
failed:
|
||||
syslog(LOG_ERR, "<%s> received RR was invalid", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
rr_input(size_t len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi,
|
||||
struct sockaddr_in6 *from, struct in6_addr *dst)
|
||||
{
|
||||
char ntopbuf[2][INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
|
||||
|
||||
syslog(LOG_DEBUG,
|
||||
"<%s> RR received from %s to %s on %s",
|
||||
__func__,
|
||||
inet_ntop(AF_INET6, &from->sin6_addr,
|
||||
ntopbuf[0], INET6_ADDRSTRLEN),
|
||||
inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
|
||||
/* packet validation based on Section 4.1 of RFC2894 */
|
||||
if (len < sizeof(struct icmp6_router_renum)) {
|
||||
syslog(LOG_NOTICE,
|
||||
"<%s>: RR short message (size %zd) from %s to %s on %s",
|
||||
__func__, len,
|
||||
inet_ntop(AF_INET6, &from->sin6_addr,
|
||||
ntopbuf[0], INET6_ADDRSTRLEN),
|
||||
inet_ntop(AF_INET6, &dst, ntopbuf[1], INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the IPv6 destination address is neither an All Routers multicast
|
||||
* address [AARCH] nor one of the receiving router's unicast addresses,
|
||||
* the message MUST be discarded and SHOULD be logged to network
|
||||
* management.
|
||||
* We rely on the kernel input routine for unicast addresses, and thus
|
||||
* check multicast destinations only.
|
||||
*/
|
||||
if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) &&
|
||||
!IN6_ARE_ADDR_EQUAL(&sin6_sitelocal_allrouters.sin6_addr,
|
||||
&pi->ipi6_addr))
|
||||
{
|
||||
syslog(LOG_NOTICE,
|
||||
"<%s>: RR message with invalid destination (%s) "
|
||||
"from %s on %s",
|
||||
__func__,
|
||||
inet_ntop(AF_INET6, &dst, ntopbuf[0], INET6_ADDRSTRLEN),
|
||||
inet_ntop(AF_INET6, &from->sin6_addr,
|
||||
ntopbuf[1], INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
rr_rcvifindex = pi->ipi6_ifindex;
|
||||
|
||||
switch (rr->rr_code) {
|
||||
case ICMP6_ROUTER_RENUMBERING_COMMAND:
|
||||
rr_command_input(len, rr, &from->sin6_addr, dst);
|
||||
/* TODO: send reply msg */
|
||||
break;
|
||||
case ICMP6_ROUTER_RENUMBERING_RESULT:
|
||||
/* RESULT will be processed by rrenumd */
|
||||
break;
|
||||
case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:
|
||||
/* TODO: sequence number reset */
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "<%s> received unknown code %d",
|
||||
__func__, rr->rr_code);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
34
usr.sbin/rtadvd/rrenum.h
Normal file
34
usr.sbin/rtadvd/rrenum.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* $NetBSD: rrenum.h,v 1.5 2011/12/10 19:14:29 roy Exp $ */
|
||||
/* $KAME: rrenum.h,v 1.3 2001/01/21 15:37:14 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
void rr_input(size_t, struct icmp6_router_renum *, struct in6_pktinfo *,
|
||||
struct sockaddr_in6 *, struct in6_addr *);
|
||||
216
usr.sbin/rtadvd/rtadvd.8
Normal file
216
usr.sbin/rtadvd/rtadvd.8
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
.\" $NetBSD: rtadvd.8,v 1.24 2012/12/13 21:49:38 wiz Exp $
|
||||
.\" $KAME: rtadvd.8,v 1.24 2002/05/31 16:16:08 jinmei Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the project nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd December 13, 2006
|
||||
.Dt RTADVD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rtadvd
|
||||
.Nd router advertisement daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl DdfRs
|
||||
.Op Fl c Ar configfile
|
||||
.Op Fl M Ar ifname
|
||||
.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.
|
||||
If an interface direct route is
|
||||
added on an advertising interface and no static prefixes are
|
||||
specified by the configuration file,
|
||||
.Nm
|
||||
adds the corresponding prefix to its advertising list.
|
||||
.Pp
|
||||
Similarly, when an interface direct route is deleted,
|
||||
.Nm
|
||||
will start advertising the prefixes with zero valid and preferred
|
||||
lifetimes to help the receiving hosts switch to a new prefix when
|
||||
renumbering.
|
||||
Note, however, that the zero valid lifetime cannot invalidate the
|
||||
autoconfigured addresses at a receiving host immediately.
|
||||
According to the specification, the host will retain the address
|
||||
for a certain period, which will typically be two hours.
|
||||
The zero lifetimes rather intend to make the address deprecated,
|
||||
indicating that a new non-deprecated address should be used as the
|
||||
source address of a new connection.
|
||||
This behavior will last for two hours.
|
||||
Then
|
||||
.Nm
|
||||
will completely remove the prefix from the advertising list,
|
||||
and succeeding advertisements will not contain the prefix information.
|
||||
.Pp
|
||||
Moreover, if the status of an advertising interface changes,
|
||||
.Nm
|
||||
will start or stop sending router advertisements according
|
||||
to the latest status.
|
||||
.Pp
|
||||
The
|
||||
.Fl s
|
||||
option may be used to disable this behavior;
|
||||
.Nm
|
||||
will not watch the routing table and the whole functionality described
|
||||
above will be suppressed.
|
||||
.Pp
|
||||
Basically, hosts MUST NOT send Router Advertisement messages at any
|
||||
time (RFC 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,
|
||||
.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
|
||||
Even more debugging information than that offered by the
|
||||
.Fl d
|
||||
option is printed.
|
||||
.It Fl d
|
||||
Print debugging information.
|
||||
.It Fl f
|
||||
Foreground mode (useful when debugging).
|
||||
Log messages will be dumped to stderr when this option is specified.
|
||||
.It Fl M Ar ifname
|
||||
Specify an interface to join the all-routers site-local multicast group.
|
||||
By default,
|
||||
.Nm
|
||||
tries to join the first advertising interface appearing on the command
|
||||
line.
|
||||
This option has meaning only with the
|
||||
.Fl R
|
||||
option, which enables routing renumbering protocol support.
|
||||
.\".It Fl m
|
||||
.\"Enables mobile IPv6 support.
|
||||
.\"This changes the content of router advertisement option, as well as
|
||||
.\"permitted configuration directives.
|
||||
.It Fl R
|
||||
Accept router renumbering requests.
|
||||
If you enable it, an
|
||||
.Xr ipsec 4
|
||||
setup is suggested for security reasons.
|
||||
.\"On KAME-based systems,
|
||||
.\".Xr rrenumd 8
|
||||
.\"generates router renumbering request packets.
|
||||
This option is currently disabled, and is ignored by
|
||||
.Nm
|
||||
with a warning message.
|
||||
.It Fl s
|
||||
Do not add or delete prefixes dynamically.
|
||||
Only statically configured prefixes, if any, will be advertised.
|
||||
.El
|
||||
.Pp
|
||||
Use
|
||||
.Dv SIGHUP
|
||||
to reload the configuration file
|
||||
.Pa /etc/rtadvd.conf .
|
||||
If an invalid parameter is found in the configuration file upon the reload, the
|
||||
entry will be ignored and the old configuration will be used.
|
||||
When parameters in an existing entry are updated,
|
||||
.Nm
|
||||
will send Router Advertisement messages with the old configuration but zero
|
||||
router lifetime to the interface first, and then start to send a new message.
|
||||
.Pp
|
||||
Upon receipt of signal
|
||||
.Dv SIGUSR1 ,
|
||||
.Nm
|
||||
will dump the current internal state into
|
||||
.Pa /var/run/rtadvd.dump .
|
||||
.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 2461 6.2.5 .
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/run/rtadvd.dumpXX -compact
|
||||
.It Pa /etc/rtadvd.conf
|
||||
The default configuration file.
|
||||
.It Pa /var/run/rtadvd.pid
|
||||
Contains the PID of the currently running
|
||||
.Nm .
|
||||
.It Pa /var/run/rtadvd.dump
|
||||
The file in which
|
||||
.Nm
|
||||
dumps its internal state.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std rtadvd
|
||||
.Sh SEE ALSO
|
||||
.Xr rtadvd.conf 5 ,
|
||||
.Xr rtsol 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.
|
||||
1820
usr.sbin/rtadvd/rtadvd.c
Normal file
1820
usr.sbin/rtadvd/rtadvd.c
Normal file
File diff suppressed because it is too large
Load Diff
21
usr.sbin/rtadvd/rtadvd.conf
Normal file
21
usr.sbin/rtadvd/rtadvd.conf
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# $NetBSD: rtadvd.conf,v 1.4 2009/11/01 15:17:59 jakllsch Exp $
|
||||
# $KAME: rtadvd.conf,v 1.13 2003/06/25 03:45:21 itojun Exp $
|
||||
#
|
||||
# Note: All of the following parameters have default values defined
|
||||
# in specifications, and hence you usually do not have to set them
|
||||
# by hand unless you need special non-default values.
|
||||
#
|
||||
# You even do not need to create the configuration file. rtadvd
|
||||
# would usually work well without a configuration file.
|
||||
# See also: rtadvd(8)
|
||||
|
||||
# per-interface definitions.
|
||||
# Mainly IPv6 prefixes are configured in this part. However, rtadvd
|
||||
# automatically learns appropriate prefixes from the kernel's routing
|
||||
# table, and advertises the prefixes, so you don't have to configure
|
||||
# this part, either.
|
||||
# If you don't want the automatic advertisement, (uncomment and) configure
|
||||
# this part by hand, and then invoke rtadvd with the -s option.
|
||||
|
||||
#ef0:\
|
||||
# :addr="2001:db8:ffff:1000::":prefixlen#64:
|
||||
497
usr.sbin/rtadvd/rtadvd.conf.5
Normal file
497
usr.sbin/rtadvd/rtadvd.conf.5
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
.\" $NetBSD: rtadvd.conf.5,v 1.18 2012/12/11 16:37:23 roy Exp $
|
||||
.\" $KAME: rtadvd.conf.5,v 1.50 2005/01/14 05:30:59 jinmei Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the project nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd December 11, 2012
|
||||
.Dt RTADVD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rtadvd.conf
|
||||
.Nd config file for router advertisement daemon
|
||||
.Sh DESCRIPTION
|
||||
This file describes how the router advertisement packets must be constructed
|
||||
for each of the interfaces.
|
||||
.Pp
|
||||
As described in
|
||||
.Xr rtadvd 8 ,
|
||||
you do not have to set this configuration file up at all,
|
||||
unless you need some special configurations.
|
||||
You may even omit the file as a whole.
|
||||
In such cases, the
|
||||
.Nm rtadvd
|
||||
daemon will automatically configure itself using default values
|
||||
specified in the specification.
|
||||
.Pp
|
||||
It obeys the famous
|
||||
.Xr capfile 5
|
||||
file format.
|
||||
Each line in the file describes a network interface.
|
||||
Fields are separated by a colon
|
||||
.Pq Sq \&: ,
|
||||
and each field contains one capability description.
|
||||
Lines may be concatenated by the
|
||||
.Sq \e
|
||||
character.
|
||||
The comment marker is the
|
||||
.Sq \&#
|
||||
character.
|
||||
.Sh CAPABILITIES
|
||||
Capabilities describe the value to be filled into ICMPv6 router
|
||||
advertisement messages and to control
|
||||
.Xr rtadvd 8
|
||||
behavior.
|
||||
Therefore, you are encouraged to read IETF neighbor discovery documents
|
||||
if you would like to modify the sample configuration file.
|
||||
.Pp
|
||||
Note that almost all items have default values.
|
||||
If you omit an item, the default value of the item will be used.
|
||||
.Pp
|
||||
There are two items which control the interval of sending router advertisements.
|
||||
These items can be omitted, then
|
||||
.Nm rtadvd
|
||||
will use the default values.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&maxinterval
|
||||
(num) The maximum time allowed between sending unsolicited
|
||||
multicast router advertisements
|
||||
.Pq unit: seconds .
|
||||
The default value is 600.
|
||||
Its value must be no less than 4 seconds
|
||||
and no greater than 1800 seconds.
|
||||
.It Cm \&mininterval
|
||||
(num) The minimum time allowed between sending unsolicited multicast
|
||||
router advertisements
|
||||
.Pq unit: seconds .
|
||||
The default value is the one third of value of
|
||||
.Cm maxinterval .
|
||||
Its value must be no less than 3 seconds and no greater than .75 *
|
||||
the value of
|
||||
.Cm maxinterval .
|
||||
.El
|
||||
.Pp
|
||||
The following items are for ICMPv6 router advertisement message
|
||||
header.
|
||||
These items can be omitted, then
|
||||
.Nm rtadvd
|
||||
will use the default values.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&chlim
|
||||
(num) The value for Cur Hop Limit field.
|
||||
The default value is 64.
|
||||
.It Cm \&raflags
|
||||
(str or num) A 8-bit flags field in router advertisement message header.
|
||||
This field can be specified either as a case-sensitive string or as an
|
||||
integer.
|
||||
A sting consists of characters each of which corresponds to a
|
||||
particular flag bit(s).
|
||||
An integer should be the logical OR of all enabled bits.
|
||||
Bit 7
|
||||
.Po
|
||||
.Li 'm' or 0x80
|
||||
.Pc
|
||||
means Managed address configuration flag bit,
|
||||
and Bit 6
|
||||
.Po
|
||||
.Li 'o' or 0x40
|
||||
.Pc
|
||||
means Other stateful configuration flag bit.
|
||||
Bit 4
|
||||
.Po
|
||||
.Li 0x10
|
||||
.Pc
|
||||
and Bit 3
|
||||
.Po
|
||||
.Li 0x08
|
||||
.Pc
|
||||
are used to encode router preference.
|
||||
Bits 01
|
||||
.Po
|
||||
or 'h'
|
||||
.Pc
|
||||
means high, 00 means medium, and 11
|
||||
.Po
|
||||
or 'l'
|
||||
.Pc
|
||||
means low.
|
||||
Bits 10 is reserved, and must not be specified.
|
||||
There is no character to specify the medium preference explicitly.
|
||||
The default value of the entire flag is 0
|
||||
.Po
|
||||
or a null string,
|
||||
.Pc
|
||||
which means no additional
|
||||
configuration methods, and the medium router preference.
|
||||
.It Cm \&rltime
|
||||
(num) Router lifetime field
|
||||
.Pq unit: seconds .
|
||||
The value must be either zero or between
|
||||
the value of
|
||||
.Cm maxinterval
|
||||
and 9000.
|
||||
When
|
||||
.Nm rtadvd
|
||||
runs on a host, this value must explicitly set 0 on all the
|
||||
advertising interfaces as described in
|
||||
.Xr rtadvd 8 .
|
||||
The default value is 1800.
|
||||
.It Cm \&rtime
|
||||
(num) Reachable time field
|
||||
.Pq unit: milliseconds .
|
||||
The default value is 0, which means unspecified by this router.
|
||||
.It Cm \&retrans
|
||||
(num) Retrans Timer field
|
||||
.Pq unit: milliseconds .
|
||||
The default value is 0, which means unspecified by this router.
|
||||
.El
|
||||
.Pp
|
||||
The following items are for ICMPv6 prefix information option,
|
||||
which will be attached to router advertisement header.
|
||||
These items can be omitted, then
|
||||
.Nm rtadvd
|
||||
will automatically get appropriate prefixes from the kernel's routing table,
|
||||
and advertise the prefixes with the default parameters, unless the
|
||||
.Cm noifprefix
|
||||
flag is specified.
|
||||
Keywords other than
|
||||
.Cm clockskew
|
||||
and
|
||||
.Cm noifprefix
|
||||
can be augmented with a number, like
|
||||
.Dq Li prefix2 ,
|
||||
to specify multiple prefixes.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&noifprefix
|
||||
(bool) Specified 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 \&clockskew
|
||||
(num) Time skew to adjust link propagation delays and clock skews
|
||||
between routers on the link
|
||||
.Pq unit: seconds .
|
||||
This value is used in consistency check for locally-configured and
|
||||
advertised prefix lifetimes, and has its meaning when the local router
|
||||
configures a prefix on the link with a lifetime that decrements in
|
||||
real time.
|
||||
If the value is 0, it means the consistency check will be skipped
|
||||
for such prefixes.
|
||||
The default value is 0.
|
||||
.It Cm \&prefixlen
|
||||
(num) Prefix length field.
|
||||
The default value is 64.
|
||||
.It Cm \&pinfoflags
|
||||
(str or num) A 8-bit flags field in prefix information option.
|
||||
This field can be specified either as a case-sensitive string or as an
|
||||
integer.
|
||||
A sting consists of characters each of which corresponds to a
|
||||
particular flag bit(s).
|
||||
An integer should be the logical OR of all enabled bits.
|
||||
Bit 7
|
||||
.Po
|
||||
.Li 'l' or 0x80
|
||||
.Pc
|
||||
means On-link flag bit,
|
||||
and Bit 6
|
||||
.Po
|
||||
.Li 'a' or 0x40
|
||||
.Pc
|
||||
means Autonomous address-configuration flag bit.
|
||||
The default value is "la" or 0xc0, i.e., both bits are set.
|
||||
.It Cm \&addr
|
||||
(str) The address filled into Prefix field.
|
||||
Since
|
||||
.Dq \&:
|
||||
is used for
|
||||
.Xr capfile 5
|
||||
file format as well as IPv6 numeric address, the field MUST be quoted by
|
||||
doublequote character.
|
||||
.It Cm \&vltime
|
||||
(num) Valid lifetime field
|
||||
.Pq unit: seconds .
|
||||
The default value is 2592000 (30 days).
|
||||
.It Cm \&vltimedecr
|
||||
(bool) This item means the advertised valid lifetime will decrement
|
||||
in real time, which is disabled by default.
|
||||
.It Cm \&pltime
|
||||
(num) Preferred lifetime field
|
||||
.Pq unit: seconds .
|
||||
The default value is 604800 (7 days).
|
||||
.It Cm \&pltimedecr
|
||||
(bool) This item means the advertised preferred lifetime will decrement
|
||||
in real time, which is disabled by default.
|
||||
.El
|
||||
.Pp
|
||||
The following item is for ICMPv6 MTU option,
|
||||
which will be attached to router advertisement header.
|
||||
This item can be omitted, then
|
||||
.Nm rtadvd
|
||||
will use the default value.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&mtu
|
||||
(num or str) MTU (maximum transmission unit) field.
|
||||
If 0 is specified, it means that the option will not be included.
|
||||
The default value is 0.
|
||||
If the special string
|
||||
.Dq auto
|
||||
is specified for this item, MTU option will be included and its value
|
||||
will be set to the interface MTU automatically.
|
||||
.El
|
||||
.Pp
|
||||
The following item controls ICMPv6 source link-layer address option,
|
||||
which will be attached to router advertisement header.
|
||||
As noted above, you can just omit the item, then
|
||||
.Nm rtadvd
|
||||
will use the default value.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&nolladdr
|
||||
(bool) By default
|
||||
.Po
|
||||
if
|
||||
.Cm \&nolladdr
|
||||
is not specified
|
||||
.Pc ,
|
||||
.Xr rtadvd 8
|
||||
will try to get link-layer address for the interface from the kernel,
|
||||
and attach that in source link-layer address option.
|
||||
If this capability exists,
|
||||
.Xr rtadvd 8
|
||||
will not attach source link-layer address option to
|
||||
router advertisement packets.
|
||||
.El
|
||||
.Pp
|
||||
The following items are for ICMPv6 route information option,
|
||||
which will be attached to router advertisement header.
|
||||
These items are optional.
|
||||
Each items can be augmented with number, like
|
||||
.Dq Li rtplen2 ,
|
||||
to specify multiple routes.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&rtprefix
|
||||
(str) The prefix filled into the Prefix field of route information option.
|
||||
Since
|
||||
.Dq \&:
|
||||
is used for
|
||||
.Xr capfile 5
|
||||
file format as well as IPv6 numeric address, the field MUST be quoted by
|
||||
doublequote character.
|
||||
.It Cm \&rtplen
|
||||
(num) Prefix length field in route information option.
|
||||
The default value is 64.
|
||||
.It Cm \&rtflags
|
||||
(str or num) A 8-bit flags field in route information option.
|
||||
Currently only the preference values are defined.
|
||||
The notation is same as that of the raflags field.
|
||||
Bit 4
|
||||
.Po
|
||||
.Li 0x10
|
||||
.Pc
|
||||
and Bit 3
|
||||
.Po
|
||||
.Li 0x08
|
||||
.Pc
|
||||
are used to encode the route preference for the route.
|
||||
The default value is 0x00, i.e. medium preference.
|
||||
.It Cm \&rtltime
|
||||
(num) route lifetime field in route information option.
|
||||
.Pq unit: seconds .
|
||||
Since the specification does not define the default value of this
|
||||
item, the value for this item should be specified by hand.
|
||||
However,
|
||||
.Nm rtadvd
|
||||
allows this item to be unspecified, and uses the router lifetime
|
||||
as the default value in such a case, just for compatibility with an
|
||||
old version of the program.
|
||||
.El
|
||||
.Pp
|
||||
In the above list, each keyword beginning with
|
||||
.Dq Li rt
|
||||
could be replaced with the one beginning with
|
||||
.Dq Li rtr
|
||||
for backward compatibility reason.
|
||||
For example,
|
||||
.Cm rtrplen
|
||||
is accepted instead of
|
||||
.Cm rtplen .
|
||||
However, keywords that start with
|
||||
.Dq Li rtr
|
||||
have basically been obsoleted, and should not be used any more.
|
||||
.Pp
|
||||
The following items are for ICMPv6 Recursive DNS Server Option and
|
||||
DNS Search List Option
|
||||
.Pq RFC 6106 ,
|
||||
which will be attached to router advertisement header.
|
||||
These items are optional.
|
||||
.Bl -tag -width indent
|
||||
.It Cm \&rdnss
|
||||
(str) The IPv6 address of one or more recursive DNS servers.
|
||||
The argument must be inside double quotes.
|
||||
Multiple DNS servers can be specified in a comma-separated string.
|
||||
If different lifetimes are needed for different servers,
|
||||
separate entries can be given by using
|
||||
.Cm rdnss ,
|
||||
.Cm rdnss0 ,
|
||||
.Cm rdnss1 ,
|
||||
.Cm rdnss2 ...
|
||||
options with corresponding
|
||||
.Cm rdnssltime ,
|
||||
.Cm rdnssltime0 ,
|
||||
.Cm rdnssltime1 ,
|
||||
.Cm rdnssltime2 ...
|
||||
entries.
|
||||
Note that the maximum number of servers depends on the receiver side.
|
||||
See also the
|
||||
.Xr resolv.conf 5
|
||||
manual page for the resolver implementation.
|
||||
.It Cm \&rdnssltime
|
||||
The lifetime of the
|
||||
.Cm rdnss
|
||||
DNS server entries.
|
||||
The default value is 3/2 of the interval time.
|
||||
.It Cm \&dnssl
|
||||
(str) One or more domain names in a comma-separated string.
|
||||
These domain names will be used when making DNS queries on a
|
||||
non-fully-qualified domain name.
|
||||
If different lifetimes are needed for different domains, separate entries
|
||||
can be given by using
|
||||
.Cm dnssl ,
|
||||
.Cm dnssl0 ,
|
||||
.Cm dnssl1 ,
|
||||
.Cm dnssl2 ...
|
||||
options with corresponding
|
||||
.Cm dnsslltime ,
|
||||
.Cm dnsslltime0 ,
|
||||
.Cm dnsslltime1 ,
|
||||
.Cm dnsslltime2 ...
|
||||
entries.
|
||||
Note that the maximum number of names depends on the receiver side.
|
||||
See also the
|
||||
.Xr resolv.conf 5
|
||||
manual page for the resolver implementation.
|
||||
.It Cm \&dnsslltime
|
||||
The lifetime of the
|
||||
.Cm dnssl
|
||||
DNS search list entries.
|
||||
The default value is 3/2 of the interval time.
|
||||
.El
|
||||
.Pp
|
||||
You can also refer one line from another by using
|
||||
.Cm tc
|
||||
capability.
|
||||
See
|
||||
.Xr capfile 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
|
||||
ne0:\\
|
||||
:rltime#0:
|
||||
.Ed
|
||||
.Pp
|
||||
The following example manually configures prefixes advertised from the
|
||||
.Li ef0
|
||||
interface.
|
||||
The configuration must be used with the
|
||||
.Fl s
|
||||
option to
|
||||
.Xr rtadvd 8 .
|
||||
.Bd -literal
|
||||
ef0:\\
|
||||
:addr="2001:db8:ffff:1000::":prefixlen#64:
|
||||
.Ed
|
||||
.Pp
|
||||
The following example configures the
|
||||
.Li wlan0
|
||||
interface and adds two DNS servers and a DNS domain search options
|
||||
using the default option lifetime values.
|
||||
.Bd -literal -offset
|
||||
wlan0:\\
|
||||
:addr="2001:db8:ffff:1000::":prefixlen#64:\\
|
||||
:rdnss="2001:db8:ffff::10,2001:db8:ffff::2:43":\\
|
||||
:dnssl="example.com":
|
||||
.Ed
|
||||
.Pp
|
||||
The following example presents the default values in an explicit manner.
|
||||
The configuration is provided just for reference purposes;
|
||||
YOU DO NOT NEED TO HAVE IT AT ALL.
|
||||
.Bd -literal
|
||||
default:\\
|
||||
:chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\\
|
||||
:pinfoflags="la":vltime#2592000:pltime#604800:mtu#0:
|
||||
ef0:\\
|
||||
:addr="2001:db8:ffff:1000::":prefixlen#64:tc=default:
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr capfile 5 ,
|
||||
.Xr rtadvd 8 ,
|
||||
.Xr rtsol 8
|
||||
.Pp
|
||||
Thomas Narten, Erik Nordmark and W. A. Simpson,
|
||||
.Do
|
||||
Neighbor Discovery for IP version 6 (IPv6)
|
||||
.Dc ,
|
||||
RFC 2461
|
||||
.Pp
|
||||
Richard Draves,
|
||||
.Do
|
||||
Default Router Preferences and More-Specific Routes
|
||||
.Dc ,
|
||||
RFC 4191
|
||||
.Pp
|
||||
J. Jeong, S. Park, L. Beloeil, S. Madanapalli
|
||||
.Do
|
||||
IPv6 Router Advertisement Options for DNS Configuration
|
||||
.Dc ,
|
||||
RFC 6106
|
||||
.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)
|
||||
196
usr.sbin/rtadvd/rtadvd.h
Normal file
196
usr.sbin/rtadvd/rtadvd.h
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/* $NetBSD: rtadvd.h,v 1.14 2015/06/05 14:09:20 roy Exp $ */
|
||||
/* $KAME: rtadvd.h,v 1.30 2005/10/17 14:40:02 suz 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"
|
||||
#define ALLROUTERS_SITE "ff05::2"
|
||||
|
||||
#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT \
|
||||
{{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
|
||||
|
||||
//extern struct sockaddr_in6 sin6_linklocal_allnodes;
|
||||
//extern struct sockaddr_in6 sin6_linklocal_allrouters;
|
||||
extern struct sockaddr_in6 sin6_sitelocal_allrouters;
|
||||
|
||||
/* protocol constants and default values */
|
||||
#define DEF_MAXRTRADVINTERVAL 600
|
||||
#define DEF_ADVLINKMTU 0
|
||||
#define DEF_ADVREACHABLETIME 0
|
||||
#define DEF_ADVRETRANSTIMER 0
|
||||
#define DEF_ADVCURHOPLIMIT 64
|
||||
#define DEF_ADVVALIDLIFETIME 2592000
|
||||
#define DEF_ADVPREFERREDLIFETIME 604800
|
||||
|
||||
#define MAXROUTERLIFETIME 9000
|
||||
#define MIN_MAXINTERVAL 4
|
||||
#define MAX_MAXINTERVAL 1800
|
||||
#define MIN_MININTERVAL 3
|
||||
#define MAXREACHABLETIME 3600000
|
||||
|
||||
#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16
|
||||
#define MAX_INITIAL_RTR_ADVERTISEMENTS 3
|
||||
#define MAX_FINAL_RTR_ADVERTISEMENTS 3
|
||||
#define MIN_DELAY_BETWEEN_RAS 3
|
||||
#define MAX_RA_DELAY_TIME 500000000 /* nsec */
|
||||
|
||||
#define PREFIX_FROM_KERNEL 1
|
||||
#define PREFIX_FROM_CONFIG 2
|
||||
#define PREFIX_FROM_DYNAMIC 3
|
||||
|
||||
struct prefix {
|
||||
TAILQ_ENTRY(prefix) next;
|
||||
|
||||
struct rainfo *rainfo; /* back pointer to the interface */
|
||||
|
||||
struct rtadvd_timer *timer; /* expiration timer. used when a prefix
|
||||
* derived from the kernel is deleted.
|
||||
*/
|
||||
|
||||
uint32_t validlifetime; /* AdvValidLifetime */
|
||||
long vltimeexpire; /* expiration of vltime; decrement case only */
|
||||
uint32_t preflifetime; /* AdvPreferredLifetime */
|
||||
long pltimeexpire; /* expiration of pltime; decrement case only */
|
||||
uint16_t onlinkflg; /* bool: AdvOnLinkFlag */
|
||||
uint16_t autoconfflg; /* bool: AdvAutonomousFlag */
|
||||
int prefixlen;
|
||||
int origin; /* from kernel or config */
|
||||
struct in6_addr prefix;
|
||||
};
|
||||
|
||||
struct rtinfo {
|
||||
TAILQ_ENTRY(rtinfo) next;
|
||||
|
||||
uint32_t ltime; /* route lifetime */
|
||||
uint16_t rtpref; /* route preference */
|
||||
int prefixlen;
|
||||
struct in6_addr prefix;
|
||||
};
|
||||
|
||||
struct rdnss_addr {
|
||||
TAILQ_ENTRY(rdnss_addr) next;
|
||||
|
||||
struct in6_addr addr;
|
||||
};
|
||||
|
||||
struct rdnss {
|
||||
TAILQ_ENTRY(rdnss) next;
|
||||
|
||||
TAILQ_HEAD(, rdnss_addr) list;
|
||||
uint32_t lifetime;
|
||||
};
|
||||
|
||||
struct dnssl_domain {
|
||||
TAILQ_ENTRY(dnssl_domain) next;
|
||||
|
||||
int len;
|
||||
char domain[256];
|
||||
};
|
||||
|
||||
struct dnssl {
|
||||
TAILQ_ENTRY(dnssl) next;
|
||||
|
||||
TAILQ_HEAD(, dnssl_domain) list;
|
||||
uint32_t lifetime;
|
||||
};
|
||||
|
||||
struct soliciter {
|
||||
TAILQ_ENTRY(soliciter) next;
|
||||
|
||||
struct sockaddr_in6 addr;
|
||||
};
|
||||
|
||||
struct rainfo {
|
||||
TAILQ_ENTRY(rainfo) next;
|
||||
|
||||
/* timer related parameters */
|
||||
struct rtadvd_timer *timer;
|
||||
int initcounter; /* counter for the first few advertisements */
|
||||
struct timespec lastsent; /* timestamp when the latest RA was sent */
|
||||
int waiting; /* number of RS waiting for RA */
|
||||
struct rainfo *leaving; /* the config which is leaving */
|
||||
struct rainfo *leaving_for; /* the new config to activate */
|
||||
int leaving_adv; /* number of RA left to send */
|
||||
|
||||
/* interface information */
|
||||
uint16_t ifindex;
|
||||
int ifflags;
|
||||
int advlinkopt; /* bool: whether include link-layer addr opt */
|
||||
struct sockaddr_dl *sdl;
|
||||
char ifname[16];
|
||||
uint32_t phymtu; /* mtu of the physical interface */
|
||||
|
||||
/* Router configuration variables */
|
||||
uint16_t lifetime; /* AdvDefaultLifetime */
|
||||
uint16_t maxinterval; /* MaxRtrAdvInterval */
|
||||
uint16_t mininterval; /* MinRtrAdvInterval */
|
||||
int managedflg; /* AdvManagedFlag */
|
||||
int otherflg; /* AdvOtherConfigFlag */
|
||||
|
||||
int rtpref; /* router preference */
|
||||
uint32_t linkmtu; /* AdvLinkMTU */
|
||||
uint32_t reachabletime; /* AdvReachableTime */
|
||||
uint32_t retranstimer; /* AdvRetransTimer */
|
||||
uint16_t hoplimit; /* AdvCurHopLimit */
|
||||
TAILQ_HEAD(, prefix) prefix; /* AdvPrefixList(link head) */
|
||||
int pfxs;
|
||||
uint16_t clockskew;/* used for consisitency check of lifetimes */
|
||||
|
||||
TAILQ_HEAD(, rtinfo) route;
|
||||
TAILQ_HEAD(, rdnss) rdnss; /* RDNSS list */
|
||||
TAILQ_HEAD(, dnssl) dnssl; /* DNS Search List */
|
||||
|
||||
/* actual RA packet data and its length */
|
||||
size_t ra_datalen;
|
||||
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 */
|
||||
|
||||
/* info about soliciter */
|
||||
TAILQ_HEAD(, soliciter) soliciter; /* recent solication source */
|
||||
};
|
||||
|
||||
extern TAILQ_HEAD(ralist_head_t, rainfo) ralist;
|
||||
|
||||
struct rtadvd_timer *ra_timeout(void *);
|
||||
void ra_timer_update(void *, struct timespec *);
|
||||
void ra_timer_set_short_delay(struct rainfo *);
|
||||
|
||||
int prefix_match(struct in6_addr *, int, struct in6_addr *, int);
|
||||
struct rainfo *if_indextorainfo(unsigned int);
|
||||
struct prefix *find_prefix(struct rainfo *, struct in6_addr *, int);
|
||||
168
usr.sbin/rtadvd/timer.c
Normal file
168
usr.sbin/rtadvd/timer.c
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/* $NetBSD: timer.c,v 1.12 2015/06/05 14:09:20 roy Exp $ */
|
||||
/* $KAME: timer.c,v 1.11 2005/04/14 06:22:35 suz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <search.h>
|
||||
#include "timer.h"
|
||||
|
||||
struct rtadvd_timer_head_t ra_timer = TAILQ_HEAD_INITIALIZER(ra_timer);
|
||||
static struct timespec tm_limit = { LONG_MAX, 1000000000L - 1 };
|
||||
static struct timespec tm_max;
|
||||
|
||||
void
|
||||
rtadvd_timer_init(void)
|
||||
{
|
||||
|
||||
TAILQ_INIT(&ra_timer);
|
||||
tm_max = tm_limit;
|
||||
}
|
||||
|
||||
struct rtadvd_timer *
|
||||
rtadvd_add_timer(struct rtadvd_timer *(*timeout) (void *),
|
||||
void (*update) (void *, struct timespec *),
|
||||
void *timeodata, void *updatedata)
|
||||
{
|
||||
struct rtadvd_timer *newtimer;
|
||||
|
||||
if ((newtimer = malloc(sizeof(*newtimer))) == NULL) {
|
||||
syslog(LOG_ERR,
|
||||
"<%s> can't allocate memory", __func__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(newtimer, 0, sizeof(*newtimer));
|
||||
|
||||
if (timeout == NULL) {
|
||||
syslog(LOG_ERR,
|
||||
"<%s> timeout function unspecified", __func__);
|
||||
exit(1);
|
||||
}
|
||||
newtimer->expire = timeout;
|
||||
newtimer->update = update;
|
||||
newtimer->expire_data = timeodata;
|
||||
newtimer->update_data = updatedata;
|
||||
newtimer->tm = tm_max;
|
||||
|
||||
/* link into chain */
|
||||
TAILQ_INSERT_TAIL(&ra_timer, newtimer, next);
|
||||
|
||||
return(newtimer);
|
||||
}
|
||||
|
||||
void
|
||||
rtadvd_remove_timer(struct rtadvd_timer **timer)
|
||||
{
|
||||
|
||||
if (*timer) {
|
||||
TAILQ_REMOVE(&ra_timer, *timer, next);
|
||||
free(*timer);
|
||||
*timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtadvd_set_timer(struct timespec *tm, struct rtadvd_timer *timer)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
/* reset the timer */
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
timespecadd(&now, tm, &timer->tm);
|
||||
|
||||
/* upate the next expiration time */
|
||||
if (timespeccmp(&timer->tm, &tm_max, <))
|
||||
tm_max = timer->tm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check expiration for each timer. If a timer expires,
|
||||
* call the expire function for the timer and update the timer.
|
||||
* Return the next interval for select() call.
|
||||
*/
|
||||
struct timespec *
|
||||
rtadvd_check_timer(void)
|
||||
{
|
||||
static struct timespec returnval;
|
||||
struct timespec now;
|
||||
struct rtadvd_timer *tm, *tmn;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
tm_max = tm_limit;
|
||||
|
||||
TAILQ_FOREACH_SAFE(tm, &ra_timer, next, tmn) {
|
||||
if (timespeccmp(&tm->tm, &now, <=)) {
|
||||
if ((*tm->expire)(tm->expire_data) == NULL)
|
||||
continue; /* the timer was removed */
|
||||
if (tm->update)
|
||||
(*tm->update)(tm->update_data, &tm->tm);
|
||||
timespecadd(&tm->tm, &now, &tm->tm);
|
||||
}
|
||||
if (timespeccmp(&tm->tm, &tm_max, <))
|
||||
tm_max = tm->tm;
|
||||
}
|
||||
|
||||
if (timespeccmp(&tm_max, &tm_limit, ==))
|
||||
return(NULL);
|
||||
if (timespeccmp(&tm_max, &now, <)) {
|
||||
/* this may occur when the interval is too small */
|
||||
timespecclear(&returnval);
|
||||
} else
|
||||
timespecsub(&tm_max, &now, &returnval);
|
||||
return(&returnval);
|
||||
}
|
||||
|
||||
struct timespec *
|
||||
rtadvd_timer_rest(struct rtadvd_timer *timer)
|
||||
{
|
||||
static struct timespec returnval;
|
||||
struct timespec now;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
if (timespeccmp(&timer->tm, &now, <=)) {
|
||||
syslog(LOG_DEBUG,
|
||||
"<%s> a timer must be expired, but not yet",
|
||||
__func__);
|
||||
returnval.tv_sec = 0;
|
||||
returnval.tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
timespecsub(&timer->tm, &now, &returnval);
|
||||
|
||||
return(&returnval);
|
||||
}
|
||||
51
usr.sbin/rtadvd/timer.h
Normal file
51
usr.sbin/rtadvd/timer.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* $NetBSD: timer.h,v 1.8 2015/06/05 14:09:20 roy Exp $ */
|
||||
/* $KAME: timer.h,v 1.5 2002/05/31 13:30:38 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
extern TAILQ_HEAD(rtadvd_timer_head_t, rtadvd_timer) ra_timer;
|
||||
struct rtadvd_timer {
|
||||
TAILQ_ENTRY(rtadvd_timer) next;
|
||||
struct rainfo *rai;
|
||||
struct timespec tm;
|
||||
|
||||
struct rtadvd_timer *(*expire) (void *); /* expiration function */
|
||||
void *expire_data;
|
||||
void (*update)(void *, struct timespec *); /* update function */
|
||||
void *update_data;
|
||||
};
|
||||
|
||||
void rtadvd_timer_init(void);
|
||||
struct rtadvd_timer *rtadvd_add_timer(struct rtadvd_timer *(*) (void *),
|
||||
void (*) (void *, struct timespec *), void *, void *);
|
||||
void rtadvd_set_timer(struct timespec *, struct rtadvd_timer *);
|
||||
void rtadvd_remove_timer(struct rtadvd_timer **);
|
||||
struct timespec * rtadvd_check_timer(void);
|
||||
struct timespec * rtadvd_timer_rest(struct rtadvd_timer *);
|
||||
Loading…
Reference in New Issue
Block a user