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:
parent
a261e36179
commit
81dacd8beb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287407
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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");
|
||||
|
@ -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>
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
54
usr.bin/netstat/nlist_symbols
Normal file
54
usr.bin/netstat/nlist_symbols
Normal 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
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user