inet6.c revision 54263
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: head/usr.bin/netstat/inet6.c 54263 1999-12-07 17:39:16Z shin $ 35 */ 36 37#ifndef lint 38/* 39static 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 70struct socket sockb; 71 72char *inet6name __P((struct in6_addr *)); 73void inet6print __P((struct in6_addr *, int, char *, int)); 74 75static char ntop_buf[INET6_ADDRSTRLEN]; 76 77static 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 */ 339void 340ip6_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 if (ip6stat.ip6s_m2m[i] != 0) { 394 if (first) { 395 printf("\t\ttwo or more mbuf:\n"); 396 first = 0; 397 } 398 printf("\t\t\t" 399#ifdef notyet 400 "%s" 401#else 402 "if%d" 403#endif 404 "= %ld\n", 405#ifdef notyet 406 if_indextoname(i, ifbuf), 407#else 408 i, 409#endif 410 ip6stat.ip6s_m2m[i]); 411 } 412 } 413 printf("\t\t%lu one ext mbuf\n", ip6stat.ip6s_mext1); 414 printf("\t\t%lu two or more ext mbuf\n", ip6stat.ip6s_mext2m); 415 p(ip6s_exthdrtoolong, "\t%lu packet%s whose headers are not continuous\n"); 416 p(ip6s_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 417 p(ip6s_toomanyhdr, "\t%lu packet%s discarded due to too may headers\n"); 418#undef p 419} 420 421/* 422 * Dump IPv6 per-interface statistics based on RFC 2465. 423 */ 424void 425ip6_ifstats(ifname) 426 char *ifname; 427{ 428 struct in6_ifreq ifr; 429 int s; 430#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 431 printf(m, ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f)) 432#define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 433 printf(m, ip6stat.f) 434 435 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 436 perror("Warning: socket(AF_INET6)"); 437 return; 438 } 439 440 strcpy(ifr.ifr_name, ifname); 441 printf("ip6 on %s:\n", ifr.ifr_name); 442 443 if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 444 perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); 445 goto end; 446 } 447 448 p(ifs6_in_receive, "\t%qu total input datagram%s\n"); 449 p(ifs6_in_hdrerr, "\t%qu datagram%s with invalid header received\n"); 450 p(ifs6_in_toobig, "\t%qu datagram%s exceeded MTU received\n"); 451 p(ifs6_in_noroute, "\t%qu datagram%s with no route received\n"); 452 p(ifs6_in_addrerr, "\t%qu datagram%s with invalid dst received\n"); 453 p(ifs6_in_protounknown, "\t%qu datagram%s with unknown proto received\n"); 454 p(ifs6_in_truncated, "\t%qu truncated datagram%s received\n"); 455 p(ifs6_in_discard, "\t%qu input datagram%s discarded\n"); 456 p(ifs6_in_deliver, 457 "\t%qu datagram%s delivered to an upper layer protocol\n"); 458 p(ifs6_out_forward, "\t%qu datagram%s forwarded to this interface\n"); 459 p(ifs6_out_request, 460 "\t%qu datagram%s sent from an upper layer protocol\n"); 461 p(ifs6_out_discard, "\t%qu total discarded output datagram%s\n"); 462 p(ifs6_out_fragok, "\t%qu output datagram%s fragmented\n"); 463 p(ifs6_out_fragfail, "\t%qu output datagram%s failed on fragment\n"); 464 p(ifs6_out_fragcreat, "\t%qu output datagram%s succeeded on fragment\n"); 465 p(ifs6_reass_reqd, "\t%qu incoming datagram%s fragmented\n"); 466 p(ifs6_reass_ok, "\t%qu datagram%s reassembled\n"); 467 p(ifs6_reass_fail, "\t%qu datagram%s failed on reassembling\n"); 468 p(ifs6_in_mcast, "\t%qu multicast datagram%s received\n"); 469 p(ifs6_out_mcast, "\t%qu multicast datagram%s sent\n"); 470 471 end: 472 close(s); 473 474#undef p 475#undef p_5 476} 477 478static char *icmp6names[] = { 479 "#0", 480 "unreach", 481 "packet too big", 482 "time exceed", 483 "parameter problem", 484 "#5", 485 "#6", 486 "#7", 487 "#8", 488 "#9", 489 "#10", 490 "#11", 491 "#12", 492 "#13", 493 "#14", 494 "#15", 495 "#16", 496 "#17", 497 "#18", 498 "#19", 499 "#20", 500 "#21", 501 "#22", 502 "#23", 503 "#24", 504 "#25", 505 "#26", 506 "#27", 507 "#28", 508 "#29", 509 "#30", 510 "#31", 511 "#32", 512 "#33", 513 "#34", 514 "#35", 515 "#36", 516 "#37", 517 "#38", 518 "#39", 519 "#40", 520 "#41", 521 "#42", 522 "#43", 523 "#44", 524 "#45", 525 "#46", 526 "#47", 527 "#48", 528 "#49", 529 "#50", 530 "#51", 531 "#52", 532 "#53", 533 "#54", 534 "#55", 535 "#56", 536 "#57", 537 "#58", 538 "#59", 539 "#60", 540 "#61", 541 "#62", 542 "#63", 543 "#64", 544 "#65", 545 "#66", 546 "#67", 547 "#68", 548 "#69", 549 "#70", 550 "#71", 551 "#72", 552 "#73", 553 "#74", 554 "#75", 555 "#76", 556 "#77", 557 "#78", 558 "#79", 559 "#80", 560 "#81", 561 "#82", 562 "#83", 563 "#84", 564 "#85", 565 "#86", 566 "#87", 567 "#88", 568 "#89", 569 "#80", 570 "#91", 571 "#92", 572 "#93", 573 "#94", 574 "#95", 575 "#96", 576 "#97", 577 "#98", 578 "#99", 579 "#100", 580 "#101", 581 "#102", 582 "#103", 583 "#104", 584 "#105", 585 "#106", 586 "#107", 587 "#108", 588 "#109", 589 "#110", 590 "#111", 591 "#112", 592 "#113", 593 "#114", 594 "#115", 595 "#116", 596 "#117", 597 "#118", 598 "#119", 599 "#120", 600 "#121", 601 "#122", 602 "#123", 603 "#124", 604 "#125", 605 "#126", 606 "#127", 607 "echo", 608 "echo reply", 609 "multicast listener query", 610 "multicast listener report", 611 "multicast listener done", 612 "router solicitation", 613 "router advertisment", 614 "neighbor solicitation", 615 "neighbor advertisment", 616 "redirect", 617 "router renumbering", 618 "node information request", 619 "node information reply", 620 "#141", 621 "#142", 622 "#143", 623 "#144", 624 "#145", 625 "#146", 626 "#147", 627 "#148", 628 "#149", 629 "#150", 630 "#151", 631 "#152", 632 "#153", 633 "#154", 634 "#155", 635 "#156", 636 "#157", 637 "#158", 638 "#159", 639 "#160", 640 "#161", 641 "#162", 642 "#163", 643 "#164", 644 "#165", 645 "#166", 646 "#167", 647 "#168", 648 "#169", 649 "#170", 650 "#171", 651 "#172", 652 "#173", 653 "#174", 654 "#175", 655 "#176", 656 "#177", 657 "#178", 658 "#179", 659 "#180", 660 "#181", 661 "#182", 662 "#183", 663 "#184", 664 "#185", 665 "#186", 666 "#187", 667 "#188", 668 "#189", 669 "#180", 670 "#191", 671 "#192", 672 "#193", 673 "#194", 674 "#195", 675 "#196", 676 "#197", 677 "#198", 678 "#199", 679 "#200", 680 "#201", 681 "#202", 682 "#203", 683 "#204", 684 "#205", 685 "#206", 686 "#207", 687 "#208", 688 "#209", 689 "#210", 690 "#211", 691 "#212", 692 "#213", 693 "#214", 694 "#215", 695 "#216", 696 "#217", 697 "#218", 698 "#219", 699 "#220", 700 "#221", 701 "#222", 702 "#223", 703 "#224", 704 "#225", 705 "#226", 706 "#227", 707 "#228", 708 "#229", 709 "#230", 710 "#231", 711 "#232", 712 "#233", 713 "#234", 714 "#235", 715 "#236", 716 "#237", 717 "#238", 718 "#239", 719 "#240", 720 "#241", 721 "#242", 722 "#243", 723 "#244", 724 "#245", 725 "#246", 726 "#247", 727 "#248", 728 "#249", 729 "#250", 730 "#251", 731 "#252", 732 "#253", 733 "#254", 734 "#255", 735}; 736 737/* 738 * Dump ICMP6 statistics. 739 */ 740void 741icmp6_stats(off, name) 742 u_long off; 743 char *name; 744{ 745 struct icmp6stat icmp6stat; 746 register int i, first; 747 748 if (off == 0) 749 return; 750 kread(off, (char *)&icmp6stat, sizeof (icmp6stat)); 751 printf("%s:\n", name); 752 753#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 754 printf(m, icmp6stat.f, plural(icmp6stat.f)) 755 756 p(icp6s_error, "\t%lu call%s to icmp_error\n"); 757 p(icp6s_canterror, 758 "\t%lu error%s not generated because old message was icmp error or so\n"); 759 p(icp6s_toofreq, 760 "\t%lu error%s not generated because rate limitation\n"); 761 for (first = 1, i = 0; i < 256; i++) 762 if (icmp6stat.icp6s_outhist[i] != 0) { 763 if (first) { 764 printf("\tOutput histogram:\n"); 765 first = 0; 766 } 767 printf("\t\t%s: %lu\n", icmp6names[i], 768 icmp6stat.icp6s_outhist[i]); 769 } 770 p(icp6s_badcode, "\t%lu message%s with bad code fields\n"); 771 p(icp6s_tooshort, "\t%lu message%s < minimum length\n"); 772 p(icp6s_checksum, "\t%lu bad checksum%s\n"); 773 p(icp6s_badlen, "\t%lu message%s with bad length\n"); 774 for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++) 775 if (icmp6stat.icp6s_inhist[i] != 0) { 776 if (first) { 777 printf("\tInput histogram:\n"); 778 first = 0; 779 } 780 printf("\t\t%s: %lu\n", icmp6names[i], 781 icmp6stat.icp6s_inhist[i]); 782 } 783 p(icp6s_reflect, "\t%lu message response%s generated\n"); 784#undef p 785#undef p_5 786} 787 788/* 789 * Dump ICMPv6 per-interface statistics based on RFC 2466. 790 */ 791void 792icmp6_ifstats(ifname) 793 char *ifname; 794{ 795 struct in6_ifreq ifr; 796 int s; 797#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 798 printf(m, (u_quad_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 799 800 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 801 perror("Warning: socket(AF_INET6)"); 802 return; 803 } 804 805 strcpy(ifr.ifr_name, ifname); 806 printf("icmp6 on %s:\n", ifr.ifr_name); 807 808 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 809 perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 810 goto end; 811 } 812 813 p(ifs6_in_msg, "\t%qu total input message%s\n"); 814 p(ifs6_in_error, "\t%qu total input error message%s\n"); 815 p(ifs6_in_dstunreach, "\t%qu input destination unreachable error%s\n"); 816 p(ifs6_in_adminprohib, "\t%qu input administratively prohibited error%s\n"); 817 p(ifs6_in_timeexceed, "\t%qu input time exceeded error%s\n"); 818 p(ifs6_in_paramprob, "\t%qu input parameter problem error%s\n"); 819 p(ifs6_in_pkttoobig, "\t%qu input packet too big error%s\n"); 820 p(ifs6_in_echo, "\t%qu input echo request%s\n"); 821 p(ifs6_in_echoreply, "\t%qu input echo reply%s\n"); 822 p(ifs6_in_routersolicit, "\t%qu input router solicitation%s\n"); 823 p(ifs6_in_routeradvert, "\t%qu input router advertisement%s\n"); 824 p(ifs6_in_neighborsolicit, "\t%qu input neighbor solicitation%s\n"); 825 p(ifs6_in_neighboradvert, "\t%qu input neighbor advertisement%s\n"); 826 p(ifs6_in_redirect, "\t%qu input redirect%s\n"); 827 p(ifs6_in_mldquery, "\t%qu input MLD query%s\n"); 828 p(ifs6_in_mldreport, "\t%qu input MLD report%s\n"); 829 p(ifs6_in_mlddone, "\t%qu input MLD done%s\n"); 830 831 p(ifs6_out_msg, "\t%qu total output message%s\n"); 832 p(ifs6_out_error, "\t%qu total output error message%s\n"); 833 p(ifs6_out_dstunreach, "\t%qu output destination unreachable error%s\n"); 834 p(ifs6_out_adminprohib, "\t%qu output administratively prohibited error%s\n"); 835 p(ifs6_out_timeexceed, "\t%qu output time exceeded error%s\n"); 836 p(ifs6_out_paramprob, "\t%qu output parameter problem error%s\n"); 837 p(ifs6_out_pkttoobig, "\t%qu output packet too big error%s\n"); 838 p(ifs6_out_echo, "\t%qu output echo request%s\n"); 839 p(ifs6_out_echoreply, "\t%qu output echo reply%s\n"); 840 p(ifs6_out_routersolicit, "\t%qu output router solicitation%s\n"); 841 p(ifs6_out_routeradvert, "\t%qu output router advertisement%s\n"); 842 p(ifs6_out_neighborsolicit, "\t%qu output neighbor solicitation%s\n"); 843 p(ifs6_out_neighboradvert, "\t%qu output neighbor advertisement%s\n"); 844 p(ifs6_out_redirect, "\t%qu output redirect%s\n"); 845 p(ifs6_out_mldquery, "\t%qu output MLD query%s\n"); 846 p(ifs6_out_mldreport, "\t%qu output MLD report%s\n"); 847 p(ifs6_out_mlddone, "\t%qu output MLD done%s\n"); 848 849 end: 850 close(s); 851#undef p 852} 853 854/* 855 * Dump PIM statistics structure. 856 */ 857void 858pim6_stats(off, name) 859 u_long off; 860 char *name; 861{ 862 struct pim6stat pim6stat; 863 864 if (off == 0) 865 return; 866 kread(off, (char *)&pim6stat, sizeof(pim6stat)); 867 printf("%s:\n", name); 868 869#define p(f, m) if (pim6stat.f || sflag <= 1) \ 870 printf(m, pim6stat.f, plural(pim6stat.f)) 871 p(pim6s_rcv_total, "\t%u message%s received\n"); 872 p(pim6s_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 873 p(pim6s_rcv_badsum, "\t%u message%s received with bad checksum\n"); 874 p(pim6s_rcv_badversion, "\t%u message%s received with bad version\n"); 875 p(pim6s_rcv_registers, "\t%u register%s received\n"); 876 p(pim6s_rcv_badregisters, "\t%u bad register%s received\n"); 877 p(pim6s_snd_registers, "\t%u register%s sent\n"); 878#undef p 879} 880 881/* 882 * Pretty print an Internet address (net address + port). 883 * If the nflag was specified, use numbers instead of names. 884 */ 885#define GETSERVBYPORT6(port, proto, ret)\ 886{\ 887 if (strcmp((proto), "tcp6") == 0)\ 888 (ret) = getservbyport((int)(port), "tcp");\ 889 else if (strcmp((proto), "udp6") == 0)\ 890 (ret) = getservbyport((int)(port), "udp");\ 891 else\ 892 (ret) = getservbyport((int)(port), (proto));\ 893}; 894 895void 896inet6print(in6, port, proto, numeric) 897 register struct in6_addr *in6; 898 int port; 899 char *proto; 900 int numeric; 901{ 902 struct servent *sp = 0; 903 char line[80], *cp; 904 int width; 905 906 sprintf(line, "%.*s.", lflag ? 39 : 907 (Aflag && !numeric) ? 12 : 16, inet6name(in6)); 908 cp = index(line, '\0'); 909 if (!numeric && port) 910 GETSERVBYPORT6(port, proto, sp); 911 if (sp || port == 0) 912 sprintf(cp, "%.8s", sp ? sp->s_name : "*"); 913 else 914 sprintf(cp, "%d", ntohs((u_short)port)); 915 width = lflag ? 45 : Aflag ? 18 : 22; 916 printf(" %-*.*s", width, width, line); 917} 918 919/* 920 * Construct an Internet address representation. 921 * If the nflag has been supplied, give 922 * numeric value, otherwise try for symbolic name. 923 */ 924 925char * 926inet6name(in6p) 927 struct in6_addr *in6p; 928{ 929 register char *cp; 930 static char line[50]; 931 struct hostent *hp; 932 static char domain[MAXHOSTNAMELEN + 1]; 933 static int first = 1; 934 935 if (first && !nflag) { 936 first = 0; 937 if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 938 (cp = index(domain, '.'))) 939 (void) strcpy(domain, cp + 1); 940 else 941 domain[0] = 0; 942 } 943 cp = 0; 944 if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { 945 hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); 946 if (hp) { 947 if ((cp = index(hp->h_name, '.')) && 948 !strcmp(cp + 1, domain)) 949 *cp = 0; 950 cp = hp->h_name; 951 } 952 } 953 if (IN6_IS_ADDR_UNSPECIFIED(in6p)) 954 strcpy(line, "*"); 955 else if (cp) 956 strcpy(line, cp); 957 else 958 sprintf(line, "%s", 959 inet_ntop(AF_INET6, (void *)in6p, ntop_buf, 960 sizeof(ntop_buf))); 961 return (line); 962} 963