19b50d902SRodney W. Grimes /* 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 * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #ifndef lint 355d422d6aSPhilippe Charnier char const copyright[] = 369b50d902SRodney W. Grimes "@(#) Copyright (c) 1983, 1988, 1993\n\ 379b50d902SRodney W. Grimes Regents of the University of California. All rights reserved.\n"; 389b50d902SRodney W. Grimes #endif /* not lint */ 399b50d902SRodney W. Grimes 409b50d902SRodney W. Grimes #ifndef lint 415d422d6aSPhilippe Charnier #if 0 429b50d902SRodney W. Grimes static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94"; 435d422d6aSPhilippe Charnier #endif 445d422d6aSPhilippe Charnier static const char rcsid[] = 45c3aac50fSPeter Wemm "$FreeBSD$"; 469b50d902SRodney W. Grimes #endif /* not lint */ 479b50d902SRodney W. Grimes 489b50d902SRodney W. Grimes #include <sys/param.h> 499b50d902SRodney W. Grimes #include <sys/file.h> 509b50d902SRodney W. Grimes #include <sys/protosw.h> 519b50d902SRodney W. Grimes #include <sys/socket.h> 529b50d902SRodney W. Grimes 539b50d902SRodney W. Grimes #include <netinet/in.h> 549b50d902SRodney W. Grimes 554cf49a43SJulian Elischer #include <netgraph/ng_socket.h> 564cf49a43SJulian Elischer 579b50d902SRodney W. Grimes #include <ctype.h> 585d422d6aSPhilippe Charnier #include <err.h> 599b50d902SRodney W. Grimes #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> 649b50d902SRodney W. Grimes #include <paths.h> 659b50d902SRodney W. Grimes #include <stdio.h> 669b50d902SRodney W. Grimes #include <stdlib.h> 679b50d902SRodney W. Grimes #include <string.h> 689b50d902SRodney W. Grimes #include <unistd.h> 699b50d902SRodney W. Grimes #include "netstat.h" 709b50d902SRodney W. Grimes 71c6620a13SPoul-Henning Kamp static struct nlist nl[] = { 724f81ef50SGarrett Wollman #define N_IFNET 0 739b50d902SRodney W. Grimes { "_ifnet" }, 744f81ef50SGarrett Wollman #define N_IMP 1 759b50d902SRodney W. Grimes { "_imp_softc" }, 764f81ef50SGarrett Wollman #define N_RTSTAT 2 779b50d902SRodney W. Grimes { "_rtstat" }, 784f81ef50SGarrett Wollman #define N_UNIXSW 3 79f3117d66SPeter Wemm { "_localsw" }, 804f81ef50SGarrett Wollman #define N_IDP 4 819b50d902SRodney W. Grimes { "_nspcb"}, 824f81ef50SGarrett Wollman #define N_IDPSTAT 5 839b50d902SRodney W. Grimes { "_idpstat"}, 844f81ef50SGarrett Wollman #define N_SPPSTAT 6 859b50d902SRodney W. Grimes { "_spp_istat"}, 864f81ef50SGarrett Wollman #define N_NSERR 7 879b50d902SRodney W. Grimes { "_ns_errstat"}, 884f81ef50SGarrett Wollman #define N_CLNPSTAT 8 899b50d902SRodney W. Grimes { "_clnp_stat"}, 904f81ef50SGarrett Wollman #define IN_NOTUSED 9 919b50d902SRodney W. Grimes { "_tp_inpcb" }, 924f81ef50SGarrett Wollman #define ISO_TP 10 939b50d902SRodney W. Grimes { "_tp_refinfo" }, 944f81ef50SGarrett Wollman #define N_TPSTAT 11 959b50d902SRodney W. Grimes { "_tp_stat" }, 964f81ef50SGarrett Wollman #define N_ESISSTAT 12 979b50d902SRodney W. Grimes { "_esis_stat"}, 984f81ef50SGarrett Wollman #define N_NIMP 13 999b50d902SRodney W. Grimes { "_nimp"}, 1004f81ef50SGarrett Wollman #define N_RTREE 14 1019b50d902SRodney W. Grimes { "_rt_tables"}, 1024f81ef50SGarrett Wollman #define N_CLTP 15 1039b50d902SRodney W. Grimes { "_cltb"}, 1044f81ef50SGarrett Wollman #define N_CLTPSTAT 16 1059b50d902SRodney W. Grimes { "_cltpstat"}, 1064f81ef50SGarrett Wollman #define N_NFILE 17 1079b50d902SRodney W. Grimes { "_nfile" }, 1084f81ef50SGarrett Wollman #define N_FILE 18 1099b50d902SRodney W. Grimes { "_file" }, 11067a451ccSBill Fenner #define N_MRTSTAT 19 1119b50d902SRodney W. Grimes { "_mrtstat" }, 11267a451ccSBill Fenner #define N_MFCTABLE 20 113ef105c25SGarrett Wollman { "_mfctable" }, 11467a451ccSBill Fenner #define N_VIFTABLE 21 1159b50d902SRodney W. Grimes { "_viftable" }, 11667a451ccSBill Fenner #define N_IPX 22 117cc6a66f2SJulian Elischer { "_ipxpcb"}, 11867a451ccSBill Fenner #define N_IPXSTAT 23 119cc6a66f2SJulian Elischer { "_ipxstat"}, 12067a451ccSBill Fenner #define N_SPXSTAT 24 121cc6a66f2SJulian Elischer { "_spx_istat"}, 12267a451ccSBill Fenner #define N_DDPSTAT 25 12363bf4575SJulian Elischer { "_ddpstat"}, 12467a451ccSBill Fenner #define N_DDPCB 26 12563bf4575SJulian Elischer { "_ddpcb"}, 1264cf49a43SJulian Elischer #define N_NGSOCKS 27 1274cf49a43SJulian Elischer { "_ngsocklist"}, 128cfa1ca9dSYoshinobu Inoue #define N_IP6STAT 28 129cfa1ca9dSYoshinobu Inoue { "_ip6stat" }, 130cfa1ca9dSYoshinobu Inoue #define N_ICMP6STAT 29 131cfa1ca9dSYoshinobu Inoue { "_icmp6stat" }, 132cfa1ca9dSYoshinobu Inoue #ifdef notyet 133cfa1ca9dSYoshinobu Inoue #define N_IPSECSTAT 30 134cfa1ca9dSYoshinobu Inoue { "_ipsecstat" }, 135cfa1ca9dSYoshinobu Inoue #define N_IPSEC6STAT 31 136cfa1ca9dSYoshinobu Inoue { "_ipsec6stat" }, 137cfa1ca9dSYoshinobu Inoue #define N_PIM6STAT 32 138cfa1ca9dSYoshinobu Inoue { "_pim6stat" }, 139cfa1ca9dSYoshinobu Inoue #define N_MRT6PROTO 33 140cfa1ca9dSYoshinobu Inoue { "_ip6_mrtproto" }, 141cfa1ca9dSYoshinobu Inoue #define N_MRT6STAT 34 142cfa1ca9dSYoshinobu Inoue { "_mrt6stat" }, 143cfa1ca9dSYoshinobu Inoue #define N_MF6CTABLE 35 144cfa1ca9dSYoshinobu Inoue { "_mf6ctable" }, 145cfa1ca9dSYoshinobu Inoue #define N_MIF6TABLE 36 146cfa1ca9dSYoshinobu Inoue { "_mif6table" }, 147cfa1ca9dSYoshinobu Inoue #endif 1487d56c0eeSAlexander Langer { "" }, 1499b50d902SRodney W. Grimes }; 1509b50d902SRodney W. Grimes 1519b50d902SRodney W. Grimes struct protox { 1529b50d902SRodney W. Grimes u_char pr_index; /* index into nlist of cb head */ 1539b50d902SRodney W. Grimes u_char pr_sindex; /* index into nlist of stat block */ 1549b50d902SRodney W. Grimes u_char pr_wanted; /* 1 if wanted, 0 otherwise */ 1559b50d902SRodney W. Grimes void (*pr_cblocks)(); /* control blocks printing routine */ 1569b50d902SRodney W. Grimes void (*pr_stats)(); /* statistics printing routine */ 157cfa1ca9dSYoshinobu Inoue void (*pr_istats)(); /* per/if statistics printing routine */ 1589b50d902SRodney W. Grimes char *pr_name; /* well-known name */ 1594f81ef50SGarrett Wollman int pr_usesysctl; /* true if we use sysctl, not kvm */ 1609b50d902SRodney W. Grimes } protox[] = { 1614f81ef50SGarrett Wollman { -1, -1, 1, protopr, 162cfa1ca9dSYoshinobu Inoue tcp_stats, NULL, "tcp", IPPROTO_TCP }, 1634f81ef50SGarrett Wollman { -1, -1, 1, protopr, 164cfa1ca9dSYoshinobu Inoue udp_stats, NULL, "udp", IPPROTO_UDP }, 1654f81ef50SGarrett Wollman { -1, -1, 1, protopr, 166cfa1ca9dSYoshinobu Inoue NULL, NULL, "divert",IPPROTO_DIVERT }, 1674f81ef50SGarrett Wollman { -1, -1, 1, protopr, 168cfa1ca9dSYoshinobu Inoue ip_stats, NULL, "ip", IPPROTO_RAW }, 1694f81ef50SGarrett Wollman { -1, -1, 1, protopr, 170cfa1ca9dSYoshinobu Inoue icmp_stats, NULL, "icmp", IPPROTO_ICMP }, 1714f81ef50SGarrett Wollman { -1, -1, 1, protopr, 172cfa1ca9dSYoshinobu Inoue igmp_stats, NULL, "igmp", IPPROTO_IGMP }, 173cfa1ca9dSYoshinobu Inoue #ifdef IPSEC 174cfa1ca9dSYoshinobu Inoue { -1, N_IPSECSTAT, 1, 0, 175cfa1ca9dSYoshinobu Inoue ipsec_stats, NULL, "ipsec", 0}, 176cfa1ca9dSYoshinobu Inoue #endif 1770024d1dbSLuigi Rizzo { -1, -1, 1, protopr, 178cfa1ca9dSYoshinobu Inoue bdg_stats, NULL, "bdg", 1 /* bridging... */ }, 1799b50d902SRodney W. Grimes { -1, -1, 0, 0, 180cfa1ca9dSYoshinobu Inoue 0, NULL, 0 } 1819b50d902SRodney W. Grimes }; 1829b50d902SRodney W. Grimes 183cfa1ca9dSYoshinobu Inoue #ifdef INET6 184cfa1ca9dSYoshinobu Inoue struct protox ip6protox[] = { 185cfa1ca9dSYoshinobu Inoue { -1, -1, 1, protopr, 186cfa1ca9dSYoshinobu Inoue tcp_stats, NULL, "tcp", IPPROTO_TCP }, 187cfa1ca9dSYoshinobu Inoue { -1, -1, 1, protopr, 188cfa1ca9dSYoshinobu Inoue udp_stats, NULL, "udp", IPPROTO_UDP }, 189cfa1ca9dSYoshinobu Inoue { -1, N_IP6STAT, 1, 0, 190cfa1ca9dSYoshinobu Inoue ip6_stats, ip6_ifstats, "ip6", 0 }, 191cfa1ca9dSYoshinobu Inoue { -1, N_ICMP6STAT, 1, 0, 192cfa1ca9dSYoshinobu Inoue icmp6_stats, icmp6_ifstats, "icmp6",0 }, 193cfa1ca9dSYoshinobu Inoue #ifdef IPSEC 194cfa1ca9dSYoshinobu Inoue { -1, N_IPSEC6STAT, 1, 0, 195cfa1ca9dSYoshinobu Inoue ipsec_stats, NULL, "ipsec6",0 }, 196cfa1ca9dSYoshinobu Inoue #endif 197cfa1ca9dSYoshinobu Inoue #ifdef notyet 198cfa1ca9dSYoshinobu Inoue { -1, N_PIM6STAT, 1, 0, 199cfa1ca9dSYoshinobu Inoue pim6_stats, NULL, "pim6", 0 }, 200cfa1ca9dSYoshinobu Inoue #endif 201cfa1ca9dSYoshinobu Inoue { -1, -1, 1, protopr, 202cfa1ca9dSYoshinobu Inoue bdg_stats, NULL, "bdg", 1 /* bridging... */ }, 203cfa1ca9dSYoshinobu Inoue { -1, -1, 0, 0, 204cfa1ca9dSYoshinobu Inoue 0, NULL, 0, 0 } 205cfa1ca9dSYoshinobu Inoue }; 206cfa1ca9dSYoshinobu Inoue #endif /*INET6*/ 207cfa1ca9dSYoshinobu Inoue 20863bf4575SJulian Elischer struct protox atalkprotox[] = { 20963bf4575SJulian Elischer { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, 210cfa1ca9dSYoshinobu Inoue ddp_stats, NULL, "ddp" }, 21163bf4575SJulian Elischer { -1, -1, 0, 0, 212cfa1ca9dSYoshinobu Inoue 0, NULL, 0 } 21363bf4575SJulian Elischer }; 21463bf4575SJulian Elischer 2154cf49a43SJulian Elischer struct protox netgraphprotox[] = { 2164cf49a43SJulian Elischer { N_NGSOCKS, -1, 1, netgraphprotopr, 217cfa1ca9dSYoshinobu Inoue NULL, NULL, "ctrl" }, 2184cf49a43SJulian Elischer { N_NGSOCKS, -1, 1, netgraphprotopr, 219cfa1ca9dSYoshinobu Inoue NULL, NULL, "data" }, 220cfa1ca9dSYoshinobu Inoue { -1, NULL, 0, 0, 221cfa1ca9dSYoshinobu Inoue 0, NULL, 0 } 2224cf49a43SJulian Elischer }; 2234cf49a43SJulian Elischer 224cc6a66f2SJulian Elischer struct protox ipxprotox[] = { 225cc6a66f2SJulian Elischer { N_IPX, N_IPXSTAT, 1, ipxprotopr, 226cfa1ca9dSYoshinobu Inoue ipx_stats, NULL, "ipx", 0 }, 227cc6a66f2SJulian Elischer { N_IPX, N_SPXSTAT, 1, ipxprotopr, 228cfa1ca9dSYoshinobu Inoue spx_stats, NULL, "spx", 0 }, 229cc6a66f2SJulian Elischer { -1, -1, 0, 0, 230cfa1ca9dSYoshinobu Inoue 0, NULL, 0, 0 } 231cc6a66f2SJulian Elischer }; 232cc6a66f2SJulian Elischer 233cbc17e71SGarrett Wollman #ifdef NS 2349b50d902SRodney W. Grimes struct protox nsprotox[] = { 2359b50d902SRodney W. Grimes { N_IDP, N_IDPSTAT, 1, nsprotopr, 236cfa1ca9dSYoshinobu Inoue idp_stats, NULL, "idp" }, 2379b50d902SRodney W. Grimes { N_IDP, N_SPPSTAT, 1, nsprotopr, 238cfa1ca9dSYoshinobu Inoue spp_stats, NULL, "spp" }, 2399b50d902SRodney W. Grimes { -1, N_NSERR, 1, 0, 240cfa1ca9dSYoshinobu Inoue nserr_stats, NULL, "ns_err" }, 2419b50d902SRodney W. Grimes { -1, -1, 0, 0, 242cfa1ca9dSYoshinobu Inoue 0, NULL, 0 } 2439b50d902SRodney W. Grimes }; 244cbc17e71SGarrett Wollman #endif 2459b50d902SRodney W. Grimes 2460761cb29SGarrett Wollman #ifdef ISO 2479b50d902SRodney W. Grimes struct protox isoprotox[] = { 2489b50d902SRodney W. Grimes { ISO_TP, N_TPSTAT, 1, iso_protopr, 249cfa1ca9dSYoshinobu Inoue tp_stats, NULL, "tp" }, 2509b50d902SRodney W. Grimes { N_CLTP, N_CLTPSTAT, 1, iso_protopr, 251cfa1ca9dSYoshinobu Inoue cltp_stats, NULL, "cltp" }, 2529b50d902SRodney W. Grimes { -1, N_CLNPSTAT, 1, 0, 253cfa1ca9dSYoshinobu Inoue clnp_stats, NULL, "clnp"}, 2549b50d902SRodney W. Grimes { -1, N_ESISSTAT, 1, 0, 255cfa1ca9dSYoshinobu Inoue esis_stats, NULL, "esis"}, 2569b50d902SRodney W. Grimes { -1, -1, 0, 0, 257cfa1ca9dSYoshinobu Inoue 0, NULL, 0 } 2589b50d902SRodney W. Grimes }; 2590761cb29SGarrett Wollman #endif 2609b50d902SRodney W. Grimes 261cfa1ca9dSYoshinobu Inoue struct protox *protoprotox[] = { 262cfa1ca9dSYoshinobu Inoue protox, 263cfa1ca9dSYoshinobu Inoue #ifdef INET6 264cfa1ca9dSYoshinobu Inoue ip6protox, 265cfa1ca9dSYoshinobu Inoue #endif 266cfa1ca9dSYoshinobu Inoue ipxprotox, atalkprotox, 267cbc17e71SGarrett Wollman #ifdef NS 268cbc17e71SGarrett Wollman nsprotox, 269cbc17e71SGarrett Wollman #endif 2700761cb29SGarrett Wollman #ifdef ISO 2710761cb29SGarrett Wollman isoprotox, 2720761cb29SGarrett Wollman #endif 2730761cb29SGarrett Wollman NULL }; 2749b50d902SRodney W. Grimes 2759b50d902SRodney W. Grimes static void printproto __P((struct protox *, char *)); 2769b50d902SRodney W. Grimes static void usage __P((void)); 2779b50d902SRodney W. Grimes static struct protox *name2protox __P((char *)); 2789b50d902SRodney W. Grimes static struct protox *knownname __P((char *)); 2799b50d902SRodney W. Grimes 280c6620a13SPoul-Henning Kamp static kvm_t *kvmd; 28199453c6aSPoul-Henning Kamp char *nlistf = NULL, *memf = NULL; 2829b50d902SRodney W. Grimes 2839b50d902SRodney W. Grimes int 2849b50d902SRodney W. Grimes main(argc, argv) 2859b50d902SRodney W. Grimes int argc; 2869b50d902SRodney W. Grimes char *argv[]; 2879b50d902SRodney W. Grimes { 2884cf49a43SJulian Elischer register struct protox *tp = NULL; /* for printing cblocks & stats */ 2899b50d902SRodney W. Grimes int ch; 2909b50d902SRodney W. Grimes 2919b50d902SRodney W. Grimes af = AF_UNSPEC; 2929b50d902SRodney W. Grimes 293ac55add0SGuido van Rooij while ((ch = getopt(argc, argv, "Aabdf:ghI:lLiM:mN:np:rstuw:")) != -1) 2949b50d902SRodney W. Grimes switch(ch) { 2959b50d902SRodney W. Grimes case 'A': 2969b50d902SRodney W. Grimes Aflag = 1; 2979b50d902SRodney W. Grimes break; 2989b50d902SRodney W. Grimes case 'a': 2999b50d902SRodney W. Grimes aflag = 1; 3009b50d902SRodney W. Grimes break; 301e1e293a5SDavid Greenman case 'b': 302e1e293a5SDavid Greenman bflag = 1; 303e1e293a5SDavid Greenman break; 3049b50d902SRodney W. Grimes case 'd': 3059b50d902SRodney W. Grimes dflag = 1; 3069b50d902SRodney W. Grimes break; 3079b50d902SRodney W. Grimes case 'f': 308cbc17e71SGarrett Wollman #ifdef NS 3099b50d902SRodney W. Grimes if (strcmp(optarg, "ns") == 0) 3109b50d902SRodney W. Grimes af = AF_NS; 311cbc17e71SGarrett Wollman else 312cbc17e71SGarrett Wollman #endif 313cbc17e71SGarrett Wollman if (strcmp(optarg, "ipx") == 0) 314cc6a66f2SJulian Elischer af = AF_IPX; 3159b50d902SRodney W. Grimes else if (strcmp(optarg, "inet") == 0) 3169b50d902SRodney W. Grimes af = AF_INET; 317cfa1ca9dSYoshinobu Inoue #ifdef INET6 318cfa1ca9dSYoshinobu Inoue else if (strcmp(optarg, "inet6") == 0) 319cfa1ca9dSYoshinobu Inoue af = AF_INET6; 320cfa1ca9dSYoshinobu Inoue #endif /*INET6*/ 3219b50d902SRodney W. Grimes else if (strcmp(optarg, "unix") == 0) 3229b50d902SRodney W. Grimes af = AF_UNIX; 32363bf4575SJulian Elischer else if (strcmp(optarg, "atalk") == 0) 32463bf4575SJulian Elischer af = AF_APPLETALK; 3254cf49a43SJulian Elischer else if (strcmp(optarg, "ng") == 0 3264cf49a43SJulian Elischer || strcmp(optarg, "netgraph") == 0) 3274cf49a43SJulian Elischer af = AF_NETGRAPH; 3280761cb29SGarrett Wollman #ifdef ISO 3299b50d902SRodney W. Grimes else if (strcmp(optarg, "iso") == 0) 3309b50d902SRodney W. Grimes af = AF_ISO; 3310761cb29SGarrett Wollman #endif 3329b50d902SRodney W. Grimes else { 33351e7d42cSGarrett Wollman errx(1, "%s: unknown address family", optarg); 3349b50d902SRodney W. Grimes } 3359b50d902SRodney W. Grimes break; 3369b50d902SRodney W. Grimes case 'g': 3379b50d902SRodney W. Grimes gflag = 1; 3389b50d902SRodney W. Grimes break; 3399b50d902SRodney W. Grimes case 'I': { 3409b50d902SRodney W. Grimes char *cp; 3419b50d902SRodney W. Grimes 3429b50d902SRodney W. Grimes iflag = 1; 3439b50d902SRodney W. Grimes for (cp = interface = optarg; isalpha(*cp); cp++) 3449b50d902SRodney W. Grimes continue; 3459b50d902SRodney W. Grimes unit = atoi(cp); 3469b50d902SRodney W. Grimes break; 3479b50d902SRodney W. Grimes } 3489b50d902SRodney W. Grimes case 'i': 3499b50d902SRodney W. Grimes iflag = 1; 3509b50d902SRodney W. Grimes break; 351cfa1ca9dSYoshinobu Inoue case 'l': 352cfa1ca9dSYoshinobu Inoue lflag = 1; 353cfa1ca9dSYoshinobu Inoue break; 354ac55add0SGuido van Rooij case 'L': 355ac55add0SGuido van Rooij Lflag = 1; 356ac55add0SGuido van Rooij break; 3579b50d902SRodney W. Grimes case 'M': 3589b50d902SRodney W. Grimes memf = optarg; 3599b50d902SRodney W. Grimes break; 3609b50d902SRodney W. Grimes case 'm': 3619b50d902SRodney W. Grimes mflag = 1; 3629b50d902SRodney W. Grimes break; 3639b50d902SRodney W. Grimes case 'N': 3649b50d902SRodney W. Grimes nlistf = optarg; 3659b50d902SRodney W. Grimes break; 3669b50d902SRodney W. Grimes case 'n': 3679b50d902SRodney W. Grimes nflag = 1; 3689b50d902SRodney W. Grimes break; 3699b50d902SRodney W. Grimes case 'p': 3709b50d902SRodney W. Grimes if ((tp = name2protox(optarg)) == NULL) { 37151e7d42cSGarrett Wollman errx(1, 37251e7d42cSGarrett Wollman "%s: unknown or uninstrumented protocol", 37351e7d42cSGarrett Wollman optarg); 3749b50d902SRodney W. Grimes } 3759b50d902SRodney W. Grimes pflag = 1; 3769b50d902SRodney W. Grimes break; 3779b50d902SRodney W. Grimes case 'r': 3789b50d902SRodney W. Grimes rflag = 1; 3799b50d902SRodney W. Grimes break; 3809b50d902SRodney W. Grimes case 's': 3819b50d902SRodney W. Grimes ++sflag; 3829b50d902SRodney W. Grimes break; 3839b50d902SRodney W. Grimes case 't': 3849b50d902SRodney W. Grimes tflag = 1; 3859b50d902SRodney W. Grimes break; 3869b50d902SRodney W. Grimes case 'u': 3879b50d902SRodney W. Grimes af = AF_UNIX; 3889b50d902SRodney W. Grimes break; 3899b50d902SRodney W. Grimes case 'w': 3909b50d902SRodney W. Grimes interval = atoi(optarg); 3919b50d902SRodney W. Grimes iflag = 1; 3929b50d902SRodney W. Grimes break; 3939b50d902SRodney W. Grimes case '?': 3949b50d902SRodney W. Grimes default: 3959b50d902SRodney W. Grimes usage(); 3969b50d902SRodney W. Grimes } 3979b50d902SRodney W. Grimes argv += optind; 3989b50d902SRodney W. Grimes argc -= optind; 3999b50d902SRodney W. Grimes 4009b50d902SRodney W. Grimes #define BACKWARD_COMPATIBILITY 4019b50d902SRodney W. Grimes #ifdef BACKWARD_COMPATIBILITY 4029b50d902SRodney W. Grimes if (*argv) { 4039b50d902SRodney W. Grimes if (isdigit(**argv)) { 4049b50d902SRodney W. Grimes interval = atoi(*argv); 4059b50d902SRodney W. Grimes if (interval <= 0) 4069b50d902SRodney W. Grimes usage(); 4079b50d902SRodney W. Grimes ++argv; 4089b50d902SRodney W. Grimes iflag = 1; 4099b50d902SRodney W. Grimes } 4109b50d902SRodney W. Grimes if (*argv) { 4119b50d902SRodney W. Grimes nlistf = *argv; 4129b50d902SRodney W. Grimes if (*++argv) 4139b50d902SRodney W. Grimes memf = *argv; 4149b50d902SRodney W. Grimes } 4159b50d902SRodney W. Grimes } 4169b50d902SRodney W. Grimes #endif 4179b50d902SRodney W. Grimes 4189b50d902SRodney W. Grimes /* 4199b50d902SRodney W. Grimes * Discard setgid privileges if not the running kernel so that bad 4209b50d902SRodney W. Grimes * guys can't print interesting stuff from kernel memory. 4219b50d902SRodney W. Grimes */ 4229b50d902SRodney W. Grimes if (nlistf != NULL || memf != NULL) 4239b50d902SRodney W. Grimes setgid(getgid()); 4249b50d902SRodney W. Grimes 4259b50d902SRodney W. Grimes if (mflag) { 4264f81ef50SGarrett Wollman mbpr(); 4279b50d902SRodney W. Grimes exit(0); 4289b50d902SRodney W. Grimes } 4299b50d902SRodney W. Grimes if (pflag) { 430cfa1ca9dSYoshinobu Inoue if (iflag && tp->pr_istats) { 431cfa1ca9dSYoshinobu Inoue kread(0, 0, 0); 432cfa1ca9dSYoshinobu Inoue intpr(interval, nl[N_IFNET].n_value, tp->pr_istats); 433cfa1ca9dSYoshinobu Inoue exit(0); 434cfa1ca9dSYoshinobu Inoue } 435c6620a13SPoul-Henning Kamp if (!tp->pr_stats) { 4369b50d902SRodney W. Grimes printf("%s: no stats routine\n", tp->pr_name); 4379b50d902SRodney W. Grimes exit(0); 4389b50d902SRodney W. Grimes } 439c6620a13SPoul-Henning Kamp if (tp->pr_usesysctl) { 440c6620a13SPoul-Henning Kamp (*tp->pr_stats)(tp->pr_usesysctl, tp->pr_name); 441c6620a13SPoul-Henning Kamp } else { 442c6620a13SPoul-Henning Kamp kread(0, 0, 0); 443c6620a13SPoul-Henning Kamp (*tp->pr_stats)(nl[tp->pr_sindex].n_value, 444c6620a13SPoul-Henning Kamp tp->pr_name); 445c6620a13SPoul-Henning Kamp } 446c6620a13SPoul-Henning Kamp exit(0); 447c6620a13SPoul-Henning Kamp } 448cc63cd56SPeter Wemm #if 0 4499b50d902SRodney W. Grimes /* 4509b50d902SRodney W. Grimes * Keep file descriptors open to avoid overhead 4519b50d902SRodney W. Grimes * of open/close on each call to get* routines. 4529b50d902SRodney W. Grimes */ 4539b50d902SRodney W. Grimes sethostent(1); 4549b50d902SRodney W. Grimes setnetent(1); 455cc63cd56SPeter Wemm #else 456cc63cd56SPeter Wemm /* 457cc63cd56SPeter Wemm * This does not make sense any more with DNS being default over 458cc63cd56SPeter Wemm * the files. Doing a setXXXXent(1) causes a tcp connection to be 459cc63cd56SPeter Wemm * used for the queries, which is slower. 460cc63cd56SPeter Wemm */ 461cc63cd56SPeter Wemm #endif 4629b50d902SRodney W. Grimes if (iflag) { 463cfa1ca9dSYoshinobu Inoue if (af != AF_UNSPEC) 464cfa1ca9dSYoshinobu Inoue goto protostat; 465cfa1ca9dSYoshinobu Inoue 466c6620a13SPoul-Henning Kamp kread(0, 0, 0); 467cfa1ca9dSYoshinobu Inoue intpr(interval, nl[N_IFNET].n_value, NULL); 4689b50d902SRodney W. Grimes exit(0); 4699b50d902SRodney W. Grimes } 4709b50d902SRodney W. Grimes if (rflag) { 471c6620a13SPoul-Henning Kamp kread(0, 0, 0); 4729b50d902SRodney W. Grimes if (sflag) 4739b50d902SRodney W. Grimes rt_stats(nl[N_RTSTAT].n_value); 4749b50d902SRodney W. Grimes else 4759b50d902SRodney W. Grimes routepr(nl[N_RTREE].n_value); 4769b50d902SRodney W. Grimes exit(0); 4779b50d902SRodney W. Grimes } 4789b50d902SRodney W. Grimes if (gflag) { 479c6620a13SPoul-Henning Kamp kread(0, 0, 0); 480cfa1ca9dSYoshinobu Inoue if (sflag) { 481cfa1ca9dSYoshinobu Inoue if (af == AF_INET || af == AF_UNSPEC) 48267a451ccSBill Fenner mrt_stats(nl[N_MRTSTAT].n_value); 483cfa1ca9dSYoshinobu Inoue #ifdef INET6 484cfa1ca9dSYoshinobu Inoue #ifdef notyet 485cfa1ca9dSYoshinobu Inoue if (af == AF_INET6 || af == AF_UNSPEC) 486cfa1ca9dSYoshinobu Inoue mrt6_stats(nl[N_MRT6STAT].n_value); 487cfa1ca9dSYoshinobu Inoue #endif 488cfa1ca9dSYoshinobu Inoue #endif 489cfa1ca9dSYoshinobu Inoue } else { 490cfa1ca9dSYoshinobu Inoue if (af == AF_INET || af == AF_UNSPEC) 49167a451ccSBill Fenner mroutepr(nl[N_MFCTABLE].n_value, 4929b50d902SRodney W. Grimes nl[N_VIFTABLE].n_value); 493cfa1ca9dSYoshinobu Inoue #ifdef INET6 494cfa1ca9dSYoshinobu Inoue #ifdef notyet 495cfa1ca9dSYoshinobu Inoue if (af == AF_INET6 || af == AF_UNSPEC) 496cfa1ca9dSYoshinobu Inoue mroute6pr(nl[N_MF6CTABLE].n_value, 497cfa1ca9dSYoshinobu Inoue nl[N_MIF6TABLE].n_value); 498cfa1ca9dSYoshinobu Inoue #endif 499cfa1ca9dSYoshinobu Inoue #endif 500cfa1ca9dSYoshinobu Inoue } 5019b50d902SRodney W. Grimes exit(0); 5029b50d902SRodney W. Grimes } 503cfa1ca9dSYoshinobu Inoue 504cfa1ca9dSYoshinobu Inoue protostat: 505cfa1ca9dSYoshinobu Inoue kread(0, 0, 0); 506cfa1ca9dSYoshinobu Inoue if (af == AF_INET || af == AF_UNSPEC) 5079b50d902SRodney W. Grimes for (tp = protox; tp->pr_name; tp++) 508cfa1ca9dSYoshinobu Inoue printproto(tp, tp->pr_name); 509cfa1ca9dSYoshinobu Inoue #ifdef INET6 510cfa1ca9dSYoshinobu Inoue if (af == AF_INET6 || af == AF_UNSPEC) 511cfa1ca9dSYoshinobu Inoue for (tp = ip6protox; tp->pr_name; tp++) 512cfa1ca9dSYoshinobu Inoue printproto(tp, tp->pr_name); 513cfa1ca9dSYoshinobu Inoue #endif /*INET6*/ 514e30e913cSJohn Hay if (af == AF_IPX || af == AF_UNSPEC) { 515e30e913cSJohn Hay kread(0, 0, 0); 516cc6a66f2SJulian Elischer for (tp = ipxprotox; tp->pr_name; tp++) 517cc6a66f2SJulian Elischer printproto(tp, tp->pr_name); 518e30e913cSJohn Hay } 51963bf4575SJulian Elischer if (af == AF_APPLETALK || af == AF_UNSPEC) 52063bf4575SJulian Elischer for (tp = atalkprotox; tp->pr_name; tp++) 52163bf4575SJulian Elischer printproto(tp, tp->pr_name); 5224cf49a43SJulian Elischer if (af == AF_NETGRAPH || af == AF_UNSPEC) 5234cf49a43SJulian Elischer for (tp = netgraphprotox; tp->pr_name; tp++) 5244cf49a43SJulian Elischer printproto(tp, tp->pr_name); 525cbc17e71SGarrett Wollman #ifdef NS 5269b50d902SRodney W. Grimes if (af == AF_NS || af == AF_UNSPEC) 5279b50d902SRodney W. Grimes for (tp = nsprotox; tp->pr_name; tp++) 5289b50d902SRodney W. Grimes printproto(tp, tp->pr_name); 529cbc17e71SGarrett Wollman #endif 5300761cb29SGarrett Wollman #ifdef ISO 5319b50d902SRodney W. Grimes if (af == AF_ISO || af == AF_UNSPEC) 5329b50d902SRodney W. Grimes for (tp = isoprotox; tp->pr_name; tp++) 5339b50d902SRodney W. Grimes printproto(tp, tp->pr_name); 5340761cb29SGarrett Wollman #endif 535ac55add0SGuido van Rooij if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag) 5364f81ef50SGarrett Wollman unixpr(); 5379b50d902SRodney W. Grimes exit(0); 5389b50d902SRodney W. Grimes } 5399b50d902SRodney W. Grimes 5409b50d902SRodney W. Grimes /* 5419b50d902SRodney W. Grimes * Print out protocol statistics or control blocks (per sflag). 5429b50d902SRodney W. Grimes * If the interface was not specifically requested, and the symbol 5439b50d902SRodney W. Grimes * is not in the namelist, ignore this one. 5449b50d902SRodney W. Grimes */ 5459b50d902SRodney W. Grimes static void 5469b50d902SRodney W. Grimes printproto(tp, name) 5479b50d902SRodney W. Grimes register struct protox *tp; 5489b50d902SRodney W. Grimes char *name; 5499b50d902SRodney W. Grimes { 5509b50d902SRodney W. Grimes void (*pr)(); 5519b50d902SRodney W. Grimes u_long off; 5529b50d902SRodney W. Grimes 5539b50d902SRodney W. Grimes if (sflag) { 554cfa1ca9dSYoshinobu Inoue if (iflag) { 555cfa1ca9dSYoshinobu Inoue if (tp->pr_istats) 556cfa1ca9dSYoshinobu Inoue intpr(interval, nl[N_IFNET].n_value, 557cfa1ca9dSYoshinobu Inoue tp->pr_istats); 558cfa1ca9dSYoshinobu Inoue return; 559cfa1ca9dSYoshinobu Inoue } 560cfa1ca9dSYoshinobu Inoue else { 5619b50d902SRodney W. Grimes pr = tp->pr_stats; 5624f81ef50SGarrett Wollman off = tp->pr_usesysctl ? tp->pr_usesysctl 5634f81ef50SGarrett Wollman : nl[tp->pr_sindex].n_value; 564cfa1ca9dSYoshinobu Inoue } 5659b50d902SRodney W. Grimes } else { 5669b50d902SRodney W. Grimes pr = tp->pr_cblocks; 5674f81ef50SGarrett Wollman off = tp->pr_usesysctl ? tp->pr_usesysctl 5684f81ef50SGarrett Wollman : nl[tp->pr_index].n_value; 5699b50d902SRodney W. Grimes } 5709b50d902SRodney W. Grimes if (pr != NULL && (off || af != AF_UNSPEC)) 571cfa1ca9dSYoshinobu Inoue (*pr)(off, name, af); 5729b50d902SRodney W. Grimes } 5739b50d902SRodney W. Grimes 5749b50d902SRodney W. Grimes /* 5759b50d902SRodney W. Grimes * Read kernel memory, return 0 on success. 5769b50d902SRodney W. Grimes */ 5779b50d902SRodney W. Grimes int 5789b50d902SRodney W. Grimes kread(addr, buf, size) 5799b50d902SRodney W. Grimes u_long addr; 5809b50d902SRodney W. Grimes char *buf; 5819b50d902SRodney W. Grimes int size; 5829b50d902SRodney W. Grimes { 5834f81ef50SGarrett Wollman if (kvmd == 0) { 58499453c6aSPoul-Henning Kamp /* 58599453c6aSPoul-Henning Kamp * XXX. 58699453c6aSPoul-Henning Kamp */ 58799453c6aSPoul-Henning Kamp kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf); 58899453c6aSPoul-Henning Kamp if (kvmd != NULL) { 58999453c6aSPoul-Henning Kamp if (kvm_nlist(kvmd, nl) < 0) { 59099453c6aSPoul-Henning Kamp if(nlistf) 59199453c6aSPoul-Henning Kamp errx(1, "%s: kvm_nlist: %s", nlistf, 59299453c6aSPoul-Henning Kamp kvm_geterr(kvmd)); 59399453c6aSPoul-Henning Kamp else 59499453c6aSPoul-Henning Kamp errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); 59599453c6aSPoul-Henning Kamp } 59699453c6aSPoul-Henning Kamp 59799453c6aSPoul-Henning Kamp if (nl[0].n_type == 0) { 59899453c6aSPoul-Henning Kamp if(nlistf) 59999453c6aSPoul-Henning Kamp errx(1, "%s: no namelist", nlistf); 60099453c6aSPoul-Henning Kamp else 60199453c6aSPoul-Henning Kamp errx(1, "no namelist"); 60299453c6aSPoul-Henning Kamp } 60399453c6aSPoul-Henning Kamp } else { 60499453c6aSPoul-Henning Kamp warnx("kvm not available"); 60599453c6aSPoul-Henning Kamp return(-1); 60699453c6aSPoul-Henning Kamp } 6074f81ef50SGarrett Wollman } 608c6620a13SPoul-Henning Kamp if (!buf) 609c6620a13SPoul-Henning Kamp return (0); 6109b50d902SRodney W. Grimes if (kvm_read(kvmd, addr, buf, size) != size) { 6113aa80b1dSDavid Greenman warnx("%s", kvm_geterr(kvmd)); 6129b50d902SRodney W. Grimes return (-1); 6139b50d902SRodney W. Grimes } 6149b50d902SRodney W. Grimes return (0); 6159b50d902SRodney W. Grimes } 6169b50d902SRodney W. Grimes 6179b50d902SRodney W. Grimes char * 6189b50d902SRodney W. Grimes plural(n) 6199b50d902SRodney W. Grimes int n; 6209b50d902SRodney W. Grimes { 6219b50d902SRodney W. Grimes return (n != 1 ? "s" : ""); 6229b50d902SRodney W. Grimes } 6239b50d902SRodney W. Grimes 6249b50d902SRodney W. Grimes char * 6259b50d902SRodney W. Grimes plurales(n) 6269b50d902SRodney W. Grimes int n; 6279b50d902SRodney W. Grimes { 6289b50d902SRodney W. Grimes return (n != 1 ? "es" : ""); 6299b50d902SRodney W. Grimes } 6309b50d902SRodney W. Grimes 6319b50d902SRodney W. Grimes /* 6329b50d902SRodney W. Grimes * Find the protox for the given "well-known" name. 6339b50d902SRodney W. Grimes */ 6349b50d902SRodney W. Grimes static struct protox * 6359b50d902SRodney W. Grimes knownname(name) 6369b50d902SRodney W. Grimes char *name; 6379b50d902SRodney W. Grimes { 6389b50d902SRodney W. Grimes struct protox **tpp, *tp; 6399b50d902SRodney W. Grimes 6409b50d902SRodney W. Grimes for (tpp = protoprotox; *tpp; tpp++) 6419b50d902SRodney W. Grimes for (tp = *tpp; tp->pr_name; tp++) 6429b50d902SRodney W. Grimes if (strcmp(tp->pr_name, name) == 0) 6439b50d902SRodney W. Grimes return (tp); 6449b50d902SRodney W. Grimes return (NULL); 6459b50d902SRodney W. Grimes } 6469b50d902SRodney W. Grimes 6479b50d902SRodney W. Grimes /* 6489b50d902SRodney W. Grimes * Find the protox corresponding to name. 6499b50d902SRodney W. Grimes */ 6509b50d902SRodney W. Grimes static struct protox * 6519b50d902SRodney W. Grimes name2protox(name) 6529b50d902SRodney W. Grimes char *name; 6539b50d902SRodney W. Grimes { 6549b50d902SRodney W. Grimes struct protox *tp; 6559b50d902SRodney W. Grimes char **alias; /* alias from p->aliases */ 6569b50d902SRodney W. Grimes struct protoent *p; 6579b50d902SRodney W. Grimes 6589b50d902SRodney W. Grimes /* 6599b50d902SRodney W. Grimes * Try to find the name in the list of "well-known" names. If that 6609b50d902SRodney W. Grimes * fails, check if name is an alias for an Internet protocol. 6619b50d902SRodney W. Grimes */ 662cfa1ca9dSYoshinobu Inoue if ((tp = knownname(name)) != NULL) 6639b50d902SRodney W. Grimes return (tp); 6649b50d902SRodney W. Grimes 6659b50d902SRodney W. Grimes setprotoent(1); /* make protocol lookup cheaper */ 666cfa1ca9dSYoshinobu Inoue while ((p = getprotoent()) != NULL) { 6679b50d902SRodney W. Grimes /* assert: name not same as p->name */ 6689b50d902SRodney W. Grimes for (alias = p->p_aliases; *alias; alias++) 6699b50d902SRodney W. Grimes if (strcmp(name, *alias) == 0) { 6709b50d902SRodney W. Grimes endprotoent(); 6719b50d902SRodney W. Grimes return (knownname(p->p_name)); 6729b50d902SRodney W. Grimes } 6739b50d902SRodney W. Grimes } 6749b50d902SRodney W. Grimes endprotoent(); 6759b50d902SRodney W. Grimes return (NULL); 6769b50d902SRodney W. Grimes } 6779b50d902SRodney W. Grimes 6789b50d902SRodney W. Grimes static void 6799b50d902SRodney W. Grimes usage() 6809b50d902SRodney W. Grimes { 6815d422d6aSPhilippe Charnier (void)fprintf(stderr, "%s\n%s\n%s\n%s\n", 6825d422d6aSPhilippe Charnier "usage: netstat [-Aan] [-f address_family] [-M core] [-N system]", 6836d6189a4SNik Clayton " netstat [-abdghimnrs] [-f address_family] [-M core] [-N system]", 6845d422d6aSPhilippe Charnier " netstat [-bdn] [-I interface] [-M core] [-N system] [-w wait]", 6855d422d6aSPhilippe Charnier " netstat [-M core] [-N system] [-p protocol]"); 6869b50d902SRodney W. Grimes exit(1); 6879b50d902SRodney W. Grimes } 6889c437f50SPeter Wemm 6899c437f50SPeter Wemm void 6909c437f50SPeter Wemm trimdomain(cp) 6919c437f50SPeter Wemm char *cp; 6929c437f50SPeter Wemm { 6939c437f50SPeter Wemm static char domain[MAXHOSTNAMELEN + 1]; 6949c437f50SPeter Wemm static int first = 1; 6959c437f50SPeter Wemm char *s; 6969c437f50SPeter Wemm 6979c437f50SPeter Wemm if (first) { 6989c437f50SPeter Wemm first = 0; 6999c437f50SPeter Wemm if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 7009c437f50SPeter Wemm (s = strchr(domain, '.'))) 7019c437f50SPeter Wemm (void) strcpy(domain, s + 1); 7029c437f50SPeter Wemm else 7039c437f50SPeter Wemm domain[0] = 0; 7049c437f50SPeter Wemm } 7059c437f50SPeter Wemm 7069c437f50SPeter Wemm if (domain[0]) { 7079c437f50SPeter Wemm while ((cp = strchr(cp, '.'))) { 7089c437f50SPeter Wemm if (!strcasecmp(cp + 1, domain)) { 7099c437f50SPeter Wemm *cp = 0; /* hit it */ 7109c437f50SPeter Wemm break; 7119c437f50SPeter Wemm } else { 7129c437f50SPeter Wemm cp++; 7139c437f50SPeter Wemm } 7149c437f50SPeter Wemm } 7159c437f50SPeter Wemm } 7169c437f50SPeter Wemm } 7179c437f50SPeter Wemm 718