+/*
+ * Copyright (c) 2008-2015 Apple 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. 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,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
/*
* Copyright (c) 1983, 1988, 1993
* $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 <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/if.h>
#include <net/if_var.h>
+#include <net/net_perf.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <netinet6/in6_pcb.h>
#include <netinet6/in6_var.h>
#include <netinet6/ip6_var.h>
-#include <netinet6/pim6_var.h>
#include <netinet6/raw_ip6.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "netstat.h"
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined(__unused)
#define __unused
#endif
char *inet6name (struct in6_addr *);
void inet6print (struct in6_addr *, int, char *, int);
-static char ntop_buf[INET6_ADDRSTRLEN];
-
static char *ip6nh[] = {
"hop by hop",
"ICMP",
"no next header",
"destination option",
"#61",
- "#62",
+ "mobility",
"#63",
"#64",
"#65",
"#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.
*/
void
-ip6_stats(u_long off __unused, char *name, int af __unused)
+ip6_stats(uint32_t off __unused, char *name, int af __unused)
{
+ static struct ip6stat pip6stat;
struct ip6stat ip6stat;
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;
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 p(f, m) if (ip6stat.f || sflag <= 1) \
- printf(m, (unsigned long long)ip6stat.f, plural(ip6stat.f))
-#define p1a(f, m) if (ip6stat.f || sflag <= 1) \
- printf(m, (unsigned long long)ip6stat.f)
+#define IP6DIFF(f) (ip6stat.f - pip6stat.f)
+#define p(f, m) if (IP6DIFF(f) || sflag <= 1) \
+ printf(m, (unsigned long long)IP6DIFF(f), plural(IP6DIFF(f)))
+#define p1a(f, m) if (IP6DIFF(f) || sflag <= 1) \
+ 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 (ip6stat.ip6s_nxthist[i] != 0) {
+ if (IP6DIFF(ip6s_nxthist[i]) != 0) {
if (first) {
printf("\tInput histogram:\n");
first = 0;
}
printf("\t\t%s: %llu\n", ip6nh[i],
- (unsigned long long)ip6stat.ip6s_nxthist[i]);
+ (unsigned long long)IP6DIFF(ip6s_nxthist[i]));
}
printf("\tMbuf statistics:\n");
- printf("\t\t%llu one mbuf\n", (unsigned long long)ip6stat.ip6s_m1);
+ printf("\t\t%llu one mbuf\n", (unsigned long long)IP6DIFF(ip6s_m1));
for (first = 1, i = 0; i < 32; i++) {
char ifbuf[IFNAMSIZ];
- if (ip6stat.ip6s_m2m[i] != 0) {
+ if (IP6DIFF(ip6s_m2m[i]) != 0) {
if (first) {
printf("\t\ttwo or more mbuf:\n");
first = 0;
}
printf("\t\t\t%s= %llu\n",
if_indextoname(i, ifbuf),
- (unsigned long long)ip6stat.ip6s_m2m[i]);
+ (unsigned long long)IP6DIFF(ip6s_m2m[i]));
}
}
printf("\t\t%llu one ext mbuf\n",
- (unsigned long long)ip6stat.ip6s_mext1);
+ (unsigned long long)IP6DIFF(ip6s_mext1));
printf("\t\t%llu two or more ext mbuf\n",
- (unsigned long long)ip6stat.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");
+ (unsigned long long)IP6DIFF(ip6s_mext2m));
/* 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",\
- (unsigned long long)ip6stat.s, i);\
+ 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 (ip6stat.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 (ip6stat.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 (ip6stat.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 (ip6stat.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 (ip6stat.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);
+
+ 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);
+ }
+ }
+
+ 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");
- p1a(ip6s_forward_cachehit, "\t%llu forward cache hit\n");
- p1a(ip6s_forward_cachemiss, "\t%llu forward cache miss\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
}
return;
}
- strcpy(ifr.ifr_name, ifname);
+ if (interval && vflag > 0)
+ print_time();
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
printf("ip6 on %s:\n", ifr.ifr_name);
if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
"echo",
"echo reply",
"multicast listener query",
- "multicast listener report",
- "multicast listener done",
+ "MLDv1 listener report",
+ "MLDv1 listener done",
"router solicitation",
"router advertisement",
"neighbor solicitation",
"node information reply",
"inverse neighbor solicitation",
"inverse neighbor advertisement",
- "#143",
+ "MLDv2 listener report",
"#144",
"#145",
"#146",
* Dump ICMP6 statistics.
*/
void
-icmp6_stats(u_long off __unused, char *name, int af __unused)
+icmp6_stats(uint32_t off __unused, char *name, int af __unused)
{
+ static struct icmp6stat picmp6stat;
struct icmp6stat icmp6stat;
register int i, first;
int mib[4];
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 p(f, m) if (icmp6stat.f || sflag <= 1) \
- printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f))
-#define p_5(f, m) printf(m, (unsigned long long)icmp6stat.f)
+#define ICMP6DIFF(f) (icmp6stat.f - picmp6stat.f)
+#define p(f, m) if (ICMP6DIFF(f) || sflag <= 1) \
+ printf(m, (unsigned long long)ICMP6DIFF(f), plural(ICMP6DIFF(f)))
+#define p_5(f, m) printf(m, (unsigned long long)ICMP6DIFF(f))
p(icp6s_error, "\t%llu call%s to icmp_error\n");
p(icp6s_canterror,
"\t%llu error%s not generated because rate limitation\n");
#define NELEM (sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
for (first = 1, i = 0; i < NELEM; i++)
- if (icmp6stat.icp6s_outhist[i] != 0) {
+ if (ICMP6DIFF(icp6s_outhist[i]) != 0) {
if (first) {
printf("\tOutput histogram:\n");
first = 0;
}
printf("\t\t%s: %llu\n", icmp6names[i],
- (unsigned long long)icmp6stat.icp6s_outhist[i]);
+ (unsigned long long)ICMP6DIFF(icp6s_outhist[i]));
}
#undef NELEM
p(icp6s_badcode, "\t%llu message%s with bad code fields\n");
p(icp6s_badlen, "\t%llu message%s with bad length\n");
#define NELEM (sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
for (first = 1, i = 0; i < NELEM; i++)
- if (icmp6stat.icp6s_inhist[i] != 0) {
+ if (ICMP6DIFF(icp6s_inhist[i]) != 0) {
if (first) {
printf("\tInput histogram:\n");
first = 0;
}
printf("\t\t%s: %llu\n", icmp6names[i],
- (unsigned long long)icmp6stat.icp6s_inhist[i]);
+ (unsigned long long)ICMP6DIFF(icp6s_inhist[i]));
}
#undef NELEM
printf("\tHistogram of error messages to be generated:\n");
p(icp6s_badra, "\t%qu bad router advertisement message%s\n");
p(icp6s_badredirect, "\t%qu bad redirect message%s\n");
p(icp6s_pmtuchg, "\t%llu path MTU change%s\n");
+
+ if (interval > 0)
+ bcopy(&icmp6stat, &picmp6stat, len);
+
+#undef ICMP6DIFF
#undef p
#undef p_5
}
return;
}
- strcpy(ifr.ifr_name, ifname);
+ if (interval && vflag > 0)
+ print_time();
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
printf("icmp6 on %s:\n", ifr.ifr_name);
if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
#undef p
}
-/*
- * Dump PIM statistics structure.
- */
-#ifdef notyet
-void
-pim6_stats(void)
-{
- 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 p(f, m) if (pim6stat.f || sflag <= 1) \
- printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.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");
-#undef p
-}
-#endif
-
/*
* Dump raw ip6 statistics structure.
*/
void
-rip6_stats(u_long off __unused, char *name, int af __unused)
+rip6_stats(uint32_t off __unused, char *name, int af __unused)
{
+ static struct rip6stat prip6stat;
struct rip6stat rip6stat;
u_quad_t delivered;
int mib[4];
return;
}
+ if (interval && vflag > 0)
+ print_time();
printf("%s:\n", name);
-#define p(f, m) if (rip6stat.f || sflag <= 1) \
- printf(m, (unsigned long long)rip6stat.f, plural(rip6stat.f))
+#define RIP6DIFF(f) (rip6stat.f - prip6stat.f)
+#define p(f, m) if (RIP6DIFF(f) || sflag <= 1) \
+ printf(m, (unsigned long long)RIP6DIFF(f), plural(RIP6DIFF(f)))
p(rip6s_ipackets, "\t%llu message%s received\n");
p(rip6s_isum, "\t%llu checksum calcuration%s on inbound\n");
p(rip6s_badsum, "\t%llu message%s with bad checksum\n");
"\t%llu multicast message%s dropped due to no socket\n");
p(rip6s_fullsock,
"\t%llu message%s dropped due to full socket buffers\n");
- delivered = rip6stat.rip6s_ipackets -
- rip6stat.rip6s_badsum -
- rip6stat.rip6s_nosock -
- rip6stat.rip6s_nosockmcast -
- rip6stat.rip6s_fullsock;
+ delivered = RIP6DIFF(rip6s_ipackets) -
+ RIP6DIFF(rip6s_badsum) -
+ RIP6DIFF(rip6s_nosock) -
+ RIP6DIFF(rip6s_nosockmcast) -
+ RIP6DIFF(rip6s_fullsock);
if (delivered || sflag <= 1)
printf("\t%llu delivered\n", (unsigned long long)delivered);
p(rip6s_opackets, "\t%llu datagram%s output\n");
+
+ if (interval > 0)
+ bcopy(&rip6stat, &prip6stat, l);
+
+#undef RIP6DIFF
#undef p
}
char line[80], *cp;
int width;
- sprintf(line, "%.*s.", lflag ? 39 :
+ snprintf(line, sizeof(line), "%.*s.", lflag ? 39 :
(Aflag && !numeric) ? 12 : 16, inet6name(in6));
cp = index(line, '\0');
if (!numeric && port)
GETSERVBYPORT6(port, proto, sp);
if (sp || port == 0)
- sprintf(cp, "%.8s", sp ? sp->s_name : "*");
+ snprintf(cp, sizeof(line) - (cp - line), "%.8s", sp ? sp->s_name : "*");
else
- sprintf(cp, "%d", ntohs((u_short)port));
+ snprintf(cp, sizeof(line) - (cp - line), "%d", ntohs((u_short)port));
width = lflag ? 45 : Aflag ? 18 : 22;
printf("%-*.*s ", width, width, line);
}
struct hostent *hp;
static char domain[MAXHOSTNAMELEN];
static int first = 1;
+ char hbuf[NI_MAXHOST];
+ struct sockaddr_in6 sin6;
+ const int niflag = NI_NUMERICHOST;
if (first && !nflag) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = index(domain, '.')))
- (void) strcpy(domain, cp + 1);
+ (void) memmove(domain, cp + 1, strlen(cp + 1) + 1);
else
domain[0] = 0;
}
}
}
if (IN6_IS_ADDR_UNSPECIFIED(in6p))
- strcpy(line, "*");
+ strlcpy(line, "*", sizeof(line));
else if (cp)
- strcpy(line, cp);
- else
- sprintf(line, "%s",
- inet_ntop(AF_INET6, (void *)in6p, ntop_buf,
- sizeof(ntop_buf)));
+ strlcpy(line, cp, sizeof(line));
+ else {
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr = *in6p;
+
+ if (IN6_IS_ADDR_LINKLOCAL(in6p) ||
+ IN6_IS_ADDR_MC_NODELOCAL(in6p) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(in6p)) {
+ sin6.sin6_scope_id =
+ ntohs(*(u_int16_t *)&in6p->s6_addr[2]);
+ sin6.sin6_addr.s6_addr[2] = 0;
+ sin6.sin6_addr.s6_addr[3] = 0;
+ }
+
+ if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
+ hbuf, sizeof(hbuf), NULL, 0, niflag) != 0)
+ strlcpy(hbuf, "?", sizeof(hbuf));
+ strlcpy(line, hbuf, sizeof(line));
+ }
return (line);
}
#endif /*INET6*/