1 /* $NetBSD: inet6.c,v 1.3 1999/07/30 10:31:22 itojun 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.3 1999/07/30 10:31:22 itojun 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_long 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, udp6stat.f, plural(udp6stat.f)) 300 #define p1(f, m) if (udp6stat.f || sflag <= 1) \ 301 printf(m, udp6stat.f) 302 p(udp6s_ipackets, "\t%lu datagram%s received\n"); 303 p1(udp6s_hdrops, "\t%lu with incomplete header\n"); 304 p1(udp6s_badlen, "\t%lu with bad data length field\n"); 305 p1(udp6s_badsum, "\t%lu with bad checksum\n"); 306 p1(udp6s_nosum, "\t%lu with no checksum\n"); 307 p1(udp6s_noport, "\t%lu dropped due to no socket\n"); 308 p(udp6s_noportmcast, "\t%lu multicast datagram%s dropped due to no socket\n"); 309 p1(udp6s_fullsock, "\t%lu 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%lu delivered\n", delivered); 319 p(udp6s_opackets, "\t%lu 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, ip6stat.f, plural(ip6stat.f)) 602 #define p1(f, m) if (ip6stat.f || sflag <= 1) \ 603 printf(m, ip6stat.f) 604 605 p(ip6s_total, "\t%lu total packet%s received\n"); 606 p1(ip6s_toosmall, "\t%lu with size smaller than minimum\n"); 607 p1(ip6s_tooshort, "\t%lu with data size < data length\n"); 608 p1(ip6s_badoptions, "\t%lu with bad options\n"); 609 p1(ip6s_badvers, "\t%lu with incorrect version number\n"); 610 p(ip6s_fragments, "\t%lu fragment%s received\n"); 611 p(ip6s_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 612 p(ip6s_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 613 p(ip6s_fragoverflow, "\t%lu fragment%s that exceeded limit\n"); 614 p(ip6s_reassembled, "\t%lu packet%s reassembled ok\n"); 615 p(ip6s_delivered, "\t%lu packet%s for this host\n"); 616 p(ip6s_forward, "\t%lu packet%s forwarded\n"); 617 p(ip6s_cantforward, "\t%lu packet%s not forwardable\n"); 618 p(ip6s_redirectsent, "\t%lu redirect%s sent\n"); 619 p(ip6s_localout, "\t%lu packet%s sent from this host\n"); 620 p(ip6s_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 621 p(ip6s_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n"); 622 p(ip6s_noroute, "\t%lu output packet%s discarded due to no route\n"); 623 p(ip6s_fragmented, "\t%lu output datagram%s fragmented\n"); 624 p(ip6s_ofragments, "\t%lu fragment%s created\n"); 625 p(ip6s_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 626 p(ip6s_badscope, "\t%lu packet%s that violated scope rules\n"); 627 p(ip6s_notmember, "\t%lu multicast packet%s which we don't join\n"); 628 for (first = 1, i = 0; i < 256; i++) 629 if (ip6stat.ip6s_nxthist[i] != 0) { 630 if (first) { 631 printf("\tInput histogram:\n"); 632 first = 0; 633 } 634 printf("\t\t%s: %lu\n", ip6nh[i], 635 ip6stat.ip6s_nxthist[i]); 636 } 637 printf("\tMbuf statics:\n"); 638 printf("\t\t%lu one mbuf\n", ip6stat.ip6s_m1); 639 for (first = 1, i = 0; i < 32; i++) { 640 char ifbuf[IFNAMSIZ]; 641 if (ip6stat.ip6s_m2m[i] != 0) { 642 if (first) { 643 printf("\t\ttwo or more mbuf:\n"); 644 first = 0; 645 } 646 printf("\t\t\t%s = %ld\n", 647 if_indextoname(i, ifbuf), 648 ip6stat.ip6s_m2m[i]); 649 } 650 } 651 printf("\t\t%lu one ext mbuf\n", ip6stat.ip6s_mext1); 652 printf("\t\t%lu two or more ext mbuf\n", ip6stat.ip6s_mext2m); 653 p(ip6s_exthdrtoolong, "\t%lu packet%s whose headers are not continuous\n"); 654 p(ip6s_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 655 #undef p 656 #undef p1 657 } 658 659 static char *icmp6names[] = { 660 "#0", 661 "unreach", 662 "packet too big", 663 "time exceed", 664 "parameter problem", 665 "#5", 666 "#6", 667 "#7", 668 "#8", 669 "#9", 670 "#10", 671 "#11", 672 "#12", 673 "#13", 674 "#14", 675 "#15", 676 "#16", 677 "#17", 678 "#18", 679 "#19", 680 "#20", 681 "#21", 682 "#22", 683 "#23", 684 "#24", 685 "#25", 686 "#26", 687 "#27", 688 "#28", 689 "#29", 690 "#30", 691 "#31", 692 "#32", 693 "#33", 694 "#34", 695 "#35", 696 "#36", 697 "#37", 698 "#38", 699 "#39", 700 "#40", 701 "#41", 702 "#42", 703 "#43", 704 "#44", 705 "#45", 706 "#46", 707 "#47", 708 "#48", 709 "#49", 710 "#50", 711 "#51", 712 "#52", 713 "#53", 714 "#54", 715 "#55", 716 "#56", 717 "#57", 718 "#58", 719 "#59", 720 "#60", 721 "#61", 722 "#62", 723 "#63", 724 "#64", 725 "#65", 726 "#66", 727 "#67", 728 "#68", 729 "#69", 730 "#70", 731 "#71", 732 "#72", 733 "#73", 734 "#74", 735 "#75", 736 "#76", 737 "#77", 738 "#78", 739 "#79", 740 "#80", 741 "#81", 742 "#82", 743 "#83", 744 "#84", 745 "#85", 746 "#86", 747 "#87", 748 "#88", 749 "#89", 750 "#80", 751 "#91", 752 "#92", 753 "#93", 754 "#94", 755 "#95", 756 "#96", 757 "#97", 758 "#98", 759 "#99", 760 "#100", 761 "#101", 762 "#102", 763 "#103", 764 "#104", 765 "#105", 766 "#106", 767 "#107", 768 "#108", 769 "#109", 770 "#110", 771 "#111", 772 "#112", 773 "#113", 774 "#114", 775 "#115", 776 "#116", 777 "#117", 778 "#118", 779 "#119", 780 "#120", 781 "#121", 782 "#122", 783 "#123", 784 "#124", 785 "#125", 786 "#126", 787 "#127", 788 "echo", 789 "echo reply", 790 "group member query", 791 "group member report", 792 "group member termination", 793 "router solicitation", 794 "router advertisment", 795 "neighbor solicitation", 796 "neighbor advertisment", 797 "redirect", 798 "router renumbering", 799 "node information request", 800 "node information reply", 801 "#141", 802 "#142", 803 "#143", 804 "#144", 805 "#145", 806 "#146", 807 "#147", 808 "#148", 809 "#149", 810 "#150", 811 "#151", 812 "#152", 813 "#153", 814 "#154", 815 "#155", 816 "#156", 817 "#157", 818 "#158", 819 "#159", 820 "#160", 821 "#161", 822 "#162", 823 "#163", 824 "#164", 825 "#165", 826 "#166", 827 "#167", 828 "#168", 829 "#169", 830 "#170", 831 "#171", 832 "#172", 833 "#173", 834 "#174", 835 "#175", 836 "#176", 837 "#177", 838 "#178", 839 "#179", 840 "#180", 841 "#181", 842 "#182", 843 "#183", 844 "#184", 845 "#185", 846 "#186", 847 "#187", 848 "#188", 849 "#189", 850 "#180", 851 "#191", 852 "#192", 853 "#193", 854 "#194", 855 "#195", 856 "#196", 857 "#197", 858 "#198", 859 "#199", 860 "#200", 861 "#201", 862 "#202", 863 "#203", 864 "#204", 865 "#205", 866 "#206", 867 "#207", 868 "#208", 869 "#209", 870 "#210", 871 "#211", 872 "#212", 873 "#213", 874 "#214", 875 "#215", 876 "#216", 877 "#217", 878 "#218", 879 "#219", 880 "#220", 881 "#221", 882 "#222", 883 "#223", 884 "#224", 885 "#225", 886 "#226", 887 "#227", 888 "#228", 889 "#229", 890 "#230", 891 "#231", 892 "#232", 893 "#233", 894 "#234", 895 "#235", 896 "#236", 897 "#237", 898 "#238", 899 "#239", 900 "#240", 901 "#241", 902 "#242", 903 "#243", 904 "#244", 905 "#245", 906 "#246", 907 "#247", 908 "#248", 909 "#249", 910 "#250", 911 "#251", 912 "#252", 913 "#253", 914 "#254", 915 "#255", 916 }; 917 918 /* 919 * Dump ICMP6 statistics. 920 */ 921 void 922 icmp6_stats(off, name) 923 u_long off; 924 char *name; 925 { 926 struct icmp6stat icmp6stat; 927 register int i, first; 928 929 if (off == 0) 930 return; 931 kread(off, (char *)&icmp6stat, sizeof (icmp6stat)); 932 printf("%s:\n", name); 933 934 #define p(f, m) if (icmp6stat.f || sflag <= 1) \ 935 printf(m, icmp6stat.f, plural(icmp6stat.f)) 936 937 p(icp6s_error, "\t%lu call%s to icmp_error\n"); 938 p(icp6s_canterror, 939 "\t%lu error%s not generated because old message was icmp or so\n"); 940 for (first = 1, i = 0; i < 256; i++) 941 if (icmp6stat.icp6s_outhist[i] != 0) { 942 if (first) { 943 printf("\tOutput histogram:\n"); 944 first = 0; 945 } 946 printf("\t\t%s: %lu\n", icmp6names[i], 947 icmp6stat.icp6s_outhist[i]); 948 } 949 p(icp6s_badcode, "\t%lu message%s with bad code fields\n"); 950 p(icp6s_tooshort, "\t%lu message%s < minimum length\n"); 951 p(icp6s_checksum, "\t%lu bad checksum%s\n"); 952 p(icp6s_badlen, "\t%lu message%s with bad length\n"); 953 for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++) 954 if (icmp6stat.icp6s_inhist[i] != 0) { 955 if (first) { 956 printf("\tInput histogram:\n"); 957 first = 0; 958 } 959 printf("\t\t%s: %lu\n", icmp6names[i], 960 icmp6stat.icp6s_inhist[i]); 961 } 962 p(icp6s_reflect, "\t%lu message response%s generated\n"); 963 #undef p 964 } 965 966 /* 967 * Dump PIM statistics structure. 968 */ 969 void 970 pim6_stats(off, name) 971 u_long off; 972 char *name; 973 { 974 struct pim6stat pim6stat; 975 976 if (off == 0) 977 return; 978 kread(off, (char *)&pim6stat, sizeof(pim6stat)); 979 printf("%s:\n", name); 980 981 #define p(f, m) if (pim6stat.f || sflag <= 1) \ 982 printf(m, pim6stat.f, plural(pim6stat.f)) 983 p(pim6s_rcv_total, "\t%u message%s received\n"); 984 p(pim6s_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 985 p(pim6s_rcv_badsum, "\t%u message%s received with bad checksum\n"); 986 p(pim6s_rcv_badversion, "\t%u message%s received with bad version\n"); 987 p(pim6s_rcv_registers, "\t%u register%s received\n"); 988 p(pim6s_rcv_badregisters, "\t%u bad register%s received\n"); 989 p(pim6s_snd_registers, "\t%u register%s sent\n"); 990 #undef p 991 } 992 993 /* 994 * Pretty print an Internet address (net address + port). 995 * If the nflag was specified, use numbers instead of names. 996 */ 997 998 void 999 inet6print(in6, port, proto) 1000 register struct in6_addr *in6; 1001 int port; 1002 char *proto; 1003 { 1004 #define GETSERVBYPORT6(port, proto, ret)\ 1005 {\ 1006 if (strcmp((proto), "tcp6") == 0)\ 1007 (ret) = getservbyport((int)(port), "tcp");\ 1008 else if (strcmp((proto), "udp6") == 0)\ 1009 (ret) = getservbyport((int)(port), "udp");\ 1010 else\ 1011 (ret) = getservbyport((int)(port), (proto));\ 1012 }; 1013 struct servent *sp = 0; 1014 char line[80], *cp; 1015 int width; 1016 1017 sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inet6name(in6)); 1018 cp = index(line, '\0'); 1019 if (!nflag && port) 1020 GETSERVBYPORT6(port, proto, sp); 1021 if (sp || port == 0) 1022 sprintf(cp, "%.8s", sp ? sp->s_name : "*"); 1023 else 1024 sprintf(cp, "%d", ntohs((u_short)port)); 1025 width = Aflag ? 18 : 22; 1026 printf(" %-*.*s", width, width, line); 1027 } 1028 1029 /* 1030 * Construct an Internet address representation. 1031 * If the nflag has been supplied, give 1032 * numeric value, otherwise try for symbolic name. 1033 */ 1034 1035 char * 1036 inet6name(in6p) 1037 struct in6_addr *in6p; 1038 { 1039 register char *cp; 1040 static char line[50]; 1041 struct hostent *hp; 1042 static char domain[MAXHOSTNAMELEN + 1]; 1043 static int first = 1; 1044 1045 if (first && !nflag) { 1046 first = 0; 1047 if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 1048 (cp = index(domain, '.'))) 1049 (void) strcpy(domain, cp + 1); 1050 else 1051 domain[0] = 0; 1052 } 1053 cp = 0; 1054 if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { 1055 hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); 1056 if (hp) { 1057 if ((cp = index(hp->h_name, '.')) && 1058 !strcmp(cp + 1, domain)) 1059 *cp = 0; 1060 cp = hp->h_name; 1061 } 1062 } 1063 if (IN6_IS_ADDR_UNSPECIFIED(in6p)) 1064 strcpy(line, "*"); 1065 else if (cp) 1066 strcpy(line, cp); 1067 else 1068 sprintf(line, "%s", 1069 inet_ntop(AF_INET6, (void *)in6p, ntop_buf, 1070 sizeof(ntop_buf))); 1071 return (line); 1072 } 1073 1074 #ifdef TCP6 1075 /* 1076 * Dump the contents of a TCP6 PCB. 1077 */ 1078 void 1079 tcp6_dump(pcbaddr) 1080 u_long pcbaddr; 1081 { 1082 struct tcp6cb tcp6cb; 1083 int i; 1084 1085 kread(pcbaddr, (char *)&tcp6cb, sizeof(tcp6cb)); 1086 1087 printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr); 1088 1089 printf("Timers:\n"); 1090 for (i = 0; i < TCP6T_NTIMERS; i++) 1091 printf("\t%s: %u", tcp6timers[i], tcp6cb.t_timer[i]); 1092 printf("\n\n"); 1093 1094 if (tcp6cb.t_state < 0 || tcp6cb.t_state >= TCP6_NSTATES) 1095 printf("State: %d", tcp6cb.t_state); 1096 else 1097 printf("State: %s", tcp6states[tcp6cb.t_state]); 1098 printf(", flags 0x%x, in6pcb 0x%lx\n\n", tcp6cb.t_flags, 1099 (u_long)tcp6cb.t_in6pcb); 1100 1101 printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcp6cb.t_rxtshift, 1102 tcp6cb.t_rxtcur, tcp6cb.t_dupacks); 1103 printf("peermaxseg %u, maxseg %u, force %d\n\n", tcp6cb.t_peermaxseg, 1104 tcp6cb.t_maxseg, tcp6cb.t_force); 1105 1106 printf("snd_una %u, snd_nxt %u, snd_up %u\n", 1107 tcp6cb.snd_una, tcp6cb.snd_nxt, tcp6cb.snd_up); 1108 printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %lu\n\n", 1109 tcp6cb.snd_wl1, tcp6cb.snd_wl2, tcp6cb.iss, tcp6cb.snd_wnd); 1110 1111 printf("rcv_wnd %lu, rcv_nxt %u, rcv_up %u, irs %u\n\n", 1112 tcp6cb.rcv_wnd, tcp6cb.rcv_nxt, tcp6cb.rcv_up, tcp6cb.irs); 1113 1114 printf("rcv_adv %u, snd_max %u, snd_cwnd %lu, snd_ssthresh %lu\n", 1115 tcp6cb.rcv_adv, tcp6cb.snd_max, tcp6cb.snd_cwnd, tcp6cb.snd_ssthresh); 1116 1117 printf("idle %d, rtt %d, rtseq %u, srtt %d, rttvar %d, rttmin %d, " 1118 "max_sndwnd %lu\n\n", tcp6cb.t_idle, tcp6cb.t_rtt, tcp6cb.t_rtseq, 1119 tcp6cb.t_srtt, tcp6cb.t_rttvar, tcp6cb.t_rttmin, tcp6cb.max_sndwnd); 1120 1121 printf("oobflags %d, iobc %d, softerror %d\n\n", tcp6cb.t_oobflags, 1122 tcp6cb.t_iobc, tcp6cb.t_softerror); 1123 1124 printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n", 1125 tcp6cb.snd_scale, tcp6cb.rcv_scale, tcp6cb.request_r_scale, 1126 tcp6cb.requested_s_scale); 1127 printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n", 1128 tcp6cb.ts_recent, tcp6cb.ts_recent_age, tcp6cb.last_ack_sent); 1129 } 1130 #endif 1131 1132 #endif /*INET6*/ 1133