Date: Sat, 16 Jul 2005 01:21:22 GMT From: soc-anders <soc-anders@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 80309 for review Message-ID: <200507160121.j6G1LMk6050595@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80309 Change 80309 by soc-anders@soc-anders_gimli on 2005/07/16 01:20:57 Routing information is now obtained using only sysctl. Extended previous work such that information provided is more complete. Issues: * -A flag will for obvious reasons not work, and the goal it to have that be part of a separate debugging tool. * Reference count (rt_refcnt) is not available. * -rs mode currently disables due to kvm usage. Should rtstat be available via sysctl? Affected files ... .. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/route.c#2 edit Differences ... ==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/route.c#2 (text+ko) ==== @@ -47,10 +47,8 @@ #include <net/ethernet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> -#include <net/radix.h> #include <net/route.h> #include <netinet/in.h> @@ -71,8 +69,6 @@ #include <time.h> #include "netstat.h" -#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) - /* * Definitions for showing gateway flags. */ @@ -107,22 +103,7 @@ u_short u_data[128]; } sa_u; -static sa_u pt_u; - -int do_rtent = 0; -struct rtentry rtentry; -struct radix_node rnode; -struct radix_mask rmask; -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 size_cols (int ef); static void ntreestuff (void); static void np_rtentry (struct rt_msghdr *); static void p_sockaddr (struct sockaddr *, struct sockaddr *, int, int); @@ -130,7 +111,6 @@ int flags); static void p_flags (int, const 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); @@ -140,38 +120,9 @@ void routepr(u_long rtree) { - struct radix_node_head *rnh, head; - int i; - printf("Routing tables\n"); - if (Aflag == 0 && NewTree) - ntreestuff(); - else { - if (rtree == 0) { - printf("rt_tables: symbol not in namelist\n"); - return; - } - - kget(rtree, rt_tables); - for (i = 0; i <= AF_MAX; i++) { - if ((rnh = rt_tables[i]) == 0) - continue; - kget(rnh, head); - if (i == AF_UNSPEC) { - if (Aflag && af == 0) { - printf("Netmasks:\n"); - 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); - p_tree(head.rnh_treetop); - } - } - } + ntreestuff(); } /* @@ -239,7 +190,7 @@ static int wid_expire; static void -size_cols(int ef, struct radix_node *rn) +size_cols(int ef) { wid_dst = WID_DST_DEFAULT(ef); wid_gw = WID_GW_DEFAULT(ef); @@ -249,126 +200,29 @@ 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) { - kget(rt->rt_ifp, ifnet); - lastif = rt->rt_ifp; - len = strlen(ifnet.if_xname); - 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. */ void pr_rthdr(int af1) { - - if (Aflag) - printf("%-8.8s ","Address"); if (af1 == AF_INET || Wflag) { if (Wflag) { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*.*s %*s\n", + 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_mtu, wid_mtu, "Mtu", wid_if, wid_if, "Netif", wid_expire, "Expire"); } else { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n", + printf("%-*.*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"); @@ -383,92 +237,7 @@ } } -static struct sockaddr * -kgetsa(struct sockaddr *dst) -{ - - kget(dst, pt_u.u_sa); - if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) - kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len); - return (&pt_u.u_sa); -} - -static void -p_tree(struct radix_node *rn) -{ - -again: - kget(rn, rnode); - if (rnode.rn_bit < 0) { - if (Aflag) - printf("%-8.8lx ", (u_long)rn); - if (rnode.rn_flags & RNF_ROOT) { - if (Aflag) - printf("(root node)%s", - rnode.rn_dupedkey ? " =>\n" : "\n"); - } else if (do_rtent) { - kget(rn, rtentry); - p_rtentry(&rtentry); - if (Aflag) - p_rtnode(); - } else { - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - NULL, 0, 44); - putchar('\n'); - } - if ((rn = rnode.rn_dupedkey)) - goto again; - } else { - if (Aflag && do_rtent) { - printf("%-8.8lx ", (u_long)rn); - p_rtnode(); - } - rn = rnode.rn_right; - p_tree(rnode.rn_left); - p_tree(rn); - } -} - -char nbuf[20]; - static void -p_rtnode(void) -{ - struct radix_mask *rm = rnode.rn_mklist; - - if (rnode.rn_bit < 0) { - if (rnode.rn_mask) { - printf("\t mask "); - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask), - NULL, 0, -1); - } else if (rm == 0) - return; - } else { - sprintf(nbuf, "(%d)", rnode.rn_bit); - printf("%6.6s %8.8lx : %8.8lx", nbuf, (u_long)rnode.rn_left, (u_long)rnode.rn_right); - } - while (rm) { - kget(rm, rmask); - sprintf(nbuf, " %d refs, ", rmask.rm_refs); - printf(" mk = %8.8lx {(%d),%s", - (u_long)rm, -1 - rmask.rm_bit, rmask.rm_refs ? nbuf : " "); - if (rmask.rm_flags & RNF_NORMAL) { - struct radix_node rnode_aux; - printf(" <normal>, "); - kget(rmask.rm_leaf, rnode_aux); - p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask), - NULL, 0, -1); - } else - p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), - NULL, 0, -1); - putchar('}'); - if ((rm = rmask.rm_mklist)) - printf(" ->"); - } - putchar('\n'); -} - -static void ntreestuff(void) { size_t needed; @@ -479,7 +248,7 @@ mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; - mib[3] = 0; + mib[3] = af; mib[4] = NET_RT_DUMP; mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { @@ -502,12 +271,46 @@ static void np_rtentry(struct rt_msghdr *rtm) { - struct sockaddr *sa = (struct sockaddr *)(rtm + 1); + + char *cp = (char *)(rtm) + sizeof(*rtm); + char ifname[IFNAMSIZ]; + char buffer[100]; + sa_u dst, gw, mask, genmask; #ifdef notdef static int masks_done, banner_printed; #endif static int old_af; - int af1 = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST; + int af1 = 0; + int addrs = rtm->rtm_addrs; + int i; + + bzero(&dst, sizeof(dst)); bzero(&gw, sizeof(gw)); + bzero(&mask, sizeof(mask)); bzero(&genmask, sizeof(genmask)); + for (i = 0; addrs != 0 && i < RTAX_MAX; addrs &= ~(1<<i), i++) { + struct sockaddr *sa = (struct sockaddr *)cp; + if (!(addrs & 1<<i)) + continue; + cp += SA_SIZE(sa); + if (sa->sa_len == 0) + continue; + + switch (1<<i) { + case RTA_DST: + bcopy(sa, &dst, sa->sa_len); + break; + case RTA_GATEWAY: + bcopy(sa, &gw, sa->sa_len); + break; + case RTA_NETMASK: + bcopy(sa, &mask, sa->sa_len); + break; + case RTA_GENMASK: + bcopy(sa, &genmask, sa->sa_len); + break; + default: + break; + } + } #ifdef notdef /* for the moment, netmasks are skipped over */ @@ -522,19 +325,42 @@ } } else #endif - af1 = sa->sa_family; + af1 = dst.u_sa.sa_family; if (af1 != old_af) { pr_family(af1); + size_cols(af1); + pr_rthdr(af1); old_af = af1; } if (rtm->rtm_addrs == RTA_DST) - p_sockaddr(sa, NULL, 0, 36); + p_sockaddr(&dst.u_sa, NULL, 0, wid_dst+wid_gw); else { - p_sockaddr(sa, NULL, rtm->rtm_flags, 16); - sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); - p_sockaddr(sa, NULL, 0, 18); + p_sockaddr(&dst.u_sa, rtm->rtm_addrs&RTA_NETMASK?&mask.u_sa:NULL, + rtm->rtm_flags, wid_dst); + p_sockaddr(&gw.u_sa, NULL, RTF_HOST, wid_gw); + } + snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); + p_flags(rtm->rtm_flags, buffer); + + if (dst.u_sa.sa_family == AF_INET || Wflag) { + printf("%*d ", 6, rtm->rtm_use); + if (Wflag) { + if (rtm->rtm_rmx.rmx_mtu != 0) + printf("%*lu ", wid_mtu, rtm->rtm_rmx.rmx_mtu); + else + printf("%*s ", wid_mtu, ""); + } + } + printf("%*.*s", wid_if, wid_if, + if_indextoname(rtm->rtm_index, ifname)); + + if (rtm->rtm_rmx.rmx_expire) { + time_t expire_time; + + if ((expire_time = + rtm->rtm_rmx.rmx_expire - time((time_t *)0)) > 0) + printf(" %*d", wid_expire, (int)expire_time); } - p_flags(rtm->rtm_flags & interesting, "%-6.6s "); putchar('\n'); } @@ -701,65 +527,6 @@ return (name); } -static void -p_rtentry(struct rtentry *rt) -{ - static struct ifnet ifnet, *lastif; - struct rtentry parent; - static char buffer[128]; - static char prettyname[128]; - struct sockaddr *sa; - sa_u addr, mask; - - /* - * 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); - 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("%*ld %*lu ", wid_refs, rt->rt_refcnt, - wid_use, rt->rt_use); - if (Wflag) { - if (rt->rt_rmx.rmx_mtu != 0) - printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_mtu); - else - printf("%*s ", wid_mtu, ""); - } - } - if (rt->rt_ifp) { - if (rt->rt_ifp != lastif) { - kget(rt->rt_ifp, ifnet); - lastif = rt->rt_ifp; - strlcpy(prettyname, ifnet.if_xname, sizeof(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(" %*d", wid_expire, (int)expire_time); - } - if (rt->rt_nodes[0].rn_dupedkey) - printf(" =>"); - } - putchar('\n'); -} - char * routename(u_long in) { @@ -989,6 +756,11 @@ struct rtstat rtstat; int rttrash; + /* IFCLEANUP + * rtstat should be accessible via sysctl.. until then skip this + */ + return; + if (rtsaddr == 0) { printf("rtstat: symbol not in namelist\n"); return;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507160121.j6G1LMk6050595>