154263Sshin/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2175061Sobrien/*- 354263Sshin * Copyright (c) 1983, 1988, 1993 454263Sshin * The Regents of the University of California. All rights reserved. 554263Sshin * 654263Sshin * Redistribution and use in source and binary forms, with or without 754263Sshin * modification, are permitted provided that the following conditions 854263Sshin * are met: 954263Sshin * 1. Redistributions of source code must retain the above copyright 1054263Sshin * notice, this list of conditions and the following disclaimer. 1154263Sshin * 2. Redistributions in binary form must reproduce the above copyright 1254263Sshin * notice, this list of conditions and the following disclaimer in the 1354263Sshin * documentation and/or other materials provided with the distribution. 1454263Sshin * 4. Neither the name of the University nor the names of its contributors 1554263Sshin * may be used to endorse or promote products derived from this software 1654263Sshin * without specific prior written permission. 1754263Sshin * 1854263Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1954263Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2054263Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2154263Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2254263Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2354263Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2454263Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2554263Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2654263Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2754263Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2854263Sshin * SUCH DAMAGE. 2954263Sshin */ 3054263Sshin 31132671Scharnier#if 0 3254263Sshin#ifndef lint 3354263Sshinstatic char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; 3454263Sshin#endif /* not lint */ 35132671Scharnier#endif 3654263Sshin 37132671Scharnier#include <sys/cdefs.h> 38132671Scharnier__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/inet6.c 319260 2017-05-30 22:35:36Z asomers $"); 39132671Scharnier 4064342Sume#ifdef INET6 4154263Sshin#include <sys/param.h> 4254263Sshin#include <sys/socket.h> 4354263Sshin#include <sys/socketvar.h> 4454263Sshin#include <sys/ioctl.h> 4554263Sshin#include <sys/mbuf.h> 4654263Sshin#include <sys/protosw.h> 4754263Sshin 4854263Sshin#include <net/route.h> 4954263Sshin#include <net/if.h> 5054263Sshin#include <net/if_var.h> 5154263Sshin#include <netinet/in.h> 5254263Sshin#include <netinet/ip6.h> 5354263Sshin#include <netinet/icmp6.h> 5454263Sshin#include <netinet/in_systm.h> 5554263Sshin#include <netinet6/in6_pcb.h> 5654263Sshin#include <netinet6/in6_var.h> 5754263Sshin#include <netinet6/ip6_var.h> 5854263Sshin#include <netinet6/pim6_var.h> 5978064Sume#include <netinet6/raw_ip6.h> 6054263Sshin 6154263Sshin#include <arpa/inet.h> 6254263Sshin#include <netdb.h> 6354263Sshin 64166952Sbms#include <err.h> 65160787Syar#include <stdint.h> 6654263Sshin#include <stdio.h> 67160373Sjulian#include <errno.h> 6854263Sshin#include <string.h> 6954263Sshin#include <unistd.h> 7054263Sshin#include "netstat.h" 7154263Sshin 7254263Sshinstruct socket sockb; 7354263Sshin 74132671Scharnierchar *inet6name(struct in6_addr *); 7554263Sshin 7654263Sshinstatic char ntop_buf[INET6_ADDRSTRLEN]; 7754263Sshin 78102975Sdwmalonestatic const char *ip6nh[] = { 7954263Sshin "hop by hop", 8054263Sshin "ICMP", 8154263Sshin "IGMP", 8254263Sshin "#3", 8354263Sshin "IP", 8454263Sshin "#5", 8554263Sshin "TCP", 8654263Sshin "#7", 8754263Sshin "#8", 8854263Sshin "#9", 8954263Sshin "#10", 9054263Sshin "#11", 9154263Sshin "#12", 9254263Sshin "#13", 9354263Sshin "#14", 9454263Sshin "#15", 9554263Sshin "#16", 9654263Sshin "UDP", 9754263Sshin "#18", 98175061Sobrien "#19", 9954263Sshin "#20", 10054263Sshin "#21", 10154263Sshin "IDP", 10254263Sshin "#23", 10354263Sshin "#24", 10454263Sshin "#25", 10554263Sshin "#26", 10654263Sshin "#27", 10754263Sshin "#28", 108175061Sobrien "TP", 10954263Sshin "#30", 11054263Sshin "#31", 11154263Sshin "#32", 11254263Sshin "#33", 11354263Sshin "#34", 11454263Sshin "#35", 11554263Sshin "#36", 11654263Sshin "#37", 11754263Sshin "#38", 118175061Sobrien "#39", 11954263Sshin "#40", 12054263Sshin "IP6", 12154263Sshin "#42", 12254263Sshin "routing", 12354263Sshin "fragment", 12454263Sshin "#45", 12554263Sshin "#46", 12654263Sshin "#47", 12754263Sshin "#48", 128175061Sobrien "#49", 12954263Sshin "ESP", 13054263Sshin "AH", 13154263Sshin "#52", 13254263Sshin "#53", 13354263Sshin "#54", 13454263Sshin "#55", 13554263Sshin "#56", 13654263Sshin "#57", 13754263Sshin "ICMP6", 138175061Sobrien "no next header", 13954263Sshin "destination option", 14054263Sshin "#61", 141125482Sume "mobility", 14254263Sshin "#63", 14354263Sshin "#64", 14454263Sshin "#65", 14554263Sshin "#66", 14654263Sshin "#67", 14754263Sshin "#68", 148175061Sobrien "#69", 14954263Sshin "#70", 15054263Sshin "#71", 15154263Sshin "#72", 15254263Sshin "#73", 15354263Sshin "#74", 15454263Sshin "#75", 15554263Sshin "#76", 15654263Sshin "#77", 15754263Sshin "#78", 158175061Sobrien "#79", 15954263Sshin "ISOIP", 16054263Sshin "#81", 16154263Sshin "#82", 16254263Sshin "#83", 16354263Sshin "#84", 16454263Sshin "#85", 16554263Sshin "#86", 16654263Sshin "#87", 16754263Sshin "#88", 168175061Sobrien "OSPF", 16954263Sshin "#80", 17054263Sshin "#91", 17154263Sshin "#92", 17254263Sshin "#93", 17354263Sshin "#94", 17454263Sshin "#95", 17554263Sshin "#96", 17654263Sshin "Ethernet", 17754263Sshin "#98", 178175061Sobrien "#99", 17954263Sshin "#100", 18054263Sshin "#101", 18154263Sshin "#102", 18254263Sshin "PIM", 18354263Sshin "#104", 18454263Sshin "#105", 18554263Sshin "#106", 18654263Sshin "#107", 18754263Sshin "#108", 188175061Sobrien "#109", 18954263Sshin "#110", 19054263Sshin "#111", 19154263Sshin "#112", 19254263Sshin "#113", 19354263Sshin "#114", 19454263Sshin "#115", 19554263Sshin "#116", 19654263Sshin "#117", 19754263Sshin "#118", 198175061Sobrien "#119", 19954263Sshin "#120", 20054263Sshin "#121", 20154263Sshin "#122", 20254263Sshin "#123", 20354263Sshin "#124", 20454263Sshin "#125", 20554263Sshin "#126", 20654263Sshin "#127", 20754263Sshin "#128", 208175061Sobrien "#129", 20954263Sshin "#130", 21054263Sshin "#131", 21154263Sshin "#132", 21254263Sshin "#133", 21354263Sshin "#134", 21454263Sshin "#135", 21554263Sshin "#136", 21654263Sshin "#137", 21754263Sshin "#138", 218175061Sobrien "#139", 21954263Sshin "#140", 22054263Sshin "#141", 22154263Sshin "#142", 22254263Sshin "#143", 22354263Sshin "#144", 22454263Sshin "#145", 22554263Sshin "#146", 22654263Sshin "#147", 22754263Sshin "#148", 228175061Sobrien "#149", 22954263Sshin "#150", 23054263Sshin "#151", 23154263Sshin "#152", 23254263Sshin "#153", 23354263Sshin "#154", 23454263Sshin "#155", 23554263Sshin "#156", 23654263Sshin "#157", 23754263Sshin "#158", 238175061Sobrien "#159", 23954263Sshin "#160", 24054263Sshin "#161", 24154263Sshin "#162", 24254263Sshin "#163", 24354263Sshin "#164", 24454263Sshin "#165", 24554263Sshin "#166", 24654263Sshin "#167", 24754263Sshin "#168", 248175061Sobrien "#169", 24954263Sshin "#170", 25054263Sshin "#171", 25154263Sshin "#172", 25254263Sshin "#173", 25354263Sshin "#174", 25454263Sshin "#175", 25554263Sshin "#176", 25654263Sshin "#177", 25754263Sshin "#178", 258175061Sobrien "#179", 25954263Sshin "#180", 26054263Sshin "#181", 26154263Sshin "#182", 26254263Sshin "#183", 26354263Sshin "#184", 26454263Sshin "#185", 26554263Sshin "#186", 26654263Sshin "#187", 26754263Sshin "#188", 268175061Sobrien "#189", 26954263Sshin "#180", 27054263Sshin "#191", 27154263Sshin "#192", 27254263Sshin "#193", 27354263Sshin "#194", 27454263Sshin "#195", 27554263Sshin "#196", 27654263Sshin "#197", 27754263Sshin "#198", 278175061Sobrien "#199", 27954263Sshin "#200", 28054263Sshin "#201", 28154263Sshin "#202", 28254263Sshin "#203", 28354263Sshin "#204", 28454263Sshin "#205", 28554263Sshin "#206", 28654263Sshin "#207", 28754263Sshin "#208", 288175061Sobrien "#209", 28954263Sshin "#210", 29054263Sshin "#211", 29154263Sshin "#212", 29254263Sshin "#213", 29354263Sshin "#214", 29454263Sshin "#215", 29554263Sshin "#216", 29654263Sshin "#217", 29754263Sshin "#218", 298175061Sobrien "#219", 29954263Sshin "#220", 30054263Sshin "#221", 30154263Sshin "#222", 30254263Sshin "#223", 30354263Sshin "#224", 30454263Sshin "#225", 30554263Sshin "#226", 30654263Sshin "#227", 30754263Sshin "#228", 308175061Sobrien "#229", 30954263Sshin "#230", 31054263Sshin "#231", 31154263Sshin "#232", 31254263Sshin "#233", 31354263Sshin "#234", 31454263Sshin "#235", 31554263Sshin "#236", 31654263Sshin "#237", 31754263Sshin "#238", 318175061Sobrien "#239", 31954263Sshin "#240", 32054263Sshin "#241", 32154263Sshin "#242", 32254263Sshin "#243", 32354263Sshin "#244", 32454263Sshin "#245", 32554263Sshin "#246", 32654263Sshin "#247", 32754263Sshin "#248", 328175061Sobrien "#249", 32954263Sshin "#250", 33054263Sshin "#251", 33154263Sshin "#252", 33254263Sshin "#253", 33354263Sshin "#254", 33454263Sshin "#255", 33554263Sshin}; 33654263Sshin 337246988Scharnierstatic const char *srcrule_str[] = { 338125483Sume "first candidate", 339125483Sume "same address", 340125483Sume "appropriate scope", 341125483Sume "deprecated address", 342125483Sume "home address", 343125483Sume "outgoing interface", 344125483Sume "matching label", 345125483Sume "public/temporary address", 346125483Sume "alive interface", 347271288Sae "better virtual status", 348272790Sae "preferred source", 349125483Sume "rule #11", 350125483Sume "rule #12", 351125483Sume "rule #13", 352125483Sume "longest match", 353125483Sume "rule #15", 354125483Sume}; 355125483Sume 35654263Sshin/* 35754263Sshin * Dump IP6 statistics structure. 35854263Sshin */ 35954263Sshinvoid 360171465Sjhbip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 36154263Sshin{ 362293307Smarkj struct ip6stat ip6stat; 36354263Sshin int first, i; 36454263Sshin 365293307Smarkj if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat, 366293307Smarkj sizeof(ip6stat), kread_counters) != 0) 367293307Smarkj return; 36854263Sshin 36954263Sshin printf("%s:\n", name); 37054263Sshin 37154263Sshin#define p(f, m) if (ip6stat.f || sflag <= 1) \ 372160787Syar printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) 37354263Sshin#define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 374160787Syar printf(m, (uintmax_t)ip6stat.f) 37554263Sshin 376160787Syar p(ip6s_total, "\t%ju total packet%s received\n"); 377160787Syar p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n"); 378160787Syar p1a(ip6s_tooshort, "\t%ju with data size < data length\n"); 379160787Syar p1a(ip6s_badoptions, "\t%ju with bad options\n"); 380160787Syar p1a(ip6s_badvers, "\t%ju with incorrect version number\n"); 381160787Syar p(ip6s_fragments, "\t%ju fragment%s received\n"); 382160787Syar p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n"); 383160787Syar p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n"); 384160787Syar p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n"); 385160787Syar p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n"); 386160787Syar p(ip6s_delivered, "\t%ju packet%s for this host\n"); 387160787Syar p(ip6s_forward, "\t%ju packet%s forwarded\n"); 388160787Syar p(ip6s_cantforward, "\t%ju packet%s not forwardable\n"); 389160787Syar p(ip6s_redirectsent, "\t%ju redirect%s sent\n"); 390160787Syar p(ip6s_localout, "\t%ju packet%s sent from this host\n"); 391160787Syar p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n"); 392160787Syar p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n"); 393160787Syar p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n"); 394160787Syar p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n"); 395160787Syar p(ip6s_ofragments, "\t%ju fragment%s created\n"); 396160787Syar p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n"); 397160787Syar p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n"); 398160787Syar p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n"); 399249545Sae for (first = 1, i = 0; i < IP6S_HDRCNT; i++) 40054263Sshin if (ip6stat.ip6s_nxthist[i] != 0) { 40154263Sshin if (first) { 40254263Sshin printf("\tInput histogram:\n"); 40354263Sshin first = 0; 40454263Sshin } 405160787Syar printf("\t\t%s: %ju\n", ip6nh[i], 406160787Syar (uintmax_t)ip6stat.ip6s_nxthist[i]); 40754263Sshin } 40854263Sshin printf("\tMbuf statistics:\n"); 409160787Syar printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1); 410249545Sae for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { 41155163Sshin char ifbuf[IFNAMSIZ]; 412175061Sobrien if (ip6stat.ip6s_m2m[i] != 0) { 41354263Sshin if (first) { 41454263Sshin printf("\t\ttwo or more mbuf:\n"); 41554263Sshin first = 0; 41654263Sshin } 417160787Syar printf("\t\t\t%s= %ju\n", 41862584Sitojun if_indextoname(i, ifbuf), 419160787Syar (uintmax_t)ip6stat.ip6s_m2m[i]); 42054263Sshin } 42154263Sshin } 422160787Syar printf("\t\t%ju one ext mbuf\n", 423160787Syar (uintmax_t)ip6stat.ip6s_mext1); 424160787Syar printf("\t\t%ju two or more ext mbuf\n", 425175061Sobrien (uintmax_t)ip6stat.ip6s_mext2m); 42662584Sitojun p(ip6s_exthdrtoolong, 427215955Sbrucec "\t%ju packet%s whose headers are not contiguous\n"); 428160787Syar p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n"); 42962584Sitojun p(ip6s_toomanyhdr, 430160787Syar "\t%ju packet%s discarded because of too many headers\n"); 43162584Sitojun 43262584Sitojun /* for debugging source address selection */ 433175061Sobrien#define PRINT_SCOPESTAT(s,i) do {\ 43462584Sitojun switch(i) { /* XXX hardcoding in each case */\ 43562584Sitojun case 1:\ 436249545Sae p(s, "\t\t%ju interface-local%s\n");\ 43762584Sitojun break;\ 43862584Sitojun case 2:\ 439160787Syar p(s,"\t\t%ju link-local%s\n");\ 44062584Sitojun break;\ 44162584Sitojun case 5:\ 442160787Syar p(s,"\t\t%ju site-local%s\n");\ 44362584Sitojun break;\ 44462584Sitojun case 14:\ 445160787Syar p(s,"\t\t%ju global%s\n");\ 44662584Sitojun break;\ 44762584Sitojun default:\ 448160787Syar printf("\t\t%ju addresses scope=%x\n",\ 449160787Syar (uintmax_t)ip6stat.s, i);\ 45062584Sitojun }\ 45162584Sitojun } while (0); 45262584Sitojun 45362584Sitojun p(ip6s_sources_none, 454160787Syar "\t%ju failure%s of source address selection\n"); 455249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 45662584Sitojun if (ip6stat.ip6s_sources_sameif[i]) { 45762584Sitojun if (first) { 45862584Sitojun printf("\tsource addresses on an outgoing I/F\n"); 45962584Sitojun first = 0; 46062584Sitojun } 46162584Sitojun PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); 46262584Sitojun } 46362584Sitojun } 464249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 46562584Sitojun if (ip6stat.ip6s_sources_otherif[i]) { 46662584Sitojun if (first) { 46762584Sitojun printf("\tsource addresses on a non-outgoing I/F\n"); 46862584Sitojun first = 0; 46962584Sitojun } 47062584Sitojun PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); 47162584Sitojun } 47262584Sitojun } 473249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 47462584Sitojun if (ip6stat.ip6s_sources_samescope[i]) { 47562584Sitojun if (first) { 47662584Sitojun printf("\tsource addresses of same scope\n"); 47762584Sitojun first = 0; 47862584Sitojun } 47962584Sitojun PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); 48062584Sitojun } 48162584Sitojun } 482249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 48362584Sitojun if (ip6stat.ip6s_sources_otherscope[i]) { 48462584Sitojun if (first) { 48562584Sitojun printf("\tsource addresses of a different scope\n"); 48662584Sitojun first = 0; 48762584Sitojun } 48862584Sitojun PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); 48962584Sitojun } 49062584Sitojun } 491249545Sae for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 49262584Sitojun if (ip6stat.ip6s_sources_deprecated[i]) { 49362584Sitojun if (first) { 49462584Sitojun printf("\tdeprecated source addresses\n"); 49562584Sitojun first = 0; 49662584Sitojun } 49762584Sitojun PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); 49862584Sitojun } 49962584Sitojun } 50062584Sitojun 501125483Sume printf("\tSource addresses selection rule applied:\n"); 502249545Sae for (i = 0; i < IP6S_RULESMAX; i++) { 503125483Sume if (ip6stat.ip6s_sources_rule[i]) 504160787Syar printf("\t\t%ju %s\n", 505160787Syar (uintmax_t)ip6stat.ip6s_sources_rule[i], 506125483Sume srcrule_str[i]); 507125483Sume } 50854263Sshin#undef p 50962584Sitojun#undef p1a 51054263Sshin} 51154263Sshin 51254263Sshin/* 51354263Sshin * Dump IPv6 per-interface statistics based on RFC 2465. 51454263Sshin */ 51554263Sshinvoid 51678314Sassarip6_ifstats(char *ifname) 51754263Sshin{ 51854263Sshin struct in6_ifreq ifr; 51954263Sshin int s; 52054263Sshin#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 521160787Syar printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f)) 52254263Sshin#define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 523160787Syar printf(m, (uintmax_t)ip6stat.f) 52454263Sshin 52554263Sshin if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 52654263Sshin perror("Warning: socket(AF_INET6)"); 52754263Sshin return; 52854263Sshin } 52954263Sshin 530319260Sasomers strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 53154263Sshin if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 532271185Smarkj if (errno != EPFNOSUPPORT) 533271185Smarkj perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); 53454263Sshin goto end; 53554263Sshin } 53654263Sshin 537271185Smarkj printf("ip6 on %s:\n", ifr.ifr_name); 538160787Syar p(ifs6_in_receive, "\t%ju total input datagram%s\n"); 539160787Syar p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n"); 540160787Syar p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n"); 541160787Syar p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n"); 542160787Syar p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n"); 543160787Syar p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n"); 544160787Syar p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n"); 545160787Syar p(ifs6_in_discard, "\t%ju input datagram%s discarded\n"); 54654263Sshin p(ifs6_in_deliver, 547160787Syar "\t%ju datagram%s delivered to an upper layer protocol\n"); 548160787Syar p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n"); 54954263Sshin p(ifs6_out_request, 550160787Syar "\t%ju datagram%s sent from an upper layer protocol\n"); 551160787Syar p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n"); 552160787Syar p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n"); 553160787Syar p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n"); 554160787Syar p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n"); 555160787Syar p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n"); 556160787Syar p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n"); 557160787Syar p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n"); 558160787Syar p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n"); 559160787Syar p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n"); 56054263Sshin 56154263Sshin end: 56254263Sshin close(s); 56354263Sshin 56454263Sshin#undef p 56554263Sshin#undef p_5 56654263Sshin} 56754263Sshin 568102975Sdwmalonestatic const char *icmp6names[] = { 56954263Sshin "#0", 57054263Sshin "unreach", 57154263Sshin "packet too big", 57254263Sshin "time exceed", 57354263Sshin "parameter problem", 57454263Sshin "#5", 57554263Sshin "#6", 57654263Sshin "#7", 57754263Sshin "#8", 57854263Sshin "#9", 57954263Sshin "#10", 58054263Sshin "#11", 58154263Sshin "#12", 58254263Sshin "#13", 58354263Sshin "#14", 58454263Sshin "#15", 58554263Sshin "#16", 58654263Sshin "#17", 58754263Sshin "#18", 588175061Sobrien "#19", 58954263Sshin "#20", 59054263Sshin "#21", 59154263Sshin "#22", 59254263Sshin "#23", 59354263Sshin "#24", 59454263Sshin "#25", 59554263Sshin "#26", 59654263Sshin "#27", 59754263Sshin "#28", 598175061Sobrien "#29", 59954263Sshin "#30", 60054263Sshin "#31", 60154263Sshin "#32", 60254263Sshin "#33", 60354263Sshin "#34", 60454263Sshin "#35", 60554263Sshin "#36", 60654263Sshin "#37", 60754263Sshin "#38", 608175061Sobrien "#39", 60954263Sshin "#40", 61054263Sshin "#41", 61154263Sshin "#42", 61254263Sshin "#43", 61354263Sshin "#44", 61454263Sshin "#45", 61554263Sshin "#46", 61654263Sshin "#47", 61754263Sshin "#48", 618175061Sobrien "#49", 61954263Sshin "#50", 62054263Sshin "#51", 62154263Sshin "#52", 62254263Sshin "#53", 62354263Sshin "#54", 62454263Sshin "#55", 62554263Sshin "#56", 62654263Sshin "#57", 62754263Sshin "#58", 628175061Sobrien "#59", 62954263Sshin "#60", 63054263Sshin "#61", 63154263Sshin "#62", 63254263Sshin "#63", 63354263Sshin "#64", 63454263Sshin "#65", 63554263Sshin "#66", 63654263Sshin "#67", 63754263Sshin "#68", 638175061Sobrien "#69", 63954263Sshin "#70", 64054263Sshin "#71", 64154263Sshin "#72", 64254263Sshin "#73", 64354263Sshin "#74", 64454263Sshin "#75", 64554263Sshin "#76", 64654263Sshin "#77", 64754263Sshin "#78", 648175061Sobrien "#79", 64954263Sshin "#80", 65054263Sshin "#81", 65154263Sshin "#82", 65254263Sshin "#83", 65354263Sshin "#84", 65454263Sshin "#85", 65554263Sshin "#86", 65654263Sshin "#87", 65754263Sshin "#88", 658175061Sobrien "#89", 65954263Sshin "#80", 66054263Sshin "#91", 66154263Sshin "#92", 66254263Sshin "#93", 66354263Sshin "#94", 66454263Sshin "#95", 66554263Sshin "#96", 66654263Sshin "#97", 66754263Sshin "#98", 668175061Sobrien "#99", 66954263Sshin "#100", 67054263Sshin "#101", 67154263Sshin "#102", 67254263Sshin "#103", 67354263Sshin "#104", 67454263Sshin "#105", 67554263Sshin "#106", 67654263Sshin "#107", 67754263Sshin "#108", 678175061Sobrien "#109", 67954263Sshin "#110", 68054263Sshin "#111", 68154263Sshin "#112", 68254263Sshin "#113", 68354263Sshin "#114", 68454263Sshin "#115", 68554263Sshin "#116", 68654263Sshin "#117", 68754263Sshin "#118", 688175061Sobrien "#119", 68954263Sshin "#120", 69054263Sshin "#121", 69154263Sshin "#122", 69254263Sshin "#123", 69354263Sshin "#124", 69454263Sshin "#125", 69554263Sshin "#126", 69654263Sshin "#127", 69754263Sshin "echo", 698175061Sobrien "echo reply", 69954263Sshin "multicast listener query", 700191652Sbms "MLDv1 listener report", 701191652Sbms "MLDv1 listener done", 70254263Sshin "router solicitation", 70377565Sdd "router advertisement", 70454263Sshin "neighbor solicitation", 70577565Sdd "neighbor advertisement", 70654263Sshin "redirect", 70754263Sshin "router renumbering", 70854263Sshin "node information request", 70954263Sshin "node information reply", 71078540Ssumikawa "inverse neighbor solicitation", 71178540Ssumikawa "inverse neighbor advertisement", 712191652Sbms "MLDv2 listener report", 71354263Sshin "#144", 71454263Sshin "#145", 71554263Sshin "#146", 71654263Sshin "#147", 71754263Sshin "#148", 718175061Sobrien "#149", 71954263Sshin "#150", 72054263Sshin "#151", 72154263Sshin "#152", 72254263Sshin "#153", 72354263Sshin "#154", 72454263Sshin "#155", 72554263Sshin "#156", 72654263Sshin "#157", 72754263Sshin "#158", 728175061Sobrien "#159", 72954263Sshin "#160", 73054263Sshin "#161", 73154263Sshin "#162", 73254263Sshin "#163", 73354263Sshin "#164", 73454263Sshin "#165", 73554263Sshin "#166", 73654263Sshin "#167", 73754263Sshin "#168", 738175061Sobrien "#169", 73954263Sshin "#170", 74054263Sshin "#171", 74154263Sshin "#172", 74254263Sshin "#173", 74354263Sshin "#174", 74454263Sshin "#175", 74554263Sshin "#176", 74654263Sshin "#177", 74754263Sshin "#178", 748175061Sobrien "#179", 74954263Sshin "#180", 75054263Sshin "#181", 75154263Sshin "#182", 75254263Sshin "#183", 75354263Sshin "#184", 75454263Sshin "#185", 75554263Sshin "#186", 75654263Sshin "#187", 75754263Sshin "#188", 758175061Sobrien "#189", 75954263Sshin "#180", 76054263Sshin "#191", 76154263Sshin "#192", 76254263Sshin "#193", 76354263Sshin "#194", 76454263Sshin "#195", 76554263Sshin "#196", 76654263Sshin "#197", 76754263Sshin "#198", 768175061Sobrien "#199", 76954263Sshin "#200", 77054263Sshin "#201", 77154263Sshin "#202", 77254263Sshin "#203", 77354263Sshin "#204", 77454263Sshin "#205", 77554263Sshin "#206", 77654263Sshin "#207", 77754263Sshin "#208", 778175061Sobrien "#209", 77954263Sshin "#210", 78054263Sshin "#211", 78154263Sshin "#212", 78254263Sshin "#213", 78354263Sshin "#214", 78454263Sshin "#215", 78554263Sshin "#216", 78654263Sshin "#217", 78754263Sshin "#218", 788175061Sobrien "#219", 78954263Sshin "#220", 79054263Sshin "#221", 79154263Sshin "#222", 79254263Sshin "#223", 79354263Sshin "#224", 79454263Sshin "#225", 79554263Sshin "#226", 79654263Sshin "#227", 79754263Sshin "#228", 798175061Sobrien "#229", 79954263Sshin "#230", 80054263Sshin "#231", 80154263Sshin "#232", 80254263Sshin "#233", 80354263Sshin "#234", 80454263Sshin "#235", 80554263Sshin "#236", 80654263Sshin "#237", 80754263Sshin "#238", 808175061Sobrien "#239", 80954263Sshin "#240", 81054263Sshin "#241", 81154263Sshin "#242", 81254263Sshin "#243", 81354263Sshin "#244", 81454263Sshin "#245", 81554263Sshin "#246", 81654263Sshin "#247", 81754263Sshin "#248", 818175061Sobrien "#249", 81954263Sshin "#250", 82054263Sshin "#251", 82154263Sshin "#252", 82254263Sshin "#253", 82354263Sshin "#254", 82454263Sshin "#255", 82554263Sshin}; 82654263Sshin 82754263Sshin/* 82854263Sshin * Dump ICMP6 statistics. 82954263Sshin */ 83054263Sshinvoid 831171465Sjhbicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 83254263Sshin{ 833293307Smarkj struct icmp6stat icmp6stat; 83495637Smarkm int i, first; 83554263Sshin 836293307Smarkj if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat, 837293307Smarkj sizeof(icmp6stat), kread_counters) != 0) 838293307Smarkj return; 83978931Sume 84054263Sshin printf("%s:\n", name); 84154263Sshin 84254263Sshin#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 843160787Syar printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) 844187134Smaxim#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ 845187134Smaxim printf(m, (uintmax_t)icmp6stat.f) 84654263Sshin 847160787Syar p(icp6s_error, "\t%ju call%s to icmp6_error\n"); 84854263Sshin p(icp6s_canterror, 849160787Syar "\t%ju error%s not generated in response to an icmp6 message\n"); 85054263Sshin p(icp6s_toofreq, 851160787Syar "\t%ju error%s not generated because of rate limitation\n"); 852175061Sobrien#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) 85378540Ssumikawa for (first = 1, i = 0; i < NELEM; i++) 85454263Sshin if (icmp6stat.icp6s_outhist[i] != 0) { 85554263Sshin if (first) { 85654263Sshin printf("\tOutput histogram:\n"); 85754263Sshin first = 0; 85854263Sshin } 859160787Syar printf("\t\t%s: %ju\n", icmp6names[i], 860160787Syar (uintmax_t)icmp6stat.icp6s_outhist[i]); 86154263Sshin } 86278540Ssumikawa#undef NELEM 863160787Syar p(icp6s_badcode, "\t%ju message%s with bad code fields\n"); 864160787Syar p(icp6s_tooshort, "\t%ju message%s < minimum length\n"); 865160787Syar p(icp6s_checksum, "\t%ju bad checksum%s\n"); 866160787Syar p(icp6s_badlen, "\t%ju message%s with bad length\n"); 867175061Sobrien#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) 86878540Ssumikawa for (first = 1, i = 0; i < NELEM; i++) 86954263Sshin if (icmp6stat.icp6s_inhist[i] != 0) { 87054263Sshin if (first) { 87154263Sshin printf("\tInput histogram:\n"); 87254263Sshin first = 0; 87354263Sshin } 874160787Syar printf("\t\t%s: %ju\n", icmp6names[i], 875160787Syar (uintmax_t)icmp6stat.icp6s_inhist[i]); 87654263Sshin } 87778540Ssumikawa#undef NELEM 87877565Sdd printf("\tHistogram of error messages to be generated:\n"); 879160787Syar p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n"); 880160787Syar p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n"); 881160787Syar p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n"); 882160787Syar p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n"); 883160787Syar p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n"); 884160787Syar p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n"); 885160787Syar p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n"); 886160787Syar p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n"); 887160787Syar p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n"); 888160787Syar p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n"); 889160787Syar p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n"); 890160787Syar p_5(icp6s_oredirect, "\t\t%ju redirect\n"); 891160787Syar p_5(icp6s_ounknown, "\t\t%ju unknown\n"); 89262584Sitojun 893160787Syar p(icp6s_reflect, "\t%ju message response%s generated\n"); 894160787Syar p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n"); 895160787Syar p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n"); 896160787Syar p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n"); 897160787Syar p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n"); 898160787Syar p(icp6s_badrs, "\t%ju bad router solicitation message%s\n"); 899160787Syar p(icp6s_badra, "\t%ju bad router advertisement message%s\n"); 900160787Syar p(icp6s_badredirect, "\t%ju bad redirect message%s\n"); 901160787Syar p(icp6s_pmtuchg, "\t%ju path MTU change%s\n"); 90254263Sshin#undef p 90354263Sshin#undef p_5 90454263Sshin} 90554263Sshin 90654263Sshin/* 90754263Sshin * Dump ICMPv6 per-interface statistics based on RFC 2466. 90854263Sshin */ 90954263Sshinvoid 91078314Sassaricmp6_ifstats(char *ifname) 91154263Sshin{ 91254263Sshin struct in6_ifreq ifr; 91354263Sshin int s; 91454263Sshin#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 915160787Syar printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 916109234Smtm#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 917160787Syar printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) 91854263Sshin 91954263Sshin if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 92054263Sshin perror("Warning: socket(AF_INET6)"); 92154263Sshin return; 92254263Sshin } 92354263Sshin 924319260Sasomers strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 92554263Sshin if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 926271185Smarkj if (errno != EPFNOSUPPORT) 927271185Smarkj perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 92854263Sshin goto end; 92954263Sshin } 93054263Sshin 931271185Smarkj printf("icmp6 on %s:\n", ifr.ifr_name); 932160787Syar p(ifs6_in_msg, "\t%ju total input message%s\n"); 933175061Sobrien p(ifs6_in_error, "\t%ju total input error message%s\n"); 934160787Syar p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n"); 935160787Syar p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n"); 936160787Syar p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n"); 937160787Syar p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n"); 938160787Syar p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n"); 939160787Syar p(ifs6_in_echo, "\t%ju input echo request%s\n"); 940160787Syar p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n"); 941160787Syar p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n"); 942160787Syar p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n"); 943160787Syar p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n"); 944160787Syar p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n"); 945160787Syar p(ifs6_in_redirect, "\t%ju input redirect%s\n"); 946160787Syar p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n"); 947160787Syar p(ifs6_in_mldreport, "\t%ju input MLD report%s\n"); 948160787Syar p(ifs6_in_mlddone, "\t%ju input MLD done%s\n"); 94954263Sshin 950160787Syar p(ifs6_out_msg, "\t%ju total output message%s\n"); 951160787Syar p(ifs6_out_error, "\t%ju total output error message%s\n"); 952160787Syar p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n"); 953160787Syar p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n"); 954160787Syar p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n"); 955160787Syar p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n"); 956160787Syar p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n"); 957160787Syar p(ifs6_out_echo, "\t%ju output echo request%s\n"); 958160787Syar p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n"); 959160787Syar p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n"); 960160787Syar p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n"); 961160787Syar p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n"); 962160787Syar p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n"); 963160787Syar p(ifs6_out_redirect, "\t%ju output redirect%s\n"); 964160787Syar p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n"); 965160787Syar p(ifs6_out_mldreport, "\t%ju output MLD report%s\n"); 966160787Syar p(ifs6_out_mlddone, "\t%ju output MLD done%s\n"); 96754263Sshin 96854263Sshin end: 96954263Sshin close(s); 97054263Sshin#undef p 97154263Sshin} 97254263Sshin 97354263Sshin/* 97454263Sshin * Dump PIM statistics structure. 97554263Sshin */ 97654263Sshinvoid 977171465Sjhbpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 97854263Sshin{ 979293307Smarkj struct pim6stat pim6stat; 98054263Sshin 981293307Smarkj if (fetch_stats("net.inet6.pim.stats", off, &pim6stat, 982293307Smarkj sizeof(pim6stat), kread) != 0) 983293307Smarkj return; 984171465Sjhb 98554263Sshin printf("%s:\n", name); 98654263Sshin 98754263Sshin#define p(f, m) if (pim6stat.f || sflag <= 1) \ 988160787Syar printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) 989160787Syar p(pim6s_rcv_total, "\t%ju message%s received\n"); 990160787Syar p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); 991160787Syar p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n"); 992160787Syar p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n"); 993160787Syar p(pim6s_rcv_registers, "\t%ju register%s received\n"); 994160787Syar p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n"); 995160787Syar p(pim6s_snd_registers, "\t%ju register%s sent\n"); 99654263Sshin#undef p 99754263Sshin} 99854263Sshin 99954263Sshin/* 100078064Sume * Dump raw ip6 statistics structure. 100178064Sume */ 100278064Sumevoid 1003171465Sjhbrip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 100478064Sume{ 1005293307Smarkj struct rip6stat rip6stat; 100678064Sume u_quad_t delivered; 100778064Sume 1008293307Smarkj if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat, 1009293307Smarkj sizeof(rip6stat), kread_counters) != 0) 1010293307Smarkj return; 101178064Sume 101278064Sume printf("%s:\n", name); 101378064Sume 101478064Sume#define p(f, m) if (rip6stat.f || sflag <= 1) \ 1015160787Syar printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) 1016160787Syar p(rip6s_ipackets, "\t%ju message%s received\n"); 1017186498Smaxim p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n"); 1018160787Syar p(rip6s_badsum, "\t%ju message%s with bad checksum\n"); 1019160787Syar p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n"); 102078064Sume p(rip6s_nosockmcast, 1021160787Syar "\t%ju multicast message%s dropped due to no socket\n"); 102278064Sume p(rip6s_fullsock, 1023160787Syar "\t%ju message%s dropped due to full socket buffers\n"); 102478064Sume delivered = rip6stat.rip6s_ipackets - 102578064Sume rip6stat.rip6s_badsum - 102678064Sume rip6stat.rip6s_nosock - 102778064Sume rip6stat.rip6s_nosockmcast - 102878064Sume rip6stat.rip6s_fullsock; 102978064Sume if (delivered || sflag <= 1) 1030160787Syar printf("\t%ju delivered\n", (uintmax_t)delivered); 1031160787Syar p(rip6s_opackets, "\t%ju datagram%s output\n"); 103278064Sume#undef p 103378064Sume} 103478064Sume 103578064Sume/* 103654263Sshin * Pretty print an Internet address (net address + port). 103778238Sassar * Take numeric_addr and numeric_port into consideration. 103854263Sshin */ 1039175061Sobrien#define GETSERVBYPORT6(port, proto, ret)\ 104054263Sshin{\ 104154263Sshin if (strcmp((proto), "tcp6") == 0)\ 104254263Sshin (ret) = getservbyport((int)(port), "tcp");\ 104354263Sshin else if (strcmp((proto), "udp6") == 0)\ 104454263Sshin (ret) = getservbyport((int)(port), "udp");\ 104554263Sshin else\ 104654263Sshin (ret) = getservbyport((int)(port), (proto));\ 104754263Sshin}; 104854263Sshin 104954263Sshinvoid 1050102975Sdwmaloneinet6print(struct in6_addr *in6, int port, const char *proto, int numeric) 105154263Sshin{ 105254263Sshin struct servent *sp = 0; 105354263Sshin char line[80], *cp; 105454263Sshin int width; 105554263Sshin 105683200Sru sprintf(line, "%.*s.", Wflag ? 39 : 105754263Sshin (Aflag && !numeric) ? 12 : 16, inet6name(in6)); 1058229403Sed cp = strchr(line, '\0'); 105954263Sshin if (!numeric && port) 106054263Sshin GETSERVBYPORT6(port, proto, sp); 106154263Sshin if (sp || port == 0) 1062177352Sume sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 106354263Sshin else 106454263Sshin sprintf(cp, "%d", ntohs((u_short)port)); 106583200Sru width = Wflag ? 45 : Aflag ? 18 : 22; 106655533Sshin printf("%-*.*s ", width, width, line); 106754263Sshin} 106854263Sshin 106954263Sshin/* 107054263Sshin * Construct an Internet address representation. 107178238Sassar * If the numeric_addr has been supplied, give 107254263Sshin * numeric value, otherwise try for symbolic name. 107354263Sshin */ 107454263Sshin 107554263Sshinchar * 107678314Sassarinet6name(struct in6_addr *in6p) 107754263Sshin{ 1078254459Shrs struct sockaddr_in6 sin6; 1079254459Shrs char hbuf[NI_MAXHOST], *cp; 108054263Sshin static char line[50]; 108174262Sbrian static char domain[MAXHOSTNAMELEN]; 108254263Sshin static int first = 1; 1083254459Shrs int flags, error; 108454263Sshin 1085254459Shrs if (IN6_IS_ADDR_UNSPECIFIED(in6p)) { 1086254459Shrs strcpy(line, "*"); 1087254459Shrs return (line); 1088254459Shrs } 108978238Sassar if (first && !numeric_addr) { 109054263Sshin first = 0; 109154263Sshin if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 1092229403Sed (cp = strchr(domain, '.'))) 109354263Sshin (void) strcpy(domain, cp + 1); 109454263Sshin else 109554263Sshin domain[0] = 0; 109654263Sshin } 1097254459Shrs memset(&sin6, 0, sizeof(sin6)); 1098254459Shrs memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p)); 1099254459Shrs sin6.sin6_family = AF_INET6; 1100254459Shrs /* XXX: in6p.s6_addr[2] can contain scopeid. */ 1101254459Shrs in6_fillscopeid(&sin6); 1102254459Shrs flags = (numeric_addr) ? NI_NUMERICHOST : 0; 1103254459Shrs error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, 1104254459Shrs sizeof(hbuf), NULL, 0, flags); 1105254459Shrs if (error == 0) { 1106254459Shrs if ((flags & NI_NUMERICHOST) == 0 && 1107254459Shrs (cp = strchr(hbuf, '.')) && 1108254459Shrs !strcmp(cp + 1, domain)) 1109254459Shrs *cp = 0; 1110254459Shrs strcpy(line, hbuf); 1111254459Shrs } else { 1112254459Shrs /* XXX: this should not happen. */ 111354263Sshin sprintf(line, "%s", 1114254459Shrs inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, 111554263Sshin sizeof(ntop_buf))); 1116254459Shrs } 111754263Sshin return (line); 111854263Sshin} 111964342Sume#endif /*INET6*/ 1120