From c6314d6139f759e125980cf1c2c8c42075171b82 Mon Sep 17 00:00:00 2001 From: roy Date: Thu, 11 Sep 2014 13:10:03 +0000 Subject: [PATCH] Remove rtsol(8) and rtsold(8) as their functionality is in dhcpcd(8). Remove rtsol(8) from rc.d/network. Add -w seconds command to ifconfig to wait for N seconds for until DAD has finished on all addresses. Use ifconfig -w in rc.d/network instead of a forced sleep. As discussed on tech-net@ --- distrib/sets/lists/base/mi | 6 +- doc/CHANGES | 4 +- etc/defaults/rc.conf | 3 +- etc/rc.d/network | 39 +- etc/rc.d/rtsold | 26 -- rescue/list.inet6 | 3 +- sbin/Makefile | 4 +- sbin/ifconfig/ifconfig.8 | 16 +- sbin/ifconfig/ifconfig.c | 108 ++++- sbin/rtsol/Makefile | 19 - usr.sbin/postinstall/postinstall | 4 +- usr.sbin/rtsold/Makefile | 13 +- usr.sbin/rtsold/dump.c | 146 ------ usr.sbin/rtsold/if.c | 366 --------------- usr.sbin/rtsold/probe.c | 182 -------- usr.sbin/rtsold/rtsock.c | 175 -------- usr.sbin/rtsold/rtsol.c | 346 -------------- usr.sbin/rtsold/rtsold.8 | 185 +------- usr.sbin/rtsold/rtsold.c | 749 ------------------------------- usr.sbin/rtsold/rtsold.h | 100 ----- 20 files changed, 147 insertions(+), 2347 deletions(-) delete mode 100755 etc/rc.d/rtsold delete mode 100644 sbin/rtsol/Makefile delete mode 100644 usr.sbin/rtsold/dump.c delete mode 100644 usr.sbin/rtsold/if.c delete mode 100644 usr.sbin/rtsold/probe.c delete mode 100644 usr.sbin/rtsold/rtsock.c delete mode 100644 usr.sbin/rtsold/rtsol.c delete mode 100644 usr.sbin/rtsold/rtsold.c delete mode 100644 usr.sbin/rtsold/rtsold.h diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index 1311e5cce20c..b708bca3e072 100644 --- a/distrib/sets/lists/base/mi +++ b/distrib/sets/lists/base/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1088 2014/08/22 10:51:38 apb Exp $ +# $NetBSD: mi,v 1.1089 2014/09/11 13:10:03 roy Exp $ # # Note: Don't delete entries from here - mark them as "obsolete" instead, # unless otherwise stated below. @@ -359,7 +359,7 @@ ./sbin/route base-netutil-root ./sbin/routed base-router-root ./sbin/rrestore base-netutil-root -./sbin/rtsol base-netutil-root use_inet6 +./sbin/rtsol base-obsolete obsolete ./sbin/rump.cgdconfig base-sysutil-root crypto,rump ./sbin/rump.ifconfig base-netutil-root rump ./sbin/rump.modload base-sysutil-root rump @@ -1631,7 +1631,7 @@ ./usr/sbin/rpcbind base-rpcbind-bin ./usr/sbin/rtadvd base-router-bin use_inet6 ./usr/sbin/rtquery base-netutil-bin -./usr/sbin/rtsold base-netutil-bin inet6 +./usr/sbin/rtsold base-obsolete obsolete ./usr/sbin/rump.envstat base-sysutil-bin rump ./usr/sbin/rump.powerd base-sysutil-bin rump ./usr/sbin/rump.traceroute base-netutil-bin rump diff --git a/doc/CHANGES b/doc/CHANGES index acd1428fb213..b68604f97ff3 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,4 +1,4 @@ -# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1978 $> +# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1979 $> # # # [Note: This file does not mention every change made to the NetBSD source tree. @@ -46,3 +46,5 @@ Changes from NetBSD 7.0 to NetBSD 8.0: awinrtc(4): Add support for AllWinner A10/A20 real-time clock. [jmcneill 20140907] awinmmc(4): Use DMA for MMC transfers. [jmcneill 20140908] + rtsol(8): Removed in favour of dhcpcd. [roy 20140911] + rtsold(8): Removed in favour of dhcpcd. [roy 20140911] diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 2ecd24ab1416..bfbb9ba0f961 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -1,4 +1,4 @@ -# $NetBSD: rc.conf,v 1.123 2014/07/22 17:11:09 wiz Exp $ +# $NetBSD: rc.conf,v 1.124 2014/09/11 13:10:03 roy Exp $ # # /etc/defaults/rc.conf -- # default configuration of /etc/rc.conf @@ -253,7 +253,6 @@ routed=NO routed_flags="-q" gated=NO mrouted=NO mrouted_flags="" route6d=NO route6d_flags="" -rtsold=NO rtsold_flags="-a" # for ip6mode=autohost only ldpd=NO # Daemons used to boot other hosts over a network. diff --git a/etc/rc.d/network b/etc/rc.d/network index cd3e163eff44..b2bef92c8d31 100755 --- a/etc/rc.d/network +++ b/etc/rc.d/network @@ -1,6 +1,6 @@ #!/bin/sh # -# $NetBSD: network,v 1.66 2014/04/29 09:58:18 uebayasi Exp $ +# $NetBSD: network,v 1.67 2014/09/11 13:10:03 roy Exp $ # # PROVIDE: network @@ -432,33 +432,26 @@ network_start_defaultroute6() network_start_ipv6_autoconf() { # IPv6 interface autoconfiguration. - # - # wait till DAD is completed. always invoke it in case - # if are configured manually by ifconfig - # - echo 'Waiting for DAD completion for' \ - 'statically configured addresses...' + dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null) - sleep $dadcount - sleep 1 + if [ -n "$dadcount" -a "$dadcount" != 0 ]; then + # wait till DAD is completed + echo 'Waiting for DAD to complete for' \ + 'statically configured addresses...' + # Add 1 for MAX_RTR_SOLICITATION_DELAY and another + # to give time for the last DAD packet to respond and + # a few more for luck. + waitsecs=$((dadcount + 4)) + /sbin/ifconfig -w $waitsecs + fi - if checkyesno rtsol; then + # dhcpcd will ensure DAD completes before forking + if checkyesno rtsol && !checkyesno dhcpcd; then if [ "$ip6mode" = "autohost" ]; then - echo 'Sending router solicitation...' - /sbin/rtsol $rtsol_flags - else echo - warn \ - "ip6mode must be set to 'autohost' to use rtsol." + warn "rtsol has been removed, " \ + "please configure dhcpcd in its place." fi - - # wait till DAD is completed, for global addresses - # configured by router advert message. - # - echo 'Waiting for DAD completion for' \ - 'addresses configured by router advert message...' - sleep $dadcount - sleep 1 fi } diff --git a/etc/rc.d/rtsold b/etc/rc.d/rtsold deleted file mode 100755 index 2fb33ccc9d69..000000000000 --- a/etc/rc.d/rtsold +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# -# $NetBSD: rtsold,v 1.7 2006/10/07 21:41:41 rpaulo Exp $ -# - -# PROVIDE: rtsold -# REQUIRE: network mountcritlocal -# BEFORE: NETWORKING - -$_rc_subr_loaded . /etc/rc.subr - -name="rtsold" -rcvar=$name -command="/usr/sbin/${name}" -start_precmd="rtsold_precmd" - -rtsold_precmd() -{ - if [ "$ip6mode" != "autohost" ]; then - warn "\$ip6mode must be set to 'autohost' to use ${name}." - return 1 - fi -} - -load_rc_config $name -run_rc_command "$1" diff --git a/rescue/list.inet6 b/rescue/list.inet6 index ede4228593ec..a90bd01990db 100644 --- a/rescue/list.inet6 +++ b/rescue/list.inet6 @@ -1,4 +1,3 @@ -# $NetBSD: list.inet6,v 1.1 2005/01/10 02:58:59 lukem Exp $ +# $NetBSD: list.inet6,v 1.2 2014/09/11 13:10:03 roy Exp $ PROG ping6 -PROG rtsol diff --git a/sbin/Makefile b/sbin/Makefile index f0be9fdc80ca..32b7800e57fa 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.126 2013/12/25 22:04:52 christos Exp $ +# $NetBSD: Makefile,v 1.127 2014/09/11 13:10:03 roy Exp $ # @(#)Makefile 8.5 (Berkeley) 3/31/94 # Not ported: XNSrouted enpload scsiformat startslip @@ -55,7 +55,7 @@ SUBDIR+= cgdconfig .endif .if (${USE_INET6} != "no") -SUBDIR+= ping6 rtsol +SUBDIR+= ping6 .endif .if (${MKISCSI} != "no") diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 93dfbcaad08c..8b09f19ce3d8 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: ifconfig.8,v 1.106 2014/01/07 20:25:24 degroote Exp $ +.\" $NetBSD: ifconfig.8,v 1.107 2014/09/11 13:10:04 roy Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -59,6 +59,9 @@ .Fl s .Ar interface .Nm +.Fl w +.Ar secs +.Nm .Fl C .Sh DESCRIPTION .Nm @@ -860,6 +863,17 @@ flag except that it zeros the interface input and output statistics after printing them. .Pp The +.Fl w +flag may be used to wait +.Ar seconds +seconds for the +.Cm tentative +flag to be removed from all addresses. +0 seconds means to wait indefinitely until all addresses no longer have the +.Cm tentative +flag. +.Pp +The .Fl N flag is just the opposite of the .Fl n diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 96cbcccc5b2c..51931178b862 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $NetBSD: ifconfig.c,v 1.231 2013/10/19 00:35:30 christos Exp $ */ +/* $NetBSD: ifconfig.c,v 1.232 2014/09/11 13:10:04 roy Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1983, 1993\ The Regents of the University of California. All rights reserved."); -__RCSID("$NetBSD: ifconfig.c,v 1.231 2013/10/19 00:35:30 christos Exp $"); +__RCSID("$NetBSD: ifconfig.c,v 1.232 2014/09/11 13:10:04 roy Exp $"); #endif /* not lint */ #include @@ -102,10 +102,13 @@ __RCSID("$NetBSD: ifconfig.c,v 1.231 2013/10/19 00:35:30 christos Exp $"); #include "env.h" #include "prog_ops.h" -static bool bflag, dflag, hflag, sflag, uflag; -bool lflag, Nflag, vflag, zflag; +#define WAIT_DAD 10000000 /* nanoseconds between each poll, 10ms */ -static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvz"; +static bool bflag, dflag, hflag, sflag, uflag, wflag; +bool lflag, Nflag, vflag, zflag; +static long wflag_secs; + +static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvw:z"; bool gflagset[10 + 26 * 2]; static int carrier(prop_dictionary_t); @@ -115,6 +118,7 @@ static int flag_index(int); static void init_afs(void); static int list_cloners(prop_dictionary_t, prop_dictionary_t); static int media_status_exec(prop_dictionary_t, prop_dictionary_t); +static int wait_dad_exec(prop_dictionary_t, prop_dictionary_t); static int no_cmds_exec(prop_dictionary_t, prop_dictionary_t); static int notrailers(prop_dictionary_t, prop_dictionary_t); static void printall(const char *, prop_dictionary_t); @@ -223,6 +227,9 @@ static struct kwinst familykw[24]; struct pterm cloneterm = PTERM_INITIALIZER(&cloneterm, "list cloners", list_cloners, "none"); +struct pterm wait_dad = PTERM_INITIALIZER(&wait_dad, "wait DAD", wait_dad_exec, + "none"); + struct pterm no_cmds = PTERM_INITIALIZER(&no_cmds, "no commands", no_cmds_exec, "none"); @@ -505,6 +512,70 @@ no_cmds_exec(prop_dictionary_t env, prop_dictionary_t oenv) exit(EXIT_SUCCESS); } +static int +wait_dad_exec(prop_dictionary_t env, prop_dictionary_t oenv) +{ +#ifdef INET6 + bool waiting; + struct ifaddrs *ifaddrs, *ifa; + struct in6_ifreq ifr6; + int s; + const struct timespec ts = { .tv_sec = 0, .tv_nsec = WAIT_DAD }; + const struct timespec add = { .tv_sec = wflag_secs, .tv_nsec = 0}; + struct timespec now, end; + + if (wflag_secs) { + if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) + err(EXIT_FAILURE, "clock_gettime"); + timespecadd(&now, &add, &end); + } + + if (getifaddrs(&ifaddrs) == -1) + err(EXIT_FAILURE, "getifaddrs"); + + for (;;) { + waiting = false; + for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + switch (ifa->ifa_addr->sa_family) { + case AF_INET6: + memset(&ifr6, 0, sizeof(ifr6)); + strncpy(ifr6.ifr_name, + ifa->ifa_name, sizeof(ifr6.ifr_name)); + ifr6.ifr_addr = + *(struct sockaddr_in6 *)ifa->ifa_addr; + if ((s = getsock(AF_INET6)) == -1) + err(EXIT_FAILURE, + "%s: getsock", __func__); + if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == -1) + err(EXIT_FAILURE, "SIOCGIFAFLAG_IN6"); + if (ifr6.ifr_ifru.ifru_flags6 & + IN6_IFF_TENTATIVE) + { + waiting = true; + break; + } + } + if (waiting) + break; + } + if (!waiting) + break; + nanosleep(&ts, NULL); + if (wflag_secs) { + if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) + err(EXIT_FAILURE, "clock_gettime"); + if (timespeccmp(&now, &end, >)) + errx(EXIT_FAILURE, "timed out"); + } + } + + freeifaddrs(ifaddrs); +#endif + exit(EXIT_SUCCESS); +} + static int media_status_exec(prop_dictionary_t env, prop_dictionary_t oenv) { @@ -549,6 +620,7 @@ main(int argc, char **argv) int ch, narg = 0, rc; prop_dictionary_t env, oenv; const char *ifname; + char *end; memset(match, 0, sizeof(match)); @@ -605,6 +677,14 @@ main(int argc, char **argv) vflag = true; break; + case 'w': + wflag = true; + wflag_secs = strtol(optarg, &end, 10); + if ((end != NULL && *end != '\0') || + wflag_secs < 0 || wflag_secs >= INT32_MAX) + errx(EXIT_FAILURE, "%s: not a number", optarg); + break; + case 'z': zflag = true; break; @@ -636,6 +716,9 @@ main(int argc, char **argv) start != &opt_family_only.pb_parser) start = &iface_only.pif_parser; break; + case 'w': + start = &wait_dad.pt_parser; + break; default: break; } @@ -644,19 +727,23 @@ main(int argc, char **argv) argv += optind; /* - * -l means "list all interfaces", and is mutally exclusive with + * -l means "list all interfaces", and is mutually exclusive with * all other flags/commands. * * -C means "list all names of cloners", and it mutually exclusive * with all other flags/commands. * * -a means "print status of all interfaces". + * + * -w means "spin until DAD completes for all addreseses", and is + * mutually exclusivewith all other flags/commands. */ - if ((lflag || Cflag) && (aflag || get_flag('m') || vflag || zflag)) + if ((lflag || Cflag || wflag) && + (aflag || get_flag('m') || vflag || zflag)) usage(); - if ((lflag || Cflag) && get_flag('L')) + if ((lflag || Cflag || wflag) && get_flag('L')) usage(); - if (lflag && Cflag) + if ((lflag && Cflag) || (lflag & wflag) || (Cflag && wflag)) usage(); nmatch = __arraycount(match); @@ -1399,10 +1486,11 @@ usage(void) " %s -a [-b] [-d] [-h] %s[-u] [-v] [-z] [ af ]\n" " %s -l [-b] [-d] [-s] [-u]\n" " %s -C\n" + " %s -w n\n" " %s interface create\n" " %s interface destroy\n", progname, flag_is_registered(gflags, 'm') ? "[-m] " : "", - progname, progname, progname, progname); + progname, progname, progname, progname, progname); prop_object_release((prop_object_t)env); exit(EXIT_FAILURE); diff --git a/sbin/rtsol/Makefile b/sbin/rtsol/Makefile deleted file mode 100644 index 096977a0daaf..000000000000 --- a/sbin/rtsol/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# $NetBSD: Makefile,v 1.13 2004/01/03 01:40:31 itojun Exp $ - -NOMAN= # defined - -.include - -PROG= rtsol -SRCS= rtsold.c rtsol.c if.c probe.c rtsock.c - -CPPFLAGS+=-DSMALL -DUSE_RTSOCK - -#MAN= rtsold.8 - -.PATH: ${NETBSDSRCDIR}/usr.sbin/rtsold - -LDADD+= -lutil -DPADD+= ${LIBUTIL} - -.include diff --git a/usr.sbin/postinstall/postinstall b/usr.sbin/postinstall/postinstall index 8e6a6dca60bd..c70bb18f7472 100755 --- a/usr.sbin/postinstall/postinstall +++ b/usr.sbin/postinstall/postinstall @@ -1,6 +1,6 @@ #!/bin/sh # -# $NetBSD: postinstall,v 1.179 2014/08/12 09:12:18 apb Exp $ +# $NetBSD: postinstall,v 1.180 2014/09/11 13:10:04 roy Exp $ # # Copyright (c) 2002-2008 The NetBSD Foundation, Inc. # All rights reserved. @@ -1332,7 +1332,7 @@ do_rc() quota \ racoon rpcbind raidframe raidframeparity random_seed rarpd \ rbootd rndctl root route6d routed rtadvd rtclocaltime \ - rtsold rwho \ + rwho \ savecore screenblank securelevel sshd \ staticroute swap1 swap2 sysctl sysdb syslogd \ timed tpctl ttys \ diff --git a/usr.sbin/rtsold/Makefile b/usr.sbin/rtsold/Makefile index ea941e7bf928..af75e8ecc3f3 100644 --- a/usr.sbin/rtsold/Makefile +++ b/usr.sbin/rtsold/Makefile @@ -1,17 +1,6 @@ -# $NetBSD: Makefile,v 1.15 2014/03/18 00:16:49 christos Exp $ - -WARNS?=6 -USE_FORT?= yes # network client (local server) - -PROG= rtsold -SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c - -CPPFLAGS+=-DUSE_RTSOCK +# $NetBSD: Makefile,v 1.16 2014/09/11 13:10:04 roy Exp $ MAN= rtsold.8 MLINKS= rtsold.8 rtsol.8 -LDADD+= -lutil -DPADD+= ${LIBUTIL} - .include diff --git a/usr.sbin/rtsold/dump.c b/usr.sbin/rtsold/dump.c deleted file mode 100644 index c6dda6480702..000000000000 --- a/usr.sbin/rtsold/dump.c +++ /dev/null @@ -1,146 +0,0 @@ -/* $NetBSD: dump.c,v 1.10 2014/03/18 00:16:49 christos Exp $ */ -/* $KAME: dump.c,v 1.10 2002/05/31 10:10:03 itojun Exp $ */ - -/* - * Copyright (C) 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "rtsold.h" - -static FILE *fp; - -static void dump_interface_status(void); -static const char *sec2str(time_t); -static const char *ifstatstr[] = { - "IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE" -}; - -static void -dump_interface_status(void) -{ - struct ifinfo *ifinfo; - struct timeval now; - - gettimeofday(&now, NULL); - - for (ifinfo = iflist; ifinfo; ifinfo = ifinfo->next) { - fprintf(fp, "Interface %s\n", ifinfo->ifname); - fprintf(fp, " probe interval: "); - if (ifinfo->probeinterval) { - fprintf(fp, "%d\n", ifinfo->probeinterval); - fprintf(fp, " probe timer: %d\n", ifinfo->probetimer); - } else { - fprintf(fp, "infinity\n"); - fprintf(fp, " no probe timer\n"); - } - fprintf(fp, " interface status: %s\n", - ifinfo->active > 0 ? "active" : "inactive"); - fprintf(fp, " rtsold status: %s\n", ifstatstr[ifinfo->state]); - fprintf(fp, " carrier detection: %s\n", - ifinfo->mediareqok ? "available" : "unavailable"); - fprintf(fp, " probes: %d, dadcount = %d\n", - ifinfo->probes, ifinfo->dadcount); - if (ifinfo->timer.tv_sec == tm_max.tv_sec && - ifinfo->timer.tv_usec == tm_max.tv_usec) - fprintf(fp, " no timer\n"); - else { - fprintf(fp, " timer: interval=%d:%d, expire=%s\n", - (int)ifinfo->timer.tv_sec, - (int)ifinfo->timer.tv_usec, - (ifinfo->expire.tv_sec < now.tv_sec) ? "expired" - : sec2str(ifinfo->expire.tv_sec - now.tv_sec)); - } - fprintf(fp, " number of valid RAs: %d\n", ifinfo->racnt); - } -} - -void -rtsold_dump_file(const char *dumpfile) -{ - if ((fp = fopen(dumpfile, "w")) == NULL) { - warnmsg(LOG_WARNING, __func__, "open a dump file(%s): %s", - dumpfile, strerror(errno)); - return; - } - dump_interface_status(); - fclose(fp); -} - -static const char * -sec2str(time_t total) -{ - static char result[256]; - int days, hours, mins, secs; - int first = 1; - char *p = result; - char *ep = &result[sizeof(result)]; - int n; - - days = (int)(total / 3600 / 24); - hours = (int)((total / 3600) % 24); - mins = (int)((total / 60) % 60); - secs = (int)(total % 60); - - if (days) { - first = 0; - n = snprintf(p, (size_t)(ep - p), "%dd", days); - if (n < 0 || n >= ep - p) - return "?"; - p += n; - } - if (!first || hours) { - first = 0; - n = snprintf(p, (size_t)(ep - p), "%dh", hours); - if (n < 0 || n >= ep - p) - return "?"; - p += n; - } - if (!first || mins) { - first = 0; - n = snprintf(p, (size_t)(ep - p), "%dm", mins); - if (n < 0 || n >= ep - p) - return "?"; - p += n; - } - snprintf(p, (size_t)(ep - p), "%ds", secs); - return result; -} diff --git a/usr.sbin/rtsold/if.c b/usr.sbin/rtsold/if.c deleted file mode 100644 index 313cac9baf99..000000000000 --- a/usr.sbin/rtsold/if.c +++ /dev/null @@ -1,366 +0,0 @@ -/* $NetBSD: if.c,v 1.16 2014/03/18 00:16:49 christos Exp $ */ -/* $KAME: if.c,v 1.18 2002/05/31 10:10:03 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtsold.h" - -static int ifsock; - -static int get_llflag(const char *); -static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); - -int -ifinit(void) -{ - ifsock = rssock; - - return 0; -} - -int -interface_up(char *name) -{ - struct ifreq ifr; - int llflag; - - strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - - if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) { - warnmsg(LOG_WARNING, __func__, "ioctl(SIOCGIFFLAGS): %s", - strerror(errno)); - return -1; - } - if (!(ifr.ifr_flags & IFF_UP)) { - ifr.ifr_flags |= IFF_UP; - if (ioctl(ifsock, SIOCSIFFLAGS, &ifr) < 0) - warnmsg(LOG_ERR, __func__, - "ioctl(SIOCSIFFLAGS): %s", strerror(errno)); - return -1; - } - - warnmsg(LOG_DEBUG, __func__, "checking if %s is ready...", name); - - llflag = get_llflag(name); - if (llflag < 0) { - warnmsg(LOG_WARNING, __func__, - "get_llflag() failed, anyway I'll try"); - return 0; - } - - if (!(llflag & IN6_IFF_NOTREADY)) { - warnmsg(LOG_DEBUG, __func__, "%s is ready", name); - return 0; - } else { - if (llflag & IN6_IFF_TENTATIVE) { - warnmsg(LOG_DEBUG, __func__, "%s is tentative", - name); - return IFS_TENTATIVE; - } - if (llflag & IN6_IFF_DUPLICATED) - warnmsg(LOG_DEBUG, __func__, "%s is duplicated", - name); - return -1; - } -} - -int -interface_status(struct ifinfo *ifinfo) -{ - char *ifname = ifinfo->ifname; - struct ifreq ifr; - struct ifmediareq ifmr; - - /* get interface flags */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) { - warnmsg(LOG_ERR, __func__, "ioctl(SIOCGIFFLAGS) on %s: %s", - ifname, strerror(errno)); - return -1; - } - /* - * if one of UP and RUNNING flags is dropped, - * the interface is not active. - */ - if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { - goto inactive; - } - - /* Next, check carrier on the interface, if possible */ - if (!ifinfo->mediareqok) - goto active; - memset(&ifmr, 0, sizeof(ifmr)); - strncpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); - - if (ioctl(ifsock, SIOCGIFMEDIA, &ifmr) < 0) { - if (errno != EINVAL) { - warnmsg(LOG_DEBUG, __func__, - "ioctl(SIOCGIFMEDIA) on %s: %s", - ifname, strerror(errno)); - return -1; - } - /* - * EINVAL simply means that the interface does not support - * the SIOCGIFMEDIA ioctl. We regard it alive. - */ - ifinfo->mediareqok = 0; - goto active; - } - - if (ifmr.ifm_status & IFM_AVALID) { - switch (ifmr.ifm_active & IFM_NMASK) { - case IFM_ETHER: - if (ifmr.ifm_status & IFM_ACTIVE) - goto active; - else - goto inactive; - break; - default: - goto inactive; - } - } - - inactive: - return 0; - - active: - return 1; -} - -#define ROUNDUP(a, size) \ - (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) - -#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ - ((char *)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\ - sizeof(u_long)) : sizeof(u_long))) -#define ROUNDUP8(a) (1 + (((a) - 1) | 7)) - -size_t -lladdropt_length(struct sockaddr_dl *sdl) -{ - switch (sdl->sdl_type) { - case IFT_ETHER: -#ifdef IFT_IEEE80211 - case IFT_IEEE80211: -#endif - return ROUNDUP8(ETHER_ADDR_LEN + 2); - default: - return 0; - } -} - -void -lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt) -{ - char *addr; - - ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */ - - switch (sdl->sdl_type) { - case IFT_ETHER: -#ifdef IFT_IEEE80211 - case IFT_IEEE80211: -#endif - ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3; - addr = (char *)(ndopt + 1); - memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN); - break; - default: - warnmsg(LOG_ERR, __func__, - "unsupported link type(%d)", sdl->sdl_type); - exit(1); - } - - return; -} - -struct sockaddr_dl * -if_nametosdl(char *name) -{ - int mib[6] = {CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; - char *buf, *next, *lim; - size_t len; - struct if_msghdr *ifm; - struct sockaddr *sa, *rti_info[RTAX_MAX]; - struct sockaddr_dl *sdl = NULL, *ret_sdl; - - if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) - return NULL; - if ((buf = malloc(len)) == NULL) - return NULL; - if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { - free(buf); - return NULL; - } - - lim = buf + len; - for (next = buf; next < lim; next += ifm->ifm_msglen) { - ifm = (struct if_msghdr *)next; - if (ifm->ifm_type == RTM_IFINFO) { - sa = (struct sockaddr *)(ifm + 1); - get_rtaddrs(ifm->ifm_addrs, sa, rti_info); - if ((sa = rti_info[RTAX_IFP]) != NULL) { - if (sa->sa_family == AF_LINK) { - sdl = (struct sockaddr_dl *)sa; - if (strlen(name) != sdl->sdl_nlen) - continue; /* not same len */ - if (strncmp(&sdl->sdl_data[0], - name, - sdl->sdl_nlen) == 0) { - break; - } - } - } - } - } - if (next == lim || sdl == NULL) { - /* search failed */ - free(buf); - return NULL; - } - - if ((ret_sdl = malloc(sdl->sdl_len)) == NULL) { - free(buf); - return NULL; - } - memcpy(ret_sdl, sdl, sdl->sdl_len); - - free(buf); - return(ret_sdl); -} - -int -getinet6sysctl(int code) -{ - int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 }; - int value; - size_t size; - - mib[3] = code; - size = sizeof(value); - if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0) < 0) - return -1; - else - return value; -} - -/*------------------------------------------------------------*/ - -/* get ia6_flags for link-local addr on if. returns -1 on error. */ -static int -get_llflag(const char *name) -{ - struct ifaddrs *ifap, *ifa; - struct in6_ifreq ifr6; - struct sockaddr_in6 *sin6; - int s; - - if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) { - warnmsg(LOG_ERR, __func__, "socket(SOCK_DGRAM): %s", - strerror(errno)); - exit(1); - } - if (getifaddrs(&ifap) != 0) { - warnmsg(LOG_ERR, __func__, "getifaddrs: %s", - strerror(errno)); - exit(1); - } - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (strlen(ifa->ifa_name) != strlen(name) || - strncmp(ifa->ifa_name, name, strlen(name)) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; - if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - continue; - - memset(&ifr6, 0, sizeof(ifr6)); - strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name)); - memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len); - if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { - warnmsg(LOG_ERR, __func__, - "ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno)); - exit(1); - } - - freeifaddrs(ifap); - close(s); - return ifr6.ifr_ifru.ifru_flags6; - } - - freeifaddrs(ifap); - close(s); - return -1; -} - - -static void -get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) -{ - int i; - - for (i = 0; i < RTAX_MAX; i++) { - if (addrs & (1 << i)) { - rti_info[i] = sa; - NEXT_SA(sa); - } else - rti_info[i] = NULL; - } -} diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c deleted file mode 100644 index 46f60fcd1fd4..000000000000 --- a/usr.sbin/rtsold/probe.c +++ /dev/null @@ -1,182 +0,0 @@ -/* $NetBSD: probe.c,v 1.12 2014/03/18 00:16:49 christos Exp $ */ -/* $KAME: probe.c,v 1.15 2002/05/31 21:22:08 itojun Exp $ */ - -/* - * Copyright (C) 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include "rtsold.h" - -static struct msghdr sndmhdr; -static struct iovec sndiov[2]; -static int probesock; -static void sendprobe(struct in6_addr *, struct ifinfo *); - -int -probe_init(void) -{ - size_t scmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int)); - static u_char *sndcmsgbuf = NULL; - - if (sndcmsgbuf == NULL && - (sndcmsgbuf = malloc(scmsglen)) == NULL) { - warnmsg(LOG_ERR, __func__, "malloc failed"); - return -1; - } - - if ((probesock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) { - warnmsg(LOG_ERR, __func__, "socket: %s", strerror(errno)); - return -1; - } - - /* make the socket send-only */ - if (shutdown(probesock, 0)) { - warnmsg(LOG_ERR, __func__, "shutdown: %s", strerror(errno)); - return -1; - } - - /* initialize msghdr for sending packets */ - sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); - sndmhdr.msg_iov = sndiov; - sndmhdr.msg_iovlen = 1; - sndmhdr.msg_control = sndcmsgbuf; - sndmhdr.msg_controllen = (socklen_t)scmsglen; - return 0; -} - -/* - * Probe if each router in the default router list is still alive. - */ -void -defrouter_probe(struct ifinfo *ifinfo) -{ - char ntopbuf[INET6_ADDRSTRLEN]; - struct in6_drlist dr; - int s, i; - int ifindex = ifinfo->sdl->sdl_index; - - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - warnmsg(LOG_ERR, __func__, "socket: %s", strerror(errno)); - return; - } - memset(&dr, 0, sizeof(dr)); - strlcpy(dr.ifname, "lo0", sizeof dr.ifname); /* dummy interface */ - if (ioctl(s, SIOCGDRLST_IN6, &dr) < 0) { - warnmsg(LOG_ERR, __func__, "ioctl(SIOCGDRLST_IN6): %s", - strerror(errno)); - goto closeandend; - } - - for (i = 0; i < PRLSTSIZ && dr.defrouter[i].if_index; i++) { - if (ifindex && dr.defrouter[i].if_index == ifindex) { - /* sanity check */ - if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) { - warnmsg(LOG_ERR, __func__, - "default router list contains a " - "non-link-local address(%s)", - inet_ntop(AF_INET6, - &dr.defrouter[i].rtaddr, - ntopbuf, INET6_ADDRSTRLEN)); - continue; /* ignore the address */ - } - sendprobe(&dr.defrouter[i].rtaddr, ifinfo); - } - } - -closeandend: - close(s); -} - -static void -sendprobe(struct in6_addr *addr, struct ifinfo *ifinfo) -{ - char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; - struct sockaddr_in6 sa6_probe; - struct in6_pktinfo *pi; - struct cmsghdr *cm; - 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 = &sa6_probe; - sndmhdr.msg_iov[0].iov_base = NULL; - sndmhdr.msg_iov[0].iov_len = 0; - - cm = CMSG_FIRSTHDR(&sndmhdr); - /* specify the outgoing interface */ - cm->cmsg_level = IPPROTO_IPV6; - cm->cmsg_type = IPV6_PKTINFO; - cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); - pi = (struct in6_pktinfo *)CMSG_DATA(cm); - memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ - pi->ipi6_ifindex = ifindex; - - /* specify the hop limit of the packet for safety */ - cm = CMSG_NXTHDR(&sndmhdr, cm); - cm->cmsg_level = IPPROTO_IPV6; - cm->cmsg_type = IPV6_HOPLIMIT; - cm->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); - - warnmsg(LOG_DEBUG, __func__, "probe a router %s on %s", - inet_ntop(AF_INET6, addr, ntopbuf, INET6_ADDRSTRLEN), - if_indextoname(ifindex, ifnamebuf)); - - if (sendmsg(probesock, &sndmhdr, 0)) - warnmsg(LOG_ERR, __func__, "sendmsg on %s: %s", - if_indextoname(ifindex, ifnamebuf), strerror(errno)); -} diff --git a/usr.sbin/rtsold/rtsock.c b/usr.sbin/rtsold/rtsock.c deleted file mode 100644 index c974bbfa67b3..000000000000 --- a/usr.sbin/rtsold/rtsock.c +++ /dev/null @@ -1,175 +0,0 @@ -/* $NetBSD: rtsock.c,v 1.7 2014/03/18 00:16:49 christos Exp $ */ -/* $KAME: rtsock.c,v 1.4 2001/09/19 06:59:41 sakane Exp $ */ - -/* - * Copyright (C) 2000 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rtsold.h" - -#define ROUNDUP(a, size) \ - (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) - -#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ - ((char *)(ap) + \ - ((ap)->sa_len ? ROUNDUP((ap)->sa_len, sizeof(u_long)) \ - : sizeof(u_long))) - -#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/ -static int rtsock_input_ifannounce(int, struct rt_msghdr *, char *); -#endif - -static struct { - u_char type; - size_t minlen; - int (*func) __P((int, struct rt_msghdr *, char *)); -} rtsock_dispatch[] = { -#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/ - { RTM_IFANNOUNCE, sizeof(struct if_announcemsghdr), - rtsock_input_ifannounce }, -#endif - { 0, 0, NULL }, -}; - -int -rtsock_open(void) -{ - - return socket(PF_ROUTE, SOCK_RAW, 0); -} - -int -rtsock_input(int s) -{ - ssize_t n; - char msg[2048]; - char *lim, *next; - struct rt_msghdr *rtm; - int idx; - size_t len; - int ret = 0; - const size_t lenlim = - offsetof(struct rt_msghdr, rtm_msglen) + sizeof(rtm->rtm_msglen); - - n = read(s, msg, sizeof(msg)); - - lim = msg + n; - for (next = msg; next < lim; next += len) { - rtm = (struct rt_msghdr *)next; - if (lim - next < (intptr_t)lenlim) - break; - len = rtm->rtm_msglen; - if (len < lenlim) - break; - - if (dflag > 1) { - warnmsg(LOG_INFO, __func__, - "rtmsg type %d, len=%lu", rtm->rtm_type, - (u_long)len); - } - - for (idx = 0; rtsock_dispatch[idx].func; idx++) { - if (rtm->rtm_type != rtsock_dispatch[idx].type) - continue; - if (rtm->rtm_msglen < rtsock_dispatch[idx].minlen) { - warnmsg(LOG_INFO, __func__, - "rtmsg type %d too short!", rtm->rtm_type); - continue; - } - - ret = (*rtsock_dispatch[idx].func)(s, rtm, lim); - break; - } - } - - return ret; -} - -#ifdef RTM_IFANNOUNCE /*NetBSD 1.5 or later*/ -static int -rtsock_input_ifannounce(int s, struct rt_msghdr *rtm, char *lim) -{ - struct if_announcemsghdr *ifan; - struct ifinfo *ifinfo; - - ifan = (struct if_announcemsghdr *)rtm; - if ((char *)(ifan + 1) > lim) - return -1; - - switch (ifan->ifan_what) { - case IFAN_ARRIVAL: - /* - * XXX for NetBSD 1.5, interface index will monotonically be - * increased as new pcmcia card gets inserted. - * we may be able to do a name-based interface match, - * and call ifreconfig() to enable the interface again. - */ - warnmsg(LOG_INFO, __func__, - "interface %s inserted", ifan->ifan_name); - break; - case IFAN_DEPARTURE: - warnmsg(LOG_WARNING, __func__, - "interface %s removed", ifan->ifan_name); - ifinfo = find_ifinfo(ifan->ifan_index); - if (ifinfo) { - if (dflag > 1) { - warnmsg(LOG_INFO, __func__, - "bring interface %s to DOWN state", - ifan->ifan_name); - } - ifinfo->state = IFS_DOWN; - } - break; - } - - return 0; -} -#endif diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c deleted file mode 100644 index 9c7d1e6563c7..000000000000 --- a/usr.sbin/rtsold/rtsol.c +++ /dev/null @@ -1,346 +0,0 @@ -/* $NetBSD: rtsol.c,v 1.16 2014/03/18 00:16:49 christos Exp $ */ -/* $KAME: rtsol.c,v 1.15 2002/05/31 10:10:03 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "rtsold.h" - -#define ALLROUTER "ff02::2" - -static struct msghdr rcvmhdr; -static struct msghdr sndmhdr; -static struct iovec rcviov[2]; -static struct iovec sndiov[2]; -static struct sockaddr_in6 from; - -int rssock; - -static struct sockaddr_in6 sin6_allrouters = { - .sin6_len = sizeof(sin6_allrouters), - .sin6_family = AF_INET6 -}; - -int -sockopen(void) -{ - static u_char *rcvcmsgbuf = NULL, *sndcmsgbuf = NULL; - size_t rcvcmsglen, sndcmsglen; - int on; - static u_char answer[1500]; - struct icmp6_filter filt; - - sndcmsglen = rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int)); - if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { - warnmsg(LOG_ERR, __func__, - "malloc for receive msghdr failed"); - return -1; - } - if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL) { - warnmsg(LOG_ERR, __func__, - "malloc for send msghdr failed"); - return -1; - } - memset(&sin6_allrouters, 0, sizeof(struct sockaddr_in6)); - sin6_allrouters.sin6_family = AF_INET6; - sin6_allrouters.sin6_len = sizeof(sin6_allrouters); - if (inet_pton(AF_INET6, ALLROUTER, - &sin6_allrouters.sin6_addr.s6_addr) != 1) { - warnmsg(LOG_ERR, __func__, "inet_pton failed for %s", - ALLROUTER); - return -1; - } - - if ((rssock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { - warnmsg(LOG_ERR, __func__, "socket: %s", strerror(errno)); - return -1; - } - - /* specify to tell receiving interface */ - on = 1; -#ifdef IPV6_RECVPKTINFO - if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, - sizeof(on)) < 0) { - warnmsg(LOG_ERR, __func__, "IPV6_RECVPKTINFO: %s", - strerror(errno)); - exit(1); - } -#else /* old adv. API */ - if (setsockopt(rssock, IPPROTO_IPV6, IPV6_PKTINFO, &on, - sizeof(on)) < 0) { - warnmsg(LOG_ERR, __func__, "IPV6_PKTINFO: %s", - strerror(errno)); - exit(1); - } -#endif - - on = 1; - /* specify to tell value of hoplimit field of received IP6 hdr */ -#ifdef IPV6_RECVHOPLIMIT - if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, - sizeof(on)) < 0) { - warnmsg(LOG_ERR, __func__, "IPV6_RECVHOPLIMIT: %s", - strerror(errno)); - exit(1); - } -#else /* old adv. API */ - if (setsockopt(rssock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, - sizeof(on)) < 0) { - warnmsg(LOG_ERR, __func__, "IPV6_HOPLIMIT: %s", - strerror(errno)); - exit(1); - } -#endif - - /* specfiy to accept only router advertisements on the socket */ - ICMP6_FILTER_SETBLOCKALL(&filt); - ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); - if (setsockopt(rssock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, - sizeof(filt)) == -1) { - warnmsg(LOG_ERR, __func__, "setsockopt(ICMP6_FILTER): %s", - strerror(errno)); - return -1; - } - - /* initialize msghdr for receiving packets */ - rcviov[0].iov_base = answer; - rcviov[0].iov_len = sizeof(answer); - rcvmhdr.msg_name = &from; - rcvmhdr.msg_namelen = sizeof(from); - rcvmhdr.msg_iov = rcviov; - rcvmhdr.msg_iovlen = 1; - rcvmhdr.msg_control = rcvcmsgbuf; - rcvmhdr.msg_controllen = (socklen_t)rcvcmsglen; - - /* initialize msghdr for sending packets */ - sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); - sndmhdr.msg_iov = sndiov; - sndmhdr.msg_iovlen = 1; - sndmhdr.msg_control = sndcmsgbuf; - sndmhdr.msg_controllen = (socklen_t)sndcmsglen; - - return rssock; -} - -void -sendpacket(struct ifinfo *ifinfo) -{ - struct in6_pktinfo *pi; - struct cmsghdr *cm; - int hoplimit = 255; - ssize_t i; - struct sockaddr_in6 dst; - - dst = sin6_allrouters; - dst.sin6_scope_id = ifinfo->linkid; - - sndmhdr.msg_name = &dst; - sndmhdr.msg_iov[0].iov_base = ifinfo->rs_data; - sndmhdr.msg_iov[0].iov_len = ifinfo->rs_datalen; - - cm = CMSG_FIRSTHDR(&sndmhdr); - /* specify the outgoing interface */ - cm->cmsg_level = IPPROTO_IPV6; - cm->cmsg_type = IPV6_PKTINFO; - cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); - pi = (struct in6_pktinfo *)CMSG_DATA(cm); - memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ - pi->ipi6_ifindex = ifinfo->sdl->sdl_index; - - /* specify the hop limit of the packet */ - cm = CMSG_NXTHDR(&sndmhdr, cm); - cm->cmsg_level = IPPROTO_IPV6; - cm->cmsg_type = IPV6_HOPLIMIT; - cm->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); - - warnmsg(LOG_DEBUG, __func__, - "send RS on %s, whose state is %d", - ifinfo->ifname, ifinfo->state); - - i = sendmsg(rssock, &sndmhdr, 0); - - if (i < 0 || (size_t)i != ifinfo->rs_datalen) { - /* - * ENETDOWN is not so serious, especially when using several - * network cards on a mobile node. We ignore it. - */ - if (errno != ENETDOWN || dflag > 0) - warnmsg(LOG_ERR, __func__, "sendmsg on %s: %s", - ifinfo->ifname, strerror(errno)); - } - - /* update counter */ - ifinfo->probes++; -} - -void -rtsol_input(int s) -{ - char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; - int *hlimp = NULL; - ssize_t i; - size_t ifindex = 0; - struct in6_pktinfo *pi = NULL; - struct ifinfo *ifi = NULL; - struct icmp6_hdr *icp; - struct cmsghdr *cm; - - /* get message */ - if ((i = recvmsg(s, &rcvmhdr, 0)) < 0) { - warnmsg(LOG_ERR, __func__, "recvmsg: %s", strerror(errno)); - return; - } - - /* extract optional information via Advanced API */ - for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr); cm; - cm = (struct cmsghdr *)CMSG_NXTHDR(&rcvmhdr, cm)) { - if (cm->cmsg_level == IPPROTO_IPV6 && - cm->cmsg_type == IPV6_PKTINFO && - cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { - pi = (struct in6_pktinfo *)(CMSG_DATA(cm)); - ifindex = pi->ipi6_ifindex; - } - if (cm->cmsg_level == IPPROTO_IPV6 && - cm->cmsg_type == IPV6_HOPLIMIT && - cm->cmsg_len == CMSG_LEN(sizeof(int))) - hlimp = (int *)CMSG_DATA(cm); - } - - if (ifindex == 0) { - warnmsg(LOG_ERR, __func__, - "failed to get receiving interface"); - return; - } - if (hlimp == NULL) { - warnmsg(LOG_ERR, __func__, - "failed to get receiving hop limit"); - return; - } - - if (i < (ssize_t)sizeof(struct nd_router_advert)) { - warnmsg(LOG_ERR, __func__, - "packet size(%zd) is too short", i); - return; - } - - icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base; - - if (icp->icmp6_type != ND_ROUTER_ADVERT) { - warnmsg(LOG_ERR, __func__, - "invalid icmp type(%d) from %s on %s", icp->icmp6_type, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - if (icp->icmp6_code != 0) { - warnmsg(LOG_ERR, __func__, - "invalid icmp code(%d) from %s on %s", icp->icmp6_code, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - if (*hlimp != 255) { - warnmsg(LOG_NOTICE, __func__, - "invalid RA with hop limit(%d) from %s on %s", - *hlimp, - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - if (pi && !IN6_IS_ADDR_LINKLOCAL(&from.sin6_addr)) { - warnmsg(LOG_NOTICE, __func__, - "invalid RA with non link-local source from %s on %s", - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - /* xxx: more validation? */ - - if ((ifi = find_ifinfo(pi->ipi6_ifindex)) == NULL) { - warnmsg(LOG_NOTICE, __func__, - "received RA from %s on an unexpected IF(%s)", - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), - if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - return; - } - - warnmsg(LOG_DEBUG, __func__, - "received RA from %s on %s, state is %d", - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, INET6_ADDRSTRLEN), - ifi->ifname, ifi->state); - - ifi->racnt++; - - switch (ifi->state) { - case IFS_IDLE: /* should be ignored */ - case IFS_DELAY: /* right? */ - break; - case IFS_PROBE: - ifi->state = IFS_IDLE; - ifi->probes = 0; - rtsol_timer_update(ifi); - break; - } -} diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8 index 48fc4db9ca3f..f2ee8d397d8e 100644 --- a/usr.sbin/rtsold/rtsold.8 +++ b/usr.sbin/rtsold/rtsold.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: rtsold.8,v 1.33 2013/05/26 17:25:53 wiz Exp $ +.\" $NetBSD: rtsold.8,v 1.34 2014/09/11 13:10:04 roy Exp $ .\" $KAME: rtsold.8,v 1.17 2001/07/09 22:30:37 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 24, 2013 +.Dd September 9, 2014 .Dt RTSOLD 8 .Os .\" @@ -36,184 +36,9 @@ .Nm rtsold .Nd router solicitation daemon .\" -.Sh SYNOPSIS -.Nm rtsold -.Op Fl 1Ddfm -.Ar interface ... -.Nm rtsold -.Op Fl 1Ddfm -.Fl a -.Nm rtsol -.Op Fl Dd -.Ar interface ... -.Nm rtsol -.Op Fl Dd -.Fl a -.\" .Sh DESCRIPTION .Nm -is the daemon program to send ICMPv6 Router Solicitation messages -on the specified interfaces. -If a node (re)attaches to a link, -.Nm -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 hosts -.Pq non-router nodes -only. -.Pp -If you invoke the program as -.Nm rtsol , -it will transmit probes from the specified -.Ar interface , -without becoming a daemon. -In other words, +and .Nm rtsol -behaves as -.Dq rtsold -f1 interface ... . -.Pp -Specifically, -.Nm -sends at most 3 Router Solicitations on an interface -after one of the following events: -.Bl -bullet -.It -Just after invocation of the -.Nm -daemon. -.It -The interface is up after a temporary interface failure. -.Nm -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. -In such cases, -.Nm -cannot detect the change of the interface status. -.It -Every 60 seconds if the -.Fl m -option is specified and the -.Nm -daemon cannot get the interface status. -This feature does not conform to the IPv6 neighbor discovery -specification, but is provided for mobile stations. -The default interval for router advertisements, -which is approximately 10 minutes, -is slightly long for mobile stations. -This feature is provided -for such stations so that they can find new routers as soon as possible -when they attach to another link. -.El -.Pp -Once -.Nm -has sent a Router Solicitation, and has received a valid Router Advertisement, -it refrains from sending additional solicitations on that interface, until -the next time one of the above events occurs. -.Pp -When sending a Router Solicitation on an interface, -.Nm -includes a Source Link-layer address option if the interface -has a link-layer address. -.Pp -Upon receipt of signal -.Dv SIGUSR1 , -.Nm -will dump the current internal state into -.Pa /var/run/rtsold.dump . -Also note that -.Nm -will not be able to update the kernel routing tables unless -.Xr sysctl 8 -reports that -net.inet6.ip6.accept_rtadv=1. -.\" -.Pp -The options are as follows: -.Bl -tag -width indent -.It Fl 1 -Perform only one probe. -Transmit Router Solicitation packets until at least one valid Router -Advertisement packet has arrived on each -.Ar interface , -then exit. -.It Fl a -Autoprobe outgoing interfaces. -.Nm -will try to find a non-loopback, non-point-to-point, IPv6-capable interfaces, -and send router solicitation messages on all of them. -.It Fl D -Enable more debugging (than that offered by the -.Fl d -option) including the printing of internal timer information. -.It Fl d -Enable debugging. -.It Fl f -This option prevents -.Nm -from becoming a daemon (foreground mode). -Warning messages are generated to standard error -instead of -.Xr syslog 3 . -.It Fl m -Enable mobility support. -If this option is specified, -.Nm -sends probing packets to default routers that have advertised Router -Advertisements -when the node (re)attaches to an interface. -Moreover, if the option is specified, -.Nm -periodically sends Router Solicitation on an interface that does not support -the -.Dv SIOCGIFMEDIA -ioctl. -.El -.\" -.Sh EXIT STATUS -.Ex -std rtsold -.\" -.Sh FILES -.Bl -tag -width /var/run/rtsold.dumpXX -compact -.It Pa /var/run/rtsold.pid -The PID of the currently running -.Nm rtsold . -.It Pa /var/run/rtsold.dump -Internal state dump file. -.El -.\" -.Sh SEE ALSO -.Xr rtadvd 8 , -.Xr sysctl 8 -.\" -.Sh HISTORY -The -.Nm -command is based on the -.Nm rtsol -command, which first appeared in the WIDE/KAME IPv6 protocol stack kit. -.Nm rtsol -is now integrated into -.Nm . -.\" -.Sh BUGS -In some operating systems, when a PCMCIA network card is removed -and reinserted, the corresponding interface index is changed. -However, -.Nm -assumes such changes will not occur, 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 -You may see kernel error messages if you try to autoconfigure a host with -multiple interfaces. +have been removed from NetBSD as their functionality is now included in +.Xr dhcpcd 8 . diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c deleted file mode 100644 index 2f22c434a230..000000000000 --- a/usr.sbin/rtsold/rtsold.c +++ /dev/null @@ -1,749 +0,0 @@ -/* $NetBSD: rtsold.c,v 1.42 2014/03/25 21:07:59 joerg Exp $ */ -/* $KAME: rtsold.c,v 1.77 2004/01/03 01:35:13 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtsold.h" - -struct ifinfo *iflist; -struct timeval tm_max = {0x7fffffff, 0x7fffffff}; -static int log_upto = 999; -static int fflag = 0; -static int isdaemon = 0; - -int aflag = 0; -int dflag = 0; - -/* protocol constatns */ -#define MAX_RTR_SOLICITATION_DELAY 1 /* second */ -#define RTR_SOLICITATION_INTERVAL 4 /* seconds */ -#define MAX_RTR_SOLICITATIONS 3 /* times */ - -/* - * implementation dependent constants in seconds - * XXX: should be configurable - */ -#define PROBE_INTERVAL 60 - -/* static variables and functions */ -static int mobile_node = 0; -#ifndef SMALL -static int do_dump; -static const char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */ -#endif - -#if 0 -static int ifreconfig(char *); -#endif -static int make_packet(struct ifinfo *); -static struct timeval *rtsol_check_timer(void); - -#ifndef SMALL -static void rtsold_set_dump_file(int); -#endif -__dead static void usage(void); - -int -main(int argc, char **argv) -{ - int s, ch, once = 0; - struct timeval *timeout; - const char *ident; - const char *opts; - struct pollfd set[2]; -#ifdef USE_RTSOCK - int rtsock; -#endif - - /* - * Initialization - */ - ident = getprogname(); - isdaemon = ident[strlen(ident) - 1] == 'd'; - - /* get option */ - if (!isdaemon) { - fflag = 1; - once = 1; - opts = "adD"; - } else - opts = "adDfm1"; - - while ((ch = getopt(argc, argv, opts)) != -1) { - 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(); - /*NOTREACHED*/ - } - } - argc -= optind; - argv += optind; - - if ((!aflag && argc == 0) || (aflag && argc != 0)) { - usage(); - /*NOTREACHED*/ - } - - /* set log level */ - if (dflag == 0) - log_upto = LOG_NOTICE; - if (!fflag) { - openlog(ident, LOG_NDELAY|LOG_PID, LOG_DAEMON); - if (log_upto >= 0) - setlogmask(LOG_UPTO(log_upto)); - } - - /* 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"); - -#ifndef SMALL - /* initialization to dump internal status to a file */ - signal(SIGUSR1, rtsold_set_dump_file); -#endif - - if (!fflag) - daemon(0, 0); /* act as a daemon */ - - /* - * 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) { - warnmsg(LOG_ERR, __func__, "failed to open a socket"); - exit(1); - /*NOTREACHED*/ - } - set[0].fd = s; - set[0].events = POLLIN; - - set[1].fd = -1; - -#ifdef USE_RTSOCK - if ((rtsock = rtsock_open()) < 0) { - warnmsg(LOG_ERR, __func__, "failed to open a socket"); - exit(1); - /*NOTREACHED*/ - } - set[1].fd = rtsock; - set[1].events = POLLIN; -#endif - - /* configuration per interface */ - if (ifinit()) { - warnmsg(LOG_ERR, __func__, - "failed to initilizatoin interfaces"); - exit(1); - /*NOTREACHED*/ - } - if (aflag) - argv = autoifprobe(); - while (argv && *argv) { - if (ifconfig(*argv)) { - warnmsg(LOG_ERR, __func__, - "failed to initialize %s", *argv); - exit(1); - /*NOTREACHED*/ - } - argv++; - } - - /* setup for probing default routers */ - if (probe_init()) { - warnmsg(LOG_ERR, __func__, - "failed to setup for probing routers"); - exit(1); - /*NOTREACHED*/ - } - - /* dump the current pid */ - if (!once) { - if (pidfile(NULL) < 0) { - warnmsg(LOG_ERR, __func__, - "failed to open a pid log file: %s", - strerror(errno)); - } - } - - for (;;) { /* main loop */ - int e; - -#ifndef SMALL - if (do_dump) { /* SIGUSR1 */ - do_dump = 0; - rtsold_dump_file(dumpfilename); - } -#endif - - timeout = rtsol_check_timer(); - - if (once) { - struct ifinfo *ifi; - - /* if we have no timeout, we are done (or failed) */ - if (timeout == NULL) - break; - - /* if all interfaces have got RA packet, we are done */ - for (ifi = iflist; ifi; ifi = ifi->next) { - if (ifi->state != IFS_DOWN && ifi->racnt == 0) - break; - } - if (ifi == NULL) - break; - } - e = poll(set, 2, (int)(timeout ? - (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : - INFTIM)); - if (e < 1) { - if (e < 0 && errno != EINTR) { - warnmsg(LOG_ERR, __func__, "poll: %s", - strerror(errno)); - } - continue; - } - - /* packet reception */ -#ifdef USE_RTSOCK - if (set[1].revents & POLLIN) - rtsock_input(rtsock); -#endif - if (set[0].revents & POLLIN) - rtsol_input(s); - } - /* NOTREACHED */ - - return 0; -} - -int -ifconfig(char *ifname) -{ - struct ifinfo *ifinfo; - struct sockaddr_dl *sdl; - int flags; - - if ((sdl = if_nametosdl(ifname)) == NULL) { - warnmsg(LOG_ERR, __func__, - "failed to get link layer information for %s", ifname); - return -1; - } - if (find_ifinfo(sdl->sdl_index)) { - warnmsg(LOG_ERR, __func__, - "interface %s was already configured", ifname); - free(sdl); - return -1; - } - - if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) { - warnmsg(LOG_ERR, __func__, "memory allocation failed"); - free(sdl); - return -1; - } - memset(ifinfo, 0, sizeof(*ifinfo)); - ifinfo->sdl = sdl; - - strlcpy(ifinfo->ifname, ifname, sizeof(ifinfo->ifname)); - - /* construct a router solicitation message */ - 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. - */ - ifinfo->mediareqok = 1; - ifinfo->active = interface_status(ifinfo); - if (!ifinfo->mediareqok) { - /* - * probe routers periodically even if the link status - * does not change. - */ - ifinfo->probeinterval = PROBE_INTERVAL; - } - - /* activate interface: interface_up returns 0 on success */ - flags = interface_up(ifinfo->ifname); - if (flags == 0) - ifinfo->state = IFS_DELAY; - else if (flags == IFS_TENTATIVE) - ifinfo->state = IFS_TENTATIVE; - else - ifinfo->state = IFS_DOWN; - - rtsol_timer_update(ifinfo); - - /* link into chain */ - if (iflist) - ifinfo->next = iflist; - iflist = ifinfo; - - return 0; - -bad: - free(ifinfo->sdl); - free(ifinfo); - return -1; -} - -void -iflist_init(void) -{ - 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) -{ - struct ifinfo *ifi, *prev; - int rv; - - prev = NULL; - for (ifi = iflist; ifi; ifi = ifi->next) { - if (strncmp(ifi->ifname, ifname, sizeof(ifi->ifname)) == 0) - break; - prev = ifi; - } - prev->next = ifi->next; - - rv = ifconfig(ifname); - - /* reclaim it after ifconfig() in case ifname is pointer inside ifi */ - if (ifi->rs_data) - free(ifi->rs_data); - free(ifi->sdl); - free(ifi); - return rv; -} -#endif - -struct ifinfo * -find_ifinfo(size_t ifindex) -{ - struct ifinfo *ifi; - - for (ifi = iflist; ifi; ifi = ifi->next) - if (ifi->sdl->sdl_index == ifindex) - return ifi; - return NULL; -} - -static int -make_packet(struct ifinfo *ifinfo) -{ - size_t packlen = sizeof(struct nd_router_solicit), lladdroptlen; - struct nd_router_solicit *rs; - u_char *buf; - - if ((lladdroptlen = lladdropt_length(ifinfo->sdl)) == 0) { - warnmsg(LOG_INFO, __func__, - "link-layer address option has null length" - " on %s. Treat as not included.", ifinfo->ifname); - } - packlen += lladdroptlen; - ifinfo->rs_datalen = packlen; - - /* allocate buffer */ - if ((buf = malloc(packlen)) == NULL) { - warnmsg(LOG_ERR, __func__, - "memory allocation failed for %s", ifinfo->ifname); - return -1; - } - ifinfo->rs_data = buf; - - /* fill in the message */ - rs = (struct nd_router_solicit *)buf; - rs->nd_rs_type = ND_ROUTER_SOLICIT; - rs->nd_rs_code = 0; - rs->nd_rs_cksum = 0; - rs->nd_rs_reserved = 0; - buf += sizeof(*rs); - - /* fill in source link-layer address option */ - if (lladdroptlen) - lladdropt_fill(ifinfo->sdl, (struct nd_opt_hdr *)buf); - - return 0; -} - -static struct timeval * -rtsol_check_timer(void) -{ - static struct timeval returnval; - struct timeval now, rtsol_timer; - struct ifinfo *ifinfo; - int flags; - - gettimeofday(&now, NULL); - - rtsol_timer = tm_max; - - for (ifinfo = iflist; ifinfo; ifinfo = ifinfo->next) { - if (timercmp(&ifinfo->expire, &now, <=)) { - if (dflag > 1) - warnmsg(LOG_DEBUG, __func__, - "timer expiration on %s, " - "state = %d", ifinfo->ifname, - ifinfo->state); - - switch (ifinfo->state) { - case IFS_DOWN: - case IFS_TENTATIVE: - /* interface_up returns 0 on success */ - flags = interface_up(ifinfo->ifname); - if (flags == 0) - ifinfo->state = IFS_DELAY; - else if (flags == IFS_TENTATIVE) - ifinfo->state = IFS_TENTATIVE; - else - ifinfo->state = IFS_DOWN; - break; - case IFS_IDLE: - { - int oldstatus = ifinfo->active; - int probe = 0; - - ifinfo->active = interface_status(ifinfo); - - if (oldstatus != ifinfo->active) { - warnmsg(LOG_DEBUG, __func__, - "%s status is changed" - " from %d to %d", - ifinfo->ifname, - oldstatus, ifinfo->active); - probe = 1; - ifinfo->state = IFS_DELAY; - } else if (ifinfo->probeinterval && - (ifinfo->probetimer -= (int) - ifinfo->timer.tv_sec) <= 0) { - /* probe timer expired */ - ifinfo->probetimer = - ifinfo->probeinterval; - probe = 1; - ifinfo->state = IFS_PROBE; - } - - if (probe && mobile_node) - defrouter_probe(ifinfo); - break; - } - case IFS_DELAY: - ifinfo->state = IFS_PROBE; - sendpacket(ifinfo); - break; - case IFS_PROBE: - if (ifinfo->probes < MAX_RTR_SOLICITATIONS) - sendpacket(ifinfo); - else { - warnmsg(LOG_INFO, __func__, - "No answer after sending %d RSs", - ifinfo->probes); - ifinfo->probes = 0; - ifinfo->state = IFS_IDLE; - } - break; - } - rtsol_timer_update(ifinfo); - } - - if (timercmp(&ifinfo->expire, &rtsol_timer, <)) - rtsol_timer = ifinfo->expire; - } - - if (timercmp(&rtsol_timer, &tm_max, ==)) { - warnmsg(LOG_DEBUG, __func__, "there is no timer"); - return NULL; - } else if (timercmp(&rtsol_timer, &now, <)) - /* this may occur when the interval is too small */ - returnval.tv_sec = returnval.tv_usec = 0; - else - timersub(&rtsol_timer, &now, &returnval); - - if (dflag > 1) - warnmsg(LOG_DEBUG, __func__, "New timer is %ld:%08ld", - (long)returnval.tv_sec, (long)returnval.tv_usec); - - return &returnval; -} - -void -rtsol_timer_update(struct ifinfo *ifinfo) -{ -#define MILLION 1000000 -#define DADRETRY 10 /* XXX: adhoc */ - uint32_t interval; - struct timeval now; - - bzero(&ifinfo->timer, sizeof(ifinfo->timer)); - - switch (ifinfo->state) { - case IFS_DOWN: - case IFS_TENTATIVE: - if (++ifinfo->dadcount > DADRETRY) { - ifinfo->dadcount = 0; - ifinfo->timer.tv_sec = PROBE_INTERVAL; - } else - ifinfo->timer.tv_sec = 1; - break; - case IFS_IDLE: - if (mobile_node) { - /* XXX should be configurable */ - ifinfo->timer.tv_sec = 3; - } else - ifinfo->timer = tm_max; /* stop timer(valid?) */ - break; - case IFS_DELAY: - interval = arc4random() % (MAX_RTR_SOLICITATION_DELAY * MILLION); - ifinfo->timer.tv_sec = interval / MILLION; - ifinfo->timer.tv_usec = (suseconds_t)(interval % MILLION); - break; - case IFS_PROBE: - if (ifinfo->probes < MAX_RTR_SOLICITATIONS) - ifinfo->timer.tv_sec = RTR_SOLICITATION_INTERVAL; - else { - /* - * After sending MAX_RTR_SOLICITATIONS solicitations, - * we're just waiting for possible replies; there - * will be no more solicatation. Thus, we change - * the timer value to MAX_RTR_SOLICITATION_DELAY based - * on RFC 2461, Section 6.3.7. - */ - ifinfo->timer.tv_sec = MAX_RTR_SOLICITATION_DELAY; - } - break; - default: - warnmsg(LOG_ERR, __func__, - "illegal interface state(%d) on %s", - ifinfo->state, ifinfo->ifname); - return; - } - - /* reset the timer */ - if (timercmp(&ifinfo->timer, &tm_max, ==)) { - ifinfo->expire = tm_max; - warnmsg(LOG_DEBUG, __func__, - "stop timer for %s", ifinfo->ifname); - } else { - gettimeofday(&now, NULL); - timeradd(&now, &ifinfo->timer, &ifinfo->expire); - - if (dflag > 1) - warnmsg(LOG_DEBUG, __func__, - "set timer for %s to %d:%d", ifinfo->ifname, - (int)ifinfo->timer.tv_sec, - (int)ifinfo->timer.tv_usec); - } - -#undef MILLION -} - -/* timer related utility functions */ -#define MILLION 1000000 - -#ifndef SMALL -static void -rtsold_set_dump_file(int sig) -{ - do_dump = 1; -} -#endif - -static void -usage(void) -{ - const char *opts = isdaemon ? "-1Ddfm" : "Dd"; - fprintf(stderr, "Usage: %s [%s] interface ...\n", getprogname(), opts); - fprintf(stderr, "\t%s [%s] -a\n", getprogname(), opts); - exit(1); -} - -void -warnmsg(int priority, const char *func, const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - if (fflag) { - if (priority <= log_upto) - vwarnx(msg, ap); - } else { - char *buf; - evasprintf(&buf, msg, ap); - syslog(priority, "<%s> %s", func, buf); - free(buf); - } - va_end(ap); -} - -/* - * return a list of interfaces which is suitable to sending an RS. - */ -char ** -autoifprobe(void) -{ - static char **argv = NULL; - static size_t n = 0; - char **a; - size_t i; - int found; - struct ifaddrs *ifap, *ifa; - - /* initialize */ - while (n--) - free(argv[n]); - if (argv) { - free(argv); - argv = NULL; - } - n = 0; - - if (getifaddrs(&ifap) != 0) - return 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; - - found = 0; - for (i = 0; i < n; i++) { - if (strcmp(argv[i], ifa->ifa_name) == 0) { - found++; - break; - } - } - if (found) - continue; - - /* if we find multiple candidates, just warn. */ - if (n != 0 && dflag > 1) - warnx("multiple interfaces found"); - - a = realloc(argv, (n + 1) * sizeof(char **)); - if (a == NULL) - err(EXIT_FAILURE, "realloc"); - argv = a; - argv[n] = strdup(ifa->ifa_name); - if (!argv[n]) - err(EXIT_FAILURE, "strdup"); - n++; - } - - if (n) { - a = realloc(argv, (n + 1) * sizeof(char **)); - if (a == NULL) - err(EXIT_FAILURE, "realloc"); - argv = a; - argv[n] = NULL; - - if (dflag > 0) { - for (i = 0; i < n; i++) - warnx("probing %s", argv[i]); - } - } - freeifaddrs(ifap); - return argv; -} diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h deleted file mode 100644 index bb61611cca39..000000000000 --- a/usr.sbin/rtsold/rtsold.h +++ /dev/null @@ -1,100 +0,0 @@ -/* $NetBSD: rtsold.h,v 1.11 2014/03/18 00:16:49 christos Exp $ */ -/* $KAME: rtsold.h,v 1.14 2002/05/31 10:10:03 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -struct ifinfo { - struct ifinfo *next; /* pointer to the next interface */ - - 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 */ - int mediareqok; /* whether the IF supports SIOCGIFMEDIA */ - int state; - int probes; - int dadcount; - struct timeval timer; - struct timeval expire; - int errors; /* # of errors we've got - detect wedge */ - - int racnt; /* total # of valid RAs it have got */ - - size_t rs_datalen; - u_char *rs_data; -}; - -/* per interface status */ -#define IFS_IDLE 0 -#define IFS_DELAY 1 -#define IFS_PROBE 2 -#define IFS_DOWN 3 -#define IFS_TENTATIVE 4 - -/* rtsold.c */ -extern struct timeval tm_max; -extern int dflag; -extern int aflag; -extern struct ifinfo *iflist; -extern int rssock; - -int ifconfig(char *); -void iflist_init(void); -struct ifinfo *find_ifinfo(size_t); -void rtsol_timer_update(struct ifinfo *); -void warnmsg(int, const char *, const char *, ...) __printflike(3, 4); -char **autoifprobe(void); - -/* if.c */ -int ifinit(void); -int interface_up(char *); -int interface_status(struct ifinfo *); -size_t lladdropt_length(struct sockaddr_dl *); -void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *); -struct sockaddr_dl *if_nametosdl(char *); -int getinet6sysctl(int); - -/* rtsol.c */ -int sockopen(void); -void sendpacket(struct ifinfo *); -void rtsol_input(int); - -/* probe.c */ -int probe_init(void); -void defrouter_probe(struct ifinfo *); - -/* dump.c */ -void rtsold_dump_file(const char *); - -/* rtsock.c */ -int rtsock_open(void); -int rtsock_input(int);