1/*	BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp	*/
2/*-
3 * Copyright (c) 1983, 1988, 1993
4 *	The Regents of the University of California.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 4. Neither the name of the University nor the names of its contributors
15 *    may be used to endorse or promote products derived from this software
16 *    without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#if 0
32#ifndef lint
33static char sccsid[] = "@(#)inet6.c	8.4 (Berkeley) 4/20/94";
34#endif /* not lint */
35#endif
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: stable/11/usr.bin/netstat/inet6.c 355869 2019-12-17 23:45:50Z bz $");
39
40#ifdef INET6
41#include <sys/param.h>
42#include <sys/socket.h>
43#include <sys/socketvar.h>
44#include <sys/ioctl.h>
45#include <sys/mbuf.h>
46#include <sys/protosw.h>
47
48#include <net/route.h>
49#include <net/if.h>
50#include <netinet/in.h>
51#include <netinet/ip6.h>
52#include <netinet/icmp6.h>
53#include <netinet/in_systm.h>
54#include <netinet6/in6_pcb.h>
55#include <netinet6/in6_var.h>
56#include <netinet6/ip6_var.h>
57#include <netinet6/pim6_var.h>
58#include <netinet6/raw_ip6.h>
59
60#include <arpa/inet.h>
61#include <netdb.h>
62
63#include <err.h>
64#include <stdint.h>
65#include <stdio.h>
66#include <stdbool.h>
67#include <errno.h>
68#include <string.h>
69#include <unistd.h>
70#include <libxo/xo.h>
71#include "netstat.h"
72
73static char ntop_buf[INET6_ADDRSTRLEN];
74
75static	const char *ip6nh[] = {
76	"hop by hop",
77	"ICMP",
78	"IGMP",
79	"#3",
80	"IP",
81	"#5",
82	"TCP",
83	"#7",
84	"#8",
85	"#9",
86	"#10",
87	"#11",
88	"#12",
89	"#13",
90	"#14",
91	"#15",
92	"#16",
93	"UDP",
94	"#18",
95	"#19",
96	"#20",
97	"#21",
98	"IDP",
99	"#23",
100	"#24",
101	"#25",
102	"#26",
103	"#27",
104	"#28",
105	"TP",
106	"#30",
107	"#31",
108	"#32",
109	"#33",
110	"#34",
111	"#35",
112	"#36",
113	"#37",
114	"#38",
115	"#39",
116	"#40",
117	"IP6",
118	"#42",
119	"routing",
120	"fragment",
121	"#45",
122	"#46",
123	"#47",
124	"#48",
125	"#49",
126	"ESP",
127	"AH",
128	"#52",
129	"#53",
130	"#54",
131	"#55",
132	"#56",
133	"#57",
134	"ICMP6",
135	"no next header",
136	"destination option",
137	"#61",
138	"mobility",
139	"#63",
140	"#64",
141	"#65",
142	"#66",
143	"#67",
144	"#68",
145	"#69",
146	"#70",
147	"#71",
148	"#72",
149	"#73",
150	"#74",
151	"#75",
152	"#76",
153	"#77",
154	"#78",
155	"#79",
156	"ISOIP",
157	"#81",
158	"#82",
159	"#83",
160	"#84",
161	"#85",
162	"#86",
163	"#87",
164	"#88",
165	"OSPF",
166	"#80",
167	"#91",
168	"#92",
169	"#93",
170	"#94",
171	"#95",
172	"#96",
173	"Ethernet",
174	"#98",
175	"#99",
176	"#100",
177	"#101",
178	"#102",
179	"PIM",
180	"#104",
181	"#105",
182	"#106",
183	"#107",
184	"#108",
185	"#109",
186	"#110",
187	"#111",
188	"#112",
189	"#113",
190	"#114",
191	"#115",
192	"#116",
193	"#117",
194	"#118",
195	"#119",
196	"#120",
197	"#121",
198	"#122",
199	"#123",
200	"#124",
201	"#125",
202	"#126",
203	"#127",
204	"#128",
205	"#129",
206	"#130",
207	"#131",
208	"SCTP",
209	"#133",
210	"#134",
211	"#135",
212	"UDPLite",
213	"#137",
214	"#138",
215	"#139",
216	"#140",
217	"#141",
218	"#142",
219	"#143",
220	"#144",
221	"#145",
222	"#146",
223	"#147",
224	"#148",
225	"#149",
226	"#150",
227	"#151",
228	"#152",
229	"#153",
230	"#154",
231	"#155",
232	"#156",
233	"#157",
234	"#158",
235	"#159",
236	"#160",
237	"#161",
238	"#162",
239	"#163",
240	"#164",
241	"#165",
242	"#166",
243	"#167",
244	"#168",
245	"#169",
246	"#170",
247	"#171",
248	"#172",
249	"#173",
250	"#174",
251	"#175",
252	"#176",
253	"#177",
254	"#178",
255	"#179",
256	"#180",
257	"#181",
258	"#182",
259	"#183",
260	"#184",
261	"#185",
262	"#186",
263	"#187",
264	"#188",
265	"#189",
266	"#180",
267	"#191",
268	"#192",
269	"#193",
270	"#194",
271	"#195",
272	"#196",
273	"#197",
274	"#198",
275	"#199",
276	"#200",
277	"#201",
278	"#202",
279	"#203",
280	"#204",
281	"#205",
282	"#206",
283	"#207",
284	"#208",
285	"#209",
286	"#210",
287	"#211",
288	"#212",
289	"#213",
290	"#214",
291	"#215",
292	"#216",
293	"#217",
294	"#218",
295	"#219",
296	"#220",
297	"#221",
298	"#222",
299	"#223",
300	"#224",
301	"#225",
302	"#226",
303	"#227",
304	"#228",
305	"#229",
306	"#230",
307	"#231",
308	"#232",
309	"#233",
310	"#234",
311	"#235",
312	"#236",
313	"#237",
314	"#238",
315	"#239",
316	"#240",
317	"#241",
318	"#242",
319	"#243",
320	"#244",
321	"#245",
322	"#246",
323	"#247",
324	"#248",
325	"#249",
326	"#250",
327	"#251",
328	"#252",
329	"#253",
330	"#254",
331	"#255",
332};
333
334static const char *srcrule_str[] = {
335	"first candidate",
336	"same address",
337	"appropriate scope",
338	"deprecated address",
339	"home address",
340	"outgoing interface",
341	"matching label",
342	"public/temporary address",
343	"alive interface",
344	"better virtual status",
345	"preferred source",
346	"rule #11",
347	"rule #12",
348	"rule #13",
349	"longest match",
350	"rule #15",
351};
352
353/*
354 * Dump IP6 statistics structure.
355 */
356void
357ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
358{
359	struct ip6stat ip6stat;
360	int first, i;
361
362	if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat,
363	    sizeof(ip6stat), kread_counters) != 0)
364		return;
365
366	xo_open_container(name);
367	xo_emit("{T:/%s}:\n", name);
368
369#define	p(f, m) if (ip6stat.f || sflag <= 1) \
370	xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
371#define	p1a(f, m) if (ip6stat.f || sflag <= 1) \
372	xo_emit(m, (uintmax_t)ip6stat.f)
373
374	p(ip6s_total, "\t{:received-packets/%ju} "
375	    "{N:/total packet%s received}\n");
376	p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} "
377	    "{N:/with size smaller than minimum}\n");
378	p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} "
379	    "{N:/with data size < data length}\n");
380	p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} "
381	    "{N:/with bad options}\n");
382	p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} "
383	    "{N:/with incorrect version number}\n");
384	p(ip6s_fragments, "\t{:received-fragments/%ju} "
385	    "{N:/fragment%s received}\n");
386	p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} "
387	    "{N:/fragment%s dropped (dup or out of space)}\n");
388	p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} "
389	    "{N:/fragment%s dropped after timeout}\n");
390	p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
391	    "{N:/fragment%s that exceeded limit}\n");
392	p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
393	    "{N:/packet%s reassembled ok}\n");
394	p(ip6s_delivered, "\t{:received-local-packets/%ju} "
395	    "{N:/packet%s for this host}\n");
396	p(ip6s_forward, "\t{:forwarded-packets/%ju} "
397	    "{N:/packet%s forwarded}\n");
398	p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} "
399	    "{N:/packet%s not forwardable}\n");
400	p(ip6s_redirectsent, "\t{:sent-redirects/%ju} "
401	    "{N:/redirect%s sent}\n");
402	p(ip6s_localout, "\t{:sent-packets/%ju} "
403	    "{N:/packet%s sent from this host}\n");
404	p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} "
405	    "{N:/packet%s sent with fabricated ip header}\n");
406	p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} "
407	    "{N:/output packet%s dropped due to no bufs, etc.}\n");
408	p(ip6s_noroute, "\t{:discard-no-route/%ju} "
409	    "{N:/output packet%s discarded due to no route}\n");
410	p(ip6s_fragmented, "\t{:sent-fragments/%ju} "
411	    "{N:/output datagram%s fragmented}\n");
412	p(ip6s_ofragments, "\t{:fragments-created/%ju} "
413	    "{N:/fragment%s created}\n");
414	p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} "
415	    "{N:/datagram%s that can't be fragmented}\n");
416	p(ip6s_badscope, "\t{:discard-scope-violations/%ju} "
417	    "{N:/packet%s that violated scope rules}\n");
418	p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} "
419	    "{N:/multicast packet%s which we don't join}\n");
420	for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
421		if (ip6stat.ip6s_nxthist[i] != 0) {
422			if (first) {
423				xo_emit("\t{T:Input histogram}:\n");
424				xo_open_list("input-histogram");
425				first = 0;
426			}
427			xo_open_instance("input-histogram");
428			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i],
429			    (uintmax_t)ip6stat.ip6s_nxthist[i]);
430			xo_close_instance("input-histogram");
431		}
432	if (!first)
433		xo_close_list("input-histogram");
434
435	xo_open_container("mbuf-statistics");
436	xo_emit("\t{T:Mbuf statistics}:\n");
437	xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n",
438	    (uintmax_t)ip6stat.ip6s_m1);
439	for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
440		char ifbuf[IFNAMSIZ];
441		if (ip6stat.ip6s_m2m[i] != 0) {
442			if (first) {
443				xo_emit("\t\t{N:two or more mbuf}:\n");
444				xo_open_list("mbuf-data");
445				first = 0;
446			}
447			xo_open_instance("mbuf-data");
448			xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n",
449			    if_indextoname(i, ifbuf),
450			    (uintmax_t)ip6stat.ip6s_m2m[i]);
451			xo_close_instance("mbuf-data");
452		}
453	}
454	if (!first)
455		xo_close_list("mbuf-data");
456	xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n",
457	    (uintmax_t)ip6stat.ip6s_mext1);
458	xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} "
459	    "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m);
460	xo_close_container("mbuf-statistics");
461
462	p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} "
463	    "{N:/packet%s whose headers are not contiguous}\n");
464	p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} "
465	    "{N:/tunneling packet%s that can't find gif}\n");
466	p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} "
467	    "{N:/packet%s discarded because of too many headers}\n");
468
469	/* for debugging source address selection */
470#define	PRINT_SCOPESTAT(s,i) do {\
471		switch(i) { /* XXX hardcoding in each case */\
472		case 1:\
473			p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \
474			  "{N:/interface-local%s}\n");	\
475			break;\
476		case 2:\
477			p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \
478			"{N:/link-local%s}\n"); \
479			break;\
480		case 5:\
481			p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \
482			  "{N:/site-local%s}\n");\
483			break;\
484		case 14:\
485			p(s,"\t\t{ke:name/globals}{:count/%ju} " \
486			  "{N:/global%s}\n");\
487			break;\
488		default:\
489			xo_emit("\t\t{qke:name/%#x}{:count/%ju} " \
490				"{N:/addresses scope=%#x}\n",\
491				i, (uintmax_t)ip6stat.s, i);	   \
492		}\
493	} while (0);
494
495	xo_open_container("source-address-selection");
496	p(ip6s_sources_none, "\t{:address-selection-failures/%ju} "
497	    "{N:/failure%s of source address selection}\n");
498
499	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
500		if (ip6stat.ip6s_sources_sameif[i]) {
501			if (first) {
502				xo_open_list("outgoing-interface");
503				xo_emit("\tsource addresses on an outgoing "
504				    "I/F\n");
505				first = 0;
506			}
507			xo_open_instance("outgoing-interface");
508			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
509			xo_close_instance("outgoing-interface");
510		}
511	}
512	if (!first)
513		xo_close_list("outgoing-interface");
514
515	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
516		if (ip6stat.ip6s_sources_otherif[i]) {
517			if (first) {
518				xo_open_list("non-outgoing-interface");
519				xo_emit("\tsource addresses on a non-outgoing "
520				    "I/F\n");
521				first = 0;
522			}
523			xo_open_instance("non-outgoing-interface");
524			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
525			xo_close_instance("non-outgoing-interface");
526		}
527	}
528	if (!first)
529		xo_close_list("non-outgoing-interface");
530
531	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
532		if (ip6stat.ip6s_sources_samescope[i]) {
533			if (first) {
534				xo_open_list("same-source");
535				xo_emit("\tsource addresses of same scope\n");
536				first = 0;
537			}
538			xo_open_instance("same-source");
539			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
540			xo_close_instance("same-source");
541		}
542	}
543	if (!first)
544		xo_close_list("same-source");
545
546	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
547		if (ip6stat.ip6s_sources_otherscope[i]) {
548			if (first) {
549				xo_open_list("different-scope");
550				xo_emit("\tsource addresses of a different "
551				    "scope\n");
552				first = 0;
553			}
554			xo_open_instance("different-scope");
555			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
556			xo_close_instance("different-scope");
557		}
558	}
559	if (!first)
560		xo_close_list("different-scope");
561
562	for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
563		if (ip6stat.ip6s_sources_deprecated[i]) {
564			if (first) {
565				xo_open_list("deprecated-source");
566				xo_emit("\tdeprecated source addresses\n");
567				first = 0;
568			}
569			xo_open_instance("deprecated-source");
570			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
571			xo_close_instance("deprecated-source");
572		}
573	}
574	if (!first)
575		xo_close_list("deprecated-source");
576
577	for (first = 1, i = 0; i < IP6S_RULESMAX; i++) {
578		if (ip6stat.ip6s_sources_rule[i]) {
579			if (first) {
580				xo_open_list("rules-applied");
581				xo_emit("\t{T:Source addresses selection "
582				    "rule applied}:\n");
583				first = 0;
584			}
585			xo_open_instance("rules-applied");
586			xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n",
587			    srcrule_str[i],
588			    (uintmax_t)ip6stat.ip6s_sources_rule[i],
589			    srcrule_str[i]);
590			xo_close_instance("rules-applied");
591		}
592	}
593	if (!first)
594		xo_close_list("rules-applied");
595
596	xo_close_container("source-address-selection");
597
598#undef p
599#undef p1a
600	xo_close_container(name);
601}
602
603/*
604 * Dump IPv6 per-interface statistics based on RFC 2465.
605 */
606void
607ip6_ifstats(char *ifname)
608{
609	struct in6_ifreq ifr;
610	int s;
611
612#define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1)	\
613	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f,		\
614	    plural(ifr.ifr_ifru.ifru_stat.f))
615
616	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
617		xo_warn("Warning: socket(AF_INET6)");
618		return;
619	}
620
621	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
622	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
623		if (errno != EPFNOSUPPORT)
624			xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)");
625		goto end;
626	}
627
628	xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name);
629
630	xo_open_instance("ip6-interface-statistics");
631	xo_emit("{ke:name/%s}", ifr.ifr_name);
632
633	p(ifs6_in_receive, "\t{:received-packets/%ju} "
634	    "{N:/total input datagram%s}\n");
635	p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} "
636	    "{N:/datagram%s with invalid header received}\n");
637	p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} "
638	    "{N:/datagram%s exceeded MTU received}\n");
639	p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} "
640	    "{N:/datagram%s with no route received}\n");
641	p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} "
642	    "{N:/datagram%s with invalid dst received}\n");
643	p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} "
644	    "{N:/datagram%s with unknown proto received}\n");
645	p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} "
646	    "{N:/truncated datagram%s received}\n");
647	p(ifs6_in_discard, "\t{:dropped-discarded/%ju} "
648	    "{N:/input datagram%s discarded}\n");
649 	p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} "
650	    "{N:/datagram%s delivered to an upper layer protocol}\n");
651	p(ifs6_out_forward, "\t{:sent-forwarded/%ju} "
652	    "{N:/datagram%s forwarded to this interface}\n");
653 	p(ifs6_out_request, "\t{:sent-packets/%ju} "
654	    "{N:/datagram%s sent from an upper layer protocol}\n");
655	p(ifs6_out_discard, "\t{:discard-packets/%ju} "
656	    "{N:/total discarded output datagram%s}\n");
657	p(ifs6_out_fragok, "\t{:discard-fragments/%ju} "
658	    "{N:/output datagram%s fragmented}\n");
659	p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} "
660	    "{N:/output datagram%s failed on fragment}\n");
661	p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} "
662	    "{N:/output datagram%s succeeded on fragment}\n");
663	p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} "
664	    "{N:/incoming datagram%s fragmented}\n");
665	p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} "
666	    "{N:/datagram%s reassembled}\n");
667	p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} "
668	    "{N:/datagram%s failed on reassembly}\n");
669	p(ifs6_in_mcast, "\t{:received-multicast/%ju} "
670	    "{N:/multicast datagram%s received}\n");
671	p(ifs6_out_mcast, "\t{:sent-multicast/%ju} "
672	    "{N:/multicast datagram%s sent}\n");
673
674 end:
675	xo_close_instance("ip6-interface-statistics");
676 	close(s);
677
678#undef p
679}
680
681static	const char *icmp6names[] = {
682	"#0",
683	"unreach",
684	"packet too big",
685	"time exceed",
686	"parameter problem",
687	"#5",
688	"#6",
689	"#7",
690	"#8",
691	"#9",
692	"#10",
693	"#11",
694	"#12",
695	"#13",
696	"#14",
697	"#15",
698	"#16",
699	"#17",
700	"#18",
701	"#19",
702	"#20",
703	"#21",
704	"#22",
705	"#23",
706	"#24",
707	"#25",
708	"#26",
709	"#27",
710	"#28",
711	"#29",
712	"#30",
713	"#31",
714	"#32",
715	"#33",
716	"#34",
717	"#35",
718	"#36",
719	"#37",
720	"#38",
721	"#39",
722	"#40",
723	"#41",
724	"#42",
725	"#43",
726	"#44",
727	"#45",
728	"#46",
729	"#47",
730	"#48",
731	"#49",
732	"#50",
733	"#51",
734	"#52",
735	"#53",
736	"#54",
737	"#55",
738	"#56",
739	"#57",
740	"#58",
741	"#59",
742	"#60",
743	"#61",
744	"#62",
745	"#63",
746	"#64",
747	"#65",
748	"#66",
749	"#67",
750	"#68",
751	"#69",
752	"#70",
753	"#71",
754	"#72",
755	"#73",
756	"#74",
757	"#75",
758	"#76",
759	"#77",
760	"#78",
761	"#79",
762	"#80",
763	"#81",
764	"#82",
765	"#83",
766	"#84",
767	"#85",
768	"#86",
769	"#87",
770	"#88",
771	"#89",
772	"#80",
773	"#91",
774	"#92",
775	"#93",
776	"#94",
777	"#95",
778	"#96",
779	"#97",
780	"#98",
781	"#99",
782	"#100",
783	"#101",
784	"#102",
785	"#103",
786	"#104",
787	"#105",
788	"#106",
789	"#107",
790	"#108",
791	"#109",
792	"#110",
793	"#111",
794	"#112",
795	"#113",
796	"#114",
797	"#115",
798	"#116",
799	"#117",
800	"#118",
801	"#119",
802	"#120",
803	"#121",
804	"#122",
805	"#123",
806	"#124",
807	"#125",
808	"#126",
809	"#127",
810	"echo",
811	"echo reply",
812	"multicast listener query",
813	"MLDv1 listener report",
814	"MLDv1 listener done",
815	"router solicitation",
816	"router advertisement",
817	"neighbor solicitation",
818	"neighbor advertisement",
819	"redirect",
820	"router renumbering",
821	"node information request",
822	"node information reply",
823	"inverse neighbor solicitation",
824	"inverse neighbor advertisement",
825	"MLDv2 listener report",
826	"#144",
827	"#145",
828	"#146",
829	"#147",
830	"#148",
831	"#149",
832	"#150",
833	"#151",
834	"#152",
835	"#153",
836	"#154",
837	"#155",
838	"#156",
839	"#157",
840	"#158",
841	"#159",
842	"#160",
843	"#161",
844	"#162",
845	"#163",
846	"#164",
847	"#165",
848	"#166",
849	"#167",
850	"#168",
851	"#169",
852	"#170",
853	"#171",
854	"#172",
855	"#173",
856	"#174",
857	"#175",
858	"#176",
859	"#177",
860	"#178",
861	"#179",
862	"#180",
863	"#181",
864	"#182",
865	"#183",
866	"#184",
867	"#185",
868	"#186",
869	"#187",
870	"#188",
871	"#189",
872	"#180",
873	"#191",
874	"#192",
875	"#193",
876	"#194",
877	"#195",
878	"#196",
879	"#197",
880	"#198",
881	"#199",
882	"#200",
883	"#201",
884	"#202",
885	"#203",
886	"#204",
887	"#205",
888	"#206",
889	"#207",
890	"#208",
891	"#209",
892	"#210",
893	"#211",
894	"#212",
895	"#213",
896	"#214",
897	"#215",
898	"#216",
899	"#217",
900	"#218",
901	"#219",
902	"#220",
903	"#221",
904	"#222",
905	"#223",
906	"#224",
907	"#225",
908	"#226",
909	"#227",
910	"#228",
911	"#229",
912	"#230",
913	"#231",
914	"#232",
915	"#233",
916	"#234",
917	"#235",
918	"#236",
919	"#237",
920	"#238",
921	"#239",
922	"#240",
923	"#241",
924	"#242",
925	"#243",
926	"#244",
927	"#245",
928	"#246",
929	"#247",
930	"#248",
931	"#249",
932	"#250",
933	"#251",
934	"#252",
935	"#253",
936	"#254",
937	"#255",
938};
939
940/*
941 * Dump ICMP6 statistics.
942 */
943void
944icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
945{
946	struct icmp6stat icmp6stat;
947	int i, first;
948
949	if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat,
950	    sizeof(icmp6stat), kread_counters) != 0)
951		return;
952
953	xo_emit("{T:/%s}:\n", name);
954	xo_open_container(name);
955
956#define	p(f, m) if (icmp6stat.f || sflag <= 1) \
957	xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
958#define	p_5(f, m) if (icmp6stat.f || sflag <= 1) \
959	xo_emit(m, (uintmax_t)icmp6stat.f)
960
961	p(icp6s_error, "\t{:icmp6-calls/%ju} "
962	    "{N:/call%s to icmp6_error}\n");
963	p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} "
964	    "{N:/error%s not generated in response to an icmp6 message}\n");
965	p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} "
966	    "{N:/error%s not generated because of rate limitation}\n");
967#define	NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
968	for (first = 1, i = 0; i < NELEM; i++)
969		if (icmp6stat.icp6s_outhist[i] != 0) {
970			if (first) {
971				xo_open_list("output-histogram");
972				xo_emit("\t{T:Output histogram}:\n");
973				first = 0;
974			}
975			xo_open_instance("output-histogram");
976			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
977			    icmp6names[i],
978			    (uintmax_t)icmp6stat.icp6s_outhist[i]);
979			xo_close_instance("output-histogram");
980		}
981	if (!first)
982		xo_close_list("output-histogram");
983#undef NELEM
984
985	p(icp6s_badcode, "\t{:dropped-bad-code/%ju} "
986	    "{N:/message%s with bad code fields}\n");
987	p(icp6s_tooshort, "\t{:dropped-too-short/%ju} "
988	    "{N:/message%s < minimum length}\n");
989	p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} "
990	    "{N:/bad checksum%s}\n");
991	p(icp6s_badlen, "\t{:dropped-bad-length/%ju} "
992	    "{N:/message%s with bad length}\n");
993#define	NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
994	for (first = 1, i = 0; i < NELEM; i++)
995		if (icmp6stat.icp6s_inhist[i] != 0) {
996			if (first) {
997				xo_open_list("input-histogram");
998				xo_emit("\t{T:Input histogram}:\n");
999				first = 0;
1000			}
1001			xo_open_instance("input-histogram");
1002			xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
1003			    icmp6names[i],
1004			    (uintmax_t)icmp6stat.icp6s_inhist[i]);
1005			xo_close_instance("input-histogram");
1006		}
1007	if (!first)
1008		xo_close_list("input-histogram");
1009#undef NELEM
1010	xo_emit("\t{T:Histogram of error messages to be generated}:\n");
1011	xo_open_container("errors");
1012	p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} "
1013	    "{N:/no route}\n");
1014	p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} "
1015	    "{N:/administratively prohibited}\n");
1016	p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} "
1017	    "{N:/beyond scope}\n");
1018	p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} "
1019	    "{N:/address unreachable}\n");
1020	p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} "
1021	    "{N:/port unreachable}\n");
1022	p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} "
1023	    "{N:/packet too big}\n");
1024	p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} "
1025	    "{N:/time exceed transit}\n");
1026	p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} "
1027	    "{N:/time exceed reassembly}\n");
1028	p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} "
1029	    "{N:/erroneous header field}\n");
1030	p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} "
1031	    "{N:/unrecognized next header}\n");
1032	p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} "
1033	    "{N:/unrecognized option}\n");
1034	p_5(icp6s_oredirect, "\t\t{:redirects/%ju} "
1035	    "{N:/redirect}\n");
1036	p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n");
1037
1038	p(icp6s_reflect, "\t{:reflect/%ju} "
1039	    "{N:/message response%s generated}\n");
1040	p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} "
1041	    "{N:/message%s with too many ND options}\n");
1042	p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} "
1043	    "{N:/message%s with bad ND options}\n");
1044	p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} "
1045	    "{N:/bad neighbor solicitation message%s}\n");
1046	p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} "
1047	    "{N:/bad neighbor advertisement message%s}\n");
1048	p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} "
1049	    "{N:/bad router solicitation message%s}\n");
1050	p(icp6s_badra, "\t{:bad-router-advertisement/%ju} "
1051	    "{N:/bad router advertisement message%s}\n");
1052	p(icp6s_badredirect, "\t{:bad-redirect/%ju} "
1053	    "{N:/bad redirect message%s}\n");
1054	xo_close_container("errors");
1055	p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n");
1056#undef p
1057#undef p_5
1058	xo_close_container(name);
1059}
1060
1061/*
1062 * Dump ICMPv6 per-interface statistics based on RFC 2466.
1063 */
1064void
1065icmp6_ifstats(char *ifname)
1066{
1067	struct in6_ifreq ifr;
1068	int s;
1069
1070#define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1)	\
1071	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f,		\
1072	    plural(ifr.ifr_ifru.ifru_icmp6stat.f))
1073#define	p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1)	\
1074	xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f,		\
1075	    pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
1076
1077	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1078		xo_warn("Warning: socket(AF_INET6)");
1079		return;
1080	}
1081
1082	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1083	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
1084		if (errno != EPFNOSUPPORT)
1085			xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
1086		goto end;
1087	}
1088
1089	xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name);
1090
1091	xo_open_instance("icmp6-interface-statistics");
1092	xo_emit("{ke:name/%s}", ifr.ifr_name);
1093	p(ifs6_in_msg, "\t{:received-packets/%ju} "
1094	    "{N:/total input message%s}\n");
1095	p(ifs6_in_error, "\t{:received-errors/%ju} "
1096	    "{N:/total input error message%s}\n");
1097	p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} "
1098	    "{N:/input destination unreachable error%s}\n");
1099	p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} "
1100	    "{N:/input administratively prohibited error%s}\n");
1101	p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} "
1102	    "{N:/input time exceeded error%s}\n");
1103	p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} "
1104	    "{N:/input parameter problem error%s}\n");
1105	p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} "
1106	    "{N:/input packet too big error%s}\n");
1107	p(ifs6_in_echo, "\t{:received-echo-requests/%ju} "
1108	    "{N:/input echo request%s}\n");
1109	p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} "
1110	    "{N:/input echo repl%s}\n");
1111	p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} "
1112	    "{N:/input router solicitation%s}\n");
1113	p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} "
1114	    "{N:/input router advertisement%s}\n");
1115	p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} "
1116	    "{N:/input neighbor solicitation%s}\n");
1117	p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} "
1118	    "{N:/input neighbor advertisement%s}\n");
1119	p(ifs6_in_redirect, "\t{received-redirects/%ju} "
1120	    "{N:/input redirect%s}\n");
1121	p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} "
1122	    "{N:/input MLD quer%s}\n");
1123	p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} "
1124	    "{N:/input MLD report%s}\n");
1125	p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} "
1126	    "{N:/input MLD done%s}\n");
1127
1128	p(ifs6_out_msg, "\t{:sent-packets/%ju} "
1129	    "{N:/total output message%s}\n");
1130	p(ifs6_out_error, "\t{:sent-errors/%ju} "
1131	    "{N:/total output error message%s}\n");
1132	p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} "
1133	    "{N:/output destination unreachable error%s}\n");
1134	p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} "
1135	    "{N:/output administratively prohibited error%s}\n");
1136	p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} "
1137	    "{N:/output time exceeded error%s}\n");
1138	p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} "
1139	    "{N:/output parameter problem error%s}\n");
1140	p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} "
1141	    "{N:/output packet too big error%s}\n");
1142	p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} "
1143	    "{N:/output echo request%s}\n");
1144	p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} "
1145	    "{N:/output echo repl%s}\n");
1146	p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} "
1147	    "{N:/output router solicitation%s}\n");
1148	p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} "
1149	    "{N:/output router advertisement%s}\n");
1150	p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} "
1151	    "{N:/output neighbor solicitation%s}\n");
1152	p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} "
1153	    "{N:/output neighbor advertisement%s}\n");
1154	p(ifs6_out_redirect, "\t{:sent-redirects/%ju} "
1155	    "{N:/output redirect%s}\n");
1156	p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} "
1157	    "{N:/output MLD quer%s}\n");
1158	p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} "
1159	    "{N:/output MLD report%s}\n");
1160	p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} "
1161	    "{N:/output MLD done%s}\n");
1162
1163end:
1164	xo_close_instance("icmp6-interface-statistics");
1165	close(s);
1166#undef p
1167}
1168
1169/*
1170 * Dump PIM statistics structure.
1171 */
1172void
1173pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
1174{
1175	struct pim6stat pim6stat;
1176
1177	if (fetch_stats("net.inet6.pim.stats", off, &pim6stat,
1178	    sizeof(pim6stat), kread) != 0)
1179		return;
1180
1181	xo_emit("{T:/%s}:\n", name);
1182	xo_open_container(name);
1183
1184#define	p(f, m) if (pim6stat.f || sflag <= 1) \
1185	xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
1186
1187	p(pim6s_rcv_total, "\t{:received-packets/%ju} "
1188	    "{N:/message%s received}\n");
1189	p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} "
1190	    "{N:/message%s received with too few bytes}\n");
1191	p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} "
1192	    "{N:/message%s received with bad checksum}\n");
1193	p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} "
1194	    "{N:/message%s received with bad version}\n");
1195	p(pim6s_rcv_registers, "\t{:received-registers/%ju} "
1196	    "{N:/register%s received}\n");
1197	p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} "
1198	    "{N:/bad register%s received}\n");
1199	p(pim6s_snd_registers, "\t{:sent-registers/%ju} "
1200	    "{N:/register%s sent}\n");
1201#undef p
1202	xo_close_container(name);
1203}
1204
1205/*
1206 * Dump raw ip6 statistics structure.
1207 */
1208void
1209rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
1210{
1211	struct rip6stat rip6stat;
1212	u_quad_t delivered;
1213
1214	if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat,
1215	    sizeof(rip6stat), kread_counters) != 0)
1216		return;
1217
1218	xo_emit("{T:/%s}:\n", name);
1219	xo_open_container(name);
1220
1221#define	p(f, m) if (rip6stat.f || sflag <= 1) \
1222	xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1223
1224	p(rip6s_ipackets, "\t{:received-packets/%ju} "
1225	    "{N:/message%s received}\n");
1226	p(rip6s_isum, "\t{:input-checksum-computation/%ju} "
1227	    "{N:/checksum calculation%s on inbound}\n");
1228	p(rip6s_badsum, "\t{:received-bad-checksum/%ju} "
1229	    "{N:/message%s with bad checksum}\n");
1230	p(rip6s_nosock, "\t{:dropped-no-socket/%ju} "
1231	    "{N:/message%s dropped due to no socket}\n");
1232	p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} "
1233	    "{N:/multicast message%s dropped due to no socket}\n");
1234	p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} "
1235	    "{N:/message%s dropped due to full socket buffers}\n");
1236	delivered = rip6stat.rip6s_ipackets -
1237		    rip6stat.rip6s_badsum -
1238		    rip6stat.rip6s_nosock -
1239		    rip6stat.rip6s_nosockmcast -
1240		    rip6stat.rip6s_fullsock;
1241	if (delivered || sflag <= 1)
1242		xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n",
1243		    (uintmax_t)delivered);
1244	p(rip6s_opackets, "\t{:sent-packets/%ju} "
1245	    "{N:/datagram%s output}\n");
1246#undef p
1247	xo_close_container(name);
1248}
1249
1250/*
1251 * Pretty print an Internet address (net address + port).
1252 * Take numeric_addr and numeric_port into consideration.
1253 */
1254#define	GETSERVBYPORT6(port, proto, ret)\
1255{\
1256	if (strcmp((proto), "tcp6") == 0)\
1257		(ret) = getservbyport((int)(port), "tcp");\
1258	else if (strcmp((proto), "udp6") == 0)\
1259		(ret) = getservbyport((int)(port), "udp");\
1260	else\
1261		(ret) = getservbyport((int)(port), (proto));\
1262};
1263
1264void
1265inet6print(const char *container, struct in6_addr *in6, int port,
1266    const char *proto, int numeric)
1267{
1268	struct servent *sp = 0;
1269	char line[80], *cp;
1270	int width;
1271	size_t alen, plen;
1272
1273	if (container)
1274		xo_open_container(container);
1275
1276	snprintf(line, sizeof(line), "%.*s.",
1277	    Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
1278	    inet6name(in6));
1279	alen = strlen(line);
1280	cp = line + alen;
1281	if (!numeric && port)
1282		GETSERVBYPORT6(port, proto, sp);
1283	if (sp || port == 0)
1284		snprintf(cp, sizeof(line) - alen,
1285		    "%.15s", sp ? sp->s_name : "*");
1286	else
1287		snprintf(cp, sizeof(line) - alen,
1288		    "%d", ntohs((u_short)port));
1289	width = Wflag ? 45 : Aflag ? 18 : 22;
1290
1291	xo_emit("{d:target/%-*.*s} ", width, width, line);
1292
1293	plen = strlen(cp);
1294	alen--;
1295	xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
1296	    plen, cp);
1297
1298	if (container)
1299		xo_close_container(container);
1300}
1301
1302/*
1303 * Construct an Internet address representation.
1304 * If the numeric_addr has been supplied, give
1305 * numeric value, otherwise try for symbolic name.
1306 */
1307
1308char *
1309inet6name(struct in6_addr *ia6)
1310{
1311	struct sockaddr_in6 sin6;
1312	char hbuf[NI_MAXHOST], *cp;
1313	static char line[NI_MAXHOST];
1314	static char domain[MAXHOSTNAMELEN];
1315	static int first = 1;
1316	int flags, error;
1317
1318	if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
1319		strcpy(line, "*");
1320		return (line);
1321	}
1322	if (first && !numeric_addr) {
1323		first = 0;
1324		if (gethostname(domain, sizeof(domain)) == 0 &&
1325		    (cp = strchr(domain, '.')))
1326			strlcpy(domain, cp + 1, sizeof(domain));
1327		else
1328			domain[0] = 0;
1329	}
1330	memset(&sin6, 0, sizeof(sin6));
1331	memcpy(&sin6.sin6_addr, ia6, sizeof(*ia6));
1332	sin6.sin6_family = AF_INET6;
1333	/* XXX: ia6.s6_addr[2] can contain scopeid. */
1334	in6_fillscopeid(&sin6);
1335	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
1336	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
1337	    sizeof(hbuf), NULL, 0, flags);
1338	if (error == 0) {
1339		if ((flags & NI_NUMERICHOST) == 0 &&
1340		    (cp = strchr(hbuf, '.')) &&
1341		    !strcmp(cp + 1, domain))
1342			*cp = 0;
1343		strlcpy(line, hbuf, sizeof(line));
1344	} else {
1345		/* XXX: this should not happen. */
1346		snprintf(line, sizeof(line), "%s",
1347			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
1348				sizeof(ntop_buf)));
1349	}
1350	return (line);
1351}
1352#endif /*INET6*/
1353