summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ndp/ndp.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-11-13 16:02:44 +0000
committerume <ume@FreeBSD.org>2003-11-13 16:02:44 +0000
commit59af8d55c7f5cc534f1685da36373c3445ef7954 (patch)
tree3e0528436ece4d58e7b145e6ab35ea51b175f8dc /usr.sbin/ndp/ndp.c
parent650f540b8d6f1e889ef3f8bd86211668f13343dc (diff)
downloadFreeBSD-src-59af8d55c7f5cc534f1685da36373c3445ef7954.zip
FreeBSD-src-59af8d55c7f5cc534f1685da36373c3445ef7954.tar.gz
- 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
Diffstat (limited to 'usr.sbin/ndp/ndp.c')
-rw-r--r--usr.sbin/ndp/ndp.c300
1 files changed, 172 insertions, 128 deletions
diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index bd55ef7..a761f96 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -1,5 +1,5 @@
/* $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.
@@ -111,6 +111,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
+#include <err.h>
#include "gmt2local.h"
/* packing rule for routing socket */
@@ -119,7 +120,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 */
@@ -136,14 +136,13 @@ void getsocket __P((void));
int set __P((int, char **));
void get __P((char *));
int delete __P((char *));
-void dump __P((struct in6_addr *));
-static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *addr,
- int ifindex, int));
+void dump __P((struct in6_addr *, int));
+static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *, int, int));
static char *ether_str __P((struct sockaddr_dl *));
int ndp_ether_aton __P((char *, u_char *));
void usage __P((void));
int rtmsg __P((int));
-void ifinfo __P((int, char **));
+void ifinfo __P((char *, int, char **));
void rtrlist __P((void));
void plist __P((void));
void pfx_flush __P((void));
@@ -154,16 +153,21 @@ void harmonize_rtr __P((void));
static void getdefif __P((void));
static void setdefif __P((char *));
#endif
-static char *sec2str __P((time_t t));
-static char *ether_str __P((struct sockaddr_dl *sdl));
+static char *sec2str __P((time_t));
+static char *ether_str __P((struct sockaddr_dl *));
static void ts_print __P((const struct timeval *));
+#ifdef ICMPV6CTL_ND6_DRLIST
static char *rtpref_str[] = {
"medium", /* 00 */
"high", /* 01 */
"rsv", /* 10 */
"low" /* 11 */
};
+#endif
+
+int mode = 0;
+char *arg = NULL;
int
main(argc, argv)
@@ -171,76 +175,54 @@ main(argc, argv)
char **argv;
{
int ch;
- int aflag = 0, dflag = 0, sflag = 0, Hflag = 0,
- pflag = 0, rflag = 0, Pflag = 0, Rflag = 0;
pid = getpid();
thiszone = gmt2local(0);
- while ((ch = getopt(argc, argv, "acndfIilprstA:HPR")) != -1)
+ while ((ch = getopt(argc, argv, "acd:f:Ii: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':
+ case 'I':
+ if (mode) {
+ usage();
+ /*NOTREACHED*/
+ }
+ mode = ch;
+ arg = NULL;
break;
case 'd':
- dflag = 1;
- 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 'f':
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 +231,90 @@ 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 > 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();
- 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);
}
@@ -313,8 +340,8 @@ file(name)
args[4] = &arg[4][0];
retval = 0;
while (fgets(line, 100, fp) != NULL) {
- i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2],
- arg[3], arg[4]);
+ i = sscanf(line, "%49s %49s %49s %49s %49s",
+ arg[0], arg[1], arg[2], arg[3], arg[4]);
if (i < 2) {
fprintf(stderr, "ndp: bad line: %s\n", line);
retval = 1;
@@ -408,10 +435,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 +486,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,
@@ -541,7 +570,7 @@ delete:
return 0;
}
-#define W_ADDR 31
+#define W_ADDR 36
#define W_LL 17
#define W_IF 6
@@ -549,8 +578,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 +599,9 @@ dump(addr)
/* Print header */
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_IF, W_IF, "Netif", "Expire", "St", "Flgs", "Prbs");
+ W_IF, W_IF, "Netif", "Expire", "S", "Flags");
again:;
mib[0] = CTL_NET;
@@ -614,6 +644,9 @@ again:;
if (sdl->sdl_family != AF_LINK)
continue;
+ if (!(rtm->rtm_flags & RTF_HOST))
+ continue;
+
if (addr) {
if (!IN6_ARE_ADDR_EQUAL(addr, &sin->sin6_addr))
continue;
@@ -632,10 +665,13 @@ again:;
}
getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf,
sizeof(host_buf), NULL, 0, (nflag ? NI_NUMERICHOST : 0));
- if (cflag == 1) {
+ if (cflag) {
#ifdef RTF_WASCLONED
if (rtm->rtm_flags & RTF_WASCLONED)
delete(host_buf);
+#elif defined(RTF_CLONED)
+ if (rtm->rtm_flags & RTF_CLONED)
+ delete(host_buf);
#else
delete(host_buf);
#endif
@@ -707,7 +743,6 @@ again:;
warnx("failed to get neighbor information");
printf(" ");
}
- putchar(' ');
/*
* other flags. R: router, P: proxy, W: ??
@@ -719,16 +754,22 @@ again:;
} else {
sin = (struct sockaddr_in6 *)
(sdl->sdl_len + (char *)sdl);
+#if 0 /* W and P are mystery even for us */
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" : "",
(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)
- printf(" %4d", prbs);
+ printf(" %d", prbs);
printf("\n");
}
@@ -806,22 +847,16 @@ ndp_ether_aton(a, n)
void
usage()
{
- printf("usage: ndp hostname\n");
- printf(" ndp -a[nt]\n");
+ printf("usage: ndp [-nt] hostname\n");
+ printf(" ndp [-nt] -a | -c | -p | -r | -H | -P | -R\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 -i interface [flags...]\n");
+ printf(" ndp [-nt] -d hostname\n");
+ printf(" ndp [-nt] -f filename\n");
+ printf(" ndp [-nt] -i interface [flags...]\n");
#ifdef SIOCSDEFIFACE_IN6
- printf(" ndp -I [interface|delete]\n");
+ printf(" ndp [-nt] -I [interface|delete]\n");
#endif
- printf(" ndp -p\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");
+ printf(" ndp [-nt] -s nodename etheraddr [temp] [proxy]\n");
exit(1);
}
@@ -848,8 +883,10 @@ rtmsg(cmd)
exit(1);
case RTM_ADD:
rtm->rtm_addrs |= RTA_GATEWAY;
- rtm->rtm_rmx.rmx_expire = expire_time;
- rtm->rtm_inits = RTV_EXPIRE;
+ if (expire_time) {
+ 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;
@@ -889,13 +926,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];
@@ -910,10 +947,10 @@ ifinfo(argc, argv)
if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) {
err(1, "ioctl(SIOCGIFINFO_IN6)");
/* NOTREACHED */
- }
+ }
#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];
@@ -935,6 +972,9 @@ ifinfo(argc, argv)
#ifdef ND6_IFF_ACCEPT_RTADV
SETFLAG("accept_rtadv", ND6_IFF_ACCEPT_RTADV);
#endif
+#ifdef ND6_IFF_PREFER_SOURCE
+ SETFLAG("prefer_source", ND6_IFF_PREFER_SOURCE);
+#endif
ND.flags = newflags;
if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) {
@@ -990,7 +1030,11 @@ ifinfo(argc, argv)
if ((ND.flags & ND6_IFF_ACCEPT_RTADV))
printf("accept_rtadv ");
#endif
-}
+#ifdef ND6_IFF_PREFER_SOURCE
+ if ((ND.flags & ND6_IFF_PREFER_SOURCE))
+ printf("prefer_source ");
+#endif
+ }
putc('\n', stdout);
#undef ND
@@ -1153,11 +1197,11 @@ plist()
if (p->vltime == ND6_INFINITE_LIFETIME)
printf(" vltime=infinity");
else
- printf(" vltime=%ld", (long)p->vltime);
+ printf(" vltime=%lu", (unsigned long)p->vltime);
if (p->pltime == ND6_INFINITE_LIFETIME)
printf(", pltime=infinity");
else
- printf(", pltime=%ld", (long)p->pltime);
+ printf(", pltime=%lu", (unsigned long)p->pltime);
if (p->expire == 0)
printf(", expire=Never");
else if (p->expire >= time.tv_sec)
@@ -1175,7 +1219,7 @@ plist()
int j;
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)(p + 1);
+ sin6 = advrtr;
printf(" advertised by\n");
for (j = 0; j < p->advrtrs; j++) {
struct in6_nbrinfo *nbi;
@@ -1293,11 +1337,11 @@ plist()
if (PR.vltime == ND6_INFINITE_LIFETIME)
printf(" vltime=infinity");
else
- printf(" vltime=%ld", (long)PR.vltime);
+ printf(" vltime=%lu", PR.vltime);
if (PR.pltime == ND6_INFINITE_LIFETIME)
printf(", pltime=infinity");
else
- printf(", pltime=%ld", (long)PR.pltime);
+ printf(", pltime=%lu", PR.pltime);
if (PR.expire == 0)
printf(", expire=Never");
else if (PR.expire >= time.tv_sec)
OpenPOWER on IntegriCloud