xref: /netbsd-src/usr.bin/netstat/inet6.c (revision 481fca6e59249d8ffcf24fef7cfbe7b131bfb080)
1 /*	$NetBSD: inet6.c,v 1.11 2000/07/13 03:53:03 itojun Exp $	*/
2 /*	BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1983, 1988, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  */
65 
66 #include <sys/cdefs.h>
67 #ifndef lint
68 #if 0
69 static char sccsid[] = "@(#)inet.c	8.4 (Berkeley) 4/20/94";
70 #else
71 __RCSID("$NetBSD: inet6.c,v 1.11 2000/07/13 03:53:03 itojun Exp $");
72 #endif
73 #endif /* not lint */
74 
75 #include <sys/param.h>
76 #include <sys/socket.h>
77 #include <sys/socketvar.h>
78 #include <sys/ioctl.h>
79 #include <sys/mbuf.h>
80 #include <sys/protosw.h>
81 
82 #include <net/route.h>
83 #include <net/if.h>
84 #include <netinet/in.h>
85 #include <netinet/ip6.h>
86 #include <netinet/icmp6.h>
87 #include <netinet/in_systm.h>
88 #ifndef TCP6
89 #include <netinet/ip.h>
90 #include <netinet/ip_var.h>
91 #endif
92 #include <netinet6/ip6_var.h>
93 #include <netinet6/in6_pcb.h>
94 #include <netinet6/in6_var.h>
95 #include <netinet6/ip6_var.h>
96 #ifdef TCP6
97 #include <netinet6/tcp6.h>
98 #include <netinet6/tcp6_seq.h>
99 #define TCP6STATES
100 #include <netinet6/tcp6_fsm.h>
101 #define TCP6TIMERS
102 #include <netinet6/tcp6_timer.h>
103 #include <netinet6/tcp6_var.h>
104 #include <netinet6/tcp6_debug.h>
105 #else
106 #include <netinet/tcp.h>
107 #include <netinet/tcpip.h>
108 #include <netinet/tcp_seq.h>
109 /*#define TCPSTATES*/
110 #include <netinet/tcp_fsm.h>
111 extern char *tcpstates[];
112 /*#define	TCPTIMERS*/
113 #include <netinet/tcp_timer.h>
114 #include <netinet/tcp_var.h>
115 #include <netinet/tcp_debug.h>
116 #endif /*TCP6*/
117 #include <netinet6/udp6.h>
118 #include <netinet6/udp6_var.h>
119 #include <netinet6/pim6_var.h>
120 
121 #include <arpa/inet.h>
122 #if 0
123 #include "gethostbyname2.h"
124 #endif
125 #include <netdb.h>
126 
127 #include <stdio.h>
128 #include <string.h>
129 #include <unistd.h>
130 #include "netstat.h"
131 
132 #ifdef INET6
133 
134 struct	in6pcb in6pcb;
135 #ifdef TCP6
136 struct	tcp6cb tcp6cb;
137 #else
138 struct	tcpcb tcpcb;
139 #endif
140 struct	socket sockb;
141 
142 char	*inet6name __P((struct in6_addr *));
143 void	inet6print __P((struct in6_addr *, int, char *));
144 
145 /*
146  * Print a summary of connections related to an Internet
147  * protocol.  For TCP, also give state of connection.
148  * Listening processes (aflag) are suppressed unless the
149  * -a (all) flag is specified.
150  */
151 void
152 ip6protopr(off, name)
153 	u_long off;
154 	char *name;
155 {
156 	struct in6pcb cb;
157 	register struct in6pcb *prev, *next;
158 	int istcp;
159 	static int first = 1;
160 
161 	if (off == 0)
162 		return;
163 	istcp = strcmp(name, "tcp6") == 0;
164 	kread(off, (char *)&cb, sizeof (struct in6pcb));
165 	in6pcb = cb;
166 	prev = (struct in6pcb *)off;
167 	if (in6pcb.in6p_next == (struct in6pcb *)off)
168 		return;
169 	while (in6pcb.in6p_next != (struct in6pcb *)off) {
170 		next = in6pcb.in6p_next;
171 		kread((u_long)next, (char *)&in6pcb, sizeof (in6pcb));
172 		if (in6pcb.in6p_prev != prev) {
173 			printf("???\n");
174 			break;
175 		}
176 		if (!aflag && IN6_IS_ADDR_UNSPECIFIED(&in6pcb.in6p_laddr)) {
177 			prev = next;
178 			continue;
179 		}
180 		kread((u_long)in6pcb.in6p_socket, (char *)&sockb, sizeof (sockb));
181 		if (istcp) {
182 #ifdef TCP6
183 			kread((u_long)in6pcb.in6p_ppcb,
184 			    (char *)&tcp6cb, sizeof (tcp6cb));
185 #else
186 			kread((u_long)in6pcb.in6p_ppcb,
187 			    (char *)&tcpcb, sizeof (tcpcb));
188 #endif
189 		}
190 		if (first) {
191 			printf("Active Internet6 connections");
192 			if (aflag)
193 				printf(" (including servers)");
194 			putchar('\n');
195 			if (Aflag)
196 				printf("%-8.8s ", "PCB");
197 			printf(Aflag ?
198 				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
199 				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
200 				"Proto", "Recv-Q", "Send-Q",
201 				"Local Address", "Foreign Address", "(state)");
202 			first = 0;
203 		}
204 		if (Aflag) {
205 			if (istcp)
206 				printf("%8p ", in6pcb.in6p_ppcb);
207 			else
208 				printf("%8p ", next);
209 		}
210 		printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
211 			sockb.so_snd.sb_cc);
212 		/* xxx */
213 		inet6print(&in6pcb.in6p_laddr, (int)in6pcb.in6p_lport, name);
214 		inet6print(&in6pcb.in6p_faddr, (int)in6pcb.in6p_fport, name);
215 		if (istcp) {
216 #ifdef TCP6
217 			if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
218 				printf(" %d", tcp6cb.t_state);
219 			else
220 				printf(" %s", tcp6states[tcp6cb.t_state]);
221 #else
222 			if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
223 				printf(" %d", tcpcb.t_state);
224 			else
225 				printf(" %s", tcpstates[tcpcb.t_state]);
226 #endif
227 		}
228 		putchar('\n');
229 		prev = next;
230 	}
231 }
232 
233 #ifdef TCP6
234 /*
235  * Dump TCP6 statistics structure.
236  */
237 void
238 tcp6_stats(off, name)
239 	u_long off;
240 	char *name;
241 {
242 	struct tcp6stat tcp6stat;
243 
244 	if (off == 0)
245 		return;
246 	printf ("%s:\n", name);
247 	kread(off, (char *)&tcp6stat, sizeof (tcp6stat));
248 
249 #define	p(f, m) if (tcp6stat.f || sflag <= 1) \
250     printf(m, tcp6stat.f, plural(tcp6stat.f))
251 #define	p2(f1, f2, m) if (tcp6stat.f1 || tcp6stat.f2 || sflag <= 1) \
252     printf(m, tcp6stat.f1, plural(tcp6stat.f1), tcp6stat.f2, plural(tcp6stat.f2))
253 #define	p3(f, m) if (tcp6stat.f || sflag <= 1) \
254     printf(m, tcp6stat.f, plurales(tcp6stat.f))
255 
256 	p(tcp6s_sndtotal, "\t%ld packet%s sent\n");
257 	p2(tcp6s_sndpack,tcp6s_sndbyte,
258 		"\t\t%ld data packet%s (%ld byte%s)\n");
259 	p2(tcp6s_sndrexmitpack, tcp6s_sndrexmitbyte,
260 		"\t\t%ld data packet%s (%ld byte%s) retransmitted\n");
261 	p2(tcp6s_sndacks, tcp6s_delack,
262 		"\t\t%ld ack-only packet%s (%ld packet%s delayed)\n");
263 	p(tcp6s_sndurg, "\t\t%ld URG only packet%s\n");
264 	p(tcp6s_sndprobe, "\t\t%ld window probe packet%s\n");
265 	p(tcp6s_sndwinup, "\t\t%ld window update packet%s\n");
266 	p(tcp6s_sndctrl, "\t\t%ld control packet%s\n");
267 	p(tcp6s_rcvtotal, "\t%ld packet%s received\n");
268 	p2(tcp6s_rcvackpack, tcp6s_rcvackbyte, "\t\t%ld ack%s (for %ld byte%s)\n");
269 	p(tcp6s_rcvdupack, "\t\t%ld duplicate ack%s\n");
270 	p(tcp6s_rcvacktoomuch, "\t\t%ld ack%s for unsent data\n");
271 	p2(tcp6s_rcvpack, tcp6s_rcvbyte,
272 		"\t\t%ld packet%s (%ld byte%s) received in-sequence\n");
273 	p2(tcp6s_rcvduppack, tcp6s_rcvdupbyte,
274 		"\t\t%ld completely duplicate packet%s (%ld byte%s)\n");
275 	p(tcp6s_pawsdrop, "\t\t%ld old duplicate packet%s\n");
276 	p2(tcp6s_rcvpartduppack, tcp6s_rcvpartdupbyte,
277 		"\t\t%ld packet%s with some dup. data (%ld byte%s duped)\n");
278 	p2(tcp6s_rcvoopack, tcp6s_rcvoobyte,
279 		"\t\t%ld out-of-order packet%s (%ld byte%s)\n");
280 	p2(tcp6s_rcvpackafterwin, tcp6s_rcvbyteafterwin,
281 		"\t\t%ld packet%s (%ld byte%s) of data after window\n");
282 	p(tcp6s_rcvwinprobe, "\t\t%ld window probe%s\n");
283 	p(tcp6s_rcvwinupd, "\t\t%ld window update packet%s\n");
284 	p(tcp6s_rcvafterclose, "\t\t%ld packet%s received after close\n");
285 	p(tcp6s_rcvbadsum, "\t\t%ld discarded for bad checksum%s\n");
286 	p(tcp6s_rcvbadoff, "\t\t%ld discarded for bad header offset field%s\n");
287 	p(tcp6s_rcvshort, "\t\t%ld discarded because packet%s too short\n");
288 	p(tcp6s_connattempt, "\t%ld connection request%s\n");
289 	p(tcp6s_accepts, "\t%ld connection accept%s\n");
290 	p(tcp6s_badsyn, "\t%ld bad connection attempt%s\n");
291 	p(tcp6s_connects, "\t%ld connection%s established (including accepts)\n");
292 	p2(tcp6s_closed, tcp6s_drops,
293 		"\t%ld connection%s closed (including %ld drop%s)\n");
294 	p(tcp6s_conndrops, "\t%ld embryonic connection%s dropped\n");
295 	p2(tcp6s_rttupdated, tcp6s_segstimed,
296 		"\t%ld segment%s updated rtt (of %ld attempt%s)\n");
297 	p(tcp6s_rexmttimeo, "\t%ld retransmit timeout%s\n");
298 	p(tcp6s_timeoutdrop, "\t\t%ld connection%s dropped by rexmit timeout\n");
299 	p(tcp6s_persisttimeo, "\t%ld persist timeout%s\n");
300 	p(tcp6s_persistdrop, "\t%ld connection%s timed out in persist\n");
301 	p(tcp6s_keeptimeo, "\t%ld keepalive timeout%s\n");
302 	p(tcp6s_keepprobe, "\t\t%ld keepalive probe%s sent\n");
303 	p(tcp6s_keepdrops, "\t\t%ld connection%s dropped by keepalive\n");
304 	p(tcp6s_predack, "\t%ld correct ACK header prediction%s\n");
305 	p(tcp6s_preddat, "\t%ld correct data packet header prediction%s\n");
306 	p3(tcp6s_pcbcachemiss, "\t%ld PCB cache miss%s\n");
307 #undef p
308 #undef p2
309 #undef p3
310 }
311 #endif
312 
313 /*
314  * Dump UDP6 statistics structure.
315  */
316 void
317 udp6_stats(off, name)
318 	u_long off;
319 	char *name;
320 {
321 	struct udp6stat udp6stat;
322 	u_quad_t delivered;
323 
324 	if (off == 0)
325 		return;
326 	kread(off, (char *)&udp6stat, sizeof (udp6stat));
327 	printf("%s:\n", name);
328 #define	p(f, m) if (udp6stat.f || sflag <= 1) \
329     printf(m, (unsigned long long)udp6stat.f, plural(udp6stat.f))
330 #define	p1(f, m) if (udp6stat.f || sflag <= 1) \
331     printf(m, (unsigned long long)udp6stat.f)
332 	p(udp6s_ipackets, "\t%llu datagram%s received\n");
333 	p1(udp6s_hdrops, "\t%llu with incomplete header\n");
334 	p1(udp6s_badlen, "\t%llu with bad data length field\n");
335 	p1(udp6s_badsum, "\t%llu with bad checksum\n");
336 	p1(udp6s_nosum, "\t%llu with no checksum\n");
337 	p1(udp6s_noport, "\t%llu dropped due to no socket\n");
338 	p(udp6s_noportmcast,
339 	    "\t%llu multicast datagram%s dropped due to no socket\n");
340 	p1(udp6s_fullsock, "\t%llu dropped due to full socket buffers\n");
341 	delivered = udp6stat.udp6s_ipackets -
342 		    udp6stat.udp6s_hdrops -
343 		    udp6stat.udp6s_badlen -
344 		    udp6stat.udp6s_badsum -
345 		    udp6stat.udp6s_noport -
346 		    udp6stat.udp6s_noportmcast -
347 		    udp6stat.udp6s_fullsock;
348 	if (delivered || sflag <= 1)
349 		printf("\t%llu delivered\n", (unsigned long long)delivered);
350 	p(udp6s_opackets, "\t%llu datagram%s output\n");
351 #undef p
352 #undef p1
353 }
354 
355 static	char *ip6nh[] = {
356 	"hop by hop",
357 	"ICMP",
358 	"IGMP",
359 	"#3",
360 	"IP",
361 	"#5",
362 	"TCP",
363 	"#7",
364 	"#8",
365 	"#9",
366 	"#10",
367 	"#11",
368 	"#12",
369 	"#13",
370 	"#14",
371 	"#15",
372 	"#16",
373 	"UDP",
374 	"#18",
375 	"#19",
376 	"#20",
377 	"#21",
378 	"IDP",
379 	"#23",
380 	"#24",
381 	"#25",
382 	"#26",
383 	"#27",
384 	"#28",
385 	"TP",
386 	"#30",
387 	"#31",
388 	"#32",
389 	"#33",
390 	"#34",
391 	"#35",
392 	"#36",
393 	"#37",
394 	"#38",
395 	"#39",
396 	"#40",
397 	"IP6",
398 	"#42",
399 	"routing",
400 	"fragment",
401 	"#45",
402 	"#46",
403 	"#47",
404 	"#48",
405 	"#49",
406 	"ESP",
407 	"AH",
408 	"#52",
409 	"#53",
410 	"#54",
411 	"#55",
412 	"#56",
413 	"#57",
414 	"ICMP6",
415 	"no next header",
416 	"destination option",
417 	"#61",
418 	"#62",
419 	"#63",
420 	"#64",
421 	"#65",
422 	"#66",
423 	"#67",
424 	"#68",
425 	"#69",
426 	"#70",
427 	"#71",
428 	"#72",
429 	"#73",
430 	"#74",
431 	"#75",
432 	"#76",
433 	"#77",
434 	"#78",
435 	"#79",
436 	"ISOIP",
437 	"#81",
438 	"#82",
439 	"#83",
440 	"#84",
441 	"#85",
442 	"#86",
443 	"#87",
444 	"#88",
445 	"OSPF",
446 	"#80",
447 	"#91",
448 	"#92",
449 	"#93",
450 	"#94",
451 	"#95",
452 	"#96",
453 	"Ethernet",
454 	"#98",
455 	"#99",
456 	"#100",
457 	"#101",
458 	"#102",
459 	"PIM",
460 	"#104",
461 	"#105",
462 	"#106",
463 	"#107",
464 	"#108",
465 	"#109",
466 	"#110",
467 	"#111",
468 	"#112",
469 	"#113",
470 	"#114",
471 	"#115",
472 	"#116",
473 	"#117",
474 	"#118",
475 	"#119",
476 	"#120",
477 	"#121",
478 	"#122",
479 	"#123",
480 	"#124",
481 	"#125",
482 	"#126",
483 	"#127",
484 	"#128",
485 	"#129",
486 	"#130",
487 	"#131",
488 	"#132",
489 	"#133",
490 	"#134",
491 	"#135",
492 	"#136",
493 	"#137",
494 	"#138",
495 	"#139",
496 	"#140",
497 	"#141",
498 	"#142",
499 	"#143",
500 	"#144",
501 	"#145",
502 	"#146",
503 	"#147",
504 	"#148",
505 	"#149",
506 	"#150",
507 	"#151",
508 	"#152",
509 	"#153",
510 	"#154",
511 	"#155",
512 	"#156",
513 	"#157",
514 	"#158",
515 	"#159",
516 	"#160",
517 	"#161",
518 	"#162",
519 	"#163",
520 	"#164",
521 	"#165",
522 	"#166",
523 	"#167",
524 	"#168",
525 	"#169",
526 	"#170",
527 	"#171",
528 	"#172",
529 	"#173",
530 	"#174",
531 	"#175",
532 	"#176",
533 	"#177",
534 	"#178",
535 	"#179",
536 	"#180",
537 	"#181",
538 	"#182",
539 	"#183",
540 	"#184",
541 	"#185",
542 	"#186",
543 	"#187",
544 	"#188",
545 	"#189",
546 	"#180",
547 	"#191",
548 	"#192",
549 	"#193",
550 	"#194",
551 	"#195",
552 	"#196",
553 	"#197",
554 	"#198",
555 	"#199",
556 	"#200",
557 	"#201",
558 	"#202",
559 	"#203",
560 	"#204",
561 	"#205",
562 	"#206",
563 	"#207",
564 	"#208",
565 	"#209",
566 	"#210",
567 	"#211",
568 	"#212",
569 	"#213",
570 	"#214",
571 	"#215",
572 	"#216",
573 	"#217",
574 	"#218",
575 	"#219",
576 	"#220",
577 	"#221",
578 	"#222",
579 	"#223",
580 	"#224",
581 	"#225",
582 	"#226",
583 	"#227",
584 	"#228",
585 	"#229",
586 	"#230",
587 	"#231",
588 	"#232",
589 	"#233",
590 	"#234",
591 	"#235",
592 	"#236",
593 	"#237",
594 	"#238",
595 	"#239",
596 	"#240",
597 	"#241",
598 	"#242",
599 	"#243",
600 	"#244",
601 	"#245",
602 	"#246",
603 	"#247",
604 	"#248",
605 	"#249",
606 	"#250",
607 	"#251",
608 	"#252",
609 	"#253",
610 	"#254",
611 	"#255",
612 };
613 
614 /*
615  * Dump IP6 statistics structure.
616  */
617 void
618 ip6_stats(off, name)
619 	u_long off;
620 	char *name;
621 {
622 	struct ip6stat ip6stat;
623 	int first, i;
624 
625 	if (off == 0)
626 		return;
627 
628 	kread(off, (char *)&ip6stat, sizeof (ip6stat));
629 	printf("%s:\n", name);
630 
631 #define	p(f, m) if (ip6stat.f || sflag <= 1) \
632     printf(m, (unsigned long long)ip6stat.f, plural(ip6stat.f))
633 #define	p1(f, m) if (ip6stat.f || sflag <= 1) \
634     printf(m, (unsigned long long)ip6stat.f)
635 
636 	p(ip6s_total, "\t%llu total packet%s received\n");
637 	p1(ip6s_toosmall, "\t%llu with size smaller than minimum\n");
638 	p1(ip6s_tooshort, "\t%llu with data size < data length\n");
639 	p1(ip6s_badoptions, "\t%llu with bad options\n");
640 	p1(ip6s_badvers, "\t%llu with incorrect version number\n");
641 	p(ip6s_fragments, "\t%llu fragment%s received\n");
642 	p(ip6s_fragdropped,
643 	    "\t%llu fragment%s dropped (dup or out of space)\n");
644 	p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n");
645 	p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n");
646 	p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n");
647 	p(ip6s_delivered, "\t%llu packet%s for this host\n");
648 	p(ip6s_forward, "\t%llu packet%s forwarded\n");
649 	p(ip6s_cantforward, "\t%llu packet%s not forwardable\n");
650 	p(ip6s_redirectsent, "\t%llu redirect%s sent\n");
651 	p(ip6s_localout, "\t%llu packet%s sent from this host\n");
652 	p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n");
653 	p(ip6s_odropped,
654 	    "\t%llu output packet%s dropped due to no bufs, etc.\n");
655 	p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n");
656 	p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n");
657 	p(ip6s_ofragments, "\t%llu fragment%s created\n");
658 	p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n");
659 	p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n");
660 	p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n");
661 	for (first = 1, i = 0; i < 256; i++)
662 		if (ip6stat.ip6s_nxthist[i] != 0) {
663 			if (first) {
664 				printf("\tInput histogram:\n");
665 				first = 0;
666 			}
667 			printf("\t\t%s: %llu\n", ip6nh[i],
668 			       (unsigned long long)ip6stat.ip6s_nxthist[i]);
669 		}
670 	printf("\tMbuf statics:\n");
671 	printf("\t\t%llu one mbuf\n", (unsigned long long)ip6stat.ip6s_m1);
672 	for (first = 1, i = 0; i < 32; i++) {
673 		char ifbuf[IFNAMSIZ];
674 		if (ip6stat.ip6s_m2m[i] != 0) {
675 			if (first) {
676 				printf("\t\ttwo or more mbuf:\n");
677 				first = 0;
678 			}
679 			printf("\t\t\t%s = %llu\n",
680 			       if_indextoname(i, ifbuf),
681 			       (unsigned long long)ip6stat.ip6s_m2m[i]);
682 		}
683 	}
684 	printf("\t\t%llu one ext mbuf\n",
685 	    (unsigned long long)ip6stat.ip6s_mext1);
686 	printf("\t\t%llu two or more ext mbuf\n",
687 	    (unsigned long long)ip6stat.ip6s_mext2m);
688 	p(ip6s_exthdrtoolong,
689 	    "\t%llu packet%s whose headers are not continuous\n");
690 	p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n");
691 	p(ip6s_toomanyhdr,
692 	    "\t%llu packet%s discarded due to too many headers\n");
693 
694 	/* for debugging source address selection */
695 #define PRINT_SCOPESTAT(s,i) do {\
696 		switch(i) { /* XXX hardcoding in each case */\
697 		case 1:\
698 			p(s, "\t\t%llu node-local%s\n");\
699 			break;\
700 		case 2:\
701 			p(s, "\t\t%llu link-local%s\n");\
702 			break;\
703 		case 5:\
704 			p(s, "\t\t%llu site-local%s\n");\
705 			break;\
706 		case 14:\
707 			p(s, "\t\t%llu global%s\n");\
708 			break;\
709 		default:\
710 			printf("\t\t%llu addresses scope=%x\n",\
711 			       (unsigned long long)ip6stat.s, i);\
712 		}\
713 	} while(0);
714 
715 	p(ip6s_sources_none,
716 	  "\t%llu failure%s of source address selection\n");
717 	for (first = 1, i = 0; i < 16; i++) {
718 		if (ip6stat.ip6s_sources_sameif[i]) {
719 			if (first) {
720 				printf("\tsource addresses on an outgoing I/F\n");
721 				first = 0;
722 			}
723 			PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
724 		}
725 	}
726 	for (first = 1, i = 0; i < 16; i++) {
727 		if (ip6stat.ip6s_sources_otherif[i]) {
728 			if (first) {
729 				printf("\tsource addresses on a non-outgoing I/F\n");
730 				first = 0;
731 			}
732 			PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
733 		}
734 	}
735 	for (first = 1, i = 0; i < 16; i++) {
736 		if (ip6stat.ip6s_sources_samescope[i]) {
737 			if (first) {
738 				printf("\tsource addresses of same scope\n");
739 				first = 0;
740 			}
741 			PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
742 		}
743 	}
744 	for (first = 1, i = 0; i < 16; i++) {
745 		if (ip6stat.ip6s_sources_otherscope[i]) {
746 			if (first) {
747 				printf("\tsource addresses of a different scope\n");
748 				first = 0;
749 			}
750 			PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
751 		}
752 	}
753 	for (first = 1, i = 0; i < 16; i++) {
754 		if (ip6stat.ip6s_sources_deprecated[i]) {
755 			if (first) {
756 				printf("\tdeprecated source addresses\n");
757 				first = 0;
758 			}
759 			PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
760 		}
761 	}
762 
763 	p1(ip6s_forward_cachehit, "\t%llu forward cache hit\n");
764 	p1(ip6s_forward_cachemiss, "\t%llu forward cache miss\n");
765 #undef p
766 #undef p1
767 }
768 
769 /*
770  * Dump IPv6 per-interface statistics based on RFC 2465.
771  */
772 void
773 ip6_ifstats(ifname)
774 	char *ifname;
775 {
776 	struct in6_ifreq ifr;
777 	int s;
778 #define	p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
779     printf(m, (unsigned long long)ifr.ifr_ifru.ifru_stat.f, \
780 	plural(ifr.ifr_ifru.ifru_stat.f))
781 #define	p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
782     printf(m, (unsigned long long)ip6stat.f)
783 
784 	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
785 		perror("Warning: socket(AF_INET6)");
786 		return;
787 	}
788 
789 	strcpy(ifr.ifr_name, ifname);
790 	printf("ip6 on %s:\n", ifr.ifr_name);
791 
792 	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
793 		perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
794 		goto end;
795 	}
796 
797 	p(ifs6_in_receive, "\t%llu total input datagram%s\n");
798 	p(ifs6_in_hdrerr, "\t%llu datagram%s with invalid header received\n");
799 	p(ifs6_in_toobig, "\t%llu datagram%s exceeded MTU received\n");
800 	p(ifs6_in_noroute, "\t%llu datagram%s with no route received\n");
801 	p(ifs6_in_addrerr, "\t%llu datagram%s with invalid dst received\n");
802 	p(ifs6_in_truncated, "\t%llu truncated datagram%s received\n");
803 	p(ifs6_in_protounknown, "\t%llu datagram%s with unknown proto received\n");
804 	p(ifs6_in_discard, "\t%llu input datagram%s discarded\n");
805 	p(ifs6_in_deliver,
806 	  "\t%llu datagram%s delivered to an upper layer protocol\n");
807 	p(ifs6_out_forward, "\t%llu datagram%s forwarded to this interface\n");
808 	p(ifs6_out_request,
809 	  "\t%llu datagram%s sent from an upper layer protocol\n");
810 	p(ifs6_out_discard, "\t%llu total discarded output datagram%s\n");
811 	p(ifs6_out_fragok, "\t%llu output datagram%s fragmented\n");
812 	p(ifs6_out_fragfail, "\t%llu output datagram%s failed on fragment\n");
813 	p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n");
814 	p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n");
815 	p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n");
816 	p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n");
817 	p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n");
818 	p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n");
819 
820   end:
821 	close(s);
822 
823 #undef p
824 #undef p_5
825 }
826 
827 static	char *icmp6names[] = {
828 	"#0",
829 	"unreach",
830 	"packet too big",
831 	"time exceed",
832 	"parameter problem",
833 	"#5",
834 	"#6",
835 	"#7",
836 	"#8",
837 	"#9",
838 	"#10",
839 	"#11",
840 	"#12",
841 	"#13",
842 	"#14",
843 	"#15",
844 	"#16",
845 	"#17",
846 	"#18",
847 	"#19",
848 	"#20",
849 	"#21",
850 	"#22",
851 	"#23",
852 	"#24",
853 	"#25",
854 	"#26",
855 	"#27",
856 	"#28",
857 	"#29",
858 	"#30",
859 	"#31",
860 	"#32",
861 	"#33",
862 	"#34",
863 	"#35",
864 	"#36",
865 	"#37",
866 	"#38",
867 	"#39",
868 	"#40",
869 	"#41",
870 	"#42",
871 	"#43",
872 	"#44",
873 	"#45",
874 	"#46",
875 	"#47",
876 	"#48",
877 	"#49",
878 	"#50",
879 	"#51",
880 	"#52",
881 	"#53",
882 	"#54",
883 	"#55",
884 	"#56",
885 	"#57",
886 	"#58",
887 	"#59",
888 	"#60",
889 	"#61",
890 	"#62",
891 	"#63",
892 	"#64",
893 	"#65",
894 	"#66",
895 	"#67",
896 	"#68",
897 	"#69",
898 	"#70",
899 	"#71",
900 	"#72",
901 	"#73",
902 	"#74",
903 	"#75",
904 	"#76",
905 	"#77",
906 	"#78",
907 	"#79",
908 	"#80",
909 	"#81",
910 	"#82",
911 	"#83",
912 	"#84",
913 	"#85",
914 	"#86",
915 	"#87",
916 	"#88",
917 	"#89",
918 	"#80",
919 	"#91",
920 	"#92",
921 	"#93",
922 	"#94",
923 	"#95",
924 	"#96",
925 	"#97",
926 	"#98",
927 	"#99",
928 	"#100",
929 	"#101",
930 	"#102",
931 	"#103",
932 	"#104",
933 	"#105",
934 	"#106",
935 	"#107",
936 	"#108",
937 	"#109",
938 	"#110",
939 	"#111",
940 	"#112",
941 	"#113",
942 	"#114",
943 	"#115",
944 	"#116",
945 	"#117",
946 	"#118",
947 	"#119",
948 	"#120",
949 	"#121",
950 	"#122",
951 	"#123",
952 	"#124",
953 	"#125",
954 	"#126",
955 	"#127",
956 	"echo",
957 	"echo reply",
958 	"multicast listener query",
959 	"multicast listener report",
960 	"multicast listener done",
961 	"router solicitation",
962 	"router advertisment",
963 	"neighbor solicitation",
964 	"neighbor advertisment",
965 	"redirect",
966 	"router renumbering",
967 	"node information request",
968 	"node information reply",
969 	"#141",
970 	"#142",
971 	"#143",
972 	"#144",
973 	"#145",
974 	"#146",
975 	"#147",
976 	"#148",
977 	"#149",
978 	"#150",
979 	"#151",
980 	"#152",
981 	"#153",
982 	"#154",
983 	"#155",
984 	"#156",
985 	"#157",
986 	"#158",
987 	"#159",
988 	"#160",
989 	"#161",
990 	"#162",
991 	"#163",
992 	"#164",
993 	"#165",
994 	"#166",
995 	"#167",
996 	"#168",
997 	"#169",
998 	"#170",
999 	"#171",
1000 	"#172",
1001 	"#173",
1002 	"#174",
1003 	"#175",
1004 	"#176",
1005 	"#177",
1006 	"#178",
1007 	"#179",
1008 	"#180",
1009 	"#181",
1010 	"#182",
1011 	"#183",
1012 	"#184",
1013 	"#185",
1014 	"#186",
1015 	"#187",
1016 	"#188",
1017 	"#189",
1018 	"#180",
1019 	"#191",
1020 	"#192",
1021 	"#193",
1022 	"#194",
1023 	"#195",
1024 	"#196",
1025 	"#197",
1026 	"#198",
1027 	"#199",
1028 	"#200",
1029 	"#201",
1030 	"#202",
1031 	"#203",
1032 	"#204",
1033 	"#205",
1034 	"#206",
1035 	"#207",
1036 	"#208",
1037 	"#209",
1038 	"#210",
1039 	"#211",
1040 	"#212",
1041 	"#213",
1042 	"#214",
1043 	"#215",
1044 	"#216",
1045 	"#217",
1046 	"#218",
1047 	"#219",
1048 	"#220",
1049 	"#221",
1050 	"#222",
1051 	"#223",
1052 	"#224",
1053 	"#225",
1054 	"#226",
1055 	"#227",
1056 	"#228",
1057 	"#229",
1058 	"#230",
1059 	"#231",
1060 	"#232",
1061 	"#233",
1062 	"#234",
1063 	"#235",
1064 	"#236",
1065 	"#237",
1066 	"#238",
1067 	"#239",
1068 	"#240",
1069 	"#241",
1070 	"#242",
1071 	"#243",
1072 	"#244",
1073 	"#245",
1074 	"#246",
1075 	"#247",
1076 	"#248",
1077 	"#249",
1078 	"#250",
1079 	"#251",
1080 	"#252",
1081 	"#253",
1082 	"#254",
1083 	"#255",
1084 };
1085 
1086 /*
1087  * Dump ICMPv6 statistics.
1088  */
1089 void
1090 icmp6_stats(off, name)
1091 	u_long off;
1092 	char *name;
1093 {
1094 	struct icmp6stat icmp6stat;
1095 	register int i, first;
1096 
1097 	if (off == 0)
1098 		return;
1099 	kread(off, (char *)&icmp6stat, sizeof (icmp6stat));
1100 	printf("%s:\n", name);
1101 
1102 #define	p(f, m) if (icmp6stat.f || sflag <= 1) \
1103     printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f))
1104 #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
1105     printf(m, (unsigned long long)icmp6stat.f)
1106 
1107 	p(icp6s_error, "\t%llu call%s to icmp6_error\n");
1108 	p(icp6s_canterror,
1109 	    "\t%llu error%s not generated because old message was icmp6 or so\n");
1110 	p(icp6s_toofreq,
1111 	    "\t%llu error%s not generated because rate limitation\n");
1112 	for (first = 1, i = 0; i < 256; i++)
1113 		if (icmp6stat.icp6s_outhist[i] != 0) {
1114 			if (first) {
1115 				printf("\tOutput histogram:\n");
1116 				first = 0;
1117 			}
1118 			printf("\t\t%s: %llu\n", icmp6names[i],
1119 				(unsigned long long)icmp6stat.icp6s_outhist[i]);
1120 		}
1121 	p(icp6s_badcode, "\t%llu message%s with bad code fields\n");
1122 	p(icp6s_tooshort, "\t%llu message%s < minimum length\n");
1123 	p(icp6s_checksum, "\t%llu bad checksum%s\n");
1124 	p(icp6s_badlen, "\t%llu message%s with bad length\n");
1125 	for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++)
1126 		if (icmp6stat.icp6s_inhist[i] != 0) {
1127 			if (first) {
1128 				printf("\tInput histogram:\n");
1129 				first = 0;
1130 			}
1131 			printf("\t\t%s: %llu\n", icmp6names[i],
1132 				(unsigned long long)icmp6stat.icp6s_inhist[i]);
1133 		}
1134 	printf("\tHistogram of error messages to be generated:\n");
1135 	p_5(icp6s_odst_unreach_noroute, "\t\t%llu no route\n");
1136 	p_5(icp6s_odst_unreach_admin, "\t\t%llu administratively prohibited\n");
1137 	p_5(icp6s_odst_unreach_beyondscope, "\t\t%llu beyond scope\n");
1138 	p_5(icp6s_odst_unreach_addr, "\t\t%llu address unreachable\n");
1139 	p_5(icp6s_odst_unreach_noport, "\t\t%llu port unreachable\n");
1140 	p_5(icp6s_opacket_too_big, "\t\t%llu packet too big\n");
1141 	p_5(icp6s_otime_exceed_transit, "\t\t%llu time exceed transit\n");
1142 	p_5(icp6s_otime_exceed_reassembly, "\t\t%llu time exceed reassembly\n");
1143 	p_5(icp6s_oparamprob_header, "\t\t%llu erroneous header field\n");
1144 	p_5(icp6s_oparamprob_nextheader, "\t\t%llu unrecognized next header\n");
1145 	p_5(icp6s_oparamprob_option, "\t\t%llu unrecognized option\n");
1146 	p_5(icp6s_oredirect, "\t\t%llu redirect\n");
1147 	p_5(icp6s_ounknown, "\t\t%llu unknown\n");
1148 
1149 	p(icp6s_reflect, "\t%llu message response%s generated\n");
1150 	p(icp6s_nd_toomanyopt, "\t%llu message%s with too many ND options\n");
1151 #undef p
1152 #undef p_5
1153 }
1154 
1155 /*
1156  * Dump ICMPv6 per-interface statistics based on RFC 2466.
1157  */
1158 void
1159 icmp6_ifstats(ifname)
1160 	char *ifname;
1161 {
1162 	struct in6_ifreq ifr;
1163 	int s;
1164 #define	p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
1165     printf(m, (unsigned long long)ifr.ifr_ifru.ifru_icmp6stat.f, \
1166 	plural(ifr.ifr_ifru.ifru_icmp6stat.f))
1167 
1168 	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1169 		perror("Warning: socket(AF_INET6)");
1170 		return;
1171 	}
1172 
1173 	strcpy(ifr.ifr_name, ifname);
1174 	printf("icmp6 on %s:\n", ifr.ifr_name);
1175 
1176 	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
1177 		perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
1178 		goto end;
1179 	}
1180 
1181 	p(ifs6_in_msg, "\t%llu total input message%s\n");
1182 	p(ifs6_in_error, "\t%llu total input error message%s\n");
1183 	p(ifs6_in_dstunreach, "\t%llu input destination unreachable error%s\n");
1184 	p(ifs6_in_adminprohib, "\t%llu input administratively prohibited error%s\n");
1185 	p(ifs6_in_timeexceed, "\t%llu input time exceeded error%s\n");
1186 	p(ifs6_in_paramprob, "\t%llu input parameter problem error%s\n");
1187 	p(ifs6_in_pkttoobig, "\t%llu input packet too big error%s\n");
1188 	p(ifs6_in_echo, "\t%llu input echo request%s\n");
1189 	p(ifs6_in_echoreply, "\t%llu input echo reply%s\n");
1190 	p(ifs6_in_routersolicit, "\t%llu input router solicitation%s\n");
1191 	p(ifs6_in_routeradvert, "\t%llu input router advertisement%s\n");
1192 	p(ifs6_in_neighborsolicit, "\t%llu input neighbor solicitation%s\n");
1193 	p(ifs6_in_neighboradvert, "\t%llu input neighbor advertisement%s\n");
1194 	p(ifs6_in_redirect, "\t%llu input redirect%s\n");
1195 	p(ifs6_in_mldquery, "\t%llu input MLD query%s\n");
1196 	p(ifs6_in_mldreport, "\t%llu input MLD report%s\n");
1197 	p(ifs6_in_mlddone, "\t%llu input MLD done%s\n");
1198 
1199 	p(ifs6_out_msg, "\t%llu total output message%s\n");
1200 	p(ifs6_out_error, "\t%llu total output error message%s\n");
1201 	p(ifs6_out_dstunreach, "\t%llu output destination unreachable error%s\n");
1202 	p(ifs6_out_adminprohib, "\t%llu output administratively prohibited error%s\n");
1203 	p(ifs6_out_timeexceed, "\t%llu output time exceeded error%s\n");
1204 	p(ifs6_out_paramprob, "\t%llu output parameter problem error%s\n");
1205 	p(ifs6_out_pkttoobig, "\t%llu output packet too big error%s\n");
1206 	p(ifs6_out_echo, "\t%llu output echo request%s\n");
1207 	p(ifs6_out_echoreply, "\t%llu output echo reply%s\n");
1208 	p(ifs6_out_routersolicit, "\t%llu output router solicitation%s\n");
1209 	p(ifs6_out_routeradvert, "\t%llu output router advertisement%s\n");
1210 	p(ifs6_out_neighborsolicit, "\t%llu output neighbor solicitation%s\n");
1211 	p(ifs6_out_neighboradvert, "\t%llu output neighbor advertisement%s\n");
1212 	p(ifs6_out_redirect, "\t%llu output redirect%s\n");
1213 	p(ifs6_out_mldquery, "\t%llu output MLD query%s\n");
1214 	p(ifs6_out_mldreport, "\t%llu output MLD report%s\n");
1215 	p(ifs6_out_mlddone, "\t%llu output MLD done%s\n");
1216 
1217   end:
1218 	close(s);
1219 #undef p
1220 }
1221 
1222 /*
1223  * Dump PIM statistics structure.
1224  */
1225 void
1226 pim6_stats(off, name)
1227 	u_long off;
1228 	char *name;
1229 {
1230 	struct pim6stat pim6stat;
1231 
1232 	if (off == 0)
1233 		return;
1234 	kread(off, (char *)&pim6stat, sizeof(pim6stat));
1235 	printf("%s:\n", name);
1236 
1237 #define	p(f, m) if (pim6stat.f || sflag <= 1) \
1238     printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.f))
1239 	p(pim6s_rcv_total, "\t%llu message%s received\n");
1240 	p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
1241 	p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n");
1242 	p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n");
1243 	p(pim6s_rcv_registers, "\t%llu register%s received\n");
1244 	p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n");
1245 	p(pim6s_snd_registers, "\t%llu register%s sent\n");
1246 #undef p
1247 }
1248 
1249 /*
1250  * Pretty print an Internet address (net address + port).
1251  * If the nflag was specified, use numbers instead of names.
1252  */
1253 
1254 void
1255 inet6print(in6, port, proto)
1256 	register struct in6_addr *in6;
1257 	int port;
1258 	char *proto;
1259 {
1260 #define GETSERVBYPORT6(port, proto, ret)\
1261 do {\
1262 	if (strcmp((proto), "tcp6") == 0)\
1263 		(ret) = getservbyport((int)(port), "tcp");\
1264 	else if (strcmp((proto), "udp6") == 0)\
1265 		(ret) = getservbyport((int)(port), "udp");\
1266 	else\
1267 		(ret) = getservbyport((int)(port), (proto));\
1268 } while (0)
1269 	struct servent *sp = 0;
1270 	char line[80], *cp;
1271 	int width;
1272 
1273 	width = Aflag ? 12 : 16;
1274 	if (vflag && width < strlen(inet6name(in6)))
1275 		width = strlen(inet6name(in6));
1276 	sprintf(line, "%.*s.", width, inet6name(in6));
1277 	cp = index(line, '\0');
1278 	if (!nflag && port)
1279 		GETSERVBYPORT6(port, proto, sp);
1280 	if (sp || port == 0)
1281 		sprintf(cp, "%.8s", sp ? sp->s_name : "*");
1282 	else
1283 		sprintf(cp, "%d", ntohs((u_short)port));
1284 	width = Aflag ? 18 : 22;
1285 	if (vflag && width < strlen(line))
1286 		width = strlen(line);
1287 	printf(" %-*.*s", width, width, line);
1288 }
1289 
1290 /*
1291  * Construct an Internet address representation.
1292  * If the nflag has been supplied, give
1293  * numeric value, otherwise try for symbolic name.
1294  */
1295 
1296 char *
1297 inet6name(in6p)
1298 	struct in6_addr *in6p;
1299 {
1300 	register char *cp;
1301 	static char line[50];
1302 	struct hostent *hp;
1303 	static char domain[MAXHOSTNAMELEN + 1];
1304 	static int first = 1;
1305 	char hbuf[NI_MAXHOST];
1306 	struct sockaddr_in6 sin6;
1307 #ifdef KAME_SCOPEID
1308 	const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
1309 #else
1310 	const int niflag = NI_NUMERICHOST;
1311 #endif
1312 
1313 	if (first && !nflag) {
1314 		first = 0;
1315 		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1316 		    (cp = index(domain, '.')))
1317 			(void) strcpy(domain, cp + 1);
1318 		else
1319 			domain[0] = 0;
1320 	}
1321 	cp = 0;
1322 	if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1323 		hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
1324 		if (hp) {
1325 			if ((cp = index(hp->h_name, '.')) &&
1326 			    !strcmp(cp + 1, domain))
1327 				*cp = 0;
1328 			cp = hp->h_name;
1329 		}
1330 	}
1331 	if (IN6_IS_ADDR_UNSPECIFIED(in6p))
1332 		strcpy(line, "*");
1333 	else if (cp)
1334 		strcpy(line, cp);
1335 	else  {
1336 		memset(&sin6, 0, sizeof(sin6));
1337 		sin6.sin6_len = sizeof(sin6);
1338 		sin6.sin6_family = AF_INET6;
1339 		sin6.sin6_addr = *in6p;
1340 #ifdef KAME_SCOPEID
1341 		if (IN6_IS_ADDR_LINKLOCAL(in6p)) {
1342 			sin6.sin6_scope_id =
1343 				ntohs(*(u_int16_t *)&in6p->s6_addr[2]);
1344 			sin6.sin6_addr.s6_addr[2] = 0;
1345 			sin6.sin6_addr.s6_addr[3] = 0;
1346 		}
1347 #endif
1348 		if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
1349 				hbuf, sizeof(hbuf), NULL, 0, niflag))
1350 			strcpy(hbuf, "?");
1351 		sprintf(line, "%s", hbuf);
1352 	}
1353 	return (line);
1354 }
1355 
1356 #ifdef TCP6
1357 /*
1358  * Dump the contents of a TCP6 PCB.
1359  */
1360 void
1361 tcp6_dump(pcbaddr)
1362 	u_long pcbaddr;
1363 {
1364 	struct tcp6cb tcp6cb;
1365 	int i;
1366 
1367 	kread(pcbaddr, (char *)&tcp6cb, sizeof(tcp6cb));
1368 
1369 	printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
1370 
1371 	printf("Timers:\n");
1372 	for (i = 0; i < TCP6T_NTIMERS; i++)
1373 		printf("\t%s: %u", tcp6timers[i], tcp6cb.t_timer[i]);
1374 	printf("\n\n");
1375 
1376 	if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
1377 		printf("State: %d", tcp6cb.t_state);
1378 	else
1379 		printf("State: %s", tcp6states[tcp6cb.t_state]);
1380 	printf(", flags 0x%x, in6pcb 0x%lx\n\n", tcp6cb.t_flags,
1381 	    (u_long)tcp6cb.t_in6pcb);
1382 
1383 	printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcp6cb.t_rxtshift,
1384 	    tcp6cb.t_rxtcur, tcp6cb.t_dupacks);
1385 	printf("peermaxseg %u, maxseg %u, force %d\n\n", tcp6cb.t_peermaxseg,
1386 	    tcp6cb.t_maxseg, tcp6cb.t_force);
1387 
1388 	printf("snd_una %u, snd_nxt %u, snd_up %u\n",
1389 	    tcp6cb.snd_una, tcp6cb.snd_nxt, tcp6cb.snd_up);
1390 	printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %llu\n\n",
1391 	    tcp6cb.snd_wl1, tcp6cb.snd_wl2, tcp6cb.iss,
1392 	    (unsigned long long)tcp6cb.snd_wnd);
1393 
1394 	printf("rcv_wnd %llu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
1395 	    (unsigned long long)cp6cb.rcv_wnd, tcp6cb.rcv_nxt,
1396 	    tcp6cb.rcv_up, tcp6cb.irs);
1397 
1398 	printf("rcv_adv %u, snd_max %u, snd_cwnd %llu, snd_ssthresh %llu\n",
1399 	    tcp6cb.rcv_adv, tcp6cb.snd_max, (unsigned long long)tcp6cb.snd_cwnd,
1400 	    (unsigned long long)tcp6cb.snd_ssthresh);
1401 
1402 	printf("idle %d, rtt %d, rtseq %u, srtt %d, rttvar %d, rttmin %d, "
1403 	    "max_sndwnd %llu\n\n", tcp6cb.t_idle, tcp6cb.t_rtt, tcp6cb.t_rtseq,
1404 	    tcp6cb.t_srtt, tcp6cb.t_rttvar, tcp6cb.t_rttmin,
1405 	    (unsigned long long)tcp6cb.max_sndwnd);
1406 
1407 	printf("oobflags %d, iobc %d, softerror %d\n\n", tcp6cb.t_oobflags,
1408 	    tcp6cb.t_iobc, tcp6cb.t_softerror);
1409 
1410 	printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
1411 	    tcp6cb.snd_scale, tcp6cb.rcv_scale, tcp6cb.request_r_scale,
1412 	    tcp6cb.requested_s_scale);
1413 	printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
1414 	    tcp6cb.ts_recent, tcp6cb.ts_recent_age, tcp6cb.last_ack_sent);
1415 }
1416 #endif
1417 
1418 #endif /*INET6*/
1419