- 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
This commit is contained in:
parent
d21c6d5071
commit
e63e485957
@ -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 @@ defrouter_probe(int ifindex)
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
||||
sndmhdr.msg_name = (caddr_t)&sin6_allrouters;
|
||||
dst = sin6_allrouters;
|
||||
dst.sin6_scope_id = ifinfo->linkid;
|
||||
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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 @@ ifconfig(char *ifname)
|
||||
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 (n) {
|
||||
a = (char **)realloc(argv, (n + 1) * sizeof(char **));
|
||||
if (a == NULL)
|
||||
err(1, "realloc");
|
||||
argv = a;
|
||||
argv[n] = NULL;
|
||||
|
||||
if (dflag > 0) {
|
||||
for (i = 0; i < n; i++)
|
||||
warnx("probing %s", argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
return argv;
|
||||
}
|
||||
|
@ -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 *));
|
||||
|
Loading…
Reference in New Issue
Block a user