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 52546Scarlsonj * Common Development and Distribution License (the "License"). 62546Scarlsonj * 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*11754SKacheong.Poon@Sun.COM * Copyright 2010 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 <sys/types.h> 270Sstevel@tonic-gate #include <sys/stropts.h> 280Sstevel@tonic-gate #include <sys/stream.h> 290Sstevel@tonic-gate #include <sys/socket.h> 300Sstevel@tonic-gate #include <sys/avl_impl.h> 319089SVasumathi.Sundaram@Sun.COM #include <net/if_types.h> 320Sstevel@tonic-gate #include <net/if.h> 330Sstevel@tonic-gate #include <net/route.h> 340Sstevel@tonic-gate #include <netinet/in.h> 350Sstevel@tonic-gate #include <netinet/ip6.h> 360Sstevel@tonic-gate #include <netinet/udp.h> 370Sstevel@tonic-gate #include <netinet/sctp.h> 380Sstevel@tonic-gate #include <inet/mib2.h> 390Sstevel@tonic-gate #include <inet/common.h> 400Sstevel@tonic-gate #include <inet/ip.h> 410Sstevel@tonic-gate #include <inet/ip_ire.h> 420Sstevel@tonic-gate #include <inet/ip6.h> 430Sstevel@tonic-gate #include <inet/ipclassifier.h> 440Sstevel@tonic-gate #include <inet/mi.h> 450Sstevel@tonic-gate #include <sys/squeue_impl.h> 465023Scarlsonj #include <sys/modhash_impl.h> 475940Ssowmini #include <inet/ip_ndp.h> 485940Ssowmini #include <inet/ip_if.h> 4910946SSangeeta.Misra@Sun.COM #include <ilb.h> 5010946SSangeeta.Misra@Sun.COM #include <ilb/ilb_impl.h> 5110946SSangeeta.Misra@Sun.COM #include <ilb/ilb_stack.h> 5210946SSangeeta.Misra@Sun.COM #include <ilb/ilb_nat.h> 5310946SSangeeta.Misra@Sun.COM #include <ilb/ilb_conn.h> 545940Ssowmini #include <sys/dlpi.h> 5511042SErik.Nordmark@Sun.COM #include <sys/zone.h> 560Sstevel@tonic-gate 570Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 580Sstevel@tonic-gate #include <mdb/mdb_ks.h> 590Sstevel@tonic-gate 600Sstevel@tonic-gate #define ADDR_WIDTH 11 615940Ssowmini #define L2MAXADDRSTRLEN 255 625940Ssowmini #define MAX_SAP_LEN 255 639089SVasumathi.Sundaram@Sun.COM #define DEFCOLS 80 640Sstevel@tonic-gate 650Sstevel@tonic-gate typedef struct { 660Sstevel@tonic-gate const char *bit_name; /* name of bit */ 670Sstevel@tonic-gate const char *bit_descr; /* description of bit's purpose */ 680Sstevel@tonic-gate } bitname_t; 690Sstevel@tonic-gate 700Sstevel@tonic-gate static const bitname_t squeue_states[] = { 710Sstevel@tonic-gate { "SQS_PROC", "being processed" }, 720Sstevel@tonic-gate { "SQS_WORKER", "... by a worker thread" }, 730Sstevel@tonic-gate { "SQS_ENTER", "... by an squeue_enter() thread" }, 740Sstevel@tonic-gate { "SQS_FAST", "... in fast-path mode" }, 750Sstevel@tonic-gate { "SQS_USER", "A non interrupt user" }, 760Sstevel@tonic-gate { "SQS_BOUND", "worker thread bound to CPU" }, 770Sstevel@tonic-gate { "SQS_PROFILE", "profiling enabled" }, 780Sstevel@tonic-gate { "SQS_REENTER", "re-entered thred" }, 790Sstevel@tonic-gate { NULL } 800Sstevel@tonic-gate }; 810Sstevel@tonic-gate 820Sstevel@tonic-gate typedef struct illif_walk_data { 830Sstevel@tonic-gate ill_g_head_t ill_g_heads[MAX_G_HEADS]; 840Sstevel@tonic-gate int ill_list; 850Sstevel@tonic-gate ill_if_t ill_if; 860Sstevel@tonic-gate } illif_walk_data_t; 870Sstevel@tonic-gate 8811042SErik.Nordmark@Sun.COM typedef struct ncec_walk_data_s { 8911042SErik.Nordmark@Sun.COM struct ndp_g_s ncec_ip_ndp; 9011042SErik.Nordmark@Sun.COM int ncec_hash_tbl_index; 9111042SErik.Nordmark@Sun.COM ncec_t ncec; 9211042SErik.Nordmark@Sun.COM } ncec_walk_data_t; 9311042SErik.Nordmark@Sun.COM 9411042SErik.Nordmark@Sun.COM typedef struct ncec_cbdata_s { 9511042SErik.Nordmark@Sun.COM uintptr_t ncec_addr; 9611042SErik.Nordmark@Sun.COM int ncec_ipversion; 9711042SErik.Nordmark@Sun.COM } ncec_cbdata_t; 985940Ssowmini 995940Ssowmini typedef struct nce_cbdata_s { 10011042SErik.Nordmark@Sun.COM int nce_ipversion; 10111042SErik.Nordmark@Sun.COM char nce_ill_name[LIFNAMSIZ]; 1025940Ssowmini } nce_cbdata_t; 1035940Ssowmini 1045940Ssowmini typedef struct ire_cbdata_s { 1055940Ssowmini int ire_ipversion; 1065940Ssowmini boolean_t verbose; 1075940Ssowmini } ire_cbdata_t; 1085940Ssowmini 10911042SErik.Nordmark@Sun.COM typedef struct zi_cbdata_s { 11011042SErik.Nordmark@Sun.COM const char *zone_name; 11111042SErik.Nordmark@Sun.COM ip_stack_t *ipst; 11211042SErik.Nordmark@Sun.COM boolean_t shared_ip_zone; 11311042SErik.Nordmark@Sun.COM } zi_cbdata_t; 11411042SErik.Nordmark@Sun.COM 1155023Scarlsonj typedef struct th_walk_data { 1165023Scarlsonj uint_t thw_non_zero_only; 1175023Scarlsonj boolean_t thw_match; 1185023Scarlsonj uintptr_t thw_matchkey; 1195023Scarlsonj uintptr_t thw_ipst; 1205023Scarlsonj clock_t thw_lbolt; 1215023Scarlsonj } th_walk_data_t; 1225023Scarlsonj 1239089SVasumathi.Sundaram@Sun.COM typedef struct ipcl_hash_walk_data_s { 1249089SVasumathi.Sundaram@Sun.COM conn_t *conn; 1259089SVasumathi.Sundaram@Sun.COM int connf_tbl_index; 1269089SVasumathi.Sundaram@Sun.COM uintptr_t hash_tbl; 1279089SVasumathi.Sundaram@Sun.COM int hash_tbl_size; 1289089SVasumathi.Sundaram@Sun.COM } ipcl_hash_walk_data_t; 1299089SVasumathi.Sundaram@Sun.COM 1309089SVasumathi.Sundaram@Sun.COM typedef struct ill_walk_data_s { 1319089SVasumathi.Sundaram@Sun.COM ill_t ill; 1329089SVasumathi.Sundaram@Sun.COM } ill_walk_data_t; 1339089SVasumathi.Sundaram@Sun.COM 1349089SVasumathi.Sundaram@Sun.COM typedef struct ill_cbdata_s { 1359089SVasumathi.Sundaram@Sun.COM uintptr_t ill_addr; 1369089SVasumathi.Sundaram@Sun.COM int ill_ipversion; 13711042SErik.Nordmark@Sun.COM ip_stack_t *ill_ipst; 1389089SVasumathi.Sundaram@Sun.COM boolean_t verbose; 1399089SVasumathi.Sundaram@Sun.COM } ill_cbdata_t; 1409089SVasumathi.Sundaram@Sun.COM 1419089SVasumathi.Sundaram@Sun.COM typedef struct ipif_walk_data_s { 1429089SVasumathi.Sundaram@Sun.COM ipif_t ipif; 1439089SVasumathi.Sundaram@Sun.COM } ipif_walk_data_t; 1449089SVasumathi.Sundaram@Sun.COM 1459089SVasumathi.Sundaram@Sun.COM typedef struct ipif_cbdata_s { 1469089SVasumathi.Sundaram@Sun.COM ill_t ill; 1479089SVasumathi.Sundaram@Sun.COM int ipif_ipversion; 1489089SVasumathi.Sundaram@Sun.COM boolean_t verbose; 1499089SVasumathi.Sundaram@Sun.COM } ipif_cbdata_t; 1509089SVasumathi.Sundaram@Sun.COM 1519089SVasumathi.Sundaram@Sun.COM typedef struct hash_walk_arg_s { 1529089SVasumathi.Sundaram@Sun.COM off_t tbl_off; 1539089SVasumathi.Sundaram@Sun.COM off_t size_off; 1549089SVasumathi.Sundaram@Sun.COM } hash_walk_arg_t; 1559089SVasumathi.Sundaram@Sun.COM 1569089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t udp_hash_arg = { 1579089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_udp_fanout), 1589089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_udp_fanout_size) 1599089SVasumathi.Sundaram@Sun.COM }; 1609089SVasumathi.Sundaram@Sun.COM 1619089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t conn_hash_arg = { 1629089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_conn_fanout), 1639089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_conn_fanout_size) 1649089SVasumathi.Sundaram@Sun.COM }; 1659089SVasumathi.Sundaram@Sun.COM 1669089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t bind_hash_arg = { 1679089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_bind_fanout), 1689089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_bind_fanout_size) 1699089SVasumathi.Sundaram@Sun.COM }; 1709089SVasumathi.Sundaram@Sun.COM 1719089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t proto_hash_arg = { 17211042SErik.Nordmark@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4), 1739089SVasumathi.Sundaram@Sun.COM 0 1749089SVasumathi.Sundaram@Sun.COM }; 1759089SVasumathi.Sundaram@Sun.COM 1769089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t proto_v6_hash_arg = { 1779089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6), 1789089SVasumathi.Sundaram@Sun.COM 0 1799089SVasumathi.Sundaram@Sun.COM }; 1809089SVasumathi.Sundaram@Sun.COM 1819089SVasumathi.Sundaram@Sun.COM typedef struct ip_list_walk_data_s { 1829089SVasumathi.Sundaram@Sun.COM off_t nextoff; 1839089SVasumathi.Sundaram@Sun.COM } ip_list_walk_data_t; 1849089SVasumathi.Sundaram@Sun.COM 1859089SVasumathi.Sundaram@Sun.COM typedef struct ip_list_walk_arg_s { 1869089SVasumathi.Sundaram@Sun.COM off_t off; 1879089SVasumathi.Sundaram@Sun.COM size_t size; 1889089SVasumathi.Sundaram@Sun.COM off_t nextp_off; 1899089SVasumathi.Sundaram@Sun.COM } ip_list_walk_arg_t; 1909089SVasumathi.Sundaram@Sun.COM 1919089SVasumathi.Sundaram@Sun.COM static ip_list_walk_arg_t ipif_walk_arg = { 1929089SVasumathi.Sundaram@Sun.COM OFFSETOF(ill_t, ill_ipif), 1939089SVasumathi.Sundaram@Sun.COM sizeof (ipif_t), 1949089SVasumathi.Sundaram@Sun.COM OFFSETOF(ipif_t, ipif_next) 1959089SVasumathi.Sundaram@Sun.COM }; 1969089SVasumathi.Sundaram@Sun.COM 1979089SVasumathi.Sundaram@Sun.COM static ip_list_walk_arg_t srcid_walk_arg = { 1989089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_srcid_head), 1999089SVasumathi.Sundaram@Sun.COM sizeof (srcid_map_t), 2009089SVasumathi.Sundaram@Sun.COM OFFSETOF(srcid_map_t, sm_next) 2019089SVasumathi.Sundaram@Sun.COM }; 2029089SVasumathi.Sundaram@Sun.COM 2030Sstevel@tonic-gate static int iphdr(uintptr_t, uint_t, int, const mdb_arg_t *); 2040Sstevel@tonic-gate static int ip6hdr(uintptr_t, uint_t, int, const mdb_arg_t *); 2050Sstevel@tonic-gate 2069089SVasumathi.Sundaram@Sun.COM static int ill(uintptr_t, uint_t, int, const mdb_arg_t *); 2079089SVasumathi.Sundaram@Sun.COM static void ill_help(void); 2089089SVasumathi.Sundaram@Sun.COM static int ill_walk_init(mdb_walk_state_t *); 2099089SVasumathi.Sundaram@Sun.COM static int ill_walk_step(mdb_walk_state_t *); 2109089SVasumathi.Sundaram@Sun.COM static int ill_format(uintptr_t, const void *, void *); 2119089SVasumathi.Sundaram@Sun.COM static void ill_header(boolean_t); 2129089SVasumathi.Sundaram@Sun.COM 2139089SVasumathi.Sundaram@Sun.COM static int ipif(uintptr_t, uint_t, int, const mdb_arg_t *); 2149089SVasumathi.Sundaram@Sun.COM static void ipif_help(void); 2159089SVasumathi.Sundaram@Sun.COM static int ipif_walk_init(mdb_walk_state_t *); 2169089SVasumathi.Sundaram@Sun.COM static int ipif_walk_step(mdb_walk_state_t *); 2179089SVasumathi.Sundaram@Sun.COM static int ipif_format(uintptr_t, const void *, void *); 2189089SVasumathi.Sundaram@Sun.COM static void ipif_header(boolean_t); 2199089SVasumathi.Sundaram@Sun.COM 2209089SVasumathi.Sundaram@Sun.COM static int ip_list_walk_init(mdb_walk_state_t *); 2219089SVasumathi.Sundaram@Sun.COM static int ip_list_walk_step(mdb_walk_state_t *); 2229089SVasumathi.Sundaram@Sun.COM static void ip_list_walk_fini(mdb_walk_state_t *); 2239089SVasumathi.Sundaram@Sun.COM static int srcid_walk_step(mdb_walk_state_t *); 2249089SVasumathi.Sundaram@Sun.COM 2255940Ssowmini static int ire_format(uintptr_t addr, const void *, void *); 22611042SErik.Nordmark@Sun.COM static int ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion); 22711042SErik.Nordmark@Sun.COM static int ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv); 22811042SErik.Nordmark@Sun.COM static int ncec_walk_step(mdb_walk_state_t *wsp); 22911042SErik.Nordmark@Sun.COM static int ncec_stack_walk_init(mdb_walk_state_t *wsp); 23011042SErik.Nordmark@Sun.COM static int ncec_stack_walk_step(mdb_walk_state_t *wsp); 23111042SErik.Nordmark@Sun.COM static void ncec_stack_walk_fini(mdb_walk_state_t *wsp); 23211042SErik.Nordmark@Sun.COM static int ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw, 23311042SErik.Nordmark@Sun.COM ncec_cbdata_t *id); 23411042SErik.Nordmark@Sun.COM static char *nce_l2_addr(const nce_t *, const ill_t *); 2353448Sdh155122 2369089SVasumathi.Sundaram@Sun.COM static int ipcl_hash_walk_init(mdb_walk_state_t *); 2379089SVasumathi.Sundaram@Sun.COM static int ipcl_hash_walk_step(mdb_walk_state_t *); 2389089SVasumathi.Sundaram@Sun.COM static void ipcl_hash_walk_fini(mdb_walk_state_t *); 2399089SVasumathi.Sundaram@Sun.COM 2409089SVasumathi.Sundaram@Sun.COM static int conn_status_walk_step(mdb_walk_state_t *); 2419089SVasumathi.Sundaram@Sun.COM static int conn_status(uintptr_t, uint_t, int, const mdb_arg_t *); 2429089SVasumathi.Sundaram@Sun.COM static void conn_status_help(void); 2439089SVasumathi.Sundaram@Sun.COM 2449089SVasumathi.Sundaram@Sun.COM static int srcid_status(uintptr_t, uint_t, int, const mdb_arg_t *); 2459089SVasumathi.Sundaram@Sun.COM 24610946SSangeeta.Misra@Sun.COM static int ilb_stacks_walk_step(mdb_walk_state_t *); 24710946SSangeeta.Misra@Sun.COM static int ilb_rules_walk_init(mdb_walk_state_t *); 24810946SSangeeta.Misra@Sun.COM static int ilb_rules_walk_step(mdb_walk_state_t *); 24910946SSangeeta.Misra@Sun.COM static int ilb_servers_walk_init(mdb_walk_state_t *); 25010946SSangeeta.Misra@Sun.COM static int ilb_servers_walk_step(mdb_walk_state_t *); 25110946SSangeeta.Misra@Sun.COM static int ilb_nat_src_walk_init(mdb_walk_state_t *); 25210946SSangeeta.Misra@Sun.COM static int ilb_nat_src_walk_step(mdb_walk_state_t *); 25310946SSangeeta.Misra@Sun.COM static int ilb_conn_walk_init(mdb_walk_state_t *); 25410946SSangeeta.Misra@Sun.COM static int ilb_conn_walk_step(mdb_walk_state_t *); 25510946SSangeeta.Misra@Sun.COM static int ilb_sticky_walk_init(mdb_walk_state_t *); 25610946SSangeeta.Misra@Sun.COM static int ilb_sticky_walk_step(mdb_walk_state_t *); 25710946SSangeeta.Misra@Sun.COM static void ilb_common_walk_fini(mdb_walk_state_t *); 25810946SSangeeta.Misra@Sun.COM 2593448Sdh155122 /* 2603448Sdh155122 * Given the kernel address of an ip_stack_t, return the stackid 2613448Sdh155122 */ 2623448Sdh155122 static int 2633448Sdh155122 ips_to_stackid(uintptr_t kaddr) 2643448Sdh155122 { 2653448Sdh155122 ip_stack_t ipss; 2663448Sdh155122 netstack_t nss; 2673448Sdh155122 2683448Sdh155122 if (mdb_vread(&ipss, sizeof (ipss), kaddr) == -1) { 2693448Sdh155122 mdb_warn("failed to read ip_stack_t %p", kaddr); 2703448Sdh155122 return (0); 2713448Sdh155122 } 2723448Sdh155122 kaddr = (uintptr_t)ipss.ips_netstack; 2733448Sdh155122 if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) { 2743448Sdh155122 mdb_warn("failed to read netstack_t %p", kaddr); 2753448Sdh155122 return (0); 2763448Sdh155122 } 2773448Sdh155122 return (nss.netstack_stackid); 2783448Sdh155122 } 2793448Sdh155122 28011042SErik.Nordmark@Sun.COM /* ARGSUSED */ 28111042SErik.Nordmark@Sun.COM static int 28211042SErik.Nordmark@Sun.COM zone_to_ips_cb(uintptr_t addr, const void *zi_arg, void *zi_cb_arg) 28311042SErik.Nordmark@Sun.COM { 28411042SErik.Nordmark@Sun.COM zi_cbdata_t *zi_cb = zi_cb_arg; 28511042SErik.Nordmark@Sun.COM zone_t zone; 28611042SErik.Nordmark@Sun.COM char zone_name[ZONENAME_MAX]; 28711042SErik.Nordmark@Sun.COM netstack_t ns; 28811042SErik.Nordmark@Sun.COM 28911042SErik.Nordmark@Sun.COM if (mdb_vread(&zone, sizeof (zone_t), addr) == -1) { 29011042SErik.Nordmark@Sun.COM mdb_warn("can't read zone at %p", addr); 29111042SErik.Nordmark@Sun.COM return (WALK_ERR); 29211042SErik.Nordmark@Sun.COM } 29311042SErik.Nordmark@Sun.COM 29411042SErik.Nordmark@Sun.COM (void) mdb_readstr(zone_name, ZONENAME_MAX, (uintptr_t)zone.zone_name); 29511042SErik.Nordmark@Sun.COM 29611042SErik.Nordmark@Sun.COM if (strcmp(zi_cb->zone_name, zone_name) != 0) 29711042SErik.Nordmark@Sun.COM return (WALK_NEXT); 29811042SErik.Nordmark@Sun.COM 29911042SErik.Nordmark@Sun.COM zi_cb->shared_ip_zone = (!(zone.zone_flags & ZF_NET_EXCL) && 30011042SErik.Nordmark@Sun.COM (strcmp(zone_name, "global") != 0)); 30111042SErik.Nordmark@Sun.COM 30211042SErik.Nordmark@Sun.COM if (mdb_vread(&ns, sizeof (netstack_t), (uintptr_t)zone.zone_netstack) 30311042SErik.Nordmark@Sun.COM == -1) { 30411042SErik.Nordmark@Sun.COM mdb_warn("can't read netstack at %p", zone.zone_netstack); 30511042SErik.Nordmark@Sun.COM return (WALK_ERR); 30611042SErik.Nordmark@Sun.COM } 30711042SErik.Nordmark@Sun.COM 30811042SErik.Nordmark@Sun.COM zi_cb->ipst = ns.netstack_ip; 30911042SErik.Nordmark@Sun.COM return (WALK_DONE); 31011042SErik.Nordmark@Sun.COM } 31111042SErik.Nordmark@Sun.COM 31211042SErik.Nordmark@Sun.COM static ip_stack_t * 31311042SErik.Nordmark@Sun.COM zone_to_ips(const char *zone_name) 31411042SErik.Nordmark@Sun.COM { 31511042SErik.Nordmark@Sun.COM zi_cbdata_t zi_cb; 31611042SErik.Nordmark@Sun.COM 31711042SErik.Nordmark@Sun.COM if (zone_name == NULL) 31811042SErik.Nordmark@Sun.COM return (NULL); 31911042SErik.Nordmark@Sun.COM 32011042SErik.Nordmark@Sun.COM zi_cb.zone_name = zone_name; 32111042SErik.Nordmark@Sun.COM zi_cb.ipst = NULL; 32211042SErik.Nordmark@Sun.COM zi_cb.shared_ip_zone = B_FALSE; 32311042SErik.Nordmark@Sun.COM 32411042SErik.Nordmark@Sun.COM if (mdb_walk("zone", (mdb_walk_cb_t)zone_to_ips_cb, &zi_cb) == -1) { 32511042SErik.Nordmark@Sun.COM mdb_warn("failed to walk zone"); 32611042SErik.Nordmark@Sun.COM return (NULL); 32711042SErik.Nordmark@Sun.COM } 32811042SErik.Nordmark@Sun.COM 32911042SErik.Nordmark@Sun.COM if (zi_cb.shared_ip_zone) { 33011042SErik.Nordmark@Sun.COM mdb_warn("%s is a Shared-IP zone, try '-s global' instead\n", 33111042SErik.Nordmark@Sun.COM zone_name); 33211042SErik.Nordmark@Sun.COM return (NULL); 33311042SErik.Nordmark@Sun.COM } 33411042SErik.Nordmark@Sun.COM 33511042SErik.Nordmark@Sun.COM if (zi_cb.ipst == NULL) { 33611042SErik.Nordmark@Sun.COM mdb_warn("failed to find zone %s\n", zone_name); 33711042SErik.Nordmark@Sun.COM return (NULL); 33811042SErik.Nordmark@Sun.COM } 33911042SErik.Nordmark@Sun.COM 34011042SErik.Nordmark@Sun.COM return (zi_cb.ipst); 34111042SErik.Nordmark@Sun.COM } 34211042SErik.Nordmark@Sun.COM 343*11754SKacheong.Poon@Sun.COM /* 344*11754SKacheong.Poon@Sun.COM * Generic network stack walker initialization function. It is used by all 345*11754SKacheong.Poon@Sun.COM * other netwrok stack walkers. 346*11754SKacheong.Poon@Sun.COM */ 3470Sstevel@tonic-gate int 348*11754SKacheong.Poon@Sun.COM ns_walk_init(mdb_walk_state_t *wsp) 3493448Sdh155122 { 3503448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 3513448Sdh155122 mdb_warn("can't walk 'netstack'"); 3523448Sdh155122 return (WALK_ERR); 3533448Sdh155122 } 3543448Sdh155122 return (WALK_NEXT); 3553448Sdh155122 } 3563448Sdh155122 357*11754SKacheong.Poon@Sun.COM /* 358*11754SKacheong.Poon@Sun.COM * Generic network stack walker stepping function. It is used by all other 359*11754SKacheong.Poon@Sun.COM * network stack walkers. The which parameter differentiates the different 360*11754SKacheong.Poon@Sun.COM * walkers. 361*11754SKacheong.Poon@Sun.COM */ 3623448Sdh155122 int 363*11754SKacheong.Poon@Sun.COM ns_walk_step(mdb_walk_state_t *wsp, int which) 3643448Sdh155122 { 3653448Sdh155122 uintptr_t kaddr; 3663448Sdh155122 netstack_t nss; 3673448Sdh155122 3683448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 3693448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 3703448Sdh155122 return (WALK_ERR); 3713448Sdh155122 } 372*11754SKacheong.Poon@Sun.COM kaddr = (uintptr_t)nss.netstack_modules[which]; 3733448Sdh155122 3743448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 3753448Sdh155122 } 3763448Sdh155122 377*11754SKacheong.Poon@Sun.COM /* 378*11754SKacheong.Poon@Sun.COM * IP network stack walker stepping function. 379*11754SKacheong.Poon@Sun.COM */ 380*11754SKacheong.Poon@Sun.COM int 381*11754SKacheong.Poon@Sun.COM ip_stacks_walk_step(mdb_walk_state_t *wsp) 382*11754SKacheong.Poon@Sun.COM { 383*11754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_IP)); 384*11754SKacheong.Poon@Sun.COM } 385*11754SKacheong.Poon@Sun.COM 386*11754SKacheong.Poon@Sun.COM /* 387*11754SKacheong.Poon@Sun.COM * TCP network stack walker stepping function. 388*11754SKacheong.Poon@Sun.COM */ 389*11754SKacheong.Poon@Sun.COM int 390*11754SKacheong.Poon@Sun.COM tcp_stacks_walk_step(mdb_walk_state_t *wsp) 391*11754SKacheong.Poon@Sun.COM { 392*11754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_TCP)); 393*11754SKacheong.Poon@Sun.COM } 394*11754SKacheong.Poon@Sun.COM 395*11754SKacheong.Poon@Sun.COM /* 396*11754SKacheong.Poon@Sun.COM * SCTP network stack walker stepping function. 397*11754SKacheong.Poon@Sun.COM */ 398*11754SKacheong.Poon@Sun.COM int 399*11754SKacheong.Poon@Sun.COM sctp_stacks_walk_step(mdb_walk_state_t *wsp) 400*11754SKacheong.Poon@Sun.COM { 401*11754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_SCTP)); 402*11754SKacheong.Poon@Sun.COM } 403*11754SKacheong.Poon@Sun.COM 404*11754SKacheong.Poon@Sun.COM /* 405*11754SKacheong.Poon@Sun.COM * UDP network stack walker stepping function. 406*11754SKacheong.Poon@Sun.COM */ 407*11754SKacheong.Poon@Sun.COM int 408*11754SKacheong.Poon@Sun.COM udp_stacks_walk_step(mdb_walk_state_t *wsp) 409*11754SKacheong.Poon@Sun.COM { 410*11754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_UDP)); 411*11754SKacheong.Poon@Sun.COM } 412*11754SKacheong.Poon@Sun.COM 413*11754SKacheong.Poon@Sun.COM /* 414*11754SKacheong.Poon@Sun.COM * Initialization function for the per CPU TCP stats counter walker of a given 415*11754SKacheong.Poon@Sun.COM * TCP stack. 416*11754SKacheong.Poon@Sun.COM */ 417*11754SKacheong.Poon@Sun.COM int 418*11754SKacheong.Poon@Sun.COM tcps_sc_walk_init(mdb_walk_state_t *wsp) 419*11754SKacheong.Poon@Sun.COM { 420*11754SKacheong.Poon@Sun.COM tcp_stack_t tcps; 421*11754SKacheong.Poon@Sun.COM 422*11754SKacheong.Poon@Sun.COM if (wsp->walk_addr == NULL) 423*11754SKacheong.Poon@Sun.COM return (WALK_ERR); 424*11754SKacheong.Poon@Sun.COM 425*11754SKacheong.Poon@Sun.COM if (mdb_vread(&tcps, sizeof (tcps), wsp->walk_addr) == -1) { 426*11754SKacheong.Poon@Sun.COM mdb_warn("failed to read tcp_stack_t at %p", wsp->walk_addr); 427*11754SKacheong.Poon@Sun.COM return (WALK_ERR); 428*11754SKacheong.Poon@Sun.COM } 429*11754SKacheong.Poon@Sun.COM if (tcps.tcps_sc_cnt == 0) 430*11754SKacheong.Poon@Sun.COM return (WALK_DONE); 431*11754SKacheong.Poon@Sun.COM 432*11754SKacheong.Poon@Sun.COM /* 433*11754SKacheong.Poon@Sun.COM * Store the tcp_stack_t pointer in walk_data. The stepping function 434*11754SKacheong.Poon@Sun.COM * used it to calculate if the end of the counter has reached. 435*11754SKacheong.Poon@Sun.COM */ 436*11754SKacheong.Poon@Sun.COM wsp->walk_data = (void *)wsp->walk_addr; 437*11754SKacheong.Poon@Sun.COM wsp->walk_addr = (uintptr_t)tcps.tcps_sc; 438*11754SKacheong.Poon@Sun.COM return (WALK_NEXT); 439*11754SKacheong.Poon@Sun.COM } 440*11754SKacheong.Poon@Sun.COM 441*11754SKacheong.Poon@Sun.COM /* 442*11754SKacheong.Poon@Sun.COM * Stepping function for the per CPU TCP stats counterwalker. 443*11754SKacheong.Poon@Sun.COM */ 444*11754SKacheong.Poon@Sun.COM int 445*11754SKacheong.Poon@Sun.COM tcps_sc_walk_step(mdb_walk_state_t *wsp) 446*11754SKacheong.Poon@Sun.COM { 447*11754SKacheong.Poon@Sun.COM int status; 448*11754SKacheong.Poon@Sun.COM tcp_stack_t tcps; 449*11754SKacheong.Poon@Sun.COM tcp_stats_cpu_t *stats; 450*11754SKacheong.Poon@Sun.COM char *next, *end; 451*11754SKacheong.Poon@Sun.COM 452*11754SKacheong.Poon@Sun.COM if (mdb_vread(&tcps, sizeof (tcps), (uintptr_t)wsp->walk_data) == -1) { 453*11754SKacheong.Poon@Sun.COM mdb_warn("failed to read tcp_stack_t at %p", wsp->walk_addr); 454*11754SKacheong.Poon@Sun.COM return (WALK_ERR); 455*11754SKacheong.Poon@Sun.COM } 456*11754SKacheong.Poon@Sun.COM if (mdb_vread(&stats, sizeof (stats), wsp->walk_addr) == -1) { 457*11754SKacheong.Poon@Sun.COM mdb_warn("failed ot read tcp_stats_cpu_t at %p", 458*11754SKacheong.Poon@Sun.COM wsp->walk_addr); 459*11754SKacheong.Poon@Sun.COM return (WALK_ERR); 460*11754SKacheong.Poon@Sun.COM } 461*11754SKacheong.Poon@Sun.COM status = wsp->walk_callback((uintptr_t)stats, &stats, wsp->walk_cbdata); 462*11754SKacheong.Poon@Sun.COM if (status != WALK_NEXT) 463*11754SKacheong.Poon@Sun.COM return (status); 464*11754SKacheong.Poon@Sun.COM 465*11754SKacheong.Poon@Sun.COM next = (char *)wsp->walk_addr + sizeof (tcp_stats_cpu_t *); 466*11754SKacheong.Poon@Sun.COM end = (char *)tcps.tcps_sc + tcps.tcps_sc_cnt * 467*11754SKacheong.Poon@Sun.COM sizeof (tcp_stats_cpu_t *); 468*11754SKacheong.Poon@Sun.COM if (next >= end) 469*11754SKacheong.Poon@Sun.COM return (WALK_DONE); 470*11754SKacheong.Poon@Sun.COM wsp->walk_addr = (uintptr_t)next; 471*11754SKacheong.Poon@Sun.COM return (WALK_NEXT); 472*11754SKacheong.Poon@Sun.COM } 473*11754SKacheong.Poon@Sun.COM 4745023Scarlsonj int 4755023Scarlsonj th_hash_walk_init(mdb_walk_state_t *wsp) 4765023Scarlsonj { 4775023Scarlsonj GElf_Sym sym; 4785023Scarlsonj list_node_t *next; 4795023Scarlsonj 4805023Scarlsonj if (wsp->walk_addr == NULL) { 4815023Scarlsonj if (mdb_lookup_by_obj("ip", "ip_thread_list", &sym) == 0) { 4825023Scarlsonj wsp->walk_addr = sym.st_value; 4835023Scarlsonj } else { 4845023Scarlsonj mdb_warn("unable to locate ip_thread_list\n"); 4855023Scarlsonj return (WALK_ERR); 4865023Scarlsonj } 4875023Scarlsonj } 4885023Scarlsonj 4895023Scarlsonj if (mdb_vread(&next, sizeof (next), 4905023Scarlsonj wsp->walk_addr + offsetof(list_t, list_head) + 4915023Scarlsonj offsetof(list_node_t, list_next)) == -1 || 4925023Scarlsonj next == NULL) { 4935023Scarlsonj mdb_warn("non-DEBUG image; cannot walk th_hash list\n"); 4945023Scarlsonj return (WALK_ERR); 4955023Scarlsonj } 4965023Scarlsonj 4975023Scarlsonj if (mdb_layered_walk("list", wsp) == -1) { 4985023Scarlsonj mdb_warn("can't walk 'list'"); 4995023Scarlsonj return (WALK_ERR); 5005023Scarlsonj } else { 5015023Scarlsonj return (WALK_NEXT); 5025023Scarlsonj } 5035023Scarlsonj } 5045023Scarlsonj 5055023Scarlsonj int 5065023Scarlsonj th_hash_walk_step(mdb_walk_state_t *wsp) 5075023Scarlsonj { 5085023Scarlsonj return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 5095023Scarlsonj wsp->walk_cbdata)); 5105023Scarlsonj } 5115023Scarlsonj 5123448Sdh155122 /* 5133448Sdh155122 * Called with walk_addr being the address of ips_ill_g_heads 5143448Sdh155122 */ 5153448Sdh155122 int 5163448Sdh155122 illif_stack_walk_init(mdb_walk_state_t *wsp) 5170Sstevel@tonic-gate { 5180Sstevel@tonic-gate illif_walk_data_t *iw; 5190Sstevel@tonic-gate 5203448Sdh155122 if (wsp->walk_addr == NULL) { 5213448Sdh155122 mdb_warn("illif_stack supports only local walks\n"); 5220Sstevel@tonic-gate return (WALK_ERR); 5230Sstevel@tonic-gate } 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate iw = mdb_alloc(sizeof (illif_walk_data_t), UM_SLEEP); 5260Sstevel@tonic-gate 5273448Sdh155122 if (mdb_vread(iw->ill_g_heads, MAX_G_HEADS * sizeof (ill_g_head_t), 5283448Sdh155122 wsp->walk_addr) == -1) { 5293448Sdh155122 mdb_warn("failed to read 'ips_ill_g_heads' at %p", 5303448Sdh155122 wsp->walk_addr); 5310Sstevel@tonic-gate mdb_free(iw, sizeof (illif_walk_data_t)); 5320Sstevel@tonic-gate return (WALK_ERR); 5330Sstevel@tonic-gate } 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate iw->ill_list = 0; 5363448Sdh155122 wsp->walk_addr = (uintptr_t)iw->ill_g_heads[0].ill_g_list_head; 5370Sstevel@tonic-gate wsp->walk_data = iw; 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate return (WALK_NEXT); 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate int 5433448Sdh155122 illif_stack_walk_step(mdb_walk_state_t *wsp) 5440Sstevel@tonic-gate { 5450Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 5460Sstevel@tonic-gate illif_walk_data_t *iw = wsp->walk_data; 5470Sstevel@tonic-gate int list = iw->ill_list; 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate if (mdb_vread(&iw->ill_if, sizeof (ill_if_t), addr) == -1) { 5500Sstevel@tonic-gate mdb_warn("failed to read ill_if_t at %p", addr); 5510Sstevel@tonic-gate return (WALK_ERR); 5520Sstevel@tonic-gate } 5530Sstevel@tonic-gate 5540Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)iw->ill_if.illif_next; 5550Sstevel@tonic-gate 5563448Sdh155122 if (wsp->walk_addr == 5573448Sdh155122 (uintptr_t)iw->ill_g_heads[list].ill_g_list_head) { 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate if (++list >= MAX_G_HEADS) 5600Sstevel@tonic-gate return (WALK_DONE); 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate iw->ill_list = list; 5633448Sdh155122 wsp->walk_addr = 5643448Sdh155122 (uintptr_t)iw->ill_g_heads[list].ill_g_list_head; 5650Sstevel@tonic-gate return (WALK_NEXT); 5660Sstevel@tonic-gate } 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate return (wsp->walk_callback(addr, iw, wsp->walk_cbdata)); 5690Sstevel@tonic-gate } 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate void 5723448Sdh155122 illif_stack_walk_fini(mdb_walk_state_t *wsp) 5730Sstevel@tonic-gate { 5740Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (illif_walk_data_t)); 5750Sstevel@tonic-gate } 5760Sstevel@tonic-gate 5770Sstevel@tonic-gate typedef struct illif_cbdata { 5780Sstevel@tonic-gate uint_t ill_flags; 5790Sstevel@tonic-gate uintptr_t ill_addr; 5800Sstevel@tonic-gate int ill_printlist; /* list to be printed (MAX_G_HEADS for all) */ 5810Sstevel@tonic-gate boolean_t ill_printed; 5820Sstevel@tonic-gate } illif_cbdata_t; 5830Sstevel@tonic-gate 5840Sstevel@tonic-gate static int 5850Sstevel@tonic-gate illif_cb(uintptr_t addr, const illif_walk_data_t *iw, illif_cbdata_t *id) 5860Sstevel@tonic-gate { 5870Sstevel@tonic-gate const char *version; 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate if (id->ill_printlist < MAX_G_HEADS && 5900Sstevel@tonic-gate id->ill_printlist != iw->ill_list) 5910Sstevel@tonic-gate return (WALK_NEXT); 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate if (id->ill_flags & DCMD_ADDRSPEC && id->ill_addr != addr) 5940Sstevel@tonic-gate return (WALK_NEXT); 5950Sstevel@tonic-gate 5960Sstevel@tonic-gate if (id->ill_flags & DCMD_PIPE_OUT) { 5970Sstevel@tonic-gate mdb_printf("%p\n", addr); 5980Sstevel@tonic-gate return (WALK_NEXT); 5990Sstevel@tonic-gate } 6000Sstevel@tonic-gate 6010Sstevel@tonic-gate switch (iw->ill_list) { 6020Sstevel@tonic-gate case IP_V4_G_HEAD: version = "v4"; break; 6030Sstevel@tonic-gate case IP_V6_G_HEAD: version = "v6"; break; 6040Sstevel@tonic-gate default: version = "??"; break; 6050Sstevel@tonic-gate } 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate mdb_printf("%?p %2s %?p %10d %?p %s\n", 6080Sstevel@tonic-gate addr, version, addr + offsetof(ill_if_t, illif_avl_by_ppa), 6090Sstevel@tonic-gate iw->ill_if.illif_avl_by_ppa.avl_numnodes, 6100Sstevel@tonic-gate iw->ill_if.illif_ppa_arena, iw->ill_if.illif_name); 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate id->ill_printed = TRUE; 6130Sstevel@tonic-gate 6140Sstevel@tonic-gate return (WALK_NEXT); 6150Sstevel@tonic-gate } 6160Sstevel@tonic-gate 6170Sstevel@tonic-gate int 6185940Ssowmini ip_stacks_common_walk_init(mdb_walk_state_t *wsp) 6193448Sdh155122 { 6203448Sdh155122 if (mdb_layered_walk("ip_stacks", wsp) == -1) { 6213448Sdh155122 mdb_warn("can't walk 'ip_stacks'"); 6223448Sdh155122 return (WALK_ERR); 6233448Sdh155122 } 6243448Sdh155122 6253448Sdh155122 return (WALK_NEXT); 6263448Sdh155122 } 6273448Sdh155122 6283448Sdh155122 int 6293448Sdh155122 illif_walk_step(mdb_walk_state_t *wsp) 6303448Sdh155122 { 6313448Sdh155122 uintptr_t kaddr; 6323448Sdh155122 6333448Sdh155122 kaddr = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ill_g_heads); 6343448Sdh155122 6353448Sdh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) { 6363448Sdh155122 mdb_warn("can't read ips_ip_cache_table at %p", kaddr); 6373448Sdh155122 return (WALK_ERR); 6383448Sdh155122 } 6393448Sdh155122 6403448Sdh155122 if (mdb_pwalk("illif_stack", wsp->walk_callback, 6415023Scarlsonj wsp->walk_cbdata, kaddr) == -1) { 6423448Sdh155122 mdb_warn("couldn't walk 'illif_stack' for ips_ill_g_heads %p", 6433448Sdh155122 kaddr); 6443448Sdh155122 return (WALK_ERR); 6453448Sdh155122 } 6463448Sdh155122 return (WALK_NEXT); 6473448Sdh155122 } 6483448Sdh155122 6493448Sdh155122 int 6500Sstevel@tonic-gate illif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 6510Sstevel@tonic-gate { 6520Sstevel@tonic-gate illif_cbdata_t id; 6530Sstevel@tonic-gate ill_if_t ill_if; 6540Sstevel@tonic-gate const char *opt_P = NULL; 6550Sstevel@tonic-gate int printlist = MAX_G_HEADS; 6560Sstevel@tonic-gate 6570Sstevel@tonic-gate if (mdb_getopts(argc, argv, 6580Sstevel@tonic-gate 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 6590Sstevel@tonic-gate return (DCMD_USAGE); 6600Sstevel@tonic-gate 6610Sstevel@tonic-gate if (opt_P != NULL) { 6620Sstevel@tonic-gate if (strcmp("v4", opt_P) == 0) { 6630Sstevel@tonic-gate printlist = IP_V4_G_HEAD; 6640Sstevel@tonic-gate } else if (strcmp("v6", opt_P) == 0) { 6650Sstevel@tonic-gate printlist = IP_V6_G_HEAD; 6660Sstevel@tonic-gate } else { 6670Sstevel@tonic-gate mdb_warn("invalid protocol '%s'\n", opt_P); 6680Sstevel@tonic-gate return (DCMD_USAGE); 6690Sstevel@tonic-gate } 6700Sstevel@tonic-gate } 6710Sstevel@tonic-gate 6720Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && (flags & DCMD_PIPE_OUT) == 0) { 6730Sstevel@tonic-gate mdb_printf("%<u>%?s %2s %?s %10s %?s %-10s%</u>\n", 6740Sstevel@tonic-gate "ADDR", "IP", "AVLADDR", "NUMNODES", "ARENA", "NAME"); 6750Sstevel@tonic-gate } 6760Sstevel@tonic-gate 6770Sstevel@tonic-gate id.ill_flags = flags; 6780Sstevel@tonic-gate id.ill_addr = addr; 6790Sstevel@tonic-gate id.ill_printlist = printlist; 6800Sstevel@tonic-gate id.ill_printed = FALSE; 6810Sstevel@tonic-gate 6820Sstevel@tonic-gate if (mdb_walk("illif", (mdb_walk_cb_t)illif_cb, &id) == -1) { 6830Sstevel@tonic-gate mdb_warn("can't walk ill_if_t structures"); 6840Sstevel@tonic-gate return (DCMD_ERR); 6850Sstevel@tonic-gate } 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) || opt_P != NULL || id.ill_printed) 6880Sstevel@tonic-gate return (DCMD_OK); 6890Sstevel@tonic-gate 6900Sstevel@tonic-gate /* 6910Sstevel@tonic-gate * If an address is specified and the walk doesn't find it, 6920Sstevel@tonic-gate * print it anyway. 6930Sstevel@tonic-gate */ 6940Sstevel@tonic-gate if (mdb_vread(&ill_if, sizeof (ill_if_t), addr) == -1) { 6950Sstevel@tonic-gate mdb_warn("failed to read ill_if_t at %p", addr); 6960Sstevel@tonic-gate return (DCMD_ERR); 6970Sstevel@tonic-gate } 6980Sstevel@tonic-gate 6990Sstevel@tonic-gate mdb_printf("%?p %2s %?p %10d %?p %s\n", 7000Sstevel@tonic-gate addr, "??", addr + offsetof(ill_if_t, illif_avl_by_ppa), 7010Sstevel@tonic-gate ill_if.illif_avl_by_ppa.avl_numnodes, 7020Sstevel@tonic-gate ill_if.illif_ppa_arena, ill_if.illif_name); 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate return (DCMD_OK); 7050Sstevel@tonic-gate } 7060Sstevel@tonic-gate 7070Sstevel@tonic-gate static void 7080Sstevel@tonic-gate illif_help(void) 7090Sstevel@tonic-gate { 7100Sstevel@tonic-gate mdb_printf("Options:\n"); 7110Sstevel@tonic-gate mdb_printf("\t-P v4 | v6" 7120Sstevel@tonic-gate "\tfilter interface structures for the specified protocol\n"); 7130Sstevel@tonic-gate } 7140Sstevel@tonic-gate 7150Sstevel@tonic-gate int 71611042SErik.Nordmark@Sun.COM nce_walk_init(mdb_walk_state_t *wsp) 71711042SErik.Nordmark@Sun.COM { 71811042SErik.Nordmark@Sun.COM if (mdb_layered_walk("nce_cache", wsp) == -1) { 71911042SErik.Nordmark@Sun.COM mdb_warn("can't walk 'nce_cache'"); 72011042SErik.Nordmark@Sun.COM return (WALK_ERR); 72111042SErik.Nordmark@Sun.COM } 72211042SErik.Nordmark@Sun.COM 72311042SErik.Nordmark@Sun.COM return (WALK_NEXT); 72411042SErik.Nordmark@Sun.COM } 72511042SErik.Nordmark@Sun.COM 72611042SErik.Nordmark@Sun.COM int 72711042SErik.Nordmark@Sun.COM nce_walk_step(mdb_walk_state_t *wsp) 72811042SErik.Nordmark@Sun.COM { 72911042SErik.Nordmark@Sun.COM nce_t nce; 73011042SErik.Nordmark@Sun.COM 73111042SErik.Nordmark@Sun.COM if (mdb_vread(&nce, sizeof (nce), wsp->walk_addr) == -1) { 73211042SErik.Nordmark@Sun.COM mdb_warn("can't read nce at %p", wsp->walk_addr); 73311042SErik.Nordmark@Sun.COM return (WALK_ERR); 73411042SErik.Nordmark@Sun.COM } 73511042SErik.Nordmark@Sun.COM 73611042SErik.Nordmark@Sun.COM return (wsp->walk_callback(wsp->walk_addr, &nce, wsp->walk_cbdata)); 73711042SErik.Nordmark@Sun.COM } 73811042SErik.Nordmark@Sun.COM 73911042SErik.Nordmark@Sun.COM static int 74011042SErik.Nordmark@Sun.COM nce_format(uintptr_t addr, const nce_t *ncep, void *nce_cb_arg) 74111042SErik.Nordmark@Sun.COM { 74211042SErik.Nordmark@Sun.COM nce_cbdata_t *nce_cb = nce_cb_arg; 74311042SErik.Nordmark@Sun.COM ill_t ill; 74411042SErik.Nordmark@Sun.COM char ill_name[LIFNAMSIZ]; 74511042SErik.Nordmark@Sun.COM ncec_t ncec; 74611042SErik.Nordmark@Sun.COM 74711042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec), 74811042SErik.Nordmark@Sun.COM (uintptr_t)ncep->nce_common) == -1) { 74911042SErik.Nordmark@Sun.COM mdb_warn("can't read ncec at %p", ncep->nce_common); 75011042SErik.Nordmark@Sun.COM return (WALK_NEXT); 75111042SErik.Nordmark@Sun.COM } 75211042SErik.Nordmark@Sun.COM if (nce_cb->nce_ipversion != 0 && 75311042SErik.Nordmark@Sun.COM ncec.ncec_ipversion != nce_cb->nce_ipversion) 75411042SErik.Nordmark@Sun.COM return (WALK_NEXT); 75511042SErik.Nordmark@Sun.COM 75611042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncep->nce_ill) == -1) { 75711042SErik.Nordmark@Sun.COM mdb_snprintf(ill_name, sizeof (ill_name), "--"); 75811042SErik.Nordmark@Sun.COM } else { 75911042SErik.Nordmark@Sun.COM (void) mdb_readstr(ill_name, 76011042SErik.Nordmark@Sun.COM MIN(LIFNAMSIZ, ill.ill_name_length), 76111042SErik.Nordmark@Sun.COM (uintptr_t)ill.ill_name); 76211042SErik.Nordmark@Sun.COM } 76311042SErik.Nordmark@Sun.COM 76411042SErik.Nordmark@Sun.COM if (nce_cb->nce_ill_name[0] != '\0' && 76511042SErik.Nordmark@Sun.COM strncmp(nce_cb->nce_ill_name, ill_name, LIFNAMSIZ) != 0) 76611042SErik.Nordmark@Sun.COM return (WALK_NEXT); 76711042SErik.Nordmark@Sun.COM 76811042SErik.Nordmark@Sun.COM if (ncec.ncec_ipversion == IPV6_VERSION) { 76911042SErik.Nordmark@Sun.COM 77011042SErik.Nordmark@Sun.COM mdb_printf("%?p %5s %-18s %?p %6d %N\n", 77111042SErik.Nordmark@Sun.COM addr, ill_name, 77211042SErik.Nordmark@Sun.COM nce_l2_addr(ncep, &ill), 77311042SErik.Nordmark@Sun.COM ncep->nce_fp_mp, 77411042SErik.Nordmark@Sun.COM ncep->nce_refcnt, 77511042SErik.Nordmark@Sun.COM &ncep->nce_addr); 77611042SErik.Nordmark@Sun.COM 77711042SErik.Nordmark@Sun.COM } else { 77811042SErik.Nordmark@Sun.COM struct in_addr nceaddr; 77911042SErik.Nordmark@Sun.COM 78011042SErik.Nordmark@Sun.COM IN6_V4MAPPED_TO_INADDR(&ncep->nce_addr, &nceaddr); 78111042SErik.Nordmark@Sun.COM mdb_printf("%?p %5s %-18s %?p %6d %I\n", 78211042SErik.Nordmark@Sun.COM addr, ill_name, 78311042SErik.Nordmark@Sun.COM nce_l2_addr(ncep, &ill), 78411042SErik.Nordmark@Sun.COM ncep->nce_fp_mp, 78511042SErik.Nordmark@Sun.COM ncep->nce_refcnt, 78611042SErik.Nordmark@Sun.COM nceaddr.s_addr); 78711042SErik.Nordmark@Sun.COM } 78811042SErik.Nordmark@Sun.COM 78911042SErik.Nordmark@Sun.COM return (WALK_NEXT); 79011042SErik.Nordmark@Sun.COM } 79111042SErik.Nordmark@Sun.COM 79211042SErik.Nordmark@Sun.COM int 79311042SErik.Nordmark@Sun.COM dce_walk_init(mdb_walk_state_t *wsp) 79411042SErik.Nordmark@Sun.COM { 79511042SErik.Nordmark@Sun.COM wsp->walk_data = (void *)wsp->walk_addr; 79611042SErik.Nordmark@Sun.COM 79711042SErik.Nordmark@Sun.COM if (mdb_layered_walk("dce_cache", wsp) == -1) { 79811042SErik.Nordmark@Sun.COM mdb_warn("can't walk 'dce_cache'"); 79911042SErik.Nordmark@Sun.COM return (WALK_ERR); 80011042SErik.Nordmark@Sun.COM } 80111042SErik.Nordmark@Sun.COM 80211042SErik.Nordmark@Sun.COM return (WALK_NEXT); 80311042SErik.Nordmark@Sun.COM } 80411042SErik.Nordmark@Sun.COM 80511042SErik.Nordmark@Sun.COM int 80611042SErik.Nordmark@Sun.COM dce_walk_step(mdb_walk_state_t *wsp) 80711042SErik.Nordmark@Sun.COM { 80811042SErik.Nordmark@Sun.COM dce_t dce; 80911042SErik.Nordmark@Sun.COM 81011042SErik.Nordmark@Sun.COM if (mdb_vread(&dce, sizeof (dce), wsp->walk_addr) == -1) { 81111042SErik.Nordmark@Sun.COM mdb_warn("can't read dce at %p", wsp->walk_addr); 81211042SErik.Nordmark@Sun.COM return (WALK_ERR); 81311042SErik.Nordmark@Sun.COM } 81411042SErik.Nordmark@Sun.COM 81511042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip DCEs that don't belong to it. */ 81611042SErik.Nordmark@Sun.COM if ((wsp->walk_data != NULL) && (wsp->walk_data != dce.dce_ipst)) 81711042SErik.Nordmark@Sun.COM return (WALK_NEXT); 81811042SErik.Nordmark@Sun.COM 81911042SErik.Nordmark@Sun.COM return (wsp->walk_callback(wsp->walk_addr, &dce, wsp->walk_cbdata)); 82011042SErik.Nordmark@Sun.COM } 82111042SErik.Nordmark@Sun.COM 82211042SErik.Nordmark@Sun.COM int 8230Sstevel@tonic-gate ire_walk_init(mdb_walk_state_t *wsp) 8240Sstevel@tonic-gate { 82511042SErik.Nordmark@Sun.COM wsp->walk_data = (void *)wsp->walk_addr; 82611042SErik.Nordmark@Sun.COM 8270Sstevel@tonic-gate if (mdb_layered_walk("ire_cache", wsp) == -1) { 8280Sstevel@tonic-gate mdb_warn("can't walk 'ire_cache'"); 8290Sstevel@tonic-gate return (WALK_ERR); 8300Sstevel@tonic-gate } 8310Sstevel@tonic-gate 8320Sstevel@tonic-gate return (WALK_NEXT); 8330Sstevel@tonic-gate } 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate int 8360Sstevel@tonic-gate ire_walk_step(mdb_walk_state_t *wsp) 8370Sstevel@tonic-gate { 8380Sstevel@tonic-gate ire_t ire; 8390Sstevel@tonic-gate 8400Sstevel@tonic-gate if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) { 8410Sstevel@tonic-gate mdb_warn("can't read ire at %p", wsp->walk_addr); 8420Sstevel@tonic-gate return (WALK_ERR); 8430Sstevel@tonic-gate } 8440Sstevel@tonic-gate 84511042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip IREs that don't belong to it. */ 84611042SErik.Nordmark@Sun.COM if ((wsp->walk_data != NULL) && (wsp->walk_data != ire.ire_ipst)) 84711042SErik.Nordmark@Sun.COM return (WALK_NEXT); 84811042SErik.Nordmark@Sun.COM 8490Sstevel@tonic-gate return (wsp->walk_callback(wsp->walk_addr, &ire, wsp->walk_cbdata)); 8500Sstevel@tonic-gate } 8510Sstevel@tonic-gate 8523448Sdh155122 /* ARGSUSED */ 8533448Sdh155122 int 8543448Sdh155122 ire_next_walk_init(mdb_walk_state_t *wsp) 8553448Sdh155122 { 8563448Sdh155122 return (WALK_NEXT); 8573448Sdh155122 } 8583448Sdh155122 8593448Sdh155122 int 8603448Sdh155122 ire_next_walk_step(mdb_walk_state_t *wsp) 8613448Sdh155122 { 8623448Sdh155122 ire_t ire; 8633448Sdh155122 int status; 8643448Sdh155122 8653448Sdh155122 8663448Sdh155122 if (wsp->walk_addr == NULL) 8673448Sdh155122 return (WALK_DONE); 8683448Sdh155122 8693448Sdh155122 if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) { 8703448Sdh155122 mdb_warn("can't read ire at %p", wsp->walk_addr); 8713448Sdh155122 return (WALK_ERR); 8723448Sdh155122 } 8733448Sdh155122 status = wsp->walk_callback(wsp->walk_addr, &ire, 8743448Sdh155122 wsp->walk_cbdata); 8753448Sdh155122 8763448Sdh155122 if (status != WALK_NEXT) 8773448Sdh155122 return (status); 8783448Sdh155122 8793448Sdh155122 wsp->walk_addr = (uintptr_t)ire.ire_next; 8803448Sdh155122 return (status); 8813448Sdh155122 } 8823448Sdh155122 8830Sstevel@tonic-gate static int 8845940Ssowmini ire_format(uintptr_t addr, const void *ire_arg, void *ire_cb_arg) 8850Sstevel@tonic-gate { 8865940Ssowmini const ire_t *irep = ire_arg; 8875940Ssowmini ire_cbdata_t *ire_cb = ire_cb_arg; 8885940Ssowmini boolean_t verbose = ire_cb->verbose; 88911042SErik.Nordmark@Sun.COM ill_t ill; 89011042SErik.Nordmark@Sun.COM char ill_name[LIFNAMSIZ]; 89111042SErik.Nordmark@Sun.COM boolean_t condemned = irep->ire_generation == IRE_GENERATION_CONDEMNED; 8925940Ssowmini 8930Sstevel@tonic-gate static const mdb_bitmask_t tmasks[] = { 8940Sstevel@tonic-gate { "BROADCAST", IRE_BROADCAST, IRE_BROADCAST }, 8950Sstevel@tonic-gate { "DEFAULT", IRE_DEFAULT, IRE_DEFAULT }, 8960Sstevel@tonic-gate { "LOCAL", IRE_LOCAL, IRE_LOCAL }, 8970Sstevel@tonic-gate { "LOOPBACK", IRE_LOOPBACK, IRE_LOOPBACK }, 8980Sstevel@tonic-gate { "PREFIX", IRE_PREFIX, IRE_PREFIX }, 89911042SErik.Nordmark@Sun.COM { "MULTICAST", IRE_MULTICAST, IRE_MULTICAST }, 90011042SErik.Nordmark@Sun.COM { "NOROUTE", IRE_NOROUTE, IRE_NOROUTE }, 9010Sstevel@tonic-gate { "IF_NORESOLVER", IRE_IF_NORESOLVER, IRE_IF_NORESOLVER }, 9020Sstevel@tonic-gate { "IF_RESOLVER", IRE_IF_RESOLVER, IRE_IF_RESOLVER }, 90311042SErik.Nordmark@Sun.COM { "IF_CLONE", IRE_IF_CLONE, IRE_IF_CLONE }, 9040Sstevel@tonic-gate { "HOST", IRE_HOST, IRE_HOST }, 9050Sstevel@tonic-gate { NULL, 0, 0 } 9060Sstevel@tonic-gate }; 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate static const mdb_bitmask_t fmasks[] = { 9090Sstevel@tonic-gate { "UP", RTF_UP, RTF_UP }, 9100Sstevel@tonic-gate { "GATEWAY", RTF_GATEWAY, RTF_GATEWAY }, 9110Sstevel@tonic-gate { "HOST", RTF_HOST, RTF_HOST }, 9120Sstevel@tonic-gate { "REJECT", RTF_REJECT, RTF_REJECT }, 9130Sstevel@tonic-gate { "DYNAMIC", RTF_DYNAMIC, RTF_DYNAMIC }, 9140Sstevel@tonic-gate { "MODIFIED", RTF_MODIFIED, RTF_MODIFIED }, 9150Sstevel@tonic-gate { "DONE", RTF_DONE, RTF_DONE }, 9160Sstevel@tonic-gate { "MASK", RTF_MASK, RTF_MASK }, 9170Sstevel@tonic-gate { "CLONING", RTF_CLONING, RTF_CLONING }, 9180Sstevel@tonic-gate { "XRESOLVE", RTF_XRESOLVE, RTF_XRESOLVE }, 9190Sstevel@tonic-gate { "LLINFO", RTF_LLINFO, RTF_LLINFO }, 9200Sstevel@tonic-gate { "STATIC", RTF_STATIC, RTF_STATIC }, 9210Sstevel@tonic-gate { "BLACKHOLE", RTF_BLACKHOLE, RTF_BLACKHOLE }, 9220Sstevel@tonic-gate { "PRIVATE", RTF_PRIVATE, RTF_PRIVATE }, 9230Sstevel@tonic-gate { "PROTO2", RTF_PROTO2, RTF_PROTO2 }, 9240Sstevel@tonic-gate { "PROTO1", RTF_PROTO1, RTF_PROTO1 }, 9250Sstevel@tonic-gate { "MULTIRT", RTF_MULTIRT, RTF_MULTIRT }, 9260Sstevel@tonic-gate { "SETSRC", RTF_SETSRC, RTF_SETSRC }, 92711042SErik.Nordmark@Sun.COM { "INDIRECT", RTF_INDIRECT, RTF_INDIRECT }, 9280Sstevel@tonic-gate { NULL, 0, 0 } 9290Sstevel@tonic-gate }; 9300Sstevel@tonic-gate 9315940Ssowmini if (ire_cb->ire_ipversion != 0 && 9325940Ssowmini irep->ire_ipversion != ire_cb->ire_ipversion) 9335940Ssowmini return (WALK_NEXT); 9345940Ssowmini 93511042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)irep->ire_ill) == -1) { 93611042SErik.Nordmark@Sun.COM mdb_snprintf(ill_name, sizeof (ill_name), "--"); 93711042SErik.Nordmark@Sun.COM } else { 93811042SErik.Nordmark@Sun.COM (void) mdb_readstr(ill_name, 93911042SErik.Nordmark@Sun.COM MIN(LIFNAMSIZ, ill.ill_name_length), 94011042SErik.Nordmark@Sun.COM (uintptr_t)ill.ill_name); 94111042SErik.Nordmark@Sun.COM } 94211042SErik.Nordmark@Sun.COM 9435940Ssowmini if (irep->ire_ipversion == IPV6_VERSION && verbose) { 9440Sstevel@tonic-gate 94511042SErik.Nordmark@Sun.COM mdb_printf("%<b>%?p%</b>%3s %40N <%hb%s>\n" 94611042SErik.Nordmark@Sun.COM "%?s %40N\n" 94711042SErik.Nordmark@Sun.COM "%?s %40d %4d <%hb> %s\n", 94811042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6, 94911042SErik.Nordmark@Sun.COM irep->ire_type, tmasks, 95011042SErik.Nordmark@Sun.COM (irep->ire_testhidden ? ", HIDDEN" : ""), 95111042SErik.Nordmark@Sun.COM "", &irep->ire_addr_v6, 9523448Sdh155122 "", ips_to_stackid((uintptr_t)irep->ire_ipst), 9533448Sdh155122 irep->ire_zoneid, 95411042SErik.Nordmark@Sun.COM irep->ire_flags, fmasks, ill_name); 9550Sstevel@tonic-gate 9565940Ssowmini } else if (irep->ire_ipversion == IPV6_VERSION) { 9570Sstevel@tonic-gate 95811042SErik.Nordmark@Sun.COM mdb_printf("%?p%3s %30N %30N %5d %4d %s\n", 95911042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6, 9603448Sdh155122 &irep->ire_addr_v6, 9613448Sdh155122 ips_to_stackid((uintptr_t)irep->ire_ipst), 96211042SErik.Nordmark@Sun.COM irep->ire_zoneid, ill_name); 9630Sstevel@tonic-gate 9645940Ssowmini } else if (verbose) { 9650Sstevel@tonic-gate 96611042SErik.Nordmark@Sun.COM mdb_printf("%<b>%?p%</b>%3s %40I <%hb%s>\n" 96711042SErik.Nordmark@Sun.COM "%?s %40I\n" 96811042SErik.Nordmark@Sun.COM "%?s %40d %4d <%hb> %s\n", 96911042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", irep->ire_setsrc_addr, 97011042SErik.Nordmark@Sun.COM irep->ire_type, tmasks, 97111042SErik.Nordmark@Sun.COM (irep->ire_testhidden ? ", HIDDEN" : ""), 97211042SErik.Nordmark@Sun.COM "", irep->ire_addr, 9733448Sdh155122 "", ips_to_stackid((uintptr_t)irep->ire_ipst), 97411042SErik.Nordmark@Sun.COM irep->ire_zoneid, irep->ire_flags, fmasks, ill_name); 9750Sstevel@tonic-gate 9760Sstevel@tonic-gate } else { 9770Sstevel@tonic-gate 97811042SErik.Nordmark@Sun.COM mdb_printf("%?p%3s %30I %30I %5d %4d %s\n", addr, 97911042SErik.Nordmark@Sun.COM condemned ? "(C)" : "", irep->ire_setsrc_addr, 9803448Sdh155122 irep->ire_addr, ips_to_stackid((uintptr_t)irep->ire_ipst), 98111042SErik.Nordmark@Sun.COM irep->ire_zoneid, ill_name); 9820Sstevel@tonic-gate } 9830Sstevel@tonic-gate 9840Sstevel@tonic-gate return (WALK_NEXT); 9850Sstevel@tonic-gate } 9860Sstevel@tonic-gate 9870Sstevel@tonic-gate /* 9880Sstevel@tonic-gate * There are faster ways to do this. Given the interactive nature of this 9890Sstevel@tonic-gate * use I don't think its worth much effort. 9900Sstevel@tonic-gate */ 9910Sstevel@tonic-gate static unsigned short 9920Sstevel@tonic-gate ipcksum(void *p, int len) 9930Sstevel@tonic-gate { 9940Sstevel@tonic-gate int32_t sum = 0; 9950Sstevel@tonic-gate 9960Sstevel@tonic-gate while (len > 1) { 9970Sstevel@tonic-gate /* alignment */ 9980Sstevel@tonic-gate sum += *(uint16_t *)p; 9990Sstevel@tonic-gate p = (char *)p + sizeof (uint16_t); 10000Sstevel@tonic-gate if (sum & 0x80000000) 10010Sstevel@tonic-gate sum = (sum & 0xFFFF) + (sum >> 16); 10020Sstevel@tonic-gate len -= 2; 10030Sstevel@tonic-gate } 10040Sstevel@tonic-gate 10050Sstevel@tonic-gate if (len) 10060Sstevel@tonic-gate sum += (uint16_t)*(unsigned char *)p; 10070Sstevel@tonic-gate 10080Sstevel@tonic-gate while (sum >> 16) 10090Sstevel@tonic-gate sum = (sum & 0xFFFF) + (sum >> 16); 10100Sstevel@tonic-gate 10110Sstevel@tonic-gate return (~sum); 10120Sstevel@tonic-gate } 10130Sstevel@tonic-gate 10140Sstevel@tonic-gate static const mdb_bitmask_t tcp_flags[] = { 10150Sstevel@tonic-gate { "SYN", TH_SYN, TH_SYN }, 10160Sstevel@tonic-gate { "ACK", TH_ACK, TH_ACK }, 10170Sstevel@tonic-gate { "FIN", TH_FIN, TH_FIN }, 10180Sstevel@tonic-gate { "RST", TH_RST, TH_RST }, 10190Sstevel@tonic-gate { "PSH", TH_PUSH, TH_PUSH }, 10200Sstevel@tonic-gate { "ECE", TH_ECE, TH_ECE }, 10210Sstevel@tonic-gate { "CWR", TH_CWR, TH_CWR }, 10220Sstevel@tonic-gate { NULL, 0, 0 } 10230Sstevel@tonic-gate }; 10240Sstevel@tonic-gate 10250Sstevel@tonic-gate static void 10260Sstevel@tonic-gate tcphdr_print(struct tcphdr *tcph) 10270Sstevel@tonic-gate { 10280Sstevel@tonic-gate in_port_t sport, dport; 10290Sstevel@tonic-gate tcp_seq seq, ack; 10300Sstevel@tonic-gate uint16_t win, urp; 10310Sstevel@tonic-gate 10320Sstevel@tonic-gate mdb_printf("%<b>TCP header%</b>\n"); 10330Sstevel@tonic-gate 10340Sstevel@tonic-gate mdb_nhconvert(&sport, &tcph->th_sport, sizeof (sport)); 10350Sstevel@tonic-gate mdb_nhconvert(&dport, &tcph->th_dport, sizeof (dport)); 10360Sstevel@tonic-gate mdb_nhconvert(&seq, &tcph->th_seq, sizeof (seq)); 10370Sstevel@tonic-gate mdb_nhconvert(&ack, &tcph->th_ack, sizeof (ack)); 10380Sstevel@tonic-gate mdb_nhconvert(&win, &tcph->th_win, sizeof (win)); 10390Sstevel@tonic-gate mdb_nhconvert(&urp, &tcph->th_urp, sizeof (urp)); 10400Sstevel@tonic-gate 10410Sstevel@tonic-gate mdb_printf("%<u>%6s %6s %10s %10s %4s %5s %5s %5s %-15s%</u>\n", 10420Sstevel@tonic-gate "SPORT", "DPORT", "SEQ", "ACK", "HLEN", "WIN", "CSUM", "URP", 10430Sstevel@tonic-gate "FLAGS"); 10440Sstevel@tonic-gate mdb_printf("%6hu %6hu %10u %10u %4d %5hu %5hu %5hu <%b>\n", 10450Sstevel@tonic-gate sport, dport, seq, ack, tcph->th_off << 2, win, 10460Sstevel@tonic-gate tcph->th_sum, urp, tcph->th_flags, tcp_flags); 10470Sstevel@tonic-gate mdb_printf("0x%04x 0x%04x 0x%08x 0x%08x\n\n", 10480Sstevel@tonic-gate sport, dport, seq, ack); 10490Sstevel@tonic-gate } 10500Sstevel@tonic-gate 10510Sstevel@tonic-gate /* ARGSUSED */ 10520Sstevel@tonic-gate static int 10530Sstevel@tonic-gate tcphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 10540Sstevel@tonic-gate { 10550Sstevel@tonic-gate struct tcphdr tcph; 10560Sstevel@tonic-gate 10570Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 10580Sstevel@tonic-gate return (DCMD_USAGE); 10590Sstevel@tonic-gate 10600Sstevel@tonic-gate if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) { 10610Sstevel@tonic-gate mdb_warn("failed to read TCP header at %p", addr); 10620Sstevel@tonic-gate return (DCMD_ERR); 10630Sstevel@tonic-gate } 10640Sstevel@tonic-gate tcphdr_print(&tcph); 10650Sstevel@tonic-gate return (DCMD_OK); 10660Sstevel@tonic-gate } 10670Sstevel@tonic-gate 10680Sstevel@tonic-gate static void 10690Sstevel@tonic-gate udphdr_print(struct udphdr *udph) 10700Sstevel@tonic-gate { 10710Sstevel@tonic-gate in_port_t sport, dport; 10720Sstevel@tonic-gate uint16_t hlen; 10730Sstevel@tonic-gate 10740Sstevel@tonic-gate mdb_printf("%<b>UDP header%</b>\n"); 10750Sstevel@tonic-gate 10760Sstevel@tonic-gate mdb_nhconvert(&sport, &udph->uh_sport, sizeof (sport)); 10770Sstevel@tonic-gate mdb_nhconvert(&dport, &udph->uh_dport, sizeof (dport)); 10780Sstevel@tonic-gate mdb_nhconvert(&hlen, &udph->uh_ulen, sizeof (hlen)); 10790Sstevel@tonic-gate 10800Sstevel@tonic-gate mdb_printf("%<u>%14s %14s %5s %6s%</u>\n", 10810Sstevel@tonic-gate "SPORT", "DPORT", "LEN", "CSUM"); 10820Sstevel@tonic-gate mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %5hu 0x%04hx\n\n", sport, sport, 10830Sstevel@tonic-gate dport, dport, hlen, udph->uh_sum); 10840Sstevel@tonic-gate } 10850Sstevel@tonic-gate 10860Sstevel@tonic-gate /* ARGSUSED */ 10870Sstevel@tonic-gate static int 10880Sstevel@tonic-gate udphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 10890Sstevel@tonic-gate { 10900Sstevel@tonic-gate struct udphdr udph; 10910Sstevel@tonic-gate 10920Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 10930Sstevel@tonic-gate return (DCMD_USAGE); 10940Sstevel@tonic-gate 10950Sstevel@tonic-gate if (mdb_vread(&udph, sizeof (udph), addr) == -1) { 10960Sstevel@tonic-gate mdb_warn("failed to read UDP header at %p", addr); 10970Sstevel@tonic-gate return (DCMD_ERR); 10980Sstevel@tonic-gate } 10990Sstevel@tonic-gate udphdr_print(&udph); 11000Sstevel@tonic-gate return (DCMD_OK); 11010Sstevel@tonic-gate } 11020Sstevel@tonic-gate 11030Sstevel@tonic-gate static void 11040Sstevel@tonic-gate sctphdr_print(sctp_hdr_t *sctph) 11050Sstevel@tonic-gate { 11060Sstevel@tonic-gate in_port_t sport, dport; 11070Sstevel@tonic-gate 11080Sstevel@tonic-gate mdb_printf("%<b>SCTP header%</b>\n"); 11090Sstevel@tonic-gate mdb_nhconvert(&sport, &sctph->sh_sport, sizeof (sport)); 11100Sstevel@tonic-gate mdb_nhconvert(&dport, &sctph->sh_dport, sizeof (dport)); 11110Sstevel@tonic-gate 11120Sstevel@tonic-gate mdb_printf("%<u>%14s %14s %10s %10s%</u>\n", 11130Sstevel@tonic-gate "SPORT", "DPORT", "VTAG", "CHKSUM"); 11140Sstevel@tonic-gate mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %10u 0x%08x\n\n", sport, sport, 11150Sstevel@tonic-gate dport, dport, sctph->sh_verf, sctph->sh_chksum); 11160Sstevel@tonic-gate } 11170Sstevel@tonic-gate 11180Sstevel@tonic-gate /* ARGSUSED */ 11190Sstevel@tonic-gate static int 11200Sstevel@tonic-gate sctphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 11210Sstevel@tonic-gate { 11220Sstevel@tonic-gate sctp_hdr_t sctph; 11230Sstevel@tonic-gate 11240Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 11250Sstevel@tonic-gate return (DCMD_USAGE); 11260Sstevel@tonic-gate 11270Sstevel@tonic-gate if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) { 11280Sstevel@tonic-gate mdb_warn("failed to read SCTP header at %p", addr); 11290Sstevel@tonic-gate return (DCMD_ERR); 11300Sstevel@tonic-gate } 11310Sstevel@tonic-gate 11320Sstevel@tonic-gate sctphdr_print(&sctph); 11330Sstevel@tonic-gate return (DCMD_OK); 11340Sstevel@tonic-gate } 11350Sstevel@tonic-gate 11360Sstevel@tonic-gate static int 11370Sstevel@tonic-gate transport_hdr(int proto, uintptr_t addr) 11380Sstevel@tonic-gate { 11390Sstevel@tonic-gate mdb_printf("\n"); 11400Sstevel@tonic-gate switch (proto) { 11410Sstevel@tonic-gate case IPPROTO_TCP: { 11420Sstevel@tonic-gate struct tcphdr tcph; 11430Sstevel@tonic-gate 11440Sstevel@tonic-gate if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) { 11450Sstevel@tonic-gate mdb_warn("failed to read TCP header at %p", addr); 11460Sstevel@tonic-gate return (DCMD_ERR); 11470Sstevel@tonic-gate } 11480Sstevel@tonic-gate tcphdr_print(&tcph); 11490Sstevel@tonic-gate break; 11500Sstevel@tonic-gate } 11510Sstevel@tonic-gate case IPPROTO_UDP: { 11520Sstevel@tonic-gate struct udphdr udph; 11530Sstevel@tonic-gate 11540Sstevel@tonic-gate if (mdb_vread(&udph, sizeof (udph), addr) == -1) { 11550Sstevel@tonic-gate mdb_warn("failed to read UDP header at %p", addr); 11560Sstevel@tonic-gate return (DCMD_ERR); 11570Sstevel@tonic-gate } 11580Sstevel@tonic-gate udphdr_print(&udph); 11590Sstevel@tonic-gate break; 11600Sstevel@tonic-gate } 11610Sstevel@tonic-gate case IPPROTO_SCTP: { 11620Sstevel@tonic-gate sctp_hdr_t sctph; 11630Sstevel@tonic-gate 11640Sstevel@tonic-gate if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) { 11650Sstevel@tonic-gate mdb_warn("failed to read SCTP header at %p", addr); 11660Sstevel@tonic-gate return (DCMD_ERR); 11670Sstevel@tonic-gate } 11680Sstevel@tonic-gate sctphdr_print(&sctph); 11690Sstevel@tonic-gate break; 11700Sstevel@tonic-gate } 11710Sstevel@tonic-gate default: 11720Sstevel@tonic-gate break; 11730Sstevel@tonic-gate } 11740Sstevel@tonic-gate 11750Sstevel@tonic-gate return (DCMD_OK); 11760Sstevel@tonic-gate } 11770Sstevel@tonic-gate 11780Sstevel@tonic-gate static const mdb_bitmask_t ip_flags[] = { 11790Sstevel@tonic-gate { "DF", IPH_DF, IPH_DF }, 11800Sstevel@tonic-gate { "MF", IPH_MF, IPH_MF }, 11810Sstevel@tonic-gate { NULL, 0, 0 } 11820Sstevel@tonic-gate }; 11830Sstevel@tonic-gate 11840Sstevel@tonic-gate /* ARGSUSED */ 11850Sstevel@tonic-gate static int 11860Sstevel@tonic-gate iphdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 11870Sstevel@tonic-gate { 11880Sstevel@tonic-gate uint_t verbose = FALSE, force = FALSE; 11890Sstevel@tonic-gate ipha_t iph[1]; 11900Sstevel@tonic-gate uint16_t ver, totlen, hdrlen, ipid, off, csum; 11910Sstevel@tonic-gate uintptr_t nxt_proto; 11920Sstevel@tonic-gate char exp_csum[8]; 11930Sstevel@tonic-gate 11940Sstevel@tonic-gate if (mdb_getopts(argc, argv, 11950Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 11960Sstevel@tonic-gate 'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc) 11970Sstevel@tonic-gate return (DCMD_USAGE); 11980Sstevel@tonic-gate 11990Sstevel@tonic-gate if (mdb_vread(iph, sizeof (*iph), addr) == -1) { 12000Sstevel@tonic-gate mdb_warn("failed to read IPv4 header at %p", addr); 12010Sstevel@tonic-gate return (DCMD_ERR); 12020Sstevel@tonic-gate } 12030Sstevel@tonic-gate 12040Sstevel@tonic-gate ver = (iph->ipha_version_and_hdr_length & 0xf0) >> 4; 12050Sstevel@tonic-gate if (ver != IPV4_VERSION) { 12060Sstevel@tonic-gate if (ver == IPV6_VERSION) { 12070Sstevel@tonic-gate return (ip6hdr(addr, flags, argc, argv)); 12080Sstevel@tonic-gate } else if (!force) { 12090Sstevel@tonic-gate mdb_warn("unknown IP version: %d\n", ver); 12100Sstevel@tonic-gate return (DCMD_ERR); 12110Sstevel@tonic-gate } 12120Sstevel@tonic-gate } 12130Sstevel@tonic-gate 12140Sstevel@tonic-gate mdb_printf("%<b>IPv4 header%</b>\n"); 12150Sstevel@tonic-gate mdb_printf("%-34s %-34s\n" 12160Sstevel@tonic-gate "%<u>%-4s %-4s %-5s %-5s %-6s %-5s %-5s %-6s %-8s %-6s%</u>\n", 12170Sstevel@tonic-gate "SRC", "DST", 12180Sstevel@tonic-gate "HLEN", "TOS", "LEN", "ID", "OFFSET", "TTL", "PROTO", "CHKSUM", 12190Sstevel@tonic-gate "EXP-CSUM", "FLGS"); 12200Sstevel@tonic-gate 12210Sstevel@tonic-gate hdrlen = (iph->ipha_version_and_hdr_length & 0x0f) << 2; 12220Sstevel@tonic-gate mdb_nhconvert(&totlen, &iph->ipha_length, sizeof (totlen)); 12230Sstevel@tonic-gate mdb_nhconvert(&ipid, &iph->ipha_ident, sizeof (ipid)); 12240Sstevel@tonic-gate mdb_nhconvert(&off, &iph->ipha_fragment_offset_and_flags, sizeof (off)); 12250Sstevel@tonic-gate if (hdrlen == IP_SIMPLE_HDR_LENGTH) { 12260Sstevel@tonic-gate if ((csum = ipcksum(iph, sizeof (*iph))) != 0) 12270Sstevel@tonic-gate csum = ~(~csum + ~iph->ipha_hdr_checksum); 12280Sstevel@tonic-gate else 12290Sstevel@tonic-gate csum = iph->ipha_hdr_checksum; 12300Sstevel@tonic-gate mdb_snprintf(exp_csum, 8, "%u", csum); 12310Sstevel@tonic-gate } else { 12320Sstevel@tonic-gate mdb_snprintf(exp_csum, 8, "<n/a>"); 12330Sstevel@tonic-gate } 12340Sstevel@tonic-gate 12350Sstevel@tonic-gate mdb_printf("%-34I %-34I%\n" 12360Sstevel@tonic-gate "%-4d %-4d %-5hu %-5hu %-6hu %-5hu %-5hu %-6u %-8s <%5hb>\n", 12370Sstevel@tonic-gate iph->ipha_src, iph->ipha_dst, 12380Sstevel@tonic-gate hdrlen, iph->ipha_type_of_service, totlen, ipid, 12390Sstevel@tonic-gate (off << 3) & 0xffff, iph->ipha_ttl, iph->ipha_protocol, 12400Sstevel@tonic-gate iph->ipha_hdr_checksum, exp_csum, off, ip_flags); 12410Sstevel@tonic-gate 12420Sstevel@tonic-gate if (verbose) { 12430Sstevel@tonic-gate nxt_proto = addr + hdrlen; 12440Sstevel@tonic-gate return (transport_hdr(iph->ipha_protocol, nxt_proto)); 12450Sstevel@tonic-gate } else { 12460Sstevel@tonic-gate return (DCMD_OK); 12470Sstevel@tonic-gate } 12480Sstevel@tonic-gate } 12490Sstevel@tonic-gate 12500Sstevel@tonic-gate /* ARGSUSED */ 12510Sstevel@tonic-gate static int 12520Sstevel@tonic-gate ip6hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 12530Sstevel@tonic-gate { 12540Sstevel@tonic-gate uint_t verbose = FALSE, force = FALSE; 12550Sstevel@tonic-gate ip6_t iph[1]; 12560Sstevel@tonic-gate int ver, class, flow; 12570Sstevel@tonic-gate uint16_t plen; 12580Sstevel@tonic-gate uintptr_t nxt_proto; 12590Sstevel@tonic-gate 12600Sstevel@tonic-gate if (mdb_getopts(argc, argv, 12610Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 12620Sstevel@tonic-gate 'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc) 12630Sstevel@tonic-gate return (DCMD_USAGE); 12640Sstevel@tonic-gate 12650Sstevel@tonic-gate if (mdb_vread(iph, sizeof (*iph), addr) == -1) { 12660Sstevel@tonic-gate mdb_warn("failed to read IPv6 header at %p", addr); 12670Sstevel@tonic-gate return (DCMD_ERR); 12680Sstevel@tonic-gate } 12690Sstevel@tonic-gate 12700Sstevel@tonic-gate ver = (iph->ip6_vfc & 0xf0) >> 4; 12710Sstevel@tonic-gate if (ver != IPV6_VERSION) { 12720Sstevel@tonic-gate if (ver == IPV4_VERSION) { 12730Sstevel@tonic-gate return (iphdr(addr, flags, argc, argv)); 12740Sstevel@tonic-gate } else if (!force) { 12750Sstevel@tonic-gate mdb_warn("unknown IP version: %d\n", ver); 12760Sstevel@tonic-gate return (DCMD_ERR); 12770Sstevel@tonic-gate } 12780Sstevel@tonic-gate } 12790Sstevel@tonic-gate 12800Sstevel@tonic-gate mdb_printf("%<b>IPv6 header%</b>\n"); 12810Sstevel@tonic-gate mdb_printf("%<u>%-26s %-26s %4s %7s %5s %3s %3s%</u>\n", 12820Sstevel@tonic-gate "SRC", "DST", "TCLS", "FLOW-ID", "PLEN", "NXT", "HOP"); 12830Sstevel@tonic-gate 12840Sstevel@tonic-gate class = (iph->ip6_vcf & IPV6_FLOWINFO_TCLASS) >> 20; 12850Sstevel@tonic-gate mdb_nhconvert(&class, &class, sizeof (class)); 12860Sstevel@tonic-gate flow = iph->ip6_vcf & IPV6_FLOWINFO_FLOWLABEL; 12870Sstevel@tonic-gate mdb_nhconvert(&flow, &flow, sizeof (flow)); 12880Sstevel@tonic-gate mdb_nhconvert(&plen, &iph->ip6_plen, sizeof (plen)); 12890Sstevel@tonic-gate 12900Sstevel@tonic-gate mdb_printf("%-26N %-26N %4d %7d %5hu %3d %3d\n", 12910Sstevel@tonic-gate &iph->ip6_src, &iph->ip6_dst, 12920Sstevel@tonic-gate class, flow, plen, iph->ip6_nxt, iph->ip6_hlim); 12930Sstevel@tonic-gate 12940Sstevel@tonic-gate if (verbose) { 12950Sstevel@tonic-gate nxt_proto = addr + sizeof (ip6_t); 12960Sstevel@tonic-gate return (transport_hdr(iph->ip6_nxt, nxt_proto)); 12970Sstevel@tonic-gate } else { 12980Sstevel@tonic-gate return (DCMD_OK); 12990Sstevel@tonic-gate } 13000Sstevel@tonic-gate } 13010Sstevel@tonic-gate 13020Sstevel@tonic-gate int 130311042SErik.Nordmark@Sun.COM nce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 130411042SErik.Nordmark@Sun.COM { 130511042SErik.Nordmark@Sun.COM nce_t nce; 130611042SErik.Nordmark@Sun.COM nce_cbdata_t nce_cb; 130711042SErik.Nordmark@Sun.COM int ipversion = 0; 130811042SErik.Nordmark@Sun.COM const char *opt_P = NULL, *opt_ill; 130911042SErik.Nordmark@Sun.COM 131011042SErik.Nordmark@Sun.COM if (mdb_getopts(argc, argv, 131111042SErik.Nordmark@Sun.COM 'i', MDB_OPT_STR, &opt_ill, 131211042SErik.Nordmark@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 131311042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 131411042SErik.Nordmark@Sun.COM 131511042SErik.Nordmark@Sun.COM if (opt_P != NULL) { 131611042SErik.Nordmark@Sun.COM if (strcmp("v4", opt_P) == 0) { 131711042SErik.Nordmark@Sun.COM ipversion = IPV4_VERSION; 131811042SErik.Nordmark@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 131911042SErik.Nordmark@Sun.COM ipversion = IPV6_VERSION; 132011042SErik.Nordmark@Sun.COM } else { 132111042SErik.Nordmark@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 132211042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 132311042SErik.Nordmark@Sun.COM } 132411042SErik.Nordmark@Sun.COM } 132511042SErik.Nordmark@Sun.COM 132611042SErik.Nordmark@Sun.COM if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 132711042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s %5s %18s %?s %s %s %</u>\n", 132811042SErik.Nordmark@Sun.COM "ADDR", "INTF", "LLADDR", "FP_MP", "REFCNT", 132911042SErik.Nordmark@Sun.COM "NCE_ADDR"); 133011042SErik.Nordmark@Sun.COM } 133111042SErik.Nordmark@Sun.COM 133211042SErik.Nordmark@Sun.COM bzero(&nce_cb, sizeof (nce_cb)); 133311042SErik.Nordmark@Sun.COM if (opt_ill != NULL) { 133411042SErik.Nordmark@Sun.COM strcpy(nce_cb.nce_ill_name, opt_ill); 133511042SErik.Nordmark@Sun.COM } 133611042SErik.Nordmark@Sun.COM nce_cb.nce_ipversion = ipversion; 133711042SErik.Nordmark@Sun.COM 133811042SErik.Nordmark@Sun.COM if (flags & DCMD_ADDRSPEC) { 133911042SErik.Nordmark@Sun.COM (void) mdb_vread(&nce, sizeof (nce_t), addr); 134011042SErik.Nordmark@Sun.COM (void) nce_format(addr, &nce, &nce_cb); 134111042SErik.Nordmark@Sun.COM } else if (mdb_walk("nce", (mdb_walk_cb_t)nce_format, &nce_cb) == -1) { 134211042SErik.Nordmark@Sun.COM mdb_warn("failed to walk ire table"); 134311042SErik.Nordmark@Sun.COM return (DCMD_ERR); 134411042SErik.Nordmark@Sun.COM } 134511042SErik.Nordmark@Sun.COM 134611042SErik.Nordmark@Sun.COM return (DCMD_OK); 134711042SErik.Nordmark@Sun.COM } 134811042SErik.Nordmark@Sun.COM 134911042SErik.Nordmark@Sun.COM /* ARGSUSED */ 135011042SErik.Nordmark@Sun.COM static int 135111042SErik.Nordmark@Sun.COM dce_format(uintptr_t addr, const dce_t *dcep, void *dce_cb_arg) 135211042SErik.Nordmark@Sun.COM { 135311042SErik.Nordmark@Sun.COM static const mdb_bitmask_t dmasks[] = { 135411042SErik.Nordmark@Sun.COM { "D", DCEF_DEFAULT, DCEF_DEFAULT }, 135511042SErik.Nordmark@Sun.COM { "P", DCEF_PMTU, DCEF_PMTU }, 135611042SErik.Nordmark@Sun.COM { "U", DCEF_UINFO, DCEF_UINFO }, 135711042SErik.Nordmark@Sun.COM { "S", DCEF_TOO_SMALL_PMTU, DCEF_TOO_SMALL_PMTU }, 135811042SErik.Nordmark@Sun.COM { NULL, 0, 0 } 135911042SErik.Nordmark@Sun.COM }; 136011042SErik.Nordmark@Sun.COM char flagsbuf[2 * A_CNT(dmasks)]; 136111042SErik.Nordmark@Sun.COM int ipversion = *(int *)dce_cb_arg; 136211042SErik.Nordmark@Sun.COM boolean_t condemned = dcep->dce_generation == DCE_GENERATION_CONDEMNED; 136311042SErik.Nordmark@Sun.COM 136411042SErik.Nordmark@Sun.COM if (ipversion != 0 && ipversion != dcep->dce_ipversion) 136511042SErik.Nordmark@Sun.COM return (WALK_NEXT); 136611042SErik.Nordmark@Sun.COM 136711042SErik.Nordmark@Sun.COM mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%b", dcep->dce_flags, 136811042SErik.Nordmark@Sun.COM dmasks); 136911042SErik.Nordmark@Sun.COM 137011042SErik.Nordmark@Sun.COM switch (dcep->dce_ipversion) { 137111042SErik.Nordmark@Sun.COM case IPV4_VERSION: 137211042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30I %</u>\n", addr, condemned ? 137311042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v4addr); 137411042SErik.Nordmark@Sun.COM break; 137511042SErik.Nordmark@Sun.COM case IPV6_VERSION: 137611042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30N %</u>\n", addr, condemned ? 137711042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v6addr); 137811042SErik.Nordmark@Sun.COM break; 137911042SErik.Nordmark@Sun.COM default: 138011042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30s %</u>\n", addr, condemned ? 138111042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, ""); 138211042SErik.Nordmark@Sun.COM } 138311042SErik.Nordmark@Sun.COM 138411042SErik.Nordmark@Sun.COM return (WALK_NEXT); 138511042SErik.Nordmark@Sun.COM } 138611042SErik.Nordmark@Sun.COM 138711042SErik.Nordmark@Sun.COM int 138811042SErik.Nordmark@Sun.COM dce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 138911042SErik.Nordmark@Sun.COM { 139011042SErik.Nordmark@Sun.COM dce_t dce; 139111042SErik.Nordmark@Sun.COM const char *opt_P = NULL; 139211042SErik.Nordmark@Sun.COM const char *zone_name = NULL; 139311042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL; 139411042SErik.Nordmark@Sun.COM int ipversion = 0; 139511042SErik.Nordmark@Sun.COM 139611042SErik.Nordmark@Sun.COM if (mdb_getopts(argc, argv, 139711042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name, 139811042SErik.Nordmark@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 139911042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 140011042SErik.Nordmark@Sun.COM 140111042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */ 140211042SErik.Nordmark@Sun.COM if (zone_name != NULL) { 140311042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name); 140411042SErik.Nordmark@Sun.COM if (ipst == NULL) 140511042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 140611042SErik.Nordmark@Sun.COM } 140711042SErik.Nordmark@Sun.COM 140811042SErik.Nordmark@Sun.COM if (opt_P != NULL) { 140911042SErik.Nordmark@Sun.COM if (strcmp("v4", opt_P) == 0) { 141011042SErik.Nordmark@Sun.COM ipversion = IPV4_VERSION; 141111042SErik.Nordmark@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 141211042SErik.Nordmark@Sun.COM ipversion = IPV6_VERSION; 141311042SErik.Nordmark@Sun.COM } else { 141411042SErik.Nordmark@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 141511042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 141611042SErik.Nordmark@Sun.COM } 141711042SErik.Nordmark@Sun.COM } 141811042SErik.Nordmark@Sun.COM 141911042SErik.Nordmark@Sun.COM if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 142011042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s%3s %8s %8s %30s %</u>\n", 142111042SErik.Nordmark@Sun.COM "ADDR", "", "FLAGS", "PMTU", "DST_ADDR"); 142211042SErik.Nordmark@Sun.COM } 142311042SErik.Nordmark@Sun.COM 142411042SErik.Nordmark@Sun.COM if (flags & DCMD_ADDRSPEC) { 142511042SErik.Nordmark@Sun.COM (void) mdb_vread(&dce, sizeof (dce_t), addr); 142611042SErik.Nordmark@Sun.COM (void) dce_format(addr, &dce, &ipversion); 142711042SErik.Nordmark@Sun.COM } else if (mdb_pwalk("dce", (mdb_walk_cb_t)dce_format, &ipversion, 142811042SErik.Nordmark@Sun.COM (uintptr_t)ipst) == -1) { 142911042SErik.Nordmark@Sun.COM mdb_warn("failed to walk dce cache"); 143011042SErik.Nordmark@Sun.COM return (DCMD_ERR); 143111042SErik.Nordmark@Sun.COM } 143211042SErik.Nordmark@Sun.COM 143311042SErik.Nordmark@Sun.COM return (DCMD_OK); 143411042SErik.Nordmark@Sun.COM } 143511042SErik.Nordmark@Sun.COM 143611042SErik.Nordmark@Sun.COM int 14370Sstevel@tonic-gate ire(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 14380Sstevel@tonic-gate { 14390Sstevel@tonic-gate uint_t verbose = FALSE; 14400Sstevel@tonic-gate ire_t ire; 14415940Ssowmini ire_cbdata_t ire_cb; 14425940Ssowmini int ipversion = 0; 14435940Ssowmini const char *opt_P = NULL; 144411042SErik.Nordmark@Sun.COM const char *zone_name = NULL; 144511042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL; 14460Sstevel@tonic-gate 14470Sstevel@tonic-gate if (mdb_getopts(argc, argv, 14485940Ssowmini 'v', MDB_OPT_SETBITS, TRUE, &verbose, 144911042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name, 14505940Ssowmini 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 14510Sstevel@tonic-gate return (DCMD_USAGE); 14520Sstevel@tonic-gate 145311042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */ 145411042SErik.Nordmark@Sun.COM if (zone_name != NULL) { 145511042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name); 145611042SErik.Nordmark@Sun.COM if (ipst == NULL) 145711042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 145811042SErik.Nordmark@Sun.COM } 145911042SErik.Nordmark@Sun.COM 14605940Ssowmini if (opt_P != NULL) { 14615940Ssowmini if (strcmp("v4", opt_P) == 0) { 14625940Ssowmini ipversion = IPV4_VERSION; 14635940Ssowmini } else if (strcmp("v6", opt_P) == 0) { 14645940Ssowmini ipversion = IPV6_VERSION; 14655940Ssowmini } else { 14665940Ssowmini mdb_warn("invalid protocol '%s'\n", opt_P); 14675940Ssowmini return (DCMD_USAGE); 14685940Ssowmini } 14695940Ssowmini } 14705940Ssowmini 14710Sstevel@tonic-gate if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 14720Sstevel@tonic-gate 14730Sstevel@tonic-gate if (verbose) { 14740Sstevel@tonic-gate mdb_printf("%?s %40s %-20s%\n" 14750Sstevel@tonic-gate "%?s %40s %-20s%\n" 147611042SErik.Nordmark@Sun.COM "%<u>%?s %40s %4s %-20s %s%</u>\n", 14770Sstevel@tonic-gate "ADDR", "SRC", "TYPE", 14780Sstevel@tonic-gate "", "DST", "MARKS", 147911042SErik.Nordmark@Sun.COM "", "STACK", "ZONE", "FLAGS", "INTF"); 14800Sstevel@tonic-gate } else { 148111042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s %30s %30s %5s %4s %s%</u>\n", 148211042SErik.Nordmark@Sun.COM "ADDR", "SRC", "DST", "STACK", "ZONE", "INTF"); 14830Sstevel@tonic-gate } 14840Sstevel@tonic-gate } 14850Sstevel@tonic-gate 14865940Ssowmini ire_cb.verbose = (verbose == TRUE); 14875940Ssowmini ire_cb.ire_ipversion = ipversion; 14885940Ssowmini 14890Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) { 14900Sstevel@tonic-gate (void) mdb_vread(&ire, sizeof (ire_t), addr); 14915940Ssowmini (void) ire_format(addr, &ire, &ire_cb); 149211042SErik.Nordmark@Sun.COM } else if (mdb_pwalk("ire", (mdb_walk_cb_t)ire_format, &ire_cb, 149311042SErik.Nordmark@Sun.COM (uintptr_t)ipst) == -1) { 14940Sstevel@tonic-gate mdb_warn("failed to walk ire table"); 14950Sstevel@tonic-gate return (DCMD_ERR); 14960Sstevel@tonic-gate } 14970Sstevel@tonic-gate 14980Sstevel@tonic-gate return (DCMD_OK); 14990Sstevel@tonic-gate } 15000Sstevel@tonic-gate 15010Sstevel@tonic-gate static size_t 15020Sstevel@tonic-gate mi_osize(const queue_t *q) 15030Sstevel@tonic-gate { 15040Sstevel@tonic-gate /* 15050Sstevel@tonic-gate * The code in common/inet/mi.c allocates an extra word to store the 15060Sstevel@tonic-gate * size of the allocation. An mi_o_s is thus a size_t plus an mi_o_s. 15070Sstevel@tonic-gate */ 15080Sstevel@tonic-gate struct mi_block { 15090Sstevel@tonic-gate size_t mi_nbytes; 15100Sstevel@tonic-gate struct mi_o_s mi_o; 15110Sstevel@tonic-gate } m; 15120Sstevel@tonic-gate 15130Sstevel@tonic-gate if (mdb_vread(&m, sizeof (m), (uintptr_t)q->q_ptr - 15140Sstevel@tonic-gate sizeof (m)) == sizeof (m)) 15150Sstevel@tonic-gate return (m.mi_nbytes - sizeof (m)); 15160Sstevel@tonic-gate 15170Sstevel@tonic-gate return (0); 15180Sstevel@tonic-gate } 15190Sstevel@tonic-gate 15200Sstevel@tonic-gate static void 15210Sstevel@tonic-gate ip_ill_qinfo(const queue_t *q, char *buf, size_t nbytes) 15220Sstevel@tonic-gate { 15230Sstevel@tonic-gate char name[32]; 15240Sstevel@tonic-gate ill_t ill; 15250Sstevel@tonic-gate 15260Sstevel@tonic-gate if (mdb_vread(&ill, sizeof (ill), 15270Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill) && 15280Sstevel@tonic-gate mdb_readstr(name, sizeof (name), (uintptr_t)ill.ill_name) > 0) 15290Sstevel@tonic-gate (void) mdb_snprintf(buf, nbytes, "if: %s", name); 15300Sstevel@tonic-gate } 15310Sstevel@tonic-gate 15320Sstevel@tonic-gate void 15330Sstevel@tonic-gate ip_qinfo(const queue_t *q, char *buf, size_t nbytes) 15340Sstevel@tonic-gate { 15350Sstevel@tonic-gate size_t size = mi_osize(q); 15360Sstevel@tonic-gate 15370Sstevel@tonic-gate if (size == sizeof (ill_t)) 15380Sstevel@tonic-gate ip_ill_qinfo(q, buf, nbytes); 15390Sstevel@tonic-gate } 15400Sstevel@tonic-gate 15410Sstevel@tonic-gate uintptr_t 15420Sstevel@tonic-gate ip_rnext(const queue_t *q) 15430Sstevel@tonic-gate { 15440Sstevel@tonic-gate size_t size = mi_osize(q); 15450Sstevel@tonic-gate ill_t ill; 15460Sstevel@tonic-gate 15470Sstevel@tonic-gate if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill), 15480Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill)) 15490Sstevel@tonic-gate return ((uintptr_t)ill.ill_rq); 15500Sstevel@tonic-gate 15510Sstevel@tonic-gate return (NULL); 15520Sstevel@tonic-gate } 15530Sstevel@tonic-gate 15540Sstevel@tonic-gate uintptr_t 15550Sstevel@tonic-gate ip_wnext(const queue_t *q) 15560Sstevel@tonic-gate { 15570Sstevel@tonic-gate size_t size = mi_osize(q); 15580Sstevel@tonic-gate ill_t ill; 15590Sstevel@tonic-gate 15600Sstevel@tonic-gate if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill), 15610Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill)) 15620Sstevel@tonic-gate return ((uintptr_t)ill.ill_wq); 15630Sstevel@tonic-gate 15640Sstevel@tonic-gate return (NULL); 15650Sstevel@tonic-gate } 15660Sstevel@tonic-gate 15670Sstevel@tonic-gate /* 15680Sstevel@tonic-gate * Print the core fields in an squeue_t. With the "-v" argument, 15690Sstevel@tonic-gate * provide more verbose output. 15700Sstevel@tonic-gate */ 15710Sstevel@tonic-gate static int 15720Sstevel@tonic-gate squeue(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 15730Sstevel@tonic-gate { 15740Sstevel@tonic-gate unsigned int i; 15750Sstevel@tonic-gate unsigned int verbose = FALSE; 15760Sstevel@tonic-gate const int SQUEUE_STATEDELT = (int)(sizeof (uintptr_t) + 9); 15770Sstevel@tonic-gate boolean_t arm; 15780Sstevel@tonic-gate squeue_t squeue; 15790Sstevel@tonic-gate 15800Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 15810Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`squeue_cache", "ip`squeue", 15820Sstevel@tonic-gate argc, argv) == -1) { 15830Sstevel@tonic-gate mdb_warn("failed to walk squeue cache"); 15840Sstevel@tonic-gate return (DCMD_ERR); 15850Sstevel@tonic-gate } 15860Sstevel@tonic-gate return (DCMD_OK); 15870Sstevel@tonic-gate } 15880Sstevel@tonic-gate 15890Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) 15900Sstevel@tonic-gate != argc) 15910Sstevel@tonic-gate return (DCMD_USAGE); 15920Sstevel@tonic-gate 15930Sstevel@tonic-gate if (!DCMD_HDRSPEC(flags) && verbose) 15940Sstevel@tonic-gate mdb_printf("\n\n"); 15950Sstevel@tonic-gate 15960Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) || verbose) { 15970Sstevel@tonic-gate mdb_printf("%?s %-5s %-3s %?s %?s %?s\n", 15980Sstevel@tonic-gate "ADDR", "STATE", "CPU", 15990Sstevel@tonic-gate "FIRST", "LAST", "WORKER"); 16000Sstevel@tonic-gate } 16010Sstevel@tonic-gate 16020Sstevel@tonic-gate if (mdb_vread(&squeue, sizeof (squeue_t), addr) == -1) { 16030Sstevel@tonic-gate mdb_warn("cannot read squeue_t at %p", addr); 16040Sstevel@tonic-gate return (DCMD_ERR); 16050Sstevel@tonic-gate } 16060Sstevel@tonic-gate 16070Sstevel@tonic-gate mdb_printf("%0?p %05x %3d %0?p %0?p %0?p\n", 16080Sstevel@tonic-gate addr, squeue.sq_state, squeue.sq_bind, 16090Sstevel@tonic-gate squeue.sq_first, squeue.sq_last, squeue.sq_worker); 16100Sstevel@tonic-gate 16110Sstevel@tonic-gate if (!verbose) 16120Sstevel@tonic-gate return (DCMD_OK); 16130Sstevel@tonic-gate 16140Sstevel@tonic-gate arm = B_TRUE; 16150Sstevel@tonic-gate for (i = 0; squeue_states[i].bit_name != NULL; i++) { 16160Sstevel@tonic-gate if (((squeue.sq_state) & (1 << i)) == 0) 16170Sstevel@tonic-gate continue; 16180Sstevel@tonic-gate 16190Sstevel@tonic-gate if (arm) { 16200Sstevel@tonic-gate mdb_printf("%*s|\n", SQUEUE_STATEDELT, ""); 16210Sstevel@tonic-gate mdb_printf("%*s+--> ", SQUEUE_STATEDELT, ""); 16220Sstevel@tonic-gate arm = B_FALSE; 16230Sstevel@tonic-gate } else 16240Sstevel@tonic-gate mdb_printf("%*s ", SQUEUE_STATEDELT, ""); 16250Sstevel@tonic-gate 16260Sstevel@tonic-gate mdb_printf("%-12s %s\n", squeue_states[i].bit_name, 16270Sstevel@tonic-gate squeue_states[i].bit_descr); 16280Sstevel@tonic-gate } 16290Sstevel@tonic-gate 16300Sstevel@tonic-gate return (DCMD_OK); 16310Sstevel@tonic-gate } 16320Sstevel@tonic-gate 16330Sstevel@tonic-gate static void 16340Sstevel@tonic-gate ip_squeue_help(void) 16350Sstevel@tonic-gate { 16360Sstevel@tonic-gate mdb_printf("Print the core information for a given NCA squeue_t.\n\n"); 16370Sstevel@tonic-gate mdb_printf("Options:\n"); 16380Sstevel@tonic-gate mdb_printf("\t-v\tbe verbose (more descriptive)\n"); 16390Sstevel@tonic-gate } 16400Sstevel@tonic-gate 16415023Scarlsonj /* 16425023Scarlsonj * This is called by ::th_trace (via a callback) when walking the th_hash 16435023Scarlsonj * list. It calls modent to find the entries. 16445023Scarlsonj */ 16455023Scarlsonj /* ARGSUSED */ 16465023Scarlsonj static int 16475023Scarlsonj modent_summary(uintptr_t addr, const void *data, void *private) 16485023Scarlsonj { 16495023Scarlsonj th_walk_data_t *thw = private; 16505023Scarlsonj const struct mod_hash_entry *mhe = data; 16515023Scarlsonj th_trace_t th; 16525023Scarlsonj 16535023Scarlsonj if (mdb_vread(&th, sizeof (th), (uintptr_t)mhe->mhe_val) == -1) { 16545023Scarlsonj mdb_warn("failed to read th_trace_t %p", mhe->mhe_val); 16555023Scarlsonj return (WALK_ERR); 16565023Scarlsonj } 16575023Scarlsonj 16585023Scarlsonj if (th.th_refcnt == 0 && thw->thw_non_zero_only) 16595023Scarlsonj return (WALK_NEXT); 16605023Scarlsonj 16615023Scarlsonj if (!thw->thw_match) { 16625023Scarlsonj mdb_printf("%?p %?p %?p %8d %?p\n", thw->thw_ipst, mhe->mhe_key, 16635023Scarlsonj mhe->mhe_val, th.th_refcnt, th.th_id); 16645023Scarlsonj } else if (thw->thw_matchkey == (uintptr_t)mhe->mhe_key) { 16655023Scarlsonj int i, j, k; 16665023Scarlsonj tr_buf_t *tr; 16675023Scarlsonj 16685023Scarlsonj mdb_printf("Object %p in IP stack %p:\n", mhe->mhe_key, 16695023Scarlsonj thw->thw_ipst); 16705023Scarlsonj i = th.th_trace_lastref; 16715023Scarlsonj mdb_printf("\tThread %p refcnt %d:\n", th.th_id, 16725023Scarlsonj th.th_refcnt); 16735023Scarlsonj for (j = TR_BUF_MAX; j > 0; j--) { 16745023Scarlsonj tr = th.th_trbuf + i; 16755023Scarlsonj if (tr->tr_depth == 0 || tr->tr_depth > TR_STACK_DEPTH) 16765023Scarlsonj break; 16775023Scarlsonj mdb_printf("\t T%+ld:\n", tr->tr_time - 16785023Scarlsonj thw->thw_lbolt); 16795023Scarlsonj for (k = 0; k < tr->tr_depth; k++) 16805023Scarlsonj mdb_printf("\t\t%a\n", tr->tr_stack[k]); 16815023Scarlsonj if (--i < 0) 16825023Scarlsonj i = TR_BUF_MAX - 1; 16835023Scarlsonj } 16845023Scarlsonj } 16855023Scarlsonj return (WALK_NEXT); 16865023Scarlsonj } 16875023Scarlsonj 16885023Scarlsonj /* 16895023Scarlsonj * This is called by ::th_trace (via a callback) when walking the th_hash 16905023Scarlsonj * list. It calls modent to find the entries. 16915023Scarlsonj */ 16925023Scarlsonj /* ARGSUSED */ 16935023Scarlsonj static int 16945023Scarlsonj th_hash_summary(uintptr_t addr, const void *data, void *private) 16955023Scarlsonj { 16965023Scarlsonj const th_hash_t *thh = data; 16975023Scarlsonj th_walk_data_t *thw = private; 16985023Scarlsonj 16995023Scarlsonj thw->thw_ipst = (uintptr_t)thh->thh_ipst; 17005023Scarlsonj return (mdb_pwalk("modent", modent_summary, private, 17015023Scarlsonj (uintptr_t)thh->thh_hash)); 17025023Scarlsonj } 17035023Scarlsonj 17045023Scarlsonj /* 17055023Scarlsonj * Print or summarize the th_trace_t structures. 17065023Scarlsonj */ 17075023Scarlsonj static int 17085023Scarlsonj th_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 17095023Scarlsonj { 17105023Scarlsonj th_walk_data_t thw; 17115023Scarlsonj 17125023Scarlsonj (void) memset(&thw, 0, sizeof (thw)); 17135023Scarlsonj 17145023Scarlsonj if (mdb_getopts(argc, argv, 17155023Scarlsonj 'n', MDB_OPT_SETBITS, TRUE, &thw.thw_non_zero_only, 17165023Scarlsonj NULL) != argc) 17175023Scarlsonj return (DCMD_USAGE); 17185023Scarlsonj 17195023Scarlsonj if (!(flags & DCMD_ADDRSPEC)) { 17205023Scarlsonj /* 17215023Scarlsonj * No address specified. Walk all of the th_hash_t in the 17225023Scarlsonj * system, and summarize the th_trace_t entries in each. 17235023Scarlsonj */ 17245023Scarlsonj mdb_printf("%?s %?s %?s %8s %?s\n", 17255023Scarlsonj "IPSTACK", "OBJECT", "TRACE", "REFCNT", "THREAD"); 17265023Scarlsonj thw.thw_match = B_FALSE; 17275023Scarlsonj } else { 17285023Scarlsonj thw.thw_match = B_TRUE; 17295023Scarlsonj thw.thw_matchkey = addr; 173011066Srafael.vanoni@sun.com 173111066Srafael.vanoni@sun.com if ((thw.thw_lbolt = (clock_t)mdb_get_lbolt()) == -1) { 17325023Scarlsonj mdb_warn("failed to read lbolt"); 17335023Scarlsonj return (DCMD_ERR); 17345023Scarlsonj } 17355023Scarlsonj } 17365023Scarlsonj if (mdb_pwalk("th_hash", th_hash_summary, &thw, NULL) == -1) { 17375023Scarlsonj mdb_warn("can't walk th_hash entries"); 17385023Scarlsonj return (DCMD_ERR); 17395023Scarlsonj } 17405023Scarlsonj return (DCMD_OK); 17415023Scarlsonj } 17425023Scarlsonj 17435023Scarlsonj static void 17445023Scarlsonj th_trace_help(void) 17455023Scarlsonj { 174611042SErik.Nordmark@Sun.COM mdb_printf("If given an address of an ill_t, ipif_t, ire_t, or ncec_t, " 17475023Scarlsonj "print the\n" 17485023Scarlsonj "corresponding th_trace_t structure in detail. Otherwise, if no " 17495023Scarlsonj "address is\n" 17505023Scarlsonj "given, then summarize all th_trace_t structures.\n\n"); 17515023Scarlsonj mdb_printf("Options:\n" 17525023Scarlsonj "\t-n\tdisplay only entries with non-zero th_refcnt\n"); 17535023Scarlsonj } 17545023Scarlsonj 17550Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = { 17569089SVasumathi.Sundaram@Sun.COM { "conn_status", ":", 17579089SVasumathi.Sundaram@Sun.COM "display connection structures from ipcl hash tables", 17589089SVasumathi.Sundaram@Sun.COM conn_status, conn_status_help }, 17599089SVasumathi.Sundaram@Sun.COM { "srcid_status", ":", 17609089SVasumathi.Sundaram@Sun.COM "display connection structures from ipcl hash tables", 17619089SVasumathi.Sundaram@Sun.COM srcid_status }, 176211042SErik.Nordmark@Sun.COM { "ill", "?[-v] [-P v4 | v6] [-s exclusive-ip-zone-name]", 176311042SErik.Nordmark@Sun.COM "display ill_t structures", ill, ill_help }, 17640Sstevel@tonic-gate { "illif", "?[-P v4 | v6]", 17650Sstevel@tonic-gate "display or filter IP Lower Level InterFace structures", illif, 17660Sstevel@tonic-gate illif_help }, 17670Sstevel@tonic-gate { "iphdr", ":[-vf]", "display an IPv4 header", iphdr }, 17680Sstevel@tonic-gate { "ip6hdr", ":[-vf]", "display an IPv6 header", ip6hdr }, 17699089SVasumathi.Sundaram@Sun.COM { "ipif", "?[-v] [-P v4 | v6]", "display ipif structures", 17709089SVasumathi.Sundaram@Sun.COM ipif, ipif_help }, 177111042SErik.Nordmark@Sun.COM { "ire", "?[-v] [-P v4|v6] [-s exclusive-ip-zone-name]", 17725940Ssowmini "display Internet Route Entry structures", ire }, 177311042SErik.Nordmark@Sun.COM { "nce", "?[-P v4|v6] [-i <interface>]", 177411042SErik.Nordmark@Sun.COM "display interface-specific Neighbor Cache structures", nce }, 177511042SErik.Nordmark@Sun.COM { "ncec", "?[-P v4 | v6]", "display Neighbor Cache Entry structures", 177611042SErik.Nordmark@Sun.COM ncec }, 177711042SErik.Nordmark@Sun.COM { "dce", "?[-P v4|v6] [-s exclusive-ip-zone-name]", 177811042SErik.Nordmark@Sun.COM "display Destination Cache Entry structures", dce }, 17790Sstevel@tonic-gate { "squeue", ":[-v]", "print core squeue_t info", squeue, 17800Sstevel@tonic-gate ip_squeue_help }, 17810Sstevel@tonic-gate { "tcphdr", ":", "display a TCP header", tcphdr }, 17820Sstevel@tonic-gate { "udphdr", ":", "display an UDP header", udphdr }, 17830Sstevel@tonic-gate { "sctphdr", ":", "display an SCTP header", sctphdr }, 17845023Scarlsonj { "th_trace", "?[-n]", "display th_trace_t structures", th_trace, 17855023Scarlsonj th_trace_help }, 17860Sstevel@tonic-gate { NULL } 17870Sstevel@tonic-gate }; 17880Sstevel@tonic-gate 17890Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 17909089SVasumathi.Sundaram@Sun.COM { "conn_status", "walk list of conn_t structures", 17919089SVasumathi.Sundaram@Sun.COM ip_stacks_common_walk_init, conn_status_walk_step, NULL }, 17923448Sdh155122 { "illif", "walk list of ill interface types for all stacks", 17935940Ssowmini ip_stacks_common_walk_init, illif_walk_step, NULL }, 17943448Sdh155122 { "illif_stack", "walk list of ill interface types", 17953448Sdh155122 illif_stack_walk_init, illif_stack_walk_step, 17963448Sdh155122 illif_stack_walk_fini }, 179711042SErik.Nordmark@Sun.COM { "ill", "walk active ill_t structures for all stacks", 17989089SVasumathi.Sundaram@Sun.COM ill_walk_init, ill_walk_step, NULL }, 17999089SVasumathi.Sundaram@Sun.COM { "ipif", "walk list of ipif structures for all stacks", 18009089SVasumathi.Sundaram@Sun.COM ipif_walk_init, ipif_walk_step, NULL }, 18019089SVasumathi.Sundaram@Sun.COM { "ipif_list", "walk the linked list of ipif structures " 18029089SVasumathi.Sundaram@Sun.COM "for a given ill", 18039089SVasumathi.Sundaram@Sun.COM ip_list_walk_init, ip_list_walk_step, 18049089SVasumathi.Sundaram@Sun.COM ip_list_walk_fini, &ipif_walk_arg }, 18059089SVasumathi.Sundaram@Sun.COM { "srcid", "walk list of srcid_map structures for all stacks", 18069089SVasumathi.Sundaram@Sun.COM ip_stacks_common_walk_init, srcid_walk_step, NULL }, 18079089SVasumathi.Sundaram@Sun.COM { "srcid_list", "walk list of srcid_map structures for a stack", 18089089SVasumathi.Sundaram@Sun.COM ip_list_walk_init, ip_list_walk_step, ip_list_walk_fini, 18099089SVasumathi.Sundaram@Sun.COM &srcid_walk_arg }, 18100Sstevel@tonic-gate { "ire", "walk active ire_t structures", 18110Sstevel@tonic-gate ire_walk_init, ire_walk_step, NULL }, 18123448Sdh155122 { "ire_next", "walk ire_t structures in the ctable", 18133448Sdh155122 ire_next_walk_init, ire_next_walk_step, NULL }, 181411042SErik.Nordmark@Sun.COM { "nce", "walk active nce_t structures", 181511042SErik.Nordmark@Sun.COM nce_walk_init, nce_walk_step, NULL }, 181611042SErik.Nordmark@Sun.COM { "dce", "walk active dce_t structures", 181711042SErik.Nordmark@Sun.COM dce_walk_init, dce_walk_step, NULL }, 18183448Sdh155122 { "ip_stacks", "walk all the ip_stack_t", 1819*11754SKacheong.Poon@Sun.COM ns_walk_init, ip_stacks_walk_step, NULL }, 1820*11754SKacheong.Poon@Sun.COM { "tcp_stacks", "walk all the tcp_stack_t", 1821*11754SKacheong.Poon@Sun.COM ns_walk_init, tcp_stacks_walk_step, NULL }, 1822*11754SKacheong.Poon@Sun.COM { "sctp_stacks", "walk all the sctp_stack_t", 1823*11754SKacheong.Poon@Sun.COM ns_walk_init, sctp_stacks_walk_step, NULL }, 1824*11754SKacheong.Poon@Sun.COM { "udp_stacks", "walk all the udp_stack_t", 1825*11754SKacheong.Poon@Sun.COM ns_walk_init, udp_stacks_walk_step, NULL }, 18265023Scarlsonj { "th_hash", "walk all the th_hash_t entries", 18275023Scarlsonj th_hash_walk_init, th_hash_walk_step, NULL }, 182811042SErik.Nordmark@Sun.COM { "ncec", "walk list of ncec structures for all stacks", 182911042SErik.Nordmark@Sun.COM ip_stacks_common_walk_init, ncec_walk_step, NULL }, 183011042SErik.Nordmark@Sun.COM { "ncec_stack", "walk list of ncec structures", 183111042SErik.Nordmark@Sun.COM ncec_stack_walk_init, ncec_stack_walk_step, 183211042SErik.Nordmark@Sun.COM ncec_stack_walk_fini}, 18339089SVasumathi.Sundaram@Sun.COM { "udp_hash", "walk list of conn_t structures in ips_ipcl_udp_fanout", 18349089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 18359089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &udp_hash_arg}, 18369089SVasumathi.Sundaram@Sun.COM { "conn_hash", "walk list of conn_t structures in ips_ipcl_conn_fanout", 18379089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 18389089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &conn_hash_arg}, 18399089SVasumathi.Sundaram@Sun.COM { "bind_hash", "walk list of conn_t structures in ips_ipcl_bind_fanout", 18409089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 18419089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &bind_hash_arg}, 18429089SVasumathi.Sundaram@Sun.COM { "proto_hash", "walk list of conn_t structures in " 18439089SVasumathi.Sundaram@Sun.COM "ips_ipcl_proto_fanout", 18449089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 18459089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &proto_hash_arg}, 18469089SVasumathi.Sundaram@Sun.COM { "proto_v6_hash", "walk list of conn_t structures in " 18479089SVasumathi.Sundaram@Sun.COM "ips_ipcl_proto_fanout_v6", 18489089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 18499089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &proto_v6_hash_arg}, 1850*11754SKacheong.Poon@Sun.COM { "ilb_stacks", "walk all ilb_stack_t", 1851*11754SKacheong.Poon@Sun.COM ns_walk_init, ilb_stacks_walk_step, NULL }, 185210946SSangeeta.Misra@Sun.COM { "ilb_rules", "walk ilb rules in a given ilb_stack_t", 185310946SSangeeta.Misra@Sun.COM ilb_rules_walk_init, ilb_rules_walk_step, NULL }, 185410946SSangeeta.Misra@Sun.COM { "ilb_servers", "walk server in a given ilb_rule_t", 185510946SSangeeta.Misra@Sun.COM ilb_servers_walk_init, ilb_servers_walk_step, NULL }, 185610946SSangeeta.Misra@Sun.COM { "ilb_nat_src", "walk NAT source table of a given ilb_stack_t", 185710946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_init, ilb_nat_src_walk_step, 185810946SSangeeta.Misra@Sun.COM ilb_common_walk_fini }, 185910946SSangeeta.Misra@Sun.COM { "ilb_conns", "walk NAT table of a given ilb_stack_t", 186010946SSangeeta.Misra@Sun.COM ilb_conn_walk_init, ilb_conn_walk_step, ilb_common_walk_fini }, 186110946SSangeeta.Misra@Sun.COM { "ilb_stickys", "walk sticky table of a given ilb_stack_t", 186210946SSangeeta.Misra@Sun.COM ilb_sticky_walk_init, ilb_sticky_walk_step, 186310946SSangeeta.Misra@Sun.COM ilb_common_walk_fini }, 1864*11754SKacheong.Poon@Sun.COM { "tcps_sc", "walk all the per CPU stats counters of a tcp_stack_t", 1865*11754SKacheong.Poon@Sun.COM tcps_sc_walk_init, tcps_sc_walk_step, NULL }, 18660Sstevel@tonic-gate { NULL } 18670Sstevel@tonic-gate }; 18680Sstevel@tonic-gate 18690Sstevel@tonic-gate static const mdb_qops_t ip_qops = { ip_qinfo, ip_rnext, ip_wnext }; 18700Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 18710Sstevel@tonic-gate 18720Sstevel@tonic-gate const mdb_modinfo_t * 18730Sstevel@tonic-gate _mdb_init(void) 18740Sstevel@tonic-gate { 18750Sstevel@tonic-gate GElf_Sym sym; 18760Sstevel@tonic-gate 18772546Scarlsonj if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0) 18780Sstevel@tonic-gate mdb_qops_install(&ip_qops, (uintptr_t)sym.st_value); 18790Sstevel@tonic-gate 18800Sstevel@tonic-gate return (&modinfo); 18810Sstevel@tonic-gate } 18820Sstevel@tonic-gate 18830Sstevel@tonic-gate void 18840Sstevel@tonic-gate _mdb_fini(void) 18850Sstevel@tonic-gate { 18860Sstevel@tonic-gate GElf_Sym sym; 18870Sstevel@tonic-gate 18882546Scarlsonj if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0) 18890Sstevel@tonic-gate mdb_qops_remove(&ip_qops, (uintptr_t)sym.st_value); 18900Sstevel@tonic-gate } 18915940Ssowmini 18925940Ssowmini static char * 189311042SErik.Nordmark@Sun.COM ncec_state(int ncec_state) 18945940Ssowmini { 189511042SErik.Nordmark@Sun.COM switch (ncec_state) { 18965940Ssowmini case ND_UNCHANGED: 18975940Ssowmini return ("unchanged"); 18985940Ssowmini case ND_INCOMPLETE: 18995940Ssowmini return ("incomplete"); 19005940Ssowmini case ND_REACHABLE: 19015940Ssowmini return ("reachable"); 19025940Ssowmini case ND_STALE: 19035940Ssowmini return ("stale"); 19045940Ssowmini case ND_DELAY: 19055940Ssowmini return ("delay"); 19065940Ssowmini case ND_PROBE: 19075940Ssowmini return ("probe"); 19085940Ssowmini case ND_UNREACHABLE: 19095940Ssowmini return ("unreach"); 19105940Ssowmini case ND_INITIAL: 19115940Ssowmini return ("initial"); 19125940Ssowmini default: 19135940Ssowmini return ("??"); 19145940Ssowmini } 19155940Ssowmini } 19165940Ssowmini 19175940Ssowmini static char * 191811042SErik.Nordmark@Sun.COM ncec_l2_addr(const ncec_t *ncec, const ill_t *ill) 191911042SErik.Nordmark@Sun.COM { 192011042SErik.Nordmark@Sun.COM uchar_t *h; 192111042SErik.Nordmark@Sun.COM static char addr_buf[L2MAXADDRSTRLEN]; 192211042SErik.Nordmark@Sun.COM 192311042SErik.Nordmark@Sun.COM if (ncec->ncec_lladdr == NULL) { 192411042SErik.Nordmark@Sun.COM return ("None"); 192511042SErik.Nordmark@Sun.COM } 192611042SErik.Nordmark@Sun.COM 192711042SErik.Nordmark@Sun.COM if (ill->ill_net_type == IRE_IF_RESOLVER) { 192811042SErik.Nordmark@Sun.COM 192911042SErik.Nordmark@Sun.COM if (ill->ill_phys_addr_length == 0) 193011042SErik.Nordmark@Sun.COM return ("None"); 193111042SErik.Nordmark@Sun.COM h = mdb_zalloc(ill->ill_phys_addr_length, UM_SLEEP); 193211042SErik.Nordmark@Sun.COM if (mdb_vread(h, ill->ill_phys_addr_length, 193311042SErik.Nordmark@Sun.COM (uintptr_t)ncec->ncec_lladdr) == -1) { 193411042SErik.Nordmark@Sun.COM mdb_warn("failed to read hwaddr at %p", 193511042SErik.Nordmark@Sun.COM ncec->ncec_lladdr); 193611042SErik.Nordmark@Sun.COM return ("Unknown"); 193711042SErik.Nordmark@Sun.COM } 193811042SErik.Nordmark@Sun.COM mdb_mac_addr(h, ill->ill_phys_addr_length, 193911042SErik.Nordmark@Sun.COM addr_buf, sizeof (addr_buf)); 194011042SErik.Nordmark@Sun.COM } else { 194111042SErik.Nordmark@Sun.COM return ("None"); 194211042SErik.Nordmark@Sun.COM } 194311042SErik.Nordmark@Sun.COM mdb_free(h, ill->ill_phys_addr_length); 194411042SErik.Nordmark@Sun.COM return (addr_buf); 194511042SErik.Nordmark@Sun.COM } 194611042SErik.Nordmark@Sun.COM 194711042SErik.Nordmark@Sun.COM static char * 19485940Ssowmini nce_l2_addr(const nce_t *nce, const ill_t *ill) 19495940Ssowmini { 19505940Ssowmini uchar_t *h; 19515940Ssowmini static char addr_buf[L2MAXADDRSTRLEN]; 19525940Ssowmini mblk_t mp; 19535940Ssowmini size_t mblen; 19545940Ssowmini 195511042SErik.Nordmark@Sun.COM if (nce->nce_dlur_mp == NULL) 19565940Ssowmini return ("None"); 19575940Ssowmini 19585940Ssowmini if (ill->ill_net_type == IRE_IF_RESOLVER) { 19595940Ssowmini if (mdb_vread(&mp, sizeof (mblk_t), 196011042SErik.Nordmark@Sun.COM (uintptr_t)nce->nce_dlur_mp) == -1) { 196111042SErik.Nordmark@Sun.COM mdb_warn("failed to read nce_dlur_mp at %p", 196211042SErik.Nordmark@Sun.COM nce->nce_dlur_mp); 196311042SErik.Nordmark@Sun.COM return ("None"); 19645940Ssowmini } 196511042SErik.Nordmark@Sun.COM if (ill->ill_phys_addr_length == 0) 19665940Ssowmini return ("None"); 19675940Ssowmini mblen = mp.b_wptr - mp.b_rptr; 19685940Ssowmini if (mblen > (sizeof (dl_unitdata_req_t) + MAX_SAP_LEN) || 196911042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length > MAX_SAP_LEN || 197011042SErik.Nordmark@Sun.COM (NCE_LL_ADDR_OFFSET(ill) + 197111042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length) > mblen) { 197211042SErik.Nordmark@Sun.COM return ("Unknown"); 19735940Ssowmini } 19745940Ssowmini h = mdb_zalloc(mblen, UM_SLEEP); 19755940Ssowmini if (mdb_vread(h, mblen, (uintptr_t)(mp.b_rptr)) == -1) { 19765940Ssowmini mdb_warn("failed to read hwaddr at %p", 19775940Ssowmini mp.b_rptr + NCE_LL_ADDR_OFFSET(ill)); 19785940Ssowmini return ("Unknown"); 19795940Ssowmini } 198011042SErik.Nordmark@Sun.COM mdb_mac_addr(h + NCE_LL_ADDR_OFFSET(ill), 198111042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length, addr_buf, sizeof (addr_buf)); 19825940Ssowmini } else { 19835940Ssowmini return ("None"); 19845940Ssowmini } 19855940Ssowmini mdb_free(h, mblen); 19865940Ssowmini return (addr_buf); 19875940Ssowmini } 19885940Ssowmini 19895940Ssowmini static void 199011042SErik.Nordmark@Sun.COM ncec_header(uint_t flags) 19915940Ssowmini { 19925940Ssowmini if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 19935940Ssowmini 19945940Ssowmini mdb_printf("%<u>%?s %-20s %-10s %-8s %-5s %s%</u>\n", 19955940Ssowmini "ADDR", "HW_ADDR", "STATE", "FLAGS", "ILL", "IP ADDR"); 19965940Ssowmini } 19975940Ssowmini } 19985940Ssowmini 19995940Ssowmini int 200011042SErik.Nordmark@Sun.COM ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 20015940Ssowmini { 200211042SErik.Nordmark@Sun.COM ncec_t ncec; 200311042SErik.Nordmark@Sun.COM ncec_cbdata_t id; 20045940Ssowmini int ipversion = 0; 20055940Ssowmini const char *opt_P = NULL; 20065940Ssowmini 20075940Ssowmini if (mdb_getopts(argc, argv, 20085940Ssowmini 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 20095940Ssowmini return (DCMD_USAGE); 20105940Ssowmini 20115940Ssowmini if (opt_P != NULL) { 20125940Ssowmini if (strcmp("v4", opt_P) == 0) { 20135940Ssowmini ipversion = IPV4_VERSION; 20145940Ssowmini } else if (strcmp("v6", opt_P) == 0) { 20155940Ssowmini ipversion = IPV6_VERSION; 20165940Ssowmini } else { 20175940Ssowmini mdb_warn("invalid protocol '%s'\n", opt_P); 20185940Ssowmini return (DCMD_USAGE); 20195940Ssowmini } 20205940Ssowmini } 20215940Ssowmini 20225940Ssowmini if (flags & DCMD_ADDRSPEC) { 20235940Ssowmini 202411042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) { 202511042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec at %p\n", addr); 20265940Ssowmini return (DCMD_ERR); 20275940Ssowmini } 202811042SErik.Nordmark@Sun.COM if (ipversion != 0 && ncec.ncec_ipversion != ipversion) { 20295940Ssowmini mdb_printf("IP Version mismatch\n"); 20305940Ssowmini return (DCMD_ERR); 20315940Ssowmini } 203211042SErik.Nordmark@Sun.COM ncec_header(flags); 203311042SErik.Nordmark@Sun.COM return (ncec_format(addr, &ncec, ipversion)); 20345940Ssowmini 20355940Ssowmini } else { 203611042SErik.Nordmark@Sun.COM id.ncec_addr = addr; 203711042SErik.Nordmark@Sun.COM id.ncec_ipversion = ipversion; 203811042SErik.Nordmark@Sun.COM ncec_header(flags); 203911042SErik.Nordmark@Sun.COM if (mdb_walk("ncec", (mdb_walk_cb_t)ncec_cb, &id) == -1) { 204011042SErik.Nordmark@Sun.COM mdb_warn("failed to walk ncec table\n"); 20415940Ssowmini return (DCMD_ERR); 20425940Ssowmini } 20435940Ssowmini } 20445940Ssowmini return (DCMD_OK); 20455940Ssowmini } 20465940Ssowmini 20475940Ssowmini static int 204811042SErik.Nordmark@Sun.COM ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion) 20495940Ssowmini { 205011042SErik.Nordmark@Sun.COM static const mdb_bitmask_t ncec_flags[] = { 205111042SErik.Nordmark@Sun.COM { "P", NCE_F_NONUD, NCE_F_NONUD }, 20525940Ssowmini { "R", NCE_F_ISROUTER, NCE_F_ISROUTER }, 20535940Ssowmini { "N", NCE_F_NONUD, NCE_F_NONUD }, 20545940Ssowmini { "A", NCE_F_ANYCAST, NCE_F_ANYCAST }, 20555940Ssowmini { "C", NCE_F_CONDEMNED, NCE_F_CONDEMNED }, 20565940Ssowmini { "U", NCE_F_UNSOL_ADV, NCE_F_UNSOL_ADV }, 20575940Ssowmini { "B", NCE_F_BCAST, NCE_F_BCAST }, 20585940Ssowmini { NULL, 0, 0 } 20595940Ssowmini }; 206011042SErik.Nordmark@Sun.COM #define NCE_MAX_FLAGS (sizeof (ncec_flags) / sizeof (mdb_bitmask_t)) 20615940Ssowmini struct in_addr nceaddr; 20625940Ssowmini ill_t ill; 20635940Ssowmini char ill_name[LIFNAMSIZ]; 20645940Ssowmini char flagsbuf[NCE_MAX_FLAGS]; 20655940Ssowmini 206611042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncec->ncec_ill) == -1) { 206711042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec_ill at %p", 206811042SErik.Nordmark@Sun.COM ncec->ncec_ill); 20695940Ssowmini return (DCMD_ERR); 20705940Ssowmini } 20715940Ssowmini 20725940Ssowmini (void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill.ill_name_length), 20735940Ssowmini (uintptr_t)ill.ill_name); 20745940Ssowmini 20755940Ssowmini mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%hb", 207611042SErik.Nordmark@Sun.COM ncec->ncec_flags, ncec_flags); 207711042SErik.Nordmark@Sun.COM 207811042SErik.Nordmark@Sun.COM if (ipversion != 0 && ncec->ncec_ipversion != ipversion) 20795940Ssowmini return (DCMD_OK); 20805940Ssowmini 208111042SErik.Nordmark@Sun.COM if (ncec->ncec_ipversion == IPV4_VERSION) { 208211042SErik.Nordmark@Sun.COM IN6_V4MAPPED_TO_INADDR(&ncec->ncec_addr, &nceaddr); 20835940Ssowmini mdb_printf("%?p %-20s %-10s " 20845940Ssowmini "%-8s " 20855940Ssowmini "%-5s %I\n", 208611042SErik.Nordmark@Sun.COM addr, ncec_l2_addr(ncec, &ill), 208711042SErik.Nordmark@Sun.COM ncec_state(ncec->ncec_state), 20885940Ssowmini flagsbuf, 20895940Ssowmini ill_name, nceaddr.s_addr); 20905940Ssowmini } else { 20915940Ssowmini mdb_printf("%?p %-20s %-10s %-8s %-5s %N\n", 209211042SErik.Nordmark@Sun.COM addr, ncec_l2_addr(ncec, &ill), 209311042SErik.Nordmark@Sun.COM ncec_state(ncec->ncec_state), 20945940Ssowmini flagsbuf, 209511042SErik.Nordmark@Sun.COM ill_name, &ncec->ncec_addr); 20965940Ssowmini } 20975940Ssowmini 20985940Ssowmini return (DCMD_OK); 20995940Ssowmini } 21005940Ssowmini 21015940Ssowmini static uintptr_t 210211042SErik.Nordmark@Sun.COM ncec_get_next_hash_tbl(uintptr_t start, int *index, struct ndp_g_s ndp) 21035940Ssowmini { 21045940Ssowmini uintptr_t addr = start; 21055940Ssowmini int i = *index; 21065940Ssowmini 21075940Ssowmini while (addr == NULL) { 21085940Ssowmini 21095940Ssowmini if (++i >= NCE_TABLE_SIZE) 21105940Ssowmini break; 21115940Ssowmini addr = (uintptr_t)ndp.nce_hash_tbl[i]; 21125940Ssowmini } 21135940Ssowmini *index = i; 21145940Ssowmini return (addr); 21155940Ssowmini } 21165940Ssowmini 21175940Ssowmini static int 211811042SErik.Nordmark@Sun.COM ncec_walk_step(mdb_walk_state_t *wsp) 21195940Ssowmini { 21205940Ssowmini uintptr_t kaddr4, kaddr6; 21215940Ssowmini 21225940Ssowmini kaddr4 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp4); 21235940Ssowmini kaddr6 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp6); 21245940Ssowmini 21255940Ssowmini if (mdb_vread(&kaddr4, sizeof (kaddr4), kaddr4) == -1) { 21265940Ssowmini mdb_warn("can't read ips_ip_cache_table at %p", kaddr4); 21275940Ssowmini return (WALK_ERR); 21285940Ssowmini } 21295940Ssowmini if (mdb_vread(&kaddr6, sizeof (kaddr6), kaddr6) == -1) { 21305940Ssowmini mdb_warn("can't read ips_ip_cache_table at %p", kaddr6); 21315940Ssowmini return (WALK_ERR); 21325940Ssowmini } 213311042SErik.Nordmark@Sun.COM if (mdb_pwalk("ncec_stack", wsp->walk_callback, wsp->walk_cbdata, 21345940Ssowmini kaddr4) == -1) { 213511042SErik.Nordmark@Sun.COM mdb_warn("couldn't walk 'ncec_stack' for ips_ndp4 %p", 21365940Ssowmini kaddr4); 21375940Ssowmini return (WALK_ERR); 21385940Ssowmini } 213911042SErik.Nordmark@Sun.COM if (mdb_pwalk("ncec_stack", wsp->walk_callback, 21405940Ssowmini wsp->walk_cbdata, kaddr6) == -1) { 214111042SErik.Nordmark@Sun.COM mdb_warn("couldn't walk 'ncec_stack' for ips_ndp6 %p", 21425940Ssowmini kaddr6); 21435940Ssowmini return (WALK_ERR); 21445940Ssowmini } 21455940Ssowmini return (WALK_NEXT); 21465940Ssowmini } 21475940Ssowmini 21489089SVasumathi.Sundaram@Sun.COM static uintptr_t 21499089SVasumathi.Sundaram@Sun.COM ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t *iw) 21509089SVasumathi.Sundaram@Sun.COM { 21519089SVasumathi.Sundaram@Sun.COM struct connf_s connf; 21529089SVasumathi.Sundaram@Sun.COM uintptr_t addr = NULL, next; 21539089SVasumathi.Sundaram@Sun.COM int index = iw->connf_tbl_index; 21549089SVasumathi.Sundaram@Sun.COM 21559089SVasumathi.Sundaram@Sun.COM do { 21569089SVasumathi.Sundaram@Sun.COM next = iw->hash_tbl + index * sizeof (struct connf_s); 21579089SVasumathi.Sundaram@Sun.COM if (++index >= iw->hash_tbl_size) { 21589089SVasumathi.Sundaram@Sun.COM addr = NULL; 21599089SVasumathi.Sundaram@Sun.COM break; 21609089SVasumathi.Sundaram@Sun.COM } 21619089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&connf, sizeof (struct connf_s), next) == -1) { 21629089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", next); 21639089SVasumathi.Sundaram@Sun.COM return (NULL); 21649089SVasumathi.Sundaram@Sun.COM } 21659089SVasumathi.Sundaram@Sun.COM addr = (uintptr_t)connf.connf_head; 21669089SVasumathi.Sundaram@Sun.COM } while (addr == NULL); 21679089SVasumathi.Sundaram@Sun.COM iw->connf_tbl_index = index; 21689089SVasumathi.Sundaram@Sun.COM return (addr); 21699089SVasumathi.Sundaram@Sun.COM } 21709089SVasumathi.Sundaram@Sun.COM 21719089SVasumathi.Sundaram@Sun.COM static int 21729089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init(mdb_walk_state_t *wsp) 21739089SVasumathi.Sundaram@Sun.COM { 21749089SVasumathi.Sundaram@Sun.COM const hash_walk_arg_t *arg = wsp->walk_arg; 21759089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw; 21769089SVasumathi.Sundaram@Sun.COM uintptr_t tbladdr; 21779089SVasumathi.Sundaram@Sun.COM uintptr_t sizeaddr; 21789089SVasumathi.Sundaram@Sun.COM 21799089SVasumathi.Sundaram@Sun.COM iw = mdb_alloc(sizeof (ipcl_hash_walk_data_t), UM_SLEEP); 21809089SVasumathi.Sundaram@Sun.COM iw->conn = mdb_alloc(sizeof (conn_t), UM_SLEEP); 21819089SVasumathi.Sundaram@Sun.COM tbladdr = wsp->walk_addr + arg->tbl_off; 21829089SVasumathi.Sundaram@Sun.COM sizeaddr = wsp->walk_addr + arg->size_off; 21839089SVasumathi.Sundaram@Sun.COM 21849089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&iw->hash_tbl, sizeof (uintptr_t), tbladdr) == -1) { 21859089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read fanout table addr at %p", tbladdr); 21869089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t)); 21879089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t)); 21889089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 21899089SVasumathi.Sundaram@Sun.COM } 219011042SErik.Nordmark@Sun.COM if (arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4) || 21919089SVasumathi.Sundaram@Sun.COM arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6)) { 21929089SVasumathi.Sundaram@Sun.COM iw->hash_tbl_size = IPPROTO_MAX; 21939089SVasumathi.Sundaram@Sun.COM } else { 21949089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&iw->hash_tbl_size, sizeof (int), 21959089SVasumathi.Sundaram@Sun.COM sizeaddr) == -1) { 21969089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read fanout table size addr at %p", 21979089SVasumathi.Sundaram@Sun.COM sizeaddr); 21989089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t)); 21999089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t)); 22009089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 22019089SVasumathi.Sundaram@Sun.COM } 22029089SVasumathi.Sundaram@Sun.COM } 22039089SVasumathi.Sundaram@Sun.COM iw->connf_tbl_index = 0; 22049089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw); 22059089SVasumathi.Sundaram@Sun.COM wsp->walk_data = iw; 22069089SVasumathi.Sundaram@Sun.COM 22079089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr != NULL) 22089089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 22099089SVasumathi.Sundaram@Sun.COM else 22109089SVasumathi.Sundaram@Sun.COM return (WALK_DONE); 22119089SVasumathi.Sundaram@Sun.COM } 22129089SVasumathi.Sundaram@Sun.COM 22139089SVasumathi.Sundaram@Sun.COM static int 22149089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_step(mdb_walk_state_t *wsp) 22159089SVasumathi.Sundaram@Sun.COM { 22169089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr; 22179089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw = wsp->walk_data; 22189089SVasumathi.Sundaram@Sun.COM conn_t *conn = iw->conn; 22199089SVasumathi.Sundaram@Sun.COM int ret = WALK_DONE; 22209089SVasumathi.Sundaram@Sun.COM 22219089SVasumathi.Sundaram@Sun.COM while (addr != NULL) { 22229089SVasumathi.Sundaram@Sun.COM if (mdb_vread(conn, sizeof (conn_t), addr) == -1) { 22239089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", addr); 22249089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 22259089SVasumathi.Sundaram@Sun.COM } 22269089SVasumathi.Sundaram@Sun.COM ret = wsp->walk_callback(addr, iw, wsp->walk_cbdata); 22279089SVasumathi.Sundaram@Sun.COM if (ret != WALK_NEXT) 22289089SVasumathi.Sundaram@Sun.COM break; 22299089SVasumathi.Sundaram@Sun.COM addr = (uintptr_t)conn->conn_next; 22309089SVasumathi.Sundaram@Sun.COM } 22319089SVasumathi.Sundaram@Sun.COM if (ret == WALK_NEXT) { 22329089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw); 22339089SVasumathi.Sundaram@Sun.COM 22349089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr != NULL) 22359089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 22369089SVasumathi.Sundaram@Sun.COM else 22379089SVasumathi.Sundaram@Sun.COM return (WALK_DONE); 22389089SVasumathi.Sundaram@Sun.COM } 22399089SVasumathi.Sundaram@Sun.COM 22409089SVasumathi.Sundaram@Sun.COM return (ret); 22419089SVasumathi.Sundaram@Sun.COM } 22429089SVasumathi.Sundaram@Sun.COM 22439089SVasumathi.Sundaram@Sun.COM static void 22449089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini(mdb_walk_state_t *wsp) 22459089SVasumathi.Sundaram@Sun.COM { 22469089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw = wsp->walk_data; 22479089SVasumathi.Sundaram@Sun.COM 22489089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t)); 22499089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t)); 22509089SVasumathi.Sundaram@Sun.COM } 22519089SVasumathi.Sundaram@Sun.COM 22525940Ssowmini /* 22535940Ssowmini * Called with walk_addr being the address of ips_ndp{4,6} 22545940Ssowmini */ 22555940Ssowmini static int 225611042SErik.Nordmark@Sun.COM ncec_stack_walk_init(mdb_walk_state_t *wsp) 22575940Ssowmini { 225811042SErik.Nordmark@Sun.COM ncec_walk_data_t *nw; 22595940Ssowmini 22605940Ssowmini if (wsp->walk_addr == NULL) { 226111042SErik.Nordmark@Sun.COM mdb_warn("ncec_stack requires ndp_g_s address\n"); 22625940Ssowmini return (WALK_ERR); 22635940Ssowmini } 22645940Ssowmini 226511042SErik.Nordmark@Sun.COM nw = mdb_alloc(sizeof (ncec_walk_data_t), UM_SLEEP); 226611042SErik.Nordmark@Sun.COM 226711042SErik.Nordmark@Sun.COM if (mdb_vread(&nw->ncec_ip_ndp, sizeof (struct ndp_g_s), 22685940Ssowmini wsp->walk_addr) == -1) { 22695940Ssowmini mdb_warn("failed to read 'ip_ndp' at %p", 22705940Ssowmini wsp->walk_addr); 227111042SErik.Nordmark@Sun.COM mdb_free(nw, sizeof (ncec_walk_data_t)); 22725940Ssowmini return (WALK_ERR); 22735940Ssowmini } 22745940Ssowmini 227511042SErik.Nordmark@Sun.COM /* 227611042SErik.Nordmark@Sun.COM * ncec_get_next_hash_tbl() starts at ++i , so initialize index to -1 227711042SErik.Nordmark@Sun.COM */ 227811042SErik.Nordmark@Sun.COM nw->ncec_hash_tbl_index = -1; 227911042SErik.Nordmark@Sun.COM wsp->walk_addr = ncec_get_next_hash_tbl(NULL, 228011042SErik.Nordmark@Sun.COM &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp); 22815940Ssowmini wsp->walk_data = nw; 22825940Ssowmini 22835940Ssowmini return (WALK_NEXT); 22845940Ssowmini } 22855940Ssowmini 22865940Ssowmini static int 228711042SErik.Nordmark@Sun.COM ncec_stack_walk_step(mdb_walk_state_t *wsp) 22885940Ssowmini { 22895940Ssowmini uintptr_t addr = wsp->walk_addr; 229011042SErik.Nordmark@Sun.COM ncec_walk_data_t *nw = wsp->walk_data; 22915940Ssowmini 22925940Ssowmini if (addr == NULL) 22935940Ssowmini return (WALK_DONE); 22945940Ssowmini 229511042SErik.Nordmark@Sun.COM if (mdb_vread(&nw->ncec, sizeof (ncec_t), addr) == -1) { 229611042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec_t at %p", addr); 22975940Ssowmini return (WALK_ERR); 22985940Ssowmini } 22995940Ssowmini 230011042SErik.Nordmark@Sun.COM wsp->walk_addr = (uintptr_t)nw->ncec.ncec_next; 230111042SErik.Nordmark@Sun.COM 230211042SErik.Nordmark@Sun.COM wsp->walk_addr = ncec_get_next_hash_tbl(wsp->walk_addr, 230311042SErik.Nordmark@Sun.COM &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp); 23045940Ssowmini 23055940Ssowmini return (wsp->walk_callback(addr, nw, wsp->walk_cbdata)); 23065940Ssowmini } 23075940Ssowmini 23085940Ssowmini static void 230911042SErik.Nordmark@Sun.COM ncec_stack_walk_fini(mdb_walk_state_t *wsp) 23105940Ssowmini { 231111042SErik.Nordmark@Sun.COM mdb_free(wsp->walk_data, sizeof (ncec_walk_data_t)); 23125940Ssowmini } 23135940Ssowmini 23145940Ssowmini /* ARGSUSED */ 23155940Ssowmini static int 231611042SErik.Nordmark@Sun.COM ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw, ncec_cbdata_t *id) 23175940Ssowmini { 231811042SErik.Nordmark@Sun.COM ncec_t ncec; 231911042SErik.Nordmark@Sun.COM 232011042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) { 232111042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec at %p", addr); 23225940Ssowmini return (WALK_NEXT); 23235940Ssowmini } 232411042SErik.Nordmark@Sun.COM (void) ncec_format(addr, &ncec, id->ncec_ipversion); 23255940Ssowmini return (WALK_NEXT); 23265940Ssowmini } 23279089SVasumathi.Sundaram@Sun.COM 23289089SVasumathi.Sundaram@Sun.COM static int 23299089SVasumathi.Sundaram@Sun.COM ill_walk_init(mdb_walk_state_t *wsp) 23309089SVasumathi.Sundaram@Sun.COM { 23319089SVasumathi.Sundaram@Sun.COM if (mdb_layered_walk("illif", wsp) == -1) { 23329089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'illif'"); 23339089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 23349089SVasumathi.Sundaram@Sun.COM } 23359089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 23369089SVasumathi.Sundaram@Sun.COM } 23379089SVasumathi.Sundaram@Sun.COM 23389089SVasumathi.Sundaram@Sun.COM static int 23399089SVasumathi.Sundaram@Sun.COM ill_walk_step(mdb_walk_state_t *wsp) 23409089SVasumathi.Sundaram@Sun.COM { 23419089SVasumathi.Sundaram@Sun.COM ill_if_t ill_if; 23429089SVasumathi.Sundaram@Sun.COM 23439089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill_if, sizeof (ill_if_t), wsp->walk_addr) == -1) { 23449089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read ill_if_t at %p", wsp->walk_addr); 23459089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 23469089SVasumathi.Sundaram@Sun.COM } 23479089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = (uintptr_t)(wsp->walk_addr + 23489089SVasumathi.Sundaram@Sun.COM offsetof(ill_if_t, illif_avl_by_ppa)); 23499089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("avl", wsp->walk_callback, wsp->walk_cbdata, 23509089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 23519089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'avl'"); 23529089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 23539089SVasumathi.Sundaram@Sun.COM } 23549089SVasumathi.Sundaram@Sun.COM 23559089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 23569089SVasumathi.Sundaram@Sun.COM } 23579089SVasumathi.Sundaram@Sun.COM 23589089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 23599089SVasumathi.Sundaram@Sun.COM static int 23609089SVasumathi.Sundaram@Sun.COM ill_cb(uintptr_t addr, const ill_walk_data_t *iw, ill_cbdata_t *id) 23619089SVasumathi.Sundaram@Sun.COM { 23629089SVasumathi.Sundaram@Sun.COM ill_t ill; 23639089SVasumathi.Sundaram@Sun.COM 23649089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill, sizeof (ill_t), (uintptr_t)addr) == -1) { 23659089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", addr); 23669089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 23679089SVasumathi.Sundaram@Sun.COM } 236811042SErik.Nordmark@Sun.COM 236911042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip ILLs that don't belong to it. */ 237011042SErik.Nordmark@Sun.COM if (id->ill_ipst != NULL && ill.ill_ipst != id->ill_ipst) 237111042SErik.Nordmark@Sun.COM return (WALK_NEXT); 237211042SErik.Nordmark@Sun.COM 23739089SVasumathi.Sundaram@Sun.COM return (ill_format((uintptr_t)addr, &ill, id)); 23749089SVasumathi.Sundaram@Sun.COM } 23759089SVasumathi.Sundaram@Sun.COM 23769089SVasumathi.Sundaram@Sun.COM static void 23779089SVasumathi.Sundaram@Sun.COM ill_header(boolean_t verbose) 23789089SVasumathi.Sundaram@Sun.COM { 23799089SVasumathi.Sundaram@Sun.COM if (verbose) { 23809089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-8s %3s %-10s %-?s %-?s %-10s%</u>\n", 23819089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "VER", "TYPE", "WQ", "IPST", "FLAGS"); 23829089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %4s%4s %-?s\n", 23839089SVasumathi.Sundaram@Sun.COM "PHYINT", "CNT", "", "GROUP"); 23849089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 23859089SVasumathi.Sundaram@Sun.COM } else { 23869089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s %-8s %-3s %-10s %4s %-?s %-10s%</u>\n", 23879089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "VER", "TYPE", "CNT", "WQ", "FLAGS"); 23889089SVasumathi.Sundaram@Sun.COM } 23899089SVasumathi.Sundaram@Sun.COM } 23909089SVasumathi.Sundaram@Sun.COM 23919089SVasumathi.Sundaram@Sun.COM static int 23929089SVasumathi.Sundaram@Sun.COM ill_format(uintptr_t addr, const void *illptr, void *ill_cb_arg) 23939089SVasumathi.Sundaram@Sun.COM { 23949089SVasumathi.Sundaram@Sun.COM ill_t *ill = (ill_t *)illptr; 23959089SVasumathi.Sundaram@Sun.COM ill_cbdata_t *illcb = ill_cb_arg; 23969089SVasumathi.Sundaram@Sun.COM boolean_t verbose = illcb->verbose; 23979089SVasumathi.Sundaram@Sun.COM phyint_t phyi; 23989089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t fmasks[] = { 23999089SVasumathi.Sundaram@Sun.COM { "R", PHYI_RUNNING, PHYI_RUNNING }, 24009089SVasumathi.Sundaram@Sun.COM { "P", PHYI_PROMISC, PHYI_PROMISC }, 24019089SVasumathi.Sundaram@Sun.COM { "V", PHYI_VIRTUAL, PHYI_VIRTUAL }, 24029089SVasumathi.Sundaram@Sun.COM { "I", PHYI_IPMP, PHYI_IPMP }, 24039089SVasumathi.Sundaram@Sun.COM { "f", PHYI_FAILED, PHYI_FAILED }, 24049089SVasumathi.Sundaram@Sun.COM { "S", PHYI_STANDBY, PHYI_STANDBY }, 24059089SVasumathi.Sundaram@Sun.COM { "i", PHYI_INACTIVE, PHYI_INACTIVE }, 24069089SVasumathi.Sundaram@Sun.COM { "O", PHYI_OFFLINE, PHYI_OFFLINE }, 24079089SVasumathi.Sundaram@Sun.COM { "T", ILLF_NOTRAILERS, ILLF_NOTRAILERS }, 24089089SVasumathi.Sundaram@Sun.COM { "A", ILLF_NOARP, ILLF_NOARP }, 24099089SVasumathi.Sundaram@Sun.COM { "M", ILLF_MULTICAST, ILLF_MULTICAST }, 24109089SVasumathi.Sundaram@Sun.COM { "F", ILLF_ROUTER, ILLF_ROUTER }, 24119089SVasumathi.Sundaram@Sun.COM { "D", ILLF_NONUD, ILLF_NONUD }, 24129089SVasumathi.Sundaram@Sun.COM { "X", ILLF_NORTEXCH, ILLF_NORTEXCH }, 24139089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 24149089SVasumathi.Sundaram@Sun.COM }; 24159089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t v_fmasks[] = { 24169089SVasumathi.Sundaram@Sun.COM { "RUNNING", PHYI_RUNNING, PHYI_RUNNING }, 24179089SVasumathi.Sundaram@Sun.COM { "PROMISC", PHYI_PROMISC, PHYI_PROMISC }, 24189089SVasumathi.Sundaram@Sun.COM { "VIRTUAL", PHYI_VIRTUAL, PHYI_VIRTUAL }, 24199089SVasumathi.Sundaram@Sun.COM { "IPMP", PHYI_IPMP, PHYI_IPMP }, 24209089SVasumathi.Sundaram@Sun.COM { "FAILED", PHYI_FAILED, PHYI_FAILED }, 24219089SVasumathi.Sundaram@Sun.COM { "STANDBY", PHYI_STANDBY, PHYI_STANDBY }, 24229089SVasumathi.Sundaram@Sun.COM { "INACTIVE", PHYI_INACTIVE, PHYI_INACTIVE }, 24239089SVasumathi.Sundaram@Sun.COM { "OFFLINE", PHYI_OFFLINE, PHYI_OFFLINE }, 24249089SVasumathi.Sundaram@Sun.COM { "NOTRAILER", ILLF_NOTRAILERS, ILLF_NOTRAILERS }, 24259089SVasumathi.Sundaram@Sun.COM { "NOARP", ILLF_NOARP, ILLF_NOARP }, 24269089SVasumathi.Sundaram@Sun.COM { "MULTICAST", ILLF_MULTICAST, ILLF_MULTICAST }, 24279089SVasumathi.Sundaram@Sun.COM { "ROUTER", ILLF_ROUTER, ILLF_ROUTER }, 24289089SVasumathi.Sundaram@Sun.COM { "NONUD", ILLF_NONUD, ILLF_NONUD }, 24299089SVasumathi.Sundaram@Sun.COM { "NORTEXCH", ILLF_NORTEXCH, ILLF_NORTEXCH }, 24309089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 24319089SVasumathi.Sundaram@Sun.COM }; 24329089SVasumathi.Sundaram@Sun.COM char ill_name[LIFNAMSIZ]; 24339089SVasumathi.Sundaram@Sun.COM int cnt; 24349089SVasumathi.Sundaram@Sun.COM char *typebuf; 24359089SVasumathi.Sundaram@Sun.COM char sbuf[DEFCOLS]; 24369089SVasumathi.Sundaram@Sun.COM int ipver = illcb->ill_ipversion; 24379089SVasumathi.Sundaram@Sun.COM 24389089SVasumathi.Sundaram@Sun.COM if (ipver != 0) { 24399089SVasumathi.Sundaram@Sun.COM if ((ipver == IPV4_VERSION && ill->ill_isv6) || 24409089SVasumathi.Sundaram@Sun.COM (ipver == IPV6_VERSION && !ill->ill_isv6)) { 24419089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 24429089SVasumathi.Sundaram@Sun.COM } 24439089SVasumathi.Sundaram@Sun.COM } 24449089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&phyi, sizeof (phyint_t), 24459089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_phyint) == -1) { 24469089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill_phyint at %p", 24479089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_phyint); 24489089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 24499089SVasumathi.Sundaram@Sun.COM } 24509089SVasumathi.Sundaram@Sun.COM (void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill->ill_name_length), 24519089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_name); 24529089SVasumathi.Sundaram@Sun.COM 24539089SVasumathi.Sundaram@Sun.COM switch (ill->ill_type) { 24549089SVasumathi.Sundaram@Sun.COM case 0: 24559089SVasumathi.Sundaram@Sun.COM typebuf = "LOOPBACK"; 24569089SVasumathi.Sundaram@Sun.COM break; 24579089SVasumathi.Sundaram@Sun.COM case IFT_ETHER: 24589089SVasumathi.Sundaram@Sun.COM typebuf = "ETHER"; 24599089SVasumathi.Sundaram@Sun.COM break; 24609089SVasumathi.Sundaram@Sun.COM case IFT_OTHER: 24619089SVasumathi.Sundaram@Sun.COM typebuf = "OTHER"; 24629089SVasumathi.Sundaram@Sun.COM break; 24639089SVasumathi.Sundaram@Sun.COM default: 24649089SVasumathi.Sundaram@Sun.COM typebuf = NULL; 24659089SVasumathi.Sundaram@Sun.COM break; 24669089SVasumathi.Sundaram@Sun.COM } 24679089SVasumathi.Sundaram@Sun.COM cnt = ill->ill_refcnt + ill->ill_ire_cnt + ill->ill_nce_cnt + 246811042SErik.Nordmark@Sun.COM ill->ill_ilm_cnt + ill->ill_ncec_cnt; 24699089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-8s %-3s ", 24709089SVasumathi.Sundaram@Sun.COM addr, ill_name, ill->ill_isv6 ? "v6" : "v4"); 24719089SVasumathi.Sundaram@Sun.COM if (typebuf != NULL) 24729089SVasumathi.Sundaram@Sun.COM mdb_printf("%-10s ", typebuf); 24739089SVasumathi.Sundaram@Sun.COM else 24749089SVasumathi.Sundaram@Sun.COM mdb_printf("%-10x ", ill->ill_type); 24759089SVasumathi.Sundaram@Sun.COM if (verbose) { 24769089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-?p %-llb\n", 24779089SVasumathi.Sundaram@Sun.COM ill->ill_wq, ill->ill_ipst, 24789089SVasumathi.Sundaram@Sun.COM ill->ill_flags | phyi.phyint_flags, v_fmasks); 24799089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %4d%4s %-?p\n", 24809089SVasumathi.Sundaram@Sun.COM ill->ill_phyint, cnt, "", ill->ill_grp); 24819089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sbuf, sizeof (sbuf), "%*s %3s", 24829089SVasumathi.Sundaram@Sun.COM sizeof (uintptr_t) * 2, "", ""); 24839089SVasumathi.Sundaram@Sun.COM mdb_printf("%s|\n%s+--> %3d %-18s " 24849089SVasumathi.Sundaram@Sun.COM "references from active threads\n", 24859089SVasumathi.Sundaram@Sun.COM sbuf, sbuf, ill->ill_refcnt, "ill_refcnt"); 24869089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s ires referencing this ill\n", 24879089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_ire_cnt, "ill_ire_cnt"); 24889089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s nces referencing this ill\n", 24899089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_nce_cnt, "ill_nce_cnt"); 249011042SErik.Nordmark@Sun.COM mdb_printf("%*s %7d %-18s ncecs referencing this ill\n", 249111042SErik.Nordmark@Sun.COM strlen(sbuf), "", ill->ill_ncec_cnt, "ill_ncec_cnt"); 24929089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s ilms referencing this ill\n", 24939089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_ilm_cnt, "ill_ilm_cnt"); 24949089SVasumathi.Sundaram@Sun.COM } else { 24959089SVasumathi.Sundaram@Sun.COM mdb_printf("%4d %-?p %-llb\n", 24969089SVasumathi.Sundaram@Sun.COM cnt, ill->ill_wq, 24979089SVasumathi.Sundaram@Sun.COM ill->ill_flags | phyi.phyint_flags, fmasks); 24989089SVasumathi.Sundaram@Sun.COM } 24999089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25009089SVasumathi.Sundaram@Sun.COM } 25019089SVasumathi.Sundaram@Sun.COM 25029089SVasumathi.Sundaram@Sun.COM static int 25039089SVasumathi.Sundaram@Sun.COM ill(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 25049089SVasumathi.Sundaram@Sun.COM { 25059089SVasumathi.Sundaram@Sun.COM ill_t ill_data; 25069089SVasumathi.Sundaram@Sun.COM ill_cbdata_t id; 25079089SVasumathi.Sundaram@Sun.COM int ipversion = 0; 250811042SErik.Nordmark@Sun.COM const char *zone_name = NULL; 25099089SVasumathi.Sundaram@Sun.COM const char *opt_P = NULL; 25109089SVasumathi.Sundaram@Sun.COM uint_t verbose = FALSE; 251111042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL; 25129089SVasumathi.Sundaram@Sun.COM 25139089SVasumathi.Sundaram@Sun.COM if (mdb_getopts(argc, argv, 25149089SVasumathi.Sundaram@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 251511042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name, 25169089SVasumathi.Sundaram@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 25179089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 25189089SVasumathi.Sundaram@Sun.COM 251911042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */ 252011042SErik.Nordmark@Sun.COM if (zone_name != NULL) { 252111042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name); 252211042SErik.Nordmark@Sun.COM if (ipst == NULL) 252311042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 252411042SErik.Nordmark@Sun.COM } 252511042SErik.Nordmark@Sun.COM 25269089SVasumathi.Sundaram@Sun.COM if (opt_P != NULL) { 25279089SVasumathi.Sundaram@Sun.COM if (strcmp("v4", opt_P) == 0) { 25289089SVasumathi.Sundaram@Sun.COM ipversion = IPV4_VERSION; 25299089SVasumathi.Sundaram@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 25309089SVasumathi.Sundaram@Sun.COM ipversion = IPV6_VERSION; 25319089SVasumathi.Sundaram@Sun.COM } else { 25329089SVasumathi.Sundaram@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 25339089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 25349089SVasumathi.Sundaram@Sun.COM } 25359089SVasumathi.Sundaram@Sun.COM } 25369089SVasumathi.Sundaram@Sun.COM 25379089SVasumathi.Sundaram@Sun.COM id.verbose = verbose; 25389089SVasumathi.Sundaram@Sun.COM id.ill_addr = addr; 25399089SVasumathi.Sundaram@Sun.COM id.ill_ipversion = ipversion; 254011042SErik.Nordmark@Sun.COM id.ill_ipst = ipst; 25419089SVasumathi.Sundaram@Sun.COM 25429089SVasumathi.Sundaram@Sun.COM ill_header(verbose); 25439089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 25449089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill_data, sizeof (ill_t), addr) == -1) { 25459089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p\n", addr); 25469089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 25479089SVasumathi.Sundaram@Sun.COM } 25489089SVasumathi.Sundaram@Sun.COM (void) ill_format(addr, &ill_data, &id); 25499089SVasumathi.Sundaram@Sun.COM } else { 25509089SVasumathi.Sundaram@Sun.COM if (mdb_walk("ill", (mdb_walk_cb_t)ill_cb, &id) == -1) { 25519089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk ills\n"); 25529089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 25539089SVasumathi.Sundaram@Sun.COM } 25549089SVasumathi.Sundaram@Sun.COM } 25559089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 25569089SVasumathi.Sundaram@Sun.COM } 25579089SVasumathi.Sundaram@Sun.COM 25589089SVasumathi.Sundaram@Sun.COM static void 25599089SVasumathi.Sundaram@Sun.COM ill_help(void) 25609089SVasumathi.Sundaram@Sun.COM { 25619089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints the following fields: ill ptr, name, " 25629089SVasumathi.Sundaram@Sun.COM "IP version, count, ill type and ill flags.\n" 25639089SVasumathi.Sundaram@Sun.COM "The count field is a sum of individual refcnts and is expanded " 25649089SVasumathi.Sundaram@Sun.COM "with the -v option.\n\n"); 25659089SVasumathi.Sundaram@Sun.COM mdb_printf("Options:\n"); 25669089SVasumathi.Sundaram@Sun.COM mdb_printf("\t-P v4 | v6" 25679089SVasumathi.Sundaram@Sun.COM "\tfilter ill structures for the specified protocol\n"); 25689089SVasumathi.Sundaram@Sun.COM } 25699089SVasumathi.Sundaram@Sun.COM 25709089SVasumathi.Sundaram@Sun.COM static int 25719089SVasumathi.Sundaram@Sun.COM ip_list_walk_init(mdb_walk_state_t *wsp) 25729089SVasumathi.Sundaram@Sun.COM { 25739089SVasumathi.Sundaram@Sun.COM const ip_list_walk_arg_t *arg = wsp->walk_arg; 25749089SVasumathi.Sundaram@Sun.COM ip_list_walk_data_t *iw; 25759089SVasumathi.Sundaram@Sun.COM uintptr_t addr = (uintptr_t)(wsp->walk_addr + arg->off); 25769089SVasumathi.Sundaram@Sun.COM 25779089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr == NULL) { 25789089SVasumathi.Sundaram@Sun.COM mdb_warn("only local walks supported\n"); 25799089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 25809089SVasumathi.Sundaram@Sun.COM } 25819089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), 25829089SVasumathi.Sundaram@Sun.COM addr) == -1) { 25839089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read list head at %p", addr); 25849089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 25859089SVasumathi.Sundaram@Sun.COM } 25869089SVasumathi.Sundaram@Sun.COM iw = mdb_alloc(sizeof (ip_list_walk_data_t), UM_SLEEP); 25879089SVasumathi.Sundaram@Sun.COM iw->nextoff = arg->nextp_off; 25889089SVasumathi.Sundaram@Sun.COM wsp->walk_data = iw; 25899089SVasumathi.Sundaram@Sun.COM 25909089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25919089SVasumathi.Sundaram@Sun.COM } 25929089SVasumathi.Sundaram@Sun.COM 25939089SVasumathi.Sundaram@Sun.COM static int 25949089SVasumathi.Sundaram@Sun.COM ip_list_walk_step(mdb_walk_state_t *wsp) 25959089SVasumathi.Sundaram@Sun.COM { 25969089SVasumathi.Sundaram@Sun.COM ip_list_walk_data_t *iw = wsp->walk_data; 25979089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr; 25989089SVasumathi.Sundaram@Sun.COM 25999089SVasumathi.Sundaram@Sun.COM if (addr == NULL) 26009089SVasumathi.Sundaram@Sun.COM return (WALK_DONE); 26019089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = addr + iw->nextoff; 26029089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), 26039089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 26049089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read list node at %p", addr); 26059089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 26069089SVasumathi.Sundaram@Sun.COM } 26079089SVasumathi.Sundaram@Sun.COM return (wsp->walk_callback(addr, iw, wsp->walk_cbdata)); 26089089SVasumathi.Sundaram@Sun.COM } 26099089SVasumathi.Sundaram@Sun.COM 26109089SVasumathi.Sundaram@Sun.COM static void 26119089SVasumathi.Sundaram@Sun.COM ip_list_walk_fini(mdb_walk_state_t *wsp) 26129089SVasumathi.Sundaram@Sun.COM { 26139089SVasumathi.Sundaram@Sun.COM mdb_free(wsp->walk_data, sizeof (ip_list_walk_data_t)); 26149089SVasumathi.Sundaram@Sun.COM } 26159089SVasumathi.Sundaram@Sun.COM 26169089SVasumathi.Sundaram@Sun.COM static int 26179089SVasumathi.Sundaram@Sun.COM ipif_walk_init(mdb_walk_state_t *wsp) 26189089SVasumathi.Sundaram@Sun.COM { 26199089SVasumathi.Sundaram@Sun.COM if (mdb_layered_walk("ill", wsp) == -1) { 26209089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'ills'"); 26219089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 26229089SVasumathi.Sundaram@Sun.COM } 26239089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26249089SVasumathi.Sundaram@Sun.COM } 26259089SVasumathi.Sundaram@Sun.COM 26269089SVasumathi.Sundaram@Sun.COM static int 26279089SVasumathi.Sundaram@Sun.COM ipif_walk_step(mdb_walk_state_t *wsp) 26289089SVasumathi.Sundaram@Sun.COM { 26299089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("ipif_list", wsp->walk_callback, wsp->walk_cbdata, 26309089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 26319089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'ipif_list'"); 26329089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 26339089SVasumathi.Sundaram@Sun.COM } 26349089SVasumathi.Sundaram@Sun.COM 26359089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26369089SVasumathi.Sundaram@Sun.COM } 26379089SVasumathi.Sundaram@Sun.COM 26389089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 26399089SVasumathi.Sundaram@Sun.COM static int 26409089SVasumathi.Sundaram@Sun.COM ipif_cb(uintptr_t addr, const ipif_walk_data_t *iw, ipif_cbdata_t *id) 26419089SVasumathi.Sundaram@Sun.COM { 26429089SVasumathi.Sundaram@Sun.COM ipif_t ipif; 26439089SVasumathi.Sundaram@Sun.COM 26449089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ipif, sizeof (ipif_t), (uintptr_t)addr) == -1) { 26459089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ipif at %p", addr); 26469089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26479089SVasumathi.Sundaram@Sun.COM } 26489089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&id->ill, sizeof (ill_t), 26499089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipif.ipif_ill) == -1) { 26509089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", ipif.ipif_ill); 26519089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26529089SVasumathi.Sundaram@Sun.COM } 26539089SVasumathi.Sundaram@Sun.COM (void) ipif_format((uintptr_t)addr, &ipif, id); 26549089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26559089SVasumathi.Sundaram@Sun.COM } 26569089SVasumathi.Sundaram@Sun.COM 26579089SVasumathi.Sundaram@Sun.COM static void 26589089SVasumathi.Sundaram@Sun.COM ipif_header(boolean_t verbose) 26599089SVasumathi.Sundaram@Sun.COM { 26609089SVasumathi.Sundaram@Sun.COM if (verbose) { 26619089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-10s %-3s %-?s %-8s %-30s\n", 26629089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS"); 26639089SVasumathi.Sundaram@Sun.COM mdb_printf("%s\n%s\n", 26649089SVasumathi.Sundaram@Sun.COM "LCLADDR", "BROADCAST"); 26659089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 26669089SVasumathi.Sundaram@Sun.COM } else { 26679089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-10s %6s %-?s %-8s %-30s\n", 26689089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS"); 26699089SVasumathi.Sundaram@Sun.COM mdb_printf("%s\n%<u>%80s%</u>\n", "LCLADDR", ""); 26709089SVasumathi.Sundaram@Sun.COM } 26719089SVasumathi.Sundaram@Sun.COM } 26729089SVasumathi.Sundaram@Sun.COM 26739089SVasumathi.Sundaram@Sun.COM #ifdef _BIG_ENDIAN 26749089SVasumathi.Sundaram@Sun.COM #define ip_ntohl_32(x) ((x) & 0xffffffff) 26759089SVasumathi.Sundaram@Sun.COM #else 26769089SVasumathi.Sundaram@Sun.COM #define ip_ntohl_32(x) (((uint32_t)(x) << 24) | \ 26779089SVasumathi.Sundaram@Sun.COM (((uint32_t)(x) << 8) & 0xff0000) | \ 26789089SVasumathi.Sundaram@Sun.COM (((uint32_t)(x) >> 8) & 0xff00) | \ 26799089SVasumathi.Sundaram@Sun.COM ((uint32_t)(x) >> 24)) 26809089SVasumathi.Sundaram@Sun.COM #endif 26819089SVasumathi.Sundaram@Sun.COM 26829089SVasumathi.Sundaram@Sun.COM int 26839089SVasumathi.Sundaram@Sun.COM mask_to_prefixlen(int af, const in6_addr_t *addr) 26849089SVasumathi.Sundaram@Sun.COM { 26859089SVasumathi.Sundaram@Sun.COM int len = 0; 26869089SVasumathi.Sundaram@Sun.COM int i; 26879089SVasumathi.Sundaram@Sun.COM uint_t mask = 0; 26889089SVasumathi.Sundaram@Sun.COM 26899089SVasumathi.Sundaram@Sun.COM if (af == AF_INET6) { 26909089SVasumathi.Sundaram@Sun.COM for (i = 0; i < 4; i++) { 26919089SVasumathi.Sundaram@Sun.COM if (addr->s6_addr32[i] == 0xffffffff) { 26929089SVasumathi.Sundaram@Sun.COM len += 32; 26939089SVasumathi.Sundaram@Sun.COM } else { 26949089SVasumathi.Sundaram@Sun.COM mask = addr->s6_addr32[i]; 26959089SVasumathi.Sundaram@Sun.COM break; 26969089SVasumathi.Sundaram@Sun.COM } 26979089SVasumathi.Sundaram@Sun.COM } 26989089SVasumathi.Sundaram@Sun.COM } else { 26999089SVasumathi.Sundaram@Sun.COM mask = V4_PART_OF_V6((*addr)); 27009089SVasumathi.Sundaram@Sun.COM } 27019089SVasumathi.Sundaram@Sun.COM if (mask > 0) 27029089SVasumathi.Sundaram@Sun.COM len += (33 - mdb_ffs(ip_ntohl_32(mask))); 27039089SVasumathi.Sundaram@Sun.COM return (len); 27049089SVasumathi.Sundaram@Sun.COM } 27059089SVasumathi.Sundaram@Sun.COM 27069089SVasumathi.Sundaram@Sun.COM static int 27079089SVasumathi.Sundaram@Sun.COM ipif_format(uintptr_t addr, const void *ipifptr, void *ipif_cb_arg) 27089089SVasumathi.Sundaram@Sun.COM { 27099089SVasumathi.Sundaram@Sun.COM const ipif_t *ipif = ipifptr; 27109089SVasumathi.Sundaram@Sun.COM ipif_cbdata_t *ipifcb = ipif_cb_arg; 27119089SVasumathi.Sundaram@Sun.COM boolean_t verbose = ipifcb->verbose; 27129089SVasumathi.Sundaram@Sun.COM char ill_name[LIFNAMSIZ]; 27139089SVasumathi.Sundaram@Sun.COM char buf[LIFNAMSIZ]; 27149089SVasumathi.Sundaram@Sun.COM int cnt; 27159089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t sfmasks[] = { 27169089SVasumathi.Sundaram@Sun.COM { "CO", IPIF_CONDEMNED, IPIF_CONDEMNED}, 27179089SVasumathi.Sundaram@Sun.COM { "CH", IPIF_CHANGING, IPIF_CHANGING}, 27189089SVasumathi.Sundaram@Sun.COM { "SL", IPIF_SET_LINKLOCAL, IPIF_SET_LINKLOCAL}, 27199089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 27209089SVasumathi.Sundaram@Sun.COM }; 27219089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t fmasks[] = { 27229089SVasumathi.Sundaram@Sun.COM { "UP", IPIF_UP, IPIF_UP }, 27239089SVasumathi.Sundaram@Sun.COM { "UNN", IPIF_UNNUMBERED, IPIF_UNNUMBERED}, 27249089SVasumathi.Sundaram@Sun.COM { "DHCP", IPIF_DHCPRUNNING, IPIF_DHCPRUNNING}, 27259089SVasumathi.Sundaram@Sun.COM { "PRIV", IPIF_PRIVATE, IPIF_PRIVATE}, 27269089SVasumathi.Sundaram@Sun.COM { "NOXMT", IPIF_NOXMIT, IPIF_NOXMIT}, 27279089SVasumathi.Sundaram@Sun.COM { "NOLCL", IPIF_NOLOCAL, IPIF_NOLOCAL}, 27289089SVasumathi.Sundaram@Sun.COM { "DEPR", IPIF_DEPRECATED, IPIF_DEPRECATED}, 27299089SVasumathi.Sundaram@Sun.COM { "PREF", IPIF_PREFERRED, IPIF_PREFERRED}, 27309089SVasumathi.Sundaram@Sun.COM { "TEMP", IPIF_TEMPORARY, IPIF_TEMPORARY}, 27319089SVasumathi.Sundaram@Sun.COM { "ACONF", IPIF_ADDRCONF, IPIF_ADDRCONF}, 27329089SVasumathi.Sundaram@Sun.COM { "ANY", IPIF_ANYCAST, IPIF_ANYCAST}, 27339089SVasumathi.Sundaram@Sun.COM { "NFAIL", IPIF_NOFAILOVER, IPIF_NOFAILOVER}, 27349089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 27359089SVasumathi.Sundaram@Sun.COM }; 27369089SVasumathi.Sundaram@Sun.COM char flagsbuf[2 * A_CNT(fmasks)]; 27379089SVasumathi.Sundaram@Sun.COM char bitfields[A_CNT(fmasks)]; 27389089SVasumathi.Sundaram@Sun.COM char sflagsbuf[A_CNT(sfmasks)]; 27399089SVasumathi.Sundaram@Sun.COM char sbuf[DEFCOLS], addrstr[INET6_ADDRSTRLEN]; 27409089SVasumathi.Sundaram@Sun.COM int ipver = ipifcb->ipif_ipversion; 27419089SVasumathi.Sundaram@Sun.COM int af; 27429089SVasumathi.Sundaram@Sun.COM 27439089SVasumathi.Sundaram@Sun.COM if (ipver != 0) { 27449089SVasumathi.Sundaram@Sun.COM if ((ipver == IPV4_VERSION && ipifcb->ill.ill_isv6) || 27459089SVasumathi.Sundaram@Sun.COM (ipver == IPV6_VERSION && !ipifcb->ill.ill_isv6)) { 27469089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 27479089SVasumathi.Sundaram@Sun.COM } 27489089SVasumathi.Sundaram@Sun.COM } 27499089SVasumathi.Sundaram@Sun.COM if ((mdb_readstr(ill_name, MIN(LIFNAMSIZ, 27509089SVasumathi.Sundaram@Sun.COM ipifcb->ill.ill_name_length), 27519089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipifcb->ill.ill_name)) == -1) { 27529089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill_name of ill %p\n", ipifcb->ill); 27539089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 27549089SVasumathi.Sundaram@Sun.COM } 27559089SVasumathi.Sundaram@Sun.COM if (ipif->ipif_id != 0) { 27569089SVasumathi.Sundaram@Sun.COM mdb_snprintf(buf, LIFNAMSIZ, "%s:%d", 27579089SVasumathi.Sundaram@Sun.COM ill_name, ipif->ipif_id); 27589089SVasumathi.Sundaram@Sun.COM } else { 27599089SVasumathi.Sundaram@Sun.COM mdb_snprintf(buf, LIFNAMSIZ, "%s", ill_name); 27609089SVasumathi.Sundaram@Sun.COM } 27619089SVasumathi.Sundaram@Sun.COM mdb_snprintf(bitfields, sizeof (bitfields), "%s", 27629089SVasumathi.Sundaram@Sun.COM ipif->ipif_addr_ready ? ",ADR" : "", 27639089SVasumathi.Sundaram@Sun.COM ipif->ipif_was_up ? ",WU" : "", 276411042SErik.Nordmark@Sun.COM ipif->ipif_was_dup ? ",WD" : ""); 27659089SVasumathi.Sundaram@Sun.COM mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%llb%s", 27669089SVasumathi.Sundaram@Sun.COM ipif->ipif_flags, fmasks, bitfields); 27679089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sflagsbuf, sizeof (sflagsbuf), "%b", 27689089SVasumathi.Sundaram@Sun.COM ipif->ipif_state_flags, sfmasks); 27699089SVasumathi.Sundaram@Sun.COM 277011042SErik.Nordmark@Sun.COM cnt = ipif->ipif_refcnt; 27719089SVasumathi.Sundaram@Sun.COM 27729089SVasumathi.Sundaram@Sun.COM if (ipifcb->ill.ill_isv6) { 27739089SVasumathi.Sundaram@Sun.COM mdb_snprintf(addrstr, sizeof (addrstr), "%N", 27749089SVasumathi.Sundaram@Sun.COM &ipif->ipif_v6lcl_addr); 27759089SVasumathi.Sundaram@Sun.COM af = AF_INET6; 27769089SVasumathi.Sundaram@Sun.COM } else { 27779089SVasumathi.Sundaram@Sun.COM mdb_snprintf(addrstr, sizeof (addrstr), "%I", 27789089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((ipif->ipif_v6lcl_addr))); 27799089SVasumathi.Sundaram@Sun.COM af = AF_INET; 27809089SVasumathi.Sundaram@Sun.COM } 27819089SVasumathi.Sundaram@Sun.COM 27829089SVasumathi.Sundaram@Sun.COM if (verbose) { 27839089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-10s %3d %-?p %-8s %-30s\n", 27849089SVasumathi.Sundaram@Sun.COM addr, buf, cnt, ipif->ipif_ill, 27859089SVasumathi.Sundaram@Sun.COM sflagsbuf, flagsbuf); 27869089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sbuf, sizeof (sbuf), "%*s %12s", 27879089SVasumathi.Sundaram@Sun.COM sizeof (uintptr_t) * 2, "", ""); 27889089SVasumathi.Sundaram@Sun.COM mdb_printf("%s |\n%s +---> %4d %-15s " 27899089SVasumathi.Sundaram@Sun.COM "Active consistent reader cnt\n", 27909089SVasumathi.Sundaram@Sun.COM sbuf, sbuf, ipif->ipif_refcnt, "ipif_refcnt"); 27919089SVasumathi.Sundaram@Sun.COM mdb_printf("%-s/%d\n", 27929089SVasumathi.Sundaram@Sun.COM addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask)); 27939089SVasumathi.Sundaram@Sun.COM if (ipifcb->ill.ill_isv6) { 27949089SVasumathi.Sundaram@Sun.COM mdb_printf("%-N\n", &ipif->ipif_v6brd_addr); 27959089SVasumathi.Sundaram@Sun.COM } else { 27969089SVasumathi.Sundaram@Sun.COM mdb_printf("%-I\n", 27979089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((ipif->ipif_v6brd_addr))); 27989089SVasumathi.Sundaram@Sun.COM } 27999089SVasumathi.Sundaram@Sun.COM } else { 28009089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-10s %6d %-?p %-8s %-30s\n", 28019089SVasumathi.Sundaram@Sun.COM addr, buf, cnt, ipif->ipif_ill, 28029089SVasumathi.Sundaram@Sun.COM sflagsbuf, flagsbuf); 28039089SVasumathi.Sundaram@Sun.COM mdb_printf("%-s/%d\n", 28049089SVasumathi.Sundaram@Sun.COM addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask)); 28059089SVasumathi.Sundaram@Sun.COM } 28069089SVasumathi.Sundaram@Sun.COM 28079089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 28089089SVasumathi.Sundaram@Sun.COM } 28099089SVasumathi.Sundaram@Sun.COM 28109089SVasumathi.Sundaram@Sun.COM static int 28119089SVasumathi.Sundaram@Sun.COM ipif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 28129089SVasumathi.Sundaram@Sun.COM { 28139089SVasumathi.Sundaram@Sun.COM ipif_t ipif; 28149089SVasumathi.Sundaram@Sun.COM ipif_cbdata_t id; 28159089SVasumathi.Sundaram@Sun.COM int ipversion = 0; 28169089SVasumathi.Sundaram@Sun.COM const char *opt_P = NULL; 28179089SVasumathi.Sundaram@Sun.COM uint_t verbose = FALSE; 28189089SVasumathi.Sundaram@Sun.COM 28199089SVasumathi.Sundaram@Sun.COM if (mdb_getopts(argc, argv, 28209089SVasumathi.Sundaram@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 28219089SVasumathi.Sundaram@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 28229089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 28239089SVasumathi.Sundaram@Sun.COM 28249089SVasumathi.Sundaram@Sun.COM if (opt_P != NULL) { 28259089SVasumathi.Sundaram@Sun.COM if (strcmp("v4", opt_P) == 0) { 28269089SVasumathi.Sundaram@Sun.COM ipversion = IPV4_VERSION; 28279089SVasumathi.Sundaram@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 28289089SVasumathi.Sundaram@Sun.COM ipversion = IPV6_VERSION; 28299089SVasumathi.Sundaram@Sun.COM } else { 28309089SVasumathi.Sundaram@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 28319089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 28329089SVasumathi.Sundaram@Sun.COM } 28339089SVasumathi.Sundaram@Sun.COM } 28349089SVasumathi.Sundaram@Sun.COM 28359089SVasumathi.Sundaram@Sun.COM id.verbose = verbose; 28369089SVasumathi.Sundaram@Sun.COM id.ipif_ipversion = ipversion; 28379089SVasumathi.Sundaram@Sun.COM 28389089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 28399089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ipif, sizeof (ipif_t), addr) == -1) { 28409089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ipif at %p\n", addr); 28419089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 28429089SVasumathi.Sundaram@Sun.COM } 28439089SVasumathi.Sundaram@Sun.COM ipif_header(verbose); 28449089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&id.ill, sizeof (ill_t), 28459089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipif.ipif_ill) == -1) { 28469089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", ipif.ipif_ill); 28479089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 28489089SVasumathi.Sundaram@Sun.COM } 28499089SVasumathi.Sundaram@Sun.COM return (ipif_format(addr, &ipif, &id)); 28509089SVasumathi.Sundaram@Sun.COM } else { 28519089SVasumathi.Sundaram@Sun.COM ipif_header(verbose); 28529089SVasumathi.Sundaram@Sun.COM if (mdb_walk("ipif", (mdb_walk_cb_t)ipif_cb, &id) == -1) { 28539089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk ipifs\n"); 28549089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 28559089SVasumathi.Sundaram@Sun.COM } 28569089SVasumathi.Sundaram@Sun.COM } 28579089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 28589089SVasumathi.Sundaram@Sun.COM } 28599089SVasumathi.Sundaram@Sun.COM 28609089SVasumathi.Sundaram@Sun.COM static void 28619089SVasumathi.Sundaram@Sun.COM ipif_help(void) 28629089SVasumathi.Sundaram@Sun.COM { 28639089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints the following fields: ipif ptr, name, " 28649089SVasumathi.Sundaram@Sun.COM "count, ill ptr, state flags and ipif flags.\n" 28659089SVasumathi.Sundaram@Sun.COM "The count field is a sum of individual refcnts and is expanded " 28669089SVasumathi.Sundaram@Sun.COM "with the -v option.\n" 28679089SVasumathi.Sundaram@Sun.COM "The flags field shows the following:" 28689089SVasumathi.Sundaram@Sun.COM "\n\tUNN -> UNNUMBERED, DHCP -> DHCPRUNNING, PRIV -> PRIVATE, " 28699089SVasumathi.Sundaram@Sun.COM "\n\tNOXMT -> NOXMIT, NOLCL -> NOLOCAL, DEPR -> DEPRECATED, " 28709089SVasumathi.Sundaram@Sun.COM "\n\tPREF -> PREFERRED, TEMP -> TEMPORARY, ACONF -> ADDRCONF, " 28719089SVasumathi.Sundaram@Sun.COM "\n\tANY -> ANYCAST, NFAIL -> NOFAILOVER, " 28729089SVasumathi.Sundaram@Sun.COM "\n\tADR -> ipif_addr_ready, MU -> ipif_multicast_up, " 28739089SVasumathi.Sundaram@Sun.COM "\n\tWU -> ipif_was_up, WD -> ipif_was_dup, " 28749089SVasumathi.Sundaram@Sun.COM "JA -> ipif_joined_allhosts.\n\n"); 28759089SVasumathi.Sundaram@Sun.COM mdb_printf("Options:\n"); 28769089SVasumathi.Sundaram@Sun.COM mdb_printf("\t-P v4 | v6" 28779089SVasumathi.Sundaram@Sun.COM "\tfilter ipif structures on ills for the specified protocol\n"); 28789089SVasumathi.Sundaram@Sun.COM } 28799089SVasumathi.Sundaram@Sun.COM 28809089SVasumathi.Sundaram@Sun.COM static int 28819089SVasumathi.Sundaram@Sun.COM conn_status_walk_fanout(uintptr_t addr, mdb_walk_state_t *wsp, 28829089SVasumathi.Sundaram@Sun.COM const char *walkname) 28839089SVasumathi.Sundaram@Sun.COM { 28849089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk(walkname, wsp->walk_callback, wsp->walk_cbdata, 28859089SVasumathi.Sundaram@Sun.COM addr) == -1) { 28869089SVasumathi.Sundaram@Sun.COM mdb_warn("couldn't walk '%s' at %p", walkname, addr); 28879089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 28889089SVasumathi.Sundaram@Sun.COM } 28899089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 28909089SVasumathi.Sundaram@Sun.COM } 28919089SVasumathi.Sundaram@Sun.COM 28929089SVasumathi.Sundaram@Sun.COM static int 28939089SVasumathi.Sundaram@Sun.COM conn_status_walk_step(mdb_walk_state_t *wsp) 28949089SVasumathi.Sundaram@Sun.COM { 28959089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr; 28969089SVasumathi.Sundaram@Sun.COM 28979089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "udp_hash"); 28989089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "conn_hash"); 28999089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "bind_hash"); 29009089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "proto_hash"); 29019089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "proto_v6_hash"); 29029089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 29039089SVasumathi.Sundaram@Sun.COM } 29049089SVasumathi.Sundaram@Sun.COM 29059089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 29069089SVasumathi.Sundaram@Sun.COM static int 29079089SVasumathi.Sundaram@Sun.COM conn_status_cb(uintptr_t addr, const void *walk_data, 29089089SVasumathi.Sundaram@Sun.COM void *private) 29099089SVasumathi.Sundaram@Sun.COM { 29109089SVasumathi.Sundaram@Sun.COM netstack_t nss; 29119089SVasumathi.Sundaram@Sun.COM char src_addrstr[INET6_ADDRSTRLEN]; 29129089SVasumathi.Sundaram@Sun.COM char rem_addrstr[INET6_ADDRSTRLEN]; 29139089SVasumathi.Sundaram@Sun.COM const ipcl_hash_walk_data_t *iw = walk_data; 29149089SVasumathi.Sundaram@Sun.COM conn_t *conn = iw->conn; 29159089SVasumathi.Sundaram@Sun.COM 29169089SVasumathi.Sundaram@Sun.COM if (mdb_vread(conn, sizeof (conn_t), addr) == -1) { 29179089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", addr); 29189089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 29199089SVasumathi.Sundaram@Sun.COM } 29209089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&nss, sizeof (nss), 29219089SVasumathi.Sundaram@Sun.COM (uintptr_t)conn->conn_netstack) == -1) { 29229089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read netstack_t %p", 29239089SVasumathi.Sundaram@Sun.COM conn->conn_netstack); 29249089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 29259089SVasumathi.Sundaram@Sun.COM } 29269089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-?p %?d %?d\n", addr, conn->conn_wq, 29279089SVasumathi.Sundaram@Sun.COM nss.netstack_stackid, conn->conn_zoneid); 29289089SVasumathi.Sundaram@Sun.COM 292911042SErik.Nordmark@Sun.COM if (conn->conn_family == AF_INET6) { 29309089SVasumathi.Sundaram@Sun.COM mdb_snprintf(src_addrstr, sizeof (rem_addrstr), "%N", 293111042SErik.Nordmark@Sun.COM &conn->conn_laddr_v6); 29329089SVasumathi.Sundaram@Sun.COM mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%N", 293311042SErik.Nordmark@Sun.COM &conn->conn_faddr_v6); 29349089SVasumathi.Sundaram@Sun.COM } else { 29359089SVasumathi.Sundaram@Sun.COM mdb_snprintf(src_addrstr, sizeof (src_addrstr), "%I", 293611042SErik.Nordmark@Sun.COM V4_PART_OF_V6((conn->conn_laddr_v6))); 29379089SVasumathi.Sundaram@Sun.COM mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%I", 293811042SErik.Nordmark@Sun.COM V4_PART_OF_V6((conn->conn_faddr_v6))); 29399089SVasumathi.Sundaram@Sun.COM } 29409089SVasumathi.Sundaram@Sun.COM mdb_printf("%s:%-5d\n%s:%-5d\n", 29419089SVasumathi.Sundaram@Sun.COM src_addrstr, conn->conn_lport, rem_addrstr, conn->conn_fport); 29429089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 29439089SVasumathi.Sundaram@Sun.COM } 29449089SVasumathi.Sundaram@Sun.COM 29459089SVasumathi.Sundaram@Sun.COM static void 29469089SVasumathi.Sundaram@Sun.COM conn_header(void) 29479089SVasumathi.Sundaram@Sun.COM { 29489089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-?s %?s %?s\n%s\n%s\n", 29499089SVasumathi.Sundaram@Sun.COM "ADDR", "WQ", "STACK", "ZONE", "SRC:PORT", "DEST:PORT"); 29509089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 29519089SVasumathi.Sundaram@Sun.COM } 29529089SVasumathi.Sundaram@Sun.COM 29539089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/ 29549089SVasumathi.Sundaram@Sun.COM static int 29559089SVasumathi.Sundaram@Sun.COM conn_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 29569089SVasumathi.Sundaram@Sun.COM { 29579089SVasumathi.Sundaram@Sun.COM conn_header(); 29589089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 29599089SVasumathi.Sundaram@Sun.COM (void) conn_status_cb(addr, NULL, NULL); 29609089SVasumathi.Sundaram@Sun.COM } else { 29619089SVasumathi.Sundaram@Sun.COM if (mdb_walk("conn_status", (mdb_walk_cb_t)conn_status_cb, 29629089SVasumathi.Sundaram@Sun.COM NULL) == -1) { 29639089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk conn_fanout"); 29649089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 29659089SVasumathi.Sundaram@Sun.COM } 29669089SVasumathi.Sundaram@Sun.COM } 29679089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 29689089SVasumathi.Sundaram@Sun.COM } 29699089SVasumathi.Sundaram@Sun.COM 29709089SVasumathi.Sundaram@Sun.COM static void 29719089SVasumathi.Sundaram@Sun.COM conn_status_help(void) 29729089SVasumathi.Sundaram@Sun.COM { 29739089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints conn_t structures from the following hash tables: " 29749089SVasumathi.Sundaram@Sun.COM "\n\tips_ipcl_udp_fanout\n\tips_ipcl_bind_fanout" 297511042SErik.Nordmark@Sun.COM "\n\tips_ipcl_conn_fanout\n\tips_ipcl_proto_fanout_v4" 29769089SVasumathi.Sundaram@Sun.COM "\n\tips_ipcl_proto_fanout_v6\n"); 29779089SVasumathi.Sundaram@Sun.COM } 29789089SVasumathi.Sundaram@Sun.COM 29799089SVasumathi.Sundaram@Sun.COM static int 29809089SVasumathi.Sundaram@Sun.COM srcid_walk_step(mdb_walk_state_t *wsp) 29819089SVasumathi.Sundaram@Sun.COM { 29829089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("srcid_list", wsp->walk_callback, wsp->walk_cbdata, 29839089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 29849089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'srcid_list'"); 29859089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 29869089SVasumathi.Sundaram@Sun.COM } 29879089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 29889089SVasumathi.Sundaram@Sun.COM } 29899089SVasumathi.Sundaram@Sun.COM 29909089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 29919089SVasumathi.Sundaram@Sun.COM static int 29929089SVasumathi.Sundaram@Sun.COM srcid_status_cb(uintptr_t addr, const void *walk_data, 29939089SVasumathi.Sundaram@Sun.COM void *private) 29949089SVasumathi.Sundaram@Sun.COM { 29959089SVasumathi.Sundaram@Sun.COM srcid_map_t smp; 29969089SVasumathi.Sundaram@Sun.COM 29979089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&smp, sizeof (srcid_map_t), addr) == -1) { 29989089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read srcid_map at %p", addr); 29999089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 30009089SVasumathi.Sundaram@Sun.COM } 30019089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %3d %4d %6d %N\n", 30029089SVasumathi.Sundaram@Sun.COM addr, smp.sm_srcid, smp.sm_zoneid, smp.sm_refcnt, 30039089SVasumathi.Sundaram@Sun.COM &smp.sm_addr); 30049089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 30059089SVasumathi.Sundaram@Sun.COM } 30069089SVasumathi.Sundaram@Sun.COM 30079089SVasumathi.Sundaram@Sun.COM static void 30089089SVasumathi.Sundaram@Sun.COM srcid_header(void) 30099089SVasumathi.Sundaram@Sun.COM { 30109089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %3s %4s %6s %s\n", 30119089SVasumathi.Sundaram@Sun.COM "ADDR", "ID", "ZONE", "REFCNT", "IPADDR"); 30129089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 30139089SVasumathi.Sundaram@Sun.COM } 30149089SVasumathi.Sundaram@Sun.COM 30159089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/ 30169089SVasumathi.Sundaram@Sun.COM static int 30179089SVasumathi.Sundaram@Sun.COM srcid_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 30189089SVasumathi.Sundaram@Sun.COM { 30199089SVasumathi.Sundaram@Sun.COM srcid_header(); 30209089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 30219089SVasumathi.Sundaram@Sun.COM (void) srcid_status_cb(addr, NULL, NULL); 30229089SVasumathi.Sundaram@Sun.COM } else { 30239089SVasumathi.Sundaram@Sun.COM if (mdb_walk("srcid", (mdb_walk_cb_t)srcid_status_cb, 30249089SVasumathi.Sundaram@Sun.COM NULL) == -1) { 30259089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk srcid_map"); 30269089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 30279089SVasumathi.Sundaram@Sun.COM } 30289089SVasumathi.Sundaram@Sun.COM } 30299089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 30309089SVasumathi.Sundaram@Sun.COM } 303110946SSangeeta.Misra@Sun.COM 303210946SSangeeta.Misra@Sun.COM static int 303310946SSangeeta.Misra@Sun.COM ilb_stacks_walk_step(mdb_walk_state_t *wsp) 303410946SSangeeta.Misra@Sun.COM { 3035*11754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_ILB)); 303610946SSangeeta.Misra@Sun.COM } 303710946SSangeeta.Misra@Sun.COM 303810946SSangeeta.Misra@Sun.COM static int 303910946SSangeeta.Misra@Sun.COM ilb_rules_walk_init(mdb_walk_state_t *wsp) 304010946SSangeeta.Misra@Sun.COM { 304110946SSangeeta.Misra@Sun.COM ilb_stack_t ilbs; 304210946SSangeeta.Misra@Sun.COM 304310946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 304410946SSangeeta.Misra@Sun.COM return (WALK_ERR); 304510946SSangeeta.Misra@Sun.COM 304610946SSangeeta.Misra@Sun.COM if (mdb_vread(&ilbs, sizeof (ilbs), wsp->walk_addr) == -1) { 304710946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 304810946SSangeeta.Misra@Sun.COM return (WALK_ERR); 304910946SSangeeta.Misra@Sun.COM } 305010946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)ilbs.ilbs_rule_head) != NULL) 305110946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 305210946SSangeeta.Misra@Sun.COM else 305310946SSangeeta.Misra@Sun.COM return (WALK_DONE); 305410946SSangeeta.Misra@Sun.COM } 305510946SSangeeta.Misra@Sun.COM 305610946SSangeeta.Misra@Sun.COM static int 305710946SSangeeta.Misra@Sun.COM ilb_rules_walk_step(mdb_walk_state_t *wsp) 305810946SSangeeta.Misra@Sun.COM { 305910946SSangeeta.Misra@Sun.COM ilb_rule_t rule; 306010946SSangeeta.Misra@Sun.COM int status; 306110946SSangeeta.Misra@Sun.COM 306210946SSangeeta.Misra@Sun.COM if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) { 306310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr); 306410946SSangeeta.Misra@Sun.COM return (WALK_ERR); 306510946SSangeeta.Misra@Sun.COM } 306610946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &rule, wsp->walk_cbdata); 306710946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 306810946SSangeeta.Misra@Sun.COM return (status); 306910946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)rule.ir_next) == NULL) 307010946SSangeeta.Misra@Sun.COM return (WALK_DONE); 307110946SSangeeta.Misra@Sun.COM else 307210946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 307310946SSangeeta.Misra@Sun.COM } 307410946SSangeeta.Misra@Sun.COM 307510946SSangeeta.Misra@Sun.COM static int 307610946SSangeeta.Misra@Sun.COM ilb_servers_walk_init(mdb_walk_state_t *wsp) 307710946SSangeeta.Misra@Sun.COM { 307810946SSangeeta.Misra@Sun.COM ilb_rule_t rule; 307910946SSangeeta.Misra@Sun.COM 308010946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 308110946SSangeeta.Misra@Sun.COM return (WALK_ERR); 308210946SSangeeta.Misra@Sun.COM 308310946SSangeeta.Misra@Sun.COM if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) { 308410946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr); 308510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 308610946SSangeeta.Misra@Sun.COM } 308710946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)rule.ir_servers) != NULL) 308810946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 308910946SSangeeta.Misra@Sun.COM else 309010946SSangeeta.Misra@Sun.COM return (WALK_DONE); 309110946SSangeeta.Misra@Sun.COM } 309210946SSangeeta.Misra@Sun.COM 309310946SSangeeta.Misra@Sun.COM static int 309410946SSangeeta.Misra@Sun.COM ilb_servers_walk_step(mdb_walk_state_t *wsp) 309510946SSangeeta.Misra@Sun.COM { 309610946SSangeeta.Misra@Sun.COM ilb_server_t server; 309710946SSangeeta.Misra@Sun.COM int status; 309810946SSangeeta.Misra@Sun.COM 309910946SSangeeta.Misra@Sun.COM if (mdb_vread(&server, sizeof (server), wsp->walk_addr) == -1) { 310010946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_server_t at %p", wsp->walk_addr); 310110946SSangeeta.Misra@Sun.COM return (WALK_ERR); 310210946SSangeeta.Misra@Sun.COM } 310310946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &server, wsp->walk_cbdata); 310410946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 310510946SSangeeta.Misra@Sun.COM return (status); 310610946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)server.iser_next) == NULL) 310710946SSangeeta.Misra@Sun.COM return (WALK_DONE); 310810946SSangeeta.Misra@Sun.COM else 310910946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 311010946SSangeeta.Misra@Sun.COM } 311110946SSangeeta.Misra@Sun.COM 311210946SSangeeta.Misra@Sun.COM /* 311310946SSangeeta.Misra@Sun.COM * Helper structure for ilb_nat_src walker. It stores the current index of the 311410946SSangeeta.Misra@Sun.COM * nat src table. 311510946SSangeeta.Misra@Sun.COM */ 311610946SSangeeta.Misra@Sun.COM typedef struct { 311710946SSangeeta.Misra@Sun.COM ilb_stack_t ilbs; 311810946SSangeeta.Misra@Sun.COM int idx; 311910946SSangeeta.Misra@Sun.COM } ilb_walk_t; 312010946SSangeeta.Misra@Sun.COM 312110946SSangeeta.Misra@Sun.COM /* Copy from list.c */ 312210946SSangeeta.Misra@Sun.COM #define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset)) 312310946SSangeeta.Misra@Sun.COM 312410946SSangeeta.Misra@Sun.COM static int 312510946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_init(mdb_walk_state_t *wsp) 312610946SSangeeta.Misra@Sun.COM { 312710946SSangeeta.Misra@Sun.COM int i; 312810946SSangeeta.Misra@Sun.COM ilb_walk_t *ns_walk; 312910946SSangeeta.Misra@Sun.COM ilb_nat_src_entry_t *entry = NULL; 313010946SSangeeta.Misra@Sun.COM 313110946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 313210946SSangeeta.Misra@Sun.COM return (WALK_ERR); 313310946SSangeeta.Misra@Sun.COM 313410946SSangeeta.Misra@Sun.COM ns_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP); 313510946SSangeeta.Misra@Sun.COM if (mdb_vread(&ns_walk->ilbs, sizeof (ns_walk->ilbs), 313610946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 313710946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 313810946SSangeeta.Misra@Sun.COM mdb_free(ns_walk, sizeof (ilb_walk_t)); 313910946SSangeeta.Misra@Sun.COM return (WALK_ERR); 314010946SSangeeta.Misra@Sun.COM } 314110946SSangeeta.Misra@Sun.COM 314210946SSangeeta.Misra@Sun.COM if (ns_walk->ilbs.ilbs_nat_src == NULL) { 314310946SSangeeta.Misra@Sun.COM mdb_free(ns_walk, sizeof (ilb_walk_t)); 314410946SSangeeta.Misra@Sun.COM return (WALK_DONE); 314510946SSangeeta.Misra@Sun.COM } 314610946SSangeeta.Misra@Sun.COM 314710946SSangeeta.Misra@Sun.COM wsp->walk_data = ns_walk; 314810946SSangeeta.Misra@Sun.COM for (i = 0; i < ns_walk->ilbs.ilbs_nat_src_hash_size; i++) { 314910946SSangeeta.Misra@Sun.COM list_t head; 315010946SSangeeta.Misra@Sun.COM char *khead; 315110946SSangeeta.Misra@Sun.COM 315210946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 315310946SSangeeta.Misra@Sun.COM khead = (char *)ns_walk->ilbs.ilbs_nat_src + i * 315410946SSangeeta.Misra@Sun.COM sizeof (ilb_nat_src_hash_t); 315510946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 315610946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead); 315710946SSangeeta.Misra@Sun.COM return (WALK_ERR); 315810946SSangeeta.Misra@Sun.COM } 315910946SSangeeta.Misra@Sun.COM 316010946SSangeeta.Misra@Sun.COM /* 316110946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need 316210946SSangeeta.Misra@Sun.COM * to compare list_next with the kernel address of the list 316310946SSangeeta.Misra@Sun.COM * head. So we need to calculate the address manually. 316410946SSangeeta.Misra@Sun.COM */ 316510946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 316610946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 316710946SSangeeta.Misra@Sun.COM entry = list_object(&head, head.list_head.list_next); 316810946SSangeeta.Misra@Sun.COM break; 316910946SSangeeta.Misra@Sun.COM } 317010946SSangeeta.Misra@Sun.COM } 317110946SSangeeta.Misra@Sun.COM 317210946SSangeeta.Misra@Sun.COM if (entry == NULL) 317310946SSangeeta.Misra@Sun.COM return (WALK_DONE); 317410946SSangeeta.Misra@Sun.COM 317510946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)entry; 317610946SSangeeta.Misra@Sun.COM ns_walk->idx = i; 317710946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 317810946SSangeeta.Misra@Sun.COM } 317910946SSangeeta.Misra@Sun.COM 318010946SSangeeta.Misra@Sun.COM static int 318110946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_step(mdb_walk_state_t *wsp) 318210946SSangeeta.Misra@Sun.COM { 318310946SSangeeta.Misra@Sun.COM int status; 318410946SSangeeta.Misra@Sun.COM ilb_nat_src_entry_t entry, *next_entry; 318510946SSangeeta.Misra@Sun.COM ilb_walk_t *ns_walk; 318610946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs; 318710946SSangeeta.Misra@Sun.COM list_t head; 318810946SSangeeta.Misra@Sun.COM char *khead; 318910946SSangeeta.Misra@Sun.COM int i; 319010946SSangeeta.Misra@Sun.COM 319110946SSangeeta.Misra@Sun.COM if (mdb_vread(&entry, sizeof (ilb_nat_src_entry_t), 319210946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 319310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_nat_src_entry_t at %p", 319410946SSangeeta.Misra@Sun.COM wsp->walk_addr); 319510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 319610946SSangeeta.Misra@Sun.COM } 319710946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &entry, wsp->walk_cbdata); 319810946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 319910946SSangeeta.Misra@Sun.COM return (status); 320010946SSangeeta.Misra@Sun.COM 320110946SSangeeta.Misra@Sun.COM ns_walk = (ilb_walk_t *)wsp->walk_data; 320210946SSangeeta.Misra@Sun.COM ilbs = &ns_walk->ilbs; 320310946SSangeeta.Misra@Sun.COM i = ns_walk->idx; 320410946SSangeeta.Misra@Sun.COM 320510946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 320610946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_nat_src + i * sizeof (ilb_nat_src_hash_t); 320710946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 320810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead); 320910946SSangeeta.Misra@Sun.COM return (WALK_ERR); 321010946SSangeeta.Misra@Sun.COM } 321110946SSangeeta.Misra@Sun.COM 321210946SSangeeta.Misra@Sun.COM /* 321310946SSangeeta.Misra@Sun.COM * Check if there is still entry in the current list. 321410946SSangeeta.Misra@Sun.COM * 321510946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need to 321610946SSangeeta.Misra@Sun.COM * compare list_next with the kernel address of the list head. 321710946SSangeeta.Misra@Sun.COM * So we need to calculate the address manually. 321810946SSangeeta.Misra@Sun.COM */ 321910946SSangeeta.Misra@Sun.COM if ((char *)entry.nse_link.list_next != khead + offsetof(list_t, 322010946SSangeeta.Misra@Sun.COM list_head)) { 322110946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)list_object(&head, 322210946SSangeeta.Misra@Sun.COM entry.nse_link.list_next); 322310946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 322410946SSangeeta.Misra@Sun.COM } 322510946SSangeeta.Misra@Sun.COM 322610946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */ 322710946SSangeeta.Misra@Sun.COM next_entry = NULL; 322810946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) { 322910946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_nat_src + i * 323010946SSangeeta.Misra@Sun.COM sizeof (ilb_nat_src_hash_t); 323110946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 323210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead); 323310946SSangeeta.Misra@Sun.COM return (WALK_ERR); 323410946SSangeeta.Misra@Sun.COM } 323510946SSangeeta.Misra@Sun.COM 323610946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 323710946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 323810946SSangeeta.Misra@Sun.COM next_entry = list_object(&head, 323910946SSangeeta.Misra@Sun.COM head.list_head.list_next); 324010946SSangeeta.Misra@Sun.COM break; 324110946SSangeeta.Misra@Sun.COM } 324210946SSangeeta.Misra@Sun.COM } 324310946SSangeeta.Misra@Sun.COM 324410946SSangeeta.Misra@Sun.COM if (next_entry == NULL) 324510946SSangeeta.Misra@Sun.COM return (WALK_DONE); 324610946SSangeeta.Misra@Sun.COM 324710946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)next_entry; 324810946SSangeeta.Misra@Sun.COM ns_walk->idx = i; 324910946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 325010946SSangeeta.Misra@Sun.COM } 325110946SSangeeta.Misra@Sun.COM 325210946SSangeeta.Misra@Sun.COM static void 325310946SSangeeta.Misra@Sun.COM ilb_common_walk_fini(mdb_walk_state_t *wsp) 325410946SSangeeta.Misra@Sun.COM { 325510946SSangeeta.Misra@Sun.COM ilb_walk_t *walk; 325610946SSangeeta.Misra@Sun.COM 325710946SSangeeta.Misra@Sun.COM walk = (ilb_walk_t *)wsp->walk_data; 325810946SSangeeta.Misra@Sun.COM if (walk == NULL) 325910946SSangeeta.Misra@Sun.COM return; 326010946SSangeeta.Misra@Sun.COM mdb_free(walk, sizeof (ilb_walk_t *)); 326110946SSangeeta.Misra@Sun.COM } 326210946SSangeeta.Misra@Sun.COM 326310946SSangeeta.Misra@Sun.COM static int 326410946SSangeeta.Misra@Sun.COM ilb_conn_walk_init(mdb_walk_state_t *wsp) 326510946SSangeeta.Misra@Sun.COM { 326610946SSangeeta.Misra@Sun.COM int i; 326710946SSangeeta.Misra@Sun.COM ilb_walk_t *conn_walk; 326810946SSangeeta.Misra@Sun.COM ilb_conn_hash_t head; 326910946SSangeeta.Misra@Sun.COM 327010946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 327110946SSangeeta.Misra@Sun.COM return (WALK_ERR); 327210946SSangeeta.Misra@Sun.COM 327310946SSangeeta.Misra@Sun.COM conn_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP); 327410946SSangeeta.Misra@Sun.COM if (mdb_vread(&conn_walk->ilbs, sizeof (conn_walk->ilbs), 327510946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 327610946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 327710946SSangeeta.Misra@Sun.COM mdb_free(conn_walk, sizeof (ilb_walk_t)); 327810946SSangeeta.Misra@Sun.COM return (WALK_ERR); 327910946SSangeeta.Misra@Sun.COM } 328010946SSangeeta.Misra@Sun.COM 328110946SSangeeta.Misra@Sun.COM if (conn_walk->ilbs.ilbs_c2s_conn_hash == NULL) { 328210946SSangeeta.Misra@Sun.COM mdb_free(conn_walk, sizeof (ilb_walk_t)); 328310946SSangeeta.Misra@Sun.COM return (WALK_DONE); 328410946SSangeeta.Misra@Sun.COM } 328510946SSangeeta.Misra@Sun.COM 328610946SSangeeta.Misra@Sun.COM wsp->walk_data = conn_walk; 328710946SSangeeta.Misra@Sun.COM for (i = 0; i < conn_walk->ilbs.ilbs_conn_hash_size; i++) { 328810946SSangeeta.Misra@Sun.COM char *khead; 328910946SSangeeta.Misra@Sun.COM 329010946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 329110946SSangeeta.Misra@Sun.COM khead = (char *)conn_walk->ilbs.ilbs_c2s_conn_hash + i * 329210946SSangeeta.Misra@Sun.COM sizeof (ilb_conn_hash_t); 329310946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (ilb_conn_hash_t), 329410946SSangeeta.Misra@Sun.COM (uintptr_t)khead) == -1) { 329510946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n", 329610946SSangeeta.Misra@Sun.COM khead); 329710946SSangeeta.Misra@Sun.COM return (WALK_ERR); 329810946SSangeeta.Misra@Sun.COM } 329910946SSangeeta.Misra@Sun.COM 330010946SSangeeta.Misra@Sun.COM if (head.ilb_connp != NULL) 330110946SSangeeta.Misra@Sun.COM break; 330210946SSangeeta.Misra@Sun.COM } 330310946SSangeeta.Misra@Sun.COM 330410946SSangeeta.Misra@Sun.COM if (head.ilb_connp == NULL) 330510946SSangeeta.Misra@Sun.COM return (WALK_DONE); 330610946SSangeeta.Misra@Sun.COM 330710946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)head.ilb_connp; 330810946SSangeeta.Misra@Sun.COM conn_walk->idx = i; 330910946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 331010946SSangeeta.Misra@Sun.COM } 331110946SSangeeta.Misra@Sun.COM 331210946SSangeeta.Misra@Sun.COM static int 331310946SSangeeta.Misra@Sun.COM ilb_conn_walk_step(mdb_walk_state_t *wsp) 331410946SSangeeta.Misra@Sun.COM { 331510946SSangeeta.Misra@Sun.COM int status; 331610946SSangeeta.Misra@Sun.COM ilb_conn_t conn; 331710946SSangeeta.Misra@Sun.COM ilb_walk_t *conn_walk; 331810946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs; 331910946SSangeeta.Misra@Sun.COM ilb_conn_hash_t head; 332010946SSangeeta.Misra@Sun.COM char *khead; 332110946SSangeeta.Misra@Sun.COM int i; 332210946SSangeeta.Misra@Sun.COM 332310946SSangeeta.Misra@Sun.COM if (mdb_vread(&conn, sizeof (ilb_conn_t), wsp->walk_addr) == -1) { 332410946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_conn_t at %p", wsp->walk_addr); 332510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 332610946SSangeeta.Misra@Sun.COM } 332710946SSangeeta.Misra@Sun.COM 332810946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &conn, wsp->walk_cbdata); 332910946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 333010946SSangeeta.Misra@Sun.COM return (status); 333110946SSangeeta.Misra@Sun.COM 333210946SSangeeta.Misra@Sun.COM conn_walk = (ilb_walk_t *)wsp->walk_data; 333310946SSangeeta.Misra@Sun.COM ilbs = &conn_walk->ilbs; 333410946SSangeeta.Misra@Sun.COM i = conn_walk->idx; 333510946SSangeeta.Misra@Sun.COM 333610946SSangeeta.Misra@Sun.COM /* Check if there is still entry in the current list. */ 333710946SSangeeta.Misra@Sun.COM if (conn.conn_c2s_next != NULL) { 333810946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)conn.conn_c2s_next; 333910946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 334010946SSangeeta.Misra@Sun.COM } 334110946SSangeeta.Misra@Sun.COM 334210946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */ 334310946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_conn_hash_size; i++) { 334410946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_c2s_conn_hash + i * 334510946SSangeeta.Misra@Sun.COM sizeof (ilb_conn_hash_t); 334610946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (ilb_conn_hash_t), 334710946SSangeeta.Misra@Sun.COM (uintptr_t)khead) == -1) { 334810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n", 334910946SSangeeta.Misra@Sun.COM khead); 335010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 335110946SSangeeta.Misra@Sun.COM } 335210946SSangeeta.Misra@Sun.COM 335310946SSangeeta.Misra@Sun.COM if (head.ilb_connp != NULL) 335410946SSangeeta.Misra@Sun.COM break; 335510946SSangeeta.Misra@Sun.COM } 335610946SSangeeta.Misra@Sun.COM 335710946SSangeeta.Misra@Sun.COM if (head.ilb_connp == NULL) 335810946SSangeeta.Misra@Sun.COM return (WALK_DONE); 335910946SSangeeta.Misra@Sun.COM 336010946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)head.ilb_connp; 336110946SSangeeta.Misra@Sun.COM conn_walk->idx = i; 336210946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 336310946SSangeeta.Misra@Sun.COM } 336410946SSangeeta.Misra@Sun.COM 336510946SSangeeta.Misra@Sun.COM static int 336610946SSangeeta.Misra@Sun.COM ilb_sticky_walk_init(mdb_walk_state_t *wsp) 336710946SSangeeta.Misra@Sun.COM { 336810946SSangeeta.Misra@Sun.COM int i; 336910946SSangeeta.Misra@Sun.COM ilb_walk_t *sticky_walk; 337010946SSangeeta.Misra@Sun.COM ilb_sticky_t *st = NULL; 337110946SSangeeta.Misra@Sun.COM 337210946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 337310946SSangeeta.Misra@Sun.COM return (WALK_ERR); 337410946SSangeeta.Misra@Sun.COM 337510946SSangeeta.Misra@Sun.COM sticky_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP); 337610946SSangeeta.Misra@Sun.COM if (mdb_vread(&sticky_walk->ilbs, sizeof (sticky_walk->ilbs), 337710946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 337810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 337910946SSangeeta.Misra@Sun.COM mdb_free(sticky_walk, sizeof (ilb_walk_t)); 338010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 338110946SSangeeta.Misra@Sun.COM } 338210946SSangeeta.Misra@Sun.COM 338310946SSangeeta.Misra@Sun.COM if (sticky_walk->ilbs.ilbs_sticky_hash == NULL) { 338410946SSangeeta.Misra@Sun.COM mdb_free(sticky_walk, sizeof (ilb_walk_t)); 338510946SSangeeta.Misra@Sun.COM return (WALK_DONE); 338610946SSangeeta.Misra@Sun.COM } 338710946SSangeeta.Misra@Sun.COM 338810946SSangeeta.Misra@Sun.COM wsp->walk_data = sticky_walk; 338910946SSangeeta.Misra@Sun.COM for (i = 0; i < sticky_walk->ilbs.ilbs_sticky_hash_size; i++) { 339010946SSangeeta.Misra@Sun.COM list_t head; 339110946SSangeeta.Misra@Sun.COM char *khead; 339210946SSangeeta.Misra@Sun.COM 339310946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 339410946SSangeeta.Misra@Sun.COM khead = (char *)sticky_walk->ilbs.ilbs_sticky_hash + i * 339510946SSangeeta.Misra@Sun.COM sizeof (ilb_sticky_hash_t); 339610946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 339710946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", 339810946SSangeeta.Misra@Sun.COM khead); 339910946SSangeeta.Misra@Sun.COM return (WALK_ERR); 340010946SSangeeta.Misra@Sun.COM } 340110946SSangeeta.Misra@Sun.COM 340210946SSangeeta.Misra@Sun.COM /* 340310946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need 340410946SSangeeta.Misra@Sun.COM * to compare list_next with the kernel address of the list 340510946SSangeeta.Misra@Sun.COM * head. So we need to calculate the address manually. 340610946SSangeeta.Misra@Sun.COM */ 340710946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 340810946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 340910946SSangeeta.Misra@Sun.COM st = list_object(&head, head.list_head.list_next); 341010946SSangeeta.Misra@Sun.COM break; 341110946SSangeeta.Misra@Sun.COM } 341210946SSangeeta.Misra@Sun.COM } 341310946SSangeeta.Misra@Sun.COM 341410946SSangeeta.Misra@Sun.COM if (st == NULL) 341510946SSangeeta.Misra@Sun.COM return (WALK_DONE); 341610946SSangeeta.Misra@Sun.COM 341710946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)st; 341810946SSangeeta.Misra@Sun.COM sticky_walk->idx = i; 341910946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 342010946SSangeeta.Misra@Sun.COM } 342110946SSangeeta.Misra@Sun.COM 342210946SSangeeta.Misra@Sun.COM static int 342310946SSangeeta.Misra@Sun.COM ilb_sticky_walk_step(mdb_walk_state_t *wsp) 342410946SSangeeta.Misra@Sun.COM { 342510946SSangeeta.Misra@Sun.COM int status; 342610946SSangeeta.Misra@Sun.COM ilb_sticky_t st, *st_next; 342710946SSangeeta.Misra@Sun.COM ilb_walk_t *sticky_walk; 342810946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs; 342910946SSangeeta.Misra@Sun.COM list_t head; 343010946SSangeeta.Misra@Sun.COM char *khead; 343110946SSangeeta.Misra@Sun.COM int i; 343210946SSangeeta.Misra@Sun.COM 343310946SSangeeta.Misra@Sun.COM if (mdb_vread(&st, sizeof (ilb_sticky_t), wsp->walk_addr) == -1) { 343410946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_sticky_t at %p", wsp->walk_addr); 343510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 343610946SSangeeta.Misra@Sun.COM } 343710946SSangeeta.Misra@Sun.COM 343810946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &st, wsp->walk_cbdata); 343910946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 344010946SSangeeta.Misra@Sun.COM return (status); 344110946SSangeeta.Misra@Sun.COM 344210946SSangeeta.Misra@Sun.COM sticky_walk = (ilb_walk_t *)wsp->walk_data; 344310946SSangeeta.Misra@Sun.COM ilbs = &sticky_walk->ilbs; 344410946SSangeeta.Misra@Sun.COM i = sticky_walk->idx; 344510946SSangeeta.Misra@Sun.COM 344610946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 344710946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_sticky_hash + i * sizeof (ilb_sticky_hash_t); 344810946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 344910946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", khead); 345010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 345110946SSangeeta.Misra@Sun.COM } 345210946SSangeeta.Misra@Sun.COM 345310946SSangeeta.Misra@Sun.COM /* 345410946SSangeeta.Misra@Sun.COM * Check if there is still entry in the current list. 345510946SSangeeta.Misra@Sun.COM * 345610946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need to 345710946SSangeeta.Misra@Sun.COM * compare list_next with the kernel address of the list head. 345810946SSangeeta.Misra@Sun.COM * So we need to calculate the address manually. 345910946SSangeeta.Misra@Sun.COM */ 346010946SSangeeta.Misra@Sun.COM if ((char *)st.list.list_next != khead + offsetof(list_t, 346110946SSangeeta.Misra@Sun.COM list_head)) { 346210946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)list_object(&head, 346310946SSangeeta.Misra@Sun.COM st.list.list_next); 346410946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 346510946SSangeeta.Misra@Sun.COM } 346610946SSangeeta.Misra@Sun.COM 346710946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */ 346810946SSangeeta.Misra@Sun.COM st_next = NULL; 346910946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) { 347010946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_sticky_hash + i * 347110946SSangeeta.Misra@Sun.COM sizeof (ilb_sticky_hash_t); 347210946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 347310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", 347410946SSangeeta.Misra@Sun.COM khead); 347510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 347610946SSangeeta.Misra@Sun.COM } 347710946SSangeeta.Misra@Sun.COM 347810946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 347910946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 348010946SSangeeta.Misra@Sun.COM st_next = list_object(&head, 348110946SSangeeta.Misra@Sun.COM head.list_head.list_next); 348210946SSangeeta.Misra@Sun.COM break; 348310946SSangeeta.Misra@Sun.COM } 348410946SSangeeta.Misra@Sun.COM } 348510946SSangeeta.Misra@Sun.COM 348610946SSangeeta.Misra@Sun.COM if (st_next == NULL) 348710946SSangeeta.Misra@Sun.COM return (WALK_DONE); 348810946SSangeeta.Misra@Sun.COM 348910946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)st_next; 349010946SSangeeta.Misra@Sun.COM sticky_walk->idx = i; 349110946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 349210946SSangeeta.Misra@Sun.COM } 3493