Simplify kvm symbol resolution and error handling. The symbol table

nl_symbols will eventually be organized into several modules depending
on MK_* variables.
This commit is contained in:
Hiroki Sato 2015-09-02 18:51:36 +00:00
parent a261e36179
commit 81dacd8beb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287407
8 changed files with 151 additions and 241 deletions

View File

@ -4,9 +4,32 @@
.include <src.opts.mk>
PROG= netstat
SRCS= if.c inet.c main.c mbuf.c mroute.c netisr.c route.c \
SRCS= if.c inet.c main.c mbuf.c mroute.c netisr.c nl_symbols.c route.c \
unix.c mroute6.c ipsec.c bpf.c pfkey.c sctp.c \
flowtable.c
DPSRCS= nl_defs.h
nl_symbols.c: nlist_symbols
awk '\
BEGIN { \
print "#include <sys/param.h>"; \
print "#include <nlist.h>"; \
print "struct nlist nl[] = {"; \
} \
!/^\#/ { printf("\t{ .n_name = \"%s\" },\n", $$2); } \
END { print "\t{ .n_name = NULL },\n};" } \
' < ${.ALLSRC} > ${.TARGET} || rm -f ${.TARGET}
nl_defs.h: nlist_symbols
awk '\
BEGIN { \
print "#include <nlist.h>"; \
print "extern struct nlist nl[];"; \
i = 0; \
} \
!/^\#/ { printf("\#define\tN%s\t%s\n", toupper($$2), i++); }' \
< ${.ALLSRC} > ${.TARGET} || rm -f ${.TARGET}
CLEANFILES+= nl_symbols.c nl_defs.h
CFLAGS+= -I${.OBJDIR}
WARNS?= 3
CFLAGS+=-fno-strict-aliasing

View File

