Skip site navigation (1)Skip section navigation (2)
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>