summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-02-28 11:56:42 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-02-28 11:56:42 +0000
commit607685e18ba9cdeff5d77cdea210e356184f0f97 (patch)
tree4fa8dc1eb7e9d23a5f6ecebd570d5e1c2614bac3
parent15bfd42ebaec37ba450f58b4943cb687022f54e1 (diff)
bring in latest kame code.
- ndp -I (set default outgoing interface when no default router is defined) - ndp -s proxy (proxy NDP)
-rw-r--r--usr.sbin/ndp/ndp.841
-rw-r--r--usr.sbin/ndp/ndp.c127
2 files changed, 131 insertions, 37 deletions
diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8
index 9b0d1bcd5af..fc410e3165c 100644
--- a/usr.sbin/ndp/ndp.8
+++ b/usr.sbin/ndp/ndp.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ndp.8,v 1.3 2000/01/04 21:12:18 deraadt Exp $
+.\" $OpenBSD: ndp.8,v 1.4 2000/02/28 11:56:40 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" KAME Id: ndp.8,v 1.1.1.1 1999/12/10 07:17:07 itojun Exp
+.\" KAME Id: ndp.8,v 1.5 2000/02/17 05:35:56 itojun Exp
.\"
.Dd May 17, 1998
.Dt NDP 8
@@ -57,9 +57,9 @@
.Ar filename
.Nm ndp
.Fl H
-.\" .Nm ndp
-.\" .Fl I
-.\" .Ar interface
+.Nm ndp
+.Fl I
+.Op delete \(ba Ar interface
.Nm ndp
.Fl i
.Ar interface
@@ -76,7 +76,8 @@
.Op Fl nt
.Ar nodename
.Ar ether_addr
-.Op temp
+.Op Li temp
+.Op Li proxy
.\"
.Sh DESCRIPTION
.Nm
@@ -102,12 +103,19 @@ 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
-.\" .Ar interface
-.\" Specifies the default interface used as the default route when
-.\" there is no default router.
-.It Fl i Ar interface
-View ND information for specified interface.
+.It Fl I Op delete \(ba 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 deafult interface will be shown.
+If an
+.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.
+.It Fl i
+.Ar interface
+view ND information for specified interface.
.It Fl l
Do not truncate numeric IPv6 address.
.It Fl n
@@ -122,6 +130,15 @@ Show default router list.
Flush all the entries in the default router list.
.It Fl s
Register a NDP entry for a node.
+The entry will be permanent unless the word
+.Li temp
+is given in the command.
+If the word
+.Li 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
diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index b4235555418..e02383d527a 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ndp.c,v 1.3 2000/02/01 03:24:05 deraadt Exp $ */
+/* $OpenBSD: ndp.c,v 1.4 2000/02/28 11:56:41 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@@ -156,7 +156,8 @@ void plist __P((void));
void pfx_flush __P((void));
void rtr_flush __P((void));
void harmonize_rtr __P((void));
-#ifdef SIOCSDEFIFACE_IN6
+#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */
+static void getdefif __P((void));
static void setdefif __P((char *));
#endif
static char *sec2str __P((time_t t));
@@ -176,7 +177,7 @@ main(argc, argv)
pid = getpid();
thiszone = gmt2local(0);
- while ((ch = getopt(argc, argv, "acndfI:ilprstA:HPR")) != EOF)
+ while ((ch = getopt(argc, argv, "acndfIilprstA:HPR")) != EOF)
switch ((char)ch) {
case 'a':
aflag = 1;
@@ -189,8 +190,10 @@ main(argc, argv)
dflag = 1;
break;
case 'I':
-#ifdef SIOCSDEFIFACE_IN6
- setdefif(optarg);
+#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");
@@ -335,7 +338,7 @@ getsocket()
}
}
-struct sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}};
+struct sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 };
struct sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m;
struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
int expire_time, flags, found_entry;
@@ -384,7 +387,8 @@ set(argc, argv)
struct timeval time;
gettimeofday(&time, 0);
expire_time = time.tv_sec + 20 * 60;
- }
+ } else if (strncmp(argv[0], "proxy", 5) == 0)
+ flags |= RTF_ANNOUNCE;
argv++;
}
tryagain:
@@ -642,17 +646,19 @@ again:;
* other flags. R: router, P: proxy, W: ??
*/
if ((rtm->rtm_addrs & RTA_NETMASK) == 0) {
- snprintf(flgbuf, sizeof(flgbuf), "%s",
- isrouter ? "R" : "");
+ snprintf(flgbuf, sizeof(flgbuf), "%s%s",
+ isrouter ? "R" : "",
+ (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : "");
} else {
sin = (struct sockaddr_in6 *)
(sdl->sdl_len + (char *)sdl);
- snprintf(flgbuf, sizeof(flgbuf), "%s%s%s",
+ 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" : "");
+ ? "W" : "",
+ (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : "");
}
printf(" %-4.4s", flgbuf);
@@ -743,11 +749,11 @@ usage()
printf(" ndp -f[nt] filename\n");
printf(" ndp -i interface\n");
#ifdef SIOCSDEFIFACE_IN6
- printf(" ndp -I interface\n");
+ printf(" ndp -I [interface|delete]\n");
#endif
printf(" ndp -p\n");
printf(" ndp -r\n");
- printf(" ndp -s hostname ether_addr [temp]\n");
+ printf(" ndp -s hostname ether_addr [temp] [proxy]\n");
printf(" ndp -H\n");
printf(" ndp -P\n");
printf(" ndp -R\n");
@@ -780,6 +786,10 @@ rtmsg(cmd)
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;
+ rtm->rtm_flags |= RTA_NETMASK;
+ }
/* FALLTHROUGH */
case RTM_GET:
rtm->rtm_addrs |= RTA_DST;
@@ -790,6 +800,7 @@ rtmsg(cmd)
NEXTADDR(RTA_DST, sin_m);
NEXTADDR(RTA_GATEWAY, sdl_m);
+ memset(&so_mask.sin6_addr, 0xff, sizeof(so_mask.sin6_addr));
NEXTADDR(RTA_NETMASK, so_mask);
rtm->rtm_msglen = cp - (char *)&m_rtmsg;
@@ -911,7 +922,12 @@ plist()
sizeof(ntop_buf)), PR.prefixlen,
if_indextoname(PR.if_index, ifix_buf));
gettimeofday(&time, 0);
- printf(" flags=%s%s",
+ /*
+ * meaning of fields, especially flags, is very different
+ * by origin. notify the difference to the users.
+ */
+ printf(" %s", PR.origin == PR_ORIG_RA ? "" : "advertise: ");
+ printf("flags=%s%s",
PR.raflags.onlink ? "L" : "",
PR.raflags.autonomous ? "A" : "");
if (PR.vltime == ND6_INFINITE_LIFETIME)
@@ -923,13 +939,37 @@ plist()
else
printf(", pltime=%ld", (long)PR.pltime);
if (PR.expire == 0)
- printf(", expire=Never\n");
+ printf(", expire=Never");
else if (PR.expire >= time.tv_sec)
- printf(", expire=%s\n",
+ printf(", expire=%s",
sec2str(PR.expire - time.tv_sec));
else
- printf(", expired\n");
- if (PR.advrtrs) {
+ printf(", expired");
+ switch (PR.origin) {
+ case PR_ORIG_RA:
+ printf(", origin=RA");
+ break;
+ case PR_ORIG_RR:
+ printf(", origin=RR");
+ break;
+ case PR_ORIG_STATIC:
+ printf(", origin=static");
+ break;
+ case PR_ORIG_KERNEL:
+ printf(", origin=kernel");
+ break;
+ default:
+ printf(", origin=?");
+ break;
+ }
+ printf("\n");
+ /*
+ * "advertising router" list is meaningful only if the prefix
+ * information is from RA.
+ */
+ if (PR.origin != PR_ORIG_RA)
+ ;
+ else if (PR.advrtrs) {
int j;
printf(" advertised by\n");
for (j = 0; j < PR.advrtrs; j++) {
@@ -967,8 +1007,7 @@ plist()
if (PR.advrtrs > DRLSTSIZ)
printf(" and %d routers\n",
PR.advrtrs - DRLSTSIZ);
- }
- else
+ } else
printf(" No advertising router\n");
}
#undef PR
@@ -1010,7 +1049,7 @@ harmonize_rtr()
int s;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
- err(1, "ndp: socket");
+ err(1, "socket");
strcpy(dummyif, "lo0"); /* dummy */
if (ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0)
err(1, "ioctl (SIOCSNDFLUSH_IN6)");
@@ -1018,21 +1057,59 @@ harmonize_rtr()
close(s);
}
-#ifdef SIOCSDEFIFACE_IN6
+#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */
static void
setdefif(ifname)
char *ifname;
{
- int s;
+ struct in6_ndifreq ndifreq;
+ unsigned int ifindex;
+
+ if (strcasecmp(ifname, "delete") == 0)
+ ifindex = 0;
+ else {
+ if ((ifindex = if_nametoindex(ifname)) == 0)
+ err(1, "failed to resolve i/f index for %s", ifname);
+ }
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
- err(1, "ndp: socket");
+ err(1, "socket");
+
+ strcpy(ndifreq.ifname, "lo0"); /* dummy */
+ ndifreq.ifindex = ifindex;
- if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)ifname) < 0)
+ if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) < 0)
err(1, "ioctl (SIOCSDEFIFACE_IN6)");
close(s);
}
+
+static void
+getdefif()
+{
+ struct in6_ndifreq ndifreq;
+ char ifname[IFNAMSIZ+8];
+
+ if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ err(1, "socket");
+
+ memset(&ndifreq, 0, sizeof(ndifreq));
+ strcpy(ndifreq.ifname, "lo0"); /* dummy */
+
+ if (ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq) < 0)
+ err(1, "ioctl (SIOCGDEFIFACE_IN6)");
+
+ if (ndifreq.ifindex == 0)
+ printf("No default interface.\n");
+ else {
+ if ((if_indextoname(ndifreq.ifindex, ifname)) == NULL)
+ err(1, "failed to resolve ifname for index %lu",
+ ndifreq.ifindex);
+ printf("ND default interface = %s\n", ifname);
+ }
+
+ close(s);
+}
#endif
static char *