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*9089SVasumathi.Sundaram@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 270Sstevel@tonic-gate #include <mdb/mdb_ks.h> 280Sstevel@tonic-gate #include <mdb/mdb_ctf.h> 290Sstevel@tonic-gate #include <sys/types.h> 300Sstevel@tonic-gate #include <sys/tihdr.h> 310Sstevel@tonic-gate #include <inet/led.h> 320Sstevel@tonic-gate #include <inet/common.h> 330Sstevel@tonic-gate #include <netinet/in.h> 340Sstevel@tonic-gate #include <netinet/ip6.h> 350Sstevel@tonic-gate #include <netinet/icmp6.h> 360Sstevel@tonic-gate #include <inet/ip.h> 370Sstevel@tonic-gate #include <inet/ip6.h> 380Sstevel@tonic-gate #include <inet/ipclassifier.h> 390Sstevel@tonic-gate #include <inet/tcp.h> 400Sstevel@tonic-gate #include <sys/stream.h> 410Sstevel@tonic-gate #include <sys/vfs.h> 420Sstevel@tonic-gate #include <sys/stropts.h> 430Sstevel@tonic-gate #include <sys/tpicommon.h> 440Sstevel@tonic-gate #include <sys/socket.h> 450Sstevel@tonic-gate #include <sys/socketvar.h> 460Sstevel@tonic-gate #include <sys/cred_impl.h> 470Sstevel@tonic-gate #include <inet/udp_impl.h> 480Sstevel@tonic-gate #include <inet/arp_impl.h> 490Sstevel@tonic-gate #include <inet/rawip_impl.h> 500Sstevel@tonic-gate #include <inet/mi.h> 518348SEric.Yu@Sun.COM #include <fs/sockfs/socktpi_impl.h> 520Sstevel@tonic-gate 530Sstevel@tonic-gate #define ADDR_V6_WIDTH 23 540Sstevel@tonic-gate #define ADDR_V4_WIDTH 15 550Sstevel@tonic-gate 561676Sjpk #define NETSTAT_ALL 0x01 571676Sjpk #define NETSTAT_VERBOSE 0x02 581676Sjpk #define NETSTAT_ROUTE 0x04 591676Sjpk #define NETSTAT_V4 0x08 601676Sjpk #define NETSTAT_V6 0x10 611676Sjpk #define NETSTAT_UNIX 0x20 621676Sjpk 631676Sjpk #define NETSTAT_FIRST 0x80000000u 640Sstevel@tonic-gate 65*9089SVasumathi.Sundaram@Sun.COM typedef struct netstat_cb_data_s { 66*9089SVasumathi.Sundaram@Sun.COM uint_t opts; 67*9089SVasumathi.Sundaram@Sun.COM conn_t conn; 68*9089SVasumathi.Sundaram@Sun.COM int af; 69*9089SVasumathi.Sundaram@Sun.COM } netstat_cb_data_t; 703448Sdh155122 713448Sdh155122 /* Walkers for various *_stack_t */ 723448Sdh155122 int 733448Sdh155122 ar_stacks_walk_init(mdb_walk_state_t *wsp) 743448Sdh155122 { 753448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 763448Sdh155122 mdb_warn("can't walk 'netstack'"); 773448Sdh155122 return (WALK_ERR); 783448Sdh155122 } 793448Sdh155122 return (WALK_NEXT); 803448Sdh155122 } 813448Sdh155122 823448Sdh155122 int 833448Sdh155122 ar_stacks_walk_step(mdb_walk_state_t *wsp) 843448Sdh155122 { 853448Sdh155122 uintptr_t kaddr; 863448Sdh155122 netstack_t nss; 873448Sdh155122 883448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 893448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 903448Sdh155122 return (WALK_ERR); 913448Sdh155122 } 923448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_ARP]; 933448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 943448Sdh155122 } 953448Sdh155122 963448Sdh155122 int 973448Sdh155122 icmp_stacks_walk_init(mdb_walk_state_t *wsp) 983448Sdh155122 { 993448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 1003448Sdh155122 mdb_warn("can't walk 'netstack'"); 1013448Sdh155122 return (WALK_ERR); 1023448Sdh155122 } 1033448Sdh155122 return (WALK_NEXT); 1043448Sdh155122 } 1053448Sdh155122 1063448Sdh155122 int 1073448Sdh155122 icmp_stacks_walk_step(mdb_walk_state_t *wsp) 1083448Sdh155122 { 1093448Sdh155122 uintptr_t kaddr; 1103448Sdh155122 netstack_t nss; 1113448Sdh155122 1123448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 1133448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 1143448Sdh155122 return (WALK_ERR); 1153448Sdh155122 } 1163448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_ICMP]; 1173448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 1183448Sdh155122 } 1193448Sdh155122 1203448Sdh155122 int 1213448Sdh155122 tcp_stacks_walk_init(mdb_walk_state_t *wsp) 1223448Sdh155122 { 1233448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 1243448Sdh155122 mdb_warn("can't walk 'netstack'"); 1253448Sdh155122 return (WALK_ERR); 1263448Sdh155122 } 1273448Sdh155122 return (WALK_NEXT); 1283448Sdh155122 } 1293448Sdh155122 1303448Sdh155122 int 1313448Sdh155122 tcp_stacks_walk_step(mdb_walk_state_t *wsp) 1323448Sdh155122 { 1333448Sdh155122 uintptr_t kaddr; 1343448Sdh155122 netstack_t nss; 1353448Sdh155122 1363448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 1373448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 1383448Sdh155122 return (WALK_ERR); 1393448Sdh155122 } 1403448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_TCP]; 1413448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 1423448Sdh155122 } 1433448Sdh155122 1443448Sdh155122 int 1453448Sdh155122 udp_stacks_walk_init(mdb_walk_state_t *wsp) 1463448Sdh155122 { 1473448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 1483448Sdh155122 mdb_warn("can't walk 'netstack'"); 1493448Sdh155122 return (WALK_ERR); 1503448Sdh155122 } 1513448Sdh155122 return (WALK_NEXT); 1523448Sdh155122 } 1533448Sdh155122 1543448Sdh155122 int 1553448Sdh155122 udp_stacks_walk_step(mdb_walk_state_t *wsp) 1563448Sdh155122 { 1573448Sdh155122 uintptr_t kaddr; 1583448Sdh155122 netstack_t nss; 1593448Sdh155122 1603448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 1613448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 1623448Sdh155122 return (WALK_ERR); 1633448Sdh155122 } 1643448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_UDP]; 1653448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 1663448Sdh155122 } 1673448Sdh155122 1680Sstevel@tonic-gate /* 1690Sstevel@tonic-gate * Print an IPv4 address and port number in a compact and easy to read format 1700Sstevel@tonic-gate * The arguments are in network byte order 1710Sstevel@tonic-gate */ 1720Sstevel@tonic-gate static void 1730Sstevel@tonic-gate net_ipv4addrport_pr(const in6_addr_t *nipv6addr, in_port_t nport) 1740Sstevel@tonic-gate { 1750Sstevel@tonic-gate uint32_t naddr = V4_PART_OF_V6((*nipv6addr)); 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate mdb_nhconvert(&nport, &nport, sizeof (nport)); 1780Sstevel@tonic-gate mdb_printf("%*I.%-5hu", ADDR_V4_WIDTH, naddr, nport); 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate /* 1820Sstevel@tonic-gate * Print an IPv6 address and port number in a compact and easy to read format 1830Sstevel@tonic-gate * The arguments are in network byte order 1840Sstevel@tonic-gate */ 1850Sstevel@tonic-gate static void 1860Sstevel@tonic-gate net_ipv6addrport_pr(const in6_addr_t *naddr, in_port_t nport) 1870Sstevel@tonic-gate { 1880Sstevel@tonic-gate mdb_nhconvert(&nport, &nport, sizeof (nport)); 1890Sstevel@tonic-gate mdb_printf("%*N.%-5hu", ADDR_V6_WIDTH, naddr, nport); 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate static int 1930Sstevel@tonic-gate net_tcp_active(const tcp_t *tcp) 1940Sstevel@tonic-gate { 1950Sstevel@tonic-gate return (tcp->tcp_state >= TCPS_ESTABLISHED); 1960Sstevel@tonic-gate } 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate static int 1990Sstevel@tonic-gate net_tcp_ipv4(const tcp_t *tcp) 2000Sstevel@tonic-gate { 2010Sstevel@tonic-gate return ((tcp->tcp_ipversion == IPV4_VERSION) || 2020Sstevel@tonic-gate (IN6_IS_ADDR_UNSPECIFIED(&tcp->tcp_ip_src_v6) && 2030Sstevel@tonic-gate (tcp->tcp_state <= TCPS_LISTEN))); 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate static int 2070Sstevel@tonic-gate net_tcp_ipv6(const tcp_t *tcp) 2080Sstevel@tonic-gate { 2090Sstevel@tonic-gate return (tcp->tcp_ipversion == IPV6_VERSION); 2100Sstevel@tonic-gate } 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate static int 2130Sstevel@tonic-gate net_udp_active(const udp_t *udp) 2140Sstevel@tonic-gate { 215741Smasputra return ((udp->udp_state == TS_IDLE) || 216741Smasputra (udp->udp_state == TS_DATA_XFER)); 2170Sstevel@tonic-gate } 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate static int 2200Sstevel@tonic-gate net_udp_ipv4(const udp_t *udp) 2210Sstevel@tonic-gate { 2220Sstevel@tonic-gate return ((udp->udp_ipversion == IPV4_VERSION) || 2230Sstevel@tonic-gate (IN6_IS_ADDR_UNSPECIFIED(&udp->udp_v6src) && 2240Sstevel@tonic-gate (udp->udp_state <= TS_IDLE))); 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate static int 2280Sstevel@tonic-gate net_udp_ipv6(const udp_t *udp) 2290Sstevel@tonic-gate { 2300Sstevel@tonic-gate return (udp->udp_ipversion == IPV6_VERSION); 2310Sstevel@tonic-gate } 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate int 2340Sstevel@tonic-gate sonode_walk_init(mdb_walk_state_t *wsp) 2350Sstevel@tonic-gate { 2360Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 2370Sstevel@tonic-gate GElf_Sym sym; 2380Sstevel@tonic-gate struct socklist *slp; 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate if (mdb_lookup_by_obj("sockfs", "socklist", &sym) == -1) { 2410Sstevel@tonic-gate mdb_warn("failed to lookup sockfs`socklist"); 2420Sstevel@tonic-gate return (WALK_ERR); 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate slp = (struct socklist *)(uintptr_t)sym.st_value; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 2480Sstevel@tonic-gate (uintptr_t)&slp->sl_list) == -1) { 2490Sstevel@tonic-gate mdb_warn("failed to read address of initial sonode " 2500Sstevel@tonic-gate "at %p", &slp->sl_list); 2510Sstevel@tonic-gate return (WALK_ERR); 2520Sstevel@tonic-gate } 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate 2558348SEric.Yu@Sun.COM wsp->walk_data = mdb_alloc(sizeof (struct sotpi_sonode), UM_SLEEP); 2560Sstevel@tonic-gate return (WALK_NEXT); 2570Sstevel@tonic-gate } 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate int 2600Sstevel@tonic-gate sonode_walk_step(mdb_walk_state_t *wsp) 2610Sstevel@tonic-gate { 2620Sstevel@tonic-gate int status; 2638348SEric.Yu@Sun.COM struct sotpi_sonode *stp; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate if (wsp->walk_addr == NULL) 2660Sstevel@tonic-gate return (WALK_DONE); 2670Sstevel@tonic-gate 2688348SEric.Yu@Sun.COM if (mdb_vread(wsp->walk_data, sizeof (struct sotpi_sonode), 2690Sstevel@tonic-gate wsp->walk_addr) == -1) { 2700Sstevel@tonic-gate mdb_warn("failed to read sonode at %p", wsp->walk_addr); 2710Sstevel@tonic-gate return (WALK_ERR); 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 2750Sstevel@tonic-gate wsp->walk_cbdata); 2760Sstevel@tonic-gate 2778348SEric.Yu@Sun.COM stp = wsp->walk_data; 2780Sstevel@tonic-gate 2798348SEric.Yu@Sun.COM wsp->walk_addr = (uintptr_t)stp->st_info.sti_next_so; 2800Sstevel@tonic-gate return (status); 2810Sstevel@tonic-gate } 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate void 2840Sstevel@tonic-gate sonode_walk_fini(mdb_walk_state_t *wsp) 2850Sstevel@tonic-gate { 2868348SEric.Yu@Sun.COM mdb_free(wsp->walk_data, sizeof (struct sotpi_sonode)); 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate struct mi_walk_data { 2900Sstevel@tonic-gate uintptr_t mi_wd_miofirst; 2910Sstevel@tonic-gate MI_O mi_wd_miodata; 2920Sstevel@tonic-gate }; 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate int 2950Sstevel@tonic-gate mi_walk_init(mdb_walk_state_t *wsp) 2960Sstevel@tonic-gate { 2970Sstevel@tonic-gate struct mi_walk_data *wdp; 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 3000Sstevel@tonic-gate mdb_warn("mi doesn't support global walks\n"); 3010Sstevel@tonic-gate return (WALK_ERR); 3020Sstevel@tonic-gate } 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate wdp = mdb_alloc(sizeof (struct mi_walk_data), UM_SLEEP); 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate /* So that we do not immediately return WALK_DONE below */ 3070Sstevel@tonic-gate wdp->mi_wd_miofirst = NULL; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate wsp->walk_data = wdp; 3100Sstevel@tonic-gate return (WALK_NEXT); 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate int 3140Sstevel@tonic-gate mi_walk_step(mdb_walk_state_t *wsp) 3150Sstevel@tonic-gate { 3160Sstevel@tonic-gate struct mi_walk_data *wdp = wsp->walk_data; 3170Sstevel@tonic-gate MI_OP miop = &wdp->mi_wd_miodata; 3180Sstevel@tonic-gate int status; 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate /* Always false in the first iteration */ 3210Sstevel@tonic-gate if ((wsp->walk_addr == (uintptr_t)NULL) || 3220Sstevel@tonic-gate (wsp->walk_addr == wdp->mi_wd_miofirst)) { 3230Sstevel@tonic-gate return (WALK_DONE); 3240Sstevel@tonic-gate } 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate if (mdb_vread(miop, sizeof (MI_O), wsp->walk_addr) == -1) { 3270Sstevel@tonic-gate mdb_warn("failed to read MI object at %p", wsp->walk_addr); 3280Sstevel@tonic-gate return (WALK_ERR); 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate /* Only true in the first iteration */ 3323448Sdh155122 if (wdp->mi_wd_miofirst == NULL) { 3330Sstevel@tonic-gate wdp->mi_wd_miofirst = wsp->walk_addr; 3343448Sdh155122 status = WALK_NEXT; 3353448Sdh155122 } else { 3363448Sdh155122 status = wsp->walk_callback(wsp->walk_addr + sizeof (MI_O), 3373448Sdh155122 &miop[1], wsp->walk_cbdata); 3383448Sdh155122 } 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)miop->mi_o_next; 3410Sstevel@tonic-gate return (status); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate void 3450Sstevel@tonic-gate mi_walk_fini(mdb_walk_state_t *wsp) 3460Sstevel@tonic-gate { 3470Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (struct mi_walk_data)); 3480Sstevel@tonic-gate } 3490Sstevel@tonic-gate 3500Sstevel@tonic-gate typedef struct mi_payload_walk_arg_s { 3513448Sdh155122 const char *mi_pwa_walker; /* Underlying walker */ 3523448Sdh155122 const off_t mi_pwa_head_off; /* Offset for mi_o_head_t * in stack */ 3530Sstevel@tonic-gate const size_t mi_pwa_size; /* size of mi payload */ 3540Sstevel@tonic-gate const uint_t mi_pwa_flags; /* device and/or module */ 3550Sstevel@tonic-gate } mi_payload_walk_arg_t; 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate #define MI_PAYLOAD_DEVICE 0x1 3580Sstevel@tonic-gate #define MI_PAYLOAD_MODULE 0x2 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate int 3610Sstevel@tonic-gate mi_payload_walk_init(mdb_walk_state_t *wsp) 3620Sstevel@tonic-gate { 3630Sstevel@tonic-gate const mi_payload_walk_arg_t *arg = wsp->walk_arg; 3640Sstevel@tonic-gate 3653448Sdh155122 if (mdb_layered_walk(arg->mi_pwa_walker, wsp) == -1) { 3663448Sdh155122 mdb_warn("can't walk '%s'", arg->mi_pwa_walker); 3670Sstevel@tonic-gate return (WALK_ERR); 3680Sstevel@tonic-gate } 3690Sstevel@tonic-gate return (WALK_NEXT); 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate int 3730Sstevel@tonic-gate mi_payload_walk_step(mdb_walk_state_t *wsp) 3740Sstevel@tonic-gate { 3750Sstevel@tonic-gate const mi_payload_walk_arg_t *arg = wsp->walk_arg; 3763448Sdh155122 uintptr_t kaddr; 3770Sstevel@tonic-gate 3783448Sdh155122 kaddr = wsp->walk_addr + arg->mi_pwa_head_off; 3790Sstevel@tonic-gate 3803448Sdh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) { 3813448Sdh155122 mdb_warn("can't read address of mi head at %p for %s", 3823448Sdh155122 kaddr, arg->mi_pwa_walker); 3830Sstevel@tonic-gate return (WALK_ERR); 3840Sstevel@tonic-gate } 3850Sstevel@tonic-gate 3863448Sdh155122 if (kaddr == 0) { 3873448Sdh155122 /* Empty list */ 3883448Sdh155122 return (WALK_DONE); 3893448Sdh155122 } 3900Sstevel@tonic-gate 3913448Sdh155122 if (mdb_pwalk("genunix`mi", wsp->walk_callback, 3923448Sdh155122 wsp->walk_cbdata, kaddr) == -1) { 3933448Sdh155122 mdb_warn("failed to walk genunix`mi"); 3943448Sdh155122 return (WALK_ERR); 3953448Sdh155122 } 3963448Sdh155122 return (WALK_NEXT); 3970Sstevel@tonic-gate } 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate const mi_payload_walk_arg_t mi_ar_arg = { 4003448Sdh155122 "ar_stacks", OFFSETOF(arp_stack_t, as_head), sizeof (ar_t), 4010Sstevel@tonic-gate MI_PAYLOAD_DEVICE | MI_PAYLOAD_MODULE 4020Sstevel@tonic-gate }; 4030Sstevel@tonic-gate 4040Sstevel@tonic-gate const mi_payload_walk_arg_t mi_icmp_arg = { 4053448Sdh155122 "icmp_stacks", OFFSETOF(icmp_stack_t, is_head), sizeof (icmp_t), 4060Sstevel@tonic-gate MI_PAYLOAD_DEVICE | MI_PAYLOAD_MODULE 4070Sstevel@tonic-gate }; 4080Sstevel@tonic-gate 4090Sstevel@tonic-gate int 4100Sstevel@tonic-gate sonode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 4110Sstevel@tonic-gate { 4120Sstevel@tonic-gate const char *optf = NULL; 4130Sstevel@tonic-gate const char *optt = NULL; 4140Sstevel@tonic-gate const char *optp = NULL; 4150Sstevel@tonic-gate int family, type, proto; 4160Sstevel@tonic-gate int filter = 0; 4170Sstevel@tonic-gate struct sonode so; 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 4200Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`sonode", "genunix`sonode", argc, 4210Sstevel@tonic-gate argv) == -1) { 4220Sstevel@tonic-gate mdb_warn("failed to walk sonode"); 4230Sstevel@tonic-gate return (DCMD_ERR); 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate return (DCMD_OK); 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate if (mdb_getopts(argc, argv, 4300Sstevel@tonic-gate 'f', MDB_OPT_STR, &optf, 4310Sstevel@tonic-gate 't', MDB_OPT_STR, &optt, 4320Sstevel@tonic-gate 'p', MDB_OPT_STR, &optp, 4330Sstevel@tonic-gate NULL) != argc) 4340Sstevel@tonic-gate return (DCMD_USAGE); 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate if (optf != NULL) { 4370Sstevel@tonic-gate if (strcmp("inet", optf) == 0) 4380Sstevel@tonic-gate family = AF_INET; 4390Sstevel@tonic-gate else if (strcmp("inet6", optf) == 0) 4400Sstevel@tonic-gate family = AF_INET6; 4410Sstevel@tonic-gate else if (strcmp("unix", optf) == 0) 4420Sstevel@tonic-gate family = AF_UNIX; 4430Sstevel@tonic-gate else 4440Sstevel@tonic-gate family = mdb_strtoull(optf); 4450Sstevel@tonic-gate filter = 1; 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate if (optt != NULL) { 4490Sstevel@tonic-gate if (strcmp("stream", optt) == 0) 4500Sstevel@tonic-gate type = SOCK_STREAM; 4510Sstevel@tonic-gate else if (strcmp("dgram", optt) == 0) 4520Sstevel@tonic-gate type = SOCK_DGRAM; 4530Sstevel@tonic-gate else if (strcmp("raw", optt) == 0) 4540Sstevel@tonic-gate type = SOCK_RAW; 4550Sstevel@tonic-gate else 4560Sstevel@tonic-gate type = mdb_strtoull(optt); 4570Sstevel@tonic-gate filter = 1; 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate if (optp != NULL) { 4610Sstevel@tonic-gate proto = mdb_strtoull(optp); 4620Sstevel@tonic-gate filter = 1; 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !filter) { 4660Sstevel@tonic-gate mdb_printf("%<u>%-?s Family Type Proto State Mode Flag " 4670Sstevel@tonic-gate "AccessVP%</u>\n", "Sonode:"); 4680Sstevel@tonic-gate } 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate if (mdb_vread(&so, sizeof (so), addr) == -1) { 4710Sstevel@tonic-gate mdb_warn("failed to read sonode at %p", addr); 4720Sstevel@tonic-gate return (DCMD_ERR); 4730Sstevel@tonic-gate } 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate if ((optf != NULL) && (so.so_family != family)) 4760Sstevel@tonic-gate return (DCMD_OK); 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate if ((optt != NULL) && (so.so_type != type)) 4790Sstevel@tonic-gate return (DCMD_OK); 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate if ((optp != NULL) && (so.so_protocol != proto)) 4820Sstevel@tonic-gate return (DCMD_OK); 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate if (filter) { 4850Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 4860Sstevel@tonic-gate return (DCMD_OK); 4870Sstevel@tonic-gate } 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate mdb_printf("%0?p ", addr); 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate switch (so.so_family) { 4925563Snordmark case AF_UNIX: 4930Sstevel@tonic-gate mdb_printf("unix "); 4940Sstevel@tonic-gate break; 4955563Snordmark case AF_INET: 4960Sstevel@tonic-gate mdb_printf("inet "); 4970Sstevel@tonic-gate break; 4985563Snordmark case AF_INET6: 4990Sstevel@tonic-gate mdb_printf("inet6 "); 5000Sstevel@tonic-gate break; 5015563Snordmark default: 5020Sstevel@tonic-gate mdb_printf("%6hi", so.so_family); 5030Sstevel@tonic-gate } 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate switch (so.so_type) { 5065563Snordmark case SOCK_STREAM: 5070Sstevel@tonic-gate mdb_printf(" strm"); 5080Sstevel@tonic-gate break; 5095563Snordmark case SOCK_DGRAM: 5100Sstevel@tonic-gate mdb_printf(" dgrm"); 5110Sstevel@tonic-gate break; 5125563Snordmark case SOCK_RAW: 5130Sstevel@tonic-gate mdb_printf(" raw "); 5140Sstevel@tonic-gate break; 5155563Snordmark default: 5160Sstevel@tonic-gate mdb_printf(" %4hi", so.so_type); 5170Sstevel@tonic-gate } 5180Sstevel@tonic-gate 5198348SEric.Yu@Sun.COM mdb_printf(" %5hi %05x %04x %04hx\n", 5200Sstevel@tonic-gate so.so_protocol, so.so_state, so.so_mode, 5218348SEric.Yu@Sun.COM so.so_flag); 5220Sstevel@tonic-gate 5230Sstevel@tonic-gate return (DCMD_OK); 5240Sstevel@tonic-gate } 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate #define MI_PAYLOAD 0x1 5270Sstevel@tonic-gate #define MI_DEVICE 0x2 5280Sstevel@tonic-gate #define MI_MODULE 0x4 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate int 5310Sstevel@tonic-gate mi(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5320Sstevel@tonic-gate { 5330Sstevel@tonic-gate uint_t opts = 0; 5340Sstevel@tonic-gate MI_O mio; 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 5370Sstevel@tonic-gate return (DCMD_USAGE); 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate if (mdb_getopts(argc, argv, 5400Sstevel@tonic-gate 'p', MDB_OPT_SETBITS, MI_PAYLOAD, &opts, 5410Sstevel@tonic-gate 'd', MDB_OPT_SETBITS, MI_DEVICE, &opts, 5420Sstevel@tonic-gate 'm', MDB_OPT_SETBITS, MI_MODULE, &opts, 5430Sstevel@tonic-gate NULL) != argc) 5440Sstevel@tonic-gate return (DCMD_USAGE); 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate if ((opts & (MI_DEVICE | MI_MODULE)) == (MI_DEVICE | MI_MODULE)) { 5470Sstevel@tonic-gate mdb_warn("at most one filter, d for devices or m " 5480Sstevel@tonic-gate "for modules, may be specified\n"); 5490Sstevel@tonic-gate return (DCMD_USAGE); 5500Sstevel@tonic-gate } 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate if ((opts == 0) && (DCMD_HDRSPEC(flags))) { 5530Sstevel@tonic-gate mdb_printf("%<u>%-?s %-?s %-?s IsDev Dev%</u>\n", 5540Sstevel@tonic-gate "MI_O", "Next", "Prev"); 5550Sstevel@tonic-gate } 5560Sstevel@tonic-gate 5570Sstevel@tonic-gate if (mdb_vread(&mio, sizeof (mio), addr) == -1) { 5580Sstevel@tonic-gate mdb_warn("failed to read mi object MI_O at %p", addr); 5590Sstevel@tonic-gate return (DCMD_ERR); 5600Sstevel@tonic-gate } 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate if (opts != 0) { 5630Sstevel@tonic-gate if (mio.mi_o_isdev == B_FALSE) { 5640Sstevel@tonic-gate /* mio is a module */ 5650Sstevel@tonic-gate if (!(opts & MI_MODULE) && (opts & MI_DEVICE)) 5660Sstevel@tonic-gate return (DCMD_OK); 5670Sstevel@tonic-gate } else { 5680Sstevel@tonic-gate /* mio is a device */ 5690Sstevel@tonic-gate if (!(opts & MI_DEVICE) && (opts & MI_MODULE)) 5700Sstevel@tonic-gate return (DCMD_OK); 5710Sstevel@tonic-gate } 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate if (opts & MI_PAYLOAD) 5740Sstevel@tonic-gate mdb_printf("%p\n", addr + sizeof (MI_O)); 5750Sstevel@tonic-gate else 5760Sstevel@tonic-gate mdb_printf("%p\n", addr); 5770Sstevel@tonic-gate return (DCMD_OK); 5780Sstevel@tonic-gate } 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate mdb_printf("%0?p %0?p %0?p ", addr, mio.mi_o_next, mio.mi_o_prev); 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate if (mio.mi_o_isdev == B_FALSE) 5830Sstevel@tonic-gate mdb_printf("FALSE"); 5840Sstevel@tonic-gate else 5850Sstevel@tonic-gate mdb_printf("TRUE "); 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate mdb_printf(" %0?p\n", mio.mi_o_dev); 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate return (DCMD_OK); 5900Sstevel@tonic-gate } 5910Sstevel@tonic-gate 5923448Sdh155122 static int 5933448Sdh155122 ns_to_stackid(uintptr_t kaddr) 5943448Sdh155122 { 5953448Sdh155122 netstack_t nss; 5963448Sdh155122 5973448Sdh155122 if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) { 5983448Sdh155122 mdb_warn("failed to read netstack_t %p", kaddr); 5993448Sdh155122 return (0); 6003448Sdh155122 } 6013448Sdh155122 return (nss.netstack_stackid); 6023448Sdh155122 } 6033448Sdh155122 6043448Sdh155122 6053448Sdh155122 6060Sstevel@tonic-gate static void 6070Sstevel@tonic-gate netstat_tcp_verbose_pr(const tcp_t *tcp) 6080Sstevel@tonic-gate { 6090Sstevel@tonic-gate mdb_printf(" %5i %08x %08x %5i %08x %08x %5li %5i\n", 6100Sstevel@tonic-gate tcp->tcp_swnd, tcp->tcp_snxt, tcp->tcp_suna, tcp->tcp_rwnd, 6110Sstevel@tonic-gate tcp->tcp_rack, tcp->tcp_rnxt, tcp->tcp_rto, tcp->tcp_mss); 6120Sstevel@tonic-gate } 6130Sstevel@tonic-gate 6140Sstevel@tonic-gate /*ARGSUSED*/ 6150Sstevel@tonic-gate static int 616*9089SVasumathi.Sundaram@Sun.COM netstat_tcp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 6170Sstevel@tonic-gate { 618*9089SVasumathi.Sundaram@Sun.COM netstat_cb_data_t *ncb = cb_data; 619*9089SVasumathi.Sundaram@Sun.COM uint_t opts = ncb->opts; 620*9089SVasumathi.Sundaram@Sun.COM int af = ncb->af; 6210Sstevel@tonic-gate uintptr_t tcp_kaddr; 622*9089SVasumathi.Sundaram@Sun.COM conn_t *connp = &ncb->conn; 6235563Snordmark tcp_t tcps, *tcp; 6240Sstevel@tonic-gate 625*9089SVasumathi.Sundaram@Sun.COM if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) { 6265563Snordmark mdb_warn("failed to read conn_t at %p", kaddr); 6275563Snordmark return (WALK_ERR); 6280Sstevel@tonic-gate } 6290Sstevel@tonic-gate 6305563Snordmark tcp_kaddr = (uintptr_t)connp->conn_tcp; 6315563Snordmark if (mdb_vread(&tcps, sizeof (tcp_t), tcp_kaddr) == -1) { 6325563Snordmark mdb_warn("failed to read tcp_t at %p", kaddr); 6330Sstevel@tonic-gate return (WALK_ERR); 6340Sstevel@tonic-gate } 6350Sstevel@tonic-gate 6365563Snordmark tcp = &tcps; 6370Sstevel@tonic-gate connp->conn_tcp = tcp; 6380Sstevel@tonic-gate tcp->tcp_connp = connp; 6390Sstevel@tonic-gate 640741Smasputra if (!((opts & NETSTAT_ALL) || net_tcp_active(tcp)) || 6410Sstevel@tonic-gate (af == AF_INET && !net_tcp_ipv4(tcp)) || 6420Sstevel@tonic-gate (af == AF_INET6 && !net_tcp_ipv6(tcp))) { 6430Sstevel@tonic-gate return (WALK_NEXT); 6440Sstevel@tonic-gate } 6450Sstevel@tonic-gate 6460Sstevel@tonic-gate mdb_printf("%0?p %2i ", tcp_kaddr, tcp->tcp_state); 6470Sstevel@tonic-gate if (af == AF_INET) { 6480Sstevel@tonic-gate net_ipv4addrport_pr(&tcp->tcp_ip_src_v6, tcp->tcp_lport); 6490Sstevel@tonic-gate mdb_printf(" "); 6500Sstevel@tonic-gate net_ipv4addrport_pr(&tcp->tcp_remote_v6, tcp->tcp_fport); 6510Sstevel@tonic-gate } else if (af == AF_INET6) { 6520Sstevel@tonic-gate net_ipv6addrport_pr(&tcp->tcp_ip_src_v6, tcp->tcp_lport); 6530Sstevel@tonic-gate mdb_printf(" "); 6540Sstevel@tonic-gate net_ipv6addrport_pr(&tcp->tcp_remote_v6, tcp->tcp_fport); 6550Sstevel@tonic-gate } 656*9089SVasumathi.Sundaram@Sun.COM mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack)); 6570Sstevel@tonic-gate mdb_printf(" %4i\n", connp->conn_zoneid); 6580Sstevel@tonic-gate if (opts & NETSTAT_VERBOSE) 6590Sstevel@tonic-gate netstat_tcp_verbose_pr(tcp); 6600Sstevel@tonic-gate 6610Sstevel@tonic-gate return (WALK_NEXT); 6620Sstevel@tonic-gate } 6630Sstevel@tonic-gate 664741Smasputra /*ARGSUSED*/ 6650Sstevel@tonic-gate static int 666*9089SVasumathi.Sundaram@Sun.COM netstat_udp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 6670Sstevel@tonic-gate { 668*9089SVasumathi.Sundaram@Sun.COM netstat_cb_data_t *ncb = cb_data; 669*9089SVasumathi.Sundaram@Sun.COM uint_t opts = ncb->opts; 670*9089SVasumathi.Sundaram@Sun.COM int af = ncb->af; 671741Smasputra udp_t udp; 672*9089SVasumathi.Sundaram@Sun.COM conn_t *connp = &ncb->conn; 673*9089SVasumathi.Sundaram@Sun.COM char *state; 674741Smasputra 675*9089SVasumathi.Sundaram@Sun.COM if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) { 6765563Snordmark mdb_warn("failed to read conn_t at %p", kaddr); 677741Smasputra return (WALK_ERR); 678741Smasputra } 6790Sstevel@tonic-gate 6805563Snordmark if (mdb_vread(&udp, sizeof (udp_t), 681*9089SVasumathi.Sundaram@Sun.COM (uintptr_t)connp->conn_udp) == -1) { 6825563Snordmark mdb_warn("failed to read conn_udp at %p", 683*9089SVasumathi.Sundaram@Sun.COM (uintptr_t)connp->conn_udp); 684741Smasputra return (WALK_ERR); 685741Smasputra } 6860Sstevel@tonic-gate 687741Smasputra if (!((opts & NETSTAT_ALL) || net_udp_active(&udp)) || 688741Smasputra (af == AF_INET && !net_udp_ipv4(&udp)) || 689741Smasputra (af == AF_INET6 && !net_udp_ipv6(&udp))) { 690741Smasputra return (WALK_NEXT); 691741Smasputra } 692741Smasputra 693*9089SVasumathi.Sundaram@Sun.COM if (udp.udp_state == TS_UNBND) 694*9089SVasumathi.Sundaram@Sun.COM state = "UNBOUND"; 695*9089SVasumathi.Sundaram@Sun.COM else if (udp.udp_state == TS_IDLE) 696*9089SVasumathi.Sundaram@Sun.COM state = "IDLE"; 697*9089SVasumathi.Sundaram@Sun.COM else if (udp.udp_state == TS_DATA_XFER) 698*9089SVasumathi.Sundaram@Sun.COM state = "CONNECTED"; 699*9089SVasumathi.Sundaram@Sun.COM else 700*9089SVasumathi.Sundaram@Sun.COM state = "UNKNOWN"; 701*9089SVasumathi.Sundaram@Sun.COM 702*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%0?p %10s ", (uintptr_t)connp->conn_udp, state); 703741Smasputra if (af == AF_INET) { 704741Smasputra net_ipv4addrport_pr(&udp.udp_v6src, udp.udp_port); 705741Smasputra mdb_printf(" "); 706741Smasputra net_ipv4addrport_pr(&udp.udp_v6dst, udp.udp_dstport); 707741Smasputra } else if (af == AF_INET6) { 708741Smasputra net_ipv6addrport_pr(&udp.udp_v6src, udp.udp_port); 709741Smasputra mdb_printf(" "); 710741Smasputra net_ipv6addrport_pr(&udp.udp_v6dst, udp.udp_dstport); 711741Smasputra } 712*9089SVasumathi.Sundaram@Sun.COM mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack)); 713*9089SVasumathi.Sundaram@Sun.COM mdb_printf(" %4i\n", connp->conn_zoneid); 7140Sstevel@tonic-gate 7150Sstevel@tonic-gate return (WALK_NEXT); 7160Sstevel@tonic-gate } 7170Sstevel@tonic-gate 718*9089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/ 7190Sstevel@tonic-gate static int 720*9089SVasumathi.Sundaram@Sun.COM netstat_icmp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 721741Smasputra { 722*9089SVasumathi.Sundaram@Sun.COM netstat_cb_data_t *ncb = cb_data; 723*9089SVasumathi.Sundaram@Sun.COM int af = ncb->af; 724*9089SVasumathi.Sundaram@Sun.COM icmp_t icmp; 725*9089SVasumathi.Sundaram@Sun.COM conn_t *connp = &ncb->conn; 726*9089SVasumathi.Sundaram@Sun.COM char *state; 727*9089SVasumathi.Sundaram@Sun.COM 728*9089SVasumathi.Sundaram@Sun.COM if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) { 729*9089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", kaddr); 730*9089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 731*9089SVasumathi.Sundaram@Sun.COM } 732*9089SVasumathi.Sundaram@Sun.COM 733*9089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&icmp, sizeof (icmp_t), 734*9089SVasumathi.Sundaram@Sun.COM (uintptr_t)connp->conn_icmp) == -1) { 735*9089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_icmp at %p", 736*9089SVasumathi.Sundaram@Sun.COM (uintptr_t)connp->conn_icmp); 737*9089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 738*9089SVasumathi.Sundaram@Sun.COM } 739*9089SVasumathi.Sundaram@Sun.COM 740*9089SVasumathi.Sundaram@Sun.COM if ((af == AF_INET && icmp.icmp_ipversion != IPV4_VERSION) || 741*9089SVasumathi.Sundaram@Sun.COM (af == AF_INET6 && icmp.icmp_ipversion != IPV6_VERSION)) { 742*9089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 743*9089SVasumathi.Sundaram@Sun.COM } 744741Smasputra 745*9089SVasumathi.Sundaram@Sun.COM if (icmp.icmp_state == TS_UNBND) 746*9089SVasumathi.Sundaram@Sun.COM state = "UNBOUND"; 747*9089SVasumathi.Sundaram@Sun.COM else if (icmp.icmp_state == TS_IDLE) 748*9089SVasumathi.Sundaram@Sun.COM state = "IDLE"; 749*9089SVasumathi.Sundaram@Sun.COM else if (icmp.icmp_state == TS_DATA_XFER) 750*9089SVasumathi.Sundaram@Sun.COM state = "CONNECTED"; 751*9089SVasumathi.Sundaram@Sun.COM else 752*9089SVasumathi.Sundaram@Sun.COM state = "UNKNOWN"; 753*9089SVasumathi.Sundaram@Sun.COM 754*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%0?p %10s ", (uintptr_t)connp->conn_icmp, state); 755*9089SVasumathi.Sundaram@Sun.COM if (af == AF_INET) { 756*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%*I ", ADDR_V4_WIDTH, 757*9089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((icmp.icmp_v6src))); 758*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%*I ", ADDR_V4_WIDTH, 759*9089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((icmp.icmp_v6dst.sin6_addr))); 760*9089SVasumathi.Sundaram@Sun.COM } else if (af == AF_INET6) { 761*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%*N ", ADDR_V6_WIDTH, &icmp.icmp_v6src); 762*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%*N ", ADDR_V6_WIDTH, &icmp.icmp_v6dst); 763*9089SVasumathi.Sundaram@Sun.COM } 764*9089SVasumathi.Sundaram@Sun.COM mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack)); 765*9089SVasumathi.Sundaram@Sun.COM mdb_printf(" %4i\n", icmp.icmp_zoneid); 766*9089SVasumathi.Sundaram@Sun.COM 767*9089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 7680Sstevel@tonic-gate } 7690Sstevel@tonic-gate 7700Sstevel@tonic-gate /* 7710Sstevel@tonic-gate * print the address of a unix domain socket 7720Sstevel@tonic-gate * 7730Sstevel@tonic-gate * so is the address of a AF_UNIX struct sonode in mdb's address space 7740Sstevel@tonic-gate * soa is the address of the struct soaddr to print 7750Sstevel@tonic-gate * 7760Sstevel@tonic-gate * returns 0 on success, -1 otherwise 7770Sstevel@tonic-gate */ 7780Sstevel@tonic-gate static int 7798348SEric.Yu@Sun.COM netstat_unix_name_pr(const struct sotpi_sonode *st, const struct soaddr *soa) 7800Sstevel@tonic-gate { 7818348SEric.Yu@Sun.COM const struct sonode *so = &st->st_sonode; 7820Sstevel@tonic-gate const char none[] = " (none)"; 7830Sstevel@tonic-gate 7840Sstevel@tonic-gate if ((so->so_state & SS_ISBOUND) && (soa->soa_len != 0)) { 7858348SEric.Yu@Sun.COM if (st->st_info.sti_faddr_noxlate) { 7860Sstevel@tonic-gate mdb_printf("%-14s ", " (socketpair)"); 7870Sstevel@tonic-gate } else { 7880Sstevel@tonic-gate if (soa->soa_len > sizeof (sa_family_t)) { 7890Sstevel@tonic-gate char addr[MAXPATHLEN + 1]; 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate if (mdb_readstr(addr, sizeof (addr), 7920Sstevel@tonic-gate (uintptr_t)&soa->soa_sa->sa_data) == -1) { 7930Sstevel@tonic-gate mdb_warn("failed to read unix address " 7940Sstevel@tonic-gate "at %p", &soa->soa_sa->sa_data); 7950Sstevel@tonic-gate return (-1); 7960Sstevel@tonic-gate } 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate mdb_printf("%-14s ", addr); 7990Sstevel@tonic-gate } else { 8000Sstevel@tonic-gate mdb_printf("%-14s ", none); 8010Sstevel@tonic-gate } 8020Sstevel@tonic-gate } 8030Sstevel@tonic-gate } else { 8040Sstevel@tonic-gate mdb_printf("%-14s ", none); 8050Sstevel@tonic-gate } 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate return (0); 8080Sstevel@tonic-gate } 8090Sstevel@tonic-gate 8100Sstevel@tonic-gate /* based on sockfs_snapshot */ 8110Sstevel@tonic-gate /*ARGSUSED*/ 8120Sstevel@tonic-gate static int 8130Sstevel@tonic-gate netstat_unix_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 8140Sstevel@tonic-gate { 8158348SEric.Yu@Sun.COM const struct sotpi_sonode *st = walk_data; 8168348SEric.Yu@Sun.COM const struct sonode *so = &st->st_sonode; 8178348SEric.Yu@Sun.COM const struct sotpi_info *sti = &st->st_info; 8180Sstevel@tonic-gate 8198348SEric.Yu@Sun.COM if (so->so_count == 0) 8200Sstevel@tonic-gate return (WALK_NEXT); 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate if (so->so_family != AF_UNIX) { 8230Sstevel@tonic-gate mdb_warn("sonode of family %hi at %p\n", so->so_family, kaddr); 8240Sstevel@tonic-gate return (WALK_ERR); 8250Sstevel@tonic-gate } 8260Sstevel@tonic-gate 8270Sstevel@tonic-gate mdb_printf("%-?p ", kaddr); 8280Sstevel@tonic-gate 8298348SEric.Yu@Sun.COM switch (sti->sti_serv_type) { 8305563Snordmark case T_CLTS: 8310Sstevel@tonic-gate mdb_printf("%-10s ", "dgram"); 8320Sstevel@tonic-gate break; 8335563Snordmark case T_COTS: 8340Sstevel@tonic-gate mdb_printf("%-10s ", "stream"); 8350Sstevel@tonic-gate break; 8365563Snordmark case T_COTS_ORD: 8370Sstevel@tonic-gate mdb_printf("%-10s ", "stream-ord"); 8380Sstevel@tonic-gate break; 8395563Snordmark default: 8408348SEric.Yu@Sun.COM mdb_printf("%-10i ", sti->sti_serv_type); 8410Sstevel@tonic-gate } 8420Sstevel@tonic-gate 8430Sstevel@tonic-gate if ((so->so_state & SS_ISBOUND) && 8448348SEric.Yu@Sun.COM (sti->sti_ux_laddr.soua_magic == SOU_MAGIC_EXPLICIT)) { 8458348SEric.Yu@Sun.COM mdb_printf("%0?p ", sti->sti_ux_laddr.soua_vp); 8460Sstevel@tonic-gate } else { 8470Sstevel@tonic-gate mdb_printf("%0?p ", NULL); 8480Sstevel@tonic-gate } 8490Sstevel@tonic-gate 8500Sstevel@tonic-gate if ((so->so_state & SS_ISCONNECTED) && 8518348SEric.Yu@Sun.COM (sti->sti_ux_faddr.soua_magic == SOU_MAGIC_EXPLICIT)) { 8528348SEric.Yu@Sun.COM mdb_printf("%0?p ", sti->sti_ux_faddr.soua_vp); 8530Sstevel@tonic-gate } else { 8540Sstevel@tonic-gate mdb_printf("%0?p ", NULL); 8550Sstevel@tonic-gate } 8560Sstevel@tonic-gate 8578348SEric.Yu@Sun.COM if (netstat_unix_name_pr(st, &sti->sti_laddr) == -1) 8580Sstevel@tonic-gate return (WALK_ERR); 8590Sstevel@tonic-gate 8608348SEric.Yu@Sun.COM if (netstat_unix_name_pr(st, &sti->sti_faddr) == -1) 8610Sstevel@tonic-gate return (WALK_ERR); 8620Sstevel@tonic-gate 8630Sstevel@tonic-gate mdb_printf("%4i\n", so->so_zoneid); 8640Sstevel@tonic-gate 8650Sstevel@tonic-gate return (WALK_NEXT); 8660Sstevel@tonic-gate } 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate static void 8690Sstevel@tonic-gate netstat_tcp_verbose_header_pr(void) 8700Sstevel@tonic-gate { 8710Sstevel@tonic-gate mdb_printf(" %<u>%-5s %-8s %-8s %-5s %-8s %-8s %5s %5s%</u>\n", 8720Sstevel@tonic-gate "Swind", "Snext", "Suna", "Rwind", "Rack", "Rnext", "Rto", "Mss"); 8730Sstevel@tonic-gate } 8740Sstevel@tonic-gate 8751676Sjpk static void 8761676Sjpk get_ifname(const ire_t *ire, char *intf) 8771676Sjpk { 8781676Sjpk ill_t ill; 8791676Sjpk 8801676Sjpk *intf = '\0'; 8811676Sjpk if (ire->ire_type == IRE_CACHE) { 8821676Sjpk queue_t stq; 8831676Sjpk 8841676Sjpk if (mdb_vread(&stq, sizeof (stq), (uintptr_t)ire->ire_stq) == 8851676Sjpk -1) 8861676Sjpk return; 8871676Sjpk if (mdb_vread(&ill, sizeof (ill), (uintptr_t)stq.q_ptr) == -1) 8881676Sjpk return; 8891676Sjpk (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length), 8901676Sjpk (uintptr_t)ill.ill_name); 8911676Sjpk } else if (ire->ire_ipif != NULL) { 8921676Sjpk ipif_t ipif; 8931676Sjpk char *cp; 8941676Sjpk 8951676Sjpk if (mdb_vread(&ipif, sizeof (ipif), 8961676Sjpk (uintptr_t)ire->ire_ipif) == -1) 8971676Sjpk return; 8981676Sjpk if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ipif.ipif_ill) == 8991676Sjpk -1) 9001676Sjpk return; 9011676Sjpk (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length), 9021676Sjpk (uintptr_t)ill.ill_name); 9031676Sjpk if (ipif.ipif_id != 0) { 9041676Sjpk cp = intf + strlen(intf); 9051676Sjpk (void) mdb_snprintf(cp, LIFNAMSIZ + 1 - (cp - intf), 9061676Sjpk ":%u", ipif.ipif_id); 9071676Sjpk } 9081676Sjpk } 9091676Sjpk } 9101676Sjpk 9111676Sjpk static void 9121676Sjpk get_v4flags(const ire_t *ire, char *flags) 9131676Sjpk { 9141676Sjpk (void) strcpy(flags, "U"); 9151676Sjpk if (ire->ire_type == IRE_DEFAULT || ire->ire_type == IRE_PREFIX || 9161676Sjpk ire->ire_type == IRE_HOST || ire->ire_type == IRE_HOST_REDIRECT) 9171676Sjpk (void) strcat(flags, "G"); 9181676Sjpk if (ire->ire_mask == IP_HOST_MASK) 9191676Sjpk (void) strcat(flags, "H"); 9201676Sjpk if (ire->ire_type == IRE_HOST_REDIRECT) 9211676Sjpk (void) strcat(flags, "D"); 9221676Sjpk if (ire->ire_type == IRE_CACHE) 9231676Sjpk (void) strcat(flags, "A"); 9241676Sjpk if (ire->ire_type == IRE_BROADCAST) 9251676Sjpk (void) strcat(flags, "B"); 9261676Sjpk if (ire->ire_type == IRE_LOCAL) 9271676Sjpk (void) strcat(flags, "L"); 9281676Sjpk if (ire->ire_flags & RTF_MULTIRT) 9291676Sjpk (void) strcat(flags, "M"); 9301676Sjpk if (ire->ire_flags & RTF_SETSRC) 9311676Sjpk (void) strcat(flags, "S"); 9321676Sjpk } 9331676Sjpk 9341676Sjpk static int 9351676Sjpk netstat_irev4_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 9361676Sjpk { 9371676Sjpk const ire_t *ire = walk_data; 9381676Sjpk uint_t *opts = cb_data; 9391676Sjpk ipaddr_t gate; 9401676Sjpk char flags[10], intf[LIFNAMSIZ + 1]; 9411676Sjpk 9424823Sseb if (ire->ire_ipversion != IPV4_VERSION) 9431676Sjpk return (WALK_NEXT); 9441676Sjpk 9451676Sjpk if (!(*opts & NETSTAT_ALL) && (ire->ire_type == IRE_CACHE || 9461676Sjpk ire->ire_type == IRE_BROADCAST || ire->ire_type == IRE_LOCAL)) 9471676Sjpk return (WALK_NEXT); 9481676Sjpk 9491676Sjpk if (*opts & NETSTAT_FIRST) { 9501676Sjpk *opts &= ~NETSTAT_FIRST; 9511676Sjpk mdb_printf("%<u>%s Table: IPv4%</u>\n", 9521676Sjpk (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing"); 9531676Sjpk if (*opts & NETSTAT_VERBOSE) { 9541676Sjpk mdb_printf("%<u>%-?s %-*s %-*s %-*s Device Mxfrg Rtt " 9551676Sjpk " Ref Flg Out In/Fwd%</u>\n", 9561676Sjpk "Address", ADDR_V4_WIDTH, "Destination", 9571676Sjpk ADDR_V4_WIDTH, "Mask", ADDR_V4_WIDTH, "Gateway"); 9581676Sjpk } else { 9591676Sjpk mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use " 9601676Sjpk "Interface%</u>\n", 9611676Sjpk "Address", ADDR_V4_WIDTH, "Destination", 9621676Sjpk ADDR_V4_WIDTH, "Gateway"); 9631676Sjpk } 9641676Sjpk } 9651676Sjpk 9661676Sjpk gate = (ire->ire_type & (IRE_INTERFACE|IRE_LOOPBACK|IRE_BROADCAST)) ? 9671676Sjpk ire->ire_src_addr : ire->ire_gateway_addr; 9681676Sjpk 9691676Sjpk get_v4flags(ire, flags); 9701676Sjpk 9711676Sjpk get_ifname(ire, intf); 9721676Sjpk 9731676Sjpk if (*opts & NETSTAT_VERBOSE) { 9741676Sjpk mdb_printf("%?p %-*I %-*I %-*I %-6s %5u%c %4u %3u %-3s %5u " 9751676Sjpk "%u\n", kaddr, ADDR_V4_WIDTH, ire->ire_addr, ADDR_V4_WIDTH, 9761676Sjpk ire->ire_mask, ADDR_V4_WIDTH, gate, intf, 9771676Sjpk ire->ire_max_frag, ire->ire_frag_flag ? '*' : ' ', 9781676Sjpk ire->ire_uinfo.iulp_rtt, ire->ire_refcnt, flags, 9791676Sjpk ire->ire_ob_pkt_count, ire->ire_ib_pkt_count); 9801676Sjpk } else { 9811676Sjpk mdb_printf("%?p %-*I %-*I %-5s %4u %5u %s\n", kaddr, 9821676Sjpk ADDR_V4_WIDTH, ire->ire_addr, ADDR_V4_WIDTH, gate, flags, 9831676Sjpk ire->ire_refcnt, 9841676Sjpk ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf); 9851676Sjpk } 9861676Sjpk 9871676Sjpk return (WALK_NEXT); 9881676Sjpk } 9891676Sjpk 9901676Sjpk int 9911676Sjpk ip_mask_to_plen_v6(const in6_addr_t *v6mask) 9921676Sjpk { 9931676Sjpk int plen; 9941676Sjpk int i; 9951676Sjpk uint32_t val; 9961676Sjpk 9971676Sjpk for (i = 3; i >= 0; i--) 9981676Sjpk if (v6mask->s6_addr32[i] != 0) 9991676Sjpk break; 10001676Sjpk if (i < 0) 10011676Sjpk return (0); 10021676Sjpk plen = 32 + 32 * i; 10031676Sjpk val = v6mask->s6_addr32[i]; 10041676Sjpk while (!(val & 1)) { 10051676Sjpk val >>= 1; 10061676Sjpk plen--; 10071676Sjpk } 10081676Sjpk 10091676Sjpk return (plen); 10101676Sjpk } 10111676Sjpk 10121676Sjpk static int 10131676Sjpk netstat_irev6_cb(uintptr_t kaddr, const void *walk_data, void *cb_data) 10141676Sjpk { 10151676Sjpk const ire_t *ire = walk_data; 10161676Sjpk uint_t *opts = cb_data; 10171676Sjpk const in6_addr_t *gatep; 10181676Sjpk char deststr[ADDR_V6_WIDTH + 5]; 10191676Sjpk char flags[10], intf[LIFNAMSIZ + 1]; 10201676Sjpk int masklen; 10211676Sjpk 10221676Sjpk if (ire->ire_ipversion != IPV6_VERSION) 10231676Sjpk return (WALK_NEXT); 10241676Sjpk 10251676Sjpk if (!(*opts & NETSTAT_ALL) && ire->ire_type == IRE_CACHE) 10261676Sjpk return (WALK_NEXT); 10271676Sjpk 10281676Sjpk if (*opts & NETSTAT_FIRST) { 10291676Sjpk *opts &= ~NETSTAT_FIRST; 10301676Sjpk mdb_printf("\n%<u>%s Table: IPv6%</u>\n", 10311676Sjpk (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing"); 10321676Sjpk if (*opts & NETSTAT_VERBOSE) { 10331676Sjpk mdb_printf("%<u>%-?s %-*s %-*s If PMTU Rtt Ref " 10341676Sjpk "Flags Out In/Fwd%</u>\n", 10351676Sjpk "Address", ADDR_V6_WIDTH+4, "Destination/Mask", 10361676Sjpk ADDR_V6_WIDTH, "Gateway"); 10371676Sjpk } else { 10381676Sjpk mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use If" 10391676Sjpk "%</u>\n", 10401676Sjpk "Address", ADDR_V6_WIDTH+4, "Destination/Mask", 10411676Sjpk ADDR_V6_WIDTH, "Gateway"); 10421676Sjpk } 10431676Sjpk } 10441676Sjpk 10451676Sjpk gatep = (ire->ire_type & (IRE_INTERFACE|IRE_LOOPBACK)) ? 10461676Sjpk &ire->ire_src_addr_v6 : &ire->ire_gateway_addr_v6; 10471676Sjpk 10481676Sjpk masklen = ip_mask_to_plen_v6(&ire->ire_mask_v6); 10491676Sjpk (void) mdb_snprintf(deststr, sizeof (deststr), "%N/%d", 10501676Sjpk &ire->ire_addr_v6, masklen); 10511676Sjpk 10521676Sjpk (void) strcpy(flags, "U"); 10531676Sjpk if (ire->ire_type == IRE_DEFAULT || ire->ire_type == IRE_PREFIX || 10541676Sjpk ire->ire_type == IRE_HOST || ire->ire_type == IRE_HOST_REDIRECT) 10551676Sjpk (void) strcat(flags, "G"); 10561676Sjpk if (masklen == IPV6_ABITS) 10571676Sjpk (void) strcat(flags, "H"); 10581676Sjpk if (ire->ire_type == IRE_HOST_REDIRECT) 10591676Sjpk (void) strcat(flags, "D"); 10601676Sjpk if (ire->ire_type == IRE_CACHE) 10611676Sjpk (void) strcat(flags, "A"); 10621676Sjpk if (ire->ire_type == IRE_LOCAL) 10631676Sjpk (void) strcat(flags, "L"); 10641676Sjpk if (ire->ire_flags & RTF_MULTIRT) 10651676Sjpk (void) strcat(flags, "M"); 10661676Sjpk if (ire->ire_flags & RTF_SETSRC) 10671676Sjpk (void) strcat(flags, "S"); 10681676Sjpk 10691676Sjpk get_ifname(ire, intf); 10701676Sjpk 10711676Sjpk if (*opts & NETSTAT_VERBOSE) { 10721676Sjpk mdb_printf("%?p %-*s %-*N %-5s %5u%c %5u %3u %-5s %6u %u\n", 10731676Sjpk kaddr, ADDR_V6_WIDTH+4, deststr, ADDR_V6_WIDTH, gatep, 10741676Sjpk intf, ire->ire_max_frag, ire->ire_frag_flag ? '*' : ' ', 10751676Sjpk ire->ire_uinfo.iulp_rtt, ire->ire_refcnt, 10761676Sjpk flags, ire->ire_ob_pkt_count, ire->ire_ib_pkt_count); 10771676Sjpk } else { 10781676Sjpk mdb_printf("%?p %-*s %-*N %-5s %3u %6u %s\n", kaddr, 10791676Sjpk ADDR_V6_WIDTH+4, deststr, ADDR_V6_WIDTH, gatep, flags, 10801676Sjpk ire->ire_refcnt, 10811676Sjpk ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf); 10821676Sjpk } 10831676Sjpk 10841676Sjpk return (WALK_NEXT); 10851676Sjpk } 10861676Sjpk 1087*9089SVasumathi.Sundaram@Sun.COM static void 1088*9089SVasumathi.Sundaram@Sun.COM netstat_header_v4(int proto) 1089*9089SVasumathi.Sundaram@Sun.COM { 1090*9089SVasumathi.Sundaram@Sun.COM if (proto == IPPROTO_TCP) 1091*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s ", "TCPv4"); 1092*9089SVasumathi.Sundaram@Sun.COM else if (proto == IPPROTO_UDP) 1093*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s ", "UDPv4"); 1094*9089SVasumathi.Sundaram@Sun.COM else if (proto == IPPROTO_ICMP) 1095*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s ", "ICMPv4"); 1096*9089SVasumathi.Sundaram@Sun.COM mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n", 1097*9089SVasumathi.Sundaram@Sun.COM "", ADDR_V4_WIDTH, "Local Address", 1098*9089SVasumathi.Sundaram@Sun.COM "", ADDR_V4_WIDTH, "Remote Address", "Stack", "Zone"); 1099*9089SVasumathi.Sundaram@Sun.COM } 1100*9089SVasumathi.Sundaram@Sun.COM 1101*9089SVasumathi.Sundaram@Sun.COM static void 1102*9089SVasumathi.Sundaram@Sun.COM netstat_header_v6(int proto) 1103*9089SVasumathi.Sundaram@Sun.COM { 1104*9089SVasumathi.Sundaram@Sun.COM if (proto == IPPROTO_TCP) 1105*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s ", "TCPv6"); 1106*9089SVasumathi.Sundaram@Sun.COM else if (proto == IPPROTO_UDP) 1107*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s ", "UDPv6"); 1108*9089SVasumathi.Sundaram@Sun.COM else if (proto == IPPROTO_ICMP) 1109*9089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s ", "ICMPv6"); 1110*9089SVasumathi.Sundaram@Sun.COM mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n", 1111*9089SVasumathi.Sundaram@Sun.COM "", ADDR_V6_WIDTH, "Local Address", 1112*9089SVasumathi.Sundaram@Sun.COM "", ADDR_V6_WIDTH, "Remote Address", "Stack", "Zone"); 1113*9089SVasumathi.Sundaram@Sun.COM } 1114*9089SVasumathi.Sundaram@Sun.COM 1115*9089SVasumathi.Sundaram@Sun.COM static int 1116*9089SVasumathi.Sundaram@Sun.COM netstat_print_conn(const char *cache, int proto, mdb_walk_cb_t cbfunc, 1117*9089SVasumathi.Sundaram@Sun.COM void *cbdata) 1118*9089SVasumathi.Sundaram@Sun.COM { 1119*9089SVasumathi.Sundaram@Sun.COM netstat_cb_data_t *ncb = cbdata; 1120*9089SVasumathi.Sundaram@Sun.COM 1121*9089SVasumathi.Sundaram@Sun.COM if ((ncb->opts & NETSTAT_VERBOSE) && proto == IPPROTO_TCP) 1122*9089SVasumathi.Sundaram@Sun.COM netstat_tcp_verbose_header_pr(); 1123*9089SVasumathi.Sundaram@Sun.COM if (mdb_walk(cache, cbfunc, cbdata) == -1) { 1124*9089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk %s", cache); 1125*9089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 1126*9089SVasumathi.Sundaram@Sun.COM } 1127*9089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 1128*9089SVasumathi.Sundaram@Sun.COM } 1129*9089SVasumathi.Sundaram@Sun.COM 1130*9089SVasumathi.Sundaram@Sun.COM static int 1131*9089SVasumathi.Sundaram@Sun.COM netstat_print_common(const char *cache, int proto, mdb_walk_cb_t cbfunc, 1132*9089SVasumathi.Sundaram@Sun.COM void *cbdata) 1133*9089SVasumathi.Sundaram@Sun.COM { 1134*9089SVasumathi.Sundaram@Sun.COM netstat_cb_data_t *ncb = cbdata; 1135*9089SVasumathi.Sundaram@Sun.COM int af = ncb->af; 1136*9089SVasumathi.Sundaram@Sun.COM int status = DCMD_OK; 1137*9089SVasumathi.Sundaram@Sun.COM 1138*9089SVasumathi.Sundaram@Sun.COM if (af != AF_INET6) { 1139*9089SVasumathi.Sundaram@Sun.COM ncb->af = AF_INET; 1140*9089SVasumathi.Sundaram@Sun.COM netstat_header_v4(proto); 1141*9089SVasumathi.Sundaram@Sun.COM status = netstat_print_conn(cache, proto, cbfunc, cbdata); 1142*9089SVasumathi.Sundaram@Sun.COM } 1143*9089SVasumathi.Sundaram@Sun.COM if (status == DCMD_OK && af != AF_INET) { 1144*9089SVasumathi.Sundaram@Sun.COM ncb->af = AF_INET6; 1145*9089SVasumathi.Sundaram@Sun.COM netstat_header_v6(proto); 1146*9089SVasumathi.Sundaram@Sun.COM status = netstat_print_conn(cache, proto, cbfunc, cbdata); 1147*9089SVasumathi.Sundaram@Sun.COM } 1148*9089SVasumathi.Sundaram@Sun.COM ncb->af = af; 1149*9089SVasumathi.Sundaram@Sun.COM return (status); 1150*9089SVasumathi.Sundaram@Sun.COM } 1151*9089SVasumathi.Sundaram@Sun.COM 11520Sstevel@tonic-gate /*ARGSUSED*/ 11530Sstevel@tonic-gate int 11540Sstevel@tonic-gate netstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 11550Sstevel@tonic-gate { 11560Sstevel@tonic-gate uint_t opts = 0; 11570Sstevel@tonic-gate const char *optf = NULL; 11580Sstevel@tonic-gate const char *optP = NULL; 1159*9089SVasumathi.Sundaram@Sun.COM netstat_cb_data_t *cbdata; 1160*9089SVasumathi.Sundaram@Sun.COM int status; 1161*9089SVasumathi.Sundaram@Sun.COM int af = 0; 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate if (mdb_getopts(argc, argv, 11640Sstevel@tonic-gate 'a', MDB_OPT_SETBITS, NETSTAT_ALL, &opts, 11650Sstevel@tonic-gate 'f', MDB_OPT_STR, &optf, 11660Sstevel@tonic-gate 'P', MDB_OPT_STR, &optP, 11671676Sjpk 'r', MDB_OPT_SETBITS, NETSTAT_ROUTE, &opts, 11681676Sjpk 'v', MDB_OPT_SETBITS, NETSTAT_VERBOSE, &opts, 11690Sstevel@tonic-gate NULL) != argc) 11700Sstevel@tonic-gate return (DCMD_USAGE); 11710Sstevel@tonic-gate 11720Sstevel@tonic-gate if (optP != NULL) { 1173*9089SVasumathi.Sundaram@Sun.COM if ((strcmp("tcp", optP) != 0) && (strcmp("udp", optP) != 0) && 1174*9089SVasumathi.Sundaram@Sun.COM (strcmp("icmp", optP) != 0)) 11750Sstevel@tonic-gate return (DCMD_USAGE); 11761676Sjpk if (opts & NETSTAT_ROUTE) 11771676Sjpk return (DCMD_USAGE); 11780Sstevel@tonic-gate } 11790Sstevel@tonic-gate 11801676Sjpk if (optf == NULL) 11811676Sjpk opts |= NETSTAT_V4 | NETSTAT_V6 | NETSTAT_UNIX; 11821676Sjpk else if (strcmp("inet", optf) == 0) 11831676Sjpk opts |= NETSTAT_V4; 11841676Sjpk else if (strcmp("inet6", optf) == 0) 11851676Sjpk opts |= NETSTAT_V6; 11861676Sjpk else if (strcmp("unix", optf) == 0) 11871676Sjpk opts |= NETSTAT_UNIX; 11881676Sjpk else 11891676Sjpk return (DCMD_USAGE); 11901676Sjpk 11911676Sjpk if (opts & NETSTAT_ROUTE) { 11921676Sjpk if (!(opts & (NETSTAT_V4|NETSTAT_V6))) 11930Sstevel@tonic-gate return (DCMD_USAGE); 11941676Sjpk if (opts & NETSTAT_V4) { 11951676Sjpk opts |= NETSTAT_FIRST; 11961676Sjpk if (mdb_walk("ip`ire", netstat_irev4_cb, &opts) == -1) { 11971676Sjpk mdb_warn("failed to walk ip`ire"); 11981676Sjpk return (DCMD_ERR); 11991676Sjpk } 12001676Sjpk } 12011676Sjpk if (opts & NETSTAT_V6) { 12021676Sjpk opts |= NETSTAT_FIRST; 12031676Sjpk if (mdb_walk("ip`ire", netstat_irev6_cb, &opts) == -1) { 12041676Sjpk mdb_warn("failed to walk ip`ire"); 12051676Sjpk return (DCMD_ERR); 12061676Sjpk } 12071676Sjpk } 12081676Sjpk return (DCMD_OK); 12090Sstevel@tonic-gate } 12100Sstevel@tonic-gate 1211*9089SVasumathi.Sundaram@Sun.COM if ((opts & NETSTAT_UNIX) && (optP == NULL)) { 12120Sstevel@tonic-gate /* Print Unix Domain Sockets */ 12130Sstevel@tonic-gate mdb_printf("%<u>%-?s %-10s %-?s %-?s %-14s %-14s %s%</u>\n", 12140Sstevel@tonic-gate "AF_UNIX", "Type", "Vnode", "Conn", "Local Addr", 12150Sstevel@tonic-gate "Remote Addr", "Zone"); 12160Sstevel@tonic-gate 12170Sstevel@tonic-gate if (mdb_walk("genunix`sonode", netstat_unix_cb, NULL) == -1) { 12180Sstevel@tonic-gate mdb_warn("failed to walk genunix`sonode"); 12190Sstevel@tonic-gate return (DCMD_ERR); 12200Sstevel@tonic-gate } 1221*9089SVasumathi.Sundaram@Sun.COM if (!(opts & (NETSTAT_V4 | NETSTAT_V6))) 1222*9089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 12230Sstevel@tonic-gate } 12240Sstevel@tonic-gate 1225*9089SVasumathi.Sundaram@Sun.COM cbdata = mdb_alloc(sizeof (netstat_cb_data_t), UM_SLEEP); 1226*9089SVasumathi.Sundaram@Sun.COM cbdata->opts = opts; 1227*9089SVasumathi.Sundaram@Sun.COM if ((optf != NULL) && (opts & NETSTAT_V4)) 1228*9089SVasumathi.Sundaram@Sun.COM af = AF_INET; 1229*9089SVasumathi.Sundaram@Sun.COM else if ((optf != NULL) && (opts & NETSTAT_V6)) 1230*9089SVasumathi.Sundaram@Sun.COM af = AF_INET6; 1231*9089SVasumathi.Sundaram@Sun.COM 1232*9089SVasumathi.Sundaram@Sun.COM cbdata->af = af; 1233*9089SVasumathi.Sundaram@Sun.COM if ((optP == NULL) || (strcmp("tcp", optP) == 0)) { 1234*9089SVasumathi.Sundaram@Sun.COM status = netstat_print_common("tcp_conn_cache", IPPROTO_TCP, 1235*9089SVasumathi.Sundaram@Sun.COM netstat_tcp_cb, cbdata); 1236*9089SVasumathi.Sundaram@Sun.COM if (status != DCMD_OK) 1237*9089SVasumathi.Sundaram@Sun.COM goto out; 1238*9089SVasumathi.Sundaram@Sun.COM } 1239*9089SVasumathi.Sundaram@Sun.COM 1240*9089SVasumathi.Sundaram@Sun.COM if ((optP == NULL) || (strcmp("udp", optP) == 0)) { 1241*9089SVasumathi.Sundaram@Sun.COM status = netstat_print_common("udp_conn_cache", IPPROTO_UDP, 1242*9089SVasumathi.Sundaram@Sun.COM netstat_udp_cb, cbdata); 1243*9089SVasumathi.Sundaram@Sun.COM if (status != DCMD_OK) 1244*9089SVasumathi.Sundaram@Sun.COM goto out; 1245*9089SVasumathi.Sundaram@Sun.COM } 1246*9089SVasumathi.Sundaram@Sun.COM 1247*9089SVasumathi.Sundaram@Sun.COM if ((optP == NULL) || (strcmp("icmp", optP) == 0)) { 1248*9089SVasumathi.Sundaram@Sun.COM status = netstat_print_common("rawip_conn_cache", IPPROTO_ICMP, 1249*9089SVasumathi.Sundaram@Sun.COM netstat_icmp_cb, cbdata); 1250*9089SVasumathi.Sundaram@Sun.COM if (status != DCMD_OK) 1251*9089SVasumathi.Sundaram@Sun.COM goto out; 1252*9089SVasumathi.Sundaram@Sun.COM } 1253*9089SVasumathi.Sundaram@Sun.COM out: 1254*9089SVasumathi.Sundaram@Sun.COM mdb_free(cbdata, sizeof (netstat_cb_data_t)); 1255*9089SVasumathi.Sundaram@Sun.COM return (status); 12560Sstevel@tonic-gate } 1257