xref: /f-stack/tools/netstat/inet6.c (revision d4a07e70)
11eaf0ac3Slogwang /*	BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp	*/
21eaf0ac3Slogwang /*-
322ce4affSfengbojiang  * SPDX-License-Identifier: BSD-3-Clause
422ce4affSfengbojiang  *
51eaf0ac3Slogwang  * Copyright (c) 1983, 1988, 1993
61eaf0ac3Slogwang  *	The Regents of the University of California.  All rights reserved.
71eaf0ac3Slogwang  *
81eaf0ac3Slogwang  * Redistribution and use in source and binary forms, with or without
91eaf0ac3Slogwang  * modification, are permitted provided that the following conditions
101eaf0ac3Slogwang  * are met:
111eaf0ac3Slogwang  * 1. Redistributions of source code must retain the above copyright
121eaf0ac3Slogwang  *    notice, this list of conditions and the following disclaimer.
131eaf0ac3Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
141eaf0ac3Slogwang  *    notice, this list of conditions and the following disclaimer in the
151eaf0ac3Slogwang  *    documentation and/or other materials provided with the distribution.
1622ce4affSfengbojiang  * 3. Neither the name of the University nor the names of its contributors
171eaf0ac3Slogwang  *    may be used to endorse or promote products derived from this software
181eaf0ac3Slogwang  *    without specific prior written permission.
191eaf0ac3Slogwang  *
201eaf0ac3Slogwang  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
211eaf0ac3Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221eaf0ac3Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231eaf0ac3Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
241eaf0ac3Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
251eaf0ac3Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
261eaf0ac3Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
271eaf0ac3Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
281eaf0ac3Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
291eaf0ac3Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
301eaf0ac3Slogwang  * SUCH DAMAGE.
311eaf0ac3Slogwang  */
321eaf0ac3Slogwang 
331eaf0ac3Slogwang #if 0
341eaf0ac3Slogwang #ifndef lint
351eaf0ac3Slogwang static char sccsid[] = "@(#)inet6.c	8.4 (Berkeley) 4/20/94";
361eaf0ac3Slogwang #endif /* not lint */
371eaf0ac3Slogwang #endif
381eaf0ac3Slogwang 
391eaf0ac3Slogwang #include <sys/cdefs.h>
401eaf0ac3Slogwang __FBSDID("$FreeBSD$");
411eaf0ac3Slogwang 
421eaf0ac3Slogwang #ifdef INET6
431eaf0ac3Slogwang #include <sys/param.h>
441eaf0ac3Slogwang #include <sys/socket.h>
451eaf0ac3Slogwang #include <sys/socketvar.h>
461eaf0ac3Slogwang #include <sys/ioctl.h>
471eaf0ac3Slogwang #include <sys/mbuf.h>
481eaf0ac3Slogwang #include <sys/protosw.h>
491eaf0ac3Slogwang 
501eaf0ac3Slogwang #include <net/route.h>
511eaf0ac3Slogwang #include <net/if.h>
521eaf0ac3Slogwang #include <netinet/in.h>
531eaf0ac3Slogwang #include <netinet/ip6.h>
541eaf0ac3Slogwang #include <netinet/icmp6.h>
551eaf0ac3Slogwang #include <netinet/in_systm.h>
561eaf0ac3Slogwang #include <netinet6/in6_pcb.h>
571eaf0ac3Slogwang #include <netinet6/in6_var.h>
581eaf0ac3Slogwang #include <netinet6/ip6_var.h>
591eaf0ac3Slogwang #include <netinet6/pim6_var.h>
601eaf0ac3Slogwang #include <netinet6/raw_ip6.h>
611eaf0ac3Slogwang 
621eaf0ac3Slogwang #include <arpa/inet.h>
631eaf0ac3Slogwang #include <netdb.h>
641eaf0ac3Slogwang 
651eaf0ac3Slogwang #include <err.h>
661eaf0ac3Slogwang #include <stdint.h>
671eaf0ac3Slogwang #include <stdio.h>
681eaf0ac3Slogwang #include <stdbool.h>
691eaf0ac3Slogwang #include <errno.h>
701eaf0ac3Slogwang #include <string.h>
711eaf0ac3Slogwang #include <unistd.h>
721eaf0ac3Slogwang #include <libxo/xo.h>
731eaf0ac3Slogwang #include "netstat.h"
741eaf0ac3Slogwang 
751eaf0ac3Slogwang static char ntop_buf[INET6_ADDRSTRLEN];
761eaf0ac3Slogwang 
771eaf0ac3Slogwang static	const char *ip6nh[] = {
781eaf0ac3Slogwang 	"hop by hop",
791eaf0ac3Slogwang 	"ICMP",
801eaf0ac3Slogwang 	"IGMP",
811eaf0ac3Slogwang 	"#3",
821eaf0ac3Slogwang 	"IP",
831eaf0ac3Slogwang 	"#5",
841eaf0ac3Slogwang 	"TCP",
851eaf0ac3Slogwang 	"#7",
861eaf0ac3Slogwang 	"#8",
871eaf0ac3Slogwang 	"#9",
881eaf0ac3Slogwang 	"#10",
891eaf0ac3Slogwang 	"#11",
901eaf0ac3Slogwang 	"#12",
911eaf0ac3Slogwang 	"#13",
921eaf0ac3Slogwang 	"#14",
931eaf0ac3Slogwang 	"#15",
941eaf0ac3Slogwang 	"#16",
951eaf0ac3Slogwang 	"UDP",
961eaf0ac3Slogwang 	"#18",
971eaf0ac3Slogwang 	"#19",
981eaf0ac3Slogwang 	"#20",
991eaf0ac3Slogwang 	"#21",
1001eaf0ac3Slogwang 	"IDP",
1011eaf0ac3Slogwang 	"#23",
1021eaf0ac3Slogwang 	"#24",
1031eaf0ac3Slogwang 	"#25",
1041eaf0ac3Slogwang 	"#26",
1051eaf0ac3Slogwang 	"#27",
1061eaf0ac3Slogwang 	"#28",
1071eaf0ac3Slogwang 	"TP",
1081eaf0ac3Slogwang 	"#30",
1091eaf0ac3Slogwang 	"#31",
1101eaf0ac3Slogwang 	"#32",
1111eaf0ac3Slogwang 	"#33",
1121eaf0ac3Slogwang 	"#34",
1131eaf0ac3Slogwang 	"#35",
1141eaf0ac3Slogwang 	"#36",
1151eaf0ac3Slogwang 	"#37",
1161eaf0ac3Slogwang 	"#38",
1171eaf0ac3Slogwang 	"#39",
1181eaf0ac3Slogwang 	"#40",
1191eaf0ac3Slogwang 	"IP6",
1201eaf0ac3Slogwang 	"#42",
1211eaf0ac3Slogwang 	"routing",
1221eaf0ac3Slogwang 	"fragment",
1231eaf0ac3Slogwang 	"#45",
1241eaf0ac3Slogwang 	"#46",
1251eaf0ac3Slogwang 	"#47",
1261eaf0ac3Slogwang 	"#48",
1271eaf0ac3Slogwang 	"#49",
1281eaf0ac3Slogwang 	"ESP",
1291eaf0ac3Slogwang 	"AH",
1301eaf0ac3Slogwang 	"#52",
1311eaf0ac3Slogwang 	"#53",
1321eaf0ac3Slogwang 	"#54",
1331eaf0ac3Slogwang 	"#55",
1341eaf0ac3Slogwang 	"#56",
1351eaf0ac3Slogwang 	"#57",
1361eaf0ac3Slogwang 	"ICMP6",
1371eaf0ac3Slogwang 	"no next header",
1381eaf0ac3Slogwang 	"destination option",
1391eaf0ac3Slogwang 	"#61",
1401eaf0ac3Slogwang 	"mobility",
1411eaf0ac3Slogwang 	"#63",
1421eaf0ac3Slogwang 	"#64",
1431eaf0ac3Slogwang 	"#65",
1441eaf0ac3Slogwang 	"#66",
1451eaf0ac3Slogwang 	"#67",
1461eaf0ac3Slogwang 	"#68",
1471eaf0ac3Slogwang 	"#69",
1481eaf0ac3Slogwang 	"#70",
1491eaf0ac3Slogwang 	"#71",
1501eaf0ac3Slogwang 	"#72",
1511eaf0ac3Slogwang 	"#73",
1521eaf0ac3Slogwang 	"#74",
1531eaf0ac3Slogwang 	"#75",
1541eaf0ac3Slogwang 	"#76",
1551eaf0ac3Slogwang 	"#77",
1561eaf0ac3Slogwang 	"#78",
1571eaf0ac3Slogwang 	"#79",
1581eaf0ac3Slogwang 	"ISOIP",
1591eaf0ac3Slogwang 	"#81",
1601eaf0ac3Slogwang 	"#82",
1611eaf0ac3Slogwang 	"#83",
1621eaf0ac3Slogwang 	"#84",
1631eaf0ac3Slogwang 	"#85",
1641eaf0ac3Slogwang 	"#86",
1651eaf0ac3Slogwang 	"#87",
1661eaf0ac3Slogwang 	"#88",
1671eaf0ac3Slogwang 	"OSPF",
1681eaf0ac3Slogwang 	"#80",
1691eaf0ac3Slogwang 	"#91",
1701eaf0ac3Slogwang 	"#92",
1711eaf0ac3Slogwang 	"#93",
1721eaf0ac3Slogwang 	"#94",
1731eaf0ac3Slogwang 	"#95",
1741eaf0ac3Slogwang 	"#96",
1751eaf0ac3Slogwang 	"Ethernet",
1761eaf0ac3Slogwang 	"#98",
1771eaf0ac3Slogwang 	"#99",
1781eaf0ac3Slogwang 	"#100",
1791eaf0ac3Slogwang 	"#101",
1801eaf0ac3Slogwang 	"#102",
1811eaf0ac3Slogwang 	"PIM",
1821eaf0ac3Slogwang 	"#104",
1831eaf0ac3Slogwang 	"#105",
1841eaf0ac3Slogwang 	"#106",
1851eaf0ac3Slogwang 	"#107",
1861eaf0ac3Slogwang 	"#108",
1871eaf0ac3Slogwang 	"#109",
1881eaf0ac3Slogwang 	"#110",
1891eaf0ac3Slogwang 	"#111",
1901eaf0ac3Slogwang 	"#112",
1911eaf0ac3Slogwang 	"#113",
1921eaf0ac3Slogwang 	"#114",
1931eaf0ac3Slogwang 	"#115",
1941eaf0ac3Slogwang 	"#116",
1951eaf0ac3Slogwang 	"#117",
1961eaf0ac3Slogwang 	"#118",
1971eaf0ac3Slogwang 	"#119",
1981eaf0ac3Slogwang 	"#120",
1991eaf0ac3Slogwang 	"#121",
2001eaf0ac3Slogwang 	"#122",
2011eaf0ac3Slogwang 	"#123",
2021eaf0ac3Slogwang 	"#124",
2031eaf0ac3Slogwang 	"#125",
2041eaf0ac3Slogwang 	"#126",
2051eaf0ac3Slogwang 	"#127",
2061eaf0ac3Slogwang 	"#128",
2071eaf0ac3Slogwang 	"#129",
2081eaf0ac3Slogwang 	"#130",
2091eaf0ac3Slogwang 	"#131",
2101eaf0ac3Slogwang 	"SCTP",
2111eaf0ac3Slogwang 	"#133",
2121eaf0ac3Slogwang 	"#134",
2131eaf0ac3Slogwang 	"#135",
2141eaf0ac3Slogwang 	"UDPLite",
2151eaf0ac3Slogwang 	"#137",
2161eaf0ac3Slogwang 	"#138",
2171eaf0ac3Slogwang 	"#139",
2181eaf0ac3Slogwang 	"#140",
2191eaf0ac3Slogwang 	"#141",
2201eaf0ac3Slogwang 	"#142",
2211eaf0ac3Slogwang 	"#143",
2221eaf0ac3Slogwang 	"#144",
2231eaf0ac3Slogwang 	"#145",
2241eaf0ac3Slogwang 	"#146",
2251eaf0ac3Slogwang 	"#147",
2261eaf0ac3Slogwang 	"#148",
2271eaf0ac3Slogwang 	"#149",
2281eaf0ac3Slogwang 	"#150",
2291eaf0ac3Slogwang 	"#151",
2301eaf0ac3Slogwang 	"#152",
2311eaf0ac3Slogwang 	"#153",
2321eaf0ac3Slogwang 	"#154",
2331eaf0ac3Slogwang 	"#155",
2341eaf0ac3Slogwang 	"#156",
2351eaf0ac3Slogwang 	"#157",
2361eaf0ac3Slogwang 	"#158",
2371eaf0ac3Slogwang 	"#159",
2381eaf0ac3Slogwang 	"#160",
2391eaf0ac3Slogwang 	"#161",
2401eaf0ac3Slogwang 	"#162",
2411eaf0ac3Slogwang 	"#163",
2421eaf0ac3Slogwang 	"#164",
2431eaf0ac3Slogwang 	"#165",
2441eaf0ac3Slogwang 	"#166",
2451eaf0ac3Slogwang 	"#167",
2461eaf0ac3Slogwang 	"#168",
2471eaf0ac3Slogwang 	"#169",
2481eaf0ac3Slogwang 	"#170",
2491eaf0ac3Slogwang 	"#171",
2501eaf0ac3Slogwang 	"#172",
2511eaf0ac3Slogwang 	"#173",
2521eaf0ac3Slogwang 	"#174",
2531eaf0ac3Slogwang 	"#175",
2541eaf0ac3Slogwang 	"#176",
2551eaf0ac3Slogwang 	"#177",
2561eaf0ac3Slogwang 	"#178",
2571eaf0ac3Slogwang 	"#179",
2581eaf0ac3Slogwang 	"#180",
2591eaf0ac3Slogwang 	"#181",
2601eaf0ac3Slogwang 	"#182",
2611eaf0ac3Slogwang 	"#183",
2621eaf0ac3Slogwang 	"#184",
2631eaf0ac3Slogwang 	"#185",
2641eaf0ac3Slogwang 	"#186",
2651eaf0ac3Slogwang 	"#187",
2661eaf0ac3Slogwang 	"#188",
2671eaf0ac3Slogwang 	"#189",
2681eaf0ac3Slogwang 	"#180",
2691eaf0ac3Slogwang 	"#191",
2701eaf0ac3Slogwang 	"#192",
2711eaf0ac3Slogwang 	"#193",
2721eaf0ac3Slogwang 	"#194",
2731eaf0ac3Slogwang 	"#195",
2741eaf0ac3Slogwang 	"#196",
2751eaf0ac3Slogwang 	"#197",
2761eaf0ac3Slogwang 	"#198",
2771eaf0ac3Slogwang 	"#199",
2781eaf0ac3Slogwang 	"#200",
2791eaf0ac3Slogwang 	"#201",
2801eaf0ac3Slogwang 	"#202",
2811eaf0ac3Slogwang 	"#203",
2821eaf0ac3Slogwang 	"#204",
2831eaf0ac3Slogwang 	"#205",
2841eaf0ac3Slogwang 	"#206",
2851eaf0ac3Slogwang 	"#207",
2861eaf0ac3Slogwang 	"#208",
2871eaf0ac3Slogwang 	"#209",
2881eaf0ac3Slogwang 	"#210",
2891eaf0ac3Slogwang 	"#211",
2901eaf0ac3Slogwang 	"#212",
2911eaf0ac3Slogwang 	"#213",
2921eaf0ac3Slogwang 	"#214",
2931eaf0ac3Slogwang 	"#215",
2941eaf0ac3Slogwang 	"#216",
2951eaf0ac3Slogwang 	"#217",
2961eaf0ac3Slogwang 	"#218",
2971eaf0ac3Slogwang 	"#219",
2981eaf0ac3Slogwang 	"#220",
2991eaf0ac3Slogwang 	"#221",
3001eaf0ac3Slogwang 	"#222",
3011eaf0ac3Slogwang 	"#223",
3021eaf0ac3Slogwang 	"#224",
3031eaf0ac3Slogwang 	"#225",
3041eaf0ac3Slogwang 	"#226",
3051eaf0ac3Slogwang 	"#227",
3061eaf0ac3Slogwang 	"#228",
3071eaf0ac3Slogwang 	"#229",
3081eaf0ac3Slogwang 	"#230",
3091eaf0ac3Slogwang 	"#231",
3101eaf0ac3Slogwang 	"#232",
3111eaf0ac3Slogwang 	"#233",
3121eaf0ac3Slogwang 	"#234",
3131eaf0ac3Slogwang 	"#235",
3141eaf0ac3Slogwang 	"#236",
3151eaf0ac3Slogwang 	"#237",
3161eaf0ac3Slogwang 	"#238",
3171eaf0ac3Slogwang 	"#239",
3181eaf0ac3Slogwang 	"#240",
3191eaf0ac3Slogwang 	"#241",
3201eaf0ac3Slogwang 	"#242",
3211eaf0ac3Slogwang 	"#243",
3221eaf0ac3Slogwang 	"#244",
3231eaf0ac3Slogwang 	"#245",
3241eaf0ac3Slogwang 	"#246",
3251eaf0ac3Slogwang 	"#247",
3261eaf0ac3Slogwang 	"#248",
3271eaf0ac3Slogwang 	"#249",
3281eaf0ac3Slogwang 	"#250",
3291eaf0ac3Slogwang 	"#251",
3301eaf0ac3Slogwang 	"#252",
3311eaf0ac3Slogwang 	"#253",
3321eaf0ac3Slogwang 	"#254",
3331eaf0ac3Slogwang 	"#255",
3341eaf0ac3Slogwang };
3351eaf0ac3Slogwang 
3361eaf0ac3Slogwang static const char *srcrule_str[] = {
3371eaf0ac3Slogwang 	"first candidate",
3381eaf0ac3Slogwang 	"same address",
3391eaf0ac3Slogwang 	"appropriate scope",
3401eaf0ac3Slogwang 	"deprecated address",
3411eaf0ac3Slogwang 	"home address",
3421eaf0ac3Slogwang 	"outgoing interface",
3431eaf0ac3Slogwang 	"matching label",
3441eaf0ac3Slogwang 	"public/temporary address",
3451eaf0ac3Slogwang 	"alive interface",
3461eaf0ac3Slogwang 	"better virtual status",
3471eaf0ac3Slogwang 	"preferred source",
3481eaf0ac3Slogwang 	"rule #11",
3491eaf0ac3Slogwang 	"rule #12",
3501eaf0ac3Slogwang 	"rule #13",
3511eaf0ac3Slogwang 	"longest match",
3521eaf0ac3Slogwang 	"rule #15",
3531eaf0ac3Slogwang };
3541eaf0ac3Slogwang 
3551eaf0ac3Slogwang /*
3561eaf0ac3Slogwang  * Dump IP6 statistics structure.
3571eaf0ac3Slogwang  */
3581eaf0ac3Slogwang void
ip6_stats(u_long off,const char * name,int af1 __unused,int proto __unused)3591eaf0ac3Slogwang ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
3601eaf0ac3Slogwang {
3611eaf0ac3Slogwang 	struct ip6stat ip6stat;
3621eaf0ac3Slogwang 	int first, i;
3631eaf0ac3Slogwang 
3641eaf0ac3Slogwang 	if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat,
3651eaf0ac3Slogwang 	    sizeof(ip6stat), kread_counters) != 0)
3661eaf0ac3Slogwang 		return;
3671eaf0ac3Slogwang 
3681eaf0ac3Slogwang 	xo_open_container(name);
3691eaf0ac3Slogwang 	xo_emit("{T:/%s}:\n", name);
3701eaf0ac3Slogwang 
3711eaf0ac3Slogwang #define	p(f, m) if (ip6stat.f || sflag <= 1) \
3721eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
3731eaf0ac3Slogwang #define	p1a(f, m) if (ip6stat.f || sflag <= 1) \
3741eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)ip6stat.f)
3751eaf0ac3Slogwang 
3761eaf0ac3Slogwang 	p(ip6s_total, "\t{:received-packets/%ju} "
3771eaf0ac3Slogwang 	    "{N:/total packet%s received}\n");
3781eaf0ac3Slogwang 	p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} "
3791eaf0ac3Slogwang 	    "{N:/with size smaller than minimum}\n");
3801eaf0ac3Slogwang 	p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} "
3811eaf0ac3Slogwang 	    "{N:/with data size < data length}\n");
3821eaf0ac3Slogwang 	p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} "
3831eaf0ac3Slogwang 	    "{N:/with bad options}\n");
3841eaf0ac3Slogwang 	p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} "
3851eaf0ac3Slogwang 	    "{N:/with incorrect version number}\n");
3861eaf0ac3Slogwang 	p(ip6s_fragments, "\t{:received-fragments/%ju} "
3871eaf0ac3Slogwang 	    "{N:/fragment%s received}\n");
3881eaf0ac3Slogwang 	p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} "
3891eaf0ac3Slogwang 	    "{N:/fragment%s dropped (dup or out of space)}\n");
3901eaf0ac3Slogwang 	p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} "
3911eaf0ac3Slogwang 	    "{N:/fragment%s dropped after timeout}\n");
3921eaf0ac3Slogwang 	p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
3931eaf0ac3Slogwang 	    "{N:/fragment%s that exceeded limit}\n");
39422ce4affSfengbojiang 	p(ip6s_atomicfrags, "\t{:atomic-fragments/%ju} "
39522ce4affSfengbojiang 	    "{N:/atomic fragment%s}\n");
3961eaf0ac3Slogwang 	p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
3971eaf0ac3Slogwang 	    "{N:/packet%s reassembled ok}\n");
3981eaf0ac3Slogwang 	p(ip6s_delivered, "\t{:received-local-packets/%ju} "
3991eaf0ac3Slogwang 	    "{N:/packet%s for this host}\n");
4001eaf0ac3Slogwang 	p(ip6s_forward, "\t{:forwarded-packets/%ju} "
4011eaf0ac3Slogwang 	    "{N:/packet%s forwarded}\n");
4021eaf0ac3Slogwang 	p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} "
4031eaf0ac3Slogwang 	    "{N:/packet%s not forwardable}\n");
4041eaf0ac3Slogwang 	p(ip6s_redirectsent, "\t{:sent-redirects/%ju} "
4051eaf0ac3Slogwang 	    "{N:/redirect%s sent}\n");
4061eaf0ac3Slogwang 	p(ip6s_localout, "\t{:sent-packets/%ju} "
4071eaf0ac3Slogwang 	    "{N:/packet%s sent from this host}\n");
4081eaf0ac3Slogwang 	p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} "
4091eaf0ac3Slogwang 	    "{N:/packet%s sent with fabricated ip header}\n");
4101eaf0ac3Slogwang 	p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} "
4111eaf0ac3Slogwang 	    "{N:/output packet%s dropped due to no bufs, etc.}\n");
4121eaf0ac3Slogwang 	p(ip6s_noroute, "\t{:discard-no-route/%ju} "
4131eaf0ac3Slogwang 	    "{N:/output packet%s discarded due to no route}\n");
4141eaf0ac3Slogwang 	p(ip6s_fragmented, "\t{:sent-fragments/%ju} "
4151eaf0ac3Slogwang 	    "{N:/output datagram%s fragmented}\n");
4161eaf0ac3Slogwang 	p(ip6s_ofragments, "\t{:fragments-created/%ju} "
4171eaf0ac3Slogwang 	    "{N:/fragment%s created}\n");
4181eaf0ac3Slogwang 	p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} "
4191eaf0ac3Slogwang 	    "{N:/datagram%s that can't be fragmented}\n");
4201eaf0ac3Slogwang 	p(ip6s_badscope, "\t{:discard-scope-violations/%ju} "
4211eaf0ac3Slogwang 	    "{N:/packet%s that violated scope rules}\n");
4221eaf0ac3Slogwang 	p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} "
4231eaf0ac3Slogwang 	    "{N:/multicast packet%s which we don't join}\n");
4241eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
4251eaf0ac3Slogwang 		if (ip6stat.ip6s_nxthist[i] != 0) {
4261eaf0ac3Slogwang 			if (first) {
4271eaf0ac3Slogwang 				xo_emit("\t{T:Input histogram}:\n");
4281eaf0ac3Slogwang 				xo_open_list("input-histogram");
4291eaf0ac3Slogwang 				first = 0;
4301eaf0ac3Slogwang 			}
4311eaf0ac3Slogwang 			xo_open_instance("input-histogram");
4321eaf0ac3Slogwang 			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i],
4331eaf0ac3Slogwang 			    (uintmax_t)ip6stat.ip6s_nxthist[i]);
4341eaf0ac3Slogwang 			xo_close_instance("input-histogram");
4351eaf0ac3Slogwang 		}
4361eaf0ac3Slogwang 	if (!first)
4371eaf0ac3Slogwang 		xo_close_list("input-histogram");
4381eaf0ac3Slogwang 
4391eaf0ac3Slogwang 	xo_open_container("mbuf-statistics");
4401eaf0ac3Slogwang 	xo_emit("\t{T:Mbuf statistics}:\n");
4411eaf0ac3Slogwang 	xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n",
4421eaf0ac3Slogwang 	    (uintmax_t)ip6stat.ip6s_m1);
4431eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
4441eaf0ac3Slogwang 		char ifbuf[IFNAMSIZ];
4451eaf0ac3Slogwang 		if (ip6stat.ip6s_m2m[i] != 0) {
4461eaf0ac3Slogwang 			if (first) {
4471eaf0ac3Slogwang 				xo_emit("\t\t{N:two or more mbuf}:\n");
4481eaf0ac3Slogwang 				xo_open_list("mbuf-data");
4491eaf0ac3Slogwang 				first = 0;
4501eaf0ac3Slogwang 			}
4511eaf0ac3Slogwang 			xo_open_instance("mbuf-data");
4521eaf0ac3Slogwang 			xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n",
4531eaf0ac3Slogwang 			    if_indextoname(i, ifbuf),
4541eaf0ac3Slogwang 			    (uintmax_t)ip6stat.ip6s_m2m[i]);
4551eaf0ac3Slogwang 			xo_close_instance("mbuf-data");
4561eaf0ac3Slogwang 		}
4571eaf0ac3Slogwang 	}
4581eaf0ac3Slogwang 	if (!first)
4591eaf0ac3Slogwang 		xo_close_list("mbuf-data");
4601eaf0ac3Slogwang 	xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n",
4611eaf0ac3Slogwang 	    (uintmax_t)ip6stat.ip6s_mext1);
4621eaf0ac3Slogwang 	xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} "
4631eaf0ac3Slogwang 	    "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m);
4641eaf0ac3Slogwang 	xo_close_container("mbuf-statistics");
4651eaf0ac3Slogwang 
4661eaf0ac3Slogwang 	p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} "
4671eaf0ac3Slogwang 	    "{N:/packet%s whose headers are not contiguous}\n");
4681eaf0ac3Slogwang 	p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} "
4691eaf0ac3Slogwang 	    "{N:/tunneling packet%s that can't find gif}\n");
4701eaf0ac3Slogwang 	p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} "
4711eaf0ac3Slogwang 	    "{N:/packet%s discarded because of too many headers}\n");
4721eaf0ac3Slogwang 
4731eaf0ac3Slogwang 	/* for debugging source address selection */
4741eaf0ac3Slogwang #define	PRINT_SCOPESTAT(s,i) do {\
4751eaf0ac3Slogwang 		switch(i) { /* XXX hardcoding in each case */\
4761eaf0ac3Slogwang 		case 1:\
4771eaf0ac3Slogwang 			p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \
4781eaf0ac3Slogwang 			  "{N:/interface-local%s}\n");	\
4791eaf0ac3Slogwang 			break;\
4801eaf0ac3Slogwang 		case 2:\
4811eaf0ac3Slogwang 			p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \
4821eaf0ac3Slogwang 			"{N:/link-local%s}\n"); \
4831eaf0ac3Slogwang 			break;\
4841eaf0ac3Slogwang 		case 5:\
4851eaf0ac3Slogwang 			p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \
4861eaf0ac3Slogwang 			  "{N:/site-local%s}\n");\
4871eaf0ac3Slogwang 			break;\
4881eaf0ac3Slogwang 		case 14:\
4891eaf0ac3Slogwang 			p(s,"\t\t{ke:name/globals}{:count/%ju} " \
4901eaf0ac3Slogwang 			  "{N:/global%s}\n");\
4911eaf0ac3Slogwang 			break;\
4921eaf0ac3Slogwang 		default:\
4931eaf0ac3Slogwang 			xo_emit("\t\t{qke:name/%#x}{:count/%ju} " \
4941eaf0ac3Slogwang 				"{N:/addresses scope=%#x}\n",\
4951eaf0ac3Slogwang 				i, (uintmax_t)ip6stat.s, i);	   \
4961eaf0ac3Slogwang 		}\
4971eaf0ac3Slogwang 	} while (0);
4981eaf0ac3Slogwang 
4991eaf0ac3Slogwang 	xo_open_container("source-address-selection");
5001eaf0ac3Slogwang 	p(ip6s_sources_none, "\t{:address-selection-failures/%ju} "
5011eaf0ac3Slogwang 	    "{N:/failure%s of source address selection}\n");
5021eaf0ac3Slogwang 
5031eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
5041eaf0ac3Slogwang 		if (ip6stat.ip6s_sources_sameif[i]) {
5051eaf0ac3Slogwang 			if (first) {
5061eaf0ac3Slogwang 				xo_open_list("outgoing-interface");
5071eaf0ac3Slogwang 				xo_emit("\tsource addresses on an outgoing "
5081eaf0ac3Slogwang 				    "I/F\n");
5091eaf0ac3Slogwang 				first = 0;
5101eaf0ac3Slogwang 			}
5111eaf0ac3Slogwang 			xo_open_instance("outgoing-interface");
5121eaf0ac3Slogwang 			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
5131eaf0ac3Slogwang 			xo_close_instance("outgoing-interface");
5141eaf0ac3Slogwang 		}
5151eaf0ac3Slogwang 	}
5161eaf0ac3Slogwang 	if (!first)
5171eaf0ac3Slogwang 		xo_close_list("outgoing-interface");
5181eaf0ac3Slogwang 
5191eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
5201eaf0ac3Slogwang 		if (ip6stat.ip6s_sources_otherif[i]) {
5211eaf0ac3Slogwang 			if (first) {
5221eaf0ac3Slogwang 				xo_open_list("non-outgoing-interface");
5231eaf0ac3Slogwang 				xo_emit("\tsource addresses on a non-outgoing "
5241eaf0ac3Slogwang 				    "I/F\n");
5251eaf0ac3Slogwang 				first = 0;
5261eaf0ac3Slogwang 			}
5271eaf0ac3Slogwang 			xo_open_instance("non-outgoing-interface");
5281eaf0ac3Slogwang 			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
5291eaf0ac3Slogwang 			xo_close_instance("non-outgoing-interface");
5301eaf0ac3Slogwang 		}
5311eaf0ac3Slogwang 	}
5321eaf0ac3Slogwang 	if (!first)
5331eaf0ac3Slogwang 		xo_close_list("non-outgoing-interface");
5341eaf0ac3Slogwang 
5351eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
5361eaf0ac3Slogwang 		if (ip6stat.ip6s_sources_samescope[i]) {
5371eaf0ac3Slogwang 			if (first) {
5381eaf0ac3Slogwang 				xo_open_list("same-source");
5391eaf0ac3Slogwang 				xo_emit("\tsource addresses of same scope\n");
5401eaf0ac3Slogwang 				first = 0;
5411eaf0ac3Slogwang 			}
5421eaf0ac3Slogwang 			xo_open_instance("same-source");
5431eaf0ac3Slogwang 			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
5441eaf0ac3Slogwang 			xo_close_instance("same-source");
5451eaf0ac3Slogwang 		}
5461eaf0ac3Slogwang 	}
5471eaf0ac3Slogwang 	if (!first)
5481eaf0ac3Slogwang 		xo_close_list("same-source");
5491eaf0ac3Slogwang 
5501eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
5511eaf0ac3Slogwang 		if (ip6stat.ip6s_sources_otherscope[i]) {
5521eaf0ac3Slogwang 			if (first) {
5531eaf0ac3Slogwang 				xo_open_list("different-scope");
5541eaf0ac3Slogwang 				xo_emit("\tsource addresses of a different "
5551eaf0ac3Slogwang 				    "scope\n");
5561eaf0ac3Slogwang 				first = 0;
5571eaf0ac3Slogwang 			}
5581eaf0ac3Slogwang 			xo_open_instance("different-scope");
5591eaf0ac3Slogwang 			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
5601eaf0ac3Slogwang 			xo_close_instance("different-scope");
5611eaf0ac3Slogwang 		}
5621eaf0ac3Slogwang 	}
5631eaf0ac3Slogwang 	if (!first)
5641eaf0ac3Slogwang 		xo_close_list("different-scope");
5651eaf0ac3Slogwang 
5661eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
5671eaf0ac3Slogwang 		if (ip6stat.ip6s_sources_deprecated[i]) {
5681eaf0ac3Slogwang 			if (first) {
5691eaf0ac3Slogwang 				xo_open_list("deprecated-source");
5701eaf0ac3Slogwang 				xo_emit("\tdeprecated source addresses\n");
5711eaf0ac3Slogwang 				first = 0;
5721eaf0ac3Slogwang 			}
5731eaf0ac3Slogwang 			xo_open_instance("deprecated-source");
5741eaf0ac3Slogwang 			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
5751eaf0ac3Slogwang 			xo_close_instance("deprecated-source");
5761eaf0ac3Slogwang 		}
5771eaf0ac3Slogwang 	}
5781eaf0ac3Slogwang 	if (!first)
5791eaf0ac3Slogwang 		xo_close_list("deprecated-source");
5801eaf0ac3Slogwang 
5811eaf0ac3Slogwang 	for (first = 1, i = 0; i < IP6S_RULESMAX; i++) {
5821eaf0ac3Slogwang 		if (ip6stat.ip6s_sources_rule[i]) {
5831eaf0ac3Slogwang 			if (first) {
5841eaf0ac3Slogwang 				xo_open_list("rules-applied");
5851eaf0ac3Slogwang 				xo_emit("\t{T:Source addresses selection "
5861eaf0ac3Slogwang 				    "rule applied}:\n");
5871eaf0ac3Slogwang 				first = 0;
5881eaf0ac3Slogwang 			}
5891eaf0ac3Slogwang 			xo_open_instance("rules-applied");
5901eaf0ac3Slogwang 			xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n",
5911eaf0ac3Slogwang 			    srcrule_str[i],
5921eaf0ac3Slogwang 			    (uintmax_t)ip6stat.ip6s_sources_rule[i],
5931eaf0ac3Slogwang 			    srcrule_str[i]);
5941eaf0ac3Slogwang 			xo_close_instance("rules-applied");
5951eaf0ac3Slogwang 		}
5961eaf0ac3Slogwang 	}
5971eaf0ac3Slogwang 	if (!first)
5981eaf0ac3Slogwang 		xo_close_list("rules-applied");
5991eaf0ac3Slogwang 
6001eaf0ac3Slogwang 	xo_close_container("source-address-selection");
6011eaf0ac3Slogwang 
6021eaf0ac3Slogwang #undef p
6031eaf0ac3Slogwang #undef p1a
6041eaf0ac3Slogwang 	xo_close_container(name);
6051eaf0ac3Slogwang }
6061eaf0ac3Slogwang 
6071eaf0ac3Slogwang /*
6081eaf0ac3Slogwang  * Dump IPv6 per-interface statistics based on RFC 2465.
6091eaf0ac3Slogwang  */
6101eaf0ac3Slogwang void
ip6_ifstats(char * ifname)6111eaf0ac3Slogwang ip6_ifstats(char *ifname)
6121eaf0ac3Slogwang {
6131eaf0ac3Slogwang 	struct in6_ifreq ifr;
6141eaf0ac3Slogwang 	int s;
6151eaf0ac3Slogwang 
6161eaf0ac3Slogwang #define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1)	\
6171eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f,		\
6181eaf0ac3Slogwang 	    plural(ifr.ifr_ifru.ifru_stat.f))
6191eaf0ac3Slogwang 
6201eaf0ac3Slogwang 	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
6211eaf0ac3Slogwang 		xo_warn("Warning: socket(AF_INET6)");
6221eaf0ac3Slogwang 		return;
6231eaf0ac3Slogwang 	}
6241eaf0ac3Slogwang 
62522ce4affSfengbojiang 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
626*d4a07e70Sfengbojiang #ifndef FSTACK
6271eaf0ac3Slogwang 	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
628*d4a07e70Sfengbojiang #else
629*d4a07e70Sfengbojiang 	if (ioctl_va(s, SIOCGIFSTAT_IN6, (char *)&ifr, 1, AF_INET6) < 0) {
630*d4a07e70Sfengbojiang #endif
6311eaf0ac3Slogwang 		if (errno != EPFNOSUPPORT)
6321eaf0ac3Slogwang 			xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)");
6331eaf0ac3Slogwang 		goto end;
6341eaf0ac3Slogwang 	}
6351eaf0ac3Slogwang 
6361eaf0ac3Slogwang 	xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name);
6371eaf0ac3Slogwang 
6381eaf0ac3Slogwang 	xo_open_instance("ip6-interface-statistics");
6391eaf0ac3Slogwang 	xo_emit("{ke:name/%s}", ifr.ifr_name);
6401eaf0ac3Slogwang 
6411eaf0ac3Slogwang 	p(ifs6_in_receive, "\t{:received-packets/%ju} "
6421eaf0ac3Slogwang 	    "{N:/total input datagram%s}\n");
6431eaf0ac3Slogwang 	p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} "
6441eaf0ac3Slogwang 	    "{N:/datagram%s with invalid header received}\n");
6451eaf0ac3Slogwang 	p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} "
6461eaf0ac3Slogwang 	    "{N:/datagram%s exceeded MTU received}\n");
6471eaf0ac3Slogwang 	p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} "
6481eaf0ac3Slogwang 	    "{N:/datagram%s with no route received}\n");
6491eaf0ac3Slogwang 	p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} "
6501eaf0ac3Slogwang 	    "{N:/datagram%s with invalid dst received}\n");
6511eaf0ac3Slogwang 	p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} "
6521eaf0ac3Slogwang 	    "{N:/datagram%s with unknown proto received}\n");
6531eaf0ac3Slogwang 	p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} "
6541eaf0ac3Slogwang 	    "{N:/truncated datagram%s received}\n");
6551eaf0ac3Slogwang 	p(ifs6_in_discard, "\t{:dropped-discarded/%ju} "
6561eaf0ac3Slogwang 	    "{N:/input datagram%s discarded}\n");
6571eaf0ac3Slogwang  	p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} "
6581eaf0ac3Slogwang 	    "{N:/datagram%s delivered to an upper layer protocol}\n");
6591eaf0ac3Slogwang 	p(ifs6_out_forward, "\t{:sent-forwarded/%ju} "
6601eaf0ac3Slogwang 	    "{N:/datagram%s forwarded to this interface}\n");
6611eaf0ac3Slogwang  	p(ifs6_out_request, "\t{:sent-packets/%ju} "
6621eaf0ac3Slogwang 	    "{N:/datagram%s sent from an upper layer protocol}\n");
6631eaf0ac3Slogwang 	p(ifs6_out_discard, "\t{:discard-packets/%ju} "
6641eaf0ac3Slogwang 	    "{N:/total discarded output datagram%s}\n");
6651eaf0ac3Slogwang 	p(ifs6_out_fragok, "\t{:discard-fragments/%ju} "
6661eaf0ac3Slogwang 	    "{N:/output datagram%s fragmented}\n");
6671eaf0ac3Slogwang 	p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} "
6681eaf0ac3Slogwang 	    "{N:/output datagram%s failed on fragment}\n");
6691eaf0ac3Slogwang 	p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} "
6701eaf0ac3Slogwang 	    "{N:/output datagram%s succeeded on fragment}\n");
6711eaf0ac3Slogwang 	p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} "
6721eaf0ac3Slogwang 	    "{N:/incoming datagram%s fragmented}\n");
6731eaf0ac3Slogwang 	p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} "
6741eaf0ac3Slogwang 	    "{N:/datagram%s reassembled}\n");
6751eaf0ac3Slogwang 	p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} "
6761eaf0ac3Slogwang 	    "{N:/datagram%s failed on reassembly}\n");
6771eaf0ac3Slogwang 	p(ifs6_in_mcast, "\t{:received-multicast/%ju} "
6781eaf0ac3Slogwang 	    "{N:/multicast datagram%s received}\n");
6791eaf0ac3Slogwang 	p(ifs6_out_mcast, "\t{:sent-multicast/%ju} "
6801eaf0ac3Slogwang 	    "{N:/multicast datagram%s sent}\n");
6811eaf0ac3Slogwang 
6821eaf0ac3Slogwang  end:
6831eaf0ac3Slogwang 	xo_close_instance("ip6-interface-statistics");
6841eaf0ac3Slogwang  	close(s);
6851eaf0ac3Slogwang 
6861eaf0ac3Slogwang #undef p
6871eaf0ac3Slogwang }
6881eaf0ac3Slogwang 
6891eaf0ac3Slogwang static	const char *icmp6names[] = {
6901eaf0ac3Slogwang 	"#0",
6911eaf0ac3Slogwang 	"unreach",
6921eaf0ac3Slogwang 	"packet too big",
6931eaf0ac3Slogwang 	"time exceed",
6941eaf0ac3Slogwang 	"parameter problem",
6951eaf0ac3Slogwang 	"#5",
6961eaf0ac3Slogwang 	"#6",
6971eaf0ac3Slogwang 	"#7",
6981eaf0ac3Slogwang 	"#8",
6991eaf0ac3Slogwang 	"#9",
7001eaf0ac3Slogwang 	"#10",
7011eaf0ac3Slogwang 	"#11",
7021eaf0ac3Slogwang 	"#12",
7031eaf0ac3Slogwang 	"#13",
7041eaf0ac3Slogwang 	"#14",
7051eaf0ac3Slogwang 	"#15",
7061eaf0ac3Slogwang 	"#16",
7071eaf0ac3Slogwang 	"#17",
7081eaf0ac3Slogwang 	"#18",
7091eaf0ac3Slogwang 	"#19",
7101eaf0ac3Slogwang 	"#20",
7111eaf0ac3Slogwang 	"#21",
7121eaf0ac3Slogwang 	"#22",
7131eaf0ac3Slogwang 	"#23",
7141eaf0ac3Slogwang 	"#24",
7151eaf0ac3Slogwang 	"#25",
7161eaf0ac3Slogwang 	"#26",
7171eaf0ac3Slogwang 	"#27",
7181eaf0ac3Slogwang 	"#28",
7191eaf0ac3Slogwang 	"#29",
7201eaf0ac3Slogwang 	"#30",
7211eaf0ac3Slogwang 	"#31",
7221eaf0ac3Slogwang 	"#32",
7231eaf0ac3Slogwang 	"#33",
7241eaf0ac3Slogwang 	"#34",
7251eaf0ac3Slogwang 	"#35",
7261eaf0ac3Slogwang 	"#36",
7271eaf0ac3Slogwang 	"#37",
7281eaf0ac3Slogwang 	"#38",
7291eaf0ac3Slogwang 	"#39",
7301eaf0ac3Slogwang 	"#40",
7311eaf0ac3Slogwang 	"#41",
7321eaf0ac3Slogwang 	"#42",
7331eaf0ac3Slogwang 	"#43",
7341eaf0ac3Slogwang 	"#44",
7351eaf0ac3Slogwang 	"#45",
7361eaf0ac3Slogwang 	"#46",
7371eaf0ac3Slogwang 	"#47",
7381eaf0ac3Slogwang 	"#48",
7391eaf0ac3Slogwang 	"#49",
7401eaf0ac3Slogwang 	"#50",
7411eaf0ac3Slogwang 	"#51",
7421eaf0ac3Slogwang 	"#52",
7431eaf0ac3Slogwang 	"#53",
7441eaf0ac3Slogwang 	"#54",
7451eaf0ac3Slogwang 	"#55",
7461eaf0ac3Slogwang 	"#56",
7471eaf0ac3Slogwang 	"#57",
7481eaf0ac3Slogwang 	"#58",
7491eaf0ac3Slogwang 	"#59",
7501eaf0ac3Slogwang 	"#60",
7511eaf0ac3Slogwang 	"#61",
7521eaf0ac3Slogwang 	"#62",
7531eaf0ac3Slogwang 	"#63",
7541eaf0ac3Slogwang 	"#64",
7551eaf0ac3Slogwang 	"#65",
7561eaf0ac3Slogwang 	"#66",
7571eaf0ac3Slogwang 	"#67",
7581eaf0ac3Slogwang 	"#68",
7591eaf0ac3Slogwang 	"#69",
7601eaf0ac3Slogwang 	"#70",
7611eaf0ac3Slogwang 	"#71",
7621eaf0ac3Slogwang 	"#72",
7631eaf0ac3Slogwang 	"#73",
7641eaf0ac3Slogwang 	"#74",
7651eaf0ac3Slogwang 	"#75",
7661eaf0ac3Slogwang 	"#76",
7671eaf0ac3Slogwang 	"#77",
7681eaf0ac3Slogwang 	"#78",
7691eaf0ac3Slogwang 	"#79",
7701eaf0ac3Slogwang 	"#80",
7711eaf0ac3Slogwang 	"#81",
7721eaf0ac3Slogwang 	"#82",
7731eaf0ac3Slogwang 	"#83",
7741eaf0ac3Slogwang 	"#84",
7751eaf0ac3Slogwang 	"#85",
7761eaf0ac3Slogwang 	"#86",
7771eaf0ac3Slogwang 	"#87",
7781eaf0ac3Slogwang 	"#88",
7791eaf0ac3Slogwang 	"#89",
7801eaf0ac3Slogwang 	"#80",
7811eaf0ac3Slogwang 	"#91",
7821eaf0ac3Slogwang 	"#92",
7831eaf0ac3Slogwang 	"#93",
7841eaf0ac3Slogwang 	"#94",
7851eaf0ac3Slogwang 	"#95",
7861eaf0ac3Slogwang 	"#96",
7871eaf0ac3Slogwang 	"#97",
7881eaf0ac3Slogwang 	"#98",
7891eaf0ac3Slogwang 	"#99",
7901eaf0ac3Slogwang 	"#100",
7911eaf0ac3Slogwang 	"#101",
7921eaf0ac3Slogwang 	"#102",
7931eaf0ac3Slogwang 	"#103",
7941eaf0ac3Slogwang 	"#104",
7951eaf0ac3Slogwang 	"#105",
7961eaf0ac3Slogwang 	"#106",
7971eaf0ac3Slogwang 	"#107",
7981eaf0ac3Slogwang 	"#108",
7991eaf0ac3Slogwang 	"#109",
8001eaf0ac3Slogwang 	"#110",
8011eaf0ac3Slogwang 	"#111",
8021eaf0ac3Slogwang 	"#112",
8031eaf0ac3Slogwang 	"#113",
8041eaf0ac3Slogwang 	"#114",
8051eaf0ac3Slogwang 	"#115",
8061eaf0ac3Slogwang 	"#116",
8071eaf0ac3Slogwang 	"#117",
8081eaf0ac3Slogwang 	"#118",
8091eaf0ac3Slogwang 	"#119",
8101eaf0ac3Slogwang 	"#120",
8111eaf0ac3Slogwang 	"#121",
8121eaf0ac3Slogwang 	"#122",
8131eaf0ac3Slogwang 	"#123",
8141eaf0ac3Slogwang 	"#124",
8151eaf0ac3Slogwang 	"#125",
8161eaf0ac3Slogwang 	"#126",
8171eaf0ac3Slogwang 	"#127",
8181eaf0ac3Slogwang 	"echo",
8191eaf0ac3Slogwang 	"echo reply",
8201eaf0ac3Slogwang 	"multicast listener query",
8211eaf0ac3Slogwang 	"MLDv1 listener report",
8221eaf0ac3Slogwang 	"MLDv1 listener done",
8231eaf0ac3Slogwang 	"router solicitation",
8241eaf0ac3Slogwang 	"router advertisement",
8251eaf0ac3Slogwang 	"neighbor solicitation",
8261eaf0ac3Slogwang 	"neighbor advertisement",
8271eaf0ac3Slogwang 	"redirect",
8281eaf0ac3Slogwang 	"router renumbering",
8291eaf0ac3Slogwang 	"node information request",
8301eaf0ac3Slogwang 	"node information reply",
8311eaf0ac3Slogwang 	"inverse neighbor solicitation",
8321eaf0ac3Slogwang 	"inverse neighbor advertisement",
8331eaf0ac3Slogwang 	"MLDv2 listener report",
8341eaf0ac3Slogwang 	"#144",
8351eaf0ac3Slogwang 	"#145",
8361eaf0ac3Slogwang 	"#146",
8371eaf0ac3Slogwang 	"#147",
8381eaf0ac3Slogwang 	"#148",
8391eaf0ac3Slogwang 	"#149",
8401eaf0ac3Slogwang 	"#150",
8411eaf0ac3Slogwang 	"#151",
8421eaf0ac3Slogwang 	"#152",
8431eaf0ac3Slogwang 	"#153",
8441eaf0ac3Slogwang 	"#154",
8451eaf0ac3Slogwang 	"#155",
8461eaf0ac3Slogwang 	"#156",
8471eaf0ac3Slogwang 	"#157",
8481eaf0ac3Slogwang 	"#158",
8491eaf0ac3Slogwang 	"#159",
8501eaf0ac3Slogwang 	"#160",
8511eaf0ac3Slogwang 	"#161",
8521eaf0ac3Slogwang 	"#162",
8531eaf0ac3Slogwang 	"#163",
8541eaf0ac3Slogwang 	"#164",
8551eaf0ac3Slogwang 	"#165",
8561eaf0ac3Slogwang 	"#166",
8571eaf0ac3Slogwang 	"#167",
8581eaf0ac3Slogwang 	"#168",
8591eaf0ac3Slogwang 	"#169",
8601eaf0ac3Slogwang 	"#170",
8611eaf0ac3Slogwang 	"#171",
8621eaf0ac3Slogwang 	"#172",
8631eaf0ac3Slogwang 	"#173",
8641eaf0ac3Slogwang 	"#174",
8651eaf0ac3Slogwang 	"#175",
8661eaf0ac3Slogwang 	"#176",
8671eaf0ac3Slogwang 	"#177",
8681eaf0ac3Slogwang 	"#178",
8691eaf0ac3Slogwang 	"#179",
8701eaf0ac3Slogwang 	"#180",
8711eaf0ac3Slogwang 	"#181",
8721eaf0ac3Slogwang 	"#182",
8731eaf0ac3Slogwang 	"#183",
8741eaf0ac3Slogwang 	"#184",
8751eaf0ac3Slogwang 	"#185",
8761eaf0ac3Slogwang 	"#186",
8771eaf0ac3Slogwang 	"#187",
8781eaf0ac3Slogwang 	"#188",
8791eaf0ac3Slogwang 	"#189",
8801eaf0ac3Slogwang 	"#180",
8811eaf0ac3Slogwang 	"#191",
8821eaf0ac3Slogwang 	"#192",
8831eaf0ac3Slogwang 	"#193",
8841eaf0ac3Slogwang 	"#194",
8851eaf0ac3Slogwang 	"#195",
8861eaf0ac3Slogwang 	"#196",
8871eaf0ac3Slogwang 	"#197",
8881eaf0ac3Slogwang 	"#198",
8891eaf0ac3Slogwang 	"#199",
8901eaf0ac3Slogwang 	"#200",
8911eaf0ac3Slogwang 	"#201",
8921eaf0ac3Slogwang 	"#202",
8931eaf0ac3Slogwang 	"#203",
8941eaf0ac3Slogwang 	"#204",
8951eaf0ac3Slogwang 	"#205",
8961eaf0ac3Slogwang 	"#206",
8971eaf0ac3Slogwang 	"#207",
8981eaf0ac3Slogwang 	"#208",
8991eaf0ac3Slogwang 	"#209",
9001eaf0ac3Slogwang 	"#210",
9011eaf0ac3Slogwang 	"#211",
9021eaf0ac3Slogwang 	"#212",
9031eaf0ac3Slogwang 	"#213",
9041eaf0ac3Slogwang 	"#214",
9051eaf0ac3Slogwang 	"#215",
9061eaf0ac3Slogwang 	"#216",
9071eaf0ac3Slogwang 	"#217",
9081eaf0ac3Slogwang 	"#218",
9091eaf0ac3Slogwang 	"#219",
9101eaf0ac3Slogwang 	"#220",
9111eaf0ac3Slogwang 	"#221",
9121eaf0ac3Slogwang 	"#222",
9131eaf0ac3Slogwang 	"#223",
9141eaf0ac3Slogwang 	"#224",
9151eaf0ac3Slogwang 	"#225",
9161eaf0ac3Slogwang 	"#226",
9171eaf0ac3Slogwang 	"#227",
9181eaf0ac3Slogwang 	"#228",
9191eaf0ac3Slogwang 	"#229",
9201eaf0ac3Slogwang 	"#230",
9211eaf0ac3Slogwang 	"#231",
9221eaf0ac3Slogwang 	"#232",
9231eaf0ac3Slogwang 	"#233",
9241eaf0ac3Slogwang 	"#234",
9251eaf0ac3Slogwang 	"#235",
9261eaf0ac3Slogwang 	"#236",
9271eaf0ac3Slogwang 	"#237",
9281eaf0ac3Slogwang 	"#238",
9291eaf0ac3Slogwang 	"#239",
9301eaf0ac3Slogwang 	"#240",
9311eaf0ac3Slogwang 	"#241",
9321eaf0ac3Slogwang 	"#242",
9331eaf0ac3Slogwang 	"#243",
9341eaf0ac3Slogwang 	"#244",
9351eaf0ac3Slogwang 	"#245",
9361eaf0ac3Slogwang 	"#246",
9371eaf0ac3Slogwang 	"#247",
9381eaf0ac3Slogwang 	"#248",
9391eaf0ac3Slogwang 	"#249",
9401eaf0ac3Slogwang 	"#250",
9411eaf0ac3Slogwang 	"#251",
9421eaf0ac3Slogwang 	"#252",
9431eaf0ac3Slogwang 	"#253",
9441eaf0ac3Slogwang 	"#254",
9451eaf0ac3Slogwang 	"#255",
9461eaf0ac3Slogwang };
9471eaf0ac3Slogwang 
9481eaf0ac3Slogwang /*
9491eaf0ac3Slogwang  * Dump ICMP6 statistics.
9501eaf0ac3Slogwang  */
9511eaf0ac3Slogwang void
9521eaf0ac3Slogwang icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
9531eaf0ac3Slogwang {
9541eaf0ac3Slogwang 	struct icmp6stat icmp6stat;
9551eaf0ac3Slogwang 	int i, first;
9561eaf0ac3Slogwang 
9571eaf0ac3Slogwang 	if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat,
9581eaf0ac3Slogwang 	    sizeof(icmp6stat), kread_counters) != 0)
9591eaf0ac3Slogwang 		return;
9601eaf0ac3Slogwang 
9611eaf0ac3Slogwang 	xo_emit("{T:/%s}:\n", name);
9621eaf0ac3Slogwang 	xo_open_container(name);
9631eaf0ac3Slogwang 
9641eaf0ac3Slogwang #define	p(f, m) if (icmp6stat.f || sflag <= 1) \
9651eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
9661eaf0ac3Slogwang #define	p_5(f, m) if (icmp6stat.f || sflag <= 1) \
9671eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)icmp6stat.f)
9681eaf0ac3Slogwang 
9691eaf0ac3Slogwang 	p(icp6s_error, "\t{:icmp6-calls/%ju} "
9701eaf0ac3Slogwang 	    "{N:/call%s to icmp6_error}\n");
9711eaf0ac3Slogwang 	p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} "
9721eaf0ac3Slogwang 	    "{N:/error%s not generated in response to an icmp6 message}\n");
9731eaf0ac3Slogwang 	p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} "
9741eaf0ac3Slogwang 	    "{N:/error%s not generated because of rate limitation}\n");
9751eaf0ac3Slogwang #define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
9761eaf0ac3Slogwang 	for (first = 1, i = 0; i < NELEM; i++)
9771eaf0ac3Slogwang 		if (icmp6stat.icp6s_outhist[i] != 0) {
9781eaf0ac3Slogwang 			if (first) {
9791eaf0ac3Slogwang 				xo_open_list("output-histogram");
9801eaf0ac3Slogwang 				xo_emit("\t{T:Output histogram}:\n");
9811eaf0ac3Slogwang 				first = 0;
9821eaf0ac3Slogwang 			}
9831eaf0ac3Slogwang 			xo_open_instance("output-histogram");
9841eaf0ac3Slogwang 			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
9851eaf0ac3Slogwang 			    icmp6names[i],
9861eaf0ac3Slogwang 			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
9871eaf0ac3Slogwang 			xo_close_instance("output-histogram");
9881eaf0ac3Slogwang 		}
9891eaf0ac3Slogwang 	if (!first)
9901eaf0ac3Slogwang 		xo_close_list("output-histogram");
9911eaf0ac3Slogwang #undef NELEM
9921eaf0ac3Slogwang 
9931eaf0ac3Slogwang 	p(icp6s_badcode, "\t{:dropped-bad-code/%ju} "
9941eaf0ac3Slogwang 	    "{N:/message%s with bad code fields}\n");
9951eaf0ac3Slogwang 	p(icp6s_tooshort, "\t{:dropped-too-short/%ju} "
9961eaf0ac3Slogwang 	    "{N:/message%s < minimum length}\n");
9971eaf0ac3Slogwang 	p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} "
9981eaf0ac3Slogwang 	    "{N:/bad checksum%s}\n");
9991eaf0ac3Slogwang 	p(icp6s_badlen, "\t{:dropped-bad-length/%ju} "
10001eaf0ac3Slogwang 	    "{N:/message%s with bad length}\n");
10011eaf0ac3Slogwang #define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
10021eaf0ac3Slogwang 	for (first = 1, i = 0; i < NELEM; i++)
10031eaf0ac3Slogwang 		if (icmp6stat.icp6s_inhist[i] != 0) {
10041eaf0ac3Slogwang 			if (first) {
10051eaf0ac3Slogwang 				xo_open_list("input-histogram");
10061eaf0ac3Slogwang 				xo_emit("\t{T:Input histogram}:\n");
10071eaf0ac3Slogwang 				first = 0;
10081eaf0ac3Slogwang 			}
10091eaf0ac3Slogwang 			xo_open_instance("input-histogram");
10101eaf0ac3Slogwang 			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
10111eaf0ac3Slogwang 			    icmp6names[i],
10121eaf0ac3Slogwang 			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
10131eaf0ac3Slogwang 			xo_close_instance("input-histogram");
10141eaf0ac3Slogwang 		}
10151eaf0ac3Slogwang 	if (!first)
10161eaf0ac3Slogwang 		xo_close_list("input-histogram");
10171eaf0ac3Slogwang #undef NELEM
10181eaf0ac3Slogwang 	xo_emit("\t{T:Histogram of error messages to be generated}:\n");
10191eaf0ac3Slogwang 	xo_open_container("errors");
10201eaf0ac3Slogwang 	p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} "
10211eaf0ac3Slogwang 	    "{N:/no route}\n");
10221eaf0ac3Slogwang 	p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} "
10231eaf0ac3Slogwang 	    "{N:/administratively prohibited}\n");
10241eaf0ac3Slogwang 	p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} "
10251eaf0ac3Slogwang 	    "{N:/beyond scope}\n");
10261eaf0ac3Slogwang 	p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} "
10271eaf0ac3Slogwang 	    "{N:/address unreachable}\n");
10281eaf0ac3Slogwang 	p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} "
10291eaf0ac3Slogwang 	    "{N:/port unreachable}\n");
10301eaf0ac3Slogwang 	p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} "
10311eaf0ac3Slogwang 	    "{N:/packet too big}\n");
10321eaf0ac3Slogwang 	p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} "
10331eaf0ac3Slogwang 	    "{N:/time exceed transit}\n");
10341eaf0ac3Slogwang 	p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} "
10351eaf0ac3Slogwang 	    "{N:/time exceed reassembly}\n");
10361eaf0ac3Slogwang 	p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} "
10371eaf0ac3Slogwang 	    "{N:/erroneous header field}\n");
10381eaf0ac3Slogwang 	p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} "
10391eaf0ac3Slogwang 	    "{N:/unrecognized next header}\n");
10401eaf0ac3Slogwang 	p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} "
10411eaf0ac3Slogwang 	    "{N:/unrecognized option}\n");
10421eaf0ac3Slogwang 	p_5(icp6s_oredirect, "\t\t{:redirects/%ju} "
10431eaf0ac3Slogwang 	    "{N:/redirect}\n");
10441eaf0ac3Slogwang 	p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n");
10451eaf0ac3Slogwang 
10461eaf0ac3Slogwang 	p(icp6s_reflect, "\t{:reflect/%ju} "
10471eaf0ac3Slogwang 	    "{N:/message response%s generated}\n");
10481eaf0ac3Slogwang 	p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} "
10491eaf0ac3Slogwang 	    "{N:/message%s with too many ND options}\n");
10501eaf0ac3Slogwang 	p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} "
10511eaf0ac3Slogwang 	    "{N:/message%s with bad ND options}\n");
10521eaf0ac3Slogwang 	p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} "
10531eaf0ac3Slogwang 	    "{N:/bad neighbor solicitation message%s}\n");
10541eaf0ac3Slogwang 	p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} "
10551eaf0ac3Slogwang 	    "{N:/bad neighbor advertisement message%s}\n");
10561eaf0ac3Slogwang 	p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} "
10571eaf0ac3Slogwang 	    "{N:/bad router solicitation message%s}\n");
10581eaf0ac3Slogwang 	p(icp6s_badra, "\t{:bad-router-advertisement/%ju} "
10591eaf0ac3Slogwang 	    "{N:/bad router advertisement message%s}\n");
10601eaf0ac3Slogwang 	p(icp6s_badredirect, "\t{:bad-redirect/%ju} "
10611eaf0ac3Slogwang 	    "{N:/bad redirect message%s}\n");
106222ce4affSfengbojiang 	p(icp6s_overflowdefrtr, "\t{:default-routers-overflows/%ju} "
106322ce4affSfengbojiang 	    "{N:/default routers overflow%s}\n");
106422ce4affSfengbojiang 	p(icp6s_overflowprfx, "\t{:prefixes-overflows/%ju} "
106522ce4affSfengbojiang 	    "{N:/prefix overflow%s}\n");
106622ce4affSfengbojiang 	p(icp6s_overflownndp, "\t{:neighbour-entries-overflows/%ju} "
106722ce4affSfengbojiang 	    "{N:/neighbour entries overflow%s}\n");
106822ce4affSfengbojiang 	p(icp6s_overflowredirect, "\t{:redirect-overflows/%ju} "
106922ce4affSfengbojiang 	    "{N:/redirect overflow%s}\n");
107022ce4affSfengbojiang 	p(icp6s_invlhlim, "\t{:dropped-invalid-hop-limit/%ju} "
107122ce4affSfengbojiang 	    "{N:/message%s with invalid hop limit}\n");
10721eaf0ac3Slogwang 	xo_close_container("errors");
10731eaf0ac3Slogwang 	p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n");
10741eaf0ac3Slogwang #undef p
10751eaf0ac3Slogwang #undef p_5
10761eaf0ac3Slogwang 	xo_close_container(name);
10771eaf0ac3Slogwang }
10781eaf0ac3Slogwang 
10791eaf0ac3Slogwang /*
10801eaf0ac3Slogwang  * Dump ICMPv6 per-interface statistics based on RFC 2466.
10811eaf0ac3Slogwang  */
10821eaf0ac3Slogwang void
10831eaf0ac3Slogwang icmp6_ifstats(char *ifname)
10841eaf0ac3Slogwang {
10851eaf0ac3Slogwang 	struct in6_ifreq ifr;
10861eaf0ac3Slogwang 	int s;
10871eaf0ac3Slogwang 
10881eaf0ac3Slogwang #define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1)	\
10891eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f,		\
10901eaf0ac3Slogwang 	    plural(ifr.ifr_ifru.ifru_icmp6stat.f))
10911eaf0ac3Slogwang #define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1)	\
10921eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f,		\
10931eaf0ac3Slogwang 	    pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
10941eaf0ac3Slogwang 
10951eaf0ac3Slogwang 	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
10961eaf0ac3Slogwang 		xo_warn("Warning: socket(AF_INET6)");
10971eaf0ac3Slogwang 		return;
10981eaf0ac3Slogwang 	}
10991eaf0ac3Slogwang 
110022ce4affSfengbojiang 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1101*d4a07e70Sfengbojiang #ifndef FSTACK
11021eaf0ac3Slogwang 	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
1103*d4a07e70Sfengbojiang #else
1104*d4a07e70Sfengbojiang 	if (ioctl_va(s, SIOCGIFSTAT_ICMP6, (char *)&ifr, 1, AF_INET6) < 0) {
1105*d4a07e70Sfengbojiang #endif
11061eaf0ac3Slogwang 		if (errno != EPFNOSUPPORT)
11071eaf0ac3Slogwang 			xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
11081eaf0ac3Slogwang 		goto end;
11091eaf0ac3Slogwang 	}
11101eaf0ac3Slogwang 
11111eaf0ac3Slogwang 	xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name);
11121eaf0ac3Slogwang 
11131eaf0ac3Slogwang 	xo_open_instance("icmp6-interface-statistics");
11141eaf0ac3Slogwang 	xo_emit("{ke:name/%s}", ifr.ifr_name);
11151eaf0ac3Slogwang 	p(ifs6_in_msg, "\t{:received-packets/%ju} "
11161eaf0ac3Slogwang 	    "{N:/total input message%s}\n");
11171eaf0ac3Slogwang 	p(ifs6_in_error, "\t{:received-errors/%ju} "
11181eaf0ac3Slogwang 	    "{N:/total input error message%s}\n");
11191eaf0ac3Slogwang 	p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} "
11201eaf0ac3Slogwang 	    "{N:/input destination unreachable error%s}\n");
11211eaf0ac3Slogwang 	p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} "
11221eaf0ac3Slogwang 	    "{N:/input administratively prohibited error%s}\n");
11231eaf0ac3Slogwang 	p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} "
11241eaf0ac3Slogwang 	    "{N:/input time exceeded error%s}\n");
11251eaf0ac3Slogwang 	p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} "
11261eaf0ac3Slogwang 	    "{N:/input parameter problem error%s}\n");
11271eaf0ac3Slogwang 	p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} "
11281eaf0ac3Slogwang 	    "{N:/input packet too big error%s}\n");
11291eaf0ac3Slogwang 	p(ifs6_in_echo, "\t{:received-echo-requests/%ju} "
11301eaf0ac3Slogwang 	    "{N:/input echo request%s}\n");
11311eaf0ac3Slogwang 	p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} "
11321eaf0ac3Slogwang 	    "{N:/input echo repl%s}\n");
11331eaf0ac3Slogwang 	p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} "
11341eaf0ac3Slogwang 	    "{N:/input router solicitation%s}\n");
11351eaf0ac3Slogwang 	p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} "
11361eaf0ac3Slogwang 	    "{N:/input router advertisement%s}\n");
11371eaf0ac3Slogwang 	p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} "
11381eaf0ac3Slogwang 	    "{N:/input neighbor solicitation%s}\n");
11391eaf0ac3Slogwang 	p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} "
11401eaf0ac3Slogwang 	    "{N:/input neighbor advertisement%s}\n");
11411eaf0ac3Slogwang 	p(ifs6_in_redirect, "\t{received-redirects/%ju} "
11421eaf0ac3Slogwang 	    "{N:/input redirect%s}\n");
11431eaf0ac3Slogwang 	p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} "
11441eaf0ac3Slogwang 	    "{N:/input MLD quer%s}\n");
11451eaf0ac3Slogwang 	p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} "
11461eaf0ac3Slogwang 	    "{N:/input MLD report%s}\n");
11471eaf0ac3Slogwang 	p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} "
11481eaf0ac3Slogwang 	    "{N:/input MLD done%s}\n");
11491eaf0ac3Slogwang 
11501eaf0ac3Slogwang 	p(ifs6_out_msg, "\t{:sent-packets/%ju} "
11511eaf0ac3Slogwang 	    "{N:/total output message%s}\n");
11521eaf0ac3Slogwang 	p(ifs6_out_error, "\t{:sent-errors/%ju} "
11531eaf0ac3Slogwang 	    "{N:/total output error message%s}\n");
11541eaf0ac3Slogwang 	p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} "
11551eaf0ac3Slogwang 	    "{N:/output destination unreachable error%s}\n");
11561eaf0ac3Slogwang 	p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} "
11571eaf0ac3Slogwang 	    "{N:/output administratively prohibited error%s}\n");
11581eaf0ac3Slogwang 	p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} "
11591eaf0ac3Slogwang 	    "{N:/output time exceeded error%s}\n");
11601eaf0ac3Slogwang 	p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} "
11611eaf0ac3Slogwang 	    "{N:/output parameter problem error%s}\n");
11621eaf0ac3Slogwang 	p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} "
11631eaf0ac3Slogwang 	    "{N:/output packet too big error%s}\n");
11641eaf0ac3Slogwang 	p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} "
11651eaf0ac3Slogwang 	    "{N:/output echo request%s}\n");
11661eaf0ac3Slogwang 	p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} "
11671eaf0ac3Slogwang 	    "{N:/output echo repl%s}\n");
11681eaf0ac3Slogwang 	p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} "
11691eaf0ac3Slogwang 	    "{N:/output router solicitation%s}\n");
11701eaf0ac3Slogwang 	p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} "
11711eaf0ac3Slogwang 	    "{N:/output router advertisement%s}\n");
11721eaf0ac3Slogwang 	p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} "
11731eaf0ac3Slogwang 	    "{N:/output neighbor solicitation%s}\n");
11741eaf0ac3Slogwang 	p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} "
11751eaf0ac3Slogwang 	    "{N:/output neighbor advertisement%s}\n");
11761eaf0ac3Slogwang 	p(ifs6_out_redirect, "\t{:sent-redirects/%ju} "
11771eaf0ac3Slogwang 	    "{N:/output redirect%s}\n");
11781eaf0ac3Slogwang 	p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} "
11791eaf0ac3Slogwang 	    "{N:/output MLD quer%s}\n");
11801eaf0ac3Slogwang 	p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} "
11811eaf0ac3Slogwang 	    "{N:/output MLD report%s}\n");
11821eaf0ac3Slogwang 	p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} "
11831eaf0ac3Slogwang 	    "{N:/output MLD done%s}\n");
11841eaf0ac3Slogwang 
11851eaf0ac3Slogwang end:
11861eaf0ac3Slogwang 	xo_close_instance("icmp6-interface-statistics");
11871eaf0ac3Slogwang 	close(s);
11881eaf0ac3Slogwang #undef p
11891eaf0ac3Slogwang }
11901eaf0ac3Slogwang 
11911eaf0ac3Slogwang /*
11921eaf0ac3Slogwang  * Dump PIM statistics structure.
11931eaf0ac3Slogwang  */
11941eaf0ac3Slogwang void
11951eaf0ac3Slogwang pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
11961eaf0ac3Slogwang {
11971eaf0ac3Slogwang 	struct pim6stat pim6stat;
11981eaf0ac3Slogwang 
11991eaf0ac3Slogwang 	if (fetch_stats("net.inet6.pim.stats", off, &pim6stat,
12001eaf0ac3Slogwang 	    sizeof(pim6stat), kread) != 0)
12011eaf0ac3Slogwang 		return;
12021eaf0ac3Slogwang 
12031eaf0ac3Slogwang 	xo_emit("{T:/%s}:\n", name);
12041eaf0ac3Slogwang 	xo_open_container(name);
12051eaf0ac3Slogwang 
12061eaf0ac3Slogwang #define	p(f, m) if (pim6stat.f || sflag <= 1) \
12071eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
12081eaf0ac3Slogwang 
12091eaf0ac3Slogwang 	p(pim6s_rcv_total, "\t{:received-packets/%ju} "
12101eaf0ac3Slogwang 	    "{N:/message%s received}\n");
12111eaf0ac3Slogwang 	p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} "
12121eaf0ac3Slogwang 	    "{N:/message%s received with too few bytes}\n");
12131eaf0ac3Slogwang 	p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} "
12141eaf0ac3Slogwang 	    "{N:/message%s received with bad checksum}\n");
12151eaf0ac3Slogwang 	p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} "
12161eaf0ac3Slogwang 	    "{N:/message%s received with bad version}\n");
12171eaf0ac3Slogwang 	p(pim6s_rcv_registers, "\t{:received-registers/%ju} "
12181eaf0ac3Slogwang 	    "{N:/register%s received}\n");
12191eaf0ac3Slogwang 	p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} "
12201eaf0ac3Slogwang 	    "{N:/bad register%s received}\n");
12211eaf0ac3Slogwang 	p(pim6s_snd_registers, "\t{:sent-registers/%ju} "
12221eaf0ac3Slogwang 	    "{N:/register%s sent}\n");
12231eaf0ac3Slogwang #undef p
12241eaf0ac3Slogwang 	xo_close_container(name);
12251eaf0ac3Slogwang }
12261eaf0ac3Slogwang 
12271eaf0ac3Slogwang /*
12281eaf0ac3Slogwang  * Dump raw ip6 statistics structure.
12291eaf0ac3Slogwang  */
12301eaf0ac3Slogwang void
12311eaf0ac3Slogwang rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
12321eaf0ac3Slogwang {
12331eaf0ac3Slogwang 	struct rip6stat rip6stat;
12341eaf0ac3Slogwang 	u_quad_t delivered;
12351eaf0ac3Slogwang 
12361eaf0ac3Slogwang 	if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat,
12371eaf0ac3Slogwang 	    sizeof(rip6stat), kread_counters) != 0)
12381eaf0ac3Slogwang 		return;
12391eaf0ac3Slogwang 
12401eaf0ac3Slogwang 	xo_emit("{T:/%s}:\n", name);
12411eaf0ac3Slogwang 	xo_open_container(name);
12421eaf0ac3Slogwang 
12431eaf0ac3Slogwang #define	p(f, m) if (rip6stat.f || sflag <= 1) \
12441eaf0ac3Slogwang 	xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
12451eaf0ac3Slogwang 
12461eaf0ac3Slogwang 	p(rip6s_ipackets, "\t{:received-packets/%ju} "
12471eaf0ac3Slogwang 	    "{N:/message%s received}\n");
12481eaf0ac3Slogwang 	p(rip6s_isum, "\t{:input-checksum-computation/%ju} "
12491eaf0ac3Slogwang 	    "{N:/checksum calculation%s on inbound}\n");
12501eaf0ac3Slogwang 	p(rip6s_badsum, "\t{:received-bad-checksum/%ju} "
12511eaf0ac3Slogwang 	    "{N:/message%s with bad checksum}\n");
12521eaf0ac3Slogwang 	p(rip6s_nosock, "\t{:dropped-no-socket/%ju} "
12531eaf0ac3Slogwang 	    "{N:/message%s dropped due to no socket}\n");
12541eaf0ac3Slogwang 	p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} "
12551eaf0ac3Slogwang 	    "{N:/multicast message%s dropped due to no socket}\n");
12561eaf0ac3Slogwang 	p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} "
12571eaf0ac3Slogwang 	    "{N:/message%s dropped due to full socket buffers}\n");
12581eaf0ac3Slogwang 	delivered = rip6stat.rip6s_ipackets -
12591eaf0ac3Slogwang 		    rip6stat.rip6s_badsum -
12601eaf0ac3Slogwang 		    rip6stat.rip6s_nosock -
12611eaf0ac3Slogwang 		    rip6stat.rip6s_nosockmcast -
12621eaf0ac3Slogwang 		    rip6stat.rip6s_fullsock;
12631eaf0ac3Slogwang 	if (delivered || sflag <= 1)
12641eaf0ac3Slogwang 		xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n",
12651eaf0ac3Slogwang 		    (uintmax_t)delivered);
12661eaf0ac3Slogwang 	p(rip6s_opackets, "\t{:sent-packets/%ju} "
12671eaf0ac3Slogwang 	    "{N:/datagram%s output}\n");
12681eaf0ac3Slogwang #undef p
12691eaf0ac3Slogwang 	xo_close_container(name);
12701eaf0ac3Slogwang }
12711eaf0ac3Slogwang 
12721eaf0ac3Slogwang /*
12731eaf0ac3Slogwang  * Pretty print an Internet address (net address + port).
12741eaf0ac3Slogwang  * Take numeric_addr and numeric_port into consideration.
12751eaf0ac3Slogwang  */
12761eaf0ac3Slogwang #define	GETSERVBYPORT6(port, proto, ret)\
12771eaf0ac3Slogwang {\
12781eaf0ac3Slogwang 	if (strcmp((proto), "tcp6") == 0)\
12791eaf0ac3Slogwang 		(ret) = getservbyport((int)(port), "tcp");\
12801eaf0ac3Slogwang 	else if (strcmp((proto), "udp6") == 0)\
12811eaf0ac3Slogwang 		(ret) = getservbyport((int)(port), "udp");\
12821eaf0ac3Slogwang 	else\
12831eaf0ac3Slogwang 		(ret) = getservbyport((int)(port), (proto));\
12841eaf0ac3Slogwang };
12851eaf0ac3Slogwang 
12861eaf0ac3Slogwang void
12871eaf0ac3Slogwang inet6print(const char *container, struct in6_addr *in6, int port,
12881eaf0ac3Slogwang     const char *proto, int numeric)
12891eaf0ac3Slogwang {
12901eaf0ac3Slogwang 	struct servent *sp = 0;
12911eaf0ac3Slogwang 	char line[80], *cp;
12921eaf0ac3Slogwang 	int width;
129322ce4affSfengbojiang 	size_t alen, plen;
12941eaf0ac3Slogwang 
12951eaf0ac3Slogwang 	if (container)
12961eaf0ac3Slogwang 		xo_open_container(container);
12971eaf0ac3Slogwang 
129822ce4affSfengbojiang 	snprintf(line, sizeof(line), "%.*s.",
129922ce4affSfengbojiang 	    Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
13001eaf0ac3Slogwang 	    inet6name(in6));
130122ce4affSfengbojiang 	alen = strlen(line);
130222ce4affSfengbojiang 	cp = line + alen;
13031eaf0ac3Slogwang 	if (!numeric && port)
13041eaf0ac3Slogwang 		GETSERVBYPORT6(port, proto, sp);
13051eaf0ac3Slogwang 	if (sp || port == 0)
130622ce4affSfengbojiang 		snprintf(cp, sizeof(line) - alen,
130722ce4affSfengbojiang 		    "%.15s", sp ? sp->s_name : "*");
13081eaf0ac3Slogwang 	else
130922ce4affSfengbojiang 		snprintf(cp, sizeof(line) - alen,
131022ce4affSfengbojiang 		    "%d", ntohs((u_short)port));
13111eaf0ac3Slogwang 	width = Wflag ? 45 : Aflag ? 18 : 22;
13121eaf0ac3Slogwang 
13131eaf0ac3Slogwang 	xo_emit("{d:target/%-*.*s} ", width, width, line);
13141eaf0ac3Slogwang 
131522ce4affSfengbojiang 	plen = strlen(cp);
131622ce4affSfengbojiang 	alen--;
13171eaf0ac3Slogwang 	xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
13181eaf0ac3Slogwang 	    plen, cp);
13191eaf0ac3Slogwang 
13201eaf0ac3Slogwang 	if (container)
13211eaf0ac3Slogwang 		xo_close_container(container);
13221eaf0ac3Slogwang }
13231eaf0ac3Slogwang 
13241eaf0ac3Slogwang /*
13251eaf0ac3Slogwang  * Construct an Internet address representation.
13261eaf0ac3Slogwang  * If the numeric_addr has been supplied, give
13271eaf0ac3Slogwang  * numeric value, otherwise try for symbolic name.
13281eaf0ac3Slogwang  */
13291eaf0ac3Slogwang 
13301eaf0ac3Slogwang char *
133122ce4affSfengbojiang inet6name(struct in6_addr *ia6)
13321eaf0ac3Slogwang {
13331eaf0ac3Slogwang 	struct sockaddr_in6 sin6;
13341eaf0ac3Slogwang 	char hbuf[NI_MAXHOST], *cp;
133522ce4affSfengbojiang 	static char line[NI_MAXHOST];
13361eaf0ac3Slogwang 	static char domain[MAXHOSTNAMELEN];
13371eaf0ac3Slogwang 	static int first = 1;
13381eaf0ac3Slogwang 	int flags, error;
13391eaf0ac3Slogwang 
134022ce4affSfengbojiang 	if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
13411eaf0ac3Slogwang 		strcpy(line, "*");
13421eaf0ac3Slogwang 		return (line);
13431eaf0ac3Slogwang 	}
1344*d4a07e70Sfengbojiang 
1345*d4a07e70Sfengbojiang #ifndef FSTACK
13461eaf0ac3Slogwang 	if (first && !numeric_addr) {
13471eaf0ac3Slogwang 		first = 0;
134822ce4affSfengbojiang 		if (gethostname(domain, sizeof(domain)) == 0 &&
13491eaf0ac3Slogwang 		    (cp = strchr(domain, '.')))
135022ce4affSfengbojiang 			strlcpy(domain, cp + 1, sizeof(domain));
13511eaf0ac3Slogwang 		else
13521eaf0ac3Slogwang 			domain[0] = 0;
13531eaf0ac3Slogwang 	}
1354*d4a07e70Sfengbojiang #endif
1355*d4a07e70Sfengbojiang 
13561eaf0ac3Slogwang 	memset(&sin6, 0, sizeof(sin6));
135722ce4affSfengbojiang 	memcpy(&sin6.sin6_addr, ia6, sizeof(*ia6));
13581eaf0ac3Slogwang 	sin6.sin6_family = AF_INET6;
135922ce4affSfengbojiang 	/* XXX: ia6.s6_addr[2] can contain scopeid. */
13601eaf0ac3Slogwang 	in6_fillscopeid(&sin6);
1361*d4a07e70Sfengbojiang 
1362*d4a07e70Sfengbojiang #ifndef FSTACK
13631eaf0ac3Slogwang 	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
13641eaf0ac3Slogwang 	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
13651eaf0ac3Slogwang 	    sizeof(hbuf), NULL, 0, flags);
13661eaf0ac3Slogwang 	if (error == 0) {
13671eaf0ac3Slogwang 		if ((flags & NI_NUMERICHOST) == 0 &&
13681eaf0ac3Slogwang 		    (cp = strchr(hbuf, '.')) &&
13691eaf0ac3Slogwang 		    !strcmp(cp + 1, domain))
13701eaf0ac3Slogwang 			*cp = 0;
137122ce4affSfengbojiang 		strlcpy(line, hbuf, sizeof(line));
137222ce4affSfengbojiang 	} else {
1373*d4a07e70Sfengbojiang #else
1374*d4a07e70Sfengbojiang 	{
1375*d4a07e70Sfengbojiang #endif
13761eaf0ac3Slogwang 		/* XXX: this should not happen. */
137722ce4affSfengbojiang 		snprintf(line, sizeof(line), "%s",
1378*d4a07e70Sfengbojiang #ifndef FSTACK
13791eaf0ac3Slogwang 			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
1380*d4a07e70Sfengbojiang #else
1381*d4a07e70Sfengbojiang 			inet_ntop(AF_INET6_LINUX, (void *)&sin6.sin6_addr, ntop_buf,
1382*d4a07e70Sfengbojiang #endif
13831eaf0ac3Slogwang 				sizeof(ntop_buf)));
13841eaf0ac3Slogwang 	}
13851eaf0ac3Slogwang 	return (line);
13861eaf0ac3Slogwang }
13871eaf0ac3Slogwang #endif /*INET6*/
1388