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 /* 228485SPeter.Memishian@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <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> 55*11042SErik.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 88*11042SErik.Nordmark@Sun.COM typedef struct ncec_walk_data_s { 89*11042SErik.Nordmark@Sun.COM struct ndp_g_s ncec_ip_ndp; 90*11042SErik.Nordmark@Sun.COM int ncec_hash_tbl_index; 91*11042SErik.Nordmark@Sun.COM ncec_t ncec; 92*11042SErik.Nordmark@Sun.COM } ncec_walk_data_t; 93*11042SErik.Nordmark@Sun.COM 94*11042SErik.Nordmark@Sun.COM typedef struct ncec_cbdata_s { 95*11042SErik.Nordmark@Sun.COM uintptr_t ncec_addr; 96*11042SErik.Nordmark@Sun.COM int ncec_ipversion; 97*11042SErik.Nordmark@Sun.COM } ncec_cbdata_t; 985940Ssowmini 995940Ssowmini typedef struct nce_cbdata_s { 100*11042SErik.Nordmark@Sun.COM int nce_ipversion; 101*11042SErik.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 109*11042SErik.Nordmark@Sun.COM typedef struct zi_cbdata_s { 110*11042SErik.Nordmark@Sun.COM const char *zone_name; 111*11042SErik.Nordmark@Sun.COM ip_stack_t *ipst; 112*11042SErik.Nordmark@Sun.COM boolean_t shared_ip_zone; 113*11042SErik.Nordmark@Sun.COM } zi_cbdata_t; 114*11042SErik.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; 137*11042SErik.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 = { 172*11042SErik.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 *); 226*11042SErik.Nordmark@Sun.COM static int ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion); 227*11042SErik.Nordmark@Sun.COM static int ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv); 228*11042SErik.Nordmark@Sun.COM static int ncec_walk_step(mdb_walk_state_t *wsp); 229*11042SErik.Nordmark@Sun.COM static int ncec_stack_walk_init(mdb_walk_state_t *wsp); 230*11042SErik.Nordmark@Sun.COM static int ncec_stack_walk_step(mdb_walk_state_t *wsp); 231*11042SErik.Nordmark@Sun.COM static void ncec_stack_walk_fini(mdb_walk_state_t *wsp); 232*11042SErik.Nordmark@Sun.COM static int ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw, 233*11042SErik.Nordmark@Sun.COM ncec_cbdata_t *id); 234*11042SErik.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 280*11042SErik.Nordmark@Sun.COM /* ARGSUSED */ 281*11042SErik.Nordmark@Sun.COM static int 282*11042SErik.Nordmark@Sun.COM zone_to_ips_cb(uintptr_t addr, const void *zi_arg, void *zi_cb_arg) 283*11042SErik.Nordmark@Sun.COM { 284*11042SErik.Nordmark@Sun.COM zi_cbdata_t *zi_cb = zi_cb_arg; 285*11042SErik.Nordmark@Sun.COM zone_t zone; 286*11042SErik.Nordmark@Sun.COM char zone_name[ZONENAME_MAX]; 287*11042SErik.Nordmark@Sun.COM netstack_t ns; 288*11042SErik.Nordmark@Sun.COM 289*11042SErik.Nordmark@Sun.COM if (mdb_vread(&zone, sizeof (zone_t), addr) == -1) { 290*11042SErik.Nordmark@Sun.COM mdb_warn("can't read zone at %p", addr); 291*11042SErik.Nordmark@Sun.COM return (WALK_ERR); 292*11042SErik.Nordmark@Sun.COM } 293*11042SErik.Nordmark@Sun.COM 294*11042SErik.Nordmark@Sun.COM (void) mdb_readstr(zone_name, ZONENAME_MAX, (uintptr_t)zone.zone_name); 295*11042SErik.Nordmark@Sun.COM 296*11042SErik.Nordmark@Sun.COM if (strcmp(zi_cb->zone_name, zone_name) != 0) 297*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 298*11042SErik.Nordmark@Sun.COM 299*11042SErik.Nordmark@Sun.COM zi_cb->shared_ip_zone = (!(zone.zone_flags & ZF_NET_EXCL) && 300*11042SErik.Nordmark@Sun.COM (strcmp(zone_name, "global") != 0)); 301*11042SErik.Nordmark@Sun.COM 302*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ns, sizeof (netstack_t), (uintptr_t)zone.zone_netstack) 303*11042SErik.Nordmark@Sun.COM == -1) { 304*11042SErik.Nordmark@Sun.COM mdb_warn("can't read netstack at %p", zone.zone_netstack); 305*11042SErik.Nordmark@Sun.COM return (WALK_ERR); 306*11042SErik.Nordmark@Sun.COM } 307*11042SErik.Nordmark@Sun.COM 308*11042SErik.Nordmark@Sun.COM zi_cb->ipst = ns.netstack_ip; 309*11042SErik.Nordmark@Sun.COM return (WALK_DONE); 310*11042SErik.Nordmark@Sun.COM } 311*11042SErik.Nordmark@Sun.COM 312*11042SErik.Nordmark@Sun.COM static ip_stack_t * 313*11042SErik.Nordmark@Sun.COM zone_to_ips(const char *zone_name) 314*11042SErik.Nordmark@Sun.COM { 315*11042SErik.Nordmark@Sun.COM zi_cbdata_t zi_cb; 316*11042SErik.Nordmark@Sun.COM 317*11042SErik.Nordmark@Sun.COM if (zone_name == NULL) 318*11042SErik.Nordmark@Sun.COM return (NULL); 319*11042SErik.Nordmark@Sun.COM 320*11042SErik.Nordmark@Sun.COM zi_cb.zone_name = zone_name; 321*11042SErik.Nordmark@Sun.COM zi_cb.ipst = NULL; 322*11042SErik.Nordmark@Sun.COM zi_cb.shared_ip_zone = B_FALSE; 323*11042SErik.Nordmark@Sun.COM 324*11042SErik.Nordmark@Sun.COM if (mdb_walk("zone", (mdb_walk_cb_t)zone_to_ips_cb, &zi_cb) == -1) { 325*11042SErik.Nordmark@Sun.COM mdb_warn("failed to walk zone"); 326*11042SErik.Nordmark@Sun.COM return (NULL); 327*11042SErik.Nordmark@Sun.COM } 328*11042SErik.Nordmark@Sun.COM 329*11042SErik.Nordmark@Sun.COM if (zi_cb.shared_ip_zone) { 330*11042SErik.Nordmark@Sun.COM mdb_warn("%s is a Shared-IP zone, try '-s global' instead\n", 331*11042SErik.Nordmark@Sun.COM zone_name); 332*11042SErik.Nordmark@Sun.COM return (NULL); 333*11042SErik.Nordmark@Sun.COM } 334*11042SErik.Nordmark@Sun.COM 335*11042SErik.Nordmark@Sun.COM if (zi_cb.ipst == NULL) { 336*11042SErik.Nordmark@Sun.COM mdb_warn("failed to find zone %s\n", zone_name); 337*11042SErik.Nordmark@Sun.COM return (NULL); 338*11042SErik.Nordmark@Sun.COM } 339*11042SErik.Nordmark@Sun.COM 340*11042SErik.Nordmark@Sun.COM return (zi_cb.ipst); 341*11042SErik.Nordmark@Sun.COM } 342*11042SErik.Nordmark@Sun.COM 3430Sstevel@tonic-gate int 3443448Sdh155122 ip_stacks_walk_init(mdb_walk_state_t *wsp) 3453448Sdh155122 { 3463448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 3473448Sdh155122 mdb_warn("can't walk 'netstack'"); 3483448Sdh155122 return (WALK_ERR); 3493448Sdh155122 } 3503448Sdh155122 return (WALK_NEXT); 3513448Sdh155122 } 3523448Sdh155122 3533448Sdh155122 int 3543448Sdh155122 ip_stacks_walk_step(mdb_walk_state_t *wsp) 3553448Sdh155122 { 3563448Sdh155122 uintptr_t kaddr; 3573448Sdh155122 netstack_t nss; 3583448Sdh155122 3593448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 3603448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 3613448Sdh155122 return (WALK_ERR); 3623448Sdh155122 } 3633448Sdh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_IP]; 3643448Sdh155122 3653448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 3663448Sdh155122 } 3673448Sdh155122 3685023Scarlsonj int 3695023Scarlsonj th_hash_walk_init(mdb_walk_state_t *wsp) 3705023Scarlsonj { 3715023Scarlsonj GElf_Sym sym; 3725023Scarlsonj list_node_t *next; 3735023Scarlsonj 3745023Scarlsonj if (wsp->walk_addr == NULL) { 3755023Scarlsonj if (mdb_lookup_by_obj("ip", "ip_thread_list", &sym) == 0) { 3765023Scarlsonj wsp->walk_addr = sym.st_value; 3775023Scarlsonj } else { 3785023Scarlsonj mdb_warn("unable to locate ip_thread_list\n"); 3795023Scarlsonj return (WALK_ERR); 3805023Scarlsonj } 3815023Scarlsonj } 3825023Scarlsonj 3835023Scarlsonj if (mdb_vread(&next, sizeof (next), 3845023Scarlsonj wsp->walk_addr + offsetof(list_t, list_head) + 3855023Scarlsonj offsetof(list_node_t, list_next)) == -1 || 3865023Scarlsonj next == NULL) { 3875023Scarlsonj mdb_warn("non-DEBUG image; cannot walk th_hash list\n"); 3885023Scarlsonj return (WALK_ERR); 3895023Scarlsonj } 3905023Scarlsonj 3915023Scarlsonj if (mdb_layered_walk("list", wsp) == -1) { 3925023Scarlsonj mdb_warn("can't walk 'list'"); 3935023Scarlsonj return (WALK_ERR); 3945023Scarlsonj } else { 3955023Scarlsonj return (WALK_NEXT); 3965023Scarlsonj } 3975023Scarlsonj } 3985023Scarlsonj 3995023Scarlsonj int 4005023Scarlsonj th_hash_walk_step(mdb_walk_state_t *wsp) 4015023Scarlsonj { 4025023Scarlsonj return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 4035023Scarlsonj wsp->walk_cbdata)); 4045023Scarlsonj } 4055023Scarlsonj 4063448Sdh155122 /* 4073448Sdh155122 * Called with walk_addr being the address of ips_ill_g_heads 4083448Sdh155122 */ 4093448Sdh155122 int 4103448Sdh155122 illif_stack_walk_init(mdb_walk_state_t *wsp) 4110Sstevel@tonic-gate { 4120Sstevel@tonic-gate illif_walk_data_t *iw; 4130Sstevel@tonic-gate 4143448Sdh155122 if (wsp->walk_addr == NULL) { 4153448Sdh155122 mdb_warn("illif_stack supports only local walks\n"); 4160Sstevel@tonic-gate return (WALK_ERR); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate iw = mdb_alloc(sizeof (illif_walk_data_t), UM_SLEEP); 4200Sstevel@tonic-gate 4213448Sdh155122 if (mdb_vread(iw->ill_g_heads, MAX_G_HEADS * sizeof (ill_g_head_t), 4223448Sdh155122 wsp->walk_addr) == -1) { 4233448Sdh155122 mdb_warn("failed to read 'ips_ill_g_heads' at %p", 4243448Sdh155122 wsp->walk_addr); 4250Sstevel@tonic-gate mdb_free(iw, sizeof (illif_walk_data_t)); 4260Sstevel@tonic-gate return (WALK_ERR); 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate iw->ill_list = 0; 4303448Sdh155122 wsp->walk_addr = (uintptr_t)iw->ill_g_heads[0].ill_g_list_head; 4310Sstevel@tonic-gate wsp->walk_data = iw; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate return (WALK_NEXT); 4340Sstevel@tonic-gate } 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate int 4373448Sdh155122 illif_stack_walk_step(mdb_walk_state_t *wsp) 4380Sstevel@tonic-gate { 4390Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 4400Sstevel@tonic-gate illif_walk_data_t *iw = wsp->walk_data; 4410Sstevel@tonic-gate int list = iw->ill_list; 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate if (mdb_vread(&iw->ill_if, sizeof (ill_if_t), addr) == -1) { 4440Sstevel@tonic-gate mdb_warn("failed to read ill_if_t at %p", addr); 4450Sstevel@tonic-gate return (WALK_ERR); 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)iw->ill_if.illif_next; 4490Sstevel@tonic-gate 4503448Sdh155122 if (wsp->walk_addr == 4513448Sdh155122 (uintptr_t)iw->ill_g_heads[list].ill_g_list_head) { 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate if (++list >= MAX_G_HEADS) 4540Sstevel@tonic-gate return (WALK_DONE); 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate iw->ill_list = list; 4573448Sdh155122 wsp->walk_addr = 4583448Sdh155122 (uintptr_t)iw->ill_g_heads[list].ill_g_list_head; 4590Sstevel@tonic-gate return (WALK_NEXT); 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate return (wsp->walk_callback(addr, iw, wsp->walk_cbdata)); 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate void 4663448Sdh155122 illif_stack_walk_fini(mdb_walk_state_t *wsp) 4670Sstevel@tonic-gate { 4680Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (illif_walk_data_t)); 4690Sstevel@tonic-gate } 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate typedef struct illif_cbdata { 4720Sstevel@tonic-gate uint_t ill_flags; 4730Sstevel@tonic-gate uintptr_t ill_addr; 4740Sstevel@tonic-gate int ill_printlist; /* list to be printed (MAX_G_HEADS for all) */ 4750Sstevel@tonic-gate boolean_t ill_printed; 4760Sstevel@tonic-gate } illif_cbdata_t; 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate static int 4790Sstevel@tonic-gate illif_cb(uintptr_t addr, const illif_walk_data_t *iw, illif_cbdata_t *id) 4800Sstevel@tonic-gate { 4810Sstevel@tonic-gate const char *version; 4820Sstevel@tonic-gate 4830Sstevel@tonic-gate if (id->ill_printlist < MAX_G_HEADS && 4840Sstevel@tonic-gate id->ill_printlist != iw->ill_list) 4850Sstevel@tonic-gate return (WALK_NEXT); 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate if (id->ill_flags & DCMD_ADDRSPEC && id->ill_addr != addr) 4880Sstevel@tonic-gate return (WALK_NEXT); 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate if (id->ill_flags & DCMD_PIPE_OUT) { 4910Sstevel@tonic-gate mdb_printf("%p\n", addr); 4920Sstevel@tonic-gate return (WALK_NEXT); 4930Sstevel@tonic-gate } 4940Sstevel@tonic-gate 4950Sstevel@tonic-gate switch (iw->ill_list) { 4960Sstevel@tonic-gate case IP_V4_G_HEAD: version = "v4"; break; 4970Sstevel@tonic-gate case IP_V6_G_HEAD: version = "v6"; break; 4980Sstevel@tonic-gate default: version = "??"; break; 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate mdb_printf("%?p %2s %?p %10d %?p %s\n", 5020Sstevel@tonic-gate addr, version, addr + offsetof(ill_if_t, illif_avl_by_ppa), 5030Sstevel@tonic-gate iw->ill_if.illif_avl_by_ppa.avl_numnodes, 5040Sstevel@tonic-gate iw->ill_if.illif_ppa_arena, iw->ill_if.illif_name); 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate id->ill_printed = TRUE; 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate return (WALK_NEXT); 5090Sstevel@tonic-gate } 5100Sstevel@tonic-gate 5110Sstevel@tonic-gate int 5125940Ssowmini ip_stacks_common_walk_init(mdb_walk_state_t *wsp) 5133448Sdh155122 { 5143448Sdh155122 if (mdb_layered_walk("ip_stacks", wsp) == -1) { 5153448Sdh155122 mdb_warn("can't walk 'ip_stacks'"); 5163448Sdh155122 return (WALK_ERR); 5173448Sdh155122 } 5183448Sdh155122 5193448Sdh155122 return (WALK_NEXT); 5203448Sdh155122 } 5213448Sdh155122 5223448Sdh155122 int 5233448Sdh155122 illif_walk_step(mdb_walk_state_t *wsp) 5243448Sdh155122 { 5253448Sdh155122 uintptr_t kaddr; 5263448Sdh155122 5273448Sdh155122 kaddr = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ill_g_heads); 5283448Sdh155122 5293448Sdh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) { 5303448Sdh155122 mdb_warn("can't read ips_ip_cache_table at %p", kaddr); 5313448Sdh155122 return (WALK_ERR); 5323448Sdh155122 } 5333448Sdh155122 5343448Sdh155122 if (mdb_pwalk("illif_stack", wsp->walk_callback, 5355023Scarlsonj wsp->walk_cbdata, kaddr) == -1) { 5363448Sdh155122 mdb_warn("couldn't walk 'illif_stack' for ips_ill_g_heads %p", 5373448Sdh155122 kaddr); 5383448Sdh155122 return (WALK_ERR); 5393448Sdh155122 } 5403448Sdh155122 return (WALK_NEXT); 5413448Sdh155122 } 5423448Sdh155122 5433448Sdh155122 int 5440Sstevel@tonic-gate illif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5450Sstevel@tonic-gate { 5460Sstevel@tonic-gate illif_cbdata_t id; 5470Sstevel@tonic-gate ill_if_t ill_if; 5480Sstevel@tonic-gate const char *opt_P = NULL; 5490Sstevel@tonic-gate int printlist = MAX_G_HEADS; 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate if (mdb_getopts(argc, argv, 5520Sstevel@tonic-gate 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 5530Sstevel@tonic-gate return (DCMD_USAGE); 5540Sstevel@tonic-gate 5550Sstevel@tonic-gate if (opt_P != NULL) { 5560Sstevel@tonic-gate if (strcmp("v4", opt_P) == 0) { 5570Sstevel@tonic-gate printlist = IP_V4_G_HEAD; 5580Sstevel@tonic-gate } else if (strcmp("v6", opt_P) == 0) { 5590Sstevel@tonic-gate printlist = IP_V6_G_HEAD; 5600Sstevel@tonic-gate } else { 5610Sstevel@tonic-gate mdb_warn("invalid protocol '%s'\n", opt_P); 5620Sstevel@tonic-gate return (DCMD_USAGE); 5630Sstevel@tonic-gate } 5640Sstevel@tonic-gate } 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && (flags & DCMD_PIPE_OUT) == 0) { 5670Sstevel@tonic-gate mdb_printf("%<u>%?s %2s %?s %10s %?s %-10s%</u>\n", 5680Sstevel@tonic-gate "ADDR", "IP", "AVLADDR", "NUMNODES", "ARENA", "NAME"); 5690Sstevel@tonic-gate } 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate id.ill_flags = flags; 5720Sstevel@tonic-gate id.ill_addr = addr; 5730Sstevel@tonic-gate id.ill_printlist = printlist; 5740Sstevel@tonic-gate id.ill_printed = FALSE; 5750Sstevel@tonic-gate 5760Sstevel@tonic-gate if (mdb_walk("illif", (mdb_walk_cb_t)illif_cb, &id) == -1) { 5770Sstevel@tonic-gate mdb_warn("can't walk ill_if_t structures"); 5780Sstevel@tonic-gate return (DCMD_ERR); 5790Sstevel@tonic-gate } 5800Sstevel@tonic-gate 5810Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) || opt_P != NULL || id.ill_printed) 5820Sstevel@tonic-gate return (DCMD_OK); 5830Sstevel@tonic-gate 5840Sstevel@tonic-gate /* 5850Sstevel@tonic-gate * If an address is specified and the walk doesn't find it, 5860Sstevel@tonic-gate * print it anyway. 5870Sstevel@tonic-gate */ 5880Sstevel@tonic-gate if (mdb_vread(&ill_if, sizeof (ill_if_t), addr) == -1) { 5890Sstevel@tonic-gate mdb_warn("failed to read ill_if_t at %p", addr); 5900Sstevel@tonic-gate return (DCMD_ERR); 5910Sstevel@tonic-gate } 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate mdb_printf("%?p %2s %?p %10d %?p %s\n", 5940Sstevel@tonic-gate addr, "??", addr + offsetof(ill_if_t, illif_avl_by_ppa), 5950Sstevel@tonic-gate ill_if.illif_avl_by_ppa.avl_numnodes, 5960Sstevel@tonic-gate ill_if.illif_ppa_arena, ill_if.illif_name); 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate return (DCMD_OK); 5990Sstevel@tonic-gate } 6000Sstevel@tonic-gate 6010Sstevel@tonic-gate static void 6020Sstevel@tonic-gate illif_help(void) 6030Sstevel@tonic-gate { 6040Sstevel@tonic-gate mdb_printf("Options:\n"); 6050Sstevel@tonic-gate mdb_printf("\t-P v4 | v6" 6060Sstevel@tonic-gate "\tfilter interface structures for the specified protocol\n"); 6070Sstevel@tonic-gate } 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate int 610*11042SErik.Nordmark@Sun.COM nce_walk_init(mdb_walk_state_t *wsp) 611*11042SErik.Nordmark@Sun.COM { 612*11042SErik.Nordmark@Sun.COM if (mdb_layered_walk("nce_cache", wsp) == -1) { 613*11042SErik.Nordmark@Sun.COM mdb_warn("can't walk 'nce_cache'"); 614*11042SErik.Nordmark@Sun.COM return (WALK_ERR); 615*11042SErik.Nordmark@Sun.COM } 616*11042SErik.Nordmark@Sun.COM 617*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 618*11042SErik.Nordmark@Sun.COM } 619*11042SErik.Nordmark@Sun.COM 620*11042SErik.Nordmark@Sun.COM int 621*11042SErik.Nordmark@Sun.COM nce_walk_step(mdb_walk_state_t *wsp) 622*11042SErik.Nordmark@Sun.COM { 623*11042SErik.Nordmark@Sun.COM nce_t nce; 624*11042SErik.Nordmark@Sun.COM 625*11042SErik.Nordmark@Sun.COM if (mdb_vread(&nce, sizeof (nce), wsp->walk_addr) == -1) { 626*11042SErik.Nordmark@Sun.COM mdb_warn("can't read nce at %p", wsp->walk_addr); 627*11042SErik.Nordmark@Sun.COM return (WALK_ERR); 628*11042SErik.Nordmark@Sun.COM } 629*11042SErik.Nordmark@Sun.COM 630*11042SErik.Nordmark@Sun.COM return (wsp->walk_callback(wsp->walk_addr, &nce, wsp->walk_cbdata)); 631*11042SErik.Nordmark@Sun.COM } 632*11042SErik.Nordmark@Sun.COM 633*11042SErik.Nordmark@Sun.COM static int 634*11042SErik.Nordmark@Sun.COM nce_format(uintptr_t addr, const nce_t *ncep, void *nce_cb_arg) 635*11042SErik.Nordmark@Sun.COM { 636*11042SErik.Nordmark@Sun.COM nce_cbdata_t *nce_cb = nce_cb_arg; 637*11042SErik.Nordmark@Sun.COM ill_t ill; 638*11042SErik.Nordmark@Sun.COM char ill_name[LIFNAMSIZ]; 639*11042SErik.Nordmark@Sun.COM ncec_t ncec; 640*11042SErik.Nordmark@Sun.COM 641*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec), 642*11042SErik.Nordmark@Sun.COM (uintptr_t)ncep->nce_common) == -1) { 643*11042SErik.Nordmark@Sun.COM mdb_warn("can't read ncec at %p", ncep->nce_common); 644*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 645*11042SErik.Nordmark@Sun.COM } 646*11042SErik.Nordmark@Sun.COM if (nce_cb->nce_ipversion != 0 && 647*11042SErik.Nordmark@Sun.COM ncec.ncec_ipversion != nce_cb->nce_ipversion) 648*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 649*11042SErik.Nordmark@Sun.COM 650*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncep->nce_ill) == -1) { 651*11042SErik.Nordmark@Sun.COM mdb_snprintf(ill_name, sizeof (ill_name), "--"); 652*11042SErik.Nordmark@Sun.COM } else { 653*11042SErik.Nordmark@Sun.COM (void) mdb_readstr(ill_name, 654*11042SErik.Nordmark@Sun.COM MIN(LIFNAMSIZ, ill.ill_name_length), 655*11042SErik.Nordmark@Sun.COM (uintptr_t)ill.ill_name); 656*11042SErik.Nordmark@Sun.COM } 657*11042SErik.Nordmark@Sun.COM 658*11042SErik.Nordmark@Sun.COM if (nce_cb->nce_ill_name[0] != '\0' && 659*11042SErik.Nordmark@Sun.COM strncmp(nce_cb->nce_ill_name, ill_name, LIFNAMSIZ) != 0) 660*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 661*11042SErik.Nordmark@Sun.COM 662*11042SErik.Nordmark@Sun.COM if (ncec.ncec_ipversion == IPV6_VERSION) { 663*11042SErik.Nordmark@Sun.COM 664*11042SErik.Nordmark@Sun.COM mdb_printf("%?p %5s %-18s %?p %6d %N\n", 665*11042SErik.Nordmark@Sun.COM addr, ill_name, 666*11042SErik.Nordmark@Sun.COM nce_l2_addr(ncep, &ill), 667*11042SErik.Nordmark@Sun.COM ncep->nce_fp_mp, 668*11042SErik.Nordmark@Sun.COM ncep->nce_refcnt, 669*11042SErik.Nordmark@Sun.COM &ncep->nce_addr); 670*11042SErik.Nordmark@Sun.COM 671*11042SErik.Nordmark@Sun.COM } else { 672*11042SErik.Nordmark@Sun.COM struct in_addr nceaddr; 673*11042SErik.Nordmark@Sun.COM 674*11042SErik.Nordmark@Sun.COM IN6_V4MAPPED_TO_INADDR(&ncep->nce_addr, &nceaddr); 675*11042SErik.Nordmark@Sun.COM mdb_printf("%?p %5s %-18s %?p %6d %I\n", 676*11042SErik.Nordmark@Sun.COM addr, ill_name, 677*11042SErik.Nordmark@Sun.COM nce_l2_addr(ncep, &ill), 678*11042SErik.Nordmark@Sun.COM ncep->nce_fp_mp, 679*11042SErik.Nordmark@Sun.COM ncep->nce_refcnt, 680*11042SErik.Nordmark@Sun.COM nceaddr.s_addr); 681*11042SErik.Nordmark@Sun.COM } 682*11042SErik.Nordmark@Sun.COM 683*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 684*11042SErik.Nordmark@Sun.COM } 685*11042SErik.Nordmark@Sun.COM 686*11042SErik.Nordmark@Sun.COM int 687*11042SErik.Nordmark@Sun.COM dce_walk_init(mdb_walk_state_t *wsp) 688*11042SErik.Nordmark@Sun.COM { 689*11042SErik.Nordmark@Sun.COM wsp->walk_data = (void *)wsp->walk_addr; 690*11042SErik.Nordmark@Sun.COM 691*11042SErik.Nordmark@Sun.COM if (mdb_layered_walk("dce_cache", wsp) == -1) { 692*11042SErik.Nordmark@Sun.COM mdb_warn("can't walk 'dce_cache'"); 693*11042SErik.Nordmark@Sun.COM return (WALK_ERR); 694*11042SErik.Nordmark@Sun.COM } 695*11042SErik.Nordmark@Sun.COM 696*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 697*11042SErik.Nordmark@Sun.COM } 698*11042SErik.Nordmark@Sun.COM 699*11042SErik.Nordmark@Sun.COM int 700*11042SErik.Nordmark@Sun.COM dce_walk_step(mdb_walk_state_t *wsp) 701*11042SErik.Nordmark@Sun.COM { 702*11042SErik.Nordmark@Sun.COM dce_t dce; 703*11042SErik.Nordmark@Sun.COM 704*11042SErik.Nordmark@Sun.COM if (mdb_vread(&dce, sizeof (dce), wsp->walk_addr) == -1) { 705*11042SErik.Nordmark@Sun.COM mdb_warn("can't read dce at %p", wsp->walk_addr); 706*11042SErik.Nordmark@Sun.COM return (WALK_ERR); 707*11042SErik.Nordmark@Sun.COM } 708*11042SErik.Nordmark@Sun.COM 709*11042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip DCEs that don't belong to it. */ 710*11042SErik.Nordmark@Sun.COM if ((wsp->walk_data != NULL) && (wsp->walk_data != dce.dce_ipst)) 711*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 712*11042SErik.Nordmark@Sun.COM 713*11042SErik.Nordmark@Sun.COM return (wsp->walk_callback(wsp->walk_addr, &dce, wsp->walk_cbdata)); 714*11042SErik.Nordmark@Sun.COM } 715*11042SErik.Nordmark@Sun.COM 716*11042SErik.Nordmark@Sun.COM int 7170Sstevel@tonic-gate ire_walk_init(mdb_walk_state_t *wsp) 7180Sstevel@tonic-gate { 719*11042SErik.Nordmark@Sun.COM wsp->walk_data = (void *)wsp->walk_addr; 720*11042SErik.Nordmark@Sun.COM 7210Sstevel@tonic-gate if (mdb_layered_walk("ire_cache", wsp) == -1) { 7220Sstevel@tonic-gate mdb_warn("can't walk 'ire_cache'"); 7230Sstevel@tonic-gate return (WALK_ERR); 7240Sstevel@tonic-gate } 7250Sstevel@tonic-gate 7260Sstevel@tonic-gate return (WALK_NEXT); 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate 7290Sstevel@tonic-gate int 7300Sstevel@tonic-gate ire_walk_step(mdb_walk_state_t *wsp) 7310Sstevel@tonic-gate { 7320Sstevel@tonic-gate ire_t ire; 7330Sstevel@tonic-gate 7340Sstevel@tonic-gate if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) { 7350Sstevel@tonic-gate mdb_warn("can't read ire at %p", wsp->walk_addr); 7360Sstevel@tonic-gate return (WALK_ERR); 7370Sstevel@tonic-gate } 7380Sstevel@tonic-gate 739*11042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip IREs that don't belong to it. */ 740*11042SErik.Nordmark@Sun.COM if ((wsp->walk_data != NULL) && (wsp->walk_data != ire.ire_ipst)) 741*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 742*11042SErik.Nordmark@Sun.COM 7430Sstevel@tonic-gate return (wsp->walk_callback(wsp->walk_addr, &ire, wsp->walk_cbdata)); 7440Sstevel@tonic-gate } 7450Sstevel@tonic-gate 7463448Sdh155122 /* ARGSUSED */ 7473448Sdh155122 int 7483448Sdh155122 ire_next_walk_init(mdb_walk_state_t *wsp) 7493448Sdh155122 { 7503448Sdh155122 return (WALK_NEXT); 7513448Sdh155122 } 7523448Sdh155122 7533448Sdh155122 int 7543448Sdh155122 ire_next_walk_step(mdb_walk_state_t *wsp) 7553448Sdh155122 { 7563448Sdh155122 ire_t ire; 7573448Sdh155122 int status; 7583448Sdh155122 7593448Sdh155122 7603448Sdh155122 if (wsp->walk_addr == NULL) 7613448Sdh155122 return (WALK_DONE); 7623448Sdh155122 7633448Sdh155122 if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) { 7643448Sdh155122 mdb_warn("can't read ire at %p", wsp->walk_addr); 7653448Sdh155122 return (WALK_ERR); 7663448Sdh155122 } 7673448Sdh155122 status = wsp->walk_callback(wsp->walk_addr, &ire, 7683448Sdh155122 wsp->walk_cbdata); 7693448Sdh155122 7703448Sdh155122 if (status != WALK_NEXT) 7713448Sdh155122 return (status); 7723448Sdh155122 7733448Sdh155122 wsp->walk_addr = (uintptr_t)ire.ire_next; 7743448Sdh155122 return (status); 7753448Sdh155122 } 7763448Sdh155122 7770Sstevel@tonic-gate static int 7785940Ssowmini ire_format(uintptr_t addr, const void *ire_arg, void *ire_cb_arg) 7790Sstevel@tonic-gate { 7805940Ssowmini const ire_t *irep = ire_arg; 7815940Ssowmini ire_cbdata_t *ire_cb = ire_cb_arg; 7825940Ssowmini boolean_t verbose = ire_cb->verbose; 783*11042SErik.Nordmark@Sun.COM ill_t ill; 784*11042SErik.Nordmark@Sun.COM char ill_name[LIFNAMSIZ]; 785*11042SErik.Nordmark@Sun.COM boolean_t condemned = irep->ire_generation == IRE_GENERATION_CONDEMNED; 7865940Ssowmini 7870Sstevel@tonic-gate static const mdb_bitmask_t tmasks[] = { 7880Sstevel@tonic-gate { "BROADCAST", IRE_BROADCAST, IRE_BROADCAST }, 7890Sstevel@tonic-gate { "DEFAULT", IRE_DEFAULT, IRE_DEFAULT }, 7900Sstevel@tonic-gate { "LOCAL", IRE_LOCAL, IRE_LOCAL }, 7910Sstevel@tonic-gate { "LOOPBACK", IRE_LOOPBACK, IRE_LOOPBACK }, 7920Sstevel@tonic-gate { "PREFIX", IRE_PREFIX, IRE_PREFIX }, 793*11042SErik.Nordmark@Sun.COM { "MULTICAST", IRE_MULTICAST, IRE_MULTICAST }, 794*11042SErik.Nordmark@Sun.COM { "NOROUTE", IRE_NOROUTE, IRE_NOROUTE }, 7950Sstevel@tonic-gate { "IF_NORESOLVER", IRE_IF_NORESOLVER, IRE_IF_NORESOLVER }, 7960Sstevel@tonic-gate { "IF_RESOLVER", IRE_IF_RESOLVER, IRE_IF_RESOLVER }, 797*11042SErik.Nordmark@Sun.COM { "IF_CLONE", IRE_IF_CLONE, IRE_IF_CLONE }, 7980Sstevel@tonic-gate { "HOST", IRE_HOST, IRE_HOST }, 7990Sstevel@tonic-gate { NULL, 0, 0 } 8000Sstevel@tonic-gate }; 8010Sstevel@tonic-gate 8020Sstevel@tonic-gate static const mdb_bitmask_t fmasks[] = { 8030Sstevel@tonic-gate { "UP", RTF_UP, RTF_UP }, 8040Sstevel@tonic-gate { "GATEWAY", RTF_GATEWAY, RTF_GATEWAY }, 8050Sstevel@tonic-gate { "HOST", RTF_HOST, RTF_HOST }, 8060Sstevel@tonic-gate { "REJECT", RTF_REJECT, RTF_REJECT }, 8070Sstevel@tonic-gate { "DYNAMIC", RTF_DYNAMIC, RTF_DYNAMIC }, 8080Sstevel@tonic-gate { "MODIFIED", RTF_MODIFIED, RTF_MODIFIED }, 8090Sstevel@tonic-gate { "DONE", RTF_DONE, RTF_DONE }, 8100Sstevel@tonic-gate { "MASK", RTF_MASK, RTF_MASK }, 8110Sstevel@tonic-gate { "CLONING", RTF_CLONING, RTF_CLONING }, 8120Sstevel@tonic-gate { "XRESOLVE", RTF_XRESOLVE, RTF_XRESOLVE }, 8130Sstevel@tonic-gate { "LLINFO", RTF_LLINFO, RTF_LLINFO }, 8140Sstevel@tonic-gate { "STATIC", RTF_STATIC, RTF_STATIC }, 8150Sstevel@tonic-gate { "BLACKHOLE", RTF_BLACKHOLE, RTF_BLACKHOLE }, 8160Sstevel@tonic-gate { "PRIVATE", RTF_PRIVATE, RTF_PRIVATE }, 8170Sstevel@tonic-gate { "PROTO2", RTF_PROTO2, RTF_PROTO2 }, 8180Sstevel@tonic-gate { "PROTO1", RTF_PROTO1, RTF_PROTO1 }, 8190Sstevel@tonic-gate { "MULTIRT", RTF_MULTIRT, RTF_MULTIRT }, 8200Sstevel@tonic-gate { "SETSRC", RTF_SETSRC, RTF_SETSRC }, 821*11042SErik.Nordmark@Sun.COM { "INDIRECT", RTF_INDIRECT, RTF_INDIRECT }, 8220Sstevel@tonic-gate { NULL, 0, 0 } 8230Sstevel@tonic-gate }; 8240Sstevel@tonic-gate 8255940Ssowmini if (ire_cb->ire_ipversion != 0 && 8265940Ssowmini irep->ire_ipversion != ire_cb->ire_ipversion) 8275940Ssowmini return (WALK_NEXT); 8285940Ssowmini 829*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)irep->ire_ill) == -1) { 830*11042SErik.Nordmark@Sun.COM mdb_snprintf(ill_name, sizeof (ill_name), "--"); 831*11042SErik.Nordmark@Sun.COM } else { 832*11042SErik.Nordmark@Sun.COM (void) mdb_readstr(ill_name, 833*11042SErik.Nordmark@Sun.COM MIN(LIFNAMSIZ, ill.ill_name_length), 834*11042SErik.Nordmark@Sun.COM (uintptr_t)ill.ill_name); 835*11042SErik.Nordmark@Sun.COM } 836*11042SErik.Nordmark@Sun.COM 8375940Ssowmini if (irep->ire_ipversion == IPV6_VERSION && verbose) { 8380Sstevel@tonic-gate 839*11042SErik.Nordmark@Sun.COM mdb_printf("%<b>%?p%</b>%3s %40N <%hb%s>\n" 840*11042SErik.Nordmark@Sun.COM "%?s %40N\n" 841*11042SErik.Nordmark@Sun.COM "%?s %40d %4d <%hb> %s\n", 842*11042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6, 843*11042SErik.Nordmark@Sun.COM irep->ire_type, tmasks, 844*11042SErik.Nordmark@Sun.COM (irep->ire_testhidden ? ", HIDDEN" : ""), 845*11042SErik.Nordmark@Sun.COM "", &irep->ire_addr_v6, 8463448Sdh155122 "", ips_to_stackid((uintptr_t)irep->ire_ipst), 8473448Sdh155122 irep->ire_zoneid, 848*11042SErik.Nordmark@Sun.COM irep->ire_flags, fmasks, ill_name); 8490Sstevel@tonic-gate 8505940Ssowmini } else if (irep->ire_ipversion == IPV6_VERSION) { 8510Sstevel@tonic-gate 852*11042SErik.Nordmark@Sun.COM mdb_printf("%?p%3s %30N %30N %5d %4d %s\n", 853*11042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6, 8543448Sdh155122 &irep->ire_addr_v6, 8553448Sdh155122 ips_to_stackid((uintptr_t)irep->ire_ipst), 856*11042SErik.Nordmark@Sun.COM irep->ire_zoneid, ill_name); 8570Sstevel@tonic-gate 8585940Ssowmini } else if (verbose) { 8590Sstevel@tonic-gate 860*11042SErik.Nordmark@Sun.COM mdb_printf("%<b>%?p%</b>%3s %40I <%hb%s>\n" 861*11042SErik.Nordmark@Sun.COM "%?s %40I\n" 862*11042SErik.Nordmark@Sun.COM "%?s %40d %4d <%hb> %s\n", 863*11042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", irep->ire_setsrc_addr, 864*11042SErik.Nordmark@Sun.COM irep->ire_type, tmasks, 865*11042SErik.Nordmark@Sun.COM (irep->ire_testhidden ? ", HIDDEN" : ""), 866*11042SErik.Nordmark@Sun.COM "", irep->ire_addr, 8673448Sdh155122 "", ips_to_stackid((uintptr_t)irep->ire_ipst), 868*11042SErik.Nordmark@Sun.COM irep->ire_zoneid, irep->ire_flags, fmasks, ill_name); 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate } else { 8710Sstevel@tonic-gate 872*11042SErik.Nordmark@Sun.COM mdb_printf("%?p%3s %30I %30I %5d %4d %s\n", addr, 873*11042SErik.Nordmark@Sun.COM condemned ? "(C)" : "", irep->ire_setsrc_addr, 8743448Sdh155122 irep->ire_addr, ips_to_stackid((uintptr_t)irep->ire_ipst), 875*11042SErik.Nordmark@Sun.COM irep->ire_zoneid, ill_name); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate return (WALK_NEXT); 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate 8810Sstevel@tonic-gate /* 8820Sstevel@tonic-gate * There are faster ways to do this. Given the interactive nature of this 8830Sstevel@tonic-gate * use I don't think its worth much effort. 8840Sstevel@tonic-gate */ 8850Sstevel@tonic-gate static unsigned short 8860Sstevel@tonic-gate ipcksum(void *p, int len) 8870Sstevel@tonic-gate { 8880Sstevel@tonic-gate int32_t sum = 0; 8890Sstevel@tonic-gate 8900Sstevel@tonic-gate while (len > 1) { 8910Sstevel@tonic-gate /* alignment */ 8920Sstevel@tonic-gate sum += *(uint16_t *)p; 8930Sstevel@tonic-gate p = (char *)p + sizeof (uint16_t); 8940Sstevel@tonic-gate if (sum & 0x80000000) 8950Sstevel@tonic-gate sum = (sum & 0xFFFF) + (sum >> 16); 8960Sstevel@tonic-gate len -= 2; 8970Sstevel@tonic-gate } 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate if (len) 9000Sstevel@tonic-gate sum += (uint16_t)*(unsigned char *)p; 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate while (sum >> 16) 9030Sstevel@tonic-gate sum = (sum & 0xFFFF) + (sum >> 16); 9040Sstevel@tonic-gate 9050Sstevel@tonic-gate return (~sum); 9060Sstevel@tonic-gate } 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate static const mdb_bitmask_t tcp_flags[] = { 9090Sstevel@tonic-gate { "SYN", TH_SYN, TH_SYN }, 9100Sstevel@tonic-gate { "ACK", TH_ACK, TH_ACK }, 9110Sstevel@tonic-gate { "FIN", TH_FIN, TH_FIN }, 9120Sstevel@tonic-gate { "RST", TH_RST, TH_RST }, 9130Sstevel@tonic-gate { "PSH", TH_PUSH, TH_PUSH }, 9140Sstevel@tonic-gate { "ECE", TH_ECE, TH_ECE }, 9150Sstevel@tonic-gate { "CWR", TH_CWR, TH_CWR }, 9160Sstevel@tonic-gate { NULL, 0, 0 } 9170Sstevel@tonic-gate }; 9180Sstevel@tonic-gate 9190Sstevel@tonic-gate static void 9200Sstevel@tonic-gate tcphdr_print(struct tcphdr *tcph) 9210Sstevel@tonic-gate { 9220Sstevel@tonic-gate in_port_t sport, dport; 9230Sstevel@tonic-gate tcp_seq seq, ack; 9240Sstevel@tonic-gate uint16_t win, urp; 9250Sstevel@tonic-gate 9260Sstevel@tonic-gate mdb_printf("%<b>TCP header%</b>\n"); 9270Sstevel@tonic-gate 9280Sstevel@tonic-gate mdb_nhconvert(&sport, &tcph->th_sport, sizeof (sport)); 9290Sstevel@tonic-gate mdb_nhconvert(&dport, &tcph->th_dport, sizeof (dport)); 9300Sstevel@tonic-gate mdb_nhconvert(&seq, &tcph->th_seq, sizeof (seq)); 9310Sstevel@tonic-gate mdb_nhconvert(&ack, &tcph->th_ack, sizeof (ack)); 9320Sstevel@tonic-gate mdb_nhconvert(&win, &tcph->th_win, sizeof (win)); 9330Sstevel@tonic-gate mdb_nhconvert(&urp, &tcph->th_urp, sizeof (urp)); 9340Sstevel@tonic-gate 9350Sstevel@tonic-gate mdb_printf("%<u>%6s %6s %10s %10s %4s %5s %5s %5s %-15s%</u>\n", 9360Sstevel@tonic-gate "SPORT", "DPORT", "SEQ", "ACK", "HLEN", "WIN", "CSUM", "URP", 9370Sstevel@tonic-gate "FLAGS"); 9380Sstevel@tonic-gate mdb_printf("%6hu %6hu %10u %10u %4d %5hu %5hu %5hu <%b>\n", 9390Sstevel@tonic-gate sport, dport, seq, ack, tcph->th_off << 2, win, 9400Sstevel@tonic-gate tcph->th_sum, urp, tcph->th_flags, tcp_flags); 9410Sstevel@tonic-gate mdb_printf("0x%04x 0x%04x 0x%08x 0x%08x\n\n", 9420Sstevel@tonic-gate sport, dport, seq, ack); 9430Sstevel@tonic-gate } 9440Sstevel@tonic-gate 9450Sstevel@tonic-gate /* ARGSUSED */ 9460Sstevel@tonic-gate static int 9470Sstevel@tonic-gate tcphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 9480Sstevel@tonic-gate { 9490Sstevel@tonic-gate struct tcphdr tcph; 9500Sstevel@tonic-gate 9510Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 9520Sstevel@tonic-gate return (DCMD_USAGE); 9530Sstevel@tonic-gate 9540Sstevel@tonic-gate if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) { 9550Sstevel@tonic-gate mdb_warn("failed to read TCP header at %p", addr); 9560Sstevel@tonic-gate return (DCMD_ERR); 9570Sstevel@tonic-gate } 9580Sstevel@tonic-gate tcphdr_print(&tcph); 9590Sstevel@tonic-gate return (DCMD_OK); 9600Sstevel@tonic-gate } 9610Sstevel@tonic-gate 9620Sstevel@tonic-gate static void 9630Sstevel@tonic-gate udphdr_print(struct udphdr *udph) 9640Sstevel@tonic-gate { 9650Sstevel@tonic-gate in_port_t sport, dport; 9660Sstevel@tonic-gate uint16_t hlen; 9670Sstevel@tonic-gate 9680Sstevel@tonic-gate mdb_printf("%<b>UDP header%</b>\n"); 9690Sstevel@tonic-gate 9700Sstevel@tonic-gate mdb_nhconvert(&sport, &udph->uh_sport, sizeof (sport)); 9710Sstevel@tonic-gate mdb_nhconvert(&dport, &udph->uh_dport, sizeof (dport)); 9720Sstevel@tonic-gate mdb_nhconvert(&hlen, &udph->uh_ulen, sizeof (hlen)); 9730Sstevel@tonic-gate 9740Sstevel@tonic-gate mdb_printf("%<u>%14s %14s %5s %6s%</u>\n", 9750Sstevel@tonic-gate "SPORT", "DPORT", "LEN", "CSUM"); 9760Sstevel@tonic-gate mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %5hu 0x%04hx\n\n", sport, sport, 9770Sstevel@tonic-gate dport, dport, hlen, udph->uh_sum); 9780Sstevel@tonic-gate } 9790Sstevel@tonic-gate 9800Sstevel@tonic-gate /* ARGSUSED */ 9810Sstevel@tonic-gate static int 9820Sstevel@tonic-gate udphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 9830Sstevel@tonic-gate { 9840Sstevel@tonic-gate struct udphdr udph; 9850Sstevel@tonic-gate 9860Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 9870Sstevel@tonic-gate return (DCMD_USAGE); 9880Sstevel@tonic-gate 9890Sstevel@tonic-gate if (mdb_vread(&udph, sizeof (udph), addr) == -1) { 9900Sstevel@tonic-gate mdb_warn("failed to read UDP header at %p", addr); 9910Sstevel@tonic-gate return (DCMD_ERR); 9920Sstevel@tonic-gate } 9930Sstevel@tonic-gate udphdr_print(&udph); 9940Sstevel@tonic-gate return (DCMD_OK); 9950Sstevel@tonic-gate } 9960Sstevel@tonic-gate 9970Sstevel@tonic-gate static void 9980Sstevel@tonic-gate sctphdr_print(sctp_hdr_t *sctph) 9990Sstevel@tonic-gate { 10000Sstevel@tonic-gate in_port_t sport, dport; 10010Sstevel@tonic-gate 10020Sstevel@tonic-gate mdb_printf("%<b>SCTP header%</b>\n"); 10030Sstevel@tonic-gate mdb_nhconvert(&sport, &sctph->sh_sport, sizeof (sport)); 10040Sstevel@tonic-gate mdb_nhconvert(&dport, &sctph->sh_dport, sizeof (dport)); 10050Sstevel@tonic-gate 10060Sstevel@tonic-gate mdb_printf("%<u>%14s %14s %10s %10s%</u>\n", 10070Sstevel@tonic-gate "SPORT", "DPORT", "VTAG", "CHKSUM"); 10080Sstevel@tonic-gate mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %10u 0x%08x\n\n", sport, sport, 10090Sstevel@tonic-gate dport, dport, sctph->sh_verf, sctph->sh_chksum); 10100Sstevel@tonic-gate } 10110Sstevel@tonic-gate 10120Sstevel@tonic-gate /* ARGSUSED */ 10130Sstevel@tonic-gate static int 10140Sstevel@tonic-gate sctphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 10150Sstevel@tonic-gate { 10160Sstevel@tonic-gate sctp_hdr_t sctph; 10170Sstevel@tonic-gate 10180Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 10190Sstevel@tonic-gate return (DCMD_USAGE); 10200Sstevel@tonic-gate 10210Sstevel@tonic-gate if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) { 10220Sstevel@tonic-gate mdb_warn("failed to read SCTP header at %p", addr); 10230Sstevel@tonic-gate return (DCMD_ERR); 10240Sstevel@tonic-gate } 10250Sstevel@tonic-gate 10260Sstevel@tonic-gate sctphdr_print(&sctph); 10270Sstevel@tonic-gate return (DCMD_OK); 10280Sstevel@tonic-gate } 10290Sstevel@tonic-gate 10300Sstevel@tonic-gate static int 10310Sstevel@tonic-gate transport_hdr(int proto, uintptr_t addr) 10320Sstevel@tonic-gate { 10330Sstevel@tonic-gate mdb_printf("\n"); 10340Sstevel@tonic-gate switch (proto) { 10350Sstevel@tonic-gate case IPPROTO_TCP: { 10360Sstevel@tonic-gate struct tcphdr tcph; 10370Sstevel@tonic-gate 10380Sstevel@tonic-gate if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) { 10390Sstevel@tonic-gate mdb_warn("failed to read TCP header at %p", addr); 10400Sstevel@tonic-gate return (DCMD_ERR); 10410Sstevel@tonic-gate } 10420Sstevel@tonic-gate tcphdr_print(&tcph); 10430Sstevel@tonic-gate break; 10440Sstevel@tonic-gate } 10450Sstevel@tonic-gate case IPPROTO_UDP: { 10460Sstevel@tonic-gate struct udphdr udph; 10470Sstevel@tonic-gate 10480Sstevel@tonic-gate if (mdb_vread(&udph, sizeof (udph), addr) == -1) { 10490Sstevel@tonic-gate mdb_warn("failed to read UDP header at %p", addr); 10500Sstevel@tonic-gate return (DCMD_ERR); 10510Sstevel@tonic-gate } 10520Sstevel@tonic-gate udphdr_print(&udph); 10530Sstevel@tonic-gate break; 10540Sstevel@tonic-gate } 10550Sstevel@tonic-gate case IPPROTO_SCTP: { 10560Sstevel@tonic-gate sctp_hdr_t sctph; 10570Sstevel@tonic-gate 10580Sstevel@tonic-gate if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) { 10590Sstevel@tonic-gate mdb_warn("failed to read SCTP header at %p", addr); 10600Sstevel@tonic-gate return (DCMD_ERR); 10610Sstevel@tonic-gate } 10620Sstevel@tonic-gate sctphdr_print(&sctph); 10630Sstevel@tonic-gate break; 10640Sstevel@tonic-gate } 10650Sstevel@tonic-gate default: 10660Sstevel@tonic-gate break; 10670Sstevel@tonic-gate } 10680Sstevel@tonic-gate 10690Sstevel@tonic-gate return (DCMD_OK); 10700Sstevel@tonic-gate } 10710Sstevel@tonic-gate 10720Sstevel@tonic-gate static const mdb_bitmask_t ip_flags[] = { 10730Sstevel@tonic-gate { "DF", IPH_DF, IPH_DF }, 10740Sstevel@tonic-gate { "MF", IPH_MF, IPH_MF }, 10750Sstevel@tonic-gate { NULL, 0, 0 } 10760Sstevel@tonic-gate }; 10770Sstevel@tonic-gate 10780Sstevel@tonic-gate /* ARGSUSED */ 10790Sstevel@tonic-gate static int 10800Sstevel@tonic-gate iphdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 10810Sstevel@tonic-gate { 10820Sstevel@tonic-gate uint_t verbose = FALSE, force = FALSE; 10830Sstevel@tonic-gate ipha_t iph[1]; 10840Sstevel@tonic-gate uint16_t ver, totlen, hdrlen, ipid, off, csum; 10850Sstevel@tonic-gate uintptr_t nxt_proto; 10860Sstevel@tonic-gate char exp_csum[8]; 10870Sstevel@tonic-gate 10880Sstevel@tonic-gate if (mdb_getopts(argc, argv, 10890Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 10900Sstevel@tonic-gate 'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc) 10910Sstevel@tonic-gate return (DCMD_USAGE); 10920Sstevel@tonic-gate 10930Sstevel@tonic-gate if (mdb_vread(iph, sizeof (*iph), addr) == -1) { 10940Sstevel@tonic-gate mdb_warn("failed to read IPv4 header at %p", addr); 10950Sstevel@tonic-gate return (DCMD_ERR); 10960Sstevel@tonic-gate } 10970Sstevel@tonic-gate 10980Sstevel@tonic-gate ver = (iph->ipha_version_and_hdr_length & 0xf0) >> 4; 10990Sstevel@tonic-gate if (ver != IPV4_VERSION) { 11000Sstevel@tonic-gate if (ver == IPV6_VERSION) { 11010Sstevel@tonic-gate return (ip6hdr(addr, flags, argc, argv)); 11020Sstevel@tonic-gate } else if (!force) { 11030Sstevel@tonic-gate mdb_warn("unknown IP version: %d\n", ver); 11040Sstevel@tonic-gate return (DCMD_ERR); 11050Sstevel@tonic-gate } 11060Sstevel@tonic-gate } 11070Sstevel@tonic-gate 11080Sstevel@tonic-gate mdb_printf("%<b>IPv4 header%</b>\n"); 11090Sstevel@tonic-gate mdb_printf("%-34s %-34s\n" 11100Sstevel@tonic-gate "%<u>%-4s %-4s %-5s %-5s %-6s %-5s %-5s %-6s %-8s %-6s%</u>\n", 11110Sstevel@tonic-gate "SRC", "DST", 11120Sstevel@tonic-gate "HLEN", "TOS", "LEN", "ID", "OFFSET", "TTL", "PROTO", "CHKSUM", 11130Sstevel@tonic-gate "EXP-CSUM", "FLGS"); 11140Sstevel@tonic-gate 11150Sstevel@tonic-gate hdrlen = (iph->ipha_version_and_hdr_length & 0x0f) << 2; 11160Sstevel@tonic-gate mdb_nhconvert(&totlen, &iph->ipha_length, sizeof (totlen)); 11170Sstevel@tonic-gate mdb_nhconvert(&ipid, &iph->ipha_ident, sizeof (ipid)); 11180Sstevel@tonic-gate mdb_nhconvert(&off, &iph->ipha_fragment_offset_and_flags, sizeof (off)); 11190Sstevel@tonic-gate if (hdrlen == IP_SIMPLE_HDR_LENGTH) { 11200Sstevel@tonic-gate if ((csum = ipcksum(iph, sizeof (*iph))) != 0) 11210Sstevel@tonic-gate csum = ~(~csum + ~iph->ipha_hdr_checksum); 11220Sstevel@tonic-gate else 11230Sstevel@tonic-gate csum = iph->ipha_hdr_checksum; 11240Sstevel@tonic-gate mdb_snprintf(exp_csum, 8, "%u", csum); 11250Sstevel@tonic-gate } else { 11260Sstevel@tonic-gate mdb_snprintf(exp_csum, 8, "<n/a>"); 11270Sstevel@tonic-gate } 11280Sstevel@tonic-gate 11290Sstevel@tonic-gate mdb_printf("%-34I %-34I%\n" 11300Sstevel@tonic-gate "%-4d %-4d %-5hu %-5hu %-6hu %-5hu %-5hu %-6u %-8s <%5hb>\n", 11310Sstevel@tonic-gate iph->ipha_src, iph->ipha_dst, 11320Sstevel@tonic-gate hdrlen, iph->ipha_type_of_service, totlen, ipid, 11330Sstevel@tonic-gate (off << 3) & 0xffff, iph->ipha_ttl, iph->ipha_protocol, 11340Sstevel@tonic-gate iph->ipha_hdr_checksum, exp_csum, off, ip_flags); 11350Sstevel@tonic-gate 11360Sstevel@tonic-gate if (verbose) { 11370Sstevel@tonic-gate nxt_proto = addr + hdrlen; 11380Sstevel@tonic-gate return (transport_hdr(iph->ipha_protocol, nxt_proto)); 11390Sstevel@tonic-gate } else { 11400Sstevel@tonic-gate return (DCMD_OK); 11410Sstevel@tonic-gate } 11420Sstevel@tonic-gate } 11430Sstevel@tonic-gate 11440Sstevel@tonic-gate /* ARGSUSED */ 11450Sstevel@tonic-gate static int 11460Sstevel@tonic-gate ip6hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 11470Sstevel@tonic-gate { 11480Sstevel@tonic-gate uint_t verbose = FALSE, force = FALSE; 11490Sstevel@tonic-gate ip6_t iph[1]; 11500Sstevel@tonic-gate int ver, class, flow; 11510Sstevel@tonic-gate uint16_t plen; 11520Sstevel@tonic-gate uintptr_t nxt_proto; 11530Sstevel@tonic-gate 11540Sstevel@tonic-gate if (mdb_getopts(argc, argv, 11550Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 11560Sstevel@tonic-gate 'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc) 11570Sstevel@tonic-gate return (DCMD_USAGE); 11580Sstevel@tonic-gate 11590Sstevel@tonic-gate if (mdb_vread(iph, sizeof (*iph), addr) == -1) { 11600Sstevel@tonic-gate mdb_warn("failed to read IPv6 header at %p", addr); 11610Sstevel@tonic-gate return (DCMD_ERR); 11620Sstevel@tonic-gate } 11630Sstevel@tonic-gate 11640Sstevel@tonic-gate ver = (iph->ip6_vfc & 0xf0) >> 4; 11650Sstevel@tonic-gate if (ver != IPV6_VERSION) { 11660Sstevel@tonic-gate if (ver == IPV4_VERSION) { 11670Sstevel@tonic-gate return (iphdr(addr, flags, argc, argv)); 11680Sstevel@tonic-gate } else if (!force) { 11690Sstevel@tonic-gate mdb_warn("unknown IP version: %d\n", ver); 11700Sstevel@tonic-gate return (DCMD_ERR); 11710Sstevel@tonic-gate } 11720Sstevel@tonic-gate } 11730Sstevel@tonic-gate 11740Sstevel@tonic-gate mdb_printf("%<b>IPv6 header%</b>\n"); 11750Sstevel@tonic-gate mdb_printf("%<u>%-26s %-26s %4s %7s %5s %3s %3s%</u>\n", 11760Sstevel@tonic-gate "SRC", "DST", "TCLS", "FLOW-ID", "PLEN", "NXT", "HOP"); 11770Sstevel@tonic-gate 11780Sstevel@tonic-gate class = (iph->ip6_vcf & IPV6_FLOWINFO_TCLASS) >> 20; 11790Sstevel@tonic-gate mdb_nhconvert(&class, &class, sizeof (class)); 11800Sstevel@tonic-gate flow = iph->ip6_vcf & IPV6_FLOWINFO_FLOWLABEL; 11810Sstevel@tonic-gate mdb_nhconvert(&flow, &flow, sizeof (flow)); 11820Sstevel@tonic-gate mdb_nhconvert(&plen, &iph->ip6_plen, sizeof (plen)); 11830Sstevel@tonic-gate 11840Sstevel@tonic-gate mdb_printf("%-26N %-26N %4d %7d %5hu %3d %3d\n", 11850Sstevel@tonic-gate &iph->ip6_src, &iph->ip6_dst, 11860Sstevel@tonic-gate class, flow, plen, iph->ip6_nxt, iph->ip6_hlim); 11870Sstevel@tonic-gate 11880Sstevel@tonic-gate if (verbose) { 11890Sstevel@tonic-gate nxt_proto = addr + sizeof (ip6_t); 11900Sstevel@tonic-gate return (transport_hdr(iph->ip6_nxt, nxt_proto)); 11910Sstevel@tonic-gate } else { 11920Sstevel@tonic-gate return (DCMD_OK); 11930Sstevel@tonic-gate } 11940Sstevel@tonic-gate } 11950Sstevel@tonic-gate 11960Sstevel@tonic-gate int 1197*11042SErik.Nordmark@Sun.COM nce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1198*11042SErik.Nordmark@Sun.COM { 1199*11042SErik.Nordmark@Sun.COM nce_t nce; 1200*11042SErik.Nordmark@Sun.COM nce_cbdata_t nce_cb; 1201*11042SErik.Nordmark@Sun.COM int ipversion = 0; 1202*11042SErik.Nordmark@Sun.COM const char *opt_P = NULL, *opt_ill; 1203*11042SErik.Nordmark@Sun.COM 1204*11042SErik.Nordmark@Sun.COM if (mdb_getopts(argc, argv, 1205*11042SErik.Nordmark@Sun.COM 'i', MDB_OPT_STR, &opt_ill, 1206*11042SErik.Nordmark@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 1207*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 1208*11042SErik.Nordmark@Sun.COM 1209*11042SErik.Nordmark@Sun.COM if (opt_P != NULL) { 1210*11042SErik.Nordmark@Sun.COM if (strcmp("v4", opt_P) == 0) { 1211*11042SErik.Nordmark@Sun.COM ipversion = IPV4_VERSION; 1212*11042SErik.Nordmark@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 1213*11042SErik.Nordmark@Sun.COM ipversion = IPV6_VERSION; 1214*11042SErik.Nordmark@Sun.COM } else { 1215*11042SErik.Nordmark@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 1216*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 1217*11042SErik.Nordmark@Sun.COM } 1218*11042SErik.Nordmark@Sun.COM } 1219*11042SErik.Nordmark@Sun.COM 1220*11042SErik.Nordmark@Sun.COM if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 1221*11042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s %5s %18s %?s %s %s %</u>\n", 1222*11042SErik.Nordmark@Sun.COM "ADDR", "INTF", "LLADDR", "FP_MP", "REFCNT", 1223*11042SErik.Nordmark@Sun.COM "NCE_ADDR"); 1224*11042SErik.Nordmark@Sun.COM } 1225*11042SErik.Nordmark@Sun.COM 1226*11042SErik.Nordmark@Sun.COM bzero(&nce_cb, sizeof (nce_cb)); 1227*11042SErik.Nordmark@Sun.COM if (opt_ill != NULL) { 1228*11042SErik.Nordmark@Sun.COM strcpy(nce_cb.nce_ill_name, opt_ill); 1229*11042SErik.Nordmark@Sun.COM } 1230*11042SErik.Nordmark@Sun.COM nce_cb.nce_ipversion = ipversion; 1231*11042SErik.Nordmark@Sun.COM 1232*11042SErik.Nordmark@Sun.COM if (flags & DCMD_ADDRSPEC) { 1233*11042SErik.Nordmark@Sun.COM (void) mdb_vread(&nce, sizeof (nce_t), addr); 1234*11042SErik.Nordmark@Sun.COM (void) nce_format(addr, &nce, &nce_cb); 1235*11042SErik.Nordmark@Sun.COM } else if (mdb_walk("nce", (mdb_walk_cb_t)nce_format, &nce_cb) == -1) { 1236*11042SErik.Nordmark@Sun.COM mdb_warn("failed to walk ire table"); 1237*11042SErik.Nordmark@Sun.COM return (DCMD_ERR); 1238*11042SErik.Nordmark@Sun.COM } 1239*11042SErik.Nordmark@Sun.COM 1240*11042SErik.Nordmark@Sun.COM return (DCMD_OK); 1241*11042SErik.Nordmark@Sun.COM } 1242*11042SErik.Nordmark@Sun.COM 1243*11042SErik.Nordmark@Sun.COM /* ARGSUSED */ 1244*11042SErik.Nordmark@Sun.COM static int 1245*11042SErik.Nordmark@Sun.COM dce_format(uintptr_t addr, const dce_t *dcep, void *dce_cb_arg) 1246*11042SErik.Nordmark@Sun.COM { 1247*11042SErik.Nordmark@Sun.COM static const mdb_bitmask_t dmasks[] = { 1248*11042SErik.Nordmark@Sun.COM { "D", DCEF_DEFAULT, DCEF_DEFAULT }, 1249*11042SErik.Nordmark@Sun.COM { "P", DCEF_PMTU, DCEF_PMTU }, 1250*11042SErik.Nordmark@Sun.COM { "U", DCEF_UINFO, DCEF_UINFO }, 1251*11042SErik.Nordmark@Sun.COM { "S", DCEF_TOO_SMALL_PMTU, DCEF_TOO_SMALL_PMTU }, 1252*11042SErik.Nordmark@Sun.COM { NULL, 0, 0 } 1253*11042SErik.Nordmark@Sun.COM }; 1254*11042SErik.Nordmark@Sun.COM char flagsbuf[2 * A_CNT(dmasks)]; 1255*11042SErik.Nordmark@Sun.COM int ipversion = *(int *)dce_cb_arg; 1256*11042SErik.Nordmark@Sun.COM boolean_t condemned = dcep->dce_generation == DCE_GENERATION_CONDEMNED; 1257*11042SErik.Nordmark@Sun.COM 1258*11042SErik.Nordmark@Sun.COM if (ipversion != 0 && ipversion != dcep->dce_ipversion) 1259*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 1260*11042SErik.Nordmark@Sun.COM 1261*11042SErik.Nordmark@Sun.COM mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%b", dcep->dce_flags, 1262*11042SErik.Nordmark@Sun.COM dmasks); 1263*11042SErik.Nordmark@Sun.COM 1264*11042SErik.Nordmark@Sun.COM switch (dcep->dce_ipversion) { 1265*11042SErik.Nordmark@Sun.COM case IPV4_VERSION: 1266*11042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30I %</u>\n", addr, condemned ? 1267*11042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v4addr); 1268*11042SErik.Nordmark@Sun.COM break; 1269*11042SErik.Nordmark@Sun.COM case IPV6_VERSION: 1270*11042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30N %</u>\n", addr, condemned ? 1271*11042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v6addr); 1272*11042SErik.Nordmark@Sun.COM break; 1273*11042SErik.Nordmark@Sun.COM default: 1274*11042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30s %</u>\n", addr, condemned ? 1275*11042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, ""); 1276*11042SErik.Nordmark@Sun.COM } 1277*11042SErik.Nordmark@Sun.COM 1278*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 1279*11042SErik.Nordmark@Sun.COM } 1280*11042SErik.Nordmark@Sun.COM 1281*11042SErik.Nordmark@Sun.COM int 1282*11042SErik.Nordmark@Sun.COM dce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1283*11042SErik.Nordmark@Sun.COM { 1284*11042SErik.Nordmark@Sun.COM dce_t dce; 1285*11042SErik.Nordmark@Sun.COM const char *opt_P = NULL; 1286*11042SErik.Nordmark@Sun.COM const char *zone_name = NULL; 1287*11042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL; 1288*11042SErik.Nordmark@Sun.COM int ipversion = 0; 1289*11042SErik.Nordmark@Sun.COM 1290*11042SErik.Nordmark@Sun.COM if (mdb_getopts(argc, argv, 1291*11042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name, 1292*11042SErik.Nordmark@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 1293*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 1294*11042SErik.Nordmark@Sun.COM 1295*11042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */ 1296*11042SErik.Nordmark@Sun.COM if (zone_name != NULL) { 1297*11042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name); 1298*11042SErik.Nordmark@Sun.COM if (ipst == NULL) 1299*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 1300*11042SErik.Nordmark@Sun.COM } 1301*11042SErik.Nordmark@Sun.COM 1302*11042SErik.Nordmark@Sun.COM if (opt_P != NULL) { 1303*11042SErik.Nordmark@Sun.COM if (strcmp("v4", opt_P) == 0) { 1304*11042SErik.Nordmark@Sun.COM ipversion = IPV4_VERSION; 1305*11042SErik.Nordmark@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 1306*11042SErik.Nordmark@Sun.COM ipversion = IPV6_VERSION; 1307*11042SErik.Nordmark@Sun.COM } else { 1308*11042SErik.Nordmark@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 1309*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 1310*11042SErik.Nordmark@Sun.COM } 1311*11042SErik.Nordmark@Sun.COM } 1312*11042SErik.Nordmark@Sun.COM 1313*11042SErik.Nordmark@Sun.COM if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 1314*11042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s%3s %8s %8s %30s %</u>\n", 1315*11042SErik.Nordmark@Sun.COM "ADDR", "", "FLAGS", "PMTU", "DST_ADDR"); 1316*11042SErik.Nordmark@Sun.COM } 1317*11042SErik.Nordmark@Sun.COM 1318*11042SErik.Nordmark@Sun.COM if (flags & DCMD_ADDRSPEC) { 1319*11042SErik.Nordmark@Sun.COM (void) mdb_vread(&dce, sizeof (dce_t), addr); 1320*11042SErik.Nordmark@Sun.COM (void) dce_format(addr, &dce, &ipversion); 1321*11042SErik.Nordmark@Sun.COM } else if (mdb_pwalk("dce", (mdb_walk_cb_t)dce_format, &ipversion, 1322*11042SErik.Nordmark@Sun.COM (uintptr_t)ipst) == -1) { 1323*11042SErik.Nordmark@Sun.COM mdb_warn("failed to walk dce cache"); 1324*11042SErik.Nordmark@Sun.COM return (DCMD_ERR); 1325*11042SErik.Nordmark@Sun.COM } 1326*11042SErik.Nordmark@Sun.COM 1327*11042SErik.Nordmark@Sun.COM return (DCMD_OK); 1328*11042SErik.Nordmark@Sun.COM } 1329*11042SErik.Nordmark@Sun.COM 1330*11042SErik.Nordmark@Sun.COM int 13310Sstevel@tonic-gate ire(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 13320Sstevel@tonic-gate { 13330Sstevel@tonic-gate uint_t verbose = FALSE; 13340Sstevel@tonic-gate ire_t ire; 13355940Ssowmini ire_cbdata_t ire_cb; 13365940Ssowmini int ipversion = 0; 13375940Ssowmini const char *opt_P = NULL; 1338*11042SErik.Nordmark@Sun.COM const char *zone_name = NULL; 1339*11042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL; 13400Sstevel@tonic-gate 13410Sstevel@tonic-gate if (mdb_getopts(argc, argv, 13425940Ssowmini 'v', MDB_OPT_SETBITS, TRUE, &verbose, 1343*11042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name, 13445940Ssowmini 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 13450Sstevel@tonic-gate return (DCMD_USAGE); 13460Sstevel@tonic-gate 1347*11042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */ 1348*11042SErik.Nordmark@Sun.COM if (zone_name != NULL) { 1349*11042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name); 1350*11042SErik.Nordmark@Sun.COM if (ipst == NULL) 1351*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 1352*11042SErik.Nordmark@Sun.COM } 1353*11042SErik.Nordmark@Sun.COM 13545940Ssowmini if (opt_P != NULL) { 13555940Ssowmini if (strcmp("v4", opt_P) == 0) { 13565940Ssowmini ipversion = IPV4_VERSION; 13575940Ssowmini } else if (strcmp("v6", opt_P) == 0) { 13585940Ssowmini ipversion = IPV6_VERSION; 13595940Ssowmini } else { 13605940Ssowmini mdb_warn("invalid protocol '%s'\n", opt_P); 13615940Ssowmini return (DCMD_USAGE); 13625940Ssowmini } 13635940Ssowmini } 13645940Ssowmini 13650Sstevel@tonic-gate if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 13660Sstevel@tonic-gate 13670Sstevel@tonic-gate if (verbose) { 13680Sstevel@tonic-gate mdb_printf("%?s %40s %-20s%\n" 13690Sstevel@tonic-gate "%?s %40s %-20s%\n" 1370*11042SErik.Nordmark@Sun.COM "%<u>%?s %40s %4s %-20s %s%</u>\n", 13710Sstevel@tonic-gate "ADDR", "SRC", "TYPE", 13720Sstevel@tonic-gate "", "DST", "MARKS", 1373*11042SErik.Nordmark@Sun.COM "", "STACK", "ZONE", "FLAGS", "INTF"); 13740Sstevel@tonic-gate } else { 1375*11042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s %30s %30s %5s %4s %s%</u>\n", 1376*11042SErik.Nordmark@Sun.COM "ADDR", "SRC", "DST", "STACK", "ZONE", "INTF"); 13770Sstevel@tonic-gate } 13780Sstevel@tonic-gate } 13790Sstevel@tonic-gate 13805940Ssowmini ire_cb.verbose = (verbose == TRUE); 13815940Ssowmini ire_cb.ire_ipversion = ipversion; 13825940Ssowmini 13830Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) { 13840Sstevel@tonic-gate (void) mdb_vread(&ire, sizeof (ire_t), addr); 13855940Ssowmini (void) ire_format(addr, &ire, &ire_cb); 1386*11042SErik.Nordmark@Sun.COM } else if (mdb_pwalk("ire", (mdb_walk_cb_t)ire_format, &ire_cb, 1387*11042SErik.Nordmark@Sun.COM (uintptr_t)ipst) == -1) { 13880Sstevel@tonic-gate mdb_warn("failed to walk ire table"); 13890Sstevel@tonic-gate return (DCMD_ERR); 13900Sstevel@tonic-gate } 13910Sstevel@tonic-gate 13920Sstevel@tonic-gate return (DCMD_OK); 13930Sstevel@tonic-gate } 13940Sstevel@tonic-gate 13950Sstevel@tonic-gate static size_t 13960Sstevel@tonic-gate mi_osize(const queue_t *q) 13970Sstevel@tonic-gate { 13980Sstevel@tonic-gate /* 13990Sstevel@tonic-gate * The code in common/inet/mi.c allocates an extra word to store the 14000Sstevel@tonic-gate * size of the allocation. An mi_o_s is thus a size_t plus an mi_o_s. 14010Sstevel@tonic-gate */ 14020Sstevel@tonic-gate struct mi_block { 14030Sstevel@tonic-gate size_t mi_nbytes; 14040Sstevel@tonic-gate struct mi_o_s mi_o; 14050Sstevel@tonic-gate } m; 14060Sstevel@tonic-gate 14070Sstevel@tonic-gate if (mdb_vread(&m, sizeof (m), (uintptr_t)q->q_ptr - 14080Sstevel@tonic-gate sizeof (m)) == sizeof (m)) 14090Sstevel@tonic-gate return (m.mi_nbytes - sizeof (m)); 14100Sstevel@tonic-gate 14110Sstevel@tonic-gate return (0); 14120Sstevel@tonic-gate } 14130Sstevel@tonic-gate 14140Sstevel@tonic-gate static void 14150Sstevel@tonic-gate ip_ill_qinfo(const queue_t *q, char *buf, size_t nbytes) 14160Sstevel@tonic-gate { 14170Sstevel@tonic-gate char name[32]; 14180Sstevel@tonic-gate ill_t ill; 14190Sstevel@tonic-gate 14200Sstevel@tonic-gate if (mdb_vread(&ill, sizeof (ill), 14210Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill) && 14220Sstevel@tonic-gate mdb_readstr(name, sizeof (name), (uintptr_t)ill.ill_name) > 0) 14230Sstevel@tonic-gate (void) mdb_snprintf(buf, nbytes, "if: %s", name); 14240Sstevel@tonic-gate } 14250Sstevel@tonic-gate 14260Sstevel@tonic-gate void 14270Sstevel@tonic-gate ip_qinfo(const queue_t *q, char *buf, size_t nbytes) 14280Sstevel@tonic-gate { 14290Sstevel@tonic-gate size_t size = mi_osize(q); 14300Sstevel@tonic-gate 14310Sstevel@tonic-gate if (size == sizeof (ill_t)) 14320Sstevel@tonic-gate ip_ill_qinfo(q, buf, nbytes); 14330Sstevel@tonic-gate } 14340Sstevel@tonic-gate 14350Sstevel@tonic-gate uintptr_t 14360Sstevel@tonic-gate ip_rnext(const queue_t *q) 14370Sstevel@tonic-gate { 14380Sstevel@tonic-gate size_t size = mi_osize(q); 14390Sstevel@tonic-gate ill_t ill; 14400Sstevel@tonic-gate 14410Sstevel@tonic-gate if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill), 14420Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill)) 14430Sstevel@tonic-gate return ((uintptr_t)ill.ill_rq); 14440Sstevel@tonic-gate 14450Sstevel@tonic-gate return (NULL); 14460Sstevel@tonic-gate } 14470Sstevel@tonic-gate 14480Sstevel@tonic-gate uintptr_t 14490Sstevel@tonic-gate ip_wnext(const queue_t *q) 14500Sstevel@tonic-gate { 14510Sstevel@tonic-gate size_t size = mi_osize(q); 14520Sstevel@tonic-gate ill_t ill; 14530Sstevel@tonic-gate 14540Sstevel@tonic-gate if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill), 14550Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill)) 14560Sstevel@tonic-gate return ((uintptr_t)ill.ill_wq); 14570Sstevel@tonic-gate 14580Sstevel@tonic-gate return (NULL); 14590Sstevel@tonic-gate } 14600Sstevel@tonic-gate 14610Sstevel@tonic-gate /* 14620Sstevel@tonic-gate * Print the core fields in an squeue_t. With the "-v" argument, 14630Sstevel@tonic-gate * provide more verbose output. 14640Sstevel@tonic-gate */ 14650Sstevel@tonic-gate static int 14660Sstevel@tonic-gate squeue(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 14670Sstevel@tonic-gate { 14680Sstevel@tonic-gate unsigned int i; 14690Sstevel@tonic-gate unsigned int verbose = FALSE; 14700Sstevel@tonic-gate const int SQUEUE_STATEDELT = (int)(sizeof (uintptr_t) + 9); 14710Sstevel@tonic-gate boolean_t arm; 14720Sstevel@tonic-gate squeue_t squeue; 14730Sstevel@tonic-gate 14740Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 14750Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`squeue_cache", "ip`squeue", 14760Sstevel@tonic-gate argc, argv) == -1) { 14770Sstevel@tonic-gate mdb_warn("failed to walk squeue cache"); 14780Sstevel@tonic-gate return (DCMD_ERR); 14790Sstevel@tonic-gate } 14800Sstevel@tonic-gate return (DCMD_OK); 14810Sstevel@tonic-gate } 14820Sstevel@tonic-gate 14830Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) 14840Sstevel@tonic-gate != argc) 14850Sstevel@tonic-gate return (DCMD_USAGE); 14860Sstevel@tonic-gate 14870Sstevel@tonic-gate if (!DCMD_HDRSPEC(flags) && verbose) 14880Sstevel@tonic-gate mdb_printf("\n\n"); 14890Sstevel@tonic-gate 14900Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) || verbose) { 14910Sstevel@tonic-gate mdb_printf("%?s %-5s %-3s %?s %?s %?s\n", 14920Sstevel@tonic-gate "ADDR", "STATE", "CPU", 14930Sstevel@tonic-gate "FIRST", "LAST", "WORKER"); 14940Sstevel@tonic-gate } 14950Sstevel@tonic-gate 14960Sstevel@tonic-gate if (mdb_vread(&squeue, sizeof (squeue_t), addr) == -1) { 14970Sstevel@tonic-gate mdb_warn("cannot read squeue_t at %p", addr); 14980Sstevel@tonic-gate return (DCMD_ERR); 14990Sstevel@tonic-gate } 15000Sstevel@tonic-gate 15010Sstevel@tonic-gate mdb_printf("%0?p %05x %3d %0?p %0?p %0?p\n", 15020Sstevel@tonic-gate addr, squeue.sq_state, squeue.sq_bind, 15030Sstevel@tonic-gate squeue.sq_first, squeue.sq_last, squeue.sq_worker); 15040Sstevel@tonic-gate 15050Sstevel@tonic-gate if (!verbose) 15060Sstevel@tonic-gate return (DCMD_OK); 15070Sstevel@tonic-gate 15080Sstevel@tonic-gate arm = B_TRUE; 15090Sstevel@tonic-gate for (i = 0; squeue_states[i].bit_name != NULL; i++) { 15100Sstevel@tonic-gate if (((squeue.sq_state) & (1 << i)) == 0) 15110Sstevel@tonic-gate continue; 15120Sstevel@tonic-gate 15130Sstevel@tonic-gate if (arm) { 15140Sstevel@tonic-gate mdb_printf("%*s|\n", SQUEUE_STATEDELT, ""); 15150Sstevel@tonic-gate mdb_printf("%*s+--> ", SQUEUE_STATEDELT, ""); 15160Sstevel@tonic-gate arm = B_FALSE; 15170Sstevel@tonic-gate } else 15180Sstevel@tonic-gate mdb_printf("%*s ", SQUEUE_STATEDELT, ""); 15190Sstevel@tonic-gate 15200Sstevel@tonic-gate mdb_printf("%-12s %s\n", squeue_states[i].bit_name, 15210Sstevel@tonic-gate squeue_states[i].bit_descr); 15220Sstevel@tonic-gate } 15230Sstevel@tonic-gate 15240Sstevel@tonic-gate return (DCMD_OK); 15250Sstevel@tonic-gate } 15260Sstevel@tonic-gate 15270Sstevel@tonic-gate static void 15280Sstevel@tonic-gate ip_squeue_help(void) 15290Sstevel@tonic-gate { 15300Sstevel@tonic-gate mdb_printf("Print the core information for a given NCA squeue_t.\n\n"); 15310Sstevel@tonic-gate mdb_printf("Options:\n"); 15320Sstevel@tonic-gate mdb_printf("\t-v\tbe verbose (more descriptive)\n"); 15330Sstevel@tonic-gate } 15340Sstevel@tonic-gate 15355023Scarlsonj /* 15365023Scarlsonj * This is called by ::th_trace (via a callback) when walking the th_hash 15375023Scarlsonj * list. It calls modent to find the entries. 15385023Scarlsonj */ 15395023Scarlsonj /* ARGSUSED */ 15405023Scarlsonj static int 15415023Scarlsonj modent_summary(uintptr_t addr, const void *data, void *private) 15425023Scarlsonj { 15435023Scarlsonj th_walk_data_t *thw = private; 15445023Scarlsonj const struct mod_hash_entry *mhe = data; 15455023Scarlsonj th_trace_t th; 15465023Scarlsonj 15475023Scarlsonj if (mdb_vread(&th, sizeof (th), (uintptr_t)mhe->mhe_val) == -1) { 15485023Scarlsonj mdb_warn("failed to read th_trace_t %p", mhe->mhe_val); 15495023Scarlsonj return (WALK_ERR); 15505023Scarlsonj } 15515023Scarlsonj 15525023Scarlsonj if (th.th_refcnt == 0 && thw->thw_non_zero_only) 15535023Scarlsonj return (WALK_NEXT); 15545023Scarlsonj 15555023Scarlsonj if (!thw->thw_match) { 15565023Scarlsonj mdb_printf("%?p %?p %?p %8d %?p\n", thw->thw_ipst, mhe->mhe_key, 15575023Scarlsonj mhe->mhe_val, th.th_refcnt, th.th_id); 15585023Scarlsonj } else if (thw->thw_matchkey == (uintptr_t)mhe->mhe_key) { 15595023Scarlsonj int i, j, k; 15605023Scarlsonj tr_buf_t *tr; 15615023Scarlsonj 15625023Scarlsonj mdb_printf("Object %p in IP stack %p:\n", mhe->mhe_key, 15635023Scarlsonj thw->thw_ipst); 15645023Scarlsonj i = th.th_trace_lastref; 15655023Scarlsonj mdb_printf("\tThread %p refcnt %d:\n", th.th_id, 15665023Scarlsonj th.th_refcnt); 15675023Scarlsonj for (j = TR_BUF_MAX; j > 0; j--) { 15685023Scarlsonj tr = th.th_trbuf + i; 15695023Scarlsonj if (tr->tr_depth == 0 || tr->tr_depth > TR_STACK_DEPTH) 15705023Scarlsonj break; 15715023Scarlsonj mdb_printf("\t T%+ld:\n", tr->tr_time - 15725023Scarlsonj thw->thw_lbolt); 15735023Scarlsonj for (k = 0; k < tr->tr_depth; k++) 15745023Scarlsonj mdb_printf("\t\t%a\n", tr->tr_stack[k]); 15755023Scarlsonj if (--i < 0) 15765023Scarlsonj i = TR_BUF_MAX - 1; 15775023Scarlsonj } 15785023Scarlsonj } 15795023Scarlsonj return (WALK_NEXT); 15805023Scarlsonj } 15815023Scarlsonj 15825023Scarlsonj /* 15835023Scarlsonj * This is called by ::th_trace (via a callback) when walking the th_hash 15845023Scarlsonj * list. It calls modent to find the entries. 15855023Scarlsonj */ 15865023Scarlsonj /* ARGSUSED */ 15875023Scarlsonj static int 15885023Scarlsonj th_hash_summary(uintptr_t addr, const void *data, void *private) 15895023Scarlsonj { 15905023Scarlsonj const th_hash_t *thh = data; 15915023Scarlsonj th_walk_data_t *thw = private; 15925023Scarlsonj 15935023Scarlsonj thw->thw_ipst = (uintptr_t)thh->thh_ipst; 15945023Scarlsonj return (mdb_pwalk("modent", modent_summary, private, 15955023Scarlsonj (uintptr_t)thh->thh_hash)); 15965023Scarlsonj } 15975023Scarlsonj 15985023Scarlsonj /* 15995023Scarlsonj * Print or summarize the th_trace_t structures. 16005023Scarlsonj */ 16015023Scarlsonj static int 16025023Scarlsonj th_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 16035023Scarlsonj { 16045023Scarlsonj th_walk_data_t thw; 16055023Scarlsonj 16065023Scarlsonj (void) memset(&thw, 0, sizeof (thw)); 16075023Scarlsonj 16085023Scarlsonj if (mdb_getopts(argc, argv, 16095023Scarlsonj 'n', MDB_OPT_SETBITS, TRUE, &thw.thw_non_zero_only, 16105023Scarlsonj NULL) != argc) 16115023Scarlsonj return (DCMD_USAGE); 16125023Scarlsonj 16135023Scarlsonj if (!(flags & DCMD_ADDRSPEC)) { 16145023Scarlsonj /* 16155023Scarlsonj * No address specified. Walk all of the th_hash_t in the 16165023Scarlsonj * system, and summarize the th_trace_t entries in each. 16175023Scarlsonj */ 16185023Scarlsonj mdb_printf("%?s %?s %?s %8s %?s\n", 16195023Scarlsonj "IPSTACK", "OBJECT", "TRACE", "REFCNT", "THREAD"); 16205023Scarlsonj thw.thw_match = B_FALSE; 16215023Scarlsonj } else { 16225023Scarlsonj thw.thw_match = B_TRUE; 16235023Scarlsonj thw.thw_matchkey = addr; 16245023Scarlsonj if (mdb_readvar(&thw.thw_lbolt, 16255023Scarlsonj mdb_prop_postmortem ? "panic_lbolt" : "lbolt") == -1) { 16265023Scarlsonj mdb_warn("failed to read lbolt"); 16275023Scarlsonj return (DCMD_ERR); 16285023Scarlsonj } 16295023Scarlsonj } 16305023Scarlsonj if (mdb_pwalk("th_hash", th_hash_summary, &thw, NULL) == -1) { 16315023Scarlsonj mdb_warn("can't walk th_hash entries"); 16325023Scarlsonj return (DCMD_ERR); 16335023Scarlsonj } 16345023Scarlsonj return (DCMD_OK); 16355023Scarlsonj } 16365023Scarlsonj 16375023Scarlsonj static void 16385023Scarlsonj th_trace_help(void) 16395023Scarlsonj { 1640*11042SErik.Nordmark@Sun.COM mdb_printf("If given an address of an ill_t, ipif_t, ire_t, or ncec_t, " 16415023Scarlsonj "print the\n" 16425023Scarlsonj "corresponding th_trace_t structure in detail. Otherwise, if no " 16435023Scarlsonj "address is\n" 16445023Scarlsonj "given, then summarize all th_trace_t structures.\n\n"); 16455023Scarlsonj mdb_printf("Options:\n" 16465023Scarlsonj "\t-n\tdisplay only entries with non-zero th_refcnt\n"); 16475023Scarlsonj } 16485023Scarlsonj 16490Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = { 16509089SVasumathi.Sundaram@Sun.COM { "conn_status", ":", 16519089SVasumathi.Sundaram@Sun.COM "display connection structures from ipcl hash tables", 16529089SVasumathi.Sundaram@Sun.COM conn_status, conn_status_help }, 16539089SVasumathi.Sundaram@Sun.COM { "srcid_status", ":", 16549089SVasumathi.Sundaram@Sun.COM "display connection structures from ipcl hash tables", 16559089SVasumathi.Sundaram@Sun.COM srcid_status }, 1656*11042SErik.Nordmark@Sun.COM { "ill", "?[-v] [-P v4 | v6] [-s exclusive-ip-zone-name]", 1657*11042SErik.Nordmark@Sun.COM "display ill_t structures", ill, ill_help }, 16580Sstevel@tonic-gate { "illif", "?[-P v4 | v6]", 16590Sstevel@tonic-gate "display or filter IP Lower Level InterFace structures", illif, 16600Sstevel@tonic-gate illif_help }, 16610Sstevel@tonic-gate { "iphdr", ":[-vf]", "display an IPv4 header", iphdr }, 16620Sstevel@tonic-gate { "ip6hdr", ":[-vf]", "display an IPv6 header", ip6hdr }, 16639089SVasumathi.Sundaram@Sun.COM { "ipif", "?[-v] [-P v4 | v6]", "display ipif structures", 16649089SVasumathi.Sundaram@Sun.COM ipif, ipif_help }, 1665*11042SErik.Nordmark@Sun.COM { "ire", "?[-v] [-P v4|v6] [-s exclusive-ip-zone-name]", 16665940Ssowmini "display Internet Route Entry structures", ire }, 1667*11042SErik.Nordmark@Sun.COM { "nce", "?[-P v4|v6] [-i <interface>]", 1668*11042SErik.Nordmark@Sun.COM "display interface-specific Neighbor Cache structures", nce }, 1669*11042SErik.Nordmark@Sun.COM { "ncec", "?[-P v4 | v6]", "display Neighbor Cache Entry structures", 1670*11042SErik.Nordmark@Sun.COM ncec }, 1671*11042SErik.Nordmark@Sun.COM { "dce", "?[-P v4|v6] [-s exclusive-ip-zone-name]", 1672*11042SErik.Nordmark@Sun.COM "display Destination Cache Entry structures", dce }, 16730Sstevel@tonic-gate { "squeue", ":[-v]", "print core squeue_t info", squeue, 16740Sstevel@tonic-gate ip_squeue_help }, 16750Sstevel@tonic-gate { "tcphdr", ":", "display a TCP header", tcphdr }, 16760Sstevel@tonic-gate { "udphdr", ":", "display an UDP header", udphdr }, 16770Sstevel@tonic-gate { "sctphdr", ":", "display an SCTP header", sctphdr }, 16785023Scarlsonj { "th_trace", "?[-n]", "display th_trace_t structures", th_trace, 16795023Scarlsonj th_trace_help }, 16800Sstevel@tonic-gate { NULL } 16810Sstevel@tonic-gate }; 16820Sstevel@tonic-gate 16830Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 16849089SVasumathi.Sundaram@Sun.COM { "conn_status", "walk list of conn_t structures", 16859089SVasumathi.Sundaram@Sun.COM ip_stacks_common_walk_init, conn_status_walk_step, NULL }, 16863448Sdh155122 { "illif", "walk list of ill interface types for all stacks", 16875940Ssowmini ip_stacks_common_walk_init, illif_walk_step, NULL }, 16883448Sdh155122 { "illif_stack", "walk list of ill interface types", 16893448Sdh155122 illif_stack_walk_init, illif_stack_walk_step, 16903448Sdh155122 illif_stack_walk_fini }, 1691*11042SErik.Nordmark@Sun.COM { "ill", "walk active ill_t structures for all stacks", 16929089SVasumathi.Sundaram@Sun.COM ill_walk_init, ill_walk_step, NULL }, 16939089SVasumathi.Sundaram@Sun.COM { "ipif", "walk list of ipif structures for all stacks", 16949089SVasumathi.Sundaram@Sun.COM ipif_walk_init, ipif_walk_step, NULL }, 16959089SVasumathi.Sundaram@Sun.COM { "ipif_list", "walk the linked list of ipif structures " 16969089SVasumathi.Sundaram@Sun.COM "for a given ill", 16979089SVasumathi.Sundaram@Sun.COM ip_list_walk_init, ip_list_walk_step, 16989089SVasumathi.Sundaram@Sun.COM ip_list_walk_fini, &ipif_walk_arg }, 16999089SVasumathi.Sundaram@Sun.COM { "srcid", "walk list of srcid_map structures for all stacks", 17009089SVasumathi.Sundaram@Sun.COM ip_stacks_common_walk_init, srcid_walk_step, NULL }, 17019089SVasumathi.Sundaram@Sun.COM { "srcid_list", "walk list of srcid_map structures for a stack", 17029089SVasumathi.Sundaram@Sun.COM ip_list_walk_init, ip_list_walk_step, ip_list_walk_fini, 17039089SVasumathi.Sundaram@Sun.COM &srcid_walk_arg }, 17040Sstevel@tonic-gate { "ire", "walk active ire_t structures", 17050Sstevel@tonic-gate ire_walk_init, ire_walk_step, NULL }, 17063448Sdh155122 { "ire_next", "walk ire_t structures in the ctable", 17073448Sdh155122 ire_next_walk_init, ire_next_walk_step, NULL }, 1708*11042SErik.Nordmark@Sun.COM { "nce", "walk active nce_t structures", 1709*11042SErik.Nordmark@Sun.COM nce_walk_init, nce_walk_step, NULL }, 1710*11042SErik.Nordmark@Sun.COM { "dce", "walk active dce_t structures", 1711*11042SErik.Nordmark@Sun.COM dce_walk_init, dce_walk_step, NULL }, 17123448Sdh155122 { "ip_stacks", "walk all the ip_stack_t", 17133448Sdh155122 ip_stacks_walk_init, ip_stacks_walk_step, NULL }, 17145023Scarlsonj { "th_hash", "walk all the th_hash_t entries", 17155023Scarlsonj th_hash_walk_init, th_hash_walk_step, NULL }, 1716*11042SErik.Nordmark@Sun.COM { "ncec", "walk list of ncec structures for all stacks", 1717*11042SErik.Nordmark@Sun.COM ip_stacks_common_walk_init, ncec_walk_step, NULL }, 1718*11042SErik.Nordmark@Sun.COM { "ncec_stack", "walk list of ncec structures", 1719*11042SErik.Nordmark@Sun.COM ncec_stack_walk_init, ncec_stack_walk_step, 1720*11042SErik.Nordmark@Sun.COM ncec_stack_walk_fini}, 17219089SVasumathi.Sundaram@Sun.COM { "udp_hash", "walk list of conn_t structures in ips_ipcl_udp_fanout", 17229089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 17239089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &udp_hash_arg}, 17249089SVasumathi.Sundaram@Sun.COM { "conn_hash", "walk list of conn_t structures in ips_ipcl_conn_fanout", 17259089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 17269089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &conn_hash_arg}, 17279089SVasumathi.Sundaram@Sun.COM { "bind_hash", "walk list of conn_t structures in ips_ipcl_bind_fanout", 17289089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 17299089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &bind_hash_arg}, 17309089SVasumathi.Sundaram@Sun.COM { "proto_hash", "walk list of conn_t structures in " 17319089SVasumathi.Sundaram@Sun.COM "ips_ipcl_proto_fanout", 17329089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 17339089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &proto_hash_arg}, 17349089SVasumathi.Sundaram@Sun.COM { "proto_v6_hash", "walk list of conn_t structures in " 17359089SVasumathi.Sundaram@Sun.COM "ips_ipcl_proto_fanout_v6", 17369089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step, 17379089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &proto_v6_hash_arg}, 173810946SSangeeta.Misra@Sun.COM { "ilb_stacks", "walk ilb_stack_t", 173910946SSangeeta.Misra@Sun.COM ip_stacks_walk_init, ilb_stacks_walk_step, NULL }, 174010946SSangeeta.Misra@Sun.COM { "ilb_rules", "walk ilb rules in a given ilb_stack_t", 174110946SSangeeta.Misra@Sun.COM ilb_rules_walk_init, ilb_rules_walk_step, NULL }, 174210946SSangeeta.Misra@Sun.COM { "ilb_servers", "walk server in a given ilb_rule_t", 174310946SSangeeta.Misra@Sun.COM ilb_servers_walk_init, ilb_servers_walk_step, NULL }, 174410946SSangeeta.Misra@Sun.COM { "ilb_nat_src", "walk NAT source table of a given ilb_stack_t", 174510946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_init, ilb_nat_src_walk_step, 174610946SSangeeta.Misra@Sun.COM ilb_common_walk_fini }, 174710946SSangeeta.Misra@Sun.COM { "ilb_conns", "walk NAT table of a given ilb_stack_t", 174810946SSangeeta.Misra@Sun.COM ilb_conn_walk_init, ilb_conn_walk_step, ilb_common_walk_fini }, 174910946SSangeeta.Misra@Sun.COM { "ilb_stickys", "walk sticky table of a given ilb_stack_t", 175010946SSangeeta.Misra@Sun.COM ilb_sticky_walk_init, ilb_sticky_walk_step, 175110946SSangeeta.Misra@Sun.COM ilb_common_walk_fini }, 17520Sstevel@tonic-gate { NULL } 17530Sstevel@tonic-gate }; 17540Sstevel@tonic-gate 17550Sstevel@tonic-gate static const mdb_qops_t ip_qops = { ip_qinfo, ip_rnext, ip_wnext }; 17560Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 17570Sstevel@tonic-gate 17580Sstevel@tonic-gate const mdb_modinfo_t * 17590Sstevel@tonic-gate _mdb_init(void) 17600Sstevel@tonic-gate { 17610Sstevel@tonic-gate GElf_Sym sym; 17620Sstevel@tonic-gate 17632546Scarlsonj if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0) 17640Sstevel@tonic-gate mdb_qops_install(&ip_qops, (uintptr_t)sym.st_value); 17650Sstevel@tonic-gate 17660Sstevel@tonic-gate return (&modinfo); 17670Sstevel@tonic-gate } 17680Sstevel@tonic-gate 17690Sstevel@tonic-gate void 17700Sstevel@tonic-gate _mdb_fini(void) 17710Sstevel@tonic-gate { 17720Sstevel@tonic-gate GElf_Sym sym; 17730Sstevel@tonic-gate 17742546Scarlsonj if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0) 17750Sstevel@tonic-gate mdb_qops_remove(&ip_qops, (uintptr_t)sym.st_value); 17760Sstevel@tonic-gate } 17775940Ssowmini 17785940Ssowmini static char * 1779*11042SErik.Nordmark@Sun.COM ncec_state(int ncec_state) 17805940Ssowmini { 1781*11042SErik.Nordmark@Sun.COM switch (ncec_state) { 17825940Ssowmini case ND_UNCHANGED: 17835940Ssowmini return ("unchanged"); 17845940Ssowmini case ND_INCOMPLETE: 17855940Ssowmini return ("incomplete"); 17865940Ssowmini case ND_REACHABLE: 17875940Ssowmini return ("reachable"); 17885940Ssowmini case ND_STALE: 17895940Ssowmini return ("stale"); 17905940Ssowmini case ND_DELAY: 17915940Ssowmini return ("delay"); 17925940Ssowmini case ND_PROBE: 17935940Ssowmini return ("probe"); 17945940Ssowmini case ND_UNREACHABLE: 17955940Ssowmini return ("unreach"); 17965940Ssowmini case ND_INITIAL: 17975940Ssowmini return ("initial"); 17985940Ssowmini default: 17995940Ssowmini return ("??"); 18005940Ssowmini } 18015940Ssowmini } 18025940Ssowmini 18035940Ssowmini static char * 1804*11042SErik.Nordmark@Sun.COM ncec_l2_addr(const ncec_t *ncec, const ill_t *ill) 1805*11042SErik.Nordmark@Sun.COM { 1806*11042SErik.Nordmark@Sun.COM uchar_t *h; 1807*11042SErik.Nordmark@Sun.COM static char addr_buf[L2MAXADDRSTRLEN]; 1808*11042SErik.Nordmark@Sun.COM 1809*11042SErik.Nordmark@Sun.COM if (ncec->ncec_lladdr == NULL) { 1810*11042SErik.Nordmark@Sun.COM return ("None"); 1811*11042SErik.Nordmark@Sun.COM } 1812*11042SErik.Nordmark@Sun.COM 1813*11042SErik.Nordmark@Sun.COM if (ill->ill_net_type == IRE_IF_RESOLVER) { 1814*11042SErik.Nordmark@Sun.COM 1815*11042SErik.Nordmark@Sun.COM if (ill->ill_phys_addr_length == 0) 1816*11042SErik.Nordmark@Sun.COM return ("None"); 1817*11042SErik.Nordmark@Sun.COM h = mdb_zalloc(ill->ill_phys_addr_length, UM_SLEEP); 1818*11042SErik.Nordmark@Sun.COM if (mdb_vread(h, ill->ill_phys_addr_length, 1819*11042SErik.Nordmark@Sun.COM (uintptr_t)ncec->ncec_lladdr) == -1) { 1820*11042SErik.Nordmark@Sun.COM mdb_warn("failed to read hwaddr at %p", 1821*11042SErik.Nordmark@Sun.COM ncec->ncec_lladdr); 1822*11042SErik.Nordmark@Sun.COM return ("Unknown"); 1823*11042SErik.Nordmark@Sun.COM } 1824*11042SErik.Nordmark@Sun.COM mdb_mac_addr(h, ill->ill_phys_addr_length, 1825*11042SErik.Nordmark@Sun.COM addr_buf, sizeof (addr_buf)); 1826*11042SErik.Nordmark@Sun.COM } else { 1827*11042SErik.Nordmark@Sun.COM return ("None"); 1828*11042SErik.Nordmark@Sun.COM } 1829*11042SErik.Nordmark@Sun.COM mdb_free(h, ill->ill_phys_addr_length); 1830*11042SErik.Nordmark@Sun.COM return (addr_buf); 1831*11042SErik.Nordmark@Sun.COM } 1832*11042SErik.Nordmark@Sun.COM 1833*11042SErik.Nordmark@Sun.COM static char * 18345940Ssowmini nce_l2_addr(const nce_t *nce, const ill_t *ill) 18355940Ssowmini { 18365940Ssowmini uchar_t *h; 18375940Ssowmini static char addr_buf[L2MAXADDRSTRLEN]; 18385940Ssowmini mblk_t mp; 18395940Ssowmini size_t mblen; 18405940Ssowmini 1841*11042SErik.Nordmark@Sun.COM if (nce->nce_dlur_mp == NULL) 18425940Ssowmini return ("None"); 18435940Ssowmini 18445940Ssowmini if (ill->ill_net_type == IRE_IF_RESOLVER) { 18455940Ssowmini if (mdb_vread(&mp, sizeof (mblk_t), 1846*11042SErik.Nordmark@Sun.COM (uintptr_t)nce->nce_dlur_mp) == -1) { 1847*11042SErik.Nordmark@Sun.COM mdb_warn("failed to read nce_dlur_mp at %p", 1848*11042SErik.Nordmark@Sun.COM nce->nce_dlur_mp); 1849*11042SErik.Nordmark@Sun.COM return ("None"); 18505940Ssowmini } 1851*11042SErik.Nordmark@Sun.COM if (ill->ill_phys_addr_length == 0) 18525940Ssowmini return ("None"); 18535940Ssowmini mblen = mp.b_wptr - mp.b_rptr; 18545940Ssowmini if (mblen > (sizeof (dl_unitdata_req_t) + MAX_SAP_LEN) || 1855*11042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length > MAX_SAP_LEN || 1856*11042SErik.Nordmark@Sun.COM (NCE_LL_ADDR_OFFSET(ill) + 1857*11042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length) > mblen) { 1858*11042SErik.Nordmark@Sun.COM return ("Unknown"); 18595940Ssowmini } 18605940Ssowmini h = mdb_zalloc(mblen, UM_SLEEP); 18615940Ssowmini if (mdb_vread(h, mblen, (uintptr_t)(mp.b_rptr)) == -1) { 18625940Ssowmini mdb_warn("failed to read hwaddr at %p", 18635940Ssowmini mp.b_rptr + NCE_LL_ADDR_OFFSET(ill)); 18645940Ssowmini return ("Unknown"); 18655940Ssowmini } 1866*11042SErik.Nordmark@Sun.COM mdb_mac_addr(h + NCE_LL_ADDR_OFFSET(ill), 1867*11042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length, addr_buf, sizeof (addr_buf)); 18685940Ssowmini } else { 18695940Ssowmini return ("None"); 18705940Ssowmini } 18715940Ssowmini mdb_free(h, mblen); 18725940Ssowmini return (addr_buf); 18735940Ssowmini } 18745940Ssowmini 18755940Ssowmini static void 1876*11042SErik.Nordmark@Sun.COM ncec_header(uint_t flags) 18775940Ssowmini { 18785940Ssowmini if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 18795940Ssowmini 18805940Ssowmini mdb_printf("%<u>%?s %-20s %-10s %-8s %-5s %s%</u>\n", 18815940Ssowmini "ADDR", "HW_ADDR", "STATE", "FLAGS", "ILL", "IP ADDR"); 18825940Ssowmini } 18835940Ssowmini } 18845940Ssowmini 18855940Ssowmini int 1886*11042SErik.Nordmark@Sun.COM ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 18875940Ssowmini { 1888*11042SErik.Nordmark@Sun.COM ncec_t ncec; 1889*11042SErik.Nordmark@Sun.COM ncec_cbdata_t id; 18905940Ssowmini int ipversion = 0; 18915940Ssowmini const char *opt_P = NULL; 18925940Ssowmini 18935940Ssowmini if (mdb_getopts(argc, argv, 18945940Ssowmini 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 18955940Ssowmini return (DCMD_USAGE); 18965940Ssowmini 18975940Ssowmini if (opt_P != NULL) { 18985940Ssowmini if (strcmp("v4", opt_P) == 0) { 18995940Ssowmini ipversion = IPV4_VERSION; 19005940Ssowmini } else if (strcmp("v6", opt_P) == 0) { 19015940Ssowmini ipversion = IPV6_VERSION; 19025940Ssowmini } else { 19035940Ssowmini mdb_warn("invalid protocol '%s'\n", opt_P); 19045940Ssowmini return (DCMD_USAGE); 19055940Ssowmini } 19065940Ssowmini } 19075940Ssowmini 19085940Ssowmini if (flags & DCMD_ADDRSPEC) { 19095940Ssowmini 1910*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) { 1911*11042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec at %p\n", addr); 19125940Ssowmini return (DCMD_ERR); 19135940Ssowmini } 1914*11042SErik.Nordmark@Sun.COM if (ipversion != 0 && ncec.ncec_ipversion != ipversion) { 19155940Ssowmini mdb_printf("IP Version mismatch\n"); 19165940Ssowmini return (DCMD_ERR); 19175940Ssowmini } 1918*11042SErik.Nordmark@Sun.COM ncec_header(flags); 1919*11042SErik.Nordmark@Sun.COM return (ncec_format(addr, &ncec, ipversion)); 19205940Ssowmini 19215940Ssowmini } else { 1922*11042SErik.Nordmark@Sun.COM id.ncec_addr = addr; 1923*11042SErik.Nordmark@Sun.COM id.ncec_ipversion = ipversion; 1924*11042SErik.Nordmark@Sun.COM ncec_header(flags); 1925*11042SErik.Nordmark@Sun.COM if (mdb_walk("ncec", (mdb_walk_cb_t)ncec_cb, &id) == -1) { 1926*11042SErik.Nordmark@Sun.COM mdb_warn("failed to walk ncec table\n"); 19275940Ssowmini return (DCMD_ERR); 19285940Ssowmini } 19295940Ssowmini } 19305940Ssowmini return (DCMD_OK); 19315940Ssowmini } 19325940Ssowmini 19335940Ssowmini static int 1934*11042SErik.Nordmark@Sun.COM ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion) 19355940Ssowmini { 1936*11042SErik.Nordmark@Sun.COM static const mdb_bitmask_t ncec_flags[] = { 1937*11042SErik.Nordmark@Sun.COM { "P", NCE_F_NONUD, NCE_F_NONUD }, 19385940Ssowmini { "R", NCE_F_ISROUTER, NCE_F_ISROUTER }, 19395940Ssowmini { "N", NCE_F_NONUD, NCE_F_NONUD }, 19405940Ssowmini { "A", NCE_F_ANYCAST, NCE_F_ANYCAST }, 19415940Ssowmini { "C", NCE_F_CONDEMNED, NCE_F_CONDEMNED }, 19425940Ssowmini { "U", NCE_F_UNSOL_ADV, NCE_F_UNSOL_ADV }, 19435940Ssowmini { "B", NCE_F_BCAST, NCE_F_BCAST }, 19445940Ssowmini { NULL, 0, 0 } 19455940Ssowmini }; 1946*11042SErik.Nordmark@Sun.COM #define NCE_MAX_FLAGS (sizeof (ncec_flags) / sizeof (mdb_bitmask_t)) 19475940Ssowmini struct in_addr nceaddr; 19485940Ssowmini ill_t ill; 19495940Ssowmini char ill_name[LIFNAMSIZ]; 19505940Ssowmini char flagsbuf[NCE_MAX_FLAGS]; 19515940Ssowmini 1952*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncec->ncec_ill) == -1) { 1953*11042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec_ill at %p", 1954*11042SErik.Nordmark@Sun.COM ncec->ncec_ill); 19555940Ssowmini return (DCMD_ERR); 19565940Ssowmini } 19575940Ssowmini 19585940Ssowmini (void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill.ill_name_length), 19595940Ssowmini (uintptr_t)ill.ill_name); 19605940Ssowmini 19615940Ssowmini mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%hb", 1962*11042SErik.Nordmark@Sun.COM ncec->ncec_flags, ncec_flags); 1963*11042SErik.Nordmark@Sun.COM 1964*11042SErik.Nordmark@Sun.COM if (ipversion != 0 && ncec->ncec_ipversion != ipversion) 19655940Ssowmini return (DCMD_OK); 19665940Ssowmini 1967*11042SErik.Nordmark@Sun.COM if (ncec->ncec_ipversion == IPV4_VERSION) { 1968*11042SErik.Nordmark@Sun.COM IN6_V4MAPPED_TO_INADDR(&ncec->ncec_addr, &nceaddr); 19695940Ssowmini mdb_printf("%?p %-20s %-10s " 19705940Ssowmini "%-8s " 19715940Ssowmini "%-5s %I\n", 1972*11042SErik.Nordmark@Sun.COM addr, ncec_l2_addr(ncec, &ill), 1973*11042SErik.Nordmark@Sun.COM ncec_state(ncec->ncec_state), 19745940Ssowmini flagsbuf, 19755940Ssowmini ill_name, nceaddr.s_addr); 19765940Ssowmini } else { 19775940Ssowmini mdb_printf("%?p %-20s %-10s %-8s %-5s %N\n", 1978*11042SErik.Nordmark@Sun.COM addr, ncec_l2_addr(ncec, &ill), 1979*11042SErik.Nordmark@Sun.COM ncec_state(ncec->ncec_state), 19805940Ssowmini flagsbuf, 1981*11042SErik.Nordmark@Sun.COM ill_name, &ncec->ncec_addr); 19825940Ssowmini } 19835940Ssowmini 19845940Ssowmini return (DCMD_OK); 19855940Ssowmini } 19865940Ssowmini 19875940Ssowmini static uintptr_t 1988*11042SErik.Nordmark@Sun.COM ncec_get_next_hash_tbl(uintptr_t start, int *index, struct ndp_g_s ndp) 19895940Ssowmini { 19905940Ssowmini uintptr_t addr = start; 19915940Ssowmini int i = *index; 19925940Ssowmini 19935940Ssowmini while (addr == NULL) { 19945940Ssowmini 19955940Ssowmini if (++i >= NCE_TABLE_SIZE) 19965940Ssowmini break; 19975940Ssowmini addr = (uintptr_t)ndp.nce_hash_tbl[i]; 19985940Ssowmini } 19995940Ssowmini *index = i; 20005940Ssowmini return (addr); 20015940Ssowmini } 20025940Ssowmini 20035940Ssowmini static int 2004*11042SErik.Nordmark@Sun.COM ncec_walk_step(mdb_walk_state_t *wsp) 20055940Ssowmini { 20065940Ssowmini uintptr_t kaddr4, kaddr6; 20075940Ssowmini 20085940Ssowmini kaddr4 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp4); 20095940Ssowmini kaddr6 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp6); 20105940Ssowmini 20115940Ssowmini if (mdb_vread(&kaddr4, sizeof (kaddr4), kaddr4) == -1) { 20125940Ssowmini mdb_warn("can't read ips_ip_cache_table at %p", kaddr4); 20135940Ssowmini return (WALK_ERR); 20145940Ssowmini } 20155940Ssowmini if (mdb_vread(&kaddr6, sizeof (kaddr6), kaddr6) == -1) { 20165940Ssowmini mdb_warn("can't read ips_ip_cache_table at %p", kaddr6); 20175940Ssowmini return (WALK_ERR); 20185940Ssowmini } 2019*11042SErik.Nordmark@Sun.COM if (mdb_pwalk("ncec_stack", wsp->walk_callback, wsp->walk_cbdata, 20205940Ssowmini kaddr4) == -1) { 2021*11042SErik.Nordmark@Sun.COM mdb_warn("couldn't walk 'ncec_stack' for ips_ndp4 %p", 20225940Ssowmini kaddr4); 20235940Ssowmini return (WALK_ERR); 20245940Ssowmini } 2025*11042SErik.Nordmark@Sun.COM if (mdb_pwalk("ncec_stack", wsp->walk_callback, 20265940Ssowmini wsp->walk_cbdata, kaddr6) == -1) { 2027*11042SErik.Nordmark@Sun.COM mdb_warn("couldn't walk 'ncec_stack' for ips_ndp6 %p", 20285940Ssowmini kaddr6); 20295940Ssowmini return (WALK_ERR); 20305940Ssowmini } 20315940Ssowmini return (WALK_NEXT); 20325940Ssowmini } 20335940Ssowmini 20349089SVasumathi.Sundaram@Sun.COM static uintptr_t 20359089SVasumathi.Sundaram@Sun.COM ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t *iw) 20369089SVasumathi.Sundaram@Sun.COM { 20379089SVasumathi.Sundaram@Sun.COM struct connf_s connf; 20389089SVasumathi.Sundaram@Sun.COM uintptr_t addr = NULL, next; 20399089SVasumathi.Sundaram@Sun.COM int index = iw->connf_tbl_index; 20409089SVasumathi.Sundaram@Sun.COM 20419089SVasumathi.Sundaram@Sun.COM do { 20429089SVasumathi.Sundaram@Sun.COM next = iw->hash_tbl + index * sizeof (struct connf_s); 20439089SVasumathi.Sundaram@Sun.COM if (++index >= iw->hash_tbl_size) { 20449089SVasumathi.Sundaram@Sun.COM addr = NULL; 20459089SVasumathi.Sundaram@Sun.COM break; 20469089SVasumathi.Sundaram@Sun.COM } 20479089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&connf, sizeof (struct connf_s), next) == -1) { 20489089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", next); 20499089SVasumathi.Sundaram@Sun.COM return (NULL); 20509089SVasumathi.Sundaram@Sun.COM } 20519089SVasumathi.Sundaram@Sun.COM addr = (uintptr_t)connf.connf_head; 20529089SVasumathi.Sundaram@Sun.COM } while (addr == NULL); 20539089SVasumathi.Sundaram@Sun.COM iw->connf_tbl_index = index; 20549089SVasumathi.Sundaram@Sun.COM return (addr); 20559089SVasumathi.Sundaram@Sun.COM } 20569089SVasumathi.Sundaram@Sun.COM 20579089SVasumathi.Sundaram@Sun.COM static int 20589089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init(mdb_walk_state_t *wsp) 20599089SVasumathi.Sundaram@Sun.COM { 20609089SVasumathi.Sundaram@Sun.COM const hash_walk_arg_t *arg = wsp->walk_arg; 20619089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw; 20629089SVasumathi.Sundaram@Sun.COM uintptr_t tbladdr; 20639089SVasumathi.Sundaram@Sun.COM uintptr_t sizeaddr; 20649089SVasumathi.Sundaram@Sun.COM 20659089SVasumathi.Sundaram@Sun.COM iw = mdb_alloc(sizeof (ipcl_hash_walk_data_t), UM_SLEEP); 20669089SVasumathi.Sundaram@Sun.COM iw->conn = mdb_alloc(sizeof (conn_t), UM_SLEEP); 20679089SVasumathi.Sundaram@Sun.COM tbladdr = wsp->walk_addr + arg->tbl_off; 20689089SVasumathi.Sundaram@Sun.COM sizeaddr = wsp->walk_addr + arg->size_off; 20699089SVasumathi.Sundaram@Sun.COM 20709089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&iw->hash_tbl, sizeof (uintptr_t), tbladdr) == -1) { 20719089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read fanout table addr at %p", tbladdr); 20729089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t)); 20739089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t)); 20749089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 20759089SVasumathi.Sundaram@Sun.COM } 2076*11042SErik.Nordmark@Sun.COM if (arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4) || 20779089SVasumathi.Sundaram@Sun.COM arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6)) { 20789089SVasumathi.Sundaram@Sun.COM iw->hash_tbl_size = IPPROTO_MAX; 20799089SVasumathi.Sundaram@Sun.COM } else { 20809089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&iw->hash_tbl_size, sizeof (int), 20819089SVasumathi.Sundaram@Sun.COM sizeaddr) == -1) { 20829089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read fanout table size addr at %p", 20839089SVasumathi.Sundaram@Sun.COM sizeaddr); 20849089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t)); 20859089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t)); 20869089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 20879089SVasumathi.Sundaram@Sun.COM } 20889089SVasumathi.Sundaram@Sun.COM } 20899089SVasumathi.Sundaram@Sun.COM iw->connf_tbl_index = 0; 20909089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw); 20919089SVasumathi.Sundaram@Sun.COM wsp->walk_data = iw; 20929089SVasumathi.Sundaram@Sun.COM 20939089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr != NULL) 20949089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 20959089SVasumathi.Sundaram@Sun.COM else 20969089SVasumathi.Sundaram@Sun.COM return (WALK_DONE); 20979089SVasumathi.Sundaram@Sun.COM } 20989089SVasumathi.Sundaram@Sun.COM 20999089SVasumathi.Sundaram@Sun.COM static int 21009089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_step(mdb_walk_state_t *wsp) 21019089SVasumathi.Sundaram@Sun.COM { 21029089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr; 21039089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw = wsp->walk_data; 21049089SVasumathi.Sundaram@Sun.COM conn_t *conn = iw->conn; 21059089SVasumathi.Sundaram@Sun.COM int ret = WALK_DONE; 21069089SVasumathi.Sundaram@Sun.COM 21079089SVasumathi.Sundaram@Sun.COM while (addr != NULL) { 21089089SVasumathi.Sundaram@Sun.COM if (mdb_vread(conn, sizeof (conn_t), addr) == -1) { 21099089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", addr); 21109089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 21119089SVasumathi.Sundaram@Sun.COM } 21129089SVasumathi.Sundaram@Sun.COM ret = wsp->walk_callback(addr, iw, wsp->walk_cbdata); 21139089SVasumathi.Sundaram@Sun.COM if (ret != WALK_NEXT) 21149089SVasumathi.Sundaram@Sun.COM break; 21159089SVasumathi.Sundaram@Sun.COM addr = (uintptr_t)conn->conn_next; 21169089SVasumathi.Sundaram@Sun.COM } 21179089SVasumathi.Sundaram@Sun.COM if (ret == WALK_NEXT) { 21189089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw); 21199089SVasumathi.Sundaram@Sun.COM 21209089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr != NULL) 21219089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 21229089SVasumathi.Sundaram@Sun.COM else 21239089SVasumathi.Sundaram@Sun.COM return (WALK_DONE); 21249089SVasumathi.Sundaram@Sun.COM } 21259089SVasumathi.Sundaram@Sun.COM 21269089SVasumathi.Sundaram@Sun.COM return (ret); 21279089SVasumathi.Sundaram@Sun.COM } 21289089SVasumathi.Sundaram@Sun.COM 21299089SVasumathi.Sundaram@Sun.COM static void 21309089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini(mdb_walk_state_t *wsp) 21319089SVasumathi.Sundaram@Sun.COM { 21329089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw = wsp->walk_data; 21339089SVasumathi.Sundaram@Sun.COM 21349089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t)); 21359089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t)); 21369089SVasumathi.Sundaram@Sun.COM } 21379089SVasumathi.Sundaram@Sun.COM 21385940Ssowmini /* 21395940Ssowmini * Called with walk_addr being the address of ips_ndp{4,6} 21405940Ssowmini */ 21415940Ssowmini static int 2142*11042SErik.Nordmark@Sun.COM ncec_stack_walk_init(mdb_walk_state_t *wsp) 21435940Ssowmini { 2144*11042SErik.Nordmark@Sun.COM ncec_walk_data_t *nw; 21455940Ssowmini 21465940Ssowmini if (wsp->walk_addr == NULL) { 2147*11042SErik.Nordmark@Sun.COM mdb_warn("ncec_stack requires ndp_g_s address\n"); 21485940Ssowmini return (WALK_ERR); 21495940Ssowmini } 21505940Ssowmini 2151*11042SErik.Nordmark@Sun.COM nw = mdb_alloc(sizeof (ncec_walk_data_t), UM_SLEEP); 2152*11042SErik.Nordmark@Sun.COM 2153*11042SErik.Nordmark@Sun.COM if (mdb_vread(&nw->ncec_ip_ndp, sizeof (struct ndp_g_s), 21545940Ssowmini wsp->walk_addr) == -1) { 21555940Ssowmini mdb_warn("failed to read 'ip_ndp' at %p", 21565940Ssowmini wsp->walk_addr); 2157*11042SErik.Nordmark@Sun.COM mdb_free(nw, sizeof (ncec_walk_data_t)); 21585940Ssowmini return (WALK_ERR); 21595940Ssowmini } 21605940Ssowmini 2161*11042SErik.Nordmark@Sun.COM /* 2162*11042SErik.Nordmark@Sun.COM * ncec_get_next_hash_tbl() starts at ++i , so initialize index to -1 2163*11042SErik.Nordmark@Sun.COM */ 2164*11042SErik.Nordmark@Sun.COM nw->ncec_hash_tbl_index = -1; 2165*11042SErik.Nordmark@Sun.COM wsp->walk_addr = ncec_get_next_hash_tbl(NULL, 2166*11042SErik.Nordmark@Sun.COM &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp); 21675940Ssowmini wsp->walk_data = nw; 21685940Ssowmini 21695940Ssowmini return (WALK_NEXT); 21705940Ssowmini } 21715940Ssowmini 21725940Ssowmini static int 2173*11042SErik.Nordmark@Sun.COM ncec_stack_walk_step(mdb_walk_state_t *wsp) 21745940Ssowmini { 21755940Ssowmini uintptr_t addr = wsp->walk_addr; 2176*11042SErik.Nordmark@Sun.COM ncec_walk_data_t *nw = wsp->walk_data; 21775940Ssowmini 21785940Ssowmini if (addr == NULL) 21795940Ssowmini return (WALK_DONE); 21805940Ssowmini 2181*11042SErik.Nordmark@Sun.COM if (mdb_vread(&nw->ncec, sizeof (ncec_t), addr) == -1) { 2182*11042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec_t at %p", addr); 21835940Ssowmini return (WALK_ERR); 21845940Ssowmini } 21855940Ssowmini 2186*11042SErik.Nordmark@Sun.COM wsp->walk_addr = (uintptr_t)nw->ncec.ncec_next; 2187*11042SErik.Nordmark@Sun.COM 2188*11042SErik.Nordmark@Sun.COM wsp->walk_addr = ncec_get_next_hash_tbl(wsp->walk_addr, 2189*11042SErik.Nordmark@Sun.COM &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp); 21905940Ssowmini 21915940Ssowmini return (wsp->walk_callback(addr, nw, wsp->walk_cbdata)); 21925940Ssowmini } 21935940Ssowmini 21945940Ssowmini static void 2195*11042SErik.Nordmark@Sun.COM ncec_stack_walk_fini(mdb_walk_state_t *wsp) 21965940Ssowmini { 2197*11042SErik.Nordmark@Sun.COM mdb_free(wsp->walk_data, sizeof (ncec_walk_data_t)); 21985940Ssowmini } 21995940Ssowmini 22005940Ssowmini /* ARGSUSED */ 22015940Ssowmini static int 2202*11042SErik.Nordmark@Sun.COM ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw, ncec_cbdata_t *id) 22035940Ssowmini { 2204*11042SErik.Nordmark@Sun.COM ncec_t ncec; 2205*11042SErik.Nordmark@Sun.COM 2206*11042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) { 2207*11042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec at %p", addr); 22085940Ssowmini return (WALK_NEXT); 22095940Ssowmini } 2210*11042SErik.Nordmark@Sun.COM (void) ncec_format(addr, &ncec, id->ncec_ipversion); 22115940Ssowmini return (WALK_NEXT); 22125940Ssowmini } 22139089SVasumathi.Sundaram@Sun.COM 22149089SVasumathi.Sundaram@Sun.COM static int 22159089SVasumathi.Sundaram@Sun.COM ill_walk_init(mdb_walk_state_t *wsp) 22169089SVasumathi.Sundaram@Sun.COM { 22179089SVasumathi.Sundaram@Sun.COM if (mdb_layered_walk("illif", wsp) == -1) { 22189089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'illif'"); 22199089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 22209089SVasumathi.Sundaram@Sun.COM } 22219089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 22229089SVasumathi.Sundaram@Sun.COM } 22239089SVasumathi.Sundaram@Sun.COM 22249089SVasumathi.Sundaram@Sun.COM static int 22259089SVasumathi.Sundaram@Sun.COM ill_walk_step(mdb_walk_state_t *wsp) 22269089SVasumathi.Sundaram@Sun.COM { 22279089SVasumathi.Sundaram@Sun.COM ill_if_t ill_if; 22289089SVasumathi.Sundaram@Sun.COM 22299089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill_if, sizeof (ill_if_t), wsp->walk_addr) == -1) { 22309089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read ill_if_t at %p", wsp->walk_addr); 22319089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 22329089SVasumathi.Sundaram@Sun.COM } 22339089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = (uintptr_t)(wsp->walk_addr + 22349089SVasumathi.Sundaram@Sun.COM offsetof(ill_if_t, illif_avl_by_ppa)); 22359089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("avl", wsp->walk_callback, wsp->walk_cbdata, 22369089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 22379089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'avl'"); 22389089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 22399089SVasumathi.Sundaram@Sun.COM } 22409089SVasumathi.Sundaram@Sun.COM 22419089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 22429089SVasumathi.Sundaram@Sun.COM } 22439089SVasumathi.Sundaram@Sun.COM 22449089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 22459089SVasumathi.Sundaram@Sun.COM static int 22469089SVasumathi.Sundaram@Sun.COM ill_cb(uintptr_t addr, const ill_walk_data_t *iw, ill_cbdata_t *id) 22479089SVasumathi.Sundaram@Sun.COM { 22489089SVasumathi.Sundaram@Sun.COM ill_t ill; 22499089SVasumathi.Sundaram@Sun.COM 22509089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill, sizeof (ill_t), (uintptr_t)addr) == -1) { 22519089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", addr); 22529089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 22539089SVasumathi.Sundaram@Sun.COM } 2254*11042SErik.Nordmark@Sun.COM 2255*11042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip ILLs that don't belong to it. */ 2256*11042SErik.Nordmark@Sun.COM if (id->ill_ipst != NULL && ill.ill_ipst != id->ill_ipst) 2257*11042SErik.Nordmark@Sun.COM return (WALK_NEXT); 2258*11042SErik.Nordmark@Sun.COM 22599089SVasumathi.Sundaram@Sun.COM return (ill_format((uintptr_t)addr, &ill, id)); 22609089SVasumathi.Sundaram@Sun.COM } 22619089SVasumathi.Sundaram@Sun.COM 22629089SVasumathi.Sundaram@Sun.COM static void 22639089SVasumathi.Sundaram@Sun.COM ill_header(boolean_t verbose) 22649089SVasumathi.Sundaram@Sun.COM { 22659089SVasumathi.Sundaram@Sun.COM if (verbose) { 22669089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-8s %3s %-10s %-?s %-?s %-10s%</u>\n", 22679089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "VER", "TYPE", "WQ", "IPST", "FLAGS"); 22689089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %4s%4s %-?s\n", 22699089SVasumathi.Sundaram@Sun.COM "PHYINT", "CNT", "", "GROUP"); 22709089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 22719089SVasumathi.Sundaram@Sun.COM } else { 22729089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s %-8s %-3s %-10s %4s %-?s %-10s%</u>\n", 22739089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "VER", "TYPE", "CNT", "WQ", "FLAGS"); 22749089SVasumathi.Sundaram@Sun.COM } 22759089SVasumathi.Sundaram@Sun.COM } 22769089SVasumathi.Sundaram@Sun.COM 22779089SVasumathi.Sundaram@Sun.COM static int 22789089SVasumathi.Sundaram@Sun.COM ill_format(uintptr_t addr, const void *illptr, void *ill_cb_arg) 22799089SVasumathi.Sundaram@Sun.COM { 22809089SVasumathi.Sundaram@Sun.COM ill_t *ill = (ill_t *)illptr; 22819089SVasumathi.Sundaram@Sun.COM ill_cbdata_t *illcb = ill_cb_arg; 22829089SVasumathi.Sundaram@Sun.COM boolean_t verbose = illcb->verbose; 22839089SVasumathi.Sundaram@Sun.COM phyint_t phyi; 22849089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t fmasks[] = { 22859089SVasumathi.Sundaram@Sun.COM { "R", PHYI_RUNNING, PHYI_RUNNING }, 22869089SVasumathi.Sundaram@Sun.COM { "P", PHYI_PROMISC, PHYI_PROMISC }, 22879089SVasumathi.Sundaram@Sun.COM { "V", PHYI_VIRTUAL, PHYI_VIRTUAL }, 22889089SVasumathi.Sundaram@Sun.COM { "I", PHYI_IPMP, PHYI_IPMP }, 22899089SVasumathi.Sundaram@Sun.COM { "f", PHYI_FAILED, PHYI_FAILED }, 22909089SVasumathi.Sundaram@Sun.COM { "S", PHYI_STANDBY, PHYI_STANDBY }, 22919089SVasumathi.Sundaram@Sun.COM { "i", PHYI_INACTIVE, PHYI_INACTIVE }, 22929089SVasumathi.Sundaram@Sun.COM { "O", PHYI_OFFLINE, PHYI_OFFLINE }, 22939089SVasumathi.Sundaram@Sun.COM { "T", ILLF_NOTRAILERS, ILLF_NOTRAILERS }, 22949089SVasumathi.Sundaram@Sun.COM { "A", ILLF_NOARP, ILLF_NOARP }, 22959089SVasumathi.Sundaram@Sun.COM { "M", ILLF_MULTICAST, ILLF_MULTICAST }, 22969089SVasumathi.Sundaram@Sun.COM { "F", ILLF_ROUTER, ILLF_ROUTER }, 22979089SVasumathi.Sundaram@Sun.COM { "D", ILLF_NONUD, ILLF_NONUD }, 22989089SVasumathi.Sundaram@Sun.COM { "X", ILLF_NORTEXCH, ILLF_NORTEXCH }, 22999089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 23009089SVasumathi.Sundaram@Sun.COM }; 23019089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t v_fmasks[] = { 23029089SVasumathi.Sundaram@Sun.COM { "RUNNING", PHYI_RUNNING, PHYI_RUNNING }, 23039089SVasumathi.Sundaram@Sun.COM { "PROMISC", PHYI_PROMISC, PHYI_PROMISC }, 23049089SVasumathi.Sundaram@Sun.COM { "VIRTUAL", PHYI_VIRTUAL, PHYI_VIRTUAL }, 23059089SVasumathi.Sundaram@Sun.COM { "IPMP", PHYI_IPMP, PHYI_IPMP }, 23069089SVasumathi.Sundaram@Sun.COM { "FAILED", PHYI_FAILED, PHYI_FAILED }, 23079089SVasumathi.Sundaram@Sun.COM { "STANDBY", PHYI_STANDBY, PHYI_STANDBY }, 23089089SVasumathi.Sundaram@Sun.COM { "INACTIVE", PHYI_INACTIVE, PHYI_INACTIVE }, 23099089SVasumathi.Sundaram@Sun.COM { "OFFLINE", PHYI_OFFLINE, PHYI_OFFLINE }, 23109089SVasumathi.Sundaram@Sun.COM { "NOTRAILER", ILLF_NOTRAILERS, ILLF_NOTRAILERS }, 23119089SVasumathi.Sundaram@Sun.COM { "NOARP", ILLF_NOARP, ILLF_NOARP }, 23129089SVasumathi.Sundaram@Sun.COM { "MULTICAST", ILLF_MULTICAST, ILLF_MULTICAST }, 23139089SVasumathi.Sundaram@Sun.COM { "ROUTER", ILLF_ROUTER, ILLF_ROUTER }, 23149089SVasumathi.Sundaram@Sun.COM { "NONUD", ILLF_NONUD, ILLF_NONUD }, 23159089SVasumathi.Sundaram@Sun.COM { "NORTEXCH", ILLF_NORTEXCH, ILLF_NORTEXCH }, 23169089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 23179089SVasumathi.Sundaram@Sun.COM }; 23189089SVasumathi.Sundaram@Sun.COM char ill_name[LIFNAMSIZ]; 23199089SVasumathi.Sundaram@Sun.COM int cnt; 23209089SVasumathi.Sundaram@Sun.COM char *typebuf; 23219089SVasumathi.Sundaram@Sun.COM char sbuf[DEFCOLS]; 23229089SVasumathi.Sundaram@Sun.COM int ipver = illcb->ill_ipversion; 23239089SVasumathi.Sundaram@Sun.COM 23249089SVasumathi.Sundaram@Sun.COM if (ipver != 0) { 23259089SVasumathi.Sundaram@Sun.COM if ((ipver == IPV4_VERSION && ill->ill_isv6) || 23269089SVasumathi.Sundaram@Sun.COM (ipver == IPV6_VERSION && !ill->ill_isv6)) { 23279089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 23289089SVasumathi.Sundaram@Sun.COM } 23299089SVasumathi.Sundaram@Sun.COM } 23309089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&phyi, sizeof (phyint_t), 23319089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_phyint) == -1) { 23329089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill_phyint at %p", 23339089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_phyint); 23349089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 23359089SVasumathi.Sundaram@Sun.COM } 23369089SVasumathi.Sundaram@Sun.COM (void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill->ill_name_length), 23379089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_name); 23389089SVasumathi.Sundaram@Sun.COM 23399089SVasumathi.Sundaram@Sun.COM switch (ill->ill_type) { 23409089SVasumathi.Sundaram@Sun.COM case 0: 23419089SVasumathi.Sundaram@Sun.COM typebuf = "LOOPBACK"; 23429089SVasumathi.Sundaram@Sun.COM break; 23439089SVasumathi.Sundaram@Sun.COM case IFT_ETHER: 23449089SVasumathi.Sundaram@Sun.COM typebuf = "ETHER"; 23459089SVasumathi.Sundaram@Sun.COM break; 23469089SVasumathi.Sundaram@Sun.COM case IFT_OTHER: 23479089SVasumathi.Sundaram@Sun.COM typebuf = "OTHER"; 23489089SVasumathi.Sundaram@Sun.COM break; 23499089SVasumathi.Sundaram@Sun.COM default: 23509089SVasumathi.Sundaram@Sun.COM typebuf = NULL; 23519089SVasumathi.Sundaram@Sun.COM break; 23529089SVasumathi.Sundaram@Sun.COM } 23539089SVasumathi.Sundaram@Sun.COM cnt = ill->ill_refcnt + ill->ill_ire_cnt + ill->ill_nce_cnt + 2354*11042SErik.Nordmark@Sun.COM ill->ill_ilm_cnt + ill->ill_ncec_cnt; 23559089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-8s %-3s ", 23569089SVasumathi.Sundaram@Sun.COM addr, ill_name, ill->ill_isv6 ? "v6" : "v4"); 23579089SVasumathi.Sundaram@Sun.COM if (typebuf != NULL) 23589089SVasumathi.Sundaram@Sun.COM mdb_printf("%-10s ", typebuf); 23599089SVasumathi.Sundaram@Sun.COM else 23609089SVasumathi.Sundaram@Sun.COM mdb_printf("%-10x ", ill->ill_type); 23619089SVasumathi.Sundaram@Sun.COM if (verbose) { 23629089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-?p %-llb\n", 23639089SVasumathi.Sundaram@Sun.COM ill->ill_wq, ill->ill_ipst, 23649089SVasumathi.Sundaram@Sun.COM ill->ill_flags | phyi.phyint_flags, v_fmasks); 23659089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %4d%4s %-?p\n", 23669089SVasumathi.Sundaram@Sun.COM ill->ill_phyint, cnt, "", ill->ill_grp); 23679089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sbuf, sizeof (sbuf), "%*s %3s", 23689089SVasumathi.Sundaram@Sun.COM sizeof (uintptr_t) * 2, "", ""); 23699089SVasumathi.Sundaram@Sun.COM mdb_printf("%s|\n%s+--> %3d %-18s " 23709089SVasumathi.Sundaram@Sun.COM "references from active threads\n", 23719089SVasumathi.Sundaram@Sun.COM sbuf, sbuf, ill->ill_refcnt, "ill_refcnt"); 23729089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s ires referencing this ill\n", 23739089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_ire_cnt, "ill_ire_cnt"); 23749089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s nces referencing this ill\n", 23759089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_nce_cnt, "ill_nce_cnt"); 2376*11042SErik.Nordmark@Sun.COM mdb_printf("%*s %7d %-18s ncecs referencing this ill\n", 2377*11042SErik.Nordmark@Sun.COM strlen(sbuf), "", ill->ill_ncec_cnt, "ill_ncec_cnt"); 23789089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s ilms referencing this ill\n", 23799089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_ilm_cnt, "ill_ilm_cnt"); 23809089SVasumathi.Sundaram@Sun.COM } else { 23819089SVasumathi.Sundaram@Sun.COM mdb_printf("%4d %-?p %-llb\n", 23829089SVasumathi.Sundaram@Sun.COM cnt, ill->ill_wq, 23839089SVasumathi.Sundaram@Sun.COM ill->ill_flags | phyi.phyint_flags, fmasks); 23849089SVasumathi.Sundaram@Sun.COM } 23859089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 23869089SVasumathi.Sundaram@Sun.COM } 23879089SVasumathi.Sundaram@Sun.COM 23889089SVasumathi.Sundaram@Sun.COM static int 23899089SVasumathi.Sundaram@Sun.COM ill(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 23909089SVasumathi.Sundaram@Sun.COM { 23919089SVasumathi.Sundaram@Sun.COM ill_t ill_data; 23929089SVasumathi.Sundaram@Sun.COM ill_cbdata_t id; 23939089SVasumathi.Sundaram@Sun.COM int ipversion = 0; 2394*11042SErik.Nordmark@Sun.COM const char *zone_name = NULL; 23959089SVasumathi.Sundaram@Sun.COM const char *opt_P = NULL; 23969089SVasumathi.Sundaram@Sun.COM uint_t verbose = FALSE; 2397*11042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL; 23989089SVasumathi.Sundaram@Sun.COM 23999089SVasumathi.Sundaram@Sun.COM if (mdb_getopts(argc, argv, 24009089SVasumathi.Sundaram@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 2401*11042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name, 24029089SVasumathi.Sundaram@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 24039089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 24049089SVasumathi.Sundaram@Sun.COM 2405*11042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */ 2406*11042SErik.Nordmark@Sun.COM if (zone_name != NULL) { 2407*11042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name); 2408*11042SErik.Nordmark@Sun.COM if (ipst == NULL) 2409*11042SErik.Nordmark@Sun.COM return (DCMD_USAGE); 2410*11042SErik.Nordmark@Sun.COM } 2411*11042SErik.Nordmark@Sun.COM 24129089SVasumathi.Sundaram@Sun.COM if (opt_P != NULL) { 24139089SVasumathi.Sundaram@Sun.COM if (strcmp("v4", opt_P) == 0) { 24149089SVasumathi.Sundaram@Sun.COM ipversion = IPV4_VERSION; 24159089SVasumathi.Sundaram@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 24169089SVasumathi.Sundaram@Sun.COM ipversion = IPV6_VERSION; 24179089SVasumathi.Sundaram@Sun.COM } else { 24189089SVasumathi.Sundaram@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 24199089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 24209089SVasumathi.Sundaram@Sun.COM } 24219089SVasumathi.Sundaram@Sun.COM } 24229089SVasumathi.Sundaram@Sun.COM 24239089SVasumathi.Sundaram@Sun.COM id.verbose = verbose; 24249089SVasumathi.Sundaram@Sun.COM id.ill_addr = addr; 24259089SVasumathi.Sundaram@Sun.COM id.ill_ipversion = ipversion; 2426*11042SErik.Nordmark@Sun.COM id.ill_ipst = ipst; 24279089SVasumathi.Sundaram@Sun.COM 24289089SVasumathi.Sundaram@Sun.COM ill_header(verbose); 24299089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 24309089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill_data, sizeof (ill_t), addr) == -1) { 24319089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p\n", addr); 24329089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 24339089SVasumathi.Sundaram@Sun.COM } 24349089SVasumathi.Sundaram@Sun.COM (void) ill_format(addr, &ill_data, &id); 24359089SVasumathi.Sundaram@Sun.COM } else { 24369089SVasumathi.Sundaram@Sun.COM if (mdb_walk("ill", (mdb_walk_cb_t)ill_cb, &id) == -1) { 24379089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk ills\n"); 24389089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 24399089SVasumathi.Sundaram@Sun.COM } 24409089SVasumathi.Sundaram@Sun.COM } 24419089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 24429089SVasumathi.Sundaram@Sun.COM } 24439089SVasumathi.Sundaram@Sun.COM 24449089SVasumathi.Sundaram@Sun.COM static void 24459089SVasumathi.Sundaram@Sun.COM ill_help(void) 24469089SVasumathi.Sundaram@Sun.COM { 24479089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints the following fields: ill ptr, name, " 24489089SVasumathi.Sundaram@Sun.COM "IP version, count, ill type and ill flags.\n" 24499089SVasumathi.Sundaram@Sun.COM "The count field is a sum of individual refcnts and is expanded " 24509089SVasumathi.Sundaram@Sun.COM "with the -v option.\n\n"); 24519089SVasumathi.Sundaram@Sun.COM mdb_printf("Options:\n"); 24529089SVasumathi.Sundaram@Sun.COM mdb_printf("\t-P v4 | v6" 24539089SVasumathi.Sundaram@Sun.COM "\tfilter ill structures for the specified protocol\n"); 24549089SVasumathi.Sundaram@Sun.COM } 24559089SVasumathi.Sundaram@Sun.COM 24569089SVasumathi.Sundaram@Sun.COM static int 24579089SVasumathi.Sundaram@Sun.COM ip_list_walk_init(mdb_walk_state_t *wsp) 24589089SVasumathi.Sundaram@Sun.COM { 24599089SVasumathi.Sundaram@Sun.COM const ip_list_walk_arg_t *arg = wsp->walk_arg; 24609089SVasumathi.Sundaram@Sun.COM ip_list_walk_data_t *iw; 24619089SVasumathi.Sundaram@Sun.COM uintptr_t addr = (uintptr_t)(wsp->walk_addr + arg->off); 24629089SVasumathi.Sundaram@Sun.COM 24639089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr == NULL) { 24649089SVasumathi.Sundaram@Sun.COM mdb_warn("only local walks supported\n"); 24659089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 24669089SVasumathi.Sundaram@Sun.COM } 24679089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), 24689089SVasumathi.Sundaram@Sun.COM addr) == -1) { 24699089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read list head at %p", addr); 24709089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 24719089SVasumathi.Sundaram@Sun.COM } 24729089SVasumathi.Sundaram@Sun.COM iw = mdb_alloc(sizeof (ip_list_walk_data_t), UM_SLEEP); 24739089SVasumathi.Sundaram@Sun.COM iw->nextoff = arg->nextp_off; 24749089SVasumathi.Sundaram@Sun.COM wsp->walk_data = iw; 24759089SVasumathi.Sundaram@Sun.COM 24769089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 24779089SVasumathi.Sundaram@Sun.COM } 24789089SVasumathi.Sundaram@Sun.COM 24799089SVasumathi.Sundaram@Sun.COM static int 24809089SVasumathi.Sundaram@Sun.COM ip_list_walk_step(mdb_walk_state_t *wsp) 24819089SVasumathi.Sundaram@Sun.COM { 24829089SVasumathi.Sundaram@Sun.COM ip_list_walk_data_t *iw = wsp->walk_data; 24839089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr; 24849089SVasumathi.Sundaram@Sun.COM 24859089SVasumathi.Sundaram@Sun.COM if (addr == NULL) 24869089SVasumathi.Sundaram@Sun.COM return (WALK_DONE); 24879089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = addr + iw->nextoff; 24889089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), 24899089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 24909089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read list node at %p", addr); 24919089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 24929089SVasumathi.Sundaram@Sun.COM } 24939089SVasumathi.Sundaram@Sun.COM return (wsp->walk_callback(addr, iw, wsp->walk_cbdata)); 24949089SVasumathi.Sundaram@Sun.COM } 24959089SVasumathi.Sundaram@Sun.COM 24969089SVasumathi.Sundaram@Sun.COM static void 24979089SVasumathi.Sundaram@Sun.COM ip_list_walk_fini(mdb_walk_state_t *wsp) 24989089SVasumathi.Sundaram@Sun.COM { 24999089SVasumathi.Sundaram@Sun.COM mdb_free(wsp->walk_data, sizeof (ip_list_walk_data_t)); 25009089SVasumathi.Sundaram@Sun.COM } 25019089SVasumathi.Sundaram@Sun.COM 25029089SVasumathi.Sundaram@Sun.COM static int 25039089SVasumathi.Sundaram@Sun.COM ipif_walk_init(mdb_walk_state_t *wsp) 25049089SVasumathi.Sundaram@Sun.COM { 25059089SVasumathi.Sundaram@Sun.COM if (mdb_layered_walk("ill", wsp) == -1) { 25069089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'ills'"); 25079089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 25089089SVasumathi.Sundaram@Sun.COM } 25099089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25109089SVasumathi.Sundaram@Sun.COM } 25119089SVasumathi.Sundaram@Sun.COM 25129089SVasumathi.Sundaram@Sun.COM static int 25139089SVasumathi.Sundaram@Sun.COM ipif_walk_step(mdb_walk_state_t *wsp) 25149089SVasumathi.Sundaram@Sun.COM { 25159089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("ipif_list", wsp->walk_callback, wsp->walk_cbdata, 25169089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 25179089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'ipif_list'"); 25189089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 25199089SVasumathi.Sundaram@Sun.COM } 25209089SVasumathi.Sundaram@Sun.COM 25219089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25229089SVasumathi.Sundaram@Sun.COM } 25239089SVasumathi.Sundaram@Sun.COM 25249089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 25259089SVasumathi.Sundaram@Sun.COM static int 25269089SVasumathi.Sundaram@Sun.COM ipif_cb(uintptr_t addr, const ipif_walk_data_t *iw, ipif_cbdata_t *id) 25279089SVasumathi.Sundaram@Sun.COM { 25289089SVasumathi.Sundaram@Sun.COM ipif_t ipif; 25299089SVasumathi.Sundaram@Sun.COM 25309089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ipif, sizeof (ipif_t), (uintptr_t)addr) == -1) { 25319089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ipif at %p", addr); 25329089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25339089SVasumathi.Sundaram@Sun.COM } 25349089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&id->ill, sizeof (ill_t), 25359089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipif.ipif_ill) == -1) { 25369089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", ipif.ipif_ill); 25379089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25389089SVasumathi.Sundaram@Sun.COM } 25399089SVasumathi.Sundaram@Sun.COM (void) ipif_format((uintptr_t)addr, &ipif, id); 25409089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 25419089SVasumathi.Sundaram@Sun.COM } 25429089SVasumathi.Sundaram@Sun.COM 25439089SVasumathi.Sundaram@Sun.COM static void 25449089SVasumathi.Sundaram@Sun.COM ipif_header(boolean_t verbose) 25459089SVasumathi.Sundaram@Sun.COM { 25469089SVasumathi.Sundaram@Sun.COM if (verbose) { 25479089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-10s %-3s %-?s %-8s %-30s\n", 25489089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS"); 25499089SVasumathi.Sundaram@Sun.COM mdb_printf("%s\n%s\n", 25509089SVasumathi.Sundaram@Sun.COM "LCLADDR", "BROADCAST"); 25519089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 25529089SVasumathi.Sundaram@Sun.COM } else { 25539089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-10s %6s %-?s %-8s %-30s\n", 25549089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS"); 25559089SVasumathi.Sundaram@Sun.COM mdb_printf("%s\n%<u>%80s%</u>\n", "LCLADDR", ""); 25569089SVasumathi.Sundaram@Sun.COM } 25579089SVasumathi.Sundaram@Sun.COM } 25589089SVasumathi.Sundaram@Sun.COM 25599089SVasumathi.Sundaram@Sun.COM #ifdef _BIG_ENDIAN 25609089SVasumathi.Sundaram@Sun.COM #define ip_ntohl_32(x) ((x) & 0xffffffff) 25619089SVasumathi.Sundaram@Sun.COM #else 25629089SVasumathi.Sundaram@Sun.COM #define ip_ntohl_32(x) (((uint32_t)(x) << 24) | \ 25639089SVasumathi.Sundaram@Sun.COM (((uint32_t)(x) << 8) & 0xff0000) | \ 25649089SVasumathi.Sundaram@Sun.COM (((uint32_t)(x) >> 8) & 0xff00) | \ 25659089SVasumathi.Sundaram@Sun.COM ((uint32_t)(x) >> 24)) 25669089SVasumathi.Sundaram@Sun.COM #endif 25679089SVasumathi.Sundaram@Sun.COM 25689089SVasumathi.Sundaram@Sun.COM int 25699089SVasumathi.Sundaram@Sun.COM mask_to_prefixlen(int af, const in6_addr_t *addr) 25709089SVasumathi.Sundaram@Sun.COM { 25719089SVasumathi.Sundaram@Sun.COM int len = 0; 25729089SVasumathi.Sundaram@Sun.COM int i; 25739089SVasumathi.Sundaram@Sun.COM uint_t mask = 0; 25749089SVasumathi.Sundaram@Sun.COM 25759089SVasumathi.Sundaram@Sun.COM if (af == AF_INET6) { 25769089SVasumathi.Sundaram@Sun.COM for (i = 0; i < 4; i++) { 25779089SVasumathi.Sundaram@Sun.COM if (addr->s6_addr32[i] == 0xffffffff) { 25789089SVasumathi.Sundaram@Sun.COM len += 32; 25799089SVasumathi.Sundaram@Sun.COM } else { 25809089SVasumathi.Sundaram@Sun.COM mask = addr->s6_addr32[i]; 25819089SVasumathi.Sundaram@Sun.COM break; 25829089SVasumathi.Sundaram@Sun.COM } 25839089SVasumathi.Sundaram@Sun.COM } 25849089SVasumathi.Sundaram@Sun.COM } else { 25859089SVasumathi.Sundaram@Sun.COM mask = V4_PART_OF_V6((*addr)); 25869089SVasumathi.Sundaram@Sun.COM } 25879089SVasumathi.Sundaram@Sun.COM if (mask > 0) 25889089SVasumathi.Sundaram@Sun.COM len += (33 - mdb_ffs(ip_ntohl_32(mask))); 25899089SVasumathi.Sundaram@Sun.COM return (len); 25909089SVasumathi.Sundaram@Sun.COM } 25919089SVasumathi.Sundaram@Sun.COM 25929089SVasumathi.Sundaram@Sun.COM static int 25939089SVasumathi.Sundaram@Sun.COM ipif_format(uintptr_t addr, const void *ipifptr, void *ipif_cb_arg) 25949089SVasumathi.Sundaram@Sun.COM { 25959089SVasumathi.Sundaram@Sun.COM const ipif_t *ipif = ipifptr; 25969089SVasumathi.Sundaram@Sun.COM ipif_cbdata_t *ipifcb = ipif_cb_arg; 25979089SVasumathi.Sundaram@Sun.COM boolean_t verbose = ipifcb->verbose; 25989089SVasumathi.Sundaram@Sun.COM char ill_name[LIFNAMSIZ]; 25999089SVasumathi.Sundaram@Sun.COM char buf[LIFNAMSIZ]; 26009089SVasumathi.Sundaram@Sun.COM int cnt; 26019089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t sfmasks[] = { 26029089SVasumathi.Sundaram@Sun.COM { "CO", IPIF_CONDEMNED, IPIF_CONDEMNED}, 26039089SVasumathi.Sundaram@Sun.COM { "CH", IPIF_CHANGING, IPIF_CHANGING}, 26049089SVasumathi.Sundaram@Sun.COM { "SL", IPIF_SET_LINKLOCAL, IPIF_SET_LINKLOCAL}, 26059089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 26069089SVasumathi.Sundaram@Sun.COM }; 26079089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t fmasks[] = { 26089089SVasumathi.Sundaram@Sun.COM { "UP", IPIF_UP, IPIF_UP }, 26099089SVasumathi.Sundaram@Sun.COM { "UNN", IPIF_UNNUMBERED, IPIF_UNNUMBERED}, 26109089SVasumathi.Sundaram@Sun.COM { "DHCP", IPIF_DHCPRUNNING, IPIF_DHCPRUNNING}, 26119089SVasumathi.Sundaram@Sun.COM { "PRIV", IPIF_PRIVATE, IPIF_PRIVATE}, 26129089SVasumathi.Sundaram@Sun.COM { "NOXMT", IPIF_NOXMIT, IPIF_NOXMIT}, 26139089SVasumathi.Sundaram@Sun.COM { "NOLCL", IPIF_NOLOCAL, IPIF_NOLOCAL}, 26149089SVasumathi.Sundaram@Sun.COM { "DEPR", IPIF_DEPRECATED, IPIF_DEPRECATED}, 26159089SVasumathi.Sundaram@Sun.COM { "PREF", IPIF_PREFERRED, IPIF_PREFERRED}, 26169089SVasumathi.Sundaram@Sun.COM { "TEMP", IPIF_TEMPORARY, IPIF_TEMPORARY}, 26179089SVasumathi.Sundaram@Sun.COM { "ACONF", IPIF_ADDRCONF, IPIF_ADDRCONF}, 26189089SVasumathi.Sundaram@Sun.COM { "ANY", IPIF_ANYCAST, IPIF_ANYCAST}, 26199089SVasumathi.Sundaram@Sun.COM { "NFAIL", IPIF_NOFAILOVER, IPIF_NOFAILOVER}, 26209089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 } 26219089SVasumathi.Sundaram@Sun.COM }; 26229089SVasumathi.Sundaram@Sun.COM char flagsbuf[2 * A_CNT(fmasks)]; 26239089SVasumathi.Sundaram@Sun.COM char bitfields[A_CNT(fmasks)]; 26249089SVasumathi.Sundaram@Sun.COM char sflagsbuf[A_CNT(sfmasks)]; 26259089SVasumathi.Sundaram@Sun.COM char sbuf[DEFCOLS], addrstr[INET6_ADDRSTRLEN]; 26269089SVasumathi.Sundaram@Sun.COM int ipver = ipifcb->ipif_ipversion; 26279089SVasumathi.Sundaram@Sun.COM int af; 26289089SVasumathi.Sundaram@Sun.COM 26299089SVasumathi.Sundaram@Sun.COM if (ipver != 0) { 26309089SVasumathi.Sundaram@Sun.COM if ((ipver == IPV4_VERSION && ipifcb->ill.ill_isv6) || 26319089SVasumathi.Sundaram@Sun.COM (ipver == IPV6_VERSION && !ipifcb->ill.ill_isv6)) { 26329089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26339089SVasumathi.Sundaram@Sun.COM } 26349089SVasumathi.Sundaram@Sun.COM } 26359089SVasumathi.Sundaram@Sun.COM if ((mdb_readstr(ill_name, MIN(LIFNAMSIZ, 26369089SVasumathi.Sundaram@Sun.COM ipifcb->ill.ill_name_length), 26379089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipifcb->ill.ill_name)) == -1) { 26389089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill_name of ill %p\n", ipifcb->ill); 26399089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26409089SVasumathi.Sundaram@Sun.COM } 26419089SVasumathi.Sundaram@Sun.COM if (ipif->ipif_id != 0) { 26429089SVasumathi.Sundaram@Sun.COM mdb_snprintf(buf, LIFNAMSIZ, "%s:%d", 26439089SVasumathi.Sundaram@Sun.COM ill_name, ipif->ipif_id); 26449089SVasumathi.Sundaram@Sun.COM } else { 26459089SVasumathi.Sundaram@Sun.COM mdb_snprintf(buf, LIFNAMSIZ, "%s", ill_name); 26469089SVasumathi.Sundaram@Sun.COM } 26479089SVasumathi.Sundaram@Sun.COM mdb_snprintf(bitfields, sizeof (bitfields), "%s", 26489089SVasumathi.Sundaram@Sun.COM ipif->ipif_addr_ready ? ",ADR" : "", 26499089SVasumathi.Sundaram@Sun.COM ipif->ipif_was_up ? ",WU" : "", 2650*11042SErik.Nordmark@Sun.COM ipif->ipif_was_dup ? ",WD" : ""); 26519089SVasumathi.Sundaram@Sun.COM mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%llb%s", 26529089SVasumathi.Sundaram@Sun.COM ipif->ipif_flags, fmasks, bitfields); 26539089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sflagsbuf, sizeof (sflagsbuf), "%b", 26549089SVasumathi.Sundaram@Sun.COM ipif->ipif_state_flags, sfmasks); 26559089SVasumathi.Sundaram@Sun.COM 2656*11042SErik.Nordmark@Sun.COM cnt = ipif->ipif_refcnt; 26579089SVasumathi.Sundaram@Sun.COM 26589089SVasumathi.Sundaram@Sun.COM if (ipifcb->ill.ill_isv6) { 26599089SVasumathi.Sundaram@Sun.COM mdb_snprintf(addrstr, sizeof (addrstr), "%N", 26609089SVasumathi.Sundaram@Sun.COM &ipif->ipif_v6lcl_addr); 26619089SVasumathi.Sundaram@Sun.COM af = AF_INET6; 26629089SVasumathi.Sundaram@Sun.COM } else { 26639089SVasumathi.Sundaram@Sun.COM mdb_snprintf(addrstr, sizeof (addrstr), "%I", 26649089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((ipif->ipif_v6lcl_addr))); 26659089SVasumathi.Sundaram@Sun.COM af = AF_INET; 26669089SVasumathi.Sundaram@Sun.COM } 26679089SVasumathi.Sundaram@Sun.COM 26689089SVasumathi.Sundaram@Sun.COM if (verbose) { 26699089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-10s %3d %-?p %-8s %-30s\n", 26709089SVasumathi.Sundaram@Sun.COM addr, buf, cnt, ipif->ipif_ill, 26719089SVasumathi.Sundaram@Sun.COM sflagsbuf, flagsbuf); 26729089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sbuf, sizeof (sbuf), "%*s %12s", 26739089SVasumathi.Sundaram@Sun.COM sizeof (uintptr_t) * 2, "", ""); 26749089SVasumathi.Sundaram@Sun.COM mdb_printf("%s |\n%s +---> %4d %-15s " 26759089SVasumathi.Sundaram@Sun.COM "Active consistent reader cnt\n", 26769089SVasumathi.Sundaram@Sun.COM sbuf, sbuf, ipif->ipif_refcnt, "ipif_refcnt"); 26779089SVasumathi.Sundaram@Sun.COM mdb_printf("%-s/%d\n", 26789089SVasumathi.Sundaram@Sun.COM addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask)); 26799089SVasumathi.Sundaram@Sun.COM if (ipifcb->ill.ill_isv6) { 26809089SVasumathi.Sundaram@Sun.COM mdb_printf("%-N\n", &ipif->ipif_v6brd_addr); 26819089SVasumathi.Sundaram@Sun.COM } else { 26829089SVasumathi.Sundaram@Sun.COM mdb_printf("%-I\n", 26839089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((ipif->ipif_v6brd_addr))); 26849089SVasumathi.Sundaram@Sun.COM } 26859089SVasumathi.Sundaram@Sun.COM } else { 26869089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-10s %6d %-?p %-8s %-30s\n", 26879089SVasumathi.Sundaram@Sun.COM addr, buf, cnt, ipif->ipif_ill, 26889089SVasumathi.Sundaram@Sun.COM sflagsbuf, flagsbuf); 26899089SVasumathi.Sundaram@Sun.COM mdb_printf("%-s/%d\n", 26909089SVasumathi.Sundaram@Sun.COM addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask)); 26919089SVasumathi.Sundaram@Sun.COM } 26929089SVasumathi.Sundaram@Sun.COM 26939089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 26949089SVasumathi.Sundaram@Sun.COM } 26959089SVasumathi.Sundaram@Sun.COM 26969089SVasumathi.Sundaram@Sun.COM static int 26979089SVasumathi.Sundaram@Sun.COM ipif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 26989089SVasumathi.Sundaram@Sun.COM { 26999089SVasumathi.Sundaram@Sun.COM ipif_t ipif; 27009089SVasumathi.Sundaram@Sun.COM ipif_cbdata_t id; 27019089SVasumathi.Sundaram@Sun.COM int ipversion = 0; 27029089SVasumathi.Sundaram@Sun.COM const char *opt_P = NULL; 27039089SVasumathi.Sundaram@Sun.COM uint_t verbose = FALSE; 27049089SVasumathi.Sundaram@Sun.COM 27059089SVasumathi.Sundaram@Sun.COM if (mdb_getopts(argc, argv, 27069089SVasumathi.Sundaram@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose, 27079089SVasumathi.Sundaram@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc) 27089089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 27099089SVasumathi.Sundaram@Sun.COM 27109089SVasumathi.Sundaram@Sun.COM if (opt_P != NULL) { 27119089SVasumathi.Sundaram@Sun.COM if (strcmp("v4", opt_P) == 0) { 27129089SVasumathi.Sundaram@Sun.COM ipversion = IPV4_VERSION; 27139089SVasumathi.Sundaram@Sun.COM } else if (strcmp("v6", opt_P) == 0) { 27149089SVasumathi.Sundaram@Sun.COM ipversion = IPV6_VERSION; 27159089SVasumathi.Sundaram@Sun.COM } else { 27169089SVasumathi.Sundaram@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P); 27179089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE); 27189089SVasumathi.Sundaram@Sun.COM } 27199089SVasumathi.Sundaram@Sun.COM } 27209089SVasumathi.Sundaram@Sun.COM 27219089SVasumathi.Sundaram@Sun.COM id.verbose = verbose; 27229089SVasumathi.Sundaram@Sun.COM id.ipif_ipversion = ipversion; 27239089SVasumathi.Sundaram@Sun.COM 27249089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 27259089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ipif, sizeof (ipif_t), addr) == -1) { 27269089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ipif at %p\n", addr); 27279089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 27289089SVasumathi.Sundaram@Sun.COM } 27299089SVasumathi.Sundaram@Sun.COM ipif_header(verbose); 27309089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&id.ill, sizeof (ill_t), 27319089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipif.ipif_ill) == -1) { 27329089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", ipif.ipif_ill); 27339089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 27349089SVasumathi.Sundaram@Sun.COM } 27359089SVasumathi.Sundaram@Sun.COM return (ipif_format(addr, &ipif, &id)); 27369089SVasumathi.Sundaram@Sun.COM } else { 27379089SVasumathi.Sundaram@Sun.COM ipif_header(verbose); 27389089SVasumathi.Sundaram@Sun.COM if (mdb_walk("ipif", (mdb_walk_cb_t)ipif_cb, &id) == -1) { 27399089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk ipifs\n"); 27409089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 27419089SVasumathi.Sundaram@Sun.COM } 27429089SVasumathi.Sundaram@Sun.COM } 27439089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 27449089SVasumathi.Sundaram@Sun.COM } 27459089SVasumathi.Sundaram@Sun.COM 27469089SVasumathi.Sundaram@Sun.COM static void 27479089SVasumathi.Sundaram@Sun.COM ipif_help(void) 27489089SVasumathi.Sundaram@Sun.COM { 27499089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints the following fields: ipif ptr, name, " 27509089SVasumathi.Sundaram@Sun.COM "count, ill ptr, state flags and ipif flags.\n" 27519089SVasumathi.Sundaram@Sun.COM "The count field is a sum of individual refcnts and is expanded " 27529089SVasumathi.Sundaram@Sun.COM "with the -v option.\n" 27539089SVasumathi.Sundaram@Sun.COM "The flags field shows the following:" 27549089SVasumathi.Sundaram@Sun.COM "\n\tUNN -> UNNUMBERED, DHCP -> DHCPRUNNING, PRIV -> PRIVATE, " 27559089SVasumathi.Sundaram@Sun.COM "\n\tNOXMT -> NOXMIT, NOLCL -> NOLOCAL, DEPR -> DEPRECATED, " 27569089SVasumathi.Sundaram@Sun.COM "\n\tPREF -> PREFERRED, TEMP -> TEMPORARY, ACONF -> ADDRCONF, " 27579089SVasumathi.Sundaram@Sun.COM "\n\tANY -> ANYCAST, NFAIL -> NOFAILOVER, " 27589089SVasumathi.Sundaram@Sun.COM "\n\tADR -> ipif_addr_ready, MU -> ipif_multicast_up, " 27599089SVasumathi.Sundaram@Sun.COM "\n\tWU -> ipif_was_up, WD -> ipif_was_dup, " 27609089SVasumathi.Sundaram@Sun.COM "JA -> ipif_joined_allhosts.\n\n"); 27619089SVasumathi.Sundaram@Sun.COM mdb_printf("Options:\n"); 27629089SVasumathi.Sundaram@Sun.COM mdb_printf("\t-P v4 | v6" 27639089SVasumathi.Sundaram@Sun.COM "\tfilter ipif structures on ills for the specified protocol\n"); 27649089SVasumathi.Sundaram@Sun.COM } 27659089SVasumathi.Sundaram@Sun.COM 27669089SVasumathi.Sundaram@Sun.COM static int 27679089SVasumathi.Sundaram@Sun.COM conn_status_walk_fanout(uintptr_t addr, mdb_walk_state_t *wsp, 27689089SVasumathi.Sundaram@Sun.COM const char *walkname) 27699089SVasumathi.Sundaram@Sun.COM { 27709089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk(walkname, wsp->walk_callback, wsp->walk_cbdata, 27719089SVasumathi.Sundaram@Sun.COM addr) == -1) { 27729089SVasumathi.Sundaram@Sun.COM mdb_warn("couldn't walk '%s' at %p", walkname, addr); 27739089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 27749089SVasumathi.Sundaram@Sun.COM } 27759089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 27769089SVasumathi.Sundaram@Sun.COM } 27779089SVasumathi.Sundaram@Sun.COM 27789089SVasumathi.Sundaram@Sun.COM static int 27799089SVasumathi.Sundaram@Sun.COM conn_status_walk_step(mdb_walk_state_t *wsp) 27809089SVasumathi.Sundaram@Sun.COM { 27819089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr; 27829089SVasumathi.Sundaram@Sun.COM 27839089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "udp_hash"); 27849089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "conn_hash"); 27859089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "bind_hash"); 27869089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "proto_hash"); 27879089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "proto_v6_hash"); 27889089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 27899089SVasumathi.Sundaram@Sun.COM } 27909089SVasumathi.Sundaram@Sun.COM 27919089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 27929089SVasumathi.Sundaram@Sun.COM static int 27939089SVasumathi.Sundaram@Sun.COM conn_status_cb(uintptr_t addr, const void *walk_data, 27949089SVasumathi.Sundaram@Sun.COM void *private) 27959089SVasumathi.Sundaram@Sun.COM { 27969089SVasumathi.Sundaram@Sun.COM netstack_t nss; 27979089SVasumathi.Sundaram@Sun.COM char src_addrstr[INET6_ADDRSTRLEN]; 27989089SVasumathi.Sundaram@Sun.COM char rem_addrstr[INET6_ADDRSTRLEN]; 27999089SVasumathi.Sundaram@Sun.COM const ipcl_hash_walk_data_t *iw = walk_data; 28009089SVasumathi.Sundaram@Sun.COM conn_t *conn = iw->conn; 28019089SVasumathi.Sundaram@Sun.COM 28029089SVasumathi.Sundaram@Sun.COM if (mdb_vread(conn, sizeof (conn_t), addr) == -1) { 28039089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", addr); 28049089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 28059089SVasumathi.Sundaram@Sun.COM } 28069089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&nss, sizeof (nss), 28079089SVasumathi.Sundaram@Sun.COM (uintptr_t)conn->conn_netstack) == -1) { 28089089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read netstack_t %p", 28099089SVasumathi.Sundaram@Sun.COM conn->conn_netstack); 28109089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 28119089SVasumathi.Sundaram@Sun.COM } 28129089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-?p %?d %?d\n", addr, conn->conn_wq, 28139089SVasumathi.Sundaram@Sun.COM nss.netstack_stackid, conn->conn_zoneid); 28149089SVasumathi.Sundaram@Sun.COM 2815*11042SErik.Nordmark@Sun.COM if (conn->conn_family == AF_INET6) { 28169089SVasumathi.Sundaram@Sun.COM mdb_snprintf(src_addrstr, sizeof (rem_addrstr), "%N", 2817*11042SErik.Nordmark@Sun.COM &conn->conn_laddr_v6); 28189089SVasumathi.Sundaram@Sun.COM mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%N", 2819*11042SErik.Nordmark@Sun.COM &conn->conn_faddr_v6); 28209089SVasumathi.Sundaram@Sun.COM } else { 28219089SVasumathi.Sundaram@Sun.COM mdb_snprintf(src_addrstr, sizeof (src_addrstr), "%I", 2822*11042SErik.Nordmark@Sun.COM V4_PART_OF_V6((conn->conn_laddr_v6))); 28239089SVasumathi.Sundaram@Sun.COM mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%I", 2824*11042SErik.Nordmark@Sun.COM V4_PART_OF_V6((conn->conn_faddr_v6))); 28259089SVasumathi.Sundaram@Sun.COM } 28269089SVasumathi.Sundaram@Sun.COM mdb_printf("%s:%-5d\n%s:%-5d\n", 28279089SVasumathi.Sundaram@Sun.COM src_addrstr, conn->conn_lport, rem_addrstr, conn->conn_fport); 28289089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 28299089SVasumathi.Sundaram@Sun.COM } 28309089SVasumathi.Sundaram@Sun.COM 28319089SVasumathi.Sundaram@Sun.COM static void 28329089SVasumathi.Sundaram@Sun.COM conn_header(void) 28339089SVasumathi.Sundaram@Sun.COM { 28349089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-?s %?s %?s\n%s\n%s\n", 28359089SVasumathi.Sundaram@Sun.COM "ADDR", "WQ", "STACK", "ZONE", "SRC:PORT", "DEST:PORT"); 28369089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 28379089SVasumathi.Sundaram@Sun.COM } 28389089SVasumathi.Sundaram@Sun.COM 28399089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/ 28409089SVasumathi.Sundaram@Sun.COM static int 28419089SVasumathi.Sundaram@Sun.COM conn_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 28429089SVasumathi.Sundaram@Sun.COM { 28439089SVasumathi.Sundaram@Sun.COM conn_header(); 28449089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 28459089SVasumathi.Sundaram@Sun.COM (void) conn_status_cb(addr, NULL, NULL); 28469089SVasumathi.Sundaram@Sun.COM } else { 28479089SVasumathi.Sundaram@Sun.COM if (mdb_walk("conn_status", (mdb_walk_cb_t)conn_status_cb, 28489089SVasumathi.Sundaram@Sun.COM NULL) == -1) { 28499089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk conn_fanout"); 28509089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 28519089SVasumathi.Sundaram@Sun.COM } 28529089SVasumathi.Sundaram@Sun.COM } 28539089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 28549089SVasumathi.Sundaram@Sun.COM } 28559089SVasumathi.Sundaram@Sun.COM 28569089SVasumathi.Sundaram@Sun.COM static void 28579089SVasumathi.Sundaram@Sun.COM conn_status_help(void) 28589089SVasumathi.Sundaram@Sun.COM { 28599089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints conn_t structures from the following hash tables: " 28609089SVasumathi.Sundaram@Sun.COM "\n\tips_ipcl_udp_fanout\n\tips_ipcl_bind_fanout" 2861*11042SErik.Nordmark@Sun.COM "\n\tips_ipcl_conn_fanout\n\tips_ipcl_proto_fanout_v4" 28629089SVasumathi.Sundaram@Sun.COM "\n\tips_ipcl_proto_fanout_v6\n"); 28639089SVasumathi.Sundaram@Sun.COM } 28649089SVasumathi.Sundaram@Sun.COM 28659089SVasumathi.Sundaram@Sun.COM static int 28669089SVasumathi.Sundaram@Sun.COM srcid_walk_step(mdb_walk_state_t *wsp) 28679089SVasumathi.Sundaram@Sun.COM { 28689089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("srcid_list", wsp->walk_callback, wsp->walk_cbdata, 28699089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) { 28709089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'srcid_list'"); 28719089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 28729089SVasumathi.Sundaram@Sun.COM } 28739089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 28749089SVasumathi.Sundaram@Sun.COM } 28759089SVasumathi.Sundaram@Sun.COM 28769089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */ 28779089SVasumathi.Sundaram@Sun.COM static int 28789089SVasumathi.Sundaram@Sun.COM srcid_status_cb(uintptr_t addr, const void *walk_data, 28799089SVasumathi.Sundaram@Sun.COM void *private) 28809089SVasumathi.Sundaram@Sun.COM { 28819089SVasumathi.Sundaram@Sun.COM srcid_map_t smp; 28829089SVasumathi.Sundaram@Sun.COM 28839089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&smp, sizeof (srcid_map_t), addr) == -1) { 28849089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read srcid_map at %p", addr); 28859089SVasumathi.Sundaram@Sun.COM return (WALK_ERR); 28869089SVasumathi.Sundaram@Sun.COM } 28879089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %3d %4d %6d %N\n", 28889089SVasumathi.Sundaram@Sun.COM addr, smp.sm_srcid, smp.sm_zoneid, smp.sm_refcnt, 28899089SVasumathi.Sundaram@Sun.COM &smp.sm_addr); 28909089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT); 28919089SVasumathi.Sundaram@Sun.COM } 28929089SVasumathi.Sundaram@Sun.COM 28939089SVasumathi.Sundaram@Sun.COM static void 28949089SVasumathi.Sundaram@Sun.COM srcid_header(void) 28959089SVasumathi.Sundaram@Sun.COM { 28969089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %3s %4s %6s %s\n", 28979089SVasumathi.Sundaram@Sun.COM "ADDR", "ID", "ZONE", "REFCNT", "IPADDR"); 28989089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", ""); 28999089SVasumathi.Sundaram@Sun.COM } 29009089SVasumathi.Sundaram@Sun.COM 29019089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/ 29029089SVasumathi.Sundaram@Sun.COM static int 29039089SVasumathi.Sundaram@Sun.COM srcid_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 29049089SVasumathi.Sundaram@Sun.COM { 29059089SVasumathi.Sundaram@Sun.COM srcid_header(); 29069089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) { 29079089SVasumathi.Sundaram@Sun.COM (void) srcid_status_cb(addr, NULL, NULL); 29089089SVasumathi.Sundaram@Sun.COM } else { 29099089SVasumathi.Sundaram@Sun.COM if (mdb_walk("srcid", (mdb_walk_cb_t)srcid_status_cb, 29109089SVasumathi.Sundaram@Sun.COM NULL) == -1) { 29119089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk srcid_map"); 29129089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR); 29139089SVasumathi.Sundaram@Sun.COM } 29149089SVasumathi.Sundaram@Sun.COM } 29159089SVasumathi.Sundaram@Sun.COM return (DCMD_OK); 29169089SVasumathi.Sundaram@Sun.COM } 291710946SSangeeta.Misra@Sun.COM 291810946SSangeeta.Misra@Sun.COM static int 291910946SSangeeta.Misra@Sun.COM ilb_stacks_walk_step(mdb_walk_state_t *wsp) 292010946SSangeeta.Misra@Sun.COM { 292110946SSangeeta.Misra@Sun.COM uintptr_t kaddr; 292210946SSangeeta.Misra@Sun.COM netstack_t nss; 292310946SSangeeta.Misra@Sun.COM 292410946SSangeeta.Misra@Sun.COM if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 292510946SSangeeta.Misra@Sun.COM mdb_warn("can't read netstack at %p", wsp->walk_addr); 292610946SSangeeta.Misra@Sun.COM return (WALK_ERR); 292710946SSangeeta.Misra@Sun.COM } 292810946SSangeeta.Misra@Sun.COM kaddr = (uintptr_t)nss.netstack_modules[NS_ILB]; 292910946SSangeeta.Misra@Sun.COM 293010946SSangeeta.Misra@Sun.COM return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 293110946SSangeeta.Misra@Sun.COM } 293210946SSangeeta.Misra@Sun.COM 293310946SSangeeta.Misra@Sun.COM static int 293410946SSangeeta.Misra@Sun.COM ilb_rules_walk_init(mdb_walk_state_t *wsp) 293510946SSangeeta.Misra@Sun.COM { 293610946SSangeeta.Misra@Sun.COM ilb_stack_t ilbs; 293710946SSangeeta.Misra@Sun.COM 293810946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 293910946SSangeeta.Misra@Sun.COM return (WALK_ERR); 294010946SSangeeta.Misra@Sun.COM 294110946SSangeeta.Misra@Sun.COM if (mdb_vread(&ilbs, sizeof (ilbs), wsp->walk_addr) == -1) { 294210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 294310946SSangeeta.Misra@Sun.COM return (WALK_ERR); 294410946SSangeeta.Misra@Sun.COM } 294510946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)ilbs.ilbs_rule_head) != NULL) 294610946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 294710946SSangeeta.Misra@Sun.COM else 294810946SSangeeta.Misra@Sun.COM return (WALK_DONE); 294910946SSangeeta.Misra@Sun.COM } 295010946SSangeeta.Misra@Sun.COM 295110946SSangeeta.Misra@Sun.COM static int 295210946SSangeeta.Misra@Sun.COM ilb_rules_walk_step(mdb_walk_state_t *wsp) 295310946SSangeeta.Misra@Sun.COM { 295410946SSangeeta.Misra@Sun.COM ilb_rule_t rule; 295510946SSangeeta.Misra@Sun.COM int status; 295610946SSangeeta.Misra@Sun.COM 295710946SSangeeta.Misra@Sun.COM if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) { 295810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr); 295910946SSangeeta.Misra@Sun.COM return (WALK_ERR); 296010946SSangeeta.Misra@Sun.COM } 296110946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &rule, wsp->walk_cbdata); 296210946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 296310946SSangeeta.Misra@Sun.COM return (status); 296410946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)rule.ir_next) == NULL) 296510946SSangeeta.Misra@Sun.COM return (WALK_DONE); 296610946SSangeeta.Misra@Sun.COM else 296710946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 296810946SSangeeta.Misra@Sun.COM } 296910946SSangeeta.Misra@Sun.COM 297010946SSangeeta.Misra@Sun.COM static int 297110946SSangeeta.Misra@Sun.COM ilb_servers_walk_init(mdb_walk_state_t *wsp) 297210946SSangeeta.Misra@Sun.COM { 297310946SSangeeta.Misra@Sun.COM ilb_rule_t rule; 297410946SSangeeta.Misra@Sun.COM 297510946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 297610946SSangeeta.Misra@Sun.COM return (WALK_ERR); 297710946SSangeeta.Misra@Sun.COM 297810946SSangeeta.Misra@Sun.COM if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) { 297910946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr); 298010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 298110946SSangeeta.Misra@Sun.COM } 298210946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)rule.ir_servers) != NULL) 298310946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 298410946SSangeeta.Misra@Sun.COM else 298510946SSangeeta.Misra@Sun.COM return (WALK_DONE); 298610946SSangeeta.Misra@Sun.COM } 298710946SSangeeta.Misra@Sun.COM 298810946SSangeeta.Misra@Sun.COM static int 298910946SSangeeta.Misra@Sun.COM ilb_servers_walk_step(mdb_walk_state_t *wsp) 299010946SSangeeta.Misra@Sun.COM { 299110946SSangeeta.Misra@Sun.COM ilb_server_t server; 299210946SSangeeta.Misra@Sun.COM int status; 299310946SSangeeta.Misra@Sun.COM 299410946SSangeeta.Misra@Sun.COM if (mdb_vread(&server, sizeof (server), wsp->walk_addr) == -1) { 299510946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_server_t at %p", wsp->walk_addr); 299610946SSangeeta.Misra@Sun.COM return (WALK_ERR); 299710946SSangeeta.Misra@Sun.COM } 299810946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &server, wsp->walk_cbdata); 299910946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 300010946SSangeeta.Misra@Sun.COM return (status); 300110946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)server.iser_next) == NULL) 300210946SSangeeta.Misra@Sun.COM return (WALK_DONE); 300310946SSangeeta.Misra@Sun.COM else 300410946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 300510946SSangeeta.Misra@Sun.COM } 300610946SSangeeta.Misra@Sun.COM 300710946SSangeeta.Misra@Sun.COM /* 300810946SSangeeta.Misra@Sun.COM * Helper structure for ilb_nat_src walker. It stores the current index of the 300910946SSangeeta.Misra@Sun.COM * nat src table. 301010946SSangeeta.Misra@Sun.COM */ 301110946SSangeeta.Misra@Sun.COM typedef struct { 301210946SSangeeta.Misra@Sun.COM ilb_stack_t ilbs; 301310946SSangeeta.Misra@Sun.COM int idx; 301410946SSangeeta.Misra@Sun.COM } ilb_walk_t; 301510946SSangeeta.Misra@Sun.COM 301610946SSangeeta.Misra@Sun.COM /* Copy from list.c */ 301710946SSangeeta.Misra@Sun.COM #define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset)) 301810946SSangeeta.Misra@Sun.COM 301910946SSangeeta.Misra@Sun.COM static int 302010946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_init(mdb_walk_state_t *wsp) 302110946SSangeeta.Misra@Sun.COM { 302210946SSangeeta.Misra@Sun.COM int i; 302310946SSangeeta.Misra@Sun.COM ilb_walk_t *ns_walk; 302410946SSangeeta.Misra@Sun.COM ilb_nat_src_entry_t *entry = NULL; 302510946SSangeeta.Misra@Sun.COM 302610946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 302710946SSangeeta.Misra@Sun.COM return (WALK_ERR); 302810946SSangeeta.Misra@Sun.COM 302910946SSangeeta.Misra@Sun.COM ns_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP); 303010946SSangeeta.Misra@Sun.COM if (mdb_vread(&ns_walk->ilbs, sizeof (ns_walk->ilbs), 303110946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 303210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 303310946SSangeeta.Misra@Sun.COM mdb_free(ns_walk, sizeof (ilb_walk_t)); 303410946SSangeeta.Misra@Sun.COM return (WALK_ERR); 303510946SSangeeta.Misra@Sun.COM } 303610946SSangeeta.Misra@Sun.COM 303710946SSangeeta.Misra@Sun.COM if (ns_walk->ilbs.ilbs_nat_src == NULL) { 303810946SSangeeta.Misra@Sun.COM mdb_free(ns_walk, sizeof (ilb_walk_t)); 303910946SSangeeta.Misra@Sun.COM return (WALK_DONE); 304010946SSangeeta.Misra@Sun.COM } 304110946SSangeeta.Misra@Sun.COM 304210946SSangeeta.Misra@Sun.COM wsp->walk_data = ns_walk; 304310946SSangeeta.Misra@Sun.COM for (i = 0; i < ns_walk->ilbs.ilbs_nat_src_hash_size; i++) { 304410946SSangeeta.Misra@Sun.COM list_t head; 304510946SSangeeta.Misra@Sun.COM char *khead; 304610946SSangeeta.Misra@Sun.COM 304710946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 304810946SSangeeta.Misra@Sun.COM khead = (char *)ns_walk->ilbs.ilbs_nat_src + i * 304910946SSangeeta.Misra@Sun.COM sizeof (ilb_nat_src_hash_t); 305010946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 305110946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead); 305210946SSangeeta.Misra@Sun.COM return (WALK_ERR); 305310946SSangeeta.Misra@Sun.COM } 305410946SSangeeta.Misra@Sun.COM 305510946SSangeeta.Misra@Sun.COM /* 305610946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need 305710946SSangeeta.Misra@Sun.COM * to compare list_next with the kernel address of the list 305810946SSangeeta.Misra@Sun.COM * head. So we need to calculate the address manually. 305910946SSangeeta.Misra@Sun.COM */ 306010946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 306110946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 306210946SSangeeta.Misra@Sun.COM entry = list_object(&head, head.list_head.list_next); 306310946SSangeeta.Misra@Sun.COM break; 306410946SSangeeta.Misra@Sun.COM } 306510946SSangeeta.Misra@Sun.COM } 306610946SSangeeta.Misra@Sun.COM 306710946SSangeeta.Misra@Sun.COM if (entry == NULL) 306810946SSangeeta.Misra@Sun.COM return (WALK_DONE); 306910946SSangeeta.Misra@Sun.COM 307010946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)entry; 307110946SSangeeta.Misra@Sun.COM ns_walk->idx = i; 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_nat_src_walk_step(mdb_walk_state_t *wsp) 307710946SSangeeta.Misra@Sun.COM { 307810946SSangeeta.Misra@Sun.COM int status; 307910946SSangeeta.Misra@Sun.COM ilb_nat_src_entry_t entry, *next_entry; 308010946SSangeeta.Misra@Sun.COM ilb_walk_t *ns_walk; 308110946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs; 308210946SSangeeta.Misra@Sun.COM list_t head; 308310946SSangeeta.Misra@Sun.COM char *khead; 308410946SSangeeta.Misra@Sun.COM int i; 308510946SSangeeta.Misra@Sun.COM 308610946SSangeeta.Misra@Sun.COM if (mdb_vread(&entry, sizeof (ilb_nat_src_entry_t), 308710946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 308810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_nat_src_entry_t at %p", 308910946SSangeeta.Misra@Sun.COM wsp->walk_addr); 309010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 309110946SSangeeta.Misra@Sun.COM } 309210946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &entry, wsp->walk_cbdata); 309310946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 309410946SSangeeta.Misra@Sun.COM return (status); 309510946SSangeeta.Misra@Sun.COM 309610946SSangeeta.Misra@Sun.COM ns_walk = (ilb_walk_t *)wsp->walk_data; 309710946SSangeeta.Misra@Sun.COM ilbs = &ns_walk->ilbs; 309810946SSangeeta.Misra@Sun.COM i = ns_walk->idx; 309910946SSangeeta.Misra@Sun.COM 310010946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 310110946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_nat_src + i * sizeof (ilb_nat_src_hash_t); 310210946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 310310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead); 310410946SSangeeta.Misra@Sun.COM return (WALK_ERR); 310510946SSangeeta.Misra@Sun.COM } 310610946SSangeeta.Misra@Sun.COM 310710946SSangeeta.Misra@Sun.COM /* 310810946SSangeeta.Misra@Sun.COM * Check if there is still entry in the current list. 310910946SSangeeta.Misra@Sun.COM * 311010946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need to 311110946SSangeeta.Misra@Sun.COM * compare list_next with the kernel address of the list head. 311210946SSangeeta.Misra@Sun.COM * So we need to calculate the address manually. 311310946SSangeeta.Misra@Sun.COM */ 311410946SSangeeta.Misra@Sun.COM if ((char *)entry.nse_link.list_next != khead + offsetof(list_t, 311510946SSangeeta.Misra@Sun.COM list_head)) { 311610946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)list_object(&head, 311710946SSangeeta.Misra@Sun.COM entry.nse_link.list_next); 311810946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 311910946SSangeeta.Misra@Sun.COM } 312010946SSangeeta.Misra@Sun.COM 312110946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */ 312210946SSangeeta.Misra@Sun.COM next_entry = NULL; 312310946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) { 312410946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_nat_src + i * 312510946SSangeeta.Misra@Sun.COM sizeof (ilb_nat_src_hash_t); 312610946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 312710946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead); 312810946SSangeeta.Misra@Sun.COM return (WALK_ERR); 312910946SSangeeta.Misra@Sun.COM } 313010946SSangeeta.Misra@Sun.COM 313110946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 313210946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 313310946SSangeeta.Misra@Sun.COM next_entry = list_object(&head, 313410946SSangeeta.Misra@Sun.COM head.list_head.list_next); 313510946SSangeeta.Misra@Sun.COM break; 313610946SSangeeta.Misra@Sun.COM } 313710946SSangeeta.Misra@Sun.COM } 313810946SSangeeta.Misra@Sun.COM 313910946SSangeeta.Misra@Sun.COM if (next_entry == NULL) 314010946SSangeeta.Misra@Sun.COM return (WALK_DONE); 314110946SSangeeta.Misra@Sun.COM 314210946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)next_entry; 314310946SSangeeta.Misra@Sun.COM ns_walk->idx = i; 314410946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 314510946SSangeeta.Misra@Sun.COM } 314610946SSangeeta.Misra@Sun.COM 314710946SSangeeta.Misra@Sun.COM static void 314810946SSangeeta.Misra@Sun.COM ilb_common_walk_fini(mdb_walk_state_t *wsp) 314910946SSangeeta.Misra@Sun.COM { 315010946SSangeeta.Misra@Sun.COM ilb_walk_t *walk; 315110946SSangeeta.Misra@Sun.COM 315210946SSangeeta.Misra@Sun.COM walk = (ilb_walk_t *)wsp->walk_data; 315310946SSangeeta.Misra@Sun.COM if (walk == NULL) 315410946SSangeeta.Misra@Sun.COM return; 315510946SSangeeta.Misra@Sun.COM mdb_free(walk, sizeof (ilb_walk_t *)); 315610946SSangeeta.Misra@Sun.COM } 315710946SSangeeta.Misra@Sun.COM 315810946SSangeeta.Misra@Sun.COM static int 315910946SSangeeta.Misra@Sun.COM ilb_conn_walk_init(mdb_walk_state_t *wsp) 316010946SSangeeta.Misra@Sun.COM { 316110946SSangeeta.Misra@Sun.COM int i; 316210946SSangeeta.Misra@Sun.COM ilb_walk_t *conn_walk; 316310946SSangeeta.Misra@Sun.COM ilb_conn_hash_t head; 316410946SSangeeta.Misra@Sun.COM 316510946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 316610946SSangeeta.Misra@Sun.COM return (WALK_ERR); 316710946SSangeeta.Misra@Sun.COM 316810946SSangeeta.Misra@Sun.COM conn_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP); 316910946SSangeeta.Misra@Sun.COM if (mdb_vread(&conn_walk->ilbs, sizeof (conn_walk->ilbs), 317010946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 317110946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 317210946SSangeeta.Misra@Sun.COM mdb_free(conn_walk, sizeof (ilb_walk_t)); 317310946SSangeeta.Misra@Sun.COM return (WALK_ERR); 317410946SSangeeta.Misra@Sun.COM } 317510946SSangeeta.Misra@Sun.COM 317610946SSangeeta.Misra@Sun.COM if (conn_walk->ilbs.ilbs_c2s_conn_hash == NULL) { 317710946SSangeeta.Misra@Sun.COM mdb_free(conn_walk, sizeof (ilb_walk_t)); 317810946SSangeeta.Misra@Sun.COM return (WALK_DONE); 317910946SSangeeta.Misra@Sun.COM } 318010946SSangeeta.Misra@Sun.COM 318110946SSangeeta.Misra@Sun.COM wsp->walk_data = conn_walk; 318210946SSangeeta.Misra@Sun.COM for (i = 0; i < conn_walk->ilbs.ilbs_conn_hash_size; i++) { 318310946SSangeeta.Misra@Sun.COM char *khead; 318410946SSangeeta.Misra@Sun.COM 318510946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 318610946SSangeeta.Misra@Sun.COM khead = (char *)conn_walk->ilbs.ilbs_c2s_conn_hash + i * 318710946SSangeeta.Misra@Sun.COM sizeof (ilb_conn_hash_t); 318810946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (ilb_conn_hash_t), 318910946SSangeeta.Misra@Sun.COM (uintptr_t)khead) == -1) { 319010946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n", 319110946SSangeeta.Misra@Sun.COM khead); 319210946SSangeeta.Misra@Sun.COM return (WALK_ERR); 319310946SSangeeta.Misra@Sun.COM } 319410946SSangeeta.Misra@Sun.COM 319510946SSangeeta.Misra@Sun.COM if (head.ilb_connp != NULL) 319610946SSangeeta.Misra@Sun.COM break; 319710946SSangeeta.Misra@Sun.COM } 319810946SSangeeta.Misra@Sun.COM 319910946SSangeeta.Misra@Sun.COM if (head.ilb_connp == NULL) 320010946SSangeeta.Misra@Sun.COM return (WALK_DONE); 320110946SSangeeta.Misra@Sun.COM 320210946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)head.ilb_connp; 320310946SSangeeta.Misra@Sun.COM conn_walk->idx = i; 320410946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 320510946SSangeeta.Misra@Sun.COM } 320610946SSangeeta.Misra@Sun.COM 320710946SSangeeta.Misra@Sun.COM static int 320810946SSangeeta.Misra@Sun.COM ilb_conn_walk_step(mdb_walk_state_t *wsp) 320910946SSangeeta.Misra@Sun.COM { 321010946SSangeeta.Misra@Sun.COM int status; 321110946SSangeeta.Misra@Sun.COM ilb_conn_t conn; 321210946SSangeeta.Misra@Sun.COM ilb_walk_t *conn_walk; 321310946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs; 321410946SSangeeta.Misra@Sun.COM ilb_conn_hash_t head; 321510946SSangeeta.Misra@Sun.COM char *khead; 321610946SSangeeta.Misra@Sun.COM int i; 321710946SSangeeta.Misra@Sun.COM 321810946SSangeeta.Misra@Sun.COM if (mdb_vread(&conn, sizeof (ilb_conn_t), wsp->walk_addr) == -1) { 321910946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_conn_t at %p", wsp->walk_addr); 322010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 322110946SSangeeta.Misra@Sun.COM } 322210946SSangeeta.Misra@Sun.COM 322310946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &conn, wsp->walk_cbdata); 322410946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 322510946SSangeeta.Misra@Sun.COM return (status); 322610946SSangeeta.Misra@Sun.COM 322710946SSangeeta.Misra@Sun.COM conn_walk = (ilb_walk_t *)wsp->walk_data; 322810946SSangeeta.Misra@Sun.COM ilbs = &conn_walk->ilbs; 322910946SSangeeta.Misra@Sun.COM i = conn_walk->idx; 323010946SSangeeta.Misra@Sun.COM 323110946SSangeeta.Misra@Sun.COM /* Check if there is still entry in the current list. */ 323210946SSangeeta.Misra@Sun.COM if (conn.conn_c2s_next != NULL) { 323310946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)conn.conn_c2s_next; 323410946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 323510946SSangeeta.Misra@Sun.COM } 323610946SSangeeta.Misra@Sun.COM 323710946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */ 323810946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_conn_hash_size; i++) { 323910946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_c2s_conn_hash + i * 324010946SSangeeta.Misra@Sun.COM sizeof (ilb_conn_hash_t); 324110946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (ilb_conn_hash_t), 324210946SSangeeta.Misra@Sun.COM (uintptr_t)khead) == -1) { 324310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n", 324410946SSangeeta.Misra@Sun.COM khead); 324510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 324610946SSangeeta.Misra@Sun.COM } 324710946SSangeeta.Misra@Sun.COM 324810946SSangeeta.Misra@Sun.COM if (head.ilb_connp != NULL) 324910946SSangeeta.Misra@Sun.COM break; 325010946SSangeeta.Misra@Sun.COM } 325110946SSangeeta.Misra@Sun.COM 325210946SSangeeta.Misra@Sun.COM if (head.ilb_connp == NULL) 325310946SSangeeta.Misra@Sun.COM return (WALK_DONE); 325410946SSangeeta.Misra@Sun.COM 325510946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)head.ilb_connp; 325610946SSangeeta.Misra@Sun.COM conn_walk->idx = i; 325710946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 325810946SSangeeta.Misra@Sun.COM } 325910946SSangeeta.Misra@Sun.COM 326010946SSangeeta.Misra@Sun.COM static int 326110946SSangeeta.Misra@Sun.COM ilb_sticky_walk_init(mdb_walk_state_t *wsp) 326210946SSangeeta.Misra@Sun.COM { 326310946SSangeeta.Misra@Sun.COM int i; 326410946SSangeeta.Misra@Sun.COM ilb_walk_t *sticky_walk; 326510946SSangeeta.Misra@Sun.COM ilb_sticky_t *st = NULL; 326610946SSangeeta.Misra@Sun.COM 326710946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL) 326810946SSangeeta.Misra@Sun.COM return (WALK_ERR); 326910946SSangeeta.Misra@Sun.COM 327010946SSangeeta.Misra@Sun.COM sticky_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP); 327110946SSangeeta.Misra@Sun.COM if (mdb_vread(&sticky_walk->ilbs, sizeof (sticky_walk->ilbs), 327210946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) { 327310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr); 327410946SSangeeta.Misra@Sun.COM mdb_free(sticky_walk, sizeof (ilb_walk_t)); 327510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 327610946SSangeeta.Misra@Sun.COM } 327710946SSangeeta.Misra@Sun.COM 327810946SSangeeta.Misra@Sun.COM if (sticky_walk->ilbs.ilbs_sticky_hash == NULL) { 327910946SSangeeta.Misra@Sun.COM mdb_free(sticky_walk, sizeof (ilb_walk_t)); 328010946SSangeeta.Misra@Sun.COM return (WALK_DONE); 328110946SSangeeta.Misra@Sun.COM } 328210946SSangeeta.Misra@Sun.COM 328310946SSangeeta.Misra@Sun.COM wsp->walk_data = sticky_walk; 328410946SSangeeta.Misra@Sun.COM for (i = 0; i < sticky_walk->ilbs.ilbs_sticky_hash_size; i++) { 328510946SSangeeta.Misra@Sun.COM list_t head; 328610946SSangeeta.Misra@Sun.COM char *khead; 328710946SSangeeta.Misra@Sun.COM 328810946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 328910946SSangeeta.Misra@Sun.COM khead = (char *)sticky_walk->ilbs.ilbs_sticky_hash + i * 329010946SSangeeta.Misra@Sun.COM sizeof (ilb_sticky_hash_t); 329110946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 329210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", 329310946SSangeeta.Misra@Sun.COM khead); 329410946SSangeeta.Misra@Sun.COM return (WALK_ERR); 329510946SSangeeta.Misra@Sun.COM } 329610946SSangeeta.Misra@Sun.COM 329710946SSangeeta.Misra@Sun.COM /* 329810946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need 329910946SSangeeta.Misra@Sun.COM * to compare list_next with the kernel address of the list 330010946SSangeeta.Misra@Sun.COM * head. So we need to calculate the address manually. 330110946SSangeeta.Misra@Sun.COM */ 330210946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 330310946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 330410946SSangeeta.Misra@Sun.COM st = list_object(&head, head.list_head.list_next); 330510946SSangeeta.Misra@Sun.COM break; 330610946SSangeeta.Misra@Sun.COM } 330710946SSangeeta.Misra@Sun.COM } 330810946SSangeeta.Misra@Sun.COM 330910946SSangeeta.Misra@Sun.COM if (st == NULL) 331010946SSangeeta.Misra@Sun.COM return (WALK_DONE); 331110946SSangeeta.Misra@Sun.COM 331210946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)st; 331310946SSangeeta.Misra@Sun.COM sticky_walk->idx = i; 331410946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 331510946SSangeeta.Misra@Sun.COM } 331610946SSangeeta.Misra@Sun.COM 331710946SSangeeta.Misra@Sun.COM static int 331810946SSangeeta.Misra@Sun.COM ilb_sticky_walk_step(mdb_walk_state_t *wsp) 331910946SSangeeta.Misra@Sun.COM { 332010946SSangeeta.Misra@Sun.COM int status; 332110946SSangeeta.Misra@Sun.COM ilb_sticky_t st, *st_next; 332210946SSangeeta.Misra@Sun.COM ilb_walk_t *sticky_walk; 332310946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs; 332410946SSangeeta.Misra@Sun.COM list_t head; 332510946SSangeeta.Misra@Sun.COM char *khead; 332610946SSangeeta.Misra@Sun.COM int i; 332710946SSangeeta.Misra@Sun.COM 332810946SSangeeta.Misra@Sun.COM if (mdb_vread(&st, sizeof (ilb_sticky_t), wsp->walk_addr) == -1) { 332910946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_sticky_t at %p", wsp->walk_addr); 333010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 333110946SSangeeta.Misra@Sun.COM } 333210946SSangeeta.Misra@Sun.COM 333310946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &st, wsp->walk_cbdata); 333410946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT) 333510946SSangeeta.Misra@Sun.COM return (status); 333610946SSangeeta.Misra@Sun.COM 333710946SSangeeta.Misra@Sun.COM sticky_walk = (ilb_walk_t *)wsp->walk_data; 333810946SSangeeta.Misra@Sun.COM ilbs = &sticky_walk->ilbs; 333910946SSangeeta.Misra@Sun.COM i = sticky_walk->idx; 334010946SSangeeta.Misra@Sun.COM 334110946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */ 334210946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_sticky_hash + i * sizeof (ilb_sticky_hash_t); 334310946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 334410946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", khead); 334510946SSangeeta.Misra@Sun.COM return (WALK_ERR); 334610946SSangeeta.Misra@Sun.COM } 334710946SSangeeta.Misra@Sun.COM 334810946SSangeeta.Misra@Sun.COM /* 334910946SSangeeta.Misra@Sun.COM * Check if there is still entry in the current list. 335010946SSangeeta.Misra@Sun.COM * 335110946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need to 335210946SSangeeta.Misra@Sun.COM * compare list_next with the kernel address of the list head. 335310946SSangeeta.Misra@Sun.COM * So we need to calculate the address manually. 335410946SSangeeta.Misra@Sun.COM */ 335510946SSangeeta.Misra@Sun.COM if ((char *)st.list.list_next != khead + offsetof(list_t, 335610946SSangeeta.Misra@Sun.COM list_head)) { 335710946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)list_object(&head, 335810946SSangeeta.Misra@Sun.COM st.list.list_next); 335910946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 336010946SSangeeta.Misra@Sun.COM } 336110946SSangeeta.Misra@Sun.COM 336210946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */ 336310946SSangeeta.Misra@Sun.COM st_next = NULL; 336410946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) { 336510946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_sticky_hash + i * 336610946SSangeeta.Misra@Sun.COM sizeof (ilb_sticky_hash_t); 336710946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) { 336810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", 336910946SSangeeta.Misra@Sun.COM khead); 337010946SSangeeta.Misra@Sun.COM return (WALK_ERR); 337110946SSangeeta.Misra@Sun.COM } 337210946SSangeeta.Misra@Sun.COM 337310946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead + 337410946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) { 337510946SSangeeta.Misra@Sun.COM st_next = list_object(&head, 337610946SSangeeta.Misra@Sun.COM head.list_head.list_next); 337710946SSangeeta.Misra@Sun.COM break; 337810946SSangeeta.Misra@Sun.COM } 337910946SSangeeta.Misra@Sun.COM } 338010946SSangeeta.Misra@Sun.COM 338110946SSangeeta.Misra@Sun.COM if (st_next == NULL) 338210946SSangeeta.Misra@Sun.COM return (WALK_DONE); 338310946SSangeeta.Misra@Sun.COM 338410946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)st_next; 338510946SSangeeta.Misra@Sun.COM sticky_walk->idx = i; 338610946SSangeeta.Misra@Sun.COM return (WALK_NEXT); 338710946SSangeeta.Misra@Sun.COM } 3388