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 * 4. Neither the name of the University nor the names of its contributors
1554263Sshin *    may be used to endorse or promote products derived from this software
1654263Sshin *    without specific prior written permission.
1754263Sshin *
1854263Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1954263Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2054263Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2154263Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2254263Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2354263Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2454263Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2554263Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2654263Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2754263Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2854263Sshin * SUCH DAMAGE.
2954263Sshin */
3054263Sshin
31132671Scharnier#if 0
3254263Sshin#ifndef lint
3354263Sshinstatic char sccsid[] = "@(#)inet6.c	8.4 (Berkeley) 4/20/94";
3454263Sshin#endif /* not lint */
35132671Scharnier#endif
3654263Sshin
37132671Scharnier#include <sys/cdefs.h>
38132671Scharnier__FBSDID("$FreeBSD$");
39132671Scharnier
4064342Sume#ifdef INET6
4154263Sshin#include <sys/param.h>
4254263Sshin#include <sys/socket.h>
4354263Sshin#include <sys/socketvar.h>
4454263Sshin#include <sys/ioctl.h>
4554263Sshin#include <sys/mbuf.h>
4654263Sshin#include <sys/protosw.h>
4778064Sume#include <sys/sysctl.h>
4854263Sshin
4954263Sshin#include <net/route.h>
5054263Sshin#include <net/if.h>
5154263Sshin#include <net/if_var.h>
5254263Sshin#include <netinet/in.h>
5354263Sshin#include <netinet/ip6.h>
5454263Sshin#include <netinet/icmp6.h>
5554263Sshin#include <netinet/in_systm.h>
5654263Sshin#include <netinet6/in6_pcb.h>
5754263Sshin#include <netinet6/in6_var.h>
5854263Sshin#include <netinet6/ip6_var.h>
5954263Sshin#include <netinet6/pim6_var.h>
6078064Sume#include <netinet6/raw_ip6.h>
6154263Sshin
6254263Sshin#include <arpa/inet.h>
6354263Sshin#include <netdb.h>
6454263Sshin
65166952Sbms#include <err.h>
66160787Syar#include <stdint.h>
6754263Sshin#include <stdio.h>
68160373Sjulian#include <errno.h>
6954263Sshin#include <string.h>
7054263Sshin#include <unistd.h>
7154263Sshin#include "netstat.h"
7254263Sshin
7354263Sshinstruct	socket sockb;
7454263Sshin
75132671Scharnierchar	*inet6name(struct in6_addr *);
7654263Sshin
7754263Sshinstatic char ntop_buf[INET6_ADDRSTRLEN];
7854263Sshin
79102975Sdwmalonestatic	const char *ip6nh[] = {
8054263Sshin	"hop by hop",
8154263Sshin	"ICMP",
8254263Sshin	"IGMP",
8354263Sshin	"#3",
8454263Sshin	"IP",
8554263Sshin	"#5",
8654263Sshin	"TCP",
8754263Sshin	"#7",
8854263Sshin	"#8",
8954263Sshin	"#9",
9054263Sshin	"#10",
9154263Sshin	"#11",
9254263Sshin	"#12",
9354263Sshin	"#13",
9454263Sshin	"#14",
9554263Sshin	"#15",
9654263Sshin	"#16",
9754263Sshin	"UDP",
9854263Sshin	"#18",
99175061Sobrien	"#19",
10054263Sshin	"#20",
10154263Sshin	"#21",
10254263Sshin	"IDP",
10354263Sshin	"#23",
10454263Sshin	"#24",
10554263Sshin	"#25",
10654263Sshin	"#26",
10754263Sshin	"#27",
10854263Sshin	"#28",
109175061Sobrien	"TP",
11054263Sshin	"#30",
11154263Sshin	"#31",
11254263Sshin	"#32",
11354263Sshin	"#33",
11454263Sshin	"#34",
11554263Sshin	"#35",
11654263Sshin	"#36",
11754263Sshin	"#37",
11854263Sshin	"#38",
119175061Sobrien	"#39",
12054263Sshin	"#40",
12154263Sshin	"IP6",
12254263Sshin	"#42",
12354263Sshin	"routing",
12454263Sshin	"fragment",
12554263Sshin	"#45",
12654263Sshin	"#46",
12754263Sshin	"#47",
12854263Sshin	"#48",
129175061Sobrien	"#49",
13054263Sshin	"ESP",
13154263Sshin	"AH",
13254263Sshin	"#52",
13354263Sshin	"#53",
13454263Sshin	"#54",
13554263Sshin	"#55",
13654263Sshin	"#56",
13754263Sshin	"#57",
13854263Sshin	"ICMP6",
139175061Sobrien	"no next header",
14054263Sshin	"destination option",
14154263Sshin	"#61",
142125482Sume	"mobility",
14354263Sshin	"#63",
14454263Sshin	"#64",
14554263Sshin	"#65",
14654263Sshin	"#66",
14754263Sshin	"#67",
14854263Sshin	"#68",
149175061Sobrien	"#69",
15054263Sshin	"#70",
15154263Sshin	"#71",
15254263Sshin	"#72",
15354263Sshin	"#73",
15454263Sshin	"#74",
15554263Sshin	"#75",
15654263Sshin	"#76",
15754263Sshin	"#77",
15854263Sshin	"#78",
159175061Sobrien	"#79",
16054263Sshin	"ISOIP",
16154263Sshin	"#81",
16254263Sshin	"#82",
16354263Sshin	"#83",
16454263Sshin	"#84",
16554263Sshin	"#85",
16654263Sshin	"#86",
16754263Sshin	"#87",
16854263Sshin	"#88",
169175061Sobrien	"OSPF",
17054263Sshin	"#80",
17154263Sshin	"#91",
17254263Sshin	"#92",
17354263Sshin	"#93",
17454263Sshin	"#94",
17554263Sshin	"#95",
17654263Sshin	"#96",
17754263Sshin	"Ethernet",
17854263Sshin	"#98",
179175061Sobrien	"#99",
18054263Sshin	"#100",
18154263Sshin	"#101",
18254263Sshin	"#102",
18354263Sshin	"PIM",
18454263Sshin	"#104",
18554263Sshin	"#105",
18654263Sshin	"#106",
18754263Sshin	"#107",
18854263Sshin	"#108",
189175061Sobrien	"#109",
19054263Sshin	"#110",
19154263Sshin	"#111",
19254263Sshin	"#112",
19354263Sshin	"#113",
19454263Sshin	"#114",
19554263Sshin	"#115",
19654263Sshin	"#116",
19754263Sshin	"#117",
19854263Sshin	"#118",
199175061Sobrien	"#119",
20054263Sshin	"#120",
20154263Sshin	"#121",
20254263Sshin	"#122",
20354263Sshin	"#123",
20454263Sshin	"#124",
20554263Sshin	"#125",
20654263Sshin	"#126",
20754263Sshin	"#127",
20854263Sshin	"#128",
209175061Sobrien	"#129",
21054263Sshin	"#130",
21154263Sshin	"#131",
21254263Sshin	"#132",
21354263Sshin	"#133",
21454263Sshin	"#134",
21554263Sshin	"#135",
21654263Sshin	"#136",
21754263Sshin	"#137",
21854263Sshin	"#138",
219175061Sobrien	"#139",
22054263Sshin	"#140",
22154263Sshin	"#141",
22254263Sshin	"#142",
22354263Sshin	"#143",
22454263Sshin	"#144",
22554263Sshin	"#145",
22654263Sshin	"#146",
22754263Sshin	"#147",
22854263Sshin	"#148",
229175061Sobrien	"#149",
23054263Sshin	"#150",
23154263Sshin	"#151",
23254263Sshin	"#152",
23354263Sshin	"#153",
23454263Sshin	"#154",
23554263Sshin	"#155",
23654263Sshin	"#156",
23754263Sshin	"#157",
23854263Sshin	"#158",
239175061Sobrien	"#159",
24054263Sshin	"#160",
24154263Sshin	"#161",
24254263Sshin	"#162",
24354263Sshin	"#163",
24454263Sshin	"#164",
24554263Sshin	"#165",
24654263Sshin	"#166",
24754263Sshin	"#167",
24854263Sshin	"#168",
249175061Sobrien	"#169",
25054263Sshin	"#170",
25154263Sshin	"#171",
25254263Sshin	"#172",
25354263Sshin	"#173",
25454263Sshin	"#174",
25554263Sshin	"#175",
25654263Sshin	"#176",
25754263Sshin	"#177",
25854263Sshin	"#178",
259175061Sobrien	"#179",
26054263Sshin	"#180",
26154263Sshin	"#181",
26254263Sshin	"#182",
26354263Sshin	"#183",
26454263Sshin	"#184",
26554263Sshin	"#185",
26654263Sshin	"#186",
26754263Sshin	"#187",
26854263Sshin	"#188",
269175061Sobrien	"#189",
27054263Sshin	"#180",
27154263Sshin	"#191",
27254263Sshin	"#192",
27354263Sshin	"#193",
27454263Sshin	"#194",
27554263Sshin	"#195",
27654263Sshin	"#196",
27754263Sshin	"#197",
27854263Sshin	"#198",
279175061Sobrien	"#199",
28054263Sshin	"#200",
28154263Sshin	"#201",
28254263Sshin	"#202",
28354263Sshin	"#203",
28454263Sshin	"#204",
28554263Sshin	"#205",
28654263Sshin	"#206",
28754263Sshin	"#207",
28854263Sshin	"#208",
289175061Sobrien	"#209",
29054263Sshin	"#210",
29154263Sshin	"#211",
29254263Sshin	"#212",
29354263Sshin	"#213",
29454263Sshin	"#214",
29554263Sshin	"#215",
29654263Sshin	"#216",
29754263Sshin	"#217",
29854263Sshin	"#218",
299175061Sobrien	"#219",
30054263Sshin	"#220",
30154263Sshin	"#221",
30254263Sshin	"#222",
30354263Sshin	"#223",
30454263Sshin	"#224",
30554263Sshin	"#225",
30654263Sshin	"#226",
30754263Sshin	"#227",
30854263Sshin	"#228",
309175061Sobrien	"#229",
31054263Sshin	"#230",
31154263Sshin	"#231",
31254263Sshin	"#232",
31354263Sshin	"#233",
31454263Sshin	"#234",
31554263Sshin	"#235",
31654263Sshin	"#236",
31754263Sshin	"#237",
31854263Sshin	"#238",
319175061Sobrien	"#239",
32054263Sshin	"#240",
32154263Sshin	"#241",
32254263Sshin	"#242",
32354263Sshin	"#243",
32454263Sshin	"#244",
32554263Sshin	"#245",
32654263Sshin	"#246",
32754263Sshin	"#247",
32854263Sshin	"#248",
329175061Sobrien	"#249",
33054263Sshin	"#250",
33154263Sshin	"#251",
33254263Sshin	"#252",
33354263Sshin	"#253",
33454263Sshin	"#254",
33554263Sshin	"#255",
33654263Sshin};
33754263Sshin
338246988Scharnierstatic const char *srcrule_str[] = {
339125483Sume	"first candidate",
340125483Sume	"same address",
341125483Sume	"appropriate scope",
342125483Sume	"deprecated address",
343125483Sume	"home address",
344125483Sume	"outgoing interface",
345125483Sume	"matching label",
346125483Sume	"public/temporary address",
347125483Sume	"alive interface",
348125483Sume	"preferred interface",
349125483Sume	"rule #10",
350125483Sume	"rule #11",
351125483Sume	"rule #12",
352125483Sume	"rule #13",
353125483Sume	"longest match",
354125483Sume	"rule #15",
355125483Sume};
356125483Sume
35754263Sshin/*
35854263Sshin * Dump IP6 statistics structure.
35954263Sshin */
36054263Sshinvoid
361171465Sjhbip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
36254263Sshin{
363228700Smaxim	struct ip6stat ip6stat, zerostat;
36454263Sshin	int first, i;
36578931Sume	size_t len;
36654263Sshin
367171465Sjhb	len = sizeof ip6stat;
368171465Sjhb	if (live) {
369171465Sjhb		memset(&ip6stat, 0, len);
370228700Smaxim		if (zflag)
371228700Smaxim			memset(&zerostat, 0, len);
372228700Smaxim		if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len,
373228700Smaxim		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
374171465Sjhb			if (errno != ENOENT)
375171465Sjhb				warn("sysctl: net.inet6.ip6.stats");
376171465Sjhb			return;
377171465Sjhb		}
378171465Sjhb	} else
379253085Sae		kread_counters(off, &ip6stat, len);
38054263Sshin
38154263Sshin	printf("%s:\n", name);
38254263Sshin
38354263Sshin#define	p(f, m) if (ip6stat.f || sflag <= 1) \
384160787Syar    printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
38554263Sshin#define	p1a(f, m) if (ip6stat.f || sflag <= 1) \
386160787Syar    printf(m, (uintmax_t)ip6stat.f)
38754263Sshin
388160787Syar	p(ip6s_total, "\t%ju total packet%s received\n");
389160787Syar	p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n");
390160787Syar	p1a(ip6s_tooshort, "\t%ju with data size < data length\n");
391160787Syar	p1a(ip6s_badoptions, "\t%ju with bad options\n");
392160787Syar	p1a(ip6s_badvers, "\t%ju with incorrect version number\n");
393160787Syar	p(ip6s_fragments, "\t%ju fragment%s received\n");
394160787Syar	p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n");
395160787Syar	p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n");
396160787Syar	p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n");
397160787Syar	p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n");
398160787Syar	p(ip6s_delivered, "\t%ju packet%s for this host\n");
399160787Syar	p(ip6s_forward, "\t%ju packet%s forwarded\n");
400160787Syar	p(ip6s_cantforward, "\t%ju packet%s not forwardable\n");
401160787Syar	p(ip6s_redirectsent, "\t%ju redirect%s sent\n");
402160787Syar	p(ip6s_localout, "\t%ju packet%s sent from this host\n");
403160787Syar	p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n");
404160787Syar	p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n");
405160787Syar	p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n");
406160787Syar	p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n");
407160787Syar	p(ip6s_ofragments, "\t%ju fragment%s created\n");
408160787Syar	p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n");
409160787Syar	p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n");
410160787Syar	p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n");
411249545Sae	for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
41254263Sshin		if (ip6stat.ip6s_nxthist[i] != 0) {
41354263Sshin			if (first) {
41454263Sshin				printf("\tInput histogram:\n");
41554263Sshin				first = 0;
41654263Sshin			}
417160787Syar			printf("\t\t%s: %ju\n", ip6nh[i],
418160787Syar			    (uintmax_t)ip6stat.ip6s_nxthist[i]);
41954263Sshin		}
42054263Sshin	printf("\tMbuf statistics:\n");
421160787Syar	printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1);
422249545Sae	for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
42355163Sshin		char ifbuf[IFNAMSIZ];
424175061Sobrien		if (ip6stat.ip6s_m2m[i] != 0) {
42554263Sshin			if (first) {
42654263Sshin				printf("\t\ttwo or more mbuf:\n");
42754263Sshin				first = 0;
42854263Sshin			}
429160787Syar			printf("\t\t\t%s= %ju\n",
43062584Sitojun			    if_indextoname(i, ifbuf),
431160787Syar			    (uintmax_t)ip6stat.ip6s_m2m[i]);
43254263Sshin		}
43354263Sshin	}
434160787Syar	printf("\t\t%ju one ext mbuf\n",
435160787Syar	    (uintmax_t)ip6stat.ip6s_mext1);
436160787Syar	printf("\t\t%ju two or more ext mbuf\n",
437175061Sobrien	    (uintmax_t)ip6stat.ip6s_mext2m);
43862584Sitojun	p(ip6s_exthdrtoolong,
439215955Sbrucec	    "\t%ju packet%s whose headers are not contiguous\n");
440160787Syar	p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n");
44162584Sitojun	p(ip6s_toomanyhdr,
442160787Syar	    "\t%ju packet%s discarded because of too many headers\n");
44362584Sitojun
44462584Sitojun	/* for debugging source address selection */
445175061Sobrien#define	PRINT_SCOPESTAT(s,i) do {\
44662584Sitojun		switch(i) { /* XXX hardcoding in each case */\
44762584Sitojun		case 1:\
448249545Sae			p(s, "\t\t%ju interface-local%s\n");\
44962584Sitojun			break;\
45062584Sitojun		case 2:\
451160787Syar			p(s,"\t\t%ju link-local%s\n");\
45262584Sitojun			break;\
45362584Sitojun		case 5:\
454160787Syar			p(s,"\t\t%ju site-local%s\n");\
45562584Sitojun			break;\
45662584Sitojun		case 14:\
457160787Syar			p(s,"\t\t%ju global%s\n");\
45862584Sitojun			break;\
45962584Sitojun		default:\
460160787Syar			printf("\t\t%ju addresses scope=%x\n",\
461160787Syar			    (uintmax_t)ip6stat.s, i);\
46262584Sitojun		}\
46362584Sitojun	} while (0);
46462584Sitojun
46562584Sitojun	p(ip6s_sources_none,
466160787Syar	  "\t%ju failure%s of source address selection\n");
467249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
46862584Sitojun		if (ip6stat.ip6s_sources_sameif[i]) {
46962584Sitojun			if (first) {
47062584Sitojun				printf("\tsource addresses on an outgoing I/F\n");
47162584Sitojun				first = 0;
47262584Sitojun			}
47362584Sitojun			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
47462584Sitojun		}
47562584Sitojun	}
476249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
47762584Sitojun		if (ip6stat.ip6s_sources_otherif[i]) {
47862584Sitojun			if (first) {
47962584Sitojun				printf("\tsource addresses on a non-outgoing I/F\n");
48062584Sitojun				first = 0;
48162584Sitojun			}
48262584Sitojun			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
48362584Sitojun		}
48462584Sitojun	}
485249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
48662584Sitojun		if (ip6stat.ip6s_sources_samescope[i]) {
48762584Sitojun			if (first) {
48862584Sitojun				printf("\tsource addresses of same scope\n");
48962584Sitojun				first = 0;
49062584Sitojun			}
49162584Sitojun			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
49262584Sitojun		}
49362584Sitojun	}
494249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
49562584Sitojun		if (ip6stat.ip6s_sources_otherscope[i]) {
49662584Sitojun			if (first) {
49762584Sitojun				printf("\tsource addresses of a different scope\n");
49862584Sitojun				first = 0;
49962584Sitojun			}
50062584Sitojun			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
50162584Sitojun		}
50262584Sitojun	}
503249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
50462584Sitojun		if (ip6stat.ip6s_sources_deprecated[i]) {
50562584Sitojun			if (first) {
50662584Sitojun				printf("\tdeprecated source addresses\n");
50762584Sitojun				first = 0;
50862584Sitojun			}
50962584Sitojun			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
51062584Sitojun		}
51162584Sitojun	}
51262584Sitojun
513125483Sume	printf("\tSource addresses selection rule applied:\n");
514249545Sae	for (i = 0; i < IP6S_RULESMAX; i++) {
515125483Sume		if (ip6stat.ip6s_sources_rule[i])
516160787Syar			printf("\t\t%ju %s\n",
517160787Syar			       (uintmax_t)ip6stat.ip6s_sources_rule[i],
518125483Sume			       srcrule_str[i]);
519125483Sume	}
52054263Sshin#undef p
52162584Sitojun#undef p1a
52254263Sshin}
52354263Sshin
52454263Sshin/*
52554263Sshin * Dump IPv6 per-interface statistics based on RFC 2465.
52654263Sshin */
52754263Sshinvoid
52878314Sassarip6_ifstats(char *ifname)
52954263Sshin{
53054263Sshin	struct in6_ifreq ifr;
53154263Sshin	int s;
53254263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
533160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f))
53454263Sshin#define	p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
535160787Syar    printf(m, (uintmax_t)ip6stat.f)
53654263Sshin
53754263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
53854263Sshin		perror("Warning: socket(AF_INET6)");
53954263Sshin		return;
54054263Sshin	}
54154263Sshin
54254263Sshin	strcpy(ifr.ifr_name, ifname);
54354263Sshin	printf("ip6 on %s:\n", ifr.ifr_name);
54454263Sshin
54554263Sshin	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
54654263Sshin		perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
54754263Sshin		goto end;
54854263Sshin	}
54954263Sshin
550160787Syar	p(ifs6_in_receive, "\t%ju total input datagram%s\n");
551160787Syar	p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n");
552160787Syar	p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n");
553160787Syar	p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n");
554160787Syar	p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n");
555160787Syar	p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n");
556160787Syar	p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n");
557160787Syar	p(ifs6_in_discard, "\t%ju input datagram%s discarded\n");
55854263Sshin	p(ifs6_in_deliver,
559160787Syar	  "\t%ju datagram%s delivered to an upper layer protocol\n");
560160787Syar	p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n");
56154263Sshin	p(ifs6_out_request,
562160787Syar	  "\t%ju datagram%s sent from an upper layer protocol\n");
563160787Syar	p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n");
564160787Syar	p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n");
565160787Syar	p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n");
566160787Syar	p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n");
567160787Syar	p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n");
568160787Syar	p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n");
569160787Syar	p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n");
570160787Syar	p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n");
571160787Syar	p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n");
57254263Sshin
57354263Sshin  end:
57454263Sshin	close(s);
57554263Sshin
57654263Sshin#undef p
57754263Sshin#undef p_5
57854263Sshin}
57954263Sshin
580102975Sdwmalonestatic	const char *icmp6names[] = {
58154263Sshin	"#0",
58254263Sshin	"unreach",
58354263Sshin	"packet too big",
58454263Sshin	"time exceed",
58554263Sshin	"parameter problem",
58654263Sshin	"#5",
58754263Sshin	"#6",
58854263Sshin	"#7",
58954263Sshin	"#8",
59054263Sshin	"#9",
59154263Sshin	"#10",
59254263Sshin	"#11",
59354263Sshin	"#12",
59454263Sshin	"#13",
59554263Sshin	"#14",
59654263Sshin	"#15",
59754263Sshin	"#16",
59854263Sshin	"#17",
59954263Sshin	"#18",
600175061Sobrien	"#19",
60154263Sshin	"#20",
60254263Sshin	"#21",
60354263Sshin	"#22",
60454263Sshin	"#23",
60554263Sshin	"#24",
60654263Sshin	"#25",
60754263Sshin	"#26",
60854263Sshin	"#27",
60954263Sshin	"#28",
610175061Sobrien	"#29",
61154263Sshin	"#30",
61254263Sshin	"#31",
61354263Sshin	"#32",
61454263Sshin	"#33",
61554263Sshin	"#34",
61654263Sshin	"#35",
61754263Sshin	"#36",
61854263Sshin	"#37",
61954263Sshin	"#38",
620175061Sobrien	"#39",
62154263Sshin	"#40",
62254263Sshin	"#41",
62354263Sshin	"#42",
62454263Sshin	"#43",
62554263Sshin	"#44",
62654263Sshin	"#45",
62754263Sshin	"#46",
62854263Sshin	"#47",
62954263Sshin	"#48",
630175061Sobrien	"#49",
63154263Sshin	"#50",
63254263Sshin	"#51",
63354263Sshin	"#52",
63454263Sshin	"#53",
63554263Sshin	"#54",
63654263Sshin	"#55",
63754263Sshin	"#56",
63854263Sshin	"#57",
63954263Sshin	"#58",
640175061Sobrien	"#59",
64154263Sshin	"#60",
64254263Sshin	"#61",
64354263Sshin	"#62",
64454263Sshin	"#63",
64554263Sshin	"#64",
64654263Sshin	"#65",
64754263Sshin	"#66",
64854263Sshin	"#67",
64954263Sshin	"#68",
650175061Sobrien	"#69",
65154263Sshin	"#70",
65254263Sshin	"#71",
65354263Sshin	"#72",
65454263Sshin	"#73",
65554263Sshin	"#74",
65654263Sshin	"#75",
65754263Sshin	"#76",
65854263Sshin	"#77",
65954263Sshin	"#78",
660175061Sobrien	"#79",
66154263Sshin	"#80",
66254263Sshin	"#81",
66354263Sshin	"#82",
66454263Sshin	"#83",
66554263Sshin	"#84",
66654263Sshin	"#85",
66754263Sshin	"#86",
66854263Sshin	"#87",
66954263Sshin	"#88",
670175061Sobrien	"#89",
67154263Sshin	"#80",
67254263Sshin	"#91",
67354263Sshin	"#92",
67454263Sshin	"#93",
67554263Sshin	"#94",
67654263Sshin	"#95",
67754263Sshin	"#96",
67854263Sshin	"#97",
67954263Sshin	"#98",
680175061Sobrien	"#99",
68154263Sshin	"#100",
68254263Sshin	"#101",
68354263Sshin	"#102",
68454263Sshin	"#103",
68554263Sshin	"#104",
68654263Sshin	"#105",
68754263Sshin	"#106",
68854263Sshin	"#107",
68954263Sshin	"#108",
690175061Sobrien	"#109",
69154263Sshin	"#110",
69254263Sshin	"#111",
69354263Sshin	"#112",
69454263Sshin	"#113",
69554263Sshin	"#114",
69654263Sshin	"#115",
69754263Sshin	"#116",
69854263Sshin	"#117",
69954263Sshin	"#118",
700175061Sobrien	"#119",
70154263Sshin	"#120",
70254263Sshin	"#121",
70354263Sshin	"#122",
70454263Sshin	"#123",
70554263Sshin	"#124",
70654263Sshin	"#125",
70754263Sshin	"#126",
70854263Sshin	"#127",
70954263Sshin	"echo",
710175061Sobrien	"echo reply",
71154263Sshin	"multicast listener query",
712191652Sbms	"MLDv1 listener report",
713191652Sbms	"MLDv1 listener done",
71454263Sshin	"router solicitation",
71577565Sdd	"router advertisement",
71654263Sshin	"neighbor solicitation",
71777565Sdd	"neighbor advertisement",
71854263Sshin	"redirect",
71954263Sshin	"router renumbering",
72054263Sshin	"node information request",
72154263Sshin	"node information reply",
72278540Ssumikawa	"inverse neighbor solicitation",
72378540Ssumikawa	"inverse neighbor advertisement",
724191652Sbms	"MLDv2 listener report",
72554263Sshin	"#144",
72654263Sshin	"#145",
72754263Sshin	"#146",
72854263Sshin	"#147",
72954263Sshin	"#148",
730175061Sobrien	"#149",
73154263Sshin	"#150",
73254263Sshin	"#151",
73354263Sshin	"#152",
73454263Sshin	"#153",
73554263Sshin	"#154",
73654263Sshin	"#155",
73754263Sshin	"#156",
73854263Sshin	"#157",
73954263Sshin	"#158",
740175061Sobrien	"#159",
74154263Sshin	"#160",
74254263Sshin	"#161",
74354263Sshin	"#162",
74454263Sshin	"#163",
74554263Sshin	"#164",
74654263Sshin	"#165",
74754263Sshin	"#166",
74854263Sshin	"#167",
74954263Sshin	"#168",
750175061Sobrien	"#169",
75154263Sshin	"#170",
75254263Sshin	"#171",
75354263Sshin	"#172",
75454263Sshin	"#173",
75554263Sshin	"#174",
75654263Sshin	"#175",
75754263Sshin	"#176",
75854263Sshin	"#177",
75954263Sshin	"#178",
760175061Sobrien	"#179",
76154263Sshin	"#180",
76254263Sshin	"#181",
76354263Sshin	"#182",
76454263Sshin	"#183",
76554263Sshin	"#184",
76654263Sshin	"#185",
76754263Sshin	"#186",
76854263Sshin	"#187",
76954263Sshin	"#188",
770175061Sobrien	"#189",
77154263Sshin	"#180",
77254263Sshin	"#191",
77354263Sshin	"#192",
77454263Sshin	"#193",
77554263Sshin	"#194",
77654263Sshin	"#195",
77754263Sshin	"#196",
77854263Sshin	"#197",
77954263Sshin	"#198",
780175061Sobrien	"#199",
78154263Sshin	"#200",
78254263Sshin	"#201",
78354263Sshin	"#202",
78454263Sshin	"#203",
78554263Sshin	"#204",
78654263Sshin	"#205",
78754263Sshin	"#206",
78854263Sshin	"#207",
78954263Sshin	"#208",
790175061Sobrien	"#209",
79154263Sshin	"#210",
79254263Sshin	"#211",
79354263Sshin	"#212",
79454263Sshin	"#213",
79554263Sshin	"#214",
79654263Sshin	"#215",
79754263Sshin	"#216",
79854263Sshin	"#217",
79954263Sshin	"#218",
800175061Sobrien	"#219",
80154263Sshin	"#220",
80254263Sshin	"#221",
80354263Sshin	"#222",
80454263Sshin	"#223",
80554263Sshin	"#224",
80654263Sshin	"#225",
80754263Sshin	"#226",
80854263Sshin	"#227",
80954263Sshin	"#228",
810175061Sobrien	"#229",
81154263Sshin	"#230",
81254263Sshin	"#231",
81354263Sshin	"#232",
81454263Sshin	"#233",
81554263Sshin	"#234",
81654263Sshin	"#235",
81754263Sshin	"#236",
81854263Sshin	"#237",
81954263Sshin	"#238",
820175061Sobrien	"#239",
82154263Sshin	"#240",
82254263Sshin	"#241",
82354263Sshin	"#242",
82454263Sshin	"#243",
82554263Sshin	"#244",
82654263Sshin	"#245",
82754263Sshin	"#246",
82854263Sshin	"#247",
82954263Sshin	"#248",
830175061Sobrien	"#249",
83154263Sshin	"#250",
83254263Sshin	"#251",
83354263Sshin	"#252",
83454263Sshin	"#253",
83554263Sshin	"#254",
83654263Sshin	"#255",
83754263Sshin};
83854263Sshin
83954263Sshin/*
84054263Sshin * Dump ICMP6 statistics.
84154263Sshin */
84254263Sshinvoid
843171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
84454263Sshin{
845228700Smaxim	struct icmp6stat icmp6stat, zerostat;
84695637Smarkm	int i, first;
84778931Sume	size_t len;
84854263Sshin
849171465Sjhb	len = sizeof icmp6stat;
850171465Sjhb	if (live) {
851171465Sjhb		memset(&icmp6stat, 0, len);
852228700Smaxim		if (zflag)
853228700Smaxim			memset(&zerostat, 0, len);
854171465Sjhb		if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len,
855228700Smaxim		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
856171465Sjhb			if (errno != ENOENT)
857171465Sjhb				warn("sysctl: net.inet6.icmp6.stats");
858171465Sjhb			return;
859171465Sjhb		}
860171465Sjhb	} else
861253085Sae		kread_counters(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{
1040228700Smaxim	struct rip6stat rip6stat, zerostat;
104178064Sume	u_quad_t delivered;
1042171465Sjhb	size_t len;
104378064Sume
1044171465Sjhb	len = sizeof(rip6stat);
1045171465Sjhb	if (live) {
1046228700Smaxim		if (zflag)
1047228700Smaxim			memset(&zerostat, 0, len);
1048171465Sjhb		if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len,
1049228700Smaxim		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
1050171465Sjhb			if (errno != ENOENT)
1051171465Sjhb				warn("sysctl: net.inet6.ip6.rip6stats");
1052171465Sjhb			return;
1053171465Sjhb		}
1054171465Sjhb	} else
1055253085Sae		kread_counters(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));
1103229403Sed	cp = strchr(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{
1123254459Shrs	struct sockaddr_in6 sin6;
1124254459Shrs	char hbuf[NI_MAXHOST], *cp;
112554263Sshin	static char line[50];
112674262Sbrian	static char domain[MAXHOSTNAMELEN];
112754263Sshin	static int first = 1;
1128254459Shrs	int flags, error;
112954263Sshin
1130254459Shrs	if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1131254459Shrs		strcpy(line, "*");
1132254459Shrs		return (line);
1133254459Shrs	}
113478238Sassar	if (first && !numeric_addr) {
113554263Sshin		first = 0;
113654263Sshin		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1137229403Sed		    (cp = strchr(domain, '.')))
113854263Sshin			(void) strcpy(domain, cp + 1);
113954263Sshin		else
114054263Sshin			domain[0] = 0;
114154263Sshin	}
1142254459Shrs	memset(&sin6, 0, sizeof(sin6));
1143254459Shrs	memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
1144254459Shrs	sin6.sin6_family = AF_INET6;
1145254459Shrs	/* XXX: in6p.s6_addr[2] can contain scopeid. */
1146254459Shrs	in6_fillscopeid(&sin6);
1147254459Shrs	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
1148254459Shrs	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
1149254459Shrs	    sizeof(hbuf), NULL, 0, flags);
1150254459Shrs	if (error == 0) {
1151254459Shrs		if ((flags & NI_NUMERICHOST) == 0 &&
1152254459Shrs		    (cp = strchr(hbuf, '.')) &&
1153254459Shrs		    !strcmp(cp + 1, domain))
1154254459Shrs			*cp = 0;
1155254459Shrs		strcpy(line, hbuf);
1156254459Shrs	} else {
1157254459Shrs		/* XXX: this should not happen. */
115854263Sshin		sprintf(line, "%s",
1159254459Shrs			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
116054263Sshin				sizeof(ntop_buf)));
1161254459Shrs	}
116254263Sshin	return (line);
116354263Sshin}
116464342Sume#endif /*INET6*/
1165