X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/5902acfc600aa7d331608b1286d6af0b21f6a7ba..755a8d69d575c678ea4570e9f9ef0d076b0f1557:/netstat.tproj/main.c diff --git a/netstat.tproj/main.c b/netstat.tproj/main.c index c30de82..6830b67 100644 --- a/netstat.tproj/main.c +++ b/netstat.tproj/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Apple Inc. All rights reserved. + * Copyright (c) 2008-2015 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -67,6 +67,7 @@ char const copyright[] = #include #include #include +#include #include #include @@ -102,166 +103,83 @@ char const copyright[] = * */ -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_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)(uint32_t, char *, int); /* control blocks printing routine */ 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, -1, 1, 0, - ipsec_stats, NULL, "ipsec", IPPROTO_ESP}, + { 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",IPPROTO_ESP }, -#endif -#ifdef notyet - { -1, N_PIM6STAT, 1, 0, - pim6_stats, NULL, "pim6", 0 }, + { NULL, ipsec_stats, NULL, "ipsec6", IPPROTO_ESP }, #endif - { -1, -1, 1, 0, - rip6_stats, NULL, "rip6", IPPROTO_RAW }, - { -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", PF_KEY_V2 }, - { -1, -1, 0, 0, - 0, NULL, 0, 0 } + { NULL, pfkey_stats, NULL, "pfkey", PF_KEY_V2 }, + { NULL, NULL, NULL, NULL, 0 } }; #endif + +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 } +}; + +struct protox nstatprotox[] = { + { NULL, print_nstat_stats, NULL, "nstat", 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + +struct protox ipcprotox[] = { + { NULL, print_extbkidle_stats, NULL, "xbkidle", 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + + struct protox *protoprotox[] = { - protox, + protox, #ifdef INET6 - ip6protox, + ip6protox, #endif #ifdef IPSEC - pfkeyprotox, + pfkeyprotox, #endif - NULL }; + systmprotox, + nstatprotox, + ipcprotox, + NULL +}; static void printproto (struct protox *, char *); static void usage (void); @@ -274,7 +192,9 @@ extern void _serv_cache_close(); 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 @@ -284,12 +204,19 @@ 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; /* show packet priority statistics */ +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 */ @@ -307,7 +234,7 @@ main(argc, argv) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "Aabdf:gI:iLlmnP:p:rRstuWw:")) != -1) + while ((ch = getopt(argc, argv, "Aabc:dFf:gI:ikLlmnP:p:qQrRsStuvWw:x")) != -1) switch(ch) { case 'A': Aflag = 1; @@ -318,9 +245,16 @@ 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': if (strcmp(optarg, "ipx") == 0) af = AF_IPX; @@ -336,6 +270,8 @@ main(argc, argv) #endif /*INET6*/ else if (strcmp(optarg, "unix") == 0) af = AF_UNIX; + else if (strcmp(optarg, "systm") == 0) + af = AF_SYSTEM; else { errx(1, "%s: unknown address family", optarg); } @@ -380,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; @@ -399,6 +350,10 @@ main(argc, argv) interval = atoi(optarg); iflag = 1; break; + case 'x': + xflag = 1; + Rflag = 1; + break; case '?': default: usage(); @@ -423,36 +378,44 @@ main(argc, argv) mbpr(); exit(0); } - if (iflag && !sflag) { - intpr(NULL); + if (iflag && !sflag && !Sflag && !gflag && !qflag && !Qflag) { + if (Rflag) + intpr_ri(NULL); + else + intpr(NULL); exit(0); } if (rflag) { if (sflag) rt_stats(); else - routepr(nl[N_RTREE].n_value); + routepr(); exit(0); } -#if defined(__APPLE__) - if (gflag) { -#if !TARGET_OS_EMBEDDED - if (sflag) { - if (af == AF_INET || af == AF_UNSPEC) - mrt_stats(); -#ifdef INET6 - if (af == AF_INET6 || af == AF_UNSPEC) - mrt6_stats(); -#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(); -#ifdef INET6 - if (af == AF_INET6 || af == AF_UNSPEC) - mroute6pr(); -#endif + rxpollstatpr(); } -#endif /* !TARGET_OS_EMBEDDED */ + 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); } @@ -477,6 +440,20 @@ main(argc, argv) #endif /*IPSEC*/ 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 TARGET_OS_IPHONE + if (af == AF_UNSPEC && !Lflag) + for (tp = nstatprotox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); +#endif /* TARGET_OS_IPHONE */ + + if (af == AF_UNSPEC && !Lflag) + for (tp = ipcprotox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); + #ifdef SRVCACHE _serv_cache_close(); #endif @@ -500,7 +477,7 @@ printproto(tp, name) if (iflag && !pflag) { if (tp->pr_istats) intpr(tp->pr_istats); - else + else if (vflag) printf("%s: no per-interface stats routine\n", tp->pr_name); return; @@ -508,25 +485,23 @@ 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; + off = tp->pr_protocol; } - if (pr != NULL && (off || af != AF_UNSPEC)) { + if (pr != NULL) { if (sflag && iflag && pflag) intervalpr(pr, off, name, af); else @@ -539,13 +514,19 @@ printproto(tp, name) 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"); } /* @@ -596,7 +577,7 @@ name2protox(char *name) #define NETSTAT_USAGE "\ Usage: netstat [-AaLlnW] [-f address_family | -p protocol]\n\ netstat [-gilns] [-f address_family]\n\ - netstat -i | -I interface [-w wait] [-abdgt]\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\ @@ -610,3 +591,19 @@ usage(void) (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); +} +