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