diff options
author | kbyanc <kbyanc@FreeBSD.org> | 2002-06-05 18:29:26 +0000 |
---|---|---|
committer | kbyanc <kbyanc@FreeBSD.org> | 2002-06-05 18:29:26 +0000 |
commit | 09c2c0c59df849756b9efa97b4ab1541a4691fcb (patch) | |
tree | cb873ab0790becb1b3d68573dae8eb0a14cb1926 | |
parent | e24090eb3a797e5f9a03d68354396bb36afd28f2 (diff) | |
download | FreeBSD-src-09c2c0c59df849756b9efa97b4ab1541a4691fcb.zip FreeBSD-src-09c2c0c59df849756b9efa97b4ab1541a4691fcb.tar.gz |
Use calculated column widths for the routing table display when -W is
supplied rather than arbitrarily larger widths. This (almost) guarantees
that no columns will be truncated (routing table additions between the
width calculation and display passes may create a row with column widths
larger than those calculated).
Sponsored by: NTT Multimedia Communications Labs
-rw-r--r-- | usr.bin/netstat/route.c | 263 |
1 files changed, 208 insertions, 55 deletions
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 68fbdce..35e1638 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -126,12 +126,18 @@ struct radix_node_head *rt_tables[AF_MAX+1]; int NewTree = 0; static struct sockaddr *kgetsa (struct sockaddr *); +static void size_cols (int ef, struct radix_node *rn); +static void size_cols_tree (struct radix_node *rn); +static void size_cols_rtentry (struct rtentry *rt); static void p_tree (struct radix_node *); static void p_rtnode (void); static void ntreestuff (void); static void np_rtentry (struct rt_msghdr *); static void p_sockaddr (struct sockaddr *, struct sockaddr *, int, int); +static const char *fmt_sockaddr (struct sockaddr *sa, struct sockaddr *mask, + int flags); static void p_flags (int, char *); +static const char *fmt_flags(int f); static void p_rtentry (struct rtentry *); static u_long forgemask (u_long); static void domask (char *, u_long, u_long); @@ -166,6 +172,7 @@ routepr(u_long rtree) p_tree(head.rnh_treetop); } } else if (af == AF_UNSPEC || af == i) { + size_cols(i, head.rnh_treetop); pr_family(i); do_rtent = 1; pr_rthdr(i); @@ -224,17 +231,134 @@ pr_family(int af) /* 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 */ -#define WID_IF(af) 6 /* width of netif column */ +#define WID_DST_DEFAULT(af) 18 /* width of destination column */ +#define WID_GW_DEFAULT(af) 18 /* width of gateway column */ +#define WID_IF_DEFAULT(af) 6 /* width of netif column */ #else -#define WID_DST(af) \ - ((af) == AF_INET6 ? (Wflag ? 39 : (numeric_addr ? 33: 18)) : 18) -#define WID_GW(af) \ - ((af) == AF_INET6 ? (Wflag ? 31 : (numeric_addr ? 29 : 18)) : 18) -#define WID_IF(af) ((af) == AF_INET6 ? 8 : 6) +#define WID_DST_DEFAULT(af) \ + ((af) == AF_INET6 ? (numeric_addr ? 33: 18) : 18) +#define WID_GW_DEFAULT(af) \ + ((af) == AF_INET6 ? (numeric_addr ? 29 : 18) : 18) +#define WID_IF_DEFAULT(af) ((af) == AF_INET6 ? 8 : 6) #endif /*INET6*/ +static int wid_dst; +static int wid_gw; +static int wid_flags; +static int wid_refs; +static int wid_use; +static int wid_mtu; +static int wid_if; +static int wid_expire; + +static void +size_cols(int ef, struct radix_node *rn) +{ + wid_dst = WID_DST_DEFAULT(ef); + wid_gw = WID_GW_DEFAULT(ef); + wid_flags = 6; + wid_refs = 6; + wid_use = 8; + wid_mtu = 6; + wid_if = WID_IF_DEFAULT(ef); + wid_expire = 6; + + if (Wflag) + size_cols_tree(rn); +} + +static void +size_cols_tree(struct radix_node *rn) +{ +again: + kget(rn, rnode); + if (rnode.rn_bit < 0) { + if ((rnode.rn_flags & RNF_ROOT) == 0) { + kget(rn, rtentry); + size_cols_rtentry(&rtentry); + } + if ((rn = rnode.rn_dupedkey)) + goto again; + } else { + rn = rnode.rn_right; + size_cols_tree(rnode.rn_left); + size_cols_tree(rn); + } +} + +static void +size_cols_rtentry(struct rtentry *rt) +{ + static struct ifnet ifnet, *lastif; + struct rtentry parent; + static char buffer[100]; + const char *bp; + struct sockaddr *sa; + sa_u addr, mask; + int len; + + /* + * Don't print protocol-cloned routes unless -a. + */ + if (rt->rt_flags & RTF_WASCLONED && !aflag) { + kget(rt->rt_parent, parent); + if (parent.rt_flags & RTF_PRCLONING) + return; + } + + bzero(&addr, sizeof(addr)); + if ((sa = kgetsa(rt_key(rt)))) + bcopy(sa, &addr, sa->sa_len); + bzero(&mask, sizeof(mask)); + if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) + bcopy(sa, &mask, sa->sa_len); + bp = fmt_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags); + len = strlen(bp); + wid_dst = MAX(len, wid_dst); + + bp = fmt_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST); + len = strlen(bp); + wid_gw = MAX(len, wid_gw); + + bp = fmt_flags(rt->rt_flags); + len = strlen(bp); + wid_flags = MAX(len, wid_flags); + + if (addr.u_sa.sa_family == AF_INET || Wflag) { + len = snprintf(buffer, sizeof(buffer), "%ld", rt->rt_refcnt); + wid_refs = MAX(len, wid_refs); + len = snprintf(buffer, sizeof(buffer), "%lu", rt->rt_use); + wid_use = MAX(len, wid_use); + if (Wflag && rt->rt_rmx.rmx_mtu != 0) { + len = snprintf(buffer, sizeof(buffer), + "%lu", rt->rt_rmx.rmx_mtu); + wid_mtu = MAX(len, wid_mtu); + } + } + if (rt->rt_ifp) { + if (rt->rt_ifp != lastif) { + len = snprintf(buffer, sizeof(buffer), "%d", + ifnet.if_unit); + kget(rt->rt_ifp, ifnet); + kread((u_long)ifnet.if_name, buffer, sizeof(buffer)); + lastif = rt->rt_ifp; + len += strlen(buffer); + wid_if = MAX(len, wid_if); + } + if (rt->rt_rmx.rmx_expire) { + time_t expire_time; + + if ((expire_time = + rt->rt_rmx.rmx_expire - time(NULL)) > 0) { + len = snprintf(buffer, sizeof(buffer), "%d", + (int)expire_time); + wid_expire = MAX(len, wid_expire); + } + } + } +} + + /* * Print header for routing table columns. */ @@ -244,24 +368,35 @@ pr_rthdr(int af) if (Aflag) printf("%-8.8s ","Address"); - if (af == AF_INET || Wflag) - if (Wflag) - printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %*.*s %6s\n", - WID_DST(af), WID_DST(af), "Destination", - WID_GW(af), WID_GW(af), "Gateway", - "Flags", "Refs", "Use", "Mtu", - WID_IF(af), WID_IF(af), "Netif", "Expire"); - else - printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %*.*s %6s\n", - WID_DST(af), WID_DST(af), "Destination", - WID_GW(af), WID_GW(af), "Gateway", - "Flags", "Refs", "Use", - WID_IF(af), WID_IF(af), "Netif", "Expire"); - else - printf("%-*.*s %-*.*s %-6.6s %8.8s %6s\n", - WID_DST(af), WID_DST(af), "Destination", - WID_GW(af), WID_GW(af), "Gateway", - "Flags", "Netif", "Expire"); + if (af == AF_INET || Wflag) { + if (Wflag) { + printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*.*s %*s\n", + wid_dst, wid_dst, "Destination", + wid_gw, wid_gw, "Gateway", + wid_flags, wid_flags, "Flags", + wid_refs, wid_refs, "Refs", + wid_use, wid_use, "Use", + wid_mtu, wid_mtu, "Mtu", + wid_if, wid_if, "Netif", + wid_expire, "Expire"); + } else { + printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n", + wid_dst, wid_dst, "Destination", + wid_gw, wid_gw, "Gateway", + wid_flags, wid_flags, "Flags", + wid_refs, wid_refs, "Refs", + wid_use, wid_use, "Use", + wid_if, wid_if, "Netif", + wid_expire, "Expire"); + } + } else { + printf("%-*.*s %-*.*s %-*.*s %*.*s %*s\n", + wid_dst, wid_dst, "Destination", + wid_gw, wid_gw, "Gateway", + wid_flags, wid_flags, "Flags", + wid_if, wid_if, "Netif", + wid_expire, "Expire"); + } } static struct sockaddr * @@ -422,8 +557,26 @@ np_rtentry(struct rt_msghdr *rtm) static void p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) { - char workbuf[128], *cplim; - register char *cp = workbuf; + const char *cp; + + cp = fmt_sockaddr(sa, mask, flags); + + if (width < 0 ) + printf("%s ", cp); + else { + if (numeric_addr) + printf("%-*s ", width, cp); + else + printf("%-*.*s ", width, width, cp); + } +} + +static const char * +fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) +{ + static char workbuf[128]; + char *cplim; + char *cp = workbuf; switch(sa->sa_family) { case AF_INET: @@ -542,27 +695,28 @@ p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) cp = workbuf; } } - if (width < 0 ) - printf("%s ", cp); - else { - if (numeric_addr) - printf("%-*s ", width, cp); - else - printf("%-*.*s ", width, width, cp); - } + + return (cp); } static void p_flags(int f, char *format) { - char name[33], *flags; - register struct bits *p = bits; + printf(format, fmt_flags(f)); +} + +static const char * +fmt_flags(int f) +{ + static char name[33]; + char *flags; + struct bits *p = bits; for (flags = name; p->b_mask; p++) if (p->b_mask & f) *flags++ = p->b_val; *flags = '\0'; - printf(format, name); + return (name); } static void @@ -570,8 +724,8 @@ p_rtentry(struct rtentry *rt) { static struct ifnet ifnet, *lastif; struct rtentry parent; - static char name[16]; - static char prettyname[9]; + static char buffer[128]; + static char prettyname[128]; struct sockaddr *sa; sa_u addr, mask; @@ -590,36 +744,35 @@ p_rtentry(struct rtentry *rt) bzero(&mask, sizeof(mask)); if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) bcopy(sa, &mask, sa->sa_len); - p_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags, - WID_DST(addr.u_sa.sa_family)); - p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, - WID_GW(addr.u_sa.sa_family)); - p_flags(rt->rt_flags, "%-6.6s "); + p_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags, wid_dst); + p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw); + snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); + p_flags(rt->rt_flags, buffer); if (addr.u_sa.sa_family == AF_INET || Wflag) { - printf("%6ld %8lu ", rt->rt_refcnt, rt->rt_use); + printf("%*ld %*lu ", wid_refs, rt->rt_refcnt, + wid_use, rt->rt_use); if (Wflag) { if (rt->rt_rmx.rmx_mtu != 0) - printf("%6lu ", rt->rt_rmx.rmx_mtu); + printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_mtu); else - printf("%6s ", ""); + printf("%*s ", wid_mtu, ""); } } if (rt->rt_ifp) { if (rt->rt_ifp != lastif) { kget(rt->rt_ifp, ifnet); - kread((u_long)ifnet.if_name, name, 16); + kread((u_long)ifnet.if_name, buffer, sizeof(buffer)); lastif = rt->rt_ifp; - snprintf(prettyname, sizeof prettyname, - "%s%d", name, ifnet.if_unit); + snprintf(prettyname, sizeof(prettyname), + "%s%d", buffer, ifnet.if_unit); } - printf("%*.*s", WID_IF(addr.u_sa.sa_family), - WID_IF(addr.u_sa.sa_family), prettyname); + printf("%*.*s", wid_if, wid_if, prettyname); if (rt->rt_rmx.rmx_expire) { time_t expire_time; if ((expire_time = rt->rt_rmx.rmx_expire - time((time_t *)0)) > 0) - printf(" %6d", (int)expire_time); + printf(" %*d", wid_expire, (int)expire_time); } if (rt->rt_nodes[0].rn_dupedkey) printf(" =>"); |