summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-08-13 18:24:01 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-08-13 18:24:01 +0000
commit0f7613c03c4bd997808651e637c2f8e94a438a44 (patch)
tree6ee4bfd67bb9ad181b6fe43feb2c35138111c346 /usr.sbin
parentcb11ffa4bd67f11ab1386d67ce4869a6224c0719 (diff)
add "rtsol -a" (automatically lookup outgoign interface).
warn if net.inet6.ip6.forwarding == 1. improve manpage. use $KAME$ for KAME tags. sync with kame.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rtsold/dump.c3
-rw-r--r--usr.sbin/rtsold/if.c4
-rw-r--r--usr.sbin/rtsold/probe.c19
-rw-r--r--usr.sbin/rtsold/rtsol.c26
-rw-r--r--usr.sbin/rtsold/rtsold.851
-rw-r--r--usr.sbin/rtsold/rtsold.c170
-rw-r--r--usr.sbin/rtsold/rtsold.h3
7 files changed, 223 insertions, 53 deletions
diff --git a/usr.sbin/rtsold/dump.c b/usr.sbin/rtsold/dump.c
index 29d5a4111b2..5df4ecd32be 100644
--- a/usr.sbin/rtsold/dump.c
+++ b/usr.sbin/rtsold/dump.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: dump.c,v 1.3 2000/02/25 10:32:21 itojun Exp $ */
+/* $OpenBSD: dump.c,v 1.4 2000/08/13 18:24:00 itojun Exp $ */
+/* $KAME: dump.c,v 1.7 2000/08/13 06:14:59 itojun Exp $ */
/*
* Copyright (C) 1999 WIDE Project.
diff --git a/usr.sbin/rtsold/if.c b/usr.sbin/rtsold/if.c
index 4fef07fd307..7252e5df11a 100644
--- a/usr.sbin/rtsold/if.c
+++ b/usr.sbin/rtsold/if.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: if.c,v 1.5 2000/02/25 10:32:21 itojun Exp $ */
+/* $OpenBSD: if.c,v 1.6 2000/08/13 18:24:00 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
diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c
index a4a25321e36..349b40b896b 100644
--- a/usr.sbin/rtsold/probe.c
+++ b/usr.sbin/rtsold/probe.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: probe.c,v 1.2 1999/12/09 15:10:49 itojun Exp $ */
+/* $OpenBSD: probe.c,v 1.3 2000/08/13 18:24:00 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
@@ -51,6 +53,7 @@
#include <unistd.h>
#include <string.h>
#include <syslog.h>
+#include <stdlib.h>
#include "rtsold.h"
@@ -59,11 +62,19 @@ static struct iovec sndiov[2];
static int probesock;
static void sendprobe __P((struct in6_addr *addr, int ifindex));
+
int
probe_init()
{
- static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
- CMSG_SPACE(sizeof(int))];
+ int scmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
+ CMSG_SPACE(sizeof(int));
+ static u_char *sndcmsgbuf = NULL;
+
+ if (sndcmsgbuf == NULL &&
+ (sndcmsgbuf = (u_char *)malloc(scmsglen)) == NULL) {
+ warnmsg(LOG_ERR, __FUNCTION__, "malloc failed");
+ return(-1);
+ }
if ((probesock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
@@ -81,7 +92,7 @@ probe_init()
sndmhdr.msg_iov = sndiov;
sndmhdr.msg_iovlen = 1;
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
- sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
+ sndmhdr.msg_controllen = scmsglen;
return(0);
}
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index afd2e98785c..08b1b5382f1 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: rtsol.c,v 1.4 2000/01/17 16:33:49 itojun Exp $ */
+/* $OpenBSD: rtsol.c,v 1.5 2000/08/13 18:24:00 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>
@@ -73,11 +75,21 @@ sockopen()
int on;
struct icmp6_filter filt;
static u_char answer[1500];
- static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
- CMSG_SPACE(sizeof(int))];
- static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
- CMSG_SPACE(sizeof(int))];
+ int rcvcmsglen, sndcmsglen;
+ static u_char *rcvcmsgbuf = NULL, *sndcmsgbuf = NULL;
+ sndcmsglen = rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
+ CMSG_SPACE(sizeof(int));
+ if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
+ warnmsg(LOG_ERR, __FUNCTION__,
+ "malloc for receive msghdr failed");
+ return(-1);
+ }
+ if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL) {
+ warnmsg(LOG_ERR, __FUNCTION__,
+ "malloc for send msghdr failed");
+ return(-1);
+ }
memset(&sin6_allrouters, 0, sizeof(struct sockaddr_in6));
if (inet_pton(AF_INET6, ALLROUTER,
&sin6_allrouters.sin6_addr.s6_addr) != 1) {
@@ -145,14 +157,14 @@ sockopen()
rcvmhdr.msg_iov = rcviov;
rcvmhdr.msg_iovlen = 1;
rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
- rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf);
+ rcvmhdr.msg_controllen = rcvcmsglen;
/* initialize msghdr for sending packets */
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
sndmhdr.msg_iov = sndiov;
sndmhdr.msg_iovlen = 1;
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
- sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
+ sndmhdr.msg_controllen = sndcmsglen;
return(rssock);
}
diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8
index 190a7f3699f..6351818adc2 100644
--- a/usr.sbin/rtsold/rtsold.8
+++ b/usr.sbin/rtsold/rtsold.8
@@ -1,4 +1,5 @@
-.\" $OpenBSD: rtsold.8,v 1.10 2000/04/15 02:15:20 aaron Exp $
+.\" $OpenBSD: rtsold.8,v 1.11 2000/08/13 18:24:00 itojun Exp $
+.\" $KAME: rtsold.8,v 1.14 2000/08/13 18:06:39 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@@ -27,8 +28,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" KAME Id: rtsold.8,v 1.8 2000/01/02 06:25:14 itojun Exp
-.\"
.Dd May 17, 1998
.Dt RTSOLD 8
.Os
@@ -38,12 +37,18 @@
.Nd router solicitation daemon
.\"
.Sh SYNOPSIS
-.Nm rtsold
+.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
@@ -55,6 +60,11 @@ sends some Router Solicitations on the link destined to the link-local scope
all-routers multicast address to discover new routers
and to get non link-local addresses.
.Pp
+.Nm
+should be used on IPv6 host
+.Pq non-router node
+only.
+.Pp
If you invoke the program as
.Nm rtsol ,
it will transmit probes from the specified
@@ -123,6 +133,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,
+.Nm
+will exit with error.
.\"
.It Fl d
Enable debugging.
@@ -178,5 +197,25 @@ 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.
+.Pp
+IPv6 autoconfiguration specification assumes single interface host.
+You may see kernel error message if you try to autoconfigure a host with
+multiple interfaces.
+Also, it seems contradictory for
+.Nm
+to accept multiple
+.Ar interfaces
+in argument.
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index 839d2ed31f6..c6eec0d5020 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: rtsold.c,v 1.7 2000/02/25 10:32:21 itojun Exp $ */
+/* $OpenBSD: rtsold.c,v 1.8 2000/08/13 18:24:00 itojun Exp $ */
+/* $KAME: rtsold.c,v 1.26 2000/08/13 18:17:15 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)
@@ -174,31 +203,44 @@ main(argc, argv)
/* warn if accept_rtadv is down */
if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV))
warnx("kernel is configured not to accept RAs");
+ /* warn if forwarding is up */
+ if (getinet6sysctl(IPV6CTL_FORWARDING))
+ warnx("kernel is configured as a router, not a host");
/* 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 +474,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 +672,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 +708,62 @@ warnmsg(priority, func, msg, va_alist)
}
va_end(ap);
}
+
+static char **
+autoifprobe()
+{
+#ifndef HAVE_GETIFADDRS
+ errx(1, "-a is not available with the configuration");
+#else
+ 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;
+#endif
+}
diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h
index ee57153d788..41a6efd2595 100644
--- a/usr.sbin/rtsold/rtsold.h
+++ b/usr.sbin/rtsold/rtsold.h
@@ -1,4 +1,5 @@
-/* $OpenBSD: rtsold.h,v 1.3 2000/02/25 10:32:21 itojun Exp $ */
+/* $OpenBSD: rtsold.h,v 1.4 2000/08/13 18:24:00 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.