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: stable/10/usr.bin/netstat/inet6.c 319260 2017-05-30 22:35:36Z asomers $");
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>
4754263Sshin
4854263Sshin#include <net/route.h>
4954263Sshin#include <net/if.h>
5054263Sshin#include <net/if_var.h>
5154263Sshin#include <netinet/in.h>
5254263Sshin#include <netinet/ip6.h>
5354263Sshin#include <netinet/icmp6.h>
5454263Sshin#include <netinet/in_systm.h>
5554263Sshin#include <netinet6/in6_pcb.h>
5654263Sshin#include <netinet6/in6_var.h>
5754263Sshin#include <netinet6/ip6_var.h>
5854263Sshin#include <netinet6/pim6_var.h>
5978064Sume#include <netinet6/raw_ip6.h>
6054263Sshin
6154263Sshin#include <arpa/inet.h>
6254263Sshin#include <netdb.h>
6354263Sshin
64166952Sbms#include <err.h>
65160787Syar#include <stdint.h>
6654263Sshin#include <stdio.h>
67160373Sjulian#include <errno.h>
6854263Sshin#include <string.h>
6954263Sshin#include <unistd.h>
7054263Sshin#include "netstat.h"
7154263Sshin
7254263Sshinstruct	socket sockb;
7354263Sshin
74132671Scharnierchar	*inet6name(struct in6_addr *);
7554263Sshin
7654263Sshinstatic char ntop_buf[INET6_ADDRSTRLEN];
7754263Sshin
78102975Sdwmalonestatic	const char *ip6nh[] = {
7954263Sshin	"hop by hop",
8054263Sshin	"ICMP",
8154263Sshin	"IGMP",
8254263Sshin	"#3",
8354263Sshin	"IP",
8454263Sshin	"#5",
8554263Sshin	"TCP",
8654263Sshin	"#7",
8754263Sshin	"#8",
8854263Sshin	"#9",
8954263Sshin	"#10",
9054263Sshin	"#11",
9154263Sshin	"#12",
9254263Sshin	"#13",
9354263Sshin	"#14",
9454263Sshin	"#15",
9554263Sshin	"#16",
9654263Sshin	"UDP",
9754263Sshin	"#18",
98175061Sobrien	"#19",
9954263Sshin	"#20",
10054263Sshin	"#21",
10154263Sshin	"IDP",
10254263Sshin	"#23",
10354263Sshin	"#24",
10454263Sshin	"#25",
10554263Sshin	"#26",
10654263Sshin	"#27",
10754263Sshin	"#28",
108175061Sobrien	"TP",
10954263Sshin	"#30",
11054263Sshin	"#31",
11154263Sshin	"#32",
11254263Sshin	"#33",
11354263Sshin	"#34",
11454263Sshin	"#35",
11554263Sshin	"#36",
11654263Sshin	"#37",
11754263Sshin	"#38",
118175061Sobrien	"#39",
11954263Sshin	"#40",
12054263Sshin	"IP6",
12154263Sshin	"#42",
12254263Sshin	"routing",
12354263Sshin	"fragment",
12454263Sshin	"#45",
12554263Sshin	"#46",
12654263Sshin	"#47",
12754263Sshin	"#48",
128175061Sobrien	"#49",
12954263Sshin	"ESP",
13054263Sshin	"AH",
13154263Sshin	"#52",
13254263Sshin	"#53",
13354263Sshin	"#54",
13454263Sshin	"#55",
13554263Sshin	"#56",
13654263Sshin	"#57",
13754263Sshin	"ICMP6",
138175061Sobrien	"no next header",
13954263Sshin	"destination option",
14054263Sshin	"#61",
141125482Sume	"mobility",
14254263Sshin	"#63",
14354263Sshin	"#64",
14454263Sshin	"#65",
14554263Sshin	"#66",
14654263Sshin	"#67",
14754263Sshin	"#68",
148175061Sobrien	"#69",
14954263Sshin	"#70",
15054263Sshin	"#71",
15154263Sshin	"#72",
15254263Sshin	"#73",
15354263Sshin	"#74",
15454263Sshin	"#75",
15554263Sshin	"#76",
15654263Sshin	"#77",
15754263Sshin	"#78",
158175061Sobrien	"#79",
15954263Sshin	"ISOIP",
16054263Sshin	"#81",
16154263Sshin	"#82",
16254263Sshin	"#83",
16354263Sshin	"#84",
16454263Sshin	"#85",
16554263Sshin	"#86",
16654263Sshin	"#87",
16754263Sshin	"#88",
168175061Sobrien	"OSPF",
16954263Sshin	"#80",
17054263Sshin	"#91",
17154263Sshin	"#92",
17254263Sshin	"#93",
17354263Sshin	"#94",
17454263Sshin	"#95",
17554263Sshin	"#96",
17654263Sshin	"Ethernet",
17754263Sshin	"#98",
178175061Sobrien	"#99",
17954263Sshin	"#100",
18054263Sshin	"#101",
18154263Sshin	"#102",
18254263Sshin	"PIM",
18354263Sshin	"#104",
18454263Sshin	"#105",
18554263Sshin	"#106",
18654263Sshin	"#107",
18754263Sshin	"#108",
188175061Sobrien	"#109",
18954263Sshin	"#110",
19054263Sshin	"#111",
19154263Sshin	"#112",
19254263Sshin	"#113",
19354263Sshin	"#114",
19454263Sshin	"#115",
19554263Sshin	"#116",
19654263Sshin	"#117",
19754263Sshin	"#118",
198175061Sobrien	"#119",
19954263Sshin	"#120",
20054263Sshin	"#121",
20154263Sshin	"#122",
20254263Sshin	"#123",
20354263Sshin	"#124",
20454263Sshin	"#125",
20554263Sshin	"#126",
20654263Sshin	"#127",
20754263Sshin	"#128",
208175061Sobrien	"#129",
20954263Sshin	"#130",
21054263Sshin	"#131",
21154263Sshin	"#132",
21254263Sshin	"#133",
21354263Sshin	"#134",
21454263Sshin	"#135",
21554263Sshin	"#136",
21654263Sshin	"#137",
21754263Sshin	"#138",
218175061Sobrien	"#139",
21954263Sshin	"#140",
22054263Sshin	"#141",
22154263Sshin	"#142",
22254263Sshin	"#143",
22354263Sshin	"#144",
22454263Sshin	"#145",
22554263Sshin	"#146",
22654263Sshin	"#147",
22754263Sshin	"#148",
228175061Sobrien	"#149",
22954263Sshin	"#150",
23054263Sshin	"#151",
23154263Sshin	"#152",
23254263Sshin	"#153",
23354263Sshin	"#154",
23454263Sshin	"#155",
23554263Sshin	"#156",
23654263Sshin	"#157",
23754263Sshin	"#158",
238175061Sobrien	"#159",
23954263Sshin	"#160",
24054263Sshin	"#161",
24154263Sshin	"#162",
24254263Sshin	"#163",
24354263Sshin	"#164",
24454263Sshin	"#165",
24554263Sshin	"#166",
24654263Sshin	"#167",
24754263Sshin	"#168",
248175061Sobrien	"#169",
24954263Sshin	"#170",
25054263Sshin	"#171",
25154263Sshin	"#172",
25254263Sshin	"#173",
25354263Sshin	"#174",
25454263Sshin	"#175",
25554263Sshin	"#176",
25654263Sshin	"#177",
25754263Sshin	"#178",
258175061Sobrien	"#179",
25954263Sshin	"#180",
26054263Sshin	"#181",
26154263Sshin	"#182",
26254263Sshin	"#183",
26354263Sshin	"#184",
26454263Sshin	"#185",
26554263Sshin	"#186",
26654263Sshin	"#187",
26754263Sshin	"#188",
268175061Sobrien	"#189",
26954263Sshin	"#180",
27054263Sshin	"#191",
27154263Sshin	"#192",
27254263Sshin	"#193",
27354263Sshin	"#194",
27454263Sshin	"#195",
27554263Sshin	"#196",
27654263Sshin	"#197",
27754263Sshin	"#198",
278175061Sobrien	"#199",
27954263Sshin	"#200",
28054263Sshin	"#201",
28154263Sshin	"#202",
28254263Sshin	"#203",
28354263Sshin	"#204",
28454263Sshin	"#205",
28554263Sshin	"#206",
28654263Sshin	"#207",
28754263Sshin	"#208",
288175061Sobrien	"#209",
28954263Sshin	"#210",
29054263Sshin	"#211",
29154263Sshin	"#212",
29254263Sshin	"#213",
29354263Sshin	"#214",
29454263Sshin	"#215",
29554263Sshin	"#216",
29654263Sshin	"#217",
29754263Sshin	"#218",
298175061Sobrien	"#219",
29954263Sshin	"#220",
30054263Sshin	"#221",
30154263Sshin	"#222",
30254263Sshin	"#223",
30354263Sshin	"#224",
30454263Sshin	"#225",
30554263Sshin	"#226",
30654263Sshin	"#227",
30754263Sshin	"#228",
308175061Sobrien	"#229",
30954263Sshin	"#230",
31054263Sshin	"#231",
31154263Sshin	"#232",
31254263Sshin	"#233",
31354263Sshin	"#234",
31454263Sshin	"#235",
31554263Sshin	"#236",
31654263Sshin	"#237",
31754263Sshin	"#238",
318175061Sobrien	"#239",
31954263Sshin	"#240",
32054263Sshin	"#241",
32154263Sshin	"#242",
32254263Sshin	"#243",
32354263Sshin	"#244",
32454263Sshin	"#245",
32554263Sshin	"#246",
32654263Sshin	"#247",
32754263Sshin	"#248",
328175061Sobrien	"#249",
32954263Sshin	"#250",
33054263Sshin	"#251",
33154263Sshin	"#252",
33254263Sshin	"#253",
33354263Sshin	"#254",
33454263Sshin	"#255",
33554263Sshin};
33654263Sshin
337246988Scharnierstatic const char *srcrule_str[] = {
338125483Sume	"first candidate",
339125483Sume	"same address",
340125483Sume	"appropriate scope",
341125483Sume	"deprecated address",
342125483Sume	"home address",
343125483Sume	"outgoing interface",
344125483Sume	"matching label",
345125483Sume	"public/temporary address",
346125483Sume	"alive interface",
347271288Sae	"better virtual status",
348272790Sae	"preferred source",
349125483Sume	"rule #11",
350125483Sume	"rule #12",
351125483Sume	"rule #13",
352125483Sume	"longest match",
353125483Sume	"rule #15",
354125483Sume};
355125483Sume
35654263Sshin/*
35754263Sshin * Dump IP6 statistics structure.
35854263Sshin */
35954263Sshinvoid
360171465Sjhbip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
36154263Sshin{
362293307Smarkj	struct ip6stat ip6stat;
36354263Sshin	int first, i;
36454263Sshin
365293307Smarkj	if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat,
366293307Smarkj	    sizeof(ip6stat), kread_counters) != 0)
367293307Smarkj		return;
36854263Sshin
36954263Sshin	printf("%s:\n", name);
37054263Sshin
37154263Sshin#define	p(f, m) if (ip6stat.f || sflag <= 1) \
372160787Syar    printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
37354263Sshin#define	p1a(f, m) if (ip6stat.f || sflag <= 1) \
374160787Syar    printf(m, (uintmax_t)ip6stat.f)
37554263Sshin
376160787Syar	p(ip6s_total, "\t%ju total packet%s received\n");
377160787Syar	p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n");
378160787Syar	p1a(ip6s_tooshort, "\t%ju with data size < data length\n");
379160787Syar	p1a(ip6s_badoptions, "\t%ju with bad options\n");
380160787Syar	p1a(ip6s_badvers, "\t%ju with incorrect version number\n");
381160787Syar	p(ip6s_fragments, "\t%ju fragment%s received\n");
382160787Syar	p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n");
383160787Syar	p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n");
384160787Syar	p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n");
385160787Syar	p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n");
386160787Syar	p(ip6s_delivered, "\t%ju packet%s for this host\n");
387160787Syar	p(ip6s_forward, "\t%ju packet%s forwarded\n");
388160787Syar	p(ip6s_cantforward, "\t%ju packet%s not forwardable\n");
389160787Syar	p(ip6s_redirectsent, "\t%ju redirect%s sent\n");
390160787Syar	p(ip6s_localout, "\t%ju packet%s sent from this host\n");
391160787Syar	p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n");
392160787Syar	p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n");
393160787Syar	p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n");
394160787Syar	p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n");
395160787Syar	p(ip6s_ofragments, "\t%ju fragment%s created\n");
396160787Syar	p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n");
397160787Syar	p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n");
398160787Syar	p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n");
399249545Sae	for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
40054263Sshin		if (ip6stat.ip6s_nxthist[i] != 0) {
40154263Sshin			if (first) {
40254263Sshin				printf("\tInput histogram:\n");
40354263Sshin				first = 0;
40454263Sshin			}
405160787Syar			printf("\t\t%s: %ju\n", ip6nh[i],
406160787Syar			    (uintmax_t)ip6stat.ip6s_nxthist[i]);
40754263Sshin		}
40854263Sshin	printf("\tMbuf statistics:\n");
409160787Syar	printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1);
410249545Sae	for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
41155163Sshin		char ifbuf[IFNAMSIZ];
412175061Sobrien		if (ip6stat.ip6s_m2m[i] != 0) {
41354263Sshin			if (first) {
41454263Sshin				printf("\t\ttwo or more mbuf:\n");
41554263Sshin				first = 0;
41654263Sshin			}
417160787Syar			printf("\t\t\t%s= %ju\n",
41862584Sitojun			    if_indextoname(i, ifbuf),
419160787Syar			    (uintmax_t)ip6stat.ip6s_m2m[i]);
42054263Sshin		}
42154263Sshin	}
422160787Syar	printf("\t\t%ju one ext mbuf\n",
423160787Syar	    (uintmax_t)ip6stat.ip6s_mext1);
424160787Syar	printf("\t\t%ju two or more ext mbuf\n",
425175061Sobrien	    (uintmax_t)ip6stat.ip6s_mext2m);
42662584Sitojun	p(ip6s_exthdrtoolong,
427215955Sbrucec	    "\t%ju packet%s whose headers are not contiguous\n");
428160787Syar	p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n");
42962584Sitojun	p(ip6s_toomanyhdr,
430160787Syar	    "\t%ju packet%s discarded because of too many headers\n");
43162584Sitojun
43262584Sitojun	/* for debugging source address selection */
433175061Sobrien#define	PRINT_SCOPESTAT(s,i) do {\
43462584Sitojun		switch(i) { /* XXX hardcoding in each case */\
43562584Sitojun		case 1:\
436249545Sae			p(s, "\t\t%ju interface-local%s\n");\
43762584Sitojun			break;\
43862584Sitojun		case 2:\
439160787Syar			p(s,"\t\t%ju link-local%s\n");\
44062584Sitojun			break;\
44162584Sitojun		case 5:\
442160787Syar			p(s,"\t\t%ju site-local%s\n");\
44362584Sitojun			break;\
44462584Sitojun		case 14:\
445160787Syar			p(s,"\t\t%ju global%s\n");\
44662584Sitojun			break;\
44762584Sitojun		default:\
448160787Syar			printf("\t\t%ju addresses scope=%x\n",\
449160787Syar			    (uintmax_t)ip6stat.s, i);\
45062584Sitojun		}\
45162584Sitojun	} while (0);
45262584Sitojun
45362584Sitojun	p(ip6s_sources_none,
454160787Syar	  "\t%ju failure%s of source address selection\n");
455249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
45662584Sitojun		if (ip6stat.ip6s_sources_sameif[i]) {
45762584Sitojun			if (first) {
45862584Sitojun				printf("\tsource addresses on an outgoing I/F\n");
45962584Sitojun				first = 0;
46062584Sitojun			}
46162584Sitojun			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
46262584Sitojun		}
46362584Sitojun	}
464249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
46562584Sitojun		if (ip6stat.ip6s_sources_otherif[i]) {
46662584Sitojun			if (first) {
46762584Sitojun				printf("\tsource addresses on a non-outgoing I/F\n");
46862584Sitojun				first = 0;
46962584Sitojun			}
47062584Sitojun			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
47162584Sitojun		}
47262584Sitojun	}
473249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
47462584Sitojun		if (ip6stat.ip6s_sources_samescope[i]) {
47562584Sitojun			if (first) {
47662584Sitojun				printf("\tsource addresses of same scope\n");
47762584Sitojun				first = 0;
47862584Sitojun			}
47962584Sitojun			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
48062584Sitojun		}
48162584Sitojun	}
482249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
48362584Sitojun		if (ip6stat.ip6s_sources_otherscope[i]) {
48462584Sitojun			if (first) {
48562584Sitojun				printf("\tsource addresses of a different scope\n");
48662584Sitojun				first = 0;
48762584Sitojun			}
48862584Sitojun			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
48962584Sitojun		}
49062584Sitojun	}
491249545Sae	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
49262584Sitojun		if (ip6stat.ip6s_sources_deprecated[i]) {
49362584Sitojun			if (first) {
49462584Sitojun				printf("\tdeprecated source addresses\n");
49562584Sitojun				first = 0;
49662584Sitojun			}
49762584Sitojun			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
49862584Sitojun		}
49962584Sitojun	}
50062584Sitojun
501125483Sume	printf("\tSource addresses selection rule applied:\n");
502249545Sae	for (i = 0; i < IP6S_RULESMAX; i++) {
503125483Sume		if (ip6stat.ip6s_sources_rule[i])
504160787Syar			printf("\t\t%ju %s\n",
505160787Syar			       (uintmax_t)ip6stat.ip6s_sources_rule[i],
506125483Sume			       srcrule_str[i]);
507125483Sume	}
50854263Sshin#undef p
50962584Sitojun#undef p1a
51054263Sshin}
51154263Sshin
51254263Sshin/*
51354263Sshin * Dump IPv6 per-interface statistics based on RFC 2465.
51454263Sshin */
51554263Sshinvoid
51678314Sassarip6_ifstats(char *ifname)
51754263Sshin{
51854263Sshin	struct in6_ifreq ifr;
51954263Sshin	int s;
52054263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
521160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f))
52254263Sshin#define	p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
523160787Syar    printf(m, (uintmax_t)ip6stat.f)
52454263Sshin
52554263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
52654263Sshin		perror("Warning: socket(AF_INET6)");
52754263Sshin		return;
52854263Sshin	}
52954263Sshin
530319260Sasomers	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
53154263Sshin	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
532271185Smarkj		if (errno != EPFNOSUPPORT)
533271185Smarkj			perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
53454263Sshin		goto end;
53554263Sshin	}
53654263Sshin
537271185Smarkj	printf("ip6 on %s:\n", ifr.ifr_name);
538160787Syar	p(ifs6_in_receive, "\t%ju total input datagram%s\n");
539160787Syar	p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n");
540160787Syar	p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n");
541160787Syar	p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n");
542160787Syar	p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n");
543160787Syar	p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n");
544160787Syar	p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n");
545160787Syar	p(ifs6_in_discard, "\t%ju input datagram%s discarded\n");
54654263Sshin	p(ifs6_in_deliver,
547160787Syar	  "\t%ju datagram%s delivered to an upper layer protocol\n");
548160787Syar	p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n");
54954263Sshin	p(ifs6_out_request,
550160787Syar	  "\t%ju datagram%s sent from an upper layer protocol\n");
551160787Syar	p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n");
552160787Syar	p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n");
553160787Syar	p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n");
554160787Syar	p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n");
555160787Syar	p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n");
556160787Syar	p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n");
557160787Syar	p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n");
558160787Syar	p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n");
559160787Syar	p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n");
56054263Sshin
56154263Sshin  end:
56254263Sshin	close(s);
56354263Sshin
56454263Sshin#undef p
56554263Sshin#undef p_5
56654263Sshin}
56754263Sshin
568102975Sdwmalonestatic	const char *icmp6names[] = {
56954263Sshin	"#0",
57054263Sshin	"unreach",
57154263Sshin	"packet too big",
57254263Sshin	"time exceed",
57354263Sshin	"parameter problem",
57454263Sshin	"#5",
57554263Sshin	"#6",
57654263Sshin	"#7",
57754263Sshin	"#8",
57854263Sshin	"#9",
57954263Sshin	"#10",
58054263Sshin	"#11",
58154263Sshin	"#12",
58254263Sshin	"#13",
58354263Sshin	"#14",
58454263Sshin	"#15",
58554263Sshin	"#16",
58654263Sshin	"#17",
58754263Sshin	"#18",
588175061Sobrien	"#19",
58954263Sshin	"#20",
59054263Sshin	"#21",
59154263Sshin	"#22",
59254263Sshin	"#23",
59354263Sshin	"#24",
59454263Sshin	"#25",
59554263Sshin	"#26",
59654263Sshin	"#27",
59754263Sshin	"#28",
598175061Sobrien	"#29",
59954263Sshin	"#30",
60054263Sshin	"#31",
60154263Sshin	"#32",
60254263Sshin	"#33",
60354263Sshin	"#34",
60454263Sshin	"#35",
60554263Sshin	"#36",
60654263Sshin	"#37",
60754263Sshin	"#38",
608175061Sobrien	"#39",
60954263Sshin	"#40",
61054263Sshin	"#41",
61154263Sshin	"#42",
61254263Sshin	"#43",
61354263Sshin	"#44",
61454263Sshin	"#45",
61554263Sshin	"#46",
61654263Sshin	"#47",
61754263Sshin	"#48",
618175061Sobrien	"#49",
61954263Sshin	"#50",
62054263Sshin	"#51",
62154263Sshin	"#52",
62254263Sshin	"#53",
62354263Sshin	"#54",
62454263Sshin	"#55",
62554263Sshin	"#56",
62654263Sshin	"#57",
62754263Sshin	"#58",
628175061Sobrien	"#59",
62954263Sshin	"#60",
63054263Sshin	"#61",
63154263Sshin	"#62",
63254263Sshin	"#63",
63354263Sshin	"#64",
63454263Sshin	"#65",
63554263Sshin	"#66",
63654263Sshin	"#67",
63754263Sshin	"#68",
638175061Sobrien	"#69",
63954263Sshin	"#70",
64054263Sshin	"#71",
64154263Sshin	"#72",
64254263Sshin	"#73",
64354263Sshin	"#74",
64454263Sshin	"#75",
64554263Sshin	"#76",
64654263Sshin	"#77",
64754263Sshin	"#78",
648175061Sobrien	"#79",
64954263Sshin	"#80",
65054263Sshin	"#81",
65154263Sshin	"#82",
65254263Sshin	"#83",
65354263Sshin	"#84",
65454263Sshin	"#85",
65554263Sshin	"#86",
65654263Sshin	"#87",
65754263Sshin	"#88",
658175061Sobrien	"#89",
65954263Sshin	"#80",
66054263Sshin	"#91",
66154263Sshin	"#92",
66254263Sshin	"#93",
66354263Sshin	"#94",
66454263Sshin	"#95",
66554263Sshin	"#96",
66654263Sshin	"#97",
66754263Sshin	"#98",
668175061Sobrien	"#99",
66954263Sshin	"#100",
67054263Sshin	"#101",
67154263Sshin	"#102",
67254263Sshin	"#103",
67354263Sshin	"#104",
67454263Sshin	"#105",
67554263Sshin	"#106",
67654263Sshin	"#107",
67754263Sshin	"#108",
678175061Sobrien	"#109",
67954263Sshin	"#110",
68054263Sshin	"#111",
68154263Sshin	"#112",
68254263Sshin	"#113",
68354263Sshin	"#114",
68454263Sshin	"#115",
68554263Sshin	"#116",
68654263Sshin	"#117",
68754263Sshin	"#118",
688175061Sobrien	"#119",
68954263Sshin	"#120",
69054263Sshin	"#121",
69154263Sshin	"#122",
69254263Sshin	"#123",
69354263Sshin	"#124",
69454263Sshin	"#125",
69554263Sshin	"#126",
69654263Sshin	"#127",
69754263Sshin	"echo",
698175061Sobrien	"echo reply",
69954263Sshin	"multicast listener query",
700191652Sbms	"MLDv1 listener report",
701191652Sbms	"MLDv1 listener done",
70254263Sshin	"router solicitation",
70377565Sdd	"router advertisement",
70454263Sshin	"neighbor solicitation",
70577565Sdd	"neighbor advertisement",
70654263Sshin	"redirect",
70754263Sshin	"router renumbering",
70854263Sshin	"node information request",
70954263Sshin	"node information reply",
71078540Ssumikawa	"inverse neighbor solicitation",
71178540Ssumikawa	"inverse neighbor advertisement",
712191652Sbms	"MLDv2 listener report",
71354263Sshin	"#144",
71454263Sshin	"#145",
71554263Sshin	"#146",
71654263Sshin	"#147",
71754263Sshin	"#148",
718175061Sobrien	"#149",
71954263Sshin	"#150",
72054263Sshin	"#151",
72154263Sshin	"#152",
72254263Sshin	"#153",
72354263Sshin	"#154",
72454263Sshin	"#155",
72554263Sshin	"#156",
72654263Sshin	"#157",
72754263Sshin	"#158",
728175061Sobrien	"#159",
72954263Sshin	"#160",
73054263Sshin	"#161",
73154263Sshin	"#162",
73254263Sshin	"#163",
73354263Sshin	"#164",
73454263Sshin	"#165",
73554263Sshin	"#166",
73654263Sshin	"#167",
73754263Sshin	"#168",
738175061Sobrien	"#169",
73954263Sshin	"#170",
74054263Sshin	"#171",
74154263Sshin	"#172",
74254263Sshin	"#173",
74354263Sshin	"#174",
74454263Sshin	"#175",
74554263Sshin	"#176",
74654263Sshin	"#177",
74754263Sshin	"#178",
748175061Sobrien	"#179",
74954263Sshin	"#180",
75054263Sshin	"#181",
75154263Sshin	"#182",
75254263Sshin	"#183",
75354263Sshin	"#184",
75454263Sshin	"#185",
75554263Sshin	"#186",
75654263Sshin	"#187",
75754263Sshin	"#188",
758175061Sobrien	"#189",
75954263Sshin	"#180",
76054263Sshin	"#191",
76154263Sshin	"#192",
76254263Sshin	"#193",
76354263Sshin	"#194",
76454263Sshin	"#195",
76554263Sshin	"#196",
76654263Sshin	"#197",
76754263Sshin	"#198",
768175061Sobrien	"#199",
76954263Sshin	"#200",
77054263Sshin	"#201",
77154263Sshin	"#202",
77254263Sshin	"#203",
77354263Sshin	"#204",
77454263Sshin	"#205",
77554263Sshin	"#206",
77654263Sshin	"#207",
77754263Sshin	"#208",
778175061Sobrien	"#209",
77954263Sshin	"#210",
78054263Sshin	"#211",
78154263Sshin	"#212",
78254263Sshin	"#213",
78354263Sshin	"#214",
78454263Sshin	"#215",
78554263Sshin	"#216",
78654263Sshin	"#217",
78754263Sshin	"#218",
788175061Sobrien	"#219",
78954263Sshin	"#220",
79054263Sshin	"#221",
79154263Sshin	"#222",
79254263Sshin	"#223",
79354263Sshin	"#224",
79454263Sshin	"#225",
79554263Sshin	"#226",
79654263Sshin	"#227",
79754263Sshin	"#228",
798175061Sobrien	"#229",
79954263Sshin	"#230",
80054263Sshin	"#231",
80154263Sshin	"#232",
80254263Sshin	"#233",
80354263Sshin	"#234",
80454263Sshin	"#235",
80554263Sshin	"#236",
80654263Sshin	"#237",
80754263Sshin	"#238",
808175061Sobrien	"#239",
80954263Sshin	"#240",
81054263Sshin	"#241",
81154263Sshin	"#242",
81254263Sshin	"#243",
81354263Sshin	"#244",
81454263Sshin	"#245",
81554263Sshin	"#246",
81654263Sshin	"#247",
81754263Sshin	"#248",
818175061Sobrien	"#249",
81954263Sshin	"#250",
82054263Sshin	"#251",
82154263Sshin	"#252",
82254263Sshin	"#253",
82354263Sshin	"#254",
82454263Sshin	"#255",
82554263Sshin};
82654263Sshin
82754263Sshin/*
82854263Sshin * Dump ICMP6 statistics.
82954263Sshin */
83054263Sshinvoid
831171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
83254263Sshin{
833293307Smarkj	struct icmp6stat icmp6stat;
83495637Smarkm	int i, first;
83554263Sshin
836293307Smarkj	if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat,
837293307Smarkj	    sizeof(icmp6stat), kread_counters) != 0)
838293307Smarkj		return;
83978931Sume
84054263Sshin	printf("%s:\n", name);
84154263Sshin
84254263Sshin#define	p(f, m) if (icmp6stat.f || sflag <= 1) \
843160787Syar    printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
844187134Smaxim#define	p_5(f, m) if (icmp6stat.f || sflag <= 1) \
845187134Smaxim    printf(m, (uintmax_t)icmp6stat.f)
84654263Sshin
847160787Syar	p(icp6s_error, "\t%ju call%s to icmp6_error\n");
84854263Sshin	p(icp6s_canterror,
849160787Syar	    "\t%ju error%s not generated in response to an icmp6 message\n");
85054263Sshin	p(icp6s_toofreq,
851160787Syar	  "\t%ju error%s not generated because of rate limitation\n");
852175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
85378540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
85454263Sshin		if (icmp6stat.icp6s_outhist[i] != 0) {
85554263Sshin			if (first) {
85654263Sshin				printf("\tOutput histogram:\n");
85754263Sshin				first = 0;
85854263Sshin			}
859160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
860160787Syar			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
86154263Sshin		}
86278540Ssumikawa#undef NELEM
863160787Syar	p(icp6s_badcode, "\t%ju message%s with bad code fields\n");
864160787Syar	p(icp6s_tooshort, "\t%ju message%s < minimum length\n");
865160787Syar	p(icp6s_checksum, "\t%ju bad checksum%s\n");
866160787Syar	p(icp6s_badlen, "\t%ju message%s with bad length\n");
867175061Sobrien#define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
86878540Ssumikawa	for (first = 1, i = 0; i < NELEM; i++)
86954263Sshin		if (icmp6stat.icp6s_inhist[i] != 0) {
87054263Sshin			if (first) {
87154263Sshin				printf("\tInput histogram:\n");
87254263Sshin				first = 0;
87354263Sshin			}
874160787Syar			printf("\t\t%s: %ju\n", icmp6names[i],
875160787Syar			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
87654263Sshin		}
87778540Ssumikawa#undef NELEM
87877565Sdd	printf("\tHistogram of error messages to be generated:\n");
879160787Syar	p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n");
880160787Syar	p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n");
881160787Syar	p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n");
882160787Syar	p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n");
883160787Syar	p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n");
884160787Syar	p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n");
885160787Syar	p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n");
886160787Syar	p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n");
887160787Syar	p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n");
888160787Syar	p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n");
889160787Syar	p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n");
890160787Syar	p_5(icp6s_oredirect, "\t\t%ju redirect\n");
891160787Syar	p_5(icp6s_ounknown, "\t\t%ju unknown\n");
89262584Sitojun
893160787Syar	p(icp6s_reflect, "\t%ju message response%s generated\n");
894160787Syar	p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n");
895160787Syar	p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n");
896160787Syar	p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n");
897160787Syar	p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n");
898160787Syar	p(icp6s_badrs, "\t%ju bad router solicitation message%s\n");
899160787Syar	p(icp6s_badra, "\t%ju bad router advertisement message%s\n");
900160787Syar	p(icp6s_badredirect, "\t%ju bad redirect message%s\n");
901160787Syar	p(icp6s_pmtuchg, "\t%ju path MTU change%s\n");
90254263Sshin#undef p
90354263Sshin#undef p_5
90454263Sshin}
90554263Sshin
90654263Sshin/*
90754263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466.
90854263Sshin */
90954263Sshinvoid
91078314Sassaricmp6_ifstats(char *ifname)
91154263Sshin{
91254263Sshin	struct in6_ifreq ifr;
91354263Sshin	int s;
91454263Sshin#define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
915160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f))
916109234Smtm#define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
917160787Syar    printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
91854263Sshin
91954263Sshin	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
92054263Sshin		perror("Warning: socket(AF_INET6)");
92154263Sshin		return;
92254263Sshin	}
92354263Sshin
924319260Sasomers	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
92554263Sshin	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
926271185Smarkj		if (errno != EPFNOSUPPORT)
927271185Smarkj			perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
92854263Sshin		goto end;
92954263Sshin	}
93054263Sshin
931271185Smarkj	printf("icmp6 on %s:\n", ifr.ifr_name);
932160787Syar	p(ifs6_in_msg, "\t%ju total input message%s\n");
933175061Sobrien	p(ifs6_in_error, "\t%ju total input error message%s\n");
934160787Syar	p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n");
935160787Syar	p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n");
936160787Syar	p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n");
937160787Syar	p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n");
938160787Syar	p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n");
939160787Syar	p(ifs6_in_echo, "\t%ju input echo request%s\n");
940160787Syar	p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n");
941160787Syar	p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n");
942160787Syar	p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n");
943160787Syar	p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n");
944160787Syar	p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n");
945160787Syar	p(ifs6_in_redirect, "\t%ju input redirect%s\n");
946160787Syar	p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n");
947160787Syar	p(ifs6_in_mldreport, "\t%ju input MLD report%s\n");
948160787Syar	p(ifs6_in_mlddone, "\t%ju input MLD done%s\n");
94954263Sshin
950160787Syar	p(ifs6_out_msg, "\t%ju total output message%s\n");
951160787Syar	p(ifs6_out_error, "\t%ju total output error message%s\n");
952160787Syar	p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n");
953160787Syar	p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n");
954160787Syar	p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n");
955160787Syar	p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n");
956160787Syar	p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n");
957160787Syar	p(ifs6_out_echo, "\t%ju output echo request%s\n");
958160787Syar	p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n");
959160787Syar	p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n");
960160787Syar	p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n");
961160787Syar	p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n");
962160787Syar	p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n");
963160787Syar	p(ifs6_out_redirect, "\t%ju output redirect%s\n");
964160787Syar	p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n");
965160787Syar	p(ifs6_out_mldreport, "\t%ju output MLD report%s\n");
966160787Syar	p(ifs6_out_mlddone, "\t%ju output MLD done%s\n");
96754263Sshin
96854263Sshin  end:
96954263Sshin	close(s);
97054263Sshin#undef p
97154263Sshin}
97254263Sshin
97354263Sshin/*
97454263Sshin * Dump PIM statistics structure.
97554263Sshin */
97654263Sshinvoid
977171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
97854263Sshin{
979293307Smarkj	struct pim6stat pim6stat;
98054263Sshin
981293307Smarkj	if (fetch_stats("net.inet6.pim.stats", off, &pim6stat,
982293307Smarkj	    sizeof(pim6stat), kread) != 0)
983293307Smarkj		return;
984171465Sjhb
98554263Sshin	printf("%s:\n", name);
98654263Sshin
98754263Sshin#define	p(f, m) if (pim6stat.f || sflag <= 1) \
988160787Syar    printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
989160787Syar	p(pim6s_rcv_total, "\t%ju message%s received\n");
990160787Syar	p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n");
991160787Syar	p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n");
992160787Syar	p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n");
993160787Syar	p(pim6s_rcv_registers, "\t%ju register%s received\n");
994160787Syar	p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n");
995160787Syar	p(pim6s_snd_registers, "\t%ju register%s sent\n");
99654263Sshin#undef p
99754263Sshin}
99854263Sshin
99954263Sshin/*
100078064Sume * Dump raw ip6 statistics structure.
100178064Sume */
100278064Sumevoid
1003171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
100478064Sume{
1005293307Smarkj	struct rip6stat rip6stat;
100678064Sume	u_quad_t delivered;
100778064Sume
1008293307Smarkj	if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat,
1009293307Smarkj	    sizeof(rip6stat), kread_counters) != 0)
1010293307Smarkj		return;
101178064Sume
101278064Sume	printf("%s:\n", name);
101378064Sume
101478064Sume#define	p(f, m) if (rip6stat.f || sflag <= 1) \
1015160787Syar    printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1016160787Syar	p(rip6s_ipackets, "\t%ju message%s received\n");
1017186498Smaxim	p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n");
1018160787Syar	p(rip6s_badsum, "\t%ju message%s with bad checksum\n");
1019160787Syar	p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n");
102078064Sume	p(rip6s_nosockmcast,
1021160787Syar	    "\t%ju multicast message%s dropped due to no socket\n");
102278064Sume	p(rip6s_fullsock,
1023160787Syar	    "\t%ju message%s dropped due to full socket buffers\n");
102478064Sume	delivered = rip6stat.rip6s_ipackets -
102578064Sume		    rip6stat.rip6s_badsum -
102678064Sume		    rip6stat.rip6s_nosock -
102778064Sume		    rip6stat.rip6s_nosockmcast -
102878064Sume		    rip6stat.rip6s_fullsock;
102978064Sume	if (delivered || sflag <= 1)
1030160787Syar		printf("\t%ju delivered\n", (uintmax_t)delivered);
1031160787Syar	p(rip6s_opackets, "\t%ju datagram%s output\n");
103278064Sume#undef p
103378064Sume}
103478064Sume
103578064Sume/*
103654263Sshin * Pretty print an Internet address (net address + port).
103778238Sassar * Take numeric_addr and numeric_port into consideration.
103854263Sshin */
1039175061Sobrien#define	GETSERVBYPORT6(port, proto, ret)\
104054263Sshin{\
104154263Sshin	if (strcmp((proto), "tcp6") == 0)\
104254263Sshin		(ret) = getservbyport((int)(port), "tcp");\
104354263Sshin	else if (strcmp((proto), "udp6") == 0)\
104454263Sshin		(ret) = getservbyport((int)(port), "udp");\
104554263Sshin	else\
104654263Sshin		(ret) = getservbyport((int)(port), (proto));\
104754263Sshin};
104854263Sshin
104954263Sshinvoid
1050102975Sdwmaloneinet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
105154263Sshin{
105254263Sshin	struct servent *sp = 0;
105354263Sshin	char line[80], *cp;
105454263Sshin	int width;
105554263Sshin
105683200Sru	sprintf(line, "%.*s.", Wflag ? 39 :
105754263Sshin		(Aflag && !numeric) ? 12 : 16, inet6name(in6));
1058229403Sed	cp = strchr(line, '\0');
105954263Sshin	if (!numeric && port)
106054263Sshin		GETSERVBYPORT6(port, proto, sp);
106154263Sshin	if (sp || port == 0)
1062177352Sume		sprintf(cp, "%.15s", sp ? sp->s_name : "*");
106354263Sshin	else
106454263Sshin		sprintf(cp, "%d", ntohs((u_short)port));
106583200Sru	width = Wflag ? 45 : Aflag ? 18 : 22;
106655533Sshin	printf("%-*.*s ", width, width, line);
106754263Sshin}
106854263Sshin
106954263Sshin/*
107054263Sshin * Construct an Internet address representation.
107178238Sassar * If the numeric_addr has been supplied, give
107254263Sshin * numeric value, otherwise try for symbolic name.
107354263Sshin */
107454263Sshin
107554263Sshinchar *
107678314Sassarinet6name(struct in6_addr *in6p)
107754263Sshin{
1078254459Shrs	struct sockaddr_in6 sin6;
1079254459Shrs	char hbuf[NI_MAXHOST], *cp;
108054263Sshin	static char line[50];
108174262Sbrian	static char domain[MAXHOSTNAMELEN];
108254263Sshin	static int first = 1;
1083254459Shrs	int flags, error;
108454263Sshin
1085254459Shrs	if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1086254459Shrs		strcpy(line, "*");
1087254459Shrs		return (line);
1088254459Shrs	}
108978238Sassar	if (first && !numeric_addr) {
109054263Sshin		first = 0;
109154263Sshin		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1092229403Sed		    (cp = strchr(domain, '.')))
109354263Sshin			(void) strcpy(domain, cp + 1);
109454263Sshin		else
109554263Sshin			domain[0] = 0;
109654263Sshin	}
1097254459Shrs	memset(&sin6, 0, sizeof(sin6));
1098254459Shrs	memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
1099254459Shrs	sin6.sin6_family = AF_INET6;
1100254459Shrs	/* XXX: in6p.s6_addr[2] can contain scopeid. */
1101254459Shrs	in6_fillscopeid(&sin6);
1102254459Shrs	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
1103254459Shrs	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
1104254459Shrs	    sizeof(hbuf), NULL, 0, flags);
1105254459Shrs	if (error == 0) {
1106254459Shrs		if ((flags & NI_NUMERICHOST) == 0 &&
1107254459Shrs		    (cp = strchr(hbuf, '.')) &&
1108254459Shrs		    !strcmp(cp + 1, domain))
1109254459Shrs			*cp = 0;
1110254459Shrs		strcpy(line, hbuf);
1111254459Shrs	} else {
1112254459Shrs		/* XXX: this should not happen. */
111354263Sshin		sprintf(line, "%s",
1114254459Shrs			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
111554263Sshin				sizeof(ntop_buf)));
1116254459Shrs	}
111754263Sshin	return (line);
111854263Sshin}
111964342Sume#endif /*INET6*/
1120