165475bc8SDavid E. O'Brien /*- 29b50d902SRodney W. Grimes * Copyright (c) 1983, 1988, 1993 39b50d902SRodney W. Grimes * Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 149b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 159b50d902SRodney W. Grimes * without specific prior written permission. 169b50d902SRodney W. Grimes * 179b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 189b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 199b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 209b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 219b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 229b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 239b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 249b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 259b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 269b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 279b50d902SRodney W. Grimes * SUCH DAMAGE. 289b50d902SRodney W. Grimes */ 299b50d902SRodney W. Grimes 309b50d902SRodney W. Grimes #ifndef lint 315d422d6aSPhilippe Charnier char const copyright[] = 329b50d902SRodney W. Grimes "@(#) Copyright (c) 1983, 1988, 1993\n\ 339b50d902SRodney W. Grimes Regents of the University of California. All rights reserved.\n"; 349b50d902SRodney W. Grimes #endif /* not lint */ 359b50d902SRodney W. Grimes 365d422d6aSPhilippe Charnier #if 0 376cc6f122SPhilippe Charnier #ifndef lint 389b50d902SRodney W. Grimes static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94"; 399b50d902SRodney W. Grimes #endif /* not lint */ 406cc6f122SPhilippe Charnier #endif 416cc6f122SPhilippe Charnier 426cc6f122SPhilippe Charnier #include <sys/cdefs.h> 436cc6f122SPhilippe Charnier __FBSDID("$FreeBSD$"); 449b50d902SRodney W. Grimes 459b50d902SRodney W. Grimes #include <sys/param.h> 469b50d902SRodney W. Grimes #include <sys/file.h> 479b50d902SRodney W. Grimes #include <sys/protosw.h> 489b50d902SRodney W. Grimes #include <sys/socket.h> 49feda1a43SJohn Baldwin #include <sys/socketvar.h> 509b50d902SRodney W. Grimes 519b50d902SRodney W. Grimes #include <netinet/in.h> 529b50d902SRodney W. Grimes 53690f477dSSam Leffler #ifdef NETGRAPH 544cf49a43SJulian Elischer #include <netgraph/ng_socket.h> 55690f477dSSam Leffler #endif 564cf49a43SJulian Elischer 579b50d902SRodney W. Grimes #include <ctype.h> 585d422d6aSPhilippe Charnier #include <err.h> 59821df508SXin LI #include <errno.h> 609b50d902SRodney W. Grimes #include <kvm.h> 619b50d902SRodney W. Grimes #include <limits.h> 629b50d902SRodney W. Grimes #include <netdb.h> 639b50d902SRodney W. Grimes #include <nlist.h> 64821df508SXin LI #include <paths.h> 657b95a1ebSYaroslav Tykhiy #include <stdint.h> 669b50d902SRodney W. Grimes #include <stdio.h> 679b50d902SRodney W. Grimes #include <stdlib.h> 68ade9ccfeSMarcel Moolenaar #include <stdbool.h> 699b50d902SRodney W. Grimes #include <string.h> 709b50d902SRodney W. Grimes #include <unistd.h> 719b50d902SRodney W. Grimes #include "netstat.h" 72ade9ccfeSMarcel Moolenaar #include <libxo/xo.h> 739b50d902SRodney W. Grimes 74c6620a13SPoul-Henning Kamp static struct nlist nl[] = { 752c284d93SGleb Smirnoff #define N_RTSTAT 0 76096146f8SYaroslav Tykhiy { .n_name = "_rtstat" }, 772c284d93SGleb Smirnoff #define N_RTREE 1 78096146f8SYaroslav Tykhiy { .n_name = "_rt_tables"}, 792c284d93SGleb Smirnoff #define N_MRTSTAT 2 80096146f8SYaroslav Tykhiy { .n_name = "_mrtstat" }, 812c284d93SGleb Smirnoff #define N_MFCHASHTBL 3 82443fc317SBruce M Simpson { .n_name = "_mfchashtbl" }, 832c284d93SGleb Smirnoff #define N_VIFTABLE 4 84096146f8SYaroslav Tykhiy { .n_name = "_viftable" }, 8545c203fcSGleb Smirnoff #define N_NGSOCKS 5 86096146f8SYaroslav Tykhiy { .n_name = "_ngsocklist"}, 8745c203fcSGleb Smirnoff #define N_IP6STAT 6 88096146f8SYaroslav Tykhiy { .n_name = "_ip6stat" }, 8945c203fcSGleb Smirnoff #define N_ICMP6STAT 7 90096146f8SYaroslav Tykhiy { .n_name = "_icmp6stat" }, 9145c203fcSGleb Smirnoff #define N_IPSECSTAT 8 928409aedfSGeorge V. Neville-Neil { .n_name = "_ipsec4stat" }, 9345c203fcSGleb Smirnoff #define N_IPSEC6STAT 9 94096146f8SYaroslav Tykhiy { .n_name = "_ipsec6stat" }, 9545c203fcSGleb Smirnoff #define N_PIM6STAT 10 96096146f8SYaroslav Tykhiy { .n_name = "_pim6stat" }, 9745c203fcSGleb Smirnoff #define N_MRT6STAT 11 98096146f8SYaroslav Tykhiy { .n_name = "_mrt6stat" }, 9945c203fcSGleb Smirnoff #define N_MF6CTABLE 12 100096146f8SYaroslav Tykhiy { .n_name = "_mf6ctable" }, 10145c203fcSGleb Smirnoff #define N_MIF6TABLE 13 102096146f8SYaroslav Tykhiy { .n_name = "_mif6table" }, 10345c203fcSGleb Smirnoff #define N_PFKEYSTAT 14 104096146f8SYaroslav Tykhiy { .n_name = "_pfkeystat" }, 10545c203fcSGleb Smirnoff #define N_RTTRASH 15 106096146f8SYaroslav Tykhiy { .n_name = "_rttrash" }, 10745c203fcSGleb Smirnoff #define N_CARPSTAT 16 108096146f8SYaroslav Tykhiy { .n_name = "_carpstats" }, 10945c203fcSGleb Smirnoff #define N_PFSYNCSTAT 17 110096146f8SYaroslav Tykhiy { .n_name = "_pfsyncstats" }, 11145c203fcSGleb Smirnoff #define N_AHSTAT 18 112096146f8SYaroslav Tykhiy { .n_name = "_ahstat" }, 11345c203fcSGleb Smirnoff #define N_ESPSTAT 19 114096146f8SYaroslav Tykhiy { .n_name = "_espstat" }, 11545c203fcSGleb Smirnoff #define N_IPCOMPSTAT 20 116096146f8SYaroslav Tykhiy { .n_name = "_ipcompstat" }, 11745c203fcSGleb Smirnoff #define N_TCPSTAT 21 1185da0521fSAndrey V. Elsukov { .n_name = "_tcpstat" }, 11945c203fcSGleb Smirnoff #define N_UDPSTAT 22 120feda1a43SJohn Baldwin { .n_name = "_udpstat" }, 12145c203fcSGleb Smirnoff #define N_IPSTAT 23 1225da0521fSAndrey V. Elsukov { .n_name = "_ipstat" }, 12345c203fcSGleb Smirnoff #define N_ICMPSTAT 24 124feda1a43SJohn Baldwin { .n_name = "_icmpstat" }, 12545c203fcSGleb Smirnoff #define N_IGMPSTAT 25 126feda1a43SJohn Baldwin { .n_name = "_igmpstat" }, 12745c203fcSGleb Smirnoff #define N_PIMSTAT 26 128feda1a43SJohn Baldwin { .n_name = "_pimstat" }, 12945c203fcSGleb Smirnoff #define N_TCBINFO 27 130feda1a43SJohn Baldwin { .n_name = "_tcbinfo" }, 13145c203fcSGleb Smirnoff #define N_UDBINFO 28 132feda1a43SJohn Baldwin { .n_name = "_udbinfo" }, 13345c203fcSGleb Smirnoff #define N_DIVCBINFO 29 134feda1a43SJohn Baldwin { .n_name = "_divcbinfo" }, 13545c203fcSGleb Smirnoff #define N_RIPCBINFO 30 136feda1a43SJohn Baldwin { .n_name = "_ripcbinfo" }, 13745c203fcSGleb Smirnoff #define N_UNP_COUNT 31 138feda1a43SJohn Baldwin { .n_name = "_unp_count" }, 13945c203fcSGleb Smirnoff #define N_UNP_GENCNT 32 140feda1a43SJohn Baldwin { .n_name = "_unp_gencnt" }, 14145c203fcSGleb Smirnoff #define N_UNP_DHEAD 33 142feda1a43SJohn Baldwin { .n_name = "_unp_dhead" }, 14345c203fcSGleb Smirnoff #define N_UNP_SHEAD 34 144feda1a43SJohn Baldwin { .n_name = "_unp_shead" }, 14545c203fcSGleb Smirnoff #define N_RIP6STAT 36 146feda1a43SJohn Baldwin { .n_name = "_rip6stat" }, 14745c203fcSGleb Smirnoff #define N_SCTPSTAT 36 148feda1a43SJohn Baldwin { .n_name = "_sctpstat" }, 14945c203fcSGleb Smirnoff #define N_MFCTABLESIZE 37 150443fc317SBruce M Simpson { .n_name = "_mfctablesize" }, 15145c203fcSGleb Smirnoff #define N_ARPSTAT 38 15254fc657dSGeorge V. Neville-Neil { .n_name = "_arpstat" }, 15345c203fcSGleb Smirnoff #define N_UNP_SPHEAD 39 154963b7ccdSRobert Watson { .n_name = "unp_sphead" }, 15545c203fcSGleb Smirnoff #define N_SFSTAT 40 15605d1f5bcSAndrey V. Elsukov { .n_name = "_sfstat"}, 157096146f8SYaroslav Tykhiy { .n_name = NULL }, 1589b50d902SRodney W. Grimes }; 1599b50d902SRodney W. Grimes 1609b50d902SRodney W. Grimes struct protox { 161feda1a43SJohn Baldwin int pr_index; /* index into nlist of cb head */ 162feda1a43SJohn Baldwin int pr_sindex; /* index into nlist of stat block */ 1639b50d902SRodney W. Grimes u_char pr_wanted; /* 1 if wanted, 0 otherwise */ 164feda1a43SJohn Baldwin void (*pr_cblocks)(u_long, const char *, int, int); 1655e051718SAssar Westerlund /* control blocks printing routine */ 166feda1a43SJohn Baldwin void (*pr_stats)(u_long, const char *, int, int); 1675e051718SAssar Westerlund /* statistics printing routine */ 1685e051718SAssar Westerlund void (*pr_istats)(char *); /* per/if statistics printing routine */ 169fa6d48c0SMark Murray const char *pr_name; /* well-known name */ 17055fd53e2SJohn Baldwin int pr_usesysctl; /* non-zero if we use sysctl, not kvm */ 171feda1a43SJohn Baldwin int pr_protocol; 1729b50d902SRodney W. Grimes } protox[] = { 173feda1a43SJohn Baldwin { N_TCBINFO, N_TCPSTAT, 1, protopr, 174feda1a43SJohn Baldwin tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, 175feda1a43SJohn Baldwin { N_UDBINFO, N_UDPSTAT, 1, protopr, 176feda1a43SJohn Baldwin udp_stats, NULL, "udp", 1, IPPROTO_UDP }, 17774fd40c9SRandall Stewart #ifdef SCTP 178feda1a43SJohn Baldwin { -1, N_SCTPSTAT, 1, sctp_protopr, 179feda1a43SJohn Baldwin sctp_stats, NULL, "sctp", 1, IPPROTO_SCTP }, 18074fd40c9SRandall Stewart #endif 181aa0a1e58SJeff Roberson #ifdef SDP 182aa0a1e58SJeff Roberson { -1, -1, 1, protopr, 183aa0a1e58SJeff Roberson NULL, NULL, "sdp", 1, IPPROTO_TCP }, 184aa0a1e58SJeff Roberson #endif 185feda1a43SJohn Baldwin { N_DIVCBINFO, -1, 1, protopr, 186feda1a43SJohn Baldwin NULL, NULL, "divert", 1, IPPROTO_DIVERT }, 187feda1a43SJohn Baldwin { N_RIPCBINFO, N_IPSTAT, 1, protopr, 188feda1a43SJohn Baldwin ip_stats, NULL, "ip", 1, IPPROTO_RAW }, 189feda1a43SJohn Baldwin { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, 190feda1a43SJohn Baldwin icmp_stats, NULL, "icmp", 1, IPPROTO_ICMP }, 191feda1a43SJohn Baldwin { N_RIPCBINFO, N_IGMPSTAT, 1, protopr, 192feda1a43SJohn Baldwin igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP }, 193cfa1ca9dSYoshinobu Inoue #ifdef IPSEC 1948409aedfSGeorge V. Neville-Neil { -1, N_IPSECSTAT, 1, NULL, /* keep as compat */ 195feda1a43SJohn Baldwin ipsec_stats, NULL, "ipsec", 0, 0}, 1968409aedfSGeorge V. Neville-Neil { -1, N_AHSTAT, 1, NULL, 197feda1a43SJohn Baldwin ah_stats, NULL, "ah", 0, 0}, 1988409aedfSGeorge V. Neville-Neil { -1, N_ESPSTAT, 1, NULL, 199feda1a43SJohn Baldwin esp_stats, NULL, "esp", 0, 0}, 2008409aedfSGeorge V. Neville-Neil { -1, N_IPCOMPSTAT, 1, NULL, 201feda1a43SJohn Baldwin ipcomp_stats, NULL, "ipcomp", 0, 0}, 202100b98dbSKelly Yancey #endif 203feda1a43SJohn Baldwin { N_RIPCBINFO, N_PIMSTAT, 1, protopr, 204feda1a43SJohn Baldwin pim_stats, NULL, "pim", 1, IPPROTO_PIM }, 205feda1a43SJohn Baldwin { -1, N_CARPSTAT, 1, NULL, 206feda1a43SJohn Baldwin carp_stats, NULL, "carp", 1, 0 }, 2073e4d5cd3SGleb Smirnoff #ifdef PF 208feda1a43SJohn Baldwin { -1, N_PFSYNCSTAT, 1, NULL, 209feda1a43SJohn Baldwin pfsync_stats, NULL, "pfsync", 1, 0 }, 2103e4d5cd3SGleb Smirnoff #endif 21154fc657dSGeorge V. Neville-Neil { -1, N_ARPSTAT, 1, NULL, 21254fc657dSGeorge V. Neville-Neil arp_stats, NULL, "arp", 1, 0 }, 2136bb3f207SRuslan Ermilov { -1, -1, 0, NULL, 214feda1a43SJohn Baldwin NULL, NULL, NULL, 0, 0 } 2159b50d902SRodney W. Grimes }; 2169b50d902SRodney W. Grimes 217cfa1ca9dSYoshinobu Inoue #ifdef INET6 218cfa1ca9dSYoshinobu Inoue struct protox ip6protox[] = { 219feda1a43SJohn Baldwin { N_TCBINFO, N_TCPSTAT, 1, protopr, 220feda1a43SJohn Baldwin tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, 221feda1a43SJohn Baldwin { N_UDBINFO, N_UDPSTAT, 1, protopr, 222feda1a43SJohn Baldwin udp_stats, NULL, "udp", 1, IPPROTO_UDP }, 223feda1a43SJohn Baldwin { N_RIPCBINFO, N_IP6STAT, 1, protopr, 224feda1a43SJohn Baldwin ip6_stats, ip6_ifstats, "ip6", 1, IPPROTO_RAW }, 225feda1a43SJohn Baldwin { N_RIPCBINFO, N_ICMP6STAT, 1, protopr, 226feda1a43SJohn Baldwin icmp6_stats, icmp6_ifstats, "icmp6", 1, IPPROTO_ICMPV6 }, 227aa0a1e58SJeff Roberson #ifdef SDP 228aa0a1e58SJeff Roberson { -1, -1, 1, protopr, 229aa0a1e58SJeff Roberson NULL, NULL, "sdp", 1, IPPROTO_TCP }, 230aa0a1e58SJeff Roberson #endif 231cfa1ca9dSYoshinobu Inoue #ifdef IPSEC 2326bb3f207SRuslan Ermilov { -1, N_IPSEC6STAT, 1, NULL, 233feda1a43SJohn Baldwin ipsec_stats, NULL, "ipsec6", 0, 0 }, 234cfa1ca9dSYoshinobu Inoue #endif 235cfa1ca9dSYoshinobu Inoue #ifdef notyet 2366bb3f207SRuslan Ermilov { -1, N_PIM6STAT, 1, NULL, 237feda1a43SJohn Baldwin pim6_stats, NULL, "pim6", 1, 0 }, 238cfa1ca9dSYoshinobu Inoue #endif 239feda1a43SJohn Baldwin { -1, N_RIP6STAT, 1, NULL, 240feda1a43SJohn Baldwin rip6_stats, NULL, "rip6", 1, 0 }, 2416bb3f207SRuslan Ermilov { -1, -1, 0, NULL, 242feda1a43SJohn Baldwin NULL, NULL, NULL, 0, 0 } 243cfa1ca9dSYoshinobu Inoue }; 244cfa1ca9dSYoshinobu Inoue #endif /*INET6*/ 245cfa1ca9dSYoshinobu Inoue 2463b8a8567SJun-ichiro itojun Hagino #ifdef IPSEC 2473b8a8567SJun-ichiro itojun Hagino struct protox pfkeyprotox[] = { 2486bb3f207SRuslan Ermilov { -1, N_PFKEYSTAT, 1, NULL, 249feda1a43SJohn Baldwin pfkey_stats, NULL, "pfkey", 0, 0 }, 2506bb3f207SRuslan Ermilov { -1, -1, 0, NULL, 251feda1a43SJohn Baldwin NULL, NULL, NULL, 0, 0 } 2523b8a8567SJun-ichiro itojun Hagino }; 2533b8a8567SJun-ichiro itojun Hagino #endif 2543b8a8567SJun-ichiro itojun Hagino 255690f477dSSam Leffler #ifdef NETGRAPH 2564cf49a43SJulian Elischer struct protox netgraphprotox[] = { 2574cf49a43SJulian Elischer { N_NGSOCKS, -1, 1, netgraphprotopr, 258feda1a43SJohn Baldwin NULL, NULL, "ctrl", 0, 0 }, 2594cf49a43SJulian Elischer { N_NGSOCKS, -1, 1, netgraphprotopr, 260feda1a43SJohn Baldwin NULL, NULL, "data", 0, 0 }, 2616bb3f207SRuslan Ermilov { -1, -1, 0, NULL, 262feda1a43SJohn Baldwin NULL, NULL, NULL, 0, 0 } 2634cf49a43SJulian Elischer }; 264690f477dSSam Leffler #endif 265cc6a66f2SJulian Elischer 266cfa1ca9dSYoshinobu Inoue struct protox *protoprotox[] = { 267cfa1ca9dSYoshinobu Inoue protox, 268cfa1ca9dSYoshinobu Inoue #ifdef INET6 269cfa1ca9dSYoshinobu Inoue ip6protox, 270cfa1ca9dSYoshinobu Inoue #endif 2713b8a8567SJun-ichiro itojun Hagino #ifdef IPSEC 2723b8a8567SJun-ichiro itojun Hagino pfkeyprotox, 2733b8a8567SJun-ichiro itojun Hagino #endif 27445c203fcSGleb Smirnoff NULL }; 2759b50d902SRodney W. Grimes 276ade9ccfeSMarcel Moolenaar static void printproto(struct protox *, const char *, bool *); 2775e051718SAssar Westerlund static void usage(void); 278096146f8SYaroslav Tykhiy static struct protox *name2protox(const char *); 279096146f8SYaroslav Tykhiy static struct protox *knownname(const char *); 2809b50d902SRodney W. Grimes 281c6620a13SPoul-Henning Kamp static kvm_t *kvmd; 282080b7f49SDag-Erling Smørgrav static char *nlistf = NULL, *memf = NULL; 283080b7f49SDag-Erling Smørgrav 284080b7f49SDag-Erling Smørgrav int Aflag; /* show addresses of protocol control block */ 285080b7f49SDag-Erling Smørgrav int aflag; /* show all sockets (including servers) */ 2866b463eedSChristian S.J. Peron int Bflag; /* show information about bpf consumers */ 287080b7f49SDag-Erling Smørgrav int bflag; /* show i/f total bytes in/out */ 288080b7f49SDag-Erling Smørgrav int dflag; /* show i/f dropped packets */ 289080b7f49SDag-Erling Smørgrav int gflag; /* show group (multicast) routing or stats */ 290c2dfd19fSGleb Smirnoff int hflag; /* show counters in human readable format */ 291080b7f49SDag-Erling Smørgrav int iflag; /* show interfaces */ 292080b7f49SDag-Erling Smørgrav int Lflag; /* show size of listen queues */ 293080b7f49SDag-Erling Smørgrav int mflag; /* show memory stats */ 294bf10ffe1SXin LI int noutputs = 0; /* how much outputs before we exit */ 29565ea0024SAssar Westerlund int numeric_addr; /* show addresses numerically */ 29665ea0024SAssar Westerlund int numeric_port; /* show ports numerically */ 297cf5e44f8SRuslan Ermilov static int pflag; /* show given protocol */ 2980153eb66SRobert Watson int Qflag; /* show netisr information */ 299080b7f49SDag-Erling Smørgrav int rflag; /* show routing tables (or routing stats) */ 30085b0f0f3SAdrian Chadd int Rflag; /* show flow / RSS statistics */ 301080b7f49SDag-Erling Smørgrav int sflag; /* show protocol statistics */ 302080b7f49SDag-Erling Smørgrav int Wflag; /* wide display */ 303f5d34df5SGeorge V. Neville-Neil int Tflag; /* TCP Information */ 30449f287f8SGeorge V. Neville-Neil int xflag; /* extra information, includes all socket buffer info */ 305c73d99b5SRuslan Ermilov int zflag; /* zero stats */ 306080b7f49SDag-Erling Smørgrav 307080b7f49SDag-Erling Smørgrav int interval; /* repeat interval for i/f stats */ 308080b7f49SDag-Erling Smørgrav 309080b7f49SDag-Erling Smørgrav char *interface; /* desired i/f for stats, or NULL for all i/fs */ 310080b7f49SDag-Erling Smørgrav int unit; /* unit number for above */ 311080b7f49SDag-Erling Smørgrav 312080b7f49SDag-Erling Smørgrav int af; /* address family */ 313feda1a43SJohn Baldwin int live; /* true if we are examining a live system */ 3149b50d902SRodney W. Grimes 3159b50d902SRodney W. Grimes int 316a01e3379SDavid Malone main(int argc, char *argv[]) 3179b50d902SRodney W. Grimes { 318a01e3379SDavid Malone struct protox *tp = NULL; /* for printing cblocks & stats */ 3199b50d902SRodney W. Grimes int ch; 3203fddef95SHiroki Sato int fib = -1; 3213fddef95SHiroki Sato char *endptr; 322ade9ccfeSMarcel Moolenaar bool first = true; 3239b50d902SRodney W. Grimes 3249b50d902SRodney W. Grimes af = AF_UNSPEC; 3259b50d902SRodney W. Grimes 326ade9ccfeSMarcel Moolenaar argc = xo_parse_args(argc, argv); 327ade9ccfeSMarcel Moolenaar 32885b0f0f3SAdrian Chadd while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz")) 3290153eb66SRobert Watson != -1) 3309b50d902SRodney W. Grimes switch(ch) { 33117ed2e8eSAlexander V. Chernikov case '4': 33217ed2e8eSAlexander V. Chernikov #ifdef INET 33317ed2e8eSAlexander V. Chernikov af = AF_INET; 33417ed2e8eSAlexander V. Chernikov #else 33517ed2e8eSAlexander V. Chernikov errx(1, "IPv4 support is not compiled in"); 33617ed2e8eSAlexander V. Chernikov #endif 33717ed2e8eSAlexander V. Chernikov break; 33817ed2e8eSAlexander V. Chernikov case '6': 33917ed2e8eSAlexander V. Chernikov #ifdef INET6 34017ed2e8eSAlexander V. Chernikov af = AF_INET6; 34117ed2e8eSAlexander V. Chernikov #else 34217ed2e8eSAlexander V. Chernikov errx(1, "IPv6 support is not compiled in"); 34317ed2e8eSAlexander V. Chernikov #endif 34417ed2e8eSAlexander V. Chernikov break; 3459b50d902SRodney W. Grimes case 'A': 3469b50d902SRodney W. Grimes Aflag = 1; 3479b50d902SRodney W. Grimes break; 3489b50d902SRodney W. Grimes case 'a': 3499b50d902SRodney W. Grimes aflag = 1; 3509b50d902SRodney W. Grimes break; 3516b463eedSChristian S.J. Peron case 'B': 3526b463eedSChristian S.J. Peron Bflag = 1; 3536b463eedSChristian S.J. Peron break; 354e1e293a5SDavid Greenman case 'b': 355e1e293a5SDavid Greenman bflag = 1; 356e1e293a5SDavid Greenman break; 3579b50d902SRodney W. Grimes case 'd': 3589b50d902SRodney W. Grimes dflag = 1; 3599b50d902SRodney W. Grimes break; 3603fddef95SHiroki Sato case 'F': 3613fddef95SHiroki Sato fib = strtol(optarg, &endptr, 0); 3623fddef95SHiroki Sato if (*endptr != '\0' || 3633fddef95SHiroki Sato (fib == 0 && (errno == EINVAL || errno == ERANGE))) 364ade9ccfeSMarcel Moolenaar xo_errx(1, "%s: invalid fib", optarg); 3653fddef95SHiroki Sato break; 3669b50d902SRodney W. Grimes case 'f': 3672c284d93SGleb Smirnoff if (strcmp(optarg, "inet") == 0) 3689b50d902SRodney W. Grimes af = AF_INET; 369cfa1ca9dSYoshinobu Inoue #ifdef INET6 370cfa1ca9dSYoshinobu Inoue else if (strcmp(optarg, "inet6") == 0) 371cfa1ca9dSYoshinobu Inoue af = AF_INET6; 372e5134d2eSMax Laier #endif 373e5134d2eSMax Laier #ifdef IPSEC 3743b8a8567SJun-ichiro itojun Hagino else if (strcmp(optarg, "pfkey") == 0) 3753b8a8567SJun-ichiro itojun Hagino af = PF_KEY; 376e5134d2eSMax Laier #endif 3779b50d902SRodney W. Grimes else if (strcmp(optarg, "unix") == 0) 3789b50d902SRodney W. Grimes af = AF_UNIX; 379690f477dSSam Leffler #ifdef NETGRAPH 3804cf49a43SJulian Elischer else if (strcmp(optarg, "ng") == 0 3814cf49a43SJulian Elischer || strcmp(optarg, "netgraph") == 0) 3824cf49a43SJulian Elischer af = AF_NETGRAPH; 383690f477dSSam Leffler #endif 384d44ddba9SRuslan Ermilov else if (strcmp(optarg, "link") == 0) 385d44ddba9SRuslan Ermilov af = AF_LINK; 3869b50d902SRodney W. Grimes else { 387ade9ccfeSMarcel Moolenaar xo_errx(1, "%s: unknown address family", 388ade9ccfeSMarcel Moolenaar optarg); 3899b50d902SRodney W. Grimes } 3909b50d902SRodney W. Grimes break; 3919b50d902SRodney W. Grimes case 'g': 3929b50d902SRodney W. Grimes gflag = 1; 3939b50d902SRodney W. Grimes break; 394c2dfd19fSGleb Smirnoff case 'h': 395c2dfd19fSGleb Smirnoff hflag = 1; 396c2dfd19fSGleb Smirnoff break; 3979b50d902SRodney W. Grimes case 'I': { 3989b50d902SRodney W. Grimes char *cp; 3999b50d902SRodney W. Grimes 4009b50d902SRodney W. Grimes iflag = 1; 4019b50d902SRodney W. Grimes for (cp = interface = optarg; isalpha(*cp); cp++) 4029b50d902SRodney W. Grimes continue; 4039b50d902SRodney W. Grimes unit = atoi(cp); 4049b50d902SRodney W. Grimes break; 4059b50d902SRodney W. Grimes } 4069b50d902SRodney W. Grimes case 'i': 4079b50d902SRodney W. Grimes iflag = 1; 4089b50d902SRodney W. Grimes break; 409ac55add0SGuido van Rooij case 'L': 410ac55add0SGuido van Rooij Lflag = 1; 411ac55add0SGuido van Rooij break; 4129b50d902SRodney W. Grimes case 'M': 4139b50d902SRodney W. Grimes memf = optarg; 4149b50d902SRodney W. Grimes break; 4159b50d902SRodney W. Grimes case 'm': 4169b50d902SRodney W. Grimes mflag = 1; 4179b50d902SRodney W. Grimes break; 4189b50d902SRodney W. Grimes case 'N': 4199b50d902SRodney W. Grimes nlistf = optarg; 4209b50d902SRodney W. Grimes break; 4219b50d902SRodney W. Grimes case 'n': 42265ea0024SAssar Westerlund numeric_addr = numeric_port = 1; 4239b50d902SRodney W. Grimes break; 4249b50d902SRodney W. Grimes case 'p': 4259b50d902SRodney W. Grimes if ((tp = name2protox(optarg)) == NULL) { 426ade9ccfeSMarcel Moolenaar xo_errx(1, "%s: unknown or uninstrumented " 427ade9ccfeSMarcel Moolenaar "protocol", optarg); 4289b50d902SRodney W. Grimes } 4299b50d902SRodney W. Grimes pflag = 1; 4309b50d902SRodney W. Grimes break; 4310153eb66SRobert Watson case 'Q': 4320153eb66SRobert Watson Qflag = 1; 4330153eb66SRobert Watson break; 434bf10ffe1SXin LI case 'q': 435bf10ffe1SXin LI noutputs = atoi(optarg); 436bf10ffe1SXin LI if (noutputs != 0) 437bf10ffe1SXin LI noutputs++; 438bf10ffe1SXin LI break; 4399b50d902SRodney W. Grimes case 'r': 4409b50d902SRodney W. Grimes rflag = 1; 4419b50d902SRodney W. Grimes break; 44285b0f0f3SAdrian Chadd case 'R': 44385b0f0f3SAdrian Chadd Rflag = 1; 44485b0f0f3SAdrian Chadd break; 4459b50d902SRodney W. Grimes case 's': 4469b50d902SRodney W. Grimes ++sflag; 4479b50d902SRodney W. Grimes break; 44865ea0024SAssar Westerlund case 'S': 44965ea0024SAssar Westerlund numeric_addr = 1; 45065ea0024SAssar Westerlund break; 4519b50d902SRodney W. Grimes case 'u': 4529b50d902SRodney W. Grimes af = AF_UNIX; 4539b50d902SRodney W. Grimes break; 454080b7f49SDag-Erling Smørgrav case 'W': 45570057abfSRuslan Ermilov case 'l': 456080b7f49SDag-Erling Smørgrav Wflag = 1; 457080b7f49SDag-Erling Smørgrav break; 4589b50d902SRodney W. Grimes case 'w': 4599b50d902SRodney W. Grimes interval = atoi(optarg); 4609b50d902SRodney W. Grimes iflag = 1; 4619b50d902SRodney W. Grimes break; 462f5d34df5SGeorge V. Neville-Neil case 'T': 463f5d34df5SGeorge V. Neville-Neil Tflag = 1; 464f5d34df5SGeorge V. Neville-Neil break; 46549f287f8SGeorge V. Neville-Neil case 'x': 46649f287f8SGeorge V. Neville-Neil xflag = 1; 46749f287f8SGeorge V. Neville-Neil break; 468c73d99b5SRuslan Ermilov case 'z': 469c73d99b5SRuslan Ermilov zflag = 1; 470c73d99b5SRuslan Ermilov break; 4719b50d902SRodney W. Grimes case '?': 4729b50d902SRodney W. Grimes default: 4739b50d902SRodney W. Grimes usage(); 4749b50d902SRodney W. Grimes } 4759b50d902SRodney W. Grimes argv += optind; 4769b50d902SRodney W. Grimes argc -= optind; 4779b50d902SRodney W. Grimes 4789b50d902SRodney W. Grimes #define BACKWARD_COMPATIBILITY 4799b50d902SRodney W. Grimes #ifdef BACKWARD_COMPATIBILITY 4809b50d902SRodney W. Grimes if (*argv) { 4819b50d902SRodney W. Grimes if (isdigit(**argv)) { 4829b50d902SRodney W. Grimes interval = atoi(*argv); 4839b50d902SRodney W. Grimes if (interval <= 0) 4849b50d902SRodney W. Grimes usage(); 4859b50d902SRodney W. Grimes ++argv; 4869b50d902SRodney W. Grimes iflag = 1; 4879b50d902SRodney W. Grimes } 4889b50d902SRodney W. Grimes if (*argv) { 4899b50d902SRodney W. Grimes nlistf = *argv; 4909b50d902SRodney W. Grimes if (*++argv) 4919b50d902SRodney W. Grimes memf = *argv; 4929b50d902SRodney W. Grimes } 4939b50d902SRodney W. Grimes } 4949b50d902SRodney W. Grimes #endif 4959b50d902SRodney W. Grimes 4969b50d902SRodney W. Grimes /* 4979b50d902SRodney W. Grimes * Discard setgid privileges if not the running kernel so that bad 4989b50d902SRodney W. Grimes * guys can't print interesting stuff from kernel memory. 4999b50d902SRodney W. Grimes */ 500feda1a43SJohn Baldwin live = (nlistf == NULL && memf == NULL); 501*a4a889a0SXin LI if (!live) { 502*a4a889a0SXin LI if (setgid(getgid()) != 0) 503*a4a889a0SXin LI xo_err(-1, "setgid"); 504*a4a889a0SXin LI } 5059b50d902SRodney W. Grimes 506f5d34df5SGeorge V. Neville-Neil if (xflag && Tflag) 507ade9ccfeSMarcel Moolenaar xo_errx(1, "-x and -T are incompatible, pick one."); 508f5d34df5SGeorge V. Neville-Neil 5096b463eedSChristian S.J. Peron if (Bflag) { 510feda1a43SJohn Baldwin if (!live) 511feda1a43SJohn Baldwin usage(); 5126b463eedSChristian S.J. Peron bpf_stats(interface); 513ade9ccfeSMarcel Moolenaar xo_finish(); 5146b463eedSChristian S.J. Peron exit(0); 5156b463eedSChristian S.J. Peron } 5169b50d902SRodney W. Grimes if (mflag) { 51783708764SRuslan Ermilov if (!live) { 518feda1a43SJohn Baldwin if (kread(0, NULL, 0) == 0) 51905d1f5bcSAndrey V. Elsukov mbpr(kvmd, nl[N_SFSTAT].n_value); 520d15c5f56SRuslan Ermilov } else 521d4426f28SRobert Watson mbpr(NULL, 0); 522ade9ccfeSMarcel Moolenaar xo_finish(); 5239b50d902SRodney W. Grimes exit(0); 5249b50d902SRodney W. Grimes } 5250153eb66SRobert Watson if (Qflag) { 52688737be2SRobert Watson if (!live) { 52788737be2SRobert Watson if (kread(0, NULL, 0) == 0) 52888737be2SRobert Watson netisr_stats(kvmd); 52988737be2SRobert Watson } else 53088737be2SRobert Watson netisr_stats(NULL); 531ade9ccfeSMarcel Moolenaar xo_finish(); 5320153eb66SRobert Watson exit(0); 5330153eb66SRobert Watson } 534cc63cd56SPeter Wemm #if 0 5359b50d902SRodney W. Grimes /* 5369b50d902SRodney W. Grimes * Keep file descriptors open to avoid overhead 5379b50d902SRodney W. Grimes * of open/close on each call to get* routines. 5389b50d902SRodney W. Grimes */ 5399b50d902SRodney W. Grimes sethostent(1); 5409b50d902SRodney W. Grimes setnetent(1); 541cc63cd56SPeter Wemm #else 542cc63cd56SPeter Wemm /* 543cc63cd56SPeter Wemm * This does not make sense any more with DNS being default over 544cc63cd56SPeter Wemm * the files. Doing a setXXXXent(1) causes a tcp connection to be 545cc63cd56SPeter Wemm * used for the queries, which is slower. 546cc63cd56SPeter Wemm */ 547cc63cd56SPeter Wemm #endif 548cf5e44f8SRuslan Ermilov if (iflag && !sflag) { 549ade9ccfeSMarcel Moolenaar xo_open_container("statistics"); 550fc47e028SAlexander V. Chernikov intpr(interval, NULL, af); 551ade9ccfeSMarcel Moolenaar xo_close_container("statistics"); 552ade9ccfeSMarcel Moolenaar xo_finish(); 5539b50d902SRodney W. Grimes exit(0); 5549b50d902SRodney W. Grimes } 5559b50d902SRodney W. Grimes if (rflag) { 556ade9ccfeSMarcel Moolenaar xo_open_container("statistics"); 5575d6d7e75SGleb Smirnoff if (sflag) { 558fc47e028SAlexander V. Chernikov rt_stats(); 5595d6d7e75SGleb Smirnoff flowtable_stats(); 5605d6d7e75SGleb Smirnoff } else 561fc47e028SAlexander V. Chernikov routepr(fib, af); 562ade9ccfeSMarcel Moolenaar xo_close_container("statistics"); 563ade9ccfeSMarcel Moolenaar xo_finish(); 5649b50d902SRodney W. Grimes exit(0); 5659b50d902SRodney W. Grimes } 566fc47e028SAlexander V. Chernikov 5679b50d902SRodney W. Grimes if (gflag) { 568ade9ccfeSMarcel Moolenaar xo_open_container("statistics"); 569cfa1ca9dSYoshinobu Inoue if (sflag) { 570cfa1ca9dSYoshinobu Inoue if (af == AF_INET || af == AF_UNSPEC) 571fc47e028SAlexander V. Chernikov mrt_stats(); 572cfa1ca9dSYoshinobu Inoue #ifdef INET6 573cfa1ca9dSYoshinobu Inoue if (af == AF_INET6 || af == AF_UNSPEC) 574fc47e028SAlexander V. Chernikov mrt6_stats(); 575cfa1ca9dSYoshinobu Inoue #endif 576cfa1ca9dSYoshinobu Inoue } else { 577cfa1ca9dSYoshinobu Inoue if (af == AF_INET || af == AF_UNSPEC) 578fc47e028SAlexander V. Chernikov mroutepr(); 579cfa1ca9dSYoshinobu Inoue #ifdef INET6 580cfa1ca9dSYoshinobu Inoue if (af == AF_INET6 || af == AF_UNSPEC) 581fc47e028SAlexander V. Chernikov mroute6pr(); 582cfa1ca9dSYoshinobu Inoue #endif 583cfa1ca9dSYoshinobu Inoue } 584ade9ccfeSMarcel Moolenaar xo_close_container("statistics"); 585ade9ccfeSMarcel Moolenaar xo_finish(); 5869b50d902SRodney W. Grimes exit(0); 5879b50d902SRodney W. Grimes } 588cfa1ca9dSYoshinobu Inoue 589fc47e028SAlexander V. Chernikov /* Load all necessary kvm symbols */ 590fc47e028SAlexander V. Chernikov kresolve_list(nl); 591fc47e028SAlexander V. Chernikov 592cf5e44f8SRuslan Ermilov if (tp) { 593ade9ccfeSMarcel Moolenaar xo_open_container("statistics"); 594ade9ccfeSMarcel Moolenaar printproto(tp, tp->pr_name, &first); 595ade9ccfeSMarcel Moolenaar if (!first) 596ade9ccfeSMarcel Moolenaar xo_close_list("socket"); 597ade9ccfeSMarcel Moolenaar xo_close_container("statistics"); 598ade9ccfeSMarcel Moolenaar xo_finish(); 599cf5e44f8SRuslan Ermilov exit(0); 600cf5e44f8SRuslan Ermilov } 601ade9ccfeSMarcel Moolenaar 602ade9ccfeSMarcel Moolenaar xo_open_container("statistics"); 603cfa1ca9dSYoshinobu Inoue if (af == AF_INET || af == AF_UNSPEC) 6049b50d902SRodney W. Grimes for (tp = protox; tp->pr_name; tp++) 605ade9ccfeSMarcel Moolenaar printproto(tp, tp->pr_name, &first); 606cfa1ca9dSYoshinobu Inoue #ifdef INET6 607cfa1ca9dSYoshinobu Inoue if (af == AF_INET6 || af == AF_UNSPEC) 608cfa1ca9dSYoshinobu Inoue for (tp = ip6protox; tp->pr_name; tp++) 609ade9ccfeSMarcel Moolenaar printproto(tp, tp->pr_name, &first); 610cfa1ca9dSYoshinobu Inoue #endif /*INET6*/ 6113b8a8567SJun-ichiro itojun Hagino #ifdef IPSEC 6123b8a8567SJun-ichiro itojun Hagino if (af == PF_KEY || af == AF_UNSPEC) 6133b8a8567SJun-ichiro itojun Hagino for (tp = pfkeyprotox; tp->pr_name; tp++) 614ade9ccfeSMarcel Moolenaar printproto(tp, tp->pr_name, &first); 6153b8a8567SJun-ichiro itojun Hagino #endif /*IPSEC*/ 616690f477dSSam Leffler #ifdef NETGRAPH 6174cf49a43SJulian Elischer if (af == AF_NETGRAPH || af == AF_UNSPEC) 6184cf49a43SJulian Elischer for (tp = netgraphprotox; tp->pr_name; tp++) 619ade9ccfeSMarcel Moolenaar printproto(tp, tp->pr_name, &first); 620690f477dSSam Leffler #endif /* NETGRAPH */ 621f1c0a78dSMaxim Konovalov if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) 622feda1a43SJohn Baldwin unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value, 623963b7ccdSRobert Watson nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value, 624ade9ccfeSMarcel Moolenaar nl[N_UNP_SPHEAD].n_value, &first); 625ade9ccfeSMarcel Moolenaar 626ade9ccfeSMarcel Moolenaar if (!first) 627ade9ccfeSMarcel Moolenaar xo_close_list("socket"); 628ade9ccfeSMarcel Moolenaar xo_close_container("statistics"); 629ade9ccfeSMarcel Moolenaar xo_finish(); 6309b50d902SRodney W. Grimes exit(0); 6319b50d902SRodney W. Grimes } 6329b50d902SRodney W. Grimes 6339b50d902SRodney W. Grimes /* 6349b50d902SRodney W. Grimes * Print out protocol statistics or control blocks (per sflag). 6359b50d902SRodney W. Grimes * If the interface was not specifically requested, and the symbol 6369b50d902SRodney W. Grimes * is not in the namelist, ignore this one. 6379b50d902SRodney W. Grimes */ 6389b50d902SRodney W. Grimes static void 639ade9ccfeSMarcel Moolenaar printproto(struct protox *tp, const char *name, bool *first) 6409b50d902SRodney W. Grimes { 641feda1a43SJohn Baldwin void (*pr)(u_long, const char *, int, int); 6429b50d902SRodney W. Grimes u_long off; 643ade9ccfeSMarcel Moolenaar bool doingdblocks = false; 6449b50d902SRodney W. Grimes 6459b50d902SRodney W. Grimes if (sflag) { 646cfa1ca9dSYoshinobu Inoue if (iflag) { 647cfa1ca9dSYoshinobu Inoue if (tp->pr_istats) 648fc47e028SAlexander V. Chernikov intpr(interval, tp->pr_istats, af); 649cf5e44f8SRuslan Ermilov else if (pflag) 650ade9ccfeSMarcel Moolenaar xo_message("%s: no per-interface stats routine", 651cf5e44f8SRuslan Ermilov tp->pr_name); 652cfa1ca9dSYoshinobu Inoue return; 653feda1a43SJohn Baldwin } else { 6549b50d902SRodney W. Grimes pr = tp->pr_stats; 655cf5e44f8SRuslan Ermilov if (!pr) { 656cf5e44f8SRuslan Ermilov if (pflag) 657ade9ccfeSMarcel Moolenaar xo_message("%s: no stats routine", 658cf5e44f8SRuslan Ermilov tp->pr_name); 659cf5e44f8SRuslan Ermilov return; 660cf5e44f8SRuslan Ermilov } 661feda1a43SJohn Baldwin if (tp->pr_usesysctl && live) 662feda1a43SJohn Baldwin off = 0; 663feda1a43SJohn Baldwin else if (tp->pr_sindex < 0) { 664feda1a43SJohn Baldwin if (pflag) 665ade9ccfeSMarcel Moolenaar xo_message("%s: stats routine doesn't " 666ade9ccfeSMarcel Moolenaar "work on cores", tp->pr_name); 667feda1a43SJohn Baldwin return; 668feda1a43SJohn Baldwin } else 669feda1a43SJohn Baldwin off = nl[tp->pr_sindex].n_value; 670cfa1ca9dSYoshinobu Inoue } 6719b50d902SRodney W. Grimes } else { 672ade9ccfeSMarcel Moolenaar doingdblocks = true; 6739b50d902SRodney W. Grimes pr = tp->pr_cblocks; 674cf5e44f8SRuslan Ermilov if (!pr) { 675cf5e44f8SRuslan Ermilov if (pflag) 676ade9ccfeSMarcel Moolenaar xo_message("%s: no PCB routine", tp->pr_name); 677cf5e44f8SRuslan Ermilov return; 678cf5e44f8SRuslan Ermilov } 679feda1a43SJohn Baldwin if (tp->pr_usesysctl && live) 680feda1a43SJohn Baldwin off = 0; 681feda1a43SJohn Baldwin else if (tp->pr_index < 0) { 682feda1a43SJohn Baldwin if (pflag) 683ade9ccfeSMarcel Moolenaar xo_message("%s: PCB routine doesn't work on " 684ade9ccfeSMarcel Moolenaar "cores", tp->pr_name); 685feda1a43SJohn Baldwin return; 686feda1a43SJohn Baldwin } else 687feda1a43SJohn Baldwin off = nl[tp->pr_index].n_value; 6889b50d902SRodney W. Grimes } 689feda1a43SJohn Baldwin if (pr != NULL && (off || (live && tp->pr_usesysctl) || 690ade9ccfeSMarcel Moolenaar af != AF_UNSPEC)) { 691ade9ccfeSMarcel Moolenaar if (doingdblocks && *first) { 692ade9ccfeSMarcel Moolenaar xo_open_list("socket"); 693ade9ccfeSMarcel Moolenaar *first = false; 694ade9ccfeSMarcel Moolenaar } 695ade9ccfeSMarcel Moolenaar 696feda1a43SJohn Baldwin (*pr)(off, name, af, tp->pr_protocol); 6979b50d902SRodney W. Grimes } 698ade9ccfeSMarcel Moolenaar } 6999b50d902SRodney W. Grimes 70029dde48dSGleb Smirnoff static int 70129dde48dSGleb Smirnoff kvmd_init(void) 7029b50d902SRodney W. Grimes { 703feda1a43SJohn Baldwin char errbuf[_POSIX2_LINE_MAX]; 704feda1a43SJohn Baldwin 70529dde48dSGleb Smirnoff if (kvmd != NULL) 70629dde48dSGleb Smirnoff return (0); 70729dde48dSGleb Smirnoff 708feda1a43SJohn Baldwin kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 709*a4a889a0SXin LI if (setgid(getgid()) != 0) 710*a4a889a0SXin LI xo_err(-1, "setgid"); 71129dde48dSGleb Smirnoff 71229dde48dSGleb Smirnoff if (kvmd == NULL) { 713ade9ccfeSMarcel Moolenaar xo_warnx("kvm not available: %s", errbuf); 71429dde48dSGleb Smirnoff return (-1); 71529dde48dSGleb Smirnoff } 71629dde48dSGleb Smirnoff 717fc47e028SAlexander V. Chernikov return (0); 718fc47e028SAlexander V. Chernikov } 719fc47e028SAlexander V. Chernikov 720fc47e028SAlexander V. Chernikov /* 721fc47e028SAlexander V. Chernikov * Resolve symbol list, return 0 on success. 722fc47e028SAlexander V. Chernikov */ 723fc47e028SAlexander V. Chernikov int 724fc47e028SAlexander V. Chernikov kresolve_list(struct nlist *_nl) 725fc47e028SAlexander V. Chernikov { 726fc47e028SAlexander V. Chernikov 727fc47e028SAlexander V. Chernikov if ((kvmd == NULL) && (kvmd_init() != 0)) 728fc47e028SAlexander V. Chernikov return (-1); 729fc47e028SAlexander V. Chernikov 730fc47e028SAlexander V. Chernikov if (_nl[0].n_type != 0) 731fc47e028SAlexander V. Chernikov return (0); 732fc47e028SAlexander V. Chernikov 733fc47e028SAlexander V. Chernikov if (kvm_nlist(kvmd, _nl) < 0) { 73499453c6aSPoul-Henning Kamp if (nlistf) 735ade9ccfeSMarcel Moolenaar xo_errx(1, "%s: kvm_nlist: %s", nlistf, 73699453c6aSPoul-Henning Kamp kvm_geterr(kvmd)); 73799453c6aSPoul-Henning Kamp else 738ade9ccfeSMarcel Moolenaar xo_errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); 73999453c6aSPoul-Henning Kamp } 74099453c6aSPoul-Henning Kamp 74129dde48dSGleb Smirnoff return (0); 74229dde48dSGleb Smirnoff } 74329dde48dSGleb Smirnoff 74429dde48dSGleb Smirnoff /* 74529dde48dSGleb Smirnoff * Read kernel memory, return 0 on success. 74629dde48dSGleb Smirnoff */ 74729dde48dSGleb Smirnoff int 74829dde48dSGleb Smirnoff kread(u_long addr, void *buf, size_t size) 74929dde48dSGleb Smirnoff { 75029dde48dSGleb Smirnoff 75129dde48dSGleb Smirnoff if (kvmd_init() < 0) 75299453c6aSPoul-Henning Kamp return (-1); 75329dde48dSGleb Smirnoff 754c6620a13SPoul-Henning Kamp if (!buf) 755c6620a13SPoul-Henning Kamp return (0); 756feda1a43SJohn Baldwin if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) { 757ade9ccfeSMarcel Moolenaar xo_warnx("%s", kvm_geterr(kvmd)); 7589b50d902SRodney W. Grimes return (-1); 7599b50d902SRodney W. Grimes } 7609b50d902SRodney W. Grimes return (0); 7619b50d902SRodney W. Grimes } 7629b50d902SRodney W. Grimes 76329dde48dSGleb Smirnoff /* 764e3a7aa6fSGleb Smirnoff * Read single counter(9). 765e3a7aa6fSGleb Smirnoff */ 766e3a7aa6fSGleb Smirnoff uint64_t 767e3a7aa6fSGleb Smirnoff kread_counter(u_long addr) 768e3a7aa6fSGleb Smirnoff { 769e3a7aa6fSGleb Smirnoff 770e3a7aa6fSGleb Smirnoff if (kvmd_init() < 0) 771e3a7aa6fSGleb Smirnoff return (-1); 772e3a7aa6fSGleb Smirnoff 773e3a7aa6fSGleb Smirnoff return (kvm_counter_u64_fetch(kvmd, addr)); 774e3a7aa6fSGleb Smirnoff } 775e3a7aa6fSGleb Smirnoff 776e3a7aa6fSGleb Smirnoff /* 77729dde48dSGleb Smirnoff * Read an array of N counters in kernel memory into array of N uint64_t's. 77829dde48dSGleb Smirnoff */ 77929dde48dSGleb Smirnoff int 7805da0521fSAndrey V. Elsukov kread_counters(u_long addr, void *buf, size_t size) 78129dde48dSGleb Smirnoff { 782794c57d3SMark Johnston uint64_t *c; 783794c57d3SMark Johnston u_long *counters; 784794c57d3SMark Johnston size_t i, n; 78529dde48dSGleb Smirnoff 78629dde48dSGleb Smirnoff if (kvmd_init() < 0) 78729dde48dSGleb Smirnoff return (-1); 78829dde48dSGleb Smirnoff 789794c57d3SMark Johnston if (size % sizeof(uint64_t) != 0) { 790794c57d3SMark Johnston xo_warnx("kread_counters: invalid counter set size"); 7915da0521fSAndrey V. Elsukov return (-1); 7925da0521fSAndrey V. Elsukov } 793794c57d3SMark Johnston 794794c57d3SMark Johnston n = size / sizeof(uint64_t); 795794c57d3SMark Johnston if ((counters = malloc(n * sizeof(u_long))) == NULL) 796794c57d3SMark Johnston xo_err(-1, "malloc"); 797794c57d3SMark Johnston if (kread(addr, counters, n * sizeof(u_long)) < 0) { 798794c57d3SMark Johnston free(counters); 799794c57d3SMark Johnston return (-1); 800794c57d3SMark Johnston } 801794c57d3SMark Johnston 802794c57d3SMark Johnston c = buf; 803794c57d3SMark Johnston for (i = 0; i < n; i++) 804794c57d3SMark Johnston c[i] = kvm_counter_u64_fetch(kvmd, counters[i]); 805794c57d3SMark Johnston 806794c57d3SMark Johnston free(counters); 80729dde48dSGleb Smirnoff return (0); 80829dde48dSGleb Smirnoff } 80929dde48dSGleb Smirnoff 810a01e3379SDavid Malone const char * 8117b95a1ebSYaroslav Tykhiy plural(uintmax_t n) 8129b50d902SRodney W. Grimes { 8139b50d902SRodney W. Grimes return (n != 1 ? "s" : ""); 8149b50d902SRodney W. Grimes } 8159b50d902SRodney W. Grimes 816a01e3379SDavid Malone const char * 8177b95a1ebSYaroslav Tykhiy plurales(uintmax_t n) 8189b50d902SRodney W. Grimes { 8199b50d902SRodney W. Grimes return (n != 1 ? "es" : ""); 8209b50d902SRodney W. Grimes } 8219b50d902SRodney W. Grimes 822f99a4046SMike Makonnen const char * 8237b95a1ebSYaroslav Tykhiy pluralies(uintmax_t n) 824f99a4046SMike Makonnen { 825f99a4046SMike Makonnen return (n != 1 ? "ies" : "y"); 826f99a4046SMike Makonnen } 827f99a4046SMike Makonnen 8289b50d902SRodney W. Grimes /* 8299b50d902SRodney W. Grimes * Find the protox for the given "well-known" name. 8309b50d902SRodney W. Grimes */ 8319b50d902SRodney W. Grimes static struct protox * 832096146f8SYaroslav Tykhiy knownname(const char *name) 8339b50d902SRodney W. Grimes { 8349b50d902SRodney W. Grimes struct protox **tpp, *tp; 8359b50d902SRodney W. Grimes 8369b50d902SRodney W. Grimes for (tpp = protoprotox; *tpp; tpp++) 8379b50d902SRodney W. Grimes for (tp = *tpp; tp->pr_name; tp++) 8389b50d902SRodney W. Grimes if (strcmp(tp->pr_name, name) == 0) 8399b50d902SRodney W. Grimes return (tp); 8409b50d902SRodney W. Grimes return (NULL); 8419b50d902SRodney W. Grimes } 8429b50d902SRodney W. Grimes 8439b50d902SRodney W. Grimes /* 8449b50d902SRodney W. Grimes * Find the protox corresponding to name. 8459b50d902SRodney W. Grimes */ 8469b50d902SRodney W. Grimes static struct protox * 847096146f8SYaroslav Tykhiy name2protox(const char *name) 8489b50d902SRodney W. Grimes { 8499b50d902SRodney W. Grimes struct protox *tp; 8509b50d902SRodney W. Grimes char **alias; /* alias from p->aliases */ 8519b50d902SRodney W. Grimes struct protoent *p; 8529b50d902SRodney W. Grimes 8539b50d902SRodney W. Grimes /* 8549b50d902SRodney W. Grimes * Try to find the name in the list of "well-known" names. If that 8559b50d902SRodney W. Grimes * fails, check if name is an alias for an Internet protocol. 8569b50d902SRodney W. Grimes */ 857cfa1ca9dSYoshinobu Inoue if ((tp = knownname(name)) != NULL) 8589b50d902SRodney W. Grimes return (tp); 8599b50d902SRodney W. Grimes 8609b50d902SRodney W. Grimes setprotoent(1); /* make protocol lookup cheaper */ 861cfa1ca9dSYoshinobu Inoue while ((p = getprotoent()) != NULL) { 8629b50d902SRodney W. Grimes /* assert: name not same as p->name */ 8639b50d902SRodney W. Grimes for (alias = p->p_aliases; *alias; alias++) 8649b50d902SRodney W. Grimes if (strcmp(name, *alias) == 0) { 8659b50d902SRodney W. Grimes endprotoent(); 8669b50d902SRodney W. Grimes return (knownname(p->p_name)); 8679b50d902SRodney W. Grimes } 8689b50d902SRodney W. Grimes } 8699b50d902SRodney W. Grimes endprotoent(); 8709b50d902SRodney W. Grimes return (NULL); 8719b50d902SRodney W. Grimes } 8729b50d902SRodney W. Grimes 8739b50d902SRodney W. Grimes static void 8745e051718SAssar Westerlund usage(void) 8759b50d902SRodney W. Grimes { 876ade9ccfeSMarcel Moolenaar (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", 87785b0f0f3SAdrian Chadd "usage: netstat [-46AaLnRSTWx] [-f protocol_family | -p protocol]\n" 8781cb467b1SRuslan Ermilov " [-M core] [-N system]", 87917ed2e8eSAlexander V. Chernikov " netstat -i | -I interface [-46abdhnW] [-f address_family]\n" 880d44ddba9SRuslan Ermilov " [-M core] [-N system]", 881fd2c6bc9SAllan Jude " netstat -w wait [-I interface] [-46d] [-M core] [-N system]\n" 882fd2c6bc9SAllan Jude " [-q howmany]", 883fd2c6bc9SAllan Jude " netstat -s [-46sz] [-f protocol_family | -p protocol]\n" 88482d383bcSRuslan Ermilov " [-M core] [-N system]", 885fd2c6bc9SAllan Jude " netstat -i | -I interface -s [-46s]\n" 886fd2c6bc9SAllan Jude " [-f protocol_family | -p protocol] [-M core] [-N system]", 88749c2dc64SMaxim Konovalov " netstat -m [-M core] [-N system]", 888fd2c6bc9SAllan Jude " netstat -B [-z] [-I interface]", 889fd2c6bc9SAllan Jude " netstat -r [-46AnW] [-F fibnum] [-f address_family]\n" 890fd2c6bc9SAllan Jude " [-M core] [-N system]", 8911cb467b1SRuslan Ermilov " netstat -rs [-s] [-M core] [-N system]", 89217ed2e8eSAlexander V. Chernikov " netstat -g [-46W] [-f address_family] [-M core] [-N system]", 89317ed2e8eSAlexander V. Chernikov " netstat -gs [-46s] [-f address_family] [-M core] [-N system]", 8940153eb66SRobert Watson " netstat -Q"); 895ade9ccfeSMarcel Moolenaar xo_finish(); 8969b50d902SRodney W. Grimes exit(1); 8979b50d902SRodney W. Grimes } 898