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