diff options
-rw-r--r-- | usr.sbin/rtsold/dump.c | 3 | ||||
-rw-r--r-- | usr.sbin/rtsold/if.c | 4 | ||||
-rw-r--r-- | usr.sbin/rtsold/probe.c | 19 | ||||
-rw-r--r-- | usr.sbin/rtsold/rtsol.c | 26 | ||||
-rw-r--r-- | usr.sbin/rtsold/rtsold.8 | 51 | ||||
-rw-r--r-- | usr.sbin/rtsold/rtsold.c | 170 | ||||
-rw-r--r-- | usr.sbin/rtsold/rtsold.h | 3 |
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. |