summaryrefslogtreecommitdiffstats
path: root/usr.bin/netstat/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/netstat/route.c')
-rw-r--r--usr.bin/netstat/route.c193
1 files changed, 176 insertions, 17 deletions
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c
index 9b747220843..ce1643fc846 100644
--- a/usr.bin/netstat/route.c
+++ b/usr.bin/netstat/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.29 1999/09/22 05:10:04 deraadt Exp $ */
+/* $OpenBSD: route.c,v 1.30 1999/12/08 12:30:17 itojun Exp $ */
/* $NetBSD: route.c,v 1.15 1996/05/07 02:55:06 thorpej Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94";
#else
-static char *rcsid = "$OpenBSD: route.c,v 1.29 1999/09/22 05:10:04 deraadt Exp $";
+static char *rcsid = "$OpenBSD: route.c,v 1.30 1999/12/08 12:30:17 itojun Exp $";
#endif
#endif /* not lint */
@@ -64,6 +64,8 @@ static char *rcsid = "$OpenBSD: route.c,v 1.29 1999/09/22 05:10:04 deraadt Exp $
#include <sys/sysctl.h>
+#include <arpa/inet.h>
+
#include <limits.h>
#include <netdb.h>
#include <stdio.h>
@@ -167,7 +169,7 @@ routepr(rtree)
pr_family(i);
do_rtent = 1;
if (i != PF_KEY)
- pr_rthdr();
+ pr_rthdr(i);
else
pr_encaphdr();
p_tree(head.rnh_treetop);
@@ -189,6 +191,11 @@ pr_family(af)
case AF_INET:
afname = "Internet";
break;
+#ifdef INET6
+ case AF_INET6:
+ afname = "Internet6";
+ break;
+#endif
case AF_NS:
afname = "XNS";
break;
@@ -218,21 +225,35 @@ pr_family(af)
}
/* column widths; each followed by one space */
-#define WID_DST 18 /* width of destination column */
-#define WID_GW 18 /* width of gateway column */
+#ifndef INET6
+#define WID_DST(af) 18 /* width of destination column */
+#define WID_GW(af) 18 /* width of gateway column */
+#else
+/* width of destination/gateway column */
+#ifdef KAME_SCOPEID
+/* strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 */
+#define WID_DST(af) ((af) == AF_INET6 ? (nflag ? 34 : 18) : 18)
+#define WID_GW(af) ((af) == AF_INET6 ? (nflag ? 30 : 18) : 18)
+#else
+/* strlen("fe80::aaaa:bbbb:cccc:dddd") == 25, strlen("/128") == 4 */
+#define WID_DST(af) ((af) == AF_INET6 ? (nflag ? 29 : 18) : 18)
+#define WID_GW(af) ((af) == AF_INET6 ? (nflag ? 25 : 18) : 18)
+#endif
+#endif /* INET6 */
/*
* Print header for routing table columns.
*/
void
-pr_rthdr()
+pr_rthdr(af)
+ int af;
{
if (Aflag)
printf("%-*.*s ", PLEN, PLEN, "Address");
printf("%-*.*s %-*.*s %-6.6s %6.6s %6.6s %6.6s %s\n",
- WID_DST, WID_DST, "Destination",
- WID_GW, WID_GW, "Gateway",
+ WID_DST(af), WID_DST(af), "Destination",
+ WID_GW(af), WID_GW(af), "Gateway",
"Flags", "Refs", "Use", "Mtu", "Interface");
}
@@ -425,6 +446,36 @@ p_sockaddr(sa, mask, flags, width)
break;
}
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
+#ifdef KAME_SCOPEID
+ struct in6_addr *in6 = &sa6->sin6_addr;
+
+ /*
+ * XXX: This is a special workaround for KAME kernels.
+ * sin6_scope_id field of SA should be set in the future.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(in6) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(in6)) {
+ /* XXX: override is ok? */
+ sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *)&in6->s6_addr[2]);
+ *(u_short *)&in6->s6_addr[2] = 0;
+ }
+#endif
+
+ if (flags & RTF_HOST)
+ cp = routename6(sa6);
+ else if (mask) {
+ cp = netname6(sa6,
+ &((struct sockaddr_in6 *)mask)->sin6_addr);
+ } else
+ cp = netname6(sa6, NULL);
+ break;
+ }
+#endif
+
case AF_NS:
cp = ns_print(sa);
break;
@@ -532,23 +583,28 @@ p_rtentry(rt)
register struct rtentry *rt;
{
static struct ifnet ifnet, *lastif;
- struct sockaddr sock1, sock2;
- struct sockaddr *sa = &sock1, *mask = &sock2;
+ struct sockaddr_storage sock1, sock2;
+ struct sockaddr *sa = (struct sockaddr *)&sock1;
+ struct sockaddr *mask = (struct sockaddr *)&sock2;
bcopy(kgetsa(rt_key(rt)), sa, sizeof(struct sockaddr));
+ if (sa->sa_len > sizeof(struct sockaddr))
+ bcopy(kgetsa(rt_key(rt)), sa, sa->sa_len);
if (sa->sa_family == PF_KEY) {
encap_print(rt);
return;
}
- if (rt_mask(rt))
+ if (rt_mask(rt)) {
bcopy(kgetsa(rt_mask(rt)), mask, sizeof(struct sockaddr));
- else
+ if (sa->sa_len > sizeof(struct sockaddr))
+ bcopy(kgetsa(rt_mask(rt)), mask, sa->sa_len);
+ } else
mask = 0;
- p_sockaddr(sa, mask, rt->rt_flags, WID_DST);
- p_sockaddr(kgetsa(rt->rt_gateway), 0, RTF_HOST, WID_GW);
+ p_sockaddr(sa, mask, rt->rt_flags, WID_DST(sa->sa_family));
+ p_sockaddr(kgetsa(rt->rt_gateway), 0, RTF_HOST, WID_GW(sa->sa_family));
p_flags(rt->rt_flags, "%-6.6s ");
printf("%6d %8ld ", rt->rt_refcnt, rt->rt_use);
if (rt->rt_rmx.rmx_mtu)
@@ -618,13 +674,12 @@ netname(in, mask)
char *cp = 0;
static char line[MAXHOSTNAMELEN];
struct netent *np = 0;
- in_addr_t net, subnetshift;
int mbits;
in = ntohl(in);
mask = ntohl(mask);
if (!nflag && in != INADDR_ANY) {
- if (np = getnetbyaddr(in, AF_INET))
+ if ((np = getnetbyaddr(in, AF_INET)) != NULL)
cp = np->n_name;
}
mbits = mask ? 33 - ffs(mask) : 0;
@@ -645,6 +700,110 @@ netname(in, mask)
return (line);
}
+#ifdef INET6
+char *
+netname6(sa6, mask)
+ struct sockaddr_in6 *sa6;
+ struct in6_addr *mask;
+{
+ static char line[MAXHOSTNAMELEN + 1];
+ struct in6_addr net6;
+ u_char *p;
+ u_char *lim;
+ int masklen, final = 0, illegal = 0;
+ int i;
+ char hbuf[NI_MAXHOST];
+#ifdef NI_WITHSCOPEID
+ int flag = NI_WITHSCOPEID;
+#else
+ int flag = 0;
+#endif
+
+ net6 = sa6->sin6_addr;
+ for (i = 0; i < sizeof(net6); i++)
+ net6.s6_addr[i] &= mask->s6_addr[i];
+
+ masklen = 0;
+ lim = (u_char *)mask + 16;
+ for (p = (u_char *)mask; p < lim; p++) {
+ if (final && *p) {
+ illegal++;
+ continue;
+ }
+
+ switch (*p & 0xff) {
+ case 0xff:
+ masklen += 8;
+ break;
+ case 0xfe:
+ masklen += 7;
+ final++;
+ break;
+ case 0xfc:
+ masklen += 6;
+ final++;
+ break;
+ case 0xf8:
+ masklen += 5;
+ final++;
+ break;
+ case 0xf0:
+ masklen += 4;
+ final++;
+ break;
+ case 0xe0:
+ masklen += 3;
+ final++;
+ break;
+ case 0xc0:
+ masklen += 2;
+ final++;
+ break;
+ case 0x80:
+ masklen += 1;
+ final++;
+ break;
+ case 0x00:
+ final++;
+ break;
+ default:
+ final++;
+ illegal++;
+ break;
+ }
+ }
+
+ if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr))
+ return("default");
+
+ if (illegal)
+ fprintf(stderr, "illegal prefixlen\n");
+
+ if (nflag)
+ flag |= NI_NUMERICHOST;
+ getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, hbuf, sizeof(hbuf),
+ NULL, 0, flag);
+ snprintf(line, sizeof(line), "%s/%d", hbuf, masklen);
+ return line;
+}
+
+char *
+routename6(sa6)
+ struct sockaddr_in6 *sa6;
+{
+ static char line[NI_MAXHOST];
+#ifdef NI_WITHSCOPEID
+ const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
+#else
+ const int niflag = NI_NUMERICHOST;
+#endif
+ if (getnameinfo((struct sockaddr *)sa6, sa6->sin6_len,
+ line, sizeof(line), NULL, 0, niflag) != 0)
+ strcpy(line, "");
+ return line;
+}
+#endif /*INET6*/
+
/*
* Print routing statistics
*/
@@ -826,7 +985,7 @@ encap_print(rt)
sen2.sen_ip_dst.s_addr),
sen1.sen_dport, sen1.sen_proto);
- printf("%s/%08x/%-lu\n", inet_ntoa(sen3.sen_ipsp_dst),
+ printf("%s/%08x/%-u\n", inet_ntoa(sen3.sen_ipsp_dst),
ntohl(sen3.sen_ipsp_spi), sen3.sen_ipsp_sproto);
}