inet6.c revision 187134
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 187134 2009-01-13 07:58:57Z maxim $");
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))
869187134Smaxim#define	p_5(f, m) if (icmp6stat.f || sflag <= 1) \
870187134Smaxim    printf(m, (uintmax_t)icmp6stat.f)
87154263Sshin
872160787Syar	p(icp6s_error, "\t%ju call%s to icmp6_error\n");
87354263Sshin	p(icp6s_canterror,
874160787Syar	    "\t%ju error%s not generated in response to an icmp6 message\n");
87554263Sshin	p(icp6s_toofreq,
876160787Syar	  "\t%ju error%s not generated because of rate limitation\n");
877175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
87878540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
87954263Sshin		if (icmp6stat.icp6s_outhist[i] != 0) {
88054263Sshin			if (first) {
88154263Sshin				printf("\tOutput histogram:\n");
88254263Sshin				first = 0;
88354263Sshin			}
884160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
885160787Syar			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
88654263Sshin		}
88778540Ssumikawa#undef NELEM
888160787Syar	p(icp6s_badcode, "\t%ju message%s with bad code fields\n");
889160787Syar	p(icp6s_tooshort, "\t%ju message%s < minimum length\n");
890160787Syar	p(icp6s_checksum, "\t%ju bad checksum%s\n");
891160787Syar	p(icp6s_badlen, "\t%ju message%s with bad length\n");
892175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
89378540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
89454263Sshin		if (icmp6stat.icp6s_inhist[i] != 0) {
89554263Sshin			if (first) {
89654263Sshin				printf("\tInput histogram:\n");
89754263Sshin				first = 0;
89854263Sshin			}
899160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
900160787Syar			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
90154263Sshin		}
90278540Ssumikawa#undef NELEM
90377565Sdd	printf("\tHistogram of error messages to be generated:\n");
904160787Syar	p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n");
905160787Syar	p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n");
906160787Syar	p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n");
907160787Syar	p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n");
908160787Syar	p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n");
909160787Syar	p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n");
910160787Syar	p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n");
911160787Syar	p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n");
912160787Syar	p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n");
913160787Syar	p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n");
914160787Syar	p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n");
915160787Syar	p_5(icp6s_oredirect, "\t\t%ju redirect\n");
916160787Syar	p_5(icp6s_ounknown, "\t\t%ju unknown\n");
91762584Sitojun
918160787Syar	p(icp6s_reflect, "\t%ju message response%s generated\n");
919160787Syar	p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n");
920160787Syar	p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n");
921160787Syar	p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n");
922160787Syar	p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n");
923160787Syar	p(icp6s_badrs, "\t%ju bad router solicitation message%s\n");
924160787Syar	p(icp6s_badra, "\t%ju bad router advertisement message%s\n");
925160787Syar	p(icp6s_badredirect, "\t%ju bad redirect message%s\n");
926160787Syar	p(icp6s_pmtuchg, "\t%ju path MTU change%s\n");
92754263Sshin#undef p
92854263Sshin#undef p_5
92954263Sshin}
93054263Sshin
93154263Sshin/*
93254263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466.
93354263Sshin */
93454263Sshinvoid
93578314Sassaricmp6_ifstats(char *ifname)
93654263Sshin{
93754263Sshin	struct in6_ifreq ifr;
93854263Sshin	int s;
93954263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
940160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f))
941109234Smtm#define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
942160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
94354263Sshin
94454263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
94554263Sshin		perror("Warning: socket(AF_INET6)");
94654263Sshin		return;
94754263Sshin	}
94854263Sshin
94954263Sshin	strcpy(ifr.ifr_name, ifname);
95054263Sshin	printf("icmp6 on %s:\n", ifr.ifr_name);
95154263Sshin
95254263Sshin	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
95354263Sshin		perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
95454263Sshin		goto end;
95554263Sshin	}
95654263Sshin
957160787Syar	p(ifs6_in_msg, "\t%ju total input message%s\n");
958175061Sobrien	p(ifs6_in_error, "\t%ju total input error message%s\n");
959160787Syar	p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n");
960160787Syar	p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n");
961160787Syar	p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n");
962160787Syar	p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n");
963160787Syar	p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n");
964160787Syar	p(ifs6_in_echo, "\t%ju input echo request%s\n");
965160787Syar	p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n");
966160787Syar	p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n");
967160787Syar	p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n");
968160787Syar	p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n");
969160787Syar	p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n");
970160787Syar	p(ifs6_in_redirect, "\t%ju input redirect%s\n");
971160787Syar	p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n");
972160787Syar	p(ifs6_in_mldreport, "\t%ju input MLD report%s\n");
973160787Syar	p(ifs6_in_mlddone, "\t%ju input MLD done%s\n");
97454263Sshin
975160787Syar	p(ifs6_out_msg, "\t%ju total output message%s\n");
976160787Syar	p(ifs6_out_error, "\t%ju total output error message%s\n");
977160787Syar	p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n");
978160787Syar	p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n");
979160787Syar	p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n");
980160787Syar	p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n");
981160787Syar	p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n");
982160787Syar	p(ifs6_out_echo, "\t%ju output echo request%s\n");
983160787Syar	p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n");
984160787Syar	p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n");
985160787Syar	p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n");
986160787Syar	p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n");
987160787Syar	p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n");
988160787Syar	p(ifs6_out_redirect, "\t%ju output redirect%s\n");
989160787Syar	p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n");
990160787Syar	p(ifs6_out_mldreport, "\t%ju output MLD report%s\n");
991160787Syar	p(ifs6_out_mlddone, "\t%ju output MLD done%s\n");
99254263Sshin
99354263Sshin  end:
99454263Sshin	close(s);
99554263Sshin#undef p
99654263Sshin}
99754263Sshin
99854263Sshin/*
99954263Sshin * Dump PIM statistics structure.
100054263Sshin */
100154263Sshinvoid
1002171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
100354263Sshin{
1004166952Sbms	struct pim6stat pim6stat, zerostat;
1005166952Sbms	size_t len = sizeof pim6stat;
100654263Sshin
1007171465Sjhb	if (live) {
1008171465Sjhb		if (zflag)
1009171465Sjhb			memset(&zerostat, 0, len);
1010171465Sjhb		if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len,
1011171465Sjhb		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
1012171465Sjhb			if (errno != ENOENT)
1013171465Sjhb				warn("sysctl: net.inet6.pim.stats");
1014171465Sjhb			return;
1015171465Sjhb		}
1016171465Sjhb	} else {
1017171465Sjhb		if (off == 0)
1018171465Sjhb			return;
1019171465Sjhb		kread(off, &pim6stat, len);
1020166952Sbms	}
1021171465Sjhb
102254263Sshin	printf("%s:\n", name);
102354263Sshin
102454263Sshin#define	p(f, m) if (pim6stat.f || sflag <= 1) \
1025160787Syar    printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
1026160787Syar	p(pim6s_rcv_total, "\t%ju message%s received\n");
1027160787Syar	p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n");
1028160787Syar	p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n");
1029160787Syar	p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n");
1030160787Syar	p(pim6s_rcv_registers, "\t%ju register%s received\n");
1031160787Syar	p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n");
1032160787Syar	p(pim6s_snd_registers, "\t%ju register%s sent\n");
103354263Sshin#undef p
103454263Sshin}
103554263Sshin
103654263Sshin/*
103778064Sume * Dump raw ip6 statistics structure.
103878064Sume */
103978064Sumevoid
1040171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
104178064Sume{
104278064Sume	struct rip6stat rip6stat;
104378064Sume	u_quad_t delivered;
1044171465Sjhb	size_t len;
104578064Sume
1046171465Sjhb	len = sizeof(rip6stat);
1047171465Sjhb	if (live) {
1048171465Sjhb		if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len,
1049171465Sjhb		    NULL, 0) < 0) {
1050171465Sjhb			if (errno != ENOENT)
1051171465Sjhb				warn("sysctl: net.inet6.ip6.rip6stats");
1052171465Sjhb			return;
1053171465Sjhb		}
1054171465Sjhb	} else
1055171465Sjhb		kread(off, &rip6stat, len);
105678064Sume
105778064Sume	printf("%s:\n", name);
105878064Sume
105978064Sume#define	p(f, m) if (rip6stat.f || sflag <= 1) \
1060160787Syar    printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1061160787Syar	p(rip6s_ipackets, "\t%ju message%s received\n");
1062186498Smaxim	p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n");
1063160787Syar	p(rip6s_badsum, "\t%ju message%s with bad checksum\n");
1064160787Syar	p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n");
106578064Sume	p(rip6s_nosockmcast,
1066160787Syar	    "\t%ju multicast message%s dropped due to no socket\n");
106778064Sume	p(rip6s_fullsock,
1068160787Syar	    "\t%ju message%s dropped due to full socket buffers\n");
106978064Sume	delivered = rip6stat.rip6s_ipackets -
107078064Sume		    rip6stat.rip6s_badsum -
107178064Sume		    rip6stat.rip6s_nosock -
107278064Sume		    rip6stat.rip6s_nosockmcast -
107378064Sume		    rip6stat.rip6s_fullsock;
107478064Sume	if (delivered || sflag <= 1)
1075160787Syar		printf("\t%ju delivered\n", (uintmax_t)delivered);
1076160787Syar	p(rip6s_opackets, "\t%ju datagram%s output\n");
107778064Sume#undef p
107878064Sume}
107978064Sume
108078064Sume/*
108154263Sshin * Pretty print an Internet address (net address + port).
108278238Sassar * Take numeric_addr and numeric_port into consideration.
108354263Sshin */
1084175061Sobrien#define	GETSERVBYPORT6(port, proto, ret)\
108554263Sshin{\
108654263Sshin	if (strcmp((proto), "tcp6") == 0)\
108754263Sshin		(ret) = getservbyport((int)(port), "tcp");\
108854263Sshin	else if (strcmp((proto), "udp6") == 0)\
108954263Sshin		(ret) = getservbyport((int)(port), "udp");\
109054263Sshin	else\
109154263Sshin		(ret) = getservbyport((int)(port), (proto));\
109254263Sshin};
109354263Sshin
109454263Sshinvoid
1095102975Sdwmaloneinet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
109654263Sshin{
109754263Sshin	struct servent *sp = 0;
109854263Sshin	char line[80], *cp;
109954263Sshin	int width;
110054263Sshin
110183200Sru	sprintf(line, "%.*s.", Wflag ? 39 :
110254263Sshin		(Aflag && !numeric) ? 12 : 16, inet6name(in6));
110354263Sshin	cp = index(line, '\0');
110454263Sshin	if (!numeric && port)
110554263Sshin		GETSERVBYPORT6(port, proto, sp);
110654263Sshin	if (sp || port == 0)
1107177352Sume		sprintf(cp, "%.15s", sp ? sp->s_name : "*");
110854263Sshin	else
110954263Sshin		sprintf(cp, "%d", ntohs((u_short)port));
111083200Sru	width = Wflag ? 45 : Aflag ? 18 : 22;
111155533Sshin	printf("%-*.*s ", width, width, line);
111254263Sshin}
111354263Sshin
111454263Sshin/*
111554263Sshin * Construct an Internet address representation.
111678238Sassar * If the numeric_addr has been supplied, give
111754263Sshin * numeric value, otherwise try for symbolic name.
111854263Sshin */
111954263Sshin
112054263Sshinchar *
112178314Sassarinet6name(struct in6_addr *in6p)
112254263Sshin{
1123102975Sdwmalone	char *cp;
112454263Sshin	static char line[50];
112554263Sshin	struct hostent *hp;
112674262Sbrian	static char domain[MAXHOSTNAMELEN];
112754263Sshin	static int first = 1;
112854263Sshin
112978238Sassar	if (first && !numeric_addr) {
113054263Sshin		first = 0;
113154263Sshin		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
113254263Sshin		    (cp = index(domain, '.')))
113354263Sshin			(void) strcpy(domain, cp + 1);
113454263Sshin		else
113554263Sshin			domain[0] = 0;
113654263Sshin	}
113754263Sshin	cp = 0;
113878238Sassar	if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
113954263Sshin		hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
114054263Sshin		if (hp) {
114154263Sshin			if ((cp = index(hp->h_name, '.')) &&
114254263Sshin			    !strcmp(cp + 1, domain))
114354263Sshin				*cp = 0;
114454263Sshin			cp = hp->h_name;
114554263Sshin		}
114654263Sshin	}
114754263Sshin	if (IN6_IS_ADDR_UNSPECIFIED(in6p))
114854263Sshin		strcpy(line, "*");
114954263Sshin	else if (cp)
115054263Sshin		strcpy(line, cp);
1151175061Sobrien	else
115254263Sshin		sprintf(line, "%s",
115354263Sshin			inet_ntop(AF_INET6, (void *)in6p, ntop_buf,
115454263Sshin				sizeof(ntop_buf)));
115554263Sshin	return (line);
115654263Sshin}
115764342Sume#endif /*INET6*/
1158