add -a flag: automatically probe an interface, works only if there's

only single external non-p2p interface.  idea from thopej.
$KAME$.

(sync with kame)
This commit is contained in:
itojun 2000-08-13 06:20:02 +00:00
parent 4915bd101e
commit ba6d02ed0c
7 changed files with 178 additions and 47 deletions

View File

@ -1,4 +1,5 @@
/* $NetBSD: dump.c,v 1.2 2000/02/25 09:19:07 itojun Exp $ */
/* $NetBSD: dump.c,v 1.3 2000/08/13 06:20:02 itojun Exp $ */
/* $KAME: dump.c,v 1.7 2000/08/13 06:14:59 itojun Exp $ */
/*
* Copyright (C) 1999 WIDE Project.

View File

@ -1,4 +1,5 @@
/* $NetBSD: if.c,v 1.5 2000/02/25 09:19:07 itojun Exp $ */
/* $NetBSD: if.c,v 1.6 2000/08/13 06:20:02 itojun Exp $ */
/* $KAME: if.c,v 1.13 2000/08/13 06:14:59 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -33,6 +34,7 @@
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <sys/queue.h>
#include <net/if.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3

View File

@ -1,4 +1,5 @@
/* $NetBSD: probe.c,v 1.4 2000/02/28 07:20:43 itojun Exp $ */
/* $NetBSD: probe.c,v 1.5 2000/08/13 06:20:02 itojun Exp $ */
/* $KAME: probe.c,v 1.10 2000/08/13 06:14:59 itojun Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@ -34,6 +35,7 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/queue.h>
#include <net/if.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3

View File

@ -1,4 +1,5 @@
/* $NetBSD: rtsol.c,v 1.6 2000/02/28 07:20:44 itojun Exp $ */
/* $NetBSD: rtsol.c,v 1.7 2000/08/13 06:20:03 itojun Exp $ */
/* $KAME: rtsol.c,v 1.11 2000/08/13 06:14:59 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -33,6 +34,7 @@
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <net/if.h>
#include <net/route.h>

View File

@ -1,6 +1,9 @@
.\" $NetBSD: rtsold.8,v 1.8 2000/08/13 06:20:03 itojun Exp $
.\" $KAME: rtsold.8,v 1.12 2000/08/13 06:17:59 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:
@ -12,7 +15,7 @@
.\" 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
@ -25,9 +28,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $NetBSD: rtsold.8,v 1.7 2000/01/02 06:30:15 itojun Exp $
.\" KAME Id: rtsold.8,v 1.8 2000/01/02 06:25:14 itojun Exp
.\"
.Dd May 17, 1998
.Dt RTSOLD 8
.Os
@ -40,12 +40,18 @@
.Nm
.Op Fl dDfm1
.Ar interface ...
.Nm ""
.Op Fl dDfm1
.Fl a
.Nm rtsol
.Op Fl dD
.Ar interface ...
.Nm rtsol
.Op Fl dD
.Fl a
.\"
.Sh DESCRIPTION
.Nm Rtsold
.Nm
is the daemon program to send ICMPv6 Router Solicitation messages
on the specified interfaces.
If a node (re)attaches to a link,
@ -80,7 +86,7 @@ Just after invocation of
daemon.
.It
The interface is up after a temporary interface failure.
.Nm Rtsold
.Nm
detects such failures by periodically probing to see if the status
of the interface is active or not.
Note that some network cards and drivers do not allow the extraction
@ -122,6 +128,15 @@ will dump the current internal state into
.\"
.Sh OPTIONS
.Bl -tag -width indent
.It Fl a
Autoprobe outgoing interface.
.Nm
will try to find a non-loopback, non-p2p and IPv6-capable, interface.
If
.Nm
finds multiple interfaces, it will fail.
This is because IPv6 specification talks about single interface node,
in autoconfiguration spec.
.\"
.It Fl d
Enable debugging.
@ -177,5 +192,16 @@ command, which first appeared in WIDE/KAME IPv6 protocol stack kit.
.Nm rtsol
is now integrated into
.Xr rtsold 8 .
.\" .Sh BUGS
.\" (to be written)
.\"
.Sh BUGS
In some operating systems, when a PCMCIA network card is removed
and reinserted, the corresponding interface index is changed.
However,
.Nm
does not assume such changes, and always uses the index that
it got at invocation. As a result,
.Nm
may not work if you reinsert a network card.
In such a case,
.Nm
should be killed and restarted.

View File

@ -1,4 +1,5 @@
/* $NetBSD: rtsold.c,v 1.6 2000/02/25 09:19:08 itojun Exp $ */
/* $NetBSD: rtsold.c,v 1.7 2000/08/13 06:20:03 itojun Exp $ */
/* $KAME: rtsold.c,v 1.22 2000/08/13 06:14:59 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -48,11 +49,13 @@
#include <errno.h>
#include <err.h>
#include <stdarg.h>
#include <ifaddrs.h>
#include "rtsold.h"
struct ifinfo *iflist;
struct timeval tm_max = {0x7fffffff, 0x7fffffff};
int dflag;
int aflag = 0;
int dflag = 0;
static int log_upto = 999;
static int fflag = 0;
@ -99,6 +102,7 @@ static void TIMEVAL_SUB __P((struct timeval *a, struct timeval *b,
static void rtsold_set_dump_file __P((void));
static void usage __P((char *progname));
static char **autoifprobe __P((void));
int
main(argc, argv)
@ -121,35 +125,60 @@ main(argc, argv)
if (argv0 && argv0[strlen(argv0) - 1] != 'd') {
fflag = 1;
once = 1;
opts = "dD";
opts = "adD";
} else
opts = "dDfm1";
opts = "adDfm1";
while ((ch = getopt(argc, argv, opts)) != -1) {
switch(ch) {
case 'd':
dflag = 1;
break;
case 'D':
dflag = 2;
break;
case 'f':
fflag = 1;
break;
case 'm':
mobile_node = 1;
break;
case '1':
once = 1;
break;
default:
usage(argv0);
switch (ch) {
case 'a':
aflag = 1;
break;
case 'd':
dflag = 1;
break;
case 'D':
dflag = 2;
break;
case 'f':
fflag = 1;
break;
case 'm':
mobile_node = 1;
break;
case '1':
once = 1;
break;
default:
usage(argv0);
/*NOTREACHED*/
}
}
argc -= optind;
argv += optind;
if (argc == 0)
if (aflag) {
int i;
if (argc != 0) {
usage(argv0);
/*NOTREACHED*/
}
argv = autoifprobe();
if (!argv) {
errx(1, "could not autoprobe interface");
/*NOTREACHED*/
}
for (i = 0; argv[i]; i++)
;
argc = i;
}
if (argc == 0) {
usage(argv0);
/*NOTREACHED*/
}
/* set log level */
if (dflag == 0)
@ -176,29 +205,39 @@ main(argc, argv)
warnx("kernel is configured not to accept RAs");
/* initialization to dump internal status to a file */
if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0)
if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0) {
errx(1, "failed to set signal for dump status");
/*NOTREACHED*/
}
/*
* Open a socket for sending RS and receiving RA.
* This should be done before calling ifinit(), since the function
* uses the socket.
*/
if ((s = sockopen()) < 0)
if ((s = sockopen()) < 0) {
errx(1, "failed to open a socket");
/*NOTREACHED*/
}
/* configuration per interface */
if (ifinit())
if (ifinit()) {
errx(1, "failed to initilizatoin interfaces");
/*NOTREACHED*/
}
while (argc--) {
if (ifconfig(*argv))
if (ifconfig(*argv)) {
errx(1, "failed to initialize %s", *argv);
/*NOTREACHED*/
}
argv++;
}
/* setup for probing default routers */
if (probe_init())
if (probe_init()) {
errx(1, "failed to setup for probing routers");
/*NOTREACHED*/
}
if (!fflag)
daemon(0, 0); /* act as a daemon */
@ -432,7 +471,7 @@ rtsol_check_timer()
"state = %d", ifinfo->ifname,
ifinfo->state);
switch(ifinfo->state) {
switch (ifinfo->state) {
case IFS_DOWN:
case IFS_TENTATIVE:
/* interface_up returns 0 on success */
@ -630,10 +669,13 @@ rtsold_set_dump_file()
static void
usage(char *progname)
{
if (progname && progname[strlen(progname) - 1] != 'd')
fprintf(stderr, "usage: rtsol [-dD] interfaces\n");
else
fprintf(stderr, "usage: rtsold [-dDfm1] interfaces\n");
if (progname && progname[strlen(progname) - 1] != 'd') {
fprintf(stderr, "usage: rtsol [-dD] interfaces...\n");
fprintf(stderr, "usage: rtsol [-dD] -a\n");
} else {
fprintf(stderr, "usage: rtsold [-adDfm1] interfaces...\n");
fprintf(stderr, "usage: rtsold [-dDfm1] -a\n");
}
exit(1);
}
@ -663,3 +705,58 @@ warnmsg(priority, func, msg, va_alist)
}
va_end(ap);
}
static char **
autoifprobe()
{
static char ifname[IFNAMSIZ + 1];
static char *argv[2];
struct ifaddrs *ifap, *ifa, *target;
if (getifaddrs(&ifap) != 0)
return NULL;
target = NULL;
/* find an ethernet */
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0)
continue;
if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
continue;
if ((ifa->ifa_flags & IFF_MULTICAST) == 0)
continue;
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
if (target && strcmp(target->ifa_name, ifa->ifa_name) == 0)
continue;
if (!target)
target = ifa;
else {
/* if we find multiple candidates, failure. */
if (dflag > 1)
warnx("multiple interfaces found");
target = NULL;
break;
}
}
if (target) {
strncpy(ifname, target->ifa_name, sizeof(ifname) - 1);
ifname[sizeof(ifname) - 1] = '\0';
argv[0] = ifname;
argv[1] = NULL;
if (dflag > 0)
warnx("probing %s", argv[0]);
}
freeifaddrs(ifap);
if (target)
return argv;
else
return (char **)NULL;
}

View File

@ -1,4 +1,5 @@
/* $NetBSD: rtsold.h,v 1.4 2000/02/25 09:19:10 itojun Exp $ */
/* $NetBSD: rtsold.h,v 1.5 2000/08/13 06:20:03 itojun Exp $ */
/* $KAME: rtsold.h,v 1.9 2000/08/13 06:15:00 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.