10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51676Sjpk * Common Development and Distribution License (the "License"). 61676Sjpk * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*3448Sdh155122 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 290Sstevel@tonic-gate #include <mdb/mdb_ks.h> 300Sstevel@tonic-gate #include <mdb/mdb_ctf.h> 310Sstevel@tonic-gate #include <sys/types.h> 320Sstevel@tonic-gate #include <sys/tihdr.h> 330Sstevel@tonic-gate #include <inet/led.h> 340Sstevel@tonic-gate #include <inet/common.h> 350Sstevel@tonic-gate #include <netinet/in.h> 360Sstevel@tonic-gate #include <netinet/ip6.h> 370Sstevel@tonic-gate #include <netinet/icmp6.h> 380Sstevel@tonic-gate #include <inet/ip.h> 390Sstevel@tonic-gate #include <inet/ip6.h> 400Sstevel@tonic-gate #include <inet/ipclassifier.h> 410Sstevel@tonic-gate #include <inet/tcp.h> 420Sstevel@tonic-gate #include <sys/stream.h> 430Sstevel@tonic-gate #include <sys/vfs.h> 440Sstevel@tonic-gate #include <sys/stropts.h> 450Sstevel@tonic-gate #include <sys/tpicommon.h> 460Sstevel@tonic-gate #include <sys/socket.h> 470Sstevel@tonic-gate #include <sys/socketvar.h> 480Sstevel@tonic-gate #include <sys/cred_impl.h> 490Sstevel@tonic-gate #include <inet/udp_impl.h> 500Sstevel@tonic-gate #include <inet/arp_impl.h> 510Sstevel@tonic-gate #include <inet/rawip_impl.h> 520Sstevel@tonic-gate #include <inet/mi.h> 530Sstevel@tonic-gate 540Sstevel@tonic-gate #define ADDR_V6_WIDTH 23 550Sstevel@tonic-gate #define ADDR_V4_WIDTH 15 560Sstevel@tonic-gate 571676Sjpk #define NETSTAT_ALL 0x01 581676Sjpk #define NETSTAT_VERBOSE 0x02 591676Sjpk #define NETSTAT_ROUTE 0x04 601676Sjpk #define NETSTAT_V4 0x08 611676Sjpk #define NETSTAT_V6 0x10 621676Sjpk #define NETSTAT_UNIX 0x20 631676Sjpk 641676Sjpk #define NETSTAT_FIRST 0x80000000u 650Sstevel@tonic-gate 66*3448Sdh155122 67*3448Sdh155122 /* Walkers for various *_stack_t */ 68*3448Sdh155122 int 69*3448Sdh155122 ar_stacks_walk_init(mdb_walk_state_t *wsp) 70*3448Sdh155122 { 71*3448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 72*3448Sdh155122 mdb_warn("can't walk 'netstack'"); 73*3448Sdh155122 return (WALK_ERR); 74*3448Sdh155122 } 75*3448Sdh155122 return (WALK_NEXT); 76*3448Sdh155122 } 77*3448Sdh155122 78*3448Sdh155122 int 79*3448Sdh155122 ar_stacks_walk_step(mdb_walk_state_t *wsp) 80*3448Sdh155122 { 81*3448Sdh155122 uintptr_t kaddr; 82*3448Sdh155122 netstack_t nss; 83*3448Sdh155122 84*3448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 85*3448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 86*3448Sdh155122 return (WALK_ERR); 87*3448Sdh155122 } 88*3448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_ARP]; 89*3448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 90*3448Sdh155122 } 91*3448Sdh155122 92*3448Sdh155122 int 93*3448Sdh155122 icmp_stacks_walk_init(mdb_walk_state_t *wsp) 94*3448Sdh155122 { 95*3448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 96*3448Sdh155122 mdb_warn("can't walk 'netstack'"); 97*3448Sdh155122 return (WALK_ERR); 98*3448Sdh155122 } 99*3448Sdh155122 return (WALK_NEXT); 100*3448Sdh155122 } 101*3448Sdh155122 102*3448Sdh155122 int 103*3448Sdh155122 icmp_stacks_walk_step(mdb_walk_state_t *wsp) 104*3448Sdh155122 { 105*3448Sdh155122 uintptr_t kaddr; 106*3448Sdh155122 netstack_t nss; 107*3448Sdh155122 108*3448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 109*3448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 110*3448Sdh155122 return (WALK_ERR); 111*3448Sdh155122 } 112*3448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_ICMP]; 113*3448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 114*3448Sdh155122 } 115*3448Sdh155122 116*3448Sdh155122 int 117*3448Sdh155122 tcp_stacks_walk_init(mdb_walk_state_t *wsp) 118*3448Sdh155122 { 119*3448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 120*3448Sdh155122 mdb_warn("can't walk 'netstack'"); 121*3448Sdh155122 return (WALK_ERR); 122*3448Sdh155122 } 123*3448Sdh155122 return (WALK_NEXT); 124*3448Sdh155122 } 125*3448Sdh155122 126*3448Sdh155122 int 127*3448Sdh155122 tcp_stacks_walk_step(mdb_walk_state_t *wsp) 128*3448Sdh155122 { 129*3448Sdh155122 uintptr_t kaddr; 130*3448Sdh155122 netstack_t nss; 131*3448Sdh155122 132*3448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 133*3448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 134*3448Sdh155122 return (WALK_ERR); 135*3448Sdh155122 } 136*3448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_TCP]; 137*3448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 138*3448Sdh155122 } 139*3448Sdh155122 140*3448Sdh155122 int 141*3448Sdh155122 udp_stacks_walk_init(mdb_walk_state_t *wsp) 142*3448Sdh155122 { 143*3448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 144*3448Sdh155122 mdb_warn("can't walk 'netstack'"); 145*3448Sdh155122 return (WALK_ERR); 146*3448Sdh155122 } 147*3448Sdh155122 return (WALK_NEXT); 148*3448Sdh155122 } 149*3448Sdh155122 150*3448Sdh155122 int 151*3448Sdh155122 udp_stacks_walk_step(mdb_walk_state_t *wsp) 152*3448Sdh155122 { 153*3448Sdh155122 uintptr_t kaddr; 154*3448Sdh155122 netstack_t nss; 155*3448Sdh155122 156*3448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 157*3448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 158*3448Sdh155122 return (WALK_ERR); 159*3448Sdh155122 } 160*3448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_UDP]; 161*3448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 162*3448Sdh155122 } 163*3448Sdh155122 1640Sstevel@tonic-gate /* 1650Sstevel@tonic-gate * Print an IPv4 address and port number in a compact and easy to read format 1660Sstevel@tonic-gate * The arguments are in network byte order 1670Sstevel@tonic-gate */ 1680Sstevel@tonic-gate static void 1690Sstevel@tonic-gate net_ipv4addrport_pr(const in6_addr_t *nipv6addr, in_port_t nport) 1700Sstevel@tonic-gate { 1710Sstevel@tonic-gate uint32_t naddr = V4_PART_OF_V6((*nipv6addr)); 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate mdb_nhconvert(&nport, &nport, sizeof (nport)); 1740Sstevel@tonic-gate mdb_printf("%*I.%-5hu", ADDR_V4_WIDTH, naddr, nport); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate /* 1780Sstevel@tonic-gate * Print an IPv6 address and port number in a compact and easy to read format 1790Sstevel@tonic-gate * The arguments are in network byte order 1800Sstevel@tonic-gate */ 1810Sstevel@tonic-gate static void 1820Sstevel@tonic-gate net_ipv6addrport_pr(const in6_addr_t *naddr, in_port_t nport) 1830Sstevel@tonic-gate { 1840Sstevel@tonic-gate mdb_nhconvert(&nport, &nport, sizeof (nport)); 1850Sstevel@tonic-gate mdb_printf("%*N.%-5hu", ADDR_V6_WIDTH, naddr, nport); 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate static int 1890Sstevel@tonic-gate net_tcp_active(const tcp_t *tcp) 1900Sstevel@tonic-gate { 1910Sstevel@tonic-gate return (tcp->tcp_state >= TCPS_ESTABLISHED); 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate static int 1950Sstevel@tonic-gate net_tcp_ipv4(const tcp_t *tcp) 1960Sstevel@tonic-gate { 1970Sstevel@tonic-gate return ((tcp->tcp_ipversion == IPV4_VERSION) || 1980Sstevel@tonic-gate (IN6_IS_ADDR_UNSPECIFIED(&tcp->tcp_ip_src_v6) && 1990Sstevel@tonic-gate (tcp->tcp_state <= TCPS_LISTEN))); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate static int 2030Sstevel@tonic-gate net_tcp_ipv6(const tcp_t *tcp) 2040Sstevel@tonic-gate { 2050Sstevel@tonic-gate return (tcp->tcp_ipversion == IPV6_VERSION); 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate static int 2090Sstevel@tonic-gate net_udp_active(const udp_t *udp) 2100Sstevel@tonic-gate { 211741Smasputra return ((udp->udp_state == TS_IDLE) || 212741Smasputra (udp->udp_state == TS_DATA_XFER)); 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate static int 2160Sstevel@tonic-gate net_udp_ipv4(const udp_t *udp) 2170Sstevel@tonic-gate { 2180Sstevel@tonic-gate return ((udp->udp_ipversion == IPV4_VERSION) || 2190Sstevel@tonic-gate (IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src) && 2200Sstevel@tonic-gate (udp->udp_state <= TS_IDLE))); 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate static int 2240Sstevel@tonic-gate net_udp_ipv6(const udp_t *udp) 2250Sstevel@tonic-gate { 2260Sstevel@tonic-gate return (udp->udp_ipversion == IPV6_VERSION); 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate int 2300Sstevel@tonic-gate sonode_walk_init(mdb_walk_state_t *wsp) 2310Sstevel@tonic-gate { 2320Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 2330Sstevel@tonic-gate GElf_Sym sym; 2340Sstevel@tonic-gate struct socklist *slp; 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate if (mdb_lookup_by_obj("sockfs", "socklist", &sym) == -1) { 2370Sstevel@tonic-gate mdb_warn("failed to lookup sockfs`socklist"); 2380Sstevel@tonic-gate return (WALK_ERR); 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate slp = (struct socklist *)(uintptr_t)sym.st_value; 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 2440Sstevel@tonic-gate (uintptr_t)&slp->sl_list) == -1) { 2450Sstevel@tonic-gate mdb_warn("failed to read address of initial sonode " 2460Sstevel@tonic-gate "at %p", &slp->sl_list); 2470Sstevel@tonic-gate return (WALK_ERR); 2480Sstevel@tonic-gate } 2490Sstevel@tonic-gate } 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (struct sonode), UM_SLEEP); 2520Sstevel@tonic-gate return (WALK_NEXT); 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate int 2560Sstevel@tonic-gate sonode_walk_step(mdb_walk_state_t *wsp) 2570Sstevel@tonic-gate { 2580Sstevel@tonic-gate int status; 2590Sstevel@tonic-gate struct sonode *sonodep; 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate if (wsp->walk_addr == NULL) 2620Sstevel@tonic-gate return (WALK_DONE); 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (struct sonode), 2650Sstevel@tonic-gate wsp->walk_addr) == -1) { 2660Sstevel@tonic-gate mdb_warn("failed to read sonode at %p", wsp->walk_addr); 2670Sstevel@tonic-gate return (WALK_ERR); 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 2710Sstevel@tonic-gate wsp->walk_cbdata); 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate sonodep = wsp->walk_data; 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)sonodep->so_next; 2760Sstevel@tonic-gate return (status); 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate void 2800Sstevel@tonic-gate sonode_walk_fini(mdb_walk_state_t *wsp) 2810Sstevel@tonic-gate { 2820Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (struct sonode)); 2830Sstevel@tonic-gate } 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate struct mi_walk_data { 2860Sstevel@tonic-gate uintptr_t mi_wd_miofirst; 2870Sstevel@tonic-gate MI_O mi_wd_miodata; 2880Sstevel@tonic-gate }; 2890Sstevel@tonic-gate 2900Sstevel@tonic-gate int 2910Sstevel@tonic-gate mi_walk_init(mdb_walk_state_t *wsp) 2920Sstevel@tonic-gate { 2930Sstevel@tonic-gate struct mi_walk_data *wdp; 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 2960Sstevel@tonic-gate mdb_warn("mi doesn't support global walks\n"); 2970Sstevel@tonic-gate return (WALK_ERR); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate wdp = mdb_alloc(sizeof (struct mi_walk_data), UM_SLEEP); 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate /* So that we do not immediately return WALK_DONE below */ 3030Sstevel@tonic-gate wdp->mi_wd_miofirst = NULL; 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate wsp->walk_data = wdp; 3060Sstevel@tonic-gate return (WALK_NEXT); 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate int 3100Sstevel@tonic-gate mi_walk_step(mdb_walk_state_t *wsp) 3110Sstevel@tonic-gate { 3120Sstevel@tonic-gate struct mi_walk_data *wdp = wsp->walk_data; 3130Sstevel@tonic-gate MI_OP miop = &wdp->mi_wd_miodata; 3140Sstevel@tonic-gate int status; 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate /* Always false in the first iteration */ 3170Sstevel@tonic-gate if ((wsp->walk_addr == (uintptr_t)NULL) || 3180Sstevel@tonic-gate (wsp->walk_addr == wdp->mi_wd_miofirst)) { 3190Sstevel@tonic-gate return (WALK_DONE); 3200Sstevel@tonic-gate } 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate if (mdb_vread(miop, sizeof (MI_O), wsp->walk_addr) == -1) { 3230Sstevel@tonic-gate mdb_warn("failed to read MI object at %p", wsp->walk_addr); 3240Sstevel@tonic-gate return (WALK_ERR); 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate /* Only true in the first iteration */ 328*3448Sdh155122 if (wdp->mi_wd_miofirst == NULL) { 3290Sstevel@tonic-gate wdp->mi_wd_miofirst = wsp->walk_addr; 330*3448Sdh155122 status = WALK_NEXT; 331*3448Sdh155122 } else { 332*3448Sdh155122 status = wsp->walk_callback(wsp->walk_addr + sizeof (MI_O), 333*3448Sdh155122 &miop[1], wsp->walk_cbdata); 334*3448Sdh155122 } 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)miop->mi_o_next; 3370Sstevel@tonic-gate return (status); 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate void 3410Sstevel@tonic-gate mi_walk_fini(mdb_walk_state_t *wsp) 3420Sstevel@tonic-gate { 3430Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (struct mi_walk_data)); 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate typedef struct mi_payload_walk_arg_s { 347*3448Sdh155122 const char *mi_pwa_walker; /* Underlying walker */ 348*3448Sdh155122 const off_t mi_pwa_head_off; /* Offset for mi_o_head_t * in stack */ 3490Sstevel@tonic-gate const size_t mi_pwa_size; /* size of mi payload */ 3500Sstevel@tonic-gate const uint_t mi_pwa_flags; /* device and/or module */ 3510Sstevel@tonic-gate } mi_payload_walk_arg_t; 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate #define MI_PAYLOAD_DEVICE 0x1 3540Sstevel@tonic-gate #define MI_PAYLOAD_MODULE 0x2 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate int 3570Sstevel@tonic-gate mi_payload_walk_init(mdb_walk_state_t *wsp) 3580Sstevel@tonic-gate { 3590Sstevel@tonic-gate const mi_payload_walk_arg_t *arg = wsp->walk_arg; 3600Sstevel@tonic-gate 361*3448Sdh155122 if (mdb_layered_walk(arg->mi_pwa_walker, wsp) == -1) { 362*3448Sdh155122 mdb_warn("can't walk '%s'", arg->mi_pwa_walker); 3630Sstevel@tonic-gate return (WALK_ERR); 3640Sstevel@tonic-gate } 3650Sstevel@tonic-gate return (WALK_NEXT); 3660Sstevel@tonic-gate } 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate int 3690Sstevel@tonic-gate mi_payload_walk_step(mdb_walk_state_t *wsp) 3700Sstevel@tonic-gate { 3710Sstevel@tonic-gate const mi_payload_walk_arg_t *arg = wsp->walk_arg; 372*3448Sdh155122 uintptr_t kaddr; 3730Sstevel@tonic-gate 374*3448Sdh155122 kaddr = wsp->walk_addr + arg->mi_pwa_head_off; 3750Sstevel@tonic-gate 376*3448Sdh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) { 377*3448Sdh155122 mdb_warn("can't read address of mi head at %p for %s", 378*3448Sdh155122 kaddr, arg->mi_pwa_walker); 3790Sstevel@tonic-gate return (WALK_ERR); 3800Sstevel@tonic-gate } 3810Sstevel@tonic-gate 382*3448Sdh155122 if (kaddr == 0) { 383*3448Sdh155122 /* Empty list */ 384*3448Sdh155122 return (WALK_DONE); 385*3448Sdh155122 } 3860Sstevel@tonic-gate 387*3448Sdh155122 if (mdb_pwalk("genunix`mi", wsp->walk_callback, 388*3448Sdh155122 wsp->walk_cbdata, kaddr) == -1) { 389*3448Sdh155122 mdb_warn("failed to walk genunix`mi"); 390*3448Sdh155122 return (WALK_ERR); 391*3448Sdh155122 } 392*3448Sdh155122 return (WALK_NEXT); 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate const mi_payload_walk_arg_t mi_ar_arg = { 396*3448Sdh155122 "ar_stacks", OFFSETOF(arp_stack_t, as_head), sizeof (ar_t), 3970Sstevel@tonic-gate MI_PAYLOAD_DEVICE | MI_PAYLOAD_MODULE 3980Sstevel@tonic-gate }; 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate const mi_payload_walk_arg_t mi_icmp_arg = { 401*3448Sdh155122 "icmp_stacks", OFFSETOF(icmp_stack_t, is_head), sizeof (icmp_t), 4020Sstevel@tonic-gate MI_PAYLOAD_DEVICE | MI_PAYLOAD_MODULE 4030Sstevel@tonic-gate }; 4040Sstevel@tonic-gate 405*3448Sdh155122 const mi_payload_walk_arg_t mi_ill_arg = { 406*3448Sdh155122 "ip_stacks", OFFSETOF(ip_stack_t, ips_ip_g_head), sizeof (ill_t), 407*3448Sdh155122 MI_PAYLOAD_MODULE 408*3448Sdh155122 }; 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate int 4110Sstevel@tonic-gate sonode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 4120Sstevel@tonic-gate { 4130Sstevel@tonic-gate const char *optf = NULL; 4140Sstevel@tonic-gate const char *optt = NULL; 4150Sstevel@tonic-gate const char *optp = NULL; 4160Sstevel@tonic-gate int family, type, proto; 4170Sstevel@tonic-gate int filter = 0; 4180Sstevel@tonic-gate struct sonode so; 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 4210Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`sonode", "genunix`sonode", argc, 4220Sstevel@tonic-gate argv) == -1) { 4230Sstevel@tonic-gate mdb_warn("failed to walk sonode"); 4240Sstevel@tonic-gate return (DCMD_ERR); 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate return (DCMD_OK); 4280Sstevel@tonic-gate } 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate if (mdb_getopts(argc, argv, 4310Sstevel@tonic-gate 'f', MDB_OPT_STR, &optf, 4320Sstevel@tonic-gate 't', MDB_OPT_STR, &optt, 4330Sstevel@tonic-gate 'p', MDB_OPT_STR, &optp, 4340Sstevel@tonic-gate NULL) != argc) 4350Sstevel@tonic-gate return (DCMD_USAGE); 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate if (optf != NULL) { 4380Sstevel@tonic-gate if (strcmp("inet", optf) == 0) 4390Sstevel@tonic-gate family = AF_INET; 4400Sstevel@tonic-gate else if (strcmp("inet6", optf) == 0) 4410Sstevel@tonic-gate family = AF_INET6; 4420Sstevel@tonic-gate else if (strcmp("unix", optf) == 0) 4430Sstevel@tonic-gate family = AF_UNIX; 4440Sstevel@tonic-gate else 4450Sstevel@tonic-gate family = mdb_strtoull(optf); 4460Sstevel@tonic-gate filter = 1; 4470Sstevel@tonic-gate } 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate if (optt != NULL) { 4500Sstevel@tonic-gate if (strcmp("stream", optt) == 0) 4510Sstevel@tonic-gate type = SOCK_STREAM; 4520Sstevel@tonic-gate else if (strcmp("dgram", optt) == 0) 4530Sstevel@tonic-gate type = SOCK_DGRAM; 4540Sstevel@tonic-gate else if (strcmp("raw", optt) == 0) 4550Sstevel@tonic-gate type = SOCK_RAW; 4560Sstevel@tonic-gate else 4570Sstevel@tonic-gate type = mdb_strtoull(optt); 4580Sstevel@tonic-gate filter = 1; 4590Sstevel@tonic-gate } 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate if (optp != NULL) { 4620Sstevel@tonic-gate proto = mdb_strtoull(optp); 4630Sstevel@tonic-gate filter = 1; 4640Sstevel@tonic-gate } 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !filter) { 4670Sstevel@tonic-gate mdb_printf("%<u>%-?s Family Type Proto State Mode Flag " 4680Sstevel@tonic-gate "AccessVP%</u>\n", "Sonode:"); 4690Sstevel@tonic-gate } 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate if (mdb_vread(&so, sizeof (so), addr) == -1) { 4720Sstevel@tonic-gate mdb_warn("failed to read sonode at %p", addr); 4730Sstevel@tonic-gate return (DCMD_ERR); 4740Sstevel@tonic-gate } 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate if ((optf != NULL) && (so.so_family != family)) 4770Sstevel@tonic-gate return (DCMD_OK); 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate if ((optt != NULL) && (so.so_type != type)) 4800Sstevel@tonic-gate return (DCMD_OK); 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate if ((optp != NULL) && (so.so_protocol != proto)) 4830Sstevel@tonic-gate return (DCMD_OK); 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate if (filter) { 4860Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 4870Sstevel@tonic-gate return (DCMD_OK); 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate mdb_printf("%0?p ", addr); 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate switch (so.so_family) { 4930Sstevel@tonic-gate case AF_UNIX: 4940Sstevel@tonic-gate mdb_printf("unix "); 4950Sstevel@tonic-gate break; 4960Sstevel@tonic-gate case AF_INET: 4970Sstevel@tonic-gate mdb_printf("inet "); 4980Sstevel@tonic-gate break; 4990Sstevel@tonic-gate case AF_INET6: 5000Sstevel@tonic-gate mdb_printf("inet6 "); 5010Sstevel@tonic-gate break; 5020Sstevel@tonic-gate default: 5030Sstevel@tonic-gate mdb_printf("%6hi", so.so_family); 5040Sstevel@tonic-gate } 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate switch (so.so_type) { 5070Sstevel@tonic-gate case SOCK_STREAM: 5080Sstevel@tonic-gate mdb_printf(" strm"); 5090Sstevel@tonic-gate break; 5100Sstevel@tonic-gate case SOCK_DGRAM: 5110Sstevel@tonic-gate mdb_printf(" dgrm"); 5120Sstevel@tonic-gate break; 5130Sstevel@tonic-gate case SOCK_RAW: 5140Sstevel@tonic-gate mdb_printf(" raw "); 5150Sstevel@tonic-gate break; 5160Sstevel@tonic-gate default: 5170Sstevel@tonic-gate mdb_printf(" %4hi", so.so_type); 5180Sstevel@tonic-gate } 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate mdb_printf(" %5hi %05x %04x %04hx %0?p\n", 5210Sstevel@tonic-gate so.so_protocol, so.so_state, so.so_mode, 5220Sstevel@tonic-gate so.so_flag, so.so_accessvp); 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate return (DCMD_OK); 5250Sstevel@tonic-gate } 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate #define MI_PAYLOAD 0x1 5280Sstevel@tonic-gate #define MI_DEVICE 0x2 5290Sstevel@tonic-gate #define MI_MODULE 0x4 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate int 5320Sstevel@tonic-gate mi(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5330Sstevel@tonic-gate { 5340Sstevel@tonic-gate uint_t opts = 0; 5350Sstevel@tonic-gate MI_O mio; 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 5380Sstevel@tonic-gate return (DCMD_USAGE); 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate if (mdb_getopts(argc, argv, 5410Sstevel@tonic-gate 'p', MDB_OPT_SETBITS, MI_PAYLOAD, &opts, 5420Sstevel@tonic-gate 'd', MDB_OPT_SETBITS, MI_DEVICE, &opts, 5430Sstevel@tonic-gate 'm', MDB_OPT_SETBITS, MI_MODULE, &opts, 5440Sstevel@tonic-gate NULL) != argc) 5450Sstevel@tonic-gate return (DCMD_USAGE); 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate if ((opts & (MI_DEVICE | MI_MODULE)) == (MI_DEVICE | MI_MODULE)) { 5480Sstevel@tonic-gate mdb_warn("at most one filter, d for devices or m " 5490Sstevel@tonic-gate "for modules, may be specified\n"); 5500Sstevel@tonic-gate return (DCMD_USAGE); 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate if ((opts == 0) && (DCMD_HDRSPEC(flags))) { 5540Sstevel@tonic-gate mdb_printf("%<u>%-?s %-?s %-?s IsDev Dev%</u>\n", 5550Sstevel@tonic-gate "MI_O", "Next", "Prev"); 5560Sstevel@tonic-gate } 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate if (mdb_vread(&mio, sizeof (mio), addr) == -1) { 5590Sstevel@tonic-gate mdb_warn("failed to read mi object MI_O at %p", addr); 5600Sstevel@tonic-gate return (DCMD_ERR); 5610Sstevel@tonic-gate } 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate if (opts != 0) { 5640Sstevel@tonic-gate if (mio.mi_o_isdev == B_FALSE) { 5650Sstevel@tonic-gate /* mio is a module */ 5660Sstevel@tonic-gate if (!(opts & MI_MODULE) && (opts & MI_DEVICE)) 5670Sstevel@tonic-gate return (DCMD_OK); 5680Sstevel@tonic-gate } else { 5690Sstevel@tonic-gate /* mio is a device */ 5700Sstevel@tonic-gate if (!(opts & MI_DEVICE) && (opts & MI_MODULE)) 5710Sstevel@tonic-gate return (DCMD_OK); 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate if (opts & MI_PAYLOAD) 5750Sstevel@tonic-gate mdb_printf("%p\n", addr + sizeof (MI_O)); 5760Sstevel@tonic-gate else 5770Sstevel@tonic-gate mdb_printf("%p\n", addr); 5780Sstevel@tonic-gate return (DCMD_OK); 5790Sstevel@tonic-gate } 5800Sstevel@tonic-gate 5810Sstevel@tonic-gate mdb_printf("%0?p %0?p %0?p ", addr, mio.mi_o_next, mio.mi_o_prev); 5820Sstevel@tonic-gate 5830Sstevel@tonic-gate if (mio.mi_o_isdev == B_FALSE) 5840Sstevel@tonic-gate mdb_printf("FALSE"); 5850Sstevel@tonic-gate else 5860Sstevel@tonic-gate mdb_printf("TRUE "); 5870Sstevel@tonic-gate 5880Sstevel@tonic-gate mdb_printf(" %0?p\n", mio.mi_o_dev); 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate return (DCMD_OK); 5910Sstevel@tonic-gate } 5920Sstevel@tonic-gate 593*3448Sdh155122 static int 594*3448Sdh155122 ns_to_stackid(uintptr_t kaddr) 595*3448Sdh155122 { 596*3448Sdh155122 netstack_t nss; 597*3448Sdh155122 598*3448Sdh155122 if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) { 599*3448Sdh155122 mdb_warn("failed to read netstack_t %p", kaddr); 600*3448Sdh155122 return (0); 601*3448Sdh155122 } 602*3448Sdh155122 return (nss.netstack_stackid); 603*3448Sdh155122 } 604*3448Sdh155122 605*3448Sdh155122 606*3448Sdh155122 6070Sstevel@tonic-gate static void 6080Sstevel@tonic-gate netstat_tcp_verbose_pr(const tcp_t *tcp) 6090Sstevel@tonic-gate { 6100Sstevel@tonic-gate mdb_printf(" %5i %08x %08x %5i %08x %08x %5li %5i\n", 6110Sstevel@tonic-gate tcp->tcp_swnd, tcp->tcp_snxt, tcp->tcp_suna, tcp->tcp_rwnd, 6120Sstevel@tonic-gate tcp->tcp_rack, tcp->tcp_rnxt, tcp->tcp_rto, tcp->tcp_mss); 6130Sstevel@tonic-gate } 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate /*ARGSUSED*/ 6160Sstevel@tonic-gate static int 6170Sstevel@tonic-gate netstat_tcp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data, int af) 6180Sstevel@tonic-gate { 6190Sstevel@tonic-gate const uintptr_t opts = (uintptr_t)cb_data; 6200Sstevel@tonic-gate static size_t itc_size = 0; 6210Sstevel@tonic-gate uintptr_t tcp_kaddr; 6220Sstevel@tonic-gate conn_t *connp; 6230Sstevel@tonic-gate tcp_t *tcp; 6240Sstevel@tonic-gate 6250Sstevel@tonic-gate if (itc_size == 0) { 6260Sstevel@tonic-gate mdb_ctf_id_t id; 6270Sstevel@tonic-gate 6280Sstevel@tonic-gate if (mdb_ctf_lookup_by_name("itc_t", &id) != 0) { 6290Sstevel@tonic-gate mdb_warn("failed to lookup type 'itc_t'"); 6300Sstevel@tonic-gate return (WALK_ERR); 6310Sstevel@tonic-gate } 6320Sstevel@tonic-gate itc_size = mdb_ctf_type_size(id); 6330Sstevel@tonic-gate } 6340Sstevel@tonic-gate 6350Sstevel@tonic-gate connp = (conn_t *)mdb_alloc(itc_size, UM_SLEEP | UM_GC); 6360Sstevel@tonic-gate 6370Sstevel@tonic-gate if (mdb_vread(connp, itc_size, kaddr) == -1) { 6380Sstevel@tonic-gate mdb_warn("failed to read connection info at %p", kaddr); 6390Sstevel@tonic-gate return (WALK_ERR); 6400Sstevel@tonic-gate } 6410Sstevel@tonic-gate 6420Sstevel@tonic-gate tcp_kaddr = (uintptr_t)connp->conn_tcp; 6430Sstevel@tonic-gate tcp = (tcp_t *)((uintptr_t)connp + (tcp_kaddr - kaddr)); 6440Sstevel@tonic-gate 6450Sstevel@tonic-gate if ((uintptr_t)tcp < (uintptr_t)connp || 646741Smasputra (uintptr_t)(tcp + 1) > (uintptr_t)connp + itc_size || 6470Sstevel@tonic-gate (uintptr_t)tcp->tcp_connp != kaddr) { 6480Sstevel@tonic-gate mdb_warn("conn_tcp %p is invalid", tcp_kaddr); 6490Sstevel@tonic-gate return (WALK_NEXT); 6500Sstevel@tonic-gate } 6510Sstevel@tonic-gate connp->conn_tcp = tcp; 6520Sstevel@tonic-gate tcp->tcp_connp = connp; 6530Sstevel@tonic-gate 654741Smasputra if (!((opts & NETSTAT_ALL) || net_tcp_active(tcp)) || 6550Sstevel@tonic-gate (af == AF_INET && !net_tcp_ipv4(tcp)) || 6560Sstevel@tonic-gate (af == AF_INET6 && !net_tcp_ipv6(tcp))) { 6570Sstevel@tonic-gate return (WALK_NEXT); 6580Sstevel@tonic-gate } 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate mdb_printf("%0?p %2i ", tcp_kaddr, tcp->tcp_state); 6610Sstevel@tonic-gate if (af == AF_INET) { 6620Sstevel@tonic-gate net_ipv4addrport_pr(&tcp->tcp_ip_src_v6, tcp->tcp_lport); 6630Sstevel@tonic-gate mdb_printf(" "); 6640Sstevel@tonic-gate net_ipv4addrport_pr(&tcp->tcp_remote_v6, tcp->tcp_fport); 6650Sstevel@tonic-gate } else if (af == AF_INET6) { 6660Sstevel@tonic-gate net_ipv6addrport_pr(&tcp->tcp_ip_src_v6, tcp->tcp_lport); 6670Sstevel@tonic-gate mdb_printf(" "); 6680Sstevel@tonic-gate net_ipv6addrport_pr(&tcp->tcp_remote_v6, tcp->tcp_fport); 6690Sstevel@tonic-gate } 670*3448Sdh155122 mdb_printf(" %4i", ns_to_stackid((uintptr_t)connp->conn_netstack)); 671*3448Sdh155122 6720Sstevel@tonic-gate mdb_printf(" %4i\n", connp->conn_zoneid); 6730Sstevel@tonic-gate 6740Sstevel@tonic-gate if (opts & NETSTAT_VERBOSE) 6750Sstevel@tonic-gate netstat_tcp_verbose_pr(tcp); 6760Sstevel@tonic-gate 6770Sstevel@tonic-gate return (WALK_NEXT); 6780Sstevel@tonic-gate } 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate static int 6810Sstevel@tonic-gate netstat_tcpv4_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 6820Sstevel@tonic-gate { 6830Sstevel@tonic-gate return (netstat_tcp_cb(kaddr, walk_data, cb_data, AF_INET)); 6840Sstevel@tonic-gate } 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate static int 6870Sstevel@tonic-gate netstat_tcpv6_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 6880Sstevel@tonic-gate { 6890Sstevel@tonic-gate return (netstat_tcp_cb(kaddr, walk_data, cb_data, AF_INET6)); 6900Sstevel@tonic-gate } 6910Sstevel@tonic-gate 692741Smasputra /*ARGSUSED*/ 6930Sstevel@tonic-gate static int 694741Smasputra netstat_udp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data, int af) 6950Sstevel@tonic-gate { 6960Sstevel@tonic-gate const uintptr_t opts = (uintptr_t)cb_data; 697741Smasputra udp_t udp; 698741Smasputra conn_t connp; 699741Smasputra 700741Smasputra if (mdb_vread(&udp, sizeof (udp_t), kaddr) == -1) { 701741Smasputra mdb_warn("failed to read udp at %p", kaddr); 702741Smasputra return (WALK_ERR); 703741Smasputra } 7040Sstevel@tonic-gate 705741Smasputra if (mdb_vread(&connp, sizeof (conn_t), 706741Smasputra (uintptr_t)udp.udp_connp) == -1) { 707741Smasputra mdb_warn("failed to read udp_connp at %p", 708741Smasputra (uintptr_t)udp.udp_connp); 709741Smasputra return (WALK_ERR); 710741Smasputra } 7110Sstevel@tonic-gate 712741Smasputra if (!((opts & NETSTAT_ALL) || net_udp_active(&udp)) || 713741Smasputra (af == AF_INET && !net_udp_ipv4(&udp)) || 714741Smasputra (af == AF_INET6 && !net_udp_ipv6(&udp))) { 715741Smasputra return (WALK_NEXT); 716741Smasputra } 717741Smasputra 718741Smasputra mdb_printf("%0?p %2i ", kaddr, udp.udp_state); 719741Smasputra if (af == AF_INET) { 720741Smasputra net_ipv4addrport_pr(&udp.udp_v6src, udp.udp_port); 721741Smasputra mdb_printf(" "); 722741Smasputra net_ipv4addrport_pr(&udp.udp_v6dst, udp.udp_dstport); 723741Smasputra } else if (af == AF_INET6) { 724741Smasputra net_ipv6addrport_pr(&udp.udp_v6src, udp.udp_port); 725741Smasputra mdb_printf(" "); 726741Smasputra net_ipv6addrport_pr(&udp.udp_v6dst, udp.udp_dstport); 727741Smasputra } 728*3448Sdh155122 mdb_printf(" %4i", ns_to_stackid((uintptr_t)connp.conn_netstack)); 729*3448Sdh155122 730741Smasputra mdb_printf(" %4i\n", connp.conn_zoneid); 7310Sstevel@tonic-gate 7320Sstevel@tonic-gate return (WALK_NEXT); 7330Sstevel@tonic-gate } 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate static int 736741Smasputra netstat_udpv4_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 737741Smasputra { 738741Smasputra return (netstat_udp_cb(kaddr, walk_data, cb_data, AF_INET)); 739741Smasputra } 740741Smasputra 741741Smasputra static int 7420Sstevel@tonic-gate netstat_udpv6_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 7430Sstevel@tonic-gate { 744741Smasputra return (netstat_udp_cb(kaddr, walk_data, cb_data, AF_INET6)); 7450Sstevel@tonic-gate } 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate /* 7480Sstevel@tonic-gate * print the address of a unix domain socket 7490Sstevel@tonic-gate * 7500Sstevel@tonic-gate * so is the address of a AF_UNIX struct sonode in mdb's address space 7510Sstevel@tonic-gate * soa is the address of the struct soaddr to print 7520Sstevel@tonic-gate * 7530Sstevel@tonic-gate * returns 0 on success, -1 otherwise 7540Sstevel@tonic-gate */ 7550Sstevel@tonic-gate static int 7560Sstevel@tonic-gate netstat_unix_name_pr(const struct sonode *so, const struct soaddr *soa) 7570Sstevel@tonic-gate { 7580Sstevel@tonic-gate const char none[] = " (none)"; 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate if ((so->so_state & SS_ISBOUND) && (soa->soa_len != 0)) { 7610Sstevel@tonic-gate if (so->so_state & SS_FADDR_NOXLATE) { 7620Sstevel@tonic-gate mdb_printf("%-14s ", " (socketpair)"); 7630Sstevel@tonic-gate } else { 7640Sstevel@tonic-gate if (soa->soa_len > sizeof (sa_family_t)) { 7650Sstevel@tonic-gate char addr[MAXPATHLEN + 1]; 7660Sstevel@tonic-gate 7670Sstevel@tonic-gate if (mdb_readstr(addr, sizeof (addr), 7680Sstevel@tonic-gate (uintptr_t)&soa->soa_sa->sa_data) == -1) { 7690Sstevel@tonic-gate mdb_warn("failed to read unix address " 7700Sstevel@tonic-gate "at %p", &soa->soa_sa->sa_data); 7710Sstevel@tonic-gate return (-1); 7720Sstevel@tonic-gate } 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate mdb_printf("%-14s ", addr); 7750Sstevel@tonic-gate } else { 7760Sstevel@tonic-gate mdb_printf("%-14s ", none); 7770Sstevel@tonic-gate } 7780Sstevel@tonic-gate } 7790Sstevel@tonic-gate } else { 7800Sstevel@tonic-gate mdb_printf("%-14s ", none); 7810Sstevel@tonic-gate } 7820Sstevel@tonic-gate 7830Sstevel@tonic-gate return (0); 7840Sstevel@tonic-gate } 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate /* based on sockfs_snapshot */ 7870Sstevel@tonic-gate /*ARGSUSED*/ 7880Sstevel@tonic-gate static int 7890Sstevel@tonic-gate netstat_unix_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 7900Sstevel@tonic-gate { 7910Sstevel@tonic-gate const struct sonode *so = walk_data; 7920Sstevel@tonic-gate 7930Sstevel@tonic-gate if (so->so_accessvp == NULL) 7940Sstevel@tonic-gate return (WALK_NEXT); 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate if (so->so_family != AF_UNIX) { 7970Sstevel@tonic-gate mdb_warn("sonode of family %hi at %p\n", so->so_family, kaddr); 7980Sstevel@tonic-gate return (WALK_ERR); 7990Sstevel@tonic-gate } 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate mdb_printf("%-?p ", kaddr); 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate switch (so->so_serv_type) { 8040Sstevel@tonic-gate case T_CLTS: 8050Sstevel@tonic-gate mdb_printf("%-10s ", "dgram"); 8060Sstevel@tonic-gate break; 8070Sstevel@tonic-gate case T_COTS: 8080Sstevel@tonic-gate mdb_printf("%-10s ", "stream"); 8090Sstevel@tonic-gate break; 8100Sstevel@tonic-gate case T_COTS_ORD: 8110Sstevel@tonic-gate mdb_printf("%-10s ", "stream-ord"); 8120Sstevel@tonic-gate break; 8130Sstevel@tonic-gate default: 8140Sstevel@tonic-gate mdb_printf("%-10i ", so->so_serv_type); 8150Sstevel@tonic-gate } 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate if ((so->so_state & SS_ISBOUND) && 8180Sstevel@tonic-gate (so->so_ux_laddr.soua_magic == SOU_MAGIC_EXPLICIT)) { 8190Sstevel@tonic-gate mdb_printf("%0?p ", so->so_ux_laddr.soua_vp); 8200Sstevel@tonic-gate } else { 8210Sstevel@tonic-gate mdb_printf("%0?p ", NULL); 8220Sstevel@tonic-gate } 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate if ((so->so_state & SS_ISCONNECTED) && 8250Sstevel@tonic-gate (so->so_ux_faddr.soua_magic == SOU_MAGIC_EXPLICIT)) { 8260Sstevel@tonic-gate mdb_printf("%0?p ", so->so_ux_faddr.soua_vp); 8270Sstevel@tonic-gate } else { 8280Sstevel@tonic-gate mdb_printf("%0?p ", NULL); 8290Sstevel@tonic-gate } 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate if (netstat_unix_name_pr(so, &so->so_laddr) == -1) 8320Sstevel@tonic-gate return (WALK_ERR); 8330Sstevel@tonic-gate 8340Sstevel@tonic-gate if (netstat_unix_name_pr(so, &so->so_faddr) == -1) 8350Sstevel@tonic-gate return (WALK_ERR); 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate mdb_printf("%4i\n", so->so_zoneid); 8380Sstevel@tonic-gate 8390Sstevel@tonic-gate return (WALK_NEXT); 8400Sstevel@tonic-gate } 8410Sstevel@tonic-gate 8420Sstevel@tonic-gate static void 8430Sstevel@tonic-gate netstat_tcp_verbose_header_pr(void) 8440Sstevel@tonic-gate { 8450Sstevel@tonic-gate mdb_printf(" %<u>%-5s %-8s %-8s %-5s %-8s %-8s %5s %5s%</u>\n", 8460Sstevel@tonic-gate "Swind", "Snext", "Suna", "Rwind", "Rack", "Rnext", "Rto", "Mss"); 8470Sstevel@tonic-gate } 8480Sstevel@tonic-gate 8491676Sjpk static void 8501676Sjpk get_ifname(const ire_t *ire, char *intf) 8511676Sjpk { 8521676Sjpk ill_t ill; 8531676Sjpk 8541676Sjpk *intf = '\0'; 8551676Sjpk if (ire->ire_type == IRE_CACHE) { 8561676Sjpk queue_t stq; 8571676Sjpk 8581676Sjpk if (mdb_vread(&stq, sizeof (stq), (uintptr_t)ire->ire_stq) == 8591676Sjpk -1) 8601676Sjpk return; 8611676Sjpk if (mdb_vread(&ill, sizeof (ill), (uintptr_t)stq.q_ptr) == -1) 8621676Sjpk return; 8631676Sjpk (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length), 8641676Sjpk (uintptr_t)ill.ill_name); 8651676Sjpk } else if (ire->ire_ipif != NULL) { 8661676Sjpk ipif_t ipif; 8671676Sjpk char *cp; 8681676Sjpk 8691676Sjpk if (mdb_vread(&ipif, sizeof (ipif), 8701676Sjpk (uintptr_t)ire->ire_ipif) == -1) 8711676Sjpk return; 8721676Sjpk if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ipif.ipif_ill) == 8731676Sjpk -1) 8741676Sjpk return; 8751676Sjpk (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length), 8761676Sjpk (uintptr_t)ill.ill_name); 8771676Sjpk if (ipif.ipif_id != 0) { 8781676Sjpk cp = intf + strlen(intf); 8791676Sjpk (void) mdb_snprintf(cp, LIFNAMSIZ + 1 - (cp - intf), 8801676Sjpk ":%u", ipif.ipif_id); 8811676Sjpk } 8821676Sjpk } 8831676Sjpk } 8841676Sjpk 8851676Sjpk static void 8861676Sjpk get_v4flags(const ire_t *ire, char *flags) 8871676Sjpk { 8881676Sjpk (void) strcpy(flags, "U"); 8891676Sjpk if (ire->ire_type == IRE_DEFAULT || ire->ire_type == IRE_PREFIX || 8901676Sjpk ire->ire_type == IRE_HOST || ire->ire_type == IRE_HOST_REDIRECT) 8911676Sjpk (void) strcat(flags, "G"); 8921676Sjpk if (ire->ire_mask == IP_HOST_MASK) 8931676Sjpk (void) strcat(flags, "H"); 8941676Sjpk if (ire->ire_type == IRE_HOST_REDIRECT) 8951676Sjpk (void) strcat(flags, "D"); 8961676Sjpk if (ire->ire_type == IRE_CACHE) 8971676Sjpk (void) strcat(flags, "A"); 8981676Sjpk if (ire->ire_type == IRE_BROADCAST) 8991676Sjpk (void) strcat(flags, "B"); 9001676Sjpk if (ire->ire_type == IRE_LOCAL) 9011676Sjpk (void) strcat(flags, "L"); 9021676Sjpk if (ire->ire_flags & RTF_MULTIRT) 9031676Sjpk (void) strcat(flags, "M"); 9041676Sjpk if (ire->ire_flags & RTF_SETSRC) 9051676Sjpk (void) strcat(flags, "S"); 9061676Sjpk } 9071676Sjpk 9081676Sjpk static int 9091676Sjpk ip_mask_to_plen(ipaddr_t mask) 9101676Sjpk { 9111676Sjpk int i; 9121676Sjpk 9131676Sjpk if (mask == 0) 9141676Sjpk return (0); 9151676Sjpk for (i = 32; i > 0; i--, mask >>= 1) 9161676Sjpk if (mask & 1) 9171676Sjpk break; 9181676Sjpk return (i); 9191676Sjpk } 9201676Sjpk 9211676Sjpk static int 9221676Sjpk netstat_irev4_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 9231676Sjpk { 9241676Sjpk const ire_t *ire = walk_data; 9251676Sjpk uint_t *opts = cb_data; 9261676Sjpk ipaddr_t gate; 9271676Sjpk char flags[10], intf[LIFNAMSIZ + 1]; 9281676Sjpk 9291676Sjpk if (ire->ire_ipversion != IPV4_VERSION || ire->ire_in_src_addr != 0 || 9301676Sjpk ire->ire_in_ill != NULL) 9311676Sjpk return (WALK_NEXT); 9321676Sjpk 9331676Sjpk if (!(*opts & NETSTAT_ALL) && (ire->ire_type == IRE_CACHE || 9341676Sjpk ire->ire_type == IRE_BROADCAST || ire->ire_type == IRE_LOCAL)) 9351676Sjpk return (WALK_NEXT); 9361676Sjpk 9371676Sjpk if (*opts & NETSTAT_FIRST) { 9381676Sjpk *opts &= ~NETSTAT_FIRST; 9391676Sjpk mdb_printf("%<u>%s Table: IPv4%</u>\n", 9401676Sjpk (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing"); 9411676Sjpk if (*opts & NETSTAT_VERBOSE) { 9421676Sjpk mdb_printf("%<u>%-?s %-*s %-*s %-*s Device Mxfrg Rtt " 9431676Sjpk " Ref Flg Out In/Fwd%</u>\n", 9441676Sjpk "Address", ADDR_V4_WIDTH, "Destination", 9451676Sjpk ADDR_V4_WIDTH, "Mask", ADDR_V4_WIDTH, "Gateway"); 9461676Sjpk } else { 9471676Sjpk mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use " 9481676Sjpk "Interface%</u>\n", 9491676Sjpk "Address", ADDR_V4_WIDTH, "Destination", 9501676Sjpk ADDR_V4_WIDTH, "Gateway"); 9511676Sjpk } 9521676Sjpk } 9531676Sjpk 9541676Sjpk gate = (ire->ire_type & (IRE_INTERFACE|IRE_LOOPBACK|IRE_BROADCAST)) ? 9551676Sjpk ire->ire_src_addr : ire->ire_gateway_addr; 9561676Sjpk 9571676Sjpk get_v4flags(ire, flags); 9581676Sjpk 9591676Sjpk get_ifname(ire, intf); 9601676Sjpk 9611676Sjpk if (*opts & NETSTAT_VERBOSE) { 9621676Sjpk mdb_printf("%?p %-*I %-*I %-*I %-6s %5u%c %4u %3u %-3s %5u " 9631676Sjpk "%u\n", kaddr, ADDR_V4_WIDTH, ire->ire_addr, ADDR_V4_WIDTH, 9641676Sjpk ire->ire_mask, ADDR_V4_WIDTH, gate, intf, 9651676Sjpk ire->ire_max_frag, ire->ire_frag_flag ? '*' : ' ', 9661676Sjpk ire->ire_uinfo.iulp_rtt, ire->ire_refcnt, flags, 9671676Sjpk ire->ire_ob_pkt_count, ire->ire_ib_pkt_count); 9681676Sjpk } else { 9691676Sjpk mdb_printf("%?p %-*I %-*I %-5s %4u %5u %s\n", kaddr, 9701676Sjpk ADDR_V4_WIDTH, ire->ire_addr, ADDR_V4_WIDTH, gate, flags, 9711676Sjpk ire->ire_refcnt, 9721676Sjpk ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf); 9731676Sjpk } 9741676Sjpk 9751676Sjpk return (WALK_NEXT); 9761676Sjpk } 9771676Sjpk 9781676Sjpk static int 9791676Sjpk netstat_irev4src_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 9801676Sjpk { 9811676Sjpk const ire_t *ire = walk_data; 9821676Sjpk uint_t *opts = cb_data; 9831676Sjpk ipaddr_t gate; 9841676Sjpk char flags[10], intf[LIFNAMSIZ + 1], srcif[LIFNAMSIZ + 1]; 9851676Sjpk char dest[ADDR_V4_WIDTH + 3 + 1]; 9861676Sjpk ill_t ill; 9871676Sjpk 9881676Sjpk if (ire->ire_ipversion != IPV4_VERSION || 9891676Sjpk (ire->ire_in_src_addr == 0 && ire->ire_in_ill == NULL)) 9901676Sjpk return (WALK_NEXT); 9911676Sjpk 9921676Sjpk if (!(*opts & NETSTAT_ALL) && (ire->ire_type == IRE_CACHE || 9931676Sjpk ire->ire_type == IRE_BROADCAST || ire->ire_type == IRE_LOCAL)) 9941676Sjpk return (WALK_NEXT); 9951676Sjpk 9961676Sjpk if (*opts & NETSTAT_FIRST) { 9971676Sjpk *opts &= ~NETSTAT_FIRST; 9981676Sjpk mdb_printf("\n%<u>%s Table: IPv4 Source-Specific%</u>\n", 9991676Sjpk (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing"); 10001676Sjpk if (*opts & NETSTAT_VERBOSE) { 10011676Sjpk mdb_printf("%<u>%-?s %-*s In If %-*s %-*s " 10021676Sjpk "Out If Mxfrg Rtt Ref Flg Out In/Fwd" 10031676Sjpk "%</u>\n", 10041676Sjpk "Address", ADDR_V4_WIDTH+3, "Destination", 10051676Sjpk ADDR_V4_WIDTH, "Source", ADDR_V4_WIDTH, "Gateway"); 10061676Sjpk } else { 10071676Sjpk mdb_printf("%<u>%-?s %-*s In If %-*s %-*s Flags " 10081676Sjpk "Ref Use Out If%</u>\n", 10091676Sjpk "Address", ADDR_V4_WIDTH+3, "Destination", 10101676Sjpk ADDR_V4_WIDTH, "Source", ADDR_V4_WIDTH, "Gateway"); 10111676Sjpk } 10121676Sjpk } 10131676Sjpk 10141676Sjpk gate = (ire->ire_type & (IRE_INTERFACE|IRE_LOOPBACK|IRE_BROADCAST)) ? 10151676Sjpk ire->ire_src_addr : ire->ire_gateway_addr; 10161676Sjpk 10171676Sjpk get_v4flags(ire, flags); 10181676Sjpk 10191676Sjpk get_ifname(ire, intf); 10201676Sjpk 10211676Sjpk srcif[0] = '\0'; 10221676Sjpk if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ire->ire_in_ill) != -1) 10231676Sjpk (void) mdb_readstr(srcif, MIN(LIFNAMSIZ, ill.ill_name_length), 10241676Sjpk (uintptr_t)ill.ill_name); 10251676Sjpk 10261676Sjpk if (ire->ire_in_src_addr != 0 && ire->ire_addr == 0 && 10271676Sjpk ire->ire_mask == 0) 10281676Sjpk strcpy(dest, " --"); 10291676Sjpk else 10301676Sjpk mdb_snprintf(dest, sizeof (dest), "%I/%d", ire->ire_addr, 10311676Sjpk ip_mask_to_plen(ire->ire_mask)); 10321676Sjpk 10331676Sjpk if (*opts & NETSTAT_VERBOSE) { 10341676Sjpk mdb_printf("%?p %-*s %-11s %-*I %-*I %-11s %5u%c %4u %3u %-3s " 10351676Sjpk "%5u %u\n", kaddr, ADDR_V4_WIDTH+3, dest, srcif, 10361676Sjpk ADDR_V4_WIDTH, ire->ire_in_src_addr, ADDR_V4_WIDTH, gate, 10371676Sjpk intf, ire->ire_max_frag, ire->ire_frag_flag ? '*' : ' ', 10381676Sjpk ire->ire_uinfo.iulp_rtt, ire->ire_refcnt, flags, 10391676Sjpk ire->ire_ob_pkt_count, ire->ire_ib_pkt_count); 10401676Sjpk } else { 10411676Sjpk mdb_printf("%?p %-*s %-8s %-*I %-*I %-5s %4u %5u %s\n", kaddr, 10421676Sjpk ADDR_V4_WIDTH+3, dest, srcif, ADDR_V4_WIDTH, 10431676Sjpk ire->ire_in_src_addr, ADDR_V4_WIDTH, gate, flags, 10441676Sjpk ire->ire_refcnt, 10451676Sjpk ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf); 10461676Sjpk } 10471676Sjpk 10481676Sjpk return (WALK_NEXT); 10491676Sjpk } 10501676Sjpk 10511676Sjpk int 10521676Sjpk ip_mask_to_plen_v6(const in6_addr_t *v6mask) 10531676Sjpk { 10541676Sjpk int plen; 10551676Sjpk int i; 10561676Sjpk uint32_t val; 10571676Sjpk 10581676Sjpk for (i = 3; i >= 0; i--) 10591676Sjpk if (v6mask->s6_addr32[i] != 0) 10601676Sjpk break; 10611676Sjpk if (i < 0) 10621676Sjpk return (0); 10631676Sjpk plen = 32 + 32 * i; 10641676Sjpk val = v6mask->s6_addr32[i]; 10651676Sjpk while (!(val & 1)) { 10661676Sjpk val >>= 1; 10671676Sjpk plen--; 10681676Sjpk } 10691676Sjpk 10701676Sjpk return (plen); 10711676Sjpk } 10721676Sjpk 10731676Sjpk static int 10741676Sjpk netstat_irev6_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 10751676Sjpk { 10761676Sjpk const ire_t *ire = walk_data; 10771676Sjpk uint_t *opts = cb_data; 10781676Sjpk const in6_addr_t *gatep; 10791676Sjpk char deststr[ADDR_V6_WIDTH + 5]; 10801676Sjpk char flags[10], intf[LIFNAMSIZ + 1]; 10811676Sjpk int masklen; 10821676Sjpk 10831676Sjpk if (ire->ire_ipversion != IPV6_VERSION) 10841676Sjpk return (WALK_NEXT); 10851676Sjpk 10861676Sjpk if (!(*opts & NETSTAT_ALL) && ire->ire_type == IRE_CACHE) 10871676Sjpk return (WALK_NEXT); 10881676Sjpk 10891676Sjpk if (*opts & NETSTAT_FIRST) { 10901676Sjpk *opts &= ~NETSTAT_FIRST; 10911676Sjpk mdb_printf("\n%<u>%s Table: IPv6%</u>\n", 10921676Sjpk (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing"); 10931676Sjpk if (*opts & NETSTAT_VERBOSE) { 10941676Sjpk mdb_printf("%<u>%-?s %-*s %-*s If PMTU Rtt Ref " 10951676Sjpk "Flags Out In/Fwd%</u>\n", 10961676Sjpk "Address", ADDR_V6_WIDTH+4, "Destination/Mask", 10971676Sjpk ADDR_V6_WIDTH, "Gateway"); 10981676Sjpk } else { 10991676Sjpk mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use If" 11001676Sjpk "%</u>\n", 11011676Sjpk "Address", ADDR_V6_WIDTH+4, "Destination/Mask", 11021676Sjpk ADDR_V6_WIDTH, "Gateway"); 11031676Sjpk } 11041676Sjpk } 11051676Sjpk 11061676Sjpk gatep = (ire->ire_type & (IRE_INTERFACE|IRE_LOOPBACK)) ? 11071676Sjpk &ire->ire_src_addr_v6 : &ire->ire_gateway_addr_v6; 11081676Sjpk 11091676Sjpk masklen = ip_mask_to_plen_v6(&ire->ire_mask_v6); 11101676Sjpk (void) mdb_snprintf(deststr, sizeof (deststr), "%N/%d", 11111676Sjpk &ire->ire_addr_v6, masklen); 11121676Sjpk 11131676Sjpk (void) strcpy(flags, "U"); 11141676Sjpk if (ire->ire_type == IRE_DEFAULT || ire->ire_type == IRE_PREFIX || 11151676Sjpk ire->ire_type == IRE_HOST || ire->ire_type == IRE_HOST_REDIRECT) 11161676Sjpk (void) strcat(flags, "G"); 11171676Sjpk if (masklen == IPV6_ABITS) 11181676Sjpk (void) strcat(flags, "H"); 11191676Sjpk if (ire->ire_type == IRE_HOST_REDIRECT) 11201676Sjpk (void) strcat(flags, "D"); 11211676Sjpk if (ire->ire_type == IRE_CACHE) 11221676Sjpk (void) strcat(flags, "A"); 11231676Sjpk if (ire->ire_type == IRE_LOCAL) 11241676Sjpk (void) strcat(flags, "L"); 11251676Sjpk if (ire->ire_flags & RTF_MULTIRT) 11261676Sjpk (void) strcat(flags, "M"); 11271676Sjpk if (ire->ire_flags & RTF_SETSRC) 11281676Sjpk (void) strcat(flags, "S"); 11291676Sjpk 11301676Sjpk get_ifname(ire, intf); 11311676Sjpk 11321676Sjpk if (*opts & NETSTAT_VERBOSE) { 11331676Sjpk mdb_printf("%?p %-*s %-*N %-5s %5u%c %5u %3u %-5s %6u %u\n", 11341676Sjpk kaddr, ADDR_V6_WIDTH+4, deststr, ADDR_V6_WIDTH, gatep, 11351676Sjpk intf, ire->ire_max_frag, ire->ire_frag_flag ? '*' : ' ', 11361676Sjpk ire->ire_uinfo.iulp_rtt, ire->ire_refcnt, 11371676Sjpk flags, ire->ire_ob_pkt_count, ire->ire_ib_pkt_count); 11381676Sjpk } else { 11391676Sjpk mdb_printf("%?p %-*s %-*N %-5s %3u %6u %s\n", kaddr, 11401676Sjpk ADDR_V6_WIDTH+4, deststr, ADDR_V6_WIDTH, gatep, flags, 11411676Sjpk ire->ire_refcnt, 11421676Sjpk ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf); 11431676Sjpk } 11441676Sjpk 11451676Sjpk return (WALK_NEXT); 11461676Sjpk } 11471676Sjpk 11480Sstevel@tonic-gate /*ARGSUSED*/ 11490Sstevel@tonic-gate int 11500Sstevel@tonic-gate netstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 11510Sstevel@tonic-gate { 11520Sstevel@tonic-gate uint_t opts = 0; 11530Sstevel@tonic-gate const char *optf = NULL; 11540Sstevel@tonic-gate const char *optP = NULL; 11550Sstevel@tonic-gate 11560Sstevel@tonic-gate if (mdb_getopts(argc, argv, 11570Sstevel@tonic-gate 'a', MDB_OPT_SETBITS, NETSTAT_ALL, &opts, 11580Sstevel@tonic-gate 'f', MDB_OPT_STR, &optf, 11590Sstevel@tonic-gate 'P', MDB_OPT_STR, &optP, 11601676Sjpk 'r', MDB_OPT_SETBITS, NETSTAT_ROUTE, &opts, 11611676Sjpk 'v', MDB_OPT_SETBITS, NETSTAT_VERBOSE, &opts, 11620Sstevel@tonic-gate NULL) != argc) 11630Sstevel@tonic-gate return (DCMD_USAGE); 11640Sstevel@tonic-gate 11650Sstevel@tonic-gate if (optP != NULL) { 11660Sstevel@tonic-gate if ((strcmp("tcp", optP) != 0) && (strcmp("udp", optP) != 0)) 11670Sstevel@tonic-gate return (DCMD_USAGE); 11681676Sjpk if (opts & NETSTAT_ROUTE) 11691676Sjpk return (DCMD_USAGE); 11700Sstevel@tonic-gate } 11710Sstevel@tonic-gate 11721676Sjpk if (optf == NULL) 11731676Sjpk opts |= NETSTAT_V4 | NETSTAT_V6 | NETSTAT_UNIX; 11741676Sjpk else if (strcmp("inet", optf) == 0) 11751676Sjpk opts |= NETSTAT_V4; 11761676Sjpk else if (strcmp("inet6", optf) == 0) 11771676Sjpk opts |= NETSTAT_V6; 11781676Sjpk else if (strcmp("unix", optf) == 0) 11791676Sjpk opts |= NETSTAT_UNIX; 11801676Sjpk else 11811676Sjpk return (DCMD_USAGE); 11821676Sjpk 11831676Sjpk if (opts & NETSTAT_ROUTE) { 11841676Sjpk if (!(opts & (NETSTAT_V4|NETSTAT_V6))) 11850Sstevel@tonic-gate return (DCMD_USAGE); 11861676Sjpk if (opts & NETSTAT_V4) { 11871676Sjpk opts |= NETSTAT_FIRST; 11881676Sjpk if (mdb_walk("ip`ire", netstat_irev4_cb, &opts) == -1) { 11891676Sjpk mdb_warn("failed to walk ip`ire"); 11901676Sjpk return (DCMD_ERR); 11911676Sjpk } 11921676Sjpk opts |= NETSTAT_FIRST; 11931676Sjpk if (mdb_walk("ip`ire", netstat_irev4src_cb, 11941676Sjpk &opts) == -1) { 11951676Sjpk mdb_warn("failed to walk ip`ire"); 11961676Sjpk return (DCMD_ERR); 11971676Sjpk } 11981676Sjpk } 11991676Sjpk if (opts & NETSTAT_V6) { 12001676Sjpk opts |= NETSTAT_FIRST; 12011676Sjpk if (mdb_walk("ip`ire", netstat_irev6_cb, &opts) == -1) { 12021676Sjpk mdb_warn("failed to walk ip`ire"); 12031676Sjpk return (DCMD_ERR); 12041676Sjpk } 12051676Sjpk } 12061676Sjpk return (DCMD_OK); 12070Sstevel@tonic-gate } 12080Sstevel@tonic-gate 12090Sstevel@tonic-gate if ((optP == NULL) || (strcmp("tcp", optP) == 0)) { 12100Sstevel@tonic-gate if ((optf == NULL) || (strcmp("inet", optf) == 0)) { 12110Sstevel@tonic-gate /* Print TCPv4 connection */ 1212*3448Sdh155122 mdb_printf("%<u>%-?s St %*s %*s " 1213*3448Sdh155122 "%s% %s%</u>\n", 12140Sstevel@tonic-gate "TCPv4", ADDR_V4_WIDTH, "Local Address", 1215*3448Sdh155122 ADDR_V4_WIDTH, "Remote Address", "Stack", "Zone"); 12160Sstevel@tonic-gate 12170Sstevel@tonic-gate if (opts & NETSTAT_VERBOSE) 12180Sstevel@tonic-gate netstat_tcp_verbose_header_pr(); 12190Sstevel@tonic-gate 12200Sstevel@tonic-gate if (mdb_walk("ipcl_tcpconn_cache", netstat_tcpv4_cb, 12210Sstevel@tonic-gate (void *)(uintptr_t)opts) == -1) { 12220Sstevel@tonic-gate mdb_warn("failed to walk ipcl_tcpconn_cache"); 12230Sstevel@tonic-gate return (DCMD_ERR); 12240Sstevel@tonic-gate } 12250Sstevel@tonic-gate } 12260Sstevel@tonic-gate 12270Sstevel@tonic-gate if ((optf == NULL) || (strcmp("inet6", optf) == 0)) { 12280Sstevel@tonic-gate /* Print TCPv6 connection */ 1229*3448Sdh155122 mdb_printf("%<u>%-?s St %*s %*s " 1230*3448Sdh155122 "%s %s%\n%</u>", 12310Sstevel@tonic-gate "TCPv6", ADDR_V6_WIDTH, "Local Address", 1232*3448Sdh155122 ADDR_V6_WIDTH, "Remote Address", "Stack", "Zone"); 12330Sstevel@tonic-gate 12340Sstevel@tonic-gate if (opts & NETSTAT_VERBOSE) 12350Sstevel@tonic-gate netstat_tcp_verbose_header_pr(); 12360Sstevel@tonic-gate 12370Sstevel@tonic-gate if (mdb_walk("ipcl_tcpconn_cache", netstat_tcpv6_cb, 12380Sstevel@tonic-gate (void *)(uintptr_t)opts) == -1) { 12390Sstevel@tonic-gate mdb_warn("failed to walk ipcl_tcpconn_cache"); 12400Sstevel@tonic-gate return (DCMD_ERR); 12410Sstevel@tonic-gate } 12420Sstevel@tonic-gate } 12430Sstevel@tonic-gate } 12440Sstevel@tonic-gate 12450Sstevel@tonic-gate if ((optP == NULL) || (strcmp("udp", optP) == 0)) { 12460Sstevel@tonic-gate if ((optf == NULL) || (strcmp("inet", optf) == 0)) { 12470Sstevel@tonic-gate /* Print UDPv4 connection */ 1248*3448Sdh155122 mdb_printf("%<u>%-?s St %*s %*s " 1249*3448Sdh155122 "%s %s%\n%</u>", 12500Sstevel@tonic-gate "UDPv4", ADDR_V4_WIDTH, "Local Address", 1251*3448Sdh155122 ADDR_V4_WIDTH, "Remote Address", "Stack", "Zone"); 12520Sstevel@tonic-gate 1253741Smasputra if (mdb_walk("udp_cache", netstat_udpv4_cb, 12540Sstevel@tonic-gate (void *)(uintptr_t)opts) == -1) { 12550Sstevel@tonic-gate mdb_warn("failed to walk genunix`udp"); 12560Sstevel@tonic-gate return (DCMD_ERR); 12570Sstevel@tonic-gate } 12580Sstevel@tonic-gate 12590Sstevel@tonic-gate } 12600Sstevel@tonic-gate 12610Sstevel@tonic-gate if ((optf == NULL) || (strcmp("inet6", optf) == 0)) { 12620Sstevel@tonic-gate /* Print UDPv6 connection */ 1263*3448Sdh155122 mdb_printf("%<u>%-?s St %*s %*s " 1264*3448Sdh155122 "%s %s%\n%</u>", 12650Sstevel@tonic-gate "UDPv6", ADDR_V6_WIDTH, "Local Address", 1266*3448Sdh155122 ADDR_V6_WIDTH, "Remote Address", "Stack", "Zone"); 12670Sstevel@tonic-gate 1268741Smasputra if (mdb_walk("udp_cache", netstat_udpv6_cb, 12690Sstevel@tonic-gate (void *)(uintptr_t)opts) == -1) { 12700Sstevel@tonic-gate mdb_warn("failed to walk genunix`udp"); 12710Sstevel@tonic-gate return (DCMD_ERR); 12720Sstevel@tonic-gate } 12730Sstevel@tonic-gate } 12740Sstevel@tonic-gate } 12750Sstevel@tonic-gate 12760Sstevel@tonic-gate if (((optf == NULL) || (strcmp("unix", optf) == 0)) && (optP == NULL)) { 12770Sstevel@tonic-gate /* Print Unix Domain Sockets */ 12780Sstevel@tonic-gate mdb_printf("%<u>%-?s %-10s %-?s %-?s %-14s %-14s %s%</u>\n", 12790Sstevel@tonic-gate "AF_UNIX", "Type", "Vnode", "Conn", "Local Addr", 12800Sstevel@tonic-gate "Remote Addr", "Zone"); 12810Sstevel@tonic-gate 12820Sstevel@tonic-gate if (mdb_walk("genunix`sonode", netstat_unix_cb, NULL) == -1) { 12830Sstevel@tonic-gate mdb_warn("failed to walk genunix`sonode"); 12840Sstevel@tonic-gate return (DCMD_ERR); 12850Sstevel@tonic-gate } 12860Sstevel@tonic-gate } 12870Sstevel@tonic-gate 12880Sstevel@tonic-gate return (DCMD_OK); 12890Sstevel@tonic-gate } 1290