- make command line argument parsing POSIX compliant. comment from

deraadt NOTE: -I needs to take an arg (there's no way we can take no
  arg/an arg with a single option)
- sscanf overrun
- no variable name on prototype.
- u_int32_t may not be u_long.
- skipped non-host route when printing neighbor cache entries.
- valid and preferred lifetimes are unsigned.
- wording.

Obtained from:	KAME
This commit is contained in:
Hajimu UMEMOTO 2003-11-13 16:02:44 +00:00
parent 835ab74093
commit 3174c1d413
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122615
2 changed files with 284 additions and 185 deletions

View File

@ -1,5 +1,5 @@
.\" $FreeBSD$ .\" $FreeBSD$
.\" $KAME: ndp.8,v 1.15 2001/02/08 07:17:03 itojun Exp $ .\" $KAME: ndp.8,v 1.28 2002/07/17 08:46:33 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.
@ -37,60 +37,97 @@
.Nd control/diagnose IPv6 neighbor discovery protocol .Nd control/diagnose IPv6 neighbor discovery protocol
.\" .\"
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm ndp
.Fl a
.Op Fl nt
.Nm
.Fl A Ar wait
.Op Fl nt
.Nm
.Fl c
.Op Fl nt
.Nm
.Fl d
.Op Fl nt .Op Fl nt
.Ar hostname .Ar hostname
.Nm .Nm ndp
.Fl f .Op Fl nt
.Fl a | Fl c | Fl p
.Nm ndp
.Op Fl nt
.Fl r
.Nm ndp
.Op Fl nt
.Fl H | Fl P | Fl R
.Nm ndp
.Op Fl nt
.Fl A Ar wait
.Nm ndp
.Op Fl nt
.Fl d Ar hostname
.Nm ndp
.Op Fl nt
.Fl f Ar filename
.Nm ndp
.Op Fl nt .Op Fl nt
.Ar filename
.Nm
.Fl H
.Nm
.Fl I
.Op Cm delete | Ar interface
.Nm
.Fl i .Fl i
.Ar interface .Ar interface
.Op Ar flags... .Op Ar flags ...
.Nm .Nm ndp
.Fl p
.Nm
.Fl P
.Nm
.Fl r
.Nm
.Fl R
.Nm
.Fl s
.Op Fl nt .Op Fl nt
.Ar nodename .Fl I Op Ar interface | Li delete
.Ar ether_addr .Nm ndp
.Op Fl nt
.Fl s Ar nodename etheraddr
.Op Li temp .Op Li temp
.Op Li proxy .Op Li proxy
.\" .\"
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm .Nm
utility 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:
.Bl -tag -width NeighborXX
.It Neighbor
IPv6 address of the neighbor.
.It Linklayer Address
Linklayer address of the neighbor.
It could be
.Dq Li (incomplete)
when the address is not available.
.It Netif
Network interface associated with the neighbor cache entry.
.It Expire
The time until expiry of the entry.
The entry could become
.Dq Li permanent ,
in which case it will never expire.
.It S
State of the neighbor cache entry, as a single letter:
.Pp
.Bl -tag -width indent -compact
.It N
Nostate
.It W
Waitdelete
.It I
Incomplete
.It R
Reachable
.It S
Stale
.It D
Delay
.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 .
The field could be followed by a decimal number,
which means the number of NS probes the node has sent during the current state.
.El
.It Fl A Ar wait .It Fl A Ar wait
Repeat Repeat
.Fl a .Fl a
(dump NDP entries) .Pq dump NDP entries
every every
.Ar wait .Ar wait
seconds. seconds.
@ -104,35 +141,42 @@ 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 Cm delete | Ar interface .It Fl I
Shows or specifies the default interface used as the default route when Shows 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, .It Fl I Ar interface
the current default interface will be shown. Specifies the default interface used as the default route when
If an there is no default router.
The
.Ar interface .Ar interface
is specified, the interface will be used as the default. will be used as the default.
If a special keyword .It Fl I Li delete
.Ic delete The current default interface will be deleted from the kernel.
is specified, 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
.Ar flags .Ar flags
are given, are given,
.Nm .Nm
sets or clears the specified flags for the interface. sets or clears the specified flags for the interface.
Each flag should be separated by white spaces or tab characters.
Possible flags are as follows. Possible flags are as follows.
All of the flags can begin with the All of the flags can begin with the
special character special character
.Ql - , .Ql - ,
which means the flag should be cleared. which means the flag should be cleared.
Note that you need
.Fl -
before
.Fl foo
in this case.
.\" .\"
.Pp
.Bl -tag -width Ds -compact .Bl -tag -width Ds -compact
.It Xo .It Xo
.Ic nud .Ic nud
.Xc .Xc
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 .It Xo
@ -146,9 +190,20 @@ unless the
.Li net.inet6.ip6.accept_rtadv .Li net.inet6.ip6.accept_rtadv
variable is non-0, even if the flag is on. variable is non-0, even if the flag is on.
This flag is set to 1 by default. 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
@ -158,20 +213,20 @@ Show default router list.
.It Fl R .It Fl R
Flush all the entries in the default router list. Flush all the entries in the default router list.
.It Fl s .It Fl s
Register an NDP entry for a node. Register a NDP entry for a node.
The entry will be permanent unless the word The entry will be permanent unless the word
.Li temp .Li temp
is given in the command. is given in the command.
If the word If the word
.Li proxy .Li proxy
is given, this system will act as a proxy NDP server, is given, this system will act as an proxy NDP server,
responding to requests for 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 1 . .Xr tcpdump 8 .
Most useful when used with Most useful when used with
.Fl A . .Fl A .
.El .El
@ -179,7 +234,7 @@ Most useful when used with
.Sh RETURN VALUES .Sh RETURN VALUES
The The
.Nm .Nm
utility will exit with 0 on success, and non-zero on errors. command will exit with 0 on success, and non-zero on errors.
.\" .\"
.Sh SEE ALSO .Sh SEE ALSO
.Xr arp 8 .Xr arp 8
@ -187,7 +242,7 @@ utility will exit with 0 on success, and non-zero on errors.
.Sh HISTORY .Sh HISTORY
The The
.Nm .Nm
utility first appeared in WIDE Hydrangea IPv6 protocol stack kit. command first appeared in the WIDE Hydrangea IPv6 protocol stack kit.
.\" .\"
.\" .Sh BUGS .\" .Sh BUGS
.\" (to be written) .\" (to be written)

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* $KAME: ndp.c,v 1.65 2001/05/08 04:36:34 itojun Exp $ */ /* $KAME: ndp.c,v 1.104 2003/06/27 07:48:39 itojun Exp $ */
/* /*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -111,6 +111,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <err.h>
#include "gmt2local.h" #include "gmt2local.h"
/* packing rule for routing socket */ /* packing rule for routing socket */
@ -119,7 +120,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 */
@ -136,14 +136,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 *addr, static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *, int, int));
int ifindex, 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));
@ -154,16 +153,21 @@ void harmonize_rtr __P((void));
static void getdefif __P((void)); static void getdefif __P((void));
static void setdefif __P((char *)); static void setdefif __P((char *));
#endif #endif
static char *sec2str __P((time_t t)); static char *sec2str __P((time_t));
static char *ether_str __P((struct sockaddr_dl *sdl)); static char *ether_str __P((struct sockaddr_dl *));
static void ts_print __P((const struct timeval *)); static void ts_print __P((const struct timeval *));
#ifdef ICMPV6CTL_ND6_DRLIST
static char *rtpref_str[] = { static char *rtpref_str[] = {
"medium", /* 00 */ "medium", /* 00 */
"high", /* 01 */ "high", /* 01 */
"rsv", /* 10 */ "rsv", /* 10 */
"low" /* 11 */ "low" /* 11 */
}; };
#endif
int mode = 0;
char *arg = NULL;
int int
main(argc, argv) main(argc, argv)
@ -171,76 +175,54 @@ main(argc, argv)
char **argv; char **argv;
{ {
int ch; int ch;
int aflag = 0, dflag = 0, sflag = 0, Hflag = 0,
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:Ii:nprstA:HPR")) != -1)
switch (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':
case 'I':
if (mode) {
usage();
/*NOTREACHED*/
}
mode = ch;
arg = NULL;
break; break;
case 'd': case 'd':
dflag = 1; case 'f':
break;
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();
@ -249,45 +231,90 @@ 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 > 1) {
usage();
/*NOTREACHED*/
} else if (argc == 1) {
if (strcmp(*argv, "delete") == 0 ||
if_nametoindex(*argv))
setdefif(*argv);
else
errx(1, "invalid interface %s", *argv);
}
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);
} }
@ -313,8 +340,8 @@ file(name)
args[4] = &arg[4][0]; args[4] = &arg[4][0];
retval = 0; retval = 0;
while (fgets(line, 100, fp) != NULL) { while (fgets(line, 100, fp) != NULL) {
i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2], i = sscanf(line, "%49s %49s %49s %49s %49s",
arg[3], arg[4]); arg[0], arg[1], arg[2], arg[3], arg[4]);
if (i < 2) { if (i < 2) {
fprintf(stderr, "ndp: bad line: %s\n", line); fprintf(stderr, "ndp: bad line: %s\n", line);
retval = 1; retval = 1;
@ -408,10 +435,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.
@ -457,7 +486,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,
@ -541,7 +570,7 @@ delete(host)
return 0; return 0;
} }
#define W_ADDR 31 #define W_ADDR 36
#define W_LL 17 #define W_LL 17
#define W_IF 6 #define W_IF 6
@ -549,8 +578,9 @@ delete(host)
* 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;
@ -569,9 +599,9 @@ dump(addr)
/* Print header */ /* Print header */
if (!tflag && !cflag) if (!tflag && !cflag)
printf("%-*.*s %-*.*s %*.*s %-9.9s %2s %4s %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", "St", "Flgs", "Prbs"); W_IF, W_IF, "Netif", "Expire", "S", "Flags");
again:; again:;
mib[0] = CTL_NET; mib[0] = CTL_NET;
@ -614,6 +644,9 @@ again:;
if (sdl->sdl_family != AF_LINK) if (sdl->sdl_family != AF_LINK)
continue; continue;
if (!(rtm->rtm_flags & RTF_HOST))
continue;
if (addr) { if (addr) {
if (!IN6_ARE_ADDR_EQUAL(addr, &sin->sin6_addr)) if (!IN6_ARE_ADDR_EQUAL(addr, &sin->sin6_addr))
continue; continue;
@ -632,10 +665,13 @@ again:;
} }
getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf,
sizeof(host_buf), NULL, 0, (nflag ? NI_NUMERICHOST : 0)); sizeof(host_buf), NULL, 0, (nflag ? NI_NUMERICHOST : 0));
if (cflag == 1) { if (cflag) {
#ifdef RTF_WASCLONED #ifdef RTF_WASCLONED
if (rtm->rtm_flags & RTF_WASCLONED) if (rtm->rtm_flags & RTF_WASCLONED)
delete(host_buf); delete(host_buf);
#elif defined(RTF_CLONED)
if (rtm->rtm_flags & RTF_CLONED)
delete(host_buf);
#else #else
delete(host_buf); delete(host_buf);
#endif #endif
@ -707,7 +743,6 @@ again:;
warnx("failed to get neighbor information"); warnx("failed to get neighbor information");
printf(" "); printf(" ");
} }
putchar(' ');
/* /*
* other flags. R: router, P: proxy, W: ?? * other flags. R: router, P: proxy, W: ??
@ -719,16 +754,22 @@ again:;
} else { } else {
sin = (struct sockaddr_in6 *) sin = (struct sockaddr_in6 *)
(sdl->sdl_len + (char *)sdl); (sdl->sdl_len + (char *)sdl);
#if 0 /* W and P are mystery even for us */
snprintf(flgbuf, sizeof(flgbuf), "%s%s%s%s", snprintf(flgbuf, sizeof(flgbuf), "%s%s%s%s",
isrouter ? "R" : "", isrouter ? "R" : "",
!IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) ? "P" : "", !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) ? "P" : "",
(sin->sin6_len != sizeof(struct sockaddr_in6)) ? "W" : "", (sin->sin6_len != sizeof(struct sockaddr_in6)) ? "W" : "",
(rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : "");
#else
snprintf(flgbuf, sizeof(flgbuf), "%s%s",
isrouter ? "R" : "",
(rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : "");
#endif
} }
printf(" %-4.4s", flgbuf); printf(" %s", flgbuf);
if (prbs) if (prbs)
printf(" %4d", prbs); printf(" %d", prbs);
printf("\n"); printf("\n");
} }
@ -806,22 +847,16 @@ ndp_ether_aton(a, n)
void void
usage() usage()
{ {
printf("usage: ndp hostname\n"); printf("usage: ndp [-nt] hostname\n");
printf(" ndp -a[nt]\n"); printf(" ndp [-nt] -a | -c | -p | -r | -H | -P | -R\n");
printf(" ndp [-nt] -A wait\n"); printf(" ndp [-nt] -A wait\n");
printf(" ndp -c[nt]\n"); printf(" ndp [-nt] -d hostname\n");
printf(" ndp -d[nt] hostname\n"); printf(" ndp [-nt] -f filename\n");
printf(" ndp -f[nt] filename\n"); printf(" ndp [-nt] -i interface [flags...]\n");
printf(" ndp -i interface [flags...]\n");
#ifdef SIOCSDEFIFACE_IN6 #ifdef SIOCSDEFIFACE_IN6
printf(" ndp -I [interface|delete]\n"); printf(" ndp [-nt] -I [interface|delete]\n");
#endif #endif
printf(" ndp -p\n"); printf(" ndp [-nt] -s nodename etheraddr [temp] [proxy]\n");
printf(" ndp -r\n");
printf(" ndp -s hostname ether_addr [temp] [proxy]\n");
printf(" ndp -H\n");
printf(" ndp -P\n");
printf(" ndp -R\n");
exit(1); exit(1);
} }
@ -848,8 +883,10 @@ rtmsg(cmd)
exit(1); exit(1);
case RTM_ADD: case RTM_ADD:
rtm->rtm_addrs |= RTA_GATEWAY; rtm->rtm_addrs |= RTA_GATEWAY;
rtm->rtm_rmx.rmx_expire = expire_time; if (expire_time) {
rtm->rtm_inits = RTV_EXPIRE; rtm->rtm_rmx.rmx_expire = expire_time;
rtm->rtm_inits = RTV_EXPIRE;
}
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC); rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
if (rtm->rtm_flags & RTF_ANNOUNCE) { if (rtm->rtm_flags & RTF_ANNOUNCE) {
rtm->rtm_flags &= ~RTF_HOST; rtm->rtm_flags &= ~RTF_HOST;
@ -889,13 +926,13 @@ rtmsg(cmd)
} }
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];
@ -910,10 +947,10 @@ ifinfo(argc, argv)
if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) {
err(1, "ioctl(SIOCGIFINFO_IN6)"); err(1, "ioctl(SIOCGIFINFO_IN6)");
/* NOTREACHED */ /* NOTREACHED */
} }
#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];
@ -935,6 +972,9 @@ ifinfo(argc, argv)
#ifdef ND6_IFF_ACCEPT_RTADV #ifdef ND6_IFF_ACCEPT_RTADV
SETFLAG("accept_rtadv", ND6_IFF_ACCEPT_RTADV); SETFLAG("accept_rtadv", ND6_IFF_ACCEPT_RTADV);
#endif #endif
#ifdef ND6_IFF_PREFER_SOURCE
SETFLAG("prefer_source", ND6_IFF_PREFER_SOURCE);
#endif
ND.flags = newflags; ND.flags = newflags;
if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) { if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) {
@ -990,7 +1030,11 @@ ifinfo(argc, argv)
if ((ND.flags & ND6_IFF_ACCEPT_RTADV)) if ((ND.flags & ND6_IFF_ACCEPT_RTADV))
printf("accept_rtadv "); printf("accept_rtadv ");
#endif #endif
} #ifdef ND6_IFF_PREFER_SOURCE
if ((ND.flags & ND6_IFF_PREFER_SOURCE))
printf("prefer_source ");
#endif
}
putc('\n', stdout); putc('\n', stdout);
#undef ND #undef ND
@ -1153,11 +1197,11 @@ plist()
if (p->vltime == ND6_INFINITE_LIFETIME) if (p->vltime == ND6_INFINITE_LIFETIME)
printf(" vltime=infinity"); printf(" vltime=infinity");
else else
printf(" vltime=%ld", (long)p->vltime); printf(" vltime=%lu", (unsigned long)p->vltime);
if (p->pltime == ND6_INFINITE_LIFETIME) if (p->pltime == ND6_INFINITE_LIFETIME)
printf(", pltime=infinity"); printf(", pltime=infinity");
else else
printf(", pltime=%ld", (long)p->pltime); printf(", pltime=%lu", (unsigned long)p->pltime);
if (p->expire == 0) if (p->expire == 0)
printf(", expire=Never"); printf(", expire=Never");
else if (p->expire >= time.tv_sec) else if (p->expire >= time.tv_sec)
@ -1175,7 +1219,7 @@ plist()
int j; int j;
struct sockaddr_in6 *sin6; struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)(p + 1); sin6 = advrtr;
printf(" advertised by\n"); printf(" advertised by\n");
for (j = 0; j < p->advrtrs; j++) { for (j = 0; j < p->advrtrs; j++) {
struct in6_nbrinfo *nbi; struct in6_nbrinfo *nbi;
@ -1293,11 +1337,11 @@ plist()
if (PR.vltime == ND6_INFINITE_LIFETIME) if (PR.vltime == ND6_INFINITE_LIFETIME)
printf(" vltime=infinity"); printf(" vltime=infinity");
else else
printf(" vltime=%ld", (long)PR.vltime); printf(" vltime=%lu", PR.vltime);
if (PR.pltime == ND6_INFINITE_LIFETIME) if (PR.pltime == ND6_INFINITE_LIFETIME)
printf(", pltime=infinity"); printf(", pltime=infinity");
else else
printf(", pltime=%ld", (long)PR.pltime); printf(", pltime=%lu", PR.pltime);
if (PR.expire == 0) if (PR.expire == 0)
printf(", expire=Never"); printf(", expire=Never");
else if (PR.expire >= time.tv_sec) else if (PR.expire >= time.tv_sec)