more posix-compliant arg parsing. sync with kame. help from deraadt

This commit is contained in:
itojun 2002-06-03 03:34:36 +00:00
parent ad4cab117d
commit 016477e967
2 changed files with 199 additions and 140 deletions

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ndp.8,v 1.15 2002/05/29 08:51:28 wiz Exp $ .\" $NetBSD: ndp.8,v 1.16 2002/06/03 03:34:36 itojun Exp $
.\" $KAME: ndp.8,v 1.19 2002/05/29 07:34:01 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. .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved. .\" All rights reserved.
@ -38,27 +38,26 @@
.\" .\"
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm ndp .Nm ndp
.Op Fl nt
.Fl a .Fl a
.Op Fl nt
.Nm ndp .Nm ndp
.Op Fl nt
.Fl A Ar wait .Fl A Ar wait
.Op Fl nt
.Nm ndp .Nm ndp
.Op Fl nt
.Fl c .Fl c
.Op Fl nt
.Nm ndp .Nm ndp
.Fl d
.Op Fl nt .Op Fl nt
.Ar hostname .Fl d Ar hostname
.Nm ndp .Nm ndp
.Fl f
.Op Fl nt .Op Fl nt
.Ar filename .Fl f Ar filename
.Nm ndp .Nm ndp
.Fl H .Fl H
.Nm ndp .Nm ndp
.Fl I .Fl I Ar interface
.Op delete \(ba Ar interface .Nm ndp
.Fl I Li delete
.Nm ndp .Nm ndp
.Fl i .Fl i
.Ar interface .Ar interface
@ -72,10 +71,8 @@
.Nm ndp .Nm ndp
.Fl R .Fl R
.Nm ndp .Nm ndp
.Fl s
.Op Fl nt .Op Fl nt
.Ar nodename .Fl s Ar nodename ether_addr
.Ar ether_addr
.Op Li temp .Op Li temp
.Op Li proxy .Op Li proxy
.\" .\"
@ -83,12 +80,12 @@
The The
.Nm .Nm
command manipulates the address mapping table command manipulates the address mapping table
used by Neighbor Discovery Protocol (NDP). used by the Neighbor Discovery Protocol (NDP).
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl a .It Fl a
Dump the currently existing NDP entries. Dump the currently existing NDP entries.
The following information will be printed: The following information will be printed:
.Bl -tag -width Ds .Bl -tag -width NeighborXX
.It Neighbor .It Neighbor
IPv6 address of the neighbor. IPv6 address of the neighbor.
.It Linklayer Address .It Linklayer Address
@ -99,17 +96,32 @@ when the address is not available.
.It Netif .It Netif
Network interface associated with the neighbor cache entry. Network interface associated with the neighbor cache entry.
.It Expire .It Expire
The time until the expiry of the entry. The time until expiry of the entry.
The entry could become The entry could become
.Dq Li permanent .Dq Li permanent ,
when it will never expire. in which case it will never expire.
.It S .It S
State of the neighbor cache entry, in a single letter. State of the neighbor cache entry, as a single letter:
They are: .Bl -tag -width indent -compact
Nostate, Waitdelete, Incomplete, Reachable, Stale, Delay and Probe. .Pp
.Dq Li ? .It N
indicates unknown state, which should never happen. Nostate
.It Flgs .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. Flags on the neighbor cache entry, in a single letter.
They are: Router, proxy neighbor advertisement They are: Router, proxy neighbor advertisement
.Pq Dq p . .Pq Dq p .
@ -133,17 +145,17 @@ Parse the file specified by
.It Fl H .It Fl H
Harmonize consistency between the routing table and the default router Harmonize consistency between the routing table and the default router
list; install the top entry of the list into the kernel routing table. 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 Shows or specifies the default interface used as the default route when
there is no default router. there is no default router.
If no argument is given to the option, If a valid
the current default interface will be shown.
If an
.Ar interface .Ar interface
is specified, the interface will be used as the default. is specified, the interface will be used as the default.
If a special keyword If
.Ic delete .Ar interface
is specified, the current default interface will be deleted from the kernel. 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 ... .It Fl i Ar interface Op Ar flags ...
View ND information for the specified interface. View ND information for the specified interface.
If additional arguments If additional arguments
@ -158,6 +170,7 @@ special character
.Ql - , .Ql - ,
which means the flag should be cleared. which means the flag should be cleared.
.\" .\"
.Pp
.Bl -tag -width Ds -compact .Bl -tag -width Ds -compact
.It Xo .It Xo
.Ic nud .Ic nud
@ -165,9 +178,31 @@ which means the flag should be cleared.
turn on or off NUD (Neighbor Unreachability Detection) on the turn on or off NUD (Neighbor Unreachability Detection) on the
interface. interface.
NUD is usually turned on by default. 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 .El
.It Fl n .It Fl n
Do not try to resolve numeric address to hostname. Do not try to resolve numeric addresses to hostnames.
.It Fl p .It Fl p
Show prefix list. Show prefix list.
.It Fl P .It Fl P
@ -188,8 +223,8 @@ responding to requests for
.Ar hostname .Ar hostname
even though the host address is not its own. even though the host address is not its own.
.It Fl t .It Fl t
Print timestamp on each entries, Print timestamp on each entry,
to make it possible to merge output with making it possible to merge output with
.Xr tcpdump 8 . .Xr tcpdump 8 .
Most useful when used with Most useful when used with
.Fl A . .Fl A .

View File

@ -1,5 +1,5 @@
/* $NetBSD: ndp.c,v 1.21 2002/06/02 23:43:21 itojun Exp $ */ /* $NetBSD: ndp.c,v 1.22 2002/06/03 03:34:36 itojun Exp $ */
/* $KAME: ndp.c,v 1.91 2002/06/02 15:22:07 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. * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -117,7 +117,6 @@
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
static pid_t pid; static pid_t pid;
static int cflag;
static int nflag; static int nflag;
static int tflag; static int tflag;
static int32_t thiszone; /* time difference with gmt */ static int32_t thiszone; /* time difference with gmt */
@ -134,13 +133,13 @@ void getsocket __P((void));
int set __P((int, char **)); int set __P((int, char **));
void get __P((char *)); void get __P((char *));
int delete __P((char *)); int delete __P((char *));
void dump __P((struct in6_addr *)); void dump __P((struct in6_addr *, int));
static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *, int, int)); static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *, int, int));
static char *ether_str __P((struct sockaddr_dl *)); static char *ether_str __P((struct sockaddr_dl *));
int ndp_ether_aton __P((char *, u_char *)); int ndp_ether_aton __P((char *, u_char *));
void usage __P((void)); void usage __P((void));
int rtmsg __P((int)); int rtmsg __P((int));
void ifinfo __P((int, char **)); void ifinfo __P((char *, int, char **));
void rtrlist __P((void)); void rtrlist __P((void));
void plist __P((void)); void plist __P((void));
void pfx_flush __P((void)); void pfx_flush __P((void));
@ -164,82 +163,63 @@ static char *rtpref_str[] = {
}; };
#endif #endif
int mode = 0;
char *arg = NULL;
int int
main(argc, argv) main(argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
int ch; int ch;
int aflag = 0, dflag = 0, sflag = 0, Hflag = 0;
int pflag = 0, rflag = 0, Pflag = 0, Rflag = 0;
pid = getpid(); pid = getpid();
thiszone = gmt2local(0); thiszone = gmt2local(0);
while ((ch = getopt(argc, argv, "acndfIilprstA:HPR")) != -1) while ((ch = getopt(argc, argv, "acd:f:I:i:nprstA:HPR")) != -1)
switch ((char)ch) { switch (ch) {
case 'a': case 'a':
aflag = 1;
break;
case 'c': 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; break;
case 'd': case 'd':
dflag = 1; case 'f':
break;
case 'I': 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' : case 'i' :
argc -= optind; if (mode) {
argv += optind;
if (argc < 1)
usage(); usage();
ifinfo(argc, argv); /*NOTREACHED*/
exit(0); }
mode = ch;
arg = optarg;
break;
case 'n': case 'n':
nflag = 1; 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; break;
case 't': case 't':
tflag = 1; tflag = 1;
break; break;
case 'A': case 'A':
aflag = 1; if (mode) {
repeat = atoi(optarg);
if (repeat < 0)
usage(); usage();
break; /*NOTREACHED*/
case 'H' : }
Hflag = 1; mode = 'a';
break; repeat = atoi(optarg);
case 'P': if (repeat < 0) {
Pflag = 1; usage();
break; /*NOTREACHED*/
case 'R': }
Rflag = 1;
break; break;
default: default:
usage(); usage();
@ -248,45 +228,86 @@ main(argc, argv)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (aflag || cflag) { switch (mode) {
dump(0); case 'a':
exit(0); case 'c':
} if (argc != 0) {
if (dflag) {
if (argc != 1)
usage(); usage();
delete(argv[0]); /*NOTREACHED*/
exit(0); }
} dump(0, mode == 'c');
if (pflag) { 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(); plist();
exit(0); break;
} case 'i':
if (rflag) { ifinfo(arg, argc, argv);
break;
case 'r':
if (argc != 0) {
usage();
/*NOTREACHED*/
}
rtrlist(); rtrlist();
exit(0); break;
} case 's':
if (sflag) {
if (argc < 2 || argc > 4) if (argc < 2 || argc > 4)
usage(); usage();
exit(set(argc, argv) ? 1 : 0); exit(set(argc, argv) ? 1 : 0);
} case 'H':
if (Hflag) { if (argc != 0) {
usage();
/*NOTREACHED*/
}
harmonize_rtr(); harmonize_rtr();
exit(0); break;
} case 'P':
if (Pflag) { if (argc != 0) {
usage();
/*NOTREACHED*/
}
pfx_flush(); pfx_flush();
exit(0); break;
} case 'R':
if (Rflag) { if (argc != 0) {
usage();
/*NOTREACHED*/
}
rtr_flush(); 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); exit(0);
} }
@ -407,10 +428,12 @@ set(argc, argv)
if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) {
if (sdl->sdl_family == AF_LINK && if (sdl->sdl_family == AF_LINK &&
(rtm->rtm_flags & RTF_LLINFO) && (rtm->rtm_flags & RTF_LLINFO) &&
!(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { !(rtm->rtm_flags & RTF_GATEWAY)) {
case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: switch (sdl->sdl_type) {
case IFT_ISO88024: case IFT_ISO88025: case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
goto overwrite; case IFT_ISO88024: case IFT_ISO88025:
goto overwrite;
}
} }
/* /*
* IPv4 arp command retries with sin_other = SIN_PROXY here. * IPv4 arp command retries with sin_other = SIN_PROXY here.
@ -456,7 +479,7 @@ get(host)
htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id);
} }
#endif #endif
dump(&sin->sin6_addr); dump(&sin->sin6_addr, 0);
if (found_entry == 0) { if (found_entry == 0) {
getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf,
sizeof(host_buf), NULL ,0, sizeof(host_buf), NULL ,0,
@ -548,8 +571,9 @@ delete:
* Dump the entire neighbor cache * Dump the entire neighbor cache
*/ */
void void
dump(addr) dump(addr, cflag)
struct in6_addr *addr; struct in6_addr *addr;
int cflag;
{ {
int mib[6]; int mib[6];
size_t needed; size_t needed;
@ -568,9 +592,9 @@ dump(addr)
/* Print header */ /* Print header */
if (!tflag && !cflag) 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_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:; again:;
mib[0] = CTL_NET; mib[0] = CTL_NET;
@ -633,9 +657,8 @@ again:;
#endif #endif
} }
getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf,
sizeof(host_buf), NULL, 0, sizeof(host_buf), NULL, 0, (nflag ? NI_NUMERICHOST : 0));
(nflag ? NI_NUMERICHOST : 0)); if (cflag) {
if (cflag == 1) {
#ifdef RTF_WASCLONED #ifdef RTF_WASCLONED
if (rtm->rtm_flags & RTF_WASCLONED) if (rtm->rtm_flags & RTF_WASCLONED)
delete(host_buf); delete(host_buf);
@ -817,14 +840,15 @@ void
usage() usage()
{ {
printf("usage: ndp hostname\n"); printf("usage: ndp hostname\n");
printf(" ndp -a[nt]\n"); printf(" ndp [-nt] -a\n");
printf(" ndp [-nt] -A wait\n"); printf(" ndp [-nt] -A wait\n");
printf(" ndp -c[nt]\n"); printf(" ndp [-nt]- c\n");
printf(" ndp -d[nt] hostname\n"); printf(" ndp [-nt] -d hostname\n");
printf(" ndp -f[nt] filename\n"); printf(" ndp [-nt] -f filename\n");
printf(" ndp -i interface [flags...]\n"); printf(" ndp -i interface [flags...]\n");
#ifdef SIOCSDEFIFACE_IN6 #ifdef SIOCSDEFIFACE_IN6
printf(" ndp -I [interface|delete]\n"); printf(" ndp -I interface\n");
printf(" ndp -I delete\n");
#endif #endif
printf(" ndp -p\n"); printf(" ndp -p\n");
printf(" ndp -r\n"); printf(" ndp -r\n");
@ -901,13 +925,13 @@ doit:
} }
void void
ifinfo(argc, argv) ifinfo(ifname, argc, argv)
char *ifname;
int argc; int argc;
char **argv; char **argv;
{ {
struct in6_ndireq nd; struct in6_ndireq nd;
int i, s; int i, s;
char *ifname = argv[0];
u_int32_t newflags; u_int32_t newflags;
#ifdef IPV6CTL_USETEMPADDR #ifdef IPV6CTL_USETEMPADDR
u_int8_t nullbuf[8]; u_int8_t nullbuf[8];
@ -925,7 +949,7 @@ ifinfo(argc, argv)
} }
#define ND nd.ndi #define ND nd.ndi
newflags = ND.flags; newflags = ND.flags;
for (i = 1; i < argc; i++) { for (i = 0; i < argc; i++) {
int clear = 0; int clear = 0;
char *cp = argv[i]; char *cp = argv[i];