summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ndp/ndp.8111
-rw-r--r--usr.sbin/ndp/ndp.c232
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];