diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-02-28 11:56:42 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-02-28 11:56:42 +0000 |
commit | 607685e18ba9cdeff5d77cdea210e356184f0f97 (patch) | |
tree | 4fa8dc1eb7e9d23a5f6ecebd570d5e1c2614bac3 | |
parent | 15bfd42ebaec37ba450f58b4943cb687022f54e1 (diff) |
bring in latest kame code.
- ndp -I (set default outgoing interface when no default router is defined)
- ndp -s proxy (proxy NDP)
-rw-r--r-- | usr.sbin/ndp/ndp.8 | 41 | ||||
-rw-r--r-- | usr.sbin/ndp/ndp.c | 127 |
2 files changed, 131 insertions, 37 deletions
diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8 index 9b0d1bcd5af..fc410e3165c 100644 --- a/usr.sbin/ndp/ndp.8 +++ b/usr.sbin/ndp/ndp.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ndp.8,v 1.3 2000/01/04 21:12:18 deraadt Exp $ +.\" $OpenBSD: ndp.8,v 1.4 2000/02/28 11:56:40 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" KAME Id: ndp.8,v 1.1.1.1 1999/12/10 07:17:07 itojun Exp +.\" KAME Id: ndp.8,v 1.5 2000/02/17 05:35:56 itojun Exp .\" .Dd May 17, 1998 .Dt NDP 8 @@ -57,9 +57,9 @@ .Ar filename .Nm ndp .Fl H -.\" .Nm ndp -.\" .Fl I -.\" .Ar interface +.Nm ndp +.Fl I +.Op delete \(ba Ar interface .Nm ndp .Fl i .Ar interface @@ -76,7 +76,8 @@ .Op Fl nt .Ar nodename .Ar ether_addr -.Op temp +.Op Li temp +.Op Li proxy .\" .Sh DESCRIPTION .Nm @@ -102,12 +103,19 @@ Parse the file specified by .It Fl H Harmonize consistency between the routing table and the default router list; install the top entry of the list into the kernel routing table. -.\" .It Fl I -.\" .Ar interface -.\" Specifies the default interface used as the default route when -.\" there is no default router. -.It Fl i Ar interface -View ND information for specified interface. +.It Fl I Op delete \(ba Ar interface +Shows or specifies the default interface used as the default route when +there is no default router. If no argument is given to the option, +the current deafult interface will be shown. +If an +.Ar interface +is specified, the interface will be used as the default. +If a special keyword +.Ic delete +is specified, the current default interface will be deleted from the kernel. +.It Fl i +.Ar interface +view ND information for specified interface. .It Fl l Do not truncate numeric IPv6 address. .It Fl n @@ -122,6 +130,15 @@ Show default router list. Flush all the entries in the default router list. .It Fl s Register a NDP entry for a node. +The entry will be permanent unless the word +.Li temp +is given in the command. +If the word +.Li proxy +is given, this system will act as an proxy NDP server, +responding to requests for +.Ar hostname +even though the host address is not its own. .It Fl t Print timestamp on each entries, to make it possible to merge output with diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index b4235555418..e02383d527a 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ndp.c,v 1.3 2000/02/01 03:24:05 deraadt Exp $ */ +/* $OpenBSD: ndp.c,v 1.4 2000/02/28 11:56:41 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -156,7 +156,8 @@ void plist __P((void)); void pfx_flush __P((void)); void rtr_flush __P((void)); void harmonize_rtr __P((void)); -#ifdef SIOCSDEFIFACE_IN6 +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ +static void getdefif __P((void)); static void setdefif __P((char *)); #endif static char *sec2str __P((time_t t)); @@ -176,7 +177,7 @@ main(argc, argv) pid = getpid(); thiszone = gmt2local(0); - while ((ch = getopt(argc, argv, "acndfI:ilprstA:HPR")) != EOF) + while ((ch = getopt(argc, argv, "acndfIilprstA:HPR")) != EOF) switch ((char)ch) { case 'a': aflag = 1; @@ -189,8 +190,10 @@ main(argc, argv) dflag = 1; break; case 'I': -#ifdef SIOCSDEFIFACE_IN6 - setdefif(optarg); +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ + if (argc > 2) + setdefif(argv[2]); + getdefif(); /* always call it to print the result */ exit(0); #else errx(1, "not supported yet"); @@ -335,7 +338,7 @@ getsocket() } } -struct sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}}; +struct sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 }; struct sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m; struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m; int expire_time, flags, found_entry; @@ -384,7 +387,8 @@ set(argc, argv) struct timeval time; gettimeofday(&time, 0); expire_time = time.tv_sec + 20 * 60; - } + } else if (strncmp(argv[0], "proxy", 5) == 0) + flags |= RTF_ANNOUNCE; argv++; } tryagain: @@ -642,17 +646,19 @@ again:; * other flags. R: router, P: proxy, W: ?? */ if ((rtm->rtm_addrs & RTA_NETMASK) == 0) { - snprintf(flgbuf, sizeof(flgbuf), "%s", - isrouter ? "R" : ""); + snprintf(flgbuf, sizeof(flgbuf), "%s%s", + isrouter ? "R" : "", + (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } else { sin = (struct sockaddr_in6 *) (sdl->sdl_len + (char *)sdl); - snprintf(flgbuf, sizeof(flgbuf), "%s%s%s", + snprintf(flgbuf, sizeof(flgbuf), "%s%s%s%s", isrouter ? "R" : "", !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) ? "P" : "", (sin->sin6_len != sizeof(struct sockaddr_in6)) - ? "W" : ""); + ? "W" : "", + (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } printf(" %-4.4s", flgbuf); @@ -743,11 +749,11 @@ usage() printf(" ndp -f[nt] filename\n"); printf(" ndp -i interface\n"); #ifdef SIOCSDEFIFACE_IN6 - printf(" ndp -I interface\n"); + printf(" ndp -I [interface|delete]\n"); #endif printf(" ndp -p\n"); printf(" ndp -r\n"); - printf(" ndp -s hostname ether_addr [temp]\n"); + printf(" ndp -s hostname ether_addr [temp] [proxy]\n"); printf(" ndp -H\n"); printf(" ndp -P\n"); printf(" ndp -R\n"); @@ -780,6 +786,10 @@ rtmsg(cmd) rtm->rtm_rmx.rmx_expire = expire_time; rtm->rtm_inits = RTV_EXPIRE; rtm->rtm_flags |= (RTF_HOST | RTF_STATIC); + if (rtm->rtm_flags & RTF_ANNOUNCE) { + rtm->rtm_flags &= ~RTF_HOST; + rtm->rtm_flags |= RTA_NETMASK; + } /* FALLTHROUGH */ case RTM_GET: rtm->rtm_addrs |= RTA_DST; @@ -790,6 +800,7 @@ rtmsg(cmd) NEXTADDR(RTA_DST, sin_m); NEXTADDR(RTA_GATEWAY, sdl_m); + memset(&so_mask.sin6_addr, 0xff, sizeof(so_mask.sin6_addr)); NEXTADDR(RTA_NETMASK, so_mask); rtm->rtm_msglen = cp - (char *)&m_rtmsg; @@ -911,7 +922,12 @@ plist() sizeof(ntop_buf)), PR.prefixlen, if_indextoname(PR.if_index, ifix_buf)); gettimeofday(&time, 0); - printf(" flags=%s%s", + /* + * meaning of fields, especially flags, is very different + * by origin. notify the difference to the users. + */ + printf(" %s", PR.origin == PR_ORIG_RA ? "" : "advertise: "); + printf("flags=%s%s", PR.raflags.onlink ? "L" : "", PR.raflags.autonomous ? "A" : ""); if (PR.vltime == ND6_INFINITE_LIFETIME) @@ -923,13 +939,37 @@ plist() else printf(", pltime=%ld", (long)PR.pltime); if (PR.expire == 0) - printf(", expire=Never\n"); + printf(", expire=Never"); else if (PR.expire >= time.tv_sec) - printf(", expire=%s\n", + printf(", expire=%s", sec2str(PR.expire - time.tv_sec)); else - printf(", expired\n"); - if (PR.advrtrs) { + printf(", expired"); + switch (PR.origin) { + case PR_ORIG_RA: + printf(", origin=RA"); + break; + case PR_ORIG_RR: + printf(", origin=RR"); + break; + case PR_ORIG_STATIC: + printf(", origin=static"); + break; + case PR_ORIG_KERNEL: + printf(", origin=kernel"); + break; + default: + printf(", origin=?"); + break; + } + printf("\n"); + /* + * "advertising router" list is meaningful only if the prefix + * information is from RA. + */ + if (PR.origin != PR_ORIG_RA) + ; + else if (PR.advrtrs) { int j; printf(" advertised by\n"); for (j = 0; j < PR.advrtrs; j++) { @@ -967,8 +1007,7 @@ plist() if (PR.advrtrs > DRLSTSIZ) printf(" and %d routers\n", PR.advrtrs - DRLSTSIZ); - } - else + } else printf(" No advertising router\n"); } #undef PR @@ -1010,7 +1049,7 @@ harmonize_rtr() int s; if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) - err(1, "ndp: socket"); + err(1, "socket"); strcpy(dummyif, "lo0"); /* dummy */ if (ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0) err(1, "ioctl (SIOCSNDFLUSH_IN6)"); @@ -1018,21 +1057,59 @@ harmonize_rtr() close(s); } -#ifdef SIOCSDEFIFACE_IN6 +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ static void setdefif(ifname) char *ifname; { - int s; + struct in6_ndifreq ndifreq; + unsigned int ifindex; + + if (strcasecmp(ifname, "delete") == 0) + ifindex = 0; + else { + if ((ifindex = if_nametoindex(ifname)) == 0) + err(1, "failed to resolve i/f index for %s", ifname); + } if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) - err(1, "ndp: socket"); + err(1, "socket"); + + strcpy(ndifreq.ifname, "lo0"); /* dummy */ + ndifreq.ifindex = ifindex; - if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)ifname) < 0) + if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) err(1, "ioctl (SIOCSDEFIFACE_IN6)"); close(s); } + +static void +getdefif() +{ + struct in6_ndifreq ndifreq; + char ifname[IFNAMSIZ+8]; + + if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + err(1, "socket"); + + memset(&ndifreq, 0, sizeof(ndifreq)); + strcpy(ndifreq.ifname, "lo0"); /* dummy */ + + if (ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) + err(1, "ioctl (SIOCGDEFIFACE_IN6)"); + + if (ndifreq.ifindex == 0) + printf("No default interface.\n"); + else { + if ((if_indextoname(ndifreq.ifindex, ifname)) == NULL) + err(1, "failed to resolve ifname for index %lu", + ndifreq.ifindex); + printf("ND default interface = %s\n", ifname); + } + + close(s); +} #endif static char * |