X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/07f470571f6fc2709bdcf62fad0e6c4c1bf4e1b9..755a8d69d575c678ea4570e9f9ef0d076b0f1557:/netstat.tproj/main.c diff --git a/netstat.tproj/main.c b/netstat.tproj/main.c index 9eea7a3..6830b67 100644 --- a/netstat.tproj/main.c +++ b/netstat.tproj/main.c @@ -1,17 +1,20 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2008-2015 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1983, 1988, 1993 @@ -61,25 +64,17 @@ char const copyright[] = Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94"; -#endif -static const char rcsid[] = - "$Id: main.c,v 1.5 2003/07/08 22:49:49 lindak Exp $"; -#endif /* not lint */ - #include #include -#include #include +#include #include +#include #include #include #include -#include #include #include #include @@ -92,6 +87,9 @@ static const char rcsid[] = #include #include +#ifdef __APPLE__ +#include +#endif /* * ---------------------------------------------------------------------------- @@ -101,248 +99,87 @@ static const char rcsid[] = * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: main.c,v 1.5 2003/07/08 22:49:49 lindak Exp $ + * $Id: main.c,v 1.8 2004/10/14 22:24:09 lindak Exp $ * */ - -static struct nlist nl[] = { -#define N_IFNET 0 - { "_ifnet" }, -#define N_IMP 1 - { "_imp_softc" }, -#define N_RTSTAT 2 - { "_rtstat" }, -#define N_UNIXSW 3 - { "_localsw" }, -#define N_IDP 4 - { "_nspcb"}, -#define N_IDPSTAT 5 - { "_idpstat"}, -#define N_SPPSTAT 6 - { "_spp_istat"}, -#define N_NSERR 7 - { "_ns_errstat"}, -#define N_CLNPSTAT 8 - { "_clnp_stat"}, -#define IN_NOTUSED 9 - { "_tp_inpcb" }, -#define ISO_TP 10 - { "_tp_refinfo" }, -#define N_TPSTAT 11 - { "_tp_stat" }, -#define N_ESISSTAT 12 - { "_esis_stat"}, -#define N_NIMP 13 - { "_nimp"}, -#define N_RTREE 14 - { "_rt_tables"}, -#define N_CLTP 15 - { "_cltb"}, -#define N_CLTPSTAT 16 - { "_cltpstat"}, -#define N_NFILE 17 - { "_nfile" }, -#define N_FILE 18 - { "_file" }, -#define N_MRTSTAT 19 - { "_mrtstat" }, -#define N_MFCTABLE 20 - { "_mfctable" }, -#define N_VIFTABLE 21 - { "_viftable" }, -#define N_IPX 22 - { "_ipxpcb"}, -#define N_IPXSTAT 23 - { "_ipxstat"}, -#define N_SPXSTAT 24 - { "_spx_istat"}, -#define N_DDPSTAT 25 - { "_ddpstat"}, -#define N_DDPCB 26 - { "_ddpcb"}, -#define N_NGSOCKS 27 - { "_ngsocklist"}, -#define N_IP6STAT 28 - { "_ip6stat" }, -#define N_ICMP6STAT 29 - { "_icmp6stat" }, -#define N_IPSECSTAT 30 - { "_ipsecstat" }, -#define N_IPSEC6STAT 31 - { "_ipsec6stat" }, -#define N_PIM6STAT 32 - { "_pim6stat" }, -#define N_MRT6PROTO 33 - { "_ip6_mrtproto" }, -#define N_MRT6STAT 34 - { "_mrt6stat" }, -#define N_MF6CTABLE 35 - { "_mf6ctable" }, -#define N_MIF6TABLE 36 - { "_mif6table" }, -#define N_PFKEYSTAT 37 - { "_pfkeystat" }, -#define N_MBSTAT 38 - { "_mbstat" }, -#define N_MBTYPES 39 - { "_mbtypes" }, -#define N_NMBCLUSTERS 40 - { "_nmbclusters" }, -#define N_NMBUFS 41 - { "_nmbufs" }, -#define N_RTTRASH 42 - { "_rttrash" }, - { "" }, -}; - - - struct protox { - u_char pr_index; /* index into nlist of cb head */ - u_char pr_sindex; /* index into nlist of stat block */ - u_char pr_wanted; /* 1 if wanted, 0 otherwise */ - void (*pr_cblocks)(u_long, char *, int); + void (*pr_cblocks)(uint32_t, char *, int); /* control blocks printing routine */ - void (*pr_stats)(u_long, char *, int); + void (*pr_stats)(uint32_t, char *, int); /* statistics printing routine */ void (*pr_istats)(char *); /* per/if statistics printing routine */ char *pr_name; /* well-known name */ - int pr_usesysctl; /* true if we use sysctl, not kvm */ + int pr_protocol; } protox[] = { - { -1, -1, 1, protopr, - tcp_stats, NULL, "tcp", IPPROTO_TCP }, - { -1, -1, 1, protopr, - udp_stats, NULL, "udp", IPPROTO_UDP }, - { -1, -1, 1, protopr, - NULL, NULL, "divert",IPPROTO_DIVERT }, - { -1, -1, 1, protopr, - ip_stats, NULL, "ip", IPPROTO_RAW }, - { -1, -1, 1, protopr, - icmp_stats, NULL, "icmp", IPPROTO_ICMP }, - { -1, -1, 1, protopr, - igmp_stats, NULL, "igmp", IPPROTO_IGMP }, + { protopr, tcp_stats, NULL, "tcp", IPPROTO_TCP }, + { protopr, udp_stats, NULL, "udp", IPPROTO_UDP }, + { protopr, NULL, NULL, "divert", IPPROTO_DIVERT }, + { protopr, ip_stats, NULL, "ip", IPPROTO_RAW }, + { protopr, icmp_stats, NULL, "icmp", IPPROTO_ICMP }, + { protopr, igmp_stats, NULL, "igmp", IPPROTO_IGMP }, #ifdef IPSEC - { -1, N_IPSECSTAT, 1, 0, - ipsec_stats, NULL, "ipsec", 0}, -#endif -#if 0 - { -1, -1, 1, 0, - bdg_stats, NULL, "bdg", 1 /* bridging... */ }, + { NULL, ipsec_stats, NULL, "ipsec", IPPROTO_ESP}, #endif - { -1, -1, 0, 0, - 0, NULL, 0 } + { NULL, arp_stats, NULL, "arp", 0 }, + { mptcppr, mptcp_stats, NULL, "mptcp", IPPROTO_TCP }, + { NULL, NULL, NULL, NULL, 0 } }; #ifdef INET6 struct protox ip6protox[] = { - { -1, -1, 1, protopr, - tcp_stats, NULL, "tcp", IPPROTO_TCP }, - { -1, -1, 1, protopr, - udp_stats, NULL, "udp", IPPROTO_UDP }, - { -1, N_IP6STAT, 1, protopr, - ip6_stats, ip6_ifstats, "ip6", IPPROTO_RAW }, - { -1, N_ICMP6STAT, 1, protopr, - icmp6_stats, icmp6_ifstats, "icmp6",IPPROTO_ICMPV6 }, + { protopr, tcp_stats, NULL, "tcp", IPPROTO_TCP }, + { protopr, udp_stats, NULL, "udp", IPPROTO_UDP }, + { protopr, ip6_stats, ip6_ifstats, "ip6", IPPROTO_RAW }, + { protopr, icmp6_stats, icmp6_ifstats, "icmp6",IPPROTO_ICMPV6 }, #ifdef IPSEC - { -1, N_IPSEC6STAT, 1, 0, - ipsec_stats, NULL, "ipsec6",0 }, + { NULL, ipsec_stats, NULL, "ipsec6", IPPROTO_ESP }, #endif -#ifdef notyet - { -1, N_PIM6STAT, 1, 0, - pim6_stats, NULL, "pim6", 0 }, -#endif - { -1, -1, 1, 0, - rip6_stats, NULL, "rip6", 0 }, -#if 0 - { -1, -1, 1, 0, - bdg_stats, NULL, "bdg", 1 /* bridging... */ }, -#endif - { -1, -1, 0, 0, - 0, NULL, 0, 0 } + { NULL, rip6_stats, NULL, "rip6", IPPROTO_RAW }, + { mptcppr, mptcp_stats, NULL, "mptcp", IPPROTO_TCP }, + { NULL, NULL, NULL, NULL, 0 } }; #endif /*INET6*/ #ifdef IPSEC struct protox pfkeyprotox[] = { - { -1, N_PFKEYSTAT, 1, 0, - pfkey_stats, NULL, "pfkey", 0 }, - { -1, -1, 0, 0, - 0, NULL, 0, 0 } + { NULL, pfkey_stats, NULL, "pfkey", PF_KEY_V2 }, + { NULL, NULL, NULL, NULL, 0 } }; #endif -#ifndef __APPLE__ -struct protox atalkprotox[] = { - { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, - ddp_stats, NULL, "ddp" }, - { -1, -1, 0, 0, - 0, NULL, 0 } -}; -struct protox netgraphprotox[] = { - { N_NGSOCKS, -1, 1, netgraphprotopr, - NULL, NULL, "ctrl" }, - { N_NGSOCKS, -1, 1, netgraphprotopr, - NULL, NULL, "data" }, - { -1, NULL, 0, 0, - 0, NULL, 0 } -}; -struct protox ipxprotox[] = { - { N_IPX, N_IPXSTAT, 1, ipxprotopr, - ipx_stats, NULL, "ipx", 0 }, - { N_IPX, N_SPXSTAT, 1, ipxprotopr, - spx_stats, NULL, "spx", 0 }, - { -1, -1, 0, 0, - 0, NULL, 0, 0 } +struct protox systmprotox[] = { + { systmpr, NULL, NULL, "reg", 0 }, + { systmpr, kevt_stats, NULL, "kevt", SYSPROTO_EVENT }, + { systmpr, kctl_stats, NULL, "kctl", SYSPROTO_CONTROL }, + { NULL, NULL, NULL, NULL, 0 } }; -#endif -#ifdef NS -struct protox nsprotox[] = { - { N_IDP, N_IDPSTAT, 1, nsprotopr, - idp_stats, NULL, "idp" }, - { N_IDP, N_SPPSTAT, 1, nsprotopr, - spp_stats, NULL, "spp" }, - { -1, N_NSERR, 1, 0, - nserr_stats, NULL, "ns_err" }, - { -1, -1, 0, 0, - 0, NULL, 0 } + +struct protox nstatprotox[] = { + { NULL, print_nstat_stats, NULL, "nstat", 0 }, + { NULL, NULL, NULL, NULL, 0 } }; -#endif -#ifdef ISO -struct protox isoprotox[] = { - { ISO_TP, N_TPSTAT, 1, iso_protopr, - tp_stats, NULL, "tp" }, - { N_CLTP, N_CLTPSTAT, 1, iso_protopr, - cltp_stats, NULL, "cltp" }, - { -1, N_CLNPSTAT, 1, 0, - clnp_stats, NULL, "clnp"}, - { -1, N_ESISSTAT, 1, 0, - esis_stats, NULL, "esis"}, - { -1, -1, 0, 0, - 0, NULL, 0 } +struct protox ipcprotox[] = { + { NULL, print_extbkidle_stats, NULL, "xbkidle", 0 }, + { NULL, NULL, NULL, NULL, 0 } }; -#endif + struct protox *protoprotox[] = { - protox, + protox, #ifdef INET6 - ip6protox, + ip6protox, #endif #ifdef IPSEC - pfkeyprotox, -#endif -#ifndef __APPLE__ - ipxprotox, atalkprotox, + pfkeyprotox, #endif -#ifdef NS - nsprotox, -#endif -#ifdef ISO - isoprotox, -#endif - NULL }; + systmprotox, + nstatprotox, + ipcprotox, + NULL +}; static void printproto (struct protox *, char *); static void usage (void); @@ -352,25 +189,34 @@ static struct protox *knownname (char *); extern void _serv_cache_close(); #endif -static kvm_t *kvmd; -static char *nlistf = NULL, *memf = NULL; - int Aflag; /* show addresses of protocol control block */ int aflag; /* show all sockets (including servers) */ int bflag; /* show i/f total bytes in/out */ +int cflag; /* show specific classq */ int dflag; /* show i/f dropped packets */ +int Fflag; /* show i/f forwarded packets */ +#if defined(__APPLE__) int gflag; /* show group (multicast) routing or stats */ +#endif int iflag; /* show interfaces */ int lflag; /* show routing table with use and ref */ int Lflag; /* show size of listen queues */ int mflag; /* show memory stats */ int nflag; /* show addresses numerically */ static int pflag; /* show given protocol */ +int prioflag = -1; /* show packet priority statistics */ +int Rflag; /* show reachability information */ int rflag; /* show routing tables (or routing stats) */ int sflag; /* show protocol statistics */ +int Sflag; /* show additional i/f link status */ int tflag; /* show i/f watchdog timers */ +int vflag; /* more verbose */ int Wflag; /* wide display */ +int qflag; /* classq stats display */ +int Qflag; /* opportunistic polling stats display */ +int xflag; /* show extended link-layer reachability information */ +int cq = -1; /* send classq index (-1 for all) */ int interval; /* repeat interval for i/f stats */ char *interface; /* desired i/f for stats, or NULL for all i/fs */ @@ -388,7 +234,7 @@ main(argc, argv) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "Aabdf:gI:iLlM:mN:np:rstuWw:")) != -1) + while ((ch = getopt(argc, argv, "Aabc:dFf:gI:ikLlmnP:p:qQrRsStuvWw:x")) != -1) switch(ch) { case 'A': Aflag = 1; @@ -399,15 +245,17 @@ main(argc, argv) case 'b': bflag = 1; break; + case 'c': + cflag = 1; + cq = atoi(optarg); + break; case 'd': dflag = 1; break; + case 'F': + Fflag = 1; + break; case 'f': -#ifdef NS - if (strcmp(optarg, "ns") == 0) - af = AF_NS; - else -#endif if (strcmp(optarg, "ipx") == 0) af = AF_IPX; else if (strcmp(optarg, "inet") == 0) @@ -422,24 +270,17 @@ main(argc, argv) #endif /*INET6*/ else if (strcmp(optarg, "unix") == 0) af = AF_UNIX; -#ifndef __APPLE__ - else if (strcmp(optarg, "atalk") == 0) - af = AF_APPLETALK; - else if (strcmp(optarg, "ng") == 0 - || strcmp(optarg, "netgraph") == 0) - af = AF_NETGRAPH; -#endif -#ifdef ISO - else if (strcmp(optarg, "iso") == 0) - af = AF_ISO; -#endif + else if (strcmp(optarg, "systm") == 0) + af = AF_SYSTEM; else { errx(1, "%s: unknown address family", optarg); } break; +#if defined(__APPLE__) case 'g': gflag = 1; break; +#endif case 'I': { char *cp; @@ -458,18 +299,15 @@ main(argc, argv) case 'L': Lflag = 1; break; - case 'M': - memf = optarg; - break; case 'm': - mflag = 1; - break; - case 'N': - nlistf = optarg; + mflag++; break; case 'n': nflag = 1; break; + case 'P': + prioflag = atoi(optarg); + break; case 'p': if ((tp = name2protox(optarg)) == NULL) { errx(1, @@ -478,18 +316,33 @@ main(argc, argv) } pflag = 1; break; + case 'q': + qflag++; + break; + case 'Q': + Qflag++; + break; + case 'R': + Rflag = 1; + break; case 'r': rflag = 1; break; case 's': ++sflag; break; + case 'S': + Sflag = 1; + break; case 't': tflag = 1; break; case 'u': af = AF_UNIX; break; + case 'v': + vflag++; + break; case 'W': Wflag = 1; break; @@ -497,6 +350,10 @@ main(argc, argv) interval = atoi(optarg); iflag = 1; break; + case 'x': + xflag = 1; + Rflag = 1; + break; case '?': default: usage(); @@ -514,84 +371,56 @@ main(argc, argv) ++argv; iflag = 1; } - if (*argv) { - nlistf = *argv; - if (*++argv) - memf = *argv; - } } #endif - /* - * Discard setgid privileges if not the running kernel so that bad - * guys can't print interesting stuff from kernel memory. - */ - if (nlistf != NULL || memf != NULL) - setgid(getgid()); - if (mflag) { - //if (memf != NULL) { - if (kread(0, 0, 0) == 0) - mbpr(nl[N_MBSTAT].n_value); - //mbpr(nl[N_MBSTAT].n_value, - // nl[N_MBTYPES].n_value, - // nl[N_NMBCLUSTERS].n_value, - // nl[N_NMBUFS].n_value); - //} else - // mbpr(0, 0, 0, 0); - //mbpr(0) ; + mbpr(); exit(0); } -#if 0 - /* - * Keep file descriptors open to avoid overhead - * of open/close on each call to get* routines. - */ - sethostent(1); - setnetent(1); -#else - /* - * This does not make sense any more with DNS being default over - * the files. Doing a setXXXXent(1) causes a tcp connection to be - * used for the queries, which is slower. - */ -#endif - if (iflag && !sflag) { - kread(0, 0, 0); - intpr(interval, nl[N_IFNET].n_value, NULL); + if (iflag && !sflag && !Sflag && !gflag && !qflag && !Qflag) { + if (Rflag) + intpr_ri(NULL); + else + intpr(NULL); exit(0); } if (rflag) { - kread(0, 0, 0); if (sflag) - rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value); + rt_stats(); else - routepr(nl[N_RTREE].n_value); + routepr(); exit(0); } - if (gflag) { - kread(0, 0, 0); - if (sflag) { - if (af == AF_INET || af == AF_UNSPEC) - mrt_stats(nl[N_MRTSTAT].n_value); -#ifdef INET6 - if (af == AF_INET6 || af == AF_UNSPEC) - mrt6_stats(nl[N_MRT6STAT].n_value); -#endif + if (qflag || Qflag) { + if (interface == NULL) { + fprintf(stderr, "%s statistics option " + "requires interface name\n", qflag ? "Queue" : + "Polling"); + } else if (qflag) { + aqstatpr(); } else { - if (af == AF_INET || af == AF_UNSPEC) - mroutepr(nl[N_MFCTABLE].n_value, - nl[N_VIFTABLE].n_value); -#ifdef INET6 - if (af == AF_INET6 || af == AF_UNSPEC) - mroute6pr(nl[N_MF6CTABLE].n_value, - nl[N_MIF6TABLE].n_value); -#endif + rxpollstatpr(); } exit(0); } + if (Sflag) { + if (interface == NULL) { + fprintf(stderr, "additional link status option" + " requires interface name\n"); + } else { + print_link_status(interface); + } + exit(0); + } + +#if defined(__APPLE__) + if (gflag) { + ifmalist_dump(); + exit(0); + } +#endif - kread(0, 0, 0); if (tp) { printproto(tp, tp->pr_name); exit(0); @@ -609,31 +438,22 @@ main(argc, argv) for (tp = pfkeyprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name); #endif /*IPSEC*/ -#ifndef __APPLE__ - if (af == AF_IPX || af == AF_UNSPEC) { - kread(0, 0, 0); - for (tp = ipxprotox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); - } - if (af == AF_APPLETALK || af == AF_UNSPEC) - for (tp = atalkprotox; tp->pr_name; tp++) + if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag) + unixpr(); + + if ((af == AF_SYSTEM || af == AF_UNSPEC) && !Lflag) + for (tp = systmprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name); - if (af == AF_NETGRAPH || af == AF_UNSPEC) - for (tp = netgraphprotox; tp->pr_name; tp++) +#if TARGET_OS_IPHONE + if (af == AF_UNSPEC && !Lflag) + for (tp = nstatprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name); -#endif -#ifdef NS - if (af == AF_NS || af == AF_UNSPEC) - for (tp = nsprotox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); -#endif -#ifdef ISO - if (af == AF_ISO || af == AF_UNSPEC) - for (tp = isoprotox; tp->pr_name; tp++) +#endif /* TARGET_OS_IPHONE */ + + if (af == AF_UNSPEC && !Lflag) + for (tp = ipcprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name); -#endif - if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag) - unixpr(); + #ifdef SRVCACHE _serv_cache_close(); #endif @@ -650,15 +470,14 @@ printproto(tp, name) register struct protox *tp; char *name; { - void (*pr)(u_long, char *, int); - u_long off; + void (*pr)(uint32_t, char *, int); + uint32_t off; if (sflag) { - if (iflag) { + if (iflag && !pflag) { if (tp->pr_istats) - intpr(interval, nl[N_IFNET].n_value, - tp->pr_istats); - else if (pflag) + intpr(tp->pr_istats); + else if (vflag) printf("%s: no per-interface stats routine\n", tp->pr_name); return; @@ -666,78 +485,48 @@ printproto(tp, name) else { pr = tp->pr_stats; if (!pr) { - if (pflag) + if (pflag && vflag) printf("%s: no stats routine\n", tp->pr_name); return; } - off = tp->pr_usesysctl ? tp->pr_usesysctl - : nl[tp->pr_sindex].n_value; + off = tp->pr_protocol; } } else { pr = tp->pr_cblocks; if (!pr) { - if (pflag) + if (pflag && vflag) printf("%s: no PCB routine\n", tp->pr_name); return; } - off = tp->pr_usesysctl ? tp->pr_usesysctl - : nl[tp->pr_index].n_value; - } - if (pr != NULL && (off || af != AF_UNSPEC)) - (*pr)(off, name, af); -} - -/* - * Read kernel memory, return 0 on success. - */ -int -kread(u_long addr, char *buf, int size) -{ - if (kvmd == 0) { - /* - * XXX. - */ - kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf); - if (kvmd != NULL) { - if (kvm_nlist(kvmd, nl) < 0) { - if(nlistf) - errx(1, "%s: kvm_nlist: %s", nlistf, - kvm_geterr(kvmd)); - else - errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); - } - - if (nl[0].n_type == 0) { - if(nlistf) - errx(1, "%s: no namelist", nlistf); - else - errx(1, "no namelist"); - } - } else { - warnx("kvm not available"); - return(-1); - } + off = tp->pr_protocol; } - if (!buf) - return (0); - if (kvm_read(kvmd, addr, buf, size) != size) { - warnx("%s", kvm_geterr(kvmd)); - return (-1); + if (pr != NULL) { + if (sflag && iflag && pflag) + intervalpr(pr, off, name, af); + else + (*pr)(off, name, af); + } else { + printf("### no stats for %s\n", name); } - return (0); } char * plural(int n) { - return (n != 1 ? "s" : ""); + return (n > 1 ? "s" : ""); } char * plurales(int n) { - return (n != 1 ? "es" : ""); + return (n > 1 ? "es" : ""); +} + +char * +pluralies(int n) +{ + return (n > 1 ? "ies" : "y"); } /* @@ -785,14 +574,36 @@ name2protox(char *name) return (NULL); } +#define NETSTAT_USAGE "\ +Usage: netstat [-AaLlnW] [-f address_family | -p protocol]\n\ + netstat [-gilns] [-f address_family]\n\ + netstat -i | -I interface [-w wait] [-abdgRtS]\n\ + netstat -s [-s] [-f address_family | -p protocol] [-w wait]\n\ + netstat -i | -I interface -s [-f address_family | -p protocol]\n\ + netstat -m [-m]\n\ + netstat -r [-Aaln] [-f address_family]\n\ + netstat -rs [-s]\n\ +" + static void usage(void) { - (void)fprintf(stderr, "%s\n%s\n%s\n%s\n", -"usage: netstat [-Aan] [-f address_family] [-M core] [-N system]", -" netstat [-bdghimnrs] [-f address_family] [-M core] [-N system]", -" netstat [-bdn] [-I interface] [-M core] [-N system] [-w wait]", -" netstat -m [-M core] [-N system]", -" netstat [-M core] [-N system] [-p protocol]"); + (void) fprintf(stderr, "%s\n", NETSTAT_USAGE); exit(1); } + +int +print_time(void) +{ + time_t now; + struct tm tm; + int num_written = 0; + + (void) time(&now); + (void) localtime_r(&now, &tm); + + num_written += printf("%02d:%02d:%02d ", tm.tm_hour, tm.tm_min, tm.tm_sec); + + return (num_written); +} +