diff options
-rw-r--r-- | usr.sbin/ndp/ndp.8 | 111 | ||||
-rw-r--r-- | usr.sbin/ndp/ndp.c | 232 |
2 files changed, 201 insertions, 142 deletions
diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8 index f7e63c54110..81e4199938d 100644 --- a/usr.sbin/ndp/ndp.8 +++ b/usr.sbin/ndp/ndp.8 @@ -1,5 +1,5 @@ -.\" $OpenBSD: ndp.8,v 1.11 2002/05/29 09:13:22 itojun Exp $ -.\" $KAME: ndp.8,v 1.20 2002/05/29 07:37:51 itojun Exp $ +.\" $OpenBSD: ndp.8,v 1.12 2002/06/03 03:33:53 itojun Exp $ +.\" $KAME: ndp.8,v 1.25 2002/06/03 03:30:16 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -30,7 +30,7 @@ .\" .Dd May 17, 1998 .Dt NDP 8 -.Os +.Os KAME .\" .Sh NAME .Nm ndp @@ -38,27 +38,26 @@ .\" .Sh SYNOPSIS .Nm ndp -.Fl a .Op Fl nt +.Fl a .Nm ndp -.Fl A Ar wait .Op Fl nt +.Fl A Ar wait .Nm ndp -.Fl c .Op Fl nt +.Fl c .Nm ndp -.Fl d .Op Fl nt -.Ar hostname +.Fl d Ar hostname .Nm ndp -.Fl f .Op Fl nt -.Ar filename +.Fl f Ar filename .Nm ndp .Fl H .Nm ndp -.Fl I -.Op delete \(ba Ar interface +.Fl I Ar interface +.Nm ndp +.Fl I Li delete .Nm ndp .Fl i .Ar interface @@ -72,10 +71,8 @@ .Nm ndp .Fl R .Nm ndp -.Fl s .Op Fl nt -.Ar nodename -.Ar ether_addr +.Fl s Ar nodename ether_addr .Op Li temp .Op Li proxy .\" @@ -83,12 +80,12 @@ The .Nm command manipulates the address mapping table -used by Neighbor Discovery Protocol (NDP). +used by the Neighbor Discovery Protocol (NDP). .Bl -tag -width Ds .It Fl a Dump the currently existing NDP entries. The following information will be printed: -.Bl -tag -width Ds +.Bl -tag -width NeighborXX .It Neighbor IPv6 address of the neighbor. .It Linklayer Address @@ -99,17 +96,32 @@ when the address is not available. .It Netif Network interface associated with the neighbor cache entry. .It Expire -The time until the expiry of the entry. +The time until expiry of the entry. The entry could become -.Dq Li permanent -when it will never expire. +.Dq Li permanent , +in which case it will never expire. .It S -State of the neighbor cache entry, in a single letter. -They are: -Nostate, Waitdelete, Incomplete, Reachable, Stale, Delay and Probe. -.Dq Li ? -indicates unknown state, which should never happen. -.It Flgs +State of the neighbor cache entry, as a single letter: +.Bl -tag -width indent -compact +.Pp +.It N +Nostate +.It W +Waitdelete +.It I +Incomplete +.It R +Reachable +.It S +Stale +.It D +Deay +.It P +Probe +.It ? +Unknown state (should never happen). +.El +.It Flags Flags on the neighbor cache entry, in a single letter. They are: Router, proxy neighbor advertisement .Pq Dq p . @@ -133,17 +145,17 @@ 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 Op delete \(ba Ar interface +.It Fl I 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 default interface will be shown. -If an +If a valid .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. +If +.Ar interface +is not a valid interface name, the current setting will be presented. +.It Fl I Li delete +The current default interface will be deleted from the kernel. .It Fl i Ar interface Op Ar flags ... View ND information for the specified interface. If additional arguments @@ -158,6 +170,7 @@ special character .Ql - , which means the flag should be cleared. .\" +.Pp .Bl -tag -width Ds -compact .It Xo .Ic nud @@ -165,9 +178,31 @@ which means the flag should be cleared. turn on or off NUD (Neighbor Unreachability Detection) on the interface. NUD is usually turned on by default. +.It Xo +.Ic accept_rtadv +.Xc +specify whether or not to accept Router Advertisement messages +received on the +.Ar interface . +Note that the kernel does not accept Router Advertisement messages +unless the +.Li net.inet6.ip6.accept_rtadv +variable is non-0, even if the flag is on. +This flag is set to 1 by default. +.It Xo +.Ic prefer_source +.Xc +prefer addresses on the +.Ar interface +as candidates of the source address for outgoing packets. +The default value of this flag is off. +For more details about the entire algorithm of source address +selection, see the +.Pa IMPLEMENTATION +file supplied with the KAME kit. .El .It Fl n -Do not try to resolve numeric address to hostname. +Do not try to resolve numeric addresses to hostnames. .It Fl p Show prefix list. .It Fl P @@ -179,17 +214,17 @@ Flush all the entries in the default router list. .It Fl s Register an NDP entry for a node. The entry will be permanent unless the word -.Li temp +.Ic temp is given in the command. If the word -.Li proxy +.Ic 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 +Print timestamp on each entry, +making it possible to merge output with .Xr tcpdump 8 . Most useful when used with .Fl A . diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index d63ebb40abe..1f79310654c 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ndp.c,v 1.20 2002/06/02 15:23:30 itojun Exp $ */ -/* $KAME: ndp.c,v 1.86 2002/05/26 01:16:10 itojun Exp $ */ +/* $OpenBSD: ndp.c,v 1.21 2002/06/03 03:33:53 itojun Exp $ */ +/* $KAME: ndp.c,v 1.97 2002/06/03 03:31:25 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -118,7 +118,6 @@ #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) static pid_t pid; -static int cflag; static int nflag; static int tflag; static int32_t thiszone; /* time difference with gmt */ @@ -135,13 +134,13 @@ void getsocket(void); int set(int, char **); void get(char *); int delete(char *); -void dump(struct in6_addr *); +void dump(struct in6_addr *, int); static struct in6_nbrinfo *getnbrinfo(struct in6_addr *, int, int); static char *ether_str(struct sockaddr_dl *); int ndp_ether_aton(char *, u_char *); void usage(void); int rtmsg(int); -void ifinfo(int, char **); +void ifinfo(char *, int, char **); void rtrlist(void); void plist(void); void pfx_flush(void); @@ -165,82 +164,63 @@ static char *rtpref_str[] = { }; #endif +int mode = 0; +char *arg = NULL; + int main(argc, argv) int argc; char **argv; { int ch; - int aflag = 0, dflag = 0, sflag = 0, Hflag = 0; - int pflag = 0, rflag = 0, Pflag = 0, Rflag = 0; pid = getpid(); thiszone = gmt2local(0); - while ((ch = getopt(argc, argv, "acndfIilprstA:HPR")) != -1) - switch ((char)ch) { + while ((ch = getopt(argc, argv, "acd:f:I:i:nprstA:HPR")) != -1) + switch (ch) { case 'a': - aflag = 1; - break; case 'c': - cflag = 1; + case 'p': + case 'r': + case 'H': + case 'P': + case 'R': + case 's': + if (mode) { + usage(); + /*NOTREACHED*/ + } + mode = ch; + arg = NULL; break; case 'd': - dflag = 1; - break; + case 'f': case 'I': -#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"); - /*NOTREACHED*/ -#endif case 'i' : - argc -= optind; - argv += optind; - if (argc < 1) + if (mode) { usage(); - ifinfo(argc, argv); - exit(0); + /*NOTREACHED*/ + } + mode = ch; + arg = optarg; + break; case 'n': nflag = 1; - continue; - case 'p': - pflag = 1; - break; - case 'f' : - if (argc != 3) - usage(); - file(argv[2]); - exit(0); - case 'l' : - /* obsolete, ignored */ - break; - case 'r' : - rflag = 1; - break; - case 's': - sflag = 1; break; case 't': tflag = 1; break; case 'A': - aflag = 1; + if (mode) { + usage(); + /*NOTREACHED*/ + } + mode = 'a'; repeat = atoi(optarg); - if (repeat < 0) + if (repeat < 0) { usage(); - break; - case 'H' : - Hflag = 1; - break; - case 'P': - Pflag = 1; - break; - case 'R': - Rflag = 1; + /*NOTREACHED*/ + } break; default: usage(); @@ -249,45 +229,86 @@ main(argc, argv) argc -= optind; argv += optind; - if (aflag || cflag) { - dump(0); - exit(0); - } - if (dflag) { - if (argc != 1) + switch (mode) { + case 'a': + case 'c': + if (argc != 0) { usage(); - delete(argv[0]); - exit(0); - } - if (pflag) { + /*NOTREACHED*/ + } + dump(0, mode == 'c'); + break; + case 'd': + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } + delete(arg); + break; + case 'I': +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } + if (strcmp(arg, "default") == 0 || if_nametoindex(arg)) + setdefif(arg); + getdefif(); /* always call it to print the result */ + break; +#else + errx(1, "not supported yet"); + /*NOTREACHED*/ +#endif + case 'p': + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } plist(); - exit(0); - } - if (rflag) { + break; + case 'i': + ifinfo(arg, argc, argv); + break; + case 'r': + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } rtrlist(); - exit(0); - } - if (sflag) { + break; + case 's': if (argc < 2 || argc > 4) usage(); exit(set(argc, argv) ? 1 : 0); - } - if (Hflag) { + case 'H': + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } harmonize_rtr(); - exit(0); - } - if (Pflag) { + break; + case 'P': + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } pfx_flush(); - exit(0); - } - if (Rflag) { + break; + case 'R': + if (argc != 0) { + usage(); + /*NOTREACHED*/ + } rtr_flush(); - exit(0); + break; + case 0: + if (argc != 1) { + usage(); + /*NOTREACHED*/ + } + get(argv[0]); + break; } - - if (argc != 1) - usage(); - get(argv[0]); exit(0); } @@ -408,10 +429,12 @@ set(argc, argv) if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { if (sdl->sdl_family == AF_LINK && (rtm->rtm_flags & RTF_LLINFO) && - !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { - case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: - case IFT_ISO88024: case IFT_ISO88025: - goto overwrite; + !(rtm->rtm_flags & RTF_GATEWAY)) { + switch (sdl->sdl_type) { + case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: + case IFT_ISO88024: case IFT_ISO88025: + goto overwrite; + } } /* * IPv4 arp command retries with sin_other = SIN_PROXY here. @@ -457,7 +480,7 @@ get(host) htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); } #endif - dump(&sin->sin6_addr); + dump(&sin->sin6_addr, 0); if (found_entry == 0) { getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, sizeof(host_buf), NULL ,0, @@ -549,8 +572,9 @@ delete: * Dump the entire neighbor cache */ void -dump(addr) +dump(addr, cflag) struct in6_addr *addr; + int cflag; { int mib[6]; size_t needed; @@ -569,9 +593,9 @@ dump(addr) /* Print header */ if (!tflag && !cflag) - printf("%-*.*s %-*.*s %*.*s %-9.9s %1s %4s\n", + printf("%-*.*s %-*.*s %*.*s %-9.9s %1s %5s\n", W_ADDR, W_ADDR, "Neighbor", W_LL, W_LL, "Linklayer Address", - W_IF, W_IF, "Netif", "Expire", "S", "Flgs"); + W_IF, W_IF, "Netif", "Expire", "S", "Flags"); again:; mib[0] = CTL_NET; @@ -634,9 +658,8 @@ again:; #endif } getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, - sizeof(host_buf), NULL, 0, - (nflag ? NI_NUMERICHOST : 0)); - if (cflag == 1) { + sizeof(host_buf), NULL, 0, (nflag ? NI_NUMERICHOST : 0)); + if (cflag) { #ifdef RTF_WASCLONED if (rtm->rtm_flags & RTF_WASCLONED) delete(host_buf); @@ -819,14 +842,15 @@ void usage() { printf("usage: ndp hostname\n"); - printf(" ndp -a[nt]\n"); + printf(" ndp [-nt] -a\n"); printf(" ndp [-nt] -A wait\n"); - printf(" ndp -c[nt]\n"); - printf(" ndp -d[nt] hostname\n"); - printf(" ndp -f[nt] filename\n"); + printf(" ndp [-nt]- c\n"); + printf(" ndp [-nt] -d hostname\n"); + printf(" ndp [-nt] -f filename\n"); printf(" ndp -i interface [flags...]\n"); #ifdef SIOCSDEFIFACE_IN6 - printf(" ndp -I [interface|delete]\n"); + printf(" ndp -I interface\n"); + printf(" ndp -I delete\n"); #endif printf(" ndp -p\n"); printf(" ndp -r\n"); @@ -903,13 +927,13 @@ doit: } void -ifinfo(argc, argv) +ifinfo(ifname, argc, argv) + char *ifname; int argc; char **argv; { struct in6_ndireq nd; int i, s; - char *ifname = argv[0]; u_int32_t newflags; #ifdef IPV6CTL_USETEMPADDR u_int8_t nullbuf[8]; @@ -927,7 +951,7 @@ ifinfo(argc, argv) } #define ND nd.ndi newflags = ND.flags; - for (i = 1; i < argc; i++) { + for (i = 0; i < argc; i++) { int clear = 0; char *cp = argv[i]; |