10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52546Scarlsonj * Common Development and Distribution License (the "License").
62546Scarlsonj * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12175SKacheong.Poon@Sun.COM * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <sys/types.h>
260Sstevel@tonic-gate #include <sys/stropts.h>
270Sstevel@tonic-gate #include <sys/stream.h>
280Sstevel@tonic-gate #include <sys/socket.h>
290Sstevel@tonic-gate #include <sys/avl_impl.h>
309089SVasumathi.Sundaram@Sun.COM #include <net/if_types.h>
310Sstevel@tonic-gate #include <net/if.h>
320Sstevel@tonic-gate #include <net/route.h>
330Sstevel@tonic-gate #include <netinet/in.h>
340Sstevel@tonic-gate #include <netinet/ip6.h>
350Sstevel@tonic-gate #include <netinet/udp.h>
360Sstevel@tonic-gate #include <netinet/sctp.h>
370Sstevel@tonic-gate #include <inet/mib2.h>
380Sstevel@tonic-gate #include <inet/common.h>
390Sstevel@tonic-gate #include <inet/ip.h>
400Sstevel@tonic-gate #include <inet/ip_ire.h>
410Sstevel@tonic-gate #include <inet/ip6.h>
420Sstevel@tonic-gate #include <inet/ipclassifier.h>
430Sstevel@tonic-gate #include <inet/mi.h>
440Sstevel@tonic-gate #include <sys/squeue_impl.h>
455023Scarlsonj #include <sys/modhash_impl.h>
465940Ssowmini #include <inet/ip_ndp.h>
475940Ssowmini #include <inet/ip_if.h>
4810946SSangeeta.Misra@Sun.COM #include <ilb.h>
4910946SSangeeta.Misra@Sun.COM #include <ilb/ilb_impl.h>
5010946SSangeeta.Misra@Sun.COM #include <ilb/ilb_stack.h>
5110946SSangeeta.Misra@Sun.COM #include <ilb/ilb_nat.h>
5210946SSangeeta.Misra@Sun.COM #include <ilb/ilb_conn.h>
535940Ssowmini #include <sys/dlpi.h>
5411042SErik.Nordmark@Sun.COM #include <sys/zone.h>
550Sstevel@tonic-gate
560Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
570Sstevel@tonic-gate #include <mdb/mdb_ks.h>
580Sstevel@tonic-gate
590Sstevel@tonic-gate #define ADDR_WIDTH 11
605940Ssowmini #define L2MAXADDRSTRLEN 255
615940Ssowmini #define MAX_SAP_LEN 255
629089SVasumathi.Sundaram@Sun.COM #define DEFCOLS 80
630Sstevel@tonic-gate
640Sstevel@tonic-gate typedef struct {
650Sstevel@tonic-gate const char *bit_name; /* name of bit */
660Sstevel@tonic-gate const char *bit_descr; /* description of bit's purpose */
670Sstevel@tonic-gate } bitname_t;
680Sstevel@tonic-gate
690Sstevel@tonic-gate static const bitname_t squeue_states[] = {
700Sstevel@tonic-gate { "SQS_PROC", "being processed" },
710Sstevel@tonic-gate { "SQS_WORKER", "... by a worker thread" },
720Sstevel@tonic-gate { "SQS_ENTER", "... by an squeue_enter() thread" },
730Sstevel@tonic-gate { "SQS_FAST", "... in fast-path mode" },
740Sstevel@tonic-gate { "SQS_USER", "A non interrupt user" },
750Sstevel@tonic-gate { "SQS_BOUND", "worker thread bound to CPU" },
760Sstevel@tonic-gate { "SQS_PROFILE", "profiling enabled" },
770Sstevel@tonic-gate { "SQS_REENTER", "re-entered thred" },
780Sstevel@tonic-gate { NULL }
790Sstevel@tonic-gate };
800Sstevel@tonic-gate
810Sstevel@tonic-gate typedef struct illif_walk_data {
820Sstevel@tonic-gate ill_g_head_t ill_g_heads[MAX_G_HEADS];
830Sstevel@tonic-gate int ill_list;
840Sstevel@tonic-gate ill_if_t ill_if;
850Sstevel@tonic-gate } illif_walk_data_t;
860Sstevel@tonic-gate
8711042SErik.Nordmark@Sun.COM typedef struct ncec_walk_data_s {
8811042SErik.Nordmark@Sun.COM struct ndp_g_s ncec_ip_ndp;
8911042SErik.Nordmark@Sun.COM int ncec_hash_tbl_index;
9011042SErik.Nordmark@Sun.COM ncec_t ncec;
9111042SErik.Nordmark@Sun.COM } ncec_walk_data_t;
9211042SErik.Nordmark@Sun.COM
9311042SErik.Nordmark@Sun.COM typedef struct ncec_cbdata_s {
9411042SErik.Nordmark@Sun.COM uintptr_t ncec_addr;
9511042SErik.Nordmark@Sun.COM int ncec_ipversion;
9611042SErik.Nordmark@Sun.COM } ncec_cbdata_t;
975940Ssowmini
985940Ssowmini typedef struct nce_cbdata_s {
9911042SErik.Nordmark@Sun.COM int nce_ipversion;
10011042SErik.Nordmark@Sun.COM char nce_ill_name[LIFNAMSIZ];
1015940Ssowmini } nce_cbdata_t;
1025940Ssowmini
1035940Ssowmini typedef struct ire_cbdata_s {
1045940Ssowmini int ire_ipversion;
1055940Ssowmini boolean_t verbose;
1065940Ssowmini } ire_cbdata_t;
1075940Ssowmini
10811042SErik.Nordmark@Sun.COM typedef struct zi_cbdata_s {
10911042SErik.Nordmark@Sun.COM const char *zone_name;
11011042SErik.Nordmark@Sun.COM ip_stack_t *ipst;
11111042SErik.Nordmark@Sun.COM boolean_t shared_ip_zone;
11211042SErik.Nordmark@Sun.COM } zi_cbdata_t;
11311042SErik.Nordmark@Sun.COM
1145023Scarlsonj typedef struct th_walk_data {
1155023Scarlsonj uint_t thw_non_zero_only;
1165023Scarlsonj boolean_t thw_match;
1175023Scarlsonj uintptr_t thw_matchkey;
1185023Scarlsonj uintptr_t thw_ipst;
1195023Scarlsonj clock_t thw_lbolt;
1205023Scarlsonj } th_walk_data_t;
1215023Scarlsonj
1229089SVasumathi.Sundaram@Sun.COM typedef struct ipcl_hash_walk_data_s {
1239089SVasumathi.Sundaram@Sun.COM conn_t *conn;
1249089SVasumathi.Sundaram@Sun.COM int connf_tbl_index;
1259089SVasumathi.Sundaram@Sun.COM uintptr_t hash_tbl;
1269089SVasumathi.Sundaram@Sun.COM int hash_tbl_size;
1279089SVasumathi.Sundaram@Sun.COM } ipcl_hash_walk_data_t;
1289089SVasumathi.Sundaram@Sun.COM
1299089SVasumathi.Sundaram@Sun.COM typedef struct ill_walk_data_s {
1309089SVasumathi.Sundaram@Sun.COM ill_t ill;
1319089SVasumathi.Sundaram@Sun.COM } ill_walk_data_t;
1329089SVasumathi.Sundaram@Sun.COM
1339089SVasumathi.Sundaram@Sun.COM typedef struct ill_cbdata_s {
1349089SVasumathi.Sundaram@Sun.COM uintptr_t ill_addr;
1359089SVasumathi.Sundaram@Sun.COM int ill_ipversion;
13611042SErik.Nordmark@Sun.COM ip_stack_t *ill_ipst;
1379089SVasumathi.Sundaram@Sun.COM boolean_t verbose;
1389089SVasumathi.Sundaram@Sun.COM } ill_cbdata_t;
1399089SVasumathi.Sundaram@Sun.COM
1409089SVasumathi.Sundaram@Sun.COM typedef struct ipif_walk_data_s {
1419089SVasumathi.Sundaram@Sun.COM ipif_t ipif;
1429089SVasumathi.Sundaram@Sun.COM } ipif_walk_data_t;
1439089SVasumathi.Sundaram@Sun.COM
1449089SVasumathi.Sundaram@Sun.COM typedef struct ipif_cbdata_s {
1459089SVasumathi.Sundaram@Sun.COM ill_t ill;
1469089SVasumathi.Sundaram@Sun.COM int ipif_ipversion;
1479089SVasumathi.Sundaram@Sun.COM boolean_t verbose;
1489089SVasumathi.Sundaram@Sun.COM } ipif_cbdata_t;
1499089SVasumathi.Sundaram@Sun.COM
1509089SVasumathi.Sundaram@Sun.COM typedef struct hash_walk_arg_s {
1519089SVasumathi.Sundaram@Sun.COM off_t tbl_off;
1529089SVasumathi.Sundaram@Sun.COM off_t size_off;
1539089SVasumathi.Sundaram@Sun.COM } hash_walk_arg_t;
1549089SVasumathi.Sundaram@Sun.COM
1559089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t udp_hash_arg = {
1569089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_udp_fanout),
1579089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_udp_fanout_size)
1589089SVasumathi.Sundaram@Sun.COM };
1599089SVasumathi.Sundaram@Sun.COM
1609089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t conn_hash_arg = {
1619089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_conn_fanout),
1629089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_conn_fanout_size)
1639089SVasumathi.Sundaram@Sun.COM };
1649089SVasumathi.Sundaram@Sun.COM
1659089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t bind_hash_arg = {
1669089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_bind_fanout),
1679089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_bind_fanout_size)
1689089SVasumathi.Sundaram@Sun.COM };
1699089SVasumathi.Sundaram@Sun.COM
1709089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t proto_hash_arg = {
17111042SErik.Nordmark@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4),
1729089SVasumathi.Sundaram@Sun.COM 0
1739089SVasumathi.Sundaram@Sun.COM };
1749089SVasumathi.Sundaram@Sun.COM
1759089SVasumathi.Sundaram@Sun.COM static hash_walk_arg_t proto_v6_hash_arg = {
1769089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6),
1779089SVasumathi.Sundaram@Sun.COM 0
1789089SVasumathi.Sundaram@Sun.COM };
1799089SVasumathi.Sundaram@Sun.COM
1809089SVasumathi.Sundaram@Sun.COM typedef struct ip_list_walk_data_s {
1819089SVasumathi.Sundaram@Sun.COM off_t nextoff;
1829089SVasumathi.Sundaram@Sun.COM } ip_list_walk_data_t;
1839089SVasumathi.Sundaram@Sun.COM
1849089SVasumathi.Sundaram@Sun.COM typedef struct ip_list_walk_arg_s {
1859089SVasumathi.Sundaram@Sun.COM off_t off;
1869089SVasumathi.Sundaram@Sun.COM size_t size;
1879089SVasumathi.Sundaram@Sun.COM off_t nextp_off;
1889089SVasumathi.Sundaram@Sun.COM } ip_list_walk_arg_t;
1899089SVasumathi.Sundaram@Sun.COM
1909089SVasumathi.Sundaram@Sun.COM static ip_list_walk_arg_t ipif_walk_arg = {
1919089SVasumathi.Sundaram@Sun.COM OFFSETOF(ill_t, ill_ipif),
1929089SVasumathi.Sundaram@Sun.COM sizeof (ipif_t),
1939089SVasumathi.Sundaram@Sun.COM OFFSETOF(ipif_t, ipif_next)
1949089SVasumathi.Sundaram@Sun.COM };
1959089SVasumathi.Sundaram@Sun.COM
1969089SVasumathi.Sundaram@Sun.COM static ip_list_walk_arg_t srcid_walk_arg = {
1979089SVasumathi.Sundaram@Sun.COM OFFSETOF(ip_stack_t, ips_srcid_head),
1989089SVasumathi.Sundaram@Sun.COM sizeof (srcid_map_t),
1999089SVasumathi.Sundaram@Sun.COM OFFSETOF(srcid_map_t, sm_next)
2009089SVasumathi.Sundaram@Sun.COM };
2019089SVasumathi.Sundaram@Sun.COM
2020Sstevel@tonic-gate static int iphdr(uintptr_t, uint_t, int, const mdb_arg_t *);
2030Sstevel@tonic-gate static int ip6hdr(uintptr_t, uint_t, int, const mdb_arg_t *);
2040Sstevel@tonic-gate
2059089SVasumathi.Sundaram@Sun.COM static int ill(uintptr_t, uint_t, int, const mdb_arg_t *);
2069089SVasumathi.Sundaram@Sun.COM static void ill_help(void);
2079089SVasumathi.Sundaram@Sun.COM static int ill_walk_init(mdb_walk_state_t *);
2089089SVasumathi.Sundaram@Sun.COM static int ill_walk_step(mdb_walk_state_t *);
2099089SVasumathi.Sundaram@Sun.COM static int ill_format(uintptr_t, const void *, void *);
2109089SVasumathi.Sundaram@Sun.COM static void ill_header(boolean_t);
2119089SVasumathi.Sundaram@Sun.COM
2129089SVasumathi.Sundaram@Sun.COM static int ipif(uintptr_t, uint_t, int, const mdb_arg_t *);
2139089SVasumathi.Sundaram@Sun.COM static void ipif_help(void);
2149089SVasumathi.Sundaram@Sun.COM static int ipif_walk_init(mdb_walk_state_t *);
2159089SVasumathi.Sundaram@Sun.COM static int ipif_walk_step(mdb_walk_state_t *);
2169089SVasumathi.Sundaram@Sun.COM static int ipif_format(uintptr_t, const void *, void *);
2179089SVasumathi.Sundaram@Sun.COM static void ipif_header(boolean_t);
2189089SVasumathi.Sundaram@Sun.COM
2199089SVasumathi.Sundaram@Sun.COM static int ip_list_walk_init(mdb_walk_state_t *);
2209089SVasumathi.Sundaram@Sun.COM static int ip_list_walk_step(mdb_walk_state_t *);
2219089SVasumathi.Sundaram@Sun.COM static void ip_list_walk_fini(mdb_walk_state_t *);
2229089SVasumathi.Sundaram@Sun.COM static int srcid_walk_step(mdb_walk_state_t *);
2239089SVasumathi.Sundaram@Sun.COM
2245940Ssowmini static int ire_format(uintptr_t addr, const void *, void *);
22511042SErik.Nordmark@Sun.COM static int ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion);
22611042SErik.Nordmark@Sun.COM static int ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv);
22711042SErik.Nordmark@Sun.COM static int ncec_walk_step(mdb_walk_state_t *wsp);
22811042SErik.Nordmark@Sun.COM static int ncec_stack_walk_init(mdb_walk_state_t *wsp);
22911042SErik.Nordmark@Sun.COM static int ncec_stack_walk_step(mdb_walk_state_t *wsp);
23011042SErik.Nordmark@Sun.COM static void ncec_stack_walk_fini(mdb_walk_state_t *wsp);
23111042SErik.Nordmark@Sun.COM static int ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw,
23211042SErik.Nordmark@Sun.COM ncec_cbdata_t *id);
23311042SErik.Nordmark@Sun.COM static char *nce_l2_addr(const nce_t *, const ill_t *);
2343448Sdh155122
2359089SVasumathi.Sundaram@Sun.COM static int ipcl_hash_walk_init(mdb_walk_state_t *);
2369089SVasumathi.Sundaram@Sun.COM static int ipcl_hash_walk_step(mdb_walk_state_t *);
2379089SVasumathi.Sundaram@Sun.COM static void ipcl_hash_walk_fini(mdb_walk_state_t *);
2389089SVasumathi.Sundaram@Sun.COM
2399089SVasumathi.Sundaram@Sun.COM static int conn_status_walk_step(mdb_walk_state_t *);
2409089SVasumathi.Sundaram@Sun.COM static int conn_status(uintptr_t, uint_t, int, const mdb_arg_t *);
2419089SVasumathi.Sundaram@Sun.COM static void conn_status_help(void);
2429089SVasumathi.Sundaram@Sun.COM
2439089SVasumathi.Sundaram@Sun.COM static int srcid_status(uintptr_t, uint_t, int, const mdb_arg_t *);
2449089SVasumathi.Sundaram@Sun.COM
24510946SSangeeta.Misra@Sun.COM static int ilb_stacks_walk_step(mdb_walk_state_t *);
24610946SSangeeta.Misra@Sun.COM static int ilb_rules_walk_init(mdb_walk_state_t *);
24710946SSangeeta.Misra@Sun.COM static int ilb_rules_walk_step(mdb_walk_state_t *);
24810946SSangeeta.Misra@Sun.COM static int ilb_servers_walk_init(mdb_walk_state_t *);
24910946SSangeeta.Misra@Sun.COM static int ilb_servers_walk_step(mdb_walk_state_t *);
25010946SSangeeta.Misra@Sun.COM static int ilb_nat_src_walk_init(mdb_walk_state_t *);
25110946SSangeeta.Misra@Sun.COM static int ilb_nat_src_walk_step(mdb_walk_state_t *);
25210946SSangeeta.Misra@Sun.COM static int ilb_conn_walk_init(mdb_walk_state_t *);
25310946SSangeeta.Misra@Sun.COM static int ilb_conn_walk_step(mdb_walk_state_t *);
25410946SSangeeta.Misra@Sun.COM static int ilb_sticky_walk_init(mdb_walk_state_t *);
25510946SSangeeta.Misra@Sun.COM static int ilb_sticky_walk_step(mdb_walk_state_t *);
25610946SSangeeta.Misra@Sun.COM static void ilb_common_walk_fini(mdb_walk_state_t *);
25710946SSangeeta.Misra@Sun.COM
2583448Sdh155122 /*
2593448Sdh155122 * Given the kernel address of an ip_stack_t, return the stackid
2603448Sdh155122 */
2613448Sdh155122 static int
ips_to_stackid(uintptr_t kaddr)2623448Sdh155122 ips_to_stackid(uintptr_t kaddr)
2633448Sdh155122 {
2643448Sdh155122 ip_stack_t ipss;
2653448Sdh155122 netstack_t nss;
2663448Sdh155122
2673448Sdh155122 if (mdb_vread(&ipss, sizeof (ipss), kaddr) == -1) {
2683448Sdh155122 mdb_warn("failed to read ip_stack_t %p", kaddr);
2693448Sdh155122 return (0);
2703448Sdh155122 }
2713448Sdh155122 kaddr = (uintptr_t)ipss.ips_netstack;
2723448Sdh155122 if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) {
2733448Sdh155122 mdb_warn("failed to read netstack_t %p", kaddr);
2743448Sdh155122 return (0);
2753448Sdh155122 }
2763448Sdh155122 return (nss.netstack_stackid);
2773448Sdh155122 }
2783448Sdh155122
27911042SErik.Nordmark@Sun.COM /* ARGSUSED */
28011042SErik.Nordmark@Sun.COM static int
zone_to_ips_cb(uintptr_t addr,const void * zi_arg,void * zi_cb_arg)28111042SErik.Nordmark@Sun.COM zone_to_ips_cb(uintptr_t addr, const void *zi_arg, void *zi_cb_arg)
28211042SErik.Nordmark@Sun.COM {
28311042SErik.Nordmark@Sun.COM zi_cbdata_t *zi_cb = zi_cb_arg;
28411042SErik.Nordmark@Sun.COM zone_t zone;
28511042SErik.Nordmark@Sun.COM char zone_name[ZONENAME_MAX];
28611042SErik.Nordmark@Sun.COM netstack_t ns;
28711042SErik.Nordmark@Sun.COM
28811042SErik.Nordmark@Sun.COM if (mdb_vread(&zone, sizeof (zone_t), addr) == -1) {
28911042SErik.Nordmark@Sun.COM mdb_warn("can't read zone at %p", addr);
29011042SErik.Nordmark@Sun.COM return (WALK_ERR);
29111042SErik.Nordmark@Sun.COM }
29211042SErik.Nordmark@Sun.COM
29311042SErik.Nordmark@Sun.COM (void) mdb_readstr(zone_name, ZONENAME_MAX, (uintptr_t)zone.zone_name);
29411042SErik.Nordmark@Sun.COM
29511042SErik.Nordmark@Sun.COM if (strcmp(zi_cb->zone_name, zone_name) != 0)
29611042SErik.Nordmark@Sun.COM return (WALK_NEXT);
29711042SErik.Nordmark@Sun.COM
29811042SErik.Nordmark@Sun.COM zi_cb->shared_ip_zone = (!(zone.zone_flags & ZF_NET_EXCL) &&
29911042SErik.Nordmark@Sun.COM (strcmp(zone_name, "global") != 0));
30011042SErik.Nordmark@Sun.COM
30111042SErik.Nordmark@Sun.COM if (mdb_vread(&ns, sizeof (netstack_t), (uintptr_t)zone.zone_netstack)
30211042SErik.Nordmark@Sun.COM == -1) {
30311042SErik.Nordmark@Sun.COM mdb_warn("can't read netstack at %p", zone.zone_netstack);
30411042SErik.Nordmark@Sun.COM return (WALK_ERR);
30511042SErik.Nordmark@Sun.COM }
30611042SErik.Nordmark@Sun.COM
30711042SErik.Nordmark@Sun.COM zi_cb->ipst = ns.netstack_ip;
30811042SErik.Nordmark@Sun.COM return (WALK_DONE);
30911042SErik.Nordmark@Sun.COM }
31011042SErik.Nordmark@Sun.COM
31111042SErik.Nordmark@Sun.COM static ip_stack_t *
zone_to_ips(const char * zone_name)31211042SErik.Nordmark@Sun.COM zone_to_ips(const char *zone_name)
31311042SErik.Nordmark@Sun.COM {
31411042SErik.Nordmark@Sun.COM zi_cbdata_t zi_cb;
31511042SErik.Nordmark@Sun.COM
31611042SErik.Nordmark@Sun.COM if (zone_name == NULL)
31711042SErik.Nordmark@Sun.COM return (NULL);
31811042SErik.Nordmark@Sun.COM
31911042SErik.Nordmark@Sun.COM zi_cb.zone_name = zone_name;
32011042SErik.Nordmark@Sun.COM zi_cb.ipst = NULL;
32111042SErik.Nordmark@Sun.COM zi_cb.shared_ip_zone = B_FALSE;
32211042SErik.Nordmark@Sun.COM
32311042SErik.Nordmark@Sun.COM if (mdb_walk("zone", (mdb_walk_cb_t)zone_to_ips_cb, &zi_cb) == -1) {
32411042SErik.Nordmark@Sun.COM mdb_warn("failed to walk zone");
32511042SErik.Nordmark@Sun.COM return (NULL);
32611042SErik.Nordmark@Sun.COM }
32711042SErik.Nordmark@Sun.COM
32811042SErik.Nordmark@Sun.COM if (zi_cb.shared_ip_zone) {
32911042SErik.Nordmark@Sun.COM mdb_warn("%s is a Shared-IP zone, try '-s global' instead\n",
33011042SErik.Nordmark@Sun.COM zone_name);
33111042SErik.Nordmark@Sun.COM return (NULL);
33211042SErik.Nordmark@Sun.COM }
33311042SErik.Nordmark@Sun.COM
33411042SErik.Nordmark@Sun.COM if (zi_cb.ipst == NULL) {
33511042SErik.Nordmark@Sun.COM mdb_warn("failed to find zone %s\n", zone_name);
33611042SErik.Nordmark@Sun.COM return (NULL);
33711042SErik.Nordmark@Sun.COM }
33811042SErik.Nordmark@Sun.COM
33911042SErik.Nordmark@Sun.COM return (zi_cb.ipst);
34011042SErik.Nordmark@Sun.COM }
34111042SErik.Nordmark@Sun.COM
34211754SKacheong.Poon@Sun.COM /*
34311754SKacheong.Poon@Sun.COM * Generic network stack walker initialization function. It is used by all
34411754SKacheong.Poon@Sun.COM * other netwrok stack walkers.
34511754SKacheong.Poon@Sun.COM */
3460Sstevel@tonic-gate int
ns_walk_init(mdb_walk_state_t * wsp)34711754SKacheong.Poon@Sun.COM ns_walk_init(mdb_walk_state_t *wsp)
3483448Sdh155122 {
3493448Sdh155122 if (mdb_layered_walk("netstack", wsp) == -1) {
3503448Sdh155122 mdb_warn("can't walk 'netstack'");
3513448Sdh155122 return (WALK_ERR);
3523448Sdh155122 }
3533448Sdh155122 return (WALK_NEXT);
3543448Sdh155122 }
3553448Sdh155122
35611754SKacheong.Poon@Sun.COM /*
35711754SKacheong.Poon@Sun.COM * Generic network stack walker stepping function. It is used by all other
35811754SKacheong.Poon@Sun.COM * network stack walkers. The which parameter differentiates the different
35911754SKacheong.Poon@Sun.COM * walkers.
36011754SKacheong.Poon@Sun.COM */
3613448Sdh155122 int
ns_walk_step(mdb_walk_state_t * wsp,int which)36211754SKacheong.Poon@Sun.COM ns_walk_step(mdb_walk_state_t *wsp, int which)
3633448Sdh155122 {
3643448Sdh155122 uintptr_t kaddr;
3653448Sdh155122 netstack_t nss;
3663448Sdh155122
3673448Sdh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
3683448Sdh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr);
3693448Sdh155122 return (WALK_ERR);
3703448Sdh155122 }
37111754SKacheong.Poon@Sun.COM kaddr = (uintptr_t)nss.netstack_modules[which];
3723448Sdh155122
3733448Sdh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
3743448Sdh155122 }
3753448Sdh155122
37611754SKacheong.Poon@Sun.COM /*
37711754SKacheong.Poon@Sun.COM * IP network stack walker stepping function.
37811754SKacheong.Poon@Sun.COM */
37911754SKacheong.Poon@Sun.COM int
ip_stacks_walk_step(mdb_walk_state_t * wsp)38011754SKacheong.Poon@Sun.COM ip_stacks_walk_step(mdb_walk_state_t *wsp)
38111754SKacheong.Poon@Sun.COM {
38211754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_IP));
38311754SKacheong.Poon@Sun.COM }
38411754SKacheong.Poon@Sun.COM
38511754SKacheong.Poon@Sun.COM /*
38611754SKacheong.Poon@Sun.COM * TCP network stack walker stepping function.
38711754SKacheong.Poon@Sun.COM */
38811754SKacheong.Poon@Sun.COM int
tcp_stacks_walk_step(mdb_walk_state_t * wsp)38911754SKacheong.Poon@Sun.COM tcp_stacks_walk_step(mdb_walk_state_t *wsp)
39011754SKacheong.Poon@Sun.COM {
39111754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_TCP));
39211754SKacheong.Poon@Sun.COM }
39311754SKacheong.Poon@Sun.COM
39411754SKacheong.Poon@Sun.COM /*
39511754SKacheong.Poon@Sun.COM * SCTP network stack walker stepping function.
39611754SKacheong.Poon@Sun.COM */
39711754SKacheong.Poon@Sun.COM int
sctp_stacks_walk_step(mdb_walk_state_t * wsp)39811754SKacheong.Poon@Sun.COM sctp_stacks_walk_step(mdb_walk_state_t *wsp)
39911754SKacheong.Poon@Sun.COM {
40011754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_SCTP));
40111754SKacheong.Poon@Sun.COM }
40211754SKacheong.Poon@Sun.COM
40311754SKacheong.Poon@Sun.COM /*
40411754SKacheong.Poon@Sun.COM * UDP network stack walker stepping function.
40511754SKacheong.Poon@Sun.COM */
40611754SKacheong.Poon@Sun.COM int
udp_stacks_walk_step(mdb_walk_state_t * wsp)40711754SKacheong.Poon@Sun.COM udp_stacks_walk_step(mdb_walk_state_t *wsp)
40811754SKacheong.Poon@Sun.COM {
40911754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_UDP));
41011754SKacheong.Poon@Sun.COM }
41111754SKacheong.Poon@Sun.COM
41211754SKacheong.Poon@Sun.COM /*
41311754SKacheong.Poon@Sun.COM * Initialization function for the per CPU TCP stats counter walker of a given
41411754SKacheong.Poon@Sun.COM * TCP stack.
41511754SKacheong.Poon@Sun.COM */
41611754SKacheong.Poon@Sun.COM int
tcps_sc_walk_init(mdb_walk_state_t * wsp)41711754SKacheong.Poon@Sun.COM tcps_sc_walk_init(mdb_walk_state_t *wsp)
41811754SKacheong.Poon@Sun.COM {
41911754SKacheong.Poon@Sun.COM tcp_stack_t tcps;
42011754SKacheong.Poon@Sun.COM
42111754SKacheong.Poon@Sun.COM if (wsp->walk_addr == NULL)
42211754SKacheong.Poon@Sun.COM return (WALK_ERR);
42311754SKacheong.Poon@Sun.COM
42411754SKacheong.Poon@Sun.COM if (mdb_vread(&tcps, sizeof (tcps), wsp->walk_addr) == -1) {
42511754SKacheong.Poon@Sun.COM mdb_warn("failed to read tcp_stack_t at %p", wsp->walk_addr);
42611754SKacheong.Poon@Sun.COM return (WALK_ERR);
42711754SKacheong.Poon@Sun.COM }
42811754SKacheong.Poon@Sun.COM if (tcps.tcps_sc_cnt == 0)
42911754SKacheong.Poon@Sun.COM return (WALK_DONE);
43011754SKacheong.Poon@Sun.COM
43111754SKacheong.Poon@Sun.COM /*
43211754SKacheong.Poon@Sun.COM * Store the tcp_stack_t pointer in walk_data. The stepping function
43311754SKacheong.Poon@Sun.COM * used it to calculate if the end of the counter has reached.
43411754SKacheong.Poon@Sun.COM */
43511754SKacheong.Poon@Sun.COM wsp->walk_data = (void *)wsp->walk_addr;
43611754SKacheong.Poon@Sun.COM wsp->walk_addr = (uintptr_t)tcps.tcps_sc;
43711754SKacheong.Poon@Sun.COM return (WALK_NEXT);
43811754SKacheong.Poon@Sun.COM }
43911754SKacheong.Poon@Sun.COM
44011754SKacheong.Poon@Sun.COM /*
44111754SKacheong.Poon@Sun.COM * Stepping function for the per CPU TCP stats counterwalker.
44211754SKacheong.Poon@Sun.COM */
44311754SKacheong.Poon@Sun.COM int
tcps_sc_walk_step(mdb_walk_state_t * wsp)44411754SKacheong.Poon@Sun.COM tcps_sc_walk_step(mdb_walk_state_t *wsp)
44511754SKacheong.Poon@Sun.COM {
44611754SKacheong.Poon@Sun.COM int status;
44711754SKacheong.Poon@Sun.COM tcp_stack_t tcps;
44811754SKacheong.Poon@Sun.COM tcp_stats_cpu_t *stats;
44911754SKacheong.Poon@Sun.COM char *next, *end;
45011754SKacheong.Poon@Sun.COM
45111754SKacheong.Poon@Sun.COM if (mdb_vread(&tcps, sizeof (tcps), (uintptr_t)wsp->walk_data) == -1) {
45211754SKacheong.Poon@Sun.COM mdb_warn("failed to read tcp_stack_t at %p", wsp->walk_addr);
45311754SKacheong.Poon@Sun.COM return (WALK_ERR);
45411754SKacheong.Poon@Sun.COM }
45511754SKacheong.Poon@Sun.COM if (mdb_vread(&stats, sizeof (stats), wsp->walk_addr) == -1) {
45611754SKacheong.Poon@Sun.COM mdb_warn("failed ot read tcp_stats_cpu_t at %p",
45711754SKacheong.Poon@Sun.COM wsp->walk_addr);
45811754SKacheong.Poon@Sun.COM return (WALK_ERR);
45911754SKacheong.Poon@Sun.COM }
46011754SKacheong.Poon@Sun.COM status = wsp->walk_callback((uintptr_t)stats, &stats, wsp->walk_cbdata);
46111754SKacheong.Poon@Sun.COM if (status != WALK_NEXT)
46211754SKacheong.Poon@Sun.COM return (status);
46311754SKacheong.Poon@Sun.COM
46411754SKacheong.Poon@Sun.COM next = (char *)wsp->walk_addr + sizeof (tcp_stats_cpu_t *);
46511754SKacheong.Poon@Sun.COM end = (char *)tcps.tcps_sc + tcps.tcps_sc_cnt *
46611754SKacheong.Poon@Sun.COM sizeof (tcp_stats_cpu_t *);
46711754SKacheong.Poon@Sun.COM if (next >= end)
46811754SKacheong.Poon@Sun.COM return (WALK_DONE);
46911754SKacheong.Poon@Sun.COM wsp->walk_addr = (uintptr_t)next;
47011754SKacheong.Poon@Sun.COM return (WALK_NEXT);
47111754SKacheong.Poon@Sun.COM }
47211754SKacheong.Poon@Sun.COM
4735023Scarlsonj int
th_hash_walk_init(mdb_walk_state_t * wsp)4745023Scarlsonj th_hash_walk_init(mdb_walk_state_t *wsp)
4755023Scarlsonj {
4765023Scarlsonj GElf_Sym sym;
4775023Scarlsonj list_node_t *next;
4785023Scarlsonj
4795023Scarlsonj if (wsp->walk_addr == NULL) {
4805023Scarlsonj if (mdb_lookup_by_obj("ip", "ip_thread_list", &sym) == 0) {
4815023Scarlsonj wsp->walk_addr = sym.st_value;
4825023Scarlsonj } else {
4835023Scarlsonj mdb_warn("unable to locate ip_thread_list\n");
4845023Scarlsonj return (WALK_ERR);
4855023Scarlsonj }
4865023Scarlsonj }
4875023Scarlsonj
4885023Scarlsonj if (mdb_vread(&next, sizeof (next),
4895023Scarlsonj wsp->walk_addr + offsetof(list_t, list_head) +
4905023Scarlsonj offsetof(list_node_t, list_next)) == -1 ||
4915023Scarlsonj next == NULL) {
4925023Scarlsonj mdb_warn("non-DEBUG image; cannot walk th_hash list\n");
4935023Scarlsonj return (WALK_ERR);
4945023Scarlsonj }
4955023Scarlsonj
4965023Scarlsonj if (mdb_layered_walk("list", wsp) == -1) {
4975023Scarlsonj mdb_warn("can't walk 'list'");
4985023Scarlsonj return (WALK_ERR);
4995023Scarlsonj } else {
5005023Scarlsonj return (WALK_NEXT);
5015023Scarlsonj }
5025023Scarlsonj }
5035023Scarlsonj
5045023Scarlsonj int
th_hash_walk_step(mdb_walk_state_t * wsp)5055023Scarlsonj th_hash_walk_step(mdb_walk_state_t *wsp)
5065023Scarlsonj {
5075023Scarlsonj return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
5085023Scarlsonj wsp->walk_cbdata));
5095023Scarlsonj }
5105023Scarlsonj
5113448Sdh155122 /*
5123448Sdh155122 * Called with walk_addr being the address of ips_ill_g_heads
5133448Sdh155122 */
5143448Sdh155122 int
illif_stack_walk_init(mdb_walk_state_t * wsp)5153448Sdh155122 illif_stack_walk_init(mdb_walk_state_t *wsp)
5160Sstevel@tonic-gate {
5170Sstevel@tonic-gate illif_walk_data_t *iw;
5180Sstevel@tonic-gate
5193448Sdh155122 if (wsp->walk_addr == NULL) {
5203448Sdh155122 mdb_warn("illif_stack supports only local walks\n");
5210Sstevel@tonic-gate return (WALK_ERR);
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate iw = mdb_alloc(sizeof (illif_walk_data_t), UM_SLEEP);
5250Sstevel@tonic-gate
5263448Sdh155122 if (mdb_vread(iw->ill_g_heads, MAX_G_HEADS * sizeof (ill_g_head_t),
5273448Sdh155122 wsp->walk_addr) == -1) {
5283448Sdh155122 mdb_warn("failed to read 'ips_ill_g_heads' at %p",
5293448Sdh155122 wsp->walk_addr);
5300Sstevel@tonic-gate mdb_free(iw, sizeof (illif_walk_data_t));
5310Sstevel@tonic-gate return (WALK_ERR);
5320Sstevel@tonic-gate }
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate iw->ill_list = 0;
5353448Sdh155122 wsp->walk_addr = (uintptr_t)iw->ill_g_heads[0].ill_g_list_head;
5360Sstevel@tonic-gate wsp->walk_data = iw;
5370Sstevel@tonic-gate
5380Sstevel@tonic-gate return (WALK_NEXT);
5390Sstevel@tonic-gate }
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate int
illif_stack_walk_step(mdb_walk_state_t * wsp)5423448Sdh155122 illif_stack_walk_step(mdb_walk_state_t *wsp)
5430Sstevel@tonic-gate {
5440Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr;
5450Sstevel@tonic-gate illif_walk_data_t *iw = wsp->walk_data;
5460Sstevel@tonic-gate int list = iw->ill_list;
5470Sstevel@tonic-gate
5480Sstevel@tonic-gate if (mdb_vread(&iw->ill_if, sizeof (ill_if_t), addr) == -1) {
5490Sstevel@tonic-gate mdb_warn("failed to read ill_if_t at %p", addr);
5500Sstevel@tonic-gate return (WALK_ERR);
5510Sstevel@tonic-gate }
5520Sstevel@tonic-gate
5530Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)iw->ill_if.illif_next;
5540Sstevel@tonic-gate
5553448Sdh155122 if (wsp->walk_addr ==
5563448Sdh155122 (uintptr_t)iw->ill_g_heads[list].ill_g_list_head) {
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate if (++list >= MAX_G_HEADS)
5590Sstevel@tonic-gate return (WALK_DONE);
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate iw->ill_list = list;
5623448Sdh155122 wsp->walk_addr =
5633448Sdh155122 (uintptr_t)iw->ill_g_heads[list].ill_g_list_head;
5640Sstevel@tonic-gate return (WALK_NEXT);
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate
5670Sstevel@tonic-gate return (wsp->walk_callback(addr, iw, wsp->walk_cbdata));
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate void
illif_stack_walk_fini(mdb_walk_state_t * wsp)5713448Sdh155122 illif_stack_walk_fini(mdb_walk_state_t *wsp)
5720Sstevel@tonic-gate {
5730Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (illif_walk_data_t));
5740Sstevel@tonic-gate }
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate typedef struct illif_cbdata {
5770Sstevel@tonic-gate uint_t ill_flags;
5780Sstevel@tonic-gate uintptr_t ill_addr;
5790Sstevel@tonic-gate int ill_printlist; /* list to be printed (MAX_G_HEADS for all) */
5800Sstevel@tonic-gate boolean_t ill_printed;
5810Sstevel@tonic-gate } illif_cbdata_t;
5820Sstevel@tonic-gate
5830Sstevel@tonic-gate static int
illif_cb(uintptr_t addr,const illif_walk_data_t * iw,illif_cbdata_t * id)5840Sstevel@tonic-gate illif_cb(uintptr_t addr, const illif_walk_data_t *iw, illif_cbdata_t *id)
5850Sstevel@tonic-gate {
5860Sstevel@tonic-gate const char *version;
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate if (id->ill_printlist < MAX_G_HEADS &&
5890Sstevel@tonic-gate id->ill_printlist != iw->ill_list)
5900Sstevel@tonic-gate return (WALK_NEXT);
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate if (id->ill_flags & DCMD_ADDRSPEC && id->ill_addr != addr)
5930Sstevel@tonic-gate return (WALK_NEXT);
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate if (id->ill_flags & DCMD_PIPE_OUT) {
5960Sstevel@tonic-gate mdb_printf("%p\n", addr);
5970Sstevel@tonic-gate return (WALK_NEXT);
5980Sstevel@tonic-gate }
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate switch (iw->ill_list) {
6010Sstevel@tonic-gate case IP_V4_G_HEAD: version = "v4"; break;
6020Sstevel@tonic-gate case IP_V6_G_HEAD: version = "v6"; break;
6030Sstevel@tonic-gate default: version = "??"; break;
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate
6060Sstevel@tonic-gate mdb_printf("%?p %2s %?p %10d %?p %s\n",
6070Sstevel@tonic-gate addr, version, addr + offsetof(ill_if_t, illif_avl_by_ppa),
6080Sstevel@tonic-gate iw->ill_if.illif_avl_by_ppa.avl_numnodes,
6090Sstevel@tonic-gate iw->ill_if.illif_ppa_arena, iw->ill_if.illif_name);
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate id->ill_printed = TRUE;
6120Sstevel@tonic-gate
6130Sstevel@tonic-gate return (WALK_NEXT);
6140Sstevel@tonic-gate }
6150Sstevel@tonic-gate
6160Sstevel@tonic-gate int
ip_stacks_common_walk_init(mdb_walk_state_t * wsp)6175940Ssowmini ip_stacks_common_walk_init(mdb_walk_state_t *wsp)
6183448Sdh155122 {
6193448Sdh155122 if (mdb_layered_walk("ip_stacks", wsp) == -1) {
6203448Sdh155122 mdb_warn("can't walk 'ip_stacks'");
6213448Sdh155122 return (WALK_ERR);
6223448Sdh155122 }
6233448Sdh155122
6243448Sdh155122 return (WALK_NEXT);
6253448Sdh155122 }
6263448Sdh155122
6273448Sdh155122 int
illif_walk_step(mdb_walk_state_t * wsp)6283448Sdh155122 illif_walk_step(mdb_walk_state_t *wsp)
6293448Sdh155122 {
6303448Sdh155122 uintptr_t kaddr;
6313448Sdh155122
6323448Sdh155122 kaddr = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ill_g_heads);
6333448Sdh155122
6343448Sdh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) {
6353448Sdh155122 mdb_warn("can't read ips_ip_cache_table at %p", kaddr);
6363448Sdh155122 return (WALK_ERR);
6373448Sdh155122 }
6383448Sdh155122
6393448Sdh155122 if (mdb_pwalk("illif_stack", wsp->walk_callback,
6405023Scarlsonj wsp->walk_cbdata, kaddr) == -1) {
6413448Sdh155122 mdb_warn("couldn't walk 'illif_stack' for ips_ill_g_heads %p",
6423448Sdh155122 kaddr);
6433448Sdh155122 return (WALK_ERR);
6443448Sdh155122 }
6453448Sdh155122 return (WALK_NEXT);
6463448Sdh155122 }
6473448Sdh155122
6483448Sdh155122 int
illif(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6490Sstevel@tonic-gate illif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6500Sstevel@tonic-gate {
6510Sstevel@tonic-gate illif_cbdata_t id;
6520Sstevel@tonic-gate ill_if_t ill_if;
6530Sstevel@tonic-gate const char *opt_P = NULL;
6540Sstevel@tonic-gate int printlist = MAX_G_HEADS;
6550Sstevel@tonic-gate
6560Sstevel@tonic-gate if (mdb_getopts(argc, argv,
6570Sstevel@tonic-gate 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
6580Sstevel@tonic-gate return (DCMD_USAGE);
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate if (opt_P != NULL) {
6610Sstevel@tonic-gate if (strcmp("v4", opt_P) == 0) {
6620Sstevel@tonic-gate printlist = IP_V4_G_HEAD;
6630Sstevel@tonic-gate } else if (strcmp("v6", opt_P) == 0) {
6640Sstevel@tonic-gate printlist = IP_V6_G_HEAD;
6650Sstevel@tonic-gate } else {
6660Sstevel@tonic-gate mdb_warn("invalid protocol '%s'\n", opt_P);
6670Sstevel@tonic-gate return (DCMD_USAGE);
6680Sstevel@tonic-gate }
6690Sstevel@tonic-gate }
6700Sstevel@tonic-gate
6710Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && (flags & DCMD_PIPE_OUT) == 0) {
6720Sstevel@tonic-gate mdb_printf("%<u>%?s %2s %?s %10s %?s %-10s%</u>\n",
6730Sstevel@tonic-gate "ADDR", "IP", "AVLADDR", "NUMNODES", "ARENA", "NAME");
6740Sstevel@tonic-gate }
6750Sstevel@tonic-gate
6760Sstevel@tonic-gate id.ill_flags = flags;
6770Sstevel@tonic-gate id.ill_addr = addr;
6780Sstevel@tonic-gate id.ill_printlist = printlist;
6790Sstevel@tonic-gate id.ill_printed = FALSE;
6800Sstevel@tonic-gate
6810Sstevel@tonic-gate if (mdb_walk("illif", (mdb_walk_cb_t)illif_cb, &id) == -1) {
6820Sstevel@tonic-gate mdb_warn("can't walk ill_if_t structures");
6830Sstevel@tonic-gate return (DCMD_ERR);
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) || opt_P != NULL || id.ill_printed)
6870Sstevel@tonic-gate return (DCMD_OK);
6880Sstevel@tonic-gate
6890Sstevel@tonic-gate /*
6900Sstevel@tonic-gate * If an address is specified and the walk doesn't find it,
6910Sstevel@tonic-gate * print it anyway.
6920Sstevel@tonic-gate */
6930Sstevel@tonic-gate if (mdb_vread(&ill_if, sizeof (ill_if_t), addr) == -1) {
6940Sstevel@tonic-gate mdb_warn("failed to read ill_if_t at %p", addr);
6950Sstevel@tonic-gate return (DCMD_ERR);
6960Sstevel@tonic-gate }
6970Sstevel@tonic-gate
6980Sstevel@tonic-gate mdb_printf("%?p %2s %?p %10d %?p %s\n",
6990Sstevel@tonic-gate addr, "??", addr + offsetof(ill_if_t, illif_avl_by_ppa),
7000Sstevel@tonic-gate ill_if.illif_avl_by_ppa.avl_numnodes,
7010Sstevel@tonic-gate ill_if.illif_ppa_arena, ill_if.illif_name);
7020Sstevel@tonic-gate
7030Sstevel@tonic-gate return (DCMD_OK);
7040Sstevel@tonic-gate }
7050Sstevel@tonic-gate
7060Sstevel@tonic-gate static void
illif_help(void)7070Sstevel@tonic-gate illif_help(void)
7080Sstevel@tonic-gate {
7090Sstevel@tonic-gate mdb_printf("Options:\n");
7100Sstevel@tonic-gate mdb_printf("\t-P v4 | v6"
7110Sstevel@tonic-gate "\tfilter interface structures for the specified protocol\n");
7120Sstevel@tonic-gate }
7130Sstevel@tonic-gate
7140Sstevel@tonic-gate int
nce_walk_init(mdb_walk_state_t * wsp)71511042SErik.Nordmark@Sun.COM nce_walk_init(mdb_walk_state_t *wsp)
71611042SErik.Nordmark@Sun.COM {
71711042SErik.Nordmark@Sun.COM if (mdb_layered_walk("nce_cache", wsp) == -1) {
71811042SErik.Nordmark@Sun.COM mdb_warn("can't walk 'nce_cache'");
71911042SErik.Nordmark@Sun.COM return (WALK_ERR);
72011042SErik.Nordmark@Sun.COM }
72111042SErik.Nordmark@Sun.COM
72211042SErik.Nordmark@Sun.COM return (WALK_NEXT);
72311042SErik.Nordmark@Sun.COM }
72411042SErik.Nordmark@Sun.COM
72511042SErik.Nordmark@Sun.COM int
nce_walk_step(mdb_walk_state_t * wsp)72611042SErik.Nordmark@Sun.COM nce_walk_step(mdb_walk_state_t *wsp)
72711042SErik.Nordmark@Sun.COM {
72811042SErik.Nordmark@Sun.COM nce_t nce;
72911042SErik.Nordmark@Sun.COM
73011042SErik.Nordmark@Sun.COM if (mdb_vread(&nce, sizeof (nce), wsp->walk_addr) == -1) {
73111042SErik.Nordmark@Sun.COM mdb_warn("can't read nce at %p", wsp->walk_addr);
73211042SErik.Nordmark@Sun.COM return (WALK_ERR);
73311042SErik.Nordmark@Sun.COM }
73411042SErik.Nordmark@Sun.COM
73511042SErik.Nordmark@Sun.COM return (wsp->walk_callback(wsp->walk_addr, &nce, wsp->walk_cbdata));
73611042SErik.Nordmark@Sun.COM }
73711042SErik.Nordmark@Sun.COM
73811042SErik.Nordmark@Sun.COM static int
nce_format(uintptr_t addr,const nce_t * ncep,void * nce_cb_arg)73911042SErik.Nordmark@Sun.COM nce_format(uintptr_t addr, const nce_t *ncep, void *nce_cb_arg)
74011042SErik.Nordmark@Sun.COM {
74111042SErik.Nordmark@Sun.COM nce_cbdata_t *nce_cb = nce_cb_arg;
74211042SErik.Nordmark@Sun.COM ill_t ill;
74311042SErik.Nordmark@Sun.COM char ill_name[LIFNAMSIZ];
74411042SErik.Nordmark@Sun.COM ncec_t ncec;
74511042SErik.Nordmark@Sun.COM
74611042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec),
74711042SErik.Nordmark@Sun.COM (uintptr_t)ncep->nce_common) == -1) {
74811042SErik.Nordmark@Sun.COM mdb_warn("can't read ncec at %p", ncep->nce_common);
74911042SErik.Nordmark@Sun.COM return (WALK_NEXT);
75011042SErik.Nordmark@Sun.COM }
75111042SErik.Nordmark@Sun.COM if (nce_cb->nce_ipversion != 0 &&
75211042SErik.Nordmark@Sun.COM ncec.ncec_ipversion != nce_cb->nce_ipversion)
75311042SErik.Nordmark@Sun.COM return (WALK_NEXT);
75411042SErik.Nordmark@Sun.COM
75511042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncep->nce_ill) == -1) {
75611042SErik.Nordmark@Sun.COM mdb_snprintf(ill_name, sizeof (ill_name), "--");
75711042SErik.Nordmark@Sun.COM } else {
75811042SErik.Nordmark@Sun.COM (void) mdb_readstr(ill_name,
75911042SErik.Nordmark@Sun.COM MIN(LIFNAMSIZ, ill.ill_name_length),
76011042SErik.Nordmark@Sun.COM (uintptr_t)ill.ill_name);
76111042SErik.Nordmark@Sun.COM }
76211042SErik.Nordmark@Sun.COM
76311042SErik.Nordmark@Sun.COM if (nce_cb->nce_ill_name[0] != '\0' &&
76411042SErik.Nordmark@Sun.COM strncmp(nce_cb->nce_ill_name, ill_name, LIFNAMSIZ) != 0)
76511042SErik.Nordmark@Sun.COM return (WALK_NEXT);
76611042SErik.Nordmark@Sun.COM
76711042SErik.Nordmark@Sun.COM if (ncec.ncec_ipversion == IPV6_VERSION) {
76811042SErik.Nordmark@Sun.COM
76911042SErik.Nordmark@Sun.COM mdb_printf("%?p %5s %-18s %?p %6d %N\n",
77011042SErik.Nordmark@Sun.COM addr, ill_name,
77111042SErik.Nordmark@Sun.COM nce_l2_addr(ncep, &ill),
77211042SErik.Nordmark@Sun.COM ncep->nce_fp_mp,
77311042SErik.Nordmark@Sun.COM ncep->nce_refcnt,
77411042SErik.Nordmark@Sun.COM &ncep->nce_addr);
77511042SErik.Nordmark@Sun.COM
77611042SErik.Nordmark@Sun.COM } else {
77711042SErik.Nordmark@Sun.COM struct in_addr nceaddr;
77811042SErik.Nordmark@Sun.COM
77911042SErik.Nordmark@Sun.COM IN6_V4MAPPED_TO_INADDR(&ncep->nce_addr, &nceaddr);
78011042SErik.Nordmark@Sun.COM mdb_printf("%?p %5s %-18s %?p %6d %I\n",
78111042SErik.Nordmark@Sun.COM addr, ill_name,
78211042SErik.Nordmark@Sun.COM nce_l2_addr(ncep, &ill),
78311042SErik.Nordmark@Sun.COM ncep->nce_fp_mp,
78411042SErik.Nordmark@Sun.COM ncep->nce_refcnt,
78511042SErik.Nordmark@Sun.COM nceaddr.s_addr);
78611042SErik.Nordmark@Sun.COM }
78711042SErik.Nordmark@Sun.COM
78811042SErik.Nordmark@Sun.COM return (WALK_NEXT);
78911042SErik.Nordmark@Sun.COM }
79011042SErik.Nordmark@Sun.COM
79111042SErik.Nordmark@Sun.COM int
dce_walk_init(mdb_walk_state_t * wsp)79211042SErik.Nordmark@Sun.COM dce_walk_init(mdb_walk_state_t *wsp)
79311042SErik.Nordmark@Sun.COM {
79411042SErik.Nordmark@Sun.COM wsp->walk_data = (void *)wsp->walk_addr;
79511042SErik.Nordmark@Sun.COM
79611042SErik.Nordmark@Sun.COM if (mdb_layered_walk("dce_cache", wsp) == -1) {
79711042SErik.Nordmark@Sun.COM mdb_warn("can't walk 'dce_cache'");
79811042SErik.Nordmark@Sun.COM return (WALK_ERR);
79911042SErik.Nordmark@Sun.COM }
80011042SErik.Nordmark@Sun.COM
80111042SErik.Nordmark@Sun.COM return (WALK_NEXT);
80211042SErik.Nordmark@Sun.COM }
80311042SErik.Nordmark@Sun.COM
80411042SErik.Nordmark@Sun.COM int
dce_walk_step(mdb_walk_state_t * wsp)80511042SErik.Nordmark@Sun.COM dce_walk_step(mdb_walk_state_t *wsp)
80611042SErik.Nordmark@Sun.COM {
80711042SErik.Nordmark@Sun.COM dce_t dce;
80811042SErik.Nordmark@Sun.COM
80911042SErik.Nordmark@Sun.COM if (mdb_vread(&dce, sizeof (dce), wsp->walk_addr) == -1) {
81011042SErik.Nordmark@Sun.COM mdb_warn("can't read dce at %p", wsp->walk_addr);
81111042SErik.Nordmark@Sun.COM return (WALK_ERR);
81211042SErik.Nordmark@Sun.COM }
81311042SErik.Nordmark@Sun.COM
81411042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip DCEs that don't belong to it. */
81511042SErik.Nordmark@Sun.COM if ((wsp->walk_data != NULL) && (wsp->walk_data != dce.dce_ipst))
81611042SErik.Nordmark@Sun.COM return (WALK_NEXT);
81711042SErik.Nordmark@Sun.COM
81811042SErik.Nordmark@Sun.COM return (wsp->walk_callback(wsp->walk_addr, &dce, wsp->walk_cbdata));
81911042SErik.Nordmark@Sun.COM }
82011042SErik.Nordmark@Sun.COM
82111042SErik.Nordmark@Sun.COM int
ire_walk_init(mdb_walk_state_t * wsp)8220Sstevel@tonic-gate ire_walk_init(mdb_walk_state_t *wsp)
8230Sstevel@tonic-gate {
82411042SErik.Nordmark@Sun.COM wsp->walk_data = (void *)wsp->walk_addr;
82511042SErik.Nordmark@Sun.COM
8260Sstevel@tonic-gate if (mdb_layered_walk("ire_cache", wsp) == -1) {
8270Sstevel@tonic-gate mdb_warn("can't walk 'ire_cache'");
8280Sstevel@tonic-gate return (WALK_ERR);
8290Sstevel@tonic-gate }
8300Sstevel@tonic-gate
8310Sstevel@tonic-gate return (WALK_NEXT);
8320Sstevel@tonic-gate }
8330Sstevel@tonic-gate
8340Sstevel@tonic-gate int
ire_walk_step(mdb_walk_state_t * wsp)8350Sstevel@tonic-gate ire_walk_step(mdb_walk_state_t *wsp)
8360Sstevel@tonic-gate {
8370Sstevel@tonic-gate ire_t ire;
8380Sstevel@tonic-gate
8390Sstevel@tonic-gate if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) {
8400Sstevel@tonic-gate mdb_warn("can't read ire at %p", wsp->walk_addr);
8410Sstevel@tonic-gate return (WALK_ERR);
8420Sstevel@tonic-gate }
8430Sstevel@tonic-gate
84411042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip IREs that don't belong to it. */
84511042SErik.Nordmark@Sun.COM if ((wsp->walk_data != NULL) && (wsp->walk_data != ire.ire_ipst))
84611042SErik.Nordmark@Sun.COM return (WALK_NEXT);
84711042SErik.Nordmark@Sun.COM
8480Sstevel@tonic-gate return (wsp->walk_callback(wsp->walk_addr, &ire, wsp->walk_cbdata));
8490Sstevel@tonic-gate }
8500Sstevel@tonic-gate
8513448Sdh155122 /* ARGSUSED */
8523448Sdh155122 int
ire_next_walk_init(mdb_walk_state_t * wsp)8533448Sdh155122 ire_next_walk_init(mdb_walk_state_t *wsp)
8543448Sdh155122 {
8553448Sdh155122 return (WALK_NEXT);
8563448Sdh155122 }
8573448Sdh155122
8583448Sdh155122 int
ire_next_walk_step(mdb_walk_state_t * wsp)8593448Sdh155122 ire_next_walk_step(mdb_walk_state_t *wsp)
8603448Sdh155122 {
8613448Sdh155122 ire_t ire;
8623448Sdh155122 int status;
8633448Sdh155122
8643448Sdh155122
8653448Sdh155122 if (wsp->walk_addr == NULL)
8663448Sdh155122 return (WALK_DONE);
8673448Sdh155122
8683448Sdh155122 if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) {
8693448Sdh155122 mdb_warn("can't read ire at %p", wsp->walk_addr);
8703448Sdh155122 return (WALK_ERR);
8713448Sdh155122 }
8723448Sdh155122 status = wsp->walk_callback(wsp->walk_addr, &ire,
8733448Sdh155122 wsp->walk_cbdata);
8743448Sdh155122
8753448Sdh155122 if (status != WALK_NEXT)
8763448Sdh155122 return (status);
8773448Sdh155122
8783448Sdh155122 wsp->walk_addr = (uintptr_t)ire.ire_next;
8793448Sdh155122 return (status);
8803448Sdh155122 }
8813448Sdh155122
8820Sstevel@tonic-gate static int
ire_format(uintptr_t addr,const void * ire_arg,void * ire_cb_arg)8835940Ssowmini ire_format(uintptr_t addr, const void *ire_arg, void *ire_cb_arg)
8840Sstevel@tonic-gate {
8855940Ssowmini const ire_t *irep = ire_arg;
8865940Ssowmini ire_cbdata_t *ire_cb = ire_cb_arg;
8875940Ssowmini boolean_t verbose = ire_cb->verbose;
88811042SErik.Nordmark@Sun.COM ill_t ill;
88911042SErik.Nordmark@Sun.COM char ill_name[LIFNAMSIZ];
89011042SErik.Nordmark@Sun.COM boolean_t condemned = irep->ire_generation == IRE_GENERATION_CONDEMNED;
8915940Ssowmini
8920Sstevel@tonic-gate static const mdb_bitmask_t tmasks[] = {
8930Sstevel@tonic-gate { "BROADCAST", IRE_BROADCAST, IRE_BROADCAST },
8940Sstevel@tonic-gate { "DEFAULT", IRE_DEFAULT, IRE_DEFAULT },
8950Sstevel@tonic-gate { "LOCAL", IRE_LOCAL, IRE_LOCAL },
8960Sstevel@tonic-gate { "LOOPBACK", IRE_LOOPBACK, IRE_LOOPBACK },
8970Sstevel@tonic-gate { "PREFIX", IRE_PREFIX, IRE_PREFIX },
89811042SErik.Nordmark@Sun.COM { "MULTICAST", IRE_MULTICAST, IRE_MULTICAST },
89911042SErik.Nordmark@Sun.COM { "NOROUTE", IRE_NOROUTE, IRE_NOROUTE },
9000Sstevel@tonic-gate { "IF_NORESOLVER", IRE_IF_NORESOLVER, IRE_IF_NORESOLVER },
9010Sstevel@tonic-gate { "IF_RESOLVER", IRE_IF_RESOLVER, IRE_IF_RESOLVER },
90211042SErik.Nordmark@Sun.COM { "IF_CLONE", IRE_IF_CLONE, IRE_IF_CLONE },
9030Sstevel@tonic-gate { "HOST", IRE_HOST, IRE_HOST },
9040Sstevel@tonic-gate { NULL, 0, 0 }
9050Sstevel@tonic-gate };
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate static const mdb_bitmask_t fmasks[] = {
9080Sstevel@tonic-gate { "UP", RTF_UP, RTF_UP },
9090Sstevel@tonic-gate { "GATEWAY", RTF_GATEWAY, RTF_GATEWAY },
9100Sstevel@tonic-gate { "HOST", RTF_HOST, RTF_HOST },
9110Sstevel@tonic-gate { "REJECT", RTF_REJECT, RTF_REJECT },
9120Sstevel@tonic-gate { "DYNAMIC", RTF_DYNAMIC, RTF_DYNAMIC },
9130Sstevel@tonic-gate { "MODIFIED", RTF_MODIFIED, RTF_MODIFIED },
9140Sstevel@tonic-gate { "DONE", RTF_DONE, RTF_DONE },
9150Sstevel@tonic-gate { "MASK", RTF_MASK, RTF_MASK },
9160Sstevel@tonic-gate { "CLONING", RTF_CLONING, RTF_CLONING },
9170Sstevel@tonic-gate { "XRESOLVE", RTF_XRESOLVE, RTF_XRESOLVE },
9180Sstevel@tonic-gate { "LLINFO", RTF_LLINFO, RTF_LLINFO },
9190Sstevel@tonic-gate { "STATIC", RTF_STATIC, RTF_STATIC },
9200Sstevel@tonic-gate { "BLACKHOLE", RTF_BLACKHOLE, RTF_BLACKHOLE },
9210Sstevel@tonic-gate { "PRIVATE", RTF_PRIVATE, RTF_PRIVATE },
9220Sstevel@tonic-gate { "PROTO2", RTF_PROTO2, RTF_PROTO2 },
9230Sstevel@tonic-gate { "PROTO1", RTF_PROTO1, RTF_PROTO1 },
9240Sstevel@tonic-gate { "MULTIRT", RTF_MULTIRT, RTF_MULTIRT },
9250Sstevel@tonic-gate { "SETSRC", RTF_SETSRC, RTF_SETSRC },
92611042SErik.Nordmark@Sun.COM { "INDIRECT", RTF_INDIRECT, RTF_INDIRECT },
9270Sstevel@tonic-gate { NULL, 0, 0 }
9280Sstevel@tonic-gate };
9290Sstevel@tonic-gate
9305940Ssowmini if (ire_cb->ire_ipversion != 0 &&
9315940Ssowmini irep->ire_ipversion != ire_cb->ire_ipversion)
9325940Ssowmini return (WALK_NEXT);
9335940Ssowmini
93411042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)irep->ire_ill) == -1) {
93511042SErik.Nordmark@Sun.COM mdb_snprintf(ill_name, sizeof (ill_name), "--");
93611042SErik.Nordmark@Sun.COM } else {
93711042SErik.Nordmark@Sun.COM (void) mdb_readstr(ill_name,
93811042SErik.Nordmark@Sun.COM MIN(LIFNAMSIZ, ill.ill_name_length),
93911042SErik.Nordmark@Sun.COM (uintptr_t)ill.ill_name);
94011042SErik.Nordmark@Sun.COM }
94111042SErik.Nordmark@Sun.COM
9425940Ssowmini if (irep->ire_ipversion == IPV6_VERSION && verbose) {
9430Sstevel@tonic-gate
94411042SErik.Nordmark@Sun.COM mdb_printf("%<b>%?p%</b>%3s %40N <%hb%s>\n"
94511042SErik.Nordmark@Sun.COM "%?s %40N\n"
94611042SErik.Nordmark@Sun.COM "%?s %40d %4d <%hb> %s\n",
94711042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6,
94811042SErik.Nordmark@Sun.COM irep->ire_type, tmasks,
94911042SErik.Nordmark@Sun.COM (irep->ire_testhidden ? ", HIDDEN" : ""),
95011042SErik.Nordmark@Sun.COM "", &irep->ire_addr_v6,
9513448Sdh155122 "", ips_to_stackid((uintptr_t)irep->ire_ipst),
9523448Sdh155122 irep->ire_zoneid,
95311042SErik.Nordmark@Sun.COM irep->ire_flags, fmasks, ill_name);
9540Sstevel@tonic-gate
9555940Ssowmini } else if (irep->ire_ipversion == IPV6_VERSION) {
9560Sstevel@tonic-gate
95711042SErik.Nordmark@Sun.COM mdb_printf("%?p%3s %30N %30N %5d %4d %s\n",
95811042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6,
9593448Sdh155122 &irep->ire_addr_v6,
9603448Sdh155122 ips_to_stackid((uintptr_t)irep->ire_ipst),
96111042SErik.Nordmark@Sun.COM irep->ire_zoneid, ill_name);
9620Sstevel@tonic-gate
9635940Ssowmini } else if (verbose) {
9640Sstevel@tonic-gate
96511042SErik.Nordmark@Sun.COM mdb_printf("%<b>%?p%</b>%3s %40I <%hb%s>\n"
96611042SErik.Nordmark@Sun.COM "%?s %40I\n"
96711042SErik.Nordmark@Sun.COM "%?s %40d %4d <%hb> %s\n",
96811042SErik.Nordmark@Sun.COM addr, condemned ? "(C)" : "", irep->ire_setsrc_addr,
96911042SErik.Nordmark@Sun.COM irep->ire_type, tmasks,
97011042SErik.Nordmark@Sun.COM (irep->ire_testhidden ? ", HIDDEN" : ""),
97111042SErik.Nordmark@Sun.COM "", irep->ire_addr,
9723448Sdh155122 "", ips_to_stackid((uintptr_t)irep->ire_ipst),
97311042SErik.Nordmark@Sun.COM irep->ire_zoneid, irep->ire_flags, fmasks, ill_name);
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate } else {
9760Sstevel@tonic-gate
97711042SErik.Nordmark@Sun.COM mdb_printf("%?p%3s %30I %30I %5d %4d %s\n", addr,
97811042SErik.Nordmark@Sun.COM condemned ? "(C)" : "", irep->ire_setsrc_addr,
9793448Sdh155122 irep->ire_addr, ips_to_stackid((uintptr_t)irep->ire_ipst),
98011042SErik.Nordmark@Sun.COM irep->ire_zoneid, ill_name);
9810Sstevel@tonic-gate }
9820Sstevel@tonic-gate
9830Sstevel@tonic-gate return (WALK_NEXT);
9840Sstevel@tonic-gate }
9850Sstevel@tonic-gate
9860Sstevel@tonic-gate /*
9870Sstevel@tonic-gate * There are faster ways to do this. Given the interactive nature of this
9880Sstevel@tonic-gate * use I don't think its worth much effort.
9890Sstevel@tonic-gate */
9900Sstevel@tonic-gate static unsigned short
ipcksum(void * p,int len)9910Sstevel@tonic-gate ipcksum(void *p, int len)
9920Sstevel@tonic-gate {
9930Sstevel@tonic-gate int32_t sum = 0;
9940Sstevel@tonic-gate
9950Sstevel@tonic-gate while (len > 1) {
9960Sstevel@tonic-gate /* alignment */
9970Sstevel@tonic-gate sum += *(uint16_t *)p;
9980Sstevel@tonic-gate p = (char *)p + sizeof (uint16_t);
9990Sstevel@tonic-gate if (sum & 0x80000000)
10000Sstevel@tonic-gate sum = (sum & 0xFFFF) + (sum >> 16);
10010Sstevel@tonic-gate len -= 2;
10020Sstevel@tonic-gate }
10030Sstevel@tonic-gate
10040Sstevel@tonic-gate if (len)
10050Sstevel@tonic-gate sum += (uint16_t)*(unsigned char *)p;
10060Sstevel@tonic-gate
10070Sstevel@tonic-gate while (sum >> 16)
10080Sstevel@tonic-gate sum = (sum & 0xFFFF) + (sum >> 16);
10090Sstevel@tonic-gate
10100Sstevel@tonic-gate return (~sum);
10110Sstevel@tonic-gate }
10120Sstevel@tonic-gate
10130Sstevel@tonic-gate static const mdb_bitmask_t tcp_flags[] = {
10140Sstevel@tonic-gate { "SYN", TH_SYN, TH_SYN },
10150Sstevel@tonic-gate { "ACK", TH_ACK, TH_ACK },
10160Sstevel@tonic-gate { "FIN", TH_FIN, TH_FIN },
10170Sstevel@tonic-gate { "RST", TH_RST, TH_RST },
10180Sstevel@tonic-gate { "PSH", TH_PUSH, TH_PUSH },
10190Sstevel@tonic-gate { "ECE", TH_ECE, TH_ECE },
10200Sstevel@tonic-gate { "CWR", TH_CWR, TH_CWR },
10210Sstevel@tonic-gate { NULL, 0, 0 }
10220Sstevel@tonic-gate };
10230Sstevel@tonic-gate
1024*12175SKacheong.Poon@Sun.COM /* TCP option length */
1025*12175SKacheong.Poon@Sun.COM #define TCPOPT_HEADER_LEN 2
1026*12175SKacheong.Poon@Sun.COM #define TCPOPT_MAXSEG_LEN 4
1027*12175SKacheong.Poon@Sun.COM #define TCPOPT_WS_LEN 3
1028*12175SKacheong.Poon@Sun.COM #define TCPOPT_TSTAMP_LEN 10
1029*12175SKacheong.Poon@Sun.COM #define TCPOPT_SACK_OK_LEN 2
1030*12175SKacheong.Poon@Sun.COM
1031*12175SKacheong.Poon@Sun.COM static void
tcphdr_print_options(uint8_t * opts,uint32_t opts_len)1032*12175SKacheong.Poon@Sun.COM tcphdr_print_options(uint8_t *opts, uint32_t opts_len)
1033*12175SKacheong.Poon@Sun.COM {
1034*12175SKacheong.Poon@Sun.COM uint8_t *endp;
1035*12175SKacheong.Poon@Sun.COM uint32_t len, val;
1036*12175SKacheong.Poon@Sun.COM
1037*12175SKacheong.Poon@Sun.COM mdb_printf("%<b>Options:%</b>");
1038*12175SKacheong.Poon@Sun.COM endp = opts + opts_len;
1039*12175SKacheong.Poon@Sun.COM while (opts < endp) {
1040*12175SKacheong.Poon@Sun.COM len = endp - opts;
1041*12175SKacheong.Poon@Sun.COM switch (*opts) {
1042*12175SKacheong.Poon@Sun.COM case TCPOPT_EOL:
1043*12175SKacheong.Poon@Sun.COM mdb_printf(" EOL");
1044*12175SKacheong.Poon@Sun.COM opts++;
1045*12175SKacheong.Poon@Sun.COM break;
1046*12175SKacheong.Poon@Sun.COM
1047*12175SKacheong.Poon@Sun.COM case TCPOPT_NOP:
1048*12175SKacheong.Poon@Sun.COM mdb_printf(" NOP");
1049*12175SKacheong.Poon@Sun.COM opts++;
1050*12175SKacheong.Poon@Sun.COM break;
1051*12175SKacheong.Poon@Sun.COM
1052*12175SKacheong.Poon@Sun.COM case TCPOPT_MAXSEG: {
1053*12175SKacheong.Poon@Sun.COM uint16_t mss;
1054*12175SKacheong.Poon@Sun.COM
1055*12175SKacheong.Poon@Sun.COM if (len < TCPOPT_MAXSEG_LEN ||
1056*12175SKacheong.Poon@Sun.COM opts[1] != TCPOPT_MAXSEG_LEN) {
1057*12175SKacheong.Poon@Sun.COM mdb_printf(" <Truncated MSS>\n");
1058*12175SKacheong.Poon@Sun.COM return;
1059*12175SKacheong.Poon@Sun.COM }
1060*12175SKacheong.Poon@Sun.COM mdb_nhconvert(&mss, opts + TCPOPT_HEADER_LEN,
1061*12175SKacheong.Poon@Sun.COM sizeof (mss));
1062*12175SKacheong.Poon@Sun.COM mdb_printf(" MSS=%u", mss);
1063*12175SKacheong.Poon@Sun.COM opts += TCPOPT_MAXSEG_LEN;
1064*12175SKacheong.Poon@Sun.COM break;
1065*12175SKacheong.Poon@Sun.COM }
1066*12175SKacheong.Poon@Sun.COM
1067*12175SKacheong.Poon@Sun.COM case TCPOPT_WSCALE:
1068*12175SKacheong.Poon@Sun.COM if (len < TCPOPT_WS_LEN || opts[1] != TCPOPT_WS_LEN) {
1069*12175SKacheong.Poon@Sun.COM mdb_printf(" <Truncated WS>\n");
1070*12175SKacheong.Poon@Sun.COM return;
1071*12175SKacheong.Poon@Sun.COM }
1072*12175SKacheong.Poon@Sun.COM mdb_printf(" WS=%u", opts[2]);
1073*12175SKacheong.Poon@Sun.COM opts += TCPOPT_WS_LEN;
1074*12175SKacheong.Poon@Sun.COM break;
1075*12175SKacheong.Poon@Sun.COM
1076*12175SKacheong.Poon@Sun.COM case TCPOPT_TSTAMP: {
1077*12175SKacheong.Poon@Sun.COM if (len < TCPOPT_TSTAMP_LEN ||
1078*12175SKacheong.Poon@Sun.COM opts[1] != TCPOPT_TSTAMP_LEN) {
1079*12175SKacheong.Poon@Sun.COM mdb_printf(" <Truncated TS>\n");
1080*12175SKacheong.Poon@Sun.COM return;
1081*12175SKacheong.Poon@Sun.COM }
1082*12175SKacheong.Poon@Sun.COM
1083*12175SKacheong.Poon@Sun.COM opts += TCPOPT_HEADER_LEN;
1084*12175SKacheong.Poon@Sun.COM mdb_nhconvert(&val, opts, sizeof (val));
1085*12175SKacheong.Poon@Sun.COM mdb_printf(" TS_VAL=%u,", val);
1086*12175SKacheong.Poon@Sun.COM
1087*12175SKacheong.Poon@Sun.COM opts += sizeof (val);
1088*12175SKacheong.Poon@Sun.COM mdb_nhconvert(&val, opts, sizeof (val));
1089*12175SKacheong.Poon@Sun.COM mdb_printf("TS_ECHO=%u", val);
1090*12175SKacheong.Poon@Sun.COM
1091*12175SKacheong.Poon@Sun.COM opts += sizeof (val);
1092*12175SKacheong.Poon@Sun.COM break;
1093*12175SKacheong.Poon@Sun.COM }
1094*12175SKacheong.Poon@Sun.COM
1095*12175SKacheong.Poon@Sun.COM case TCPOPT_SACK_PERMITTED:
1096*12175SKacheong.Poon@Sun.COM if (len < TCPOPT_SACK_OK_LEN ||
1097*12175SKacheong.Poon@Sun.COM opts[1] != TCPOPT_SACK_OK_LEN) {
1098*12175SKacheong.Poon@Sun.COM mdb_printf(" <Truncated SACK_OK>\n");
1099*12175SKacheong.Poon@Sun.COM return;
1100*12175SKacheong.Poon@Sun.COM }
1101*12175SKacheong.Poon@Sun.COM mdb_printf(" SACK_OK");
1102*12175SKacheong.Poon@Sun.COM opts += TCPOPT_SACK_OK_LEN;
1103*12175SKacheong.Poon@Sun.COM break;
1104*12175SKacheong.Poon@Sun.COM
1105*12175SKacheong.Poon@Sun.COM case TCPOPT_SACK: {
1106*12175SKacheong.Poon@Sun.COM uint32_t sack_len;
1107*12175SKacheong.Poon@Sun.COM
1108*12175SKacheong.Poon@Sun.COM if (len <= TCPOPT_HEADER_LEN || len < opts[1] ||
1109*12175SKacheong.Poon@Sun.COM opts[1] <= TCPOPT_HEADER_LEN) {
1110*12175SKacheong.Poon@Sun.COM mdb_printf(" <Truncated SACK>\n");
1111*12175SKacheong.Poon@Sun.COM return;
1112*12175SKacheong.Poon@Sun.COM }
1113*12175SKacheong.Poon@Sun.COM sack_len = opts[1] - TCPOPT_HEADER_LEN;
1114*12175SKacheong.Poon@Sun.COM opts += TCPOPT_HEADER_LEN;
1115*12175SKacheong.Poon@Sun.COM
1116*12175SKacheong.Poon@Sun.COM mdb_printf(" SACK=");
1117*12175SKacheong.Poon@Sun.COM while (sack_len > 0) {
1118*12175SKacheong.Poon@Sun.COM if (opts + 2 * sizeof (val) > endp) {
1119*12175SKacheong.Poon@Sun.COM mdb_printf("<Truncated SACK>\n");
1120*12175SKacheong.Poon@Sun.COM opts = endp;
1121*12175SKacheong.Poon@Sun.COM break;
1122*12175SKacheong.Poon@Sun.COM }
1123*12175SKacheong.Poon@Sun.COM
1124*12175SKacheong.Poon@Sun.COM mdb_nhconvert(&val, opts, sizeof (val));
1125*12175SKacheong.Poon@Sun.COM mdb_printf("<%u,", val);
1126*12175SKacheong.Poon@Sun.COM opts += sizeof (val);
1127*12175SKacheong.Poon@Sun.COM mdb_nhconvert(&val, opts, sizeof (val));
1128*12175SKacheong.Poon@Sun.COM mdb_printf("%u>", val);
1129*12175SKacheong.Poon@Sun.COM opts += sizeof (val);
1130*12175SKacheong.Poon@Sun.COM
1131*12175SKacheong.Poon@Sun.COM sack_len -= 2 * sizeof (val);
1132*12175SKacheong.Poon@Sun.COM }
1133*12175SKacheong.Poon@Sun.COM break;
1134*12175SKacheong.Poon@Sun.COM }
1135*12175SKacheong.Poon@Sun.COM
1136*12175SKacheong.Poon@Sun.COM default:
1137*12175SKacheong.Poon@Sun.COM mdb_printf(" Opts=<val=%u,len=%u>", *opts,
1138*12175SKacheong.Poon@Sun.COM opts[1]);
1139*12175SKacheong.Poon@Sun.COM opts += opts[1];
1140*12175SKacheong.Poon@Sun.COM break;
1141*12175SKacheong.Poon@Sun.COM }
1142*12175SKacheong.Poon@Sun.COM }
1143*12175SKacheong.Poon@Sun.COM mdb_printf("\n");
1144*12175SKacheong.Poon@Sun.COM }
1145*12175SKacheong.Poon@Sun.COM
11460Sstevel@tonic-gate static void
tcphdr_print(struct tcphdr * tcph)11470Sstevel@tonic-gate tcphdr_print(struct tcphdr *tcph)
11480Sstevel@tonic-gate {
11490Sstevel@tonic-gate in_port_t sport, dport;
11500Sstevel@tonic-gate tcp_seq seq, ack;
11510Sstevel@tonic-gate uint16_t win, urp;
11520Sstevel@tonic-gate
11530Sstevel@tonic-gate mdb_printf("%<b>TCP header%</b>\n");
11540Sstevel@tonic-gate
11550Sstevel@tonic-gate mdb_nhconvert(&sport, &tcph->th_sport, sizeof (sport));
11560Sstevel@tonic-gate mdb_nhconvert(&dport, &tcph->th_dport, sizeof (dport));
11570Sstevel@tonic-gate mdb_nhconvert(&seq, &tcph->th_seq, sizeof (seq));
11580Sstevel@tonic-gate mdb_nhconvert(&ack, &tcph->th_ack, sizeof (ack));
11590Sstevel@tonic-gate mdb_nhconvert(&win, &tcph->th_win, sizeof (win));
11600Sstevel@tonic-gate mdb_nhconvert(&urp, &tcph->th_urp, sizeof (urp));
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate mdb_printf("%<u>%6s %6s %10s %10s %4s %5s %5s %5s %-15s%</u>\n",
11630Sstevel@tonic-gate "SPORT", "DPORT", "SEQ", "ACK", "HLEN", "WIN", "CSUM", "URP",
11640Sstevel@tonic-gate "FLAGS");
11650Sstevel@tonic-gate mdb_printf("%6hu %6hu %10u %10u %4d %5hu %5hu %5hu <%b>\n",
11660Sstevel@tonic-gate sport, dport, seq, ack, tcph->th_off << 2, win,
11670Sstevel@tonic-gate tcph->th_sum, urp, tcph->th_flags, tcp_flags);
11680Sstevel@tonic-gate mdb_printf("0x%04x 0x%04x 0x%08x 0x%08x\n\n",
11690Sstevel@tonic-gate sport, dport, seq, ack);
11700Sstevel@tonic-gate }
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate /* ARGSUSED */
11730Sstevel@tonic-gate static int
tcphdr(uintptr_t addr,uint_t flags,int ac,const mdb_arg_t * av)11740Sstevel@tonic-gate tcphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
11750Sstevel@tonic-gate {
11760Sstevel@tonic-gate struct tcphdr tcph;
1177*12175SKacheong.Poon@Sun.COM uint32_t opt_len;
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
11800Sstevel@tonic-gate return (DCMD_USAGE);
11810Sstevel@tonic-gate
11820Sstevel@tonic-gate if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) {
11830Sstevel@tonic-gate mdb_warn("failed to read TCP header at %p", addr);
11840Sstevel@tonic-gate return (DCMD_ERR);
11850Sstevel@tonic-gate }
11860Sstevel@tonic-gate tcphdr_print(&tcph);
1187*12175SKacheong.Poon@Sun.COM
1188*12175SKacheong.Poon@Sun.COM /* If there are options, print them out also. */
1189*12175SKacheong.Poon@Sun.COM opt_len = (tcph.th_off << 2) - TCP_MIN_HEADER_LENGTH;
1190*12175SKacheong.Poon@Sun.COM if (opt_len > 0) {
1191*12175SKacheong.Poon@Sun.COM uint8_t *opts, *opt_buf;
1192*12175SKacheong.Poon@Sun.COM
1193*12175SKacheong.Poon@Sun.COM opt_buf = mdb_alloc(opt_len, UM_SLEEP);
1194*12175SKacheong.Poon@Sun.COM opts = (uint8_t *)addr + sizeof (tcph);
1195*12175SKacheong.Poon@Sun.COM if (mdb_vread(opt_buf, opt_len, (uintptr_t)opts) == -1) {
1196*12175SKacheong.Poon@Sun.COM mdb_warn("failed to read TCP options at %p", opts);
1197*12175SKacheong.Poon@Sun.COM return (DCMD_ERR);
1198*12175SKacheong.Poon@Sun.COM }
1199*12175SKacheong.Poon@Sun.COM tcphdr_print_options(opt_buf, opt_len);
1200*12175SKacheong.Poon@Sun.COM mdb_free(opt_buf, opt_len);
1201*12175SKacheong.Poon@Sun.COM }
1202*12175SKacheong.Poon@Sun.COM
12030Sstevel@tonic-gate return (DCMD_OK);
12040Sstevel@tonic-gate }
12050Sstevel@tonic-gate
12060Sstevel@tonic-gate static void
udphdr_print(struct udphdr * udph)12070Sstevel@tonic-gate udphdr_print(struct udphdr *udph)
12080Sstevel@tonic-gate {
12090Sstevel@tonic-gate in_port_t sport, dport;
12100Sstevel@tonic-gate uint16_t hlen;
12110Sstevel@tonic-gate
12120Sstevel@tonic-gate mdb_printf("%<b>UDP header%</b>\n");
12130Sstevel@tonic-gate
12140Sstevel@tonic-gate mdb_nhconvert(&sport, &udph->uh_sport, sizeof (sport));
12150Sstevel@tonic-gate mdb_nhconvert(&dport, &udph->uh_dport, sizeof (dport));
12160Sstevel@tonic-gate mdb_nhconvert(&hlen, &udph->uh_ulen, sizeof (hlen));
12170Sstevel@tonic-gate
12180Sstevel@tonic-gate mdb_printf("%<u>%14s %14s %5s %6s%</u>\n",
12190Sstevel@tonic-gate "SPORT", "DPORT", "LEN", "CSUM");
12200Sstevel@tonic-gate mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %5hu 0x%04hx\n\n", sport, sport,
12210Sstevel@tonic-gate dport, dport, hlen, udph->uh_sum);
12220Sstevel@tonic-gate }
12230Sstevel@tonic-gate
12240Sstevel@tonic-gate /* ARGSUSED */
12250Sstevel@tonic-gate static int
udphdr(uintptr_t addr,uint_t flags,int ac,const mdb_arg_t * av)12260Sstevel@tonic-gate udphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
12270Sstevel@tonic-gate {
12280Sstevel@tonic-gate struct udphdr udph;
12290Sstevel@tonic-gate
12300Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
12310Sstevel@tonic-gate return (DCMD_USAGE);
12320Sstevel@tonic-gate
12330Sstevel@tonic-gate if (mdb_vread(&udph, sizeof (udph), addr) == -1) {
12340Sstevel@tonic-gate mdb_warn("failed to read UDP header at %p", addr);
12350Sstevel@tonic-gate return (DCMD_ERR);
12360Sstevel@tonic-gate }
12370Sstevel@tonic-gate udphdr_print(&udph);
12380Sstevel@tonic-gate return (DCMD_OK);
12390Sstevel@tonic-gate }
12400Sstevel@tonic-gate
12410Sstevel@tonic-gate static void
sctphdr_print(sctp_hdr_t * sctph)12420Sstevel@tonic-gate sctphdr_print(sctp_hdr_t *sctph)
12430Sstevel@tonic-gate {
12440Sstevel@tonic-gate in_port_t sport, dport;
12450Sstevel@tonic-gate
12460Sstevel@tonic-gate mdb_printf("%<b>SCTP header%</b>\n");
12470Sstevel@tonic-gate mdb_nhconvert(&sport, &sctph->sh_sport, sizeof (sport));
12480Sstevel@tonic-gate mdb_nhconvert(&dport, &sctph->sh_dport, sizeof (dport));
12490Sstevel@tonic-gate
12500Sstevel@tonic-gate mdb_printf("%<u>%14s %14s %10s %10s%</u>\n",
12510Sstevel@tonic-gate "SPORT", "DPORT", "VTAG", "CHKSUM");
12520Sstevel@tonic-gate mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %10u 0x%08x\n\n", sport, sport,
12530Sstevel@tonic-gate dport, dport, sctph->sh_verf, sctph->sh_chksum);
12540Sstevel@tonic-gate }
12550Sstevel@tonic-gate
12560Sstevel@tonic-gate /* ARGSUSED */
12570Sstevel@tonic-gate static int
sctphdr(uintptr_t addr,uint_t flags,int ac,const mdb_arg_t * av)12580Sstevel@tonic-gate sctphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
12590Sstevel@tonic-gate {
12600Sstevel@tonic-gate sctp_hdr_t sctph;
12610Sstevel@tonic-gate
12620Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
12630Sstevel@tonic-gate return (DCMD_USAGE);
12640Sstevel@tonic-gate
12650Sstevel@tonic-gate if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) {
12660Sstevel@tonic-gate mdb_warn("failed to read SCTP header at %p", addr);
12670Sstevel@tonic-gate return (DCMD_ERR);
12680Sstevel@tonic-gate }
12690Sstevel@tonic-gate
12700Sstevel@tonic-gate sctphdr_print(&sctph);
12710Sstevel@tonic-gate return (DCMD_OK);
12720Sstevel@tonic-gate }
12730Sstevel@tonic-gate
12740Sstevel@tonic-gate static int
transport_hdr(int proto,uintptr_t addr)12750Sstevel@tonic-gate transport_hdr(int proto, uintptr_t addr)
12760Sstevel@tonic-gate {
12770Sstevel@tonic-gate mdb_printf("\n");
12780Sstevel@tonic-gate switch (proto) {
12790Sstevel@tonic-gate case IPPROTO_TCP: {
12800Sstevel@tonic-gate struct tcphdr tcph;
12810Sstevel@tonic-gate
12820Sstevel@tonic-gate if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) {
12830Sstevel@tonic-gate mdb_warn("failed to read TCP header at %p", addr);
12840Sstevel@tonic-gate return (DCMD_ERR);
12850Sstevel@tonic-gate }
12860Sstevel@tonic-gate tcphdr_print(&tcph);
12870Sstevel@tonic-gate break;
12880Sstevel@tonic-gate }
12890Sstevel@tonic-gate case IPPROTO_UDP: {
12900Sstevel@tonic-gate struct udphdr udph;
12910Sstevel@tonic-gate
12920Sstevel@tonic-gate if (mdb_vread(&udph, sizeof (udph), addr) == -1) {
12930Sstevel@tonic-gate mdb_warn("failed to read UDP header at %p", addr);
12940Sstevel@tonic-gate return (DCMD_ERR);
12950Sstevel@tonic-gate }
12960Sstevel@tonic-gate udphdr_print(&udph);
12970Sstevel@tonic-gate break;
12980Sstevel@tonic-gate }
12990Sstevel@tonic-gate case IPPROTO_SCTP: {
13000Sstevel@tonic-gate sctp_hdr_t sctph;
13010Sstevel@tonic-gate
13020Sstevel@tonic-gate if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) {
13030Sstevel@tonic-gate mdb_warn("failed to read SCTP header at %p", addr);
13040Sstevel@tonic-gate return (DCMD_ERR);
13050Sstevel@tonic-gate }
13060Sstevel@tonic-gate sctphdr_print(&sctph);
13070Sstevel@tonic-gate break;
13080Sstevel@tonic-gate }
13090Sstevel@tonic-gate default:
13100Sstevel@tonic-gate break;
13110Sstevel@tonic-gate }
13120Sstevel@tonic-gate
13130Sstevel@tonic-gate return (DCMD_OK);
13140Sstevel@tonic-gate }
13150Sstevel@tonic-gate
13160Sstevel@tonic-gate static const mdb_bitmask_t ip_flags[] = {
13170Sstevel@tonic-gate { "DF", IPH_DF, IPH_DF },
13180Sstevel@tonic-gate { "MF", IPH_MF, IPH_MF },
13190Sstevel@tonic-gate { NULL, 0, 0 }
13200Sstevel@tonic-gate };
13210Sstevel@tonic-gate
13220Sstevel@tonic-gate /* ARGSUSED */
13230Sstevel@tonic-gate static int
iphdr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13240Sstevel@tonic-gate iphdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13250Sstevel@tonic-gate {
13260Sstevel@tonic-gate uint_t verbose = FALSE, force = FALSE;
13270Sstevel@tonic-gate ipha_t iph[1];
13280Sstevel@tonic-gate uint16_t ver, totlen, hdrlen, ipid, off, csum;
13290Sstevel@tonic-gate uintptr_t nxt_proto;
13300Sstevel@tonic-gate char exp_csum[8];
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate if (mdb_getopts(argc, argv,
13330Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose,
13340Sstevel@tonic-gate 'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc)
13350Sstevel@tonic-gate return (DCMD_USAGE);
13360Sstevel@tonic-gate
13370Sstevel@tonic-gate if (mdb_vread(iph, sizeof (*iph), addr) == -1) {
13380Sstevel@tonic-gate mdb_warn("failed to read IPv4 header at %p", addr);
13390Sstevel@tonic-gate return (DCMD_ERR);
13400Sstevel@tonic-gate }
13410Sstevel@tonic-gate
13420Sstevel@tonic-gate ver = (iph->ipha_version_and_hdr_length & 0xf0) >> 4;
13430Sstevel@tonic-gate if (ver != IPV4_VERSION) {
13440Sstevel@tonic-gate if (ver == IPV6_VERSION) {
13450Sstevel@tonic-gate return (ip6hdr(addr, flags, argc, argv));
13460Sstevel@tonic-gate } else if (!force) {
13470Sstevel@tonic-gate mdb_warn("unknown IP version: %d\n", ver);
13480Sstevel@tonic-gate return (DCMD_ERR);
13490Sstevel@tonic-gate }
13500Sstevel@tonic-gate }
13510Sstevel@tonic-gate
13520Sstevel@tonic-gate mdb_printf("%<b>IPv4 header%</b>\n");
13530Sstevel@tonic-gate mdb_printf("%-34s %-34s\n"
13540Sstevel@tonic-gate "%<u>%-4s %-4s %-5s %-5s %-6s %-5s %-5s %-6s %-8s %-6s%</u>\n",
13550Sstevel@tonic-gate "SRC", "DST",
13560Sstevel@tonic-gate "HLEN", "TOS", "LEN", "ID", "OFFSET", "TTL", "PROTO", "CHKSUM",
13570Sstevel@tonic-gate "EXP-CSUM", "FLGS");
13580Sstevel@tonic-gate
13590Sstevel@tonic-gate hdrlen = (iph->ipha_version_and_hdr_length & 0x0f) << 2;
13600Sstevel@tonic-gate mdb_nhconvert(&totlen, &iph->ipha_length, sizeof (totlen));
13610Sstevel@tonic-gate mdb_nhconvert(&ipid, &iph->ipha_ident, sizeof (ipid));
13620Sstevel@tonic-gate mdb_nhconvert(&off, &iph->ipha_fragment_offset_and_flags, sizeof (off));
13630Sstevel@tonic-gate if (hdrlen == IP_SIMPLE_HDR_LENGTH) {
13640Sstevel@tonic-gate if ((csum = ipcksum(iph, sizeof (*iph))) != 0)
13650Sstevel@tonic-gate csum = ~(~csum + ~iph->ipha_hdr_checksum);
13660Sstevel@tonic-gate else
13670Sstevel@tonic-gate csum = iph->ipha_hdr_checksum;
13680Sstevel@tonic-gate mdb_snprintf(exp_csum, 8, "%u", csum);
13690Sstevel@tonic-gate } else {
13700Sstevel@tonic-gate mdb_snprintf(exp_csum, 8, "<n/a>");
13710Sstevel@tonic-gate }
13720Sstevel@tonic-gate
13730Sstevel@tonic-gate mdb_printf("%-34I %-34I%\n"
13740Sstevel@tonic-gate "%-4d %-4d %-5hu %-5hu %-6hu %-5hu %-5hu %-6u %-8s <%5hb>\n",
13750Sstevel@tonic-gate iph->ipha_src, iph->ipha_dst,
13760Sstevel@tonic-gate hdrlen, iph->ipha_type_of_service, totlen, ipid,
13770Sstevel@tonic-gate (off << 3) & 0xffff, iph->ipha_ttl, iph->ipha_protocol,
13780Sstevel@tonic-gate iph->ipha_hdr_checksum, exp_csum, off, ip_flags);
13790Sstevel@tonic-gate
13800Sstevel@tonic-gate if (verbose) {
13810Sstevel@tonic-gate nxt_proto = addr + hdrlen;
13820Sstevel@tonic-gate return (transport_hdr(iph->ipha_protocol, nxt_proto));
13830Sstevel@tonic-gate } else {
13840Sstevel@tonic-gate return (DCMD_OK);
13850Sstevel@tonic-gate }
13860Sstevel@tonic-gate }
13870Sstevel@tonic-gate
13880Sstevel@tonic-gate /* ARGSUSED */
13890Sstevel@tonic-gate static int
ip6hdr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13900Sstevel@tonic-gate ip6hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13910Sstevel@tonic-gate {
13920Sstevel@tonic-gate uint_t verbose = FALSE, force = FALSE;
13930Sstevel@tonic-gate ip6_t iph[1];
13940Sstevel@tonic-gate int ver, class, flow;
13950Sstevel@tonic-gate uint16_t plen;
13960Sstevel@tonic-gate uintptr_t nxt_proto;
13970Sstevel@tonic-gate
13980Sstevel@tonic-gate if (mdb_getopts(argc, argv,
13990Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose,
14000Sstevel@tonic-gate 'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc)
14010Sstevel@tonic-gate return (DCMD_USAGE);
14020Sstevel@tonic-gate
14030Sstevel@tonic-gate if (mdb_vread(iph, sizeof (*iph), addr) == -1) {
14040Sstevel@tonic-gate mdb_warn("failed to read IPv6 header at %p", addr);
14050Sstevel@tonic-gate return (DCMD_ERR);
14060Sstevel@tonic-gate }
14070Sstevel@tonic-gate
14080Sstevel@tonic-gate ver = (iph->ip6_vfc & 0xf0) >> 4;
14090Sstevel@tonic-gate if (ver != IPV6_VERSION) {
14100Sstevel@tonic-gate if (ver == IPV4_VERSION) {
14110Sstevel@tonic-gate return (iphdr(addr, flags, argc, argv));
14120Sstevel@tonic-gate } else if (!force) {
14130Sstevel@tonic-gate mdb_warn("unknown IP version: %d\n", ver);
14140Sstevel@tonic-gate return (DCMD_ERR);
14150Sstevel@tonic-gate }
14160Sstevel@tonic-gate }
14170Sstevel@tonic-gate
14180Sstevel@tonic-gate mdb_printf("%<b>IPv6 header%</b>\n");
14190Sstevel@tonic-gate mdb_printf("%<u>%-26s %-26s %4s %7s %5s %3s %3s%</u>\n",
14200Sstevel@tonic-gate "SRC", "DST", "TCLS", "FLOW-ID", "PLEN", "NXT", "HOP");
14210Sstevel@tonic-gate
14220Sstevel@tonic-gate class = (iph->ip6_vcf & IPV6_FLOWINFO_TCLASS) >> 20;
14230Sstevel@tonic-gate mdb_nhconvert(&class, &class, sizeof (class));
14240Sstevel@tonic-gate flow = iph->ip6_vcf & IPV6_FLOWINFO_FLOWLABEL;
14250Sstevel@tonic-gate mdb_nhconvert(&flow, &flow, sizeof (flow));
14260Sstevel@tonic-gate mdb_nhconvert(&plen, &iph->ip6_plen, sizeof (plen));
14270Sstevel@tonic-gate
14280Sstevel@tonic-gate mdb_printf("%-26N %-26N %4d %7d %5hu %3d %3d\n",
14290Sstevel@tonic-gate &iph->ip6_src, &iph->ip6_dst,
14300Sstevel@tonic-gate class, flow, plen, iph->ip6_nxt, iph->ip6_hlim);
14310Sstevel@tonic-gate
14320Sstevel@tonic-gate if (verbose) {
14330Sstevel@tonic-gate nxt_proto = addr + sizeof (ip6_t);
14340Sstevel@tonic-gate return (transport_hdr(iph->ip6_nxt, nxt_proto));
14350Sstevel@tonic-gate } else {
14360Sstevel@tonic-gate return (DCMD_OK);
14370Sstevel@tonic-gate }
14380Sstevel@tonic-gate }
14390Sstevel@tonic-gate
14400Sstevel@tonic-gate int
nce(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)144111042SErik.Nordmark@Sun.COM nce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
144211042SErik.Nordmark@Sun.COM {
144311042SErik.Nordmark@Sun.COM nce_t nce;
144411042SErik.Nordmark@Sun.COM nce_cbdata_t nce_cb;
144511042SErik.Nordmark@Sun.COM int ipversion = 0;
144611042SErik.Nordmark@Sun.COM const char *opt_P = NULL, *opt_ill;
144711042SErik.Nordmark@Sun.COM
144811042SErik.Nordmark@Sun.COM if (mdb_getopts(argc, argv,
144911042SErik.Nordmark@Sun.COM 'i', MDB_OPT_STR, &opt_ill,
145011042SErik.Nordmark@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
145111042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
145211042SErik.Nordmark@Sun.COM
145311042SErik.Nordmark@Sun.COM if (opt_P != NULL) {
145411042SErik.Nordmark@Sun.COM if (strcmp("v4", opt_P) == 0) {
145511042SErik.Nordmark@Sun.COM ipversion = IPV4_VERSION;
145611042SErik.Nordmark@Sun.COM } else if (strcmp("v6", opt_P) == 0) {
145711042SErik.Nordmark@Sun.COM ipversion = IPV6_VERSION;
145811042SErik.Nordmark@Sun.COM } else {
145911042SErik.Nordmark@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P);
146011042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
146111042SErik.Nordmark@Sun.COM }
146211042SErik.Nordmark@Sun.COM }
146311042SErik.Nordmark@Sun.COM
146411042SErik.Nordmark@Sun.COM if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
146511042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s %5s %18s %?s %s %s %</u>\n",
146611042SErik.Nordmark@Sun.COM "ADDR", "INTF", "LLADDR", "FP_MP", "REFCNT",
146711042SErik.Nordmark@Sun.COM "NCE_ADDR");
146811042SErik.Nordmark@Sun.COM }
146911042SErik.Nordmark@Sun.COM
147011042SErik.Nordmark@Sun.COM bzero(&nce_cb, sizeof (nce_cb));
147111042SErik.Nordmark@Sun.COM if (opt_ill != NULL) {
147211042SErik.Nordmark@Sun.COM strcpy(nce_cb.nce_ill_name, opt_ill);
147311042SErik.Nordmark@Sun.COM }
147411042SErik.Nordmark@Sun.COM nce_cb.nce_ipversion = ipversion;
147511042SErik.Nordmark@Sun.COM
147611042SErik.Nordmark@Sun.COM if (flags & DCMD_ADDRSPEC) {
147711042SErik.Nordmark@Sun.COM (void) mdb_vread(&nce, sizeof (nce_t), addr);
147811042SErik.Nordmark@Sun.COM (void) nce_format(addr, &nce, &nce_cb);
147911042SErik.Nordmark@Sun.COM } else if (mdb_walk("nce", (mdb_walk_cb_t)nce_format, &nce_cb) == -1) {
148011042SErik.Nordmark@Sun.COM mdb_warn("failed to walk ire table");
148111042SErik.Nordmark@Sun.COM return (DCMD_ERR);
148211042SErik.Nordmark@Sun.COM }
148311042SErik.Nordmark@Sun.COM
148411042SErik.Nordmark@Sun.COM return (DCMD_OK);
148511042SErik.Nordmark@Sun.COM }
148611042SErik.Nordmark@Sun.COM
148711042SErik.Nordmark@Sun.COM /* ARGSUSED */
148811042SErik.Nordmark@Sun.COM static int
dce_format(uintptr_t addr,const dce_t * dcep,void * dce_cb_arg)148911042SErik.Nordmark@Sun.COM dce_format(uintptr_t addr, const dce_t *dcep, void *dce_cb_arg)
149011042SErik.Nordmark@Sun.COM {
149111042SErik.Nordmark@Sun.COM static const mdb_bitmask_t dmasks[] = {
149211042SErik.Nordmark@Sun.COM { "D", DCEF_DEFAULT, DCEF_DEFAULT },
149311042SErik.Nordmark@Sun.COM { "P", DCEF_PMTU, DCEF_PMTU },
149411042SErik.Nordmark@Sun.COM { "U", DCEF_UINFO, DCEF_UINFO },
149511042SErik.Nordmark@Sun.COM { "S", DCEF_TOO_SMALL_PMTU, DCEF_TOO_SMALL_PMTU },
149611042SErik.Nordmark@Sun.COM { NULL, 0, 0 }
149711042SErik.Nordmark@Sun.COM };
149811042SErik.Nordmark@Sun.COM char flagsbuf[2 * A_CNT(dmasks)];
149911042SErik.Nordmark@Sun.COM int ipversion = *(int *)dce_cb_arg;
150011042SErik.Nordmark@Sun.COM boolean_t condemned = dcep->dce_generation == DCE_GENERATION_CONDEMNED;
150111042SErik.Nordmark@Sun.COM
150211042SErik.Nordmark@Sun.COM if (ipversion != 0 && ipversion != dcep->dce_ipversion)
150311042SErik.Nordmark@Sun.COM return (WALK_NEXT);
150411042SErik.Nordmark@Sun.COM
150511042SErik.Nordmark@Sun.COM mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%b", dcep->dce_flags,
150611042SErik.Nordmark@Sun.COM dmasks);
150711042SErik.Nordmark@Sun.COM
150811042SErik.Nordmark@Sun.COM switch (dcep->dce_ipversion) {
150911042SErik.Nordmark@Sun.COM case IPV4_VERSION:
151011042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30I %</u>\n", addr, condemned ?
151111042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v4addr);
151211042SErik.Nordmark@Sun.COM break;
151311042SErik.Nordmark@Sun.COM case IPV6_VERSION:
151411042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30N %</u>\n", addr, condemned ?
151511042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v6addr);
151611042SErik.Nordmark@Sun.COM break;
151711042SErik.Nordmark@Sun.COM default:
151811042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?p%3s %8s %8d %30s %</u>\n", addr, condemned ?
151911042SErik.Nordmark@Sun.COM "(C)" : "", flagsbuf, dcep->dce_pmtu, "");
152011042SErik.Nordmark@Sun.COM }
152111042SErik.Nordmark@Sun.COM
152211042SErik.Nordmark@Sun.COM return (WALK_NEXT);
152311042SErik.Nordmark@Sun.COM }
152411042SErik.Nordmark@Sun.COM
152511042SErik.Nordmark@Sun.COM int
dce(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)152611042SErik.Nordmark@Sun.COM dce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
152711042SErik.Nordmark@Sun.COM {
152811042SErik.Nordmark@Sun.COM dce_t dce;
152911042SErik.Nordmark@Sun.COM const char *opt_P = NULL;
153011042SErik.Nordmark@Sun.COM const char *zone_name = NULL;
153111042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL;
153211042SErik.Nordmark@Sun.COM int ipversion = 0;
153311042SErik.Nordmark@Sun.COM
153411042SErik.Nordmark@Sun.COM if (mdb_getopts(argc, argv,
153511042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name,
153611042SErik.Nordmark@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
153711042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
153811042SErik.Nordmark@Sun.COM
153911042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */
154011042SErik.Nordmark@Sun.COM if (zone_name != NULL) {
154111042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name);
154211042SErik.Nordmark@Sun.COM if (ipst == NULL)
154311042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
154411042SErik.Nordmark@Sun.COM }
154511042SErik.Nordmark@Sun.COM
154611042SErik.Nordmark@Sun.COM if (opt_P != NULL) {
154711042SErik.Nordmark@Sun.COM if (strcmp("v4", opt_P) == 0) {
154811042SErik.Nordmark@Sun.COM ipversion = IPV4_VERSION;
154911042SErik.Nordmark@Sun.COM } else if (strcmp("v6", opt_P) == 0) {
155011042SErik.Nordmark@Sun.COM ipversion = IPV6_VERSION;
155111042SErik.Nordmark@Sun.COM } else {
155211042SErik.Nordmark@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P);
155311042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
155411042SErik.Nordmark@Sun.COM }
155511042SErik.Nordmark@Sun.COM }
155611042SErik.Nordmark@Sun.COM
155711042SErik.Nordmark@Sun.COM if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
155811042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s%3s %8s %8s %30s %</u>\n",
155911042SErik.Nordmark@Sun.COM "ADDR", "", "FLAGS", "PMTU", "DST_ADDR");
156011042SErik.Nordmark@Sun.COM }
156111042SErik.Nordmark@Sun.COM
156211042SErik.Nordmark@Sun.COM if (flags & DCMD_ADDRSPEC) {
156311042SErik.Nordmark@Sun.COM (void) mdb_vread(&dce, sizeof (dce_t), addr);
156411042SErik.Nordmark@Sun.COM (void) dce_format(addr, &dce, &ipversion);
156511042SErik.Nordmark@Sun.COM } else if (mdb_pwalk("dce", (mdb_walk_cb_t)dce_format, &ipversion,
156611042SErik.Nordmark@Sun.COM (uintptr_t)ipst) == -1) {
156711042SErik.Nordmark@Sun.COM mdb_warn("failed to walk dce cache");
156811042SErik.Nordmark@Sun.COM return (DCMD_ERR);
156911042SErik.Nordmark@Sun.COM }
157011042SErik.Nordmark@Sun.COM
157111042SErik.Nordmark@Sun.COM return (DCMD_OK);
157211042SErik.Nordmark@Sun.COM }
157311042SErik.Nordmark@Sun.COM
157411042SErik.Nordmark@Sun.COM int
ire(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)15750Sstevel@tonic-gate ire(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
15760Sstevel@tonic-gate {
15770Sstevel@tonic-gate uint_t verbose = FALSE;
15780Sstevel@tonic-gate ire_t ire;
15795940Ssowmini ire_cbdata_t ire_cb;
15805940Ssowmini int ipversion = 0;
15815940Ssowmini const char *opt_P = NULL;
158211042SErik.Nordmark@Sun.COM const char *zone_name = NULL;
158311042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL;
15840Sstevel@tonic-gate
15850Sstevel@tonic-gate if (mdb_getopts(argc, argv,
15865940Ssowmini 'v', MDB_OPT_SETBITS, TRUE, &verbose,
158711042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name,
15885940Ssowmini 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
15890Sstevel@tonic-gate return (DCMD_USAGE);
15900Sstevel@tonic-gate
159111042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */
159211042SErik.Nordmark@Sun.COM if (zone_name != NULL) {
159311042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name);
159411042SErik.Nordmark@Sun.COM if (ipst == NULL)
159511042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
159611042SErik.Nordmark@Sun.COM }
159711042SErik.Nordmark@Sun.COM
15985940Ssowmini if (opt_P != NULL) {
15995940Ssowmini if (strcmp("v4", opt_P) == 0) {
16005940Ssowmini ipversion = IPV4_VERSION;
16015940Ssowmini } else if (strcmp("v6", opt_P) == 0) {
16025940Ssowmini ipversion = IPV6_VERSION;
16035940Ssowmini } else {
16045940Ssowmini mdb_warn("invalid protocol '%s'\n", opt_P);
16055940Ssowmini return (DCMD_USAGE);
16065940Ssowmini }
16075940Ssowmini }
16085940Ssowmini
16090Sstevel@tonic-gate if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
16100Sstevel@tonic-gate
16110Sstevel@tonic-gate if (verbose) {
16120Sstevel@tonic-gate mdb_printf("%?s %40s %-20s%\n"
16130Sstevel@tonic-gate "%?s %40s %-20s%\n"
161411042SErik.Nordmark@Sun.COM "%<u>%?s %40s %4s %-20s %s%</u>\n",
16150Sstevel@tonic-gate "ADDR", "SRC", "TYPE",
16160Sstevel@tonic-gate "", "DST", "MARKS",
161711042SErik.Nordmark@Sun.COM "", "STACK", "ZONE", "FLAGS", "INTF");
16180Sstevel@tonic-gate } else {
161911042SErik.Nordmark@Sun.COM mdb_printf("%<u>%?s %30s %30s %5s %4s %s%</u>\n",
162011042SErik.Nordmark@Sun.COM "ADDR", "SRC", "DST", "STACK", "ZONE", "INTF");
16210Sstevel@tonic-gate }
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate
16245940Ssowmini ire_cb.verbose = (verbose == TRUE);
16255940Ssowmini ire_cb.ire_ipversion = ipversion;
16265940Ssowmini
16270Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) {
16280Sstevel@tonic-gate (void) mdb_vread(&ire, sizeof (ire_t), addr);
16295940Ssowmini (void) ire_format(addr, &ire, &ire_cb);
163011042SErik.Nordmark@Sun.COM } else if (mdb_pwalk("ire", (mdb_walk_cb_t)ire_format, &ire_cb,
163111042SErik.Nordmark@Sun.COM (uintptr_t)ipst) == -1) {
16320Sstevel@tonic-gate mdb_warn("failed to walk ire table");
16330Sstevel@tonic-gate return (DCMD_ERR);
16340Sstevel@tonic-gate }
16350Sstevel@tonic-gate
16360Sstevel@tonic-gate return (DCMD_OK);
16370Sstevel@tonic-gate }
16380Sstevel@tonic-gate
16390Sstevel@tonic-gate static size_t
mi_osize(const queue_t * q)16400Sstevel@tonic-gate mi_osize(const queue_t *q)
16410Sstevel@tonic-gate {
16420Sstevel@tonic-gate /*
16430Sstevel@tonic-gate * The code in common/inet/mi.c allocates an extra word to store the
16440Sstevel@tonic-gate * size of the allocation. An mi_o_s is thus a size_t plus an mi_o_s.
16450Sstevel@tonic-gate */
16460Sstevel@tonic-gate struct mi_block {
16470Sstevel@tonic-gate size_t mi_nbytes;
16480Sstevel@tonic-gate struct mi_o_s mi_o;
16490Sstevel@tonic-gate } m;
16500Sstevel@tonic-gate
16510Sstevel@tonic-gate if (mdb_vread(&m, sizeof (m), (uintptr_t)q->q_ptr -
16520Sstevel@tonic-gate sizeof (m)) == sizeof (m))
16530Sstevel@tonic-gate return (m.mi_nbytes - sizeof (m));
16540Sstevel@tonic-gate
16550Sstevel@tonic-gate return (0);
16560Sstevel@tonic-gate }
16570Sstevel@tonic-gate
16580Sstevel@tonic-gate static void
ip_ill_qinfo(const queue_t * q,char * buf,size_t nbytes)16590Sstevel@tonic-gate ip_ill_qinfo(const queue_t *q, char *buf, size_t nbytes)
16600Sstevel@tonic-gate {
16610Sstevel@tonic-gate char name[32];
16620Sstevel@tonic-gate ill_t ill;
16630Sstevel@tonic-gate
16640Sstevel@tonic-gate if (mdb_vread(&ill, sizeof (ill),
16650Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill) &&
16660Sstevel@tonic-gate mdb_readstr(name, sizeof (name), (uintptr_t)ill.ill_name) > 0)
16670Sstevel@tonic-gate (void) mdb_snprintf(buf, nbytes, "if: %s", name);
16680Sstevel@tonic-gate }
16690Sstevel@tonic-gate
16700Sstevel@tonic-gate void
ip_qinfo(const queue_t * q,char * buf,size_t nbytes)16710Sstevel@tonic-gate ip_qinfo(const queue_t *q, char *buf, size_t nbytes)
16720Sstevel@tonic-gate {
16730Sstevel@tonic-gate size_t size = mi_osize(q);
16740Sstevel@tonic-gate
16750Sstevel@tonic-gate if (size == sizeof (ill_t))
16760Sstevel@tonic-gate ip_ill_qinfo(q, buf, nbytes);
16770Sstevel@tonic-gate }
16780Sstevel@tonic-gate
16790Sstevel@tonic-gate uintptr_t
ip_rnext(const queue_t * q)16800Sstevel@tonic-gate ip_rnext(const queue_t *q)
16810Sstevel@tonic-gate {
16820Sstevel@tonic-gate size_t size = mi_osize(q);
16830Sstevel@tonic-gate ill_t ill;
16840Sstevel@tonic-gate
16850Sstevel@tonic-gate if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill),
16860Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill))
16870Sstevel@tonic-gate return ((uintptr_t)ill.ill_rq);
16880Sstevel@tonic-gate
16890Sstevel@tonic-gate return (NULL);
16900Sstevel@tonic-gate }
16910Sstevel@tonic-gate
16920Sstevel@tonic-gate uintptr_t
ip_wnext(const queue_t * q)16930Sstevel@tonic-gate ip_wnext(const queue_t *q)
16940Sstevel@tonic-gate {
16950Sstevel@tonic-gate size_t size = mi_osize(q);
16960Sstevel@tonic-gate ill_t ill;
16970Sstevel@tonic-gate
16980Sstevel@tonic-gate if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill),
16990Sstevel@tonic-gate (uintptr_t)q->q_ptr) == sizeof (ill))
17000Sstevel@tonic-gate return ((uintptr_t)ill.ill_wq);
17010Sstevel@tonic-gate
17020Sstevel@tonic-gate return (NULL);
17030Sstevel@tonic-gate }
17040Sstevel@tonic-gate
17050Sstevel@tonic-gate /*
17060Sstevel@tonic-gate * Print the core fields in an squeue_t. With the "-v" argument,
17070Sstevel@tonic-gate * provide more verbose output.
17080Sstevel@tonic-gate */
17090Sstevel@tonic-gate static int
squeue(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)17100Sstevel@tonic-gate squeue(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
17110Sstevel@tonic-gate {
17120Sstevel@tonic-gate unsigned int i;
17130Sstevel@tonic-gate unsigned int verbose = FALSE;
17140Sstevel@tonic-gate const int SQUEUE_STATEDELT = (int)(sizeof (uintptr_t) + 9);
17150Sstevel@tonic-gate boolean_t arm;
17160Sstevel@tonic-gate squeue_t squeue;
17170Sstevel@tonic-gate
17180Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
17190Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`squeue_cache", "ip`squeue",
17200Sstevel@tonic-gate argc, argv) == -1) {
17210Sstevel@tonic-gate mdb_warn("failed to walk squeue cache");
17220Sstevel@tonic-gate return (DCMD_ERR);
17230Sstevel@tonic-gate }
17240Sstevel@tonic-gate return (DCMD_OK);
17250Sstevel@tonic-gate }
17260Sstevel@tonic-gate
17270Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL)
17280Sstevel@tonic-gate != argc)
17290Sstevel@tonic-gate return (DCMD_USAGE);
17300Sstevel@tonic-gate
17310Sstevel@tonic-gate if (!DCMD_HDRSPEC(flags) && verbose)
17320Sstevel@tonic-gate mdb_printf("\n\n");
17330Sstevel@tonic-gate
17340Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) || verbose) {
17350Sstevel@tonic-gate mdb_printf("%?s %-5s %-3s %?s %?s %?s\n",
17360Sstevel@tonic-gate "ADDR", "STATE", "CPU",
17370Sstevel@tonic-gate "FIRST", "LAST", "WORKER");
17380Sstevel@tonic-gate }
17390Sstevel@tonic-gate
17400Sstevel@tonic-gate if (mdb_vread(&squeue, sizeof (squeue_t), addr) == -1) {
17410Sstevel@tonic-gate mdb_warn("cannot read squeue_t at %p", addr);
17420Sstevel@tonic-gate return (DCMD_ERR);
17430Sstevel@tonic-gate }
17440Sstevel@tonic-gate
17450Sstevel@tonic-gate mdb_printf("%0?p %05x %3d %0?p %0?p %0?p\n",
17460Sstevel@tonic-gate addr, squeue.sq_state, squeue.sq_bind,
17470Sstevel@tonic-gate squeue.sq_first, squeue.sq_last, squeue.sq_worker);
17480Sstevel@tonic-gate
17490Sstevel@tonic-gate if (!verbose)
17500Sstevel@tonic-gate return (DCMD_OK);
17510Sstevel@tonic-gate
17520Sstevel@tonic-gate arm = B_TRUE;
17530Sstevel@tonic-gate for (i = 0; squeue_states[i].bit_name != NULL; i++) {
17540Sstevel@tonic-gate if (((squeue.sq_state) & (1 << i)) == 0)
17550Sstevel@tonic-gate continue;
17560Sstevel@tonic-gate
17570Sstevel@tonic-gate if (arm) {
17580Sstevel@tonic-gate mdb_printf("%*s|\n", SQUEUE_STATEDELT, "");
17590Sstevel@tonic-gate mdb_printf("%*s+--> ", SQUEUE_STATEDELT, "");
17600Sstevel@tonic-gate arm = B_FALSE;
17610Sstevel@tonic-gate } else
17620Sstevel@tonic-gate mdb_printf("%*s ", SQUEUE_STATEDELT, "");
17630Sstevel@tonic-gate
17640Sstevel@tonic-gate mdb_printf("%-12s %s\n", squeue_states[i].bit_name,
17650Sstevel@tonic-gate squeue_states[i].bit_descr);
17660Sstevel@tonic-gate }
17670Sstevel@tonic-gate
17680Sstevel@tonic-gate return (DCMD_OK);
17690Sstevel@tonic-gate }
17700Sstevel@tonic-gate
17710Sstevel@tonic-gate static void
ip_squeue_help(void)17720Sstevel@tonic-gate ip_squeue_help(void)
17730Sstevel@tonic-gate {
17740Sstevel@tonic-gate mdb_printf("Print the core information for a given NCA squeue_t.\n\n");
17750Sstevel@tonic-gate mdb_printf("Options:\n");
17760Sstevel@tonic-gate mdb_printf("\t-v\tbe verbose (more descriptive)\n");
17770Sstevel@tonic-gate }
17780Sstevel@tonic-gate
17795023Scarlsonj /*
17805023Scarlsonj * This is called by ::th_trace (via a callback) when walking the th_hash
17815023Scarlsonj * list. It calls modent to find the entries.
17825023Scarlsonj */
17835023Scarlsonj /* ARGSUSED */
17845023Scarlsonj static int
modent_summary(uintptr_t addr,const void * data,void * private)17855023Scarlsonj modent_summary(uintptr_t addr, const void *data, void *private)
17865023Scarlsonj {
17875023Scarlsonj th_walk_data_t *thw = private;
17885023Scarlsonj const struct mod_hash_entry *mhe = data;
17895023Scarlsonj th_trace_t th;
17905023Scarlsonj
17915023Scarlsonj if (mdb_vread(&th, sizeof (th), (uintptr_t)mhe->mhe_val) == -1) {
17925023Scarlsonj mdb_warn("failed to read th_trace_t %p", mhe->mhe_val);
17935023Scarlsonj return (WALK_ERR);
17945023Scarlsonj }
17955023Scarlsonj
17965023Scarlsonj if (th.th_refcnt == 0 && thw->thw_non_zero_only)
17975023Scarlsonj return (WALK_NEXT);
17985023Scarlsonj
17995023Scarlsonj if (!thw->thw_match) {
18005023Scarlsonj mdb_printf("%?p %?p %?p %8d %?p\n", thw->thw_ipst, mhe->mhe_key,
18015023Scarlsonj mhe->mhe_val, th.th_refcnt, th.th_id);
18025023Scarlsonj } else if (thw->thw_matchkey == (uintptr_t)mhe->mhe_key) {
18035023Scarlsonj int i, j, k;
18045023Scarlsonj tr_buf_t *tr;
18055023Scarlsonj
18065023Scarlsonj mdb_printf("Object %p in IP stack %p:\n", mhe->mhe_key,
18075023Scarlsonj thw->thw_ipst);
18085023Scarlsonj i = th.th_trace_lastref;
18095023Scarlsonj mdb_printf("\tThread %p refcnt %d:\n", th.th_id,
18105023Scarlsonj th.th_refcnt);
18115023Scarlsonj for (j = TR_BUF_MAX; j > 0; j--) {
18125023Scarlsonj tr = th.th_trbuf + i;
18135023Scarlsonj if (tr->tr_depth == 0 || tr->tr_depth > TR_STACK_DEPTH)
18145023Scarlsonj break;
18155023Scarlsonj mdb_printf("\t T%+ld:\n", tr->tr_time -
18165023Scarlsonj thw->thw_lbolt);
18175023Scarlsonj for (k = 0; k < tr->tr_depth; k++)
18185023Scarlsonj mdb_printf("\t\t%a\n", tr->tr_stack[k]);
18195023Scarlsonj if (--i < 0)
18205023Scarlsonj i = TR_BUF_MAX - 1;
18215023Scarlsonj }
18225023Scarlsonj }
18235023Scarlsonj return (WALK_NEXT);
18245023Scarlsonj }
18255023Scarlsonj
18265023Scarlsonj /*
18275023Scarlsonj * This is called by ::th_trace (via a callback) when walking the th_hash
18285023Scarlsonj * list. It calls modent to find the entries.
18295023Scarlsonj */
18305023Scarlsonj /* ARGSUSED */
18315023Scarlsonj static int
th_hash_summary(uintptr_t addr,const void * data,void * private)18325023Scarlsonj th_hash_summary(uintptr_t addr, const void *data, void *private)
18335023Scarlsonj {
18345023Scarlsonj const th_hash_t *thh = data;
18355023Scarlsonj th_walk_data_t *thw = private;
18365023Scarlsonj
18375023Scarlsonj thw->thw_ipst = (uintptr_t)thh->thh_ipst;
18385023Scarlsonj return (mdb_pwalk("modent", modent_summary, private,
18395023Scarlsonj (uintptr_t)thh->thh_hash));
18405023Scarlsonj }
18415023Scarlsonj
18425023Scarlsonj /*
18435023Scarlsonj * Print or summarize the th_trace_t structures.
18445023Scarlsonj */
18455023Scarlsonj static int
th_trace(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)18465023Scarlsonj th_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
18475023Scarlsonj {
18485023Scarlsonj th_walk_data_t thw;
18495023Scarlsonj
18505023Scarlsonj (void) memset(&thw, 0, sizeof (thw));
18515023Scarlsonj
18525023Scarlsonj if (mdb_getopts(argc, argv,
18535023Scarlsonj 'n', MDB_OPT_SETBITS, TRUE, &thw.thw_non_zero_only,
18545023Scarlsonj NULL) != argc)
18555023Scarlsonj return (DCMD_USAGE);
18565023Scarlsonj
18575023Scarlsonj if (!(flags & DCMD_ADDRSPEC)) {
18585023Scarlsonj /*
18595023Scarlsonj * No address specified. Walk all of the th_hash_t in the
18605023Scarlsonj * system, and summarize the th_trace_t entries in each.
18615023Scarlsonj */
18625023Scarlsonj mdb_printf("%?s %?s %?s %8s %?s\n",
18635023Scarlsonj "IPSTACK", "OBJECT", "TRACE", "REFCNT", "THREAD");
18645023Scarlsonj thw.thw_match = B_FALSE;
18655023Scarlsonj } else {
18665023Scarlsonj thw.thw_match = B_TRUE;
18675023Scarlsonj thw.thw_matchkey = addr;
186811066Srafael.vanoni@sun.com
186911066Srafael.vanoni@sun.com if ((thw.thw_lbolt = (clock_t)mdb_get_lbolt()) == -1) {
18705023Scarlsonj mdb_warn("failed to read lbolt");
18715023Scarlsonj return (DCMD_ERR);
18725023Scarlsonj }
18735023Scarlsonj }
18745023Scarlsonj if (mdb_pwalk("th_hash", th_hash_summary, &thw, NULL) == -1) {
18755023Scarlsonj mdb_warn("can't walk th_hash entries");
18765023Scarlsonj return (DCMD_ERR);
18775023Scarlsonj }
18785023Scarlsonj return (DCMD_OK);
18795023Scarlsonj }
18805023Scarlsonj
18815023Scarlsonj static void
th_trace_help(void)18825023Scarlsonj th_trace_help(void)
18835023Scarlsonj {
188411042SErik.Nordmark@Sun.COM mdb_printf("If given an address of an ill_t, ipif_t, ire_t, or ncec_t, "
18855023Scarlsonj "print the\n"
18865023Scarlsonj "corresponding th_trace_t structure in detail. Otherwise, if no "
18875023Scarlsonj "address is\n"
18885023Scarlsonj "given, then summarize all th_trace_t structures.\n\n");
18895023Scarlsonj mdb_printf("Options:\n"
18905023Scarlsonj "\t-n\tdisplay only entries with non-zero th_refcnt\n");
18915023Scarlsonj }
18925023Scarlsonj
18930Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
18949089SVasumathi.Sundaram@Sun.COM { "conn_status", ":",
18959089SVasumathi.Sundaram@Sun.COM "display connection structures from ipcl hash tables",
18969089SVasumathi.Sundaram@Sun.COM conn_status, conn_status_help },
18979089SVasumathi.Sundaram@Sun.COM { "srcid_status", ":",
18989089SVasumathi.Sundaram@Sun.COM "display connection structures from ipcl hash tables",
18999089SVasumathi.Sundaram@Sun.COM srcid_status },
190011042SErik.Nordmark@Sun.COM { "ill", "?[-v] [-P v4 | v6] [-s exclusive-ip-zone-name]",
190111042SErik.Nordmark@Sun.COM "display ill_t structures", ill, ill_help },
19020Sstevel@tonic-gate { "illif", "?[-P v4 | v6]",
19030Sstevel@tonic-gate "display or filter IP Lower Level InterFace structures", illif,
19040Sstevel@tonic-gate illif_help },
19050Sstevel@tonic-gate { "iphdr", ":[-vf]", "display an IPv4 header", iphdr },
19060Sstevel@tonic-gate { "ip6hdr", ":[-vf]", "display an IPv6 header", ip6hdr },
19079089SVasumathi.Sundaram@Sun.COM { "ipif", "?[-v] [-P v4 | v6]", "display ipif structures",
19089089SVasumathi.Sundaram@Sun.COM ipif, ipif_help },
190911042SErik.Nordmark@Sun.COM { "ire", "?[-v] [-P v4|v6] [-s exclusive-ip-zone-name]",
19105940Ssowmini "display Internet Route Entry structures", ire },
191111042SErik.Nordmark@Sun.COM { "nce", "?[-P v4|v6] [-i <interface>]",
191211042SErik.Nordmark@Sun.COM "display interface-specific Neighbor Cache structures", nce },
191311042SErik.Nordmark@Sun.COM { "ncec", "?[-P v4 | v6]", "display Neighbor Cache Entry structures",
191411042SErik.Nordmark@Sun.COM ncec },
191511042SErik.Nordmark@Sun.COM { "dce", "?[-P v4|v6] [-s exclusive-ip-zone-name]",
191611042SErik.Nordmark@Sun.COM "display Destination Cache Entry structures", dce },
19170Sstevel@tonic-gate { "squeue", ":[-v]", "print core squeue_t info", squeue,
19180Sstevel@tonic-gate ip_squeue_help },
19190Sstevel@tonic-gate { "tcphdr", ":", "display a TCP header", tcphdr },
19200Sstevel@tonic-gate { "udphdr", ":", "display an UDP header", udphdr },
19210Sstevel@tonic-gate { "sctphdr", ":", "display an SCTP header", sctphdr },
19225023Scarlsonj { "th_trace", "?[-n]", "display th_trace_t structures", th_trace,
19235023Scarlsonj th_trace_help },
19240Sstevel@tonic-gate { NULL }
19250Sstevel@tonic-gate };
19260Sstevel@tonic-gate
19270Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
19289089SVasumathi.Sundaram@Sun.COM { "conn_status", "walk list of conn_t structures",
19299089SVasumathi.Sundaram@Sun.COM ip_stacks_common_walk_init, conn_status_walk_step, NULL },
19303448Sdh155122 { "illif", "walk list of ill interface types for all stacks",
19315940Ssowmini ip_stacks_common_walk_init, illif_walk_step, NULL },
19323448Sdh155122 { "illif_stack", "walk list of ill interface types",
19333448Sdh155122 illif_stack_walk_init, illif_stack_walk_step,
19343448Sdh155122 illif_stack_walk_fini },
193511042SErik.Nordmark@Sun.COM { "ill", "walk active ill_t structures for all stacks",
19369089SVasumathi.Sundaram@Sun.COM ill_walk_init, ill_walk_step, NULL },
19379089SVasumathi.Sundaram@Sun.COM { "ipif", "walk list of ipif structures for all stacks",
19389089SVasumathi.Sundaram@Sun.COM ipif_walk_init, ipif_walk_step, NULL },
19399089SVasumathi.Sundaram@Sun.COM { "ipif_list", "walk the linked list of ipif structures "
19409089SVasumathi.Sundaram@Sun.COM "for a given ill",
19419089SVasumathi.Sundaram@Sun.COM ip_list_walk_init, ip_list_walk_step,
19429089SVasumathi.Sundaram@Sun.COM ip_list_walk_fini, &ipif_walk_arg },
19439089SVasumathi.Sundaram@Sun.COM { "srcid", "walk list of srcid_map structures for all stacks",
19449089SVasumathi.Sundaram@Sun.COM ip_stacks_common_walk_init, srcid_walk_step, NULL },
19459089SVasumathi.Sundaram@Sun.COM { "srcid_list", "walk list of srcid_map structures for a stack",
19469089SVasumathi.Sundaram@Sun.COM ip_list_walk_init, ip_list_walk_step, ip_list_walk_fini,
19479089SVasumathi.Sundaram@Sun.COM &srcid_walk_arg },
19480Sstevel@tonic-gate { "ire", "walk active ire_t structures",
19490Sstevel@tonic-gate ire_walk_init, ire_walk_step, NULL },
19503448Sdh155122 { "ire_next", "walk ire_t structures in the ctable",
19513448Sdh155122 ire_next_walk_init, ire_next_walk_step, NULL },
195211042SErik.Nordmark@Sun.COM { "nce", "walk active nce_t structures",
195311042SErik.Nordmark@Sun.COM nce_walk_init, nce_walk_step, NULL },
195411042SErik.Nordmark@Sun.COM { "dce", "walk active dce_t structures",
195511042SErik.Nordmark@Sun.COM dce_walk_init, dce_walk_step, NULL },
19563448Sdh155122 { "ip_stacks", "walk all the ip_stack_t",
195711754SKacheong.Poon@Sun.COM ns_walk_init, ip_stacks_walk_step, NULL },
195811754SKacheong.Poon@Sun.COM { "tcp_stacks", "walk all the tcp_stack_t",
195911754SKacheong.Poon@Sun.COM ns_walk_init, tcp_stacks_walk_step, NULL },
196011754SKacheong.Poon@Sun.COM { "sctp_stacks", "walk all the sctp_stack_t",
196111754SKacheong.Poon@Sun.COM ns_walk_init, sctp_stacks_walk_step, NULL },
196211754SKacheong.Poon@Sun.COM { "udp_stacks", "walk all the udp_stack_t",
196311754SKacheong.Poon@Sun.COM ns_walk_init, udp_stacks_walk_step, NULL },
19645023Scarlsonj { "th_hash", "walk all the th_hash_t entries",
19655023Scarlsonj th_hash_walk_init, th_hash_walk_step, NULL },
196611042SErik.Nordmark@Sun.COM { "ncec", "walk list of ncec structures for all stacks",
196711042SErik.Nordmark@Sun.COM ip_stacks_common_walk_init, ncec_walk_step, NULL },
196811042SErik.Nordmark@Sun.COM { "ncec_stack", "walk list of ncec structures",
196911042SErik.Nordmark@Sun.COM ncec_stack_walk_init, ncec_stack_walk_step,
197011042SErik.Nordmark@Sun.COM ncec_stack_walk_fini},
19719089SVasumathi.Sundaram@Sun.COM { "udp_hash", "walk list of conn_t structures in ips_ipcl_udp_fanout",
19729089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step,
19739089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &udp_hash_arg},
19749089SVasumathi.Sundaram@Sun.COM { "conn_hash", "walk list of conn_t structures in ips_ipcl_conn_fanout",
19759089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step,
19769089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &conn_hash_arg},
19779089SVasumathi.Sundaram@Sun.COM { "bind_hash", "walk list of conn_t structures in ips_ipcl_bind_fanout",
19789089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step,
19799089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &bind_hash_arg},
19809089SVasumathi.Sundaram@Sun.COM { "proto_hash", "walk list of conn_t structures in "
19819089SVasumathi.Sundaram@Sun.COM "ips_ipcl_proto_fanout",
19829089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step,
19839089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &proto_hash_arg},
19849089SVasumathi.Sundaram@Sun.COM { "proto_v6_hash", "walk list of conn_t structures in "
19859089SVasumathi.Sundaram@Sun.COM "ips_ipcl_proto_fanout_v6",
19869089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init, ipcl_hash_walk_step,
19879089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini, &proto_v6_hash_arg},
198811754SKacheong.Poon@Sun.COM { "ilb_stacks", "walk all ilb_stack_t",
198911754SKacheong.Poon@Sun.COM ns_walk_init, ilb_stacks_walk_step, NULL },
199010946SSangeeta.Misra@Sun.COM { "ilb_rules", "walk ilb rules in a given ilb_stack_t",
199110946SSangeeta.Misra@Sun.COM ilb_rules_walk_init, ilb_rules_walk_step, NULL },
199210946SSangeeta.Misra@Sun.COM { "ilb_servers", "walk server in a given ilb_rule_t",
199310946SSangeeta.Misra@Sun.COM ilb_servers_walk_init, ilb_servers_walk_step, NULL },
199410946SSangeeta.Misra@Sun.COM { "ilb_nat_src", "walk NAT source table of a given ilb_stack_t",
199510946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_init, ilb_nat_src_walk_step,
199610946SSangeeta.Misra@Sun.COM ilb_common_walk_fini },
199710946SSangeeta.Misra@Sun.COM { "ilb_conns", "walk NAT table of a given ilb_stack_t",
199810946SSangeeta.Misra@Sun.COM ilb_conn_walk_init, ilb_conn_walk_step, ilb_common_walk_fini },
199910946SSangeeta.Misra@Sun.COM { "ilb_stickys", "walk sticky table of a given ilb_stack_t",
200010946SSangeeta.Misra@Sun.COM ilb_sticky_walk_init, ilb_sticky_walk_step,
200110946SSangeeta.Misra@Sun.COM ilb_common_walk_fini },
200211754SKacheong.Poon@Sun.COM { "tcps_sc", "walk all the per CPU stats counters of a tcp_stack_t",
200311754SKacheong.Poon@Sun.COM tcps_sc_walk_init, tcps_sc_walk_step, NULL },
20040Sstevel@tonic-gate { NULL }
20050Sstevel@tonic-gate };
20060Sstevel@tonic-gate
20070Sstevel@tonic-gate static const mdb_qops_t ip_qops = { ip_qinfo, ip_rnext, ip_wnext };
20080Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
20090Sstevel@tonic-gate
20100Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)20110Sstevel@tonic-gate _mdb_init(void)
20120Sstevel@tonic-gate {
20130Sstevel@tonic-gate GElf_Sym sym;
20140Sstevel@tonic-gate
20152546Scarlsonj if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0)
20160Sstevel@tonic-gate mdb_qops_install(&ip_qops, (uintptr_t)sym.st_value);
20170Sstevel@tonic-gate
20180Sstevel@tonic-gate return (&modinfo);
20190Sstevel@tonic-gate }
20200Sstevel@tonic-gate
20210Sstevel@tonic-gate void
_mdb_fini(void)20220Sstevel@tonic-gate _mdb_fini(void)
20230Sstevel@tonic-gate {
20240Sstevel@tonic-gate GElf_Sym sym;
20250Sstevel@tonic-gate
20262546Scarlsonj if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0)
20270Sstevel@tonic-gate mdb_qops_remove(&ip_qops, (uintptr_t)sym.st_value);
20280Sstevel@tonic-gate }
20295940Ssowmini
20305940Ssowmini static char *
ncec_state(int ncec_state)203111042SErik.Nordmark@Sun.COM ncec_state(int ncec_state)
20325940Ssowmini {
203311042SErik.Nordmark@Sun.COM switch (ncec_state) {
20345940Ssowmini case ND_UNCHANGED:
20355940Ssowmini return ("unchanged");
20365940Ssowmini case ND_INCOMPLETE:
20375940Ssowmini return ("incomplete");
20385940Ssowmini case ND_REACHABLE:
20395940Ssowmini return ("reachable");
20405940Ssowmini case ND_STALE:
20415940Ssowmini return ("stale");
20425940Ssowmini case ND_DELAY:
20435940Ssowmini return ("delay");
20445940Ssowmini case ND_PROBE:
20455940Ssowmini return ("probe");
20465940Ssowmini case ND_UNREACHABLE:
20475940Ssowmini return ("unreach");
20485940Ssowmini case ND_INITIAL:
20495940Ssowmini return ("initial");
20505940Ssowmini default:
20515940Ssowmini return ("??");
20525940Ssowmini }
20535940Ssowmini }
20545940Ssowmini
20555940Ssowmini static char *
ncec_l2_addr(const ncec_t * ncec,const ill_t * ill)205611042SErik.Nordmark@Sun.COM ncec_l2_addr(const ncec_t *ncec, const ill_t *ill)
205711042SErik.Nordmark@Sun.COM {
205811042SErik.Nordmark@Sun.COM uchar_t *h;
205911042SErik.Nordmark@Sun.COM static char addr_buf[L2MAXADDRSTRLEN];
206011042SErik.Nordmark@Sun.COM
206111042SErik.Nordmark@Sun.COM if (ncec->ncec_lladdr == NULL) {
206211042SErik.Nordmark@Sun.COM return ("None");
206311042SErik.Nordmark@Sun.COM }
206411042SErik.Nordmark@Sun.COM
206511042SErik.Nordmark@Sun.COM if (ill->ill_net_type == IRE_IF_RESOLVER) {
206611042SErik.Nordmark@Sun.COM
206711042SErik.Nordmark@Sun.COM if (ill->ill_phys_addr_length == 0)
206811042SErik.Nordmark@Sun.COM return ("None");
206911042SErik.Nordmark@Sun.COM h = mdb_zalloc(ill->ill_phys_addr_length, UM_SLEEP);
207011042SErik.Nordmark@Sun.COM if (mdb_vread(h, ill->ill_phys_addr_length,
207111042SErik.Nordmark@Sun.COM (uintptr_t)ncec->ncec_lladdr) == -1) {
207211042SErik.Nordmark@Sun.COM mdb_warn("failed to read hwaddr at %p",
207311042SErik.Nordmark@Sun.COM ncec->ncec_lladdr);
207411042SErik.Nordmark@Sun.COM return ("Unknown");
207511042SErik.Nordmark@Sun.COM }
207611042SErik.Nordmark@Sun.COM mdb_mac_addr(h, ill->ill_phys_addr_length,
207711042SErik.Nordmark@Sun.COM addr_buf, sizeof (addr_buf));
207811042SErik.Nordmark@Sun.COM } else {
207911042SErik.Nordmark@Sun.COM return ("None");
208011042SErik.Nordmark@Sun.COM }
208111042SErik.Nordmark@Sun.COM mdb_free(h, ill->ill_phys_addr_length);
208211042SErik.Nordmark@Sun.COM return (addr_buf);
208311042SErik.Nordmark@Sun.COM }
208411042SErik.Nordmark@Sun.COM
208511042SErik.Nordmark@Sun.COM static char *
nce_l2_addr(const nce_t * nce,const ill_t * ill)20865940Ssowmini nce_l2_addr(const nce_t *nce, const ill_t *ill)
20875940Ssowmini {
20885940Ssowmini uchar_t *h;
20895940Ssowmini static char addr_buf[L2MAXADDRSTRLEN];
20905940Ssowmini mblk_t mp;
20915940Ssowmini size_t mblen;
20925940Ssowmini
209311042SErik.Nordmark@Sun.COM if (nce->nce_dlur_mp == NULL)
20945940Ssowmini return ("None");
20955940Ssowmini
20965940Ssowmini if (ill->ill_net_type == IRE_IF_RESOLVER) {
20975940Ssowmini if (mdb_vread(&mp, sizeof (mblk_t),
209811042SErik.Nordmark@Sun.COM (uintptr_t)nce->nce_dlur_mp) == -1) {
209911042SErik.Nordmark@Sun.COM mdb_warn("failed to read nce_dlur_mp at %p",
210011042SErik.Nordmark@Sun.COM nce->nce_dlur_mp);
210111042SErik.Nordmark@Sun.COM return ("None");
21025940Ssowmini }
210311042SErik.Nordmark@Sun.COM if (ill->ill_phys_addr_length == 0)
21045940Ssowmini return ("None");
21055940Ssowmini mblen = mp.b_wptr - mp.b_rptr;
21065940Ssowmini if (mblen > (sizeof (dl_unitdata_req_t) + MAX_SAP_LEN) ||
210711042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length > MAX_SAP_LEN ||
210811042SErik.Nordmark@Sun.COM (NCE_LL_ADDR_OFFSET(ill) +
210911042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length) > mblen) {
211011042SErik.Nordmark@Sun.COM return ("Unknown");
21115940Ssowmini }
21125940Ssowmini h = mdb_zalloc(mblen, UM_SLEEP);
21135940Ssowmini if (mdb_vread(h, mblen, (uintptr_t)(mp.b_rptr)) == -1) {
21145940Ssowmini mdb_warn("failed to read hwaddr at %p",
21155940Ssowmini mp.b_rptr + NCE_LL_ADDR_OFFSET(ill));
21165940Ssowmini return ("Unknown");
21175940Ssowmini }
211811042SErik.Nordmark@Sun.COM mdb_mac_addr(h + NCE_LL_ADDR_OFFSET(ill),
211911042SErik.Nordmark@Sun.COM ill->ill_phys_addr_length, addr_buf, sizeof (addr_buf));
21205940Ssowmini } else {
21215940Ssowmini return ("None");
21225940Ssowmini }
21235940Ssowmini mdb_free(h, mblen);
21245940Ssowmini return (addr_buf);
21255940Ssowmini }
21265940Ssowmini
21275940Ssowmini static void
ncec_header(uint_t flags)212811042SErik.Nordmark@Sun.COM ncec_header(uint_t flags)
21295940Ssowmini {
21305940Ssowmini if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
21315940Ssowmini
21325940Ssowmini mdb_printf("%<u>%?s %-20s %-10s %-8s %-5s %s%</u>\n",
21335940Ssowmini "ADDR", "HW_ADDR", "STATE", "FLAGS", "ILL", "IP ADDR");
21345940Ssowmini }
21355940Ssowmini }
21365940Ssowmini
21375940Ssowmini int
ncec(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)213811042SErik.Nordmark@Sun.COM ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
21395940Ssowmini {
214011042SErik.Nordmark@Sun.COM ncec_t ncec;
214111042SErik.Nordmark@Sun.COM ncec_cbdata_t id;
21425940Ssowmini int ipversion = 0;
21435940Ssowmini const char *opt_P = NULL;
21445940Ssowmini
21455940Ssowmini if (mdb_getopts(argc, argv,
21465940Ssowmini 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
21475940Ssowmini return (DCMD_USAGE);
21485940Ssowmini
21495940Ssowmini if (opt_P != NULL) {
21505940Ssowmini if (strcmp("v4", opt_P) == 0) {
21515940Ssowmini ipversion = IPV4_VERSION;
21525940Ssowmini } else if (strcmp("v6", opt_P) == 0) {
21535940Ssowmini ipversion = IPV6_VERSION;
21545940Ssowmini } else {
21555940Ssowmini mdb_warn("invalid protocol '%s'\n", opt_P);
21565940Ssowmini return (DCMD_USAGE);
21575940Ssowmini }
21585940Ssowmini }
21595940Ssowmini
21605940Ssowmini if (flags & DCMD_ADDRSPEC) {
21615940Ssowmini
216211042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) {
216311042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec at %p\n", addr);
21645940Ssowmini return (DCMD_ERR);
21655940Ssowmini }
216611042SErik.Nordmark@Sun.COM if (ipversion != 0 && ncec.ncec_ipversion != ipversion) {
21675940Ssowmini mdb_printf("IP Version mismatch\n");
21685940Ssowmini return (DCMD_ERR);
21695940Ssowmini }
217011042SErik.Nordmark@Sun.COM ncec_header(flags);
217111042SErik.Nordmark@Sun.COM return (ncec_format(addr, &ncec, ipversion));
21725940Ssowmini
21735940Ssowmini } else {
217411042SErik.Nordmark@Sun.COM id.ncec_addr = addr;
217511042SErik.Nordmark@Sun.COM id.ncec_ipversion = ipversion;
217611042SErik.Nordmark@Sun.COM ncec_header(flags);
217711042SErik.Nordmark@Sun.COM if (mdb_walk("ncec", (mdb_walk_cb_t)ncec_cb, &id) == -1) {
217811042SErik.Nordmark@Sun.COM mdb_warn("failed to walk ncec table\n");
21795940Ssowmini return (DCMD_ERR);
21805940Ssowmini }
21815940Ssowmini }
21825940Ssowmini return (DCMD_OK);
21835940Ssowmini }
21845940Ssowmini
21855940Ssowmini static int
ncec_format(uintptr_t addr,const ncec_t * ncec,int ipversion)218611042SErik.Nordmark@Sun.COM ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion)
21875940Ssowmini {
218811042SErik.Nordmark@Sun.COM static const mdb_bitmask_t ncec_flags[] = {
218911042SErik.Nordmark@Sun.COM { "P", NCE_F_NONUD, NCE_F_NONUD },
21905940Ssowmini { "R", NCE_F_ISROUTER, NCE_F_ISROUTER },
21915940Ssowmini { "N", NCE_F_NONUD, NCE_F_NONUD },
21925940Ssowmini { "A", NCE_F_ANYCAST, NCE_F_ANYCAST },
21935940Ssowmini { "C", NCE_F_CONDEMNED, NCE_F_CONDEMNED },
21945940Ssowmini { "U", NCE_F_UNSOL_ADV, NCE_F_UNSOL_ADV },
21955940Ssowmini { "B", NCE_F_BCAST, NCE_F_BCAST },
21965940Ssowmini { NULL, 0, 0 }
21975940Ssowmini };
219811042SErik.Nordmark@Sun.COM #define NCE_MAX_FLAGS (sizeof (ncec_flags) / sizeof (mdb_bitmask_t))
21995940Ssowmini struct in_addr nceaddr;
22005940Ssowmini ill_t ill;
22015940Ssowmini char ill_name[LIFNAMSIZ];
22025940Ssowmini char flagsbuf[NCE_MAX_FLAGS];
22035940Ssowmini
220411042SErik.Nordmark@Sun.COM if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncec->ncec_ill) == -1) {
220511042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec_ill at %p",
220611042SErik.Nordmark@Sun.COM ncec->ncec_ill);
22075940Ssowmini return (DCMD_ERR);
22085940Ssowmini }
22095940Ssowmini
22105940Ssowmini (void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill.ill_name_length),
22115940Ssowmini (uintptr_t)ill.ill_name);
22125940Ssowmini
22135940Ssowmini mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%hb",
221411042SErik.Nordmark@Sun.COM ncec->ncec_flags, ncec_flags);
221511042SErik.Nordmark@Sun.COM
221611042SErik.Nordmark@Sun.COM if (ipversion != 0 && ncec->ncec_ipversion != ipversion)
22175940Ssowmini return (DCMD_OK);
22185940Ssowmini
221911042SErik.Nordmark@Sun.COM if (ncec->ncec_ipversion == IPV4_VERSION) {
222011042SErik.Nordmark@Sun.COM IN6_V4MAPPED_TO_INADDR(&ncec->ncec_addr, &nceaddr);
22215940Ssowmini mdb_printf("%?p %-20s %-10s "
22225940Ssowmini "%-8s "
22235940Ssowmini "%-5s %I\n",
222411042SErik.Nordmark@Sun.COM addr, ncec_l2_addr(ncec, &ill),
222511042SErik.Nordmark@Sun.COM ncec_state(ncec->ncec_state),
22265940Ssowmini flagsbuf,
22275940Ssowmini ill_name, nceaddr.s_addr);
22285940Ssowmini } else {
22295940Ssowmini mdb_printf("%?p %-20s %-10s %-8s %-5s %N\n",
223011042SErik.Nordmark@Sun.COM addr, ncec_l2_addr(ncec, &ill),
223111042SErik.Nordmark@Sun.COM ncec_state(ncec->ncec_state),
22325940Ssowmini flagsbuf,
223311042SErik.Nordmark@Sun.COM ill_name, &ncec->ncec_addr);
22345940Ssowmini }
22355940Ssowmini
22365940Ssowmini return (DCMD_OK);
22375940Ssowmini }
22385940Ssowmini
22395940Ssowmini static uintptr_t
ncec_get_next_hash_tbl(uintptr_t start,int * index,struct ndp_g_s ndp)224011042SErik.Nordmark@Sun.COM ncec_get_next_hash_tbl(uintptr_t start, int *index, struct ndp_g_s ndp)
22415940Ssowmini {
22425940Ssowmini uintptr_t addr = start;
22435940Ssowmini int i = *index;
22445940Ssowmini
22455940Ssowmini while (addr == NULL) {
22465940Ssowmini
22475940Ssowmini if (++i >= NCE_TABLE_SIZE)
22485940Ssowmini break;
22495940Ssowmini addr = (uintptr_t)ndp.nce_hash_tbl[i];
22505940Ssowmini }
22515940Ssowmini *index = i;
22525940Ssowmini return (addr);
22535940Ssowmini }
22545940Ssowmini
22555940Ssowmini static int
ncec_walk_step(mdb_walk_state_t * wsp)225611042SErik.Nordmark@Sun.COM ncec_walk_step(mdb_walk_state_t *wsp)
22575940Ssowmini {
22585940Ssowmini uintptr_t kaddr4, kaddr6;
22595940Ssowmini
22605940Ssowmini kaddr4 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp4);
22615940Ssowmini kaddr6 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp6);
22625940Ssowmini
22635940Ssowmini if (mdb_vread(&kaddr4, sizeof (kaddr4), kaddr4) == -1) {
22645940Ssowmini mdb_warn("can't read ips_ip_cache_table at %p", kaddr4);
22655940Ssowmini return (WALK_ERR);
22665940Ssowmini }
22675940Ssowmini if (mdb_vread(&kaddr6, sizeof (kaddr6), kaddr6) == -1) {
22685940Ssowmini mdb_warn("can't read ips_ip_cache_table at %p", kaddr6);
22695940Ssowmini return (WALK_ERR);
22705940Ssowmini }
227111042SErik.Nordmark@Sun.COM if (mdb_pwalk("ncec_stack", wsp->walk_callback, wsp->walk_cbdata,
22725940Ssowmini kaddr4) == -1) {
227311042SErik.Nordmark@Sun.COM mdb_warn("couldn't walk 'ncec_stack' for ips_ndp4 %p",
22745940Ssowmini kaddr4);
22755940Ssowmini return (WALK_ERR);
22765940Ssowmini }
227711042SErik.Nordmark@Sun.COM if (mdb_pwalk("ncec_stack", wsp->walk_callback,
22785940Ssowmini wsp->walk_cbdata, kaddr6) == -1) {
227911042SErik.Nordmark@Sun.COM mdb_warn("couldn't walk 'ncec_stack' for ips_ndp6 %p",
22805940Ssowmini kaddr6);
22815940Ssowmini return (WALK_ERR);
22825940Ssowmini }
22835940Ssowmini return (WALK_NEXT);
22845940Ssowmini }
22855940Ssowmini
22869089SVasumathi.Sundaram@Sun.COM static uintptr_t
ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t * iw)22879089SVasumathi.Sundaram@Sun.COM ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t *iw)
22889089SVasumathi.Sundaram@Sun.COM {
22899089SVasumathi.Sundaram@Sun.COM struct connf_s connf;
22909089SVasumathi.Sundaram@Sun.COM uintptr_t addr = NULL, next;
22919089SVasumathi.Sundaram@Sun.COM int index = iw->connf_tbl_index;
22929089SVasumathi.Sundaram@Sun.COM
22939089SVasumathi.Sundaram@Sun.COM do {
22949089SVasumathi.Sundaram@Sun.COM next = iw->hash_tbl + index * sizeof (struct connf_s);
22959089SVasumathi.Sundaram@Sun.COM if (++index >= iw->hash_tbl_size) {
22969089SVasumathi.Sundaram@Sun.COM addr = NULL;
22979089SVasumathi.Sundaram@Sun.COM break;
22989089SVasumathi.Sundaram@Sun.COM }
22999089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&connf, sizeof (struct connf_s), next) == -1) {
23009089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", next);
23019089SVasumathi.Sundaram@Sun.COM return (NULL);
23029089SVasumathi.Sundaram@Sun.COM }
23039089SVasumathi.Sundaram@Sun.COM addr = (uintptr_t)connf.connf_head;
23049089SVasumathi.Sundaram@Sun.COM } while (addr == NULL);
23059089SVasumathi.Sundaram@Sun.COM iw->connf_tbl_index = index;
23069089SVasumathi.Sundaram@Sun.COM return (addr);
23079089SVasumathi.Sundaram@Sun.COM }
23089089SVasumathi.Sundaram@Sun.COM
23099089SVasumathi.Sundaram@Sun.COM static int
ipcl_hash_walk_init(mdb_walk_state_t * wsp)23109089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_init(mdb_walk_state_t *wsp)
23119089SVasumathi.Sundaram@Sun.COM {
23129089SVasumathi.Sundaram@Sun.COM const hash_walk_arg_t *arg = wsp->walk_arg;
23139089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw;
23149089SVasumathi.Sundaram@Sun.COM uintptr_t tbladdr;
23159089SVasumathi.Sundaram@Sun.COM uintptr_t sizeaddr;
23169089SVasumathi.Sundaram@Sun.COM
23179089SVasumathi.Sundaram@Sun.COM iw = mdb_alloc(sizeof (ipcl_hash_walk_data_t), UM_SLEEP);
23189089SVasumathi.Sundaram@Sun.COM iw->conn = mdb_alloc(sizeof (conn_t), UM_SLEEP);
23199089SVasumathi.Sundaram@Sun.COM tbladdr = wsp->walk_addr + arg->tbl_off;
23209089SVasumathi.Sundaram@Sun.COM sizeaddr = wsp->walk_addr + arg->size_off;
23219089SVasumathi.Sundaram@Sun.COM
23229089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&iw->hash_tbl, sizeof (uintptr_t), tbladdr) == -1) {
23239089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read fanout table addr at %p", tbladdr);
23249089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t));
23259089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t));
23269089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
23279089SVasumathi.Sundaram@Sun.COM }
232811042SErik.Nordmark@Sun.COM if (arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4) ||
23299089SVasumathi.Sundaram@Sun.COM arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6)) {
23309089SVasumathi.Sundaram@Sun.COM iw->hash_tbl_size = IPPROTO_MAX;
23319089SVasumathi.Sundaram@Sun.COM } else {
23329089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&iw->hash_tbl_size, sizeof (int),
23339089SVasumathi.Sundaram@Sun.COM sizeaddr) == -1) {
23349089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read fanout table size addr at %p",
23359089SVasumathi.Sundaram@Sun.COM sizeaddr);
23369089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t));
23379089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t));
23389089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
23399089SVasumathi.Sundaram@Sun.COM }
23409089SVasumathi.Sundaram@Sun.COM }
23419089SVasumathi.Sundaram@Sun.COM iw->connf_tbl_index = 0;
23429089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw);
23439089SVasumathi.Sundaram@Sun.COM wsp->walk_data = iw;
23449089SVasumathi.Sundaram@Sun.COM
23459089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr != NULL)
23469089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
23479089SVasumathi.Sundaram@Sun.COM else
23489089SVasumathi.Sundaram@Sun.COM return (WALK_DONE);
23499089SVasumathi.Sundaram@Sun.COM }
23509089SVasumathi.Sundaram@Sun.COM
23519089SVasumathi.Sundaram@Sun.COM static int
ipcl_hash_walk_step(mdb_walk_state_t * wsp)23529089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_step(mdb_walk_state_t *wsp)
23539089SVasumathi.Sundaram@Sun.COM {
23549089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr;
23559089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw = wsp->walk_data;
23569089SVasumathi.Sundaram@Sun.COM conn_t *conn = iw->conn;
23579089SVasumathi.Sundaram@Sun.COM int ret = WALK_DONE;
23589089SVasumathi.Sundaram@Sun.COM
23599089SVasumathi.Sundaram@Sun.COM while (addr != NULL) {
23609089SVasumathi.Sundaram@Sun.COM if (mdb_vread(conn, sizeof (conn_t), addr) == -1) {
23619089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", addr);
23629089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
23639089SVasumathi.Sundaram@Sun.COM }
23649089SVasumathi.Sundaram@Sun.COM ret = wsp->walk_callback(addr, iw, wsp->walk_cbdata);
23659089SVasumathi.Sundaram@Sun.COM if (ret != WALK_NEXT)
23669089SVasumathi.Sundaram@Sun.COM break;
23679089SVasumathi.Sundaram@Sun.COM addr = (uintptr_t)conn->conn_next;
23689089SVasumathi.Sundaram@Sun.COM }
23699089SVasumathi.Sundaram@Sun.COM if (ret == WALK_NEXT) {
23709089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw);
23719089SVasumathi.Sundaram@Sun.COM
23729089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr != NULL)
23739089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
23749089SVasumathi.Sundaram@Sun.COM else
23759089SVasumathi.Sundaram@Sun.COM return (WALK_DONE);
23769089SVasumathi.Sundaram@Sun.COM }
23779089SVasumathi.Sundaram@Sun.COM
23789089SVasumathi.Sundaram@Sun.COM return (ret);
23799089SVasumathi.Sundaram@Sun.COM }
23809089SVasumathi.Sundaram@Sun.COM
23819089SVasumathi.Sundaram@Sun.COM static void
ipcl_hash_walk_fini(mdb_walk_state_t * wsp)23829089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_fini(mdb_walk_state_t *wsp)
23839089SVasumathi.Sundaram@Sun.COM {
23849089SVasumathi.Sundaram@Sun.COM ipcl_hash_walk_data_t *iw = wsp->walk_data;
23859089SVasumathi.Sundaram@Sun.COM
23869089SVasumathi.Sundaram@Sun.COM mdb_free(iw->conn, sizeof (conn_t));
23879089SVasumathi.Sundaram@Sun.COM mdb_free(iw, sizeof (ipcl_hash_walk_data_t));
23889089SVasumathi.Sundaram@Sun.COM }
23899089SVasumathi.Sundaram@Sun.COM
23905940Ssowmini /*
23915940Ssowmini * Called with walk_addr being the address of ips_ndp{4,6}
23925940Ssowmini */
23935940Ssowmini static int
ncec_stack_walk_init(mdb_walk_state_t * wsp)239411042SErik.Nordmark@Sun.COM ncec_stack_walk_init(mdb_walk_state_t *wsp)
23955940Ssowmini {
239611042SErik.Nordmark@Sun.COM ncec_walk_data_t *nw;
23975940Ssowmini
23985940Ssowmini if (wsp->walk_addr == NULL) {
239911042SErik.Nordmark@Sun.COM mdb_warn("ncec_stack requires ndp_g_s address\n");
24005940Ssowmini return (WALK_ERR);
24015940Ssowmini }
24025940Ssowmini
240311042SErik.Nordmark@Sun.COM nw = mdb_alloc(sizeof (ncec_walk_data_t), UM_SLEEP);
240411042SErik.Nordmark@Sun.COM
240511042SErik.Nordmark@Sun.COM if (mdb_vread(&nw->ncec_ip_ndp, sizeof (struct ndp_g_s),
24065940Ssowmini wsp->walk_addr) == -1) {
24075940Ssowmini mdb_warn("failed to read 'ip_ndp' at %p",
24085940Ssowmini wsp->walk_addr);
240911042SErik.Nordmark@Sun.COM mdb_free(nw, sizeof (ncec_walk_data_t));
24105940Ssowmini return (WALK_ERR);
24115940Ssowmini }
24125940Ssowmini
241311042SErik.Nordmark@Sun.COM /*
241411042SErik.Nordmark@Sun.COM * ncec_get_next_hash_tbl() starts at ++i , so initialize index to -1
241511042SErik.Nordmark@Sun.COM */
241611042SErik.Nordmark@Sun.COM nw->ncec_hash_tbl_index = -1;
241711042SErik.Nordmark@Sun.COM wsp->walk_addr = ncec_get_next_hash_tbl(NULL,
241811042SErik.Nordmark@Sun.COM &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp);
24195940Ssowmini wsp->walk_data = nw;
24205940Ssowmini
24215940Ssowmini return (WALK_NEXT);
24225940Ssowmini }
24235940Ssowmini
24245940Ssowmini static int
ncec_stack_walk_step(mdb_walk_state_t * wsp)242511042SErik.Nordmark@Sun.COM ncec_stack_walk_step(mdb_walk_state_t *wsp)
24265940Ssowmini {
24275940Ssowmini uintptr_t addr = wsp->walk_addr;
242811042SErik.Nordmark@Sun.COM ncec_walk_data_t *nw = wsp->walk_data;
24295940Ssowmini
24305940Ssowmini if (addr == NULL)
24315940Ssowmini return (WALK_DONE);
24325940Ssowmini
243311042SErik.Nordmark@Sun.COM if (mdb_vread(&nw->ncec, sizeof (ncec_t), addr) == -1) {
243411042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec_t at %p", addr);
24355940Ssowmini return (WALK_ERR);
24365940Ssowmini }
24375940Ssowmini
243811042SErik.Nordmark@Sun.COM wsp->walk_addr = (uintptr_t)nw->ncec.ncec_next;
243911042SErik.Nordmark@Sun.COM
244011042SErik.Nordmark@Sun.COM wsp->walk_addr = ncec_get_next_hash_tbl(wsp->walk_addr,
244111042SErik.Nordmark@Sun.COM &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp);
24425940Ssowmini
24435940Ssowmini return (wsp->walk_callback(addr, nw, wsp->walk_cbdata));
24445940Ssowmini }
24455940Ssowmini
24465940Ssowmini static void
ncec_stack_walk_fini(mdb_walk_state_t * wsp)244711042SErik.Nordmark@Sun.COM ncec_stack_walk_fini(mdb_walk_state_t *wsp)
24485940Ssowmini {
244911042SErik.Nordmark@Sun.COM mdb_free(wsp->walk_data, sizeof (ncec_walk_data_t));
24505940Ssowmini }
24515940Ssowmini
24525940Ssowmini /* ARGSUSED */
24535940Ssowmini static int
ncec_cb(uintptr_t addr,const ncec_walk_data_t * iw,ncec_cbdata_t * id)245411042SErik.Nordmark@Sun.COM ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw, ncec_cbdata_t *id)
24555940Ssowmini {
245611042SErik.Nordmark@Sun.COM ncec_t ncec;
245711042SErik.Nordmark@Sun.COM
245811042SErik.Nordmark@Sun.COM if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) {
245911042SErik.Nordmark@Sun.COM mdb_warn("failed to read ncec at %p", addr);
24605940Ssowmini return (WALK_NEXT);
24615940Ssowmini }
246211042SErik.Nordmark@Sun.COM (void) ncec_format(addr, &ncec, id->ncec_ipversion);
24635940Ssowmini return (WALK_NEXT);
24645940Ssowmini }
24659089SVasumathi.Sundaram@Sun.COM
24669089SVasumathi.Sundaram@Sun.COM static int
ill_walk_init(mdb_walk_state_t * wsp)24679089SVasumathi.Sundaram@Sun.COM ill_walk_init(mdb_walk_state_t *wsp)
24689089SVasumathi.Sundaram@Sun.COM {
24699089SVasumathi.Sundaram@Sun.COM if (mdb_layered_walk("illif", wsp) == -1) {
24709089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'illif'");
24719089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
24729089SVasumathi.Sundaram@Sun.COM }
24739089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
24749089SVasumathi.Sundaram@Sun.COM }
24759089SVasumathi.Sundaram@Sun.COM
24769089SVasumathi.Sundaram@Sun.COM static int
ill_walk_step(mdb_walk_state_t * wsp)24779089SVasumathi.Sundaram@Sun.COM ill_walk_step(mdb_walk_state_t *wsp)
24789089SVasumathi.Sundaram@Sun.COM {
24799089SVasumathi.Sundaram@Sun.COM ill_if_t ill_if;
24809089SVasumathi.Sundaram@Sun.COM
24819089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill_if, sizeof (ill_if_t), wsp->walk_addr) == -1) {
24829089SVasumathi.Sundaram@Sun.COM mdb_warn("can't read ill_if_t at %p", wsp->walk_addr);
24839089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
24849089SVasumathi.Sundaram@Sun.COM }
24859089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = (uintptr_t)(wsp->walk_addr +
24869089SVasumathi.Sundaram@Sun.COM offsetof(ill_if_t, illif_avl_by_ppa));
24879089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("avl", wsp->walk_callback, wsp->walk_cbdata,
24889089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) {
24899089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'avl'");
24909089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
24919089SVasumathi.Sundaram@Sun.COM }
24929089SVasumathi.Sundaram@Sun.COM
24939089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
24949089SVasumathi.Sundaram@Sun.COM }
24959089SVasumathi.Sundaram@Sun.COM
24969089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */
24979089SVasumathi.Sundaram@Sun.COM static int
ill_cb(uintptr_t addr,const ill_walk_data_t * iw,ill_cbdata_t * id)24989089SVasumathi.Sundaram@Sun.COM ill_cb(uintptr_t addr, const ill_walk_data_t *iw, ill_cbdata_t *id)
24999089SVasumathi.Sundaram@Sun.COM {
25009089SVasumathi.Sundaram@Sun.COM ill_t ill;
25019089SVasumathi.Sundaram@Sun.COM
25029089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill, sizeof (ill_t), (uintptr_t)addr) == -1) {
25039089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", addr);
25049089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
25059089SVasumathi.Sundaram@Sun.COM }
250611042SErik.Nordmark@Sun.COM
250711042SErik.Nordmark@Sun.COM /* If ip_stack_t is specified, skip ILLs that don't belong to it. */
250811042SErik.Nordmark@Sun.COM if (id->ill_ipst != NULL && ill.ill_ipst != id->ill_ipst)
250911042SErik.Nordmark@Sun.COM return (WALK_NEXT);
251011042SErik.Nordmark@Sun.COM
25119089SVasumathi.Sundaram@Sun.COM return (ill_format((uintptr_t)addr, &ill, id));
25129089SVasumathi.Sundaram@Sun.COM }
25139089SVasumathi.Sundaram@Sun.COM
25149089SVasumathi.Sundaram@Sun.COM static void
ill_header(boolean_t verbose)25159089SVasumathi.Sundaram@Sun.COM ill_header(boolean_t verbose)
25169089SVasumathi.Sundaram@Sun.COM {
25179089SVasumathi.Sundaram@Sun.COM if (verbose) {
25189089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-8s %3s %-10s %-?s %-?s %-10s%</u>\n",
25199089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "VER", "TYPE", "WQ", "IPST", "FLAGS");
25209089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %4s%4s %-?s\n",
25219089SVasumathi.Sundaram@Sun.COM "PHYINT", "CNT", "", "GROUP");
25229089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", "");
25239089SVasumathi.Sundaram@Sun.COM } else {
25249089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%-?s %-8s %-3s %-10s %4s %-?s %-10s%</u>\n",
25259089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "VER", "TYPE", "CNT", "WQ", "FLAGS");
25269089SVasumathi.Sundaram@Sun.COM }
25279089SVasumathi.Sundaram@Sun.COM }
25289089SVasumathi.Sundaram@Sun.COM
25299089SVasumathi.Sundaram@Sun.COM static int
ill_format(uintptr_t addr,const void * illptr,void * ill_cb_arg)25309089SVasumathi.Sundaram@Sun.COM ill_format(uintptr_t addr, const void *illptr, void *ill_cb_arg)
25319089SVasumathi.Sundaram@Sun.COM {
25329089SVasumathi.Sundaram@Sun.COM ill_t *ill = (ill_t *)illptr;
25339089SVasumathi.Sundaram@Sun.COM ill_cbdata_t *illcb = ill_cb_arg;
25349089SVasumathi.Sundaram@Sun.COM boolean_t verbose = illcb->verbose;
25359089SVasumathi.Sundaram@Sun.COM phyint_t phyi;
25369089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t fmasks[] = {
25379089SVasumathi.Sundaram@Sun.COM { "R", PHYI_RUNNING, PHYI_RUNNING },
25389089SVasumathi.Sundaram@Sun.COM { "P", PHYI_PROMISC, PHYI_PROMISC },
25399089SVasumathi.Sundaram@Sun.COM { "V", PHYI_VIRTUAL, PHYI_VIRTUAL },
25409089SVasumathi.Sundaram@Sun.COM { "I", PHYI_IPMP, PHYI_IPMP },
25419089SVasumathi.Sundaram@Sun.COM { "f", PHYI_FAILED, PHYI_FAILED },
25429089SVasumathi.Sundaram@Sun.COM { "S", PHYI_STANDBY, PHYI_STANDBY },
25439089SVasumathi.Sundaram@Sun.COM { "i", PHYI_INACTIVE, PHYI_INACTIVE },
25449089SVasumathi.Sundaram@Sun.COM { "O", PHYI_OFFLINE, PHYI_OFFLINE },
25459089SVasumathi.Sundaram@Sun.COM { "T", ILLF_NOTRAILERS, ILLF_NOTRAILERS },
25469089SVasumathi.Sundaram@Sun.COM { "A", ILLF_NOARP, ILLF_NOARP },
25479089SVasumathi.Sundaram@Sun.COM { "M", ILLF_MULTICAST, ILLF_MULTICAST },
25489089SVasumathi.Sundaram@Sun.COM { "F", ILLF_ROUTER, ILLF_ROUTER },
25499089SVasumathi.Sundaram@Sun.COM { "D", ILLF_NONUD, ILLF_NONUD },
25509089SVasumathi.Sundaram@Sun.COM { "X", ILLF_NORTEXCH, ILLF_NORTEXCH },
25519089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 }
25529089SVasumathi.Sundaram@Sun.COM };
25539089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t v_fmasks[] = {
25549089SVasumathi.Sundaram@Sun.COM { "RUNNING", PHYI_RUNNING, PHYI_RUNNING },
25559089SVasumathi.Sundaram@Sun.COM { "PROMISC", PHYI_PROMISC, PHYI_PROMISC },
25569089SVasumathi.Sundaram@Sun.COM { "VIRTUAL", PHYI_VIRTUAL, PHYI_VIRTUAL },
25579089SVasumathi.Sundaram@Sun.COM { "IPMP", PHYI_IPMP, PHYI_IPMP },
25589089SVasumathi.Sundaram@Sun.COM { "FAILED", PHYI_FAILED, PHYI_FAILED },
25599089SVasumathi.Sundaram@Sun.COM { "STANDBY", PHYI_STANDBY, PHYI_STANDBY },
25609089SVasumathi.Sundaram@Sun.COM { "INACTIVE", PHYI_INACTIVE, PHYI_INACTIVE },
25619089SVasumathi.Sundaram@Sun.COM { "OFFLINE", PHYI_OFFLINE, PHYI_OFFLINE },
25629089SVasumathi.Sundaram@Sun.COM { "NOTRAILER", ILLF_NOTRAILERS, ILLF_NOTRAILERS },
25639089SVasumathi.Sundaram@Sun.COM { "NOARP", ILLF_NOARP, ILLF_NOARP },
25649089SVasumathi.Sundaram@Sun.COM { "MULTICAST", ILLF_MULTICAST, ILLF_MULTICAST },
25659089SVasumathi.Sundaram@Sun.COM { "ROUTER", ILLF_ROUTER, ILLF_ROUTER },
25669089SVasumathi.Sundaram@Sun.COM { "NONUD", ILLF_NONUD, ILLF_NONUD },
25679089SVasumathi.Sundaram@Sun.COM { "NORTEXCH", ILLF_NORTEXCH, ILLF_NORTEXCH },
25689089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 }
25699089SVasumathi.Sundaram@Sun.COM };
25709089SVasumathi.Sundaram@Sun.COM char ill_name[LIFNAMSIZ];
25719089SVasumathi.Sundaram@Sun.COM int cnt;
25729089SVasumathi.Sundaram@Sun.COM char *typebuf;
25739089SVasumathi.Sundaram@Sun.COM char sbuf[DEFCOLS];
25749089SVasumathi.Sundaram@Sun.COM int ipver = illcb->ill_ipversion;
25759089SVasumathi.Sundaram@Sun.COM
25769089SVasumathi.Sundaram@Sun.COM if (ipver != 0) {
25779089SVasumathi.Sundaram@Sun.COM if ((ipver == IPV4_VERSION && ill->ill_isv6) ||
25789089SVasumathi.Sundaram@Sun.COM (ipver == IPV6_VERSION && !ill->ill_isv6)) {
25799089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
25809089SVasumathi.Sundaram@Sun.COM }
25819089SVasumathi.Sundaram@Sun.COM }
25829089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&phyi, sizeof (phyint_t),
25839089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_phyint) == -1) {
25849089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill_phyint at %p",
25859089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_phyint);
25869089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
25879089SVasumathi.Sundaram@Sun.COM }
25889089SVasumathi.Sundaram@Sun.COM (void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill->ill_name_length),
25899089SVasumathi.Sundaram@Sun.COM (uintptr_t)ill->ill_name);
25909089SVasumathi.Sundaram@Sun.COM
25919089SVasumathi.Sundaram@Sun.COM switch (ill->ill_type) {
25929089SVasumathi.Sundaram@Sun.COM case 0:
25939089SVasumathi.Sundaram@Sun.COM typebuf = "LOOPBACK";
25949089SVasumathi.Sundaram@Sun.COM break;
25959089SVasumathi.Sundaram@Sun.COM case IFT_ETHER:
25969089SVasumathi.Sundaram@Sun.COM typebuf = "ETHER";
25979089SVasumathi.Sundaram@Sun.COM break;
25989089SVasumathi.Sundaram@Sun.COM case IFT_OTHER:
25999089SVasumathi.Sundaram@Sun.COM typebuf = "OTHER";
26009089SVasumathi.Sundaram@Sun.COM break;
26019089SVasumathi.Sundaram@Sun.COM default:
26029089SVasumathi.Sundaram@Sun.COM typebuf = NULL;
26039089SVasumathi.Sundaram@Sun.COM break;
26049089SVasumathi.Sundaram@Sun.COM }
26059089SVasumathi.Sundaram@Sun.COM cnt = ill->ill_refcnt + ill->ill_ire_cnt + ill->ill_nce_cnt +
260611042SErik.Nordmark@Sun.COM ill->ill_ilm_cnt + ill->ill_ncec_cnt;
26079089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-8s %-3s ",
26089089SVasumathi.Sundaram@Sun.COM addr, ill_name, ill->ill_isv6 ? "v6" : "v4");
26099089SVasumathi.Sundaram@Sun.COM if (typebuf != NULL)
26109089SVasumathi.Sundaram@Sun.COM mdb_printf("%-10s ", typebuf);
26119089SVasumathi.Sundaram@Sun.COM else
26129089SVasumathi.Sundaram@Sun.COM mdb_printf("%-10x ", ill->ill_type);
26139089SVasumathi.Sundaram@Sun.COM if (verbose) {
26149089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-?p %-llb\n",
26159089SVasumathi.Sundaram@Sun.COM ill->ill_wq, ill->ill_ipst,
26169089SVasumathi.Sundaram@Sun.COM ill->ill_flags | phyi.phyint_flags, v_fmasks);
26179089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %4d%4s %-?p\n",
26189089SVasumathi.Sundaram@Sun.COM ill->ill_phyint, cnt, "", ill->ill_grp);
26199089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sbuf, sizeof (sbuf), "%*s %3s",
26209089SVasumathi.Sundaram@Sun.COM sizeof (uintptr_t) * 2, "", "");
26219089SVasumathi.Sundaram@Sun.COM mdb_printf("%s|\n%s+--> %3d %-18s "
26229089SVasumathi.Sundaram@Sun.COM "references from active threads\n",
26239089SVasumathi.Sundaram@Sun.COM sbuf, sbuf, ill->ill_refcnt, "ill_refcnt");
26249089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s ires referencing this ill\n",
26259089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_ire_cnt, "ill_ire_cnt");
26269089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s nces referencing this ill\n",
26279089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_nce_cnt, "ill_nce_cnt");
262811042SErik.Nordmark@Sun.COM mdb_printf("%*s %7d %-18s ncecs referencing this ill\n",
262911042SErik.Nordmark@Sun.COM strlen(sbuf), "", ill->ill_ncec_cnt, "ill_ncec_cnt");
26309089SVasumathi.Sundaram@Sun.COM mdb_printf("%*s %7d %-18s ilms referencing this ill\n",
26319089SVasumathi.Sundaram@Sun.COM strlen(sbuf), "", ill->ill_ilm_cnt, "ill_ilm_cnt");
26329089SVasumathi.Sundaram@Sun.COM } else {
26339089SVasumathi.Sundaram@Sun.COM mdb_printf("%4d %-?p %-llb\n",
26349089SVasumathi.Sundaram@Sun.COM cnt, ill->ill_wq,
26359089SVasumathi.Sundaram@Sun.COM ill->ill_flags | phyi.phyint_flags, fmasks);
26369089SVasumathi.Sundaram@Sun.COM }
26379089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
26389089SVasumathi.Sundaram@Sun.COM }
26399089SVasumathi.Sundaram@Sun.COM
26409089SVasumathi.Sundaram@Sun.COM static int
ill(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)26419089SVasumathi.Sundaram@Sun.COM ill(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
26429089SVasumathi.Sundaram@Sun.COM {
26439089SVasumathi.Sundaram@Sun.COM ill_t ill_data;
26449089SVasumathi.Sundaram@Sun.COM ill_cbdata_t id;
26459089SVasumathi.Sundaram@Sun.COM int ipversion = 0;
264611042SErik.Nordmark@Sun.COM const char *zone_name = NULL;
26479089SVasumathi.Sundaram@Sun.COM const char *opt_P = NULL;
26489089SVasumathi.Sundaram@Sun.COM uint_t verbose = FALSE;
264911042SErik.Nordmark@Sun.COM ip_stack_t *ipst = NULL;
26509089SVasumathi.Sundaram@Sun.COM
26519089SVasumathi.Sundaram@Sun.COM if (mdb_getopts(argc, argv,
26529089SVasumathi.Sundaram@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose,
265311042SErik.Nordmark@Sun.COM 's', MDB_OPT_STR, &zone_name,
26549089SVasumathi.Sundaram@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
26559089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE);
26569089SVasumathi.Sundaram@Sun.COM
265711042SErik.Nordmark@Sun.COM /* Follow the specified zone name to find a ip_stack_t*. */
265811042SErik.Nordmark@Sun.COM if (zone_name != NULL) {
265911042SErik.Nordmark@Sun.COM ipst = zone_to_ips(zone_name);
266011042SErik.Nordmark@Sun.COM if (ipst == NULL)
266111042SErik.Nordmark@Sun.COM return (DCMD_USAGE);
266211042SErik.Nordmark@Sun.COM }
266311042SErik.Nordmark@Sun.COM
26649089SVasumathi.Sundaram@Sun.COM if (opt_P != NULL) {
26659089SVasumathi.Sundaram@Sun.COM if (strcmp("v4", opt_P) == 0) {
26669089SVasumathi.Sundaram@Sun.COM ipversion = IPV4_VERSION;
26679089SVasumathi.Sundaram@Sun.COM } else if (strcmp("v6", opt_P) == 0) {
26689089SVasumathi.Sundaram@Sun.COM ipversion = IPV6_VERSION;
26699089SVasumathi.Sundaram@Sun.COM } else {
26709089SVasumathi.Sundaram@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P);
26719089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE);
26729089SVasumathi.Sundaram@Sun.COM }
26739089SVasumathi.Sundaram@Sun.COM }
26749089SVasumathi.Sundaram@Sun.COM
26759089SVasumathi.Sundaram@Sun.COM id.verbose = verbose;
26769089SVasumathi.Sundaram@Sun.COM id.ill_addr = addr;
26779089SVasumathi.Sundaram@Sun.COM id.ill_ipversion = ipversion;
267811042SErik.Nordmark@Sun.COM id.ill_ipst = ipst;
26799089SVasumathi.Sundaram@Sun.COM
26809089SVasumathi.Sundaram@Sun.COM ill_header(verbose);
26819089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) {
26829089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ill_data, sizeof (ill_t), addr) == -1) {
26839089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p\n", addr);
26849089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR);
26859089SVasumathi.Sundaram@Sun.COM }
26869089SVasumathi.Sundaram@Sun.COM (void) ill_format(addr, &ill_data, &id);
26879089SVasumathi.Sundaram@Sun.COM } else {
26889089SVasumathi.Sundaram@Sun.COM if (mdb_walk("ill", (mdb_walk_cb_t)ill_cb, &id) == -1) {
26899089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk ills\n");
26909089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR);
26919089SVasumathi.Sundaram@Sun.COM }
26929089SVasumathi.Sundaram@Sun.COM }
26939089SVasumathi.Sundaram@Sun.COM return (DCMD_OK);
26949089SVasumathi.Sundaram@Sun.COM }
26959089SVasumathi.Sundaram@Sun.COM
26969089SVasumathi.Sundaram@Sun.COM static void
ill_help(void)26979089SVasumathi.Sundaram@Sun.COM ill_help(void)
26989089SVasumathi.Sundaram@Sun.COM {
26999089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints the following fields: ill ptr, name, "
27009089SVasumathi.Sundaram@Sun.COM "IP version, count, ill type and ill flags.\n"
27019089SVasumathi.Sundaram@Sun.COM "The count field is a sum of individual refcnts and is expanded "
27029089SVasumathi.Sundaram@Sun.COM "with the -v option.\n\n");
27039089SVasumathi.Sundaram@Sun.COM mdb_printf("Options:\n");
27049089SVasumathi.Sundaram@Sun.COM mdb_printf("\t-P v4 | v6"
27059089SVasumathi.Sundaram@Sun.COM "\tfilter ill structures for the specified protocol\n");
27069089SVasumathi.Sundaram@Sun.COM }
27079089SVasumathi.Sundaram@Sun.COM
27089089SVasumathi.Sundaram@Sun.COM static int
ip_list_walk_init(mdb_walk_state_t * wsp)27099089SVasumathi.Sundaram@Sun.COM ip_list_walk_init(mdb_walk_state_t *wsp)
27109089SVasumathi.Sundaram@Sun.COM {
27119089SVasumathi.Sundaram@Sun.COM const ip_list_walk_arg_t *arg = wsp->walk_arg;
27129089SVasumathi.Sundaram@Sun.COM ip_list_walk_data_t *iw;
27139089SVasumathi.Sundaram@Sun.COM uintptr_t addr = (uintptr_t)(wsp->walk_addr + arg->off);
27149089SVasumathi.Sundaram@Sun.COM
27159089SVasumathi.Sundaram@Sun.COM if (wsp->walk_addr == NULL) {
27169089SVasumathi.Sundaram@Sun.COM mdb_warn("only local walks supported\n");
27179089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
27189089SVasumathi.Sundaram@Sun.COM }
27199089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t),
27209089SVasumathi.Sundaram@Sun.COM addr) == -1) {
27219089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read list head at %p", addr);
27229089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
27239089SVasumathi.Sundaram@Sun.COM }
27249089SVasumathi.Sundaram@Sun.COM iw = mdb_alloc(sizeof (ip_list_walk_data_t), UM_SLEEP);
27259089SVasumathi.Sundaram@Sun.COM iw->nextoff = arg->nextp_off;
27269089SVasumathi.Sundaram@Sun.COM wsp->walk_data = iw;
27279089SVasumathi.Sundaram@Sun.COM
27289089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
27299089SVasumathi.Sundaram@Sun.COM }
27309089SVasumathi.Sundaram@Sun.COM
27319089SVasumathi.Sundaram@Sun.COM static int
ip_list_walk_step(mdb_walk_state_t * wsp)27329089SVasumathi.Sundaram@Sun.COM ip_list_walk_step(mdb_walk_state_t *wsp)
27339089SVasumathi.Sundaram@Sun.COM {
27349089SVasumathi.Sundaram@Sun.COM ip_list_walk_data_t *iw = wsp->walk_data;
27359089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr;
27369089SVasumathi.Sundaram@Sun.COM
27379089SVasumathi.Sundaram@Sun.COM if (addr == NULL)
27389089SVasumathi.Sundaram@Sun.COM return (WALK_DONE);
27399089SVasumathi.Sundaram@Sun.COM wsp->walk_addr = addr + iw->nextoff;
27409089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t),
27419089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) {
27429089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read list node at %p", addr);
27439089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
27449089SVasumathi.Sundaram@Sun.COM }
27459089SVasumathi.Sundaram@Sun.COM return (wsp->walk_callback(addr, iw, wsp->walk_cbdata));
27469089SVasumathi.Sundaram@Sun.COM }
27479089SVasumathi.Sundaram@Sun.COM
27489089SVasumathi.Sundaram@Sun.COM static void
ip_list_walk_fini(mdb_walk_state_t * wsp)27499089SVasumathi.Sundaram@Sun.COM ip_list_walk_fini(mdb_walk_state_t *wsp)
27509089SVasumathi.Sundaram@Sun.COM {
27519089SVasumathi.Sundaram@Sun.COM mdb_free(wsp->walk_data, sizeof (ip_list_walk_data_t));
27529089SVasumathi.Sundaram@Sun.COM }
27539089SVasumathi.Sundaram@Sun.COM
27549089SVasumathi.Sundaram@Sun.COM static int
ipif_walk_init(mdb_walk_state_t * wsp)27559089SVasumathi.Sundaram@Sun.COM ipif_walk_init(mdb_walk_state_t *wsp)
27569089SVasumathi.Sundaram@Sun.COM {
27579089SVasumathi.Sundaram@Sun.COM if (mdb_layered_walk("ill", wsp) == -1) {
27589089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'ills'");
27599089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
27609089SVasumathi.Sundaram@Sun.COM }
27619089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
27629089SVasumathi.Sundaram@Sun.COM }
27639089SVasumathi.Sundaram@Sun.COM
27649089SVasumathi.Sundaram@Sun.COM static int
ipif_walk_step(mdb_walk_state_t * wsp)27659089SVasumathi.Sundaram@Sun.COM ipif_walk_step(mdb_walk_state_t *wsp)
27669089SVasumathi.Sundaram@Sun.COM {
27679089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("ipif_list", wsp->walk_callback, wsp->walk_cbdata,
27689089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) {
27699089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'ipif_list'");
27709089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
27719089SVasumathi.Sundaram@Sun.COM }
27729089SVasumathi.Sundaram@Sun.COM
27739089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
27749089SVasumathi.Sundaram@Sun.COM }
27759089SVasumathi.Sundaram@Sun.COM
27769089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */
27779089SVasumathi.Sundaram@Sun.COM static int
ipif_cb(uintptr_t addr,const ipif_walk_data_t * iw,ipif_cbdata_t * id)27789089SVasumathi.Sundaram@Sun.COM ipif_cb(uintptr_t addr, const ipif_walk_data_t *iw, ipif_cbdata_t *id)
27799089SVasumathi.Sundaram@Sun.COM {
27809089SVasumathi.Sundaram@Sun.COM ipif_t ipif;
27819089SVasumathi.Sundaram@Sun.COM
27829089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ipif, sizeof (ipif_t), (uintptr_t)addr) == -1) {
27839089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ipif at %p", addr);
27849089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
27859089SVasumathi.Sundaram@Sun.COM }
27869089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&id->ill, sizeof (ill_t),
27879089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipif.ipif_ill) == -1) {
27889089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", ipif.ipif_ill);
27899089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
27909089SVasumathi.Sundaram@Sun.COM }
27919089SVasumathi.Sundaram@Sun.COM (void) ipif_format((uintptr_t)addr, &ipif, id);
27929089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
27939089SVasumathi.Sundaram@Sun.COM }
27949089SVasumathi.Sundaram@Sun.COM
27959089SVasumathi.Sundaram@Sun.COM static void
ipif_header(boolean_t verbose)27969089SVasumathi.Sundaram@Sun.COM ipif_header(boolean_t verbose)
27979089SVasumathi.Sundaram@Sun.COM {
27989089SVasumathi.Sundaram@Sun.COM if (verbose) {
27999089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-10s %-3s %-?s %-8s %-30s\n",
28009089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS");
28019089SVasumathi.Sundaram@Sun.COM mdb_printf("%s\n%s\n",
28029089SVasumathi.Sundaram@Sun.COM "LCLADDR", "BROADCAST");
28039089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", "");
28049089SVasumathi.Sundaram@Sun.COM } else {
28059089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-10s %6s %-?s %-8s %-30s\n",
28069089SVasumathi.Sundaram@Sun.COM "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS");
28079089SVasumathi.Sundaram@Sun.COM mdb_printf("%s\n%<u>%80s%</u>\n", "LCLADDR", "");
28089089SVasumathi.Sundaram@Sun.COM }
28099089SVasumathi.Sundaram@Sun.COM }
28109089SVasumathi.Sundaram@Sun.COM
28119089SVasumathi.Sundaram@Sun.COM #ifdef _BIG_ENDIAN
28129089SVasumathi.Sundaram@Sun.COM #define ip_ntohl_32(x) ((x) & 0xffffffff)
28139089SVasumathi.Sundaram@Sun.COM #else
28149089SVasumathi.Sundaram@Sun.COM #define ip_ntohl_32(x) (((uint32_t)(x) << 24) | \
28159089SVasumathi.Sundaram@Sun.COM (((uint32_t)(x) << 8) & 0xff0000) | \
28169089SVasumathi.Sundaram@Sun.COM (((uint32_t)(x) >> 8) & 0xff00) | \
28179089SVasumathi.Sundaram@Sun.COM ((uint32_t)(x) >> 24))
28189089SVasumathi.Sundaram@Sun.COM #endif
28199089SVasumathi.Sundaram@Sun.COM
28209089SVasumathi.Sundaram@Sun.COM int
mask_to_prefixlen(int af,const in6_addr_t * addr)28219089SVasumathi.Sundaram@Sun.COM mask_to_prefixlen(int af, const in6_addr_t *addr)
28229089SVasumathi.Sundaram@Sun.COM {
28239089SVasumathi.Sundaram@Sun.COM int len = 0;
28249089SVasumathi.Sundaram@Sun.COM int i;
28259089SVasumathi.Sundaram@Sun.COM uint_t mask = 0;
28269089SVasumathi.Sundaram@Sun.COM
28279089SVasumathi.Sundaram@Sun.COM if (af == AF_INET6) {
28289089SVasumathi.Sundaram@Sun.COM for (i = 0; i < 4; i++) {
28299089SVasumathi.Sundaram@Sun.COM if (addr->s6_addr32[i] == 0xffffffff) {
28309089SVasumathi.Sundaram@Sun.COM len += 32;
28319089SVasumathi.Sundaram@Sun.COM } else {
28329089SVasumathi.Sundaram@Sun.COM mask = addr->s6_addr32[i];
28339089SVasumathi.Sundaram@Sun.COM break;
28349089SVasumathi.Sundaram@Sun.COM }
28359089SVasumathi.Sundaram@Sun.COM }
28369089SVasumathi.Sundaram@Sun.COM } else {
28379089SVasumathi.Sundaram@Sun.COM mask = V4_PART_OF_V6((*addr));
28389089SVasumathi.Sundaram@Sun.COM }
28399089SVasumathi.Sundaram@Sun.COM if (mask > 0)
28409089SVasumathi.Sundaram@Sun.COM len += (33 - mdb_ffs(ip_ntohl_32(mask)));
28419089SVasumathi.Sundaram@Sun.COM return (len);
28429089SVasumathi.Sundaram@Sun.COM }
28439089SVasumathi.Sundaram@Sun.COM
28449089SVasumathi.Sundaram@Sun.COM static int
ipif_format(uintptr_t addr,const void * ipifptr,void * ipif_cb_arg)28459089SVasumathi.Sundaram@Sun.COM ipif_format(uintptr_t addr, const void *ipifptr, void *ipif_cb_arg)
28469089SVasumathi.Sundaram@Sun.COM {
28479089SVasumathi.Sundaram@Sun.COM const ipif_t *ipif = ipifptr;
28489089SVasumathi.Sundaram@Sun.COM ipif_cbdata_t *ipifcb = ipif_cb_arg;
28499089SVasumathi.Sundaram@Sun.COM boolean_t verbose = ipifcb->verbose;
28509089SVasumathi.Sundaram@Sun.COM char ill_name[LIFNAMSIZ];
28519089SVasumathi.Sundaram@Sun.COM char buf[LIFNAMSIZ];
28529089SVasumathi.Sundaram@Sun.COM int cnt;
28539089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t sfmasks[] = {
28549089SVasumathi.Sundaram@Sun.COM { "CO", IPIF_CONDEMNED, IPIF_CONDEMNED},
28559089SVasumathi.Sundaram@Sun.COM { "CH", IPIF_CHANGING, IPIF_CHANGING},
28569089SVasumathi.Sundaram@Sun.COM { "SL", IPIF_SET_LINKLOCAL, IPIF_SET_LINKLOCAL},
28579089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 }
28589089SVasumathi.Sundaram@Sun.COM };
28599089SVasumathi.Sundaram@Sun.COM static const mdb_bitmask_t fmasks[] = {
28609089SVasumathi.Sundaram@Sun.COM { "UP", IPIF_UP, IPIF_UP },
28619089SVasumathi.Sundaram@Sun.COM { "UNN", IPIF_UNNUMBERED, IPIF_UNNUMBERED},
28629089SVasumathi.Sundaram@Sun.COM { "DHCP", IPIF_DHCPRUNNING, IPIF_DHCPRUNNING},
28639089SVasumathi.Sundaram@Sun.COM { "PRIV", IPIF_PRIVATE, IPIF_PRIVATE},
28649089SVasumathi.Sundaram@Sun.COM { "NOXMT", IPIF_NOXMIT, IPIF_NOXMIT},
28659089SVasumathi.Sundaram@Sun.COM { "NOLCL", IPIF_NOLOCAL, IPIF_NOLOCAL},
28669089SVasumathi.Sundaram@Sun.COM { "DEPR", IPIF_DEPRECATED, IPIF_DEPRECATED},
28679089SVasumathi.Sundaram@Sun.COM { "PREF", IPIF_PREFERRED, IPIF_PREFERRED},
28689089SVasumathi.Sundaram@Sun.COM { "TEMP", IPIF_TEMPORARY, IPIF_TEMPORARY},
28699089SVasumathi.Sundaram@Sun.COM { "ACONF", IPIF_ADDRCONF, IPIF_ADDRCONF},
28709089SVasumathi.Sundaram@Sun.COM { "ANY", IPIF_ANYCAST, IPIF_ANYCAST},
28719089SVasumathi.Sundaram@Sun.COM { "NFAIL", IPIF_NOFAILOVER, IPIF_NOFAILOVER},
28729089SVasumathi.Sundaram@Sun.COM { NULL, 0, 0 }
28739089SVasumathi.Sundaram@Sun.COM };
28749089SVasumathi.Sundaram@Sun.COM char flagsbuf[2 * A_CNT(fmasks)];
28759089SVasumathi.Sundaram@Sun.COM char bitfields[A_CNT(fmasks)];
28769089SVasumathi.Sundaram@Sun.COM char sflagsbuf[A_CNT(sfmasks)];
28779089SVasumathi.Sundaram@Sun.COM char sbuf[DEFCOLS], addrstr[INET6_ADDRSTRLEN];
28789089SVasumathi.Sundaram@Sun.COM int ipver = ipifcb->ipif_ipversion;
28799089SVasumathi.Sundaram@Sun.COM int af;
28809089SVasumathi.Sundaram@Sun.COM
28819089SVasumathi.Sundaram@Sun.COM if (ipver != 0) {
28829089SVasumathi.Sundaram@Sun.COM if ((ipver == IPV4_VERSION && ipifcb->ill.ill_isv6) ||
28839089SVasumathi.Sundaram@Sun.COM (ipver == IPV6_VERSION && !ipifcb->ill.ill_isv6)) {
28849089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
28859089SVasumathi.Sundaram@Sun.COM }
28869089SVasumathi.Sundaram@Sun.COM }
28879089SVasumathi.Sundaram@Sun.COM if ((mdb_readstr(ill_name, MIN(LIFNAMSIZ,
28889089SVasumathi.Sundaram@Sun.COM ipifcb->ill.ill_name_length),
28899089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipifcb->ill.ill_name)) == -1) {
28909089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill_name of ill %p\n", ipifcb->ill);
28919089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
28929089SVasumathi.Sundaram@Sun.COM }
28939089SVasumathi.Sundaram@Sun.COM if (ipif->ipif_id != 0) {
28949089SVasumathi.Sundaram@Sun.COM mdb_snprintf(buf, LIFNAMSIZ, "%s:%d",
28959089SVasumathi.Sundaram@Sun.COM ill_name, ipif->ipif_id);
28969089SVasumathi.Sundaram@Sun.COM } else {
28979089SVasumathi.Sundaram@Sun.COM mdb_snprintf(buf, LIFNAMSIZ, "%s", ill_name);
28989089SVasumathi.Sundaram@Sun.COM }
28999089SVasumathi.Sundaram@Sun.COM mdb_snprintf(bitfields, sizeof (bitfields), "%s",
29009089SVasumathi.Sundaram@Sun.COM ipif->ipif_addr_ready ? ",ADR" : "",
29019089SVasumathi.Sundaram@Sun.COM ipif->ipif_was_up ? ",WU" : "",
290211042SErik.Nordmark@Sun.COM ipif->ipif_was_dup ? ",WD" : "");
29039089SVasumathi.Sundaram@Sun.COM mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%llb%s",
29049089SVasumathi.Sundaram@Sun.COM ipif->ipif_flags, fmasks, bitfields);
29059089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sflagsbuf, sizeof (sflagsbuf), "%b",
29069089SVasumathi.Sundaram@Sun.COM ipif->ipif_state_flags, sfmasks);
29079089SVasumathi.Sundaram@Sun.COM
290811042SErik.Nordmark@Sun.COM cnt = ipif->ipif_refcnt;
29099089SVasumathi.Sundaram@Sun.COM
29109089SVasumathi.Sundaram@Sun.COM if (ipifcb->ill.ill_isv6) {
29119089SVasumathi.Sundaram@Sun.COM mdb_snprintf(addrstr, sizeof (addrstr), "%N",
29129089SVasumathi.Sundaram@Sun.COM &ipif->ipif_v6lcl_addr);
29139089SVasumathi.Sundaram@Sun.COM af = AF_INET6;
29149089SVasumathi.Sundaram@Sun.COM } else {
29159089SVasumathi.Sundaram@Sun.COM mdb_snprintf(addrstr, sizeof (addrstr), "%I",
29169089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((ipif->ipif_v6lcl_addr)));
29179089SVasumathi.Sundaram@Sun.COM af = AF_INET;
29189089SVasumathi.Sundaram@Sun.COM }
29199089SVasumathi.Sundaram@Sun.COM
29209089SVasumathi.Sundaram@Sun.COM if (verbose) {
29219089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-10s %3d %-?p %-8s %-30s\n",
29229089SVasumathi.Sundaram@Sun.COM addr, buf, cnt, ipif->ipif_ill,
29239089SVasumathi.Sundaram@Sun.COM sflagsbuf, flagsbuf);
29249089SVasumathi.Sundaram@Sun.COM mdb_snprintf(sbuf, sizeof (sbuf), "%*s %12s",
29259089SVasumathi.Sundaram@Sun.COM sizeof (uintptr_t) * 2, "", "");
29269089SVasumathi.Sundaram@Sun.COM mdb_printf("%s |\n%s +---> %4d %-15s "
29279089SVasumathi.Sundaram@Sun.COM "Active consistent reader cnt\n",
29289089SVasumathi.Sundaram@Sun.COM sbuf, sbuf, ipif->ipif_refcnt, "ipif_refcnt");
29299089SVasumathi.Sundaram@Sun.COM mdb_printf("%-s/%d\n",
29309089SVasumathi.Sundaram@Sun.COM addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask));
29319089SVasumathi.Sundaram@Sun.COM if (ipifcb->ill.ill_isv6) {
29329089SVasumathi.Sundaram@Sun.COM mdb_printf("%-N\n", &ipif->ipif_v6brd_addr);
29339089SVasumathi.Sundaram@Sun.COM } else {
29349089SVasumathi.Sundaram@Sun.COM mdb_printf("%-I\n",
29359089SVasumathi.Sundaram@Sun.COM V4_PART_OF_V6((ipif->ipif_v6brd_addr)));
29369089SVasumathi.Sundaram@Sun.COM }
29379089SVasumathi.Sundaram@Sun.COM } else {
29389089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-10s %6d %-?p %-8s %-30s\n",
29399089SVasumathi.Sundaram@Sun.COM addr, buf, cnt, ipif->ipif_ill,
29409089SVasumathi.Sundaram@Sun.COM sflagsbuf, flagsbuf);
29419089SVasumathi.Sundaram@Sun.COM mdb_printf("%-s/%d\n",
29429089SVasumathi.Sundaram@Sun.COM addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask));
29439089SVasumathi.Sundaram@Sun.COM }
29449089SVasumathi.Sundaram@Sun.COM
29459089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
29469089SVasumathi.Sundaram@Sun.COM }
29479089SVasumathi.Sundaram@Sun.COM
29489089SVasumathi.Sundaram@Sun.COM static int
ipif(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)29499089SVasumathi.Sundaram@Sun.COM ipif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
29509089SVasumathi.Sundaram@Sun.COM {
29519089SVasumathi.Sundaram@Sun.COM ipif_t ipif;
29529089SVasumathi.Sundaram@Sun.COM ipif_cbdata_t id;
29539089SVasumathi.Sundaram@Sun.COM int ipversion = 0;
29549089SVasumathi.Sundaram@Sun.COM const char *opt_P = NULL;
29559089SVasumathi.Sundaram@Sun.COM uint_t verbose = FALSE;
29569089SVasumathi.Sundaram@Sun.COM
29579089SVasumathi.Sundaram@Sun.COM if (mdb_getopts(argc, argv,
29589089SVasumathi.Sundaram@Sun.COM 'v', MDB_OPT_SETBITS, TRUE, &verbose,
29599089SVasumathi.Sundaram@Sun.COM 'P', MDB_OPT_STR, &opt_P, NULL) != argc)
29609089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE);
29619089SVasumathi.Sundaram@Sun.COM
29629089SVasumathi.Sundaram@Sun.COM if (opt_P != NULL) {
29639089SVasumathi.Sundaram@Sun.COM if (strcmp("v4", opt_P) == 0) {
29649089SVasumathi.Sundaram@Sun.COM ipversion = IPV4_VERSION;
29659089SVasumathi.Sundaram@Sun.COM } else if (strcmp("v6", opt_P) == 0) {
29669089SVasumathi.Sundaram@Sun.COM ipversion = IPV6_VERSION;
29679089SVasumathi.Sundaram@Sun.COM } else {
29689089SVasumathi.Sundaram@Sun.COM mdb_warn("invalid protocol '%s'\n", opt_P);
29699089SVasumathi.Sundaram@Sun.COM return (DCMD_USAGE);
29709089SVasumathi.Sundaram@Sun.COM }
29719089SVasumathi.Sundaram@Sun.COM }
29729089SVasumathi.Sundaram@Sun.COM
29739089SVasumathi.Sundaram@Sun.COM id.verbose = verbose;
29749089SVasumathi.Sundaram@Sun.COM id.ipif_ipversion = ipversion;
29759089SVasumathi.Sundaram@Sun.COM
29769089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) {
29779089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&ipif, sizeof (ipif_t), addr) == -1) {
29789089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ipif at %p\n", addr);
29799089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR);
29809089SVasumathi.Sundaram@Sun.COM }
29819089SVasumathi.Sundaram@Sun.COM ipif_header(verbose);
29829089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&id.ill, sizeof (ill_t),
29839089SVasumathi.Sundaram@Sun.COM (uintptr_t)ipif.ipif_ill) == -1) {
29849089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read ill at %p", ipif.ipif_ill);
29859089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
29869089SVasumathi.Sundaram@Sun.COM }
29879089SVasumathi.Sundaram@Sun.COM return (ipif_format(addr, &ipif, &id));
29889089SVasumathi.Sundaram@Sun.COM } else {
29899089SVasumathi.Sundaram@Sun.COM ipif_header(verbose);
29909089SVasumathi.Sundaram@Sun.COM if (mdb_walk("ipif", (mdb_walk_cb_t)ipif_cb, &id) == -1) {
29919089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk ipifs\n");
29929089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR);
29939089SVasumathi.Sundaram@Sun.COM }
29949089SVasumathi.Sundaram@Sun.COM }
29959089SVasumathi.Sundaram@Sun.COM return (DCMD_OK);
29969089SVasumathi.Sundaram@Sun.COM }
29979089SVasumathi.Sundaram@Sun.COM
29989089SVasumathi.Sundaram@Sun.COM static void
ipif_help(void)29999089SVasumathi.Sundaram@Sun.COM ipif_help(void)
30009089SVasumathi.Sundaram@Sun.COM {
30019089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints the following fields: ipif ptr, name, "
30029089SVasumathi.Sundaram@Sun.COM "count, ill ptr, state flags and ipif flags.\n"
30039089SVasumathi.Sundaram@Sun.COM "The count field is a sum of individual refcnts and is expanded "
30049089SVasumathi.Sundaram@Sun.COM "with the -v option.\n"
30059089SVasumathi.Sundaram@Sun.COM "The flags field shows the following:"
30069089SVasumathi.Sundaram@Sun.COM "\n\tUNN -> UNNUMBERED, DHCP -> DHCPRUNNING, PRIV -> PRIVATE, "
30079089SVasumathi.Sundaram@Sun.COM "\n\tNOXMT -> NOXMIT, NOLCL -> NOLOCAL, DEPR -> DEPRECATED, "
30089089SVasumathi.Sundaram@Sun.COM "\n\tPREF -> PREFERRED, TEMP -> TEMPORARY, ACONF -> ADDRCONF, "
30099089SVasumathi.Sundaram@Sun.COM "\n\tANY -> ANYCAST, NFAIL -> NOFAILOVER, "
30109089SVasumathi.Sundaram@Sun.COM "\n\tADR -> ipif_addr_ready, MU -> ipif_multicast_up, "
30119089SVasumathi.Sundaram@Sun.COM "\n\tWU -> ipif_was_up, WD -> ipif_was_dup, "
30129089SVasumathi.Sundaram@Sun.COM "JA -> ipif_joined_allhosts.\n\n");
30139089SVasumathi.Sundaram@Sun.COM mdb_printf("Options:\n");
30149089SVasumathi.Sundaram@Sun.COM mdb_printf("\t-P v4 | v6"
30159089SVasumathi.Sundaram@Sun.COM "\tfilter ipif structures on ills for the specified protocol\n");
30169089SVasumathi.Sundaram@Sun.COM }
30179089SVasumathi.Sundaram@Sun.COM
30189089SVasumathi.Sundaram@Sun.COM static int
conn_status_walk_fanout(uintptr_t addr,mdb_walk_state_t * wsp,const char * walkname)30199089SVasumathi.Sundaram@Sun.COM conn_status_walk_fanout(uintptr_t addr, mdb_walk_state_t *wsp,
30209089SVasumathi.Sundaram@Sun.COM const char *walkname)
30219089SVasumathi.Sundaram@Sun.COM {
30229089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk(walkname, wsp->walk_callback, wsp->walk_cbdata,
30239089SVasumathi.Sundaram@Sun.COM addr) == -1) {
30249089SVasumathi.Sundaram@Sun.COM mdb_warn("couldn't walk '%s' at %p", walkname, addr);
30259089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
30269089SVasumathi.Sundaram@Sun.COM }
30279089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
30289089SVasumathi.Sundaram@Sun.COM }
30299089SVasumathi.Sundaram@Sun.COM
30309089SVasumathi.Sundaram@Sun.COM static int
conn_status_walk_step(mdb_walk_state_t * wsp)30319089SVasumathi.Sundaram@Sun.COM conn_status_walk_step(mdb_walk_state_t *wsp)
30329089SVasumathi.Sundaram@Sun.COM {
30339089SVasumathi.Sundaram@Sun.COM uintptr_t addr = wsp->walk_addr;
30349089SVasumathi.Sundaram@Sun.COM
30359089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "udp_hash");
30369089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "conn_hash");
30379089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "bind_hash");
30389089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "proto_hash");
30399089SVasumathi.Sundaram@Sun.COM (void) conn_status_walk_fanout(addr, wsp, "proto_v6_hash");
30409089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
30419089SVasumathi.Sundaram@Sun.COM }
30429089SVasumathi.Sundaram@Sun.COM
30439089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */
30449089SVasumathi.Sundaram@Sun.COM static int
conn_status_cb(uintptr_t addr,const void * walk_data,void * private)30459089SVasumathi.Sundaram@Sun.COM conn_status_cb(uintptr_t addr, const void *walk_data,
30469089SVasumathi.Sundaram@Sun.COM void *private)
30479089SVasumathi.Sundaram@Sun.COM {
30489089SVasumathi.Sundaram@Sun.COM netstack_t nss;
30499089SVasumathi.Sundaram@Sun.COM char src_addrstr[INET6_ADDRSTRLEN];
30509089SVasumathi.Sundaram@Sun.COM char rem_addrstr[INET6_ADDRSTRLEN];
30519089SVasumathi.Sundaram@Sun.COM const ipcl_hash_walk_data_t *iw = walk_data;
30529089SVasumathi.Sundaram@Sun.COM conn_t *conn = iw->conn;
30539089SVasumathi.Sundaram@Sun.COM
30549089SVasumathi.Sundaram@Sun.COM if (mdb_vread(conn, sizeof (conn_t), addr) == -1) {
30559089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read conn_t at %p", addr);
30569089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
30579089SVasumathi.Sundaram@Sun.COM }
30589089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&nss, sizeof (nss),
30599089SVasumathi.Sundaram@Sun.COM (uintptr_t)conn->conn_netstack) == -1) {
30609089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read netstack_t %p",
30619089SVasumathi.Sundaram@Sun.COM conn->conn_netstack);
30629089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
30639089SVasumathi.Sundaram@Sun.COM }
30649089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %-?p %?d %?d\n", addr, conn->conn_wq,
30659089SVasumathi.Sundaram@Sun.COM nss.netstack_stackid, conn->conn_zoneid);
30669089SVasumathi.Sundaram@Sun.COM
306711042SErik.Nordmark@Sun.COM if (conn->conn_family == AF_INET6) {
30689089SVasumathi.Sundaram@Sun.COM mdb_snprintf(src_addrstr, sizeof (rem_addrstr), "%N",
306911042SErik.Nordmark@Sun.COM &conn->conn_laddr_v6);
30709089SVasumathi.Sundaram@Sun.COM mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%N",
307111042SErik.Nordmark@Sun.COM &conn->conn_faddr_v6);
30729089SVasumathi.Sundaram@Sun.COM } else {
30739089SVasumathi.Sundaram@Sun.COM mdb_snprintf(src_addrstr, sizeof (src_addrstr), "%I",
307411042SErik.Nordmark@Sun.COM V4_PART_OF_V6((conn->conn_laddr_v6)));
30759089SVasumathi.Sundaram@Sun.COM mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%I",
307611042SErik.Nordmark@Sun.COM V4_PART_OF_V6((conn->conn_faddr_v6)));
30779089SVasumathi.Sundaram@Sun.COM }
30789089SVasumathi.Sundaram@Sun.COM mdb_printf("%s:%-5d\n%s:%-5d\n",
30799089SVasumathi.Sundaram@Sun.COM src_addrstr, conn->conn_lport, rem_addrstr, conn->conn_fport);
30809089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
30819089SVasumathi.Sundaram@Sun.COM }
30829089SVasumathi.Sundaram@Sun.COM
30839089SVasumathi.Sundaram@Sun.COM static void
conn_header(void)30849089SVasumathi.Sundaram@Sun.COM conn_header(void)
30859089SVasumathi.Sundaram@Sun.COM {
30869089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %-?s %?s %?s\n%s\n%s\n",
30879089SVasumathi.Sundaram@Sun.COM "ADDR", "WQ", "STACK", "ZONE", "SRC:PORT", "DEST:PORT");
30889089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", "");
30899089SVasumathi.Sundaram@Sun.COM }
30909089SVasumathi.Sundaram@Sun.COM
30919089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/
30929089SVasumathi.Sundaram@Sun.COM static int
conn_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)30939089SVasumathi.Sundaram@Sun.COM conn_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
30949089SVasumathi.Sundaram@Sun.COM {
30959089SVasumathi.Sundaram@Sun.COM conn_header();
30969089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) {
30979089SVasumathi.Sundaram@Sun.COM (void) conn_status_cb(addr, NULL, NULL);
30989089SVasumathi.Sundaram@Sun.COM } else {
30999089SVasumathi.Sundaram@Sun.COM if (mdb_walk("conn_status", (mdb_walk_cb_t)conn_status_cb,
31009089SVasumathi.Sundaram@Sun.COM NULL) == -1) {
31019089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk conn_fanout");
31029089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR);
31039089SVasumathi.Sundaram@Sun.COM }
31049089SVasumathi.Sundaram@Sun.COM }
31059089SVasumathi.Sundaram@Sun.COM return (DCMD_OK);
31069089SVasumathi.Sundaram@Sun.COM }
31079089SVasumathi.Sundaram@Sun.COM
31089089SVasumathi.Sundaram@Sun.COM static void
conn_status_help(void)31099089SVasumathi.Sundaram@Sun.COM conn_status_help(void)
31109089SVasumathi.Sundaram@Sun.COM {
31119089SVasumathi.Sundaram@Sun.COM mdb_printf("Prints conn_t structures from the following hash tables: "
31129089SVasumathi.Sundaram@Sun.COM "\n\tips_ipcl_udp_fanout\n\tips_ipcl_bind_fanout"
311311042SErik.Nordmark@Sun.COM "\n\tips_ipcl_conn_fanout\n\tips_ipcl_proto_fanout_v4"
31149089SVasumathi.Sundaram@Sun.COM "\n\tips_ipcl_proto_fanout_v6\n");
31159089SVasumathi.Sundaram@Sun.COM }
31169089SVasumathi.Sundaram@Sun.COM
31179089SVasumathi.Sundaram@Sun.COM static int
srcid_walk_step(mdb_walk_state_t * wsp)31189089SVasumathi.Sundaram@Sun.COM srcid_walk_step(mdb_walk_state_t *wsp)
31199089SVasumathi.Sundaram@Sun.COM {
31209089SVasumathi.Sundaram@Sun.COM if (mdb_pwalk("srcid_list", wsp->walk_callback, wsp->walk_cbdata,
31219089SVasumathi.Sundaram@Sun.COM wsp->walk_addr) == -1) {
31229089SVasumathi.Sundaram@Sun.COM mdb_warn("can't walk 'srcid_list'");
31239089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
31249089SVasumathi.Sundaram@Sun.COM }
31259089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
31269089SVasumathi.Sundaram@Sun.COM }
31279089SVasumathi.Sundaram@Sun.COM
31289089SVasumathi.Sundaram@Sun.COM /* ARGSUSED */
31299089SVasumathi.Sundaram@Sun.COM static int
srcid_status_cb(uintptr_t addr,const void * walk_data,void * private)31309089SVasumathi.Sundaram@Sun.COM srcid_status_cb(uintptr_t addr, const void *walk_data,
31319089SVasumathi.Sundaram@Sun.COM void *private)
31329089SVasumathi.Sundaram@Sun.COM {
31339089SVasumathi.Sundaram@Sun.COM srcid_map_t smp;
31349089SVasumathi.Sundaram@Sun.COM
31359089SVasumathi.Sundaram@Sun.COM if (mdb_vread(&smp, sizeof (srcid_map_t), addr) == -1) {
31369089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to read srcid_map at %p", addr);
31379089SVasumathi.Sundaram@Sun.COM return (WALK_ERR);
31389089SVasumathi.Sundaram@Sun.COM }
31399089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?p %3d %4d %6d %N\n",
31409089SVasumathi.Sundaram@Sun.COM addr, smp.sm_srcid, smp.sm_zoneid, smp.sm_refcnt,
31419089SVasumathi.Sundaram@Sun.COM &smp.sm_addr);
31429089SVasumathi.Sundaram@Sun.COM return (WALK_NEXT);
31439089SVasumathi.Sundaram@Sun.COM }
31449089SVasumathi.Sundaram@Sun.COM
31459089SVasumathi.Sundaram@Sun.COM static void
srcid_header(void)31469089SVasumathi.Sundaram@Sun.COM srcid_header(void)
31479089SVasumathi.Sundaram@Sun.COM {
31489089SVasumathi.Sundaram@Sun.COM mdb_printf("%-?s %3s %4s %6s %s\n",
31499089SVasumathi.Sundaram@Sun.COM "ADDR", "ID", "ZONE", "REFCNT", "IPADDR");
31509089SVasumathi.Sundaram@Sun.COM mdb_printf("%<u>%80s%</u>\n", "");
31519089SVasumathi.Sundaram@Sun.COM }
31529089SVasumathi.Sundaram@Sun.COM
31539089SVasumathi.Sundaram@Sun.COM /*ARGSUSED*/
31549089SVasumathi.Sundaram@Sun.COM static int
srcid_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)31559089SVasumathi.Sundaram@Sun.COM srcid_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
31569089SVasumathi.Sundaram@Sun.COM {
31579089SVasumathi.Sundaram@Sun.COM srcid_header();
31589089SVasumathi.Sundaram@Sun.COM if (flags & DCMD_ADDRSPEC) {
31599089SVasumathi.Sundaram@Sun.COM (void) srcid_status_cb(addr, NULL, NULL);
31609089SVasumathi.Sundaram@Sun.COM } else {
31619089SVasumathi.Sundaram@Sun.COM if (mdb_walk("srcid", (mdb_walk_cb_t)srcid_status_cb,
31629089SVasumathi.Sundaram@Sun.COM NULL) == -1) {
31639089SVasumathi.Sundaram@Sun.COM mdb_warn("failed to walk srcid_map");
31649089SVasumathi.Sundaram@Sun.COM return (DCMD_ERR);
31659089SVasumathi.Sundaram@Sun.COM }
31669089SVasumathi.Sundaram@Sun.COM }
31679089SVasumathi.Sundaram@Sun.COM return (DCMD_OK);
31689089SVasumathi.Sundaram@Sun.COM }
316910946SSangeeta.Misra@Sun.COM
317010946SSangeeta.Misra@Sun.COM static int
ilb_stacks_walk_step(mdb_walk_state_t * wsp)317110946SSangeeta.Misra@Sun.COM ilb_stacks_walk_step(mdb_walk_state_t *wsp)
317210946SSangeeta.Misra@Sun.COM {
317311754SKacheong.Poon@Sun.COM return (ns_walk_step(wsp, NS_ILB));
317410946SSangeeta.Misra@Sun.COM }
317510946SSangeeta.Misra@Sun.COM
317610946SSangeeta.Misra@Sun.COM static int
ilb_rules_walk_init(mdb_walk_state_t * wsp)317710946SSangeeta.Misra@Sun.COM ilb_rules_walk_init(mdb_walk_state_t *wsp)
317810946SSangeeta.Misra@Sun.COM {
317910946SSangeeta.Misra@Sun.COM ilb_stack_t ilbs;
318010946SSangeeta.Misra@Sun.COM
318110946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL)
318210946SSangeeta.Misra@Sun.COM return (WALK_ERR);
318310946SSangeeta.Misra@Sun.COM
318410946SSangeeta.Misra@Sun.COM if (mdb_vread(&ilbs, sizeof (ilbs), wsp->walk_addr) == -1) {
318510946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
318610946SSangeeta.Misra@Sun.COM return (WALK_ERR);
318710946SSangeeta.Misra@Sun.COM }
318810946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)ilbs.ilbs_rule_head) != NULL)
318910946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
319010946SSangeeta.Misra@Sun.COM else
319110946SSangeeta.Misra@Sun.COM return (WALK_DONE);
319210946SSangeeta.Misra@Sun.COM }
319310946SSangeeta.Misra@Sun.COM
319410946SSangeeta.Misra@Sun.COM static int
ilb_rules_walk_step(mdb_walk_state_t * wsp)319510946SSangeeta.Misra@Sun.COM ilb_rules_walk_step(mdb_walk_state_t *wsp)
319610946SSangeeta.Misra@Sun.COM {
319710946SSangeeta.Misra@Sun.COM ilb_rule_t rule;
319810946SSangeeta.Misra@Sun.COM int status;
319910946SSangeeta.Misra@Sun.COM
320010946SSangeeta.Misra@Sun.COM if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) {
320110946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr);
320210946SSangeeta.Misra@Sun.COM return (WALK_ERR);
320310946SSangeeta.Misra@Sun.COM }
320410946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &rule, wsp->walk_cbdata);
320510946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT)
320610946SSangeeta.Misra@Sun.COM return (status);
320710946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)rule.ir_next) == NULL)
320810946SSangeeta.Misra@Sun.COM return (WALK_DONE);
320910946SSangeeta.Misra@Sun.COM else
321010946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
321110946SSangeeta.Misra@Sun.COM }
321210946SSangeeta.Misra@Sun.COM
321310946SSangeeta.Misra@Sun.COM static int
ilb_servers_walk_init(mdb_walk_state_t * wsp)321410946SSangeeta.Misra@Sun.COM ilb_servers_walk_init(mdb_walk_state_t *wsp)
321510946SSangeeta.Misra@Sun.COM {
321610946SSangeeta.Misra@Sun.COM ilb_rule_t rule;
321710946SSangeeta.Misra@Sun.COM
321810946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL)
321910946SSangeeta.Misra@Sun.COM return (WALK_ERR);
322010946SSangeeta.Misra@Sun.COM
322110946SSangeeta.Misra@Sun.COM if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) {
322210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr);
322310946SSangeeta.Misra@Sun.COM return (WALK_ERR);
322410946SSangeeta.Misra@Sun.COM }
322510946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)rule.ir_servers) != NULL)
322610946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
322710946SSangeeta.Misra@Sun.COM else
322810946SSangeeta.Misra@Sun.COM return (WALK_DONE);
322910946SSangeeta.Misra@Sun.COM }
323010946SSangeeta.Misra@Sun.COM
323110946SSangeeta.Misra@Sun.COM static int
ilb_servers_walk_step(mdb_walk_state_t * wsp)323210946SSangeeta.Misra@Sun.COM ilb_servers_walk_step(mdb_walk_state_t *wsp)
323310946SSangeeta.Misra@Sun.COM {
323410946SSangeeta.Misra@Sun.COM ilb_server_t server;
323510946SSangeeta.Misra@Sun.COM int status;
323610946SSangeeta.Misra@Sun.COM
323710946SSangeeta.Misra@Sun.COM if (mdb_vread(&server, sizeof (server), wsp->walk_addr) == -1) {
323810946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_server_t at %p", wsp->walk_addr);
323910946SSangeeta.Misra@Sun.COM return (WALK_ERR);
324010946SSangeeta.Misra@Sun.COM }
324110946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &server, wsp->walk_cbdata);
324210946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT)
324310946SSangeeta.Misra@Sun.COM return (status);
324410946SSangeeta.Misra@Sun.COM if ((wsp->walk_addr = (uintptr_t)server.iser_next) == NULL)
324510946SSangeeta.Misra@Sun.COM return (WALK_DONE);
324610946SSangeeta.Misra@Sun.COM else
324710946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
324810946SSangeeta.Misra@Sun.COM }
324910946SSangeeta.Misra@Sun.COM
325010946SSangeeta.Misra@Sun.COM /*
325110946SSangeeta.Misra@Sun.COM * Helper structure for ilb_nat_src walker. It stores the current index of the
325210946SSangeeta.Misra@Sun.COM * nat src table.
325310946SSangeeta.Misra@Sun.COM */
325410946SSangeeta.Misra@Sun.COM typedef struct {
325510946SSangeeta.Misra@Sun.COM ilb_stack_t ilbs;
325610946SSangeeta.Misra@Sun.COM int idx;
325710946SSangeeta.Misra@Sun.COM } ilb_walk_t;
325810946SSangeeta.Misra@Sun.COM
325910946SSangeeta.Misra@Sun.COM /* Copy from list.c */
326010946SSangeeta.Misra@Sun.COM #define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
326110946SSangeeta.Misra@Sun.COM
326210946SSangeeta.Misra@Sun.COM static int
ilb_nat_src_walk_init(mdb_walk_state_t * wsp)326310946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_init(mdb_walk_state_t *wsp)
326410946SSangeeta.Misra@Sun.COM {
326510946SSangeeta.Misra@Sun.COM int i;
326610946SSangeeta.Misra@Sun.COM ilb_walk_t *ns_walk;
326710946SSangeeta.Misra@Sun.COM ilb_nat_src_entry_t *entry = NULL;
326810946SSangeeta.Misra@Sun.COM
326910946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL)
327010946SSangeeta.Misra@Sun.COM return (WALK_ERR);
327110946SSangeeta.Misra@Sun.COM
327210946SSangeeta.Misra@Sun.COM ns_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP);
327310946SSangeeta.Misra@Sun.COM if (mdb_vread(&ns_walk->ilbs, sizeof (ns_walk->ilbs),
327410946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) {
327510946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
327610946SSangeeta.Misra@Sun.COM mdb_free(ns_walk, sizeof (ilb_walk_t));
327710946SSangeeta.Misra@Sun.COM return (WALK_ERR);
327810946SSangeeta.Misra@Sun.COM }
327910946SSangeeta.Misra@Sun.COM
328010946SSangeeta.Misra@Sun.COM if (ns_walk->ilbs.ilbs_nat_src == NULL) {
328110946SSangeeta.Misra@Sun.COM mdb_free(ns_walk, sizeof (ilb_walk_t));
328210946SSangeeta.Misra@Sun.COM return (WALK_DONE);
328310946SSangeeta.Misra@Sun.COM }
328410946SSangeeta.Misra@Sun.COM
328510946SSangeeta.Misra@Sun.COM wsp->walk_data = ns_walk;
328610946SSangeeta.Misra@Sun.COM for (i = 0; i < ns_walk->ilbs.ilbs_nat_src_hash_size; i++) {
328710946SSangeeta.Misra@Sun.COM list_t head;
328810946SSangeeta.Misra@Sun.COM char *khead;
328910946SSangeeta.Misra@Sun.COM
329010946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */
329110946SSangeeta.Misra@Sun.COM khead = (char *)ns_walk->ilbs.ilbs_nat_src + i *
329210946SSangeeta.Misra@Sun.COM sizeof (ilb_nat_src_hash_t);
329310946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
329410946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead);
329510946SSangeeta.Misra@Sun.COM return (WALK_ERR);
329610946SSangeeta.Misra@Sun.COM }
329710946SSangeeta.Misra@Sun.COM
329810946SSangeeta.Misra@Sun.COM /*
329910946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need
330010946SSangeeta.Misra@Sun.COM * to compare list_next with the kernel address of the list
330110946SSangeeta.Misra@Sun.COM * head. So we need to calculate the address manually.
330210946SSangeeta.Misra@Sun.COM */
330310946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead +
330410946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) {
330510946SSangeeta.Misra@Sun.COM entry = list_object(&head, head.list_head.list_next);
330610946SSangeeta.Misra@Sun.COM break;
330710946SSangeeta.Misra@Sun.COM }
330810946SSangeeta.Misra@Sun.COM }
330910946SSangeeta.Misra@Sun.COM
331010946SSangeeta.Misra@Sun.COM if (entry == NULL)
331110946SSangeeta.Misra@Sun.COM return (WALK_DONE);
331210946SSangeeta.Misra@Sun.COM
331310946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)entry;
331410946SSangeeta.Misra@Sun.COM ns_walk->idx = i;
331510946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
331610946SSangeeta.Misra@Sun.COM }
331710946SSangeeta.Misra@Sun.COM
331810946SSangeeta.Misra@Sun.COM static int
ilb_nat_src_walk_step(mdb_walk_state_t * wsp)331910946SSangeeta.Misra@Sun.COM ilb_nat_src_walk_step(mdb_walk_state_t *wsp)
332010946SSangeeta.Misra@Sun.COM {
332110946SSangeeta.Misra@Sun.COM int status;
332210946SSangeeta.Misra@Sun.COM ilb_nat_src_entry_t entry, *next_entry;
332310946SSangeeta.Misra@Sun.COM ilb_walk_t *ns_walk;
332410946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs;
332510946SSangeeta.Misra@Sun.COM list_t head;
332610946SSangeeta.Misra@Sun.COM char *khead;
332710946SSangeeta.Misra@Sun.COM int i;
332810946SSangeeta.Misra@Sun.COM
332910946SSangeeta.Misra@Sun.COM if (mdb_vread(&entry, sizeof (ilb_nat_src_entry_t),
333010946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) {
333110946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_nat_src_entry_t at %p",
333210946SSangeeta.Misra@Sun.COM wsp->walk_addr);
333310946SSangeeta.Misra@Sun.COM return (WALK_ERR);
333410946SSangeeta.Misra@Sun.COM }
333510946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &entry, wsp->walk_cbdata);
333610946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT)
333710946SSangeeta.Misra@Sun.COM return (status);
333810946SSangeeta.Misra@Sun.COM
333910946SSangeeta.Misra@Sun.COM ns_walk = (ilb_walk_t *)wsp->walk_data;
334010946SSangeeta.Misra@Sun.COM ilbs = &ns_walk->ilbs;
334110946SSangeeta.Misra@Sun.COM i = ns_walk->idx;
334210946SSangeeta.Misra@Sun.COM
334310946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */
334410946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_nat_src + i * sizeof (ilb_nat_src_hash_t);
334510946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
334610946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead);
334710946SSangeeta.Misra@Sun.COM return (WALK_ERR);
334810946SSangeeta.Misra@Sun.COM }
334910946SSangeeta.Misra@Sun.COM
335010946SSangeeta.Misra@Sun.COM /*
335110946SSangeeta.Misra@Sun.COM * Check if there is still entry in the current list.
335210946SSangeeta.Misra@Sun.COM *
335310946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need to
335410946SSangeeta.Misra@Sun.COM * compare list_next with the kernel address of the list head.
335510946SSangeeta.Misra@Sun.COM * So we need to calculate the address manually.
335610946SSangeeta.Misra@Sun.COM */
335710946SSangeeta.Misra@Sun.COM if ((char *)entry.nse_link.list_next != khead + offsetof(list_t,
335810946SSangeeta.Misra@Sun.COM list_head)) {
335910946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)list_object(&head,
336010946SSangeeta.Misra@Sun.COM entry.nse_link.list_next);
336110946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
336210946SSangeeta.Misra@Sun.COM }
336310946SSangeeta.Misra@Sun.COM
336410946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */
336510946SSangeeta.Misra@Sun.COM next_entry = NULL;
336610946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) {
336710946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_nat_src + i *
336810946SSangeeta.Misra@Sun.COM sizeof (ilb_nat_src_hash_t);
336910946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
337010946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_nat_src at %p\n", khead);
337110946SSangeeta.Misra@Sun.COM return (WALK_ERR);
337210946SSangeeta.Misra@Sun.COM }
337310946SSangeeta.Misra@Sun.COM
337410946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead +
337510946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) {
337610946SSangeeta.Misra@Sun.COM next_entry = list_object(&head,
337710946SSangeeta.Misra@Sun.COM head.list_head.list_next);
337810946SSangeeta.Misra@Sun.COM break;
337910946SSangeeta.Misra@Sun.COM }
338010946SSangeeta.Misra@Sun.COM }
338110946SSangeeta.Misra@Sun.COM
338210946SSangeeta.Misra@Sun.COM if (next_entry == NULL)
338310946SSangeeta.Misra@Sun.COM return (WALK_DONE);
338410946SSangeeta.Misra@Sun.COM
338510946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)next_entry;
338610946SSangeeta.Misra@Sun.COM ns_walk->idx = i;
338710946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
338810946SSangeeta.Misra@Sun.COM }
338910946SSangeeta.Misra@Sun.COM
339010946SSangeeta.Misra@Sun.COM static void
ilb_common_walk_fini(mdb_walk_state_t * wsp)339110946SSangeeta.Misra@Sun.COM ilb_common_walk_fini(mdb_walk_state_t *wsp)
339210946SSangeeta.Misra@Sun.COM {
339310946SSangeeta.Misra@Sun.COM ilb_walk_t *walk;
339410946SSangeeta.Misra@Sun.COM
339510946SSangeeta.Misra@Sun.COM walk = (ilb_walk_t *)wsp->walk_data;
339610946SSangeeta.Misra@Sun.COM if (walk == NULL)
339710946SSangeeta.Misra@Sun.COM return;
339810946SSangeeta.Misra@Sun.COM mdb_free(walk, sizeof (ilb_walk_t *));
339910946SSangeeta.Misra@Sun.COM }
340010946SSangeeta.Misra@Sun.COM
340110946SSangeeta.Misra@Sun.COM static int
ilb_conn_walk_init(mdb_walk_state_t * wsp)340210946SSangeeta.Misra@Sun.COM ilb_conn_walk_init(mdb_walk_state_t *wsp)
340310946SSangeeta.Misra@Sun.COM {
340410946SSangeeta.Misra@Sun.COM int i;
340510946SSangeeta.Misra@Sun.COM ilb_walk_t *conn_walk;
340610946SSangeeta.Misra@Sun.COM ilb_conn_hash_t head;
340710946SSangeeta.Misra@Sun.COM
340810946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL)
340910946SSangeeta.Misra@Sun.COM return (WALK_ERR);
341010946SSangeeta.Misra@Sun.COM
341110946SSangeeta.Misra@Sun.COM conn_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP);
341210946SSangeeta.Misra@Sun.COM if (mdb_vread(&conn_walk->ilbs, sizeof (conn_walk->ilbs),
341310946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) {
341410946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
341510946SSangeeta.Misra@Sun.COM mdb_free(conn_walk, sizeof (ilb_walk_t));
341610946SSangeeta.Misra@Sun.COM return (WALK_ERR);
341710946SSangeeta.Misra@Sun.COM }
341810946SSangeeta.Misra@Sun.COM
341910946SSangeeta.Misra@Sun.COM if (conn_walk->ilbs.ilbs_c2s_conn_hash == NULL) {
342010946SSangeeta.Misra@Sun.COM mdb_free(conn_walk, sizeof (ilb_walk_t));
342110946SSangeeta.Misra@Sun.COM return (WALK_DONE);
342210946SSangeeta.Misra@Sun.COM }
342310946SSangeeta.Misra@Sun.COM
342410946SSangeeta.Misra@Sun.COM wsp->walk_data = conn_walk;
342510946SSangeeta.Misra@Sun.COM for (i = 0; i < conn_walk->ilbs.ilbs_conn_hash_size; i++) {
342610946SSangeeta.Misra@Sun.COM char *khead;
342710946SSangeeta.Misra@Sun.COM
342810946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */
342910946SSangeeta.Misra@Sun.COM khead = (char *)conn_walk->ilbs.ilbs_c2s_conn_hash + i *
343010946SSangeeta.Misra@Sun.COM sizeof (ilb_conn_hash_t);
343110946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (ilb_conn_hash_t),
343210946SSangeeta.Misra@Sun.COM (uintptr_t)khead) == -1) {
343310946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n",
343410946SSangeeta.Misra@Sun.COM khead);
343510946SSangeeta.Misra@Sun.COM return (WALK_ERR);
343610946SSangeeta.Misra@Sun.COM }
343710946SSangeeta.Misra@Sun.COM
343810946SSangeeta.Misra@Sun.COM if (head.ilb_connp != NULL)
343910946SSangeeta.Misra@Sun.COM break;
344010946SSangeeta.Misra@Sun.COM }
344110946SSangeeta.Misra@Sun.COM
344210946SSangeeta.Misra@Sun.COM if (head.ilb_connp == NULL)
344310946SSangeeta.Misra@Sun.COM return (WALK_DONE);
344410946SSangeeta.Misra@Sun.COM
344510946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)head.ilb_connp;
344610946SSangeeta.Misra@Sun.COM conn_walk->idx = i;
344710946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
344810946SSangeeta.Misra@Sun.COM }
344910946SSangeeta.Misra@Sun.COM
345010946SSangeeta.Misra@Sun.COM static int
ilb_conn_walk_step(mdb_walk_state_t * wsp)345110946SSangeeta.Misra@Sun.COM ilb_conn_walk_step(mdb_walk_state_t *wsp)
345210946SSangeeta.Misra@Sun.COM {
345310946SSangeeta.Misra@Sun.COM int status;
345410946SSangeeta.Misra@Sun.COM ilb_conn_t conn;
345510946SSangeeta.Misra@Sun.COM ilb_walk_t *conn_walk;
345610946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs;
345710946SSangeeta.Misra@Sun.COM ilb_conn_hash_t head;
345810946SSangeeta.Misra@Sun.COM char *khead;
345910946SSangeeta.Misra@Sun.COM int i;
346010946SSangeeta.Misra@Sun.COM
346110946SSangeeta.Misra@Sun.COM if (mdb_vread(&conn, sizeof (ilb_conn_t), wsp->walk_addr) == -1) {
346210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_conn_t at %p", wsp->walk_addr);
346310946SSangeeta.Misra@Sun.COM return (WALK_ERR);
346410946SSangeeta.Misra@Sun.COM }
346510946SSangeeta.Misra@Sun.COM
346610946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &conn, wsp->walk_cbdata);
346710946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT)
346810946SSangeeta.Misra@Sun.COM return (status);
346910946SSangeeta.Misra@Sun.COM
347010946SSangeeta.Misra@Sun.COM conn_walk = (ilb_walk_t *)wsp->walk_data;
347110946SSangeeta.Misra@Sun.COM ilbs = &conn_walk->ilbs;
347210946SSangeeta.Misra@Sun.COM i = conn_walk->idx;
347310946SSangeeta.Misra@Sun.COM
347410946SSangeeta.Misra@Sun.COM /* Check if there is still entry in the current list. */
347510946SSangeeta.Misra@Sun.COM if (conn.conn_c2s_next != NULL) {
347610946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)conn.conn_c2s_next;
347710946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
347810946SSangeeta.Misra@Sun.COM }
347910946SSangeeta.Misra@Sun.COM
348010946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */
348110946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_conn_hash_size; i++) {
348210946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_c2s_conn_hash + i *
348310946SSangeeta.Misra@Sun.COM sizeof (ilb_conn_hash_t);
348410946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (ilb_conn_hash_t),
348510946SSangeeta.Misra@Sun.COM (uintptr_t)khead) == -1) {
348610946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n",
348710946SSangeeta.Misra@Sun.COM khead);
348810946SSangeeta.Misra@Sun.COM return (WALK_ERR);
348910946SSangeeta.Misra@Sun.COM }
349010946SSangeeta.Misra@Sun.COM
349110946SSangeeta.Misra@Sun.COM if (head.ilb_connp != NULL)
349210946SSangeeta.Misra@Sun.COM break;
349310946SSangeeta.Misra@Sun.COM }
349410946SSangeeta.Misra@Sun.COM
349510946SSangeeta.Misra@Sun.COM if (head.ilb_connp == NULL)
349610946SSangeeta.Misra@Sun.COM return (WALK_DONE);
349710946SSangeeta.Misra@Sun.COM
349810946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)head.ilb_connp;
349910946SSangeeta.Misra@Sun.COM conn_walk->idx = i;
350010946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
350110946SSangeeta.Misra@Sun.COM }
350210946SSangeeta.Misra@Sun.COM
350310946SSangeeta.Misra@Sun.COM static int
ilb_sticky_walk_init(mdb_walk_state_t * wsp)350410946SSangeeta.Misra@Sun.COM ilb_sticky_walk_init(mdb_walk_state_t *wsp)
350510946SSangeeta.Misra@Sun.COM {
350610946SSangeeta.Misra@Sun.COM int i;
350710946SSangeeta.Misra@Sun.COM ilb_walk_t *sticky_walk;
350810946SSangeeta.Misra@Sun.COM ilb_sticky_t *st = NULL;
350910946SSangeeta.Misra@Sun.COM
351010946SSangeeta.Misra@Sun.COM if (wsp->walk_addr == NULL)
351110946SSangeeta.Misra@Sun.COM return (WALK_ERR);
351210946SSangeeta.Misra@Sun.COM
351310946SSangeeta.Misra@Sun.COM sticky_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP);
351410946SSangeeta.Misra@Sun.COM if (mdb_vread(&sticky_walk->ilbs, sizeof (sticky_walk->ilbs),
351510946SSangeeta.Misra@Sun.COM wsp->walk_addr) == -1) {
351610946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
351710946SSangeeta.Misra@Sun.COM mdb_free(sticky_walk, sizeof (ilb_walk_t));
351810946SSangeeta.Misra@Sun.COM return (WALK_ERR);
351910946SSangeeta.Misra@Sun.COM }
352010946SSangeeta.Misra@Sun.COM
352110946SSangeeta.Misra@Sun.COM if (sticky_walk->ilbs.ilbs_sticky_hash == NULL) {
352210946SSangeeta.Misra@Sun.COM mdb_free(sticky_walk, sizeof (ilb_walk_t));
352310946SSangeeta.Misra@Sun.COM return (WALK_DONE);
352410946SSangeeta.Misra@Sun.COM }
352510946SSangeeta.Misra@Sun.COM
352610946SSangeeta.Misra@Sun.COM wsp->walk_data = sticky_walk;
352710946SSangeeta.Misra@Sun.COM for (i = 0; i < sticky_walk->ilbs.ilbs_sticky_hash_size; i++) {
352810946SSangeeta.Misra@Sun.COM list_t head;
352910946SSangeeta.Misra@Sun.COM char *khead;
353010946SSangeeta.Misra@Sun.COM
353110946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */
353210946SSangeeta.Misra@Sun.COM khead = (char *)sticky_walk->ilbs.ilbs_sticky_hash + i *
353310946SSangeeta.Misra@Sun.COM sizeof (ilb_sticky_hash_t);
353410946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
353510946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n",
353610946SSangeeta.Misra@Sun.COM khead);
353710946SSangeeta.Misra@Sun.COM return (WALK_ERR);
353810946SSangeeta.Misra@Sun.COM }
353910946SSangeeta.Misra@Sun.COM
354010946SSangeeta.Misra@Sun.COM /*
354110946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need
354210946SSangeeta.Misra@Sun.COM * to compare list_next with the kernel address of the list
354310946SSangeeta.Misra@Sun.COM * head. So we need to calculate the address manually.
354410946SSangeeta.Misra@Sun.COM */
354510946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead +
354610946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) {
354710946SSangeeta.Misra@Sun.COM st = list_object(&head, head.list_head.list_next);
354810946SSangeeta.Misra@Sun.COM break;
354910946SSangeeta.Misra@Sun.COM }
355010946SSangeeta.Misra@Sun.COM }
355110946SSangeeta.Misra@Sun.COM
355210946SSangeeta.Misra@Sun.COM if (st == NULL)
355310946SSangeeta.Misra@Sun.COM return (WALK_DONE);
355410946SSangeeta.Misra@Sun.COM
355510946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)st;
355610946SSangeeta.Misra@Sun.COM sticky_walk->idx = i;
355710946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
355810946SSangeeta.Misra@Sun.COM }
355910946SSangeeta.Misra@Sun.COM
356010946SSangeeta.Misra@Sun.COM static int
ilb_sticky_walk_step(mdb_walk_state_t * wsp)356110946SSangeeta.Misra@Sun.COM ilb_sticky_walk_step(mdb_walk_state_t *wsp)
356210946SSangeeta.Misra@Sun.COM {
356310946SSangeeta.Misra@Sun.COM int status;
356410946SSangeeta.Misra@Sun.COM ilb_sticky_t st, *st_next;
356510946SSangeeta.Misra@Sun.COM ilb_walk_t *sticky_walk;
356610946SSangeeta.Misra@Sun.COM ilb_stack_t *ilbs;
356710946SSangeeta.Misra@Sun.COM list_t head;
356810946SSangeeta.Misra@Sun.COM char *khead;
356910946SSangeeta.Misra@Sun.COM int i;
357010946SSangeeta.Misra@Sun.COM
357110946SSangeeta.Misra@Sun.COM if (mdb_vread(&st, sizeof (ilb_sticky_t), wsp->walk_addr) == -1) {
357210946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilb_sticky_t at %p", wsp->walk_addr);
357310946SSangeeta.Misra@Sun.COM return (WALK_ERR);
357410946SSangeeta.Misra@Sun.COM }
357510946SSangeeta.Misra@Sun.COM
357610946SSangeeta.Misra@Sun.COM status = wsp->walk_callback(wsp->walk_addr, &st, wsp->walk_cbdata);
357710946SSangeeta.Misra@Sun.COM if (status != WALK_NEXT)
357810946SSangeeta.Misra@Sun.COM return (status);
357910946SSangeeta.Misra@Sun.COM
358010946SSangeeta.Misra@Sun.COM sticky_walk = (ilb_walk_t *)wsp->walk_data;
358110946SSangeeta.Misra@Sun.COM ilbs = &sticky_walk->ilbs;
358210946SSangeeta.Misra@Sun.COM i = sticky_walk->idx;
358310946SSangeeta.Misra@Sun.COM
358410946SSangeeta.Misra@Sun.COM /* Read in the nsh_head in the i-th element of the array. */
358510946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_sticky_hash + i * sizeof (ilb_sticky_hash_t);
358610946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
358710946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n", khead);
358810946SSangeeta.Misra@Sun.COM return (WALK_ERR);
358910946SSangeeta.Misra@Sun.COM }
359010946SSangeeta.Misra@Sun.COM
359110946SSangeeta.Misra@Sun.COM /*
359210946SSangeeta.Misra@Sun.COM * Check if there is still entry in the current list.
359310946SSangeeta.Misra@Sun.COM *
359410946SSangeeta.Misra@Sun.COM * Note that list_next points to a kernel address and we need to
359510946SSangeeta.Misra@Sun.COM * compare list_next with the kernel address of the list head.
359610946SSangeeta.Misra@Sun.COM * So we need to calculate the address manually.
359710946SSangeeta.Misra@Sun.COM */
359810946SSangeeta.Misra@Sun.COM if ((char *)st.list.list_next != khead + offsetof(list_t,
359910946SSangeeta.Misra@Sun.COM list_head)) {
360010946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)list_object(&head,
360110946SSangeeta.Misra@Sun.COM st.list.list_next);
360210946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
360310946SSangeeta.Misra@Sun.COM }
360410946SSangeeta.Misra@Sun.COM
360510946SSangeeta.Misra@Sun.COM /* Start with the next bucket in the array. */
360610946SSangeeta.Misra@Sun.COM st_next = NULL;
360710946SSangeeta.Misra@Sun.COM for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) {
360810946SSangeeta.Misra@Sun.COM khead = (char *)ilbs->ilbs_sticky_hash + i *
360910946SSangeeta.Misra@Sun.COM sizeof (ilb_sticky_hash_t);
361010946SSangeeta.Misra@Sun.COM if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
361110946SSangeeta.Misra@Sun.COM mdb_warn("failed to read ilbs_sticky_hash at %p\n",
361210946SSangeeta.Misra@Sun.COM khead);
361310946SSangeeta.Misra@Sun.COM return (WALK_ERR);
361410946SSangeeta.Misra@Sun.COM }
361510946SSangeeta.Misra@Sun.COM
361610946SSangeeta.Misra@Sun.COM if ((char *)head.list_head.list_next != khead +
361710946SSangeeta.Misra@Sun.COM offsetof(list_t, list_head)) {
361810946SSangeeta.Misra@Sun.COM st_next = list_object(&head,
361910946SSangeeta.Misra@Sun.COM head.list_head.list_next);
362010946SSangeeta.Misra@Sun.COM break;
362110946SSangeeta.Misra@Sun.COM }
362210946SSangeeta.Misra@Sun.COM }
362310946SSangeeta.Misra@Sun.COM
362410946SSangeeta.Misra@Sun.COM if (st_next == NULL)
362510946SSangeeta.Misra@Sun.COM return (WALK_DONE);
362610946SSangeeta.Misra@Sun.COM
362710946SSangeeta.Misra@Sun.COM wsp->walk_addr = (uintptr_t)st_next;
362810946SSangeeta.Misra@Sun.COM sticky_walk->idx = i;
362910946SSangeeta.Misra@Sun.COM return (WALK_NEXT);
363010946SSangeeta.Misra@Sun.COM }
3631