summaryrefslogtreecommitdiffstats
path: root/freebsd/usr.bin/netstat/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/usr.bin/netstat/main.c')
-rw-r--r--freebsd/usr.bin/netstat/main.c684
1 files changed, 371 insertions, 313 deletions
diff --git a/freebsd/usr.bin/netstat/main.c b/freebsd/usr.bin/netstat/main.c
index a1d66376..a58ee648 100644
--- a/freebsd/usr.bin/netstat/main.c
+++ b/freebsd/usr.bin/netstat/main.c
@@ -1,5 +1,9 @@
#include <machine/rtems-bsd-user-space.h>
+#ifdef __rtems__
+#include "rtems-bsd-netstat-namespace.h"
+#endif /* __rtems__ */
+
/*-
* Copyright (c) 1983, 1988, 1993
* Regents of the University of California. All rights reserved.
@@ -30,7 +34,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 */
@@ -44,15 +48,6 @@ static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94";
#ifdef __rtems__
#define __need_getopt_newlib
#include <getopt.h>
-#define RTEMS_BSD_PROGRAM_NO_OPEN_WRAP
-#define RTEMS_BSD_PROGRAM_NO_SOCKET_WRAP
-#define RTEMS_BSD_PROGRAM_NO_CLOSE_WRAP
-#define RTEMS_BSD_PROGRAM_NO_FOPEN_WRAP
-#define RTEMS_BSD_PROGRAM_NO_FCLOSE_WRAP
-#define RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP
-#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP
-#define RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP
-#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP
#include <machine/rtems-bsd-program.h>
#include <machine/rtems-bsd-commands.h>
#endif /* __rtems__ */
@@ -64,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/sysctl.h>
#include <netinet/in.h>
@@ -82,129 +78,21 @@ __FBSDID("$FreeBSD$");
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "netstat.h"
+#include "nl_defs.h"
+#include <libxo/xo.h>
+#ifdef __rtems__
+#include "rtems-bsd-netstat-main-data.h"
+#endif /* __rtems__ */
-static struct nlist nl[] = {
-#define N_IFNET 0
- { .n_name = "_ifnet" },
-#define N_RTSTAT 1
- { .n_name = "_rtstat" },
-#define N_RTREE 2
- { .n_name = "_rt_tables"},
-#define N_MRTSTAT 3
- { .n_name = "_mrtstat" },
-#define N_MFCHASHTBL 4
- { .n_name = "_mfchashtbl" },
-#define N_VIFTABLE 5
- { .n_name = "_viftable" },
-#define N_IPX 6
- { .n_name = "_ipxpcb_list"},
-#define N_IPXSTAT 7
- { .n_name = "_ipxstat"},
-#define N_SPXSTAT 8
- { .n_name = "_spx_istat"},
-#define N_DDPSTAT 9
- { .n_name = "_ddpstat"},
-#define N_DDPCB 10
- { .n_name = "_ddpcb"},
-#define N_NGSOCKS 11
- { .n_name = "_ngsocklist"},
-#define N_IP6STAT 12
- { .n_name = "_ip6stat" },
-#define N_ICMP6STAT 13
- { .n_name = "_icmp6stat" },
-#define N_IPSECSTAT 14
- { .n_name = "_ipsec4stat" },
-#define N_IPSEC6STAT 15
- { .n_name = "_ipsec6stat" },
-#define N_PIM6STAT 16
- { .n_name = "_pim6stat" },
-#define N_MRT6STAT 17
- { .n_name = "_mrt6stat" },
-#define N_MF6CTABLE 18
- { .n_name = "_mf6ctable" },
-#define N_MIF6TABLE 19
- { .n_name = "_mif6table" },
-#define N_PFKEYSTAT 20
- { .n_name = "_pfkeystat" },
-#define N_MBSTAT 21
- { .n_name = "_mbstat" },
-#define N_MBTYPES 22
- { .n_name = "_mbtypes" },
-#define N_NMBCLUSTERS 23
- { .n_name = "_nmbclusters" },
-#define N_NMBUFS 24
- { .n_name = "_nmbufs" },
-#define N_MBHI 25
- { .n_name = "_mbuf_hiwm" },
-#define N_CLHI 26
- { .n_name = "_clust_hiwm" },
-#define N_NCPUS 27
- { .n_name = "_smp_cpus" },
-#define N_PAGESZ 28
- { .n_name = "_pagesize" },
-#define N_MBPSTAT 29
- { .n_name = "_mb_statpcpu" },
-#define N_RTTRASH 30
- { .n_name = "_rttrash" },
-#define N_MBLO 31
- { .n_name = "_mbuf_lowm" },
-#define N_CLLO 32
- { .n_name = "_clust_lowm" },
-#define N_CARPSTAT 33
- { .n_name = "_carpstats" },
-#define N_PFSYNCSTAT 34
- { .n_name = "_pfsyncstats" },
-#define N_AHSTAT 35
- { .n_name = "_ahstat" },
-#define N_ESPSTAT 36
- { .n_name = "_espstat" },
-#define N_IPCOMPSTAT 37
- { .n_name = "_ipcompstat" },
-#define N_TCPSTAT 38
- { .n_name = "_tcpstat" },
-#define N_UDPSTAT 39
- { .n_name = "_udpstat" },
-#define N_IPSTAT 40
- { .n_name = "_ipstat" },
-#define N_ICMPSTAT 41
- { .n_name = "_icmpstat" },
-#define N_IGMPSTAT 42
- { .n_name = "_igmpstat" },
-#define N_PIMSTAT 43
- { .n_name = "_pimstat" },
-#define N_TCBINFO 44
- { .n_name = "_tcbinfo" },
-#define N_UDBINFO 45
- { .n_name = "_udbinfo" },
-#define N_DIVCBINFO 46
- { .n_name = "_divcbinfo" },
-#define N_RIPCBINFO 47
- { .n_name = "_ripcbinfo" },
-#define N_UNP_COUNT 48
- { .n_name = "_unp_count" },
-#define N_UNP_GENCNT 49
- { .n_name = "_unp_gencnt" },
-#define N_UNP_DHEAD 50
- { .n_name = "_unp_dhead" },
-#define N_UNP_SHEAD 51
- { .n_name = "_unp_shead" },
-#define N_RIP6STAT 52
- { .n_name = "_rip6stat" },
-#define N_SCTPSTAT 53
- { .n_name = "_sctpstat" },
-#define N_MFCTABLESIZE 54
- { .n_name = "_mfctablesize" },
-#define N_ARPSTAT 55
- { .n_name = "_arpstat" },
-#define N_UNP_SPHEAD 56
- { .n_name = "unp_sphead" },
- { .n_name = NULL },
-};
-
-struct protox {
+#ifndef __rtems__
+static struct protox {
+#else /* __rtems__ */
+static const struct protox {
+#endif /* __rtems__ */
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 */
@@ -216,7 +104,7 @@ struct protox {
const char *pr_name; /* well-known name */
int pr_usesysctl; /* non-zero if we use sysctl, not kvm */
int pr_protocol;
-} static const protox[] = {
+} protox[] = {
{ N_TCBINFO, N_TCPSTAT, 1, protopr,
tcp_stats, NULL, "tcp", 1, IPPROTO_TCP },
{ N_UDBINFO, N_UDPSTAT, 1, protopr,
@@ -238,21 +126,23 @@ 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 */
- ipsec_stats, NULL, "ipsec", 0, 0},
+ { -1, N_IPSEC4STAT, 1, NULL, /* keep as compat */
+ ipsec_stats, NULL, "ipsec", 1, 0},
{ -1, N_AHSTAT, 1, NULL,
- ah_stats, NULL, "ah", 0, 0},
+ ah_stats, NULL, "ah", 1, 0},
{ -1, N_ESPSTAT, 1, NULL,
- esp_stats, NULL, "esp", 0, 0},
+ esp_stats, NULL, "esp", 1, 0},
{ -1, N_IPCOMPSTAT, 1, NULL,
- ipcomp_stats, NULL, "ipcomp", 0, 0},
+ ipcomp_stats, NULL, "ipcomp", 1, 0},
#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 },
- { -1, N_PFSYNCSTAT, 1, NULL,
+#ifdef PF
+ { -1, N_PFSYNCSTATS, 1, NULL,
pfsync_stats, NULL, "pfsync", 1, 0 },
+#endif
{ -1, N_ARPSTAT, 1, NULL,
arp_stats, NULL, "arp", 1, 0 },
{ -1, -1, 0, NULL,
@@ -260,7 +150,11 @@ struct protox {
};
#ifdef INET6
+#ifndef __rtems__
+static struct protox ip6protox[] = {
+#else /* __rtems__ */
static const struct protox ip6protox[] = {
+#endif /* __rtems__ */
{ N_TCBINFO, N_TCPSTAT, 1, protopr,
tcp_stats, NULL, "tcp", 1, IPPROTO_TCP },
{ N_UDBINFO, N_UDPSTAT, 1, protopr,
@@ -275,7 +169,7 @@ static const struct protox ip6protox[] = {
#endif
#ifdef IPSEC
{ -1, N_IPSEC6STAT, 1, NULL,
- ipsec_stats, NULL, "ipsec6", 0, 0 },
+ ipsec_stats, NULL, "ipsec6", 1, 0 },
#endif
#ifdef notyet
{ -1, N_PIM6STAT, 1, NULL,
@@ -289,7 +183,11 @@ static const struct protox ip6protox[] = {
#endif /*INET6*/
#ifdef IPSEC
+#ifndef __rtems__
+static struct protox pfkeyprotox[] = {
+#else /* __rtems__ */
static const struct protox pfkeyprotox[] = {
+#endif /* __rtems__ */
{ -1, N_PFKEYSTAT, 1, NULL,
pfkey_stats, NULL, "pfkey", 0, 0 },
{ -1, -1, 0, NULL,
@@ -297,36 +195,26 @@ static const struct protox pfkeyprotox[] = {
};
#endif
-#ifndef __rtems__
-static const struct protox atalkprotox[] = {
- { N_DDPCB, N_DDPSTAT, 1, atalkprotopr,
- ddp_stats, NULL, "ddp", 0, 0 },
- { -1, -1, 0, NULL,
- NULL, NULL, NULL, 0, 0 }
-};
-#endif
#ifdef NETGRAPH
+#ifndef __rtems__
+static struct protox netgraphprotox[] = {
+#else /* __rtems__ */
static const struct protox netgraphprotox[] = {
- { N_NGSOCKS, -1, 1, netgraphprotopr,
+#endif /* __rtems__ */
+ { 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
-#ifdef IPX
-static const struct protox ipxprotox[] = {
- { N_IPX, N_IPXSTAT, 1, ipxprotopr,
- ipx_stats, NULL, "ipx", 0, 0 },
- { N_IPX, N_SPXSTAT, 1, ipxprotopr,
- spx_stats, NULL, "spx", 0, 0 },
- { -1, -1, 0, NULL,
- NULL, NULL, 0, 0, 0 }
-};
-#endif
-static const struct protox *protoprotox[] = {
+#ifndef __rtems__
+static struct protox *protoprotox[] = {
+#else /* __rtems__ */
+static const struct protox *const protoprotox[] = {
+#endif /* __rtems__ */
protox,
#ifdef INET6
ip6protox,
@@ -334,26 +222,30 @@ static const struct protox *protoprotox[] = {
#ifdef IPSEC
pfkeyprotox,
#endif
-#ifdef IPX
- ipxprotox,
-#endif
-#ifndef __rtems__
- atalkprotox, NULL };
-#else
- NULL };
-#endif
+ NULL };
-static void printproto(const struct protox *, const char *);
+#ifndef __rtems__
+static void printproto(struct protox *, const char *, bool *);
+#else /* __rtems__ */
+static void printproto(const struct protox *, const char *, bool *);
+#endif /* __rtems__ */
static void usage(void);
+#ifndef __rtems__
+static struct protox *name2protox(const char *);
+static struct protox *knownname(const char *);
+#else /* __rtems__ */
static const struct protox *name2protox(const char *);
static const struct protox *knownname(const char *);
+#endif /* __rtems__ */
+
+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 */
@@ -366,9 +258,10 @@ int numeric_addr; /* show addresses numerically */
int numeric_port; /* show ports numerically */
static int pflag; /* show given protocol */
#ifndef __rtems__
-int Qflag; /* show netisr information */
+static int Qflag; /* show netisr information */
#endif /* __rtems__ */
int rflag; /* show routing tables (or routing stats) */
+int Rflag; /* show flow / RSS statistics */
int sflag; /* show protocol statistics */
int Wflag; /* wide display */
int Tflag; /* TCP Information */
@@ -380,60 +273,27 @@ 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 */
#ifdef __rtems__
-int protopr_initialized;
-int do_rtent;
-struct radix_node_head **rt_tables;
-
static int main(int argc, char *argv[]);
-int rtems_bsd_command_netstat(int argc, char *argv[])
+RTEMS_LINKER_RWSET(bsd_prog_netstat, char);
+
+int
+rtems_bsd_command_netstat(int argc, char *argv[])
{
int exit_code;
+ void *data_begin;
+ size_t data_size;
- rtems_bsd_program_lock();
-
- nlistf = NULL;
- memf = NULL;
-
- Aflag = 0;
- aflag = 0;
- Bflag = 0;
- bflag = 0;
- dflag = 0;
- gflag = 0;
- hflag = 0;
- iflag = 0;
- Lflag = 0;
- mflag = 0;
- noutputs = 0;
- numeric_addr = 0;
- numeric_port = 0;
- pflag = 0;
- rflag = 0;
- sflag = 0;
- Wflag = 0;
- xflag = 0;
- zflag = 0;
- interval = 0;
- interface = 0;
- unit = 0;
- af = 0;
- live = 0;
-
- protopr_initialized = 0;
- do_rtent = 0;
-
- rtems_bsd_netstat_inet_init();
-
- exit_code = rtems_bsd_program_call_main("netstat", main, argc, argv);
-
- free(rt_tables);
- rt_tables = NULL;
+ data_begin = RTEMS_LINKER_SET_BEGIN(bsd_prog_netstat);
+ data_size = RTEMS_LINKER_SET_SIZE(bsd_prog_netstat);
+ rtems_bsd_program_lock();
+ exit_code = rtems_bsd_program_call_main_with_data_restore("netstat",
+ main, argc, argv, data_begin, data_size);
rtems_bsd_program_unlock();
return exit_code;
@@ -442,8 +302,15 @@ int rtems_bsd_command_netstat(int argc, char *argv[])
int
main(int argc, char *argv[])
{
+#ifndef __rtems__
+ struct protox *tp = NULL; /* for printing cblocks & stats */
+#else /* __rtems__ */
const struct protox *tp = NULL; /* for printing cblocks & stats */
+#endif /* __rtems__ */
int ch;
+ int fib = -1;
+ char *endptr;
+ bool first = true;
#ifdef __rtems__
struct getopt_data getopt_data;
memset(&getopt_data, 0, sizeof(getopt_data));
@@ -456,7 +323,11 @@ main(int argc, char *argv[])
af = AF_UNSPEC;
- while ((ch = getopt(argc, argv, "46AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz"))
+ argc = xo_parse_args(argc, argv);
+ if (argc < 0)
+ exit(EXIT_FAILURE);
+
+ while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz"))
!= -1)
switch(ch) {
case '4':
@@ -488,10 +359,14 @@ main(int argc, char *argv[])
case 'd':
dflag = 1;
break;
+ case 'F':
+ fib = strtol(optarg, &endptr, 0);
+ if (*endptr != '\0' ||
+ (fib == 0 && (errno == EINVAL || errno == ERANGE)))
+ xo_errx(1, "%s: invalid fib", optarg);
+ break;
case 'f':
- if (strcmp(optarg, "ipx") == 0)
- af = AF_IPX;
- else if (strcmp(optarg, "inet") == 0)
+ if (strcmp(optarg, "inet") == 0)
af = AF_INET;
#ifdef INET6
else if (strcmp(optarg, "inet6") == 0)
@@ -501,10 +376,9 @@ main(int argc, char *argv[])
else if (strcmp(optarg, "pfkey") == 0)
af = PF_KEY;
#endif
- else if (strcmp(optarg, "unix") == 0)
+ else if (strcmp(optarg, "unix") == 0 ||
+ strcmp(optarg, "local") == 0)
af = AF_UNIX;
- else if (strcmp(optarg, "atalk") == 0)
- af = AF_APPLETALK;
#ifdef NETGRAPH
else if (strcmp(optarg, "ng") == 0
|| strcmp(optarg, "netgraph") == 0)
@@ -513,7 +387,8 @@ main(int argc, char *argv[])
else if (strcmp(optarg, "link") == 0)
af = AF_LINK;
else {
- errx(1, "%s: unknown address family", optarg);
+ xo_errx(1, "%s: unknown address family",
+ optarg);
}
break;
case 'g':
@@ -526,7 +401,12 @@ main(int argc, char *argv[])
char *cp;
iflag = 1;
- for (cp = interface = optarg; isalpha((unsigned char) *cp); cp++)
+#ifndef __rtems__
+ for (cp = interface = optarg; isalpha(*cp); cp++)
+#else /* __rtems__ */
+ for (cp = interface = optarg; isalpha(
+ (unsigned char) *cp); cp++)
+#endif /* __rtems__ */
continue;
unit = atoi(cp);
break;
@@ -551,9 +431,8 @@ main(int argc, char *argv[])
break;
case 'p':
if ((tp = name2protox(optarg)) == NULL) {
- errx(1,
- "%s: unknown or uninstrumented protocol",
- optarg);
+ xo_errx(1, "%s: unknown or uninstrumented "
+ "protocol", optarg);
}
pflag = 1;
break;
@@ -570,6 +449,9 @@ main(int argc, char *argv[])
case 'r':
rflag = 1;
break;
+ case 'R':
+ Rflag = 1;
+ break;
case 's':
++sflag;
break;
@@ -606,7 +488,11 @@ main(int argc, char *argv[])
#define BACKWARD_COMPATIBILITY
#ifdef BACKWARD_COMPATIBILITY
if (*argv) {
+#ifndef __rtems__
+ if (isdigit(**argv)) {
+#else /* __rtems__ */
if (isdigit((unsigned char) **argv)) {
+#endif /* __rtems__ */
interval = atoi(*argv);
if (interval <= 0)
usage();
@@ -626,33 +512,38 @@ main(int argc, char *argv[])
* guys can't print interesting stuff from kernel memory.
*/
live = (nlistf == NULL && memf == NULL);
- if (!live)
- setgid(getgid());
+ if (!live) {
+ if (setgid(getgid()) != 0)
+ xo_err(-1, "setgid");
+ }
- if (xflag && Tflag)
- errx(1, "-x and -T are incompatible, pick one.");
+ if (xflag && Tflag)
+ xo_errx(1, "-x and -T are incompatible, pick one.");
if (Bflag) {
if (!live)
usage();
bpf_stats(interface);
+ xo_finish();
exit(0);
}
if (mflag) {
if (!live) {
if (kread(0, NULL, 0) == 0)
- mbpr(kvmd, nl[N_MBSTAT].n_value);
+ mbpr(kvmd, nl[N_SFSTAT].n_value);
} else
mbpr(NULL, 0);
+ xo_finish();
exit(0);
}
#ifndef __rtems__
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);
}
#endif /* __rtems__ */
@@ -670,109 +561,162 @@ main(int argc, char *argv[])
* used for the queries, which is slower.
*/
#endif
- kread(0, NULL, 0);
if (iflag && !sflag) {
- intpr(interval, nl[N_IFNET].n_value, NULL);
+ xo_open_container("statistics");
+ intpr(NULL, af);
+ xo_close_container("statistics");
+ xo_finish();
exit(0);
}
if (rflag) {
- if (sflag)
- rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value);
- else
- routepr(nl[N_RTREE].n_value);
+ xo_open_container("statistics");
+ if (sflag) {
+ rt_stats();
+ flowtable_stats();
+ } else
+ routepr(fib, af);
+ xo_close_container("statistics");
+ xo_finish();
exit(0);
}
+
if (gflag) {
+ xo_open_container("statistics");
if (sflag) {
if (af == AF_INET || af == AF_UNSPEC)
- mrt_stats(nl[N_MRTSTAT].n_value);
+ mrt_stats();
#ifdef INET6
if (af == AF_INET6 || af == AF_UNSPEC)
- mrt6_stats(nl[N_MRT6STAT].n_value);
+ mrt6_stats();
#endif
} else {
if (af == AF_INET || af == AF_UNSPEC)
- mroutepr(nl[N_MFCHASHTBL].n_value,
- nl[N_MFCTABLESIZE].n_value,
- nl[N_VIFTABLE].n_value);
+ mroutepr();
#ifdef INET6
if (af == AF_INET6 || af == AF_UNSPEC)
- mroute6pr(nl[N_MF6CTABLE].n_value,
- nl[N_MIF6TABLE].n_value);
+ mroute6pr();
#endif
}
+ xo_close_container("statistics");
+ xo_finish();
exit(0);
}
+ /* Load all necessary kvm symbols */
+ kresolve_list(nl);
+
if (tp) {
- printproto(tp, tp->pr_name);
+ xo_open_container("statistics");
+ printproto(tp, tp->pr_name, &first);
+ if (!first)
+ xo_close_list("socket");
+ xo_close_container("statistics");
+ xo_finish();
exit(0);
}
+
+ xo_open_container("statistics");
if (af == AF_INET || af == AF_UNSPEC)
for (tp = protox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
+ printproto(tp, tp->pr_name, &first);
#ifdef INET6
if (af == AF_INET6 || af == AF_UNSPEC)
for (tp = ip6protox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
+ printproto(tp, tp->pr_name, &first);
#endif /*INET6*/
#ifdef IPSEC
if (af == PF_KEY || af == AF_UNSPEC)
for (tp = pfkeyprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
+ printproto(tp, tp->pr_name, &first);
#endif /*IPSEC*/
-#ifdef IPX
- if (af == AF_IPX || af == AF_UNSPEC) {
- for (tp = ipxprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
- }
-#endif /* IPX */
-#ifndef __rtems__
- if (af == AF_APPLETALK || af == AF_UNSPEC)
- for (tp = atalkprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
-#endif
#ifdef NETGRAPH
if (af == AF_NETGRAPH || af == AF_UNSPEC)
for (tp = netgraphprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
+ printproto(tp, tp->pr_name, &first);
#endif /* NETGRAPH */
#ifndef __rtems__
if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value,
- nl[N_UNP_SPHEAD].n_value);
-#endif
+ nl[N_UNP_SPHEAD].n_value, &first);
+#endif /* __rtems__ */
+
+ if (!first)
+ xo_close_list("socket");
+ xo_close_container("statistics");
+ xo_finish();
exit(0);
}
+static int
+fetch_stats_internal(const char *sysctlname, u_long off, void *stats,
+ size_t len, kreadfn_t kreadfn, int zero)
+{
+ int error;
+
+ if (live) {
+ memset(stats, 0, len);
+ if (zero)
+ error = sysctlbyname(sysctlname, NULL, NULL, stats,
+ len);
+ else
+ error = sysctlbyname(sysctlname, stats, &len, NULL, 0);
+ if (error == -1 && errno != ENOENT)
+ xo_warn("sysctl %s", sysctlname);
+ } else {
+ if (off == 0)
+ return (1);
+ error = kreadfn(off, stats, len);
+ }
+ return (error);
+}
+
+int
+fetch_stats(const char *sysctlname, u_long off, void *stats,
+ size_t len, kreadfn_t kreadfn)
+{
+
+ return (fetch_stats_internal(sysctlname, off, stats, len, kreadfn,
+ zflag));
+}
+
+int
+fetch_stats_ro(const char *sysctlname, u_long off, void *stats,
+ size_t len, kreadfn_t kreadfn)
+{
+
+ return (fetch_stats_internal(sysctlname, off, stats, len, kreadfn, 0));
+}
+
/*
* Print out protocol statistics or control blocks (per sflag).
* If the interface was not specifically requested, and the symbol
* is not in the namelist, ignore this one.
*/
static void
-printproto(tp, name)
- const struct protox *tp;
- const char *name;
+#ifndef __rtems__
+printproto(struct protox *tp, const char *name, bool *first)
+#else /* __rtems__ */
+printproto(const struct protox *tp, const char *name, bool *first)
+#endif /* __rtems__ */
{
void (*pr)(u_long, const char *, int, int);
u_long off;
+ bool doingdblocks = false;
if (sflag) {
if (iflag) {
if (tp->pr_istats)
- intpr(interval, nl[N_IFNET].n_value,
- tp->pr_istats);
+ intpr(tp->pr_istats, af);
else if (pflag)
- printf("%s: no per-interface stats routine\n",
+ xo_message("%s: no per-interface stats routine",
tp->pr_name);
return;
} else {
pr = tp->pr_stats;
if (!pr) {
if (pflag)
- printf("%s: no stats routine\n",
+ xo_message("%s: no stats routine",
tp->pr_name);
return;
}
@@ -780,34 +724,99 @@ printproto(tp, name)
off = 0;
else if (tp->pr_sindex < 0) {
if (pflag)
- printf(
- "%s: stats routine doesn't work on cores\n",
- tp->pr_name);
+ xo_message("%s: stats routine doesn't "
+ "work on cores", tp->pr_name);
return;
} else
off = nl[tp->pr_sindex].n_value;
}
} else {
+ doingdblocks = true;
pr = tp->pr_cblocks;
if (!pr) {
if (pflag)
- printf("%s: no PCB routine\n", tp->pr_name);
+ xo_message("%s: no PCB routine", tp->pr_name);
return;
}
if (tp->pr_usesysctl && live)
off = 0;
else if (tp->pr_index < 0) {
if (pflag)
- printf(
- "%s: PCB routine doesn't work on cores\n",
- tp->pr_name);
+ xo_message("%s: PCB routine doesn't work on "
+ "cores", tp->pr_name);
return;
} else
off = nl[tp->pr_index].n_value;
}
if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
- af != AF_UNSPEC))
+ af != AF_UNSPEC)) {
+ if (doingdblocks && *first) {
+ xo_open_list("socket");
+ *first = false;
+ }
+
(*pr)(off, name, af, tp->pr_protocol);
+ }
+}
+
+static int
+kvmd_init(void)
+{
+ char errbuf[_POSIX2_LINE_MAX];
+
+ if (kvmd != NULL)
+ return (0);
+
+ kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
+ if (setgid(getgid()) != 0)
+ xo_err(-1, "setgid");
+
+ if (kvmd == NULL) {
+ xo_warnx("kvm not available: %s", errbuf);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Resolve symbol list, return 0 on success.
+ */
+static int
+kresolve_list(struct nlist *_nl)
+{
+
+ if ((kvmd == NULL) && (kvmd_init() != 0))
+ return (-1);
+
+ if (_nl[0].n_type != 0)
+ return (0);
+
+ if (kvm_nlist(kvmd, _nl) < 0) {
+ if (nlistf)
+ xo_errx(1, "%s: kvm_nlist: %s", nlistf,
+ kvm_geterr(kvmd));
+ else
+ xo_errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
+ }
+
+ 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;
}
/*
@@ -816,40 +825,70 @@ printproto(tp, name)
int
kread(u_long addr, void *buf, size_t size)
{
- char errbuf[_POSIX2_LINE_MAX];
- if (kvmd == NULL) {
- kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
- setgid(getgid());
- if (kvmd != NULL) {
- if (kvm_nlist(kvmd, nl) < 0) {
- if (nlistf)
- errx(1, "%s: kvm_nlist: %s", nlistf,
- kvm_geterr(kvmd));
- else
- errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
- }
+ if (kvmd_init() < 0)
+ return (-1);
- if (nl[0].n_type == 0) {
- if (nlistf)
- errx(1, "%s: no namelist", nlistf);
- else
- errx(1, "no namelist");
- }
- } else {
- warnx("kvm not available: %s", errbuf);
- return(-1);
- }
- }
if (!buf)
return (0);
if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) {
- warnx("%s", kvm_geterr(kvmd));
+ xo_warnx("%s", kvm_geterr(kvmd));
return (-1);
}
return (0);
}
+/*
+ * Read single counter(9).
+ */
+uint64_t
+kread_counter(u_long addr)
+{
+
+ if (kvmd_init() < 0)
+ return (-1);
+
+ return (kvm_counter_u64_fetch(kvmd, addr));
+}
+
+/*
+ * Read an array of N counters in kernel memory into array of N uint64_t's.
+ */
+int
+kread_counters(u_long addr, void *buf, size_t size)
+{
+#ifndef __rtems__
+ uint64_t *c;
+ u_long *counters;
+ size_t i, n;
+
+ if (kvmd_init() < 0)
+ return (-1);
+
+ if (size % sizeof(uint64_t) != 0) {
+ xo_warnx("kread_counters: invalid counter set size");
+ return (-1);
+ }
+
+ n = size / sizeof(uint64_t);
+ if ((counters = malloc(n * sizeof(u_long))) == NULL)
+ xo_err(-1, "malloc");
+ if (kread(addr, counters, n * sizeof(u_long)) < 0) {
+ free(counters);
+ return (-1);
+ }
+
+ c = buf;
+ for (i = 0; i < n; i++)
+ c[i] = kvm_counter_u64_fetch(kvmd, counters[i]);
+
+ free(counters);
+ return (0);
+#else /* __rtems__ */
+ return (-1);
+#endif /* __rtems__ */
+}
+
const char *
plural(uintmax_t n)
{
@@ -871,10 +910,18 @@ pluralies(uintmax_t n)
/*
* Find the protox for the given "well-known" name.
*/
+#ifndef __rtems__
+static struct protox *
+#else /* __rtems__ */
static const struct protox *
+#endif /* __rtems__ */
knownname(const char *name)
{
- const struct protox **tpp, *tp;
+#ifndef __rtems__
+ struct protox **tpp, *tp;
+#else /* __rtems__ */
+ const struct protox *const *tpp, *tp;
+#endif /* __rtems__ */
for (tpp = protoprotox; *tpp; tpp++)
for (tp = *tpp; tp->pr_name; tp++)
@@ -886,10 +933,18 @@ knownname(const char *name)
/*
* Find the protox corresponding to name.
*/
+#ifndef __rtems__
+static struct protox *
+#else /* __rtems__ */
static const struct protox *
+#endif /* __rtems__ */
name2protox(const char *name)
{
+#ifndef __rtems__
+ struct protox *tp;
+#else /* __rtems__ */
const struct protox *tp;
+#endif /* __rtems__ */
char **alias; /* alias from p->aliases */
struct protoent *p;
@@ -916,22 +971,25 @@ name2protox(const char *name)
static void
usage(void)
{
- (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
-"usage: netstat [-46AaLnSTWx] [-f protocol_family | -p protocol]\n"
+ (void)xo_error("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+"usage: netstat [-46AaLnRSTWx] [-f protocol_family | -p protocol]\n"
" [-M core] [-N system]",
" netstat -i | -I interface [-46abdhnW] [-f address_family]\n"
" [-M core] [-N system]",
-" netstat -w wait [-I interface] [-46d] [-M core] [-N system] [-q howmany]",
-" netstat -s [-s] [-46z] [-f protocol_family | -p protocol]\n"
-" [-M core] [-N system]",
-" netstat -i | -I interface [-46s] [-f protocol_family | -p protocol]\n"
+" netstat -w wait [-I interface] [-46d] [-M core] [-N system]\n"
+" [-q howmany]",
+" netstat -s [-46sz] [-f protocol_family | -p protocol]\n"
" [-M core] [-N system]",
+" netstat -i | -I interface -s [-46s]\n"
+" [-f protocol_family | -p protocol] [-M core] [-N system]",
" netstat -m [-M core] [-N system]",
-" netstat -B [-I interface]",
-" netstat -r [-46AanW] [-f address_family] [-M core] [-N system]",
+" netstat -B [-z] [-I interface]",
+" netstat -r [-46AnW] [-F fibnum] [-f address_family]\n"
+" [-M core] [-N system]",
" netstat -rs [-s] [-M core] [-N system]",
" netstat -g [-46W] [-f address_family] [-M core] [-N system]",
" netstat -gs [-46s] [-f address_family] [-M core] [-N system]",
" netstat -Q");
+ xo_finish();
exit(1);
}