Module Name: src Committed By: martin Date: Thu Jan 8 11:01:01 UTC 2015
Modified Files: src/distrib/utils/x_route [netbsd-7]: Makefile src/sbin/route [netbsd-7]: Makefile extern.h prog_ops.h route.c show.c src/usr.bin/netstat [netbsd-7]: Makefile if.c main.c mroute.c mroute6.c netstat.h route.c Added Files: src/sbin/route [netbsd-7]: rtutil.c rtutil.h Removed Files: src/usr.bin/netstat [netbsd-7]: show.c Log Message: Pull up following revision(s) (requested by prlw1 in ticket #390): usr.bin/netstat/mroute.c: revision 1.25 usr.bin/netstat/Makefile: revision 1.40 sbin/route/prog_ops.h: revision 1.3 sbin/route/rtutil.c: revision 1.1 sbin/route/rtutil.h: revision 1.1 usr.bin/netstat/mroute6.c: revision 1.15 sbin/route/extern.h: revision 1.15 usr.bin/netstat/show.c: file removal usr.bin/netstat/main.c: revision 1.93 usr.bin/netstat/route.c: revision 1.83 usr.bin/netstat/netstat.h: revision 1.51 distrib/utils/x_route/Makefile: revision 1.18 sbin/route/show.c: revision 1.46 usr.bin/netstat/if.c: revision 1.80 sbin/route/route.c: revision 1.145 sbin/route/Makefile: revision 1.26 Factor out the netstat route printing code and use it here. There is no point in having 2 different copies; fixes PR/49371 To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.17.26.1 src/distrib/utils/x_route/Makefile cvs rdiff -u -r1.25 -r1.25.24.1 src/sbin/route/Makefile cvs rdiff -u -r1.14 -r1.14.24.1 src/sbin/route/extern.h cvs rdiff -u -r1.2 -r1.2.24.1 src/sbin/route/prog_ops.h cvs rdiff -u -r1.144.4.1 -r1.144.4.2 src/sbin/route/route.c cvs rdiff -u -r0 -r1.4.2.2 src/sbin/route/rtutil.c cvs rdiff -u -r0 -r1.3.2.2 src/sbin/route/rtutil.h cvs rdiff -u -r1.45 -r1.45.8.1 src/sbin/route/show.c cvs rdiff -u -r1.39 -r1.39.8.1 src/usr.bin/netstat/Makefile cvs rdiff -u -r1.79 -r1.79.4.1 src/usr.bin/netstat/if.c cvs rdiff -u -r1.91 -r1.91.2.1 src/usr.bin/netstat/main.c cvs rdiff -u -r1.24 -r1.24.10.1 src/usr.bin/netstat/mroute.c cvs rdiff -u -r1.14 -r1.14.4.1 src/usr.bin/netstat/mroute6.c cvs rdiff -u -r1.50 -r1.50.2.1 src/usr.bin/netstat/netstat.h cvs rdiff -u -r1.82 -r1.82.2.1 src/usr.bin/netstat/route.c cvs rdiff -u -r1.20 -r0 src/usr.bin/netstat/show.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/utils/x_route/Makefile diff -u src/distrib/utils/x_route/Makefile:1.17 src/distrib/utils/x_route/Makefile:1.17.26.1 --- src/distrib/utils/x_route/Makefile:1.17 Mon Dec 13 19:19:10 2010 +++ src/distrib/utils/x_route/Makefile Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.17 2010/12/13 19:19:10 pooka Exp $ +# $NetBSD: Makefile,v 1.17.26.1 2015/01/08 11:01:01 martin Exp $ # @(#)Makefile 8.1 (Berkeley) 6/5/93 SRCDIR= ${.CURDIR}/../../../sbin/route @@ -8,7 +8,7 @@ NOMAN= # defined .include <bsd.own.mk> -SRCS= route.c show.c keywords.c +SRCS= keywords.c route.c rtutil.c show.c CPPFLAGS+= -DSMALL -I${SRCDIR} -DCRUNCHOPS .if defined(SMALLPROG_INET6) && (${USE_INET6} != "no") Index: src/sbin/route/Makefile diff -u src/sbin/route/Makefile:1.25 src/sbin/route/Makefile:1.25.24.1 --- src/sbin/route/Makefile:1.25 Mon Dec 13 17:39:47 2010 +++ src/sbin/route/Makefile Thu Jan 8 11:01:01 2015 @@ -1,11 +1,11 @@ -# $NetBSD: Makefile,v 1.25 2010/12/13 17:39:47 pooka Exp $ +# $NetBSD: Makefile,v 1.25.24.1 2015/01/08 11:01:01 martin Exp $ # @(#)Makefile 8.1 (Berkeley) 6/5/93 .include <bsd.own.mk> RUMPPRG=route MAN= route.8 -SRCS= route.c show.c keywords.c +SRCS= route.c show.c keywords.c rtutil.c .if (${USE_INET6} != "no") CPPFLAGS+=-DINET6 Index: src/sbin/route/extern.h diff -u src/sbin/route/extern.h:1.14 src/sbin/route/extern.h:1.14.24.1 --- src/sbin/route/extern.h:1.14 Wed Oct 21 01:07:46 2009 +++ src/sbin/route/extern.h Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.14 2009/10/21 01:07:46 snj Exp $ */ +/* $NetBSD: extern.h,v 1.14.24.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1997 Christos Zoulas. All rights reserved. @@ -30,15 +30,11 @@ struct sockaddr_ns; void parse_show_opts(int, char * const *, int *, int *, const char **, bool); /* show.c */ -void show(int, char * const *); +void show(int, char * const *, int); /* route.c */ extern int nflag, Sflag; #define NOTDEFSTRING "0.0.0.0/xxx.xxx.xxx.xxx\0" int keyword(const char *); -int netmask_length(struct sockaddr *, int); -char *netmask_string(const struct sockaddr *, int, int); -const char *routename(const struct sockaddr *, struct sockaddr *, int); -const char *netname(const struct sockaddr *, struct sockaddr *); const char *ns_print(struct sockaddr_ns *); void usage(const char *)__attribute__((__noreturn__)); Index: src/sbin/route/prog_ops.h diff -u src/sbin/route/prog_ops.h:1.2 src/sbin/route/prog_ops.h:1.2.24.1 --- src/sbin/route/prog_ops.h:1.2 Mon Dec 13 19:19:10 2010 +++ src/sbin/route/prog_ops.h Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: prog_ops.h,v 1.2 2010/12/13 19:19:10 pooka Exp $ */ +/* $NetBSD: prog_ops.h,v 1.2.24.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -32,9 +32,13 @@ #include <sys/types.h> #ifndef CRUNCHOPS +/* XXX: Keep same order with netstat! */ struct prog_ops { int (*op_init)(void); + int (*op_sysctl)(const int *, u_int, void *, size_t *, + const void *, size_t); + int (*op_socket)(int, int, int); int (*op_open)(const char *, int, ...); pid_t (*op_getpid)(void); @@ -42,8 +46,6 @@ struct prog_ops { ssize_t (*op_read)(int, void *, size_t); ssize_t (*op_write)(int, const void *, size_t); - int (*op_sysctl)(const int *, u_int, void *, size_t *, - const void *, size_t); int (*op_shutdown)(int, int); }; Index: src/sbin/route/route.c diff -u src/sbin/route/route.c:1.144.4.1 src/sbin/route/route.c:1.144.4.2 --- src/sbin/route/route.c:1.144.4.1 Mon Dec 29 17:27:28 2014 +++ src/sbin/route/route.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.144.4.1 2014/12/29 17:27:28 martin Exp $ */ +/* $NetBSD: route.c,v 1.144.4.2 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1983, 1989, 1991, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19 #if 0 static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: route.c,v 1.144.4.1 2014/12/29 17:27:28 martin Exp $"); +__RCSID("$NetBSD: route.c,v 1.144.4.2 2015/01/08 11:01:01 martin Exp $"); #endif #endif /* not lint */ @@ -73,6 +73,7 @@ __RCSID("$NetBSD: route.c,v 1.144.4.1 20 #include "keywords.h" #include "extern.h" #include "prog_ops.h" +#include "rtutil.h" union sockunion { struct sockaddr sa; @@ -95,7 +96,6 @@ struct sou { *so_ifp, *so_mpls; }; -static char *any_ntoa(const struct sockaddr *); static const char *route_strerror(int); static void set_metric(const char *, int); static int newroute(int, char *const *); @@ -105,6 +105,7 @@ static int inet6_makenetandmask(const st #endif static int getaddr(int, const char *, struct hostent **, struct sou *); static int flushroutes(int, char *const [], int); +static char *netmask_string(const struct sockaddr *, int, int); static int prefixlen(const char *, struct sou *); #ifndef SMALL static void interfaces(void); @@ -168,7 +169,7 @@ main(int argc, char * const *argv) doflush = 1; break; case 'n': - nflag = 1; + nflag = RT_NFLAG; break; case 'q': qflag = 1; @@ -224,7 +225,7 @@ main(int argc, char * const *argv) return newroute(argc, argv); case K_SHOW: - show(argc, argv); + show(argc, argv, nflag); return 0; #ifndef SMALL @@ -245,6 +246,36 @@ main(int argc, char * const *argv) } } +static char * +netmask_string(const struct sockaddr *mask, int len, int family) +{ + static char smask[INET6_ADDRSTRLEN]; + struct sockaddr_in nsin; + struct sockaddr_in6 nsin6; + + if (len >= 0) + snprintf(smask, sizeof(smask), "%d", len); + else { + switch (family) { + case AF_INET: + memset(&nsin, 0, sizeof(nsin)); + memcpy(&nsin, mask, mask->sa_len); + snprintf(smask, sizeof(smask), "%s", + inet_ntoa(nsin.sin_addr)); + break; + case AF_INET6: + memset(&nsin6, 0, sizeof(nsin6)); + memcpy(&nsin6, mask, mask->sa_len); + inet_ntop(family, &nsin6.sin6_addr, smask, + sizeof(smask)); + break; + default: + snprintf(smask, sizeof(smask), "%s", any_ntoa(mask)); + } + } + + return smask; +} /* * Purge all entries in the routing tables not * associated with network interfaces. @@ -320,12 +351,10 @@ flushroutes(int argc, char * const argv[ if (verbose) print_rtmsg(rtm, rlen); else { - (void)printf("%-20.20s ", - routename(sa, NULL, rtm->rtm_flags)); + (void)printf("%-20.20s ", netname(sa, NULL, nflag)); sa = (struct sockaddr *)(RT_ROUNDUP(sa->sa_len) + (char *)sa); - (void)printf("%-20.20s ", - routename(sa, NULL, RTF_HOST)); + (void)printf("%-20.20s ", routename(sa, nflag)); (void)printf("done\n"); } } @@ -333,402 +362,6 @@ flushroutes(int argc, char * const argv[ return 0; } - -static char hexlist[] = "0123456789abcdef"; - -static char * -any_ntoa(const struct sockaddr *sa) -{ - static char obuf[3 * 256]; - const char *in; - char *out; - int len; - -#if __GNUC__ > 2 - len = sa->sa_len - offsetof(struct sockaddr, sa_data); -#else - len = sa->sa_len - ((struct sockaddr*)&sa->sa_data - sa); -#endif - in = sa->sa_data; - out = obuf; - - do { - *out++ = hexlist[(*in >> 4) & 15]; - *out++ = hexlist[(*in++) & 15]; - *out++ = '.'; - } while (--len > 0); - out[-1] = '\0'; - return obuf; -} - -int -netmask_length(struct sockaddr *nm, int family) -{ - static int - /* number of bits in a nibble */ - _t[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }, - /* good nibbles are 1111, 1110, 1100, 1000, 0000 */ - _g[] = { 1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1 }; - int mask, good, zeroes, maskbytes, bit, i; - unsigned char *maskdata; - - if (nm == NULL) - return 0; - - mask = 0; - good = 1; - zeroes = 0; - - switch (family) { - case AF_INET: { - struct sockaddr_in *nsin = (struct sockaddr_in *)nm; - maskdata = (unsigned char *)&nsin->sin_addr; - maskbytes = nsin->sin_len - - ((caddr_t)&nsin->sin_addr - (caddr_t)nsin); - break; - } - case AF_INET6: { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nm; - maskdata = (unsigned char *)&sin6->sin6_addr; - maskbytes = sin6->sin6_len - - ((caddr_t)&sin6->sin6_addr - (caddr_t)sin6); - break; - } - default: - return 0; - } - - /* - * Count the bits in the nibbles of the mask, and marking the - * netmask as not good (or at best, non-standard and very - * discouraged, in the case of AF_INET) if we find either of - * a nibble with non-contiguous bits, or a non-zero nibble - * after we've found a zero nibble. - */ - for (i = 0; i < maskbytes; i++) { - /* high nibble */ - mask += bit = _t[maskdata[i] >> 4]; - good &= _g[maskdata[i] >> 4]; - if (zeroes && bit) - good = 0; - if (bit == 0) - zeroes = 1; - /* low nibble */ - mask += bit = _t[maskdata[i] & 0xf]; - good &= _g[maskdata[i] & 0xf]; - if (zeroes && bit) - good = 0; - if (bit == 0) - zeroes = 1; - } - - /* - * Always return the number of bits found, but as a negative - * if the mask wasn't one we like. - */ - return good ? mask : -mask; -} - -char * -netmask_string(const struct sockaddr *mask, int len, int family) -{ - static char smask[INET6_ADDRSTRLEN]; - struct sockaddr_in nsin; - struct sockaddr_in6 nsin6; - - if (len >= 0) - snprintf(smask, sizeof(smask), "%d", len); - else { - switch (family) { - case AF_INET: - memset(&nsin, 0, sizeof(nsin)); - memcpy(&nsin, mask, mask->sa_len); - snprintf(smask, sizeof(smask), "%s", - inet_ntoa(nsin.sin_addr)); - break; - case AF_INET6: - memset(&nsin6, 0, sizeof(nsin6)); - memcpy(&nsin6, mask, mask->sa_len); - inet_ntop(family, &nsin6.sin6_addr, smask, - sizeof(smask)); - break; - default: - snprintf(smask, sizeof(smask), "%s", any_ntoa(mask)); - } - } - - return smask; -} - -const char * -routename(const struct sockaddr *sa, struct sockaddr *nm, int flags) -{ - const char *cp; - static char line[50]; - struct hostent *hp; - static char domain[MAXHOSTNAMELEN + 1]; - static int first = 1; - struct in_addr in; - int nml; - - if ((flags & RTF_HOST) == 0) - return netname(sa, nm); - - if (first) { - first = 0; - if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = strchr(domain, '.'))) - (void)strlcpy(domain, cp + 1, sizeof(domain)); - else - domain[0] = 0; - } - - if (sa->sa_len == 0) - strlcpy(line, "default", sizeof(line)); - else switch (sa->sa_family) { - - case AF_INET: - in = ((const struct sockaddr_in *)sa)->sin_addr; - nml = netmask_length(nm, AF_INET); - - cp = 0; - if (in.s_addr == INADDR_ANY || sa->sa_len < 4) { - if (nml == 0) - cp = "default"; - else { - static char notdefault[sizeof(NOTDEFSTRING)]; - - snprintf(notdefault, sizeof(notdefault), - "0.0.0.0/%s", - netmask_string(nm, nml, AF_INET)); - cp = notdefault; - } - } - if (cp == 0 && !nflag) { - hp = gethostbyaddr((char *)&in, sizeof(struct in_addr), - AF_INET); - if (hp) { - char *ccp; - if ((ccp = strchr(hp->h_name, '.')) && - !strcmp(ccp + 1, domain)) - *ccp = '\0'; - cp = hp->h_name; - } - } - if (cp) - (void)strlcpy(line, cp, sizeof(line)); - else - (void)strlcpy(line, inet_ntoa(in), sizeof(line)); - break; - - case AF_LINK: - return link_ntoa((const struct sockaddr_dl *)sa); - -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 sin6; - int niflags; - char nihost[NI_MAXHOST]; - - niflags = 0; - if (nflag) - niflags |= NI_NUMERICHOST; - memset(&sin6, 0, sizeof(sin6)); - memcpy(&sin6, sa, sa->sa_len); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_family = AF_INET6; - inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL| - INET6_IS_ADDR_MC_LINKLOCAL); - nml = netmask_length(nm, AF_INET6); - if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) { - if (nml == 0) - strlcpy(line, "::", sizeof(line)); - else - /* noncontiguous never happens in ipv6 */ - snprintf(line, sizeof(line), "::/%d", nml); - } - else if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, - nihost, sizeof(nihost), NULL, 0, niflags) != 0) - strlcpy(line, "invalid", sizeof(line)); - else { - char *ccp; - if (!nflag && (ccp = strchr(nihost, '.')) && - strcmp(ccp + 1, domain) == 0) - *ccp = '\0'; - strlcpy(line, nihost, sizeof(line)); - } - break; - } -#endif - -#ifndef SMALL - case AF_APPLETALK: - (void)snprintf(line, sizeof(line), "atalk %d.%d", - ((const struct sockaddr_at *)sa)->sat_addr.s_net, - ((const struct sockaddr_at *)sa)->sat_addr.s_node); - break; - case AF_MPLS: - { - union mpls_shim ms; - const union mpls_shim *pms; - size_t psize = sizeof(struct sockaddr_mpls), len; - - ms.s_addr =((const struct sockaddr_mpls*)sa)->smpls_addr.s_addr; - ms.s_addr = ntohl(ms.s_addr); - - len = snprintf(line, sizeof(line), "%u", ms.shim.label); - if (len >= sizeof(line)) - errx(1, "snprintf"); - pms = &((const struct sockaddr_mpls*)sa)->smpls_addr; - while (psize < sa->sa_len) { - size_t alen; - pms++; - ms.s_addr = ntohl(pms->s_addr); - alen = snprintf(line + len, sizeof(line) - len, " %u", - ms.shim.label); - if (alen >= sizeof(line) - len) - errx(1, "snprintf"); - len += alen; - psize += sizeof(ms); - } - break; - } -#endif /* SMALL */ - - default: - (void)snprintf(line, sizeof line, "(%d) %s", - sa->sa_family, any_ntoa(sa)); - break; - - } - return line; -} - -/* - * Return the name of the network whose address is given. - * The address is assumed to be that of a net or subnet, not a host. - */ -const char * -netname(const struct sockaddr *sa, struct sockaddr *nm) -{ - const char *cp = 0; - static char line[50]; - struct netent *np = 0; - u_int32_t net, mask; - u_int32_t i; - int subnetshift, nml; - struct in_addr in; - - switch (sa->sa_family) { - - case AF_INET: - in = ((const struct sockaddr_in *)sa)->sin_addr; - i = ntohl(in.s_addr); - nml = netmask_length(nm, AF_INET); - if (i == 0) { - if (nml == 0) - cp = "default"; - else { - static char notdefault[sizeof(NOTDEFSTRING)]; - - snprintf(notdefault, sizeof(notdefault), - "0.0.0.0/%s", - netmask_string(nm, nml, AF_INET)); - cp = notdefault; - } - } - else if (!nflag) { - if (IN_CLASSA(i)) { - mask = IN_CLASSA_NET; - subnetshift = 8; - } else if (IN_CLASSB(i)) { - mask = IN_CLASSB_NET; - subnetshift = 8; - } else { - mask = IN_CLASSC_NET; - subnetshift = 4; - } - /* - * If there are more bits than the standard mask - * would suggest, subnets must be in use. - * Guess at the subnet mask, assuming reasonable - * width subnet fields. - */ - while (i &~ mask) - mask = (int32_t)mask >> subnetshift; - net = i & mask; - while ((mask & 1) == 0) - mask >>= 1, net >>= 1; - np = getnetbyaddr(net, AF_INET); - if (np) - cp = np->n_name; - } - if (cp) - (void)strlcpy(line, cp, sizeof(line)); - else { - if (nml == 0) - strlcpy(line, inet_ntoa(in), sizeof(line)); - else if (nml < 0) { - snprintf(line, sizeof(line), "%s&%s", - inet_ntoa(in), - netmask_string(nm, nml, AF_INET)); - } else { - snprintf(line, sizeof(line), "%s/%d", - inet_ntoa(in), nml); - } - } - break; - - case AF_LINK: - return link_ntoa((const struct sockaddr_dl *)sa); - -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 sin6; - int niflags; - - niflags = 0; - if (nflag) - niflags |= NI_NUMERICHOST; - memset(&sin6, 0, sizeof(sin6)); - memcpy(&sin6, sa, sa->sa_len); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_family = AF_INET6; - inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL| - INET6_IS_ADDR_MC_LINKLOCAL); - nml = netmask_length(nm, AF_INET6); - if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) { - if (nml == 0) - strlcpy(line, "::", sizeof(line)); - else - /* noncontiguous never happens in ipv6 */ - snprintf(line, sizeof(line), "::/%d", nml); - } - else if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, - line, sizeof(line), NULL, 0, niflags) != 0) - strlcpy(line, "invalid", sizeof(line)); - break; - } -#endif - -#ifndef SMALL - case AF_APPLETALK: - (void)snprintf(line, sizeof(line), "atalk %d.%d", - ((const struct sockaddr_at *)sa)->sat_addr.s_net, - ((const struct sockaddr_at *)sa)->sat_addr.s_node); - break; -#endif /* SMALL */ - - default: - (void)snprintf(line, sizeof line, "af %d: %s", - sa->sa_family, any_ntoa(sa)); - break; - } - return line; -} - static const char * route_strerror(int error) { @@ -1830,7 +1463,7 @@ print_getmsg(struct rt_msghdr *rtm, int if (! shortoutput) { (void)printf(" route to: %s\n", - routename(&soup->so_dst->sa, NULL, RTF_HOST)); + routename(&soup->so_dst->sa, nflag)); } if (rtm->rtm_version != RTM_VERSION) { warnx("routing message version %d not understood", @@ -1879,19 +1512,19 @@ print_getmsg(struct rt_msghdr *rtm, int mask->sa_family = dst->sa_family; /* XXX */ if (dst && ! shortoutput) (void)printf("destination: %s\n", - routename(dst, mask, RTF_HOST)); + routename(dst, nflag)); if (mask && ! shortoutput) { int savenflag = nflag; - nflag = 1; + nflag = RT_NFLAG; (void)printf(" mask: %s\n", - routename(mask, NULL, RTF_HOST)); + routename(mask, nflag)); nflag = savenflag; } if (gate && rtm->rtm_flags & RTF_GATEWAY) { const char *name; - name = routename(gate, NULL, RTF_HOST); + name = routename(gate, nflag); if (shortoutput) { if (*name == '\0') return 1; @@ -1901,7 +1534,7 @@ print_getmsg(struct rt_msghdr *rtm, int } if (mpls) { const char *name; - name = routename(mpls, NULL, RTF_HOST); + name = routename(mpls, nflag); if(shortoutput) { if (*name == '\0') return 1; @@ -1912,7 +1545,7 @@ print_getmsg(struct rt_msghdr *rtm, int if (ifa && ! shortoutput) (void)printf(" local addr: %s\n", - routename(ifa, NULL, RTF_HOST)); + routename(ifa, nflag)); if (ifp && ! shortoutput) (void)printf(" interface: %.*s\n", ifp->sdl_nlen, ifp->sdl_data); @@ -2006,7 +1639,7 @@ pmsg_addrs(const char *cp, int addrs) netmask_string(sa[i], -1, nmf)); else (void)printf(" %s", - routename(sa[i], NULL, RTF_HOST)); + routename(sa[i], nflag)); } } (void)putchar('\n'); Index: src/sbin/route/show.c diff -u src/sbin/route/show.c:1.45 src/sbin/route/show.c:1.45.8.1 --- src/sbin/route/show.c:1.45 Fri Mar 1 18:25:17 2013 +++ src/sbin/route/show.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: show.c,v 1.45 2013/03/01 18:25:17 joerg Exp $ */ +/* $NetBSD: show.c,v 1.45.8.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; #else -__RCSID("$NetBSD: show.c,v 1.45 2013/03/01 18:25:17 joerg Exp $"); +__RCSID("$NetBSD: show.c,v 1.45.8.1 2015/01/08 11:01:01 martin Exp $"); #endif #endif /* not lint */ @@ -62,44 +62,10 @@ __RCSID("$NetBSD: show.c,v 1.45 2013/03/ #include <err.h> #include "keywords.h" +#include "rtutil.h" #include "extern.h" #include "prog_ops.h" - -/* - * Definitions for showing gateway flags. - */ -struct bits { - int b_mask; - char b_val; -}; -static const struct bits bits[] = { - { RTF_UP, 'U' }, - { RTF_GATEWAY, 'G' }, - { RTF_HOST, 'H' }, - { RTF_REJECT, 'R' }, - { RTF_DYNAMIC, 'D' }, - { RTF_MODIFIED, 'M' }, - { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ - { RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */ - { RTF_CLONING, 'C' }, - { RTF_XRESOLVE, 'X' }, - { RTF_LLINFO, 'L' }, - { RTF_STATIC, 'S' }, - { RTF_BLACKHOLE, 'B' }, - { RTF_CLONED, 'c' }, - { RTF_PROTO1, '1' }, - { RTF_PROTO2, '2' }, - { RTF_ANNOUNCE, 'p' }, - { 0, '\0' } -}; - -static void pr_rthdr(int); -static void p_rtentry(struct rt_msghdr *); -static void pr_family(int); -static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int ); -static void p_flags(int); - void parse_show_opts(int argc, char * const *argv, int *afp, int *flagsp, const char **afnamep, bool nolink) @@ -167,261 +133,12 @@ parse_show_opts(int argc, char * const * * Print routing tables. */ void -show(int argc, char *const *argv) -{ - size_t needed; - int af, flags, mib[6]; - char *buf, *next, *lim; - struct rt_msghdr *rtm; - struct sockaddr *sa; - - parse_show_opts(argc, argv, &af, &flags, NULL, true); - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = 0; - mib[4] = NET_RT_DUMP; - mib[5] = 0; - if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) - err(EXIT_FAILURE, "route-sysctl-estimate"); - buf = lim = NULL; - if (needed) { - if ((buf = malloc(needed)) == 0) - err(EXIT_FAILURE, "malloc"); - if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0) - err(EXIT_FAILURE, "sysctl of routing table"); - lim = buf + needed; - } - - printf("Routing table%s\n", (af == AF_UNSPEC)? "s" : ""); - - if (needed) { - for (next = buf; next < lim; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - sa = (struct sockaddr *)(rtm + 1); - if ((rtm->rtm_flags & flags) != flags) - continue; - if (af == AF_UNSPEC || af == sa->sa_family) - p_rtentry(rtm); - } - free(buf); - } -} - - -/* column widths; each followed by one space */ -#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 */ -#if 1 -/* 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. - */ -static void -pr_rthdr(int af) -{ - - printf("%-*.*s %-*.*s %-6.6s\n", - WID_DST(af), WID_DST(af), "Destination", - WID_GW(af), WID_GW(af), "Gateway", - "Flags"); -} - - -/* - * Print a routing table entry. - */ -static void -p_rtentry(struct rt_msghdr *rtm) +show(int argc, char *const *argv, int flags) { - struct sockaddr *sa = (struct sockaddr *)(rtm + 1); -#ifdef notdef - static int masks_done, banner_printed; -#endif - static int old_af; - int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST | + int af, rflags; + static int interesting = RTF_UP | RTF_GATEWAY | RTF_HOST | RTF_REJECT | RTF_LLINFO; -#ifdef notdef - /* for the moment, netmasks are skipped over */ - if (!banner_printed) { - printf("Netmasks:\n"); - banner_printed = 1; - } - if (masks_done == 0) { - if (rtm->rtm_addrs != RTA_DST ) { - masks_done = 1; - af = sa->sa_family; - } - } else -#endif - af = sa->sa_family; - if (old_af != af) { - old_af = af; - pr_family(af); - pr_rthdr(af); - } - if (rtm->rtm_addrs == RTA_DST) - p_sockaddr(sa, NULL, 0, WID_DST(af) + 1 + WID_GW(af) + 1); - else { - struct sockaddr *nm; - - if ((rtm->rtm_addrs & RTA_NETMASK) == 0) - nm = NULL; - else { - /* skip to gateway */ - nm = (struct sockaddr *) - (RT_ROUNDUP(sa->sa_len) + (char *)sa); - /* skip over gateway to netmask */ - nm = (struct sockaddr *) - (RT_ROUNDUP(nm->sa_len) + (char *)nm); - } - - p_sockaddr(sa, nm, rtm->rtm_flags, WID_DST(af)); - sa = (struct sockaddr *)(RT_ROUNDUP(sa->sa_len) + (char *)sa); - p_sockaddr(sa, NULL, 0, WID_GW(af)); - } - p_flags(rtm->rtm_flags & interesting); - putchar('\n'); -} - - -/* - * Print address family header before a section of the routing table. - */ -static void -pr_family(int af) -{ - const char *afname; - - switch (af) { - case AF_INET: - afname = "Internet"; - break; -#ifdef INET6 - case AF_INET6: - afname = "Internet6"; - break; -#endif /* INET6 */ -#ifndef SMALL - case AF_MPLS: - afname = "MPLS"; - break; -#endif /* SMALL */ - case AF_APPLETALK: - afname = "AppleTalk"; - break; - default: - afname = NULL; - break; - } - if (afname) - printf("\n%s:\n", afname); - else - printf("\nProtocol Family %d:\n", af); -} - - -static void -p_sockaddr(struct sockaddr *sa, struct sockaddr *nm, int flags, int width) -{ - char workbuf[128]; - const char *cp; - - switch(sa->sa_family) { - - case AF_LINK: - if (getnameinfo(sa, sa->sa_len, workbuf, sizeof(workbuf), - NULL, 0, NI_NUMERICHOST) != 0) - strlcpy(workbuf, "invalid", sizeof(workbuf)); - cp = workbuf; - break; - - case AF_INET: - cp = routename(sa, nm, flags); - break; - -#ifdef INET6 - case AF_INET6: - cp = routename(sa, nm, flags); - /* make sure numeric address is not truncated */ - if (strchr(cp, ':') != NULL && (int)strlen(cp) > width) - width = strlen(cp); - break; -#endif /* INET6 */ - -#ifndef SMALL - case AF_MPLS: - { - struct sockaddr_mpls *smpls = (struct sockaddr_mpls *)sa; - union mpls_shim ms; - - ms.s_addr = ntohl(smpls->smpls_addr.s_addr); - - snprintf(workbuf, sizeof(workbuf), "%u", - ms.shim.label); - cp = workbuf; - } - break; - case AF_APPLETALK: - if (getnameinfo(sa, sa->sa_len, workbuf, sizeof(workbuf), - NULL, 0, NI_NUMERICHOST) != 0) - strlcpy(workbuf, "invalid", sizeof(workbuf)); - cp = workbuf; - break; - -#endif /* SMALL */ - - default: - { - u_char *s = (u_char *)sa->sa_data, *slim; - char *wp = workbuf, *wplim; - - slim = sa->sa_len + (u_char *)sa; - wplim = wp + sizeof(workbuf) - 6; - wp += snprintf(wp, wplim - wp, "(%d)", sa->sa_family); - while (s < slim && wp < wplim) { - wp += snprintf(wp, wplim - wp, " %02x", *s++); - if (s < slim) - wp += snprintf(wp, wplim - wp, "%02x", *s++); - } - cp = workbuf; - } - } - if (width < 0 ) - printf("%s ", cp); - else { - if (nflag) - printf("%-*s ", width, cp); - else - printf("%-*.*s ", width, width, cp); - } -} - -static void -p_flags(int f) -{ - char name[33], *flags; - const struct bits *p = bits; - - for (flags = name; p->b_mask; p++) - if (p->b_mask & f) - *flags++ = p->b_val; - else if (Sflag) - *flags++ = ' '; - *flags = '\0'; - printf("%-6.6s ", name); + parse_show_opts(argc, argv, &af, &rflags, NULL, true); + p_rttables(af, flags, rflags, interesting); } - Index: src/usr.bin/netstat/Makefile diff -u src/usr.bin/netstat/Makefile:1.39 src/usr.bin/netstat/Makefile:1.39.8.1 --- src/usr.bin/netstat/Makefile:1.39 Fri Mar 1 18:26:11 2013 +++ src/usr.bin/netstat/Makefile Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.39 2013/03/01 18:26:11 joerg Exp $ +# $NetBSD: Makefile,v 1.39.8.1 2015/01/08 11:01:01 martin Exp $ # from: @(#)Makefile 8.1 (Berkeley) 6/12/93 .include <bsd.own.mk> @@ -7,20 +7,22 @@ USE_FORT?= yes # setgid RUMPPRG=netstat SRCS= atalk.c bpf.c fast_ipsec.c if.c inet.c inet6.c \ - main.c mbuf.c mroute.c mroute6.c pfkey.c pfsync.c show.c route.c \ - unix.c vtw.c + main.c mbuf.c mroute.c mroute6.c pfkey.c pfsync.c route.c \ + unix.c vtw.c rtutil.c BINGRP= kmem BINMODE=2555 LDADD= -lkvm DPADD= ${LIBKVM} -CPPFLAGS+= -DIPSEC +CPPFLAGS+= -DIPSEC -I${.CURDIR} CPPFLAGS+= -I${NETBSDSRCDIR}/sys/dist/pf +CPPFLAGS+= -I${NETBSDSRCDIR}/sbin/route CWARNFLAGS.clang+= -Wno-format COPTS.show.c += -Wno-format-nonliteral .PATH: ${.CURDIR}/../../lib/libc/gen .PATH: ${.CURDIR}/../../lib/libc/net +.PATH: ${.CURDIR}/../../sbin/route CPPFLAGS+= -DRUMP_ACTION RUMPSRCS+= sysctlbyname.c sysctlgetmibinfo.c sysctlnametomib.c RUMPSRCS+= if_indextoname.c getifaddrs.c Index: src/usr.bin/netstat/if.c diff -u src/usr.bin/netstat/if.c:1.79 src/usr.bin/netstat/if.c:1.79.4.1 --- src/usr.bin/netstat/if.c:1.79 Sat Oct 19 15:56:06 2013 +++ src/usr.bin/netstat/if.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.79 2013/10/19 15:56:06 christos Exp $ */ +/* $NetBSD: if.c,v 1.79.4.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94"; #else -__RCSID("$NetBSD: if.c,v 1.79 2013/10/19 15:56:06 christos Exp $"); +__RCSID("$NetBSD: if.c,v 1.79.4.1 2015/01/08 11:01:01 martin Exp $"); #endif #endif /* not lint */ @@ -63,6 +63,7 @@ __RCSID("$NetBSD: if.c,v 1.79 2013/10/19 #include <err.h> #include "netstat.h" +#include "rtutil.h" #include "prog_ops.h" #define MAXIF 100 @@ -356,7 +357,7 @@ print_addr(struct sockaddr *sa, struct s in = inet_makeaddr(ifaddr.in.ia_subnet, INADDR_ANY); cp = netname4(in.s_addr, - ifaddr.in.ia_subnetmask); + ifaddr.in.ia_subnetmask, nflag); #else if (use_sysctl) { netmask = ((struct sockaddr_in *)rtinfo[RTAX_NETMASK])->sin_addr.s_addr; @@ -364,14 +365,14 @@ print_addr(struct sockaddr *sa, struct s struct in_ifaddr *ifaddr_in = (void *)rtinfo; netmask = ifaddr_in->ia_subnetmask; } - cp = netname4(sin->sin_addr.s_addr, netmask); + cp = netname4(sin->sin_addr.s_addr, netmask, nflag); #endif if (vflag) n = strlen(cp) < 13 ? 13 : strlen(cp); else n = 13; printf("%-*.*s ", n, n, cp); - cp = routename4(sin->sin_addr.s_addr); + cp = routename4(sin->sin_addr.s_addr, nflag); if (vflag) n = strlen(cp) < 17 ? 17 : strlen(cp); else @@ -390,7 +391,7 @@ print_addr(struct sockaddr *sa, struct s sizeof inm); printf("\n%25s %-17.17s ", "", routename4( - inm.inm_addr.s_addr)); + inm.inm_addr.s_addr, nflag)); multiaddr = (u_long)inm.inm_list.le_next; } @@ -412,7 +413,7 @@ print_addr(struct sockaddr *sa, struct s netmask6 = &ifaddr_in6->ia_prefixmask; } - cp = netname6(sin6, netmask6); + cp = netname6(sin6, netmask6, nflag); if (vflag) n = strlen(cp) < 13 ? 13 : strlen(cp); else Index: src/usr.bin/netstat/main.c diff -u src/usr.bin/netstat/main.c:1.91 src/usr.bin/netstat/main.c:1.91.2.1 --- src/usr.bin/netstat/main.c:1.91 Fri May 30 01:44:21 2014 +++ src/usr.bin/netstat/main.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.91 2014/05/30 01:44:21 rmind Exp $ */ +/* $NetBSD: main.c,v 1.91.2.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19 #if 0 static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94"; #else -__RCSID("$NetBSD: main.c,v 1.91 2014/05/30 01:44:21 rmind Exp $"); +__RCSID("$NetBSD: main.c,v 1.91.2.1 2015/01/08 11:01:01 martin Exp $"); #endif #endif /* not lint */ @@ -64,6 +64,7 @@ __RCSID("$NetBSD: main.c,v 1.91 2014/05/ #include <string.h> #include <unistd.h> #include "netstat.h" +#include "rtutil.h" #include "prog_ops.h" struct nlist nl[] = { @@ -463,7 +464,7 @@ main(int argc, char *argv[]) nlistf = optarg; break; case 'n': - numeric_addr = numeric_port = nflag = 1; + numeric_addr = numeric_port = nflag = RT_NFLAG; break; case 'P': errno = 0; @@ -632,7 +633,7 @@ main(int argc, char *argv[]) rt_stats(use_sysctl ? 0 : nl[N_RTSTAT].n_value); else { if (use_sysctl) - p_rttables(af); + p_rttables(af, nflag, 0, ~0); else routepr(nl[N_RTREE].n_value); } Index: src/usr.bin/netstat/mroute.c diff -u src/usr.bin/netstat/mroute.c:1.24 src/usr.bin/netstat/mroute.c:1.24.10.1 --- src/usr.bin/netstat/mroute.c:1.24 Tue Mar 20 20:34:58 2012 +++ src/usr.bin/netstat/mroute.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: mroute.c,v 1.24 2012/03/20 20:34:58 matt Exp $ */ +/* $NetBSD: mroute.c,v 1.24.10.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -76,7 +76,7 @@ #if 0 static char sccsid[] = "from: @(#)mroute.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: mroute.c,v 1.24 2012/03/20 20:34:58 matt Exp $"); +__RCSID("$NetBSD: mroute.c,v 1.24.10.1 2015/01/08 11:01:01 martin Exp $"); #endif #endif /* not lint */ @@ -103,6 +103,7 @@ __RCSID("$NetBSD: mroute.c,v 1.24 2012/0 #include <stdlib.h> #include <kvm.h> #include "netstat.h" +#include "rtutil.h" static char *pktscale(u_long); static void print_bw_meter(struct bw_meter *, int *); @@ -196,9 +197,9 @@ mroutepr(u_long mrpaddr, u_long mfchasht printf(" %3u %3u %5u %-15.15s", vifi, v->v_threshold, v->v_rate_limit, - routename4(v->v_lcl_addr.s_addr)); + routename4(v->v_lcl_addr.s_addr, nflag)); printf(" %-15.15s %6lu %7lu\n", (v->v_flags & VIFF_TUNNEL) ? - routename4(v->v_rmt_addr.s_addr) : "", + routename4(v->v_rmt_addr.s_addr, nflag) : "", v->v_pkt_in, v->v_pkt_out); } if (!banner_printed) @@ -223,9 +224,9 @@ mroutepr(u_long mrpaddr, u_long mfchasht kread((u_long)mfcp, (char *)&mfc, sizeof(mfc)); printf(" %3lu %-15.15s", - i, routename4(mfc.mfc_origin.s_addr)); + i, routename4(mfc.mfc_origin.s_addr, nflag)); printf(" %-15.15s %7s %3u ", - routename4(mfc.mfc_mcastgrp.s_addr), + routename4(mfc.mfc_mcastgrp.s_addr, nflag), pktscale(mfc.mfc_pkt_cnt), mfc.mfc_parent); for (vifi = 0; vifi <= numvifs; ++vifi) if (mfc.mfc_ttls[vifi]) Index: src/usr.bin/netstat/mroute6.c diff -u src/usr.bin/netstat/mroute6.c:1.14 src/usr.bin/netstat/mroute6.c:1.14.4.1 --- src/usr.bin/netstat/mroute6.c:1.14 Fri Oct 18 20:26:45 2013 +++ src/usr.bin/netstat/mroute6.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: mroute6.c,v 1.14 2013/10/18 20:26:45 christos Exp $ */ +/* $NetBSD: mroute6.c,v 1.14.4.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (C) 1998 WIDE Project. @@ -117,6 +117,7 @@ #include <stdio.h> #include <kvm.h> #include "netstat.h" +#include "rtutil.h" #ifdef INET6 @@ -212,9 +213,9 @@ mroute6pr(u_long mrpaddr, u_long mfcaddr } printf(" %-*.*s", WID_ORG, WID_ORG, - routename6(&mfc.mf6c_origin)); + routename6(&mfc.mf6c_origin, nflag)); printf(" %-*.*s", WID_GRP, WID_GRP, - routename6(&mfc.mf6c_mcastgrp)); + routename6(&mfc.mf6c_mcastgrp, nflag)); printf(" %9llu", (unsigned long long)mfc.mf6c_pkt_cnt); for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) { Index: src/usr.bin/netstat/netstat.h diff -u src/usr.bin/netstat/netstat.h:1.50 src/usr.bin/netstat/netstat.h:1.50.2.1 --- src/usr.bin/netstat/netstat.h:1.50 Mon Apr 28 15:41:15 2014 +++ src/usr.bin/netstat/netstat.h Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: netstat.h,v 1.50 2014/04/28 15:41:15 christos Exp $ */ +/* $NetBSD: netstat.h,v 1.50.2.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -102,7 +102,6 @@ void pim6_stats(u_long, const char *); void rip6_stats(u_long, const char *); void mroute6pr(u_long, u_long, u_long); void mrt6_stats(u_long, u_long); -char *routename6(struct sockaddr_in6 *); #endif /*INET6*/ #ifdef IPSEC @@ -114,28 +113,9 @@ void mbpr(u_long, u_long, u_long, u_long void hostpr(u_long, u_long); void impstats(u_long, u_long); -void pr_rthdr(int, int); -void pr_family(int); -struct rt_metrics; -void pr_rtrmx(struct rt_metrics *); void rt_stats(u_long); char *ns_phost(struct sockaddr *); -void p_rttables(int); -void p_flags(int, const char *); -void p_addr(struct sockaddr *, struct sockaddr *, int); -void p_gwaddr(struct sockaddr *, int); -void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); -char *routename(struct sockaddr *); -char *routename4(in_addr_t); -char *netname(struct sockaddr *, struct sockaddr *); -char *netname4(in_addr_t, in_addr_t); - -/* char *routename(u_int32_t); */ -/* char *netname(u_int32_t, u_int32_t); */ -#ifdef INET6 -char *netname6(struct sockaddr_in6 *, struct sockaddr_in6 *); -#endif const char *atalk_print(const struct sockaddr *, int); const char *atalk_print2(const struct sockaddr *, const struct sockaddr *, int); Index: src/usr.bin/netstat/route.c diff -u src/usr.bin/netstat/route.c:1.82 src/usr.bin/netstat/route.c:1.82.2.1 --- src/usr.bin/netstat/route.c:1.82 Mon Apr 28 15:41:15 2014 +++ src/usr.bin/netstat/route.c Thu Jan 8 11:01:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.82 2014/04/28 15:41:15 christos Exp $ */ +/* $NetBSD: route.c,v 1.82.2.1 2015/01/08 11:01:01 martin Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; #else -__RCSID("$NetBSD: route.c,v 1.82 2014/04/28 15:41:15 christos Exp $"); +__RCSID("$NetBSD: route.c,v 1.82.2.1 2015/01/08 11:01:01 martin Exp $"); #endif #endif /* not lint */ @@ -66,6 +66,7 @@ __RCSID("$NetBSD: route.c,v 1.82 2014/04 #include <unistd.h> #include "netstat.h" +#include "rtutil.h" #define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) @@ -121,9 +122,9 @@ routepr(u_long rtree) p_tree(head.rnh_treetop); } } else if (af == AF_UNSPEC || af == i) { - pr_family(i); + p_family(i); do_rtent = 1; - pr_rthdr(i, Aflag); + p_rthdr(i, Aflag); p_tree(head.rnh_treetop); } } @@ -159,7 +160,7 @@ again: p_rtnode(); } else { p_sockaddr(kgetsa((const struct sockaddr *)rnode.rn_key), - NULL, 0, 44); + NULL, 0, 44, nflag); putchar('\n'); } if ((rn = rnode.rn_dupedkey) != NULL) @@ -185,7 +186,7 @@ p_rtnode(void) if (rnode.rn_mask) { printf("\t mask "); p_sockaddr(kgetsa((const struct sockaddr *)rnode.rn_mask), - NULL, 0, -1); + NULL, 0, -1, nflag); } else if (rm == 0) return; } else { @@ -203,10 +204,10 @@ p_rtnode(void) printf(" <normal>, "); kget(rmask.rm_leaf, rnode_aux); p_sockaddr(kgetsa((const struct sockaddr *)rnode_aux.rn_mask), - NULL, 0, -1); + NULL, 0, -1, nflag); } else p_sockaddr(kgetsa((const struct sockaddr *)rmask.rm_mask), - NULL, 0, -1); + NULL, 0, -1, nflag); putchar('}'); if ((rm = rmask.rm_mklist) != NULL) printf(" ->"); @@ -251,9 +252,9 @@ p_krtentry(struct rtentry *rt) mask = sockcopy(kgetsa(rt_mask(rt)), &mask_un); else mask = sockcopy(NULL, &mask_un); - p_addr(addr, mask, rt->rt_flags); - p_gwaddr(kgetsa(rt->rt_gateway), kgetsa(rt->rt_gateway)->sa_family); - p_flags(rt->rt_flags, "%-6.6s "); + p_addr(addr, mask, rt->rt_flags, nflag); + p_gwaddr(kgetsa(rt->rt_gateway), kgetsa(rt->rt_gateway)->sa_family, nflag); + p_flags(rt->rt_flags); printf("%6d %8"PRIu64" ", rt->rt_refcnt, rt->rt_use); if (rt->rt_rmx.rmx_mtu) printf("%6"PRIu64, rt->rt_rmx.rmx_mtu); @@ -287,25 +288,7 @@ p_krtentry(struct rtentry *rt) } putchar('\n'); if (vflag) - pr_rtrmx(&rt->rt_rmx); -} - -void -pr_rtrmx(struct rt_metrics *rmx) -{ - printf("\texpire %10"PRId64"%c recvpipe %10"PRIu64"%c " - "sendpipe %10"PRIu64"%c\n", - (int64_t)rmx->rmx_expire, - (rmx->rmx_locks & RTV_EXPIRE) ? 'L' : ' ', rmx->rmx_recvpipe, - (rmx->rmx_locks & RTV_RPIPE) ? 'L' : ' ', rmx->rmx_sendpipe, - (rmx->rmx_locks & RTV_SPIPE) ? 'L' : ' '); - printf("\tssthresh %10"PRIu64"%c rtt %10"PRIu64"%c " - "rttvar %10"PRIu64"%c\n", rmx->rmx_ssthresh, - (rmx->rmx_locks & RTV_SSTHRESH) ? 'L' : ' ', - rmx->rmx_rtt, (rmx->rmx_locks & RTV_RTT) ? 'L' : ' ', - rmx->rmx_rttvar, (rmx->rmx_locks & RTV_RTTVAR) ? 'L' : ' '); - printf("\thopcount %10"PRIu64"%c\n", - rmx->rmx_hopcount, (rmx->rmx_locks & RTV_HOPCOUNT) ? 'L' : ' '); + p_rtrmx(&rt->rt_rmx); } /* Added files: Index: src/sbin/route/rtutil.c diff -u /dev/null src/sbin/route/rtutil.c:1.4.2.2 --- /dev/null Thu Jan 8 11:01:01 2015 +++ src/sbin/route/rtutil.c Thu Jan 8 11:01:01 2015 @@ -0,0 +1,786 @@ +/* $NetBSD: rtutil.c,v 1.4.2.2 2015/01/08 11:01:01 martin Exp $ */ +/* $OpenBSD: show.c,v 1.1 2006/05/27 19:16:37 claudio Exp $ */ + +/* + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/mbuf.h> +#include <sys/sysctl.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> +#include <net/pfvar.h> +#include <net/pfkeyv2.h> +#include <net/route.h> +#include <netinet/in.h> +#include <netinet/if_ether.h> +#include <netatalk/at.h> +#include <netmpls/mpls.h> +#include <arpa/inet.h> + +#include <err.h> +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "prog_ops.h" +#include "rtutil.h" + + +#define PLEN (LONG_BIT / 4 + 2) +#define PFKEYV2_CHUNK sizeof(u_int64_t) +static char *link_print(const struct sockaddr *); + +/* + * Definitions for showing gateway flags. + */ +struct bits { + int b_mask; + char b_val; +}; +static const struct bits bits[] = { + { RTF_UP, 'U' }, + { RTF_GATEWAY, 'G' }, + { RTF_HOST, 'H' }, + { RTF_REJECT, 'R' }, + { RTF_BLACKHOLE, 'B' }, + { RTF_DYNAMIC, 'D' }, + { RTF_MODIFIED, 'M' }, + { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ + { RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */ + { RTF_CLONING, 'C' }, + { RTF_XRESOLVE, 'X' }, + { RTF_LLINFO, 'L' }, + { RTF_STATIC, 'S' }, + { RTF_PROTO1, '1' }, + { RTF_PROTO2, '2' }, + /* { RTF_PROTO3, '3' }, */ + { RTF_CLONED, 'c' }, + /* { RTF_JUMBO, 'J' }, */ + { RTF_ANNOUNCE, 'p' }, + { 0, 0 } +}; + +#ifndef SMALL +static void p_tag(const struct sockaddr *sa); +#endif +static void p_rtentry(struct rt_msghdr *, int, int); + +/* + * Print routing tables. + */ +void +p_rttables(int paf, int flags, int pflags, int interesting) +{ + struct rt_msghdr *rtm; + char *buf = NULL, *next, *lim = NULL; + size_t needed; + int mib[6]; + struct sockaddr *sa; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = paf; + mib[4] = NET_RT_DUMP; + mib[5] = 0; + if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + err(1, "route-sysctl-estimate"); + if (needed > 0) { + if ((buf = malloc(needed)) == 0) + err(1, NULL); + if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + err(1, "sysctl of routing table"); + lim = buf + needed; + } + + printf("Routing tables\n"); + + if (buf) { + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + sa = (struct sockaddr *)(rtm + 1); + if ((rtm->rtm_flags & pflags) != pflags) + continue; + if (paf != AF_UNSPEC && sa->sa_family != paf) + continue; + p_rtentry(rtm, flags, interesting); + } + free(buf); + buf = NULL; + } + + if (paf != 0 && paf != PF_KEY) + return; + +#if 0 /* XXX-elad */ + mib[0] = CTL_NET; + mib[1] = PF_KEY; + mib[2] = PF_KEY_V2; + mib[3] = NET_KEY_SPD_DUMP; + mib[4] = mib[5] = 0; + + if (prog_sysctl(mib, 4, NULL, &needed, NULL, 0) == -1) { + if (errno == ENOPROTOOPT) + return; + err(1, "spd-sysctl-estimate"); + } + if (needed > 0) { + if ((buf = malloc(needed)) == 0) + err(1, NULL); + if (prog_sysctl(mib, 4, buf, &needed, NULL, 0) == -1) + err(1,"sysctl of spd"); + lim = buf + needed; + } + + if (buf) { + printf("\nEncap:\n"); + + for (next = buf; next < lim; next += msg->sadb_msg_len * + PFKEYV2_CHUNK) { + msg = (struct sadb_msg *)next; + if (msg->sadb_msg_len == 0) + break; + p_pfkentry(msg); + } + free(buf); + buf = NULL; + } +#endif /* 0 */ +} + +/* + * column widths; each followed by one space + * width of destination/gateway column + * strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 + */ +#ifndef INET6 +#define WID_DST(af) 18 /* width of destination column */ +#define WID_GW(af) 18 /* width of gateway column */ +#else +#define WID_DST(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 34 : 18) : 18) +#define WID_GW(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 30 : 18) : 18) +#endif + +/* + * Print header for routing table columns. + */ +void +p_rthdr(int paf, int flags) +{ +#ifndef SMALL + if (flags & RT_AFLAG) + printf("%-*.*s ", PLEN, PLEN, "Address"); + if (paf == PF_KEY) { + printf("%-18s %-5s %-18s %-5s %-5s %-22s\n", + "Source", "Port", "Destination", + "Port", "Proto", "SA(Address/Proto/Type/Direction)"); + return; + } + if (flags & RT_TFLAG) { + printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %7.7s" + " %s\n", WID_DST(paf), WID_DST(paf), "Destination", + WID_GW(paf), WID_GW(paf), "Gateway", + "Flags", "Refs", "Use", "Mtu", "Tag", "Interface"); + return; + } +#endif +#ifndef SMALL + printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %s\n", + WID_DST(paf), WID_DST(paf), "Destination", + WID_GW(paf), WID_GW(paf), "Gateway", + "Flags", "Refs", "Use", "Mtu", "Interface"); +#else + printf("%-*.*s %-*.*s %-6.6s\n", + WID_DST(paf), WID_DST(paf), "Destination", + WID_GW(paf), WID_GW(paf), "Gateway", + "Flags"); +#endif +} + +static void +get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) +{ + int i; + + for (i = 0; i < RTAX_MAX; i++) { + if (addrs & (1 << i)) { + rti_info[i] = sa; + sa = (struct sockaddr *)((char *)(sa) + + RT_ROUNDUP(sa->sa_len)); + } else + rti_info[i] = NULL; + } +} + +/* + * Print a routing table entry. + */ +static void +p_rtentry(struct rt_msghdr *rtm, int flags, int interesting) +{ + static int old_af = -1; + struct sockaddr *sa = (struct sockaddr *)(rtm + 1); + struct sockaddr *mask, *rti_info[RTAX_MAX]; +#ifndef SMALL + char ifbuf[IF_NAMESIZE]; +#endif + + if (old_af != sa->sa_family) { + old_af = sa->sa_family; + p_family(sa->sa_family); + p_rthdr(sa->sa_family, flags); + } + get_rtaddrs(rtm->rtm_addrs, sa, rti_info); + + mask = rti_info[RTAX_NETMASK]; + if ((sa = rti_info[RTAX_DST]) == NULL) + return; + + p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family), flags); + p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST, + WID_GW(sa->sa_family), flags); + p_flags(rtm->rtm_flags & interesting); +#if 0 /* XXX-elad */ + printf("%6d %8"PRId64" ", (int)rtm->rtm_rmx.rmx_refcnt, + rtm->rtm_rmx.rmx_pksent); +#else + printf("%6s %8s ", "-", "-"); +#endif +#ifndef SMALL + if (rtm->rtm_rmx.rmx_mtu) + printf("%6"PRId64, rtm->rtm_rmx.rmx_mtu); + else + printf("%6s", "-"); + putchar((rtm->rtm_rmx.rmx_locks & RTV_MTU) ? 'L' : ' '); + if (flags & RT_TFLAG) + p_tag(rti_info[RTAX_TAG]); + printf(" %.16s", if_indextoname(rtm->rtm_index, ifbuf)); + putchar('\n'); + if (flags & RT_VFLAG) + p_rtrmx(&rtm->rtm_rmx); +#endif +} + +/* + * Print address family header before a section of the routing table. + */ +void +p_family(int paf) +{ + const char *afname; + + switch (paf) { + case AF_INET: + afname = "Internet"; + break; +#ifdef INET6 + case AF_INET6: + afname = "Internet6"; + break; +#endif + case PF_KEY: + afname = "Encap"; + break; + case AF_APPLETALK: + afname = "AppleTalk"; + break; +#ifndef SMALL + case AF_MPLS: + afname = "MPLS"; + break; +#endif + default: + afname = NULL; + break; + } + if (afname) + printf("\n%s:\n", afname); + else + printf("\nProtocol Family %d:\n", paf); +} + +void +p_sockaddr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags, + int width, int flags) +{ + char *cp; + + switch (sa->sa_family) { +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 sa6 = *(const struct sockaddr_in6 *)sa; + + inet6_getscopeid(&sa6, INET6_IS_ADDR_LINKLOCAL| + INET6_IS_ADDR_MC_LINKLOCAL); + if (rflags & RTF_HOST) + cp = routename((const struct sockaddr *)&sa6, flags); + else + cp = netname((const struct sockaddr *)&sa6, mask, flags); + break; + } +#endif + default: + if ((rflags & RTF_HOST) || mask == NULL) + cp = routename(sa, flags); + else + cp = netname(sa, mask, flags); + break; + } + if (width < 0) + printf("%s", cp); + else { + if (flags & RT_NFLAG) + printf("%-*s ", width, cp); + else + printf("%-*.*s ", width, width, cp); + } +} + +void +p_flags(int f) +{ + char name[33], *flags; + const struct bits *p = bits; + + for (flags = name; p->b_mask && flags < &name[sizeof(name) - 2]; p++) + if (p->b_mask & f) + *flags++ = p->b_val; + *flags = '\0'; + printf("%-6.6s ", name); +} + +#ifndef SMALL +void +p_rtrmx(const struct rt_metrics *rmx) +{ + printf("\texpire %10"PRId64"%c recvpipe %10"PRIu64"%c " + "sendpipe %10"PRIu64"%c\n", + (int64_t)rmx->rmx_expire, + (rmx->rmx_locks & RTV_EXPIRE) ? 'L' : ' ', rmx->rmx_recvpipe, + (rmx->rmx_locks & RTV_RPIPE) ? 'L' : ' ', rmx->rmx_sendpipe, + (rmx->rmx_locks & RTV_SPIPE) ? 'L' : ' '); + printf("\tssthresh %10"PRIu64"%c rtt %10"PRIu64"%c " + "rttvar %10"PRIu64"%c\n", rmx->rmx_ssthresh, + (rmx->rmx_locks & RTV_SSTHRESH) ? 'L' : ' ', + rmx->rmx_rtt, (rmx->rmx_locks & RTV_RTT) ? 'L' : ' ', + rmx->rmx_rttvar, (rmx->rmx_locks & RTV_RTTVAR) ? 'L' : ' '); + printf("\thopcount %10"PRIu64"%c\n", + rmx->rmx_hopcount, (rmx->rmx_locks & RTV_HOPCOUNT) ? 'L' : ' '); +} + +static void +p_tag(const struct sockaddr *sa) +{ + char *line; + + if (sa == NULL || sa->sa_family != AF_MPLS) { + printf("%7s", "-"); + return; + } + line = mpls_ntoa(sa); + if (strlen(line) < 7) + printf("%7s", line); + else + printf("%s", line); +} +#endif + +static char line[MAXHOSTNAMELEN]; +static char domain[MAXHOSTNAMELEN]; + +char * +routename(const struct sockaddr *sa, int flags) +{ + char *cp = NULL; + static int first = 1; + + if (first) { + first = 0; + if (gethostname(domain, sizeof(domain)) == 0 && + (cp = strchr(domain, '.'))) + (void)strlcpy(domain, cp + 1, sizeof(domain)); + else + domain[0] = '\0'; + cp = NULL; + } + + if (sa->sa_len == 0) { + (void)strlcpy(line, "default", sizeof(line)); + return (line); + } + + switch (sa->sa_family) { + case AF_INET: + return routename4( + ((const struct sockaddr_in *)sa)->sin_addr.s_addr, + flags); +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 sin6; + + memset(&sin6, 0, sizeof(sin6)); + memcpy(&sin6, sa, sa->sa_len); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_family = AF_INET6; + if (sa->sa_len == sizeof(struct sockaddr_in6)) + inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL| + INET6_IS_ADDR_MC_LINKLOCAL); + return routename6(&sin6, flags); + } +#endif + case AF_LINK: + return link_print(sa); + +#ifndef SMALL + case AF_MPLS: + return mpls_ntoa(sa); + + case AF_APPLETALK: + (void)snprintf(line, sizeof(line), "atalk %d.%d", + ((const struct sockaddr_at *)sa)->sat_addr.s_net, + ((const struct sockaddr_at *)sa)->sat_addr.s_node); + break; +#endif + +#if 0 /* XXX-elad */ + case AF_UNSPEC: + if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) { + static char name[RTLABEL_LEN]; + struct sockaddr_rtlabel *sr; + + sr = (struct sockaddr_rtlabel *)sa; + strlcpy(name, sr->sr_label, sizeof(name)); + return (name); + } + /* FALLTHROUGH */ +#endif + default: + (void)snprintf(line, sizeof(line), "(%d) %s", + sa->sa_family, any_ntoa(sa)); + break; + } + return (line); +} + +char * +routename4(in_addr_t in, int flags) +{ + const char *cp = NULL; + struct in_addr ina; + struct hostent *hp; + + if (in == INADDR_ANY) + cp = "default"; + if (!cp && (flags & RT_NFLAG) == 0) { + if ((hp = gethostbyaddr((char *)&in, + sizeof(in), AF_INET)) != NULL) { + char *p; + if ((p = strchr(hp->h_name, '.')) && + !strcmp(p + 1, domain)) + *p = '\0'; + cp = hp->h_name; + } + } + ina.s_addr = in; + strlcpy(line, cp ? cp : inet_ntoa(ina), sizeof(line)); + + return (line); +} + +#ifdef INET6 +char * +routename6(const struct sockaddr_in6 *sin6, int flags) +{ + int niflags = 0; + + if ((flags & RT_NFLAG)) + niflags |= NI_NUMERICHOST; + else + niflags |= NI_NOFQDN; + + if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len, + line, sizeof(line), NULL, 0, niflags) != 0) + strncpy(line, "invalid", sizeof(line)); + + return (line); +} +#endif + +/* + * Return the name of the network whose address is given. + * The address is assumed to be that of a net or subnet, not a host. + */ +char * +netname4(in_addr_t in, in_addr_t mask, int flags) +{ + const char *cp = NULL; + struct netent *np = NULL; + int mbits; + + in = ntohl(in); + mask = ntohl(mask); + if (!(flags & RT_NFLAG) && in != INADDR_ANY) { + if ((np = getnetbyaddr(in, AF_INET)) != NULL) + cp = np->n_name; + } + mbits = mask ? 33 - ffs(mask) : 0; + if (in == INADDR_ANY && !mbits) + cp = "default"; + if (cp) + strlcpy(line, cp, sizeof(line)); +#define C(x) ((x) & 0xff) + else if (mbits < 9) + snprintf(line, sizeof(line), "%u/%d", C(in >> 24), mbits); + else if (mbits < 17) + snprintf(line, sizeof(line), "%u.%u/%d", + C(in >> 24) , C(in >> 16), mbits); + else if (mbits < 25) + snprintf(line, sizeof(line), "%u.%u.%u/%d", + C(in >> 24), C(in >> 16), C(in >> 8), mbits); + else + snprintf(line, sizeof(line), "%u.%u.%u.%u/%d", C(in >> 24), + C(in >> 16), C(in >> 8), C(in), mbits); +#undef C + return (line); +} + +#ifdef INET6 +char * +netname6(const struct sockaddr_in6 *sa6, const struct sockaddr_in6 *mask, int flags) +{ + struct sockaddr_in6 sin6; + const u_char *p; + int masklen, final = 0, illegal = 0; + int i, lim, flag, error; + char hbuf[NI_MAXHOST]; + + sin6 = *sa6; + + flag = 0; + masklen = 0; + if (mask) { + lim = mask->sin6_len - offsetof(struct sockaddr_in6, sin6_addr); + if (lim < 0) + lim = 0; + else if (lim > (int)sizeof(struct in6_addr)) + lim = sizeof(struct in6_addr); + for (p = (const u_char *)&mask->sin6_addr, i = 0; i < lim; p++) { + if (final && *p) { + illegal++; + sin6.sin6_addr.s6_addr[i++] = 0x00; + 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 (!illegal) + sin6.sin6_addr.s6_addr[i++] &= *p; + else + sin6.sin6_addr.s6_addr[i++] = 0x00; + } + while (i < (int)sizeof(struct in6_addr)) + sin6.sin6_addr.s6_addr[i++] = 0x00; + } else + masklen = 128; + + if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) { + snprintf(line, sizeof(line), "default"); + return (line); + } + + if (illegal) + warnx("illegal prefixlen"); + + if (flags & RT_NFLAG) + flag |= NI_NUMERICHOST; + error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, + hbuf, sizeof(hbuf), NULL, 0, flag); + if (error) + snprintf(hbuf, sizeof(hbuf), "invalid"); + + snprintf(line, sizeof(line), "%s/%d", hbuf, masklen); + return (line); +} +#endif + +/* + * Return the name of the network whose address is given. + * The address is assumed to be that of a net or subnet, not a host. + */ +char * +netname(const struct sockaddr *sa, const struct sockaddr *mask, int flags) +{ + switch (sa->sa_family) { + + case AF_INET: + return netname4(((const struct sockaddr_in *)sa)->sin_addr.s_addr, + ((const struct sockaddr_in *)mask)->sin_addr.s_addr, flags); +#ifdef INET6 + case AF_INET6: + return netname6((const struct sockaddr_in6 *)sa, + (const struct sockaddr_in6 *)mask, flags); +#endif + case AF_LINK: + return link_print(sa); + default: + snprintf(line, sizeof(line), "af %d: %s", + sa->sa_family, any_ntoa(sa)); + break; + } + return (line); +} + +static const char hexlist[] = "0123456789abcdef"; + +char * +any_ntoa(const struct sockaddr *sa) +{ + static char obuf[240]; + const char *in = sa->sa_data; + char *out = obuf; + int len = sa->sa_len - offsetof(struct sockaddr, sa_data); + + *out++ = 'Q'; + do { + *out++ = hexlist[(*in >> 4) & 15]; + *out++ = hexlist[(*in++) & 15]; + *out++ = '.'; + } while (--len > 0 && (out + 3) < &obuf[sizeof(obuf) - 1]); + out[-1] = '\0'; + return (obuf); +} + +static char * +link_print(const struct sockaddr *sa) +{ + const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)sa; + const u_char *lla = (const u_char *)sdl->sdl_data + sdl->sdl_nlen; + + if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && + sdl->sdl_slen == 0) { + (void)snprintf(line, sizeof(line), "link#%d", sdl->sdl_index); + return (line); + } + switch (sdl->sdl_type) { + case IFT_ETHER: + case IFT_CARP: + return ether_ntoa((const struct ether_addr *)lla); + default: + return link_ntoa(sdl); + } +} + +#ifndef SMALL +char * +mpls_ntoa(const struct sockaddr *sa) +{ + static char obuf[16]; + size_t olen; + const union mpls_shim *pms; + union mpls_shim ms; + int psize = sizeof(struct sockaddr_mpls); + + pms = &((const struct sockaddr_mpls*)sa)->smpls_addr; + ms.s_addr = ntohl(pms->s_addr); + + snprintf(obuf, sizeof(obuf), "%u", ms.shim.label); + + while(psize < sa->sa_len) { + pms++; + ms.s_addr = ntohl(pms->s_addr); + olen = strlen(obuf); + snprintf(obuf + olen, sizeof(obuf) - olen, ",%u", + ms.shim.label); + psize+=sizeof(ms); + } + return obuf; +} +#endif + +void +p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags, int flags) +{ + p_sockaddr(sa, mask, rflags, WID_DST(sa->sa_family), flags); +} + +void +p_gwaddr(const struct sockaddr *sa, int gwaf, int flags) +{ + p_sockaddr(sa, 0, RTF_HOST, WID_GW(gwaf), flags); +} Index: src/sbin/route/rtutil.h diff -u /dev/null src/sbin/route/rtutil.h:1.3.2.2 --- /dev/null Thu Jan 8 11:01:01 2015 +++ src/sbin/route/rtutil.h Thu Jan 8 11:01:01 2015 @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define RT_AFLAG 1 +#define RT_TFLAG 2 +#define RT_VFLAG 4 +#define RT_NFLAG 8 + +void p_rttables(int, int, int, int); +void p_rthdr(int, int); +void p_family(int); +void p_sockaddr(const struct sockaddr *, const struct sockaddr *, int, int, int); +void p_flags(int); +struct rt_metrics; +void p_rtrmx(const struct rt_metrics *); +void p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int, int); +void p_gwaddr(const struct sockaddr *sa, int, int); + +char *routename(const struct sockaddr *sa, int); +char *routename4(in_addr_t, int); +#ifdef INET6 +char *routename6(const struct sockaddr_in6 *, int); +char *netname6(const struct sockaddr_in6 *, const struct sockaddr_in6 *, int); +#endif +char *netname(const struct sockaddr *, const struct sockaddr *, int); +char *netname4(in_addr_t, in_addr_t, int); + +char *mpls_ntoa(const struct sockaddr *); +char *any_ntoa(const struct sockaddr *);