From: Keith Sklower Date: Sun, 8 Apr 1990 07:17:27 +0000 (-0800) Subject: dump routing tree via getkerninfo call (in progress) X-Git-Tag: BSD-4_3_Reno-Snapshot-Development~3807 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/4d9e18da99282205a2066cb7ae0b64910561b2f8?hp=20f649902fd00ae79f6004c297a2a90cffae8333 dump routing tree via getkerninfo call (in progress) SCCS-vsn: usr.bin/netstat/route.c 5.16 --- diff --git a/usr/src/usr.bin/netstat/route.c b/usr/src/usr.bin/netstat/route.c index 41267c4c6b..fd7717f7ca 100644 --- a/usr/src/usr.bin/netstat/route.c +++ b/usr/src/usr.bin/netstat/route.c @@ -16,7 +16,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)route.c 5.15 (Berkeley) %G%"; +static char sccsid[] = "@(#)route.c 5.16 (Berkeley) %G%"; #endif /* not lint */ #include @@ -35,6 +35,7 @@ static char sccsid[] = "@(#)route.c 5.15 (Berkeley) %G%"; #include #include +#include extern int kmem; extern int nflag; @@ -121,11 +122,14 @@ static union { } pt_u; static struct rtentry rtentry; +int NewTree = 0; treestuff(rtree) off_t rtree; { struct radix_node_head *rnh, head; + if (NewTree) + return(ntreestuff()); for (kget(rtree, rnh); rnh; rnh = head.rnh_next) { kget(rnh, head); if (head.rnh_af == 0) { @@ -139,6 +143,18 @@ off_t rtree; } } +struct sockaddr * +kgetsa(dst) +register struct sockaddr *dst; +{ + kget(dst, pt_u.u_sa); + if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) { + klseek(kmem, (off_t)dst, 0); + read(kmem, pt_u.u_data, pt_u.u_sa.sa_len); + } + return (&pt_u.u_sa); +} + p_tree(rn, do_rtent) struct radix_node *rn; { @@ -155,13 +171,8 @@ again: kget(rn, rtentry); p_rtentry(&rtentry); } else { - kget(rnode.rn_key, pt_u); - printf("(%d) ",pt_u.u_sa.sa_family); - if ((len = pt_u.u_sa.sa_len) == 0 || len > MAXKEYLEN) - len = MAXKEYLEN; - s = pt_u.u_data + 1; - for (slim = s + ((len - 1)/2); s < slim; s++) - printf("%x ", *s); + p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), + 0, "%-44.44s "); putchar('\n'); } if (rn = rnode.rn_dupedkey) @@ -172,61 +183,126 @@ again: } } -struct sockaddr * -kgetsa(dst) -register struct sockaddr *dst; +ntreestuff() { - kget(dst, pt_u.u_sa); - if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) { - klseek(kmem, (off_t)dst, 0); - read(kmem, pt_u.u_data, pt_u.u_sa.sa_len); + int needed; + char *buf, *next, *lim; + register struct rt_msghdr *rtm; + + if ((needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0)) < 0) + { perror("route-getkerninfo-estimate"); exit(1);} + if ((buf = malloc(needed)) == 0) + { printf("out of space\n");; exit(1);} + if (getkerninfo(KINFO_RT_DUMP, buf, &needed, 0) < 0) + { perror("actual retrieval of routing table"); exit(1);} + lim = buf + needed; + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + np_rtentry(rtm); } - return (&pt_u.u_sa); } -p_rtentry(rt) -register struct rtentry *rt; +np_rtentry(rtm) +register struct rt_msghdr *rtm; { - char name[16], *flags; - register struct bits *p; - register struct sockaddr_in *sin; - struct ifnet ifnet; + register struct sockaddr *sa = (struct sockaddr *)(rtm + 1); + static int masks_done, old_af, banner_printed; + int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST; + +#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 (af != old_af) { + printf("\nRoute Tree for Protocol Family %d:\n", af); + old_af = af; + } + if (rtm->rtm_addrs == RTA_DST) + p_sockaddr(sa, 0, "%-36.36s "); + else { + p_sockaddr(sa, rtm->rtm_flags, "%-16.16s "); + if (sa->sa_len == 0) + sa->sa_len = sizeof(long); + sa = (struct sockaddr *)(sa->sa_len + (char *)sa); + p_sockaddr(sa, 0, "%-18.18s "); + } + p_flags(rtm->rtm_flags & interesting, "%-6.6s "); + putchar('\n'); +} - sin = (struct sockaddr_in *)kgetsa(rt_key(rt)); - switch(sin->sin_family) { +p_sockaddr(sa, flags, format) +struct sockaddr *sa; +int flags; +char *format; +{ + char workbuf[128], *cp, *cplim; + register char *cpout; + + switch(sa->sa_family) { case AF_INET: - printf("%-16.16s ", - (sin->sin_addr.s_addr == 0) ? "default" : - (rt->rt_flags & RTF_HOST) ? - routename(sin->sin_addr) : - netname(sin->sin_addr, 0L)); - sin = (struct sockaddr_in *)kgetsa(rt->rt_gateway); - printf("%-18.18s ", routename(sin->sin_addr)); + { + register struct sockaddr_in *sin = (struct sockaddr_in *)sa; + + cp = (sin->sin_addr.s_addr == 0) ? "default" : + ((flags & RTF_HOST) ? + routename(sin->sin_addr) : netname(sin->sin_addr, 0L)); + } break; + case AF_NS: - printf("%-16s ", - ns_print((struct sockaddr_ns *)sin)); - printf("%-18s ", - ns_print((struct sockaddr_ns *)kgetsa(rt->rt_gateway))); + cp = ns_print((struct sockaddr_ns *)sa); break; + default: - { - u_short *s = (u_short *)pt_u.u_sa.sa_data; - printf("(%d)%x %x %x %x %x %x %x ", - sin->sin_family, - s[0], s[1], s[2], s[3], s[4], s[5], s[6]); - (void) kgetsa(rt->rt_gateway); - printf("(%d)%x %x %x %x %x %x %x ", - sin->sin_family, - s[0], s[1], s[2], s[3], s[4], s[5], s[6]); - } + { + register u_short *s = ((u_short *)sa->sa_data), + *slim = ((sa->sa_len + 1)/2) + s; + + cp = workbuf; + cplim = cp + sizeof(workbuf) - 6; + cp += sprintf(cp, "(%d)", sa->sa_family); + while (s < slim && cp < cplim) + cp += sprintf(cp, "%x ", *s++); + cp = workbuf; + } } - for (flags = name, p = bits; p->b_mask; p++) - if (p->b_mask & rt->rt_flags) + printf(format, cp); +} + +p_flags(f, format) +register int f; +char *format; +{ + char name[33], *flags; + register struct bits *p = bits; + for (flags = name; p->b_mask; p++) + if (p->b_mask & f) *flags++ = p->b_val; *flags = '\0'; - printf("%-6.6s %6d %8d ", name, - rt->rt_refcnt, rt->rt_use); + printf(format, name); +} + +p_rtentry(rt) +register struct rtentry *rt; +{ + char name[16]; + register struct sockaddr *sa; + struct ifnet ifnet; + + p_sockaddr(kgetsa(rt_key(rt)), rt->rt_flags, "%-16.16s "); + p_sockaddr(kgetsa(rt->rt_gateway), 0, "%-18.18s ");; + p_flags(rt->rt_flags, "%-6.6s "); + printf("%6d %8d ", rt->rt_refcnt, rt->rt_use); if (rt->rt_ifp == 0) { putchar('\n'); return; @@ -245,41 +321,10 @@ register struct ortentry *rt; register struct sockaddr_in *sin; struct ifnet ifnet; - switch(rt->rt_dst.sa_family) { - case AF_INET: - sin = (struct sockaddr_in *)&rt->rt_dst; - printf("%-16.16s ", - (sin->sin_addr.s_addr == 0) ? "default" : - (rt->rt_flags & RTF_HOST) ? - routename(sin->sin_addr) : - netname(sin->sin_addr, 0L)); - sin = (struct sockaddr_in *)&rt->rt_gateway; - printf("%-18.18s ", routename(sin->sin_addr)); - break; - case AF_NS: - printf("%-16s ", - ns_print((struct sockaddr_ns *)&rt->rt_dst)); - printf("%-18s ", - ns_print((struct sockaddr_ns *)&rt->rt_gateway)); - break; - default: - { - u_short *s = (u_short *)rt->rt_dst.sa_data; - printf("(%d)%x %x %x %x %x %x %x ", - rt->rt_dst.sa_family, - s[0], s[1], s[2], s[3], s[4], s[5], s[6]); - s = (u_short *)rt->rt_gateway.sa_data; - printf("(%d)%x %x %x %x %x %x %x ", - rt->rt_gateway.sa_family, - s[0], s[1], s[2], s[3], s[4], s[5], s[6]); - } - } - for (flags = name, p = bits; p->b_mask; p++) - if (p->b_mask & rt->rt_flags) - *flags++ = p->b_val; - *flags = '\0'; - printf("%-6.6s %6d %8d ", name, - rt->rt_refcnt, rt->rt_use); + p_sockaddr(&rt->rt_dst, rt->rt_flags, "%-16.16s "); + p_sockaddr(&rt->rt_gateway, 0, "%-18.18s "); + p_flags(rt->rt_flags, "%-6.6s "); + printf("%6d %8d ", rt->rt_refcnt, rt->rt_use); if (rt->rt_ifp == 0) { putchar('\n'); return;