inet6.c revision 355869
1130803Smarcel/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2130803Smarcel/*- 3130803Smarcel * Copyright (c) 1983, 1988, 1993 4130803Smarcel * The Regents of the University of California. All rights reserved. 5130803Smarcel * 6130803Smarcel * Redistribution and use in source and binary forms, with or without 7130803Smarcel * modification, are permitted provided that the following conditions 8130803Smarcel * are met: 9130803Smarcel * 1. Redistributions of source code must retain the above copyright 10130803Smarcel * notice, this list of conditions and the following disclaimer. 11130803Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12130803Smarcel * notice, this list of conditions and the following disclaimer in the 13130803Smarcel * documentation and/or other materials provided with the distribution. 14130803Smarcel * 4. Neither the name of the University nor the names of its contributors 15130803Smarcel * may be used to endorse or promote products derived from this software 16130803Smarcel * without specific prior written permission. 17130803Smarcel * 18130803Smarcel * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19130803Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20130803Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21130803Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22130803Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23130803Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24130803Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25130803Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26130803Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27130803Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28130803Smarcel * SUCH DAMAGE. 29130803Smarcel */ 30130803Smarcel 31130803Smarcel#if 0 32130803Smarcel#ifndef lint 33130803Smarcelstatic char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; 34130803Smarcel#endif /* not lint */ 35130803Smarcel#endif 36130803Smarcel 37130803Smarcel#include <sys/cdefs.h> 38130803Smarcel__FBSDID("$FreeBSD: stable/11/usr.bin/netstat/inet6.c 355869 2019-12-17 23:45:50Z bz $"); 39130803Smarcel 40130803Smarcel#ifdef INET6 41130803Smarcel#include <sys/param.h> 42130803Smarcel#include <sys/socket.h> 43130803Smarcel#include <sys/socketvar.h> 44130803Smarcel#include <sys/ioctl.h> 45130803Smarcel#include <sys/mbuf.h> 46130803Smarcel#include <sys/protosw.h> 47130803Smarcel 48130803Smarcel#include <net/route.h> 49130803Smarcel#include <net/if.h> 50130803Smarcel#include <netinet/in.h> 51130803Smarcel#include <netinet/ip6.h> 52130803Smarcel#include <netinet/icmp6.h> 53130803Smarcel#include <netinet/in_systm.h> 54130803Smarcel#include <netinet6/in6_pcb.h> 55130803Smarcel#include <netinet6/in6_var.h> 56130803Smarcel#include <netinet6/ip6_var.h> 57130803Smarcel#include <netinet6/pim6_var.h> 58130803Smarcel#include <netinet6/raw_ip6.h> 59130803Smarcel 60130803Smarcel#include <arpa/inet.h> 61130803Smarcel#include <netdb.h> 62130803Smarcel 63130803Smarcel#include <err.h> 64130803Smarcel#include <stdint.h> 65130803Smarcel#include <stdio.h> 66130803Smarcel#include <stdbool.h> 67130803Smarcel#include <errno.h> 68130803Smarcel#include <string.h> 69130803Smarcel#include <unistd.h> 70130803Smarcel#include <libxo/xo.h> 71130803Smarcel#include "netstat.h" 72130803Smarcel 73130803Smarcelstatic char ntop_buf[INET6_ADDRSTRLEN]; 74130803Smarcel 75130803Smarcelstatic const char *ip6nh[] = { 76130803Smarcel "hop by hop", 77130803Smarcel "ICMP", 78130803Smarcel "IGMP", 79130803Smarcel "#3", 80130803Smarcel "IP", 81130803Smarcel "#5", 82130803Smarcel "TCP", 83130803Smarcel "#7", 84130803Smarcel "#8", 85130803Smarcel "#9", 86130803Smarcel "#10", 87130803Smarcel "#11", 88130803Smarcel "#12", 89130803Smarcel "#13", 90130803Smarcel "#14", 91130803Smarcel "#15", 92130803Smarcel "#16", 93130803Smarcel "UDP", 94130803Smarcel "#18", 95130803Smarcel "#19", 96130803Smarcel "#20", 97130803Smarcel "#21", 98130803Smarcel "IDP", 99130803Smarcel "#23", 100130803Smarcel "#24", 101130803Smarcel "#25", 102130803Smarcel "#26", 103130803Smarcel "#27", 104130803Smarcel "#28", 105130803Smarcel "TP", 106130803Smarcel "#30", 107130803Smarcel "#31", 108130803Smarcel "#32", 109130803Smarcel "#33", 110130803Smarcel "#34", 111130803Smarcel "#35", 112130803Smarcel "#36", 113130803Smarcel "#37", 114130803Smarcel "#38", 115130803Smarcel "#39", 116130803Smarcel "#40", 117130803Smarcel "IP6", 118130803Smarcel "#42", 119130803Smarcel "routing", 120130803Smarcel "fragment", 121130803Smarcel "#45", 122130803Smarcel "#46", 123130803Smarcel "#47", 124130803Smarcel "#48", 125130803Smarcel "#49", 126130803Smarcel "ESP", 127130803Smarcel "AH", 128130803Smarcel "#52", 129130803Smarcel "#53", 130130803Smarcel "#54", 131130803Smarcel "#55", 132130803Smarcel "#56", 133130803Smarcel "#57", 134130803Smarcel "ICMP6", 135130803Smarcel "no next header", 136130803Smarcel "destination option", 137130803Smarcel "#61", 138130803Smarcel "mobility", 139130803Smarcel "#63", 140130803Smarcel "#64", 141130803Smarcel "#65", 142130803Smarcel "#66", 143130803Smarcel "#67", 144130803Smarcel "#68", 145130803Smarcel "#69", 146130803Smarcel "#70", 147130803Smarcel "#71", 148130803Smarcel "#72", 149130803Smarcel "#73", 150130803Smarcel "#74", 151130803Smarcel "#75", 152130803Smarcel "#76", 153130803Smarcel "#77", 154130803Smarcel "#78", 155130803Smarcel "#79", 156130803Smarcel "ISOIP", 157130803Smarcel "#81", 158130803Smarcel "#82", 159130803Smarcel "#83", 160130803Smarcel "#84", 161130803Smarcel "#85", 162130803Smarcel "#86", 163130803Smarcel "#87", 164130803Smarcel "#88", 165130803Smarcel "OSPF", 166130803Smarcel "#80", 167130803Smarcel "#91", 168130803Smarcel "#92", 169130803Smarcel "#93", 170130803Smarcel "#94", 171130803Smarcel "#95", 172130803Smarcel "#96", 173130803Smarcel "Ethernet", 174130803Smarcel "#98", 175130803Smarcel "#99", 176130803Smarcel "#100", 177130803Smarcel "#101", 178130803Smarcel "#102", 179130803Smarcel "PIM", 180130803Smarcel "#104", 181130803Smarcel "#105", 182130803Smarcel "#106", 183130803Smarcel "#107", 184130803Smarcel "#108", 185130803Smarcel "#109", 186130803Smarcel "#110", 187130803Smarcel "#111", 188130803Smarcel "#112", 189130803Smarcel "#113", 190130803Smarcel "#114", 191130803Smarcel "#115", 192130803Smarcel "#116", 193130803Smarcel "#117", 194130803Smarcel "#118", 195130803Smarcel "#119", 196130803Smarcel "#120", 197130803Smarcel "#121", 198130803Smarcel "#122", 199130803Smarcel "#123", 200130803Smarcel "#124", 201130803Smarcel "#125", 202130803Smarcel "#126", 203130803Smarcel "#127", 204130803Smarcel "#128", 205130803Smarcel "#129", 206130803Smarcel "#130", 207130803Smarcel "#131", 208130803Smarcel "SCTP", 209130803Smarcel "#133", 210130803Smarcel "#134", 211130803Smarcel "#135", 212130803Smarcel "UDPLite", 213130803Smarcel "#137", 214130803Smarcel "#138", 215130803Smarcel "#139", 216130803Smarcel "#140", 217130803Smarcel "#141", 218130803Smarcel "#142", 219130803Smarcel "#143", 220130803Smarcel "#144", 221130803Smarcel "#145", 222130803Smarcel "#146", 223130803Smarcel "#147", 224130803Smarcel "#148", 225130803Smarcel "#149", 226130803Smarcel "#150", 227130803Smarcel "#151", 228130803Smarcel "#152", 229130803Smarcel "#153", 230130803Smarcel "#154", 231130803Smarcel "#155", 232130803Smarcel "#156", 233130803Smarcel "#157", 234130803Smarcel "#158", 235130803Smarcel "#159", 236130803Smarcel "#160", 237130803Smarcel "#161", 238130803Smarcel "#162", 239130803Smarcel "#163", 240130803Smarcel "#164", 241130803Smarcel "#165", 242130803Smarcel "#166", 243130803Smarcel "#167", 244130803Smarcel "#168", 245130803Smarcel "#169", 246130803Smarcel "#170", 247130803Smarcel "#171", 248130803Smarcel "#172", 249130803Smarcel "#173", 250130803Smarcel "#174", 251130803Smarcel "#175", 252130803Smarcel "#176", 253130803Smarcel "#177", 254130803Smarcel "#178", 255130803Smarcel "#179", 256130803Smarcel "#180", 257130803Smarcel "#181", 258130803Smarcel "#182", 259130803Smarcel "#183", 260130803Smarcel "#184", 261130803Smarcel "#185", 262130803Smarcel "#186", 263130803Smarcel "#187", 264130803Smarcel "#188", 265130803Smarcel "#189", 266130803Smarcel "#180", 267130803Smarcel "#191", 268130803Smarcel "#192", 269130803Smarcel "#193", 270130803Smarcel "#194", 271130803Smarcel "#195", 272130803Smarcel "#196", 273130803Smarcel "#197", 274130803Smarcel "#198", 275130803Smarcel "#199", 276130803Smarcel "#200", 277130803Smarcel "#201", 278130803Smarcel "#202", 279130803Smarcel "#203", 280130803Smarcel "#204", 281130803Smarcel "#205", 282130803Smarcel "#206", 283130803Smarcel "#207", 284130803Smarcel "#208", 285130803Smarcel "#209", 286130803Smarcel "#210", 287130803Smarcel "#211", 288130803Smarcel "#212", 289130803Smarcel "#213", 290130803Smarcel "#214", 291130803Smarcel "#215", 292130803Smarcel "#216", 293130803Smarcel "#217", 294130803Smarcel "#218", 295130803Smarcel "#219", 296130803Smarcel "#220", 297130803Smarcel "#221", 298130803Smarcel "#222", 299130803Smarcel "#223", 300130803Smarcel "#224", 301130803Smarcel "#225", 302130803Smarcel "#226", 303130803Smarcel "#227", 304130803Smarcel "#228", 305130803Smarcel "#229", 306130803Smarcel "#230", 307130803Smarcel "#231", 308130803Smarcel "#232", 309130803Smarcel "#233", 310130803Smarcel "#234", 311130803Smarcel "#235", 312130803Smarcel "#236", 313130803Smarcel "#237", 314130803Smarcel "#238", 315130803Smarcel "#239", 316130803Smarcel "#240", 317130803Smarcel "#241", 318130803Smarcel "#242", 319130803Smarcel "#243", 320130803Smarcel "#244", 321130803Smarcel "#245", 322130803Smarcel "#246", 323130803Smarcel "#247", 324130803Smarcel "#248", 325130803Smarcel "#249", 326130803Smarcel "#250", 327130803Smarcel "#251", 328130803Smarcel "#252", 329130803Smarcel "#253", 330130803Smarcel "#254", 331130803Smarcel "#255", 332130803Smarcel}; 333130803Smarcel 334130803Smarcelstatic const char *srcrule_str[] = { 335130803Smarcel "first candidate", 336130803Smarcel "same address", 337130803Smarcel "appropriate scope", 338130803Smarcel "deprecated address", 339130803Smarcel "home address", 340130803Smarcel "outgoing interface", 341130803Smarcel "matching label", 342130803Smarcel "public/temporary address", 343130803Smarcel "alive interface", 344130803Smarcel "better virtual status", 345130803Smarcel "preferred source", 346130803Smarcel "rule #11", 347130803Smarcel "rule #12", 348130803Smarcel "rule #13", 349130803Smarcel "longest match", 350130803Smarcel "rule #15", 351130803Smarcel}; 352130803Smarcel 353130803Smarcel/* 354130803Smarcel * Dump IP6 statistics structure. 355130803Smarcel */ 356130803Smarcelvoid 357130803Smarcelip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 358130803Smarcel{ 359130803Smarcel struct ip6stat ip6stat; 360130803Smarcel int first, i; 361130803Smarcel 362130803Smarcel if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat, 363130803Smarcel sizeof(ip6stat), kread_counters) != 0) 364130803Smarcel return; 365130803Smarcel 366130803Smarcel xo_open_container(name); 367130803Smarcel xo_emit("{T:/%s}:\n", name); 368130803Smarcel 369130803Smarcel#define p(f, m) if (ip6stat.f || sflag <= 1) \ 370130803Smarcel xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) 371130803Smarcel#define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 372130803Smarcel xo_emit(m, (uintmax_t)ip6stat.f) 373130803Smarcel 374130803Smarcel p(ip6s_total, "\t{:received-packets/%ju} " 375130803Smarcel "{N:/total packet%s received}\n"); 376130803Smarcel p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} " 377130803Smarcel "{N:/with size smaller than minimum}\n"); 378130803Smarcel p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} " 379130803Smarcel "{N:/with data size < data length}\n"); 380130803Smarcel p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} " 381130803Smarcel "{N:/with bad options}\n"); 382130803Smarcel p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} " 383130803Smarcel "{N:/with incorrect version number}\n"); 384130803Smarcel p(ip6s_fragments, "\t{:received-fragments/%ju} " 385130803Smarcel "{N:/fragment%s received}\n"); 386130803Smarcel p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} " 387130803Smarcel "{N:/fragment%s dropped (dup or out of space)}\n"); 388130803Smarcel p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} " 389130803Smarcel "{N:/fragment%s dropped after timeout}\n"); 390130803Smarcel p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} " 391130803Smarcel "{N:/fragment%s that exceeded limit}\n"); 392130803Smarcel p(ip6s_reassembled, "\t{:reassembled-packets/%ju} " 393130803Smarcel "{N:/packet%s reassembled ok}\n"); 394130803Smarcel p(ip6s_delivered, "\t{:received-local-packets/%ju} " 395130803Smarcel "{N:/packet%s for this host}\n"); 396130803Smarcel p(ip6s_forward, "\t{:forwarded-packets/%ju} " 397130803Smarcel "{N:/packet%s forwarded}\n"); 398130803Smarcel p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} " 399130803Smarcel "{N:/packet%s not forwardable}\n"); 400130803Smarcel p(ip6s_redirectsent, "\t{:sent-redirects/%ju} " 401130803Smarcel "{N:/redirect%s sent}\n"); 402130803Smarcel p(ip6s_localout, "\t{:sent-packets/%ju} " 403130803Smarcel "{N:/packet%s sent from this host}\n"); 404130803Smarcel p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} " 405130803Smarcel "{N:/packet%s sent with fabricated ip header}\n"); 406130803Smarcel p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} " 407130803Smarcel "{N:/output packet%s dropped due to no bufs, etc.}\n"); 408130803Smarcel p(ip6s_noroute, "\t{:discard-no-route/%ju} " 409130803Smarcel "{N:/output packet%s discarded due to no route}\n"); 410130803Smarcel p(ip6s_fragmented, "\t{:sent-fragments/%ju} " 411130803Smarcel "{N:/output datagram%s fragmented}\n"); 412130803Smarcel p(ip6s_ofragments, "\t{:fragments-created/%ju} " 413130803Smarcel "{N:/fragment%s created}\n"); 414130803Smarcel p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} " 415130803Smarcel "{N:/datagram%s that can't be fragmented}\n"); 416130803Smarcel p(ip6s_badscope, "\t{:discard-scope-violations/%ju} " 417130803Smarcel "{N:/packet%s that violated scope rules}\n"); 418130803Smarcel p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} " 419130803Smarcel "{N:/multicast packet%s which we don't join}\n"); 420130803Smarcel for (first = 1, i = 0; i < IP6S_HDRCNT; i++) 421130803Smarcel if (ip6stat.ip6s_nxthist[i] != 0) { 422130803Smarcel if (first) { 423130803Smarcel xo_emit("\t{T:Input histogram}:\n"); 424130803Smarcel xo_open_list("input-histogram"); 425130803Smarcel first = 0; 426130803Smarcel } 427130803Smarcel xo_open_instance("input-histogram"); 428130803Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i], 429130803Smarcel (uintmax_t)ip6stat.ip6s_nxthist[i]); 430130803Smarcel xo_close_instance("input-histogram"); 431130803Smarcel } 432130803Smarcel if (!first) 433130803Smarcel xo_close_list("input-histogram"); 434130803Smarcel 435130803Smarcel xo_open_container("mbuf-statistics"); 436130803Smarcel xo_emit("\t{T:Mbuf statistics}:\n"); 437130803Smarcel xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n", 438130803Smarcel (uintmax_t)ip6stat.ip6s_m1); 439130803Smarcel for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { 440130803Smarcel char ifbuf[IFNAMSIZ]; 441130803Smarcel if (ip6stat.ip6s_m2m[i] != 0) { 442130803Smarcel if (first) { 443130803Smarcel xo_emit("\t\t{N:two or more mbuf}:\n"); 444130803Smarcel xo_open_list("mbuf-data"); 445130803Smarcel first = 0; 446130803Smarcel } 447130803Smarcel xo_open_instance("mbuf-data"); 448130803Smarcel xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n", 449130803Smarcel if_indextoname(i, ifbuf), 450130803Smarcel (uintmax_t)ip6stat.ip6s_m2m[i]); 451130803Smarcel xo_close_instance("mbuf-data"); 452130803Smarcel } 453130803Smarcel } 454130803Smarcel if (!first) 455130803Smarcel xo_close_list("mbuf-data"); 456130803Smarcel xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n", 457130803Smarcel (uintmax_t)ip6stat.ip6s_mext1); 458130803Smarcel xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} " 459130803Smarcel "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m); 460130803Smarcel xo_close_container("mbuf-statistics"); 461130803Smarcel 462130803Smarcel p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} " 463130803Smarcel "{N:/packet%s whose headers are not contiguous}\n"); 464130803Smarcel p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} " 465130803Smarcel "{N:/tunneling packet%s that can't find gif}\n"); 466130803Smarcel p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} " 467130803Smarcel "{N:/packet%s discarded because of too many headers}\n"); 468130803Smarcel 469130803Smarcel /* for debugging source address selection */ 470130803Smarcel#define PRINT_SCOPESTAT(s,i) do {\ 471130803Smarcel switch(i) { /* XXX hardcoding in each case */\ 472130803Smarcel case 1:\ 473130803Smarcel p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \ 474130803Smarcel "{N:/interface-local%s}\n"); \ 475130803Smarcel break;\ 476130803Smarcel case 2:\ 477130803Smarcel p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \ 478130803Smarcel "{N:/link-local%s}\n"); \ 479130803Smarcel break;\ 480130803Smarcel case 5:\ 481130803Smarcel p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \ 482130803Smarcel "{N:/site-local%s}\n");\ 483130803Smarcel break;\ 484130803Smarcel case 14:\ 485130803Smarcel p(s,"\t\t{ke:name/globals}{:count/%ju} " \ 486130803Smarcel "{N:/global%s}\n");\ 487130803Smarcel break;\ 488130803Smarcel default:\ 489130803Smarcel xo_emit("\t\t{qke:name/%#x}{:count/%ju} " \ 490130803Smarcel "{N:/addresses scope=%#x}\n",\ 491130803Smarcel i, (uintmax_t)ip6stat.s, i); \ 492130803Smarcel }\ 493130803Smarcel } while (0); 494130803Smarcel 495130803Smarcel xo_open_container("source-address-selection"); 496130803Smarcel p(ip6s_sources_none, "\t{:address-selection-failures/%ju} " 497130803Smarcel "{N:/failure%s of source address selection}\n"); 498130803Smarcel 499130803Smarcel for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 500130803Smarcel if (ip6stat.ip6s_sources_sameif[i]) { 501130803Smarcel if (first) { 502130803Smarcel xo_open_list("outgoing-interface"); 503130803Smarcel xo_emit("\tsource addresses on an outgoing " 504130803Smarcel "I/F\n"); 505130803Smarcel first = 0; 506130803Smarcel } 507130803Smarcel xo_open_instance("outgoing-interface"); 508130803Smarcel PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); 509130803Smarcel xo_close_instance("outgoing-interface"); 510130803Smarcel } 511130803Smarcel } 512130803Smarcel if (!first) 513130803Smarcel xo_close_list("outgoing-interface"); 514130803Smarcel 515130803Smarcel for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 516130803Smarcel if (ip6stat.ip6s_sources_otherif[i]) { 517130803Smarcel if (first) { 518130803Smarcel xo_open_list("non-outgoing-interface"); 519130803Smarcel xo_emit("\tsource addresses on a non-outgoing " 520130803Smarcel "I/F\n"); 521130803Smarcel first = 0; 522130803Smarcel } 523130803Smarcel xo_open_instance("non-outgoing-interface"); 524130803Smarcel PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); 525130803Smarcel xo_close_instance("non-outgoing-interface"); 526130803Smarcel } 527130803Smarcel } 528130803Smarcel if (!first) 529130803Smarcel xo_close_list("non-outgoing-interface"); 530130803Smarcel 531130803Smarcel for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 532130803Smarcel if (ip6stat.ip6s_sources_samescope[i]) { 533130803Smarcel if (first) { 534130803Smarcel xo_open_list("same-source"); 535130803Smarcel xo_emit("\tsource addresses of same scope\n"); 536130803Smarcel first = 0; 537130803Smarcel } 538130803Smarcel xo_open_instance("same-source"); 539130803Smarcel PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); 540130803Smarcel xo_close_instance("same-source"); 541130803Smarcel } 542130803Smarcel } 543130803Smarcel if (!first) 544130803Smarcel xo_close_list("same-source"); 545130803Smarcel 546130803Smarcel for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 547130803Smarcel if (ip6stat.ip6s_sources_otherscope[i]) { 548130803Smarcel if (first) { 549130803Smarcel xo_open_list("different-scope"); 550130803Smarcel xo_emit("\tsource addresses of a different " 551130803Smarcel "scope\n"); 552130803Smarcel first = 0; 553130803Smarcel } 554130803Smarcel xo_open_instance("different-scope"); 555130803Smarcel PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); 556130803Smarcel xo_close_instance("different-scope"); 557130803Smarcel } 558130803Smarcel } 559130803Smarcel if (!first) 560130803Smarcel xo_close_list("different-scope"); 561130803Smarcel 562130803Smarcel for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 563130803Smarcel if (ip6stat.ip6s_sources_deprecated[i]) { 564130803Smarcel if (first) { 565130803Smarcel xo_open_list("deprecated-source"); 566130803Smarcel xo_emit("\tdeprecated source addresses\n"); 567130803Smarcel first = 0; 568130803Smarcel } 569130803Smarcel xo_open_instance("deprecated-source"); 570130803Smarcel PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); 571130803Smarcel xo_close_instance("deprecated-source"); 572130803Smarcel } 573130803Smarcel } 574130803Smarcel if (!first) 575130803Smarcel xo_close_list("deprecated-source"); 576130803Smarcel 577130803Smarcel for (first = 1, i = 0; i < IP6S_RULESMAX; i++) { 578130803Smarcel if (ip6stat.ip6s_sources_rule[i]) { 579130803Smarcel if (first) { 580130803Smarcel xo_open_list("rules-applied"); 581130803Smarcel xo_emit("\t{T:Source addresses selection " 582130803Smarcel "rule applied}:\n"); 583130803Smarcel first = 0; 584130803Smarcel } 585130803Smarcel xo_open_instance("rules-applied"); 586130803Smarcel xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n", 587130803Smarcel srcrule_str[i], 588130803Smarcel (uintmax_t)ip6stat.ip6s_sources_rule[i], 589130803Smarcel srcrule_str[i]); 590130803Smarcel xo_close_instance("rules-applied"); 591130803Smarcel } 592130803Smarcel } 593130803Smarcel if (!first) 594130803Smarcel xo_close_list("rules-applied"); 595130803Smarcel 596130803Smarcel xo_close_container("source-address-selection"); 597130803Smarcel 598130803Smarcel#undef p 599130803Smarcel#undef p1a 600130803Smarcel xo_close_container(name); 601130803Smarcel} 602130803Smarcel 603130803Smarcel/* 604130803Smarcel * Dump IPv6 per-interface statistics based on RFC 2465. 605130803Smarcel */ 606130803Smarcelvoid 607130803Smarcelip6_ifstats(char *ifname) 608130803Smarcel{ 609130803Smarcel struct in6_ifreq ifr; 610130803Smarcel int s; 611130803Smarcel 612130803Smarcel#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 613130803Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, \ 614130803Smarcel plural(ifr.ifr_ifru.ifru_stat.f)) 615130803Smarcel 616130803Smarcel if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 617130803Smarcel xo_warn("Warning: socket(AF_INET6)"); 618130803Smarcel return; 619130803Smarcel } 620130803Smarcel 621130803Smarcel strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 622130803Smarcel if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 623130803Smarcel if (errno != EPFNOSUPPORT) 624130803Smarcel xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)"); 625130803Smarcel goto end; 626130803Smarcel } 627130803Smarcel 628130803Smarcel xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name); 629130803Smarcel 630130803Smarcel xo_open_instance("ip6-interface-statistics"); 631130803Smarcel xo_emit("{ke:name/%s}", ifr.ifr_name); 632130803Smarcel 633130803Smarcel p(ifs6_in_receive, "\t{:received-packets/%ju} " 634130803Smarcel "{N:/total input datagram%s}\n"); 635130803Smarcel p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} " 636130803Smarcel "{N:/datagram%s with invalid header received}\n"); 637130803Smarcel p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} " 638130803Smarcel "{N:/datagram%s exceeded MTU received}\n"); 639130803Smarcel p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} " 640130803Smarcel "{N:/datagram%s with no route received}\n"); 641130803Smarcel p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} " 642130803Smarcel "{N:/datagram%s with invalid dst received}\n"); 643130803Smarcel p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} " 644130803Smarcel "{N:/datagram%s with unknown proto received}\n"); 645130803Smarcel p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} " 646130803Smarcel "{N:/truncated datagram%s received}\n"); 647130803Smarcel p(ifs6_in_discard, "\t{:dropped-discarded/%ju} " 648130803Smarcel "{N:/input datagram%s discarded}\n"); 649130803Smarcel p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} " 650130803Smarcel "{N:/datagram%s delivered to an upper layer protocol}\n"); 651130803Smarcel p(ifs6_out_forward, "\t{:sent-forwarded/%ju} " 652130803Smarcel "{N:/datagram%s forwarded to this interface}\n"); 653130803Smarcel p(ifs6_out_request, "\t{:sent-packets/%ju} " 654130803Smarcel "{N:/datagram%s sent from an upper layer protocol}\n"); 655130803Smarcel p(ifs6_out_discard, "\t{:discard-packets/%ju} " 656130803Smarcel "{N:/total discarded output datagram%s}\n"); 657130803Smarcel p(ifs6_out_fragok, "\t{:discard-fragments/%ju} " 658130803Smarcel "{N:/output datagram%s fragmented}\n"); 659130803Smarcel p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} " 660130803Smarcel "{N:/output datagram%s failed on fragment}\n"); 661130803Smarcel p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} " 662130803Smarcel "{N:/output datagram%s succeeded on fragment}\n"); 663130803Smarcel p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} " 664130803Smarcel "{N:/incoming datagram%s fragmented}\n"); 665130803Smarcel p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} " 666130803Smarcel "{N:/datagram%s reassembled}\n"); 667130803Smarcel p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} " 668130803Smarcel "{N:/datagram%s failed on reassembly}\n"); 669130803Smarcel p(ifs6_in_mcast, "\t{:received-multicast/%ju} " 670130803Smarcel "{N:/multicast datagram%s received}\n"); 671130803Smarcel p(ifs6_out_mcast, "\t{:sent-multicast/%ju} " 672130803Smarcel "{N:/multicast datagram%s sent}\n"); 673130803Smarcel 674130803Smarcel end: 675130803Smarcel xo_close_instance("ip6-interface-statistics"); 676130803Smarcel close(s); 677130803Smarcel 678130803Smarcel#undef p 679130803Smarcel} 680130803Smarcel 681130803Smarcelstatic const char *icmp6names[] = { 682130803Smarcel "#0", 683130803Smarcel "unreach", 684130803Smarcel "packet too big", 685130803Smarcel "time exceed", 686130803Smarcel "parameter problem", 687130803Smarcel "#5", 688130803Smarcel "#6", 689130803Smarcel "#7", 690130803Smarcel "#8", 691130803Smarcel "#9", 692130803Smarcel "#10", 693130803Smarcel "#11", 694130803Smarcel "#12", 695130803Smarcel "#13", 696130803Smarcel "#14", 697130803Smarcel "#15", 698130803Smarcel "#16", 699130803Smarcel "#17", 700130803Smarcel "#18", 701130803Smarcel "#19", 702130803Smarcel "#20", 703130803Smarcel "#21", 704130803Smarcel "#22", 705130803Smarcel "#23", 706130803Smarcel "#24", 707130803Smarcel "#25", 708130803Smarcel "#26", 709130803Smarcel "#27", 710130803Smarcel "#28", 711130803Smarcel "#29", 712130803Smarcel "#30", 713130803Smarcel "#31", 714130803Smarcel "#32", 715130803Smarcel "#33", 716130803Smarcel "#34", 717130803Smarcel "#35", 718130803Smarcel "#36", 719130803Smarcel "#37", 720130803Smarcel "#38", 721130803Smarcel "#39", 722130803Smarcel "#40", 723130803Smarcel "#41", 724130803Smarcel "#42", 725130803Smarcel "#43", 726130803Smarcel "#44", 727130803Smarcel "#45", 728130803Smarcel "#46", 729130803Smarcel "#47", 730130803Smarcel "#48", 731130803Smarcel "#49", 732130803Smarcel "#50", 733130803Smarcel "#51", 734130803Smarcel "#52", 735130803Smarcel "#53", 736130803Smarcel "#54", 737130803Smarcel "#55", 738130803Smarcel "#56", 739130803Smarcel "#57", 740130803Smarcel "#58", 741130803Smarcel "#59", 742130803Smarcel "#60", 743130803Smarcel "#61", 744130803Smarcel "#62", 745130803Smarcel "#63", 746130803Smarcel "#64", 747130803Smarcel "#65", 748130803Smarcel "#66", 749130803Smarcel "#67", 750130803Smarcel "#68", 751130803Smarcel "#69", 752130803Smarcel "#70", 753130803Smarcel "#71", 754130803Smarcel "#72", 755130803Smarcel "#73", 756130803Smarcel "#74", 757130803Smarcel "#75", 758130803Smarcel "#76", 759130803Smarcel "#77", 760130803Smarcel "#78", 761130803Smarcel "#79", 762130803Smarcel "#80", 763130803Smarcel "#81", 764130803Smarcel "#82", 765130803Smarcel "#83", 766130803Smarcel "#84", 767130803Smarcel "#85", 768130803Smarcel "#86", 769130803Smarcel "#87", 770130803Smarcel "#88", 771130803Smarcel "#89", 772130803Smarcel "#80", 773130803Smarcel "#91", 774130803Smarcel "#92", 775130803Smarcel "#93", 776130803Smarcel "#94", 777130803Smarcel "#95", 778130803Smarcel "#96", 779130803Smarcel "#97", 780130803Smarcel "#98", 781130803Smarcel "#99", 782130803Smarcel "#100", 783130803Smarcel "#101", 784130803Smarcel "#102", 785130803Smarcel "#103", 786130803Smarcel "#104", 787130803Smarcel "#105", 788130803Smarcel "#106", 789130803Smarcel "#107", 790130803Smarcel "#108", 791130803Smarcel "#109", 792130803Smarcel "#110", 793130803Smarcel "#111", 794130803Smarcel "#112", 795130803Smarcel "#113", 796130803Smarcel "#114", 797130803Smarcel "#115", 798130803Smarcel "#116", 799130803Smarcel "#117", 800130803Smarcel "#118", 801130803Smarcel "#119", 802130803Smarcel "#120", 803130803Smarcel "#121", 804130803Smarcel "#122", 805130803Smarcel "#123", 806130803Smarcel "#124", 807130803Smarcel "#125", 808130803Smarcel "#126", 809130803Smarcel "#127", 810130803Smarcel "echo", 811130803Smarcel "echo reply", 812130803Smarcel "multicast listener query", 813130803Smarcel "MLDv1 listener report", 814130803Smarcel "MLDv1 listener done", 815130803Smarcel "router solicitation", 816130803Smarcel "router advertisement", 817130803Smarcel "neighbor solicitation", 818130803Smarcel "neighbor advertisement", 819130803Smarcel "redirect", 820130803Smarcel "router renumbering", 821130803Smarcel "node information request", 822130803Smarcel "node information reply", 823130803Smarcel "inverse neighbor solicitation", 824130803Smarcel "inverse neighbor advertisement", 825130803Smarcel "MLDv2 listener report", 826130803Smarcel "#144", 827130803Smarcel "#145", 828130803Smarcel "#146", 829130803Smarcel "#147", 830130803Smarcel "#148", 831130803Smarcel "#149", 832130803Smarcel "#150", 833130803Smarcel "#151", 834130803Smarcel "#152", 835130803Smarcel "#153", 836130803Smarcel "#154", 837130803Smarcel "#155", 838130803Smarcel "#156", 839130803Smarcel "#157", 840130803Smarcel "#158", 841130803Smarcel "#159", 842130803Smarcel "#160", 843130803Smarcel "#161", 844130803Smarcel "#162", 845130803Smarcel "#163", 846130803Smarcel "#164", 847130803Smarcel "#165", 848130803Smarcel "#166", 849130803Smarcel "#167", 850130803Smarcel "#168", 851130803Smarcel "#169", 852130803Smarcel "#170", 853130803Smarcel "#171", 854130803Smarcel "#172", 855130803Smarcel "#173", 856130803Smarcel "#174", 857130803Smarcel "#175", 858130803Smarcel "#176", 859130803Smarcel "#177", 860130803Smarcel "#178", 861130803Smarcel "#179", 862130803Smarcel "#180", 863130803Smarcel "#181", 864130803Smarcel "#182", 865130803Smarcel "#183", 866130803Smarcel "#184", 867130803Smarcel "#185", 868130803Smarcel "#186", 869130803Smarcel "#187", 870130803Smarcel "#188", 871130803Smarcel "#189", 872130803Smarcel "#180", 873130803Smarcel "#191", 874130803Smarcel "#192", 875130803Smarcel "#193", 876130803Smarcel "#194", 877130803Smarcel "#195", 878130803Smarcel "#196", 879130803Smarcel "#197", 880130803Smarcel "#198", 881130803Smarcel "#199", 882130803Smarcel "#200", 883130803Smarcel "#201", 884130803Smarcel "#202", 885130803Smarcel "#203", 886130803Smarcel "#204", 887130803Smarcel "#205", 888130803Smarcel "#206", 889130803Smarcel "#207", 890130803Smarcel "#208", 891130803Smarcel "#209", 892130803Smarcel "#210", 893130803Smarcel "#211", 894130803Smarcel "#212", 895130803Smarcel "#213", 896130803Smarcel "#214", 897130803Smarcel "#215", 898130803Smarcel "#216", 899130803Smarcel "#217", 900130803Smarcel "#218", 901130803Smarcel "#219", 902130803Smarcel "#220", 903130803Smarcel "#221", 904130803Smarcel "#222", 905130803Smarcel "#223", 906130803Smarcel "#224", 907130803Smarcel "#225", 908130803Smarcel "#226", 909130803Smarcel "#227", 910130803Smarcel "#228", 911130803Smarcel "#229", 912130803Smarcel "#230", 913130803Smarcel "#231", 914130803Smarcel "#232", 915130803Smarcel "#233", 916130803Smarcel "#234", 917130803Smarcel "#235", 918130803Smarcel "#236", 919130803Smarcel "#237", 920130803Smarcel "#238", 921130803Smarcel "#239", 922130803Smarcel "#240", 923130803Smarcel "#241", 924130803Smarcel "#242", 925130803Smarcel "#243", 926130803Smarcel "#244", 927130803Smarcel "#245", 928130803Smarcel "#246", 929130803Smarcel "#247", 930130803Smarcel "#248", 931130803Smarcel "#249", 932130803Smarcel "#250", 933130803Smarcel "#251", 934130803Smarcel "#252", 935130803Smarcel "#253", 936130803Smarcel "#254", 937130803Smarcel "#255", 938130803Smarcel}; 939130803Smarcel 940130803Smarcel/* 941130803Smarcel * Dump ICMP6 statistics. 942130803Smarcel */ 943130803Smarcelvoid 944130803Smarcelicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 945130803Smarcel{ 946130803Smarcel struct icmp6stat icmp6stat; 947130803Smarcel int i, first; 948130803Smarcel 949130803Smarcel if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat, 950130803Smarcel sizeof(icmp6stat), kread_counters) != 0) 951130803Smarcel return; 952130803Smarcel 953130803Smarcel xo_emit("{T:/%s}:\n", name); 954130803Smarcel xo_open_container(name); 955130803Smarcel 956130803Smarcel#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 957130803Smarcel xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) 958130803Smarcel#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ 959130803Smarcel xo_emit(m, (uintmax_t)icmp6stat.f) 960130803Smarcel 961130803Smarcel p(icp6s_error, "\t{:icmp6-calls/%ju} " 962130803Smarcel "{N:/call%s to icmp6_error}\n"); 963130803Smarcel p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} " 964130803Smarcel "{N:/error%s not generated in response to an icmp6 message}\n"); 965130803Smarcel p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} " 966130803Smarcel "{N:/error%s not generated because of rate limitation}\n"); 967130803Smarcel#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) 968130803Smarcel for (first = 1, i = 0; i < NELEM; i++) 969130803Smarcel if (icmp6stat.icp6s_outhist[i] != 0) { 970130803Smarcel if (first) { 971130803Smarcel xo_open_list("output-histogram"); 972130803Smarcel xo_emit("\t{T:Output histogram}:\n"); 973130803Smarcel first = 0; 974130803Smarcel } 975130803Smarcel xo_open_instance("output-histogram"); 976130803Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 977130803Smarcel icmp6names[i], 978130803Smarcel (uintmax_t)icmp6stat.icp6s_outhist[i]); 979130803Smarcel xo_close_instance("output-histogram"); 980130803Smarcel } 981130803Smarcel if (!first) 982130803Smarcel xo_close_list("output-histogram"); 983130803Smarcel#undef NELEM 984130803Smarcel 985130803Smarcel p(icp6s_badcode, "\t{:dropped-bad-code/%ju} " 986130803Smarcel "{N:/message%s with bad code fields}\n"); 987130803Smarcel p(icp6s_tooshort, "\t{:dropped-too-short/%ju} " 988130803Smarcel "{N:/message%s < minimum length}\n"); 989130803Smarcel p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} " 990130803Smarcel "{N:/bad checksum%s}\n"); 991130803Smarcel p(icp6s_badlen, "\t{:dropped-bad-length/%ju} " 992130803Smarcel "{N:/message%s with bad length}\n"); 993130803Smarcel#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) 994130803Smarcel for (first = 1, i = 0; i < NELEM; i++) 995130803Smarcel if (icmp6stat.icp6s_inhist[i] != 0) { 996130803Smarcel if (first) { 997130803Smarcel xo_open_list("input-histogram"); 998130803Smarcel xo_emit("\t{T:Input histogram}:\n"); 999130803Smarcel first = 0; 1000130803Smarcel } 1001130803Smarcel xo_open_instance("input-histogram"); 1002130803Smarcel xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 1003130803Smarcel icmp6names[i], 1004130803Smarcel (uintmax_t)icmp6stat.icp6s_inhist[i]); 1005130803Smarcel xo_close_instance("input-histogram"); 1006130803Smarcel } 1007130803Smarcel if (!first) 1008130803Smarcel xo_close_list("input-histogram"); 1009130803Smarcel#undef NELEM 1010130803Smarcel xo_emit("\t{T:Histogram of error messages to be generated}:\n"); 1011130803Smarcel xo_open_container("errors"); 1012130803Smarcel p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} " 1013130803Smarcel "{N:/no route}\n"); 1014130803Smarcel p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} " 1015130803Smarcel "{N:/administratively prohibited}\n"); 1016130803Smarcel p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} " 1017130803Smarcel "{N:/beyond scope}\n"); 1018130803Smarcel p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} " 1019130803Smarcel "{N:/address unreachable}\n"); 1020130803Smarcel p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} " 1021130803Smarcel "{N:/port unreachable}\n"); 1022130803Smarcel p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} " 1023130803Smarcel "{N:/packet too big}\n"); 1024130803Smarcel p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} " 1025130803Smarcel "{N:/time exceed transit}\n"); 1026130803Smarcel p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} " 1027130803Smarcel "{N:/time exceed reassembly}\n"); 1028130803Smarcel p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} " 1029130803Smarcel "{N:/erroneous header field}\n"); 1030130803Smarcel p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} " 1031130803Smarcel "{N:/unrecognized next header}\n"); 1032130803Smarcel p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} " 1033130803Smarcel "{N:/unrecognized option}\n"); 1034130803Smarcel p_5(icp6s_oredirect, "\t\t{:redirects/%ju} " 1035130803Smarcel "{N:/redirect}\n"); 1036130803Smarcel p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n"); 1037130803Smarcel 1038130803Smarcel p(icp6s_reflect, "\t{:reflect/%ju} " 1039130803Smarcel "{N:/message response%s generated}\n"); 1040130803Smarcel p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} " 1041130803Smarcel "{N:/message%s with too many ND options}\n"); 1042130803Smarcel p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} " 1043130803Smarcel "{N:/message%s with bad ND options}\n"); 1044130803Smarcel p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} " 1045130803Smarcel "{N:/bad neighbor solicitation message%s}\n"); 1046130803Smarcel p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} " 1047130803Smarcel "{N:/bad neighbor advertisement message%s}\n"); 1048130803Smarcel p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} " 1049130803Smarcel "{N:/bad router solicitation message%s}\n"); 1050130803Smarcel p(icp6s_badra, "\t{:bad-router-advertisement/%ju} " 1051130803Smarcel "{N:/bad router advertisement message%s}\n"); 1052130803Smarcel p(icp6s_badredirect, "\t{:bad-redirect/%ju} " 1053130803Smarcel "{N:/bad redirect message%s}\n"); 1054130803Smarcel xo_close_container("errors"); 1055130803Smarcel p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n"); 1056130803Smarcel#undef p 1057130803Smarcel#undef p_5 1058130803Smarcel xo_close_container(name); 1059130803Smarcel} 1060130803Smarcel 1061130803Smarcel/* 1062130803Smarcel * Dump ICMPv6 per-interface statistics based on RFC 2466. 1063130803Smarcel */ 1064130803Smarcelvoid 1065130803Smarcelicmp6_ifstats(char *ifname) 1066130803Smarcel{ 1067130803Smarcel struct in6_ifreq ifr; 1068130803Smarcel int s; 1069130803Smarcel 1070130803Smarcel#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1071130803Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1072130803Smarcel plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 1073130803Smarcel#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1074130803Smarcel xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1075130803Smarcel pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) 1076130803Smarcel 1077130803Smarcel if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 1078130803Smarcel xo_warn("Warning: socket(AF_INET6)"); 1079130803Smarcel return; 1080130803Smarcel } 1081130803Smarcel 1082130803Smarcel strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 1083130803Smarcel if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 1084130803Smarcel if (errno != EPFNOSUPPORT) 1085130803Smarcel xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 1086130803Smarcel goto end; 1087130803Smarcel } 1088130803Smarcel 1089130803Smarcel xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name); 1090130803Smarcel 1091130803Smarcel xo_open_instance("icmp6-interface-statistics"); 1092130803Smarcel xo_emit("{ke:name/%s}", ifr.ifr_name); 1093130803Smarcel p(ifs6_in_msg, "\t{:received-packets/%ju} " 1094130803Smarcel "{N:/total input message%s}\n"); 1095130803Smarcel p(ifs6_in_error, "\t{:received-errors/%ju} " 1096130803Smarcel "{N:/total input error message%s}\n"); 1097130803Smarcel p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} " 1098130803Smarcel "{N:/input destination unreachable error%s}\n"); 1099130803Smarcel p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} " 1100130803Smarcel "{N:/input administratively prohibited error%s}\n"); 1101130803Smarcel p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} " 1102130803Smarcel "{N:/input time exceeded error%s}\n"); 1103130803Smarcel p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} " 1104130803Smarcel "{N:/input parameter problem error%s}\n"); 1105130803Smarcel p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} " 1106130803Smarcel "{N:/input packet too big error%s}\n"); 1107130803Smarcel p(ifs6_in_echo, "\t{:received-echo-requests/%ju} " 1108130803Smarcel "{N:/input echo request%s}\n"); 1109130803Smarcel p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} " 1110130803Smarcel "{N:/input echo repl%s}\n"); 1111130803Smarcel p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} " 1112130803Smarcel "{N:/input router solicitation%s}\n"); 1113130803Smarcel p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} " 1114130803Smarcel "{N:/input router advertisement%s}\n"); 1115130803Smarcel p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} " 1116130803Smarcel "{N:/input neighbor solicitation%s}\n"); 1117130803Smarcel p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} " 1118130803Smarcel "{N:/input neighbor advertisement%s}\n"); 1119130803Smarcel p(ifs6_in_redirect, "\t{received-redirects/%ju} " 1120130803Smarcel "{N:/input redirect%s}\n"); 1121130803Smarcel p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} " 1122130803Smarcel "{N:/input MLD quer%s}\n"); 1123130803Smarcel p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} " 1124130803Smarcel "{N:/input MLD report%s}\n"); 1125130803Smarcel p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} " 1126130803Smarcel "{N:/input MLD done%s}\n"); 1127130803Smarcel 1128130803Smarcel p(ifs6_out_msg, "\t{:sent-packets/%ju} " 1129130803Smarcel "{N:/total output message%s}\n"); 1130130803Smarcel p(ifs6_out_error, "\t{:sent-errors/%ju} " 1131130803Smarcel "{N:/total output error message%s}\n"); 1132130803Smarcel p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} " 1133130803Smarcel "{N:/output destination unreachable error%s}\n"); 1134130803Smarcel p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} " 1135130803Smarcel "{N:/output administratively prohibited error%s}\n"); 1136130803Smarcel p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} " 1137130803Smarcel "{N:/output time exceeded error%s}\n"); 1138130803Smarcel p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} " 1139130803Smarcel "{N:/output parameter problem error%s}\n"); 1140130803Smarcel p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} " 1141130803Smarcel "{N:/output packet too big error%s}\n"); 1142130803Smarcel p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} " 1143130803Smarcel "{N:/output echo request%s}\n"); 1144130803Smarcel p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} " 1145130803Smarcel "{N:/output echo repl%s}\n"); 1146130803Smarcel p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} " 1147130803Smarcel "{N:/output router solicitation%s}\n"); 1148130803Smarcel p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} " 1149130803Smarcel "{N:/output router advertisement%s}\n"); 1150130803Smarcel p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} " 1151130803Smarcel "{N:/output neighbor solicitation%s}\n"); 1152130803Smarcel p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} " 1153130803Smarcel "{N:/output neighbor advertisement%s}\n"); 1154130803Smarcel p(ifs6_out_redirect, "\t{:sent-redirects/%ju} " 1155130803Smarcel "{N:/output redirect%s}\n"); 1156130803Smarcel p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} " 1157130803Smarcel "{N:/output MLD quer%s}\n"); 1158130803Smarcel p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} " 1159130803Smarcel "{N:/output MLD report%s}\n"); 1160130803Smarcel p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} " 1161130803Smarcel "{N:/output MLD done%s}\n"); 1162130803Smarcel 1163130803Smarcelend: 1164130803Smarcel xo_close_instance("icmp6-interface-statistics"); 1165130803Smarcel close(s); 1166130803Smarcel#undef p 1167130803Smarcel} 1168130803Smarcel 1169130803Smarcel/* 1170130803Smarcel * Dump PIM statistics structure. 1171130803Smarcel */ 1172130803Smarcelvoid 1173130803Smarcelpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 1174130803Smarcel{ 1175130803Smarcel struct pim6stat pim6stat; 1176130803Smarcel 1177130803Smarcel if (fetch_stats("net.inet6.pim.stats", off, &pim6stat, 1178130803Smarcel sizeof(pim6stat), kread) != 0) 1179130803Smarcel return; 1180130803Smarcel 1181130803Smarcel xo_emit("{T:/%s}:\n", name); 1182130803Smarcel xo_open_container(name); 1183130803Smarcel 1184130803Smarcel#define p(f, m) if (pim6stat.f || sflag <= 1) \ 1185130803Smarcel xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) 1186130803Smarcel 1187130803Smarcel p(pim6s_rcv_total, "\t{:received-packets/%ju} " 1188130803Smarcel "{N:/message%s received}\n"); 1189130803Smarcel p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} " 1190130803Smarcel "{N:/message%s received with too few bytes}\n"); 1191130803Smarcel p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " 1192130803Smarcel "{N:/message%s received with bad checksum}\n"); 1193130803Smarcel p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} " 1194130803Smarcel "{N:/message%s received with bad version}\n"); 1195130803Smarcel p(pim6s_rcv_registers, "\t{:received-registers/%ju} " 1196130803Smarcel "{N:/register%s received}\n"); 1197130803Smarcel p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} " 1198130803Smarcel "{N:/bad register%s received}\n"); 1199130803Smarcel p(pim6s_snd_registers, "\t{:sent-registers/%ju} " 1200130803Smarcel "{N:/register%s sent}\n"); 1201130803Smarcel#undef p 1202130803Smarcel xo_close_container(name); 1203130803Smarcel} 1204130803Smarcel 1205130803Smarcel/* 1206130803Smarcel * Dump raw ip6 statistics structure. 1207130803Smarcel */ 1208130803Smarcelvoid 1209130803Smarcelrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 1210130803Smarcel{ 1211130803Smarcel struct rip6stat rip6stat; 1212130803Smarcel u_quad_t delivered; 1213130803Smarcel 1214130803Smarcel if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat, 1215130803Smarcel sizeof(rip6stat), kread_counters) != 0) 1216130803Smarcel return; 1217130803Smarcel 1218130803Smarcel xo_emit("{T:/%s}:\n", name); 1219130803Smarcel xo_open_container(name); 1220130803Smarcel 1221130803Smarcel#define p(f, m) if (rip6stat.f || sflag <= 1) \ 1222130803Smarcel xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) 1223130803Smarcel 1224130803Smarcel p(rip6s_ipackets, "\t{:received-packets/%ju} " 1225130803Smarcel "{N:/message%s received}\n"); 1226130803Smarcel p(rip6s_isum, "\t{:input-checksum-computation/%ju} " 1227130803Smarcel "{N:/checksum calculation%s on inbound}\n"); 1228130803Smarcel p(rip6s_badsum, "\t{:received-bad-checksum/%ju} " 1229130803Smarcel "{N:/message%s with bad checksum}\n"); 1230130803Smarcel p(rip6s_nosock, "\t{:dropped-no-socket/%ju} " 1231130803Smarcel "{N:/message%s dropped due to no socket}\n"); 1232130803Smarcel p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} " 1233130803Smarcel "{N:/multicast message%s dropped due to no socket}\n"); 1234130803Smarcel p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} " 1235130803Smarcel "{N:/message%s dropped due to full socket buffers}\n"); 1236130803Smarcel delivered = rip6stat.rip6s_ipackets - 1237130803Smarcel rip6stat.rip6s_badsum - 1238130803Smarcel rip6stat.rip6s_nosock - 1239130803Smarcel rip6stat.rip6s_nosockmcast - 1240130803Smarcel rip6stat.rip6s_fullsock; 1241130803Smarcel if (delivered || sflag <= 1) 1242130803Smarcel xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n", 1243130803Smarcel (uintmax_t)delivered); 1244130803Smarcel p(rip6s_opackets, "\t{:sent-packets/%ju} " 1245130803Smarcel "{N:/datagram%s output}\n"); 1246130803Smarcel#undef p 1247130803Smarcel xo_close_container(name); 1248130803Smarcel} 1249130803Smarcel 1250130803Smarcel/* 1251130803Smarcel * Pretty print an Internet address (net address + port). 1252130803Smarcel * Take numeric_addr and numeric_port into consideration. 1253130803Smarcel */ 1254130803Smarcel#define GETSERVBYPORT6(port, proto, ret)\ 1255130803Smarcel{\ 1256130803Smarcel if (strcmp((proto), "tcp6") == 0)\ 1257130803Smarcel (ret) = getservbyport((int)(port), "tcp");\ 1258130803Smarcel else if (strcmp((proto), "udp6") == 0)\ 1259130803Smarcel (ret) = getservbyport((int)(port), "udp");\ 1260130803Smarcel else\ 1261130803Smarcel (ret) = getservbyport((int)(port), (proto));\ 1262130803Smarcel}; 1263130803Smarcel 1264130803Smarcelvoid 1265130803Smarcelinet6print(const char *container, struct in6_addr *in6, int port, 1266130803Smarcel const char *proto, int numeric) 1267130803Smarcel{ 1268130803Smarcel struct servent *sp = 0; 1269130803Smarcel char line[80], *cp; 1270130803Smarcel int width; 1271130803Smarcel size_t alen, plen; 1272130803Smarcel 1273130803Smarcel if (container) 1274130803Smarcel xo_open_container(container); 1275130803Smarcel 1276130803Smarcel snprintf(line, sizeof(line), "%.*s.", 1277130803Smarcel Wflag ? 39 : (Aflag && !numeric) ? 12 : 16, 1278130803Smarcel inet6name(in6)); 1279130803Smarcel alen = strlen(line); 1280130803Smarcel cp = line + alen; 1281130803Smarcel if (!numeric && port) 1282130803Smarcel GETSERVBYPORT6(port, proto, sp); 1283130803Smarcel if (sp || port == 0) 1284130803Smarcel snprintf(cp, sizeof(line) - alen, 1285130803Smarcel "%.15s", sp ? sp->s_name : "*"); 1286130803Smarcel else 1287130803Smarcel snprintf(cp, sizeof(line) - alen, 1288130803Smarcel "%d", ntohs((u_short)port)); 1289130803Smarcel width = Wflag ? 45 : Aflag ? 18 : 22; 1290130803Smarcel 1291130803Smarcel xo_emit("{d:target/%-*.*s} ", width, width, line); 1292130803Smarcel 1293130803Smarcel plen = strlen(cp); 1294130803Smarcel alen--; 1295130803Smarcel xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, 1296130803Smarcel plen, cp); 1297130803Smarcel 1298130803Smarcel if (container) 1299130803Smarcel xo_close_container(container); 1300130803Smarcel} 1301130803Smarcel 1302130803Smarcel/* 1303130803Smarcel * Construct an Internet address representation. 1304130803Smarcel * If the numeric_addr has been supplied, give 1305130803Smarcel * numeric value, otherwise try for symbolic name. 1306130803Smarcel */ 1307130803Smarcel 1308130803Smarcelchar * 1309130803Smarcelinet6name(struct in6_addr *ia6) 1310130803Smarcel{ 1311130803Smarcel struct sockaddr_in6 sin6; 1312130803Smarcel char hbuf[NI_MAXHOST], *cp; 1313130803Smarcel static char line[NI_MAXHOST]; 1314130803Smarcel static char domain[MAXHOSTNAMELEN]; 1315130803Smarcel static int first = 1; 1316130803Smarcel int flags, error; 1317130803Smarcel 1318130803Smarcel if (IN6_IS_ADDR_UNSPECIFIED(ia6)) { 1319130803Smarcel strcpy(line, "*"); 1320130803Smarcel return (line); 1321130803Smarcel } 1322130803Smarcel if (first && !numeric_addr) { 1323130803Smarcel first = 0; 1324130803Smarcel if (gethostname(domain, sizeof(domain)) == 0 && 1325130803Smarcel (cp = strchr(domain, '.'))) 1326130803Smarcel strlcpy(domain, cp + 1, sizeof(domain)); 1327130803Smarcel else 1328130803Smarcel domain[0] = 0; 1329130803Smarcel } 1330130803Smarcel memset(&sin6, 0, sizeof(sin6)); 1331130803Smarcel memcpy(&sin6.sin6_addr, ia6, sizeof(*ia6)); 1332130803Smarcel sin6.sin6_family = AF_INET6; 1333130803Smarcel /* XXX: ia6.s6_addr[2] can contain scopeid. */ 1334130803Smarcel in6_fillscopeid(&sin6); 1335130803Smarcel flags = (numeric_addr) ? NI_NUMERICHOST : 0; 1336130803Smarcel error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, 1337130803Smarcel sizeof(hbuf), NULL, 0, flags); 1338130803Smarcel if (error == 0) { 1339130803Smarcel if ((flags & NI_NUMERICHOST) == 0 && 1340130803Smarcel (cp = strchr(hbuf, '.')) && 1341130803Smarcel !strcmp(cp + 1, domain)) 1342130803Smarcel *cp = 0; 1343130803Smarcel strlcpy(line, hbuf, sizeof(line)); 1344130803Smarcel } else { 1345130803Smarcel /* XXX: this should not happen. */ 1346130803Smarcel snprintf(line, sizeof(line), "%s", 1347130803Smarcel inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, 1348130803Smarcel sizeof(ntop_buf))); 1349130803Smarcel } 1350130803Smarcel return (line); 1351130803Smarcel} 1352130803Smarcel#endif /*INET6*/ 1353130803Smarcel