1 /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2 /* 3 * Copyright (c) 1983, 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $FreeBSD$ 35 */ 36 37 #ifndef lint 38 /* 39 static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; 40 */ 41 #endif /* not lint */ 42 43 #include <sys/param.h> 44 #include <sys/socket.h> 45 #include <sys/socketvar.h> 46 #include <sys/ioctl.h> 47 #include <sys/mbuf.h> 48 #include <sys/protosw.h> 49 50 #include <net/route.h> 51 #include <net/if.h> 52 #include <net/if_var.h> 53 #include <netinet/in.h> 54 #include <netinet/ip6.h> 55 #include <netinet/icmp6.h> 56 #include <netinet/in_systm.h> 57 #include <netinet6/in6_pcb.h> 58 #include <netinet6/in6_var.h> 59 #include <netinet6/ip6_var.h> 60 #include <netinet6/pim6_var.h> 61 62 #include <arpa/inet.h> 63 #include <netdb.h> 64 65 #include <stdio.h> 66 #include <string.h> 67 #include <unistd.h> 68 #include "netstat.h" 69 70 struct socket sockb; 71 72 char *inet6name __P((struct in6_addr *)); 73 void inet6print __P((struct in6_addr *, int, char *, int)); 74 75 static char ntop_buf[INET6_ADDRSTRLEN]; 76 77 static char *ip6nh[] = { 78 "hop by hop", 79 "ICMP", 80 "IGMP", 81 "#3", 82 "IP", 83 "#5", 84 "TCP", 85 "#7", 86 "#8", 87 "#9", 88 "#10", 89 "#11", 90 "#12", 91 "#13", 92 "#14", 93 "#15", 94 "#16", 95 "UDP", 96 "#18", 97 "#19", 98 "#20", 99 "#21", 100 "IDP", 101 "#23", 102 "#24", 103 "#25", 104 "#26", 105 "#27", 106 "#28", 107 "TP", 108 "#30", 109 "#31", 110 "#32", 111 "#33", 112 "#34", 113 "#35", 114 "#36", 115 "#37", 116 "#38", 117 "#39", 118 "#40", 119 "IP6", 120 "#42", 121 "routing", 122 "fragment", 123 "#45", 124 "#46", 125 "#47", 126 "#48", 127 "#49", 128 "ESP", 129 "AH", 130 "#52", 131 "#53", 132 "#54", 133 "#55", 134 "#56", 135 "#57", 136 "ICMP6", 137 "no next header", 138 "destination option", 139 "#61", 140 "#62", 141 "#63", 142 "#64", 143 "#65", 144 "#66", 145 "#67", 146 "#68", 147 "#69", 148 "#70", 149 "#71", 150 "#72", 151 "#73", 152 "#74", 153 "#75", 154 "#76", 155 "#77", 156 "#78", 157 "#79", 158 "ISOIP", 159 "#81", 160 "#82", 161 "#83", 162 "#84", 163 "#85", 164 "#86", 165 "#87", 166 "#88", 167 "#89", 168 "#80", 169 "#91", 170 "#92", 171 "#93", 172 "#94", 173 "#95", 174 "#96", 175 "Ethernet", 176 "#98", 177 "#99", 178 "#100", 179 "#101", 180 "#102", 181 "PIM", 182 "#104", 183 "#105", 184 "#106", 185 "#107", 186 "#108", 187 "#109", 188 "#110", 189 "#111", 190 "#112", 191 "#113", 192 "#114", 193 "#115", 194 "#116", 195 "#117", 196 "#118", 197 "#119", 198 "#120", 199 "#121", 200 "#122", 201 "#123", 202 "#124", 203 "#125", 204 "#126", 205 "#127", 206 "#128", 207 "#129", 208 "#130", 209 "#131", 210 "#132", 211 "#133", 212 "#134", 213 "#135", 214 "#136", 215 "#137", 216 "#138", 217 "#139", 218 "#140", 219 "#141", 220 "#142", 221 "#143", 222 "#144", 223 "#145", 224 "#146", 225 "#147", 226 "#148", 227 "#149", 228 "#150", 229 "#151", 230 "#152", 231 "#153", 232 "#154", 233 "#155", 234 "#156", 235 "#157", 236 "#158", 237 "#159", 238 "#160", 239 "#161", 240 "#162", 241 "#163", 242 "#164", 243 "#165", 244 "#166", 245 "#167", 246 "#168", 247 "#169", 248 "#170", 249 "#171", 250 "#172", 251 "#173", 252 "#174", 253 "#175", 254 "#176", 255 "#177", 256 "#178", 257 "#179", 258 "#180", 259 "#181", 260 "#182", 261 "#183", 262 "#184", 263 "#185", 264 "#186", 265 "#187", 266 "#188", 267 "#189", 268 "#180", 269 "#191", 270 "#192", 271 "#193", 272 "#194", 273 "#195", 274 "#196", 275 "#197", 276 "#198", 277 "#199", 278 "#200", 279 "#201", 280 "#202", 281 "#203", 282 "#204", 283 "#205", 284 "#206", 285 "#207", 286 "#208", 287 "#209", 288 "#210", 289 "#211", 290 "#212", 291 "#213", 292 "#214", 293 "#215", 294 "#216", 295 "#217", 296 "#218", 297 "#219", 298 "#220", 299 "#221", 300 "#222", 301 "#223", 302 "#224", 303 "#225", 304 "#226", 305 "#227", 306 "#228", 307 "#229", 308 "#230", 309 "#231", 310 "#232", 311 "#233", 312 "#234", 313 "#235", 314 "#236", 315 "#237", 316 "#238", 317 "#239", 318 "#240", 319 "#241", 320 "#242", 321 "#243", 322 "#244", 323 "#245", 324 "#246", 325 "#247", 326 "#248", 327 "#249", 328 "#250", 329 "#251", 330 "#252", 331 "#253", 332 "#254", 333 "#255", 334 }; 335 336 /* 337 * Dump IP6 statistics structure. 338 */ 339 void 340 ip6_stats(off, name) 341 u_long off; 342 char *name; 343 { 344 struct ip6stat ip6stat; 345 int first, i; 346 347 if (off == 0) 348 return; 349 350 kread(off, (char *)&ip6stat, sizeof (ip6stat)); 351 printf("%s:\n", name); 352 353 #define p(f, m) if (ip6stat.f || sflag <= 1) \ 354 printf(m, ip6stat.f, plural(ip6stat.f)) 355 #define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 356 printf(m, ip6stat.f) 357 358 p(ip6s_total, "\t%lu total packet%s received\n"); 359 p1a(ip6s_toosmall, "\t%lu with size smaller than minimum\n"); 360 p1a(ip6s_tooshort, "\t%lu with data size < data length\n"); 361 p1a(ip6s_badoptions, "\t%lu with bad options\n"); 362 p1a(ip6s_badvers, "\t%lu with incorrect version number\n"); 363 p(ip6s_fragments, "\t%lu fragment%s received\n"); 364 p(ip6s_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 365 p(ip6s_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 366 p(ip6s_fragoverflow, "\t%lu fragment%s that exceeded limit\n"); 367 p(ip6s_reassembled, "\t%lu packet%s reassembled ok\n"); 368 p(ip6s_delivered, "\t%lu packet%s for this host\n"); 369 p(ip6s_forward, "\t%lu packet%s forwarded\n"); 370 p(ip6s_cantforward, "\t%lu packet%s not forwardable\n"); 371 p(ip6s_redirectsent, "\t%lu redirect%s sent\n"); 372 p(ip6s_localout, "\t%lu packet%s sent from this host\n"); 373 p(ip6s_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 374 p(ip6s_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n"); 375 p(ip6s_noroute, "\t%lu output packet%s discarded due to no route\n"); 376 p(ip6s_fragmented, "\t%lu output datagram%s fragmented\n"); 377 p(ip6s_ofragments, "\t%lu fragment%s created\n"); 378 p(ip6s_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 379 p(ip6s_badscope, "\t%lu packet%s that violated scope rules\n"); 380 p(ip6s_notmember, "\t%lu multicast packet%s which we don't join\n"); 381 for (first = 1, i = 0; i < 256; i++) 382 if (ip6stat.ip6s_nxthist[i] != 0) { 383 if (first) { 384 printf("\tInput histogram:\n"); 385 first = 0; 386 } 387 printf("\t\t%s: %lu\n", ip6nh[i], 388 ip6stat.ip6s_nxthist[i]); 389 } 390 printf("\tMbuf statistics:\n"); 391 printf("\t\t%lu one mbuf\n", ip6stat.ip6s_m1); 392 for (first = 1, i = 0; i < 32; i++) { 393 char ifbuf[IFNAMSIZ]; 394 if (ip6stat.ip6s_m2m[i] != 0) { 395 if (first) { 396 printf("\t\ttwo or more mbuf:\n"); 397 first = 0; 398 } 399 printf("\t\t\t%s= %ld\n", 400 if_indextoname(i, ifbuf), 401 ip6stat.ip6s_m2m[i]); 402 } 403 } 404 printf("\t\t%lu one ext mbuf\n", ip6stat.ip6s_mext1); 405 printf("\t\t%lu two or more ext mbuf\n", ip6stat.ip6s_mext2m); 406 p(ip6s_exthdrtoolong, "\t%lu packet%s whose headers are not continuous\n"); 407 p(ip6s_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 408 p(ip6s_toomanyhdr, "\t%lu packet%s discarded due to too may headers\n"); 409 #undef p 410 } 411 412 /* 413 * Dump IPv6 per-interface statistics based on RFC 2465. 414 */ 415 void 416 ip6_ifstats(ifname) 417 char *ifname; 418 { 419 struct in6_ifreq ifr; 420 int s; 421 #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 422 printf(m, ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f)) 423 #define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 424 printf(m, ip6stat.f) 425 426 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 427 perror("Warning: socket(AF_INET6)"); 428 return; 429 } 430 431 strcpy(ifr.ifr_name, ifname); 432 printf("ip6 on %s:\n", ifr.ifr_name); 433 434 if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 435 perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); 436 goto end; 437 } 438 439 p(ifs6_in_receive, "\t%qu total input datagram%s\n"); 440 p(ifs6_in_hdrerr, "\t%qu datagram%s with invalid header received\n"); 441 p(ifs6_in_toobig, "\t%qu datagram%s exceeded MTU received\n"); 442 p(ifs6_in_noroute, "\t%qu datagram%s with no route received\n"); 443 p(ifs6_in_addrerr, "\t%qu datagram%s with invalid dst received\n"); 444 p(ifs6_in_protounknown, "\t%qu datagram%s with unknown proto received\n"); 445 p(ifs6_in_truncated, "\t%qu truncated datagram%s received\n"); 446 p(ifs6_in_discard, "\t%qu input datagram%s discarded\n"); 447 p(ifs6_in_deliver, 448 "\t%qu datagram%s delivered to an upper layer protocol\n"); 449 p(ifs6_out_forward, "\t%qu datagram%s forwarded to this interface\n"); 450 p(ifs6_out_request, 451 "\t%qu datagram%s sent from an upper layer protocol\n"); 452 p(ifs6_out_discard, "\t%qu total discarded output datagram%s\n"); 453 p(ifs6_out_fragok, "\t%qu output datagram%s fragmented\n"); 454 p(ifs6_out_fragfail, "\t%qu output datagram%s failed on fragment\n"); 455 p(ifs6_out_fragcreat, "\t%qu output datagram%s succeeded on fragment\n"); 456 p(ifs6_reass_reqd, "\t%qu incoming datagram%s fragmented\n"); 457 p(ifs6_reass_ok, "\t%qu datagram%s reassembled\n"); 458 p(ifs6_reass_fail, "\t%qu datagram%s failed on reassembling\n"); 459 p(ifs6_in_mcast, "\t%qu multicast datagram%s received\n"); 460 p(ifs6_out_mcast, "\t%qu multicast datagram%s sent\n"); 461 462 end: 463 close(s); 464 465 #undef p 466 #undef p_5 467 } 468 469 static char *icmp6names[] = { 470 "#0", 471 "unreach", 472 "packet too big", 473 "time exceed", 474 "parameter problem", 475 "#5", 476 "#6", 477 "#7", 478 "#8", 479 "#9", 480 "#10", 481 "#11", 482 "#12", 483 "#13", 484 "#14", 485 "#15", 486 "#16", 487 "#17", 488 "#18", 489 "#19", 490 "#20", 491 "#21", 492 "#22", 493 "#23", 494 "#24", 495 "#25", 496 "#26", 497 "#27", 498 "#28", 499 "#29", 500 "#30", 501 "#31", 502 "#32", 503 "#33", 504 "#34", 505 "#35", 506 "#36", 507 "#37", 508 "#38", 509 "#39", 510 "#40", 511 "#41", 512 "#42", 513 "#43", 514 "#44", 515 "#45", 516 "#46", 517 "#47", 518 "#48", 519 "#49", 520 "#50", 521 "#51", 522 "#52", 523 "#53", 524 "#54", 525 "#55", 526 "#56", 527 "#57", 528 "#58", 529 "#59", 530 "#60", 531 "#61", 532 "#62", 533 "#63", 534 "#64", 535 "#65", 536 "#66", 537 "#67", 538 "#68", 539 "#69", 540 "#70", 541 "#71", 542 "#72", 543 "#73", 544 "#74", 545 "#75", 546 "#76", 547 "#77", 548 "#78", 549 "#79", 550 "#80", 551 "#81", 552 "#82", 553 "#83", 554 "#84", 555 "#85", 556 "#86", 557 "#87", 558 "#88", 559 "#89", 560 "#80", 561 "#91", 562 "#92", 563 "#93", 564 "#94", 565 "#95", 566 "#96", 567 "#97", 568 "#98", 569 "#99", 570 "#100", 571 "#101", 572 "#102", 573 "#103", 574 "#104", 575 "#105", 576 "#106", 577 "#107", 578 "#108", 579 "#109", 580 "#110", 581 "#111", 582 "#112", 583 "#113", 584 "#114", 585 "#115", 586 "#116", 587 "#117", 588 "#118", 589 "#119", 590 "#120", 591 "#121", 592 "#122", 593 "#123", 594 "#124", 595 "#125", 596 "#126", 597 "#127", 598 "echo", 599 "echo reply", 600 "multicast listener query", 601 "multicast listener report", 602 "multicast listener done", 603 "router solicitation", 604 "router advertisment", 605 "neighbor solicitation", 606 "neighbor advertisment", 607 "redirect", 608 "router renumbering", 609 "node information request", 610 "node information reply", 611 "#141", 612 "#142", 613 "#143", 614 "#144", 615 "#145", 616 "#146", 617 "#147", 618 "#148", 619 "#149", 620 "#150", 621 "#151", 622 "#152", 623 "#153", 624 "#154", 625 "#155", 626 "#156", 627 "#157", 628 "#158", 629 "#159", 630 "#160", 631 "#161", 632 "#162", 633 "#163", 634 "#164", 635 "#165", 636 "#166", 637 "#167", 638 "#168", 639 "#169", 640 "#170", 641 "#171", 642 "#172", 643 "#173", 644 "#174", 645 "#175", 646 "#176", 647 "#177", 648 "#178", 649 "#179", 650 "#180", 651 "#181", 652 "#182", 653 "#183", 654 "#184", 655 "#185", 656 "#186", 657 "#187", 658 "#188", 659 "#189", 660 "#180", 661 "#191", 662 "#192", 663 "#193", 664 "#194", 665 "#195", 666 "#196", 667 "#197", 668 "#198", 669 "#199", 670 "#200", 671 "#201", 672 "#202", 673 "#203", 674 "#204", 675 "#205", 676 "#206", 677 "#207", 678 "#208", 679 "#209", 680 "#210", 681 "#211", 682 "#212", 683 "#213", 684 "#214", 685 "#215", 686 "#216", 687 "#217", 688 "#218", 689 "#219", 690 "#220", 691 "#221", 692 "#222", 693 "#223", 694 "#224", 695 "#225", 696 "#226", 697 "#227", 698 "#228", 699 "#229", 700 "#230", 701 "#231", 702 "#232", 703 "#233", 704 "#234", 705 "#235", 706 "#236", 707 "#237", 708 "#238", 709 "#239", 710 "#240", 711 "#241", 712 "#242", 713 "#243", 714 "#244", 715 "#245", 716 "#246", 717 "#247", 718 "#248", 719 "#249", 720 "#250", 721 "#251", 722 "#252", 723 "#253", 724 "#254", 725 "#255", 726 }; 727 728 /* 729 * Dump ICMP6 statistics. 730 */ 731 void 732 icmp6_stats(off, name) 733 u_long off; 734 char *name; 735 { 736 struct icmp6stat icmp6stat; 737 register int i, first; 738 739 if (off == 0) 740 return; 741 kread(off, (char *)&icmp6stat, sizeof (icmp6stat)); 742 printf("%s:\n", name); 743 744 #define p(f, m) if (icmp6stat.f || sflag <= 1) \ 745 printf(m, icmp6stat.f, plural(icmp6stat.f)) 746 747 p(icp6s_error, "\t%lu call%s to icmp_error\n"); 748 p(icp6s_canterror, 749 "\t%lu error%s not generated because old message was icmp error or so\n"); 750 p(icp6s_toofreq, 751 "\t%lu error%s not generated because rate limitation\n"); 752 for (first = 1, i = 0; i < 256; i++) 753 if (icmp6stat.icp6s_outhist[i] != 0) { 754 if (first) { 755 printf("\tOutput histogram:\n"); 756 first = 0; 757 } 758 printf("\t\t%s: %lu\n", icmp6names[i], 759 icmp6stat.icp6s_outhist[i]); 760 } 761 p(icp6s_badcode, "\t%lu message%s with bad code fields\n"); 762 p(icp6s_tooshort, "\t%lu message%s < minimum length\n"); 763 p(icp6s_checksum, "\t%lu bad checksum%s\n"); 764 p(icp6s_badlen, "\t%lu message%s with bad length\n"); 765 for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++) 766 if (icmp6stat.icp6s_inhist[i] != 0) { 767 if (first) { 768 printf("\tInput histogram:\n"); 769 first = 0; 770 } 771 printf("\t\t%s: %lu\n", icmp6names[i], 772 icmp6stat.icp6s_inhist[i]); 773 } 774 p(icp6s_reflect, "\t%lu message response%s generated\n"); 775 #undef p 776 #undef p_5 777 } 778 779 /* 780 * Dump ICMPv6 per-interface statistics based on RFC 2466. 781 */ 782 void 783 icmp6_ifstats(ifname) 784 char *ifname; 785 { 786 struct in6_ifreq ifr; 787 int s; 788 #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 789 printf(m, (u_quad_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 790 791 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 792 perror("Warning: socket(AF_INET6)"); 793 return; 794 } 795 796 strcpy(ifr.ifr_name, ifname); 797 printf("icmp6 on %s:\n", ifr.ifr_name); 798 799 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 800 perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 801 goto end; 802 } 803 804 p(ifs6_in_msg, "\t%qu total input message%s\n"); 805 p(ifs6_in_error, "\t%qu total input error message%s\n"); 806 p(ifs6_in_dstunreach, "\t%qu input destination unreachable error%s\n"); 807 p(ifs6_in_adminprohib, "\t%qu input administratively prohibited error%s\n"); 808 p(ifs6_in_timeexceed, "\t%qu input time exceeded error%s\n"); 809 p(ifs6_in_paramprob, "\t%qu input parameter problem error%s\n"); 810 p(ifs6_in_pkttoobig, "\t%qu input packet too big error%s\n"); 811 p(ifs6_in_echo, "\t%qu input echo request%s\n"); 812 p(ifs6_in_echoreply, "\t%qu input echo reply%s\n"); 813 p(ifs6_in_routersolicit, "\t%qu input router solicitation%s\n"); 814 p(ifs6_in_routeradvert, "\t%qu input router advertisement%s\n"); 815 p(ifs6_in_neighborsolicit, "\t%qu input neighbor solicitation%s\n"); 816 p(ifs6_in_neighboradvert, "\t%qu input neighbor advertisement%s\n"); 817 p(ifs6_in_redirect, "\t%qu input redirect%s\n"); 818 p(ifs6_in_mldquery, "\t%qu input MLD query%s\n"); 819 p(ifs6_in_mldreport, "\t%qu input MLD report%s\n"); 820 p(ifs6_in_mlddone, "\t%qu input MLD done%s\n"); 821 822 p(ifs6_out_msg, "\t%qu total output message%s\n"); 823 p(ifs6_out_error, "\t%qu total output error message%s\n"); 824 p(ifs6_out_dstunreach, "\t%qu output destination unreachable error%s\n"); 825 p(ifs6_out_adminprohib, "\t%qu output administratively prohibited error%s\n"); 826 p(ifs6_out_timeexceed, "\t%qu output time exceeded error%s\n"); 827 p(ifs6_out_paramprob, "\t%qu output parameter problem error%s\n"); 828 p(ifs6_out_pkttoobig, "\t%qu output packet too big error%s\n"); 829 p(ifs6_out_echo, "\t%qu output echo request%s\n"); 830 p(ifs6_out_echoreply, "\t%qu output echo reply%s\n"); 831 p(ifs6_out_routersolicit, "\t%qu output router solicitation%s\n"); 832 p(ifs6_out_routeradvert, "\t%qu output router advertisement%s\n"); 833 p(ifs6_out_neighborsolicit, "\t%qu output neighbor solicitation%s\n"); 834 p(ifs6_out_neighboradvert, "\t%qu output neighbor advertisement%s\n"); 835 p(ifs6_out_redirect, "\t%qu output redirect%s\n"); 836 p(ifs6_out_mldquery, "\t%qu output MLD query%s\n"); 837 p(ifs6_out_mldreport, "\t%qu output MLD report%s\n"); 838 p(ifs6_out_mlddone, "\t%qu output MLD done%s\n"); 839 840 end: 841 close(s); 842 #undef p 843 } 844 845 /* 846 * Dump PIM statistics structure. 847 */ 848 void 849 pim6_stats(off, name) 850 u_long off; 851 char *name; 852 { 853 struct pim6stat pim6stat; 854 855 if (off == 0) 856 return; 857 kread(off, (char *)&pim6stat, sizeof(pim6stat)); 858 printf("%s:\n", name); 859 860 #define p(f, m) if (pim6stat.f || sflag <= 1) \ 861 printf(m, pim6stat.f, plural(pim6stat.f)) 862 p(pim6s_rcv_total, "\t%u message%s received\n"); 863 p(pim6s_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 864 p(pim6s_rcv_badsum, "\t%u message%s received with bad checksum\n"); 865 p(pim6s_rcv_badversion, "\t%u message%s received with bad version\n"); 866 p(pim6s_rcv_registers, "\t%u register%s received\n"); 867 p(pim6s_rcv_badregisters, "\t%u bad register%s received\n"); 868 p(pim6s_snd_registers, "\t%u register%s sent\n"); 869 #undef p 870 } 871 872 /* 873 * Pretty print an Internet address (net address + port). 874 * If the nflag was specified, use numbers instead of names. 875 */ 876 #define GETSERVBYPORT6(port, proto, ret)\ 877 {\ 878 if (strcmp((proto), "tcp6") == 0)\ 879 (ret) = getservbyport((int)(port), "tcp");\ 880 else if (strcmp((proto), "udp6") == 0)\ 881 (ret) = getservbyport((int)(port), "udp");\ 882 else\ 883 (ret) = getservbyport((int)(port), (proto));\ 884 }; 885 886 void 887 inet6print(in6, port, proto, numeric) 888 register struct in6_addr *in6; 889 int port; 890 char *proto; 891 int numeric; 892 { 893 struct servent *sp = 0; 894 char line[80], *cp; 895 int width; 896 897 sprintf(line, "%.*s.", lflag ? 39 : 898 (Aflag && !numeric) ? 12 : 16, inet6name(in6)); 899 cp = index(line, '\0'); 900 if (!numeric && port) 901 GETSERVBYPORT6(port, proto, sp); 902 if (sp || port == 0) 903 sprintf(cp, "%.8s", sp ? sp->s_name : "*"); 904 else 905 sprintf(cp, "%d", ntohs((u_short)port)); 906 width = lflag ? 45 : Aflag ? 18 : 22; 907 printf("%-*.*s ", width, width, line); 908 } 909 910 /* 911 * Construct an Internet address representation. 912 * If the nflag has been supplied, give 913 * numeric value, otherwise try for symbolic name. 914 */ 915 916 char * 917 inet6name(in6p) 918 struct in6_addr *in6p; 919 { 920 register char *cp; 921 static char line[50]; 922 struct hostent *hp; 923 static char domain[MAXHOSTNAMELEN + 1]; 924 static int first = 1; 925 926 if (first && !nflag) { 927 first = 0; 928 if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 929 (cp = index(domain, '.'))) 930 (void) strcpy(domain, cp + 1); 931 else 932 domain[0] = 0; 933 } 934 cp = 0; 935 if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { 936 hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); 937 if (hp) { 938 if ((cp = index(hp->h_name, '.')) && 939 !strcmp(cp + 1, domain)) 940 *cp = 0; 941 cp = hp->h_name; 942 } 943 } 944 if (IN6_IS_ADDR_UNSPECIFIED(in6p)) 945 strcpy(line, "*"); 946 else if (cp) 947 strcpy(line, cp); 948 else 949 sprintf(line, "%s", 950 inet_ntop(AF_INET6, (void *)in6p, ntop_buf, 951 sizeof(ntop_buf))); 952 return (line); 953 } 954