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 359b50d902SRodney W. Grimes char 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 419b50d902SRodney W. Grimes static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94"; 429b50d902SRodney W. Grimes #endif /* not lint */ 439b50d902SRodney W. Grimes 449b50d902SRodney W. Grimes #include <sys/param.h> 459b50d902SRodney W. Grimes #include <sys/file.h> 469b50d902SRodney W. Grimes #include <sys/protosw.h> 479b50d902SRodney W. Grimes #include <sys/socket.h> 489b50d902SRodney W. Grimes 499b50d902SRodney W. Grimes #include <netinet/in.h> 509b50d902SRodney W. Grimes 519b50d902SRodney W. Grimes #include <ctype.h> 529b50d902SRodney W. Grimes #include <errno.h> 539b50d902SRodney W. Grimes #include <kvm.h> 549b50d902SRodney W. Grimes #include <limits.h> 559b50d902SRodney W. Grimes #include <netdb.h> 569b50d902SRodney W. Grimes #include <nlist.h> 579b50d902SRodney W. Grimes #include <paths.h> 589b50d902SRodney W. Grimes #include <stdio.h> 599b50d902SRodney W. Grimes #include <stdlib.h> 609b50d902SRodney W. Grimes #include <string.h> 619b50d902SRodney W. Grimes #include <unistd.h> 6251e7d42cSGarrett Wollman #include <err.h> 639b50d902SRodney W. Grimes #include "netstat.h" 649b50d902SRodney W. Grimes 659b50d902SRodney W. Grimes struct nlist nl[] = { 669b50d902SRodney W. Grimes #define N_MBSTAT 0 679b50d902SRodney W. Grimes { "_mbstat" }, 689b50d902SRodney W. Grimes #define N_IPSTAT 1 699b50d902SRodney W. Grimes { "_ipstat" }, 709b50d902SRodney W. Grimes #define N_TCB 2 719b50d902SRodney W. Grimes { "_tcb" }, 729b50d902SRodney W. Grimes #define N_TCPSTAT 3 739b50d902SRodney W. Grimes { "_tcpstat" }, 749b50d902SRodney W. Grimes #define N_UDB 4 759b50d902SRodney W. Grimes { "_udb" }, 769b50d902SRodney W. Grimes #define N_UDPSTAT 5 779b50d902SRodney W. Grimes { "_udpstat" }, 789b50d902SRodney W. Grimes #define N_IFNET 6 799b50d902SRodney W. Grimes { "_ifnet" }, 809b50d902SRodney W. Grimes #define N_IMP 7 819b50d902SRodney W. Grimes { "_imp_softc" }, 829b50d902SRodney W. Grimes #define N_ICMPSTAT 8 839b50d902SRodney W. Grimes { "_icmpstat" }, 849b50d902SRodney W. Grimes #define N_RTSTAT 9 859b50d902SRodney W. Grimes { "_rtstat" }, 869b50d902SRodney W. Grimes #define N_UNIXSW 10 879b50d902SRodney W. Grimes { "_unixsw" }, 889b50d902SRodney W. Grimes #define N_IDP 11 899b50d902SRodney W. Grimes { "_nspcb"}, 909b50d902SRodney W. Grimes #define N_IDPSTAT 12 919b50d902SRodney W. Grimes { "_idpstat"}, 929b50d902SRodney W. Grimes #define N_SPPSTAT 13 939b50d902SRodney W. Grimes { "_spp_istat"}, 949b50d902SRodney W. Grimes #define N_NSERR 14 959b50d902SRodney W. Grimes { "_ns_errstat"}, 969b50d902SRodney W. Grimes #define N_CLNPSTAT 15 979b50d902SRodney W. Grimes { "_clnp_stat"}, 989b50d902SRodney W. Grimes #define IN_NOTUSED 16 999b50d902SRodney W. Grimes { "_tp_inpcb" }, 1009b50d902SRodney W. Grimes #define ISO_TP 17 1019b50d902SRodney W. Grimes { "_tp_refinfo" }, 1029b50d902SRodney W. Grimes #define N_TPSTAT 18 1039b50d902SRodney W. Grimes { "_tp_stat" }, 1049b50d902SRodney W. Grimes #define N_ESISSTAT 19 1059b50d902SRodney W. Grimes { "_esis_stat"}, 1069b50d902SRodney W. Grimes #define N_NIMP 20 1079b50d902SRodney W. Grimes { "_nimp"}, 1089b50d902SRodney W. Grimes #define N_RTREE 21 1099b50d902SRodney W. Grimes { "_rt_tables"}, 1109b50d902SRodney W. Grimes #define N_CLTP 22 1119b50d902SRodney W. Grimes { "_cltb"}, 1129b50d902SRodney W. Grimes #define N_CLTPSTAT 23 1139b50d902SRodney W. Grimes { "_cltpstat"}, 1149b50d902SRodney W. Grimes #define N_NFILE 24 1159b50d902SRodney W. Grimes { "_nfile" }, 1169b50d902SRodney W. Grimes #define N_FILE 25 1179b50d902SRodney W. Grimes { "_file" }, 1189b50d902SRodney W. Grimes #define N_IGMPSTAT 26 1199b50d902SRodney W. Grimes { "_igmpstat" }, 1209b50d902SRodney W. Grimes #define N_MRTPROTO 27 1219b50d902SRodney W. Grimes { "_ip_mrtproto" }, 1229b50d902SRodney W. Grimes #define N_MRTSTAT 28 1239b50d902SRodney W. Grimes { "_mrtstat" }, 124ef105c25SGarrett Wollman #define N_MFCTABLE 29 125ef105c25SGarrett Wollman { "_mfctable" }, 1269b50d902SRodney W. Grimes #define N_VIFTABLE 30 1279b50d902SRodney W. Grimes { "_viftable" }, 128cc6a66f2SJulian Elischer #define N_IPX 31 129cc6a66f2SJulian Elischer { "_ipxpcb"}, 130cc6a66f2SJulian Elischer #define N_IPXSTAT 32 131cc6a66f2SJulian Elischer { "_ipxstat"}, 132cc6a66f2SJulian Elischer #define N_SPXSTAT 33 133cc6a66f2SJulian Elischer { "_spx_istat"}, 134cc6a66f2SJulian Elischer #define N_IPXERR 34 135cc6a66f2SJulian Elischer { "_ipx_errstat"}, 1369b50d902SRodney W. Grimes "", 1379b50d902SRodney W. Grimes }; 1389b50d902SRodney W. Grimes 1399b50d902SRodney W. Grimes struct protox { 1409b50d902SRodney W. Grimes u_char pr_index; /* index into nlist of cb head */ 1419b50d902SRodney W. Grimes u_char pr_sindex; /* index into nlist of stat block */ 1429b50d902SRodney W. Grimes u_char pr_wanted; /* 1 if wanted, 0 otherwise */ 1439b50d902SRodney W. Grimes void (*pr_cblocks)(); /* control blocks printing routine */ 1449b50d902SRodney W. Grimes void (*pr_stats)(); /* statistics printing routine */ 1459b50d902SRodney W. Grimes char *pr_name; /* well-known name */ 1469b50d902SRodney W. Grimes } protox[] = { 1479b50d902SRodney W. Grimes { N_TCB, N_TCPSTAT, 1, protopr, 1489b50d902SRodney W. Grimes tcp_stats, "tcp" }, 1499b50d902SRodney W. Grimes { N_UDB, N_UDPSTAT, 1, protopr, 1509b50d902SRodney W. Grimes udp_stats, "udp" }, 1519b50d902SRodney W. Grimes { -1, N_IPSTAT, 1, 0, 1529b50d902SRodney W. Grimes ip_stats, "ip" }, 1539b50d902SRodney W. Grimes { -1, N_ICMPSTAT, 1, 0, 1549b50d902SRodney W. Grimes icmp_stats, "icmp" }, 1559b50d902SRodney W. Grimes { -1, N_IGMPSTAT, 1, 0, 1569b50d902SRodney W. Grimes igmp_stats, "igmp" }, 1579b50d902SRodney W. Grimes { -1, -1, 0, 0, 1589b50d902SRodney W. Grimes 0, 0 } 1599b50d902SRodney W. Grimes }; 1609b50d902SRodney W. Grimes 161cc6a66f2SJulian Elischer struct protox ipxprotox[] = { 162cc6a66f2SJulian Elischer { N_IPX, N_IPXSTAT, 1, ipxprotopr, 163cc6a66f2SJulian Elischer ipx_stats, "ipx" }, 164cc6a66f2SJulian Elischer { N_IPX, N_SPXSTAT, 1, ipxprotopr, 165cc6a66f2SJulian Elischer spx_stats, "spx" }, 166cc6a66f2SJulian Elischer { -1, N_IPXERR, 1, 0, 167cc6a66f2SJulian Elischer ipxerr_stats, "ipx_err" }, 168cc6a66f2SJulian Elischer { -1, -1, 0, 0, 169cc6a66f2SJulian Elischer 0, 0 } 170cc6a66f2SJulian Elischer }; 171cc6a66f2SJulian Elischer 1729b50d902SRodney W. Grimes struct protox nsprotox[] = { 1739b50d902SRodney W. Grimes { N_IDP, N_IDPSTAT, 1, nsprotopr, 1749b50d902SRodney W. Grimes idp_stats, "idp" }, 1759b50d902SRodney W. Grimes { N_IDP, N_SPPSTAT, 1, nsprotopr, 1769b50d902SRodney W. Grimes spp_stats, "spp" }, 1779b50d902SRodney W. Grimes { -1, N_NSERR, 1, 0, 1789b50d902SRodney W. Grimes nserr_stats, "ns_err" }, 1799b50d902SRodney W. Grimes { -1, -1, 0, 0, 1809b50d902SRodney W. Grimes 0, 0 } 1819b50d902SRodney W. Grimes }; 1829b50d902SRodney W. Grimes 1839b50d902SRodney W. Grimes struct protox isoprotox[] = { 1849b50d902SRodney W. Grimes { ISO_TP, N_TPSTAT, 1, iso_protopr, 1859b50d902SRodney W. Grimes tp_stats, "tp" }, 1869b50d902SRodney W. Grimes { N_CLTP, N_CLTPSTAT, 1, iso_protopr, 1879b50d902SRodney W. Grimes cltp_stats, "cltp" }, 1889b50d902SRodney W. Grimes { -1, N_CLNPSTAT, 1, 0, 1899b50d902SRodney W. Grimes clnp_stats, "clnp"}, 1909b50d902SRodney W. Grimes { -1, N_ESISSTAT, 1, 0, 1919b50d902SRodney W. Grimes esis_stats, "esis"}, 1929b50d902SRodney W. Grimes { -1, -1, 0, 0, 1939b50d902SRodney W. Grimes 0, 0 } 1949b50d902SRodney W. Grimes }; 1959b50d902SRodney W. Grimes 196cc6a66f2SJulian Elischer struct protox *protoprotox[] = { protox, ipxprotox, nsprotox, isoprotox, NULL }; 1979b50d902SRodney W. Grimes 1989b50d902SRodney W. Grimes static void printproto __P((struct protox *, char *)); 1999b50d902SRodney W. Grimes static void usage __P((void)); 2009b50d902SRodney W. Grimes static struct protox *name2protox __P((char *)); 2019b50d902SRodney W. Grimes static struct protox *knownname __P((char *)); 2029b50d902SRodney W. Grimes 2039b50d902SRodney W. Grimes kvm_t *kvmd; 2049b50d902SRodney W. Grimes 2059b50d902SRodney W. Grimes int 2069b50d902SRodney W. Grimes main(argc, argv) 2079b50d902SRodney W. Grimes int argc; 2089b50d902SRodney W. Grimes char *argv[]; 2099b50d902SRodney W. Grimes { 2109b50d902SRodney W. Grimes extern char *optarg; 2119b50d902SRodney W. Grimes extern int optind; 2129b50d902SRodney W. Grimes register struct protoent *p; 2139b50d902SRodney W. Grimes register struct protox *tp; /* for printing cblocks & stats */ 2149b50d902SRodney W. Grimes register char *cp; 2159b50d902SRodney W. Grimes int ch; 2169b50d902SRodney W. Grimes char *nlistf = NULL, *memf = NULL; 2179b50d902SRodney W. Grimes char buf[_POSIX2_LINE_MAX]; 21851e7d42cSGarrett Wollman char buf2[_POSIX2_LINE_MAX]; 2199b50d902SRodney W. Grimes 2209b50d902SRodney W. Grimes if (cp = rindex(argv[0], '/')) 2219b50d902SRodney W. Grimes prog = cp + 1; 2229b50d902SRodney W. Grimes else 2239b50d902SRodney W. Grimes prog = argv[0]; 2249b50d902SRodney W. Grimes af = AF_UNSPEC; 2259b50d902SRodney W. Grimes 226e1e293a5SDavid Greenman while ((ch = getopt(argc, argv, "Aabdf:ghI:iM:mN:np:rstuw:")) != EOF) 2279b50d902SRodney W. Grimes switch(ch) { 2289b50d902SRodney W. Grimes case 'A': 2299b50d902SRodney W. Grimes Aflag = 1; 2309b50d902SRodney W. Grimes break; 2319b50d902SRodney W. Grimes case 'a': 2329b50d902SRodney W. Grimes aflag = 1; 2339b50d902SRodney W. Grimes break; 234e1e293a5SDavid Greenman case 'b': 235e1e293a5SDavid Greenman bflag = 1; 236e1e293a5SDavid Greenman break; 2379b50d902SRodney W. Grimes case 'd': 2389b50d902SRodney W. Grimes dflag = 1; 2399b50d902SRodney W. Grimes break; 2409b50d902SRodney W. Grimes case 'f': 2419b50d902SRodney W. Grimes if (strcmp(optarg, "ns") == 0) 2429b50d902SRodney W. Grimes af = AF_NS; 243cc6a66f2SJulian Elischer else if (strcmp(optarg, "ipx") == 0) 244cc6a66f2SJulian Elischer af = AF_IPX; 2459b50d902SRodney W. Grimes else if (strcmp(optarg, "inet") == 0) 2469b50d902SRodney W. Grimes af = AF_INET; 2479b50d902SRodney W. Grimes else if (strcmp(optarg, "unix") == 0) 2489b50d902SRodney W. Grimes af = AF_UNIX; 2499b50d902SRodney W. Grimes else if (strcmp(optarg, "iso") == 0) 2509b50d902SRodney W. Grimes af = AF_ISO; 2519b50d902SRodney W. Grimes else { 25251e7d42cSGarrett Wollman errx(1, "%s: unknown address family", optarg); 2539b50d902SRodney W. Grimes } 2549b50d902SRodney W. Grimes break; 2559b50d902SRodney W. Grimes case 'g': 2569b50d902SRodney W. Grimes gflag = 1; 2579b50d902SRodney W. Grimes break; 2589b50d902SRodney W. Grimes case 'I': { 2599b50d902SRodney W. Grimes char *cp; 2609b50d902SRodney W. Grimes 2619b50d902SRodney W. Grimes iflag = 1; 2629b50d902SRodney W. Grimes for (cp = interface = optarg; isalpha(*cp); cp++) 2639b50d902SRodney W. Grimes continue; 2649b50d902SRodney W. Grimes unit = atoi(cp); 2659b50d902SRodney W. Grimes break; 2669b50d902SRodney W. Grimes } 2679b50d902SRodney W. Grimes case 'i': 2689b50d902SRodney W. Grimes iflag = 1; 2699b50d902SRodney W. Grimes break; 2709b50d902SRodney W. Grimes case 'M': 2719b50d902SRodney W. Grimes memf = optarg; 2729b50d902SRodney W. Grimes break; 2739b50d902SRodney W. Grimes case 'm': 2749b50d902SRodney W. Grimes mflag = 1; 2759b50d902SRodney W. Grimes break; 2769b50d902SRodney W. Grimes case 'N': 2779b50d902SRodney W. Grimes nlistf = optarg; 2789b50d902SRodney W. Grimes break; 2799b50d902SRodney W. Grimes case 'n': 2809b50d902SRodney W. Grimes nflag = 1; 2819b50d902SRodney W. Grimes break; 2829b50d902SRodney W. Grimes case 'p': 2839b50d902SRodney W. Grimes if ((tp = name2protox(optarg)) == NULL) { 28451e7d42cSGarrett Wollman errx(1, 28551e7d42cSGarrett Wollman "%s: unknown or uninstrumented protocol", 28651e7d42cSGarrett Wollman optarg); 2879b50d902SRodney W. Grimes } 2889b50d902SRodney W. Grimes pflag = 1; 2899b50d902SRodney W. Grimes break; 2909b50d902SRodney W. Grimes case 'r': 2919b50d902SRodney W. Grimes rflag = 1; 2929b50d902SRodney W. Grimes break; 2939b50d902SRodney W. Grimes case 's': 2949b50d902SRodney W. Grimes ++sflag; 2959b50d902SRodney W. Grimes break; 2969b50d902SRodney W. Grimes case 't': 2979b50d902SRodney W. Grimes tflag = 1; 2989b50d902SRodney W. Grimes break; 2999b50d902SRodney W. Grimes case 'u': 3009b50d902SRodney W. Grimes af = AF_UNIX; 3019b50d902SRodney W. Grimes break; 3029b50d902SRodney W. Grimes case 'w': 3039b50d902SRodney W. Grimes interval = atoi(optarg); 3049b50d902SRodney W. Grimes iflag = 1; 3059b50d902SRodney W. Grimes break; 3069b50d902SRodney W. Grimes case '?': 3079b50d902SRodney W. Grimes default: 3089b50d902SRodney W. Grimes usage(); 3099b50d902SRodney W. Grimes } 3109b50d902SRodney W. Grimes argv += optind; 3119b50d902SRodney W. Grimes argc -= optind; 3129b50d902SRodney W. Grimes 3139b50d902SRodney W. Grimes #define BACKWARD_COMPATIBILITY 3149b50d902SRodney W. Grimes #ifdef BACKWARD_COMPATIBILITY 3159b50d902SRodney W. Grimes if (*argv) { 3169b50d902SRodney W. Grimes if (isdigit(**argv)) { 3179b50d902SRodney W. Grimes interval = atoi(*argv); 3189b50d902SRodney W. Grimes if (interval <= 0) 3199b50d902SRodney W. Grimes usage(); 3209b50d902SRodney W. Grimes ++argv; 3219b50d902SRodney W. Grimes iflag = 1; 3229b50d902SRodney W. Grimes } 3239b50d902SRodney W. Grimes if (*argv) { 3249b50d902SRodney W. Grimes nlistf = *argv; 3259b50d902SRodney W. Grimes if (*++argv) 3269b50d902SRodney W. Grimes memf = *argv; 3279b50d902SRodney W. Grimes } 3289b50d902SRodney W. Grimes } 3299b50d902SRodney W. Grimes #endif 3309b50d902SRodney W. Grimes 3319b50d902SRodney W. Grimes /* 3329b50d902SRodney W. Grimes * Discard setgid privileges if not the running kernel so that bad 3339b50d902SRodney W. Grimes * guys can't print interesting stuff from kernel memory. 3349b50d902SRodney W. Grimes */ 3359b50d902SRodney W. Grimes if (nlistf != NULL || memf != NULL) 3369b50d902SRodney W. Grimes setgid(getgid()); 3379b50d902SRodney W. Grimes 33851e7d42cSGarrett Wollman kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf); 33951e7d42cSGarrett Wollman if (kvmd == NULL) { 34051e7d42cSGarrett Wollman errx(1, "kvm_open: %s", buf); 3419b50d902SRodney W. Grimes } 34251e7d42cSGarrett Wollman if (kvm_nlist(kvmd, nl) < 0) { 3439b50d902SRodney W. Grimes if(nlistf) 34451e7d42cSGarrett Wollman errx(1, "%s: kvm_nlist: %s", nlistf, kvm_geterr(kvmd)); 3459b50d902SRodney W. Grimes else 34651e7d42cSGarrett Wollman errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); 34751e7d42cSGarrett Wollman } 34851e7d42cSGarrett Wollman 34951e7d42cSGarrett Wollman if (nl[0].n_type == 0) { 35051e7d42cSGarrett Wollman if(nlistf) 35151e7d42cSGarrett Wollman errx(1, "%s: no namelist", nlistf); 35251e7d42cSGarrett Wollman else 35351e7d42cSGarrett Wollman errx(1, "no namelist"); 3549b50d902SRodney W. Grimes } 3559b50d902SRodney W. Grimes if (mflag) { 3569b50d902SRodney W. Grimes mbpr(nl[N_MBSTAT].n_value); 3579b50d902SRodney W. Grimes exit(0); 3589b50d902SRodney W. Grimes } 3599b50d902SRodney W. Grimes if (pflag) { 3609b50d902SRodney W. Grimes if (tp->pr_stats) 3619b50d902SRodney W. Grimes (*tp->pr_stats)(nl[tp->pr_sindex].n_value, 3629b50d902SRodney W. Grimes tp->pr_name); 3639b50d902SRodney W. Grimes else 3649b50d902SRodney W. Grimes printf("%s: no stats routine\n", tp->pr_name); 3659b50d902SRodney W. Grimes exit(0); 3669b50d902SRodney W. Grimes } 3679b50d902SRodney W. Grimes /* 3689b50d902SRodney W. Grimes * Keep file descriptors open to avoid overhead 3699b50d902SRodney W. Grimes * of open/close on each call to get* routines. 3709b50d902SRodney W. Grimes */ 3719b50d902SRodney W. Grimes sethostent(1); 3729b50d902SRodney W. Grimes setnetent(1); 3739b50d902SRodney W. Grimes if (iflag) { 3749b50d902SRodney W. Grimes intpr(interval, nl[N_IFNET].n_value); 3759b50d902SRodney W. Grimes exit(0); 3769b50d902SRodney W. Grimes } 3779b50d902SRodney W. Grimes if (rflag) { 3789b50d902SRodney W. Grimes if (sflag) 3799b50d902SRodney W. Grimes rt_stats(nl[N_RTSTAT].n_value); 3809b50d902SRodney W. Grimes else 3819b50d902SRodney W. Grimes routepr(nl[N_RTREE].n_value); 3829b50d902SRodney W. Grimes exit(0); 3839b50d902SRodney W. Grimes } 3849b50d902SRodney W. Grimes if (gflag) { 3859b50d902SRodney W. Grimes if (sflag) 3869b50d902SRodney W. Grimes mrt_stats(nl[N_MRTPROTO].n_value, 3879b50d902SRodney W. Grimes nl[N_MRTSTAT].n_value); 3889b50d902SRodney W. Grimes else 3899b50d902SRodney W. Grimes mroutepr(nl[N_MRTPROTO].n_value, 390ef105c25SGarrett Wollman nl[N_MFCTABLE].n_value, 3919b50d902SRodney W. Grimes nl[N_VIFTABLE].n_value); 3929b50d902SRodney W. Grimes exit(0); 3939b50d902SRodney W. Grimes } 3949b50d902SRodney W. Grimes if (af == AF_INET || af == AF_UNSPEC) { 3959b50d902SRodney W. Grimes setprotoent(1); 3969b50d902SRodney W. Grimes setservent(1); 3979b50d902SRodney W. Grimes /* ugh, this is O(MN) ... why do we do this? */ 3989b50d902SRodney W. Grimes while (p = getprotoent()) { 3999b50d902SRodney W. Grimes for (tp = protox; tp->pr_name; tp++) 4009b50d902SRodney W. Grimes if (strcmp(tp->pr_name, p->p_name) == 0) 4019b50d902SRodney W. Grimes break; 4029b50d902SRodney W. Grimes if (tp->pr_name == 0 || tp->pr_wanted == 0) 4039b50d902SRodney W. Grimes continue; 4049b50d902SRodney W. Grimes printproto(tp, p->p_name); 4059b50d902SRodney W. Grimes } 4069b50d902SRodney W. Grimes endprotoent(); 4079b50d902SRodney W. Grimes } 408cc6a66f2SJulian Elischer if (af == AF_IPX || af == AF_UNSPEC) 409cc6a66f2SJulian Elischer for (tp = ipxprotox; tp->pr_name; tp++) 410cc6a66f2SJulian Elischer printproto(tp, tp->pr_name); 4119b50d902SRodney W. Grimes if (af == AF_NS || af == AF_UNSPEC) 4129b50d902SRodney W. Grimes for (tp = nsprotox; tp->pr_name; tp++) 4139b50d902SRodney W. Grimes printproto(tp, tp->pr_name); 4149b50d902SRodney W. Grimes if (af == AF_ISO || af == AF_UNSPEC) 4159b50d902SRodney W. Grimes for (tp = isoprotox; tp->pr_name; tp++) 4169b50d902SRodney W. Grimes printproto(tp, tp->pr_name); 4179b50d902SRodney W. Grimes if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) 4189b50d902SRodney W. Grimes unixpr(nl[N_UNIXSW].n_value); 4199b50d902SRodney W. Grimes exit(0); 4209b50d902SRodney W. Grimes } 4219b50d902SRodney W. Grimes 4229b50d902SRodney W. Grimes /* 4239b50d902SRodney W. Grimes * Print out protocol statistics or control blocks (per sflag). 4249b50d902SRodney W. Grimes * If the interface was not specifically requested, and the symbol 4259b50d902SRodney W. Grimes * is not in the namelist, ignore this one. 4269b50d902SRodney W. Grimes */ 4279b50d902SRodney W. Grimes static void 4289b50d902SRodney W. Grimes printproto(tp, name) 4299b50d902SRodney W. Grimes register struct protox *tp; 4309b50d902SRodney W. Grimes char *name; 4319b50d902SRodney W. Grimes { 4329b50d902SRodney W. Grimes void (*pr)(); 4339b50d902SRodney W. Grimes u_long off; 4349b50d902SRodney W. Grimes 4359b50d902SRodney W. Grimes if (sflag) { 4369b50d902SRodney W. Grimes pr = tp->pr_stats; 4379b50d902SRodney W. Grimes off = nl[tp->pr_sindex].n_value; 4389b50d902SRodney W. Grimes } else { 4399b50d902SRodney W. Grimes pr = tp->pr_cblocks; 4409b50d902SRodney W. Grimes off = nl[tp->pr_index].n_value; 4419b50d902SRodney W. Grimes } 4429b50d902SRodney W. Grimes if (pr != NULL && (off || af != AF_UNSPEC)) 4439b50d902SRodney W. Grimes (*pr)(off, name); 4449b50d902SRodney W. Grimes } 4459b50d902SRodney W. Grimes 4469b50d902SRodney W. Grimes /* 4479b50d902SRodney W. Grimes * Read kernel memory, return 0 on success. 4489b50d902SRodney W. Grimes */ 4499b50d902SRodney W. Grimes int 4509b50d902SRodney W. Grimes kread(addr, buf, size) 4519b50d902SRodney W. Grimes u_long addr; 4529b50d902SRodney W. Grimes char *buf; 4539b50d902SRodney W. Grimes int size; 4549b50d902SRodney W. Grimes { 4559b50d902SRodney W. Grimes 4569b50d902SRodney W. Grimes if (kvm_read(kvmd, addr, buf, size) != size) { 4573aa80b1dSDavid Greenman warnx("%s", kvm_geterr(kvmd)); 4589b50d902SRodney W. Grimes return (-1); 4599b50d902SRodney W. Grimes } 4609b50d902SRodney W. Grimes return (0); 4619b50d902SRodney W. Grimes } 4629b50d902SRodney W. Grimes 4639b50d902SRodney W. Grimes char * 4649b50d902SRodney W. Grimes plural(n) 4659b50d902SRodney W. Grimes int n; 4669b50d902SRodney W. Grimes { 4679b50d902SRodney W. Grimes return (n != 1 ? "s" : ""); 4689b50d902SRodney W. Grimes } 4699b50d902SRodney W. Grimes 4709b50d902SRodney W. Grimes char * 4719b50d902SRodney W. Grimes plurales(n) 4729b50d902SRodney W. Grimes int n; 4739b50d902SRodney W. Grimes { 4749b50d902SRodney W. Grimes return (n != 1 ? "es" : ""); 4759b50d902SRodney W. Grimes } 4769b50d902SRodney W. Grimes 4779b50d902SRodney W. Grimes /* 4789b50d902SRodney W. Grimes * Find the protox for the given "well-known" name. 4799b50d902SRodney W. Grimes */ 4809b50d902SRodney W. Grimes static struct protox * 4819b50d902SRodney W. Grimes knownname(name) 4829b50d902SRodney W. Grimes char *name; 4839b50d902SRodney W. Grimes { 4849b50d902SRodney W. Grimes struct protox **tpp, *tp; 4859b50d902SRodney W. Grimes 4869b50d902SRodney W. Grimes for (tpp = protoprotox; *tpp; tpp++) 4879b50d902SRodney W. Grimes for (tp = *tpp; tp->pr_name; tp++) 4889b50d902SRodney W. Grimes if (strcmp(tp->pr_name, name) == 0) 4899b50d902SRodney W. Grimes return (tp); 4909b50d902SRodney W. Grimes return (NULL); 4919b50d902SRodney W. Grimes } 4929b50d902SRodney W. Grimes 4939b50d902SRodney W. Grimes /* 4949b50d902SRodney W. Grimes * Find the protox corresponding to name. 4959b50d902SRodney W. Grimes */ 4969b50d902SRodney W. Grimes static struct protox * 4979b50d902SRodney W. Grimes name2protox(name) 4989b50d902SRodney W. Grimes char *name; 4999b50d902SRodney W. Grimes { 5009b50d902SRodney W. Grimes struct protox *tp; 5019b50d902SRodney W. Grimes char **alias; /* alias from p->aliases */ 5029b50d902SRodney W. Grimes struct protoent *p; 5039b50d902SRodney W. Grimes 5049b50d902SRodney W. Grimes /* 5059b50d902SRodney W. Grimes * Try to find the name in the list of "well-known" names. If that 5069b50d902SRodney W. Grimes * fails, check if name is an alias for an Internet protocol. 5079b50d902SRodney W. Grimes */ 5089b50d902SRodney W. Grimes if (tp = knownname(name)) 5099b50d902SRodney W. Grimes return (tp); 5109b50d902SRodney W. Grimes 5119b50d902SRodney W. Grimes setprotoent(1); /* make protocol lookup cheaper */ 5129b50d902SRodney W. Grimes while (p = getprotoent()) { 5139b50d902SRodney W. Grimes /* assert: name not same as p->name */ 5149b50d902SRodney W. Grimes for (alias = p->p_aliases; *alias; alias++) 5159b50d902SRodney W. Grimes if (strcmp(name, *alias) == 0) { 5169b50d902SRodney W. Grimes endprotoent(); 5179b50d902SRodney W. Grimes return (knownname(p->p_name)); 5189b50d902SRodney W. Grimes } 5199b50d902SRodney W. Grimes } 5209b50d902SRodney W. Grimes endprotoent(); 5219b50d902SRodney W. Grimes return (NULL); 5229b50d902SRodney W. Grimes } 5239b50d902SRodney W. Grimes 5249b50d902SRodney W. Grimes static void 5259b50d902SRodney W. Grimes usage() 5269b50d902SRodney W. Grimes { 5279b50d902SRodney W. Grimes (void)fprintf(stderr, 5289b50d902SRodney W. Grimes "usage: %s [-Aan] [-f address_family] [-M core] [-N system]\n", prog); 5299b50d902SRodney W. Grimes (void)fprintf(stderr, 530e1e293a5SDavid Greenman " %s [-bdghimnrs] [-f address_family] [-M core] [-N system]\n", prog); 5319b50d902SRodney W. Grimes (void)fprintf(stderr, 532e1e293a5SDavid Greenman " %s [-bdn] [-I interface] [-M core] [-N system] [-w wait]\n", prog); 5339b50d902SRodney W. Grimes (void)fprintf(stderr, 5349b50d902SRodney W. Grimes " %s [-M core] [-N system] [-p protocol]\n", prog); 5359b50d902SRodney W. Grimes exit(1); 5369b50d902SRodney W. Grimes } 537