@ -28,7 +28,7 @@
*/
#ifndef lint
char const copyright[] =
static char const copyright[] =
"@(#) Copyright (c) 1983, 1988, 1993\n\
Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
@ -69,95 +69,10 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include "netstat.h"
#include "nl_defs.h"
#include <libxo/xo.h>
static struct nlist nl[] = {
#define N_RTSTAT 0
{ .n_name = "_rtstat" },
#define N_RTREE 1
{ .n_name = "_rt_tables"},
#define N_MRTSTAT 2
{ .n_name = "_mrtstat" },
#define N_MFCHASHTBL 3
{ .n_name = "_mfchashtbl" },
#define N_VIFTABLE 4
{ .n_name = "_viftable" },
#define N_NGSOCKS 5
{ .n_name = "_ngsocklist"},
#define N_IP6STAT 6
{ .n_name = "_ip6stat" },
#define N_ICMP6STAT 7
{ .n_name = "_icmp6stat" },
#define N_IPSECSTAT 8
{ .n_name = "_ipsec4stat" },
#define N_IPSEC6STAT 9
{ .n_name = "_ipsec6stat" },
#define N_PIM6STAT 10
{ .n_name = "_pim6stat" },
#define N_MRT6STAT 11
{ .n_name = "_mrt6stat" },
#define N_MF6CTABLE 12
{ .n_name = "_mf6ctable" },
#define N_MIF6TABLE 13
{ .n_name = "_mif6table" },
#define N_PFKEYSTAT 14
{ .n_name = "_pfkeystat" },
#define N_RTTRASH 15
{ .n_name = "_rttrash" },
#define N_CARPSTAT 16
{ .n_name = "_carpstats" },
#define N_PFSYNCSTAT 17
{ .n_name = "_pfsyncstats" },
#define N_AHSTAT 18
{ .n_name = "_ahstat" },
#define N_ESPSTAT 19
{ .n_name = "_espstat" },
#define N_IPCOMPSTAT 20
{ .n_name = "_ipcompstat" },
#define N_TCPSTAT 21
{ .n_name = "_tcpstat" },
#define N_UDPSTAT 22
{ .n_name = "_udpstat" },
#define N_IPSTAT 23
{ .n_name = "_ipstat" },
#define N_ICMPSTAT 24
{ .n_name = "_icmpstat" },
#define N_IGMPSTAT 25
{ .n_name = "_igmpstat" },
#define N_PIMSTAT 26
{ .n_name = "_pimstat" },
#define N_TCBINFO 27
{ .n_name = "_tcbinfo" },
#define N_UDBINFO 28
{ .n_name = "_udbinfo" },
#define N_DIVCBINFO 29
{ .n_name = "_divcbinfo" },
#define N_RIPCBINFO 30
{ .n_name = "_ripcbinfo" },
#define N_UNP_COUNT 31
{ .n_name = "_unp_count" },
#define N_UNP_GENCNT 32
{ .n_name = "_unp_gencnt" },
#define N_UNP_DHEAD 33
{ .n_name = "_unp_dhead" },
#define N_UNP_SHEAD 34
{ .n_name = "_unp_shead" },
#define N_RIP6STAT 36
{ .n_name = "_rip6stat" },
#define N_SCTPSTAT 36
{ .n_name = "_sctpstat" },
#define N_MFCTABLESIZE 37
{ .n_name = "_mfctablesize" },
#define N_ARPSTAT 38
{ .n_name = "_arpstat" },
#define N_UNP_SPHEAD 39
{ .n_name = "unp_sphead" },
#define N_SFSTAT 40
{ .n_name = "_sfstat"},
{ .n_name = NULL },
};
struct protox {
static struct protox {
int pr_index; /* index into nlist of cb head */
int pr_sindex; /* index into nlist of stat block */
u_char pr_wanted; /* 1 if wanted, 0 otherwise */
@ -191,7 +106,7 @@ struct protox {
{ N_RIPCBINFO, N_IGMPSTAT, 1, protopr,
igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP },
#ifdef IPSEC
{ -1, N_IPSECSTAT, 1, NULL, /* keep as compat */
{ -1, N_IPSEC4STAT, 1, NULL, /* keep as compat */
ipsec_stats, NULL, "ipsec", 0, 0},
{ -1, N_AHSTAT, 1, NULL,
ah_stats, NULL, "ah", 0, 0},
@ -202,10 +117,10 @@ struct protox {
#endif
{ N_RIPCBINFO, N_PIMSTAT, 1, protopr,
pim_stats, NULL, "pim", 1, IPPROTO_PIM },
{ -1, N_CARPSTAT, 1, NULL,
{ -1, N_CARPSTATS, 1, NULL,
carp_stats, NULL, "carp", 1, 0 },
#ifdef PF
{ -1, N_PFSYNCSTAT, 1, NULL,
{ -1, N_PFSYNCSTATS, 1, NULL,
pfsync_stats, NULL, "pfsync", 1, 0 },
#endif
{ -1, N_ARPSTAT, 1, NULL,
@ -215,7 +130,7 @@ struct protox {
};
#ifdef INET6
struct protox ip6protox[] = {
static struct protox ip6protox[] = {
{ N_TCBINFO, N_TCPSTAT, 1, protopr,
tcp_stats, NULL, "tcp", 1, IPPROTO_TCP },
{ N_UDBINFO, N_UDPSTAT, 1, protopr,
@ -244,7 +159,7 @@ struct protox ip6protox[] = {
#endif /*INET6*/
#ifdef IPSEC
struct protox pfkeyprotox[] = {
static struct protox pfkeyprotox[] = {
{ -1, N_PFKEYSTAT, 1, NULL,
pfkey_stats, NULL, "pfkey", 0, 0 },
{ -1, -1, 0, NULL,
@ -253,17 +168,17 @@ struct protox pfkeyprotox[] = {
#endif
#ifdef NETGRAPH
struct protox netgraphprotox[] = {
{ N_NGSOCKS, -1, 1, netgraphprotopr,
static struct protox netgraphprotox[] = {
{ N_NGSOCKLIST, -1, 1, netgraphprotopr,
NULL, NULL, "ctrl", 0, 0 },
{ N_NGSOCKS, -1, 1, netgraphprotopr,
{ N_NGSOCKLIST, -1, 1, netgraphprotopr,
NULL, NULL, "data", 0, 0 },
{ -1, -1, 0, NULL,
NULL, NULL, NULL, 0, 0 }
};
#endif
struct protox *protoprotox[] = {
static struct protox *protoprotox[] = {
protox,
#ifdef INET6
ip6protox,
@ -278,12 +193,14 @@ static void usage(void);
static struct protox *name2protox(const char *);
static struct protox *knownname(const char *);
static int kresolve_list(struct nlist *_nl);
static kvm_t *kvmd;
static char *nlistf = NULL, *memf = NULL;
int Aflag; /* show addresses of protocol control block */
int aflag; /* show all sockets (including servers) */
int Bflag; /* show information about bpf consumers */
static int Bflag; /* show information about bpf consumers */
int bflag; /* show i/f total bytes in/out */
int dflag; /* show i/f dropped packets */
int gflag; /* show group (multicast) routing or stats */
@ -295,7 +212,7 @@ int noutputs = 0; /* how much outputs before we exit */
int numeric_addr; /* show addresses numerically */
int numeric_port; /* show ports numerically */
static int pflag; /* show given protocol */
int Qflag; /* show netisr information */
static int Qflag; /* show netisr information */
int rflag; /* show routing tables (or routing stats) */
int Rflag; /* show flow / RSS statistics */
int sflag; /* show protocol statistics */
@ -309,7 +226,7 @@ int interval; /* repeat interval for i/f stats */
char *interface; /* desired i/f for stats, or NULL for all i/fs */
int unit; /* unit number for above */
int af; /* address family */
static int af; /* address family */
int live; /* true if we are examining a live system */
int
@ -526,9 +443,9 @@ main(int argc, char *argv[])
if (Qflag) {
if (!live) {
if (kread(0, NULL, 0) == 0)
netisr_stats(kvmd);
netisr_stats();
} else
netisr_stats(NULL);
netisr_stats();
xo_finish();
exit(0);
}
@ -721,7 +638,7 @@ kvmd_init(void)
/*
* Resolve symbol list, return 0 on success.
*/
int
static int
kresolve_list(struct nlist *_nl)
{
@ -742,6 +659,22 @@ kresolve_list(struct nlist *_nl)
return (0);
}
/*
* Wrapper of kvm_dpcpu_setcpu().
*/
void
kset_dpcpu(u_int cpuid)
{
if ((kvmd == NULL) && (kvmd_init() != 0))
xo_errx(-1, "%s: kvm is not available", __func__);
if (kvm_dpcpu_setcpu(kvmd, cpuid) < 0)
xo_errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__,
cpuid, kvm_geterr(kvmd));
return;
}
/*
* Read kernel memory, return 0 on success.
*/

View File

@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$");
#undef _KERNEL
#include <err.h>
#include <nlist.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -73,21 +72,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <libxo/xo.h>
#include "netstat.h"
/*
* kvm(3) bindings for every needed symbol
*/
static struct nlist mrl[] = {
#define N_MRTSTAT 0
{ .n_name = "_mrtstat" },
#define N_MFCHASHTBL 1
{ .n_name = "_mfchashtbl" },
#define N_VIFTABLE 2
{ .n_name = "_viftable" },
#define N_MFCTABLESIZE 3
{ .n_name = "_mfctablesize" },
{ .n_name = NULL },
};
#include "nl_defs.h"
static void print_bw_meter(struct bw_meter *, int *);
static void print_mfc(struct mfc *, int, int *);
@ -280,10 +265,9 @@ mroutepr()
return;
}
} else {
kresolve_list(mrl);
pmfchashtbl = mrl[N_MFCHASHTBL].n_value;
pmfctablesize = mrl[N_MFCTABLESIZE].n_value;
pviftbl = mrl[N_VIFTABLE].n_value;
pmfchashtbl = nl[N_MFCHASHTBL].n_value;
pmfctablesize = nl[N_MFCTABLESIZE].n_value;
pviftbl = nl[N_VIFTABLE].n_value;
if (pmfchashtbl == 0 || pmfctablesize == 0 || pviftbl == 0) {
xo_warnx("No IPv4 MROUTING kernel support.");
@ -418,8 +402,7 @@ mrt_stats()
u_long mstaddr;
size_t len = sizeof(mrtstat);
kresolve_list(mrl);
mstaddr = mrl[N_MRTSTAT].n_value;
mstaddr = nl[N_MRTSTAT].n_value;
if (mstaddr == 0) {
fprintf(stderr, "No IPv4 MROUTING kernel support.\n");

View File

@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <netgraph/ng_socket.h>
#include <netgraph/ng_socketvar.h>
#include <nlist.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>

View File

@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <net/netisr_internal.h>
#include <err.h>
#include <kvm.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -50,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <libxo/xo.h>
#include "netstat.h"
#include "nl_defs.h"
/*
* Print statistics for the kernel netisr subsystem.
@ -102,41 +102,18 @@ netisr_dispatch_policy_to_string(u_int policy, char *buf,
snprintf(buf, buflen, "%s", str);
}
static void
netisr_load_kvm_uint(kvm_t *kd, const char *name, u_int *p)
{
struct nlist nl[] = {
{ .n_name = name },
{ .n_name = NULL },
};
int ret;
ret = kvm_nlist(kd, nl);
if (ret < 0)
xo_errx(-1, "%s: kvm_nlist(%s): %s", __func__, name,
kvm_geterr(kd));
if (ret != 0)
xo_errx(-1, "%s: kvm_nlist(%s): unresolved symbol", __func__,
name);
if (kvm_read(kd, nl[0].n_value, p, sizeof(*p)) != sizeof(*p))
xo_errx(-1, "%s: kvm_read(%s): %s", __func__, name,
kvm_geterr(kd));
}
/*
* Load a nul-terminated string from KVM up to 'limit', guarantee that the
* string in local memory is nul-terminated.
*/
static void
netisr_load_kvm_string(kvm_t *kd, uintptr_t addr, char *dest, u_int limit)
netisr_load_kvm_string(uintptr_t addr, char *dest, u_int limit)
{
u_int i;
for (i = 0; i < limit; i++) {
if (kvm_read(kd, addr + i, &dest[i], sizeof(dest[i])) !=
sizeof(dest[i]))
xo_err(-1, "%s: kvm_read: %s", __func__,
kvm_geterr(kd));
if (kread(addr + i, &dest[i], sizeof(dest[i])) != 0)
xo_errx(-1, "%s: kread()", __func__);
if (dest[i] == '\0')
break;
}
@ -168,18 +145,18 @@ netisr_protoispresent(u_int proto)
}
static void
netisr_load_kvm_config(kvm_t *kd)
netisr_load_kvm_config(void)
{
u_int tmp;
netisr_load_kvm_uint(kd, "_netisr_bindthreads", &bindthreads);
netisr_load_kvm_uint(kd, "_netisr_maxthreads", &maxthreads);
netisr_load_kvm_uint(kd, "_nws_count", &numthreads);
kread(nl[N_NETISR_BINDTHREADS].n_value, &bindthreads, sizeof(u_int));
kread(nl[N_NETISR_MAXTHREADS].n_value, &maxthreads, sizeof(u_int));
kread(nl[N_NWS_COUNT].n_value, &numthreads, sizeof(u_int));
kread(nl[N_NETISR_DEFAULTQLIMIT].n_value, &defaultqlimit,
sizeof(u_int));
kread(nl[N_NETISR_MAXQLIMIT].n_value, &maxqlimit, sizeof(u_int));
kread(nl[N_NETISR_DISPATCH_POLICY].n_value, &tmp, sizeof(u_int));
netisr_load_kvm_uint(kd, "_netisr_defaultqlimit", &defaultqlimit);
netisr_load_kvm_uint(kd, "_netisr_maxqlimit", &maxqlimit);
netisr_load_kvm_uint(kd, "_netisr_dispatch_policy", &tmp);
netisr_dispatch_policy_to_string(tmp, dispatch_policy,
sizeof(dispatch_policy));
}
@ -223,41 +200,26 @@ netisr_load_sysctl_config(void)
}
static void
netisr_load_kvm_proto(kvm_t *kd)
netisr_load_kvm_proto(void)
{
struct nlist nl[] = {
#define NLIST_NETISR_PROTO 0
{ .n_name = "_netisr_proto" },
{ .n_name = NULL },
};
struct netisr_proto *np_array, *npp;
u_int i, protocount;
struct sysctl_netisr_proto *snpp;
size_t len;
int ret;
/*
* Kernel compile-time and user compile-time definitions of
* NETISR_MAXPROT must match, as we use that to size work arrays.
*/
netisr_load_kvm_uint(kd, "_netisr_maxprot", &maxprot);
kread(nl[N_NETISR_MAXPROT].n_value, &maxprot, sizeof(u_int));
if (maxprot != NETISR_MAXPROT)
xo_errx(-1, "%s: NETISR_MAXPROT mismatch", __func__);
len = maxprot * sizeof(*np_array);
np_array = malloc(len);
if (np_array == NULL)
xo_err(-1, "%s: malloc", __func__);
ret = kvm_nlist(kd, nl);
if (ret < 0)
xo_errx(-1, "%s: kvm_nlist(_netisr_proto): %s", __func__,
kvm_geterr(kd));
if (ret != 0)
xo_errx(-1, "%s: kvm_nlist(_netisr_proto): unresolved symbol",
__func__);
if (kvm_read(kd, nl[NLIST_NETISR_PROTO].n_value, np_array, len) !=
(ssize_t)len)
xo_errx(-1, "%s: kvm_read(_netisr_proto): %s", __func__,
kvm_geterr(kd));
if (kread(nl[N_NETISR_PROTO].n_value, np_array, len) != 0)
xo_errx(-1, "%s: kread(_netisr_proto)", __func__);
/*
* Size and allocate memory to hold only live protocols.
@ -278,7 +240,7 @@ netisr_load_kvm_proto(kvm_t *kd)
continue;
snpp = &proto_array[protocount];
snpp->snp_version = sizeof(*snpp);
netisr_load_kvm_string(kd, (uintptr_t)npp->np_name,
netisr_load_kvm_string((uintptr_t)npp->np_name,
snpp->snp_name, sizeof(snpp->snp_name));
snpp->snp_proto = i;
snpp->snp_qlimit = npp->np_qlimit;
@ -320,35 +282,21 @@ netisr_load_sysctl_proto(void)
}
static void
netisr_load_kvm_workstream(kvm_t *kd)
netisr_load_kvm_workstream(void)
{
struct nlist nl[] = {
#define NLIST_NWS_ARRAY 0
{ .n_name = "_nws_array" },
{ .n_name = NULL },
};
struct netisr_workstream nws;
struct sysctl_netisr_workstream *snwsp;
struct sysctl_netisr_work *snwp;
struct netisr_work *nwp;
struct nlist nl_nws[2];
u_int counter, cpuid, proto, wsid;
size_t len;
int ret;
len = numthreads * sizeof(*nws_array);
nws_array = malloc(len);
if (nws_array == NULL)
xo_err(-1, "malloc");
ret = kvm_nlist(kd, nl);
if (ret < 0)
xo_errx(-1, "%s: kvm_nlist: %s", __func__, kvm_geterr(kd));
if (ret != 0)
xo_errx(-1, "%s: kvm_nlist: unresolved symbol", __func__);
if (kvm_read(kd, nl[NLIST_NWS_ARRAY].n_value, nws_array, len) !=
(ssize_t)len)
xo_errx(-1, "%s: kvm_read(_nws_array): %s", __func__,
kvm_geterr(kd));
if (kread(nl[N_NWS_ARRAY].n_value, nws_array, len) != 0)
xo_errx(-1, "%s: kread(_nws_array)", __func__);
workstream_array = calloc(numthreads, sizeof(*workstream_array));
if (workstream_array == NULL)
xo_err(-1, "calloc");
@ -359,22 +307,9 @@ netisr_load_kvm_workstream(kvm_t *kd)
counter = 0;
for (wsid = 0; wsid < numthreads; wsid++) {
cpuid = nws_array[wsid];
if (kvm_dpcpu_setcpu(kd, cpuid) < 0)
xo_errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__,
cpuid, kvm_geterr(kd));
bzero(nl_nws, sizeof(nl_nws));
nl_nws[0].n_name = "_nws";
ret = kvm_nlist(kd, nl_nws);
if (ret < 0)
xo_errx(-1, "%s: kvm_nlist looking up nws on CPU "
"%u: %s", __func__, cpuid, kvm_geterr(kd));
if (ret != 0)
xo_errx(-1, "%s: kvm_nlist(nws): unresolved symbol on "
"CPU %u", __func__, cpuid);
if (kvm_read(kd, nl_nws[0].n_value, &nws, sizeof(nws)) !=
sizeof(nws))
xo_errx(-1, "%s: kvm_read(nw): %s", __func__,
kvm_geterr(kd));
kset_dpcpu(cpuid);
if (kread(nl[N_NWS].n_value, &nws, sizeof(nws)) != 0)
xo_errx(-1, "%s: kread(nw)", __func__);
snwsp = &workstream_array[wsid];
snwsp->snws_version = sizeof(*snwsp);
snwsp->snws_wsid = cpuid;
@ -507,11 +442,10 @@ netisr_print_workstream(struct sysctl_netisr_workstream *snwsp)
}
void
netisr_stats(void *kvmd)
netisr_stats(void)
{
struct sysctl_netisr_workstream *snwsp;
struct sysctl_netisr_proto *snpp;
kvm_t *kd = kvmd;
u_int i;
if (live) {
@ -520,11 +454,9 @@ netisr_stats(void *kvmd)
netisr_load_sysctl_workstream();
netisr_load_sysctl_work();
} else {
if (kd == NULL)
xo_errx(-1, "netisr_stats: !live but !kd");
netisr_load_kvm_config(kd);
netisr_load_kvm_proto(kd);
netisr_load_kvm_workstream(kd); /* Also does work. */
netisr_load_kvm_config();
netisr_load_kvm_proto();
netisr_load_kvm_workstream(); /* Also does work. */
}
xo_open_container("netisr");

View File

@ -63,11 +63,10 @@ extern int unit; /* unit number for above */
extern int live; /* true if we are examining a live system */
struct nlist;
int kread(u_long addr, void *buf, size_t size);
uint64_t kread_counter(u_long addr);
int kread_counters(u_long addr, void *buf, size_t size);
int kresolve_list(struct nlist *);
void kset_dpcpu(u_int);
const char *plural(uintmax_t);
const char *plurales(uintmax_t);
const char *pluralies(uintmax_t);
@ -119,7 +118,7 @@ void pfkey_stats(u_long, const char *, int, int);
void mbpr(void *, u_long);
void netisr_stats(void *);
void netisr_stats(void);
void hostpr(u_long, u_long);
void impstats(u_long, u_long);

View File

@ -0,0 +1,54 @@
# $FreeBSD$
#
# module_name symbol_name
all _ahstat
all _arpstat
all _carpstats
all _divcbinfo
all _espstat
all _icmp6stat
all _icmpstat
all _igmpstat
all _ip6stat
all _ipcompstat
all _ipsec4stat
all _ipsec6stat
all _ipstat
all _mf6ctable
all _mfchashtbl
all _mfctablesize
all _mif6table
all _mrt6stat
all _mrtstat
all _netisr_bindthreads
all _netisr_defaultqlimit
all _netisr_dispatch_policy
all _netisr_maxprot
all _netisr_maxqlimit
all _netisr_maxthreads
all _netisr_proto
all _ngsocklist
all _nws
all _nws_array
all _nws_count
all _pfkeystat
all _pfsyncstats
all _pim6stat
all _pimstat
all _rip6stat
all _ripcbinfo
all _rtree
all _rtstat
all _rttrash
all _sctpstat
all _sfstat
all _tcbinfo
all _tcpstat
all _udbinfo
all _udpstat
all _unp_count
all _unp_dhead
all _unp_gencnt
all _unp_shead
all _unp_sphead
all _viftable

View File

@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
#include <ifaddrs.h>
#include <libutil.h>
#include <netdb.h>
#include <nlist.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -67,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <libxo/xo.h>
#include "netstat.h"
#include "nl_defs.h"
/*
* Definitions for showing gateway flags.
@ -96,17 +96,6 @@ static struct bits {
{ 0 , 0, NULL }
};
/*
* kvm(3) bindings for every needed symbol
*/
static struct nlist rl[] = {
#define N_RTSTAT 0
{ .n_name = "_rtstat" },
#define N_RTTRASH 1
{ .n_name = "_rttrash" },
{ .n_name = NULL },
};
struct ifmap_entry {
char ifname[IFNAMSIZ];
};
@ -745,13 +734,11 @@ rt_stats(void)
u_long rtsaddr, rttaddr;
int rttrash;
kresolve_list(rl);
if ((rtsaddr = rl[N_RTSTAT].n_value) == 0) {
if ((rtsaddr = nl[N_RTSTAT].n_value) == 0) {
xo_emit("{W:rtstat: symbol not in namelist}\n");
return;
}
if ((rttaddr = rl[N_RTTRASH].n_value) == 0) {
if ((rttaddr = nl[N_RTTRASH].n_value) == 0) {
xo_emit("{W:rttrash: symbol not in namelist}\n");
return;
}