1 /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
3 * Copyright (c) 1983, 1988, 1993
4 * The Regents of the University of California. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94";
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
41 #include <sys/param.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/ioctl.h>
46 #include <sys/protosw.h>
48 #include <net/route.h>
50 #include <netinet/in.h>
51 #include <netinet/ip6.h>
52 #include <netinet/icmp6.h>
53 #include <netinet/in_systm.h>
54 #include <netinet6/in6_pcb.h>
55 #include <netinet6/in6_var.h>
56 #include <netinet6/ip6_var.h>
57 #include <netinet6/pim6_var.h>
58 #include <netinet6/raw_ip6.h>
60 #include <arpa/inet.h>
73 char *inet6name(struct in6_addr *);
75 static char ntop_buf[INET6_ADDRSTRLEN];
77 static const char *ip6nh[] = {
138 "destination option",
336 static const char *srcrule_str[] = {
340 "deprecated address",
342 "outgoing interface",
344 "public/temporary address",
346 "better virtual status",
356 * Dump IP6 statistics structure.
359 ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
361 struct ip6stat ip6stat;
364 if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat,
365 sizeof(ip6stat), kread_counters) != 0)
368 xo_open_container(name);
369 xo_emit("{T:/%s}:\n", name);
371 #define p(f, m) if (ip6stat.f || sflag <= 1) \
372 xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
373 #define p1a(f, m) if (ip6stat.f || sflag <= 1) \
374 xo_emit(m, (uintmax_t)ip6stat.f)
376 p(ip6s_total, "\t{:received-packets/%ju} "
377 "{N:/total packet%s received}\n");
378 p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} "
379 "{N:/with size smaller than minimum}\n");
380 p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} "
381 "{N:/with data size < data length}\n");
382 p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} "
383 "{N:/with bad options}\n");
384 p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} "
385 "{N:/with incorrect version number}\n");
386 p(ip6s_fragments, "\t{:received-fragments/%ju} "
387 "{N:/fragment%s received}\n");
388 p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} "
389 "{N:/fragment%s dropped (dup or out of space)}\n");
390 p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} "
391 "{N:/fragment%s dropped after timeout}\n");
392 p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
393 "{N:/fragment%s that exceeded limit}\n");
394 p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
395 "{N:/packet%s reassembled ok}\n");
396 p(ip6s_delivered, "\t{:received-local-packets/%ju} "
397 "{N:/packet%s for this host}\n");
398 p(ip6s_forward, "\t{:forwarded-packets/%ju} "
399 "{N:/packet%s forwarded}\n");
400 p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} "
401 "{N:/packet%s not forwardable}\n");
402 p(ip6s_redirectsent, "\t{:sent-redirects/%ju} "
403 "{N:/redirect%s sent}\n");
404 p(ip6s_localout, "\t{:sent-packets/%ju} "
405 "{N:/packet%s sent from this host}\n");
406 p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} "
407 "{N:/packet%s sent with fabricated ip header}\n");
408 p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} "
409 "{N:/output packet%s dropped due to no bufs, etc.}\n");
410 p(ip6s_noroute, "\t{:discard-no-route/%ju} "
411 "{N:/output packet%s discarded due to no route}\n");
412 p(ip6s_fragmented, "\t{:sent-fragments/%ju} "
413 "{N:/output datagram%s fragmented}\n");
414 p(ip6s_ofragments, "\t{:fragments-created/%ju} "
415 "{N:/fragment%s created}\n");
416 p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} "
417 "{N:/datagram%s that can't be fragmented}\n");
418 p(ip6s_badscope, "\t{:discard-scope-violations/%ju} "
419 "{N:/packet%s that violated scope rules}\n");
420 p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} "
421 "{N:/multicast packet%s which we don't join}\n");
422 for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
423 if (ip6stat.ip6s_nxthist[i] != 0) {
425 xo_emit("\t{T:Input histogram}:\n");
426 xo_open_list("input-histogram");
429 xo_open_instance("input-histogram");
430 xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i],
431 (uintmax_t)ip6stat.ip6s_nxthist[i]);
432 xo_close_instance("input-histogram");
435 xo_close_list("input-histogram");
437 xo_open_container("mbuf-statistics");
438 xo_emit("\t{T:Mbuf statistics}:\n");
439 xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n",
440 (uintmax_t)ip6stat.ip6s_m1);
441 for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
442 char ifbuf[IFNAMSIZ];
443 if (ip6stat.ip6s_m2m[i] != 0) {
445 xo_emit("\t\t{N:two or more mbuf}:\n");
446 xo_open_list("mbuf-data");
449 xo_open_instance("mbuf-data");
450 xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n",
451 if_indextoname(i, ifbuf),
452 (uintmax_t)ip6stat.ip6s_m2m[i]);
453 xo_close_instance("mbuf-data");
457 xo_close_list("mbuf-data");
458 xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n",
459 (uintmax_t)ip6stat.ip6s_mext1);
460 xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} "
461 "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m);
462 xo_close_container("mbuf-statistics");
464 p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} "
465 "{N:/packet%s whose headers are not contiguous}\n");
466 p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} "
467 "{N:/tunneling packet%s that can't find gif}\n");
468 p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} "
469 "{N:/packet%s discarded because of too many headers}\n");
471 /* for debugging source address selection */
472 #define PRINT_SCOPESTAT(s,i) do {\
473 switch(i) { /* XXX hardcoding in each case */\
475 p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \
476 "{N:/interface-local%s}\n"); \
479 p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \
480 "{N:/link-local%s}\n"); \
483 p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \
484 "{N:/site-local%s}\n");\
487 p(s,"\t\t{ke:name/globals}{:count/%ju} " \
491 xo_emit("\t\t{qke:name/%#x}{:count/%ju} " \
492 "{N:/addresses scope=%#x}\n",\
493 i, (uintmax_t)ip6stat.s, i); \
497 xo_open_container("source-address-selection");
498 p(ip6s_sources_none, "\t{:address-selection-failures/%ju} "
499 "{N:/failure%s of source address selection}\n");
501 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
502 if (ip6stat.ip6s_sources_sameif[i]) {
504 xo_open_list("outgoing-interface");
505 xo_emit("\tsource addresses on an outgoing "
509 xo_open_instance("outgoing-interface");
510 PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
511 xo_close_instance("outgoing-interface");
515 xo_close_list("outgoing-interface");
517 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
518 if (ip6stat.ip6s_sources_otherif[i]) {
520 xo_open_list("non-outgoing-interface");
521 xo_emit("\tsource addresses on a non-outgoing "
525 xo_open_instance("non-outgoing-interface");
526 PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
527 xo_close_instance("non-outgoing-interface");
531 xo_close_list("non-outgoing-interface");
533 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
534 if (ip6stat.ip6s_sources_samescope[i]) {
536 xo_open_list("same-source");
537 xo_emit("\tsource addresses of same scope\n");
540 xo_open_instance("same-source");
541 PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
542 xo_close_instance("same-source");
546 xo_close_list("same-source");
548 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
549 if (ip6stat.ip6s_sources_otherscope[i]) {
551 xo_open_list("different-scope");
552 xo_emit("\tsource addresses of a different "
556 xo_open_instance("different-scope");
557 PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
558 xo_close_instance("different-scope");
562 xo_close_list("different-scope");
564 for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
565 if (ip6stat.ip6s_sources_deprecated[i]) {
567 xo_open_list("deprecated-source");
568 xo_emit("\tdeprecated source addresses\n");
571 xo_open_instance("deprecated-source");
572 PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
573 xo_close_instance("deprecated-source");
577 xo_close_list("deprecated-source");
579 for (first = 1, i = 0; i < IP6S_RULESMAX; i++) {
580 if (ip6stat.ip6s_sources_rule[i]) {
582 xo_open_list("rules-applied");
583 xo_emit("\t{T:Source addresses selection "
587 xo_open_instance("rules-applied");
588 xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n",
590 (uintmax_t)ip6stat.ip6s_sources_rule[i],
592 xo_close_instance("rules-applied");
596 xo_close_list("rules-applied");
598 xo_close_container("source-address-selection");
602 xo_close_container(name);
606 * Dump IPv6 per-interface statistics based on RFC 2465.
609 ip6_ifstats(char *ifname)
611 struct in6_ifreq ifr;
614 #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \
615 xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, \
616 plural(ifr.ifr_ifru.ifru_stat.f))
618 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
619 xo_warn("Warning: socket(AF_INET6)");
623 strcpy(ifr.ifr_name, ifname);
624 if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
625 if (errno != EPFNOSUPPORT)
626 xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)");
630 xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name);
632 xo_open_instance("ip6-interface-statistics");
633 xo_emit("{ke:name/%s}", ifr.ifr_name);
635 p(ifs6_in_receive, "\t{:received-packets/%ju} "
636 "{N:/total input datagram%s}\n");
637 p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} "
638 "{N:/datagram%s with invalid header received}\n");
639 p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} "
640 "{N:/datagram%s exceeded MTU received}\n");
641 p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} "
642 "{N:/datagram%s with no route received}\n");
643 p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} "
644 "{N:/datagram%s with invalid dst received}\n");
645 p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} "
646 "{N:/datagram%s with unknown proto received}\n");
647 p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} "
648 "{N:/truncated datagram%s received}\n");
649 p(ifs6_in_discard, "\t{:dropped-discarded/%ju} "
650 "{N:/input datagram%s discarded}\n");
651 p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} "
652 "{N:/datagram%s delivered to an upper layer protocol}\n");
653 p(ifs6_out_forward, "\t{:sent-forwarded/%ju} "
654 "{N:/datagram%s forwarded to this interface}\n");
655 p(ifs6_out_request, "\t{:sent-packets/%ju} "
656 "{N:/datagram%s sent from an upper layer protocol}\n");
657 p(ifs6_out_discard, "\t{:discard-packets/%ju} "
658 "{N:/total discarded output datagram%s}\n");
659 p(ifs6_out_fragok, "\t{:discard-fragments/%ju} "
660 "{N:/output datagram%s fragmented}\n");
661 p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} "
662 "{N:/output datagram%s failed on fragment}\n");
663 p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} "
664 "{N:/output datagram%s succeeded on fragment}\n");
665 p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} "
666 "{N:/incoming datagram%s fragmented}\n");
667 p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} "
668 "{N:/datagram%s reassembled}\n");
669 p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} "
670 "{N:/datagram%s failed on reassembly}\n");
671 p(ifs6_in_mcast, "\t{:received-multicast/%ju} "
672 "{N:/multicast datagram%s received}\n");
673 p(ifs6_out_mcast, "\t{:sent-multicast/%ju} "
674 "{N:/multicast datagram%s sent}\n");
677 xo_close_instance("ip6-interface-statistics");
683 static const char *icmp6names[] = {
814 "multicast listener query",
815 "MLDv1 listener report",
816 "MLDv1 listener done",
817 "router solicitation",
818 "router advertisement",
819 "neighbor solicitation",
820 "neighbor advertisement",
822 "router renumbering",
823 "node information request",
824 "node information reply",
825 "inverse neighbor solicitation",
826 "inverse neighbor advertisement",
827 "MLDv2 listener report",
943 * Dump ICMP6 statistics.
946 icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
948 struct icmp6stat icmp6stat;
951 if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat,
952 sizeof(icmp6stat), kread_counters) != 0)
955 xo_emit("{T:/%s}:\n", name);
956 xo_open_container(name);
958 #define p(f, m) if (icmp6stat.f || sflag <= 1) \
959 xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
960 #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
961 xo_emit(m, (uintmax_t)icmp6stat.f)
963 p(icp6s_error, "\t{:icmp6-calls/%ju} "
964 "{N:/call%s to icmp6_error}\n");
965 p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} "
966 "{N:/error%s not generated in response to an icmp6 message}\n");
967 p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} "
968 "{N:/error%s not generated because of rate limitation}\n");
969 #define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
970 for (first = 1, i = 0; i < NELEM; i++)
971 if (icmp6stat.icp6s_outhist[i] != 0) {
973 xo_open_list("output-histogram");
974 xo_emit("\t{T:Output histogram}:\n");
977 xo_open_instance("output-histogram");
978 xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
980 (uintmax_t)icmp6stat.icp6s_outhist[i]);
981 xo_close_instance("output-histogram");
984 xo_close_list("output-histogram");
987 p(icp6s_badcode, "\t{:dropped-bad-code/%ju} "
988 "{N:/message%s with bad code fields}\n");
989 p(icp6s_tooshort, "\t{:dropped-too-short/%ju} "
990 "{N:/message%s < minimum length}\n");
991 p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} "
992 "{N:/bad checksum%s}\n");
993 p(icp6s_badlen, "\t{:dropped-bad-length/%ju} "
994 "{N:/message%s with bad length}\n");
995 #define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
996 for (first = 1, i = 0; i < NELEM; i++)
997 if (icmp6stat.icp6s_inhist[i] != 0) {
999 xo_open_list("input-histogram");
1000 xo_emit("\t{T:Input histogram}:\n");
1003 xo_open_instance("input-histogram");
1004 xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
1006 (uintmax_t)icmp6stat.icp6s_inhist[i]);
1007 xo_close_instance("input-histogram");
1010 xo_close_list("input-histogram");
1012 xo_emit("\t{T:Histogram of error messages to be generated}:\n");
1013 xo_open_container("errors");
1014 p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} "
1016 p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} "
1017 "{N:/administratively prohibited}\n");
1018 p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} "
1019 "{N:/beyond scope}\n");
1020 p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} "
1021 "{N:/address unreachable}\n");
1022 p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} "
1023 "{N:/port unreachable}\n");
1024 p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} "
1025 "{N:/packet too big}\n");
1026 p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} "
1027 "{N:/time exceed transit}\n");
1028 p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} "
1029 "{N:/time exceed reassembly}\n");
1030 p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} "
1031 "{N:/erroneous header field}\n");
1032 p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} "
1033 "{N:/unrecognized next header}\n");
1034 p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} "
1035 "{N:/unrecognized option}\n");
1036 p_5(icp6s_oredirect, "\t\t{:redirects/%ju} "
1038 p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n");
1040 p(icp6s_reflect, "\t{:reflect/%ju} "
1041 "{N:/message response%s generated}\n");
1042 p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} "
1043 "{N:/message%s with too many ND options}\n");
1044 p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} "
1045 "{N:/message%s with bad ND options}\n");
1046 p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} "
1047 "{N:/bad neighbor solicitation message%s}\n");
1048 p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} "
1049 "{N:/bad neighbor advertisement message%s}\n");
1050 p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} "
1051 "{N:/bad router solicitation message%s}\n");
1052 p(icp6s_badra, "\t{:bad-router-advertisement/%ju} "
1053 "{N:/bad router advertisement message%s}\n");
1054 p(icp6s_badredirect, "\t{:bad-redirect/%ju} "
1055 "{N:/bad redirect message%s}\n");
1056 xo_close_container("errors");
1057 p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n");
1060 xo_close_container(name);
1064 * Dump ICMPv6 per-interface statistics based on RFC 2466.
1067 icmp6_ifstats(char *ifname)
1069 struct in6_ifreq ifr;
1072 #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
1073 xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \
1074 plural(ifr.ifr_ifru.ifru_icmp6stat.f))
1075 #define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \
1076 xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \
1077 pluralies(ifr.ifr_ifru.ifru_icmp6stat.f))
1079 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1080 xo_warn("Warning: socket(AF_INET6)");
1084 strcpy(ifr.ifr_name, ifname);
1085 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
1086 if (errno != EPFNOSUPPORT)
1087 xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
1091 xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name);
1093 xo_open_instance("icmp6-interface-statistics");
1094 xo_emit("{ke:name/%s}", ifr.ifr_name);
1095 p(ifs6_in_msg, "\t{:received-packets/%ju} "
1096 "{N:/total input message%s}\n");
1097 p(ifs6_in_error, "\t{:received-errors/%ju} "
1098 "{N:/total input error message%s}\n");
1099 p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} "
1100 "{N:/input destination unreachable error%s}\n");
1101 p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} "
1102 "{N:/input administratively prohibited error%s}\n");
1103 p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} "
1104 "{N:/input time exceeded error%s}\n");
1105 p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} "
1106 "{N:/input parameter problem error%s}\n");
1107 p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} "
1108 "{N:/input packet too big error%s}\n");
1109 p(ifs6_in_echo, "\t{:received-echo-requests/%ju} "
1110 "{N:/input echo request%s}\n");
1111 p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} "
1112 "{N:/input echo repl%s}\n");
1113 p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} "
1114 "{N:/input router solicitation%s}\n");
1115 p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} "
1116 "{N:/input router advertisement%s}\n");
1117 p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} "
1118 "{N:/input neighbor solicitation%s}\n");
1119 p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} "
1120 "{N:/input neighbor advertisement%s}\n");
1121 p(ifs6_in_redirect, "\t{received-redirects/%ju} "
1122 "{N:/input redirect%s}\n");
1123 p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} "
1124 "{N:/input MLD quer%s}\n");
1125 p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} "
1126 "{N:/input MLD report%s}\n");
1127 p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} "
1128 "{N:/input MLD done%s}\n");
1130 p(ifs6_out_msg, "\t{:sent-packets/%ju} "
1131 "{N:/total output message%s}\n");
1132 p(ifs6_out_error, "\t{:sent-errors/%ju} "
1133 "{N:/total output error message%s}\n");
1134 p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} "
1135 "{N:/output destination unreachable error%s}\n");
1136 p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} "
1137 "{N:/output administratively prohibited error%s}\n");
1138 p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} "
1139 "{N:/output time exceeded error%s}\n");
1140 p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} "
1141 "{N:/output parameter problem error%s}\n");
1142 p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} "
1143 "{N:/output packet too big error%s}\n");
1144 p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} "
1145 "{N:/output echo request%s}\n");
1146 p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} "
1147 "{N:/output echo repl%s}\n");
1148 p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} "
1149 "{N:/output router solicitation%s}\n");
1150 p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} "
1151 "{N:/output router advertisement%s}\n");
1152 p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} "
1153 "{N:/output neighbor solicitation%s}\n");
1154 p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} "
1155 "{N:/output neighbor advertisement%s}\n");
1156 p(ifs6_out_redirect, "\t{:sent-redirects/%ju} "
1157 "{N:/output redirect%s}\n");
1158 p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} "
1159 "{N:/output MLD quer%s}\n");
1160 p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} "
1161 "{N:/output MLD report%s}\n");
1162 p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} "
1163 "{N:/output MLD done%s}\n");
1166 xo_close_instance("icmp6-interface-statistics");
1172 * Dump PIM statistics structure.
1175 pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
1177 struct pim6stat pim6stat;
1179 if (fetch_stats("net.inet6.pim.stats", off, &pim6stat,
1180 sizeof(pim6stat), kread) != 0)
1183 xo_emit("{T:/%s}:\n", name);
1184 xo_open_container(name);
1186 #define p(f, m) if (pim6stat.f || sflag <= 1) \
1187 xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
1189 p(pim6s_rcv_total, "\t{:received-packets/%ju} "
1190 "{N:/message%s received}\n");
1191 p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} "
1192 "{N:/message%s received with too few bytes}\n");
1193 p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} "
1194 "{N:/message%s received with bad checksum}\n");
1195 p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} "
1196 "{N:/message%s received with bad version}\n");
1197 p(pim6s_rcv_registers, "\t{:received-registers/%ju} "
1198 "{N:/register%s received}\n");
1199 p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} "
1200 "{N:/bad register%s received}\n");
1201 p(pim6s_snd_registers, "\t{:sent-registers/%ju} "
1202 "{N:/register%s sent}\n");
1204 xo_close_container(name);
1208 * Dump raw ip6 statistics structure.
1211 rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
1213 struct rip6stat rip6stat;
1216 if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat,
1217 sizeof(rip6stat), kread_counters) != 0)
1220 xo_emit("{T:/%s}:\n", name);
1221 xo_open_container(name);
1223 #define p(f, m) if (rip6stat.f || sflag <= 1) \
1224 xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
1226 p(rip6s_ipackets, "\t{:received-packets/%ju} "
1227 "{N:/message%s received}\n");
1228 p(rip6s_isum, "\t{:input-checksum-computation/%ju} "
1229 "{N:/checksum calculation%s on inbound}\n");
1230 p(rip6s_badsum, "\t{:received-bad-checksum/%ju} "
1231 "{N:/message%s with bad checksum}\n");
1232 p(rip6s_nosock, "\t{:dropped-no-socket/%ju} "
1233 "{N:/message%s dropped due to no socket}\n");
1234 p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} "
1235 "{N:/multicast message%s dropped due to no socket}\n");
1236 p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} "
1237 "{N:/message%s dropped due to full socket buffers}\n");
1238 delivered = rip6stat.rip6s_ipackets -
1239 rip6stat.rip6s_badsum -
1240 rip6stat.rip6s_nosock -
1241 rip6stat.rip6s_nosockmcast -
1242 rip6stat.rip6s_fullsock;
1243 if (delivered || sflag <= 1)
1244 xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n",
1245 (uintmax_t)delivered);
1246 p(rip6s_opackets, "\t{:sent-packets/%ju} "
1247 "{N:/datagram%s output}\n");
1249 xo_close_container(name);
1253 * Pretty print an Internet address (net address + port).
1254 * Take numeric_addr and numeric_port into consideration.
1256 #define GETSERVBYPORT6(port, proto, ret)\
1258 if (strcmp((proto), "tcp6") == 0)\
1259 (ret) = getservbyport((int)(port), "tcp");\
1260 else if (strcmp((proto), "udp6") == 0)\
1261 (ret) = getservbyport((int)(port), "udp");\
1263 (ret) = getservbyport((int)(port), (proto));\
1267 inet6print(const char *container, struct in6_addr *in6, int port,
1268 const char *proto, int numeric)
1270 struct servent *sp = 0;
1275 xo_open_container(container);
1277 sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
1279 cp = strchr(line, '\0');
1280 if (!numeric && port)
1281 GETSERVBYPORT6(port, proto, sp);
1282 if (sp || port == 0)
1283 sprintf(cp, "%.15s", sp ? sp->s_name : "*");
1285 sprintf(cp, "%d", ntohs((u_short)port));
1286 width = Wflag ? 45 : Aflag ? 18 : 22;
1288 xo_emit("{d:target/%-*.*s} ", width, width, line);
1290 int alen = cp - line - 1, plen = strlen(cp) - 1;
1291 xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
1295 xo_close_container(container);
1299 * Construct an Internet address representation.
1300 * If the numeric_addr has been supplied, give
1301 * numeric value, otherwise try for symbolic name.
1305 inet6name(struct in6_addr *in6p)
1307 struct sockaddr_in6 sin6;
1308 char hbuf[NI_MAXHOST], *cp;
1309 static char line[50];
1310 static char domain[MAXHOSTNAMELEN];
1311 static int first = 1;
1314 if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
1318 if (first && !numeric_addr) {
1320 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1321 (cp = strchr(domain, '.')))
1322 (void) strcpy(domain, cp + 1);
1326 memset(&sin6, 0, sizeof(sin6));
1327 memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
1328 sin6.sin6_family = AF_INET6;
1329 /* XXX: in6p.s6_addr[2] can contain scopeid. */
1330 in6_fillscopeid(&sin6);
1331 flags = (numeric_addr) ? NI_NUMERICHOST : 0;
1332 error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
1333 sizeof(hbuf), NULL, 0, flags);
1335 if ((flags & NI_NUMERICHOST) == 0 &&
1336 (cp = strchr(hbuf, '.')) &&
1337 !strcmp(cp + 1, domain))
1341 /* XXX: this should not happen. */
1343 inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,