X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/fdfd5971fdda9c24d576337643161018a5281167..fa34b6f5f32f696bb2fe92a877dfaec960fcd850:/netstat.tproj/inet6.c diff --git a/netstat.tproj/inet6.c b/netstat.tproj/inet6.c index 0d8396e..a741196 100644 --- a/netstat.tproj/inet6.c +++ b/netstat.tproj/inet6.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@ * @@ -62,12 +62,6 @@ * $FreeBSD: src/usr.bin/netstat/inet6.c,v 1.3.2.9 2001/08/10 09:07:09 ru Exp $ */ -#ifndef lint -/* -static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; -*/ -#endif /* not lint */ - #ifdef INET6 #include #include @@ -78,6 +72,7 @@ static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; #include #include #include +#include #include #include #include @@ -85,7 +80,6 @@ static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; #include #include #include -#include #include #include @@ -362,6 +356,27 @@ static char *ip6nh[] = { "#255", }; + +static const char *srcrulenames[IP6S_SRCRULE_COUNT] = { + "default", // IP6S_SRCRULE_0 + "prefer same address", // IP6S_SRCRULE_1 + "prefer appropriate scope", // IP6S_SRCRULE_2 + "avoid deprecated addresses", // IP6S_SRCRULE_3 + "prefer home addresses", // IP6S_SRCRULE_4 + "prefer outgoing interface", // IP6S_SRCRULE_5 + "prefer addresses in a prefix advertised by the next-hop", + // IP6S_SRCRULE_5_5 + "prefer matching label", // IP6S_SRCRULE_6 + "prefer temporary addresses", // IP6S_SRCRULE_7 + "prefer addresses on alive interfaces", // IP6S_SRCRULE_7x + "use longest matching prefix", // IP6S_SRCRULE_8 + NULL, + NULL, + NULL, + NULL, + NULL +}; + /* * Dump IP6 statistics structure. */ @@ -373,6 +388,20 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) int first, i; int mib[4]; size_t len; + static net_perf_t pout_net_perf, pin_net_perf; + net_perf_t out_net_perf, in_net_perf; + size_t out_net_perf_len = sizeof (out_net_perf); + size_t in_net_perf_len = sizeof (in_net_perf); + + if (sysctlbyname("net.inet6.ip6.output_perf_data", &out_net_perf, &out_net_perf_len, 0, 0) < 0) { + perror("sysctl: net.inet6.ip6.output_perf_data"); + return; + } + + if (sysctlbyname("net.inet6.ip6.input_perf_data", &in_net_perf, &in_net_perf_len, 0, 0) < 0) { + perror("sysctl: net.inet6.ip6.input_perf_data"); + return; + } mib[0] = CTL_NET; mib[1] = PF_INET6; @@ -383,6 +412,8 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) memset(&ip6stat, 0, len); if (sysctl(mib, 4, &ip6stat, &len, (void *)0, 0) < 0) return; + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define IP6DIFF(f) (ip6stat.f - pip6stat.f) @@ -392,28 +423,92 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) printf(m, (unsigned long long)IP6DIFF(f)) p(ip6s_total, "\t%llu total packet%s received\n"); - p1a(ip6s_toosmall, "\t%llu with size smaller than minimum\n"); - p1a(ip6s_tooshort, "\t%llu with data size < data length\n"); - p1a(ip6s_badoptions, "\t%llu with bad options\n"); - p1a(ip6s_badvers, "\t%llu with incorrect version number\n"); - p(ip6s_fragments, "\t%llu fragment%s received\n"); - p(ip6s_fragdropped, "\t%llu fragment%s dropped (dup or out of space)\n"); - p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n"); - p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n"); - p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n"); - p(ip6s_delivered, "\t%llu packet%s for this host\n"); - p(ip6s_forward, "\t%llu packet%s forwarded\n"); - p(ip6s_cantforward, "\t%llu packet%s not forwardable\n"); - p(ip6s_redirectsent, "\t%llu redirect%s sent\n"); + p1a(ip6s_toosmall, "\t\t%llu with size smaller than minimum\n"); + p1a(ip6s_tooshort, "\t\t%llu with data size < data length\n"); + p1a(ip6s_adj, "\t\t%llu with data size > data length\n"); + p(ip6s_adj_hwcsum_clr, + "\t\t\t%llu packet%s forced to software checksum\n"); + p1a(ip6s_badoptions, "\t\t%llu with bad options\n"); + p1a(ip6s_badvers, "\t\t%llu with incorrect version number\n"); + p(ip6s_fragments, "\t\t%llu fragment%s received\n"); + p1a(ip6s_fragdropped, + "\t\t\t%llu dropped (dup or out of space)\n"); + p1a(ip6s_fragtimeout, "\t\t\t%llu dropped after timeout\n"); + p1a(ip6s_fragoverflow, "\t\t\t%llu exceeded limit\n"); + p1a(ip6s_reassembled, "\t\t\t%llu reassembled ok\n"); + p(ip6s_delivered, "\t\t%llu packet%s for this host\n"); + p(ip6s_forward, "\t\t%llu packet%s forwarded\n"); + p(ip6s_cantforward, "\t\t%llu packet%s not forwardable\n"); + p(ip6s_redirectsent, "\t\t%llu redirect%s sent\n"); + p(ip6s_notmember, "\t\t%llu multicast packet%s which we don't join\n"); + p(ip6s_exthdrtoolong, + "\t\t%llu packet%s whose headers are not continuous\n"); + p(ip6s_nogif, "\t\t%llu tunneling packet%s that can't find gif\n"); + p(ip6s_toomanyhdr, + "\t\t%llu packet%s discarded due to too may headers\n"); + p1a(ip6s_forward_cachehit, "\t\t%llu forward cache hit\n"); + p1a(ip6s_forward_cachemiss, "\t\t%llu forward cache miss\n"); + p(ip6s_pktdropcntrl, + "\t\t%llu packet%s dropped due to no bufs for control data\n"); + +#define INPERFDIFF(f) (in_net_perf.f - pin_net_perf.f) + if (INPERFDIFF(np_total_pkts) > 0 && in_net_perf.np_total_usecs > 0) { + printf("\tInput Performance Stats:\n"); + printf("\t\t%llu total packets measured\n", INPERFDIFF(np_total_pkts)); + printf("\t\t%llu total usec elapsed\n", INPERFDIFF(np_total_usecs)); + printf("\t\t%f usec per packet\n", + (double)in_net_perf.np_total_usecs/(double)in_net_perf.np_total_pkts); + printf("\t\tPerformance Histogram:\n"); + printf("\t\t\t x <= %u: %llu\n", in_net_perf.np_hist_bars[0], + INPERFDIFF(np_hist1)); + printf("\t\t\t %u < x <= %u: %llu\n", + in_net_perf.np_hist_bars[0], in_net_perf.np_hist_bars[1], + INPERFDIFF(np_hist2)); + printf("\t\t\t %u < x <= %u: %llu\n", + in_net_perf.np_hist_bars[1], in_net_perf.np_hist_bars[2], + INPERFDIFF(np_hist3)); + printf("\t\t\t %u < x <= %u: %llu\n", + in_net_perf.np_hist_bars[2], in_net_perf.np_hist_bars[3], + INPERFDIFF(np_hist4)); + printf("\t\t\t %u < x: %llu\n", + in_net_perf.np_hist_bars[3], INPERFDIFF(np_hist5)); + } +#undef INPERFDIFF + p(ip6s_localout, "\t%llu packet%s sent from this host\n"); - p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n"); - p(ip6s_odropped, "\t%llu output packet%s dropped due to no bufs, etc.\n"); - p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n"); - p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n"); - p(ip6s_ofragments, "\t%llu fragment%s created\n"); - p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n"); - p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n"); - p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n"); + p(ip6s_rawout, "\t\t%llu packet%s sent with fabricated ip header\n"); + p(ip6s_odropped, + "\t\t%llu output packet%s dropped due to no bufs, etc.\n"); + p(ip6s_noroute, "\t\t%llu output packet%s discarded due to no route\n"); + p(ip6s_fragmented, "\t\t%llu output datagram%s fragmented\n"); + p(ip6s_ofragments, "\t\t%llu fragment%s created\n"); + p(ip6s_cantfrag, "\t\t%llu datagram%s that can't be fragmented\n"); + p(ip6s_badscope, "\t\t%llu packet%s that violated scope rules\n"); + +#define OUTPERFDIFF(f) (out_net_perf.f - pout_net_perf.f) + if (OUTPERFDIFF(np_total_pkts) > 0 && out_net_perf.np_total_usecs > 0) { + printf("\tOutput Performance Stats:\n"); + printf("\t\t%llu total packets measured\n", OUTPERFDIFF(np_total_pkts)); + printf("\t\t%llu total usec elapsed\n", OUTPERFDIFF(np_total_usecs)); + printf("\t\t%f usec per packet\n", + (double)out_net_perf.np_total_usecs/(double)out_net_perf.np_total_pkts); + printf("\t\tHistogram:\n"); + printf("\t\t\t x <= %u: %llu\n", out_net_perf.np_hist_bars[0], + OUTPERFDIFF(np_hist1)); + printf("\t\t\t %u < x <= %u: %llu\n", + out_net_perf.np_hist_bars[0], out_net_perf.np_hist_bars[1], + OUTPERFDIFF(np_hist2)); + printf("\t\t\t %u < x <= %u: %llu\n", + out_net_perf.np_hist_bars[1], out_net_perf.np_hist_bars[2], + OUTPERFDIFF(np_hist3)); + printf("\t\t\t %u < x <= %u: %llu\n", + out_net_perf.np_hist_bars[2], out_net_perf.np_hist_bars[3], + OUTPERFDIFF(np_hist4)); + printf("\t\t\t %u < x: %llu\n", + out_net_perf.np_hist_bars[3], OUTPERFDIFF(np_hist5)); + } +#undef OUTPERFDIFF + for (first = 1, i = 0; i < 256; i++) if (IP6DIFF(ip6s_nxthist[i]) != 0) { if (first) { @@ -441,88 +536,102 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) (unsigned long long)IP6DIFF(ip6s_mext1)); printf("\t\t%llu two or more ext mbuf\n", (unsigned long long)IP6DIFF(ip6s_mext2m)); - p(ip6s_exthdrtoolong, - "\t%llu packet%s whose headers are not continuous\n"); - p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n"); - p(ip6s_toomanyhdr, - "\t%llu packet%s discarded due to too may headers\n"); /* for debugging source address selection */ #define PRINT_SCOPESTAT(s,i) do {\ switch(i) { /* XXX hardcoding in each case */\ case 1:\ - p(s, "\t\t%llu node-local%s\n");\ + p(s, "\t\t\t%llu node-local%s\n");\ break;\ case 2:\ - p(s,"\t\t%llu link-local%s\n");\ + p(s,"\t\t\t%llu link-local%s\n");\ break;\ case 5:\ - p(s,"\t\t%llu site-local%s\n");\ + p(s,"\t\t\t%llu site-local%s\n");\ break;\ case 14:\ - p(s,"\t\t%llu global%s\n");\ + p(s,"\t\t\t%llu global%s\n");\ break;\ default:\ - printf("\t\t%llu addresses scope=%x\n",\ + printf("\t\t\t%llu addresses scope=%x\n",\ (unsigned long long)IP6DIFF(s), i);\ }\ } while (0); p(ip6s_sources_none, - "\t%llu failure%s of source address selection\n"); - for (first = 1, i = 0; i < 16; i++) { - if (IP6DIFF(ip6s_sources_sameif[i])) { + "\t\t%llu failure%s of source address selection\n"); + for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) { + if (IP6DIFF(ip6s_sources_sameif[i]) || 1) { if (first) { - printf("\tsource addresses on an outgoing I/F\n"); + printf("\t\tsource addresses on an outgoing I/F\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); } } - for (first = 1, i = 0; i < 16; i++) { - if (IP6DIFF(ip6s_sources_otherif[i])) { + for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) { + if (IP6DIFF(ip6s_sources_otherif[i]) || 1) { if (first) { - printf("\tsource addresses on a non-outgoing I/F\n"); + printf("\t\tsource addresses on a non-outgoing I/F\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); } } - for (first = 1, i = 0; i < 16; i++) { - if (IP6DIFF(ip6s_sources_samescope[i])) { + for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) { + if (IP6DIFF(ip6s_sources_samescope[i]) || 1) { if (first) { - printf("\tsource addresses of same scope\n"); + printf("\t\tsource addresses of same scope\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); } } - for (first = 1, i = 0; i < 16; i++) { - if (IP6DIFF(ip6s_sources_otherscope[i])) { + for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) { + if (IP6DIFF(ip6s_sources_otherscope[i]) || 1) { if (first) { - printf("\tsource addresses of a different scope\n"); + printf("\t\tsource addresses of a different scope\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); } } - for (first = 1, i = 0; i < 16; i++) { - if (IP6DIFF(ip6s_sources_deprecated[i])) { + for (first = 1, i = 0; i < SCOPE6_ID_MAX; i++) { + if (IP6DIFF(ip6s_sources_deprecated[i]) || 1) { if (first) { - printf("\tdeprecated source addresses\n"); + printf("\t\tdeprecated source addresses\n"); first = 0; } PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); } } +#define PRINT_SRCRULESTAT(s,i) do {\ + if (srcrulenames[i] != NULL) \ + printf("\t\t\t%llu rule%s %s\n", \ + (unsigned long long)IP6DIFF(s), \ + plural(IP6DIFF(s)), \ + srcrulenames[i]); \ +} while (0); - p1a(ip6s_forward_cachehit, "\t%llu forward cache hit\n"); - p1a(ip6s_forward_cachemiss, "\t%llu forward cache miss\n"); - p(ip6s_pktdropcntrl, "\t%llu packet%s dropped due to no bufs for control data\n"); + for (first = 1, i = 0; i < IP6S_SRCRULE_COUNT; i++) { + if (IP6DIFF(ip6s_sources_rule[i]) || 1) { + if (first) { + printf("\t\tsource addresse selection\n"); + first = 0; + } + PRINT_SRCRULESTAT(ip6s_sources_rule[i], i); + } + } - if (interval > 0) - bcopy(&ip6stat, &pip6stat, len); + p(ip6s_dad_collide, "\t\t%llu duplicate address detection collision%s\n"); + + p(ip6s_sources_skip_expensive_secondary_if, "\t\t%llu times%s ignored source on secondary expensive I/F\n"); + if (interval > 0) { + bcopy(&ip6stat, &pip6stat, len); + bcopy(&in_net_perf, &pin_net_perf, in_net_perf_len); + bcopy(&out_net_perf, &pout_net_perf, out_net_perf_len); + } #undef IP6DIFF #undef p #undef p1a @@ -546,6 +655,8 @@ ip6_ifstats(char *ifname) return; } + if (interval && vflag > 0) + print_time(); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); printf("ip6 on %s:\n", ifr.ifr_name); @@ -864,6 +975,8 @@ icmp6_stats(uint32_t off __unused, char *name, int af __unused) memset(&icmp6stat, 0, len); if (sysctl(mib, 4, &icmp6stat, &len, (void *)0, 0) < 0) return; + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define ICMP6DIFF(f) (icmp6stat.f - picmp6stat.f) @@ -951,6 +1064,8 @@ icmp6_ifstats(char *ifname) return; } + if (interval && vflag > 0) + print_time(); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); printf("icmp6 on %s:\n", ifr.ifr_name); @@ -1000,40 +1115,6 @@ icmp6_ifstats(char *ifname) #undef p } -/* - * Dump PIM statistics structure. - */ -#ifdef notyet -void -pim6_stats(void) -{ - static struct pim6stat ppim6stat; - struct pim6stat pim6stat; - size_t len = sizeof(struct pim6stat); - - if (sysctlbyname("net.inet6.ip6.pim6stat", &pim6stat, &len, 0, 0) == -1) - return; - printf("%s:\n", name); - -#define PIM6DIFF(f) (pim6stat.f - ppim6stat.f) -#define p(f, m) if (PIM6DIFF(f) || sflag <= 1) \ - printf(m, (unsigned long long)PIM6DIFF(f), plural(PIM6DIFF(f))) - p(pim6s_rcv_total, "\t%llu message%s received\n"); - p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n"); - p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n"); - p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n"); - p(pim6s_rcv_registers, "\t%llu register%s received\n"); - p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n"); - p(pim6s_snd_registers, "\t%llu register%s sent\n"); - - if (interval > 0) - bcopy(&pim6stat, &ppim6stat, len); - -#undef PIM6DIFF -#undef p -} -#endif - /* * Dump raw ip6 statistics structure. */ @@ -1056,6 +1137,8 @@ rip6_stats(uint32_t off __unused, char *name, int af __unused) return; } + if (interval && vflag > 0) + print_time(); printf("%s:\n", name); #define RIP6DIFF(f) (rip6stat.f - prip6stat.f) @@ -1154,7 +1237,7 @@ inet6name(struct in6_addr *in6p) first = 0; if (gethostname(domain, MAXHOSTNAMELEN) == 0 && (cp = index(domain, '.'))) - (void) strlcpy(domain, cp + 1, sizeof(domain)); + (void) memmove(domain, cp + 1, strlen(cp + 1) + 1); else domain[0] = 0; }