PERFORCE change 80309 for review
soc-anders
soc-anders at FreeBSD.org
Sat Jul 16 01:21:24 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80309
Change 80309 by soc-anders at 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;
More information about the p4-projects
mailing list