inet6.c revision 1.12 1 /* $NetBSD: inet6.c,v 1.12 2000/08/13 18:41:38 jhawk 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.12 2000/08/13 18:41:38 jhawk 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 statistics:\n");
671 p(ip6s_m1, "\t\t%llu one mbuf%s\n");
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 p(ip6s_mext1,"\t\t%llu one ext mbuf%s\n");
685 p(ip6s_mext2m, "\t\t%llu two or more ext mbuf%s\n");
686 p(ip6s_exthdrtoolong,
687 "\t%llu packet%s whose headers are not continuous\n");
688 p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n");
689 p(ip6s_toomanyhdr,
690 "\t%llu packet%s discarded due to too many headers\n");
691
692 /* for debugging source address selection */
693 #define PRINT_SCOPESTAT(s,i) do {\
694 switch(i) { /* XXX hardcoding in each case */\
695 case 1:\
696 p(s, "\t\t%llu node-local%s\n");\
697 break;\
698 case 2:\
699 p(s, "\t\t%llu link-local%s\n");\
700 break;\
701 case 5:\
702 p(s, "\t\t%llu site-local%s\n");\
703 break;\
704 case 14:\
705 p(s, "\t\t%llu global%s\n");\
706 break;\
707 default:\
708 printf("\t\t%llu addresses scope=%x\n",\
709 (unsigned long long)ip6stat.s, i);\
710 }\
711 } while(0);
712
713 p(ip6s_sources_none,
714 "\t%llu failure%s of source address selection\n");
715 for (first = 1, i = 0; i < 16; i++) {
716 if (ip6stat.ip6s_sources_sameif[i]) {
717 if (first) {
718 printf("\tsource addresses on an outgoing I/F\n");
719 first = 0;
720 }
721 PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
722 }
723 }
724 for (first = 1, i = 0; i < 16; i++) {
725 if (ip6stat.ip6s_sources_otherif[i]) {
726 if (first) {
727 printf("\tsource addresses on a non-outgoing I/F\n");
728 first = 0;
729 }
730 PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
731 }
732 }
733 for (first = 1, i = 0; i < 16; i++) {
734 if (ip6stat.ip6s_sources_samescope[i]) {
735 if (first) {
736 printf("\tsource addresses of same scope\n");
737 first = 0;
738 }
739 PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
740 }
741 }
742 for (first = 1, i = 0; i < 16; i++) {
743 if (ip6stat.ip6s_sources_otherscope[i]) {
744 if (first) {
745 printf("\tsource addresses of a different scope\n");
746 first = 0;
747 }
748 PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
749 }
750 }
751 for (first = 1, i = 0; i < 16; i++) {
752 if (ip6stat.ip6s_sources_deprecated[i]) {
753 if (first) {
754 printf("\tdeprecated source addresses\n");
755 first = 0;
756 }
757 PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
758 }
759 }
760
761 p1(ip6s_forward_cachehit, "\t%llu forward cache hit\n");
762 p1(ip6s_forward_cachemiss, "\t%llu forward cache miss\n");
763 #undef p
764 #undef p1
765 }
766
767 /*
768 * Dump IPv6 per-interface statistics based on RFC 2465.
769 */
770 void
771 ip6_ifstats(ifname)
772 char *ifname;
773 {
774 struct in6_ifreq ifr;
775 int s;
776 #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
777 printf(m, (unsigned long long)ifr.ifr_ifru.ifru_stat.f, \
778 plural(ifr.ifr_ifru.ifru_stat.f))
779 #define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
780 printf(m, (unsigned long long)ip6stat.f)
781
782 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
783 perror("Warning: socket(AF_INET6)");
784 return;
785 }
786
787 strcpy(ifr.ifr_name, ifname);
788 printf("ip6 on %s:\n", ifr.ifr_name);
789
790 if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
791 perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
792 goto end;
793 }
794
795 p(ifs6_in_receive, "\t%llu total input datagram%s\n");
796 p(ifs6_in_hdrerr, "\t%llu datagram%s with invalid header received\n");
797 p(ifs6_in_toobig, "\t%llu datagram%s exceeded MTU received\n");
798 p(ifs6_in_noroute, "\t%llu datagram%s with no route received\n");
799 p(ifs6_in_addrerr, "\t%llu datagram%s with invalid dst received\n");
800 p(ifs6_in_truncated, "\t%llu truncated datagram%s received\n");
801 p(ifs6_in_protounknown, "\t%llu datagram%s with unknown proto received\n");
802 p(ifs6_in_discard, "\t%llu input datagram%s discarded\n");
803 p(ifs6_in_deliver,
804 "\t%llu datagram%s delivered to an upper layer protocol\n");
805 p(ifs6_out_forward, "\t%llu datagram%s forwarded to this interface\n");
806 p(ifs6_out_request,
807 "\t%llu datagram%s sent from an upper layer protocol\n");
808 p(ifs6_out_discard, "\t%llu total discarded output datagram%s\n");
809 p(ifs6_out_fragok, "\t%llu output datagram%s fragmented\n");
810 p(ifs6_out_fragfail, "\t%llu output datagram%s failed on fragment\n");
811 p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n");
812 p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n");
813 p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n");
814 p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n");
815 p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n");
816 p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n");
817
818 end:
819 close(s);
820
821 #undef p
822 #undef p_5
823 }
824
825 static char *icmp6names[] = {
826 "#0",
827 "unreach",
828 "packet too big",
829 "time exceed",
830 "parameter problem",
831 "#5",
832 "#6",
833 "#7",
834 "#8",
835 "#9",
836 "#10",
837 "#11",
838 "#12",
839 "#13",
840 "#14",
841 "#15",
842 "#16",
843 "#17",
844 "#18",
845 "#19",
846 "#20",
847 "#21",
848 "#22",
849 "#23",
850 "#24",
851 "#25",
852 "#26",
853 "#27",
854 "#28",
855 "#29",
856 "#30",
857 "#31",
858 "#32",
859 "#33",
860 "#34",
861 "#35",
862 "#36",
863 "#37",
864 "#38",
865 "#39",
866 "#40",
867 "#41",
868 "#42",
869 "#43",
870 "#44",
871 "#45",
872 "#46",
873 "#47",
874 "#48",
875 "#49",
876 "#50",
877 "#51",
878 "#52",
879 "#53",
880 "#54",
881 "#55",
882 "#56",
883 "#57",
884 "#58",
885 "#59",
886 "#60",
887 "#61",
888 "#62",
889 "#63",
890 "#64",
891 "#65",
892 "#66",
893 "#67",
894 "#68",
895 "#69",
896 "#70",
897 "#71",
898 "#72",
899 "#73",
900 "#74",
901 "#75",
902 "#76",
903 "#77",
904 "#78",
905 "#79",
906 "#80",
907 "#81",
908 "#82",
909 "#83",
910 "#84",
911 "#85",
912 "#86",
913 "#87",
914 "#88",
915 "#89",
916 "#80",
917 "#91",
918 "#92",
919 "#93",
920 "#94",
921 "#95",
922 "#96",
923 "#97",
924 "#98",
925 "#99",
926 "#100",
927 "#101",
928 "#102",
929 "#103",
930 "#104",
931 "#105",
932 "#106",
933 "#107",
934 "#108",
935 "#109",
936 "#110",
937 "#111",
938 "#112",
939 "#113",
940 "#114",
941 "#115",
942 "#116",
943 "#117",
944 "#118",
945 "#119",
946 "#120",
947 "#121",
948 "#122",
949 "#123",
950 "#124",
951 "#125",
952 "#126",
953 "#127",
954 "echo",
955 "echo reply",
956 "multicast listener query",
957 "multicast listener report",
958 "multicast listener done",
959 "router solicitation",
960 "router advertisment",
961 "neighbor solicitation",
962 "neighbor advertisment",
963 "redirect",
964 "router renumbering",
965 "node information request",
966 "node information reply",
967 "#141",
968 "#142",
969 "#143",
970 "#144",
971 "#145",
972 "#146",
973 "#147",
974 "#148",
975 "#149",
976 "#150",
977 "#151",
978 "#152",
979 "#153",
980 "#154",
981 "#155",
982 "#156",
983 "#157",
984 "#158",
985 "#159",
986 "#160",
987 "#161",
988 "#162",
989 "#163",
990 "#164",
991 "#165",
992 "#166",
993 "#167",
994 "#168",
995 "#169",
996 "#170",
997 "#171",
998 "#172",
999 "#173",
1000 "#174",
1001 "#175",
1002 "#176",
1003 "#177",
1004 "#178",
1005 "#179",
1006 "#180",
1007 "#181",
1008 "#182",
1009 "#183",
1010 "#184",
1011 "#185",
1012 "#186",
1013 "#187",
1014 "#188",
1015 "#189",
1016 "#180",
1017 "#191",
1018 "#192",
1019 "#193",
1020 "#194",
1021 "#195",
1022 "#196",
1023 "#197",
1024 "#198",
1025 "#199",
1026 "#200",
1027 "#201",
1028 "#202",
1029 "#203",
1030 "#204",
1031 "#205",
1032 "#206",
1033 "#207",
1034 "#208",
1035 "#209",
1036 "#210",
1037 "#211",
1038 "#212",
1039 "#213",
1040 "#214",
1041 "#215",
1042 "#216",
1043 "#217",
1044 "#218",
1045 "#219",
1046 "#220",
1047 "#221",
1048 "#222",
1049 "#223",
1050 "#224",
1051 "#225",
1052 "#226",
1053 "#227",
1054 "#228",
1055 "#229",
1056 "#230",
1057 "#231",
1058 "#232",
1059 "#233",
1060 "#234",
1061 "#235",
1062 "#236",
1063 "#237",
1064 "#238",
1065 "#239",
1066 "#240",
1067 "#241",
1068 "#242",
1069 "#243",
1070 "#244",
1071 "#245",
1072 "#246",
1073 "#247",
1074 "#248",
1075 "#249",
1076 "#250",
1077 "#251",
1078 "#252",
1079 "#253",
1080 "#254",
1081 "#255",
1082 };
1083
1084 /*
1085 * Dump ICMPv6 statistics.
1086 */
1087 void
1088 icmp6_stats(off, name)
1089 u_long off;
1090 char *name;
1091 {
1092 struct icmp6stat icmp6stat;
1093 register int i, first;
1094
1095 if (off == 0)
1096 return;
1097 kread(off, (char *)&icmp6stat, sizeof (icmp6stat));
1098 printf("%s:\n", name);
1099
1100 #define p(f, m) if (icmp6stat.f || sflag <= 1) \
1101 printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f))
1102 #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
1103 printf(m, (unsigned long long)icmp6stat.f)
1104
1105 p(icp6s_error, "\t%llu call%s to icmp6_error\n");
1106 p(icp6s_canterror,
1107 "\t%llu error%s not generated because old message was icmp6 or so\n");
1108 p(icp6s_toofreq,
1109 "\t%llu error%s not generated because rate limitation\n");
1110 for (first = 1, i = 0; i < 256; i++)
1111 if (icmp6stat.icp6s_outhist[i] != 0) {
1112 if (first) {
1113 printf("\tOutput histogram:\n");
1114 first = 0;
1115 }
1116 printf("\t\t%s: %llu\n", icmp6names[i],
1117 (unsigned long long)icmp6stat.icp6s_outhist[i]);
1118 }
1119 p(icp6s_badcode, "\t%llu message%s with bad code fields\n");
1120 p(icp6s_tooshort, "\t%llu message%s < minimum length\n");
1121 p(icp6s_checksum, "\t%llu bad checksum%s\n");
1122 p(icp6s_badlen, "\t%llu message%s with bad length\n");
1123 for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++)
1124 if (icmp6stat.icp6s_inhist[i] != 0) {
1125 if (first) {
1126 printf("\tInput histogram:\n");
1127 first = 0;
1128 }
1129 printf("\t\t%s: %llu\n", icmp6names[i],
1130 (unsigned long long)icmp6stat.icp6s_inhist[i]);
1131 }
1132 printf("\tHistogram of error messages to be generated:\n");
1133 p_5(icp6s_odst_unreach_noroute, "\t\t%llu no route\n");
1134 p_5(icp6s_odst_unreach_admin, "\t\t%llu administratively prohibited\n");
1135 p_5(icp6s_odst_unreach_beyondscope, "\t\t%llu beyond scope\n");
1136 p_5(icp6s_odst_unreach_addr, "\t\t%llu address unreachable\n");
1137 p_5(icp6s_odst_unreach_noport, "\t\t%llu port unreachable\n");
1138 p_5(icp6s_opacket_too_big, "\t\t%llu packet too big\n");
1139 p_5(icp6s_otime_exceed_transit, "\t\t%llu time exceed transit\n");
1140 p_5(icp6s_otime_exceed_reassembly, "\t\t%llu time exceed reassembly\n");
1141 p_5(icp6s_oparamprob_header, "\t\t%llu erroneous header field\n");
1142 p_5(icp6s_oparamprob_nextheader, "\t\t%llu unrecognized next header\n");
1143 p_5(icp6s_oparamprob_option, "\t\t%llu unrecognized option\n");
1144 p_5(icp6s_oredirect, "\t\t%llu redirect\n");
1145 p_5(icp6s_ounknown, "\t\t%llu unknown\n");
1146
1147 p(icp6s_reflect, "\t%llu message response%s generated\n");
1148 p(icp6s_nd_toomanyopt, "\t%llu message%s with too many ND options\n");
1149 #undef p
1150 #undef p_5
1151 }
1152
1153 /*
1154 * Dump ICMPv6 per-interface statistics based on RFC 2466.
1155 */
1156 void
1157 icmp6_ifstats(ifname)
1158 char *ifname;
1159 {
1160 struct in6_ifreq ifr;
1161 int s;
1162 #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
1163 printf(m, (unsigned long long)ifr.ifr_ifru.ifru_icmp6stat.f, \
1164 plural(ifr.ifr_ifru.ifru_icmp6stat.f))
1165
1166 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1167 perror("Warning: socket(AF_INET6)");
1168 return;
1169 }
1170
1171 strcpy(ifr.ifr_name, ifname);
1172 printf("icmp6 on %s:\n", ifr.ifr_name);
1173
1174 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
1175 perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
1176 goto end;
1177 }
1178
1179 p(ifs6_in_msg, "\t%llu total input message%s\n");
1180 p(ifs6_in_error, "\t%llu total input error message%s\n");
1181 p(ifs6_in_dstunreach, "\t%llu input destination unreachable error%s\n");
1182 p(ifs6_in_adminprohib, "\t%llu input administratively prohibited error%s\n");
1183 p(ifs6_in_timeexceed, "\t%llu input time exceeded error%s\n");
1184 p(ifs6_in_paramprob, "\t%llu input parameter problem error%s\n");
1185 p(ifs6_in_pkttoobig, "\t%llu input packet too big error%s\n");
1186 p(ifs6_in_echo, "\t%llu input echo request%s\n");
1187 p(ifs6_in_echoreply, "\t%llu input echo reply%s\n");
1188 p(ifs6_in_routersolicit, "\t%llu input router solicitation%s\n");
1189 p(ifs6_in_routeradvert, "\t%llu input router advertisement%s\n");
1190 p(ifs6_in_neighborsolicit, "\t%llu input neighbor solicitation%s\n");
1191 p(ifs6_in_neighboradvert, "\t%llu input neighbor advertisement%s\n");
1192 p(ifs6_in_redirect, "\t%llu input redirect%s\n");
1193 p(ifs6_in_mldquery, "\t%llu input MLD query%s\n");
1194 p(ifs6_in_mldreport, "\t%llu input MLD report%s\n");
1195 p(ifs6_in_mlddone, "\t%llu input MLD done%s\n");
1196
1197 p(ifs6_out_msg, "\t%llu total output message%s\n");
1198 p(ifs6_out_error, "\t%llu total output error message%s\n");
1199 p(ifs6_out_dstunreach, "\t%llu output destination unreachable error%s\n");
1200 p(ifs6_out_adminprohib, "\t%llu output administratively prohibited error%s\n");
1201 p(ifs6_out_timeexceed, "\t%llu output time exceeded error%s\n");
1202 p(ifs6_out_paramprob, "\t%llu output parameter problem error%s\n");
1203 p(ifs6_out_pkttoobig, "\t%llu output packet too big error%s\n");
1204 p(ifs6_out_echo, "\t%llu output echo request%s\n");
1205 p(ifs6_out_echoreply, "\t%llu output echo reply%s\n");
1206 p(ifs6_out_routersolicit, "\t%llu output router solicitation%s\n");
1207 p(ifs6_out_routeradvert, "\t%llu output router advertisement%s\n");
1208 p(ifs6_out_neighborsolicit, "\t%llu output neighbor solicitation%s\n");
1209 p(ifs6_out_neighboradvert, "\t%llu output neighbor advertisement%s\n");
1210 p(ifs6_out_redirect, "\t%llu output redirect%s\n");
1211 p(ifs6_out_mldquery, "\t%llu output MLD query%s\n");
1212 p(ifs6_out_mldreport, "\t%llu output MLD report%s\n");
1213 p(ifs6_out_mlddone, "\t%llu output MLD done%s\n");
1214
1215 end:
1216 close(s);
1217 #undef p
1218 }
1219
1220 /*
1221 * Dump PIM statistics structure.
1222 */
1223 void
1224 pim6_stats(off, name)
1225 u_long off;
1226 char *name;
1227 {
1228 struct pim6stat pim6stat;
1229
1230 if (off == 0)
1231 return;
1232 kread(off, (char *)&pim6stat, sizeof(pim6stat));
1233 printf("%s:\n", name);
1234
1235 #define p(f, m) if (pim6stat.f || sflag <= 1) \
1236 printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.f))
1237 p(pim6s_rcv_total, "\t%llu message%s received\n");
1238 p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
1239 p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n");
1240 p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n");
1241 p(pim6s_rcv_registers, "\t%llu register%s received\n");
1242 p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n");
1243 p(pim6s_snd_registers, "\t%llu register%s sent\n");
1244 #undef p
1245 }
1246
1247 /*
1248 * Pretty print an Internet address (net address + port).
1249 * If the nflag was specified, use numbers instead of names.
1250 */
1251
1252 void
1253 inet6print(in6, port, proto)
1254 register struct in6_addr *in6;
1255 int port;
1256 char *proto;
1257 {
1258 #define GETSERVBYPORT6(port, proto, ret)\
1259 do {\
1260 if (strcmp((proto), "tcp6") == 0)\
1261 (ret) = getservbyport((int)(port), "tcp");\
1262 else if (strcmp((proto), "udp6") == 0)\
1263 (ret) = getservbyport((int)(port), "udp");\
1264 else\
1265 (ret) = getservbyport((int)(port), (proto));\
1266 } while (0)
1267 struct servent *sp = 0;
1268 char line[80], *cp;
1269 int width;
1270
1271 width = Aflag ? 12 : 16;
1272 if (vflag && width < strlen(inet6name(in6)))
1273 width = strlen(inet6name(in6));
1274 sprintf(line, "%.*s.", width, inet6name(in6));
1275 cp = index(line, '\0');
1276 if (!nflag && port)
1277 GETSERVBYPORT6(port, proto, sp);
1278 if (sp || port == 0)
1279 sprintf(cp, "%.8s", sp ? sp->s_name : "*");
1280 else
1281 sprintf(cp, "%d", ntohs((u_short)port));
1282 width = Aflag ? 18 : 22;
1283 if (vflag && width < strlen(line))
1284 width = strlen(line);
1285 printf(" %-*.*s", width, width, line);
1286 }
1287
1288 /*
1289 * Construct an Internet address representation.
1290 * If the nflag has been supplied, give
1291 * numeric value, otherwise try for symbolic name.
1292 */
1293
1294 char *
1295 inet6name(in6p)
1296 struct in6_addr *in6p;
1297 {
1298 register char *cp;
1299 static char line[50];
1300 struct hostent *hp;
1301 static char domain[MAXHOSTNAMELEN + 1];
1302 static int first = 1;
1303 char hbuf[NI_MAXHOST];
1304 struct sockaddr_in6 sin6;
1305 #ifdef KAME_SCOPEID
1306 const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
1307 #else
1308 const int niflag = NI_NUMERICHOST;
1309 #endif
1310
1311 if (first && !nflag) {
1312 first = 0;
1313 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1314 (cp = index(domain, '.')))
1315 (void) strcpy(domain, cp + 1);
1316 else
1317 domain[0] = 0;
1318 }
1319 cp = 0;
1320 if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1321 hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
1322 if (hp) {
1323 if ((cp = index(hp->h_name, '.')) &&
1324 !strcmp(cp + 1, domain))
1325 *cp = 0;
1326 cp = hp->h_name;
1327 }
1328 }
1329 if (IN6_IS_ADDR_UNSPECIFIED(in6p))
1330 strcpy(line, "*");
1331 else if (cp)
1332 strcpy(line, cp);
1333 else {
1334 memset(&sin6, 0, sizeof(sin6));
1335 sin6.sin6_len = sizeof(sin6);
1336 sin6.sin6_family = AF_INET6;
1337 sin6.sin6_addr = *in6p;
1338 #ifdef KAME_SCOPEID
1339 if (IN6_IS_ADDR_LINKLOCAL(in6p)) {
1340 sin6.sin6_scope_id =
1341 ntohs(*(u_int16_t *)&in6p->s6_addr[2]);
1342 sin6.sin6_addr.s6_addr[2] = 0;
1343 sin6.sin6_addr.s6_addr[3] = 0;
1344 }
1345 #endif
1346 if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
1347 hbuf, sizeof(hbuf), NULL, 0, niflag))
1348 strcpy(hbuf, "?");
1349 sprintf(line, "%s", hbuf);
1350 }
1351 return (line);
1352 }
1353
1354 #ifdef TCP6
1355 /*
1356 * Dump the contents of a TCP6 PCB.
1357 */
1358 void
1359 tcp6_dump(pcbaddr)
1360 u_long pcbaddr;
1361 {
1362 struct tcp6cb tcp6cb;
1363 int i;
1364
1365 kread(pcbaddr, (char *)&tcp6cb, sizeof(tcp6cb));
1366
1367 printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
1368
1369 printf("Timers:\n");
1370 for (i = 0; i < TCP6T_NTIMERS; i++)
1371 printf("\t%s: %u", tcp6timers[i], tcp6cb.t_timer[i]);
1372 printf("\n\n");
1373
1374 if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
1375 printf("State: %d", tcp6cb.t_state);
1376 else
1377 printf("State: %s", tcp6states[tcp6cb.t_state]);
1378 printf(", flags 0x%x, in6pcb 0x%lx\n\n", tcp6cb.t_flags,
1379 (u_long)tcp6cb.t_in6pcb);
1380
1381 printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcp6cb.t_rxtshift,
1382 tcp6cb.t_rxtcur, tcp6cb.t_dupacks);
1383 printf("peermaxseg %u, maxseg %u, force %d\n\n", tcp6cb.t_peermaxseg,
1384 tcp6cb.t_maxseg, tcp6cb.t_force);
1385
1386 printf("snd_una %u, snd_nxt %u, snd_up %u\n",
1387 tcp6cb.snd_una, tcp6cb.snd_nxt, tcp6cb.snd_up);
1388 printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %llu\n\n",
1389 tcp6cb.snd_wl1, tcp6cb.snd_wl2, tcp6cb.iss,
1390 (unsigned long long)tcp6cb.snd_wnd);
1391
1392 printf("rcv_wnd %llu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
1393 (unsigned long long)cp6cb.rcv_wnd, tcp6cb.rcv_nxt,
1394 tcp6cb.rcv_up, tcp6cb.irs);
1395
1396 printf("rcv_adv %u, snd_max %u, snd_cwnd %llu, snd_ssthresh %llu\n",
1397 tcp6cb.rcv_adv, tcp6cb.snd_max, (unsigned long long)tcp6cb.snd_cwnd,
1398 (unsigned long long)tcp6cb.snd_ssthresh);
1399
1400 printf("idle %d, rtt %d, rtseq %u, srtt %d, rttvar %d, rttmin %d, "
1401 "max_sndwnd %llu\n\n", tcp6cb.t_idle, tcp6cb.t_rtt, tcp6cb.t_rtseq,
1402 tcp6cb.t_srtt, tcp6cb.t_rttvar, tcp6cb.t_rttmin,
1403 (unsigned long long)tcp6cb.max_sndwnd);
1404
1405 printf("oobflags %d, iobc %d, softerror %d\n\n", tcp6cb.t_oobflags,
1406 tcp6cb.t_iobc, tcp6cb.t_softerror);
1407
1408 printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
1409 tcp6cb.snd_scale, tcp6cb.rcv_scale, tcp6cb.request_r_scale,
1410 tcp6cb.requested_s_scale);
1411 printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
1412 tcp6cb.ts_recent, tcp6cb.ts_recent_age, tcp6cb.last_ack_sent);
1413 }
1414 #endif
1415
1416 #endif /*INET6*/
1417