154263Sshin/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2175061Sobrien/*- 354263Sshin * Copyright (c) 1983, 1988, 1993 454263Sshin * The Regents of the University of California. All rights reserved. 554263Sshin * 654263Sshin * Redistribution and use in source and binary forms, with or without 754263Sshin * modification, are permitted provided that the following conditions 854263Sshin * are met: 954263Sshin * 1. Redistributions of source code must retain the above copyright 1054263Sshin * notice, this list of conditions and the following disclaimer. 1154263Sshin * 2. Redistributions in binary form must reproduce the above copyright 1254263Sshin * notice, this list of conditions and the following disclaimer in the 1354263Sshin * documentation and/or other materials provided with the distribution. 1454263Sshin * 4. Neither the name of the University nor the names of its contributors 1554263Sshin * may be used to endorse or promote products derived from this software 1654263Sshin * without specific prior written permission. 1754263Sshin * 1854263Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1954263Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2054263Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2154263Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2254263Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2354263Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2454263Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2554263Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2654263Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2754263Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2854263Sshin * SUCH DAMAGE. 2954263Sshin */ 3054263Sshin 31132671Scharnier#if 0 3254263Sshin#ifndef lint 3354263Sshinstatic char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; 3454263Sshin#endif /* not lint */ 35132671Scharnier#endif 3654263Sshin 37132671Scharnier#include <sys/cdefs.h> 38132671Scharnier__FBSDID("$FreeBSD: stable/11/usr.bin/netstat/inet6.c 355869 2019-12-17 23:45:50Z bz $"); 39132671Scharnier 4064342Sume#ifdef INET6 4154263Sshin#include <sys/param.h> 4254263Sshin#include <sys/socket.h> 4354263Sshin#include <sys/socketvar.h> 4454263Sshin#include <sys/ioctl.h> 4554263Sshin#include <sys/mbuf.h> 4654263Sshin#include <sys/protosw.h> 4754263Sshin 4854263Sshin#include <net/route.h> 4954263Sshin#include <net/if.h> 5054263Sshin#include <netinet/in.h> 5154263Sshin#include <netinet/ip6.h> 5254263Sshin#include <netinet/icmp6.h> 5354263Sshin#include <netinet/in_systm.h> 5454263Sshin#include <netinet6/in6_pcb.h> 5554263Sshin#include <netinet6/in6_var.h> 5654263Sshin#include <netinet6/ip6_var.h> 5754263Sshin#include <netinet6/pim6_var.h> 5878064Sume#include <netinet6/raw_ip6.h> 5954263Sshin 6054263Sshin#include <arpa/inet.h> 6154263Sshin#include <netdb.h> 6254263Sshin 63166952Sbms#include <err.h> 64160787Syar#include <stdint.h> 6554263Sshin#include <stdio.h> 66279122Smarcel#include <stdbool.h> 67160373Sjulian#include <errno.h> 6854263Sshin#include <string.h> 6954263Sshin#include <unistd.h> 70279122Smarcel#include <libxo/xo.h> 7154263Sshin#include "netstat.h" 7254263Sshin 7354263Sshinstatic char ntop_buf[INET6_ADDRSTRLEN]; 7454263Sshin 75102975Sdwmalonestatic const char *ip6nh[] = { 7654263Sshin "hop by hop", 7754263Sshin "ICMP", 7854263Sshin "IGMP", 7954263Sshin "#3", 8054263Sshin "IP", 8154263Sshin "#5", 8254263Sshin "TCP", 8354263Sshin "#7", 8454263Sshin "#8", 8554263Sshin "#9", 8654263Sshin "#10", 8754263Sshin "#11", 8854263Sshin "#12", 8954263Sshin "#13", 9054263Sshin "#14", 9154263Sshin "#15", 9254263Sshin "#16", 9354263Sshin "UDP", 9454263Sshin "#18", 95175061Sobrien "#19", 9654263Sshin "#20", 9754263Sshin "#21", 9854263Sshin "IDP", 9954263Sshin "#23", 10054263Sshin "#24", 10154263Sshin "#25", 10254263Sshin "#26", 10354263Sshin "#27", 10454263Sshin "#28", 105175061Sobrien "TP", 10654263Sshin "#30", 10754263Sshin "#31", 10854263Sshin "#32", 10954263Sshin "#33", 11054263Sshin "#34", 11154263Sshin "#35", 11254263Sshin "#36", 11354263Sshin "#37", 11454263Sshin "#38", 115175061Sobrien "#39", 11654263Sshin "#40", 11754263Sshin "IP6", 11854263Sshin "#42", 11954263Sshin "routing", 12054263Sshin "fragment", 12154263Sshin "#45", 12254263Sshin "#46", 12354263Sshin "#47", 12454263Sshin "#48", 125175061Sobrien "#49", 12654263Sshin "ESP", 12754263Sshin "AH", 12854263Sshin "#52", 12954263Sshin "#53", 13054263Sshin "#54", 13154263Sshin "#55", 13254263Sshin "#56", 13354263Sshin "#57", 13454263Sshin "ICMP6", 135175061Sobrien "no next header", 13654263Sshin "destination option", 13754263Sshin "#61", 138125482Sume "mobility", 13954263Sshin "#63", 14054263Sshin "#64", 14154263Sshin "#65", 14254263Sshin "#66", 14354263Sshin "#67", 14454263Sshin "#68", 145175061Sobrien "#69", 14654263Sshin "#70", 14754263Sshin "#71", 14854263Sshin "#72", 14954263Sshin "#73", 15054263Sshin "#74", 15154263Sshin "#75", 15254263Sshin "#76", 15354263Sshin "#77", 15454263Sshin "#78", 155175061Sobrien "#79", 15654263Sshin "ISOIP", 15754263Sshin "#81", 15854263Sshin "#82", 15954263Sshin "#83", 16054263Sshin "#84", 16154263Sshin "#85", 16254263Sshin "#86", 16354263Sshin "#87", 16454263Sshin "#88", 165175061Sobrien "OSPF", 16654263Sshin "#80", 16754263Sshin "#91", 16854263Sshin "#92", 16954263Sshin "#93", 17054263Sshin "#94", 17154263Sshin "#95", 17254263Sshin "#96", 17354263Sshin "Ethernet", 17454263Sshin "#98", 175175061Sobrien "#99", 17654263Sshin "#100", 17754263Sshin "#101", 17854263Sshin "#102", 17954263Sshin "PIM", 18054263Sshin "#104", 18154263Sshin "#105", 18254263Sshin "#106", 18354263Sshin "#107", 18454263Sshin "#108", 185175061Sobrien "#109", 18654263Sshin "#110", 18754263Sshin "#111", 18854263Sshin "#112", 18954263Sshin "#113", 19054263Sshin "#114", 19154263Sshin "#115", 19254263Sshin "#116", 19354263Sshin "#117", 19454263Sshin "#118", 195175061Sobrien "#119", 19654263Sshin "#120", 19754263Sshin "#121", 19854263Sshin "#122", 19954263Sshin "#123", 20054263Sshin "#124", 20154263Sshin "#125", 20254263Sshin "#126", 20354263Sshin "#127", 20454263Sshin "#128", 205175061Sobrien "#129", 20654263Sshin "#130", 20754263Sshin "#131", 208304519Stuexen "SCTP", 20954263Sshin "#133", 21054263Sshin "#134", 21154263Sshin "#135", 212304519Stuexen "UDPLite", 21354263Sshin "#137", 21454263Sshin "#138", 215175061Sobrien "#139", 21654263Sshin "#140", 21754263Sshin "#141", 21854263Sshin "#142", 21954263Sshin "#143", 22054263Sshin "#144", 22154263Sshin "#145", 22254263Sshin "#146", 22354263Sshin "#147", 22454263Sshin "#148", 225175061Sobrien "#149", 22654263Sshin "#150", 22754263Sshin "#151", 22854263Sshin "#152", 22954263Sshin "#153", 23054263Sshin "#154", 23154263Sshin "#155", 23254263Sshin "#156", 23354263Sshin "#157", 23454263Sshin "#158", 235175061Sobrien "#159", 23654263Sshin "#160", 23754263Sshin "#161", 23854263Sshin "#162", 23954263Sshin "#163", 24054263Sshin "#164", 24154263Sshin "#165", 24254263Sshin "#166", 24354263Sshin "#167", 24454263Sshin "#168", 245175061Sobrien "#169", 24654263Sshin "#170", 24754263Sshin "#171", 24854263Sshin "#172", 24954263Sshin "#173", 25054263Sshin "#174", 25154263Sshin "#175", 25254263Sshin "#176", 25354263Sshin "#177", 25454263Sshin "#178", 255175061Sobrien "#179", 25654263Sshin "#180", 25754263Sshin "#181", 25854263Sshin "#182", 25954263Sshin "#183", 26054263Sshin "#184", 26154263Sshin "#185", 26254263Sshin "#186", 26354263Sshin "#187", 26454263Sshin "#188", 265175061Sobrien "#189", 26654263Sshin "#180", 26754263Sshin "#191", 26854263Sshin "#192", 26954263Sshin "#193", 27054263Sshin "#194", 27154263Sshin "#195", 27254263Sshin "#196", 27354263Sshin "#197", 27454263Sshin "#198", 275175061Sobrien "#199", 27654263Sshin "#200", 27754263Sshin "#201", 27854263Sshin "#202", 27954263Sshin "#203", 28054263Sshin "#204", 28154263Sshin "#205", 28254263Sshin "#206", 28354263Sshin "#207", 28454263Sshin "#208", 285175061Sobrien "#209", 28654263Sshin "#210", 28754263Sshin "#211", 28854263Sshin "#212", 28954263Sshin "#213", 29054263Sshin "#214", 29154263Sshin "#215", 29254263Sshin "#216", 29354263Sshin "#217", 29454263Sshin "#218", 295175061Sobrien "#219", 29654263Sshin "#220", 29754263Sshin "#221", 29854263Sshin "#222", 29954263Sshin "#223", 30054263Sshin "#224", 30154263Sshin "#225", 30254263Sshin "#226", 30354263Sshin "#227", 30454263Sshin "#228", 305175061Sobrien "#229", 30654263Sshin "#230", 30754263Sshin "#231", 30854263Sshin "#232", 30954263Sshin "#233", 31054263Sshin "#234", 31154263Sshin "#235", 31254263Sshin "#236", 31354263Sshin "#237", 31454263Sshin "#238", 315175061Sobrien "#239", 31654263Sshin "#240", 31754263Sshin "#241", 31854263Sshin "#242", 31954263Sshin "#243", 32054263Sshin "#244", 32154263Sshin "#245", 32254263Sshin "#246", 32354263Sshin "#247", 32454263Sshin "#248", 325175061Sobrien "#249", 32654263Sshin "#250", 32754263Sshin "#251", 32854263Sshin "#252", 32954263Sshin "#253", 33054263Sshin "#254", 33154263Sshin "#255", 33254263Sshin}; 33354263Sshin 334246988Scharnierstatic const char *srcrule_str[] = { 335125483Sume "first candidate", 336125483Sume "same address", 337125483Sume "appropriate scope", 338125483Sume "deprecated address", 339125483Sume "home address", 340125483Sume "outgoing interface", 341125483Sume "matching label", 342125483Sume "public/temporary address", 343125483Sume "alive interface", 344270927Sae "better virtual status", 345271307Sae "preferred source", 346125483Sume "rule #11", 347125483Sume "rule #12", 348125483Sume "rule #13", 349125483Sume "longest match", 350125483Sume "rule #15", 351125483Sume}; 352125483Sume 35354263Sshin/* 35454263Sshin * Dump IP6 statistics structure. 35554263Sshin */ 35654263Sshinvoid 357171465Sjhbip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 35854263Sshin{ 359287649Smarkj struct ip6stat ip6stat; 36054263Sshin int first, i; 36154263Sshin 362287649Smarkj if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat, 363287649Smarkj sizeof(ip6stat), kread_counters) != 0) 364287649Smarkj return; 365287649Smarkj 366279122Smarcel xo_open_container(name); 367279122Smarcel xo_emit("{T:/%s}:\n", name); 36854263Sshin 36954263Sshin#define p(f, m) if (ip6stat.f || sflag <= 1) \ 370279122Smarcel xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) 37154263Sshin#define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 372279122Smarcel xo_emit(m, (uintmax_t)ip6stat.f) 37354263Sshin 374279122Smarcel p(ip6s_total, "\t{:received-packets/%ju} " 375279122Smarcel "{N:/total packet%s received}\n"); 376279122Smarcel p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} " 377279122Smarcel "{N:/with size smaller than minimum}\n"); 378279122Smarcel p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} " 379279122Smarcel "{N:/with data size < data length}\n"); 380279122Smarcel p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} " 381279122Smarcel "{N:/with bad options}\n"); 382279122Smarcel p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} " 383279122Smarcel "{N:/with incorrect version number}\n"); 384279122Smarcel p(ip6s_fragments, "\t{:received-fragments/%ju} " 385279122Smarcel "{N:/fragment%s received}\n"); 386279122Smarcel p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} " 387279122Smarcel "{N:/fragment%s dropped (dup or out of space)}\n"); 388279122Smarcel p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} " 389279122Smarcel "{N:/fragment%s dropped after timeout}\n"); 390279122Smarcel p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} " 391279122Smarcel "{N:/fragment%s that exceeded limit}\n"); 392279122Smarcel p(ip6s_reassembled, "\t{:reassembled-packets/%ju} " 393279122Smarcel "{N:/packet%s reassembled ok}\n"); 394279122Smarcel p(ip6s_delivered, "\t{:received-local-packets/%ju} " 395279122Smarcel "{N:/packet%s for this host}\n"); 396279122Smarcel p(ip6s_forward, "\t{:forwarded-packets/%ju} " 397279122Smarcel "{N:/packet%s forwarded}\n"); 398279122Smarcel p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} " 399279122Smarcel "{N:/packet%s not forwardable}\n"); 400279122Smarcel p(ip6s_redirectsent, "\t{:sent-redirects/%ju} " 401279122Smarcel "{N:/redirect%s sent}\n"); 402279122Smarcel p(ip6s_localout, "\t{:sent-packets/%ju} " 403279122Smarcel "{N:/packet%s sent from this host}\n"); 404279122Smarcel p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} " 405279122Smarcel "{N:/packet%s sent with fabricated ip header}\n"); 406279122Smarcel p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} " 407279122Smarcel "{N:/output packet%s dropped due to no bufs, etc.}\n"); 408279122Smarcel p(ip6s_noroute, "\t{:discard-no-route/%ju} " 409279122Smarcel "{N:/output packet%s discarded due to no route}\n"); 410279122Smarcel p(ip6s_fragmented, "\t{:sent-fragments/%ju} " 411279122Smarcel "{N:/output datagram%s fragmented}\n"); 412279122Smarcel p(ip6s_ofragments, "\t{:fragments-created/%ju} " 413279122Smarcel "{N:/fragment%s created}\n"); 414279122Smarcel p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} " 415279122Smarcel "{N:/datagram%s that can't be fragmented}\n"); 416279122Smarcel p(ip6s_badscope, "\t{:discard-scope-violations/%ju} " 417279122Smarcel "{N:/packet%s that violated scope rules}\n"); 418279122Smarcel p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} " 419279122Smarcel "{N:/multicast packet%s which we don't join}\n"); 420249545Sae for (first = 1, i = 0; i < IP6S_HDRCNT; i++) 42154263Sshin if (ip6stat.ip6s_nxthist[i] != 0) { 42254263Sshin if (first) { 423279122Smarcel xo_emit("\t{T:Input histogram}:\n"); 424279122Smarcel xo_open_list("input-histogram"); 42554263Sshin first = 0; 42654263Sshin } 427279122Smarcel xo_open_instance("input-histogram"); 428279122Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i], 429160787Syar (uintmax_t)ip6stat.ip6s_nxthist[i]); 430279122Smarcel xo_close_instance("input-histogram"); 43154263Sshin } 432279122Smarcel if (!first) 433279122Smarcel xo_close_list("input-histogram"); 434279122Smarcel 435279122Smarcel xo_open_container("mbuf-statistics"); 436279122Smarcel xo_emit("\t{T:Mbuf statistics}:\n"); 437279122Smarcel xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n", 438279122Smarcel (uintmax_t)ip6stat.ip6s_m1); 439249545Sae for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { 44055163Sshin char ifbuf[IFNAMSIZ]; 441175061Sobrien if (ip6stat.ip6s_m2m[i] != 0) { 44254263Sshin if (first) { 443279122Smarcel xo_emit("\t\t{N:two or more mbuf}:\n"); 444279122Smarcel xo_open_list("mbuf-data"); 44554263Sshin first = 0; 44654263Sshin } 447279122Smarcel xo_open_instance("mbuf-data"); 448279122Smarcel xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n", 44962584Sitojun if_indextoname(i, ifbuf), 450160787Syar (uintmax_t)ip6stat.ip6s_m2m[i]); 451279122Smarcel xo_close_instance("mbuf-data"); 45254263Sshin } 45354263Sshin } 454279122Smarcel if (!first) 455279122Smarcel xo_close_list("mbuf-data"); 456279122Smarcel xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n", 457160787Syar (uintmax_t)ip6stat.ip6s_mext1); 458279122Smarcel xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} " 459279122Smarcel "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m); 460279122Smarcel xo_close_container("mbuf-statistics"); 46162584Sitojun 462279122Smarcel p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} " 463279122Smarcel "{N:/packet%s whose headers are not contiguous}\n"); 464279122Smarcel p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} " 465279122Smarcel "{N:/tunneling packet%s that can't find gif}\n"); 466279122Smarcel p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} " 467279122Smarcel "{N:/packet%s discarded because of too many headers}\n"); 468279122Smarcel 46962584Sitojun /* for debugging source address selection */ 470175061Sobrien#define PRINT_SCOPESTAT(s,i) do {\ 47162584Sitojun switch(i) { /* XXX hardcoding in each case */\ 47262584Sitojun case 1:\ 473279122Smarcel p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \ 474279122Smarcel "{N:/interface-local%s}\n"); \ 47562584Sitojun break;\ 47662584Sitojun case 2:\ 477279122Smarcel p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \ 478279122Smarcel "{N:/link-local%s}\n"); \ 47962584Sitojun break;\ 48062584Sitojun case 5:\ 481279122Smarcel p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \ 482279122Smarcel "{N:/site-local%s}\n");\ 48362584Sitojun break;\ 48462584Sitojun case 14:\ 485279122Smarcel p(s,"\t\t{ke:name/globals}{:count/%ju} " \ 486279122Smarcel "{N:/global%s}\n");\ 48762584Sitojun break;\ 48862584Sitojun default:\ 489304519Stuexen xo_emit("\t\t{qke:name/%#x}{:count/%ju} " \ 490304519Stuexen "{N:/addresses scope=%#x}\n",\ 491279122Smarcel i, (uintmax_t)ip6stat.s, i); \ 49262584Sitojun }\ 49362584Sitojun } while (0); 49462584Sitojun 495279122Smarcel xo_open_container("source-address-selection"); 496279122Smarcel p(ip6s_sources_none, "\t{:address-selection-failures/%ju} " 497279122Smarcel "{N:/failure%s of source address selection}\n"); 498279122Smarcel 499249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 50062584Sitojun if (ip6stat.ip6s_sources_sameif[i]) { 50162584Sitojun if (first) { 502279122Smarcel xo_open_list("outgoing-interface"); 503279122Smarcel xo_emit("\tsource addresses on an outgoing " 504279122Smarcel "I/F\n"); 50562584Sitojun first = 0; 50662584Sitojun } 507279122Smarcel xo_open_instance("outgoing-interface"); 50862584Sitojun PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); 509279122Smarcel xo_close_instance("outgoing-interface"); 51062584Sitojun } 51162584Sitojun } 512279122Smarcel if (!first) 513279122Smarcel xo_close_list("outgoing-interface"); 514279122Smarcel 515249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 51662584Sitojun if (ip6stat.ip6s_sources_otherif[i]) { 51762584Sitojun if (first) { 518279122Smarcel xo_open_list("non-outgoing-interface"); 519279122Smarcel xo_emit("\tsource addresses on a non-outgoing " 520279122Smarcel "I/F\n"); 52162584Sitojun first = 0; 52262584Sitojun } 523279122Smarcel xo_open_instance("non-outgoing-interface"); 52462584Sitojun PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); 525279122Smarcel xo_close_instance("non-outgoing-interface"); 52662584Sitojun } 52762584Sitojun } 528279122Smarcel if (!first) 529279122Smarcel xo_close_list("non-outgoing-interface"); 530279122Smarcel 531249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 53262584Sitojun if (ip6stat.ip6s_sources_samescope[i]) { 53362584Sitojun if (first) { 534279122Smarcel xo_open_list("same-source"); 535279122Smarcel xo_emit("\tsource addresses of same scope\n"); 53662584Sitojun first = 0; 53762584Sitojun } 538279122Smarcel xo_open_instance("same-source"); 53962584Sitojun PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); 540279122Smarcel xo_close_instance("same-source"); 54162584Sitojun } 54262584Sitojun } 543279122Smarcel if (!first) 544279122Smarcel xo_close_list("same-source"); 545279122Smarcel 546249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 54762584Sitojun if (ip6stat.ip6s_sources_otherscope[i]) { 54862584Sitojun if (first) { 549279122Smarcel xo_open_list("different-scope"); 550279122Smarcel xo_emit("\tsource addresses of a different " 551279122Smarcel "scope\n"); 55262584Sitojun first = 0; 55362584Sitojun } 554279122Smarcel xo_open_instance("different-scope"); 55562584Sitojun PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); 556279122Smarcel xo_close_instance("different-scope"); 55762584Sitojun } 55862584Sitojun } 559279122Smarcel if (!first) 560279122Smarcel xo_close_list("different-scope"); 561279122Smarcel 562249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 56362584Sitojun if (ip6stat.ip6s_sources_deprecated[i]) { 56462584Sitojun if (first) { 565279122Smarcel xo_open_list("deprecated-source"); 566279122Smarcel xo_emit("\tdeprecated source addresses\n"); 56762584Sitojun first = 0; 56862584Sitojun } 569279122Smarcel xo_open_instance("deprecated-source"); 57062584Sitojun PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); 571279122Smarcel xo_close_instance("deprecated-source"); 57262584Sitojun } 57362584Sitojun } 574279122Smarcel if (!first) 575279122Smarcel xo_close_list("deprecated-source"); 57662584Sitojun 577279122Smarcel for (first = 1, i = 0; i < IP6S_RULESMAX; i++) { 578279122Smarcel if (ip6stat.ip6s_sources_rule[i]) { 579279122Smarcel if (first) { 580279122Smarcel xo_open_list("rules-applied"); 581279122Smarcel xo_emit("\t{T:Source addresses selection " 582279122Smarcel "rule applied}:\n"); 583279122Smarcel first = 0; 584279122Smarcel } 585279122Smarcel xo_open_instance("rules-applied"); 586279122Smarcel xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n", 587279122Smarcel srcrule_str[i], 588279122Smarcel (uintmax_t)ip6stat.ip6s_sources_rule[i], 589279122Smarcel srcrule_str[i]); 590279122Smarcel xo_close_instance("rules-applied"); 591279122Smarcel } 592125483Sume } 593279122Smarcel if (!first) 594279122Smarcel xo_close_list("rules-applied"); 595279122Smarcel 596279122Smarcel xo_close_container("source-address-selection"); 597279122Smarcel 59854263Sshin#undef p 59962584Sitojun#undef p1a 600279122Smarcel xo_close_container(name); 60154263Sshin} 60254263Sshin 60354263Sshin/* 60454263Sshin * Dump IPv6 per-interface statistics based on RFC 2465. 60554263Sshin */ 60654263Sshinvoid 60778314Sassarip6_ifstats(char *ifname) 60854263Sshin{ 60954263Sshin struct in6_ifreq ifr; 61054263Sshin int s; 61154263Sshin 612279122Smarcel#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 613279122Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, \ 614279122Smarcel plural(ifr.ifr_ifru.ifru_stat.f)) 615279122Smarcel 61654263Sshin if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 617279122Smarcel xo_warn("Warning: socket(AF_INET6)"); 61854263Sshin return; 61954263Sshin } 62054263Sshin 621317555Sasomers strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 62254263Sshin if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 623270349Smarkj if (errno != EPFNOSUPPORT) 624279122Smarcel xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)"); 62554263Sshin goto end; 62654263Sshin } 62754263Sshin 628279122Smarcel xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name); 62954263Sshin 630279122Smarcel xo_open_instance("ip6-interface-statistics"); 631279122Smarcel xo_emit("{ke:name/%s}", ifr.ifr_name); 63254263Sshin 633279122Smarcel p(ifs6_in_receive, "\t{:received-packets/%ju} " 634279122Smarcel "{N:/total input datagram%s}\n"); 635279122Smarcel p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} " 636279122Smarcel "{N:/datagram%s with invalid header received}\n"); 637279122Smarcel p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} " 638279122Smarcel "{N:/datagram%s exceeded MTU received}\n"); 639279122Smarcel p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} " 640279122Smarcel "{N:/datagram%s with no route received}\n"); 641279122Smarcel p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} " 642279122Smarcel "{N:/datagram%s with invalid dst received}\n"); 643279122Smarcel p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} " 644279122Smarcel "{N:/datagram%s with unknown proto received}\n"); 645279122Smarcel p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} " 646279122Smarcel "{N:/truncated datagram%s received}\n"); 647279122Smarcel p(ifs6_in_discard, "\t{:dropped-discarded/%ju} " 648279122Smarcel "{N:/input datagram%s discarded}\n"); 649279122Smarcel p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} " 650279122Smarcel "{N:/datagram%s delivered to an upper layer protocol}\n"); 651279122Smarcel p(ifs6_out_forward, "\t{:sent-forwarded/%ju} " 652279122Smarcel "{N:/datagram%s forwarded to this interface}\n"); 653279122Smarcel p(ifs6_out_request, "\t{:sent-packets/%ju} " 654279122Smarcel "{N:/datagram%s sent from an upper layer protocol}\n"); 655279122Smarcel p(ifs6_out_discard, "\t{:discard-packets/%ju} " 656279122Smarcel "{N:/total discarded output datagram%s}\n"); 657279122Smarcel p(ifs6_out_fragok, "\t{:discard-fragments/%ju} " 658279122Smarcel "{N:/output datagram%s fragmented}\n"); 659279122Smarcel p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} " 660279122Smarcel "{N:/output datagram%s failed on fragment}\n"); 661279122Smarcel p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} " 662279122Smarcel "{N:/output datagram%s succeeded on fragment}\n"); 663279122Smarcel p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} " 664279122Smarcel "{N:/incoming datagram%s fragmented}\n"); 665279122Smarcel p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} " 666279122Smarcel "{N:/datagram%s reassembled}\n"); 667279122Smarcel p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} " 668279122Smarcel "{N:/datagram%s failed on reassembly}\n"); 669279122Smarcel p(ifs6_in_mcast, "\t{:received-multicast/%ju} " 670279122Smarcel "{N:/multicast datagram%s received}\n"); 671279122Smarcel p(ifs6_out_mcast, "\t{:sent-multicast/%ju} " 672279122Smarcel "{N:/multicast datagram%s sent}\n"); 673279122Smarcel 674279122Smarcel end: 675279122Smarcel xo_close_instance("ip6-interface-statistics"); 676279122Smarcel close(s); 677279122Smarcel 67854263Sshin#undef p 67954263Sshin} 68054263Sshin 681102975Sdwmalonestatic const char *icmp6names[] = { 68254263Sshin "#0", 68354263Sshin "unreach", 68454263Sshin "packet too big", 68554263Sshin "time exceed", 68654263Sshin "parameter problem", 68754263Sshin "#5", 68854263Sshin "#6", 68954263Sshin "#7", 69054263Sshin "#8", 69154263Sshin "#9", 69254263Sshin "#10", 69354263Sshin "#11", 69454263Sshin "#12", 69554263Sshin "#13", 69654263Sshin "#14", 69754263Sshin "#15", 69854263Sshin "#16", 69954263Sshin "#17", 70054263Sshin "#18", 701175061Sobrien "#19", 70254263Sshin "#20", 70354263Sshin "#21", 70454263Sshin "#22", 70554263Sshin "#23", 70654263Sshin "#24", 70754263Sshin "#25", 70854263Sshin "#26", 70954263Sshin "#27", 71054263Sshin "#28", 711175061Sobrien "#29", 71254263Sshin "#30", 71354263Sshin "#31", 71454263Sshin "#32", 71554263Sshin "#33", 71654263Sshin "#34", 71754263Sshin "#35", 71854263Sshin "#36", 71954263Sshin "#37", 72054263Sshin "#38", 721175061Sobrien "#39", 72254263Sshin "#40", 72354263Sshin "#41", 72454263Sshin "#42", 72554263Sshin "#43", 72654263Sshin "#44", 72754263Sshin "#45", 72854263Sshin "#46", 72954263Sshin "#47", 73054263Sshin "#48", 731175061Sobrien "#49", 73254263Sshin "#50", 73354263Sshin "#51", 73454263Sshin "#52", 73554263Sshin "#53", 73654263Sshin "#54", 73754263Sshin "#55", 73854263Sshin "#56", 73954263Sshin "#57", 74054263Sshin "#58", 741175061Sobrien "#59", 74254263Sshin "#60", 74354263Sshin "#61", 74454263Sshin "#62", 74554263Sshin "#63", 74654263Sshin "#64", 74754263Sshin "#65", 74854263Sshin "#66", 74954263Sshin "#67", 75054263Sshin "#68", 751175061Sobrien "#69", 75254263Sshin "#70", 75354263Sshin "#71", 75454263Sshin "#72", 75554263Sshin "#73", 75654263Sshin "#74", 75754263Sshin "#75", 75854263Sshin "#76", 75954263Sshin "#77", 76054263Sshin "#78", 761175061Sobrien "#79", 76254263Sshin "#80", 76354263Sshin "#81", 76454263Sshin "#82", 76554263Sshin "#83", 76654263Sshin "#84", 76754263Sshin "#85", 76854263Sshin "#86", 76954263Sshin "#87", 77054263Sshin "#88", 771175061Sobrien "#89", 77254263Sshin "#80", 77354263Sshin "#91", 77454263Sshin "#92", 77554263Sshin "#93", 77654263Sshin "#94", 77754263Sshin "#95", 77854263Sshin "#96", 77954263Sshin "#97", 78054263Sshin "#98", 781175061Sobrien "#99", 78254263Sshin "#100", 78354263Sshin "#101", 78454263Sshin "#102", 78554263Sshin "#103", 78654263Sshin "#104", 78754263Sshin "#105", 78854263Sshin "#106", 78954263Sshin "#107", 79054263Sshin "#108", 791175061Sobrien "#109", 79254263Sshin "#110", 79354263Sshin "#111", 79454263Sshin "#112", 79554263Sshin "#113", 79654263Sshin "#114", 79754263Sshin "#115", 79854263Sshin "#116", 79954263Sshin "#117", 80054263Sshin "#118", 801175061Sobrien "#119", 80254263Sshin "#120", 80354263Sshin "#121", 80454263Sshin "#122", 80554263Sshin "#123", 80654263Sshin "#124", 80754263Sshin "#125", 80854263Sshin "#126", 80954263Sshin "#127", 81054263Sshin "echo", 811175061Sobrien "echo reply", 81254263Sshin "multicast listener query", 813191652Sbms "MLDv1 listener report", 814191652Sbms "MLDv1 listener done", 81554263Sshin "router solicitation", 81677565Sdd "router advertisement", 81754263Sshin "neighbor solicitation", 81877565Sdd "neighbor advertisement", 81954263Sshin "redirect", 82054263Sshin "router renumbering", 82154263Sshin "node information request", 82254263Sshin "node information reply", 82378540Ssumikawa "inverse neighbor solicitation", 82478540Ssumikawa "inverse neighbor advertisement", 825191652Sbms "MLDv2 listener report", 82654263Sshin "#144", 82754263Sshin "#145", 82854263Sshin "#146", 82954263Sshin "#147", 83054263Sshin "#148", 831175061Sobrien "#149", 83254263Sshin "#150", 83354263Sshin "#151", 83454263Sshin "#152", 83554263Sshin "#153", 83654263Sshin "#154", 83754263Sshin "#155", 83854263Sshin "#156", 83954263Sshin "#157", 84054263Sshin "#158", 841175061Sobrien "#159", 84254263Sshin "#160", 84354263Sshin "#161", 84454263Sshin "#162", 84554263Sshin "#163", 84654263Sshin "#164", 84754263Sshin "#165", 84854263Sshin "#166", 84954263Sshin "#167", 85054263Sshin "#168", 851175061Sobrien "#169", 85254263Sshin "#170", 85354263Sshin "#171", 85454263Sshin "#172", 85554263Sshin "#173", 85654263Sshin "#174", 85754263Sshin "#175", 85854263Sshin "#176", 85954263Sshin "#177", 86054263Sshin "#178", 861175061Sobrien "#179", 86254263Sshin "#180", 86354263Sshin "#181", 86454263Sshin "#182", 86554263Sshin "#183", 86654263Sshin "#184", 86754263Sshin "#185", 86854263Sshin "#186", 86954263Sshin "#187", 87054263Sshin "#188", 871175061Sobrien "#189", 87254263Sshin "#180", 87354263Sshin "#191", 87454263Sshin "#192", 87554263Sshin "#193", 87654263Sshin "#194", 87754263Sshin "#195", 87854263Sshin "#196", 87954263Sshin "#197", 88054263Sshin "#198", 881175061Sobrien "#199", 88254263Sshin "#200", 88354263Sshin "#201", 88454263Sshin "#202", 88554263Sshin "#203", 88654263Sshin "#204", 88754263Sshin "#205", 88854263Sshin "#206", 88954263Sshin "#207", 89054263Sshin "#208", 891175061Sobrien "#209", 89254263Sshin "#210", 89354263Sshin "#211", 89454263Sshin "#212", 89554263Sshin "#213", 89654263Sshin "#214", 89754263Sshin "#215", 89854263Sshin "#216", 89954263Sshin "#217", 90054263Sshin "#218", 901175061Sobrien "#219", 90254263Sshin "#220", 90354263Sshin "#221", 90454263Sshin "#222", 90554263Sshin "#223", 90654263Sshin "#224", 90754263Sshin "#225", 90854263Sshin "#226", 90954263Sshin "#227", 91054263Sshin "#228", 911175061Sobrien "#229", 91254263Sshin "#230", 91354263Sshin "#231", 91454263Sshin "#232", 91554263Sshin "#233", 91654263Sshin "#234", 91754263Sshin "#235", 91854263Sshin "#236", 91954263Sshin "#237", 92054263Sshin "#238", 921175061Sobrien "#239", 92254263Sshin "#240", 92354263Sshin "#241", 92454263Sshin "#242", 92554263Sshin "#243", 92654263Sshin "#244", 92754263Sshin "#245", 92854263Sshin "#246", 92954263Sshin "#247", 93054263Sshin "#248", 931175061Sobrien "#249", 93254263Sshin "#250", 93354263Sshin "#251", 93454263Sshin "#252", 93554263Sshin "#253", 93654263Sshin "#254", 93754263Sshin "#255", 93854263Sshin}; 93954263Sshin 94054263Sshin/* 94154263Sshin * Dump ICMP6 statistics. 94254263Sshin */ 94354263Sshinvoid 944171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 94554263Sshin{ 946287649Smarkj struct icmp6stat icmp6stat; 94795637Smarkm int i, first; 94854263Sshin 949287649Smarkj if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat, 950287649Smarkj sizeof(icmp6stat), kread_counters) != 0) 951287649Smarkj return; 95278931Sume 953279122Smarcel xo_emit("{T:/%s}:\n", name); 954279122Smarcel xo_open_container(name); 95554263Sshin 95654263Sshin#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 957279122Smarcel xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) 958187134Smaxim#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ 959279122Smarcel xo_emit(m, (uintmax_t)icmp6stat.f) 96054263Sshin 961279122Smarcel p(icp6s_error, "\t{:icmp6-calls/%ju} " 962279122Smarcel "{N:/call%s to icmp6_error}\n"); 963279122Smarcel p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} " 964279122Smarcel "{N:/error%s not generated in response to an icmp6 message}\n"); 965279122Smarcel p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} " 966279122Smarcel "{N:/error%s not generated because of rate limitation}\n"); 967175061Sobrien#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) 96878540Ssumikawa for (first = 1, i = 0; i < NELEM; i++) 96954263Sshin if (icmp6stat.icp6s_outhist[i] != 0) { 97054263Sshin if (first) { 971279122Smarcel xo_open_list("output-histogram"); 972279122Smarcel xo_emit("\t{T:Output histogram}:\n"); 97354263Sshin first = 0; 97454263Sshin } 975279122Smarcel xo_open_instance("output-histogram"); 976279122Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 977279122Smarcel icmp6names[i], 978160787Syar (uintmax_t)icmp6stat.icp6s_outhist[i]); 979279122Smarcel xo_close_instance("output-histogram"); 98054263Sshin } 981279122Smarcel if (!first) 982279122Smarcel xo_close_list("output-histogram"); 98378540Ssumikawa#undef NELEM 984279122Smarcel 985279122Smarcel p(icp6s_badcode, "\t{:dropped-bad-code/%ju} " 986279122Smarcel "{N:/message%s with bad code fields}\n"); 987279122Smarcel p(icp6s_tooshort, "\t{:dropped-too-short/%ju} " 988279122Smarcel "{N:/message%s < minimum length}\n"); 989279122Smarcel p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} " 990279122Smarcel "{N:/bad checksum%s}\n"); 991279122Smarcel p(icp6s_badlen, "\t{:dropped-bad-length/%ju} " 992279122Smarcel "{N:/message%s with bad length}\n"); 993175061Sobrien#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) 99478540Ssumikawa for (first = 1, i = 0; i < NELEM; i++) 99554263Sshin if (icmp6stat.icp6s_inhist[i] != 0) { 99654263Sshin if (first) { 997279122Smarcel xo_open_list("input-histogram"); 998279122Smarcel xo_emit("\t{T:Input histogram}:\n"); 99954263Sshin first = 0; 100054263Sshin } 1001279122Smarcel xo_open_instance("input-histogram"); 1002279122Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 1003279122Smarcel icmp6names[i], 1004160787Syar (uintmax_t)icmp6stat.icp6s_inhist[i]); 1005279122Smarcel xo_close_instance("input-histogram"); 100654263Sshin } 1007279122Smarcel if (!first) 1008279122Smarcel xo_close_list("input-histogram"); 100978540Ssumikawa#undef NELEM 1010279122Smarcel xo_emit("\t{T:Histogram of error messages to be generated}:\n"); 1011279122Smarcel xo_open_container("errors"); 1012279122Smarcel p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} " 1013279122Smarcel "{N:/no route}\n"); 1014279122Smarcel p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} " 1015279122Smarcel "{N:/administratively prohibited}\n"); 1016279122Smarcel p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} " 1017279122Smarcel "{N:/beyond scope}\n"); 1018279122Smarcel p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} " 1019279122Smarcel "{N:/address unreachable}\n"); 1020279122Smarcel p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} " 1021279122Smarcel "{N:/port unreachable}\n"); 1022279122Smarcel p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} " 1023279122Smarcel "{N:/packet too big}\n"); 1024279122Smarcel p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} " 1025279122Smarcel "{N:/time exceed transit}\n"); 1026279122Smarcel p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} " 1027279122Smarcel "{N:/time exceed reassembly}\n"); 1028279122Smarcel p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} " 1029279122Smarcel "{N:/erroneous header field}\n"); 1030279122Smarcel p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} " 1031279122Smarcel "{N:/unrecognized next header}\n"); 1032279122Smarcel p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} " 1033279122Smarcel "{N:/unrecognized option}\n"); 1034279122Smarcel p_5(icp6s_oredirect, "\t\t{:redirects/%ju} " 1035279122Smarcel "{N:/redirect}\n"); 1036279122Smarcel p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n"); 103762584Sitojun 1038279122Smarcel p(icp6s_reflect, "\t{:reflect/%ju} " 1039279122Smarcel "{N:/message response%s generated}\n"); 1040279122Smarcel p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} " 1041279122Smarcel "{N:/message%s with too many ND options}\n"); 1042279122Smarcel p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} " 1043279122Smarcel "{N:/message%s with bad ND options}\n"); 1044279122Smarcel p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} " 1045279122Smarcel "{N:/bad neighbor solicitation message%s}\n"); 1046279122Smarcel p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} " 1047279122Smarcel "{N:/bad neighbor advertisement message%s}\n"); 1048279122Smarcel p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} " 1049279122Smarcel "{N:/bad router solicitation message%s}\n"); 1050279122Smarcel p(icp6s_badra, "\t{:bad-router-advertisement/%ju} " 1051279122Smarcel "{N:/bad router advertisement message%s}\n"); 1052279122Smarcel p(icp6s_badredirect, "\t{:bad-redirect/%ju} " 1053279122Smarcel "{N:/bad redirect message%s}\n"); 1054279122Smarcel xo_close_container("errors"); 1055279122Smarcel p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n"); 105654263Sshin#undef p 105754263Sshin#undef p_5 1058279122Smarcel xo_close_container(name); 105954263Sshin} 106054263Sshin 106154263Sshin/* 106254263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466. 106354263Sshin */ 106454263Sshinvoid 106578314Sassaricmp6_ifstats(char *ifname) 106654263Sshin{ 106754263Sshin struct in6_ifreq ifr; 106854263Sshin int s; 106954263Sshin 1070279122Smarcel#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1071279122Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1072279122Smarcel plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 1073279122Smarcel#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1074279122Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1075279122Smarcel pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) 1076279122Smarcel 107754263Sshin if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 1078279122Smarcel xo_warn("Warning: socket(AF_INET6)"); 107954263Sshin return; 108054263Sshin } 108154263Sshin 1082317555Sasomers strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 108354263Sshin if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 1084270349Smarkj if (errno != EPFNOSUPPORT) 1085279122Smarcel xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 108654263Sshin goto end; 108754263Sshin } 108854263Sshin 1089279122Smarcel xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name); 109054263Sshin 1091279122Smarcel xo_open_instance("icmp6-interface-statistics"); 1092279122Smarcel xo_emit("{ke:name/%s}", ifr.ifr_name); 1093279122Smarcel p(ifs6_in_msg, "\t{:received-packets/%ju} " 1094279122Smarcel "{N:/total input message%s}\n"); 1095279122Smarcel p(ifs6_in_error, "\t{:received-errors/%ju} " 1096279122Smarcel "{N:/total input error message%s}\n"); 1097279122Smarcel p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} " 1098279122Smarcel "{N:/input destination unreachable error%s}\n"); 1099279122Smarcel p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} " 1100279122Smarcel "{N:/input administratively prohibited error%s}\n"); 1101279122Smarcel p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} " 1102279122Smarcel "{N:/input time exceeded error%s}\n"); 1103279122Smarcel p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} " 1104279122Smarcel "{N:/input parameter problem error%s}\n"); 1105279122Smarcel p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} " 1106279122Smarcel "{N:/input packet too big error%s}\n"); 1107279122Smarcel p(ifs6_in_echo, "\t{:received-echo-requests/%ju} " 1108279122Smarcel "{N:/input echo request%s}\n"); 1109279122Smarcel p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} " 1110279122Smarcel "{N:/input echo repl%s}\n"); 1111279122Smarcel p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} " 1112279122Smarcel "{N:/input router solicitation%s}\n"); 1113279122Smarcel p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} " 1114279122Smarcel "{N:/input router advertisement%s}\n"); 1115279122Smarcel p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} " 1116279122Smarcel "{N:/input neighbor solicitation%s}\n"); 1117279122Smarcel p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} " 1118279122Smarcel "{N:/input neighbor advertisement%s}\n"); 1119279122Smarcel p(ifs6_in_redirect, "\t{received-redirects/%ju} " 1120279122Smarcel "{N:/input redirect%s}\n"); 1121279122Smarcel p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} " 1122279122Smarcel "{N:/input MLD quer%s}\n"); 1123279122Smarcel p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} " 1124279122Smarcel "{N:/input MLD report%s}\n"); 1125279122Smarcel p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} " 1126279122Smarcel "{N:/input MLD done%s}\n"); 112754263Sshin 1128279122Smarcel p(ifs6_out_msg, "\t{:sent-packets/%ju} " 1129279122Smarcel "{N:/total output message%s}\n"); 1130279122Smarcel p(ifs6_out_error, "\t{:sent-errors/%ju} " 1131279122Smarcel "{N:/total output error message%s}\n"); 1132279122Smarcel p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} " 1133279122Smarcel "{N:/output destination unreachable error%s}\n"); 1134279122Smarcel p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} " 1135279122Smarcel "{N:/output administratively prohibited error%s}\n"); 1136279122Smarcel p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} " 1137279122Smarcel "{N:/output time exceeded error%s}\n"); 1138279122Smarcel p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} " 1139279122Smarcel "{N:/output parameter problem error%s}\n"); 1140279122Smarcel p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} " 1141279122Smarcel "{N:/output packet too big error%s}\n"); 1142279122Smarcel p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} " 1143279122Smarcel "{N:/output echo request%s}\n"); 1144279122Smarcel p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} " 1145279122Smarcel "{N:/output echo repl%s}\n"); 1146279122Smarcel p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} " 1147279122Smarcel "{N:/output router solicitation%s}\n"); 1148279122Smarcel p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} " 1149279122Smarcel "{N:/output router advertisement%s}\n"); 1150279122Smarcel p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} " 1151279122Smarcel "{N:/output neighbor solicitation%s}\n"); 1152279122Smarcel p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} " 1153279122Smarcel "{N:/output neighbor advertisement%s}\n"); 1154279122Smarcel p(ifs6_out_redirect, "\t{:sent-redirects/%ju} " 1155279122Smarcel "{N:/output redirect%s}\n"); 1156279122Smarcel p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} " 1157279122Smarcel "{N:/output MLD quer%s}\n"); 1158279122Smarcel p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} " 1159279122Smarcel "{N:/output MLD report%s}\n"); 1160279122Smarcel p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} " 1161279122Smarcel "{N:/output MLD done%s}\n"); 1162279122Smarcel 1163279122Smarcelend: 1164279122Smarcel xo_close_instance("icmp6-interface-statistics"); 116554263Sshin close(s); 116654263Sshin#undef p 116754263Sshin} 116854263Sshin 116954263Sshin/* 117054263Sshin * Dump PIM statistics structure. 117154263Sshin */ 117254263Sshinvoid 1173171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 117454263Sshin{ 1175287649Smarkj struct pim6stat pim6stat; 117654263Sshin 1177287649Smarkj if (fetch_stats("net.inet6.pim.stats", off, &pim6stat, 1178287649Smarkj sizeof(pim6stat), kread) != 0) 1179287649Smarkj return; 1180171465Sjhb 1181279122Smarcel xo_emit("{T:/%s}:\n", name); 1182279122Smarcel xo_open_container(name); 118354263Sshin 118454263Sshin#define p(f, m) if (pim6stat.f || sflag <= 1) \ 1185279122Smarcel xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) 1186279122Smarcel 1187279122Smarcel p(pim6s_rcv_total, "\t{:received-packets/%ju} " 1188279122Smarcel "{N:/message%s received}\n"); 1189279122Smarcel p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} " 1190279122Smarcel "{N:/message%s received with too few bytes}\n"); 1191279122Smarcel p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " 1192279122Smarcel "{N:/message%s received with bad checksum}\n"); 1193279122Smarcel p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} " 1194279122Smarcel "{N:/message%s received with bad version}\n"); 1195279122Smarcel p(pim6s_rcv_registers, "\t{:received-registers/%ju} " 1196279122Smarcel "{N:/register%s received}\n"); 1197279122Smarcel p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} " 1198279122Smarcel "{N:/bad register%s received}\n"); 1199279122Smarcel p(pim6s_snd_registers, "\t{:sent-registers/%ju} " 1200279122Smarcel "{N:/register%s sent}\n"); 120154263Sshin#undef p 1202279122Smarcel xo_close_container(name); 120354263Sshin} 120454263Sshin 120554263Sshin/* 120678064Sume * Dump raw ip6 statistics structure. 120778064Sume */ 120878064Sumevoid 1209171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 121078064Sume{ 1211287649Smarkj struct rip6stat rip6stat; 121278064Sume u_quad_t delivered; 121378064Sume 1214287649Smarkj if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat, 1215287649Smarkj sizeof(rip6stat), kread_counters) != 0) 1216287649Smarkj return; 121778064Sume 1218279122Smarcel xo_emit("{T:/%s}:\n", name); 1219279122Smarcel xo_open_container(name); 122078064Sume 122178064Sume#define p(f, m) if (rip6stat.f || sflag <= 1) \ 1222279122Smarcel xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) 1223279122Smarcel 1224279122Smarcel p(rip6s_ipackets, "\t{:received-packets/%ju} " 1225279122Smarcel "{N:/message%s received}\n"); 1226279122Smarcel p(rip6s_isum, "\t{:input-checksum-computation/%ju} " 1227279122Smarcel "{N:/checksum calculation%s on inbound}\n"); 1228279122Smarcel p(rip6s_badsum, "\t{:received-bad-checksum/%ju} " 1229279122Smarcel "{N:/message%s with bad checksum}\n"); 1230279122Smarcel p(rip6s_nosock, "\t{:dropped-no-socket/%ju} " 1231279122Smarcel "{N:/message%s dropped due to no socket}\n"); 1232279122Smarcel p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} " 1233279122Smarcel "{N:/multicast message%s dropped due to no socket}\n"); 1234279122Smarcel p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} " 1235279122Smarcel "{N:/message%s dropped due to full socket buffers}\n"); 123678064Sume delivered = rip6stat.rip6s_ipackets - 123778064Sume rip6stat.rip6s_badsum - 123878064Sume rip6stat.rip6s_nosock - 123978064Sume rip6stat.rip6s_nosockmcast - 124078064Sume rip6stat.rip6s_fullsock; 124178064Sume if (delivered || sflag <= 1) 1242279122Smarcel xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n", 1243279122Smarcel (uintmax_t)delivered); 1244279122Smarcel p(rip6s_opackets, "\t{:sent-packets/%ju} " 1245279122Smarcel "{N:/datagram%s output}\n"); 124678064Sume#undef p 1247279122Smarcel xo_close_container(name); 124878064Sume} 124978064Sume 125078064Sume/* 125154263Sshin * Pretty print an Internet address (net address + port). 125278238Sassar * Take numeric_addr and numeric_port into consideration. 125354263Sshin */ 1254175061Sobrien#define GETSERVBYPORT6(port, proto, ret)\ 125554263Sshin{\ 125654263Sshin if (strcmp((proto), "tcp6") == 0)\ 125754263Sshin (ret) = getservbyport((int)(port), "tcp");\ 125854263Sshin else if (strcmp((proto), "udp6") == 0)\ 125954263Sshin (ret) = getservbyport((int)(port), "udp");\ 126054263Sshin else\ 126154263Sshin (ret) = getservbyport((int)(port), (proto));\ 126254263Sshin}; 126354263Sshin 126454263Sshinvoid 1265279122Smarcelinet6print(const char *container, struct in6_addr *in6, int port, 1266279122Smarcel const char *proto, int numeric) 126754263Sshin{ 126854263Sshin struct servent *sp = 0; 126954263Sshin char line[80], *cp; 127054263Sshin int width; 1271311670Sdelphij size_t alen, plen; 127254263Sshin 1273279122Smarcel if (container) 1274279122Smarcel xo_open_container(container); 1275279122Smarcel 1276311670Sdelphij snprintf(line, sizeof(line), "%.*s.", 1277311670Sdelphij Wflag ? 39 : (Aflag && !numeric) ? 12 : 16, 1278279122Smarcel inet6name(in6)); 1279311670Sdelphij alen = strlen(line); 1280311670Sdelphij cp = line + alen; 128154263Sshin if (!numeric && port) 128254263Sshin GETSERVBYPORT6(port, proto, sp); 128354263Sshin if (sp || port == 0) 1284311670Sdelphij snprintf(cp, sizeof(line) - alen, 1285311670Sdelphij "%.15s", sp ? sp->s_name : "*"); 128654263Sshin else 1287311670Sdelphij snprintf(cp, sizeof(line) - alen, 1288311670Sdelphij "%d", ntohs((u_short)port)); 128983200Sru width = Wflag ? 45 : Aflag ? 18 : 22; 1290279122Smarcel 1291279122Smarcel xo_emit("{d:target/%-*.*s} ", width, width, line); 1292279122Smarcel 1293311674Sume plen = strlen(cp); 1294311670Sdelphij alen--; 1295279122Smarcel xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, 1296279122Smarcel plen, cp); 1297279122Smarcel 1298279122Smarcel if (container) 1299279122Smarcel xo_close_container(container); 130054263Sshin} 130154263Sshin 130254263Sshin/* 130354263Sshin * Construct an Internet address representation. 130478238Sassar * If the numeric_addr has been supplied, give 130554263Sshin * numeric value, otherwise try for symbolic name. 130654263Sshin */ 130754263Sshin 130854263Sshinchar * 1309355869Sbzinet6name(struct in6_addr *ia6) 131054263Sshin{ 1311254459Shrs struct sockaddr_in6 sin6; 1312254459Shrs char hbuf[NI_MAXHOST], *cp; 1313311670Sdelphij static char line[NI_MAXHOST]; 131474262Sbrian static char domain[MAXHOSTNAMELEN]; 131554263Sshin static int first = 1; 1316254459Shrs int flags, error; 131754263Sshin 1318355869Sbz if (IN6_IS_ADDR_UNSPECIFIED(ia6)) { 1319254459Shrs strcpy(line, "*"); 1320254459Shrs return (line); 1321254459Shrs } 132278238Sassar if (first && !numeric_addr) { 132354263Sshin first = 0; 1324311670Sdelphij if (gethostname(domain, sizeof(domain)) == 0 && 1325229403Sed (cp = strchr(domain, '.'))) 1326311670Sdelphij strlcpy(domain, cp + 1, sizeof(domain)); 132754263Sshin else 132854263Sshin domain[0] = 0; 132954263Sshin } 1330254459Shrs memset(&sin6, 0, sizeof(sin6)); 1331355869Sbz memcpy(&sin6.sin6_addr, ia6, sizeof(*ia6)); 1332254459Shrs sin6.sin6_family = AF_INET6; 1333355869Sbz /* XXX: ia6.s6_addr[2] can contain scopeid. */ 1334254459Shrs in6_fillscopeid(&sin6); 1335254459Shrs flags = (numeric_addr) ? NI_NUMERICHOST : 0; 1336254459Shrs error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, 1337254459Shrs sizeof(hbuf), NULL, 0, flags); 1338254459Shrs if (error == 0) { 1339254459Shrs if ((flags & NI_NUMERICHOST) == 0 && 1340254459Shrs (cp = strchr(hbuf, '.')) && 1341254459Shrs !strcmp(cp + 1, domain)) 1342254459Shrs *cp = 0; 1343311670Sdelphij strlcpy(line, hbuf, sizeof(line)); 1344254459Shrs } else { 1345254459Shrs /* XXX: this should not happen. */ 1346311670Sdelphij snprintf(line, sizeof(line), "%s", 1347254459Shrs inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, 134854263Sshin sizeof(ntop_buf))); 1349254459Shrs } 135054263Sshin return (line); 135154263Sshin} 135264342Sume#endif /*INET6*/ 1353