inet6.c revision 302408
1290931Srodrigc/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2290931Srodrigc/*- 3290931Srodrigc * Copyright (c) 1983, 1988, 1993 4290931Srodrigc * The Regents of the University of California. All rights reserved. 5290931Srodrigc * 6290931Srodrigc * Redistribution and use in source and binary forms, with or without 7290931Srodrigc * modification, are permitted provided that the following conditions 8290931Srodrigc * are met: 9290931Srodrigc * 1. Redistributions of source code must retain the above copyright 10290931Srodrigc * notice, this list of conditions and the following disclaimer. 11290931Srodrigc * 2. Redistributions in binary form must reproduce the above copyright 12290931Srodrigc * notice, this list of conditions and the following disclaimer in the 13290931Srodrigc * documentation and/or other materials provided with the distribution. 14290931Srodrigc * 4. Neither the name of the University nor the names of its contributors 15290931Srodrigc * may be used to endorse or promote products derived from this software 16290931Srodrigc * without specific prior written permission. 17290931Srodrigc * 18290931Srodrigc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19290931Srodrigc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20290931Srodrigc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21290931Srodrigc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22290931Srodrigc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23290931Srodrigc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24290931Srodrigc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25290931Srodrigc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26290931Srodrigc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27290931Srodrigc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28290931Srodrigc * SUCH DAMAGE. 29290931Srodrigc */ 30290931Srodrigc 31290931Srodrigc#if 0 32290931Srodrigc#ifndef lint 33290931Srodrigcstatic char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; 34290931Srodrigc#endif /* not lint */ 35290931Srodrigc#endif 36290931Srodrigc 37290931Srodrigc#include <sys/cdefs.h> 38290931Srodrigc__FBSDID("$FreeBSD: stable/11/usr.bin/netstat/inet6.c 287649 2015-09-11 04:37:01Z markj $"); 39290931Srodrigc 40290931Srodrigc#ifdef INET6 41290931Srodrigc#include <sys/param.h> 42290931Srodrigc#include <sys/socket.h> 43290931Srodrigc#include <sys/socketvar.h> 44290931Srodrigc#include <sys/ioctl.h> 45290931Srodrigc#include <sys/mbuf.h> 46290931Srodrigc#include <sys/protosw.h> 47290931Srodrigc 48290931Srodrigc#include <net/route.h> 49290931Srodrigc#include <net/if.h> 50290931Srodrigc#include <netinet/in.h> 51290931Srodrigc#include <netinet/ip6.h> 52290931Srodrigc#include <netinet/icmp6.h> 53290931Srodrigc#include <netinet/in_systm.h> 54290931Srodrigc#include <netinet6/in6_pcb.h> 55290931Srodrigc#include <netinet6/in6_var.h> 56290931Srodrigc#include <netinet6/ip6_var.h> 57290931Srodrigc#include <netinet6/pim6_var.h> 58290931Srodrigc#include <netinet6/raw_ip6.h> 59290931Srodrigc 60290931Srodrigc#include <arpa/inet.h> 61290931Srodrigc#include <netdb.h> 62290931Srodrigc 63290931Srodrigc#include <err.h> 64290931Srodrigc#include <stdint.h> 65290931Srodrigc#include <stdio.h> 66290931Srodrigc#include <stdbool.h> 67290931Srodrigc#include <errno.h> 68290931Srodrigc#include <string.h> 69290931Srodrigc#include <unistd.h> 70290931Srodrigc#include <libxo/xo.h> 71290931Srodrigc#include "netstat.h" 72290931Srodrigc 73290931Srodrigcchar *inet6name(struct in6_addr *); 74290940Srodrigc 75290931Srodrigcstatic char ntop_buf[INET6_ADDRSTRLEN]; 76290931Srodrigc 77290931Srodrigcstatic const char *ip6nh[] = { 78290931Srodrigc "hop by hop", 79290931Srodrigc "ICMP", 80290931Srodrigc "IGMP", 81290940Srodrigc "#3", 82290931Srodrigc "IP", 83290931Srodrigc "#5", 84290931Srodrigc "TCP", 85290931Srodrigc "#7", 86290931Srodrigc "#8", 87290931Srodrigc "#9", 88290931Srodrigc "#10", 89290931Srodrigc "#11", 90290931Srodrigc "#12", 91290931Srodrigc "#13", 92290931Srodrigc "#14", 93290931Srodrigc "#15", 94290931Srodrigc "#16", 95290931Srodrigc "UDP", 96290931Srodrigc "#18", 97290931Srodrigc "#19", 98290931Srodrigc "#20", 99290931Srodrigc "#21", 100290931Srodrigc "IDP", 101290931Srodrigc "#23", 102290931Srodrigc "#24", 103290931Srodrigc "#25", 104290931Srodrigc "#26", 105290931Srodrigc "#27", 106290931Srodrigc "#28", 107290931Srodrigc "TP", 108290931Srodrigc "#30", 109290931Srodrigc "#31", 110290931Srodrigc "#32", 111290931Srodrigc "#33", 112290931Srodrigc "#34", 113290931Srodrigc "#35", 114290931Srodrigc "#36", 115290931Srodrigc "#37", 116290931Srodrigc "#38", 117290931Srodrigc "#39", 118290931Srodrigc "#40", 119290931Srodrigc "IP6", 120290931Srodrigc "#42", 121290931Srodrigc "routing", 122290931Srodrigc "fragment", 123290931Srodrigc "#45", 124290931Srodrigc "#46", 125290931Srodrigc "#47", 126290931Srodrigc "#48", 127290931Srodrigc "#49", 128290931Srodrigc "ESP", 129290931Srodrigc "AH", 130290931Srodrigc "#52", 131290931Srodrigc "#53", 132290931Srodrigc "#54", 133290931Srodrigc "#55", 134290931Srodrigc "#56", 135290931Srodrigc "#57", 136290931Srodrigc "ICMP6", 137290931Srodrigc "no next header", 138290931Srodrigc "destination option", 139290931Srodrigc "#61", 140290931Srodrigc "mobility", 141290931Srodrigc "#63", 142290931Srodrigc "#64", 143290931Srodrigc "#65", 144290931Srodrigc "#66", 145290931Srodrigc "#67", 146290931Srodrigc "#68", 147290931Srodrigc "#69", 148290931Srodrigc "#70", 149290931Srodrigc "#71", 150290931Srodrigc "#72", 151290931Srodrigc "#73", 152290931Srodrigc "#74", 153290931Srodrigc "#75", 154290931Srodrigc "#76", 155290931Srodrigc "#77", 156290931Srodrigc "#78", 157290931Srodrigc "#79", 158290931Srodrigc "ISOIP", 159290931Srodrigc "#81", 160290931Srodrigc "#82", 161290931Srodrigc "#83", 162290931Srodrigc "#84", 163290931Srodrigc "#85", 164290931Srodrigc "#86", 165290931Srodrigc "#87", 166290931Srodrigc "#88", 167290931Srodrigc "OSPF", 168290931Srodrigc "#80", 169290931Srodrigc "#91", 170290931Srodrigc "#92", 171290931Srodrigc "#93", 172290931Srodrigc "#94", 173290931Srodrigc "#95", 174290931Srodrigc "#96", 175290931Srodrigc "Ethernet", 176290931Srodrigc "#98", 177290931Srodrigc "#99", 178290931Srodrigc "#100", 179290931Srodrigc "#101", 180290931Srodrigc "#102", 181290931Srodrigc "PIM", 182290931Srodrigc "#104", 183290931Srodrigc "#105", 184290931Srodrigc "#106", 185290931Srodrigc "#107", 186290931Srodrigc "#108", 187290931Srodrigc "#109", 188290931Srodrigc "#110", 189290931Srodrigc "#111", 190290931Srodrigc "#112", 191290931Srodrigc "#113", 192290931Srodrigc "#114", 193290931Srodrigc "#115", 194290931Srodrigc "#116", 195290931Srodrigc "#117", 196290931Srodrigc "#118", 197290931Srodrigc "#119", 198290931Srodrigc "#120", 199290931Srodrigc "#121", 200290931Srodrigc "#122", 201290931Srodrigc "#123", 202290931Srodrigc "#124", 203290931Srodrigc "#125", 204290931Srodrigc "#126", 205290931Srodrigc "#127", 206290931Srodrigc "#128", 207290931Srodrigc "#129", 208290931Srodrigc "#130", 209290931Srodrigc "#131", 210290931Srodrigc "#132", 211290931Srodrigc "#133", 212290931Srodrigc "#134", 213290931Srodrigc "#135", 214290931Srodrigc "#136", 215290931Srodrigc "#137", 216290931Srodrigc "#138", 217290931Srodrigc "#139", 218290931Srodrigc "#140", 219290931Srodrigc "#141", 220290931Srodrigc "#142", 221290931Srodrigc "#143", 222290931Srodrigc "#144", 223290931Srodrigc "#145", 224290931Srodrigc "#146", 225290931Srodrigc "#147", 226290931Srodrigc "#148", 227290931Srodrigc "#149", 228290931Srodrigc "#150", 229290931Srodrigc "#151", 230290931Srodrigc "#152", 231290931Srodrigc "#153", 232290931Srodrigc "#154", 233290931Srodrigc "#155", 234290931Srodrigc "#156", 235290931Srodrigc "#157", 236290931Srodrigc "#158", 237290931Srodrigc "#159", 238290931Srodrigc "#160", 239290931Srodrigc "#161", 240290931Srodrigc "#162", 241290931Srodrigc "#163", 242290931Srodrigc "#164", 243290931Srodrigc "#165", 244290931Srodrigc "#166", 245290931Srodrigc "#167", 246290931Srodrigc "#168", 247290931Srodrigc "#169", 248290931Srodrigc "#170", 249290931Srodrigc "#171", 250290931Srodrigc "#172", 251290931Srodrigc "#173", 252290931Srodrigc "#174", 253290931Srodrigc "#175", 254290931Srodrigc "#176", 255290931Srodrigc "#177", 256290931Srodrigc "#178", 257290931Srodrigc "#179", 258290931Srodrigc "#180", 259290931Srodrigc "#181", 260290931Srodrigc "#182", 261290931Srodrigc "#183", 262290931Srodrigc "#184", 263290931Srodrigc "#185", 264290931Srodrigc "#186", 265290931Srodrigc "#187", 266290931Srodrigc "#188", 267290931Srodrigc "#189", 268290931Srodrigc "#180", 269290931Srodrigc "#191", 270290931Srodrigc "#192", 271290931Srodrigc "#193", 272290931Srodrigc "#194", 273290931Srodrigc "#195", 274290931Srodrigc "#196", 275290931Srodrigc "#197", 276290931Srodrigc "#198", 277290931Srodrigc "#199", 278290931Srodrigc "#200", 279290931Srodrigc "#201", 280290931Srodrigc "#202", 281290931Srodrigc "#203", 282290931Srodrigc "#204", 283290931Srodrigc "#205", 284290931Srodrigc "#206", 285290931Srodrigc "#207", 286290931Srodrigc "#208", 287290931Srodrigc "#209", 288290931Srodrigc "#210", 289290931Srodrigc "#211", 290290931Srodrigc "#212", 291290931Srodrigc "#213", 292290931Srodrigc "#214", 293290931Srodrigc "#215", 294290931Srodrigc "#216", 295290931Srodrigc "#217", 296290931Srodrigc "#218", 297290931Srodrigc "#219", 298290931Srodrigc "#220", 299290931Srodrigc "#221", 300290931Srodrigc "#222", 301290931Srodrigc "#223", 302290931Srodrigc "#224", 303290931Srodrigc "#225", 304290931Srodrigc "#226", 305290931Srodrigc "#227", 306290931Srodrigc "#228", 307290931Srodrigc "#229", 308290931Srodrigc "#230", 309290931Srodrigc "#231", 310290931Srodrigc "#232", 311290931Srodrigc "#233", 312290931Srodrigc "#234", 313290931Srodrigc "#235", 314290931Srodrigc "#236", 315290931Srodrigc "#237", 316290931Srodrigc "#238", 317290931Srodrigc "#239", 318290931Srodrigc "#240", 319290931Srodrigc "#241", 320290931Srodrigc "#242", 321290931Srodrigc "#243", 322290931Srodrigc "#244", 323290931Srodrigc "#245", 324290931Srodrigc "#246", 325290931Srodrigc "#247", 326290931Srodrigc "#248", 327290931Srodrigc "#249", 328290931Srodrigc "#250", 329290931Srodrigc "#251", 330290931Srodrigc "#252", 331290931Srodrigc "#253", 332290931Srodrigc "#254", 333290931Srodrigc "#255", 334290931Srodrigc}; 335290931Srodrigc 336290931Srodrigcstatic const char *srcrule_str[] = { 337290931Srodrigc "first candidate", 338290931Srodrigc "same address", 339290931Srodrigc "appropriate scope", 340290931Srodrigc "deprecated address", 341290931Srodrigc "home address", 342290931Srodrigc "outgoing interface", 343290931Srodrigc "matching label", 344290931Srodrigc "public/temporary address", 345290931Srodrigc "alive interface", 346290931Srodrigc "better virtual status", 347290931Srodrigc "preferred source", 348290931Srodrigc "rule #11", 349290931Srodrigc "rule #12", 350290931Srodrigc "rule #13", 351290931Srodrigc "longest match", 352290931Srodrigc "rule #15", 353290931Srodrigc}; 354290931Srodrigc 355290931Srodrigc/* 356290931Srodrigc * Dump IP6 statistics structure. 357290931Srodrigc */ 358290931Srodrigcvoid 359290931Srodrigcip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 360290931Srodrigc{ 361290931Srodrigc struct ip6stat ip6stat; 362290931Srodrigc int first, i; 363290931Srodrigc 364290931Srodrigc if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat, 365290931Srodrigc sizeof(ip6stat), kread_counters) != 0) 366290931Srodrigc return; 367290931Srodrigc 368290931Srodrigc xo_open_container(name); 369290931Srodrigc xo_emit("{T:/%s}:\n", name); 370290931Srodrigc 371290931Srodrigc#define p(f, m) if (ip6stat.f || sflag <= 1) \ 372290931Srodrigc xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) 373290931Srodrigc#define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 374290931Srodrigc xo_emit(m, (uintmax_t)ip6stat.f) 375290931Srodrigc 376290931Srodrigc p(ip6s_total, "\t{:received-packets/%ju} " 377290931Srodrigc "{N:/total packet%s received}\n"); 378290931Srodrigc p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} " 379290931Srodrigc "{N:/with size smaller than minimum}\n"); 380290931Srodrigc p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} " 381290931Srodrigc "{N:/with data size < data length}\n"); 382290931Srodrigc p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} " 383290931Srodrigc "{N:/with bad options}\n"); 384290931Srodrigc p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} " 385290931Srodrigc "{N:/with incorrect version number}\n"); 386290931Srodrigc p(ip6s_fragments, "\t{:received-fragments/%ju} " 387290931Srodrigc "{N:/fragment%s received}\n"); 388290931Srodrigc p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} " 389290931Srodrigc "{N:/fragment%s dropped (dup or out of space)}\n"); 390290931Srodrigc p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} " 391290931Srodrigc "{N:/fragment%s dropped after timeout}\n"); 392290931Srodrigc p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} " 393290931Srodrigc "{N:/fragment%s that exceeded limit}\n"); 394290931Srodrigc p(ip6s_reassembled, "\t{:reassembled-packets/%ju} " 395290931Srodrigc "{N:/packet%s reassembled ok}\n"); 396290931Srodrigc p(ip6s_delivered, "\t{:received-local-packets/%ju} " 397290931Srodrigc "{N:/packet%s for this host}\n"); 398290931Srodrigc p(ip6s_forward, "\t{:forwarded-packets/%ju} " 399290931Srodrigc "{N:/packet%s forwarded}\n"); 400290931Srodrigc p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} " 401290931Srodrigc "{N:/packet%s not forwardable}\n"); 402290931Srodrigc p(ip6s_redirectsent, "\t{:sent-redirects/%ju} " 403290931Srodrigc "{N:/redirect%s sent}\n"); 404290931Srodrigc p(ip6s_localout, "\t{:sent-packets/%ju} " 405290931Srodrigc "{N:/packet%s sent from this host}\n"); 406290931Srodrigc p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} " 407290931Srodrigc "{N:/packet%s sent with fabricated ip header}\n"); 408290931Srodrigc p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} " 409290931Srodrigc "{N:/output packet%s dropped due to no bufs, etc.}\n"); 410290931Srodrigc p(ip6s_noroute, "\t{:discard-no-route/%ju} " 411290931Srodrigc "{N:/output packet%s discarded due to no route}\n"); 412290931Srodrigc p(ip6s_fragmented, "\t{:sent-fragments/%ju} " 413290931Srodrigc "{N:/output datagram%s fragmented}\n"); 414290931Srodrigc p(ip6s_ofragments, "\t{:fragments-created/%ju} " 415290931Srodrigc "{N:/fragment%s created}\n"); 416290931Srodrigc p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} " 417290931Srodrigc "{N:/datagram%s that can't be fragmented}\n"); 418290931Srodrigc p(ip6s_badscope, "\t{:discard-scope-violations/%ju} " 419290931Srodrigc "{N:/packet%s that violated scope rules}\n"); 420290931Srodrigc p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} " 421290931Srodrigc "{N:/multicast packet%s which we don't join}\n"); 422290931Srodrigc for (first = 1, i = 0; i < IP6S_HDRCNT; i++) 423290931Srodrigc if (ip6stat.ip6s_nxthist[i] != 0) { 424290931Srodrigc if (first) { 425290931Srodrigc xo_emit("\t{T:Input histogram}:\n"); 426290931Srodrigc xo_open_list("input-histogram"); 427290931Srodrigc first = 0; 428290931Srodrigc } 429290931Srodrigc xo_open_instance("input-histogram"); 430290931Srodrigc xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i], 431290931Srodrigc (uintmax_t)ip6stat.ip6s_nxthist[i]); 432290931Srodrigc xo_close_instance("input-histogram"); 433290931Srodrigc } 434290931Srodrigc if (!first) 435290931Srodrigc xo_close_list("input-histogram"); 436290931Srodrigc 437290931Srodrigc xo_open_container("mbuf-statistics"); 438290931Srodrigc xo_emit("\t{T:Mbuf statistics}:\n"); 439290931Srodrigc xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n", 440290931Srodrigc (uintmax_t)ip6stat.ip6s_m1); 441290931Srodrigc for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { 442290931Srodrigc char ifbuf[IFNAMSIZ]; 443290931Srodrigc if (ip6stat.ip6s_m2m[i] != 0) { 444290931Srodrigc if (first) { 445290931Srodrigc xo_emit("\t\t{N:two or more mbuf}:\n"); 446290931Srodrigc xo_open_list("mbuf-data"); 447290931Srodrigc first = 0; 448290931Srodrigc } 449290931Srodrigc xo_open_instance("mbuf-data"); 450290931Srodrigc xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n", 451290931Srodrigc if_indextoname(i, ifbuf), 452290931Srodrigc (uintmax_t)ip6stat.ip6s_m2m[i]); 453290931Srodrigc xo_close_instance("mbuf-data"); 454290931Srodrigc } 455290931Srodrigc } 456290931Srodrigc if (!first) 457290931Srodrigc xo_close_list("mbuf-data"); 458290931Srodrigc xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n", 459290931Srodrigc (uintmax_t)ip6stat.ip6s_mext1); 460290931Srodrigc xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} " 461290931Srodrigc "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m); 462290931Srodrigc xo_close_container("mbuf-statistics"); 463290931Srodrigc 464290931Srodrigc p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} " 465290931Srodrigc "{N:/packet%s whose headers are not contiguous}\n"); 466290931Srodrigc p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} " 467290931Srodrigc "{N:/tunneling packet%s that can't find gif}\n"); 468290931Srodrigc p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} " 469290931Srodrigc "{N:/packet%s discarded because of too many headers}\n"); 470290931Srodrigc 471290931Srodrigc /* for debugging source address selection */ 472290931Srodrigc#define PRINT_SCOPESTAT(s,i) do {\ 473290931Srodrigc switch(i) { /* XXX hardcoding in each case */\ 474290931Srodrigc case 1:\ 475290931Srodrigc p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \ 476290931Srodrigc "{N:/interface-local%s}\n"); \ 477290931Srodrigc break;\ 478290931Srodrigc case 2:\ 479290931Srodrigc p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \ 480290931Srodrigc "{N:/link-local%s}\n"); \ 481290931Srodrigc break;\ 482290931Srodrigc case 5:\ 483290931Srodrigc p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \ 484290931Srodrigc "{N:/site-local%s}\n");\ 485290931Srodrigc break;\ 486290931Srodrigc case 14:\ 487290931Srodrigc p(s,"\t\t{ke:name/globals}{:count/%ju} " \ 488290931Srodrigc "{N:/global%s}\n");\ 489290931Srodrigc break;\ 490290931Srodrigc default:\ 491290931Srodrigc xo_emit("\t\t{qke:name/%x}{:count/%ju} " \ 492290931Srodrigc "addresses scope=%x\n",\ 493290931Srodrigc i, (uintmax_t)ip6stat.s, i); \ 494290931Srodrigc }\ 495290931Srodrigc } while (0); 496290931Srodrigc 497290931Srodrigc xo_open_container("source-address-selection"); 498290931Srodrigc p(ip6s_sources_none, "\t{:address-selection-failures/%ju} " 499290931Srodrigc "{N:/failure%s of source address selection}\n"); 500290931Srodrigc 501290931Srodrigc for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 502290931Srodrigc if (ip6stat.ip6s_sources_sameif[i]) { 503290931Srodrigc if (first) { 504290931Srodrigc xo_open_list("outgoing-interface"); 505290931Srodrigc xo_emit("\tsource addresses on an outgoing " 506290931Srodrigc "I/F\n"); 507290931Srodrigc first = 0; 508290931Srodrigc } 509290931Srodrigc xo_open_instance("outgoing-interface"); 510290931Srodrigc PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); 511290931Srodrigc xo_close_instance("outgoing-interface"); 512290931Srodrigc } 513290931Srodrigc } 514290931Srodrigc if (!first) 515290931Srodrigc xo_close_list("outgoing-interface"); 516290931Srodrigc 517290931Srodrigc for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 518290931Srodrigc if (ip6stat.ip6s_sources_otherif[i]) { 519290931Srodrigc if (first) { 520290931Srodrigc xo_open_list("non-outgoing-interface"); 521290931Srodrigc xo_emit("\tsource addresses on a non-outgoing " 522290931Srodrigc "I/F\n"); 523290931Srodrigc first = 0; 524290931Srodrigc } 525290931Srodrigc xo_open_instance("non-outgoing-interface"); 526290931Srodrigc PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); 527290931Srodrigc xo_close_instance("non-outgoing-interface"); 528290931Srodrigc } 529290931Srodrigc } 530290931Srodrigc if (!first) 531290931Srodrigc xo_close_list("non-outgoing-interface"); 532290931Srodrigc 533290931Srodrigc for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 534290931Srodrigc if (ip6stat.ip6s_sources_samescope[i]) { 535290931Srodrigc if (first) { 536290931Srodrigc xo_open_list("same-source"); 537290931Srodrigc xo_emit("\tsource addresses of same scope\n"); 538290931Srodrigc first = 0; 539290931Srodrigc } 540290931Srodrigc xo_open_instance("same-source"); 541290931Srodrigc PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); 542290931Srodrigc xo_close_instance("same-source"); 543290931Srodrigc } 544290931Srodrigc } 545290931Srodrigc if (!first) 546290931Srodrigc xo_close_list("same-source"); 547290931Srodrigc 548290931Srodrigc for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 549290931Srodrigc if (ip6stat.ip6s_sources_otherscope[i]) { 550290931Srodrigc if (first) { 551290931Srodrigc xo_open_list("different-scope"); 552290931Srodrigc xo_emit("\tsource addresses of a different " 553290931Srodrigc "scope\n"); 554290931Srodrigc first = 0; 555290931Srodrigc } 556290931Srodrigc xo_open_instance("different-scope"); 557290931Srodrigc PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); 558290931Srodrigc xo_close_instance("different-scope"); 559290931Srodrigc } 560290931Srodrigc } 561290931Srodrigc if (!first) 562290931Srodrigc xo_close_list("different-scope"); 563290931Srodrigc 564290931Srodrigc for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 565290931Srodrigc if (ip6stat.ip6s_sources_deprecated[i]) { 566290931Srodrigc if (first) { 567290931Srodrigc xo_open_list("deprecated-source"); 568290931Srodrigc xo_emit("\tdeprecated source addresses\n"); 569290931Srodrigc first = 0; 570290931Srodrigc } 571290931Srodrigc xo_open_instance("deprecated-source"); 572290931Srodrigc PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); 573290931Srodrigc xo_close_instance("deprecated-source"); 574290931Srodrigc } 575290931Srodrigc } 576290931Srodrigc if (!first) 577290931Srodrigc xo_close_list("deprecated-source"); 578290931Srodrigc 579290931Srodrigc for (first = 1, i = 0; i < IP6S_RULESMAX; i++) { 580290931Srodrigc if (ip6stat.ip6s_sources_rule[i]) { 581290931Srodrigc if (first) { 582290931Srodrigc xo_open_list("rules-applied"); 583290931Srodrigc xo_emit("\t{T:Source addresses selection " 584290931Srodrigc "rule applied}:\n"); 585290931Srodrigc first = 0; 586290931Srodrigc } 587290931Srodrigc xo_open_instance("rules-applied"); 588290931Srodrigc xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n", 589290931Srodrigc srcrule_str[i], 590290931Srodrigc (uintmax_t)ip6stat.ip6s_sources_rule[i], 591290931Srodrigc srcrule_str[i]); 592290931Srodrigc xo_close_instance("rules-applied"); 593290931Srodrigc } 594290931Srodrigc } 595290931Srodrigc if (!first) 596290931Srodrigc xo_close_list("rules-applied"); 597290931Srodrigc 598290931Srodrigc xo_close_container("source-address-selection"); 599290931Srodrigc 600290931Srodrigc#undef p 601290931Srodrigc#undef p1a 602290931Srodrigc xo_close_container(name); 603290931Srodrigc} 604290931Srodrigc 605290931Srodrigc/* 606290931Srodrigc * Dump IPv6 per-interface statistics based on RFC 2465. 607290931Srodrigc */ 608290931Srodrigcvoid 609290931Srodrigcip6_ifstats(char *ifname) 610290931Srodrigc{ 611290931Srodrigc struct in6_ifreq ifr; 612290931Srodrigc int s; 613290931Srodrigc 614290931Srodrigc#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 615290931Srodrigc xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, \ 616290931Srodrigc plural(ifr.ifr_ifru.ifru_stat.f)) 617290931Srodrigc 618290931Srodrigc if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 619290931Srodrigc xo_warn("Warning: socket(AF_INET6)"); 620290931Srodrigc return; 621290931Srodrigc } 622290931Srodrigc 623290931Srodrigc strcpy(ifr.ifr_name, ifname); 624290931Srodrigc if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 625290931Srodrigc if (errno != EPFNOSUPPORT) 626290931Srodrigc xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)"); 627290931Srodrigc goto end; 628290931Srodrigc } 629290931Srodrigc 630290931Srodrigc xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name); 631290931Srodrigc 632290931Srodrigc xo_open_instance("ip6-interface-statistics"); 633290931Srodrigc xo_emit("{ke:name/%s}", ifr.ifr_name); 634290931Srodrigc 635290931Srodrigc p(ifs6_in_receive, "\t{:received-packets/%ju} " 636290931Srodrigc "{N:/total input datagram%s}\n"); 637290931Srodrigc p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} " 638290931Srodrigc "{N:/datagram%s with invalid header received}\n"); 639290931Srodrigc p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} " 640290931Srodrigc "{N:/datagram%s exceeded MTU received}\n"); 641290931Srodrigc p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} " 642290931Srodrigc "{N:/datagram%s with no route received}\n"); 643290931Srodrigc p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} " 644290931Srodrigc "{N:/datagram%s with invalid dst received}\n"); 645290931Srodrigc p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} " 646290931Srodrigc "{N:/datagram%s with unknown proto received}\n"); 647290931Srodrigc p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} " 648290931Srodrigc "{N:/truncated datagram%s received}\n"); 649290931Srodrigc p(ifs6_in_discard, "\t{:dropped-discarded/%ju} " 650290931Srodrigc "{N:/input datagram%s discarded}\n"); 651290931Srodrigc p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} " 652290931Srodrigc "{N:/datagram%s delivered to an upper layer protocol}\n"); 653290931Srodrigc p(ifs6_out_forward, "\t{:sent-forwarded/%ju} " 654290931Srodrigc "{N:/datagram%s forwarded to this interface}\n"); 655290931Srodrigc p(ifs6_out_request, "\t{:sent-packets/%ju} " 656290931Srodrigc "{N:/datagram%s sent from an upper layer protocol}\n"); 657290931Srodrigc p(ifs6_out_discard, "\t{:discard-packets/%ju} " 658290931Srodrigc "{N:/total discarded output datagram%s}\n"); 659290931Srodrigc p(ifs6_out_fragok, "\t{:discard-fragments/%ju} " 660290931Srodrigc "{N:/output datagram%s fragmented}\n"); 661290931Srodrigc p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} " 662290931Srodrigc "{N:/output datagram%s failed on fragment}\n"); 663290931Srodrigc p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} " 664290931Srodrigc "{N:/output datagram%s succeeded on fragment}\n"); 665290931Srodrigc p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} " 666290931Srodrigc "{N:/incoming datagram%s fragmented}\n"); 667290931Srodrigc p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} " 668290931Srodrigc "{N:/datagram%s reassembled}\n"); 669290931Srodrigc p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} " 670290931Srodrigc "{N:/datagram%s failed on reassembly}\n"); 671290931Srodrigc p(ifs6_in_mcast, "\t{:received-multicast/%ju} " 672290931Srodrigc "{N:/multicast datagram%s received}\n"); 673290931Srodrigc p(ifs6_out_mcast, "\t{:sent-multicast/%ju} " 674290931Srodrigc "{N:/multicast datagram%s sent}\n"); 675290931Srodrigc 676290931Srodrigc end: 677290931Srodrigc xo_close_instance("ip6-interface-statistics"); 678290931Srodrigc close(s); 679290931Srodrigc 680290931Srodrigc#undef p 681290931Srodrigc} 682290931Srodrigc 683290931Srodrigcstatic const char *icmp6names[] = { 684290931Srodrigc "#0", 685290931Srodrigc "unreach", 686290931Srodrigc "packet too big", 687290931Srodrigc "time exceed", 688290931Srodrigc "parameter problem", 689290931Srodrigc "#5", 690290931Srodrigc "#6", 691290931Srodrigc "#7", 692290931Srodrigc "#8", 693290931Srodrigc "#9", 694290931Srodrigc "#10", 695290931Srodrigc "#11", 696290931Srodrigc "#12", 697290931Srodrigc "#13", 698290931Srodrigc "#14", 699290931Srodrigc "#15", 700290931Srodrigc "#16", 701290931Srodrigc "#17", 702290931Srodrigc "#18", 703290931Srodrigc "#19", 704290931Srodrigc "#20", 705 "#21", 706 "#22", 707 "#23", 708 "#24", 709 "#25", 710 "#26", 711 "#27", 712 "#28", 713 "#29", 714 "#30", 715 "#31", 716 "#32", 717 "#33", 718 "#34", 719 "#35", 720 "#36", 721 "#37", 722 "#38", 723 "#39", 724 "#40", 725 "#41", 726 "#42", 727 "#43", 728 "#44", 729 "#45", 730 "#46", 731 "#47", 732 "#48", 733 "#49", 734 "#50", 735 "#51", 736 "#52", 737 "#53", 738 "#54", 739 "#55", 740 "#56", 741 "#57", 742 "#58", 743 "#59", 744 "#60", 745 "#61", 746 "#62", 747 "#63", 748 "#64", 749 "#65", 750 "#66", 751 "#67", 752 "#68", 753 "#69", 754 "#70", 755 "#71", 756 "#72", 757 "#73", 758 "#74", 759 "#75", 760 "#76", 761 "#77", 762 "#78", 763 "#79", 764 "#80", 765 "#81", 766 "#82", 767 "#83", 768 "#84", 769 "#85", 770 "#86", 771 "#87", 772 "#88", 773 "#89", 774 "#80", 775 "#91", 776 "#92", 777 "#93", 778 "#94", 779 "#95", 780 "#96", 781 "#97", 782 "#98", 783 "#99", 784 "#100", 785 "#101", 786 "#102", 787 "#103", 788 "#104", 789 "#105", 790 "#106", 791 "#107", 792 "#108", 793 "#109", 794 "#110", 795 "#111", 796 "#112", 797 "#113", 798 "#114", 799 "#115", 800 "#116", 801 "#117", 802 "#118", 803 "#119", 804 "#120", 805 "#121", 806 "#122", 807 "#123", 808 "#124", 809 "#125", 810 "#126", 811 "#127", 812 "echo", 813 "echo reply", 814 "multicast listener query", 815 "MLDv1 listener report", 816 "MLDv1 listener done", 817 "router solicitation", 818 "router advertisement", 819 "neighbor solicitation", 820 "neighbor advertisement", 821 "redirect", 822 "router renumbering", 823 "node information request", 824 "node information reply", 825 "inverse neighbor solicitation", 826 "inverse neighbor advertisement", 827 "MLDv2 listener report", 828 "#144", 829 "#145", 830 "#146", 831 "#147", 832 "#148", 833 "#149", 834 "#150", 835 "#151", 836 "#152", 837 "#153", 838 "#154", 839 "#155", 840 "#156", 841 "#157", 842 "#158", 843 "#159", 844 "#160", 845 "#161", 846 "#162", 847 "#163", 848 "#164", 849 "#165", 850 "#166", 851 "#167", 852 "#168", 853 "#169", 854 "#170", 855 "#171", 856 "#172", 857 "#173", 858 "#174", 859 "#175", 860 "#176", 861 "#177", 862 "#178", 863 "#179", 864 "#180", 865 "#181", 866 "#182", 867 "#183", 868 "#184", 869 "#185", 870 "#186", 871 "#187", 872 "#188", 873 "#189", 874 "#180", 875 "#191", 876 "#192", 877 "#193", 878 "#194", 879 "#195", 880 "#196", 881 "#197", 882 "#198", 883 "#199", 884 "#200", 885 "#201", 886 "#202", 887 "#203", 888 "#204", 889 "#205", 890 "#206", 891 "#207", 892 "#208", 893 "#209", 894 "#210", 895 "#211", 896 "#212", 897 "#213", 898 "#214", 899 "#215", 900 "#216", 901 "#217", 902 "#218", 903 "#219", 904 "#220", 905 "#221", 906 "#222", 907 "#223", 908 "#224", 909 "#225", 910 "#226", 911 "#227", 912 "#228", 913 "#229", 914 "#230", 915 "#231", 916 "#232", 917 "#233", 918 "#234", 919 "#235", 920 "#236", 921 "#237", 922 "#238", 923 "#239", 924 "#240", 925 "#241", 926 "#242", 927 "#243", 928 "#244", 929 "#245", 930 "#246", 931 "#247", 932 "#248", 933 "#249", 934 "#250", 935 "#251", 936 "#252", 937 "#253", 938 "#254", 939 "#255", 940}; 941 942/* 943 * Dump ICMP6 statistics. 944 */ 945void 946icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 947{ 948 struct icmp6stat icmp6stat; 949 int i, first; 950 951 if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat, 952 sizeof(icmp6stat), kread_counters) != 0) 953 return; 954 955 xo_emit("{T:/%s}:\n", name); 956 xo_open_container(name); 957 958#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 959 xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) 960#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ 961 xo_emit(m, (uintmax_t)icmp6stat.f) 962 963 p(icp6s_error, "\t{:icmp6-calls/%ju} " 964 "{N:/call%s to icmp6_error}\n"); 965 p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} " 966 "{N:/error%s not generated in response to an icmp6 message}\n"); 967 p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} " 968 "{N:/error%s not generated because of rate limitation}\n"); 969#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) 970 for (first = 1, i = 0; i < NELEM; i++) 971 if (icmp6stat.icp6s_outhist[i] != 0) { 972 if (first) { 973 xo_open_list("output-histogram"); 974 xo_emit("\t{T:Output histogram}:\n"); 975 first = 0; 976 } 977 xo_open_instance("output-histogram"); 978 xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 979 icmp6names[i], 980 (uintmax_t)icmp6stat.icp6s_outhist[i]); 981 xo_close_instance("output-histogram"); 982 } 983 if (!first) 984 xo_close_list("output-histogram"); 985#undef NELEM 986 987 p(icp6s_badcode, "\t{:dropped-bad-code/%ju} " 988 "{N:/message%s with bad code fields}\n"); 989 p(icp6s_tooshort, "\t{:dropped-too-short/%ju} " 990 "{N:/message%s < minimum length}\n"); 991 p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} " 992 "{N:/bad checksum%s}\n"); 993 p(icp6s_badlen, "\t{:dropped-bad-length/%ju} " 994 "{N:/message%s with bad length}\n"); 995#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) 996 for (first = 1, i = 0; i < NELEM; i++) 997 if (icmp6stat.icp6s_inhist[i] != 0) { 998 if (first) { 999 xo_open_list("input-histogram"); 1000 xo_emit("\t{T:Input histogram}:\n"); 1001 first = 0; 1002 } 1003 xo_open_instance("input-histogram"); 1004 xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", 1005 icmp6names[i], 1006 (uintmax_t)icmp6stat.icp6s_inhist[i]); 1007 xo_close_instance("input-histogram"); 1008 } 1009 if (!first) 1010 xo_close_list("input-histogram"); 1011#undef NELEM 1012 xo_emit("\t{T:Histogram of error messages to be generated}:\n"); 1013 xo_open_container("errors"); 1014 p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} " 1015 "{N:/no route}\n"); 1016 p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} " 1017 "{N:/administratively prohibited}\n"); 1018 p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} " 1019 "{N:/beyond scope}\n"); 1020 p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} " 1021 "{N:/address unreachable}\n"); 1022 p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} " 1023 "{N:/port unreachable}\n"); 1024 p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} " 1025 "{N:/packet too big}\n"); 1026 p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} " 1027 "{N:/time exceed transit}\n"); 1028 p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} " 1029 "{N:/time exceed reassembly}\n"); 1030 p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} " 1031 "{N:/erroneous header field}\n"); 1032 p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} " 1033 "{N:/unrecognized next header}\n"); 1034 p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} " 1035 "{N:/unrecognized option}\n"); 1036 p_5(icp6s_oredirect, "\t\t{:redirects/%ju} " 1037 "{N:/redirect}\n"); 1038 p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n"); 1039 1040 p(icp6s_reflect, "\t{:reflect/%ju} " 1041 "{N:/message response%s generated}\n"); 1042 p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} " 1043 "{N:/message%s with too many ND options}\n"); 1044 p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} " 1045 "{N:/message%s with bad ND options}\n"); 1046 p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} " 1047 "{N:/bad neighbor solicitation message%s}\n"); 1048 p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} " 1049 "{N:/bad neighbor advertisement message%s}\n"); 1050 p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} " 1051 "{N:/bad router solicitation message%s}\n"); 1052 p(icp6s_badra, "\t{:bad-router-advertisement/%ju} " 1053 "{N:/bad router advertisement message%s}\n"); 1054 p(icp6s_badredirect, "\t{:bad-redirect/%ju} " 1055 "{N:/bad redirect message%s}\n"); 1056 xo_close_container("errors"); 1057 p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n"); 1058#undef p 1059#undef p_5 1060 xo_close_container(name); 1061} 1062 1063/* 1064 * Dump ICMPv6 per-interface statistics based on RFC 2466. 1065 */ 1066void 1067icmp6_ifstats(char *ifname) 1068{ 1069 struct in6_ifreq ifr; 1070 int s; 1071 1072#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1073 xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1074 plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 1075#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1076 xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1077 pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) 1078 1079 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 1080 xo_warn("Warning: socket(AF_INET6)"); 1081 return; 1082 } 1083 1084 strcpy(ifr.ifr_name, ifname); 1085 if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 1086 if (errno != EPFNOSUPPORT) 1087 xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 1088 goto end; 1089 } 1090 1091 xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name); 1092 1093 xo_open_instance("icmp6-interface-statistics"); 1094 xo_emit("{ke:name/%s}", ifr.ifr_name); 1095 p(ifs6_in_msg, "\t{:received-packets/%ju} " 1096 "{N:/total input message%s}\n"); 1097 p(ifs6_in_error, "\t{:received-errors/%ju} " 1098 "{N:/total input error message%s}\n"); 1099 p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} " 1100 "{N:/input destination unreachable error%s}\n"); 1101 p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} " 1102 "{N:/input administratively prohibited error%s}\n"); 1103 p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} " 1104 "{N:/input time exceeded error%s}\n"); 1105 p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} " 1106 "{N:/input parameter problem error%s}\n"); 1107 p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} " 1108 "{N:/input packet too big error%s}\n"); 1109 p(ifs6_in_echo, "\t{:received-echo-requests/%ju} " 1110 "{N:/input echo request%s}\n"); 1111 p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} " 1112 "{N:/input echo repl%s}\n"); 1113 p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} " 1114 "{N:/input router solicitation%s}\n"); 1115 p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} " 1116 "{N:/input router advertisement%s}\n"); 1117 p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} " 1118 "{N:/input neighbor solicitation%s}\n"); 1119 p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} " 1120 "{N:/input neighbor advertisement%s}\n"); 1121 p(ifs6_in_redirect, "\t{received-redirects/%ju} " 1122 "{N:/input redirect%s}\n"); 1123 p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} " 1124 "{N:/input MLD quer%s}\n"); 1125 p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} " 1126 "{N:/input MLD report%s}\n"); 1127 p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} " 1128 "{N:/input MLD done%s}\n"); 1129 1130 p(ifs6_out_msg, "\t{:sent-packets/%ju} " 1131 "{N:/total output message%s}\n"); 1132 p(ifs6_out_error, "\t{:sent-errors/%ju} " 1133 "{N:/total output error message%s}\n"); 1134 p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} " 1135 "{N:/output destination unreachable error%s}\n"); 1136 p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} " 1137 "{N:/output administratively prohibited error%s}\n"); 1138 p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} " 1139 "{N:/output time exceeded error%s}\n"); 1140 p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} " 1141 "{N:/output parameter problem error%s}\n"); 1142 p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} " 1143 "{N:/output packet too big error%s}\n"); 1144 p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} " 1145 "{N:/output echo request%s}\n"); 1146 p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} " 1147 "{N:/output echo repl%s}\n"); 1148 p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} " 1149 "{N:/output router solicitation%s}\n"); 1150 p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} " 1151 "{N:/output router advertisement%s}\n"); 1152 p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} " 1153 "{N:/output neighbor solicitation%s}\n"); 1154 p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} " 1155 "{N:/output neighbor advertisement%s}\n"); 1156 p(ifs6_out_redirect, "\t{:sent-redirects/%ju} " 1157 "{N:/output redirect%s}\n"); 1158 p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} " 1159 "{N:/output MLD quer%s}\n"); 1160 p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} " 1161 "{N:/output MLD report%s}\n"); 1162 p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} " 1163 "{N:/output MLD done%s}\n"); 1164 1165end: 1166 xo_close_instance("icmp6-interface-statistics"); 1167 close(s); 1168#undef p 1169} 1170 1171/* 1172 * Dump PIM statistics structure. 1173 */ 1174void 1175pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 1176{ 1177 struct pim6stat pim6stat; 1178 1179 if (fetch_stats("net.inet6.pim.stats", off, &pim6stat, 1180 sizeof(pim6stat), kread) != 0) 1181 return; 1182 1183 xo_emit("{T:/%s}:\n", name); 1184 xo_open_container(name); 1185 1186#define p(f, m) if (pim6stat.f || sflag <= 1) \ 1187 xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) 1188 1189 p(pim6s_rcv_total, "\t{:received-packets/%ju} " 1190 "{N:/message%s received}\n"); 1191 p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} " 1192 "{N:/message%s received with too few bytes}\n"); 1193 p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " 1194 "{N:/message%s received with bad checksum}\n"); 1195 p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} " 1196 "{N:/message%s received with bad version}\n"); 1197 p(pim6s_rcv_registers, "\t{:received-registers/%ju} " 1198 "{N:/register%s received}\n"); 1199 p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} " 1200 "{N:/bad register%s received}\n"); 1201 p(pim6s_snd_registers, "\t{:sent-registers/%ju} " 1202 "{N:/register%s sent}\n"); 1203#undef p 1204 xo_close_container(name); 1205} 1206 1207/* 1208 * Dump raw ip6 statistics structure. 1209 */ 1210void 1211rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 1212{ 1213 struct rip6stat rip6stat; 1214 u_quad_t delivered; 1215 1216 if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat, 1217 sizeof(rip6stat), kread_counters) != 0) 1218 return; 1219 1220 xo_emit("{T:/%s}:\n", name); 1221 xo_open_container(name); 1222 1223#define p(f, m) if (rip6stat.f || sflag <= 1) \ 1224 xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) 1225 1226 p(rip6s_ipackets, "\t{:received-packets/%ju} " 1227 "{N:/message%s received}\n"); 1228 p(rip6s_isum, "\t{:input-checksum-computation/%ju} " 1229 "{N:/checksum calculation%s on inbound}\n"); 1230 p(rip6s_badsum, "\t{:received-bad-checksum/%ju} " 1231 "{N:/message%s with bad checksum}\n"); 1232 p(rip6s_nosock, "\t{:dropped-no-socket/%ju} " 1233 "{N:/message%s dropped due to no socket}\n"); 1234 p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} " 1235 "{N:/multicast message%s dropped due to no socket}\n"); 1236 p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} " 1237 "{N:/message%s dropped due to full socket buffers}\n"); 1238 delivered = rip6stat.rip6s_ipackets - 1239 rip6stat.rip6s_badsum - 1240 rip6stat.rip6s_nosock - 1241 rip6stat.rip6s_nosockmcast - 1242 rip6stat.rip6s_fullsock; 1243 if (delivered || sflag <= 1) 1244 xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n", 1245 (uintmax_t)delivered); 1246 p(rip6s_opackets, "\t{:sent-packets/%ju} " 1247 "{N:/datagram%s output}\n"); 1248#undef p 1249 xo_close_container(name); 1250} 1251 1252/* 1253 * Pretty print an Internet address (net address + port). 1254 * Take numeric_addr and numeric_port into consideration. 1255 */ 1256#define GETSERVBYPORT6(port, proto, ret)\ 1257{\ 1258 if (strcmp((proto), "tcp6") == 0)\ 1259 (ret) = getservbyport((int)(port), "tcp");\ 1260 else if (strcmp((proto), "udp6") == 0)\ 1261 (ret) = getservbyport((int)(port), "udp");\ 1262 else\ 1263 (ret) = getservbyport((int)(port), (proto));\ 1264}; 1265 1266void 1267inet6print(const char *container, struct in6_addr *in6, int port, 1268 const char *proto, int numeric) 1269{ 1270 struct servent *sp = 0; 1271 char line[80], *cp; 1272 int width; 1273 1274 if (container) 1275 xo_open_container(container); 1276 1277 sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16, 1278 inet6name(in6)); 1279 cp = strchr(line, '\0'); 1280 if (!numeric && port) 1281 GETSERVBYPORT6(port, proto, sp); 1282 if (sp || port == 0) 1283 sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 1284 else 1285 sprintf(cp, "%d", ntohs((u_short)port)); 1286 width = Wflag ? 45 : Aflag ? 18 : 22; 1287 1288 xo_emit("{d:target/%-*.*s} ", width, width, line); 1289 1290 int alen = cp - line - 1, plen = strlen(cp) - 1; 1291 xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, 1292 plen, cp); 1293 1294 if (container) 1295 xo_close_container(container); 1296} 1297 1298/* 1299 * Construct an Internet address representation. 1300 * If the numeric_addr has been supplied, give 1301 * numeric value, otherwise try for symbolic name. 1302 */ 1303 1304char * 1305inet6name(struct in6_addr *in6p) 1306{ 1307 struct sockaddr_in6 sin6; 1308 char hbuf[NI_MAXHOST], *cp; 1309 static char line[50]; 1310 static char domain[MAXHOSTNAMELEN]; 1311 static int first = 1; 1312 int flags, error; 1313 1314 if (IN6_IS_ADDR_UNSPECIFIED(in6p)) { 1315 strcpy(line, "*"); 1316 return (line); 1317 } 1318 if (first && !numeric_addr) { 1319 first = 0; 1320 if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 1321 (cp = strchr(domain, '.'))) 1322 (void) strcpy(domain, cp + 1); 1323 else 1324 domain[0] = 0; 1325 } 1326 memset(&sin6, 0, sizeof(sin6)); 1327 memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p)); 1328 sin6.sin6_family = AF_INET6; 1329 /* XXX: in6p.s6_addr[2] can contain scopeid. */ 1330 in6_fillscopeid(&sin6); 1331 flags = (numeric_addr) ? NI_NUMERICHOST : 0; 1332 error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, 1333 sizeof(hbuf), NULL, 0, flags); 1334 if (error == 0) { 1335 if ((flags & NI_NUMERICHOST) == 0 && 1336 (cp = strchr(hbuf, '.')) && 1337 !strcmp(cp + 1, domain)) 1338 *cp = 0; 1339 strcpy(line, hbuf); 1340 } else { 1341 /* XXX: this should not happen. */ 1342 sprintf(line, "%s", 1343 inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, 1344 sizeof(ntop_buf))); 1345 } 1346 return (line); 1347} 1348#endif /*INET6*/ 1349