diff options
author | ume <ume@FreeBSD.org> | 2003-08-17 11:11:32 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-08-17 11:11:32 +0000 |
commit | e63e485957ca75728d14f0f841a255c547024105 (patch) | |
tree | 71f0ce4c364fa35219a41194d4e21717734ebb58 /usr.sbin/rtsold/rtsold.c | |
parent | d21c6d5071dfec3042de4b42f1f7754eeb80247b (diff) | |
download | FreeBSD-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.c | 130 |
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; } |