inet6.c revision 1.4 1 /* $NetBSD: inet6.c,v 1.4 1999/11/19 10:44:33 bouyer Exp $ */
2
3 /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
4 /*
5 * Copyright (c) 1983, 1988, 1993
6 * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #include <sys/cdefs.h>
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94";
41 #else
42 __RCSID("$NetBSD: inet6.c,v 1.4 1999/11/19 10:44:33 bouyer Exp $");
43 #endif
44 #endif /* not lint */
45
46 #include <sys/param.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/mbuf.h>
50 #include <sys/protosw.h>
51
52 #include <net/route.h>
53 #include <net/if.h>
54 #include <netinet/in.h>
55 #include <netinet/ip6.h>
56 #include <netinet/icmp6.h>
57 #include <netinet/in_systm.h>
58 #ifndef TCP6
59 #include <netinet/ip.h>
60 #include <netinet/ip_var.h>
61 #endif
62 #include <netinet6/in6_pcb.h>
63 #include <netinet6/ip6_var.h>
64 #ifdef TCP6
65 #include <netinet6/tcp6.h>
66 #include <netinet6/tcp6_seq.h>
67 #define TCP6STATES
68 #include <netinet6/tcp6_fsm.h>
69 #define TCP6TIMERS
70 #include <netinet6/tcp6_timer.h>
71 #include <netinet6/tcp6_var.h>
72 #include <netinet6/tcp6_debug.h>
73 #else
74 #include <netinet/tcp.h>
75 #include <netinet/tcpip.h>
76 #include <netinet/tcp_seq.h>
77 /*#define TCPSTATES*/
78 #include <netinet/tcp_fsm.h>
79 extern char *tcpstates[];
80 /*#define TCPTIMERS*/
81 #include <netinet/tcp_timer.h>
82 #include <netinet/tcp_var.h>
83 #include <netinet/tcp_debug.h>
84 #endif /*TCP6*/
85 #include <netinet6/udp6.h>
86 #include <netinet6/udp6_var.h>
87 #include <netinet6/pim6_var.h>
88
89 #include <arpa/inet.h>
90 #if 0
91 #include "gethostbyname2.h"
92 #endif
93 #include <netdb.h>
94
95 #include <stdio.h>
96 #include <string.h>
97 #include <unistd.h>
98 #include "netstat.h"
99
100 #ifdef INET6
101
102 struct in6pcb in6pcb;
103 #ifdef TCP6
104 struct tcp6cb tcp6cb;
105 #else
106 struct tcpcb tcpcb;
107 #endif
108 struct socket sockb;
109
110 char *inet6name __P((struct in6_addr *));
111 void inet6print __P((struct in6_addr *, int, char *));
112
113 static char ntop_buf[INET6_ADDRSTRLEN];
114
115 /*
116 * Print a summary of connections related to an Internet
117 * protocol. For TCP, also give state of connection.
118 * Listening processes (aflag) are suppressed unless the
119 * -a (all) flag is specified.
120 */
121 void
122 ip6protopr(off, name)
123 u_long off;
124 char *name;
125 {
126 struct in6pcb cb;
127 register struct in6pcb *prev, *next;
128 int istcp;
129 static int first = 1;
130
131 if (off == 0)
132 return;
133 istcp = strcmp(name, "tcp6") == 0;
134 kread(off, (char *)&cb, sizeof (struct in6pcb));
135 in6pcb = cb;
136 prev = (struct in6pcb *)off;
137 if (in6pcb.in6p_next == (struct in6pcb *)off)
138 return;
139 while (in6pcb.in6p_next != (struct in6pcb *)off) {
140 next = in6pcb.in6p_next;
141 kread((u_long)next, (char *)&in6pcb, sizeof (in6pcb));
142 if (in6pcb.in6p_prev != prev) {
143 printf("???\n");
144 break;
145 }
146 if (!aflag && IN6_IS_ADDR_ANY(&in6pcb.in6p_laddr)) {
147 prev = next;
148 continue;
149 }
150 kread((u_long)in6pcb.in6p_socket, (char *)&sockb, sizeof (sockb));
151 if (istcp) {
152 #ifdef TCP6
153 kread((u_long)in6pcb.in6p_ppcb,
154 (char *)&tcp6cb, sizeof (tcp6cb));
155 #else
156 kread((u_long)in6pcb.in6p_ppcb,
157 (char *)&tcpcb, sizeof (tcpcb));
158 #endif
159 }
160 if (first) {
161 printf("Active Internet6 connections");
162 if (aflag)
163 printf(" (including servers)");
164 putchar('\n');
165 if (Aflag)
166 printf("%-8.8s ", "PCB");
167 printf(Aflag ?
168 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
169 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
170 "Proto", "Recv-Q", "Send-Q",
171 "Local Address", "Foreign Address", "(state)");
172 first = 0;
173 }
174 if (Aflag) {
175 if (istcp)
176 printf("%8p ", in6pcb.in6p_ppcb);
177 else
178 printf("%8p ", next);
179 }
180 printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
181 sockb.so_snd.sb_cc);
182 /* xxx */
183 inet6print(&in6pcb.in6p_laddr, (int)in6pcb.in6p_lport, name);
184 inet6print(&in6pcb.in6p_faddr, (int)in6pcb.in6p_fport, name);
185 if (istcp) {
186 #ifdef TCP6
187 if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
188 printf(" %d", tcp6cb.t_state);
189 else
190 printf(" %s", tcp6states[tcp6cb.t_state]);
191 #else
192 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
193 printf(" %d", tcpcb.t_state);
194 else
195 printf(" %s", tcpstates[tcpcb.t_state]);
196 #endif
197 }
198 putchar('\n');
199 prev = next;
200 }
201 }
202
203 #ifdef TCP6
204 /*
205 * Dump TCP6 statistics structure.
206 */
207 void
208 tcp6_stats(off, name)
209 u_long off;
210 char *name;
211 {
212 struct tcp6stat tcp6stat;
213
214 if (off == 0)
215 return;
216 printf ("%s:\n", name);
217 kread(off, (char *)&tcp6stat, sizeof (tcp6stat));
218
219 #define p(f, m) if (tcp6stat.f || sflag <= 1) \
220 printf(m, tcp6stat.f, plural(tcp6stat.f))
221 #define p2(f1, f2, m) if (tcp6stat.f1 || tcp6stat.f2 || sflag <= 1) \
222 printf(m, tcp6stat.f1, plural(tcp6stat.f1), tcp6stat.f2, plural(tcp6stat.f2))
223 #define p3(f, m) if (tcp6stat.f || sflag <= 1) \
224 printf(m, tcp6stat.f, plurales(tcp6stat.f))
225
226 p(tcp6s_sndtotal, "\t%ld packet%s sent\n");
227 p2(tcp6s_sndpack,tcp6s_sndbyte,
228 "\t\t%ld data packet%s (%ld byte%s)\n");
229 p2(tcp6s_sndrexmitpack, tcp6s_sndrexmitbyte,
230 "\t\t%ld data packet%s (%ld byte%s) retransmitted\n");
231 p2(tcp6s_sndacks, tcp6s_delack,
232 "\t\t%ld ack-only packet%s (%ld packet%s delayed)\n");
233 p(tcp6s_sndurg, "\t\t%ld URG only packet%s\n");
234 p(tcp6s_sndprobe, "\t\t%ld window probe packet%s\n");
235 p(tcp6s_sndwinup, "\t\t%ld window update packet%s\n");
236 p(tcp6s_sndctrl, "\t\t%ld control packet%s\n");
237 p(tcp6s_rcvtotal, "\t%ld packet%s received\n");
238 p2(tcp6s_rcvackpack, tcp6s_rcvackbyte, "\t\t%ld ack%s (for %ld byte%s)\n");
239 p(tcp6s_rcvdupack, "\t\t%ld duplicate ack%s\n");
240 p(tcp6s_rcvacktoomuch, "\t\t%ld ack%s for unsent data\n");
241 p2(tcp6s_rcvpack, tcp6s_rcvbyte,
242 "\t\t%ld packet%s (%ld byte%s) received in-sequence\n");
243 p2(tcp6s_rcvduppack, tcp6s_rcvdupbyte,
244 "\t\t%ld completely duplicate packet%s (%ld byte%s)\n");
245 p(tcp6s_pawsdrop, "\t\t%ld old duplicate packet%s\n");
246 p2(tcp6s_rcvpartduppack, tcp6s_rcvpartdupbyte,
247 "\t\t%ld packet%s with some dup. data (%ld byte%s duped)\n");
248 p2(tcp6s_rcvoopack, tcp6s_rcvoobyte,
249 "\t\t%ld out-of-order packet%s (%ld byte%s)\n");
250 p2(tcp6s_rcvpackafterwin, tcp6s_rcvbyteafterwin,
251 "\t\t%ld packet%s (%ld byte%s) of data after window\n");
252 p(tcp6s_rcvwinprobe, "\t\t%ld window probe%s\n");
253 p(tcp6s_rcvwinupd, "\t\t%ld window update packet%s\n");
254 p(tcp6s_rcvafterclose, "\t\t%ld packet%s received after close\n");
255 p(tcp6s_rcvbadsum, "\t\t%ld discarded for bad checksum%s\n");
256 p(tcp6s_rcvbadoff, "\t\t%ld discarded for bad header offset field%s\n");
257 p(tcp6s_rcvshort, "\t\t%ld discarded because packet%s too short\n");
258 p(tcp6s_connattempt, "\t%ld connection request%s\n");
259 p(tcp6s_accepts, "\t%ld connection accept%s\n");
260 p(tcp6s_badsyn, "\t%ld bad connection attempt%s\n");
261 p(tcp6s_connects, "\t%ld connection%s established (including accepts)\n");
262 p2(tcp6s_closed, tcp6s_drops,
263 "\t%ld connection%s closed (including %ld drop%s)\n");
264 p(tcp6s_conndrops, "\t%ld embryonic connection%s dropped\n");
265 p2(tcp6s_rttupdated, tcp6s_segstimed,
266 "\t%ld segment%s updated rtt (of %ld attempt%s)\n");
267 p(tcp6s_rexmttimeo, "\t%ld retransmit timeout%s\n");
268 p(tcp6s_timeoutdrop, "\t\t%ld connection%s dropped by rexmit timeout\n");
269 p(tcp6s_persisttimeo, "\t%ld persist timeout%s\n");
270 p(tcp6s_persistdrop, "\t%ld connection%s timed out in persist\n");
271 p(tcp6s_keeptimeo, "\t%ld keepalive timeout%s\n");
272 p(tcp6s_keepprobe, "\t\t%ld keepalive probe%s sent\n");
273 p(tcp6s_keepdrops, "\t\t%ld connection%s dropped by keepalive\n");
274 p(tcp6s_predack, "\t%ld correct ACK header prediction%s\n");
275 p(tcp6s_preddat, "\t%ld correct data packet header prediction%s\n");
276 p3(tcp6s_pcbcachemiss, "\t%ld PCB cache miss%s\n");
277 #undef p
278 #undef p2
279 #undef p3
280 }
281 #endif
282
283 /*
284 * Dump UDP6 statistics structure.
285 */
286 void
287 udp6_stats(off, name)
288 u_long off;
289 char *name;
290 {
291 struct udp6stat udp6stat;
292 u_quad_t delivered;
293
294 if (off == 0)
295 return;
296 kread(off, (char *)&udp6stat, sizeof (udp6stat));
297 printf("%s:\n", name);
298 #define p(f, m) if (udp6stat.f || sflag <= 1) \
299 printf(m, (unsigned long long)udp6stat.f, plural(udp6stat.f))
300 #define p1(f, m) if (udp6stat.f || sflag <= 1) \
301 printf(m, (unsigned long long)udp6stat.f)
302 p(udp6s_ipackets, "\t%llu datagram%s received\n");
303 p1(udp6s_hdrops, "\t%llu with incomplete header\n");
304 p1(udp6s_badlen, "\t%llu with bad data length field\n");
305 p1(udp6s_badsum, "\t%llu with bad checksum\n");
306 p1(udp6s_nosum, "\t%llu with no checksum\n");
307 p1(udp6s_noport, "\t%llu dropped due to no socket\n");
308 p(udp6s_noportmcast, "\t%llu multicast datagram%s dropped due to no socket\n");
309 p1(udp6s_fullsock, "\t%llu dropped due to full socket buffers\n");
310 delivered = udp6stat.udp6s_ipackets -
311 udp6stat.udp6s_hdrops -
312 udp6stat.udp6s_badlen -
313 udp6stat.udp6s_badsum -
314 udp6stat.udp6s_noport -
315 udp6stat.udp6s_noportmcast -
316 udp6stat.udp6s_fullsock;
317 if (delivered || sflag <= 1)
318 printf("\t%llu delivered\n", (unsigned long long)delivered);
319 p(udp6s_opackets, "\t%llu datagram%s output\n");
320 #undef p
321 #undef p1
322 }
323
324 static char *ip6nh[] = {
325 "hop by hop",
326 "ICMP",
327 "IGMP",
328 "#3",
329 "IP",
330 "#5",
331 "TCP",
332 "#7",
333 "#8",
334 "#9",
335 "#10",
336 "#11",
337 "#12",
338 "#13",
339 "#14",
340 "#15",
341 "#16",
342 "UDP",
343 "#18",
344 "#19",
345 "#20",
346 "#21",
347 "IDP",
348 "#23",
349 "#24",
350 "#25",
351 "#26",
352 "#27",
353 "#28",
354 "TP",
355 "#30",
356 "#31",
357 "#32",
358 "#33",
359 "#34",
360 "#35",
361 "#36",
362 "#37",
363 "#38",
364 "#39",
365 "#40",
366 "IP6",
367 "#42",
368 "routing",
369 "fragment",
370 "#45",
371 "#46",
372 "#47",
373 "#48",
374 "#49",
375 "ESP",
376 "AH",
377 "#52",
378 "#53",
379 "#54",
380 "#55",
381 "#56",
382 "#57",
383 "ICMP6",
384 "no next header",
385 "destination option",
386 "#61",
387 "#62",
388 "#63",
389 "#64",
390 "#65",
391 "#66",
392 "#67",
393 "#68",
394 "#69",
395 "#70",
396 "#71",
397 "#72",
398 "#73",
399 "#74",
400 "#75",
401 "#76",
402 "#77",
403 "#78",
404 "#79",
405 "ISOIP",
406 "#81",
407 "#82",
408 "#83",
409 "#84",
410 "#85",
411 "#86",
412 "#87",
413 "#88",
414 "#89",
415 "#80",
416 "#91",
417 "#92",
418 "#93",
419 "#94",
420 "#95",
421 "#96",
422 "Ethernet",
423 "#98",
424 "#99",
425 "#100",
426 "#101",
427 "#102",
428 "PIM",
429 "#104",
430 "#105",
431 "#106",
432 "#107",
433 "#108",
434 "#109",
435 "#110",
436 "#111",
437 "#112",
438 "#113",
439 "#114",
440 "#115",
441 "#116",
442 "#117",
443 "#118",
444 "#119",
445 "#120",
446 "#121",
447 "#122",
448 "#123",
449 "#124",
450 "#125",
451 "#126",
452 "#127",
453 "#128",
454 "#129",
455 "#130",
456 "#131",
457 "#132",
458 "#133",
459 "#134",
460 "#135",
461 "#136",
462 "#137",
463 "#138",
464 "#139",
465 "#140",
466 "#141",
467 "#142",
468 "#143",
469 "#144",
470 "#145",
471 "#146",
472 "#147",
473 "#148",
474 "#149",
475 "#150",
476 "#151",
477 "#152",
478 "#153",
479 "#154",
480 "#155",
481 "#156",
482 "#157",
483 "#158",
484 "#159",
485 "#160",
486 "#161",
487 "#162",
488 "#163",
489 "#164",
490 "#165",
491 "#166",
492 "#167",
493 "#168",
494 "#169",
495 "#170",
496 "#171",
497 "#172",
498 "#173",
499 "#174",
500 "#175",
501 "#176",
502 "#177",
503 "#178",
504 "#179",
505 "#180",
506 "#181",
507 "#182",
508 "#183",
509 "#184",
510 "#185",
511 "#186",
512 "#187",
513 "#188",
514 "#189",
515 "#180",
516 "#191",
517 "#192",
518 "#193",
519 "#194",
520 "#195",
521 "#196",
522 "#197",
523 "#198",
524 "#199",
525 "#200",
526 "#201",
527 "#202",
528 "#203",
529 "#204",
530 "#205",
531 "#206",
532 "#207",
533 "#208",
534 "#209",
535 "#210",
536 "#211",
537 "#212",
538 "#213",
539 "#214",
540 "#215",
541 "#216",
542 "#217",
543 "#218",
544 "#219",
545 "#220",
546 "#221",
547 "#222",
548 "#223",
549 "#224",
550 "#225",
551 "#226",
552 "#227",
553 "#228",
554 "#229",
555 "#230",
556 "#231",
557 "#232",
558 "#233",
559 "#234",
560 "#235",
561 "#236",
562 "#237",
563 "#238",
564 "#239",
565 "#240",
566 "#241",
567 "#242",
568 "#243",
569 "#244",
570 "#245",
571 "#246",
572 "#247",
573 "#248",
574 "#249",
575 "#250",
576 "#251",
577 "#252",
578 "#253",
579 "#254",
580 "#255",
581 };
582
583 /*
584 * Dump IP6 statistics structure.
585 */
586 void
587 ip6_stats(off, name)
588 u_long off;
589 char *name;
590 {
591 struct ip6stat ip6stat;
592 int first, i;
593
594 if (off == 0)
595 return;
596
597 kread(off, (char *)&ip6stat, sizeof (ip6stat));
598 printf("%s:\n", name);
599
600 #define p(f, m) if (ip6stat.f || sflag <= 1) \
601 printf(m, (unsigned long long)ip6stat.f, plural(ip6stat.f))
602 #define p1(f, m) if (ip6stat.f || sflag <= 1) \
603 printf(m, (unsigned long long)ip6stat.f)
604
605 p(ip6s_total, "\t%llu total packet%s received\n");
606 p1(ip6s_toosmall, "\t%llu with size smaller than minimum\n");
607 p1(ip6s_tooshort, "\t%llu with data size < data length\n");
608 p1(ip6s_badoptions, "\t%llu with bad options\n");
609 p1(ip6s_badvers, "\t%llu with incorrect version number\n");
610 p(ip6s_fragments, "\t%llu fragment%s received\n");
611 p(ip6s_fragdropped,
612 "\t%llu fragment%s dropped (dup or out of space)\n");
613 p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n");
614 p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n");
615 p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n");
616 p(ip6s_delivered, "\t%llu packet%s for this host\n");
617 p(ip6s_forward, "\t%llu packet%s forwarded\n");
618 p(ip6s_cantforward, "\t%llu packet%s not forwardable\n");
619 p(ip6s_redirectsent, "\t%llu redirect%s sent\n");
620 p(ip6s_localout, "\t%llu packet%s sent from this host\n");
621 p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n");
622 p(ip6s_odropped,
623 "\t%llu output packet%s dropped due to no bufs, etc.\n");
624 p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n");
625 p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n");
626 p(ip6s_ofragments, "\t%llu fragment%s created\n");
627 p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n");
628 p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n");
629 p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n");
630 for (first = 1, i = 0; i < 256; i++)
631 if (ip6stat.ip6s_nxthist[i] != 0) {
632 if (first) {
633 printf("\tInput histogram:\n");
634 first = 0;
635 }
636 printf("\t\t%s: %llu\n", ip6nh[i],
637 (unsigned long long)ip6stat.ip6s_nxthist[i]);
638 }
639 printf("\tMbuf statics:\n");
640 printf("\t\t%llu one mbuf\n", (unsigned long long)ip6stat.ip6s_m1);
641 for (first = 1, i = 0; i < 32; i++) {
642 char ifbuf[IFNAMSIZ];
643 if (ip6stat.ip6s_m2m[i] != 0) {
644 if (first) {
645 printf("\t\ttwo or more mbuf:\n");
646 first = 0;
647 }
648 printf("\t\t\t%s = %llu\n",
649 if_indextoname(i, ifbuf),
650 (unsigned long long)ip6stat.ip6s_m2m[i]);
651 }
652 }
653 printf("\t\t%llu one ext mbuf\n",
654 (unsigned long long)ip6stat.ip6s_mext1);
655 printf("\t\t%llu two or more ext mbuf\n",
656 (unsigned long long)ip6stat.ip6s_mext2m);
657 p(ip6s_exthdrtoolong,
658 "\t%llu packet%s whose headers are not continuous\n");
659 p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n");
660 #undef p
661 #undef p1
662 }
663
664 static char *icmp6names[] = {
665 "#0",
666 "unreach",
667 "packet too big",
668 "time exceed",
669 "parameter problem",
670 "#5",
671 "#6",
672 "#7",
673 "#8",
674 "#9",
675 "#10",
676 "#11",
677 "#12",
678 "#13",
679 "#14",
680 "#15",
681 "#16",
682 "#17",
683 "#18",
684 "#19",
685 "#20",
686 "#21",
687 "#22",
688 "#23",
689 "#24",
690 "#25",
691 "#26",
692 "#27",
693 "#28",
694 "#29",
695 "#30",
696 "#31",
697 "#32",
698 "#33",
699 "#34",
700 "#35",
701 "#36",
702 "#37",
703 "#38",
704 "#39",
705 "#40",
706 "#41",
707 "#42",
708 "#43",
709 "#44",
710 "#45",
711 "#46",
712 "#47",
713 "#48",
714 "#49",
715 "#50",
716 "#51",
717 "#52",
718 "#53",
719 "#54",
720 "#55",
721 "#56",
722 "#57",
723 "#58",
724 "#59",
725 "#60",
726 "#61",
727 "#62",
728 "#63",
729 "#64",
730 "#65",
731 "#66",
732 "#67",
733 "#68",
734 "#69",
735 "#70",
736 "#71",
737 "#72",
738 "#73",
739 "#74",
740 "#75",
741 "#76",
742 "#77",
743 "#78",
744 "#79",
745 "#80",
746 "#81",
747 "#82",
748 "#83",
749 "#84",
750 "#85",
751 "#86",
752 "#87",
753 "#88",
754 "#89",
755 "#80",
756 "#91",
757 "#92",
758 "#93",
759 "#94",
760 "#95",
761 "#96",
762 "#97",
763 "#98",
764 "#99",
765 "#100",
766 "#101",
767 "#102",
768 "#103",
769 "#104",
770 "#105",
771 "#106",
772 "#107",
773 "#108",
774 "#109",
775 "#110",
776 "#111",
777 "#112",
778 "#113",
779 "#114",
780 "#115",
781 "#116",
782 "#117",
783 "#118",
784 "#119",
785 "#120",
786 "#121",
787 "#122",
788 "#123",
789 "#124",
790 "#125",
791 "#126",
792 "#127",
793 "echo",
794 "echo reply",
795 "group member query",
796 "group member report",
797 "group member termination",
798 "router solicitation",
799 "router advertisment",
800 "neighbor solicitation",
801 "neighbor advertisment",
802 "redirect",
803 "router renumbering",
804 "node information request",
805 "node information reply",
806 "#141",
807 "#142",
808 "#143",
809 "#144",
810 "#145",
811 "#146",
812 "#147",
813 "#148",
814 "#149",
815 "#150",
816 "#151",
817 "#152",
818 "#153",
819 "#154",
820 "#155",
821 "#156",
822 "#157",
823 "#158",
824 "#159",
825 "#160",
826 "#161",
827 "#162",
828 "#163",
829 "#164",
830 "#165",
831 "#166",
832 "#167",
833 "#168",
834 "#169",
835 "#170",
836 "#171",
837 "#172",
838 "#173",
839 "#174",
840 "#175",
841 "#176",
842 "#177",
843 "#178",
844 "#179",
845 "#180",
846 "#181",
847 "#182",
848 "#183",
849 "#184",
850 "#185",
851 "#186",
852 "#187",
853 "#188",
854 "#189",
855 "#180",
856 "#191",
857 "#192",
858 "#193",
859 "#194",
860 "#195",
861 "#196",
862 "#197",
863 "#198",
864 "#199",
865 "#200",
866 "#201",
867 "#202",
868 "#203",
869 "#204",
870 "#205",
871 "#206",
872 "#207",
873 "#208",
874 "#209",
875 "#210",
876 "#211",
877 "#212",
878 "#213",
879 "#214",
880 "#215",
881 "#216",
882 "#217",
883 "#218",
884 "#219",
885 "#220",
886 "#221",
887 "#222",
888 "#223",
889 "#224",
890 "#225",
891 "#226",
892 "#227",
893 "#228",
894 "#229",
895 "#230",
896 "#231",
897 "#232",
898 "#233",
899 "#234",
900 "#235",
901 "#236",
902 "#237",
903 "#238",
904 "#239",
905 "#240",
906 "#241",
907 "#242",
908 "#243",
909 "#244",
910 "#245",
911 "#246",
912 "#247",
913 "#248",
914 "#249",
915 "#250",
916 "#251",
917 "#252",
918 "#253",
919 "#254",
920 "#255",
921 };
922
923 /*
924 * Dump ICMP6 statistics.
925 */
926 void
927 icmp6_stats(off, name)
928 u_long off;
929 char *name;
930 {
931 struct icmp6stat icmp6stat;
932 register int i, first;
933
934 if (off == 0)
935 return;
936 kread(off, (char *)&icmp6stat, sizeof (icmp6stat));
937 printf("%s:\n", name);
938
939 #define p(f, m) if (icmp6stat.f || sflag <= 1) \
940 printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f))
941
942 p(icp6s_error, "\t%llu call%s to icmp_error\n");
943 p(icp6s_canterror, "\t%llu error%s not generated because old message "
944 "was icmp or so\n");
945 for (first = 1, i = 0; i < 256; i++)
946 if (icmp6stat.icp6s_outhist[i] != 0) {
947 if (first) {
948 printf("\tOutput histogram:\n");
949 first = 0;
950 }
951 printf("\t\t%s: %llu\n", icmp6names[i],
952 (unsigned long long)icmp6stat.icp6s_outhist[i]);
953 }
954 p(icp6s_badcode, "\t%llu message%s with bad code fields\n");
955 p(icp6s_tooshort, "\t%llu message%s < minimum length\n");
956 p(icp6s_checksum, "\t%llu bad checksum%s\n");
957 p(icp6s_badlen, "\t%llu message%s with bad length\n");
958 for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++)
959 if (icmp6stat.icp6s_inhist[i] != 0) {
960 if (first) {
961 printf("\tInput histogram:\n");
962 first = 0;
963 }
964 printf("\t\t%s: %llu\n", icmp6names[i],
965 (unsigned long long)icmp6stat.icp6s_inhist[i]);
966 }
967 p(icp6s_reflect, "\t%llu message response%s generated\n");
968 #undef p
969 }
970
971 /*
972 * Dump PIM statistics structure.
973 */
974 void
975 pim6_stats(off, name)
976 u_long off;
977 char *name;
978 {
979 struct pim6stat pim6stat;
980
981 if (off == 0)
982 return;
983 kread(off, (char *)&pim6stat, sizeof(pim6stat));
984 printf("%s:\n", name);
985
986 #define p(f, m) if (pim6stat.f || sflag <= 1) \
987 printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.f))
988 p(pim6s_rcv_total, "\t%llu message%s received\n");
989 p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
990 p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n");
991 p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n");
992 p(pim6s_rcv_registers, "\t%llu register%s received\n");
993 p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n");
994 p(pim6s_snd_registers, "\t%llu register%s sent\n");
995 #undef p
996 }
997
998 /*
999 * Pretty print an Internet address (net address + port).
1000 * If the nflag was specified, use numbers instead of names.
1001 */
1002
1003 void
1004 inet6print(in6, port, proto)
1005 register struct in6_addr *in6;
1006 int port;
1007 char *proto;
1008 {
1009 #define GETSERVBYPORT6(port, proto, ret)\
1010 {\
1011 if (strcmp((proto), "tcp6") == 0)\
1012 (ret) = getservbyport((int)(port), "tcp");\
1013 else if (strcmp((proto), "udp6") == 0)\
1014 (ret) = getservbyport((int)(port), "udp");\
1015 else\
1016 (ret) = getservbyport((int)(port), (proto));\
1017 };
1018 struct servent *sp = 0;
1019 char line[80], *cp;
1020 int width;
1021
1022 sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inet6name(in6));
1023 cp = index(line, '\0');
1024 if (!nflag && port)
1025 GETSERVBYPORT6(port, proto, sp);
1026 if (sp || port == 0)
1027 sprintf(cp, "%.8s", sp ? sp->s_name : "*");
1028 else
1029 sprintf(cp, "%d", ntohs((u_short)port));
1030 width = Aflag ? 18 : 22;
1031 printf(" %-*.*s", width, width, line);
1032 }
1033
1034 /*
1035 * Construct an Internet address representation.
1036 * If the nflag has been supplied, give
1037 * numeric value, otherwise try for symbolic name.
1038 */
1039
1040 char *
1041 inet6name(in6p)
1042 struct in6_addr *in6p;
1043 {
1044 register char *cp;
1045 static char line[50];
1046 struct hostent *hp;
1047 static char domain[MAXHOSTNAMELEN + 1];
1048 static int first = 1;
1049
1050 if (first && !nflag) {
1051 first = 0;
1052 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1053 (cp = index(domain, '.')))
1054 (void) strcpy(domain, cp + 1);
1055 else
1056 domain[0] = 0;
1057 }
1058 cp = 0;
1059 if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1060 hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
1061 if (hp) {
1062 if ((cp = index(hp->h_name, '.')) &&
1063 !strcmp(cp + 1, domain))
1064 *cp = 0;
1065 cp = hp->h_name;
1066 }
1067 }
1068 if (IN6_IS_ADDR_UNSPECIFIED(in6p))
1069 strcpy(line, "*");
1070 else if (cp)
1071 strcpy(line, cp);
1072 else
1073 sprintf(line, "%s",
1074 inet_ntop(AF_INET6, (void *)in6p, ntop_buf,
1075 sizeof(ntop_buf)));
1076 return (line);
1077 }
1078
1079 #ifdef TCP6
1080 /*
1081 * Dump the contents of a TCP6 PCB.
1082 */
1083 void
1084 tcp6_dump(pcbaddr)
1085 u_long pcbaddr;
1086 {
1087 struct tcp6cb tcp6cb;
1088 int i;
1089
1090 kread(pcbaddr, (char *)&tcp6cb, sizeof(tcp6cb));
1091
1092 printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
1093
1094 printf("Timers:\n");
1095 for (i = 0; i < TCP6T_NTIMERS; i++)
1096 printf("\t%s: %u", tcp6timers[i], tcp6cb.t_timer[i]);
1097 printf("\n\n");
1098
1099 if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES)
1100 printf("State: %d", tcp6cb.t_state);
1101 else
1102 printf("State: %s", tcp6states[tcp6cb.t_state]);
1103 printf(", flags 0x%x, in6pcb 0x%lx\n\n", tcp6cb.t_flags,
1104 (u_long)tcp6cb.t_in6pcb);
1105
1106 printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcp6cb.t_rxtshift,
1107 tcp6cb.t_rxtcur, tcp6cb.t_dupacks);
1108 printf("peermaxseg %u, maxseg %u, force %d\n\n", tcp6cb.t_peermaxseg,
1109 tcp6cb.t_maxseg, tcp6cb.t_force);
1110
1111 printf("snd_una %u, snd_nxt %u, snd_up %u\n",
1112 tcp6cb.snd_una, tcp6cb.snd_nxt, tcp6cb.snd_up);
1113 printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %llu\n\n",
1114 tcp6cb.snd_wl1, tcp6cb.snd_wl2, tcp6cb.iss,
1115 (unsigned long long)tcp6cb.snd_wnd);
1116
1117 printf("rcv_wnd %llu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
1118 (unsigned long long)cp6cb.rcv_wnd, tcp6cb.rcv_nxt,
1119 tcp6cb.rcv_up, tcp6cb.irs);
1120
1121 printf("rcv_adv %u, snd_max %u, snd_cwnd %llu, snd_ssthresh %llu\n",
1122 tcp6cb.rcv_adv, tcp6cb.snd_max, (unsigned long long)tcp6cb.snd_cwnd,
1123 (unsigned long long)tcp6cb.snd_ssthresh);
1124
1125 printf("idle %d, rtt %d, rtseq %u, srtt %d, rttvar %d, rttmin %d, "
1126 "max_sndwnd %llu\n\n", tcp6cb.t_idle, tcp6cb.t_rtt, tcp6cb.t_rtseq,
1127 tcp6cb.t_srtt, tcp6cb.t_rttvar, tcp6cb.t_rttmin,
1128 (unsigned long long)tcp6cb.max_sndwnd);
1129
1130 printf("oobflags %d, iobc %d, softerror %d\n\n", tcp6cb.t_oobflags,
1131 tcp6cb.t_iobc, tcp6cb.t_softerror);
1132
1133 printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
1134 tcp6cb.snd_scale, tcp6cb.rcv_scale, tcp6cb.request_r_scale,
1135 tcp6cb.requested_s_scale);
1136 printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
1137 tcp6cb.ts_recent, tcp6cb.ts_recent_age, tcp6cb.last_ack_sent);
1138 }
1139 #endif
1140
1141 #endif /*INET6*/
1142