inet6.c revision 270349
1178172Simp/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 2195162Simp/*- 3178172Simp * Copyright (c) 1983, 1988, 1993 4178172Simp * The Regents of the University of California. All rights reserved. 5178172Simp * 6178172Simp * Redistribution and use in source and binary forms, with or without 7178172Simp * modification, are permitted provided that the following conditions 8178172Simp * are met: 9178172Simp * 1. Redistributions of source code must retain the above copyright 10178172Simp * notice, this list of conditions and the following disclaimer. 11178172Simp * 2. Redistributions in binary form must reproduce the above copyright 12178172Simp * notice, this list of conditions and the following disclaimer in the 13178172Simp * documentation and/or other materials provided with the distribution. 14178172Simp * 4. Neither the name of the University nor the names of its contributors 15178172Simp * may be used to endorse or promote products derived from this software 16178172Simp * without specific prior written permission. 17178172Simp * 18178172Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21178172Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26202046Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28178172Simp * SUCH DAMAGE. 29178172Simp */ 30178172Simp 31178172Simp#if 0 32202046Simp#ifndef lint 33202046Simpstatic char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; 34202046Simp#endif /* not lint */ 35202046Simp#endif 36178172Simp 37178172Simp#include <sys/cdefs.h> 38178172Simp__FBSDID("$FreeBSD: head/usr.bin/netstat/inet6.c 270349 2014-08-22 19:23:38Z markj $"); 39178172Simp 40289701Sian#ifdef INET6 41178172Simp#include <sys/param.h> 42178172Simp#include <sys/socket.h> 43178172Simp#include <sys/socketvar.h> 44246713Skib#include <sys/ioctl.h> 45178172Simp#include <sys/mbuf.h> 46178172Simp#include <sys/protosw.h> 47178172Simp#include <sys/sysctl.h> 48202046Simp 49246713Skib#include <net/route.h> 50178172Simp#include <net/if.h> 51289701Sian#include <net/if_var.h> 52178172Simp#include <netinet/in.h> 53289701Sian#include <netinet/ip6.h> 54289701Sian#include <netinet/icmp6.h> 55178172Simp#include <netinet/in_systm.h> 56178172Simp#include <netinet6/in6_pcb.h> 57178172Simp#include <netinet6/in6_var.h> 58178172Simp#include <netinet6/ip6_var.h> 59178172Simp#include <netinet6/pim6_var.h> 60178172Simp#include <netinet6/raw_ip6.h> 61178172Simp 62204689Sneel#include <arpa/inet.h> 63202046Simp#include <netdb.h> 64178172Simp 65202046Simp#include <err.h> 66202046Simp#include <stdint.h> 67202046Simp#include <stdio.h> 68202046Simp#include <errno.h> 69202046Simp#include <string.h> 70202046Simp#include <unistd.h> 71178172Simp#include "netstat.h" 72178172Simp 73178172Simpstruct socket sockb; 74232356Sjhb 75178172Simpchar *inet6name(struct in6_addr *); 76178172Simp 77178172Simpstatic char ntop_buf[INET6_ADDRSTRLEN]; 78178172Simp 79178172Simpstatic const char *ip6nh[] = { 80178172Simp "hop by hop", 81178172Simp "ICMP", 82178172Simp "IGMP", 83178172Simp "#3", 84178172Simp "IP", 85178172Simp "#5", 86178172Simp "TCP", 87240177Sjhb "#7", 88202046Simp "#8", 89178172Simp "#9", 90178172Simp "#10", 91202046Simp "#11", 92202046Simp "#12", 93202046Simp "#13", 94202046Simp "#14", 95202046Simp "#15", 96246713Skib "#16", 97202046Simp "UDP", 98202046Simp "#18", 99202046Simp "#19", 100202046Simp "#20", 101246713Skib "#21", 102246713Skib "IDP", 103246713Skib "#23", 104246713Skib "#24", 105246713Skib "#25", 106246713Skib "#26", 107202046Simp "#27", 108202046Simp "#28", 109202046Simp "TP", 110202046Simp "#30", 111202046Simp "#31", 112202046Simp "#32", 113202046Simp "#33", 114202046Simp "#34", 115202046Simp "#35", 116202046Simp "#36", 117202046Simp "#37", 118202046Simp "#38", 119202046Simp "#39", 120202046Simp "#40", 121202046Simp "IP6", 122202046Simp "#42", 123202046Simp "routing", 124202046Simp "fragment", 125202046Simp "#45", 126202046Simp "#46", 127202046Simp "#47", 128202046Simp "#48", 129202046Simp "#49", 130202046Simp "ESP", 131202046Simp "AH", 132227309Sed "#52", 133202046Simp "#53", 134202046Simp "#54", 135202046Simp "#55", 136289701Sian "#56", 137289701Sian "#57", 138202046Simp "ICMP6", 139178172Simp "no next header", 140202046Simp "destination option", 141202046Simp "#61", 142202046Simp "mobility", 143212284Sjchandra "#63", 144246713Skib "#64", 145178172Simp "#65", 146178172Simp "#66", 147178172Simp "#67", 148178172Simp "#68", 149202046Simp "#69", 150202046Simp "#70", 151212284Sjchandra "#71", 152246713Skib "#72", 153246713Skib "#73", 154178172Simp "#74", 155178172Simp "#75", 156202046Simp "#76", 157202046Simp "#77", 158202046Simp "#78", 159202046Simp "#79", 160202046Simp "ISOIP", 161202046Simp "#81", 162202046Simp "#82", 163202046Simp "#83", 164202046Simp "#84", 165246713Skib "#85", 166246713Skib "#86", 167202046Simp "#87", 168202046Simp "#88", 169202046Simp "OSPF", 170202046Simp "#80", 171202046Simp "#91", 172289701Sian "#92", 173289701Sian "#93", 174289701Sian "#94", 175289701Sian "#95", 176289701Sian "#96", 177289701Sian "Ethernet", 178289701Sian "#98", 179289701Sian "#99", 180202046Simp "#100", 181289701Sian "#101", 182289701Sian "#102", 183289701Sian "PIM", 184289701Sian "#104", 185289701Sian "#105", 186289701Sian "#106", 187289701Sian "#107", 188289701Sian "#108", 189289701Sian "#109", 190289701Sian "#110", 191289701Sian "#111", 192289701Sian "#112", 193289701Sian "#113", 194289701Sian "#114", 195289701Sian "#115", 196289701Sian "#116", 197289701Sian "#117", 198289701Sian "#118", 199289701Sian "#119", 200289701Sian "#120", 201289701Sian "#121", 202289701Sian "#122", 203289701Sian "#123", 204289701Sian "#124", 205289701Sian "#125", 206289701Sian "#126", 207289701Sian "#127", 208289701Sian "#128", 209289701Sian "#129", 210289701Sian "#130", 211289701Sian "#131", 212289701Sian "#132", 213289701Sian "#133", 214289701Sian "#134", 215289701Sian "#135", 216289701Sian "#136", 217289701Sian "#137", 218289701Sian "#138", 219289701Sian "#139", 220289701Sian "#140", 221289701Sian "#141", 222289701Sian "#142", 223289701Sian "#143", 224289701Sian "#144", 225289701Sian "#145", 226289701Sian "#146", 227289701Sian "#147", 228289701Sian "#148", 229289701Sian "#149", 230289701Sian "#150", 231289701Sian "#151", 232289701Sian "#152", 233289701Sian "#153", 234289701Sian "#154", 235289701Sian "#155", 236289701Sian "#156", 237289701Sian "#157", 238289701Sian "#158", 239289701Sian "#159", 240289701Sian "#160", 241289701Sian "#161", 242289701Sian "#162", 243289701Sian "#163", 244289701Sian "#164", 245289701Sian "#165", 246289701Sian "#166", 247202046Simp "#167", 248202046Simp "#168", 249202046Simp "#169", 250202046Simp "#170", 251202046Simp "#171", 252202046Simp "#172", 253202046Simp "#173", 254202046Simp "#174", 255202046Simp "#175", 256202046Simp "#176", 257202046Simp "#177", 258202046Simp "#178", 259202046Simp "#179", 260202046Simp "#180", 261202046Simp "#181", 262202046Simp "#182", 263202046Simp "#183", 264202046Simp "#184", 265202046Simp "#185", 266202046Simp "#186", 267202046Simp "#187", 268202046Simp "#188", 269202046Simp "#189", 270202046Simp "#180", 271202046Simp "#191", 272202046Simp "#192", 273178172Simp "#193", 274178172Simp "#194", 275178172Simp "#195", 276178172Simp "#196", 277178172Simp "#197", 278202046Simp "#198", 279202046Simp "#199", 280202046Simp "#200", 281202046Simp "#201", 282202046Simp "#202", 283202046Simp "#203", 284202046Simp "#204", 285202046Simp "#205", 286202046Simp "#206", 287202046Simp "#207", 288202046Simp "#208", 289202046Simp "#209", 290178172Simp "#210", 291178172Simp "#211", 292178172Simp "#212", 293178172Simp "#213", 294178172Simp "#214", 295178172Simp "#215", 296178172Simp "#216", 297178172Simp "#217", 298178172Simp "#218", 299178172Simp "#219", 300178172Simp "#220", 301178172Simp "#221", 302178172Simp "#222", 303178172Simp "#223", 304178172Simp "#224", 305178172Simp "#225", 306178172Simp "#226", 307178172Simp "#227", 308178172Simp "#228", 309178172Simp "#229", 310178172Simp "#230", 311178172Simp "#231", 312178172Simp "#232", 313178172Simp "#233", 314178172Simp "#234", 315178172Simp "#235", 316178172Simp "#236", 317178172Simp "#237", 318178172Simp "#238", 319178172Simp "#239", 320178172Simp "#240", 321178172Simp "#241", 322178172Simp "#242", 323178172Simp "#243", 324178172Simp "#244", 325178172Simp "#245", 326178172Simp "#246", 327178172Simp "#247", 328178172Simp "#248", 329178172Simp "#249", 330178172Simp "#250", 331246713Skib "#251", 332178172Simp "#252", 333246713Skib "#253", 334178172Simp "#254", 335178172Simp "#255", 336289701Sian}; 337246713Skib 338246713Skibstatic const char *srcrule_str[] = { 339289701Sian "first candidate", 340289701Sian "same address", 341246713Skib "appropriate scope", 342289701Sian "deprecated address", 343289708Sian "home address", 344178172Simp "outgoing interface", 345178172Simp "matching label", 346178172Simp "public/temporary address", 347178172Simp "alive interface", 348178172Simp "preferred interface", 349178172Simp "rule #10", 350289708Sian "rule #11", 351289708Sian "rule #12", 352289701Sian "rule #13", 353178172Simp "longest match", 354178172Simp "rule #15", 355202046Simp}; 356202046Simp 357202046Simp/* 358202046Simp * Dump IP6 statistics structure. 359202046Simp */ 360178172Simpvoid 361178172Simpip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 362232356Sjhb{ 363212284Sjchandra struct ip6stat ip6stat, zerostat; 364212284Sjchandra int first, i; 365212284Sjchandra size_t len; 366212284Sjchandra 367178172Simp len = sizeof ip6stat; 368178172Simp if (live) { 369178172Simp memset(&ip6stat, 0, len); 370178172Simp if (zflag) 371178172Simp memset(&zerostat, 0, len); 372202046Simp if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len, 373202046Simp zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 374178172Simp if (errno != ENOENT) 375289701Sian warn("sysctl: net.inet6.ip6.stats"); 376178172Simp return; 377178172Simp } 378178172Simp } else 379178172Simp kread_counters(off, &ip6stat, len); 380178172Simp 381178172Simp printf("%s:\n", name); 382178172Simp 383178172Simp#define p(f, m) if (ip6stat.f || sflag <= 1) \ 384178172Simp printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) 385202046Simp#define p1a(f, m) if (ip6stat.f || sflag <= 1) \ 386202046Simp printf(m, (uintmax_t)ip6stat.f) 387178172Simp 388178172Simp p(ip6s_total, "\t%ju total packet%s received\n"); 389212284Sjchandra p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n"); 390212284Sjchandra p1a(ip6s_tooshort, "\t%ju with data size < data length\n"); 391178172Simp p1a(ip6s_badoptions, "\t%ju with bad options\n"); 392178172Simp p1a(ip6s_badvers, "\t%ju with incorrect version number\n"); 393204689Sneel p(ip6s_fragments, "\t%ju fragment%s received\n"); 394204689Sneel p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n"); 395178172Simp p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n"); 396178172Simp p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n"); 397178172Simp p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n"); 398178172Simp p(ip6s_delivered, "\t%ju packet%s for this host\n"); 399178172Simp p(ip6s_forward, "\t%ju packet%s forwarded\n"); 400178172Simp p(ip6s_cantforward, "\t%ju packet%s not forwardable\n"); 401178172Simp p(ip6s_redirectsent, "\t%ju redirect%s sent\n"); 402178172Simp p(ip6s_localout, "\t%ju packet%s sent from this host\n"); 403178172Simp p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n"); 404240177Sjhb p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n"); 405240177Sjhb p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n"); 406212284Sjchandra p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n"); 407202046Simp p(ip6s_ofragments, "\t%ju fragment%s created\n"); 408202046Simp p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n"); 409212284Sjchandra p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n"); 410232356Sjhb p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n"); 411232356Sjhb for (first = 1, i = 0; i < IP6S_HDRCNT; i++) 412178172Simp if (ip6stat.ip6s_nxthist[i] != 0) { 413178172Simp if (first) { 414178172Simp printf("\tInput histogram:\n"); 415212284Sjchandra first = 0; 416232356Sjhb } 417202046Simp printf("\t\t%s: %ju\n", ip6nh[i], 418202046Simp (uintmax_t)ip6stat.ip6s_nxthist[i]); 419202046Simp } 420212284Sjchandra printf("\tMbuf statistics:\n"); 421212284Sjchandra printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1); 422212284Sjchandra for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { 423212284Sjchandra char ifbuf[IFNAMSIZ]; 424212284Sjchandra if (ip6stat.ip6s_m2m[i] != 0) { 425212284Sjchandra if (first) { 426212284Sjchandra printf("\t\ttwo or more mbuf:\n"); 427212284Sjchandra first = 0; 428178172Simp } 429178172Simp printf("\t\t\t%s= %ju\n", 430178172Simp if_indextoname(i, ifbuf), 431178172Simp (uintmax_t)ip6stat.ip6s_m2m[i]); 432202046Simp } 433202046Simp } 434202046Simp printf("\t\t%ju one ext mbuf\n", 435178172Simp (uintmax_t)ip6stat.ip6s_mext1); 436202046Simp printf("\t\t%ju two or more ext mbuf\n", 437202046Simp (uintmax_t)ip6stat.ip6s_mext2m); 438202046Simp p(ip6s_exthdrtoolong, 439202046Simp "\t%ju packet%s whose headers are not contiguous\n"); 440202046Simp p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n"); 441202046Simp p(ip6s_toomanyhdr, 442202046Simp "\t%ju packet%s discarded because of too many headers\n"); 443289708Sian 444202046Simp /* for debugging source address selection */ 445202046Simp#define PRINT_SCOPESTAT(s,i) do {\ 446202046Simp switch(i) { /* XXX hardcoding in each case */\ 447202046Simp case 1:\ 448202046Simp p(s, "\t\t%ju interface-local%s\n");\ 449202046Simp break;\ 450202046Simp case 2:\ 451202046Simp p(s,"\t\t%ju link-local%s\n");\ 452202046Simp break;\ 453202046Simp case 5:\ 454202046Simp p(s,"\t\t%ju site-local%s\n");\ 455202046Simp break;\ 456202046Simp case 14:\ 457202046Simp p(s,"\t\t%ju global%s\n");\ 458202046Simp break;\ 459202046Simp default:\ 460202046Simp printf("\t\t%ju addresses scope=%x\n",\ 461202046Simp (uintmax_t)ip6stat.s, i);\ 462289708Sian }\ 463202046Simp } while (0); 464178172Simp 465178172Simp p(ip6s_sources_none, 466178172Simp "\t%ju failure%s of source address selection\n"); 467202046Simp for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 468178172Simp if (ip6stat.ip6s_sources_sameif[i]) { 469178172Simp if (first) { 470178172Simp printf("\tsource addresses on an outgoing I/F\n"); 471178172Simp first = 0; 472178172Simp } 473178172Simp PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); 474178172Simp } 475178172Simp } 476178172Simp for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 477178172Simp if (ip6stat.ip6s_sources_otherif[i]) { 478178172Simp if (first) { 479212284Sjchandra printf("\tsource addresses on a non-outgoing I/F\n"); 480212284Sjchandra first = 0; 481178172Simp } 482212284Sjchandra PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); 483212284Sjchandra } 484178172Simp } 485212284Sjchandra for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 486212284Sjchandra if (ip6stat.ip6s_sources_samescope[i]) { 487212284Sjchandra if (first) { 488240177Sjhb printf("\tsource addresses of same scope\n"); 489289708Sian first = 0; 490289708Sian } 491212284Sjchandra PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); 492212284Sjchandra } 493212284Sjchandra } 494212284Sjchandra for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 495212284Sjchandra if (ip6stat.ip6s_sources_otherscope[i]) { 496212284Sjchandra if (first) { 497212284Sjchandra printf("\tsource addresses of a different scope\n"); 498240177Sjhb first = 0; 499212284Sjchandra } 500212284Sjchandra PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); 501178172Simp } 502178172Simp } 503212284Sjchandra for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { 504178172Simp if (ip6stat.ip6s_sources_deprecated[i]) { 505178172Simp if (first) { 506202046Simp printf("\tdeprecated source addresses\n"); 507178172Simp first = 0; 508178172Simp } 509178172Simp PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); 510178172Simp } 511178172Simp } 512178172Simp 513178172Simp printf("\tSource addresses selection rule applied:\n"); 514178172Simp for (i = 0; i < IP6S_RULESMAX; i++) { 515178172Simp if (ip6stat.ip6s_sources_rule[i]) 516178172Simp printf("\t\t%ju %s\n", 517240177Sjhb (uintmax_t)ip6stat.ip6s_sources_rule[i], 518240177Sjhb srcrule_str[i]); 519289701Sian } 520240177Sjhb#undef p 521240177Sjhb#undef p1a 522240177Sjhb} 523240177Sjhb 524240177Sjhb/* 525240177Sjhb * Dump IPv6 per-interface statistics based on RFC 2465. 526240177Sjhb */ 527240177Sjhbvoid 528246713Skibip6_ifstats(char *ifname) 529178172Simp{ 530178172Simp struct in6_ifreq ifr; 531178172Simp int s; 532178172Simp#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 533178172Simp printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f)) 534178172Simp#define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 535202046Simp printf(m, (uintmax_t)ip6stat.f) 536202046Simp 537202046Simp if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 538202046Simp perror("Warning: socket(AF_INET6)"); 539202046Simp return; 540202046Simp } 541202046Simp 542202046Simp strcpy(ifr.ifr_name, ifname); 543202046Simp if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 544202046Simp if (errno != EPFNOSUPPORT) 545202046Simp perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); 546202046Simp goto end; 547202046Simp } 548202046Simp 549202046Simp printf("ip6 on %s:\n", ifr.ifr_name); 550202046Simp p(ifs6_in_receive, "\t%ju total input datagram%s\n"); 551202046Simp p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n"); 552202046Simp p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n"); 553202046Simp p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n"); 554202046Simp p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n"); 555202046Simp p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n"); 556202046Simp p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n"); 557202046Simp p(ifs6_in_discard, "\t%ju input datagram%s discarded\n"); 558202046Simp p(ifs6_in_deliver, 559202046Simp "\t%ju datagram%s delivered to an upper layer protocol\n"); 560202046Simp p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n"); 561202046Simp p(ifs6_out_request, 562202046Simp "\t%ju datagram%s sent from an upper layer protocol\n"); 563202046Simp p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n"); 564202046Simp p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n"); 565202046Simp p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n"); 566202046Simp p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n"); 567202046Simp p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n"); 568202046Simp p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n"); 569202046Simp p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n"); 570202046Simp p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n"); 571202046Simp p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n"); 572202046Simp 573202046Simp end: 574202046Simp close(s); 575202046Simp 576202046Simp#undef p 577202046Simp#undef p_5 578202046Simp} 579202046Simp 580202046Simpstatic const char *icmp6names[] = { 581202046Simp "#0", 582202046Simp "unreach", 583178172Simp "packet too big", 584178172Simp "time exceed", 585178172Simp "parameter problem", 586178172Simp "#5", 587178172Simp "#6", 588178172Simp "#7", 589178172Simp "#8", 590178172Simp "#9", 591178172Simp "#10", 592178172Simp "#11", 593178172Simp "#12", 594178172Simp "#13", 595178172Simp "#14", 596202046Simp "#15", 597246713Skib "#16", 598202046Simp "#17", 599202046Simp "#18", 600202046Simp "#19", 601202046Simp "#20", 602202046Simp "#21", 603202046Simp "#22", 604242465Sadrian "#23", 605178172Simp "#24", 606178172Simp "#25", 607178172Simp "#26", 608178172Simp "#27", 609178172Simp "#28", 610178172Simp "#29", 611178172Simp "#30", 612178172Simp "#31", 613178172Simp "#32", 614178172Simp "#33", 615289701Sian "#34", 616212284Sjchandra "#35", 617178172Simp "#36", 618178172Simp "#37", 619289701Sian "#38", 620289701Sian "#39", 621289701Sian "#40", 622289701Sian "#41", 623178172Simp "#42", 624178172Simp "#43", 625178172Simp "#44", 626178172Simp "#45", 627178172Simp "#46", 628178172Simp "#47", 629178172Simp "#48", 630240177Sjhb "#49", 631240177Sjhb "#50", 632289701Sian "#51", 633240177Sjhb "#52", 634240177Sjhb "#53", 635240177Sjhb "#54", 636240177Sjhb "#55", 637240177Sjhb "#56", 638240177Sjhb "#57", 639240177Sjhb "#58", 640178172Simp "#59", 641246713Skib "#60", 642178172Simp "#61", 643178172Simp "#62", 644178172Simp "#63", 645178172Simp "#64", 646178172Simp "#65", 647202046Simp "#66", 648204689Sneel "#67", 649204689Sneel "#68", 650204689Sneel "#69", 651204689Sneel "#70", 652204689Sneel "#71", 653204689Sneel "#72", 654204689Sneel "#73", 655289701Sian "#74", 656289701Sian "#75", 657289701Sian "#76", 658289701Sian "#77", 659289701Sian "#78", 660289701Sian "#79", 661289701Sian "#80", 662289701Sian "#81", 663289701Sian "#82", 664289701Sian "#83", 665289701Sian "#84", 666289701Sian "#85", 667289701Sian "#86", 668289701Sian "#87", 669204689Sneel "#88", 670289701Sian "#89", 671289701Sian "#80", 672289701Sian "#91", 673204689Sneel "#92", 674289701Sian "#93", 675204689Sneel "#94", 676289701Sian "#95", 677289701Sian "#96", 678289701Sian "#97", 679289701Sian "#98", 680289701Sian "#99", 681289701Sian "#100", 682289701Sian "#101", 683289701Sian "#102", 684289701Sian "#103", 685289701Sian "#104", 686289701Sian "#105", 687289701Sian "#106", 688289701Sian "#107", 689289701Sian "#108", 690289701Sian "#109", 691289701Sian "#110", 692289701Sian "#111", 693289701Sian "#112", 694289701Sian "#113", 695289701Sian "#114", 696212284Sjchandra "#115", 697289701Sian "#116", 698289701Sian "#117", 699289701Sian "#118", 700212284Sjchandra "#119", 701289701Sian "#120", 702289701Sian "#121", 703289701Sian "#122", 704289701Sian "#123", 705289701Sian "#124", 706178172Simp "#125", 707289701Sian "#126", 708289701Sian "#127", 709202046Simp "echo", 710289701Sian "echo reply", 711178172Simp "multicast listener query", 712178172Simp "MLDv1 listener report", 713178172Simp "MLDv1 listener done", 714178172Simp "router solicitation", 715178172Simp "router advertisement", 716178172Simp "neighbor solicitation", 717178172Simp "neighbor advertisement", 718178172Simp "redirect", 719178172Simp "router renumbering", 720289701Sian "node information request", 721289701Sian "node information reply", 722202046Simp "inverse neighbor solicitation", 723212283Sjchandra "inverse neighbor advertisement", 724289701Sian "MLDv2 listener report", 725212284Sjchandra "#144", 726289701Sian "#145", 727202046Simp "#146", 728289708Sian "#147", 729289701Sian "#148", 730289701Sian "#149", 731289701Sian "#150", 732289701Sian "#151", 733289701Sian "#152", 734289701Sian "#153", 735289701Sian "#154", 736289701Sian "#155", 737289701Sian "#156", 738178172Simp "#157", 739202046Simp "#158", 740178172Simp "#159", 741246713Skib "#160", 742246713Skib "#161", 743246713Skib "#162", 744246713Skib "#163", 745246713Skib "#164", 746246713Skib "#165", 747246713Skib "#166", 748246713Skib "#167", 749246713Skib "#168", 750246713Skib "#169", 751246713Skib "#170", 752246713Skib "#171", 753246713Skib "#172", 754246713Skib "#173", 755246713Skib "#174", 756246713Skib "#175", 757246713Skib "#176", 758246713Skib "#177", 759246713Skib "#178", 760246713Skib "#179", 761246713Skib "#180", 762246713Skib "#181", 763246713Skib "#182", 764246713Skib "#183", 765246713Skib "#184", 766246713Skib "#185", 767246713Skib "#186", 768246713Skib "#187", 769246713Skib "#188", 770246713Skib "#189", 771246713Skib "#180", 772202046Simp "#191", 773202046Simp "#192", 774202046Simp "#193", 775202046Simp "#194", 776202046Simp "#195", 777202046Simp "#196", 778202046Simp "#197", 779202046Simp "#198", 780202046Simp "#199", 781202046Simp "#200", 782202046Simp "#201", 783202046Simp "#202", 784202046Simp "#203", 785202046Simp "#204", 786202046Simp "#205", 787202046Simp "#206", 788206405Snwhitehorn "#207", 789202046Simp "#208", 790202046Simp "#209", 791202046Simp "#210", 792206405Snwhitehorn "#211", 793206405Snwhitehorn "#212", 794202046Simp "#213", 795206405Snwhitehorn "#214", 796202046Simp "#215", 797202046Simp "#216", 798206405Snwhitehorn "#217", 799206405Snwhitehorn "#218", 800202046Simp "#219", 801206405Snwhitehorn "#220", 802206405Snwhitehorn "#221", 803202046Simp "#222", 804202046Simp "#223", 805202046Simp "#224", 806246713Skib "#225", 807202046Simp "#226", 808246713Skib "#227", 809246713Skib "#228", 810246713Skib "#229", 811246713Skib "#230", 812202046Simp "#231", 813246713Skib "#232", 814246713Skib "#233", 815246713Skib "#234", 816246713Skib "#235", 817246713Skib "#236", 818202046Simp "#237", 819246713Skib "#238", 820246713Skib "#239", 821246713Skib "#240", 822246713Skib "#241", 823246713Skib "#242", 824246713Skib "#243", 825246713Skib "#244", 826246713Skib "#245", 827202046Simp "#246", 828246713Skib "#247", 829202046Simp "#248", 830202046Simp "#249", 831178172Simp "#250", 832178172Simp "#251", 833178172Simp "#252", 834246713Skib "#253", 835246713Skib "#254", 836246713Skib "#255", 837246713Skib}; 838246713Skib 839246713Skib/* 840246713Skib * Dump ICMP6 statistics. 841246713Skib */ 842246713Skibvoid 843246713Skibicmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 844246713Skib{ 845246713Skib struct icmp6stat icmp6stat, zerostat; 846246713Skib int i, first; 847246713Skib size_t len; 848246713Skib 849246713Skib len = sizeof icmp6stat; 850246713Skib if (live) { 851246713Skib memset(&icmp6stat, 0, len); 852246713Skib if (zflag) 853246713Skib memset(&zerostat, 0, len); 854246713Skib if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len, 855246713Skib zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 856246713Skib if (errno != ENOENT) 857246713Skib warn("sysctl: net.inet6.icmp6.stats"); 858246713Skib return; 859246713Skib } 860246713Skib } else 861246713Skib kread_counters(off, &icmp6stat, len); 862246713Skib 863246713Skib printf("%s:\n", name); 864246713Skib 865246713Skib#define p(f, m) if (icmp6stat.f || sflag <= 1) \ 866246713Skib printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) 867246713Skib#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ 868246713Skib printf(m, (uintmax_t)icmp6stat.f) 869246713Skib 870246713Skib p(icp6s_error, "\t%ju call%s to icmp6_error\n"); 871246713Skib p(icp6s_canterror, 872246713Skib "\t%ju error%s not generated in response to an icmp6 message\n"); 873246713Skib p(icp6s_toofreq, 874246713Skib "\t%ju error%s not generated because of rate limitation\n"); 875246713Skib#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) 876246713Skib for (first = 1, i = 0; i < NELEM; i++) 877246713Skib if (icmp6stat.icp6s_outhist[i] != 0) { 878246713Skib if (first) { 879246713Skib printf("\tOutput histogram:\n"); 880246713Skib first = 0; 881246713Skib } 882246713Skib printf("\t\t%s: %ju\n", icmp6names[i], 883246713Skib (uintmax_t)icmp6stat.icp6s_outhist[i]); 884246713Skib } 885246713Skib#undef NELEM 886246713Skib p(icp6s_badcode, "\t%ju message%s with bad code fields\n"); 887246713Skib p(icp6s_tooshort, "\t%ju message%s < minimum length\n"); 888246713Skib p(icp6s_checksum, "\t%ju bad checksum%s\n"); 889246713Skib p(icp6s_badlen, "\t%ju message%s with bad length\n"); 890246713Skib#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) 891246713Skib for (first = 1, i = 0; i < NELEM; i++) 892246713Skib if (icmp6stat.icp6s_inhist[i] != 0) { 893246713Skib if (first) { 894246713Skib printf("\tInput histogram:\n"); 895246713Skib first = 0; 896246713Skib } 897246713Skib printf("\t\t%s: %ju\n", icmp6names[i], 898246713Skib (uintmax_t)icmp6stat.icp6s_inhist[i]); 899246713Skib } 900246713Skib#undef NELEM 901246713Skib printf("\tHistogram of error messages to be generated:\n"); 902246713Skib p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n"); 903246713Skib p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n"); 904246713Skib p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n"); 905246713Skib p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n"); 906246713Skib p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n"); 907246713Skib p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n"); 908246713Skib p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n"); 909246713Skib p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n"); 910246713Skib p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n"); 911246713Skib p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n"); 912246713Skib p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n"); 913246713Skib p_5(icp6s_oredirect, "\t\t%ju redirect\n"); 914246713Skib p_5(icp6s_ounknown, "\t\t%ju unknown\n"); 915246713Skib 916246713Skib p(icp6s_reflect, "\t%ju message response%s generated\n"); 917246713Skib p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n"); 918246713Skib p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n"); 919246713Skib p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n"); 920246713Skib p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n"); 921246713Skib p(icp6s_badrs, "\t%ju bad router solicitation message%s\n"); 922246713Skib p(icp6s_badra, "\t%ju bad router advertisement message%s\n"); 923246713Skib p(icp6s_badredirect, "\t%ju bad redirect message%s\n"); 924246713Skib p(icp6s_pmtuchg, "\t%ju path MTU change%s\n"); 925257228Skib#undef p 926257228Skib#undef p_5 927257228Skib} 928257228Skib 929257228Skib/* 930257228Skib * Dump ICMPv6 per-interface statistics based on RFC 2466. 931257228Skib */ 932257228Skibvoid 933257228Skibicmp6_ifstats(char *ifname) 934257228Skib{ 935246713Skib struct in6_ifreq ifr; 936246713Skib int s; 937178172Simp#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 938178172Simp printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 939178172Simp#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 940246713Skib printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) 941246713Skib 942246713Skib if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 943246713Skib perror("Warning: socket(AF_INET6)"); 944178172Simp return; 945178172Simp } 946246713Skib 947246713Skib strcpy(ifr.ifr_name, ifname); 948178172Simp if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 949178172Simp if (errno != EPFNOSUPPORT) 950178172Simp perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 951178172Simp goto end; 952246713Skib } 953246713Skib 954289716Sian printf("icmp6 on %s:\n", ifr.ifr_name); 955289716Sian p(ifs6_in_msg, "\t%ju total input message%s\n"); 956246713Skib p(ifs6_in_error, "\t%ju total input error message%s\n"); 957202046Simp p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n"); 958246713Skib p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n"); 959246713Skib p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n"); 960246713Skib p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n"); 961246713Skib p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n"); 962246713Skib p(ifs6_in_echo, "\t%ju input echo request%s\n"); 963246713Skib p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n"); 964202046Simp p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n"); 965202046Simp p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n"); 966202046Simp p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n"); 967202046Simp p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n"); 968246713Skib p(ifs6_in_redirect, "\t%ju input redirect%s\n"); 969178172Simp p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n"); 970178172Simp p(ifs6_in_mldreport, "\t%ju input MLD report%s\n"); 971202046Simp p(ifs6_in_mlddone, "\t%ju input MLD done%s\n"); 972202046Simp 973202046Simp p(ifs6_out_msg, "\t%ju total output message%s\n"); 974178172Simp p(ifs6_out_error, "\t%ju total output error message%s\n"); 975178172Simp p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n"); 976178172Simp p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n"); 977178172Simp p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n"); 978178172Simp p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n"); 979178172Simp p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n"); 980178172Simp p(ifs6_out_echo, "\t%ju output echo request%s\n"); 981178172Simp p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n"); 982202046Simp p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n"); 983202046Simp p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n"); 984178172Simp p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n"); 985178172Simp p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n"); 986178172Simp p(ifs6_out_redirect, "\t%ju output redirect%s\n"); 987202046Simp p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n"); 988202046Simp p(ifs6_out_mldreport, "\t%ju output MLD report%s\n"); 989246713Skib p(ifs6_out_mlddone, "\t%ju output MLD done%s\n"); 990246713Skib 991178172Simp end: 992246713Skib close(s); 993246713Skib#undef p 994246713Skib} 995246713Skib 996246713Skib/* 997246713Skib * Dump PIM statistics structure. 998246713Skib */ 999246713Skibvoid 1000246713Skibpim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 1001246713Skib{ 1002246713Skib struct pim6stat pim6stat, zerostat; 1003178172Simp size_t len = sizeof pim6stat; 1004246713Skib 1005246713Skib if (live) { 1006246713Skib if (zflag) 1007178172Simp memset(&zerostat, 0, len); 1008178172Simp if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len, 1009178172Simp zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 1010178172Simp if (errno != ENOENT) 1011178172Simp warn("sysctl: net.inet6.pim.stats"); 1012246713Skib return; 1013178172Simp } 1014178172Simp } else { 1015178172Simp if (off == 0) 1016246713Skib return; 1017246713Skib kread(off, &pim6stat, len); 1018202046Simp } 1019246713Skib 1020202046Simp printf("%s:\n", name); 1021178172Simp 1022178172Simp#define p(f, m) if (pim6stat.f || sflag <= 1) \ 1023246713Skib printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) 1024246713Skib p(pim6s_rcv_total, "\t%ju message%s received\n"); 1025246713Skib p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); 1026178172Simp p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n"); 1027178172Simp p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n"); 1028178172Simp p(pim6s_rcv_registers, "\t%ju register%s received\n"); 1029178172Simp p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n"); 1030246713Skib p(pim6s_snd_registers, "\t%ju register%s sent\n"); 1031202046Simp#undef p 1032202046Simp} 1033178172Simp 1034178172Simp/* 1035246713Skib * Dump raw ip6 statistics structure. 1036246713Skib */ 1037246713Skibvoid 1038178172Simprip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 1039178172Simp{ 1040246713Skib struct rip6stat rip6stat, zerostat; 1041246713Skib u_quad_t delivered; 1042246713Skib size_t len; 1043178172Simp 1044178172Simp len = sizeof(rip6stat); 1045178172Simp if (live) { 1046178172Simp if (zflag) 1047178172Simp memset(&zerostat, 0, len); 1048178172Simp if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len, 1049178172Simp zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 1050178172Simp if (errno != ENOENT) 1051202046Simp warn("sysctl: net.inet6.ip6.rip6stats"); 1052178172Simp return; 1053202046Simp } 1054202046Simp } else 1055202046Simp kread_counters(off, &rip6stat, len); 1056202046Simp 1057246713Skib printf("%s:\n", name); 1058178172Simp 1059178172Simp#define p(f, m) if (rip6stat.f || sflag <= 1) \ 1060178172Simp printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) 1061202046Simp p(rip6s_ipackets, "\t%ju message%s received\n"); 1062289701Sian p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n"); 1063178172Simp p(rip6s_badsum, "\t%ju message%s with bad checksum\n"); 1064202046Simp p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n"); 1065202046Simp p(rip6s_nosockmcast, 1066202046Simp "\t%ju multicast message%s dropped due to no socket\n"); 1067202046Simp p(rip6s_fullsock, 1068178172Simp "\t%ju message%s dropped due to full socket buffers\n"); 1069202046Simp delivered = rip6stat.rip6s_ipackets - 1070202046Simp rip6stat.rip6s_badsum - 1071202046Simp rip6stat.rip6s_nosock - 1072202046Simp rip6stat.rip6s_nosockmcast - 1073202046Simp rip6stat.rip6s_fullsock; 1074289701Sian if (delivered || sflag <= 1) 1075289701Sian printf("\t%ju delivered\n", (uintmax_t)delivered); 1076289716Sian p(rip6s_opackets, "\t%ju datagram%s output\n"); 1077289716Sian#undef p 1078289716Sian} 1079289716Sian 1080289716Sian/* 1081289716Sian * Pretty print an Internet address (net address + port). 1082289716Sian * Take numeric_addr and numeric_port into consideration. 1083289716Sian */ 1084289716Sian#define GETSERVBYPORT6(port, proto, ret)\ 1085289716Sian{\ 1086202046Simp if (strcmp((proto), "tcp6") == 0)\ 1087289701Sian (ret) = getservbyport((int)(port), "tcp");\ 1088289701Sian else if (strcmp((proto), "udp6") == 0)\ 1089289701Sian (ret) = getservbyport((int)(port), "udp");\ 1090289701Sian else\ 1091289701Sian (ret) = getservbyport((int)(port), (proto));\ 1092289701Sian}; 1093289701Sian 1094289701Sianvoid 1095289701Sianinet6print(struct in6_addr *in6, int port, const char *proto, int numeric) 1096289701Sian{ 1097202046Simp struct servent *sp = 0; 1098178172Simp char line[80], *cp; 1099202046Simp int width; 1100202046Simp 1101202046Simp sprintf(line, "%.*s.", Wflag ? 39 : 1102202046Simp (Aflag && !numeric) ? 12 : 16, inet6name(in6)); 1103202046Simp cp = strchr(line, '\0'); 1104202046Simp if (!numeric && port) 1105202046Simp GETSERVBYPORT6(port, proto, sp); 1106202046Simp if (sp || port == 0) 1107202046Simp sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 1108202046Simp else 1109246713Skib sprintf(cp, "%d", ntohs((u_short)port)); 1110202046Simp width = Wflag ? 45 : Aflag ? 18 : 22; 1111202046Simp printf("%-*.*s ", width, width, line); 1112202046Simp} 1113202046Simp 1114202046Simp/* 1115202046Simp * Construct an Internet address representation. 1116202046Simp * If the numeric_addr has been supplied, give 1117203080Skan * numeric value, otherwise try for symbolic name. 1118203080Skan */ 1119203080Skan 1120203080Skanchar * 1121203080Skaninet6name(struct in6_addr *in6p) 1122203080Skan{ 1123203080Skan struct sockaddr_in6 sin6; 1124246713Skib char hbuf[NI_MAXHOST], *cp; 1125203080Skan static char line[50]; 1126203080Skan static char domain[MAXHOSTNAMELEN]; 1127246713Skib static int first = 1; 1128202046Simp int flags, error; 1129202046Simp 1130178172Simp if (IN6_IS_ADDR_UNSPECIFIED(in6p)) { 1131290082Sadrian strcpy(line, "*"); 1132178172Simp return (line); 1133178172Simp } 1134178172Simp if (first && !numeric_addr) { 1135202046Simp first = 0; 1136202046Simp if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 1137202046Simp (cp = strchr(domain, '.'))) 1138202046Simp (void) strcpy(domain, cp + 1); 1139202046Simp else 1140202046Simp domain[0] = 0; 1141202046Simp } 1142246713Skib memset(&sin6, 0, sizeof(sin6)); 1143202046Simp memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p)); 1144202046Simp sin6.sin6_family = AF_INET6; 1145202046Simp /* XXX: in6p.s6_addr[2] can contain scopeid. */ 1146202046Simp in6_fillscopeid(&sin6); 1147202046Simp flags = (numeric_addr) ? NI_NUMERICHOST : 0; 1148202046Simp error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, 1149202046Simp sizeof(hbuf), NULL, 0, flags); 1150203080Skan if (error == 0) { 1151203080Skan if ((flags & NI_NUMERICHOST) == 0 && 1152203080Skan (cp = strchr(hbuf, '.')) && 1153203080Skan !strcmp(cp + 1, domain)) 1154203080Skan *cp = 0; 1155203080Skan strcpy(line, hbuf); 1156203080Skan } else { 1157246713Skib /* XXX: this should not happen. */ 1158203080Skan sprintf(line, "%s", 1159203080Skan inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, 1160246713Skib sizeof(ntop_buf))); 1161178172Simp } 1162178172Simp return (line); 1163178172Simp} 1164246713Skib#endif /*INET6*/ 1165178172Simp