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