summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2015-04-07 05:50:45 +0000
committerglebius <glebius@FreeBSD.org>2015-04-07 05:50:45 +0000
commit70540f5f7b429cf049c10870a997477bed109a51 (patch)
tree6058e0d373882170fe0ea38ca85755a6a1e2ab4c
parentfa9eb8e1eac476efbef9a03cedb44dd3c3f36521 (diff)
downloadFreeBSD-src-70540f5f7b429cf049c10870a997477bed109a51.zip
FreeBSD-src-70540f5f7b429cf049c10870a997477bed109a51.tar.gz
Like it was already done for 'netstat -i', drop the kvm(3) support
in 'netstat -r'. The netstat/route.c was the last abuser of struct ifnet and struct rtentry in the tree. With this change if_var.h can become kernel only include, _WANT_RTENTRY can go away and projects/ifnet and projects/routing can go forward. Differential Revision: https://reviews.freebsd.org/D2242 Reviewed by: melifaro, gnn Sponsored by: Nginx, Inc. Sponsored by: Netflix
-rw-r--r--usr.bin/netstat/netstat.17
-rw-r--r--usr.bin/netstat/route.c401
2 files changed, 14 insertions, 394 deletions
diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1
index 69dd25b..c9d3e42 100644
--- a/usr.bin/netstat/netstat.1
+++ b/usr.bin/netstat/netstat.1
@@ -78,11 +78,9 @@
.Op Fl I Ar interface
.It Nm Fl r
.Op Fl -libxo
-.Op Fl 46AnW
+.Op Fl 46nW
.Op Fl F Ar fibnum
.Op Fl f Ar address_family
-.Op Fl M Ar core
-.Op Fl N Ar system
.It Nm Fl rs
.Op Fl -libxo
.Op Fl s
@@ -581,9 +579,6 @@ See
Show IPv6 only.
See
.Sx GENERAL OPTIONS .
-.It Fl A
-Show the contents of the internal Patricia tree
-structures; used for debugging.
.It Fl n
Do not resolve numeric addresses and port numbers to names.
See
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c
index 5ae40b1..676f616 100644
--- a/usr.bin/netstat/route.c
+++ b/usr.bin/netstat/route.c
@@ -40,22 +40,18 @@ __FBSDID("$FreeBSD$");
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/sysctl.h>
#include <sys/time.h>
#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>
-#define _WANT_RTENTRY
#include <net/route.h>
#include <netinet/in.h>
#include <netgraph/ng_socket.h>
-#include <sys/sysctl.h>
-
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <libutil.h>
@@ -72,8 +68,6 @@ __FBSDID("$FreeBSD$");
#include <libxo/xo.h>
#include "netstat.h"
-#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d)))
-
/*
* Definitions for showing gateway flags.
*/
@@ -108,9 +102,7 @@ struct bits {
static struct nlist rl[] = {
#define N_RTSTAT 0
{ .n_name = "_rtstat" },
-#define N_RTREE 1
- { .n_name = "_rt_tables"},
-#define N_RTTRASH 2
+#define N_RTTRASH 1
{ .n_name = "_rttrash" },
{ .n_name = NULL },
};
@@ -121,33 +113,14 @@ typedef union {
u_short u_data[128];
} sa_u;
-static sa_u pt_u;
-
struct ifmap_entry {
char ifname[IFNAMSIZ];
};
-
static struct ifmap_entry *ifmap;
static int ifmap_size;
-
-int do_rtent = 0;
-struct rtentry rtentry;
-struct radix_node rnode;
-struct radix_mask rmask;
-
-int NewTree = 1;
-
struct timespec uptime;
-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_rtnode_kvm(void);
static void p_rtable_sysctl(int, int);
-static void p_rtable_kvm(int, int );
-static void p_rtree_kvm(const char *name, struct radix_node *);
-static void p_rtentry_kvm(const char *name, struct rtentry *);
static void p_rtentry_sysctl(const char *name, struct rt_msghdr *);
static void p_sockaddr(const char *name, struct sockaddr *, struct sockaddr *,
int, int);
@@ -166,6 +139,9 @@ routepr(int fibnum, int af)
size_t intsize;
int numfibs;
+ if (live == 0)
+ return;
+
intsize = sizeof(int);
if (fibnum == -1 &&
sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1)
@@ -187,11 +163,7 @@ routepr(int fibnum, int af)
if (fibnum)
xo_emit(" ({L:fib}: {:fib/%d})", fibnum);
xo_emit("\n");
-
- if (Aflag == 0 && live != 0 && NewTree)
- p_rtable_sysctl(fibnum, af);
- else
- p_rtable_kvm(fibnum, af);
+ p_rtable_sysctl(fibnum, af);
xo_close_container("route-information");
}
@@ -253,100 +225,6 @@ 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_pksent = 8;
- wid_mtu = 6;
- wid_if = WID_IF_DEFAULT(ef);
- wid_expire = 6;
-
- if (Wflag && rn != NULL)
- size_cols_tree(rn);
-}
-
-static void
-size_cols_tree(struct radix_node *rn)
-{
-again:
- if (kget(rn, rnode) != 0)
- return;
- if (!(rnode.rn_flags & RNF_ACTIVE))
- return;
- if (rnode.rn_bit < 0) {
- if ((rnode.rn_flags & RNF_ROOT) == 0) {
- if (kget(rn, rtentry) != 0)
- return;
- 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;
- static char buffer[100];
- const char *bp;
- struct sockaddr *sa;
- sa_u addr, mask;
- int len;
-
- 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 (Wflag) {
- len = snprintf(buffer, sizeof(buffer), "%ju",
- (uintmax_t )kread_counter((u_long )rt->rt_pksent));
- wid_pksent = MAX(len, wid_pksent);
- }
- if (rt->rt_ifp) {
- if (rt->rt_ifp != lastif) {
- if (kget(rt->rt_ifp, ifnet) == 0)
- len = strlen(ifnet.if_xname);
- else
- len = strlen("---");
- lastif = rt->rt_ifp;
- wid_if = MAX(len, wid_if);
- }
- if (rt->rt_expire) {
- time_t expire_time;
-
- if ((expire_time =
- rt->rt_expire - uptime.tv_sec) > 0) {
- len = snprintf(buffer, sizeof(buffer), "%d",
- (int)expire_time);
- wid_expire = MAX(len, wid_expire);
- }
- }
- }
-}
-
-
/*
* Print header for routing table columns.
*/
@@ -377,210 +255,6 @@ pr_rthdr(int af1)
}
}
-static struct sockaddr *
-kgetsa(struct sockaddr *dst)
-{
-
- if (kget(dst, pt_u.u_sa) != 0)
- return (NULL);
- 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);
-}
-
-/*
- * Print kernel routing tables for given fib
- * using debugging kvm(3) interface.
- */
-static void
-p_rtable_kvm(int fibnum, int af)
-{
- struct radix_node_head **rnhp, *rnh, head;
- struct radix_node_head **rt_tables;
- u_long rtree;
- int fam, af_size;
- bool did_rt_family = false;
-
- kresolve_list(rl);
- if ((rtree = rl[N_RTREE].n_value) == 0) {
- xo_emit("rt_tables: symbol not in namelist\n");
- return;
- }
-
- af_size = (AF_MAX + 1) * sizeof(struct radix_node_head *);
- rt_tables = calloc(1, af_size);
- if (rt_tables == NULL)
- err(EX_OSERR, "memory allocation failed");
-
- if (kread((u_long)(rtree), (char *)(rt_tables) + fibnum * af_size,
- af_size) != 0)
- err(EX_OSERR, "error retrieving radix pointers");
- xo_open_container("route-table");
- for (fam = 0; fam <= AF_MAX; fam++) {
- int tmpfib;
-
- switch (fam) {
- case AF_INET6:
- case AF_INET:
- tmpfib = fibnum;
- break;
- default:
- tmpfib = 0;
- }
- rnhp = (struct radix_node_head **)*rt_tables;
- /* Calculate the in-kernel address. */
- rnhp += tmpfib * (AF_MAX + 1) + fam;
- /* Read the in kernel rhn pointer. */
- if (kget(rnhp, rnh) != 0)
- continue;
- if (rnh == NULL)
- continue;
- /* Read the rnh data. */
- if (kget(rnh, head) != 0)
- continue;
- if (fam == AF_UNSPEC) {
- if (Aflag && af == 0) {
- xo_emit("{T:Netmasks}:\n");
- xo_open_list("netmasks");
- p_rtree_kvm("netmasks", head.rnh_treetop);
- xo_close_list("netmasks");
- }
- } else if (af == AF_UNSPEC || af == fam) {
- if (!did_rt_family) {
- xo_open_list("rt-family");
- did_rt_family = true;
- }
- size_cols(fam, head.rnh_treetop);
- xo_open_instance("rt-family");
- pr_family(fam);
- do_rtent = 1;
- xo_open_list("rt-entry");
- pr_rthdr(fam);
- p_rtree_kvm("rt-entry", head.rnh_treetop);
- xo_close_list("rt-entry");
- xo_close_instance("rt-family");
- }
- }
- if (did_rt_family)
- xo_close_list("rt-family");
- xo_close_container("route-table");
-
- free(rt_tables);
-}
-
-/*
- * Print given kernel radix tree using
- * debugging kvm(3) interface.
- */
-static void
-p_rtree_kvm(const char *name, struct radix_node *rn)
-{
- bool opened;
-
- opened = false;
-
-#define DOOPEN() do { \
- if (!opened) { xo_open_instance(name); opened = true; } \
- } while (0)
-#define DOCLOSE() do { \
- if (opened) { opened = false; xo_close_instance(name); } \
- } while(0)
-
-again:
- if (kget(rn, rnode) != 0)
- return;
- if (!(rnode.rn_flags & RNF_ACTIVE))
- return;
- if (rnode.rn_bit < 0) {
- if (Aflag) {
- DOOPEN();
- xo_emit("{q:radix-node/%-8.8lx} ", (u_long)rn);
- }
- if (rnode.rn_flags & RNF_ROOT) {
- if (Aflag) {
- DOOPEN();
- xo_emit("({:root/root} node){L:/%s}",
- rnode.rn_dupedkey ? " =>\n" : "\n");
- }
- } else if (do_rtent) {
- if (kget(rn, rtentry) == 0) {
- DOOPEN();
- p_rtentry_kvm(name, &rtentry);
- if (Aflag) {
- DOOPEN();
- p_rtnode_kvm();
- DOCLOSE();
- }
- }
- } else {
- DOOPEN();
- p_sockaddr("address",
- kgetsa((struct sockaddr *)rnode.rn_key),
- NULL, 0, 44);
- xo_emit("\n");
- }
- DOCLOSE();
- if ((rn = rnode.rn_dupedkey))
- goto again;
- } else {
- if (Aflag && do_rtent) {
- DOOPEN();
- xo_emit("{q:radix-node/%-8.8lx} ", (u_long)rn);
- p_rtnode_kvm();
- DOCLOSE();
- }
- rn = rnode.rn_right;
- p_rtree_kvm(name, rnode.rn_left);
- p_rtree_kvm(name, rn);
- }
-}
-
-char nbuf[20];
-
-static void
-p_rtnode_kvm(void)
-{
- struct radix_mask *rm = rnode.rn_mklist;
-
- if (rnode.rn_bit < 0) {
- if (rnode.rn_mask) {
- xo_emit("\t {L:mask} ");
- p_sockaddr("netmask",
- kgetsa((struct sockaddr *)rnode.rn_mask),
- NULL, 0, -1);
- } else if (rm == 0)
- return;
- } else {
- xo_emit("{[:6}{:bit/(%d)}{]:} {q:left-node/%8.8lx} "
- ": {q:right-node/%8.8lx}", rnode.rn_bit,
- (u_long)rnode.rn_left, (u_long)rnode.rn_right);
- }
- while (rm) {
- if (kget(rm, rmask) != 0)
- break;
- sprintf(nbuf, " %d refs, ", rmask.rm_refs);
- xo_emit(" mk = {q:node/%8.8lx} \\{({:bit/%d}),{nbufs/%s}",
- (u_long)rm, -1 - rmask.rm_bit, rmask.rm_refs ? nbuf : " ");
- if (rmask.rm_flags & RNF_NORMAL) {
- struct radix_node rnode_aux;
- xo_emit(" <{:mode/normal}>, ");
- if (kget(rmask.rm_leaf, rnode_aux) == 0)
- p_sockaddr("netmask",
- kgetsa(/*XXX*/(void *)rnode_aux.rn_mask),
- NULL, 0, -1);
- else
- p_sockaddr(NULL, NULL, NULL, 0, -1);
- } else
- p_sockaddr("netmask",
- kgetsa((struct sockaddr *)rmask.rm_mask),
- NULL, 0, -1);
- xo_emit("\\}");
- if ((rm = rmask.rm_mklist))
- xo_emit(" {D:->}");
- }
- xo_emit("\n");
-}
-
static void
p_rtable_sysctl(int fibnum, int af)
{
@@ -664,7 +338,13 @@ p_rtable_sysctl(int fibnum, int af)
need_table_close = true;
fam = sa->sa_family;
- size_cols(fam, NULL);
+ wid_dst = WID_DST_DEFAULT(fam);
+ wid_gw = WID_GW_DEFAULT(fam);
+ wid_flags = 6;
+ wid_pksent = 8;
+ wid_mtu = 6;
+ wid_if = WID_IF_DEFAULT(fam);
+ wid_expire = 6;
xo_open_instance("rt-family");
pr_family(fam);
xo_open_list("rt-entry");
@@ -905,61 +585,6 @@ fmt_flags(int f)
return (name);
}
-static void
-p_rtentry_kvm(const char *name, struct rtentry *rt)
-{
- static struct ifnet ifnet, *lastif;
- static char buffer[128];
- static char prettyname[128];
- struct sockaddr *sa;
- sa_u addr, mask;
-
- 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("destination", &addr.u_sa, &mask.u_sa, rt->rt_flags,
- wid_dst);
- p_sockaddr("gateway", kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw);
- snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:}",
- wid_flags);
- p_flags(rt->rt_flags, buffer);
- if (Wflag) {
- xo_emit("{[:%d}{t:use/%ju}{]:} ", -wid_pksent,
- (uintmax_t )kread_counter((u_long )rt->rt_pksent));
-
- if (rt->rt_mtu != 0)
- xo_emit("{t:mtu/%*lu} ", wid_mtu, rt->rt_mtu);
- else
- xo_emit("{P:/%*s} ", wid_mtu, "");
- }
- if (rt->rt_ifp) {
- if (rt->rt_ifp != lastif) {
- if (kget(rt->rt_ifp, ifnet) == 0)
- strlcpy(prettyname, ifnet.if_xname,
- sizeof(prettyname));
- else
- strlcpy(prettyname, "---", sizeof(prettyname));
- lastif = rt->rt_ifp;
- }
- xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if, prettyname);
- if (rt->rt_expire) {
- time_t expire_time;
-
- if ((expire_time =
- rt->rt_expire - uptime.tv_sec) > 0)
- xo_emit(" {:expire-time/%*d}",
- wid_expire, (int)expire_time);
- }
- if (rt->rt_nodes[0].rn_dupedkey)
- xo_emit(" =>");
- }
- xo_emit("\n");
-}
-
char *
routename(in_addr_t in)
{
OpenPOWER on IntegriCloud