diff --git a/sbin/rtsol/Makefile b/sbin/rtsol/Makefile index f19b4217c45f..b1d74c27aac6 100644 --- a/sbin/rtsol/Makefile +++ b/sbin/rtsol/Makefile @@ -1,10 +1,16 @@ -# $NetBSD: Makefile,v 1.1 1999/07/02 08:28:04 itojun Exp $ +# $NetBSD: Makefile,v 1.2 1999/09/03 05:25:44 itojun Exp $ PROG= rtsol +SRCS= rtsold.c rtsol.c if.c probe.c -CPPFLAGS+=-DADVAPI=1 CPPFLAGS+=-DINET6 -MAN= rtsol.8 +LDADD+= -lkvm +DPADD+= ${LIBKVM} + +#MAN= rtsold.8 +NOMAN= yes + +.PATH: ${.CURDIR}/../../usr.sbin/rtsold .include diff --git a/sbin/rtsol/rtsol.8 b/sbin/rtsol/rtsol.8 deleted file mode 100644 index 689ab28c5b30..000000000000 --- a/sbin/rtsol/rtsol.8 +++ /dev/null @@ -1,96 +0,0 @@ -.\" 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. -.\" -.\" $NetBSD: rtsol.8,v 1.2 1999/07/04 02:43:39 itojun Exp $ -.\" KAME Id: rtsol.8,v 1.1.2.5.2.2.4.2 1999/05/02 13:18:43 itojun Exp -.\" -.Dd May 17, 1998 -.Dt RTSOL 8 -.Os -.\" -.Sh NAME -.Nm rtsol -.Nd send router solicitation -.\" -.Sh SYNOPSIS -.Nm -.Op Fl nv -.Ar interface -.\" -.Sh DESCRIPTION -.Nm Rtsol -sends router solicitation packet to the specified -.Ar interface . -If there is any router on the network, the router may respond by -router advertisement packet. -Router advertisement packet contains information about the network, -the link-local address of the router, and so forth. -The kernel will install the new routing information and address prefix -for the -.Ar interface , -according to the information. -.Pp -.Nm -implements some quickhack code for notebook computers. -.Fl n -disables the behavior -.Pq the flag stands for no tricks . -.Pp -If -.Fl v -is specified, -.Nm -will generate more messages. -This is mostly for debugging. -.Pp -Router advertisement packet will be processed only if the -node is configured as a host, not a router. -To accept router advertisement packet, -.Xr sysctl 8 -variables must be set as follows: -.Bd -literal -offset -# sysctl -w net.inet6.ip6.forwarding=0 -# sysctl -w net.inet6.ip6.accept_rtadv=1 -.Ed -.Pp -Typically this is done in system startup scripts, such as -.Xr rc 8 . -.\" -.Sh RETURN VALUES -The program exits with 0 on success, non-zero on failures. -.\" -.Sh SEE ALSO -.Xr rtadvd 8 , -.Xr rtsold 8 , -.Xr sysctl 8 -.\" -.Sh HISTORY -The -.Nm -command first appeared in WIDE Hydrangea IPv6 protocol stack kit. -.\" .Sh BUGS -.\" (to be written) diff --git a/sbin/rtsol/rtsol.c b/sbin/rtsol/rtsol.c deleted file mode 100644 index f1677af090ce..000000000000 --- a/sbin/rtsol/rtsol.c +++ /dev/null @@ -1,483 +0,0 @@ -/* $NetBSD: rtsol.c,v 1.3 1999/07/29 09:57:58 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 -#ifdef ADVAPI -#include -#endif -#include - -#include -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#endif /* __FreeBSD__ >= 3 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ALLROUTER "ff02::2" - -int main __P((int, char **)); -void usage __P((void)); -int sendit __P((int, char *, int, struct sockaddr_in6 *, int)); -int interface_down __P((char *)); -int interface_up __P((char *)); -static int getifflag6 __P((char *, int *)); -static int getinet6sysctl __P((int)); - -static int trick = 1; -static int verbose = 0; -#define vmsg(x) { if (verbose) fprintf x; } - -extern char *optarg; -extern int optind; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - struct sockaddr_in6 to; - struct icmp6_hdr *icp; - u_int hlim = 255; - u_char outpack[sizeof(struct icmp6_hdr)]; - u_short index; - int s, i, cc = sizeof(struct icmp6_hdr); - int opt; - fd_set fdset; - struct timeval timeout; - int rtsol_retry = MAX_RTR_SOLICITATIONS; - long rdelay; - - srandom((unsigned)time(NULL)); - - while ((opt = getopt(argc, argv, "nv")) != EOF) { - switch (opt) { - case 'n': - trick = 0; - break; - case 'v': - verbose++; - break; - default: - usage(); - /*NOTREACHED*/ - } - } - argc -= optind; - argv += optind; - if (argc != 1) { - usage(); - /*NOTREACHED*/ - } - - index = (u_short)if_nametoindex(argv[0]); - if (index == 0) { - errx(1, "invalid interface %s", argv[0]); - /*NOTREACHED*/ - } - - if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV)) - warnx("kernel is configured not to accept RAs"); - - if (trick) { - /* - * Notebook hack: - * It looks that, most of the pccard drivers do not reset - * multicast packet filter properly on suspend/resume session. - * bring interface down, then up, to initialize it properly. - */ - if (interface_down(argv[0]) < 0) - err(1, "interface state could not be changed"); - vmsg((stderr, "a bit of delay...\n")); - usleep(500 * 1000); /* 0.5s */ - } - - if (interface_up(argv[0]) < 0) - err(1, "interface not ready"); - - { - struct addrinfo hints, *res; - int error; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET6; - error = getaddrinfo(ALLROUTER, NULL, &hints, &res); - if (error) { - errx(1, "getaddrinfo: %s", gai_strerror(error)); - /*NOTREACHED*/ - } - memcpy(&to, res->ai_addr, res->ai_addrlen); - } - - if ((s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) - err(1, "socket"); - - if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hlim, - sizeof(hlim)) == -1) - err(1, "setsockopt(IPV6_MULTICAST_HOPS)"); -#ifdef ICMP6_FILTER - { - struct icmp6_filter filt; - ICMP6_FILTER_SETBLOCKALL(&filt); - ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); - if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, - sizeof(filt)) == -1) - err(1, "setsockopt(ICMP6_FILTER)"); - } -#endif - - /* fill ICMP header */ - icp = (struct icmp6_hdr *)outpack; - icp->icmp6_type = ND_ROUTER_SOLICIT; - icp->icmp6_code = 0; - icp->icmp6_cksum = 0; - icp->icmp6_data32[0] = 0; /* RS reserved field */ - - vmsg((stderr, "sending RS for %d time%s:\n", - rtsol_retry, (1 < rtsol_retry) ? "s" : "")); - - rdelay = random() % ((long)MAX_RTR_SOLICITATION_DELAY * 1000); - vmsg((stderr, "sleep %ldmsec before sending the first one\n", rdelay)); - if (rdelay / 1000 > 0) - sleep(rdelay / 1000); - usleep(rdelay % 1000); - -retry: - vmsg((stderr, "%d, interval=%dsec\r", rtsol_retry, - RTR_SOLICITATION_INTERVAL)); - - i = sendit(s, (char *)outpack, cc, &to, index); - if (i < 0) { - err(1, "rtsol: solicitation"); - /*NOTREACHED*/ - } else if (i != cc) { - fprintf(stderr, "rtsol: short write (wrote %d of be %d)\n", - i, cc); - } - FD_ZERO(&fdset); - FD_SET(s, &fdset); - timeout.tv_sec = RTR_SOLICITATION_INTERVAL; - timeout.tv_usec = 0; - if (select(s + 1, &fdset, NULL, NULL, &timeout) < 1) { - if (0 < --rtsol_retry) - goto retry; - } else { - vmsg((stderr, "\ngot a RA packet\n")); - } - - close(s); - exit(0); - /*NOTREACHED*/ -} - -void -usage() -{ - (void)fprintf(stderr, "usage: rtsol [-nv] ifname\n"); - exit(1); - /*NOTREACHED*/ -} - -int -sendit(s, p, len, sock, ifindex) - int s; - char *p; - int len; - struct sockaddr_in6 *sock; - int ifindex; -{ -#ifndef ADVAPI - sock->sin6_addr.u6_addr.u6_addr16[1] = htons(ifindex); - return sendto(s, p, len, 0, (struct sockaddr *)sock, sock->sin6_len); -#else - struct msghdr m; - struct cmsghdr *cm; - struct iovec iov[2]; - u_char cmsgbuf[256]; - struct in6_pktinfo *pi; - - m.msg_name = (caddr_t)sock; - m.msg_namelen = sock->sin6_len; - iov[0].iov_base = p; - iov[0].iov_len = len; - m.msg_iov = iov; - m.msg_iovlen = 1; - if (!ifindex) { - m.msg_control = NULL; - m.msg_controllen = 0; - } else { - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - cm = (struct cmsghdr *)cmsgbuf; - m.msg_control = (caddr_t)cm; - m.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); - - cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); - cm->cmsg_level = IPPROTO_IPV6; - cm->cmsg_type = IPV6_PKTINFO; - pi = (struct in6_pktinfo *)CMSG_DATA(cm); - memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ - pi->ipi6_ifindex = ifindex; - } - return sendmsg(s, &m, 0); -#endif -} - -int -interface_down(name) - char *name; -{ - int s; - struct ifreq ifr; - - vmsg((stderr, "make interface %s down.\n", name)); - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - err(1, "socket"); - /*NOTREACHED*/ - } - strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - - if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) - perror("ioctl(SIOCGIFFLAGS)"); - ifr.ifr_flags &= ~IFF_UP; - if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) - perror("ioctl(SIOCSIFFLAGS)"); - close(s); - return 0; -} - -int -interface_up(name) - char *name; -{ - int s; - struct ifreq ifr; - int flag6; - int retry; - int wasup; - - vmsg((stderr, "make interface %s up.\n", name)); - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - err(1, "socket"); - /*NOTREACHED*/ - } - strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - - if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) - perror("ioctl(SIOCGIFFLAGS)"); - if (ifr.ifr_flags & IFF_UP) - wasup = 1; - else { - wasup = 0; - ifr.ifr_flags |= IFF_UP; - if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) - perror("ioctl(SIOCSIFFLAGS)"); - } - close(s); - - retry = getinet6sysctl(IPV6CTL_DAD_COUNT); - if (retry < 0) { - retry = 10; - vmsg((stderr, "invalid dad count; setting retry to %d\n", - retry)); - } else { - vmsg((stderr, "dad count is %d\n", retry)); - if (!wasup) - retry += MAX_RTR_SOLICITATIONS; - retry += 2; /* to make sure */ - } - vmsg((stderr, "checking if %s is ready...\n", name)); - while (0 < retry--) { - if (getifflag6(name, &flag6) < 0) { - vmsg((stderr, "getifflag6() failed, anyway I'll try\n")); - return 0; - } - - if (verbose) { - fprintf(stderr, "%s:", name); - if (!(flag6 & IN6_IFF_NOTREADY)) - fprintf(stderr, " ready\n"); - else { - if (flag6 & IN6_IFF_TENTATIVE) - fprintf(stderr, " tentative"); - if (flag6 & IN6_IFF_DUPLICATED) - fprintf(stderr, " duplicatd"); - fprintf(stderr, "\n"); - } - } - - if (flag6 & IN6_IFF_DUPLICATED) - break; - if (!(flag6 & IN6_IFF_NOTREADY)) - return 0; - - sleep(1); - } - fprintf(stderr, "DAD for if %s is in strange state\n", name); - return -1; -} - -/*------------------------------------------------------------*/ - -static int -getifflag6(name, flag6) - char *name; - int *flag6; -{ - int s; - struct sockaddr_in6 *sin6; -#ifndef SIOCGLIFADDR - int error; - char buf[BUFSIZ]; - int i; - struct ifreq *ifr; - struct in6_ifreq ifr6; - struct ifconf ifc; - - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - err(1, "socket"); - /*NOTREACHED*/ - } - - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { - err(1, "ioctl(SIOCGIFCONF)"); - /*NOTREACHED*/ - } - - error = -1; - for (i = 0; i < ifc.ifc_len; ) { - ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i); - i += sizeof(ifr->ifr_name) + - (ifr->ifr_addr.sa_len > sizeof(struct sockaddr) - ? ifr->ifr_addr.sa_len - : sizeof(struct sockaddr)); - if (strncmp(name, ifr->ifr_name, sizeof(ifr->ifr_name)) != 0) - continue; - if (ifr->ifr_addr.sa_family != AF_INET6) - continue; - sin6 = (struct sockaddr_in6 *)&ifr->ifr_addr; - if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - continue; - - if (verbose) { - char addrbuf[BUFSIZ]; - getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, - addrbuf, sizeof(addrbuf), NULL, 0, - NI_NUMERICHOST); - fprintf(stderr, "getting flags6 for if %s addr %s\n", - ifr->ifr_name, addrbuf); - } - - strcpy(ifr6.ifr_name, name); - memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, - ifr->ifr_addr.sa_len); - if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { - err(1, "ioctl(SIOCGIFAFLAG_IN6)"); - /*NOTREACHED*/ - } - error = 0; - if (flag6) - *flag6 = ifr6.ifr_ifru.ifru_flags6; - break; - } - if (error < 0 && verbose) - fprintf(stderr, "getifflags6: no matches\n"); - - close(s); - return error; -#else - struct if_laddrreq iflr; - - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - err(1, "socket"); - /*NOTREACHED*/ - } - - /* perform prefix match on SIOCGLIFADDR */ - memset(&iflr, 0, sizeof(iflr)); - strcpy(iflr.iflr_name, name); - iflr.prefixlen = 16; - iflr.flags = IFLR_PREFIX; - sin6 = (struct sockaddr_in6 *)&iflr.addr; - sin6->sin6_family = AF_INET6; - sin6->sin6_len = sizeof(*sin6); - sin6->sin6_addr.s6_addr16[0] = htons(0xfe80); /*XXX hardcode*/ - if (ioctl(s, SIOCGLIFADDR, &iflr) < 0) { - if (errno == EADDRNOTAVAIL) /*no match - portability?*/ - return -1; - err(1, "ioctl(SIOCGLIFADDR)"); - /*NOTREACHED*/ - } - if (verbose) { - char addrbuf[BUFSIZ]; - getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, - addrbuf, sizeof(addrbuf), NULL, 0, - NI_NUMERICHOST); - fprintf(stderr, "got flags6 for if %s addr %s=0x%08x\n", - iflr.iflr_name, addrbuf, iflr.flags); - } - if (flag6) - *flag6 = iflr.flags; - close(s); - return 0; -#endif -} - -static int -getinet6sysctl(code) - 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; -} diff --git a/usr.sbin/rtsold/Makefile b/usr.sbin/rtsold/Makefile index f9e74aa3e9e6..0731dc8ea672 100644 --- a/usr.sbin/rtsold/Makefile +++ b/usr.sbin/rtsold/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.1 1999/09/03 05:14:37 itojun Exp $ +# $NetBSD: Makefile,v 1.2 1999/09/03 05:25:43 itojun Exp $ PROG= rtsold SRCS= rtsold.c rtsol.c if.c probe.c @@ -9,5 +9,6 @@ LDADD+= -lkvm DPADD+= ${LIBKVM} MAN= rtsold.8 +MLINKS= rtsold.8 rtsol.8 .include