inet6.c revision 215955
154263Sshin/*	BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp	*/
2175061Sobrien/*-
354263Sshin * Copyright (c) 1983, 1988, 1993
454263Sshin *	The Regents of the University of California.  All rights reserved.
554263Sshin *
654263Sshin * Redistribution and use in source and binary forms, with or without
754263Sshin * modification, are permitted provided that the following conditions
854263Sshin * are met:
954263Sshin * 1. Redistributions of source code must retain the above copyright
1054263Sshin *    notice, this list of conditions and the following disclaimer.
1154263Sshin * 2. Redistributions in binary form must reproduce the above copyright
1254263Sshin *    notice, this list of conditions and the following disclaimer in the
1354263Sshin *    documentation and/or other materials provided with the distribution.
1454263Sshin * 3. All advertising materials mentioning features or use of this software
1554263Sshin *    must display the following acknowledgement:
1654263Sshin *	This product includes software developed by the University of
1754263Sshin *	California, Berkeley and its contributors.
1854263Sshin * 4. Neither the name of the University nor the names of its contributors
1954263Sshin *    may be used to endorse or promote products derived from this software
2054263Sshin *    without specific prior written permission.
2154263Sshin *
2254263Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2354263Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2454263Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2554263Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2654263Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2754263Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2854263Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2954263Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3054263Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3154263Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3254263Sshin * SUCH DAMAGE.
3354263Sshin */
3454263Sshin
35132671Scharnier#if 0
3654263Sshin#ifndef lint
3754263Sshinstatic char sccsid[] = "@(#)inet6.c	8.4 (Berkeley) 4/20/94";
3854263Sshin#endif /* not lint */
39132671Scharnier#endif
4054263Sshin
41132671Scharnier#include <sys/cdefs.h>
42132671Scharnier__FBSDID("$FreeBSD: head/usr.bin/netstat/inet6.c 215955 2010-11-27 21:35:16Z brucec $");
43132671Scharnier
4464342Sume#ifdef INET6
4554263Sshin#include <sys/param.h>
4654263Sshin#include <sys/socket.h>
4754263Sshin#include <sys/socketvar.h>
4854263Sshin#include <sys/ioctl.h>
4954263Sshin#include <sys/mbuf.h>
5054263Sshin#include <sys/protosw.h>
5178064Sume#include <sys/sysctl.h>
5254263Sshin
5354263Sshin#include <net/route.h>
5454263Sshin#include <net/if.h>
5554263Sshin#include <net/if_var.h>
5654263Sshin#include <netinet/in.h>
5754263Sshin#include <netinet/ip6.h>
5854263Sshin#include <netinet/icmp6.h>
5954263Sshin#include <netinet/in_systm.h>
6054263Sshin#include <netinet6/in6_pcb.h>
6154263Sshin#include <netinet6/in6_var.h>
6254263Sshin#include <netinet6/ip6_var.h>
6354263Sshin#include <netinet6/pim6_var.h>
6478064Sume#include <netinet6/raw_ip6.h>
6554263Sshin
6654263Sshin#include <arpa/inet.h>
6754263Sshin#include <netdb.h>
6854263Sshin
69166952Sbms#include <err.h>
70160787Syar#include <stdint.h>
7154263Sshin#include <stdio.h>
72160373Sjulian#include <errno.h>
7354263Sshin#include <string.h>
7454263Sshin#include <unistd.h>
7554263Sshin#include "netstat.h"
7654263Sshin
7754263Sshinstruct	socket sockb;
7854263Sshin
79132671Scharnierchar	*inet6name(struct in6_addr *);
8054263Sshin
8154263Sshinstatic char ntop_buf[INET6_ADDRSTRLEN];
8254263Sshin
83102975Sdwmalonestatic	const char *ip6nh[] = {
8454263Sshin	"hop by hop",
8554263Sshin	"ICMP",
8654263Sshin	"IGMP",
8754263Sshin	"#3",
8854263Sshin	"IP",
8954263Sshin	"#5",
9054263Sshin	"TCP",
9154263Sshin	"#7",
9254263Sshin	"#8",
9354263Sshin	"#9",
9454263Sshin	"#10",
9554263Sshin	"#11",
9654263Sshin	"#12",
9754263Sshin	"#13",
9854263Sshin	"#14",
9954263Sshin	"#15",
10054263Sshin	"#16",
10154263Sshin	"UDP",
10254263Sshin	"#18",
103175061Sobrien	"#19",
10454263Sshin	"#20",
10554263Sshin	"#21",
10654263Sshin	"IDP",
10754263Sshin	"#23",
10854263Sshin	"#24",
10954263Sshin	"#25",
11054263Sshin	"#26",
11154263Sshin	"#27",
11254263Sshin	"#28",
113175061Sobrien	"TP",
11454263Sshin	"#30",
11554263Sshin	"#31",
11654263Sshin	"#32",
11754263Sshin	"#33",
11854263Sshin	"#34",
11954263Sshin	"#35",
12054263Sshin	"#36",
12154263Sshin	"#37",
12254263Sshin	"#38",
123175061Sobrien	"#39",
12454263Sshin	"#40",
12554263Sshin	"IP6",
12654263Sshin	"#42",
12754263Sshin	"routing",
12854263Sshin	"fragment",
12954263Sshin	"#45",
13054263Sshin	"#46",
13154263Sshin	"#47",
13254263Sshin	"#48",
133175061Sobrien	"#49",
13454263Sshin	"ESP",
13554263Sshin	"AH",
13654263Sshin	"#52",
13754263Sshin	"#53",
13854263Sshin	"#54",
13954263Sshin	"#55",
14054263Sshin	"#56",
14154263Sshin	"#57",
14254263Sshin	"ICMP6",
143175061Sobrien	"no next header",
14454263Sshin	"destination option",
14554263Sshin	"#61",
146125482Sume	"mobility",
14754263Sshin	"#63",
14854263Sshin	"#64",
14954263Sshin	"#65",
15054263Sshin	"#66",
15154263Sshin	"#67",
15254263Sshin	"#68",
153175061Sobrien	"#69",
15454263Sshin	"#70",
15554263Sshin	"#71",
15654263Sshin	"#72",
15754263Sshin	"#73",
15854263Sshin	"#74",
15954263Sshin	"#75",
16054263Sshin	"#76",
16154263Sshin	"#77",
16254263Sshin	"#78",
163175061Sobrien	"#79",
16454263Sshin	"ISOIP",
16554263Sshin	"#81",
16654263Sshin	"#82",
16754263Sshin	"#83",
16854263Sshin	"#84",
16954263Sshin	"#85",
17054263Sshin	"#86",
17154263Sshin	"#87",
17254263Sshin	"#88",
173175061Sobrien	"OSPF",
17454263Sshin	"#80",
17554263Sshin	"#91",
17654263Sshin	"#92",
17754263Sshin	"#93",
17854263Sshin	"#94",
17954263Sshin	"#95",
18054263Sshin	"#96",
18154263Sshin	"Ethernet",
18254263Sshin	"#98",
183175061Sobrien	"#99",
18454263Sshin	"#100",
18554263Sshin	"#101",
18654263Sshin	"#102",
18754263Sshin	"PIM",
18854263Sshin	"#104",
18954263Sshin	"#105",
19054263Sshin	"#106",
19154263Sshin	"#107",
19254263Sshin	"#108",
193175061Sobrien	"#109",
19454263Sshin	"#110",
19554263Sshin	"#111",
19654263Sshin	"#112",
19754263Sshin	"#113",
19854263Sshin	"#114",
19954263Sshin	"#115",
20054263Sshin	"#116",
20154263Sshin	"#117",
20254263Sshin	"#118",
203175061Sobrien	"#119",
20454263Sshin	"#120",
20554263Sshin	"#121",
20654263Sshin	"#122",
20754263Sshin	"#123",
20854263Sshin	"#124",
20954263Sshin	"#125",
21054263Sshin	"#126",
21154263Sshin	"#127",
21254263Sshin	"#128",
213175061Sobrien	"#129",
21454263Sshin	"#130",
21554263Sshin	"#131",
21654263Sshin	"#132",
21754263Sshin	"#133",
21854263Sshin	"#134",
21954263Sshin	"#135",
22054263Sshin	"#136",
22154263Sshin	"#137",
22254263Sshin	"#138",
223175061Sobrien	"#139",
22454263Sshin	"#140",
22554263Sshin	"#141",
22654263Sshin	"#142",
22754263Sshin	"#143",
22854263Sshin	"#144",
22954263Sshin	"#145",
23054263Sshin	"#146",
23154263Sshin	"#147",
23254263Sshin	"#148",
233175061Sobrien	"#149",
23454263Sshin	"#150",
23554263Sshin	"#151",
23654263Sshin	"#152",
23754263Sshin	"#153",
23854263Sshin	"#154",
23954263Sshin	"#155",
24054263Sshin	"#156",
24154263Sshin	"#157",
24254263Sshin	"#158",
243175061Sobrien	"#159",
24454263Sshin	"#160",
24554263Sshin	"#161",
24654263Sshin	"#162",
24754263Sshin	"#163",
24854263Sshin	"#164",
24954263Sshin	"#165",
25054263Sshin	"#166",
25154263Sshin	"#167",
25254263Sshin	"#168",
253175061Sobrien	"#169",
25454263Sshin	"#170",
25554263Sshin	"#171",
25654263Sshin	"#172",
25754263Sshin	"#173",
25854263Sshin	"#174",
25954263Sshin	"#175",
26054263Sshin	"#176",
26154263Sshin	"#177",
26254263Sshin	"#178",
263175061Sobrien	"#179",
26454263Sshin	"#180",
26554263Sshin	"#181",
26654263Sshin	"#182",
26754263Sshin	"#183",
26854263Sshin	"#184",
26954263Sshin	"#185",
27054263Sshin	"#186",
27154263Sshin	"#187",
27254263Sshin	"#188",
273175061Sobrien	"#189",
27454263Sshin	"#180",
27554263Sshin	"#191",
27654263Sshin	"#192",
27754263Sshin	"#193",
27854263Sshin	"#194",
27954263Sshin	"#195",
28054263Sshin	"#196",
28154263Sshin	"#197",
28254263Sshin	"#198",
283175061Sobrien	"#199",
28454263Sshin	"#200",
28554263Sshin	"#201",
28654263Sshin	"#202",
28754263Sshin	"#203",
28854263Sshin	"#204",
28954263Sshin	"#205",
29054263Sshin	"#206",
29154263Sshin	"#207",
29254263Sshin	"#208",
293175061Sobrien	"#209",
29454263Sshin	"#210",
29554263Sshin	"#211",
29654263Sshin	"#212",
29754263Sshin	"#213",
29854263Sshin	"#214",
29954263Sshin	"#215",
30054263Sshin	"#216",
30154263Sshin	"#217",
30254263Sshin	"#218",
303175061Sobrien	"#219",
30454263Sshin	"#220",
30554263Sshin	"#221",
30654263Sshin	"#222",
30754263Sshin	"#223",
30854263Sshin	"#224",
30954263Sshin	"#225",
31054263Sshin	"#226",
31154263Sshin	"#227",
31254263Sshin	"#228",
313175061Sobrien	"#229",
31454263Sshin	"#230",
31554263Sshin	"#231",
31654263Sshin	"#232",
31754263Sshin	"#233",
31854263Sshin	"#234",
31954263Sshin	"#235",
32054263Sshin	"#236",
32154263Sshin	"#237",
32254263Sshin	"#238",
323175061Sobrien	"#239",
32454263Sshin	"#240",
32554263Sshin	"#241",
32654263Sshin	"#242",
32754263Sshin	"#243",
32854263Sshin	"#244",
32954263Sshin	"#245",
33054263Sshin	"#246",
33154263Sshin	"#247",
33254263Sshin	"#248",
333175061Sobrien	"#249",
33454263Sshin	"#250",
33554263Sshin	"#251",
33654263Sshin	"#252",
33754263Sshin	"#253",
33854263Sshin	"#254",
33954263Sshin	"#255",
34054263Sshin};
34154263Sshin
342125483Sumestatic char *srcrule_str[] = {
343125483Sume	"first candidate",
344125483Sume	"same address",
345125483Sume	"appropriate scope",
346125483Sume	"deprecated address",
347125483Sume	"home address",
348125483Sume	"outgoing interface",
349125483Sume	"matching label",
350125483Sume	"public/temporary address",
351125483Sume	"alive interface",
352125483Sume	"preferred interface",
353125483Sume	"rule #10",
354125483Sume	"rule #11",
355125483Sume	"rule #12",
356125483Sume	"rule #13",
357125483Sume	"longest match",
358125483Sume	"rule #15",
359125483Sume};
360125483Sume
36154263Sshin/*
36254263Sshin * Dump IP6 statistics structure.
36354263Sshin */
36454263Sshinvoid
365171465Sjhbip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
36654263Sshin{
36754263Sshin	struct ip6stat ip6stat;
36854263Sshin	int first, i;
36978931Sume	size_t len;
37054263Sshin
371171465Sjhb	len = sizeof ip6stat;
372171465Sjhb	if (live) {
373171465Sjhb		memset(&ip6stat, 0, len);
374171465Sjhb		if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len, NULL,
375171465Sjhb		    0) < 0) {
376171465Sjhb			if (errno != ENOENT)
377171465Sjhb				warn("sysctl: net.inet6.ip6.stats");
378171465Sjhb			return;
379171465Sjhb		}
380171465Sjhb	} else
381171465Sjhb		kread(off, &ip6stat, len);
38254263Sshin
38354263Sshin	printf("%s:\n", name);
38454263Sshin
38554263Sshin#define	p(f, m) if (ip6stat.f || sflag <= 1) \
386160787Syar    printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
38754263Sshin#define	p1a(f, m) if (ip6stat.f || sflag <= 1) \
388160787Syar    printf(m, (uintmax_t)ip6stat.f)
38954263Sshin
390160787Syar	p(ip6s_total, "\t%ju total packet%s received\n");
391160787Syar	p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n");
392160787Syar	p1a(ip6s_tooshort, "\t%ju with data size < data length\n");
393160787Syar	p1a(ip6s_badoptions, "\t%ju with bad options\n");
394160787Syar	p1a(ip6s_badvers, "\t%ju with incorrect version number\n");
395160787Syar	p(ip6s_fragments, "\t%ju fragment%s received\n");
396160787Syar	p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n");
397160787Syar	p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n");
398160787Syar	p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n");
399160787Syar	p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n");
400160787Syar	p(ip6s_delivered, "\t%ju packet%s for this host\n");
401160787Syar	p(ip6s_forward, "\t%ju packet%s forwarded\n");
402160787Syar	p(ip6s_cantforward, "\t%ju packet%s not forwardable\n");
403160787Syar	p(ip6s_redirectsent, "\t%ju redirect%s sent\n");
404160787Syar	p(ip6s_localout, "\t%ju packet%s sent from this host\n");
405160787Syar	p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n");
406160787Syar	p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n");
407160787Syar	p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n");
408160787Syar	p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n");
409160787Syar	p(ip6s_ofragments, "\t%ju fragment%s created\n");
410160787Syar	p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n");
411160787Syar	p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n");
412160787Syar	p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n");
41354263Sshin	for (first = 1, i = 0; i < 256; i++)
41454263Sshin		if (ip6stat.ip6s_nxthist[i] != 0) {
41554263Sshin			if (first) {
41654263Sshin				printf("\tInput histogram:\n");
41754263Sshin				first = 0;
41854263Sshin			}
419160787Syar			printf("\t\t%s: %ju\n", ip6nh[i],
420160787Syar			    (uintmax_t)ip6stat.ip6s_nxthist[i]);
42154263Sshin		}
42254263Sshin	printf("\tMbuf statistics:\n");
423160787Syar	printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1);
42454263Sshin	for (first = 1, i = 0; i < 32; i++) {
42555163Sshin		char ifbuf[IFNAMSIZ];
426175061Sobrien		if (ip6stat.ip6s_m2m[i] != 0) {
42754263Sshin			if (first) {
42854263Sshin				printf("\t\ttwo or more mbuf:\n");
42954263Sshin				first = 0;
43054263Sshin			}
431160787Syar			printf("\t\t\t%s= %ju\n",
43262584Sitojun			    if_indextoname(i, ifbuf),
433160787Syar			    (uintmax_t)ip6stat.ip6s_m2m[i]);
43454263Sshin		}
43554263Sshin	}
436160787Syar	printf("\t\t%ju one ext mbuf\n",
437160787Syar	    (uintmax_t)ip6stat.ip6s_mext1);
438160787Syar	printf("\t\t%ju two or more ext mbuf\n",
439175061Sobrien	    (uintmax_t)ip6stat.ip6s_mext2m);
44062584Sitojun	p(ip6s_exthdrtoolong,
441215955Sbrucec	    "\t%ju packet%s whose headers are not contiguous\n");
442160787Syar	p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n");
44362584Sitojun	p(ip6s_toomanyhdr,
444160787Syar	    "\t%ju packet%s discarded because of too many headers\n");
44562584Sitojun
44662584Sitojun	/* for debugging source address selection */
447175061Sobrien#define	PRINT_SCOPESTAT(s,i) do {\
44862584Sitojun		switch(i) { /* XXX hardcoding in each case */\
44962584Sitojun		case 1:\
450160787Syar			p(s, "\t\t%ju node-local%s\n");\
45162584Sitojun			break;\
45262584Sitojun		case 2:\
453160787Syar			p(s,"\t\t%ju link-local%s\n");\
45462584Sitojun			break;\
45562584Sitojun		case 5:\
456160787Syar			p(s,"\t\t%ju site-local%s\n");\
45762584Sitojun			break;\
45862584Sitojun		case 14:\
459160787Syar			p(s,"\t\t%ju global%s\n");\
46062584Sitojun			break;\
46162584Sitojun		default:\
462160787Syar			printf("\t\t%ju addresses scope=%x\n",\
463160787Syar			    (uintmax_t)ip6stat.s, i);\
46462584Sitojun		}\
46562584Sitojun	} while (0);
46662584Sitojun
46762584Sitojun	p(ip6s_sources_none,
468160787Syar	  "\t%ju failure%s of source address selection\n");
46962584Sitojun	for (first = 1, i = 0; i < 16; i++) {
47062584Sitojun		if (ip6stat.ip6s_sources_sameif[i]) {
47162584Sitojun			if (first) {
47262584Sitojun				printf("\tsource addresses on an outgoing I/F\n");
47362584Sitojun				first = 0;
47462584Sitojun			}
47562584Sitojun			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
47662584Sitojun		}
47762584Sitojun	}
47862584Sitojun	for (first = 1, i = 0; i < 16; i++) {
47962584Sitojun		if (ip6stat.ip6s_sources_otherif[i]) {
48062584Sitojun			if (first) {
48162584Sitojun				printf("\tsource addresses on a non-outgoing I/F\n");
48262584Sitojun				first = 0;
48362584Sitojun			}
48462584Sitojun			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
48562584Sitojun		}
48662584Sitojun	}
48762584Sitojun	for (first = 1, i = 0; i < 16; i++) {
48862584Sitojun		if (ip6stat.ip6s_sources_samescope[i]) {
48962584Sitojun			if (first) {
49062584Sitojun				printf("\tsource addresses of same scope\n");
49162584Sitojun				first = 0;
49262584Sitojun			}
49362584Sitojun			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
49462584Sitojun		}
49562584Sitojun	}
49662584Sitojun	for (first = 1, i = 0; i < 16; i++) {
49762584Sitojun		if (ip6stat.ip6s_sources_otherscope[i]) {
49862584Sitojun			if (first) {
49962584Sitojun				printf("\tsource addresses of a different scope\n");
50062584Sitojun				first = 0;
50162584Sitojun			}
50262584Sitojun			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
50362584Sitojun		}
50462584Sitojun	}
50562584Sitojun	for (first = 1, i = 0; i < 16; i++) {
50662584Sitojun		if (ip6stat.ip6s_sources_deprecated[i]) {
50762584Sitojun			if (first) {
50862584Sitojun				printf("\tdeprecated source addresses\n");
50962584Sitojun				first = 0;
51062584Sitojun			}
51162584Sitojun			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
51262584Sitojun		}
51362584Sitojun	}
51462584Sitojun
515125483Sume	printf("\tSource addresses selection rule applied:\n");
516125483Sume	for (i = 0; i < 16; i++) {
517125483Sume		if (ip6stat.ip6s_sources_rule[i])
518160787Syar			printf("\t\t%ju %s\n",
519160787Syar			       (uintmax_t)ip6stat.ip6s_sources_rule[i],
520125483Sume			       srcrule_str[i]);
521125483Sume	}
52254263Sshin#undef p
52362584Sitojun#undef p1a
52454263Sshin}
52554263Sshin
52654263Sshin/*
52754263Sshin * Dump IPv6 per-interface statistics based on RFC 2465.
52854263Sshin */
52954263Sshinvoid
53078314Sassarip6_ifstats(char *ifname)
53154263Sshin{
53254263Sshin	struct in6_ifreq ifr;
53354263Sshin	int s;
53454263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
535160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f))
53654263Sshin#define	p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
537160787Syar    printf(m, (uintmax_t)ip6stat.f)
53854263Sshin
53954263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
54054263Sshin		perror("Warning: socket(AF_INET6)");
54154263Sshin		return;
54254263Sshin	}
54354263Sshin
54454263Sshin	strcpy(ifr.ifr_name, ifname);
54554263Sshin	printf("ip6 on %s:\n", ifr.ifr_name);
54654263Sshin
54754263Sshin	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
54854263Sshin		perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
54954263Sshin		goto end;
55054263Sshin	}
55154263Sshin
552160787Syar	p(ifs6_in_receive, "\t%ju total input datagram%s\n");
553160787Syar	p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n");
554160787Syar	p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n");
555160787Syar	p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n");
556160787Syar	p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n");
557160787Syar	p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n");
558160787Syar	p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n");
559160787Syar	p(ifs6_in_discard, "\t%ju input datagram%s discarded\n");
56054263Sshin	p(ifs6_in_deliver,
561160787Syar	  "\t%ju datagram%s delivered to an upper layer protocol\n");
562160787Syar	p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n");
56354263Sshin	p(ifs6_out_request,
564160787Syar	  "\t%ju datagram%s sent from an upper layer protocol\n");
565160787Syar	p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n");
566160787Syar	p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n");
567160787Syar	p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n");
568160787Syar	p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n");
569160787Syar	p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n");
570160787Syar	p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n");
571160787Syar	p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n");
572160787Syar	p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n");
573160787Syar	p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n");
57454263Sshin
57554263Sshin  end:
57654263Sshin	close(s);
57754263Sshin
57854263Sshin#undef p
57954263Sshin#undef p_5
58054263Sshin}
58154263Sshin
582102975Sdwmalonestatic	const char *icmp6names[] = {
58354263Sshin	"#0",
58454263Sshin	"unreach",
58554263Sshin	"packet too big",
58654263Sshin	"time exceed",
58754263Sshin	"parameter problem",
58854263Sshin	"#5",
58954263Sshin	"#6",
59054263Sshin	"#7",
59154263Sshin	"#8",
59254263Sshin	"#9",
59354263Sshin	"#10",
59454263Sshin	"#11",
59554263Sshin	"#12",
59654263Sshin	"#13",
59754263Sshin	"#14",
59854263Sshin	"#15",
59954263Sshin	"#16",
60054263Sshin	"#17",
60154263Sshin	"#18",
602175061Sobrien	"#19",
60354263Sshin	"#20",
60454263Sshin	"#21",
60554263Sshin	"#22",
60654263Sshin	"#23",
60754263Sshin	"#24",
60854263Sshin	"#25",
60954263Sshin	"#26",
61054263Sshin	"#27",
61154263Sshin	"#28",
612175061Sobrien	"#29",
61354263Sshin	"#30",
61454263Sshin	"#31",
61554263Sshin	"#32",
61654263Sshin	"#33",
61754263Sshin	"#34",
61854263Sshin	"#35",
61954263Sshin	"#36",
62054263Sshin	"#37",
62154263Sshin	"#38",
622175061Sobrien	"#39",
62354263Sshin	"#40",
62454263Sshin	"#41",
62554263Sshin	"#42",
62654263Sshin	"#43",
62754263Sshin	"#44",
62854263Sshin	"#45",
62954263Sshin	"#46",
63054263Sshin	"#47",
63154263Sshin	"#48",
632175061Sobrien	"#49",
63354263Sshin	"#50",
63454263Sshin	"#51",
63554263Sshin	"#52",
63654263Sshin	"#53",
63754263Sshin	"#54",
63854263Sshin	"#55",
63954263Sshin	"#56",
64054263Sshin	"#57",
64154263Sshin	"#58",
642175061Sobrien	"#59",
64354263Sshin	"#60",
64454263Sshin	"#61",
64554263Sshin	"#62",
64654263Sshin	"#63",
64754263Sshin	"#64",
64854263Sshin	"#65",
64954263Sshin	"#66",
65054263Sshin	"#67",
65154263Sshin	"#68",
652175061Sobrien	"#69",
65354263Sshin	"#70",
65454263Sshin	"#71",
65554263Sshin	"#72",
65654263Sshin	"#73",
65754263Sshin	"#74",
65854263Sshin	"#75",
65954263Sshin	"#76",
66054263Sshin	"#77",
66154263Sshin	"#78",
662175061Sobrien	"#79",
66354263Sshin	"#80",
66454263Sshin	"#81",
66554263Sshin	"#82",
66654263Sshin	"#83",
66754263Sshin	"#84",
66854263Sshin	"#85",
66954263Sshin	"#86",
67054263Sshin	"#87",
67154263Sshin	"#88",
672175061Sobrien	"#89",
67354263Sshin	"#80",
67454263Sshin	"#91",
67554263Sshin	"#92",
67654263Sshin	"#93",
67754263Sshin	"#94",
67854263Sshin	"#95",
67954263Sshin	"#96",
68054263Sshin	"#97",
68154263Sshin	"#98",
682175061Sobrien	"#99",
68354263Sshin	"#100",
68454263Sshin	"#101",
68554263Sshin	"#102",
68654263Sshin	"#103",
68754263Sshin	"#104",
68854263Sshin	"#105",
68954263Sshin	"#106",
69054263Sshin	"#107",
69154263Sshin	"#108",
692175061Sobrien	"#109",
69354263Sshin	"#110",
69454263Sshin	"#111",
69554263Sshin	"#112",
69654263Sshin	"#113",
69754263Sshin	"#114",
69854263Sshin	"#115",
69954263Sshin	"#116",
70054263Sshin	"#117",
70154263Sshin	"#118",
702175061Sobrien	"#119",
70354263Sshin	"#120",
70454263Sshin	"#121",
70554263Sshin	"#122",
70654263Sshin	"#123",
70754263Sshin	"#124",
70854263Sshin	"#125",
70954263Sshin	"#126",
71054263Sshin	"#127",
71154263Sshin	"echo",
712175061Sobrien	"echo reply",
71354263Sshin	"multicast listener query",
714191652Sbms	"MLDv1 listener report",
715191652Sbms	"MLDv1 listener done",
71654263Sshin	"router solicitation",
71777565Sdd	"router advertisement",
71854263Sshin	"neighbor solicitation",
71977565Sdd	"neighbor advertisement",
72054263Sshin	"redirect",
72154263Sshin	"router renumbering",
72254263Sshin	"node information request",
72354263Sshin	"node information reply",
72478540Ssumikawa	"inverse neighbor solicitation",
72578540Ssumikawa	"inverse neighbor advertisement",
726191652Sbms	"MLDv2 listener report",
72754263Sshin	"#144",
72854263Sshin	"#145",
72954263Sshin	"#146",
73054263Sshin	"#147",
73154263Sshin	"#148",
732175061Sobrien	"#149",
73354263Sshin	"#150",
73454263Sshin	"#151",
73554263Sshin	"#152",
73654263Sshin	"#153",
73754263Sshin	"#154",
73854263Sshin	"#155",
73954263Sshin	"#156",
74054263Sshin	"#157",
74154263Sshin	"#158",
742175061Sobrien	"#159",
74354263Sshin	"#160",
74454263Sshin	"#161",
74554263Sshin	"#162",
74654263Sshin	"#163",
74754263Sshin	"#164",
74854263Sshin	"#165",
74954263Sshin	"#166",
75054263Sshin	"#167",
75154263Sshin	"#168",
752175061Sobrien	"#169",
75354263Sshin	"#170",
75454263Sshin	"#171",
75554263Sshin	"#172",
75654263Sshin	"#173",
75754263Sshin	"#174",
75854263Sshin	"#175",
75954263Sshin	"#176",
76054263Sshin	"#177",
76154263Sshin	"#178",
762175061Sobrien	"#179",
76354263Sshin	"#180",
76454263Sshin	"#181",
76554263Sshin	"#182",
76654263Sshin	"#183",
76754263Sshin	"#184",
76854263Sshin	"#185",
76954263Sshin	"#186",
77054263Sshin	"#187",
77154263Sshin	"#188",
772175061Sobrien	"#189",
77354263Sshin	"#180",
77454263Sshin	"#191",
77554263Sshin	"#192",
77654263Sshin	"#193",
77754263Sshin	"#194",
77854263Sshin	"#195",
77954263Sshin	"#196",
78054263Sshin	"#197",
78154263Sshin	"#198",
782175061Sobrien	"#199",
78354263Sshin	"#200",
78454263Sshin	"#201",
78554263Sshin	"#202",
78654263Sshin	"#203",
78754263Sshin	"#204",
78854263Sshin	"#205",
78954263Sshin	"#206",
79054263Sshin	"#207",
79154263Sshin	"#208",
792175061Sobrien	"#209",
79354263Sshin	"#210",
79454263Sshin	"#211",
79554263Sshin	"#212",
79654263Sshin	"#213",
79754263Sshin	"#214",
79854263Sshin	"#215",
79954263Sshin	"#216",
80054263Sshin	"#217",
80154263Sshin	"#218",
802175061Sobrien	"#219",
80354263Sshin	"#220",
80454263Sshin	"#221",
80554263Sshin	"#222",
80654263Sshin	"#223",
80754263Sshin	"#224",
80854263Sshin	"#225",
80954263Sshin	"#226",
81054263Sshin	"#227",
81154263Sshin	"#228",
812175061Sobrien	"#229",
81354263Sshin	"#230",
81454263Sshin	"#231",
81554263Sshin	"#232",
81654263Sshin	"#233",
81754263Sshin	"#234",
81854263Sshin	"#235",
81954263Sshin	"#236",
82054263Sshin	"#237",
82154263Sshin	"#238",
822175061Sobrien	"#239",
82354263Sshin	"#240",
82454263Sshin	"#241",
82554263Sshin	"#242",
82654263Sshin	"#243",
82754263Sshin	"#244",
82854263Sshin	"#245",
82954263Sshin	"#246",
83054263Sshin	"#247",
83154263Sshin	"#248",
832175061Sobrien	"#249",
83354263Sshin	"#250",
83454263Sshin	"#251",
83554263Sshin	"#252",
83654263Sshin	"#253",
83754263Sshin	"#254",
83854263Sshin	"#255",
83954263Sshin};
84054263Sshin
84154263Sshin/*
84254263Sshin * Dump ICMP6 statistics.
84354263Sshin */
84454263Sshinvoid
845171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
84654263Sshin{
84754263Sshin	struct icmp6stat icmp6stat;
84895637Smarkm	int i, first;
84978931Sume	size_t len;
85054263Sshin
851171465Sjhb	len = sizeof icmp6stat;
852171465Sjhb	if (live) {
853171465Sjhb		memset(&icmp6stat, 0, len);
854171465Sjhb		if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len,
855171465Sjhb		    NULL, 0) < 0) {
856171465Sjhb			if (errno != ENOENT)
857171465Sjhb				warn("sysctl: net.inet6.icmp6.stats");
858171465Sjhb			return;
859171465Sjhb		}
860171465Sjhb	} else
861171465Sjhb		kread(off, &icmp6stat, len);
86278931Sume
86354263Sshin	printf("%s:\n", name);
86454263Sshin
86554263Sshin#define	p(f, m) if (icmp6stat.f || sflag <= 1) \
866160787Syar    printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
867187134Smaxim#define	p_5(f, m) if (icmp6stat.f || sflag <= 1) \
868187134Smaxim    printf(m, (uintmax_t)icmp6stat.f)
86954263Sshin
870160787Syar	p(icp6s_error, "\t%ju call%s to icmp6_error\n");
87154263Sshin	p(icp6s_canterror,
872160787Syar	    "\t%ju error%s not generated in response to an icmp6 message\n");
87354263Sshin	p(icp6s_toofreq,
874160787Syar	  "\t%ju error%s not generated because of rate limitation\n");
875175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
87678540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
87754263Sshin		if (icmp6stat.icp6s_outhist[i] != 0) {
87854263Sshin			if (first) {
87954263Sshin				printf("\tOutput histogram:\n");
88054263Sshin				first = 0;
88154263Sshin			}
882160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
883160787Syar			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
88454263Sshin		}
88578540Ssumikawa#undef NELEM
886160787Syar	p(icp6s_badcode, "\t%ju message%s with bad code fields\n");
887160787Syar	p(icp6s_tooshort, "\t%ju message%s < minimum length\n");
888160787Syar	p(icp6s_checksum, "\t%ju bad checksum%s\n");
889160787Syar	p(icp6s_badlen, "\t%ju message%s with bad length\n");
890175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
89178540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
89254263Sshin		if (icmp6stat.icp6s_inhist[i] != 0) {
89354263Sshin			if (first) {
89454263Sshin				printf("\tInput histogram:\n");
89554263Sshin				first = 0;
89654263Sshin			}
897160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
898160787Syar			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
89954263Sshin		}
90078540Ssumikawa#undef NELEM
90177565Sdd	printf("\tHistogram of error messages to be generated:\n");
902160787Syar	p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n");
903160787Syar	p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n");
904160787Syar	p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n");
905160787Syar	p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n");
906160787Syar	p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n");
907160787Syar	p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n");
908160787Syar	p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n");
909160787Syar	p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n");
910160787Syar	p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n");
911160787Syar	p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n");
912160787Syar	p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n");
913160787Syar	p_5(icp6s_oredirect, "\t\t%ju redirect\n");
914160787Syar	p_5(icp6s_ounknown, "\t\t%ju unknown\n");
91562584Sitojun
916160787Syar	p(icp6s_reflect, "\t%ju message response%s generated\n");
917160787Syar	p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n");
918160787Syar	p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n");
919160787Syar	p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n");
920160787Syar	p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n");
921160787Syar	p(icp6s_badrs, "\t%ju bad router solicitation message%s\n");
922160787Syar	p(icp6s_badra, "\t%ju bad router advertisement message%s\n");
923160787Syar	p(icp6s_badredirect, "\t%ju bad redirect message%s\n");
924160787Syar	p(icp6s_pmtuchg, "\t%ju path MTU change%s\n");
92554263Sshin#undef p
92654263Sshin#undef p_5
92754263Sshin}
92854263Sshin
92954263Sshin/*
93054263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466.
93154263Sshin */
93254263Sshinvoid
93378314Sassaricmp6_ifstats(char *ifname)
93454263Sshin{
93554263Sshin	struct in6_ifreq ifr;
93654263Sshin	int s;
93754263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
938160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f))
939109234Smtm#define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
940160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
94154263Sshin
94254263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
94354263Sshin		perror("Warning: socket(AF_INET6)");
94454263Sshin		return;
94554263Sshin	}
94654263Sshin
94754263Sshin	strcpy(ifr.ifr_name, ifname);
94854263Sshin	printf("icmp6 on %s:\n", ifr.ifr_name);
94954263Sshin
95054263Sshin	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
95154263Sshin		perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
95254263Sshin		goto end;
95354263Sshin	}
95454263Sshin
955160787Syar	p(ifs6_in_msg, "\t%ju total input message%s\n");
956175061Sobrien	p(ifs6_in_error, "\t%ju total input error message%s\n");
957160787Syar	p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n");
958160787Syar	p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n");
959160787Syar	p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n");
960160787Syar	p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n");
961160787Syar	p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n");
962160787Syar	p(ifs6_in_echo, "\t%ju input echo request%s\n");
963160787Syar	p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n");
964160787Syar	p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n");
965160787Syar	p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n");
966160787Syar	p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n");
967160787Syar	p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n");
968160787Syar	p(ifs6_in_redirect, "\t%ju input redirect%s\n");
969160787Syar	p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n");
970160787Syar	p(ifs6_in_mldreport, "\t%ju input MLD report%s\n");
971160787Syar	p(ifs6_in_mlddone, "\t%ju input MLD done%s\n");
97254263Sshin
973160787Syar	p(ifs6_out_msg, "\t%ju total output message%s\n");
974160787Syar	p(ifs6_out_error, "\t%ju total output error message%s\n");
975160787Syar	p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n");
976160787Syar	p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n");
977160787Syar	p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n");
978160787Syar	p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n");
979160787Syar	p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n");
980160787Syar	p(ifs6_out_echo, "\t%ju output echo request%s\n");
981160787Syar	p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n");
982160787Syar	p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n");
983160787Syar	p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n");
984160787Syar	p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n");
985160787Syar	p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n");
986160787Syar	p(ifs6_out_redirect, "\t%ju output redirect%s\n");
987160787Syar	p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n");
988160787Syar	p(ifs6_out_mldreport, "\t%ju output MLD report%s\n");
989160787Syar	p(ifs6_out_mlddone, "\t%ju output MLD done%s\n");
99054263Sshin
99154263Sshin  end:
99254263Sshin	close(s);
99354263Sshin#undef p
99454263Sshin}
99554263Sshin
99654263Sshin/*
99754263Sshin * Dump PIM statistics structure.
99854263Sshin */
99954263Sshinvoid
1000171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
100154263Sshin{
1002166952Sbms	struct pim6stat pim6stat, zerostat;
1003166952Sbms	size_t len = sizeof pim6stat;
100454263Sshin
1005171465Sjhb	if (live) {
1006171465Sjhb		if (zflag)
1007171465Sjhb			memset(&zerostat, 0, len);
1008171465Sjhb		if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len,
1009171465Sjhb		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
1010171465Sjhb			if (errno != ENOENT)
1011171465Sjhb				warn("sysctl: net.inet6.pim.stats");
1012171465Sjhb			return;
1013171465Sjhb		}
1014171465Sjhb	} else {
1015171465Sjhb		if (off == 0)
1016171465Sjhb			return;
1017171465Sjhb		kread(off, &pim6stat, len);
1018166952Sbms	}
1019171465Sjhb
102054263Sshin	printf("%s:\n", name);
102154263Sshin
102254263Sshin#define	p(f, m) if (pim6stat.f || sflag <= 1) \
1023160787Syar    printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
1024160787Syar	p(pim6s_rcv_total, "\t%ju message%s received\n");
1025160787Syar	p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n");
1026160787Syar	p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n");
1027160787Syar	p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n");
1028160787Syar	p(pim6s_rcv_registers, "\t%ju register%s received\n");
1029160787Syar	p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n");
1030160787Syar	p(pim6s_snd_registers, "\t%ju register%s sent\n");
103154263Sshin#undef p
103254263Sshin}
103354263Sshin
103454263Sshin/*
103578064Sume * Dump raw ip6 statistics structure.
103678064Sume */
103778064Sumevoid
1038171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
103978064Sume{
104078064Sume	struct rip6stat rip6stat;
104178064Sume	u_quad_t delivered;
1042171465Sjhb	size_t len;
104378064Sume
1044171465Sjhb	len = sizeof(rip6stat);
1045171465Sjhb	if (live) {
1046171465Sjhb		if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len,
1047171465Sjhb		    NULL, 0) < 0) {
1048171465Sjhb			if (errno != ENOENT)
1049171465Sjhb				warn("sysctl: net.inet6.ip6.rip6stats");
1050171465Sjhb			return;
1051171465Sjhb		}
1052171465Sjhb	} else
1053171465Sjhb		kread(off, &rip6stat, len);
105478064Sume
105578064Sume	printf("%s:\n", name);
105678064Sume
105778064Sume#define	p(f, m) if (rip6stat.f || sflag <= 1) \
1058160787Syar    printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1059160787Syar	p(rip6s_ipackets, "\t%ju message%s received\n");
1060186498Smaxim	p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n");
1061160787Syar	p(rip6s_badsum, "\t%ju message%s with bad checksum\n");
1062160787Syar	p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n");
106378064Sume	p(rip6s_nosockmcast,
1064160787Syar	    "\t%ju multicast message%s dropped due to no socket\n");
106578064Sume	p(rip6s_fullsock,
1066160787Syar	    "\t%ju message%s dropped due to full socket buffers\n");
106778064Sume	delivered = rip6stat.rip6s_ipackets -
106878064Sume		    rip6stat.rip6s_badsum -
106978064Sume		    rip6stat.rip6s_nosock -
107078064Sume		    rip6stat.rip6s_nosockmcast -
107178064Sume		    rip6stat.rip6s_fullsock;
107278064Sume	if (delivered || sflag <= 1)
1073160787Syar		printf("\t%ju delivered\n", (uintmax_t)delivered);
1074160787Syar	p(rip6s_opackets, "\t%ju datagram%s output\n");
107578064Sume#undef p
107678064Sume}
107778064Sume
107878064Sume/*
107954263Sshin * Pretty print an Internet address (net address + port).
108078238Sassar * Take numeric_addr and numeric_port into consideration.
108154263Sshin */
1082175061Sobrien#define	GETSERVBYPORT6(port, proto, ret)\
108354263Sshin{\
108454263Sshin	if (strcmp((proto), "tcp6") == 0)\
108554263Sshin		(ret) = getservbyport((int)(port), "tcp");\
108654263Sshin	else if (strcmp((proto), "udp6") == 0)\
108754263Sshin		(ret) = getservbyport((int)(port), "udp");\
108854263Sshin	else\
108954263Sshin		(ret) = getservbyport((int)(port), (proto));\
109054263Sshin};
109154263Sshin
109254263Sshinvoid
1093102975Sdwmaloneinet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
109454263Sshin{
109554263Sshin	struct servent *sp = 0;
109654263Sshin	char line[80], *cp;
109754263Sshin	int width;
109854263Sshin
109983200Sru	sprintf(line, "%.*s.", Wflag ? 39 :
110054263Sshin		(Aflag && !numeric) ? 12 : 16, inet6name(in6));
110154263Sshin	cp = index(line, '\0');
110254263Sshin	if (!numeric && port)
110354263Sshin		GETSERVBYPORT6(port, proto, sp);
110454263Sshin	if (sp || port == 0)
1105177352Sume		sprintf(cp, "%.15s", sp ? sp->s_name : "*");
110654263Sshin	else
110754263Sshin		sprintf(cp, "%d", ntohs((u_short)port));
110883200Sru	width = Wflag ? 45 : Aflag ? 18 : 22;
110955533Sshin	printf("%-*.*s ", width, width, line);
111054263Sshin}
111154263Sshin
111254263Sshin/*
111354263Sshin * Construct an Internet address representation.
111478238Sassar * If the numeric_addr has been supplied, give
111554263Sshin * numeric value, otherwise try for symbolic name.
111654263Sshin */
111754263Sshin
111854263Sshinchar *
111978314Sassarinet6name(struct in6_addr *in6p)
112054263Sshin{
1121102975Sdwmalone	char *cp;
112254263Sshin	static char line[50];
112354263Sshin	struct hostent *hp;
112474262Sbrian	static char domain[MAXHOSTNAMELEN];
112554263Sshin	static int first = 1;
112654263Sshin
112778238Sassar	if (first && !numeric_addr) {
112854263Sshin		first = 0;
112954263Sshin		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
113054263Sshin		    (cp = index(domain, '.')))
113154263Sshin			(void) strcpy(domain, cp + 1);
113254263Sshin		else
113354263Sshin			domain[0] = 0;
113454263Sshin	}
113554263Sshin	cp = 0;
113678238Sassar	if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
113754263Sshin		hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
113854263Sshin		if (hp) {
113954263Sshin			if ((cp = index(hp->h_name, '.')) &&
114054263Sshin			    !strcmp(cp + 1, domain))
114154263Sshin				*cp = 0;
114254263Sshin			cp = hp->h_name;
114354263Sshin		}
114454263Sshin	}
114554263Sshin	if (IN6_IS_ADDR_UNSPECIFIED(in6p))
114654263Sshin		strcpy(line, "*");
114754263Sshin	else if (cp)
114854263Sshin		strcpy(line, cp);
1149175061Sobrien	else
115054263Sshin		sprintf(line, "%s",
115154263Sshin			inet_ntop(AF_INET6, (void *)in6p, ntop_buf,
115254263Sshin				sizeof(ntop_buf)));
115354263Sshin	return (line);
115454263Sshin}
115564342Sume#endif /*INET6*/
1156