inet6.c revision 279122
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: head/usr.bin/netstat/inet6.c 279122 2015-02-21 23:47:20Z marcel $"); 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> 4778064Sume#include <sys/sysctl.h> 4854263Sshin 4954263Sshin#include <net/route.h> 5054263Sshin#include <net/if.h> 5154263Sshin#include <net/if_var.h> 5254263Sshin#include <netinet/in.h> 5354263Sshin#include <netinet/ip6.h> 5454263Sshin#include <netinet/icmp6.h> 5554263Sshin#include <netinet/in_systm.h> 5654263Sshin#include <netinet6/in6_pcb.h> 5754263Sshin#include <netinet6/in6_var.h> 5854263Sshin#include <netinet6/ip6_var.h> 5954263Sshin#include <netinet6/pim6_var.h> 6078064Sume#include <netinet6/raw_ip6.h> 6154263Sshin 6254263Sshin#include <arpa/inet.h> 6354263Sshin#include <netdb.h> 6454263Sshin 65166952Sbms#include <err.h> 66160787Syar#include <stdint.h> 6754263Sshin#include <stdio.h> 68279122Smarcel#include <stdbool.h> 69160373Sjulian#include <errno.h> 7054263Sshin#include <string.h> 7154263Sshin#include <unistd.h> 72279122Smarcel#include <libxo/xo.h> 7354263Sshin#include "netstat.h" 7454263Sshin 7554263Sshinstruct socket sockb; 7654263Sshin 77132671Scharnierchar *inet6name(struct in6_addr *); 7854263Sshin 7954263Sshinstatic char ntop_buf[INET6_ADDRSTRLEN]; 8054263Sshin 81102975Sdwmalonestatic const char *ip6nh[] = { 8254263Sshin "hop by hop", 8354263Sshin "ICMP", 8454263Sshin "IGMP", 8554263Sshin "#3", 8654263Sshin "IP", 8754263Sshin "#5", 8854263Sshin "TCP", 8954263Sshin "#7", 9054263Sshin "#8", 9154263Sshin "#9", 9254263Sshin "#10", 9354263Sshin "#11", 9454263Sshin "#12", 9554263Sshin "#13", 9654263Sshin "#14", 9754263Sshin "#15", 9854263Sshin "#16", 9954263Sshin "UDP", 10054263Sshin "#18", 101175061Sobrien "#19", 10254263Sshin "#20", 10354263Sshin "#21", 10454263Sshin "IDP", 10554263Sshin "#23", 10654263Sshin "#24", 10754263Sshin "#25", 10854263Sshin "#26", 10954263Sshin "#27", 11054263Sshin "#28", 111175061Sobrien "TP", 11254263Sshin "#30", 11354263Sshin "#31", 11454263Sshin "#32", 11554263Sshin "#33", 11654263Sshin "#34", 11754263Sshin "#35", 11854263Sshin "#36", 11954263Sshin "#37", 12054263Sshin "#38", 121175061Sobrien "#39", 12254263Sshin "#40", 12354263Sshin "IP6", 12454263Sshin "#42", 12554263Sshin "routing", 12654263Sshin "fragment", 12754263Sshin "#45", 12854263Sshin "#46", 12954263Sshin "#47", 13054263Sshin "#48", 131175061Sobrien "#49", 13254263Sshin "ESP", 13354263Sshin "AH", 13454263Sshin "#52", 13554263Sshin "#53", 13654263Sshin "#54", 13754263Sshin "#55", 13854263Sshin "#56", 13954263Sshin "#57", 14054263Sshin "ICMP6", 141175061Sobrien "no next header", 14254263Sshin "destination option", 14354263Sshin "#61", 144125482Sume "mobility", 14554263Sshin "#63", 14654263Sshin "#64", 14754263Sshin "#65", 14854263Sshin "#66", 14954263Sshin "#67", 15054263Sshin "#68", 151175061Sobrien "#69", 15254263Sshin "#70", 15354263Sshin "#71", 15454263Sshin "#72", 15554263Sshin "#73", 15654263Sshin "#74", 15754263Sshin "#75", 15854263Sshin "#76", 15954263Sshin "#77", 16054263Sshin "#78", 161175061Sobrien "#79", 16254263Sshin "ISOIP", 16354263Sshin "#81", 16454263Sshin "#82", 16554263Sshin "#83", 16654263Sshin "#84", 16754263Sshin "#85", 16854263Sshin "#86", 16954263Sshin "#87", 17054263Sshin "#88", 171175061Sobrien "OSPF", 17254263Sshin "#80", 17354263Sshin "#91", 17454263Sshin "#92", 17554263Sshin "#93", 17654263Sshin "#94", 17754263Sshin "#95", 17854263Sshin "#96", 17954263Sshin "Ethernet", 18054263Sshin "#98", 181175061Sobrien "#99", 18254263Sshin "#100", 18354263Sshin "#101", 18454263Sshin "#102", 18554263Sshin "PIM", 18654263Sshin "#104", 18754263Sshin "#105", 18854263Sshin "#106", 18954263Sshin "#107", 19054263Sshin "#108", 191175061Sobrien "#109", 19254263Sshin "#110", 19354263Sshin "#111", 19454263Sshin "#112", 19554263Sshin "#113", 19654263Sshin "#114", 19754263Sshin "#115", 19854263Sshin "#116", 19954263Sshin "#117", 20054263Sshin "#118", 201175061Sobrien "#119", 20254263Sshin "#120", 20354263Sshin "#121", 20454263Sshin "#122", 20554263Sshin "#123", 20654263Sshin "#124", 20754263Sshin "#125", 20854263Sshin "#126", 20954263Sshin "#127", 21054263Sshin "#128", 211175061Sobrien "#129", 21254263Sshin "#130", 21354263Sshin "#131", 21454263Sshin "#132", 21554263Sshin "#133", 21654263Sshin "#134", 21754263Sshin "#135", 21854263Sshin "#136", 21954263Sshin "#137", 22054263Sshin "#138", 221175061Sobrien "#139", 22254263Sshin "#140", 22354263Sshin "#141", 22454263Sshin "#142", 22554263Sshin "#143", 22654263Sshin "#144", 22754263Sshin "#145", 22854263Sshin "#146", 22954263Sshin "#147", 23054263Sshin "#148", 231175061Sobrien "#149", 23254263Sshin "#150", 23354263Sshin "#151", 23454263Sshin "#152", 23554263Sshin "#153", 23654263Sshin "#154", 23754263Sshin "#155", 23854263Sshin "#156", 23954263Sshin "#157", 24054263Sshin "#158", 241175061Sobrien "#159", 24254263Sshin "#160", 24354263Sshin "#161", 24454263Sshin "#162", 24554263Sshin "#163", 24654263Sshin "#164", 24754263Sshin "#165", 24854263Sshin "#166", 24954263Sshin "#167", 25054263Sshin "#168", 251175061Sobrien "#169", 25254263Sshin "#170", 25354263Sshin "#171", 25454263Sshin "#172", 25554263Sshin "#173", 25654263Sshin "#174", 25754263Sshin "#175", 25854263Sshin "#176", 25954263Sshin "#177", 26054263Sshin "#178", 261175061Sobrien "#179", 26254263Sshin "#180", 26354263Sshin "#181", 26454263Sshin "#182", 26554263Sshin "#183", 26654263Sshin "#184", 26754263Sshin "#185", 26854263Sshin "#186", 26954263Sshin "#187", 27054263Sshin "#188", 271175061Sobrien "#189", 27254263Sshin "#180", 27354263Sshin "#191", 27454263Sshin "#192", 27554263Sshin "#193", 27654263Sshin "#194", 27754263Sshin "#195", 27854263Sshin "#196", 27954263Sshin "#197", 28054263Sshin "#198", 281175061Sobrien "#199", 28254263Sshin "#200", 28354263Sshin "#201", 28454263Sshin "#202", 28554263Sshin "#203", 28654263Sshin "#204", 28754263Sshin "#205", 28854263Sshin "#206", 28954263Sshin "#207", 29054263Sshin "#208", 291175061Sobrien "#209", 29254263Sshin "#210", 29354263Sshin "#211", 29454263Sshin "#212", 29554263Sshin "#213", 29654263Sshin "#214", 29754263Sshin "#215", 29854263Sshin "#216", 29954263Sshin "#217", 30054263Sshin "#218", 301175061Sobrien "#219", 30254263Sshin "#220", 30354263Sshin "#221", 30454263Sshin "#222", 30554263Sshin "#223", 30654263Sshin "#224", 30754263Sshin "#225", 30854263Sshin "#226", 30954263Sshin "#227", 31054263Sshin "#228", 311175061Sobrien "#229", 31254263Sshin "#230", 31354263Sshin "#231", 31454263Sshin "#232", 31554263Sshin "#233", 31654263Sshin "#234", 31754263Sshin "#235", 31854263Sshin "#236", 31954263Sshin "#237", 32054263Sshin "#238", 321175061Sobrien "#239", 32254263Sshin "#240", 32354263Sshin "#241", 32454263Sshin "#242", 32554263Sshin "#243", 32654263Sshin "#244", 32754263Sshin "#245", 32854263Sshin "#246", 32954263Sshin "#247", 33054263Sshin "#248", 331175061Sobrien "#249", 33254263Sshin "#250", 33354263Sshin "#251", 33454263Sshin "#252", 33554263Sshin "#253", 33654263Sshin "#254", 33754263Sshin "#255", 33854263Sshin}; 33954263Sshin 340246988Scharnierstatic const char *srcrule_str[] = { 341125483Sume "first candidate", 342125483Sume "same address", 343125483Sume "appropriate scope", 344125483Sume "deprecated address", 345125483Sume "home address", 346125483Sume "outgoing interface", 347125483Sume "matching label", 348125483Sume "public/temporary address", 349125483Sume "alive interface", 350270927Sae "better virtual status", 351271307Sae "preferred source", 352125483Sume "rule #11", 353125483Sume "rule #12", 354125483Sume "rule #13", 355125483Sume "longest match", 356125483Sume "rule #15", 357125483Sume}; 358125483Sume 35954263Sshin/* 36054263Sshin * Dump IP6 statistics structure. 36154263Sshin */ 36254263Sshinvoid 363171465Sjhbip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 36454263Sshin{ 365228700Smaxim struct ip6stat ip6stat, zerostat; 36654263Sshin int first, i; 36778931Sume size_t len; 36854263Sshin 369171465Sjhb len = sizeof ip6stat; 370171465Sjhb if (live) { 371171465Sjhb memset(&ip6stat, 0, len); 372228700Smaxim if (zflag) 373228700Smaxim memset(&zerostat, 0, len); 374228700Smaxim if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len, 375228700Smaxim zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 376171465Sjhb if (errno != ENOENT) 377279122Smarcel xo_warn("sysctl: net.inet6.ip6.stats"); 378171465Sjhb return; 379171465Sjhb } 380171465Sjhb } else 381253085Sae kread_counters(off, &ip6stat, len); 382279122Smarcel xo_open_container(name); 383279122Smarcel xo_emit("{T:/%s}:\n", name); 38454263Sshin 38554263Sshin#define p(f, m) if (ip6stat.f || sflag <= 1) \ 386279122Smarcel xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) 38754263Sshin#define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 388279122Smarcel xo_emit(m, (uintmax_t)ip6stat.f) 38954263Sshin 390279122Smarcel p(ip6s_total, "\t{:received-packets/%ju} " 391279122Smarcel "{N:/total packet%s received}\n"); 392279122Smarcel p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} " 393279122Smarcel "{N:/with size smaller than minimum}\n"); 394279122Smarcel p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} " 395279122Smarcel "{N:/with data size < data length}\n"); 396279122Smarcel p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} " 397279122Smarcel "{N:/with bad options}\n"); 398279122Smarcel p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} " 399279122Smarcel "{N:/with incorrect version number}\n"); 400279122Smarcel p(ip6s_fragments, "\t{:received-fragments/%ju} " 401279122Smarcel "{N:/fragment%s received}\n"); 402279122Smarcel p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} " 403279122Smarcel "{N:/fragment%s dropped (dup or out of space)}\n"); 404279122Smarcel p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} " 405279122Smarcel "{N:/fragment%s dropped after timeout}\n"); 406279122Smarcel p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} " 407279122Smarcel "{N:/fragment%s that exceeded limit}\n"); 408279122Smarcel p(ip6s_reassembled, "\t{:reassembled-packets/%ju} " 409279122Smarcel "{N:/packet%s reassembled ok}\n"); 410279122Smarcel p(ip6s_delivered, "\t{:received-local-packets/%ju} " 411279122Smarcel "{N:/packet%s for this host}\n"); 412279122Smarcel p(ip6s_forward, "\t{:forwarded-packets/%ju} " 413279122Smarcel "{N:/packet%s forwarded}\n"); 414279122Smarcel p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} " 415279122Smarcel "{N:/packet%s not forwardable}\n"); 416279122Smarcel p(ip6s_redirectsent, "\t{:sent-redirects/%ju} " 417279122Smarcel "{N:/redirect%s sent}\n"); 418279122Smarcel p(ip6s_localout, "\t{:sent-packets/%ju} " 419279122Smarcel "{N:/packet%s sent from this host}\n"); 420279122Smarcel p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} " 421279122Smarcel "{N:/packet%s sent with fabricated ip header}\n"); 422279122Smarcel p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} " 423279122Smarcel "{N:/output packet%s dropped due to no bufs, etc.}\n"); 424279122Smarcel p(ip6s_noroute, "\t{:discard-no-route/%ju} " 425279122Smarcel "{N:/output packet%s discarded due to no route}\n"); 426279122Smarcel p(ip6s_fragmented, "\t{:sent-fragments/%ju} " 427279122Smarcel "{N:/output datagram%s fragmented}\n"); 428279122Smarcel p(ip6s_ofragments, "\t{:fragments-created/%ju} " 429279122Smarcel "{N:/fragment%s created}\n"); 430279122Smarcel p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} " 431279122Smarcel "{N:/datagram%s that can't be fragmented}\n"); 432279122Smarcel p(ip6s_badscope, "\t{:discard-scope-violations/%ju} " 433279122Smarcel "{N:/packet%s that violated scope rules}\n"); 434279122Smarcel p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} " 435279122Smarcel "{N:/multicast packet%s which we don't join}\n"); 436249545Sae for (first = 1, i = 0; i < IP6S_HDRCNT; i++) 43754263Sshin if (ip6stat.ip6s_nxthist[i] != 0) { 43854263Sshin if (first) { 439279122Smarcel xo_emit("\t{T:Input histogram}:\n"); 440279122Smarcel xo_open_list("input-histogram"); 44154263Sshin first = 0; 44254263Sshin } 443279122Smarcel xo_open_instance("input-histogram"); 444279122Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i], 445160787Syar (uintmax_t)ip6stat.ip6s_nxthist[i]); 446279122Smarcel xo_close_instance("input-histogram"); 44754263Sshin } 448279122Smarcel if (!first) 449279122Smarcel xo_close_list("input-histogram"); 450279122Smarcel 451279122Smarcel xo_open_container("mbuf-statistics"); 452279122Smarcel xo_emit("\t{T:Mbuf statistics}:\n"); 453279122Smarcel xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n", 454279122Smarcel (uintmax_t)ip6stat.ip6s_m1); 455249545Sae for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { 45655163Sshin char ifbuf[IFNAMSIZ]; 457175061Sobrien if (ip6stat.ip6s_m2m[i] != 0) { 45854263Sshin if (first) { 459279122Smarcel xo_emit("\t\t{N:two or more mbuf}:\n"); 460279122Smarcel xo_open_list("mbuf-data"); 46154263Sshin first = 0; 46254263Sshin } 463279122Smarcel xo_open_instance("mbuf-data"); 464279122Smarcel xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n", 46562584Sitojun if_indextoname(i, ifbuf), 466160787Syar (uintmax_t)ip6stat.ip6s_m2m[i]); 467279122Smarcel xo_close_instance("mbuf-data"); 46854263Sshin } 46954263Sshin } 470279122Smarcel if (!first) 471279122Smarcel xo_close_list("mbuf-data"); 472279122Smarcel xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n", 473160787Syar (uintmax_t)ip6stat.ip6s_mext1); 474279122Smarcel xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} " 475279122Smarcel "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m); 476279122Smarcel xo_close_container("mbuf-statistics"); 47762584Sitojun 478279122Smarcel p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} " 479279122Smarcel "{N:/packet%s whose headers are not contiguous}\n"); 480279122Smarcel p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} " 481279122Smarcel "{N:/tunneling packet%s that can't find gif}\n"); 482279122Smarcel p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} " 483279122Smarcel "{N:/packet%s discarded because of too many headers}\n"); 484279122Smarcel 48562584Sitojun /* for debugging source address selection */ 486175061Sobrien#define PRINT_SCOPESTAT(s,i) do {\ 48762584Sitojun switch(i) { /* XXX hardcoding in each case */\ 48862584Sitojun case 1:\ 489279122Smarcel p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \ 490279122Smarcel "{N:/interface-local%s}\n"); \ 49162584Sitojun break;\ 49262584Sitojun case 2:\ 493279122Smarcel p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \ 494279122Smarcel "{N:/link-local%s}\n"); \ 49562584Sitojun break;\ 49662584Sitojun case 5:\ 497279122Smarcel p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \ 498279122Smarcel "{N:/site-local%s}\n");\ 49962584Sitojun break;\ 50062584Sitojun case 14:\ 501279122Smarcel p(s,"\t\t{ke:name/globals}{:count/%ju} " \ 502279122Smarcel "{N:/global%s}\n");\ 50362584Sitojun break;\ 50462584Sitojun default:\ 505279122Smarcel xo_emit("\t\t{qke:name/%x}{:count/%ju} " \ 506279122Smarcel "addresses scope=%x\n",\ 507279122Smarcel i, (uintmax_t)ip6stat.s, i); \ 50862584Sitojun }\ 50962584Sitojun } while (0); 51062584Sitojun 511279122Smarcel xo_open_container("source-address-selection"); 512279122Smarcel p(ip6s_sources_none, "\t{:address-selection-failures/%ju} " 513279122Smarcel "{N:/failure%s of source address selection}\n"); 514279122Smarcel 515249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 51662584Sitojun if (ip6stat.ip6s_sources_sameif[i]) { 51762584Sitojun if (first) { 518279122Smarcel xo_open_list("outgoing-interface"); 519279122Smarcel xo_emit("\tsource addresses on an outgoing " 520279122Smarcel "I/F\n"); 52162584Sitojun first = 0; 52262584Sitojun } 523279122Smarcel xo_open_instance("outgoing-interface"); 52462584Sitojun PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); 525279122Smarcel xo_close_instance("outgoing-interface"); 52662584Sitojun } 52762584Sitojun } 528279122Smarcel if (!first) 529279122Smarcel xo_close_list("outgoing-interface"); 530279122Smarcel 531249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 53262584Sitojun if (ip6stat.ip6s_sources_otherif[i]) { 53362584Sitojun if (first) { 534279122Smarcel xo_open_list("non-outgoing-interface"); 535279122Smarcel xo_emit("\tsource addresses on a non-outgoing " 536279122Smarcel "I/F\n"); 53762584Sitojun first = 0; 53862584Sitojun } 539279122Smarcel xo_open_instance("non-outgoing-interface"); 54062584Sitojun PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); 541279122Smarcel xo_close_instance("non-outgoing-interface"); 54262584Sitojun } 54362584Sitojun } 544279122Smarcel if (!first) 545279122Smarcel xo_close_list("non-outgoing-interface"); 546279122Smarcel 547249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 54862584Sitojun if (ip6stat.ip6s_sources_samescope[i]) { 54962584Sitojun if (first) { 550279122Smarcel xo_open_list("same-source"); 551279122Smarcel xo_emit("\tsource addresses of same scope\n"); 55262584Sitojun first = 0; 55362584Sitojun } 554279122Smarcel xo_open_instance("same-source"); 55562584Sitojun PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); 556279122Smarcel xo_close_instance("same-source"); 55762584Sitojun } 55862584Sitojun } 559279122Smarcel if (!first) 560279122Smarcel xo_close_list("same-source"); 561279122Smarcel 562249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 56362584Sitojun if (ip6stat.ip6s_sources_otherscope[i]) { 56462584Sitojun if (first) { 565279122Smarcel xo_open_list("different-scope"); 566279122Smarcel xo_emit("\tsource addresses of a different " 567279122Smarcel "scope\n"); 56862584Sitojun first = 0; 56962584Sitojun } 570279122Smarcel xo_open_instance("different-scope"); 57162584Sitojun PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); 572279122Smarcel xo_close_instance("different-scope"); 57362584Sitojun } 57462584Sitojun } 575279122Smarcel if (!first) 576279122Smarcel xo_close_list("different-scope"); 577279122Smarcel 578249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 57962584Sitojun if (ip6stat.ip6s_sources_deprecated[i]) { 58062584Sitojun if (first) { 581279122Smarcel xo_open_list("deprecated-source"); 582279122Smarcel xo_emit("\tdeprecated source addresses\n"); 58362584Sitojun first = 0; 58462584Sitojun } 585279122Smarcel xo_open_instance("deprecated-source"); 58662584Sitojun PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); 587279122Smarcel xo_close_instance("deprecated-source"); 58862584Sitojun } 58962584Sitojun } 590279122Smarcel if (!first) 591279122Smarcel xo_close_list("deprecated-source"); 59262584Sitojun 593279122Smarcel for (first = 1, i = 0; i < IP6S_RULESMAX; i++) { 594279122Smarcel if (ip6stat.ip6s_sources_rule[i]) { 595279122Smarcel if (first) { 596279122Smarcel xo_open_list("rules-applied"); 597279122Smarcel xo_emit("\t{T:Source addresses selection " 598279122Smarcel "rule applied}:\n"); 599279122Smarcel first = 0; 600279122Smarcel } 601279122Smarcel xo_open_instance("rules-applied"); 602279122Smarcel xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n", 603279122Smarcel srcrule_str[i], 604279122Smarcel (uintmax_t)ip6stat.ip6s_sources_rule[i], 605279122Smarcel srcrule_str[i]); 606279122Smarcel xo_close_instance("rules-applied"); 607279122Smarcel } 608125483Sume } 609279122Smarcel if (!first) 610279122Smarcel xo_close_list("rules-applied"); 611279122Smarcel 612279122Smarcel xo_close_container("source-address-selection"); 613279122Smarcel 61454263Sshin#undef p 61562584Sitojun#undef p1a 616279122Smarcel xo_close_container(name); 61754263Sshin} 61854263Sshin 61954263Sshin/* 62054263Sshin * Dump IPv6 per-interface statistics based on RFC 2465. 62154263Sshin */ 62254263Sshinvoid 62378314Sassarip6_ifstats(char *ifname) 62454263Sshin{ 62554263Sshin struct in6_ifreq ifr; 62654263Sshin int s; 62754263Sshin 628279122Smarcel#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 629279122Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, \ 630279122Smarcel plural(ifr.ifr_ifru.ifru_stat.f)) 631279122Smarcel 63254263Sshin if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 633279122Smarcel xo_warn("Warning: socket(AF_INET6)"); 63454263Sshin return; 63554263Sshin } 63654263Sshin 63754263Sshin strcpy(ifr.ifr_name, ifname); 63854263Sshin if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 639270349Smarkj if (errno != EPFNOSUPPORT) 640279122Smarcel xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)"); 64154263Sshin goto end; 64254263Sshin } 64354263Sshin 644279122Smarcel xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name); 64554263Sshin 646279122Smarcel xo_open_instance("ip6-interface-statistics"); 647279122Smarcel xo_emit("{ke:name/%s}", ifr.ifr_name); 64854263Sshin 649279122Smarcel p(ifs6_in_receive, "\t{:received-packets/%ju} " 650279122Smarcel "{N:/total input datagram%s}\n"); 651279122Smarcel p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} " 652279122Smarcel "{N:/datagram%s with invalid header received}\n"); 653279122Smarcel p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} " 654279122Smarcel "{N:/datagram%s exceeded MTU received}\n"); 655279122Smarcel p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} " 656279122Smarcel "{N:/datagram%s with no route received}\n"); 657279122Smarcel p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} " 658279122Smarcel "{N:/datagram%s with invalid dst received}\n"); 659279122Smarcel p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} " 660279122Smarcel "{N:/datagram%s with unknown proto received}\n"); 661279122Smarcel p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} " 662279122Smarcel "{N:/truncated datagram%s received}\n"); 663279122Smarcel p(ifs6_in_discard, "\t{:dropped-discarded/%ju} " 664279122Smarcel "{N:/input datagram%s discarded}\n"); 665279122Smarcel p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} " 666279122Smarcel "{N:/datagram%s delivered to an upper layer protocol}\n"); 667279122Smarcel p(ifs6_out_forward, "\t{:sent-forwarded/%ju} " 668279122Smarcel "{N:/datagram%s forwarded to this interface}\n"); 669279122Smarcel p(ifs6_out_request, "\t{:sent-packets/%ju} " 670279122Smarcel "{N:/datagram%s sent from an upper layer protocol}\n"); 671279122Smarcel p(ifs6_out_discard, "\t{:discard-packets/%ju} " 672279122Smarcel "{N:/total discarded output datagram%s}\n"); 673279122Smarcel p(ifs6_out_fragok, "\t{:discard-fragments/%ju} " 674279122Smarcel "{N:/output datagram%s fragmented}\n"); 675279122Smarcel p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} " 676279122Smarcel "{N:/output datagram%s failed on fragment}\n"); 677279122Smarcel p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} " 678279122Smarcel "{N:/output datagram%s succeeded on fragment}\n"); 679279122Smarcel p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} " 680279122Smarcel "{N:/incoming datagram%s fragmented}\n"); 681279122Smarcel p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} " 682279122Smarcel "{N:/datagram%s reassembled}\n"); 683279122Smarcel p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} " 684279122Smarcel "{N:/datagram%s failed on reassembly}\n"); 685279122Smarcel p(ifs6_in_mcast, "\t{:received-multicast/%ju} " 686279122Smarcel "{N:/multicast datagram%s received}\n"); 687279122Smarcel p(ifs6_out_mcast, "\t{:sent-multicast/%ju} " 688279122Smarcel "{N:/multicast datagram%s sent}\n"); 689279122Smarcel 690279122Smarcel end: 691279122Smarcel xo_close_instance("ip6-interface-statistics"); 692279122Smarcel close(s); 693279122Smarcel 69454263Sshin#undef p 69554263Sshin} 69654263Sshin 697102975Sdwmalonestatic const char *icmp6names[] = { 69854263Sshin "#0", 69954263Sshin "unreach", 70054263Sshin "packet too big", 70154263Sshin "time exceed", 70254263Sshin "parameter problem", 70354263Sshin "#5", 70454263Sshin "#6", 70554263Sshin "#7", 70654263Sshin "#8", 70754263Sshin "#9", 70854263Sshin "#10", 70954263Sshin "#11", 71054263Sshin "#12", 71154263Sshin "#13", 71254263Sshin "#14", 71354263Sshin "#15", 71454263Sshin "#16", 71554263Sshin "#17", 71654263Sshin "#18", 717175061Sobrien "#19", 71854263Sshin "#20", 71954263Sshin "#21", 72054263Sshin "#22", 72154263Sshin "#23", 72254263Sshin "#24", 72354263Sshin "#25", 72454263Sshin "#26", 72554263Sshin "#27", 72654263Sshin "#28", 727175061Sobrien "#29", 72854263Sshin "#30", 72954263Sshin "#31", 73054263Sshin "#32", 73154263Sshin "#33", 73254263Sshin "#34", 73354263Sshin "#35", 73454263Sshin "#36", 73554263Sshin "#37", 73654263Sshin "#38", 737175061Sobrien "#39", 73854263Sshin "#40", 73954263Sshin "#41", 74054263Sshin "#42", 74154263Sshin "#43", 74254263Sshin "#44", 74354263Sshin "#45", 74454263Sshin "#46", 74554263Sshin "#47", 74654263Sshin "#48", 747175061Sobrien "#49", 74854263Sshin "#50", 74954263Sshin "#51", 75054263Sshin "#52", 75154263Sshin "#53", 75254263Sshin "#54", 75354263Sshin "#55", 75454263Sshin "#56", 75554263Sshin "#57", 75654263Sshin "#58", 757175061Sobrien "#59", 75854263Sshin "#60", 75954263Sshin "#61", 76054263Sshin "#62", 76154263Sshin "#63", 76254263Sshin "#64", 76354263Sshin "#65", 76454263Sshin "#66", 76554263Sshin "#67", 76654263Sshin "#68", 767175061Sobrien "#69", 76854263Sshin "#70", 76954263Sshin "#71", 77054263Sshin "#72", 77154263Sshin "#73", 77254263Sshin "#74", 77354263Sshin "#75", 77454263Sshin "#76", 77554263Sshin "#77", 77654263Sshin "#78", 777175061Sobrien "#79", 77854263Sshin "#80", 77954263Sshin "#81", 78054263Sshin "#82", 78154263Sshin "#83", 78254263Sshin "#84", 78354263Sshin "#85", 78454263Sshin "#86", 78554263Sshin "#87", 78654263Sshin "#88", 787175061Sobrien "#89", 78854263Sshin "#80", 78954263Sshin "#91", 79054263Sshin "#92", 79154263Sshin "#93", 79254263Sshin "#94", 79354263Sshin "#95", 79454263Sshin "#96", 79554263Sshin "#97", 79654263Sshin "#98", 797175061Sobrien "#99", 79854263Sshin "#100", 79954263Sshin "#101", 80054263Sshin "#102", 80154263Sshin "#103", 80254263Sshin "#104", 80354263Sshin "#105", 80454263Sshin "#106", 80554263Sshin "#107", 80654263Sshin "#108", 807175061Sobrien "#109", 80854263Sshin "#110", 80954263Sshin "#111", 81054263Sshin "#112", 81154263Sshin "#113", 81254263Sshin "#114", 81354263Sshin "#115", 81454263Sshin "#116", 81554263Sshin "#117", 81654263Sshin "#118", 817175061Sobrien "#119", 81854263Sshin "#120", 81954263Sshin "#121", 82054263Sshin "#122", 82154263Sshin "#123", 82254263Sshin "#124", 82354263Sshin "#125", 82454263Sshin "#126", 82554263Sshin "#127", 82654263Sshin "echo", 827175061Sobrien "echo reply", 82854263Sshin "multicast listener query", 829191652Sbms "MLDv1 listener report", 830191652Sbms "MLDv1 listener done", 83154263Sshin "router solicitation", 83277565Sdd "router advertisement", 83354263Sshin "neighbor solicitation", 83477565Sdd "neighbor advertisement", 83554263Sshin "redirect", 83654263Sshin "router renumbering", 83754263Sshin "node information request", 83854263Sshin "node information reply", 83978540Ssumikawa "inverse neighbor solicitation", 84078540Ssumikawa "inverse neighbor advertisement", 841191652Sbms "MLDv2 listener report", 84254263Sshin "#144", 84354263Sshin "#145", 84454263Sshin "#146", 84554263Sshin "#147", 84654263Sshin "#148", 847175061Sobrien "#149", 84854263Sshin "#150", 84954263Sshin "#151", 85054263Sshin "#152", 85154263Sshin "#153", 85254263Sshin "#154", 85354263Sshin "#155", 85454263Sshin "#156", 85554263Sshin "#157", 85654263Sshin "#158", 857175061Sobrien "#159", 85854263Sshin "#160", 85954263Sshin "#161", 86054263Sshin "#162", 86154263Sshin "#163", 86254263Sshin "#164", 86354263Sshin "#165", 86454263Sshin "#166", 86554263Sshin "#167", 86654263Sshin "#168", 867175061Sobrien "#169", 86854263Sshin "#170", 86954263Sshin "#171", 87054263Sshin "#172", 87154263Sshin "#173", 87254263Sshin "#174", 87354263Sshin "#175", 87454263Sshin "#176", 87554263Sshin "#177", 87654263Sshin "#178", 877175061Sobrien "#179", 87854263Sshin "#180", 87954263Sshin "#181", 88054263Sshin "#182", 88154263Sshin "#183", 88254263Sshin "#184", 88354263Sshin "#185", 88454263Sshin "#186", 88554263Sshin "#187", 88654263Sshin "#188", 887175061Sobrien "#189", 88854263Sshin "#180", 88954263Sshin "#191", 89054263Sshin "#192", 89154263Sshin "#193", 89254263Sshin "#194", 89354263Sshin "#195", 89454263Sshin "#196", 89554263Sshin "#197", 89654263Sshin "#198", 897175061Sobrien "#199", 89854263Sshin "#200", 89954263Sshin "#201", 90054263Sshin "#202", 90154263Sshin "#203", 90254263Sshin "#204", 90354263Sshin "#205", 90454263Sshin "#206", 90554263Sshin "#207", 90654263Sshin "#208", 907175061Sobrien "#209", 90854263Sshin "#210", 90954263Sshin "#211", 91054263Sshin "#212", 91154263Sshin "#213", 91254263Sshin "#214", 91354263Sshin "#215", 91454263Sshin "#216", 91554263Sshin "#217", 91654263Sshin "#218", 917175061Sobrien "#219", 91854263Sshin "#220", 91954263Sshin "#221", 92054263Sshin "#222", 92154263Sshin "#223", 92254263Sshin "#224", 92354263Sshin "#225", 92454263Sshin "#226", 92554263Sshin "#227", 92654263Sshin "#228", 927175061Sobrien "#229", 92854263Sshin "#230", 92954263Sshin "#231", 93054263Sshin "#232", 93154263Sshin "#233", 93254263Sshin "#234", 93354263Sshin "#235", 93454263Sshin "#236", 93554263Sshin "#237", 93654263Sshin "#238", 937175061Sobrien "#239", 93854263Sshin "#240", 93954263Sshin "#241", 94054263Sshin "#242", 94154263Sshin "#243", 94254263Sshin "#244", 94354263Sshin "#245", 94454263Sshin "#246", 94554263Sshin "#247", 94654263Sshin "#248", 947175061Sobrien "#249", 94854263Sshin "#250", 94954263Sshin "#251", 95054263Sshin "#252", 95154263Sshin "#253", 95254263Sshin "#254", 95354263Sshin "#255", 95454263Sshin}; 95554263Sshin 95654263Sshin/* 95754263Sshin * Dump ICMP6 statistics. 95854263Sshin */ 95954263Sshinvoid 960171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 96154263Sshin{ 962228700Smaxim struct icmp6stat icmp6stat, zerostat; 96395637Smarkm int i, first; 96478931Sume size_t len; 96554263Sshin 966171465Sjhb len = sizeof icmp6stat; 967171465Sjhb if (live) { 968171465Sjhb memset(&icmp6stat, 0, len); 969228700Smaxim if (zflag) 970228700Smaxim memset(&zerostat, 0, len); 971171465Sjhb if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len, 972228700Smaxim zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 973171465Sjhb if (errno != ENOENT) 974279122Smarcel xo_warn("sysctl: net.inet6.icmp6.stats"); 975171465Sjhb return; 976171465Sjhb } 977171465Sjhb } else 978253085Sae kread_counters(off, &icmp6stat, len); 97978931Sume 980279122Smarcel xo_emit("{T:/%s}:\n", name); 981279122Smarcel xo_open_container(name); 98254263Sshin 98354263Sshin#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 984279122Smarcel xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) 985187134Smaxim#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ 986279122Smarcel xo_emit(m, (uintmax_t)icmp6stat.f) 98754263Sshin 988279122Smarcel p(icp6s_error, "\t{:icmp6-calls/%ju} " 989279122Smarcel "{N:/call%s to icmp6_error}\n"); 990279122Smarcel p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} " 991279122Smarcel "{N:/error%s not generated in response to an icmp6 message}\n"); 992279122Smarcel p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} " 993279122Smarcel "{N:/error%s not generated because of rate limitation}\n"); 994175061Sobrien#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) 99578540Ssumikawa for (first = 1, i = 0; i < NELEM; i++) 99654263Sshin if (icmp6stat.icp6s_outhist[i] != 0) { 99754263Sshin if (first) { 998279122Smarcel xo_open_list("output-histogram"); 999279122Smarcel xo_emit("\t{T:Output histogram}:\n"); 100054263Sshin first = 0; 100154263Sshin } 1002279122Smarcel xo_open_instance("output-histogram"); 1003279122Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 1004279122Smarcel icmp6names[i], 1005160787Syar (uintmax_t)icmp6stat.icp6s_outhist[i]); 1006279122Smarcel xo_close_instance("output-histogram"); 100754263Sshin } 1008279122Smarcel if (!first) 1009279122Smarcel xo_close_list("output-histogram"); 101078540Ssumikawa#undef NELEM 1011279122Smarcel 1012279122Smarcel p(icp6s_badcode, "\t{:dropped-bad-code/%ju} " 1013279122Smarcel "{N:/message%s with bad code fields}\n"); 1014279122Smarcel p(icp6s_tooshort, "\t{:dropped-too-short/%ju} " 1015279122Smarcel "{N:/message%s < minimum length}\n"); 1016279122Smarcel p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} " 1017279122Smarcel "{N:/bad checksum%s}\n"); 1018279122Smarcel p(icp6s_badlen, "\t{:dropped-bad-length/%ju} " 1019279122Smarcel "{N:/message%s with bad length}\n"); 1020175061Sobrien#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) 102178540Ssumikawa for (first = 1, i = 0; i < NELEM; i++) 102254263Sshin if (icmp6stat.icp6s_inhist[i] != 0) { 102354263Sshin if (first) { 1024279122Smarcel xo_open_list("input-histogram"); 1025279122Smarcel xo_emit("\t{T:Input histogram}:\n"); 102654263Sshin first = 0; 102754263Sshin } 1028279122Smarcel xo_open_instance("input-histogram"); 1029279122Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 1030279122Smarcel icmp6names[i], 1031160787Syar (uintmax_t)icmp6stat.icp6s_inhist[i]); 1032279122Smarcel xo_close_instance("input-histogram"); 103354263Sshin } 1034279122Smarcel if (!first) 1035279122Smarcel xo_close_list("input-histogram"); 103678540Ssumikawa#undef NELEM 1037279122Smarcel xo_emit("\t{T:Histogram of error messages to be generated}:\n"); 1038279122Smarcel xo_open_container("errors"); 1039279122Smarcel p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} " 1040279122Smarcel "{N:/no route}\n"); 1041279122Smarcel p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} " 1042279122Smarcel "{N:/administratively prohibited}\n"); 1043279122Smarcel p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} " 1044279122Smarcel "{N:/beyond scope}\n"); 1045279122Smarcel p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} " 1046279122Smarcel "{N:/address unreachable}\n"); 1047279122Smarcel p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} " 1048279122Smarcel "{N:/port unreachable}\n"); 1049279122Smarcel p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} " 1050279122Smarcel "{N:/packet too big}\n"); 1051279122Smarcel p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} " 1052279122Smarcel "{N:/time exceed transit}\n"); 1053279122Smarcel p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} " 1054279122Smarcel "{N:/time exceed reassembly}\n"); 1055279122Smarcel p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} " 1056279122Smarcel "{N:/erroneous header field}\n"); 1057279122Smarcel p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} " 1058279122Smarcel "{N:/unrecognized next header}\n"); 1059279122Smarcel p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} " 1060279122Smarcel "{N:/unrecognized option}\n"); 1061279122Smarcel p_5(icp6s_oredirect, "\t\t{:redirects/%ju} " 1062279122Smarcel "{N:/redirect}\n"); 1063279122Smarcel p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n"); 106462584Sitojun 1065279122Smarcel p(icp6s_reflect, "\t{:reflect/%ju} " 1066279122Smarcel "{N:/message response%s generated}\n"); 1067279122Smarcel p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} " 1068279122Smarcel "{N:/message%s with too many ND options}\n"); 1069279122Smarcel p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} " 1070279122Smarcel "{N:/message%s with bad ND options}\n"); 1071279122Smarcel p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} " 1072279122Smarcel "{N:/bad neighbor solicitation message%s}\n"); 1073279122Smarcel p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} " 1074279122Smarcel "{N:/bad neighbor advertisement message%s}\n"); 1075279122Smarcel p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} " 1076279122Smarcel "{N:/bad router solicitation message%s}\n"); 1077279122Smarcel p(icp6s_badra, "\t{:bad-router-advertisement/%ju} " 1078279122Smarcel "{N:/bad router advertisement message%s}\n"); 1079279122Smarcel p(icp6s_badredirect, "\t{:bad-redirect/%ju} " 1080279122Smarcel "{N:/bad redirect message%s}\n"); 1081279122Smarcel xo_close_container("errors"); 1082279122Smarcel p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n"); 108354263Sshin#undef p 108454263Sshin#undef p_5 1085279122Smarcel xo_close_container(name); 108654263Sshin} 108754263Sshin 108854263Sshin/* 108954263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466. 109054263Sshin */ 109154263Sshinvoid 109278314Sassaricmp6_ifstats(char *ifname) 109354263Sshin{ 109454263Sshin struct in6_ifreq ifr; 109554263Sshin int s; 109654263Sshin 1097279122Smarcel#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1098279122Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1099279122Smarcel plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 1100279122Smarcel#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1101279122Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1102279122Smarcel pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) 1103279122Smarcel 110454263Sshin if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 1105279122Smarcel xo_warn("Warning: socket(AF_INET6)"); 110654263Sshin return; 110754263Sshin } 110854263Sshin 110954263Sshin strcpy(ifr.ifr_name, ifname); 111054263Sshin if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 1111270349Smarkj if (errno != EPFNOSUPPORT) 1112279122Smarcel xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 111354263Sshin goto end; 111454263Sshin } 111554263Sshin 1116279122Smarcel xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name); 111754263Sshin 1118279122Smarcel xo_open_instance("icmp6-interface-statistics"); 1119279122Smarcel xo_emit("{ke:name/%s}", ifr.ifr_name); 1120279122Smarcel p(ifs6_in_msg, "\t{:received-packets/%ju} " 1121279122Smarcel "{N:/total input message%s}\n"); 1122279122Smarcel p(ifs6_in_error, "\t{:received-errors/%ju} " 1123279122Smarcel "{N:/total input error message%s}\n"); 1124279122Smarcel p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} " 1125279122Smarcel "{N:/input destination unreachable error%s}\n"); 1126279122Smarcel p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} " 1127279122Smarcel "{N:/input administratively prohibited error%s}\n"); 1128279122Smarcel p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} " 1129279122Smarcel "{N:/input time exceeded error%s}\n"); 1130279122Smarcel p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} " 1131279122Smarcel "{N:/input parameter problem error%s}\n"); 1132279122Smarcel p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} " 1133279122Smarcel "{N:/input packet too big error%s}\n"); 1134279122Smarcel p(ifs6_in_echo, "\t{:received-echo-requests/%ju} " 1135279122Smarcel "{N:/input echo request%s}\n"); 1136279122Smarcel p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} " 1137279122Smarcel "{N:/input echo repl%s}\n"); 1138279122Smarcel p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} " 1139279122Smarcel "{N:/input router solicitation%s}\n"); 1140279122Smarcel p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} " 1141279122Smarcel "{N:/input router advertisement%s}\n"); 1142279122Smarcel p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} " 1143279122Smarcel "{N:/input neighbor solicitation%s}\n"); 1144279122Smarcel p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} " 1145279122Smarcel "{N:/input neighbor advertisement%s}\n"); 1146279122Smarcel p(ifs6_in_redirect, "\t{received-redirects/%ju} " 1147279122Smarcel "{N:/input redirect%s}\n"); 1148279122Smarcel p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} " 1149279122Smarcel "{N:/input MLD quer%s}\n"); 1150279122Smarcel p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} " 1151279122Smarcel "{N:/input MLD report%s}\n"); 1152279122Smarcel p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} " 1153279122Smarcel "{N:/input MLD done%s}\n"); 115454263Sshin 1155279122Smarcel p(ifs6_out_msg, "\t{:sent-packets/%ju} " 1156279122Smarcel "{N:/total output message%s}\n"); 1157279122Smarcel p(ifs6_out_error, "\t{:sent-errors/%ju} " 1158279122Smarcel "{N:/total output error message%s}\n"); 1159279122Smarcel p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} " 1160279122Smarcel "{N:/output destination unreachable error%s}\n"); 1161279122Smarcel p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} " 1162279122Smarcel "{N:/output administratively prohibited error%s}\n"); 1163279122Smarcel p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} " 1164279122Smarcel "{N:/output time exceeded error%s}\n"); 1165279122Smarcel p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} " 1166279122Smarcel "{N:/output parameter problem error%s}\n"); 1167279122Smarcel p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} " 1168279122Smarcel "{N:/output packet too big error%s}\n"); 1169279122Smarcel p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} " 1170279122Smarcel "{N:/output echo request%s}\n"); 1171279122Smarcel p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} " 1172279122Smarcel "{N:/output echo repl%s}\n"); 1173279122Smarcel p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} " 1174279122Smarcel "{N:/output router solicitation%s}\n"); 1175279122Smarcel p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} " 1176279122Smarcel "{N:/output router advertisement%s}\n"); 1177279122Smarcel p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} " 1178279122Smarcel "{N:/output neighbor solicitation%s}\n"); 1179279122Smarcel p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} " 1180279122Smarcel "{N:/output neighbor advertisement%s}\n"); 1181279122Smarcel p(ifs6_out_redirect, "\t{:sent-redirects/%ju} " 1182279122Smarcel "{N:/output redirect%s}\n"); 1183279122Smarcel p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} " 1184279122Smarcel "{N:/output MLD quer%s}\n"); 1185279122Smarcel p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} " 1186279122Smarcel "{N:/output MLD report%s}\n"); 1187279122Smarcel p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} " 1188279122Smarcel "{N:/output MLD done%s}\n"); 1189279122Smarcel 1190279122Smarcelend: 1191279122Smarcel xo_close_instance("icmp6-interface-statistics"); 119254263Sshin close(s); 119354263Sshin#undef p 119454263Sshin} 119554263Sshin 119654263Sshin/* 119754263Sshin * Dump PIM statistics structure. 119854263Sshin */ 119954263Sshinvoid 1200171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 120154263Sshin{ 1202166952Sbms struct pim6stat pim6stat, zerostat; 1203166952Sbms size_t len = sizeof pim6stat; 120454263Sshin 1205171465Sjhb if (live) { 1206171465Sjhb if (zflag) 1207171465Sjhb memset(&zerostat, 0, len); 1208171465Sjhb if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len, 1209171465Sjhb zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 1210171465Sjhb if (errno != ENOENT) 1211279122Smarcel xo_warn("sysctl: net.inet6.pim.stats"); 1212171465Sjhb return; 1213171465Sjhb } 1214171465Sjhb } else { 1215171465Sjhb if (off == 0) 1216171465Sjhb return; 1217171465Sjhb kread(off, &pim6stat, len); 1218166952Sbms } 1219171465Sjhb 1220279122Smarcel xo_emit("{T:/%s}:\n", name); 1221279122Smarcel xo_open_container(name); 122254263Sshin 122354263Sshin#define p(f, m) if (pim6stat.f || sflag <= 1) \ 1224279122Smarcel xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) 1225279122Smarcel 1226279122Smarcel p(pim6s_rcv_total, "\t{:received-packets/%ju} " 1227279122Smarcel "{N:/message%s received}\n"); 1228279122Smarcel p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} " 1229279122Smarcel "{N:/message%s received with too few bytes}\n"); 1230279122Smarcel p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " 1231279122Smarcel "{N:/message%s received with bad checksum}\n"); 1232279122Smarcel p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} " 1233279122Smarcel "{N:/message%s received with bad version}\n"); 1234279122Smarcel p(pim6s_rcv_registers, "\t{:received-registers/%ju} " 1235279122Smarcel "{N:/register%s received}\n"); 1236279122Smarcel p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} " 1237279122Smarcel "{N:/bad register%s received}\n"); 1238279122Smarcel p(pim6s_snd_registers, "\t{:sent-registers/%ju} " 1239279122Smarcel "{N:/register%s sent}\n"); 124054263Sshin#undef p 1241279122Smarcel xo_close_container(name); 124254263Sshin} 124354263Sshin 124454263Sshin/* 124578064Sume * Dump raw ip6 statistics structure. 124678064Sume */ 124778064Sumevoid 1248171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 124978064Sume{ 1250228700Smaxim struct rip6stat rip6stat, zerostat; 125178064Sume u_quad_t delivered; 1252171465Sjhb size_t len; 125378064Sume 1254171465Sjhb len = sizeof(rip6stat); 1255171465Sjhb if (live) { 1256228700Smaxim if (zflag) 1257228700Smaxim memset(&zerostat, 0, len); 1258171465Sjhb if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len, 1259228700Smaxim zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 1260171465Sjhb if (errno != ENOENT) 1261279122Smarcel xo_warn("sysctl: net.inet6.ip6.rip6stats"); 1262171465Sjhb return; 1263171465Sjhb } 1264171465Sjhb } else 1265253085Sae kread_counters(off, &rip6stat, len); 126678064Sume 1267279122Smarcel xo_emit("{T:/%s}:\n", name); 1268279122Smarcel xo_open_container(name); 126978064Sume 127078064Sume#define p(f, m) if (rip6stat.f || sflag <= 1) \ 1271279122Smarcel xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) 1272279122Smarcel 1273279122Smarcel p(rip6s_ipackets, "\t{:received-packets/%ju} " 1274279122Smarcel "{N:/message%s received}\n"); 1275279122Smarcel p(rip6s_isum, "\t{:input-checksum-computation/%ju} " 1276279122Smarcel "{N:/checksum calculation%s on inbound}\n"); 1277279122Smarcel p(rip6s_badsum, "\t{:received-bad-checksum/%ju} " 1278279122Smarcel "{N:/message%s with bad checksum}\n"); 1279279122Smarcel p(rip6s_nosock, "\t{:dropped-no-socket/%ju} " 1280279122Smarcel "{N:/message%s dropped due to no socket}\n"); 1281279122Smarcel p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} " 1282279122Smarcel "{N:/multicast message%s dropped due to no socket}\n"); 1283279122Smarcel p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} " 1284279122Smarcel "{N:/message%s dropped due to full socket buffers}\n"); 128578064Sume delivered = rip6stat.rip6s_ipackets - 128678064Sume rip6stat.rip6s_badsum - 128778064Sume rip6stat.rip6s_nosock - 128878064Sume rip6stat.rip6s_nosockmcast - 128978064Sume rip6stat.rip6s_fullsock; 129078064Sume if (delivered || sflag <= 1) 1291279122Smarcel xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n", 1292279122Smarcel (uintmax_t)delivered); 1293279122Smarcel p(rip6s_opackets, "\t{:sent-packets/%ju} " 1294279122Smarcel "{N:/datagram%s output}\n"); 129578064Sume#undef p 1296279122Smarcel xo_close_container(name); 129778064Sume} 129878064Sume 129978064Sume/* 130054263Sshin * Pretty print an Internet address (net address + port). 130178238Sassar * Take numeric_addr and numeric_port into consideration. 130254263Sshin */ 1303175061Sobrien#define GETSERVBYPORT6(port, proto, ret)\ 130454263Sshin{\ 130554263Sshin if (strcmp((proto), "tcp6") == 0)\ 130654263Sshin (ret) = getservbyport((int)(port), "tcp");\ 130754263Sshin else if (strcmp((proto), "udp6") == 0)\ 130854263Sshin (ret) = getservbyport((int)(port), "udp");\ 130954263Sshin else\ 131054263Sshin (ret) = getservbyport((int)(port), (proto));\ 131154263Sshin}; 131254263Sshin 131354263Sshinvoid 1314279122Smarcelinet6print(const char *container, struct in6_addr *in6, int port, 1315279122Smarcel const char *proto, int numeric) 131654263Sshin{ 131754263Sshin struct servent *sp = 0; 131854263Sshin char line[80], *cp; 131954263Sshin int width; 132054263Sshin 1321279122Smarcel if (container) 1322279122Smarcel xo_open_container(container); 1323279122Smarcel 1324279122Smarcel sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16, 1325279122Smarcel inet6name(in6)); 1326229403Sed cp = strchr(line, '\0'); 132754263Sshin if (!numeric && port) 132854263Sshin GETSERVBYPORT6(port, proto, sp); 132954263Sshin if (sp || port == 0) 1330177352Sume sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 133154263Sshin else 133254263Sshin sprintf(cp, "%d", ntohs((u_short)port)); 133383200Sru width = Wflag ? 45 : Aflag ? 18 : 22; 1334279122Smarcel 1335279122Smarcel xo_emit("{d:target/%-*.*s} ", width, width, line); 1336279122Smarcel 1337279122Smarcel int alen = cp - line - 1, plen = strlen(cp) - 1; 1338279122Smarcel xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, 1339279122Smarcel plen, cp); 1340279122Smarcel 1341279122Smarcel if (container) 1342279122Smarcel xo_close_container(container); 134354263Sshin} 134454263Sshin 134554263Sshin/* 134654263Sshin * Construct an Internet address representation. 134778238Sassar * If the numeric_addr has been supplied, give 134854263Sshin * numeric value, otherwise try for symbolic name. 134954263Sshin */ 135054263Sshin 135154263Sshinchar * 135278314Sassarinet6name(struct in6_addr *in6p) 135354263Sshin{ 1354254459Shrs struct sockaddr_in6 sin6; 1355254459Shrs char hbuf[NI_MAXHOST], *cp; 135654263Sshin static char line[50]; 135774262Sbrian static char domain[MAXHOSTNAMELEN]; 135854263Sshin static int first = 1; 1359254459Shrs int flags, error; 136054263Sshin 1361254459Shrs if (IN6_IS_ADDR_UNSPECIFIED(in6p)) { 1362254459Shrs strcpy(line, "*"); 1363254459Shrs return (line); 1364254459Shrs } 136578238Sassar if (first && !numeric_addr) { 136654263Sshin first = 0; 136754263Sshin if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 1368229403Sed (cp = strchr(domain, '.'))) 136954263Sshin (void) strcpy(domain, cp + 1); 137054263Sshin else 137154263Sshin domain[0] = 0; 137254263Sshin } 1373254459Shrs memset(&sin6, 0, sizeof(sin6)); 1374254459Shrs memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p)); 1375254459Shrs sin6.sin6_family = AF_INET6; 1376279122Smarcel /* XXX: in6p.s6_addr[2] can contain scopeid. */ 1377254459Shrs in6_fillscopeid(&sin6); 1378254459Shrs flags = (numeric_addr) ? NI_NUMERICHOST : 0; 1379254459Shrs error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, 1380254459Shrs sizeof(hbuf), NULL, 0, flags); 1381254459Shrs if (error == 0) { 1382254459Shrs if ((flags & NI_NUMERICHOST) == 0 && 1383254459Shrs (cp = strchr(hbuf, '.')) && 1384254459Shrs !strcmp(cp + 1, domain)) 1385254459Shrs *cp = 0; 1386254459Shrs strcpy(line, hbuf); 1387254459Shrs } else { 1388254459Shrs /* XXX: this should not happen. */ 138954263Sshin sprintf(line, "%s", 1390254459Shrs inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, 139154263Sshin sizeof(ntop_buf))); 1392254459Shrs } 139354263Sshin return (line); 139454263Sshin} 139564342Sume#endif /*INET6*/ 1396