diff options
Diffstat (limited to 'usr.bin/netstat/main.c')
-rw-r--r-- | usr.bin/netstat/main.c | 200 |
1 files changed, 145 insertions, 55 deletions
diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 1a5bc14..034ffbd 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -125,6 +125,26 @@ static struct nlist nl[] = { { "_ddpcb"}, #define N_NGSOCKS 27 { "_ngsocklist"}, +#define N_IP6STAT 28 + { "_ip6stat" }, +#define N_ICMP6STAT 29 + { "_icmp6stat" }, +#ifdef notyet +#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" }, +#endif { "" }, }; @@ -134,81 +154,116 @@ struct protox { u_char pr_wanted; /* 1 if wanted, 0 otherwise */ void (*pr_cblocks)(); /* control blocks printing routine */ void (*pr_stats)(); /* statistics printing routine */ + void (*pr_istats)(); /* per/if statistics printing routine */ char *pr_name; /* well-known name */ int pr_usesysctl; /* true if we use sysctl, not kvm */ } protox[] = { { -1, -1, 1, protopr, - tcp_stats, "tcp", IPPROTO_TCP }, + tcp_stats, NULL, "tcp", IPPROTO_TCP }, { -1, -1, 1, protopr, - udp_stats, "udp", IPPROTO_UDP }, + udp_stats, NULL, "udp", IPPROTO_UDP }, { -1, -1, 1, protopr, - NULL, "divert", IPPROTO_DIVERT }, + NULL, NULL, "divert",IPPROTO_DIVERT }, { -1, -1, 1, protopr, - ip_stats, "ip", IPPROTO_RAW }, + ip_stats, NULL, "ip", IPPROTO_RAW }, { -1, -1, 1, protopr, - icmp_stats, "icmp", IPPROTO_ICMP }, + icmp_stats, NULL, "icmp", IPPROTO_ICMP }, { -1, -1, 1, protopr, - igmp_stats, "igmp", IPPROTO_IGMP }, + igmp_stats, NULL, "igmp", IPPROTO_IGMP }, +#ifdef IPSEC + { -1, N_IPSECSTAT, 1, 0, + ipsec_stats, NULL, "ipsec", 0}, +#endif { -1, -1, 1, protopr, - bdg_stats, "bdg", 1 /* bridging... */ }, + bdg_stats, NULL, "bdg", 1 /* bridging... */ }, { -1, -1, 0, 0, - 0, 0 } + 0, 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, 0, + ip6_stats, ip6_ifstats, "ip6", 0 }, + { -1, N_ICMP6STAT, 1, 0, + icmp6_stats, icmp6_ifstats, "icmp6",0 }, +#ifdef IPSEC + { -1, N_IPSEC6STAT, 1, 0, + ipsec_stats, NULL, "ipsec6",0 }, +#endif +#ifdef notyet + { -1, N_PIM6STAT, 1, 0, + pim6_stats, NULL, "pim6", 0 }, +#endif + { -1, -1, 1, protopr, + bdg_stats, NULL, "bdg", 1 /* bridging... */ }, + { -1, -1, 0, 0, + 0, NULL, 0, 0 } +}; +#endif /*INET6*/ + struct protox atalkprotox[] = { { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, - ddp_stats, "ddp" }, + ddp_stats, NULL, "ddp" }, { -1, -1, 0, 0, - 0, 0 } + 0, NULL, 0 } }; struct protox netgraphprotox[] = { { N_NGSOCKS, -1, 1, netgraphprotopr, - NULL, "ctrl" }, + NULL, NULL, "ctrl" }, { N_NGSOCKS, -1, 1, netgraphprotopr, - NULL, "data" }, - { -1, -1, 0, 0, - 0, 0 } + NULL, NULL, "data" }, + { -1, NULL, 0, 0, + 0, NULL, 0 } }; struct protox ipxprotox[] = { { N_IPX, N_IPXSTAT, 1, ipxprotopr, - ipx_stats, "ipx", 0 }, + ipx_stats, NULL, "ipx", 0 }, { N_IPX, N_SPXSTAT, 1, ipxprotopr, - spx_stats, "spx", 0 }, + spx_stats, NULL, "spx", 0 }, { -1, -1, 0, 0, - 0, 0, 0 } + 0, NULL, 0, 0 } }; #ifdef NS struct protox nsprotox[] = { { N_IDP, N_IDPSTAT, 1, nsprotopr, - idp_stats, "idp" }, + idp_stats, NULL, "idp" }, { N_IDP, N_SPPSTAT, 1, nsprotopr, - spp_stats, "spp" }, + spp_stats, NULL, "spp" }, { -1, N_NSERR, 1, 0, - nserr_stats, "ns_err" }, + nserr_stats, NULL, "ns_err" }, { -1, -1, 0, 0, - 0, 0 } + 0, NULL, 0 } }; #endif #ifdef ISO struct protox isoprotox[] = { { ISO_TP, N_TPSTAT, 1, iso_protopr, - tp_stats, "tp" }, + tp_stats, NULL, "tp" }, { N_CLTP, N_CLTPSTAT, 1, iso_protopr, - cltp_stats, "cltp" }, + cltp_stats, NULL, "cltp" }, { -1, N_CLNPSTAT, 1, 0, - clnp_stats, "clnp"}, + clnp_stats, NULL, "clnp"}, { -1, N_ESISSTAT, 1, 0, - esis_stats, "esis"}, + esis_stats, NULL, "esis"}, { -1, -1, 0, 0, - 0, 0 } + 0, NULL, 0 } }; #endif -struct protox *protoprotox[] = { protox, ipxprotox, atalkprotox, +struct protox *protoprotox[] = { + protox, +#ifdef INET6 + ip6protox, +#endif + ipxprotox, atalkprotox, #ifdef NS nsprotox, #endif @@ -230,13 +285,12 @@ main(argc, argv) int argc; char *argv[]; { - register struct protoent *p; register struct protox *tp = NULL; /* for printing cblocks & stats */ int ch; af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "Aabdf:ghI:iM:mN:np:rstuw:")) != -1) + while ((ch = getopt(argc, argv, "Aabdf:ghI:liM:mN:np:rstuw:")) != -1) switch(ch) { case 'A': Aflag = 1; @@ -260,6 +314,10 @@ main(argc, argv) af = AF_IPX; else if (strcmp(optarg, "inet") == 0) af = AF_INET; +#ifdef INET6 + else if (strcmp(optarg, "inet6") == 0) + af = AF_INET6; +#endif /*INET6*/ else if (strcmp(optarg, "unix") == 0) af = AF_UNIX; else if (strcmp(optarg, "atalk") == 0) @@ -290,6 +348,9 @@ main(argc, argv) case 'i': iflag = 1; break; + case 'l': + lflag = 1; + break; case 'M': memf = optarg; break; @@ -363,6 +424,11 @@ main(argc, argv) exit(0); } if (pflag) { + if (iflag && tp->pr_istats) { + kread(0, 0, 0); + intpr(interval, nl[N_IFNET].n_value, tp->pr_istats); + exit(0); + } if (!tp->pr_stats) { printf("%s: no stats routine\n", tp->pr_name); exit(0); @@ -391,8 +457,11 @@ main(argc, argv) */ #endif if (iflag) { + if (af != AF_UNSPEC) + goto protostat; + kread(0, 0, 0); - intpr(interval, nl[N_IFNET].n_value); + intpr(interval, nl[N_IFNET].n_value, NULL); exit(0); } if (rflag) { @@ -405,27 +474,40 @@ main(argc, argv) } if (gflag) { kread(0, 0, 0); - if (sflag) - mrt_stats(nl[N_MRTSTAT].n_value); - else - mroutepr(nl[N_MFCTABLE].n_value, - nl[N_VIFTABLE].n_value); - exit(0); - } - if (af == AF_INET || af == AF_UNSPEC) { - setprotoent(1); - setservent(1); - /* ugh, this is O(MN) ... why do we do this? */ - while ((p = getprotoent())) { - for (tp = protox; tp->pr_name; tp++) - if (strcmp(tp->pr_name, p->p_name) == 0) - break; - if (tp->pr_name == 0 || tp->pr_wanted == 0) - continue; - printproto(tp, p->p_name); + if (sflag) { + if (af == AF_INET || af == AF_UNSPEC) + mrt_stats(nl[N_MRTSTAT].n_value); +#ifdef INET6 +#ifdef notyet + if (af == AF_INET6 || af == AF_UNSPEC) + mrt6_stats(nl[N_MRT6STAT].n_value); +#endif +#endif + } else { + if (af == AF_INET || af == AF_UNSPEC) + mroutepr(nl[N_MFCTABLE].n_value, + nl[N_VIFTABLE].n_value); +#ifdef INET6 +#ifdef notyet + if (af == AF_INET6 || af == AF_UNSPEC) + mroute6pr(nl[N_MF6CTABLE].n_value, + nl[N_MIF6TABLE].n_value); +#endif +#endif } - endprotoent(); + exit(0); } + + protostat: + kread(0, 0, 0); + if (af == AF_INET || af == AF_UNSPEC) + for (tp = protox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); +#ifdef INET6 + if (af == AF_INET6 || af == AF_UNSPEC) + for (tp = ip6protox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); +#endif /*INET6*/ if (af == AF_IPX || af == AF_UNSPEC) { kread(0, 0, 0); for (tp = ipxprotox; tp->pr_name; tp++) @@ -466,16 +548,24 @@ printproto(tp, name) u_long off; if (sflag) { - pr = tp->pr_stats; - off = tp->pr_usesysctl ? tp->pr_usesysctl - : nl[tp->pr_sindex].n_value; + if (iflag) { + if (tp->pr_istats) + intpr(interval, nl[N_IFNET].n_value, + tp->pr_istats); + return; + } + else { + pr = tp->pr_stats; + off = tp->pr_usesysctl ? tp->pr_usesysctl + : nl[tp->pr_sindex].n_value; + } } else { pr = tp->pr_cblocks; off = tp->pr_usesysctl ? tp->pr_usesysctl : nl[tp->pr_index].n_value; } if (pr != NULL && (off || af != AF_UNSPEC)) - (*pr)(off, name); + (*pr)(off, name, af); } /* @@ -566,11 +656,11 @@ name2protox(name) * Try to find the name in the list of "well-known" names. If that * fails, check if name is an alias for an Internet protocol. */ - if ((tp = knownname(name))) + if ((tp = knownname(name)) != NULL) return (tp); setprotoent(1); /* make protocol lookup cheaper */ - while ((p = getprotoent())) { + while ((p = getprotoent()) != NULL) { /* assert: name not same as p->name */ for (alias = p->p_aliases; *alias; alias++) if (strcmp(name, *alias) == 0) { |