summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtsold/rtsold.c
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/rtsold.c
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/rtsold.c')
-rw-r--r--usr.sbin/rtsold/rtsold.c130
1 files changed, 81 insertions, 49 deletions
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;
}
OpenPOWER on IntegriCloud