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