inet6.c revision 175061
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 175061 2008-01-02 23:26:11Z obrien $");
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,
441160787Syar	    "\t%ju packet%s whose headers are not continuous\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
515160787Syar	p1a(ip6s_forward_cachehit, "\t%ju forward cache hit\n");
516160787Syar	p1a(ip6s_forward_cachemiss, "\t%ju forward cache miss\n");
517125483Sume	printf("\tSource addresses selection rule applied:\n");
518125483Sume	for (i = 0; i < 16; i++) {
519125483Sume		if (ip6stat.ip6s_sources_rule[i])
520160787Syar			printf("\t\t%ju %s\n",
521160787Syar			       (uintmax_t)ip6stat.ip6s_sources_rule[i],
522125483Sume			       srcrule_str[i]);
523125483Sume	}
52454263Sshin#undef p
52562584Sitojun#undef p1a
52654263Sshin}
52754263Sshin
52854263Sshin/*
52954263Sshin * Dump IPv6 per-interface statistics based on RFC 2465.
53054263Sshin */
53154263Sshinvoid
53278314Sassarip6_ifstats(char *ifname)
53354263Sshin{
53454263Sshin	struct in6_ifreq ifr;
53554263Sshin	int s;
53654263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
537160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f))
53854263Sshin#define	p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
539160787Syar    printf(m, (uintmax_t)ip6stat.f)
54054263Sshin
54154263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
54254263Sshin		perror("Warning: socket(AF_INET6)");
54354263Sshin		return;
54454263Sshin	}
54554263Sshin
54654263Sshin	strcpy(ifr.ifr_name, ifname);
54754263Sshin	printf("ip6 on %s:\n", ifr.ifr_name);
54854263Sshin
54954263Sshin	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
55054263Sshin		perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
55154263Sshin		goto end;
55254263Sshin	}
55354263Sshin
554160787Syar	p(ifs6_in_receive, "\t%ju total input datagram%s\n");
555160787Syar	p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n");
556160787Syar	p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n");
557160787Syar	p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n");
558160787Syar	p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n");
559160787Syar	p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n");
560160787Syar	p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n");
561160787Syar	p(ifs6_in_discard, "\t%ju input datagram%s discarded\n");
56254263Sshin	p(ifs6_in_deliver,
563160787Syar	  "\t%ju datagram%s delivered to an upper layer protocol\n");
564160787Syar	p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n");
56554263Sshin	p(ifs6_out_request,
566160787Syar	  "\t%ju datagram%s sent from an upper layer protocol\n");
567160787Syar	p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n");
568160787Syar	p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n");
569160787Syar	p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n");
570160787Syar	p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n");
571160787Syar	p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n");
572160787Syar	p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n");
573160787Syar	p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n");
574160787Syar	p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n");
575160787Syar	p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n");
57654263Sshin
57754263Sshin  end:
57854263Sshin	close(s);
57954263Sshin
58054263Sshin#undef p
58154263Sshin#undef p_5
58254263Sshin}
58354263Sshin
584102975Sdwmalonestatic	const char *icmp6names[] = {
58554263Sshin	"#0",
58654263Sshin	"unreach",
58754263Sshin	"packet too big",
58854263Sshin	"time exceed",
58954263Sshin	"parameter problem",
59054263Sshin	"#5",
59154263Sshin	"#6",
59254263Sshin	"#7",
59354263Sshin	"#8",
59454263Sshin	"#9",
59554263Sshin	"#10",
59654263Sshin	"#11",
59754263Sshin	"#12",
59854263Sshin	"#13",
59954263Sshin	"#14",
60054263Sshin	"#15",
60154263Sshin	"#16",
60254263Sshin	"#17",
60354263Sshin	"#18",
604175061Sobrien	"#19",
60554263Sshin	"#20",
60654263Sshin	"#21",
60754263Sshin	"#22",
60854263Sshin	"#23",
60954263Sshin	"#24",
61054263Sshin	"#25",
61154263Sshin	"#26",
61254263Sshin	"#27",
61354263Sshin	"#28",
614175061Sobrien	"#29",
61554263Sshin	"#30",
61654263Sshin	"#31",
61754263Sshin	"#32",
61854263Sshin	"#33",
61954263Sshin	"#34",
62054263Sshin	"#35",
62154263Sshin	"#36",
62254263Sshin	"#37",
62354263Sshin	"#38",
624175061Sobrien	"#39",
62554263Sshin	"#40",
62654263Sshin	"#41",
62754263Sshin	"#42",
62854263Sshin	"#43",
62954263Sshin	"#44",
63054263Sshin	"#45",
63154263Sshin	"#46",
63254263Sshin	"#47",
63354263Sshin	"#48",
634175061Sobrien	"#49",
63554263Sshin	"#50",
63654263Sshin	"#51",
63754263Sshin	"#52",
63854263Sshin	"#53",
63954263Sshin	"#54",
64054263Sshin	"#55",
64154263Sshin	"#56",
64254263Sshin	"#57",
64354263Sshin	"#58",
644175061Sobrien	"#59",
64554263Sshin	"#60",
64654263Sshin	"#61",
64754263Sshin	"#62",
64854263Sshin	"#63",
64954263Sshin	"#64",
65054263Sshin	"#65",
65154263Sshin	"#66",
65254263Sshin	"#67",
65354263Sshin	"#68",
654175061Sobrien	"#69",
65554263Sshin	"#70",
65654263Sshin	"#71",
65754263Sshin	"#72",
65854263Sshin	"#73",
65954263Sshin	"#74",
66054263Sshin	"#75",
66154263Sshin	"#76",
66254263Sshin	"#77",
66354263Sshin	"#78",
664175061Sobrien	"#79",
66554263Sshin	"#80",
66654263Sshin	"#81",
66754263Sshin	"#82",
66854263Sshin	"#83",
66954263Sshin	"#84",
67054263Sshin	"#85",
67154263Sshin	"#86",
67254263Sshin	"#87",
67354263Sshin	"#88",
674175061Sobrien	"#89",
67554263Sshin	"#80",
67654263Sshin	"#91",
67754263Sshin	"#92",
67854263Sshin	"#93",
67954263Sshin	"#94",
68054263Sshin	"#95",
68154263Sshin	"#96",
68254263Sshin	"#97",
68354263Sshin	"#98",
684175061Sobrien	"#99",
68554263Sshin	"#100",
68654263Sshin	"#101",
68754263Sshin	"#102",
68854263Sshin	"#103",
68954263Sshin	"#104",
69054263Sshin	"#105",
69154263Sshin	"#106",
69254263Sshin	"#107",
69354263Sshin	"#108",
694175061Sobrien	"#109",
69554263Sshin	"#110",
69654263Sshin	"#111",
69754263Sshin	"#112",
69854263Sshin	"#113",
69954263Sshin	"#114",
70054263Sshin	"#115",
70154263Sshin	"#116",
70254263Sshin	"#117",
70354263Sshin	"#118",
704175061Sobrien	"#119",
70554263Sshin	"#120",
70654263Sshin	"#121",
70754263Sshin	"#122",
70854263Sshin	"#123",
70954263Sshin	"#124",
71054263Sshin	"#125",
71154263Sshin	"#126",
71254263Sshin	"#127",
71354263Sshin	"echo",
714175061Sobrien	"echo reply",
71554263Sshin	"multicast listener query",
71654263Sshin	"multicast listener report",
71754263Sshin	"multicast listener done",
71854263Sshin	"router solicitation",
71977565Sdd	"router advertisement",
72054263Sshin	"neighbor solicitation",
72177565Sdd	"neighbor advertisement",
72254263Sshin	"redirect",
72354263Sshin	"router renumbering",
72454263Sshin	"node information request",
72554263Sshin	"node information reply",
72678540Ssumikawa	"inverse neighbor solicitation",
72778540Ssumikawa	"inverse neighbor advertisement",
72854263Sshin	"#143",
72954263Sshin	"#144",
73054263Sshin	"#145",
73154263Sshin	"#146",
73254263Sshin	"#147",
73354263Sshin	"#148",
734175061Sobrien	"#149",
73554263Sshin	"#150",
73654263Sshin	"#151",
73754263Sshin	"#152",
73854263Sshin	"#153",
73954263Sshin	"#154",
74054263Sshin	"#155",
74154263Sshin	"#156",
74254263Sshin	"#157",
74354263Sshin	"#158",
744175061Sobrien	"#159",
74554263Sshin	"#160",
74654263Sshin	"#161",
74754263Sshin	"#162",
74854263Sshin	"#163",
74954263Sshin	"#164",
75054263Sshin	"#165",
75154263Sshin	"#166",
75254263Sshin	"#167",
75354263Sshin	"#168",
754175061Sobrien	"#169",
75554263Sshin	"#170",
75654263Sshin	"#171",
75754263Sshin	"#172",
75854263Sshin	"#173",
75954263Sshin	"#174",
76054263Sshin	"#175",
76154263Sshin	"#176",
76254263Sshin	"#177",
76354263Sshin	"#178",
764175061Sobrien	"#179",
76554263Sshin	"#180",
76654263Sshin	"#181",
76754263Sshin	"#182",
76854263Sshin	"#183",
76954263Sshin	"#184",
77054263Sshin	"#185",
77154263Sshin	"#186",
77254263Sshin	"#187",
77354263Sshin	"#188",
774175061Sobrien	"#189",
77554263Sshin	"#180",
77654263Sshin	"#191",
77754263Sshin	"#192",
77854263Sshin	"#193",
77954263Sshin	"#194",
78054263Sshin	"#195",
78154263Sshin	"#196",
78254263Sshin	"#197",
78354263Sshin	"#198",
784175061Sobrien	"#199",
78554263Sshin	"#200",
78654263Sshin	"#201",
78754263Sshin	"#202",
78854263Sshin	"#203",
78954263Sshin	"#204",
79054263Sshin	"#205",
79154263Sshin	"#206",
79254263Sshin	"#207",
79354263Sshin	"#208",
794175061Sobrien	"#209",
79554263Sshin	"#210",
79654263Sshin	"#211",
79754263Sshin	"#212",
79854263Sshin	"#213",
79954263Sshin	"#214",
80054263Sshin	"#215",
80154263Sshin	"#216",
80254263Sshin	"#217",
80354263Sshin	"#218",
804175061Sobrien	"#219",
80554263Sshin	"#220",
80654263Sshin	"#221",
80754263Sshin	"#222",
80854263Sshin	"#223",
80954263Sshin	"#224",
81054263Sshin	"#225",
81154263Sshin	"#226",
81254263Sshin	"#227",
81354263Sshin	"#228",
814175061Sobrien	"#229",
81554263Sshin	"#230",
81654263Sshin	"#231",
81754263Sshin	"#232",
81854263Sshin	"#233",
81954263Sshin	"#234",
82054263Sshin	"#235",
82154263Sshin	"#236",
82254263Sshin	"#237",
82354263Sshin	"#238",
824175061Sobrien	"#239",
82554263Sshin	"#240",
82654263Sshin	"#241",
82754263Sshin	"#242",
82854263Sshin	"#243",
82954263Sshin	"#244",
83054263Sshin	"#245",
83154263Sshin	"#246",
83254263Sshin	"#247",
83354263Sshin	"#248",
834175061Sobrien	"#249",
83554263Sshin	"#250",
83654263Sshin	"#251",
83754263Sshin	"#252",
83854263Sshin	"#253",
83954263Sshin	"#254",
84054263Sshin	"#255",
84154263Sshin};
84254263Sshin
84354263Sshin/*
84454263Sshin * Dump ICMP6 statistics.
84554263Sshin */
84654263Sshinvoid
847171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
84854263Sshin{
84954263Sshin	struct icmp6stat icmp6stat;
85095637Smarkm	int i, first;
85178931Sume	size_t len;
85254263Sshin
853171465Sjhb	len = sizeof icmp6stat;
854171465Sjhb	if (live) {
855171465Sjhb		memset(&icmp6stat, 0, len);
856171465Sjhb		if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len,
857171465Sjhb		    NULL, 0) < 0) {
858171465Sjhb			if (errno != ENOENT)
859171465Sjhb				warn("sysctl: net.inet6.icmp6.stats");
860171465Sjhb			return;
861171465Sjhb		}
862171465Sjhb	} else
863171465Sjhb		kread(off, &icmp6stat, len);
86478931Sume
86554263Sshin	printf("%s:\n", name);
86654263Sshin
86754263Sshin#define	p(f, m) if (icmp6stat.f || sflag <= 1) \
868160787Syar    printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
869175061Sobrien#define	p_5(f, m) printf(m, (uintmax_t)icmp6stat.f)
87054263Sshin
871160787Syar	p(icp6s_error, "\t%ju call%s to icmp6_error\n");
87254263Sshin	p(icp6s_canterror,
873160787Syar	    "\t%ju error%s not generated in response to an icmp6 message\n");
87454263Sshin	p(icp6s_toofreq,
875160787Syar	  "\t%ju error%s not generated because of rate limitation\n");
876175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
87778540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
87854263Sshin		if (icmp6stat.icp6s_outhist[i] != 0) {
87954263Sshin			if (first) {
88054263Sshin				printf("\tOutput histogram:\n");
88154263Sshin				first = 0;
88254263Sshin			}
883160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
884160787Syar			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
88554263Sshin		}
88678540Ssumikawa#undef NELEM
887160787Syar	p(icp6s_badcode, "\t%ju message%s with bad code fields\n");
888160787Syar	p(icp6s_tooshort, "\t%ju message%s < minimum length\n");
889160787Syar	p(icp6s_checksum, "\t%ju bad checksum%s\n");
890160787Syar	p(icp6s_badlen, "\t%ju message%s with bad length\n");
891175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
89278540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
89354263Sshin		if (icmp6stat.icp6s_inhist[i] != 0) {
89454263Sshin			if (first) {
89554263Sshin				printf("\tInput histogram:\n");
89654263Sshin				first = 0;
89754263Sshin			}
898160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
899160787Syar			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
90054263Sshin		}
90178540Ssumikawa#undef NELEM
90277565Sdd	printf("\tHistogram of error messages to be generated:\n");
903160787Syar	p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n");
904160787Syar	p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n");
905160787Syar	p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n");
906160787Syar	p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n");
907160787Syar	p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n");
908160787Syar	p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n");
909160787Syar	p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n");
910160787Syar	p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n");
911160787Syar	p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n");
912160787Syar	p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n");
913160787Syar	p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n");
914160787Syar	p_5(icp6s_oredirect, "\t\t%ju redirect\n");
915160787Syar	p_5(icp6s_ounknown, "\t\t%ju unknown\n");
91662584Sitojun
917160787Syar	p(icp6s_reflect, "\t%ju message response%s generated\n");
918160787Syar	p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n");
919160787Syar	p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n");
920160787Syar	p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n");
921160787Syar	p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n");
922160787Syar	p(icp6s_badrs, "\t%ju bad router solicitation message%s\n");
923160787Syar	p(icp6s_badra, "\t%ju bad router advertisement message%s\n");
924160787Syar	p(icp6s_badredirect, "\t%ju bad redirect message%s\n");
925160787Syar	p(icp6s_pmtuchg, "\t%ju path MTU change%s\n");
92654263Sshin#undef p
92754263Sshin#undef p_5
92854263Sshin}
92954263Sshin
93054263Sshin/*
93154263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466.
93254263Sshin */
93354263Sshinvoid
93478314Sassaricmp6_ifstats(char *ifname)
93554263Sshin{
93654263Sshin	struct in6_ifreq ifr;
93754263Sshin	int s;
93854263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
939160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f))
940109234Smtm#define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
941160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
94254263Sshin
94354263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
94454263Sshin		perror("Warning: socket(AF_INET6)");
94554263Sshin		return;
94654263Sshin	}
94754263Sshin
94854263Sshin	strcpy(ifr.ifr_name, ifname);
94954263Sshin	printf("icmp6 on %s:\n", ifr.ifr_name);
95054263Sshin
95154263Sshin	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
95254263Sshin		perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
95354263Sshin		goto end;
95454263Sshin	}
95554263Sshin
956160787Syar	p(ifs6_in_msg, "\t%ju total input message%s\n");
957175061Sobrien	p(ifs6_in_error, "\t%ju total input error message%s\n");
958160787Syar	p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n");
959160787Syar	p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n");
960160787Syar	p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n");
961160787Syar	p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n");
962160787Syar	p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n");
963160787Syar	p(ifs6_in_echo, "\t%ju input echo request%s\n");
964160787Syar	p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n");
965160787Syar	p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n");
966160787Syar	p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n");
967160787Syar	p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n");
968160787Syar	p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n");
969160787Syar	p(ifs6_in_redirect, "\t%ju input redirect%s\n");
970160787Syar	p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n");
971160787Syar	p(ifs6_in_mldreport, "\t%ju input MLD report%s\n");
972160787Syar	p(ifs6_in_mlddone, "\t%ju input MLD done%s\n");
97354263Sshin
974160787Syar	p(ifs6_out_msg, "\t%ju total output message%s\n");
975160787Syar	p(ifs6_out_error, "\t%ju total output error message%s\n");
976160787Syar	p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n");
977160787Syar	p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n");
978160787Syar	p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n");
979160787Syar	p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n");
980160787Syar	p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n");
981160787Syar	p(ifs6_out_echo, "\t%ju output echo request%s\n");
982160787Syar	p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n");
983160787Syar	p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n");
984160787Syar	p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n");
985160787Syar	p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n");
986160787Syar	p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n");
987160787Syar	p(ifs6_out_redirect, "\t%ju output redirect%s\n");
988160787Syar	p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n");
989160787Syar	p(ifs6_out_mldreport, "\t%ju output MLD report%s\n");
990160787Syar	p(ifs6_out_mlddone, "\t%ju output MLD done%s\n");
99154263Sshin
99254263Sshin  end:
99354263Sshin	close(s);
99454263Sshin#undef p
99554263Sshin}
99654263Sshin
99754263Sshin/*
99854263Sshin * Dump PIM statistics structure.
99954263Sshin */
100054263Sshinvoid
1001171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
100254263Sshin{
1003166952Sbms	struct pim6stat pim6stat, zerostat;
1004166952Sbms	size_t len = sizeof pim6stat;
100554263Sshin
1006171465Sjhb	if (live) {
1007171465Sjhb		if (zflag)
1008171465Sjhb			memset(&zerostat, 0, len);
1009171465Sjhb		if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len,
1010171465Sjhb		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
1011171465Sjhb			if (errno != ENOENT)
1012171465Sjhb				warn("sysctl: net.inet6.pim.stats");
1013171465Sjhb			return;
1014171465Sjhb		}
1015171465Sjhb	} else {
1016171465Sjhb		if (off == 0)
1017171465Sjhb			return;
1018171465Sjhb		kread(off, &pim6stat, len);
1019166952Sbms	}
1020171465Sjhb
102154263Sshin	printf("%s:\n", name);
102254263Sshin
102354263Sshin#define	p(f, m) if (pim6stat.f || sflag <= 1) \
1024160787Syar    printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
1025160787Syar	p(pim6s_rcv_total, "\t%ju message%s received\n");
1026160787Syar	p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n");
1027160787Syar	p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n");
1028160787Syar	p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n");
1029160787Syar	p(pim6s_rcv_registers, "\t%ju register%s received\n");
1030160787Syar	p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n");
1031160787Syar	p(pim6s_snd_registers, "\t%ju register%s sent\n");
103254263Sshin#undef p
103354263Sshin}
103454263Sshin
103554263Sshin/*
103678064Sume * Dump raw ip6 statistics structure.
103778064Sume */
103878064Sumevoid
1039171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
104078064Sume{
104178064Sume	struct rip6stat rip6stat;
104278064Sume	u_quad_t delivered;
1043171465Sjhb	size_t len;
104478064Sume
1045171465Sjhb	len = sizeof(rip6stat);
1046171465Sjhb	if (live) {
1047171465Sjhb		if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len,
1048171465Sjhb		    NULL, 0) < 0) {
1049171465Sjhb			if (errno != ENOENT)
1050171465Sjhb				warn("sysctl: net.inet6.ip6.rip6stats");
1051171465Sjhb			return;
1052171465Sjhb		}
1053171465Sjhb	} else
1054171465Sjhb		kread(off, &rip6stat, len);
105578064Sume
105678064Sume	printf("%s:\n", name);
105778064Sume
105878064Sume#define	p(f, m) if (rip6stat.f || sflag <= 1) \
1059160787Syar    printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1060160787Syar	p(rip6s_ipackets, "\t%ju message%s received\n");
1061160787Syar	p(rip6s_isum, "\t%ju checksum calcuration%s on inbound\n");
1062160787Syar	p(rip6s_badsum, "\t%ju message%s with bad checksum\n");
1063160787Syar	p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n");
106478064Sume	p(rip6s_nosockmcast,
1065160787Syar	    "\t%ju multicast message%s dropped due to no socket\n");
106678064Sume	p(rip6s_fullsock,
1067160787Syar	    "\t%ju message%s dropped due to full socket buffers\n");
106878064Sume	delivered = rip6stat.rip6s_ipackets -
106978064Sume		    rip6stat.rip6s_badsum -
107078064Sume		    rip6stat.rip6s_nosock -
107178064Sume		    rip6stat.rip6s_nosockmcast -
107278064Sume		    rip6stat.rip6s_fullsock;
107378064Sume	if (delivered || sflag <= 1)
1074160787Syar		printf("\t%ju delivered\n", (uintmax_t)delivered);
1075160787Syar	p(rip6s_opackets, "\t%ju datagram%s output\n");
107678064Sume#undef p
107778064Sume}
107878064Sume
107978064Sume/*
108054263Sshin * Pretty print an Internet address (net address + port).
108178238Sassar * Take numeric_addr and numeric_port into consideration.
108254263Sshin */
1083175061Sobrien#define	GETSERVBYPORT6(port, proto, ret)\
108454263Sshin{\
108554263Sshin	if (strcmp((proto), "tcp6") == 0)\
108654263Sshin		(ret) = getservbyport((int)(port), "tcp");\
108754263Sshin	else if (strcmp((proto), "udp6") == 0)\
108854263Sshin		(ret) = getservbyport((int)(port), "udp");\
108954263Sshin	else\
109054263Sshin		(ret) = getservbyport((int)(port), (proto));\
109154263Sshin};
109254263Sshin
109354263Sshinvoid
1094102975Sdwmaloneinet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
109554263Sshin{
109654263Sshin	struct servent *sp = 0;
109754263Sshin	char line[80], *cp;
109854263Sshin	int width;
109954263Sshin
110083200Sru	sprintf(line, "%.*s.", Wflag ? 39 :
110154263Sshin		(Aflag && !numeric) ? 12 : 16, inet6name(in6));
110254263Sshin	cp = index(line, '\0');
110354263Sshin	if (!numeric && port)
110454263Sshin		GETSERVBYPORT6(port, proto, sp);
110554263Sshin	if (sp || port == 0)
110654263Sshin		sprintf(cp, "%.8s", sp ? sp->s_name : "*");
110754263Sshin	else
110854263Sshin		sprintf(cp, "%d", ntohs((u_short)port));
110983200Sru	width = Wflag ? 45 : Aflag ? 18 : 22;
111055533Sshin	printf("%-*.*s ", width, width, line);
111154263Sshin}
111254263Sshin
111354263Sshin/*
111454263Sshin * Construct an Internet address representation.
111578238Sassar * If the numeric_addr has been supplied, give
111654263Sshin * numeric value, otherwise try for symbolic name.
111754263Sshin */
111854263Sshin
111954263Sshinchar *
112078314Sassarinet6name(struct in6_addr *in6p)
112154263Sshin{
1122102975Sdwmalone	char *cp;
112354263Sshin	static char line[50];
112454263Sshin	struct hostent *hp;
112574262Sbrian	static char domain[MAXHOSTNAMELEN];
112654263Sshin	static int first = 1;
112754263Sshin
112878238Sassar	if (first && !numeric_addr) {
112954263Sshin		first = 0;
113054263Sshin		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
113154263Sshin		    (cp = index(domain, '.')))
113254263Sshin			(void) strcpy(domain, cp + 1);
113354263Sshin		else
113454263Sshin			domain[0] = 0;
113554263Sshin	}
113654263Sshin	cp = 0;
113778238Sassar	if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
113854263Sshin		hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
113954263Sshin		if (hp) {
114054263Sshin			if ((cp = index(hp->h_name, '.')) &&
114154263Sshin			    !strcmp(cp + 1, domain))
114254263Sshin				*cp = 0;
114354263Sshin			cp = hp->h_name;
114454263Sshin		}
114554263Sshin	}
114654263Sshin	if (IN6_IS_ADDR_UNSPECIFIED(in6p))
114754263Sshin		strcpy(line, "*");
114854263Sshin	else if (cp)
114954263Sshin		strcpy(line, cp);
1150175061Sobrien	else
115154263Sshin		sprintf(line, "%s",
115254263Sshin			inet_ntop(AF_INET6, (void *)in6p, ntop_buf,
115354263Sshin				sizeof(ntop_buf)));
115454263Sshin	return (line);
115554263Sshin}
115664342Sume#endif /*INET6*/
1157