summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtsold
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-08-17 11:11:32 +0000
committerume <ume@FreeBSD.org>2003-08-17 11:11:32 +0000
commite63e485957ca75728d14f0f841a255c547024105 (patch)
tree71f0ce4c364fa35219a41194d4e21717734ebb58 /usr.sbin/rtsold
parentd21c6d5071dfec3042de4b42f1f7754eeb80247b (diff)
downloadFreeBSD-src-e63e485957ca75728d14f0f841a255c547024105.zip
FreeBSD-src-e63e485957ca75728d14f0f841a255c547024105.tar.gz
- improved the -a option. it can probe a interface automatically when
the interface wake up. it can be started anytime even when there is no network interface on the list of intarfaces in the kernel. - get a correct link ID for each interface at initialization (using scope libraries if HAVE_SCOPELIB is defined). - fill in sin6_scope_id correctly before sendmsg(). Obtained from: KAME MFC after: 1 week
Diffstat (limited to 'usr.sbin/rtsold')
-rw-r--r--usr.sbin/rtsold/probe.c19
-rw-r--r--usr.sbin/rtsold/rtsol.c34
-rw-r--r--usr.sbin/rtsold/rtsold.836
-rw-r--r--usr.sbin/rtsold/rtsold.c130
-rw-r--r--usr.sbin/rtsold/rtsold.h9
5 files changed, 134 insertions, 94 deletions
diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c
index 9b86c63..b7e7cc6 100644
--- a/usr.sbin/rtsold/probe.c
+++ b/usr.sbin/rtsold/probe.c
@@ -1,4 +1,4 @@
-/* $KAME: probe.c,v 1.10 2000/08/13 06:14:59 itojun Exp $ */
+/* $KAME: probe.c,v 1.16 2002/06/10 20:00:36 itojun Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@@ -40,6 +40,7 @@
#include <net/if.h>
#include <net/if_var.h>
+#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet6/in6_var.h>
@@ -59,7 +60,7 @@
static struct msghdr sndmhdr;
static struct iovec sndiov[2];
static int probesock;
-static void sendprobe __P((struct in6_addr *, int));
+static void sendprobe __P((struct in6_addr *, struct ifinfo *));
int
probe_init()
@@ -98,11 +99,12 @@ probe_init()
* Probe if each router in the default router list is still alive.
*/
void
-defrouter_probe(int ifindex)
+defrouter_probe(struct ifinfo *ifinfo)
{
+ u_char ntopbuf[INET6_ADDRSTRLEN];
struct in6_drlist dr;
int s, i;
- u_char ntopbuf[INET6_ADDRSTRLEN];
+ int ifindex = ifinfo->sdl->sdl_index;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
warnmsg(LOG_ERR, __func__, "socket: %s", strerror(errno));
@@ -128,8 +130,7 @@ defrouter_probe(int ifindex)
ntopbuf, INET6_ADDRSTRLEN));
continue; /* ignore the address */
}
- sendprobe(&dr.defrouter[i].rtaddr,
- dr.defrouter[i].if_index);
+ sendprobe(&dr.defrouter[i].rtaddr, ifinfo);
}
}
@@ -138,18 +139,20 @@ closeandend:
}
static void
-sendprobe(struct in6_addr *addr, int ifindex)
+sendprobe(struct in6_addr *addr, struct ifinfo *ifinfo)
{
+ u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
struct sockaddr_in6 sa6_probe;
struct in6_pktinfo *pi;
struct cmsghdr *cm;
- u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
+ u_int32_t ifindex = ifinfo->sdl->sdl_index;
int hoplimit = 1;
memset(&sa6_probe, 0, sizeof(sa6_probe));
sa6_probe.sin6_family = AF_INET6;
sa6_probe.sin6_len = sizeof(sa6_probe);
sa6_probe.sin6_addr = *addr;
+ sa6_probe.sin6_scope_id = ifinfo->linkid;
sndmhdr.msg_name = (caddr_t)&sa6_probe;
sndmhdr.msg_iov[0].iov_base = NULL;
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index cbcad8a..4605016 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -1,4 +1,4 @@
-/* $KAME: rtsol.c,v 1.12 2001/11/12 11:47:11 jinmei Exp $ */
+/* $KAME: rtsol.c,v 1.26 2003/05/27 06:48:27 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -35,7 +35,6 @@
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/time.h>
-#include <fcntl.h>
#include <sys/queue.h>
#include <sys/wait.h>
#include <sys/stat.h>
@@ -52,6 +51,7 @@
#include <arpa/inet.h>
#include <time.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <err.h>
@@ -68,6 +68,7 @@ static struct msghdr sndmhdr;
static struct iovec rcviov[2];
static struct iovec sndiov[2];
static struct sockaddr_in6 from;
+static int rcvcmsglen;
int rssock;
@@ -80,11 +81,10 @@ static int safefile __P((const char *));
int
sockopen()
{
- int on;
- struct icmp6_filter filt;
- static u_char answer[1500];
- int rcvcmsglen, sndcmsglen;
static u_char *rcvcmsgbuf = NULL, *sndcmsgbuf = NULL;
+ int sndcmsglen, on;
+ static u_char answer[1500];
+ struct icmp6_filter filt;
sndcmsglen = rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int));
@@ -163,11 +163,9 @@ sockopen()
rcviov[0].iov_base = (caddr_t)answer;
rcviov[0].iov_len = sizeof(answer);
rcvmhdr.msg_name = (caddr_t)&from;
- rcvmhdr.msg_namelen = sizeof(from);
rcvmhdr.msg_iov = rcviov;
rcvmhdr.msg_iovlen = 1;
rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
- rcvmhdr.msg_controllen = rcvcmsglen;
/* initialize msghdr for sending packets */
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
@@ -186,8 +184,12 @@ sendpacket(struct ifinfo *ifinfo)
struct cmsghdr *cm;
int hoplimit = 255;
int i;
+ struct sockaddr_in6 dst;
+
+ dst = sin6_allrouters;
+ dst.sin6_scope_id = ifinfo->linkid;
- sndmhdr.msg_name = (caddr_t)&sin6_allrouters;
+ sndmhdr.msg_name = (caddr_t)&dst;
sndmhdr.msg_iov[0].iov_base = (caddr_t)ifinfo->rs_data;
sndmhdr.msg_iov[0].iov_len = ifinfo->rs_datalen;
@@ -228,17 +230,17 @@ sendpacket(struct ifinfo *ifinfo)
void
rtsol_input(int s)
{
- int i;
- int *hlimp = NULL;
- struct icmp6_hdr *icp;
- int ifindex = 0;
- struct cmsghdr *cm;
+ u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
+ int ifindex = 0, i, *hlimp = NULL;
struct in6_pktinfo *pi = NULL;
struct ifinfo *ifi = NULL;
+ struct icmp6_hdr *icp;
struct nd_router_advert *nd_ra;
- u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
+ struct cmsghdr *cm;
- /* get message */
+ /* get message. namelen and controllen must always be initialized. */
+ rcvmhdr.msg_namelen = sizeof(from);
+ rcvmhdr.msg_controllen = rcvcmsglen;
if ((i = recvmsg(s, &rcvmhdr, 0)) < 0) {
warnmsg(LOG_ERR, __func__, "recvmsg: %s", strerror(errno));
return;
diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8
index a365637..2490890 100644
--- a/usr.sbin/rtsold/rtsold.8
+++ b/usr.sbin/rtsold/rtsold.8
@@ -1,4 +1,4 @@
-.\" $KAME: rtsold.8,v 1.16 2000/10/15 13:19:05 itojun Exp $
+.\" $KAME: rtsold.8,v 1.20 2003/04/11 12:46:12 jinmei Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@@ -56,9 +56,8 @@
.Fl a
.\"
.Sh DESCRIPTION
-The
.Nm
-utility is the daemon program to send ICMPv6 Router Solicitation messages
+is the daemon program to send ICMPv6 Router Solicitation messages
on the specified interfaces.
If a node (re)attaches to a link,
.Nm
@@ -66,10 +65,9 @@ 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
-The
.Nm
-utility should be used on IPv6 hosts
-(non-router nodes)
+should be used on IPv6 hosts
+.Pq non-router nodes
only.
.Pp
If you invoke the program as
@@ -98,9 +96,8 @@ Just after invocation of
daemon.
.It
The interface is up after a temporary interface failure.
-The
.Nm
-utility detects such failures by periodically probing to see if the status
+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
of link state.
@@ -154,13 +151,12 @@ Upon receipt of signal
will dump the current internal state into
.Pa /var/run/rtsold.dump .
.\"
-.Sh OPTIONS
+.Pp
+The options are as follows:
.Bl -tag -width indent
.It Fl a
Autoprobe outgoing interface.
-The
.Nm
-utility
will try to find a non-loopback, non-point-to-point, IPv6-capable interface.
If
.Nm
@@ -173,7 +169,8 @@ Enable debugging.
.It Fl D
Enable more debugging including the printing of internal timer information.
.It Fl f
-Prevent
+.Fl f
+prevents
.Nm
from becoming a daemon (foreground mode).
Warning messages are generated to standard error
@@ -212,8 +209,10 @@ must be the absolute path from root to the script file, be a regular
file, and be created by the same owner who runs
.Nm .
.El
-.Sh DIAGNOSTICS
-.Ex -std rtsold rtsol
+.Sh RETURN VALUES
+The
+.Nm
+program exits 0 on success, and >0 on failures.
.\"
.Sh FILES
.Bl -tag -width /var/run/rtsold.dump -compact
@@ -231,13 +230,12 @@ dumps internal state on.
.Sh HISTORY
The
.Nm
-utility is based on the
+command is based on the
.Nm rtsol
-utility, which first appeared in WIDE/KAME IPv6 protocol stack kit.
-The
+command, which first appeared in WIDE/KAME IPv6 protocol stack kit.
.Nm rtsol
-utility is now integrated into
-.Nm .
+is now integrated into
+.Xr rtsold 8 .
.\"
.Sh BUGS
In some operating systems, when a PCMCIA network card is removed
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index 82cae73..be9d712 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -1,4 +1,4 @@
-/* $KAME: rtsold.c,v 1.31 2001/05/22 06:03:06 jinmei Exp $ */
+/* $KAME: rtsold.c,v 1.67 2003/05/17 18:16:15 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -101,7 +101,6 @@ static int do_dump;
static char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */
static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */
-static int ifconfig __P((char *));
#if 0
static int ifreconfig __P((char *));
#endif
@@ -114,7 +113,6 @@ static void TIMEVAL_SUB __P((struct timeval *, struct timeval *,
static void rtsold_set_dump_file __P((int));
static void usage __P((char *));
-static char **autoifprobe __P((void));
int
main(argc, argv)
@@ -177,25 +175,7 @@ main(argc, argv)
argc -= optind;
argv += optind;
- 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) {
+ if ((!aflag && argc == 0) || (aflag && argc != 0)) {
usage(argv0);
/*NOTREACHED*/
}
@@ -292,7 +272,9 @@ main(argc, argv)
exit(1);
/*NOTREACHED*/
}
- while (argc--) {
+ if (aflag)
+ argv = autoifprobe();
+ while (argv && *argv) {
if (ifconfig(*argv)) {
warnmsg(LOG_ERR, __func__,
"failed to initialize %s", *argv);
@@ -391,7 +373,7 @@ main(argc, argv)
return 0;
}
-static int
+int
ifconfig(char *ifname)
{
struct ifinfo *ifinfo;
@@ -424,6 +406,15 @@ ifconfig(char *ifname)
if (make_packet(ifinfo))
goto bad;
+ /* set link ID of this interface. */
+#ifdef HAVE_SCOPELIB
+ if (inet_zoneid(AF_INET6, 2, ifname, &ifinfo->linkid))
+ goto bad;
+#else
+ /* XXX: assume interface IDs as link IDs */
+ ifinfo->linkid = ifinfo->sdl->sdl_index;
+#endif
+
/*
* check if the interface is available.
* also check if SIOCGIFMEDIA ioctl is OK on the interface.
@@ -462,6 +453,22 @@ bad:
return(-1);
}
+void
+iflist_init()
+{
+ struct ifinfo *ifi, *next;
+
+ for (ifi = iflist; ifi; ifi = next) {
+ next = ifi->next;
+ if (ifi->sdl)
+ free(ifi->sdl);
+ if (ifi->rs_data)
+ free(ifi->rs_data);
+ free(ifi);
+ iflist = NULL;
+ }
+}
+
#if 0
static int
ifreconfig(char *ifname)
@@ -602,7 +609,7 @@ rtsol_check_timer()
ifinfo->otherconfig = 0;
if (probe && mobile_node)
- defrouter_probe(ifinfo->sdl->sdl_index);
+ defrouter_probe(ifinfo);
break;
}
case IFS_DELAY:
@@ -804,13 +811,27 @@ warnmsg(priority, func, msg, va_alist)
va_end(ap);
}
-static char **
+/*
+ * return a list of interfaces which is suitable to sending an RS.
+ */
+char **
autoifprobe()
{
- static char ifname[IFNAMSIZ + 1];
- static char *argv[2];
+ static char **argv = NULL;
+ static int n = 0;
+ char **a;
+ int i, found;
struct ifaddrs *ifap, *ifa, *target;
+ /* initialize */
+ while (n--)
+ free(argv[n]);
+ if (argv) {
+ free(argv);
+ argv = NULL;
+ }
+ n = 0;
+
if (getifaddrs(&ifap) != 0)
return NULL;
@@ -829,32 +850,43 @@ autoifprobe()
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
- if (target && strcmp(target->ifa_name, ifa->ifa_name) == 0)
+ found = 0;
+ for (i = 0; i < n; i++) {
+ if (strcmp(argv[i], ifa->ifa_name) == 0) {
+ found++;
+ break;
+ }
+ }
+ if (found)
continue;
- if (!target)
- target = ifa;
- else {
- /* if we find multiple candidates, failure. */
- if (dflag > 1)
- warnx("multiple interfaces found");
- target = NULL;
- break;
- }
+ /* if we find multiple candidates, just warn. */
+ if (n != 0 && dflag > 1)
+ warnx("multiple interfaces found");
+
+ a = (char **)realloc(argv, (n + 1) * sizeof(char **));
+ if (a == NULL)
+ err(1, "realloc");
+ argv = a;
+ argv[n] = strdup(ifa->ifa_name);
+ if (!argv[n])
+ err(1, "malloc");
+ n++;
+ argv[n] = NULL;
}
- if (target) {
- strncpy(ifname, target->ifa_name, sizeof(ifname) - 1);
- ifname[sizeof(ifname) - 1] = '\0';
- argv[0] = ifname;
- argv[1] = NULL;
+ if (n) {
+ a = (char **)realloc(argv, (n + 1) * sizeof(char **));
+ if (a == NULL)
+ err(1, "realloc");
+ argv = a;
+ argv[n] = NULL;
- if (dflag > 0)
- warnx("probing %s", argv[0]);
+ if (dflag > 0) {
+ for (i = 0; i < n; i++)
+ warnx("probing %s", argv[i]);
+ }
}
freeifaddrs(ifap);
- if (target)
- return argv;
- else
- return (char **)NULL;
+ return argv;
}
diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h
index 976a34b..09577a5 100644
--- a/usr.sbin/rtsold/rtsold.h
+++ b/usr.sbin/rtsold/rtsold.h
@@ -1,4 +1,4 @@
-/* $KAME: rtsold.h,v 1.11 2000/10/10 06:18:04 itojun Exp $ */
+/* $KAME: rtsold.h,v 1.19 2003/04/16 09:48:15 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -36,6 +36,7 @@ struct ifinfo {
struct sockaddr_dl *sdl; /* link-layer address */
char ifname[IF_NAMESIZE]; /* interface name */
+ u_int32_t linkid; /* link ID of this interface */
int active; /* interface status */
int probeinterval; /* interval of probe timer (if necessary) */
int probetimer; /* rest of probe timer */
@@ -65,11 +66,15 @@ struct ifinfo {
/* rtsold.c */
extern struct timeval tm_max;
extern int dflag;
+extern int aflag;
extern char *otherconf_script;
+extern int ifconfig __P((char *));
+extern void iflist_init __P((void));
struct ifinfo *find_ifinfo __P((int));
void rtsol_timer_update __P((struct ifinfo *));
extern void warnmsg __P((int, const char *, const char *, ...))
__attribute__((__format__(__printf__, 3, 4)));
+extern char **autoifprobe __P((void));
/* if.c */
extern int ifinit __P((void));
@@ -87,7 +92,7 @@ extern void rtsol_input __P((int));
/* probe.c */
extern int probe_init __P((void));
-extern void defrouter_probe __P((int));
+extern void defrouter_probe __P((struct ifinfo *));
/* dump.c */
extern void rtsold_dump_file __P((char *));
OpenPOWER on IntegriCloud