xref: /illumos-gate/usr/src/cmd/mdb/common/modules/ip/ip.c (revision c7685b3b)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
569bb4bb4Scarlsonj  * Common Development and Distribution License (the "License").
669bb4bb4Scarlsonj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
220870f17bSKacheong Poon  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23f6eb544aSAndy Fiddaman  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
241edba515SAndy Fiddaman  * Copyright 2024 Oxide Computer Company
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <sys/types.h>
287c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
297c478bd9Sstevel@tonic-gate #include <sys/stream.h>
307c478bd9Sstevel@tonic-gate #include <sys/socket.h>
317c478bd9Sstevel@tonic-gate #include <sys/avl_impl.h>
32d5b6ed4bSVasumathi Sundaram - Sun Microsystems #include <net/if_types.h>
337c478bd9Sstevel@tonic-gate #include <net/if.h>
347c478bd9Sstevel@tonic-gate #include <net/route.h>
357c478bd9Sstevel@tonic-gate #include <netinet/in.h>
367c478bd9Sstevel@tonic-gate #include <netinet/ip6.h>
377c478bd9Sstevel@tonic-gate #include <netinet/udp.h>
387c478bd9Sstevel@tonic-gate #include <netinet/sctp.h>
397c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
407c478bd9Sstevel@tonic-gate #include <inet/common.h>
417c478bd9Sstevel@tonic-gate #include <inet/ip.h>
427c478bd9Sstevel@tonic-gate #include <inet/ip_ire.h>
437c478bd9Sstevel@tonic-gate #include <inet/ip6.h>
447c478bd9Sstevel@tonic-gate #include <inet/ipclassifier.h>
457c478bd9Sstevel@tonic-gate #include <inet/mi.h>
467c478bd9Sstevel@tonic-gate #include <sys/squeue_impl.h>
476a8288c7Scarlsonj #include <sys/modhash_impl.h>
48ffaa671aSsowmini #include <inet/ip_ndp.h>
49ffaa671aSsowmini #include <inet/ip_if.h>
50dbed73cbSSangeeta Misra #include <ilb.h>
51dbed73cbSSangeeta Misra #include <ilb/ilb_impl.h>
52dbed73cbSSangeeta Misra #include <ilb/ilb_stack.h>
53dbed73cbSSangeeta Misra #include <ilb/ilb_nat.h>
54dbed73cbSSangeeta Misra #include <ilb/ilb_conn.h>
55ffaa671aSsowmini #include <sys/dlpi.h>
56bd670b35SErik Nordmark #include <sys/zone.h>
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
597c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate #define	ADDR_WIDTH 11
62ffaa671aSsowmini #define	L2MAXADDRSTRLEN	255
63ffaa671aSsowmini #define	MAX_SAP_LEN	255
64d5b6ed4bSVasumathi Sundaram - Sun Microsystems #define	DEFCOLS		80
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate typedef struct {
677c478bd9Sstevel@tonic-gate 	const char *bit_name;	/* name of bit */
687c478bd9Sstevel@tonic-gate 	const char *bit_descr;	/* description of bit's purpose */
697c478bd9Sstevel@tonic-gate } bitname_t;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate static const bitname_t squeue_states[] = {
727c478bd9Sstevel@tonic-gate 	{ "SQS_PROC",		"being processed" },
737c478bd9Sstevel@tonic-gate 	{ "SQS_WORKER",		"... by a worker thread" },
747c478bd9Sstevel@tonic-gate 	{ "SQS_ENTER",		"... by an squeue_enter() thread" },
757c478bd9Sstevel@tonic-gate 	{ "SQS_FAST",		"... in fast-path mode" },
767c478bd9Sstevel@tonic-gate 	{ "SQS_USER",		"A non interrupt user" },
777c478bd9Sstevel@tonic-gate 	{ "SQS_BOUND",		"worker thread bound to CPU" },
787c478bd9Sstevel@tonic-gate 	{ "SQS_PROFILE",	"profiling enabled" },
797c478bd9Sstevel@tonic-gate 	{ "SQS_REENTER",	"re-entered thred" },
807c478bd9Sstevel@tonic-gate 	{ NULL }
817c478bd9Sstevel@tonic-gate };
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate typedef struct illif_walk_data {
847c478bd9Sstevel@tonic-gate 	ill_g_head_t ill_g_heads[MAX_G_HEADS];
857c478bd9Sstevel@tonic-gate 	int ill_list;
867c478bd9Sstevel@tonic-gate 	ill_if_t ill_if;
877c478bd9Sstevel@tonic-gate } illif_walk_data_t;
887c478bd9Sstevel@tonic-gate 
89bd670b35SErik Nordmark typedef struct ncec_walk_data_s {
90bd670b35SErik Nordmark 	struct ndp_g_s	ncec_ip_ndp;
91bd670b35SErik Nordmark 	int		ncec_hash_tbl_index;
92bd670b35SErik Nordmark 	ncec_t		ncec;
93bd670b35SErik Nordmark } ncec_walk_data_t;
94bd670b35SErik Nordmark 
95bd670b35SErik Nordmark typedef struct ncec_cbdata_s {
96bd670b35SErik Nordmark 	uintptr_t ncec_addr;
97bd670b35SErik Nordmark 	int	  ncec_ipversion;
98bd670b35SErik Nordmark } ncec_cbdata_t;
99ffaa671aSsowmini 
100ffaa671aSsowmini typedef struct nce_cbdata_s {
101ffaa671aSsowmini 	int		nce_ipversion;
102bd670b35SErik Nordmark 	char		nce_ill_name[LIFNAMSIZ];
103ffaa671aSsowmini } nce_cbdata_t;
104ffaa671aSsowmini 
105ffaa671aSsowmini typedef struct ire_cbdata_s {
106ffaa671aSsowmini 	int		ire_ipversion;
107ffaa671aSsowmini 	boolean_t	verbose;
108ffaa671aSsowmini } ire_cbdata_t;
109ffaa671aSsowmini 
110bd670b35SErik Nordmark typedef struct zi_cbdata_s {
111bd670b35SErik Nordmark 	const char	*zone_name;
112bd670b35SErik Nordmark 	ip_stack_t	*ipst;
113bd670b35SErik Nordmark 	boolean_t	shared_ip_zone;
114bd670b35SErik Nordmark } zi_cbdata_t;
115bd670b35SErik Nordmark 
1166a8288c7Scarlsonj typedef struct th_walk_data {
1176a8288c7Scarlsonj 	uint_t		thw_non_zero_only;
1186a8288c7Scarlsonj 	boolean_t	thw_match;
1196a8288c7Scarlsonj 	uintptr_t	thw_matchkey;
1206a8288c7Scarlsonj 	uintptr_t	thw_ipst;
1216a8288c7Scarlsonj 	clock_t		thw_lbolt;
1226a8288c7Scarlsonj } th_walk_data_t;
1236a8288c7Scarlsonj 
124d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ipcl_hash_walk_data_s {
125d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	conn_t		*conn;
126d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int		connf_tbl_index;
127d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t	hash_tbl;
128d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int		hash_tbl_size;
129d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ipcl_hash_walk_data_t;
130d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
131d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ill_walk_data_s {
132d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_t		ill;
133d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ill_walk_data_t;
134d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
135d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ill_cbdata_s {
136d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t ill_addr;
137d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int	  ill_ipversion;
138bd670b35SErik Nordmark 	ip_stack_t *ill_ipst;
139d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	boolean_t verbose;
140d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ill_cbdata_t;
141d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
142d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ipif_walk_data_s {
143d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipif_t		ipif;
144d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ipif_walk_data_t;
145d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
146d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ipif_cbdata_s {
147d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_t		ill;
148d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int		ipif_ipversion;
149d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	boolean_t	verbose;
150d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ipif_cbdata_t;
151d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
152d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct hash_walk_arg_s {
153d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	off_t	tbl_off;
154d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	off_t	size_off;
155d5b6ed4bSVasumathi Sundaram - Sun Microsystems } hash_walk_arg_t;
156d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
157d5b6ed4bSVasumathi Sundaram - Sun Microsystems static hash_walk_arg_t udp_hash_arg = {
158d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_udp_fanout),
159d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_udp_fanout_size)
160d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
161d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
162d5b6ed4bSVasumathi Sundaram - Sun Microsystems static hash_walk_arg_t conn_hash_arg = {
163d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_conn_fanout),
164d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_conn_fanout_size)
165d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
166d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
167d5b6ed4bSVasumathi Sundaram - Sun Microsystems static hash_walk_arg_t bind_hash_arg = {
168d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_bind_fanout),
169d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_bind_fanout_size)
170d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
171d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
172d5b6ed4bSVasumathi Sundaram - Sun Microsystems static hash_walk_arg_t proto_hash_arg = {
173bd670b35SErik Nordmark 	OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4),
174d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	0
175d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
176d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
177d5b6ed4bSVasumathi Sundaram - Sun Microsystems static hash_walk_arg_t proto_v6_hash_arg = {
178d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6),
179d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	0
180d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
181d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
182d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ip_list_walk_data_s {
183d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	off_t	nextoff;
184d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ip_list_walk_data_t;
185d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
186d5b6ed4bSVasumathi Sundaram - Sun Microsystems typedef struct ip_list_walk_arg_s {
187d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	off_t	off;
188d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	size_t	size;
189d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	off_t	nextp_off;
190d5b6ed4bSVasumathi Sundaram - Sun Microsystems } ip_list_walk_arg_t;
191d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
192d5b6ed4bSVasumathi Sundaram - Sun Microsystems static ip_list_walk_arg_t ipif_walk_arg = {
193d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ill_t, ill_ipif),
194d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	sizeof (ipif_t),
195d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ipif_t, ipif_next)
196d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
197d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
198d5b6ed4bSVasumathi Sundaram - Sun Microsystems static ip_list_walk_arg_t srcid_walk_arg = {
199d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(ip_stack_t, ips_srcid_head),
200d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	sizeof (srcid_map_t),
201d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	OFFSETOF(srcid_map_t, sm_next)
202d5b6ed4bSVasumathi Sundaram - Sun Microsystems };
203d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2047c478bd9Sstevel@tonic-gate static int iphdr(uintptr_t, uint_t, int, const mdb_arg_t *);
2057c478bd9Sstevel@tonic-gate static int ip6hdr(uintptr_t, uint_t, int, const mdb_arg_t *);
2067c478bd9Sstevel@tonic-gate 
207d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ill(uintptr_t, uint_t, int, const mdb_arg_t *);
208d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void ill_help(void);
209d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ill_walk_init(mdb_walk_state_t *);
210d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ill_walk_step(mdb_walk_state_t *);
211d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ill_format(uintptr_t, const void *, void *);
212d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void ill_header(boolean_t);
213d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
214d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ipif(uintptr_t, uint_t, int, const mdb_arg_t *);
215d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void ipif_help(void);
216d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ipif_walk_init(mdb_walk_state_t *);
217d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ipif_walk_step(mdb_walk_state_t *);
218d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ipif_format(uintptr_t, const void *, void *);
219d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void ipif_header(boolean_t);
220d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
221d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ip_list_walk_init(mdb_walk_state_t *);
222d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ip_list_walk_step(mdb_walk_state_t *);
223d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void ip_list_walk_fini(mdb_walk_state_t *);
224d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int srcid_walk_step(mdb_walk_state_t *);
225d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
226ffaa671aSsowmini static int ire_format(uintptr_t addr, const void *, void *);
227bd670b35SErik Nordmark static int ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion);
228bd670b35SErik Nordmark static int ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv);
229bd670b35SErik Nordmark static int ncec_walk_step(mdb_walk_state_t *wsp);
230bd670b35SErik Nordmark static int ncec_stack_walk_init(mdb_walk_state_t *wsp);
231bd670b35SErik Nordmark static int ncec_stack_walk_step(mdb_walk_state_t *wsp);
232bd670b35SErik Nordmark static void ncec_stack_walk_fini(mdb_walk_state_t *wsp);
233bd670b35SErik Nordmark static int ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw,
234bd670b35SErik Nordmark     ncec_cbdata_t *id);
235bd670b35SErik Nordmark static char *nce_l2_addr(const nce_t *, const ill_t *);
236f4b3ec61Sdh155122 
237d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ipcl_hash_walk_init(mdb_walk_state_t *);
238d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int ipcl_hash_walk_step(mdb_walk_state_t *);
239d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void ipcl_hash_walk_fini(mdb_walk_state_t *);
240d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
241d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int conn_status_walk_step(mdb_walk_state_t *);
242d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int conn_status(uintptr_t, uint_t, int, const mdb_arg_t *);
243d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void conn_status_help(void);
244d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
245d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int srcid_status(uintptr_t, uint_t, int, const mdb_arg_t *);
246d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
247dbed73cbSSangeeta Misra static int ilb_stacks_walk_step(mdb_walk_state_t *);
248dbed73cbSSangeeta Misra static int ilb_rules_walk_init(mdb_walk_state_t *);
249dbed73cbSSangeeta Misra static int ilb_rules_walk_step(mdb_walk_state_t *);
250dbed73cbSSangeeta Misra static int ilb_servers_walk_init(mdb_walk_state_t *);
251dbed73cbSSangeeta Misra static int ilb_servers_walk_step(mdb_walk_state_t *);
252dbed73cbSSangeeta Misra static int ilb_nat_src_walk_init(mdb_walk_state_t *);
253dbed73cbSSangeeta Misra static int ilb_nat_src_walk_step(mdb_walk_state_t *);
254dbed73cbSSangeeta Misra static int ilb_conn_walk_init(mdb_walk_state_t *);
255dbed73cbSSangeeta Misra static int ilb_conn_walk_step(mdb_walk_state_t *);
256dbed73cbSSangeeta Misra static int ilb_sticky_walk_init(mdb_walk_state_t *);
257dbed73cbSSangeeta Misra static int ilb_sticky_walk_step(mdb_walk_state_t *);
258dbed73cbSSangeeta Misra static void ilb_common_walk_fini(mdb_walk_state_t *);
259dbed73cbSSangeeta Misra 
260f4b3ec61Sdh155122 /*
261f4b3ec61Sdh155122  * Given the kernel address of an ip_stack_t, return the stackid
262f4b3ec61Sdh155122  */
263f4b3ec61Sdh155122 static int
ips_to_stackid(uintptr_t kaddr)264f4b3ec61Sdh155122 ips_to_stackid(uintptr_t kaddr)
265f4b3ec61Sdh155122 {
266f4b3ec61Sdh155122 	ip_stack_t ipss;
267f4b3ec61Sdh155122 	netstack_t nss;
268f4b3ec61Sdh155122 
269f4b3ec61Sdh155122 	if (mdb_vread(&ipss, sizeof (ipss), kaddr) == -1) {
270f4b3ec61Sdh155122 		mdb_warn("failed to read ip_stack_t %p", kaddr);
271f4b3ec61Sdh155122 		return (0);
272f4b3ec61Sdh155122 	}
273f4b3ec61Sdh155122 	kaddr = (uintptr_t)ipss.ips_netstack;
274f4b3ec61Sdh155122 	if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) {
275f4b3ec61Sdh155122 		mdb_warn("failed to read netstack_t %p", kaddr);
276f4b3ec61Sdh155122 		return (0);
277f4b3ec61Sdh155122 	}
278f4b3ec61Sdh155122 	return (nss.netstack_stackid);
279f4b3ec61Sdh155122 }
280f4b3ec61Sdh155122 
281bd670b35SErik Nordmark /* ARGSUSED */
282bd670b35SErik Nordmark static int
zone_to_ips_cb(uintptr_t addr,const void * zi_arg,void * zi_cb_arg)283bd670b35SErik Nordmark zone_to_ips_cb(uintptr_t addr, const void *zi_arg, void *zi_cb_arg)
284bd670b35SErik Nordmark {
285bd670b35SErik Nordmark 	zi_cbdata_t *zi_cb = zi_cb_arg;
286bd670b35SErik Nordmark 	zone_t zone;
287bd670b35SErik Nordmark 	char zone_name[ZONENAME_MAX];
288bd670b35SErik Nordmark 	netstack_t ns;
289bd670b35SErik Nordmark 
290bd670b35SErik Nordmark 	if (mdb_vread(&zone, sizeof (zone_t), addr) == -1) {
291bd670b35SErik Nordmark 		mdb_warn("can't read zone at %p", addr);
292bd670b35SErik Nordmark 		return (WALK_ERR);
293bd670b35SErik Nordmark 	}
294bd670b35SErik Nordmark 
295bd670b35SErik Nordmark 	(void) mdb_readstr(zone_name, ZONENAME_MAX, (uintptr_t)zone.zone_name);
296bd670b35SErik Nordmark 
297bd670b35SErik Nordmark 	if (strcmp(zi_cb->zone_name, zone_name) != 0)
298bd670b35SErik Nordmark 		return (WALK_NEXT);
299bd670b35SErik Nordmark 
300bd670b35SErik Nordmark 	zi_cb->shared_ip_zone = (!(zone.zone_flags & ZF_NET_EXCL) &&
301bd670b35SErik Nordmark 	    (strcmp(zone_name, "global") != 0));
302bd670b35SErik Nordmark 
303bd670b35SErik Nordmark 	if (mdb_vread(&ns, sizeof (netstack_t), (uintptr_t)zone.zone_netstack)
304bd670b35SErik Nordmark 	    == -1) {
305bd670b35SErik Nordmark 		mdb_warn("can't read netstack at %p", zone.zone_netstack);
306bd670b35SErik Nordmark 		return (WALK_ERR);
307bd670b35SErik Nordmark 	}
308bd670b35SErik Nordmark 
309bd670b35SErik Nordmark 	zi_cb->ipst = ns.netstack_ip;
310bd670b35SErik Nordmark 	return (WALK_DONE);
311bd670b35SErik Nordmark }
312bd670b35SErik Nordmark 
313bd670b35SErik Nordmark static ip_stack_t *
zone_to_ips(const char * zone_name)314bd670b35SErik Nordmark zone_to_ips(const char *zone_name)
315bd670b35SErik Nordmark {
316bd670b35SErik Nordmark 	zi_cbdata_t zi_cb;
317bd670b35SErik Nordmark 
318bd670b35SErik Nordmark 	if (zone_name == NULL)
319bd670b35SErik Nordmark 		return (NULL);
320bd670b35SErik Nordmark 
321bd670b35SErik Nordmark 	zi_cb.zone_name = zone_name;
322bd670b35SErik Nordmark 	zi_cb.ipst = NULL;
323bd670b35SErik Nordmark 	zi_cb.shared_ip_zone = B_FALSE;
324bd670b35SErik Nordmark 
325bd670b35SErik Nordmark 	if (mdb_walk("zone", (mdb_walk_cb_t)zone_to_ips_cb, &zi_cb) == -1) {
326bd670b35SErik Nordmark 		mdb_warn("failed to walk zone");
327bd670b35SErik Nordmark 		return (NULL);
328bd670b35SErik Nordmark 	}
329bd670b35SErik Nordmark 
330bd670b35SErik Nordmark 	if (zi_cb.shared_ip_zone) {
331bd670b35SErik Nordmark 		mdb_warn("%s is a Shared-IP zone, try '-s global' instead\n",
332bd670b35SErik Nordmark 		    zone_name);
333bd670b35SErik Nordmark 		return (NULL);
334bd670b35SErik Nordmark 	}
335bd670b35SErik Nordmark 
336bd670b35SErik Nordmark 	if (zi_cb.ipst == NULL) {
337bd670b35SErik Nordmark 		mdb_warn("failed to find zone %s\n", zone_name);
338bd670b35SErik Nordmark 		return (NULL);
339bd670b35SErik Nordmark 	}
340bd670b35SErik Nordmark 
341bd670b35SErik Nordmark 	return (zi_cb.ipst);
342bd670b35SErik Nordmark }
343bd670b35SErik Nordmark 
344721fffe3SKacheong Poon /*
345721fffe3SKacheong Poon  * Generic network stack walker initialization function.  It is used by all
346721fffe3SKacheong Poon  * other netwrok stack walkers.
347721fffe3SKacheong Poon  */
3487c478bd9Sstevel@tonic-gate int
ns_walk_init(mdb_walk_state_t * wsp)349721fffe3SKacheong Poon ns_walk_init(mdb_walk_state_t *wsp)
350f4b3ec61Sdh155122 {
351f4b3ec61Sdh155122 	if (mdb_layered_walk("netstack", wsp) == -1) {
352f4b3ec61Sdh155122 		mdb_warn("can't walk 'netstack'");
353f4b3ec61Sdh155122 		return (WALK_ERR);
354f4b3ec61Sdh155122 	}
355f4b3ec61Sdh155122 	return (WALK_NEXT);
356f4b3ec61Sdh155122 }
357f4b3ec61Sdh155122 
358721fffe3SKacheong Poon /*
359721fffe3SKacheong Poon  * Generic network stack walker stepping function.  It is used by all other
360721fffe3SKacheong Poon  * network stack walkers.  The which parameter differentiates the different
361721fffe3SKacheong Poon  * walkers.
362721fffe3SKacheong Poon  */
363f4b3ec61Sdh155122 int
ns_walk_step(mdb_walk_state_t * wsp,int which)364721fffe3SKacheong Poon ns_walk_step(mdb_walk_state_t *wsp, int which)
365f4b3ec61Sdh155122 {
366f4b3ec61Sdh155122 	uintptr_t kaddr;
367f4b3ec61Sdh155122 	netstack_t nss;
368f4b3ec61Sdh155122 
369f4b3ec61Sdh155122 	if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
370f4b3ec61Sdh155122 		mdb_warn("can't read netstack at %p", wsp->walk_addr);
371f4b3ec61Sdh155122 		return (WALK_ERR);
372f4b3ec61Sdh155122 	}
373721fffe3SKacheong Poon 	kaddr = (uintptr_t)nss.netstack_modules[which];
374f4b3ec61Sdh155122 
375f4b3ec61Sdh155122 	return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
376f4b3ec61Sdh155122 }
377f4b3ec61Sdh155122 
378721fffe3SKacheong Poon /*
379721fffe3SKacheong Poon  * IP network stack walker stepping function.
380721fffe3SKacheong Poon  */
381721fffe3SKacheong Poon int
ip_stacks_walk_step(mdb_walk_state_t * wsp)382721fffe3SKacheong Poon ip_stacks_walk_step(mdb_walk_state_t *wsp)
383721fffe3SKacheong Poon {
384721fffe3SKacheong Poon 	return (ns_walk_step(wsp, NS_IP));
385721fffe3SKacheong Poon }
386721fffe3SKacheong Poon 
387721fffe3SKacheong Poon /*
388721fffe3SKacheong Poon  * TCP network stack walker stepping function.
389721fffe3SKacheong Poon  */
390721fffe3SKacheong Poon int
tcp_stacks_walk_step(mdb_walk_state_t * wsp)391721fffe3SKacheong Poon tcp_stacks_walk_step(mdb_walk_state_t *wsp)
392721fffe3SKacheong Poon {
393721fffe3SKacheong Poon 	return (ns_walk_step(wsp, NS_TCP));
394721fffe3SKacheong Poon }
395721fffe3SKacheong Poon 
396721fffe3SKacheong Poon /*
397721fffe3SKacheong Poon  * SCTP network stack walker stepping function.
398721fffe3SKacheong Poon  */
399721fffe3SKacheong Poon int
sctp_stacks_walk_step(mdb_walk_state_t * wsp)400721fffe3SKacheong Poon sctp_stacks_walk_step(mdb_walk_state_t *wsp)
401721fffe3SKacheong Poon {
402721fffe3SKacheong Poon 	return (ns_walk_step(wsp, NS_SCTP));
403721fffe3SKacheong Poon }
404721fffe3SKacheong Poon 
405721fffe3SKacheong Poon /*
406721fffe3SKacheong Poon  * UDP network stack walker stepping function.
407721fffe3SKacheong Poon  */
408721fffe3SKacheong Poon int
udp_stacks_walk_step(mdb_walk_state_t * wsp)409721fffe3SKacheong Poon udp_stacks_walk_step(mdb_walk_state_t *wsp)
410721fffe3SKacheong Poon {
411721fffe3SKacheong Poon 	return (ns_walk_step(wsp, NS_UDP));
412721fffe3SKacheong Poon }
413721fffe3SKacheong Poon 
414721fffe3SKacheong Poon /*
415721fffe3SKacheong Poon  * Initialization function for the per CPU TCP stats counter walker of a given
416721fffe3SKacheong Poon  * TCP stack.
417721fffe3SKacheong Poon  */
418721fffe3SKacheong Poon int
tcps_sc_walk_init(mdb_walk_state_t * wsp)419721fffe3SKacheong Poon tcps_sc_walk_init(mdb_walk_state_t *wsp)
420721fffe3SKacheong Poon {
421721fffe3SKacheong Poon 	tcp_stack_t tcps;
422721fffe3SKacheong Poon 
423892ad162SToomas Soome 	if (wsp->walk_addr == 0)
424721fffe3SKacheong Poon 		return (WALK_ERR);
425721fffe3SKacheong Poon 
426721fffe3SKacheong Poon 	if (mdb_vread(&tcps, sizeof (tcps), wsp->walk_addr) == -1) {
427721fffe3SKacheong Poon 		mdb_warn("failed to read tcp_stack_t at %p", wsp->walk_addr);
428721fffe3SKacheong Poon 		return (WALK_ERR);
429721fffe3SKacheong Poon 	}
430721fffe3SKacheong Poon 	if (tcps.tcps_sc_cnt == 0)
431721fffe3SKacheong Poon 		return (WALK_DONE);
432721fffe3SKacheong Poon 
433721fffe3SKacheong Poon 	/*
434721fffe3SKacheong Poon 	 * Store the tcp_stack_t pointer in walk_data.  The stepping function
435721fffe3SKacheong Poon 	 * used it to calculate if the end of the counter has reached.
436721fffe3SKacheong Poon 	 */
437721fffe3SKacheong Poon 	wsp->walk_data = (void *)wsp->walk_addr;
438721fffe3SKacheong Poon 	wsp->walk_addr = (uintptr_t)tcps.tcps_sc;
439721fffe3SKacheong Poon 	return (WALK_NEXT);
440721fffe3SKacheong Poon }
441721fffe3SKacheong Poon 
442721fffe3SKacheong Poon /*
443721fffe3SKacheong Poon  * Stepping function for the per CPU TCP stats counterwalker.
444721fffe3SKacheong Poon  */
445721fffe3SKacheong Poon int
tcps_sc_walk_step(mdb_walk_state_t * wsp)446721fffe3SKacheong Poon tcps_sc_walk_step(mdb_walk_state_t *wsp)
447721fffe3SKacheong Poon {
448721fffe3SKacheong Poon 	int status;
449721fffe3SKacheong Poon 	tcp_stack_t tcps;
450721fffe3SKacheong Poon 	tcp_stats_cpu_t *stats;
451721fffe3SKacheong Poon 	char *next, *end;
452721fffe3SKacheong Poon 
453721fffe3SKacheong Poon 	if (mdb_vread(&tcps, sizeof (tcps), (uintptr_t)wsp->walk_data) == -1) {
454721fffe3SKacheong Poon 		mdb_warn("failed to read tcp_stack_t at %p", wsp->walk_addr);
455721fffe3SKacheong Poon 		return (WALK_ERR);
456721fffe3SKacheong Poon 	}
457721fffe3SKacheong Poon 	if (mdb_vread(&stats, sizeof (stats), wsp->walk_addr) == -1) {
458721fffe3SKacheong Poon 		mdb_warn("failed ot read tcp_stats_cpu_t at %p",
459721fffe3SKacheong Poon 		    wsp->walk_addr);
460721fffe3SKacheong Poon 		return (WALK_ERR);
461721fffe3SKacheong Poon 	}
462721fffe3SKacheong Poon 	status = wsp->walk_callback((uintptr_t)stats, &stats, wsp->walk_cbdata);
463721fffe3SKacheong Poon 	if (status != WALK_NEXT)
464721fffe3SKacheong Poon 		return (status);
465721fffe3SKacheong Poon 
466721fffe3SKacheong Poon 	next = (char *)wsp->walk_addr + sizeof (tcp_stats_cpu_t *);
467721fffe3SKacheong Poon 	end = (char *)tcps.tcps_sc + tcps.tcps_sc_cnt *
468721fffe3SKacheong Poon 	    sizeof (tcp_stats_cpu_t *);
469721fffe3SKacheong Poon 	if (next >= end)
470721fffe3SKacheong Poon 		return (WALK_DONE);
471721fffe3SKacheong Poon 	wsp->walk_addr = (uintptr_t)next;
472721fffe3SKacheong Poon 	return (WALK_NEXT);
473721fffe3SKacheong Poon }
474721fffe3SKacheong Poon 
4756a8288c7Scarlsonj int
th_hash_walk_init(mdb_walk_state_t * wsp)4766a8288c7Scarlsonj th_hash_walk_init(mdb_walk_state_t *wsp)
4776a8288c7Scarlsonj {
4786a8288c7Scarlsonj 	GElf_Sym sym;
4796a8288c7Scarlsonj 	list_node_t *next;
4806a8288c7Scarlsonj 
481892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
4826a8288c7Scarlsonj 		if (mdb_lookup_by_obj("ip", "ip_thread_list", &sym) == 0) {
4836a8288c7Scarlsonj 			wsp->walk_addr = sym.st_value;
4846a8288c7Scarlsonj 		} else {
4856a8288c7Scarlsonj 			mdb_warn("unable to locate ip_thread_list\n");
4866a8288c7Scarlsonj 			return (WALK_ERR);
4876a8288c7Scarlsonj 		}
4886a8288c7Scarlsonj 	}
4896a8288c7Scarlsonj 
4906a8288c7Scarlsonj 	if (mdb_vread(&next, sizeof (next),
4916a8288c7Scarlsonj 	    wsp->walk_addr + offsetof(list_t, list_head) +
4926a8288c7Scarlsonj 	    offsetof(list_node_t, list_next)) == -1 ||
4936a8288c7Scarlsonj 	    next == NULL) {
4946a8288c7Scarlsonj 		mdb_warn("non-DEBUG image; cannot walk th_hash list\n");
4956a8288c7Scarlsonj 		return (WALK_ERR);
4966a8288c7Scarlsonj 	}
4976a8288c7Scarlsonj 
4986a8288c7Scarlsonj 	if (mdb_layered_walk("list", wsp) == -1) {
4996a8288c7Scarlsonj 		mdb_warn("can't walk 'list'");
5006a8288c7Scarlsonj 		return (WALK_ERR);
5016a8288c7Scarlsonj 	} else {
5026a8288c7Scarlsonj 		return (WALK_NEXT);
5036a8288c7Scarlsonj 	}
5046a8288c7Scarlsonj }
5056a8288c7Scarlsonj 
5066a8288c7Scarlsonj int
th_hash_walk_step(mdb_walk_state_t * wsp)5076a8288c7Scarlsonj th_hash_walk_step(mdb_walk_state_t *wsp)
5086a8288c7Scarlsonj {
5096a8288c7Scarlsonj 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
5106a8288c7Scarlsonj 	    wsp->walk_cbdata));
5116a8288c7Scarlsonj }
5126a8288c7Scarlsonj 
513f4b3ec61Sdh155122 /*
514f4b3ec61Sdh155122  * Called with walk_addr being the address of ips_ill_g_heads
515f4b3ec61Sdh155122  */
516f4b3ec61Sdh155122 int
illif_stack_walk_init(mdb_walk_state_t * wsp)517f4b3ec61Sdh155122 illif_stack_walk_init(mdb_walk_state_t *wsp)
5187c478bd9Sstevel@tonic-gate {
5197c478bd9Sstevel@tonic-gate 	illif_walk_data_t *iw;
5207c478bd9Sstevel@tonic-gate 
521892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
522f4b3ec61Sdh155122 		mdb_warn("illif_stack supports only local walks\n");
5237c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
5247c478bd9Sstevel@tonic-gate 	}
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 	iw = mdb_alloc(sizeof (illif_walk_data_t), UM_SLEEP);
5277c478bd9Sstevel@tonic-gate 
528f4b3ec61Sdh155122 	if (mdb_vread(iw->ill_g_heads, MAX_G_HEADS * sizeof (ill_g_head_t),
529f4b3ec61Sdh155122 	    wsp->walk_addr) == -1) {
530f4b3ec61Sdh155122 		mdb_warn("failed to read 'ips_ill_g_heads' at %p",
531f4b3ec61Sdh155122 		    wsp->walk_addr);
5327c478bd9Sstevel@tonic-gate 		mdb_free(iw, sizeof (illif_walk_data_t));
5337c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
5347c478bd9Sstevel@tonic-gate 	}
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 	iw->ill_list = 0;
537f4b3ec61Sdh155122 	wsp->walk_addr = (uintptr_t)iw->ill_g_heads[0].ill_g_list_head;
5387c478bd9Sstevel@tonic-gate 	wsp->walk_data = iw;
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate int
illif_stack_walk_step(mdb_walk_state_t * wsp)544f4b3ec61Sdh155122 illif_stack_walk_step(mdb_walk_state_t *wsp)
5457c478bd9Sstevel@tonic-gate {
5467c478bd9Sstevel@tonic-gate 	uintptr_t addr = wsp->walk_addr;
5477c478bd9Sstevel@tonic-gate 	illif_walk_data_t *iw = wsp->walk_data;
5487c478bd9Sstevel@tonic-gate 	int list = iw->ill_list;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	if (mdb_vread(&iw->ill_if, sizeof (ill_if_t), addr) == -1) {
5517c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read ill_if_t at %p", addr);
5527c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
5537c478bd9Sstevel@tonic-gate 	}
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)iw->ill_if.illif_next;
5567c478bd9Sstevel@tonic-gate 
557f4b3ec61Sdh155122 	if (wsp->walk_addr ==
558f4b3ec61Sdh155122 	    (uintptr_t)iw->ill_g_heads[list].ill_g_list_head) {
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 		if (++list >= MAX_G_HEADS)
5617c478bd9Sstevel@tonic-gate 			return (WALK_DONE);
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 		iw->ill_list = list;
564f4b3ec61Sdh155122 		wsp->walk_addr =
565f4b3ec61Sdh155122 		    (uintptr_t)iw->ill_g_heads[list].ill_g_list_head;
5667c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(addr, iw, wsp->walk_cbdata));
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate void
illif_stack_walk_fini(mdb_walk_state_t * wsp)573f4b3ec61Sdh155122 illif_stack_walk_fini(mdb_walk_state_t *wsp)
5747c478bd9Sstevel@tonic-gate {
5757c478bd9Sstevel@tonic-gate 	mdb_free(wsp->walk_data, sizeof (illif_walk_data_t));
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate typedef struct illif_cbdata {
5797c478bd9Sstevel@tonic-gate 	uint_t ill_flags;
5807c478bd9Sstevel@tonic-gate 	uintptr_t ill_addr;
5817c478bd9Sstevel@tonic-gate 	int ill_printlist;	/* list to be printed (MAX_G_HEADS for all) */
5827c478bd9Sstevel@tonic-gate 	boolean_t ill_printed;
5837c478bd9Sstevel@tonic-gate } illif_cbdata_t;
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate static int
illif_cb(uintptr_t addr,const illif_walk_data_t * iw,illif_cbdata_t * id)5867c478bd9Sstevel@tonic-gate illif_cb(uintptr_t addr, const illif_walk_data_t *iw, illif_cbdata_t *id)
5877c478bd9Sstevel@tonic-gate {
5887c478bd9Sstevel@tonic-gate 	const char *version;
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	if (id->ill_printlist < MAX_G_HEADS &&
5917c478bd9Sstevel@tonic-gate 	    id->ill_printlist != iw->ill_list)
5927c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 	if (id->ill_flags & DCMD_ADDRSPEC && id->ill_addr != addr)
5957c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	if (id->ill_flags & DCMD_PIPE_OUT) {
5987c478bd9Sstevel@tonic-gate 		mdb_printf("%p\n", addr);
5997c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
6007c478bd9Sstevel@tonic-gate 	}
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	switch (iw->ill_list) {
6037c478bd9Sstevel@tonic-gate 		case IP_V4_G_HEAD:	version = "v4";	break;
6047c478bd9Sstevel@tonic-gate 		case IP_V6_G_HEAD:	version = "v6";	break;
6057c478bd9Sstevel@tonic-gate 		default:		version = "??"; break;
6067c478bd9Sstevel@tonic-gate 	}
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate 	mdb_printf("%?p %2s %?p %10d %?p %s\n",
6097c478bd9Sstevel@tonic-gate 	    addr, version, addr + offsetof(ill_if_t, illif_avl_by_ppa),
6107c478bd9Sstevel@tonic-gate 	    iw->ill_if.illif_avl_by_ppa.avl_numnodes,
6117c478bd9Sstevel@tonic-gate 	    iw->ill_if.illif_ppa_arena, iw->ill_if.illif_name);
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate 	id->ill_printed = TRUE;
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
6167c478bd9Sstevel@tonic-gate }
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate int
ip_stacks_common_walk_init(mdb_walk_state_t * wsp)619ffaa671aSsowmini ip_stacks_common_walk_init(mdb_walk_state_t *wsp)
620f4b3ec61Sdh155122 {
621f4b3ec61Sdh155122 	if (mdb_layered_walk("ip_stacks", wsp) == -1) {
622f4b3ec61Sdh155122 		mdb_warn("can't walk 'ip_stacks'");
623f4b3ec61Sdh155122 		return (WALK_ERR);
624f4b3ec61Sdh155122 	}
625f4b3ec61Sdh155122 
626f4b3ec61Sdh155122 	return (WALK_NEXT);
627f4b3ec61Sdh155122 }
628f4b3ec61Sdh155122 
629f4b3ec61Sdh155122 int
illif_walk_step(mdb_walk_state_t * wsp)630f4b3ec61Sdh155122 illif_walk_step(mdb_walk_state_t *wsp)
631f4b3ec61Sdh155122 {
632f4b3ec61Sdh155122 	uintptr_t kaddr;
633f4b3ec61Sdh155122 
634f4b3ec61Sdh155122 	kaddr = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ill_g_heads);
635f4b3ec61Sdh155122 
636f4b3ec61Sdh155122 	if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) {
637f4b3ec61Sdh155122 		mdb_warn("can't read ips_ip_cache_table at %p", kaddr);
638f4b3ec61Sdh155122 		return (WALK_ERR);
639f4b3ec61Sdh155122 	}
640f4b3ec61Sdh155122 
641f4b3ec61Sdh155122 	if (mdb_pwalk("illif_stack", wsp->walk_callback,
642f4b3ec61Sdh155122 	    wsp->walk_cbdata, kaddr) == -1) {
643f4b3ec61Sdh155122 		mdb_warn("couldn't walk 'illif_stack' for ips_ill_g_heads %p",
644f4b3ec61Sdh155122 		    kaddr);
645f4b3ec61Sdh155122 		return (WALK_ERR);
646f4b3ec61Sdh155122 	}
647f4b3ec61Sdh155122 	return (WALK_NEXT);
648f4b3ec61Sdh155122 }
649f4b3ec61Sdh155122 
650f4b3ec61Sdh155122 int
illif(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6517c478bd9Sstevel@tonic-gate illif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6527c478bd9Sstevel@tonic-gate {
6537c478bd9Sstevel@tonic-gate 	illif_cbdata_t id;
6547c478bd9Sstevel@tonic-gate 	ill_if_t ill_if;
6557c478bd9Sstevel@tonic-gate 	const char *opt_P = NULL;
6567c478bd9Sstevel@tonic-gate 	int printlist = MAX_G_HEADS;
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
6597c478bd9Sstevel@tonic-gate 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
6607c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate 	if (opt_P != NULL) {
6637c478bd9Sstevel@tonic-gate 		if (strcmp("v4", opt_P) == 0) {
6647c478bd9Sstevel@tonic-gate 			printlist = IP_V4_G_HEAD;
6657c478bd9Sstevel@tonic-gate 		} else if (strcmp("v6", opt_P) == 0) {
6667c478bd9Sstevel@tonic-gate 			printlist = IP_V6_G_HEAD;
6677c478bd9Sstevel@tonic-gate 		} else {
6687c478bd9Sstevel@tonic-gate 			mdb_warn("invalid protocol '%s'\n", opt_P);
6697c478bd9Sstevel@tonic-gate 			return (DCMD_USAGE);
6707c478bd9Sstevel@tonic-gate 		}
6717c478bd9Sstevel@tonic-gate 	}
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags) && (flags & DCMD_PIPE_OUT) == 0) {
6747c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%?s %2s %?s %10s %?s %-10s%</u>\n",
6757c478bd9Sstevel@tonic-gate 		    "ADDR", "IP", "AVLADDR", "NUMNODES", "ARENA", "NAME");
6767c478bd9Sstevel@tonic-gate 	}
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	id.ill_flags = flags;
6797c478bd9Sstevel@tonic-gate 	id.ill_addr = addr;
6807c478bd9Sstevel@tonic-gate 	id.ill_printlist = printlist;
6817c478bd9Sstevel@tonic-gate 	id.ill_printed = FALSE;
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 	if (mdb_walk("illif", (mdb_walk_cb_t)illif_cb, &id) == -1) {
6847c478bd9Sstevel@tonic-gate 		mdb_warn("can't walk ill_if_t structures");
6857c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6867c478bd9Sstevel@tonic-gate 	}
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC) || opt_P != NULL || id.ill_printed)
6897c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 	/*
6927c478bd9Sstevel@tonic-gate 	 * If an address is specified and the walk doesn't find it,
6937c478bd9Sstevel@tonic-gate 	 * print it anyway.
6947c478bd9Sstevel@tonic-gate 	 */
6957c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ill_if, sizeof (ill_if_t), addr) == -1) {
6967c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read ill_if_t at %p", addr);
6977c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6987c478bd9Sstevel@tonic-gate 	}
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	mdb_printf("%?p %2s %?p %10d %?p %s\n",
7017c478bd9Sstevel@tonic-gate 	    addr, "??", addr + offsetof(ill_if_t, illif_avl_by_ppa),
7027c478bd9Sstevel@tonic-gate 	    ill_if.illif_avl_by_ppa.avl_numnodes,
7037c478bd9Sstevel@tonic-gate 	    ill_if.illif_ppa_arena, ill_if.illif_name);
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate static void
illif_help(void)7097c478bd9Sstevel@tonic-gate illif_help(void)
7107c478bd9Sstevel@tonic-gate {
7117c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
7127c478bd9Sstevel@tonic-gate 	mdb_printf("\t-P v4 | v6"
7137c478bd9Sstevel@tonic-gate 	    "\tfilter interface structures for the specified protocol\n");
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate int
nce_walk_init(mdb_walk_state_t * wsp)717bd670b35SErik Nordmark nce_walk_init(mdb_walk_state_t *wsp)
718bd670b35SErik Nordmark {
719bd670b35SErik Nordmark 	if (mdb_layered_walk("nce_cache", wsp) == -1) {
720bd670b35SErik Nordmark 		mdb_warn("can't walk 'nce_cache'");
721bd670b35SErik Nordmark 		return (WALK_ERR);
722bd670b35SErik Nordmark 	}
723bd670b35SErik Nordmark 
724bd670b35SErik Nordmark 	return (WALK_NEXT);
725bd670b35SErik Nordmark }
726bd670b35SErik Nordmark 
727bd670b35SErik Nordmark int
nce_walk_step(mdb_walk_state_t * wsp)728bd670b35SErik Nordmark nce_walk_step(mdb_walk_state_t *wsp)
729bd670b35SErik Nordmark {
730bd670b35SErik Nordmark 	nce_t nce;
731bd670b35SErik Nordmark 
732bd670b35SErik Nordmark 	if (mdb_vread(&nce, sizeof (nce), wsp->walk_addr) == -1) {
733bd670b35SErik Nordmark 		mdb_warn("can't read nce at %p", wsp->walk_addr);
734bd670b35SErik Nordmark 		return (WALK_ERR);
735bd670b35SErik Nordmark 	}
736bd670b35SErik Nordmark 
737bd670b35SErik Nordmark 	return (wsp->walk_callback(wsp->walk_addr, &nce, wsp->walk_cbdata));
738bd670b35SErik Nordmark }
739bd670b35SErik Nordmark 
740bd670b35SErik Nordmark static int
nce_format(uintptr_t addr,const nce_t * ncep,void * nce_cb_arg)741bd670b35SErik Nordmark nce_format(uintptr_t addr, const nce_t *ncep, void *nce_cb_arg)
742bd670b35SErik Nordmark {
743bd670b35SErik Nordmark 	nce_cbdata_t *nce_cb = nce_cb_arg;
744bd670b35SErik Nordmark 	ill_t ill;
745bd670b35SErik Nordmark 	char ill_name[LIFNAMSIZ];
746bd670b35SErik Nordmark 	ncec_t ncec;
747bd670b35SErik Nordmark 
748bd670b35SErik Nordmark 	if (mdb_vread(&ncec, sizeof (ncec),
749bd670b35SErik Nordmark 	    (uintptr_t)ncep->nce_common) == -1) {
750bd670b35SErik Nordmark 		mdb_warn("can't read ncec at %p", ncep->nce_common);
751bd670b35SErik Nordmark 		return (WALK_NEXT);
752bd670b35SErik Nordmark 	}
753bd670b35SErik Nordmark 	if (nce_cb->nce_ipversion != 0 &&
754bd670b35SErik Nordmark 	    ncec.ncec_ipversion != nce_cb->nce_ipversion)
755bd670b35SErik Nordmark 		return (WALK_NEXT);
756bd670b35SErik Nordmark 
757bd670b35SErik Nordmark 	if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncep->nce_ill) == -1) {
758bd670b35SErik Nordmark 		mdb_snprintf(ill_name, sizeof (ill_name), "--");
759bd670b35SErik Nordmark 	} else {
760bd670b35SErik Nordmark 		(void) mdb_readstr(ill_name,
761bd670b35SErik Nordmark 		    MIN(LIFNAMSIZ, ill.ill_name_length),
762bd670b35SErik Nordmark 		    (uintptr_t)ill.ill_name);
763bd670b35SErik Nordmark 	}
764bd670b35SErik Nordmark 
765bd670b35SErik Nordmark 	if (nce_cb->nce_ill_name[0] != '\0' &&
766bd670b35SErik Nordmark 	    strncmp(nce_cb->nce_ill_name, ill_name, LIFNAMSIZ) != 0)
767bd670b35SErik Nordmark 		return (WALK_NEXT);
768bd670b35SErik Nordmark 
769bd670b35SErik Nordmark 	if (ncec.ncec_ipversion == IPV6_VERSION) {
770bd670b35SErik Nordmark 
771bd670b35SErik Nordmark 		mdb_printf("%?p %5s %-18s %?p %6d %N\n",
772bd670b35SErik Nordmark 		    addr, ill_name,
773bd670b35SErik Nordmark 		    nce_l2_addr(ncep, &ill),
774bd670b35SErik Nordmark 		    ncep->nce_fp_mp,
775bd670b35SErik Nordmark 		    ncep->nce_refcnt,
776bd670b35SErik Nordmark 		    &ncep->nce_addr);
777bd670b35SErik Nordmark 
778bd670b35SErik Nordmark 	} else {
779bd670b35SErik Nordmark 		struct in_addr nceaddr;
780bd670b35SErik Nordmark 
781bd670b35SErik Nordmark 		IN6_V4MAPPED_TO_INADDR(&ncep->nce_addr, &nceaddr);
782bd670b35SErik Nordmark 		mdb_printf("%?p %5s %-18s %?p %6d %I\n",
783bd670b35SErik Nordmark 		    addr, ill_name,
784bd670b35SErik Nordmark 		    nce_l2_addr(ncep, &ill),
785bd670b35SErik Nordmark 		    ncep->nce_fp_mp,
786bd670b35SErik Nordmark 		    ncep->nce_refcnt,
787bd670b35SErik Nordmark 		    nceaddr.s_addr);
788bd670b35SErik Nordmark 	}
789bd670b35SErik Nordmark 
790bd670b35SErik Nordmark 	return (WALK_NEXT);
791bd670b35SErik Nordmark }
792bd670b35SErik Nordmark 
793bd670b35SErik Nordmark int
dce_walk_init(mdb_walk_state_t * wsp)794bd670b35SErik Nordmark dce_walk_init(mdb_walk_state_t *wsp)
795bd670b35SErik Nordmark {
796bd670b35SErik Nordmark 	wsp->walk_data = (void *)wsp->walk_addr;
797bd670b35SErik Nordmark 
798bd670b35SErik Nordmark 	if (mdb_layered_walk("dce_cache", wsp) == -1) {
799bd670b35SErik Nordmark 		mdb_warn("can't walk 'dce_cache'");
800bd670b35SErik Nordmark 		return (WALK_ERR);
801bd670b35SErik Nordmark 	}
802bd670b35SErik Nordmark 
803bd670b35SErik Nordmark 	return (WALK_NEXT);
804bd670b35SErik Nordmark }
805bd670b35SErik Nordmark 
806bd670b35SErik Nordmark int
dce_walk_step(mdb_walk_state_t * wsp)807bd670b35SErik Nordmark dce_walk_step(mdb_walk_state_t *wsp)
808bd670b35SErik Nordmark {
809bd670b35SErik Nordmark 	dce_t dce;
810bd670b35SErik Nordmark 
811bd670b35SErik Nordmark 	if (mdb_vread(&dce, sizeof (dce), wsp->walk_addr) == -1) {
812bd670b35SErik Nordmark 		mdb_warn("can't read dce at %p", wsp->walk_addr);
813bd670b35SErik Nordmark 		return (WALK_ERR);
814bd670b35SErik Nordmark 	}
815bd670b35SErik Nordmark 
816bd670b35SErik Nordmark 	/* If ip_stack_t is specified, skip DCEs that don't belong to it. */
817bd670b35SErik Nordmark 	if ((wsp->walk_data != NULL) && (wsp->walk_data != dce.dce_ipst))
818bd670b35SErik Nordmark 		return (WALK_NEXT);
819bd670b35SErik Nordmark 
820bd670b35SErik Nordmark 	return (wsp->walk_callback(wsp->walk_addr, &dce, wsp->walk_cbdata));
821bd670b35SErik Nordmark }
822bd670b35SErik Nordmark 
823bd670b35SErik Nordmark int
ire_walk_init(mdb_walk_state_t * wsp)8247c478bd9Sstevel@tonic-gate ire_walk_init(mdb_walk_state_t *wsp)
8257c478bd9Sstevel@tonic-gate {
826bd670b35SErik Nordmark 	wsp->walk_data = (void *)wsp->walk_addr;
827bd670b35SErik Nordmark 
8287c478bd9Sstevel@tonic-gate 	if (mdb_layered_walk("ire_cache", wsp) == -1) {
8297c478bd9Sstevel@tonic-gate 		mdb_warn("can't walk 'ire_cache'");
8307c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8317c478bd9Sstevel@tonic-gate 	}
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate int
ire_walk_step(mdb_walk_state_t * wsp)8377c478bd9Sstevel@tonic-gate ire_walk_step(mdb_walk_state_t *wsp)
8387c478bd9Sstevel@tonic-gate {
8397c478bd9Sstevel@tonic-gate 	ire_t ire;
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) {
8427c478bd9Sstevel@tonic-gate 		mdb_warn("can't read ire at %p", wsp->walk_addr);
8437c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8447c478bd9Sstevel@tonic-gate 	}
8457c478bd9Sstevel@tonic-gate 
846bd670b35SErik Nordmark 	/* If ip_stack_t is specified, skip IREs that don't belong to it. */
847bd670b35SErik Nordmark 	if ((wsp->walk_data != NULL) && (wsp->walk_data != ire.ire_ipst))
848f4b3ec61Sdh155122 		return (WALK_NEXT);
849bd670b35SErik Nordmark 
850bd670b35SErik Nordmark 	return (wsp->walk_callback(wsp->walk_addr, &ire, wsp->walk_cbdata));
851f4b3ec61Sdh155122 }
852f4b3ec61Sdh155122 
853f4b3ec61Sdh155122 /* ARGSUSED */
854f4b3ec61Sdh155122 int
ire_next_walk_init(mdb_walk_state_t * wsp)855f4b3ec61Sdh155122 ire_next_walk_init(mdb_walk_state_t *wsp)
856f4b3ec61Sdh155122 {
857f4b3ec61Sdh155122 	return (WALK_NEXT);
858f4b3ec61Sdh155122 }
859f4b3ec61Sdh155122 
860f4b3ec61Sdh155122 int
ire_next_walk_step(mdb_walk_state_t * wsp)861f4b3ec61Sdh155122 ire_next_walk_step(mdb_walk_state_t *wsp)
862f4b3ec61Sdh155122 {
863f4b3ec61Sdh155122 	ire_t ire;
864f4b3ec61Sdh155122 	int status;
865f4b3ec61Sdh155122 
866f4b3ec61Sdh155122 
867892ad162SToomas Soome 	if (wsp->walk_addr == 0)
868f4b3ec61Sdh155122 		return (WALK_DONE);
869f4b3ec61Sdh155122 
870f4b3ec61Sdh155122 	if (mdb_vread(&ire, sizeof (ire), wsp->walk_addr) == -1) {
871f4b3ec61Sdh155122 		mdb_warn("can't read ire at %p", wsp->walk_addr);
872f4b3ec61Sdh155122 		return (WALK_ERR);
873f4b3ec61Sdh155122 	}
874f4b3ec61Sdh155122 	status = wsp->walk_callback(wsp->walk_addr, &ire,
875f4b3ec61Sdh155122 	    wsp->walk_cbdata);
876f4b3ec61Sdh155122 
877f4b3ec61Sdh155122 	if (status != WALK_NEXT)
878f4b3ec61Sdh155122 		return (status);
879f4b3ec61Sdh155122 
880f4b3ec61Sdh155122 	wsp->walk_addr = (uintptr_t)ire.ire_next;
881f4b3ec61Sdh155122 	return (status);
882f4b3ec61Sdh155122 }
883f4b3ec61Sdh155122 
8847c478bd9Sstevel@tonic-gate static int
ire_format(uintptr_t addr,const void * ire_arg,void * ire_cb_arg)885ffaa671aSsowmini ire_format(uintptr_t addr, const void *ire_arg, void *ire_cb_arg)
8867c478bd9Sstevel@tonic-gate {
887ffaa671aSsowmini 	const ire_t *irep = ire_arg;
888ffaa671aSsowmini 	ire_cbdata_t *ire_cb = ire_cb_arg;
889ffaa671aSsowmini 	boolean_t verbose = ire_cb->verbose;
890bd670b35SErik Nordmark 	ill_t ill;
891bd670b35SErik Nordmark 	char ill_name[LIFNAMSIZ];
892bd670b35SErik Nordmark 	boolean_t condemned = irep->ire_generation == IRE_GENERATION_CONDEMNED;
893ffaa671aSsowmini 
8947c478bd9Sstevel@tonic-gate 	static const mdb_bitmask_t tmasks[] = {
8957c478bd9Sstevel@tonic-gate 		{ "BROADCAST",	IRE_BROADCAST,		IRE_BROADCAST	},
8967c478bd9Sstevel@tonic-gate 		{ "DEFAULT",	IRE_DEFAULT,		IRE_DEFAULT	},
8977c478bd9Sstevel@tonic-gate 		{ "LOCAL",	IRE_LOCAL,		IRE_LOCAL	},
8987c478bd9Sstevel@tonic-gate 		{ "LOOPBACK",	IRE_LOOPBACK,		IRE_LOOPBACK	},
8997c478bd9Sstevel@tonic-gate 		{ "PREFIX",	IRE_PREFIX,		IRE_PREFIX	},
900bd670b35SErik Nordmark 		{ "MULTICAST",	IRE_MULTICAST,		IRE_MULTICAST	},
901bd670b35SErik Nordmark 		{ "NOROUTE",	IRE_NOROUTE,		IRE_NOROUTE	},
9027c478bd9Sstevel@tonic-gate 		{ "IF_NORESOLVER", IRE_IF_NORESOLVER,	IRE_IF_NORESOLVER },
9037c478bd9Sstevel@tonic-gate 		{ "IF_RESOLVER", IRE_IF_RESOLVER,	IRE_IF_RESOLVER	},
904bd670b35SErik Nordmark 		{ "IF_CLONE",	IRE_IF_CLONE,		IRE_IF_CLONE	},
9057c478bd9Sstevel@tonic-gate 		{ "HOST",	IRE_HOST,		IRE_HOST	},
9067c478bd9Sstevel@tonic-gate 		{ NULL,		0,			0		}
9077c478bd9Sstevel@tonic-gate 	};
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate 	static const mdb_bitmask_t fmasks[] = {
9107c478bd9Sstevel@tonic-gate 		{ "UP",		RTF_UP,			RTF_UP		},
9117c478bd9Sstevel@tonic-gate 		{ "GATEWAY",	RTF_GATEWAY,		RTF_GATEWAY	},
9127c478bd9Sstevel@tonic-gate 		{ "HOST",	RTF_HOST,		RTF_HOST	},
9137c478bd9Sstevel@tonic-gate 		{ "REJECT",	RTF_REJECT,		RTF_REJECT	},
9147c478bd9Sstevel@tonic-gate 		{ "DYNAMIC",	RTF_DYNAMIC,		RTF_DYNAMIC	},
9157c478bd9Sstevel@tonic-gate 		{ "MODIFIED",	RTF_MODIFIED,		RTF_MODIFIED	},
9167c478bd9Sstevel@tonic-gate 		{ "DONE",	RTF_DONE,		RTF_DONE	},
9177c478bd9Sstevel@tonic-gate 		{ "MASK",	RTF_MASK,		RTF_MASK	},
9187c478bd9Sstevel@tonic-gate 		{ "CLONING",	RTF_CLONING,		RTF_CLONING	},
9197c478bd9Sstevel@tonic-gate 		{ "XRESOLVE",	RTF_XRESOLVE,		RTF_XRESOLVE	},
9207c478bd9Sstevel@tonic-gate 		{ "LLINFO",	RTF_LLINFO,		RTF_LLINFO	},
9217c478bd9Sstevel@tonic-gate 		{ "STATIC",	RTF_STATIC,		RTF_STATIC	},
9227c478bd9Sstevel@tonic-gate 		{ "BLACKHOLE",	RTF_BLACKHOLE,		RTF_BLACKHOLE	},
9237c478bd9Sstevel@tonic-gate 		{ "PRIVATE",	RTF_PRIVATE,		RTF_PRIVATE	},
9247c478bd9Sstevel@tonic-gate 		{ "PROTO2",	RTF_PROTO2,		RTF_PROTO2	},
9257c478bd9Sstevel@tonic-gate 		{ "PROTO1",	RTF_PROTO1,		RTF_PROTO1	},
9267c478bd9Sstevel@tonic-gate 		{ "MULTIRT",	RTF_MULTIRT,		RTF_MULTIRT	},
9277c478bd9Sstevel@tonic-gate 		{ "SETSRC",	RTF_SETSRC,		RTF_SETSRC	},
928bd670b35SErik Nordmark 		{ "INDIRECT",	RTF_INDIRECT,		RTF_INDIRECT	},
9297c478bd9Sstevel@tonic-gate 		{ NULL,		0,			0		}
9307c478bd9Sstevel@tonic-gate 	};
9317c478bd9Sstevel@tonic-gate 
932ffaa671aSsowmini 	if (ire_cb->ire_ipversion != 0 &&
933ffaa671aSsowmini 	    irep->ire_ipversion != ire_cb->ire_ipversion)
934ffaa671aSsowmini 		return (WALK_NEXT);
935ffaa671aSsowmini 
936bd670b35SErik Nordmark 	if (mdb_vread(&ill, sizeof (ill), (uintptr_t)irep->ire_ill) == -1) {
937bd670b35SErik Nordmark 		mdb_snprintf(ill_name, sizeof (ill_name), "--");
938bd670b35SErik Nordmark 	} else {
939bd670b35SErik Nordmark 		(void) mdb_readstr(ill_name,
940bd670b35SErik Nordmark 		    MIN(LIFNAMSIZ, ill.ill_name_length),
941bd670b35SErik Nordmark 		    (uintptr_t)ill.ill_name);
942bd670b35SErik Nordmark 	}
943bd670b35SErik Nordmark 
944ffaa671aSsowmini 	if (irep->ire_ipversion == IPV6_VERSION && verbose) {
9457c478bd9Sstevel@tonic-gate 
946bd670b35SErik Nordmark 		mdb_printf("%<b>%?p%</b>%3s %40N <%hb%s>\n"
947bd670b35SErik Nordmark 		    "%?s %40N\n"
948bd670b35SErik Nordmark 		    "%?s %40d %4d <%hb> %s\n",
949bd670b35SErik Nordmark 		    addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6,
950bd670b35SErik Nordmark 		    irep->ire_type, tmasks,
951bd670b35SErik Nordmark 		    (irep->ire_testhidden ? ", HIDDEN" : ""),
952bd670b35SErik Nordmark 		    "", &irep->ire_addr_v6,
953f4b3ec61Sdh155122 		    "", ips_to_stackid((uintptr_t)irep->ire_ipst),
954f4b3ec61Sdh155122 		    irep->ire_zoneid,
955bd670b35SErik Nordmark 		    irep->ire_flags, fmasks, ill_name);
9567c478bd9Sstevel@tonic-gate 
957ffaa671aSsowmini 	} else if (irep->ire_ipversion == IPV6_VERSION) {
9587c478bd9Sstevel@tonic-gate 
959bd670b35SErik Nordmark 		mdb_printf("%?p%3s %30N %30N %5d %4d %s\n",
960bd670b35SErik Nordmark 		    addr, condemned ? "(C)" : "", &irep->ire_setsrc_addr_v6,
961f4b3ec61Sdh155122 		    &irep->ire_addr_v6,
962f4b3ec61Sdh155122 		    ips_to_stackid((uintptr_t)irep->ire_ipst),
963bd670b35SErik Nordmark 		    irep->ire_zoneid, ill_name);
9647c478bd9Sstevel@tonic-gate 
965ffaa671aSsowmini 	} else if (verbose) {
9667c478bd9Sstevel@tonic-gate 
967bd670b35SErik Nordmark 		mdb_printf("%<b>%?p%</b>%3s %40I <%hb%s>\n"
968bd670b35SErik Nordmark 		    "%?s %40I\n"
969bd670b35SErik Nordmark 		    "%?s %40d %4d <%hb> %s\n",
970bd670b35SErik Nordmark 		    addr, condemned ? "(C)" : "", irep->ire_setsrc_addr,
971bd670b35SErik Nordmark 		    irep->ire_type, tmasks,
972bd670b35SErik Nordmark 		    (irep->ire_testhidden ? ", HIDDEN" : ""),
973bd670b35SErik Nordmark 		    "", irep->ire_addr,
974f4b3ec61Sdh155122 		    "", ips_to_stackid((uintptr_t)irep->ire_ipst),
975bd670b35SErik Nordmark 		    irep->ire_zoneid, irep->ire_flags, fmasks, ill_name);
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 	} else {
9787c478bd9Sstevel@tonic-gate 
979bd670b35SErik Nordmark 		mdb_printf("%?p%3s %30I %30I %5d %4d %s\n", addr,
980bd670b35SErik Nordmark 		    condemned ? "(C)" : "", irep->ire_setsrc_addr,
981f4b3ec61Sdh155122 		    irep->ire_addr, ips_to_stackid((uintptr_t)irep->ire_ipst),
982bd670b35SErik Nordmark 		    irep->ire_zoneid, ill_name);
9837c478bd9Sstevel@tonic-gate 	}
9847c478bd9Sstevel@tonic-gate 
9857c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
9867c478bd9Sstevel@tonic-gate }
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate /*
9897c478bd9Sstevel@tonic-gate  * There are faster ways to do this.  Given the interactive nature of this
9907c478bd9Sstevel@tonic-gate  * use I don't think its worth much effort.
9917c478bd9Sstevel@tonic-gate  */
9927c478bd9Sstevel@tonic-gate static unsigned short
ipcksum(void * p,int len)9937c478bd9Sstevel@tonic-gate ipcksum(void *p, int len)
9947c478bd9Sstevel@tonic-gate {
9957c478bd9Sstevel@tonic-gate 	int32_t	sum = 0;
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	while (len > 1) {
9987c478bd9Sstevel@tonic-gate 		/* alignment */
9997c478bd9Sstevel@tonic-gate 		sum += *(uint16_t *)p;
10007c478bd9Sstevel@tonic-gate 		p = (char *)p + sizeof (uint16_t);
10017c478bd9Sstevel@tonic-gate 		if (sum & 0x80000000)
10027c478bd9Sstevel@tonic-gate 			sum = (sum & 0xFFFF) + (sum >> 16);
10037c478bd9Sstevel@tonic-gate 		len -= 2;
10047c478bd9Sstevel@tonic-gate 	}
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate 	if (len)
10077c478bd9Sstevel@tonic-gate 		sum += (uint16_t)*(unsigned char *)p;
10087c478bd9Sstevel@tonic-gate 
10097c478bd9Sstevel@tonic-gate 	while (sum >> 16)
10107c478bd9Sstevel@tonic-gate 		sum = (sum & 0xFFFF) + (sum >> 16);
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 	return (~sum);
10137c478bd9Sstevel@tonic-gate }
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate static const mdb_bitmask_t tcp_flags[] = {
10167c478bd9Sstevel@tonic-gate 	{ "SYN",	TH_SYN,		TH_SYN	},
10177c478bd9Sstevel@tonic-gate 	{ "ACK",	TH_ACK,		TH_ACK	},
10187c478bd9Sstevel@tonic-gate 	{ "FIN",	TH_FIN,		TH_FIN	},
10197c478bd9Sstevel@tonic-gate 	{ "RST",	TH_RST,		TH_RST	},
10207c478bd9Sstevel@tonic-gate 	{ "PSH",	TH_PUSH,	TH_PUSH	},
10217c478bd9Sstevel@tonic-gate 	{ "ECE",	TH_ECE,		TH_ECE	},
10227c478bd9Sstevel@tonic-gate 	{ "CWR",	TH_CWR,		TH_CWR	},
10237c478bd9Sstevel@tonic-gate 	{ NULL,		0,		0	}
10247c478bd9Sstevel@tonic-gate };
10257c478bd9Sstevel@tonic-gate 
10260870f17bSKacheong Poon /* TCP option length */
10270870f17bSKacheong Poon #define	TCPOPT_HEADER_LEN	2
10280870f17bSKacheong Poon #define	TCPOPT_MAXSEG_LEN	4
10290870f17bSKacheong Poon #define	TCPOPT_WS_LEN		3
10300870f17bSKacheong Poon #define	TCPOPT_TSTAMP_LEN	10
10310870f17bSKacheong Poon #define	TCPOPT_SACK_OK_LEN	2
10321edba515SAndy Fiddaman #define	TCPOPT_MD5_LEN		18
10330870f17bSKacheong Poon 
10340870f17bSKacheong Poon static void
tcphdr_print_options(uint8_t * opts,uint32_t opts_len)10350870f17bSKacheong Poon tcphdr_print_options(uint8_t *opts, uint32_t opts_len)
10360870f17bSKacheong Poon {
10370870f17bSKacheong Poon 	uint8_t *endp;
10380870f17bSKacheong Poon 	uint32_t len, val;
10390870f17bSKacheong Poon 
10400870f17bSKacheong Poon 	mdb_printf("%<b>Options:%</b>");
10410870f17bSKacheong Poon 	endp = opts + opts_len;
10420870f17bSKacheong Poon 	while (opts < endp) {
10430870f17bSKacheong Poon 		len = endp - opts;
10440870f17bSKacheong Poon 		switch (*opts) {
10450870f17bSKacheong Poon 		case TCPOPT_EOL:
10460870f17bSKacheong Poon 			mdb_printf(" EOL");
10470870f17bSKacheong Poon 			opts++;
10480870f17bSKacheong Poon 			break;
10490870f17bSKacheong Poon 
10500870f17bSKacheong Poon 		case TCPOPT_NOP:
10510870f17bSKacheong Poon 			mdb_printf(" NOP");
10520870f17bSKacheong Poon 			opts++;
10530870f17bSKacheong Poon 			break;
10540870f17bSKacheong Poon 
10550870f17bSKacheong Poon 		case TCPOPT_MAXSEG: {
10560870f17bSKacheong Poon 			uint16_t mss;
10570870f17bSKacheong Poon 
10580870f17bSKacheong Poon 			if (len < TCPOPT_MAXSEG_LEN ||
10590870f17bSKacheong Poon 			    opts[1] != TCPOPT_MAXSEG_LEN) {
10600870f17bSKacheong Poon 				mdb_printf(" <Truncated MSS>\n");
10610870f17bSKacheong Poon 				return;
10620870f17bSKacheong Poon 			}
10630870f17bSKacheong Poon 			mdb_nhconvert(&mss, opts + TCPOPT_HEADER_LEN,
10640870f17bSKacheong Poon 			    sizeof (mss));
10650870f17bSKacheong Poon 			mdb_printf(" MSS=%u", mss);
10660870f17bSKacheong Poon 			opts += TCPOPT_MAXSEG_LEN;
10670870f17bSKacheong Poon 			break;
10680870f17bSKacheong Poon 		}
10690870f17bSKacheong Poon 
10700870f17bSKacheong Poon 		case TCPOPT_WSCALE:
10710870f17bSKacheong Poon 			if (len < TCPOPT_WS_LEN || opts[1] != TCPOPT_WS_LEN) {
10720870f17bSKacheong Poon 				mdb_printf(" <Truncated WS>\n");
10730870f17bSKacheong Poon 				return;
10740870f17bSKacheong Poon 			}
10750870f17bSKacheong Poon 			mdb_printf(" WS=%u", opts[2]);
10760870f17bSKacheong Poon 			opts += TCPOPT_WS_LEN;
10770870f17bSKacheong Poon 			break;
10780870f17bSKacheong Poon 
10790870f17bSKacheong Poon 		case TCPOPT_TSTAMP: {
10800870f17bSKacheong Poon 			if (len < TCPOPT_TSTAMP_LEN ||
10810870f17bSKacheong Poon 			    opts[1] != TCPOPT_TSTAMP_LEN) {
10820870f17bSKacheong Poon 				mdb_printf(" <Truncated TS>\n");
10830870f17bSKacheong Poon 				return;
10840870f17bSKacheong Poon 			}
10850870f17bSKacheong Poon 
10860870f17bSKacheong Poon 			opts += TCPOPT_HEADER_LEN;
10870870f17bSKacheong Poon 			mdb_nhconvert(&val, opts, sizeof (val));
10880870f17bSKacheong Poon 			mdb_printf(" TS_VAL=%u,", val);
10890870f17bSKacheong Poon 
10900870f17bSKacheong Poon 			opts += sizeof (val);
10910870f17bSKacheong Poon 			mdb_nhconvert(&val, opts, sizeof (val));
10920870f17bSKacheong Poon 			mdb_printf("TS_ECHO=%u", val);
10930870f17bSKacheong Poon 
10940870f17bSKacheong Poon 			opts += sizeof (val);
10950870f17bSKacheong Poon 			break;
10960870f17bSKacheong Poon 		}
10970870f17bSKacheong Poon 
10980870f17bSKacheong Poon 		case TCPOPT_SACK_PERMITTED:
10990870f17bSKacheong Poon 			if (len < TCPOPT_SACK_OK_LEN ||
11000870f17bSKacheong Poon 			    opts[1] != TCPOPT_SACK_OK_LEN) {
11010870f17bSKacheong Poon 				mdb_printf(" <Truncated SACK_OK>\n");
11020870f17bSKacheong Poon 				return;
11030870f17bSKacheong Poon 			}
11040870f17bSKacheong Poon 			mdb_printf(" SACK_OK");
11050870f17bSKacheong Poon 			opts += TCPOPT_SACK_OK_LEN;
11060870f17bSKacheong Poon 			break;
11070870f17bSKacheong Poon 
11080870f17bSKacheong Poon 		case TCPOPT_SACK: {
11090870f17bSKacheong Poon 			uint32_t sack_len;
11100870f17bSKacheong Poon 
11110870f17bSKacheong Poon 			if (len <= TCPOPT_HEADER_LEN || len < opts[1] ||
11120870f17bSKacheong Poon 			    opts[1] <= TCPOPT_HEADER_LEN) {
11130870f17bSKacheong Poon 				mdb_printf(" <Truncated SACK>\n");
11140870f17bSKacheong Poon 				return;
11150870f17bSKacheong Poon 			}
11160870f17bSKacheong Poon 			sack_len = opts[1] - TCPOPT_HEADER_LEN;
11170870f17bSKacheong Poon 			opts += TCPOPT_HEADER_LEN;
11180870f17bSKacheong Poon 
11190870f17bSKacheong Poon 			mdb_printf(" SACK=");
11200870f17bSKacheong Poon 			while (sack_len > 0) {
11210870f17bSKacheong Poon 				if (opts + 2 * sizeof (val) > endp) {
11220870f17bSKacheong Poon 					mdb_printf("<Truncated SACK>\n");
11230870f17bSKacheong Poon 					opts = endp;
11240870f17bSKacheong Poon 					break;
11250870f17bSKacheong Poon 				}
11260870f17bSKacheong Poon 
11270870f17bSKacheong Poon 				mdb_nhconvert(&val, opts, sizeof (val));
11280870f17bSKacheong Poon 				mdb_printf("<%u,", val);
11290870f17bSKacheong Poon 				opts += sizeof (val);
11300870f17bSKacheong Poon 				mdb_nhconvert(&val, opts, sizeof (val));
11310870f17bSKacheong Poon 				mdb_printf("%u>", val);
11320870f17bSKacheong Poon 				opts += sizeof (val);
11330870f17bSKacheong Poon 
11340870f17bSKacheong Poon 				sack_len -= 2 * sizeof (val);
11350870f17bSKacheong Poon 			}
11360870f17bSKacheong Poon 			break;
11370870f17bSKacheong Poon 		}
11380870f17bSKacheong Poon 
11391edba515SAndy Fiddaman 		case TCPOPT_MD5: {
11401edba515SAndy Fiddaman 			uint_t i;
11411edba515SAndy Fiddaman 
11421edba515SAndy Fiddaman 			if (len < TCPOPT_MD5_LEN || len < opts[1] ||
11431edba515SAndy Fiddaman 			    opts[1] < TCPOPT_MD5_LEN) {
11441edba515SAndy Fiddaman 				mdb_printf("<Truncated MD5>\n");
11451edba515SAndy Fiddaman 				return;
11461edba515SAndy Fiddaman 			}
11471edba515SAndy Fiddaman 			if (opts[1] > TCPOPT_MD5_LEN) {
11481edba515SAndy Fiddaman 				mdb_printf("<Oversize MD5>\n");
11491edba515SAndy Fiddaman 				return;
11501edba515SAndy Fiddaman 			}
11511edba515SAndy Fiddaman 
11521edba515SAndy Fiddaman 			mdb_printf(" MD5=0x");
11531edba515SAndy Fiddaman 			for (i = 2; i < TCPOPT_MD5_LEN - 2; i++)
11541edba515SAndy Fiddaman 				mdb_printf("%02x", opts[i]);
11551edba515SAndy Fiddaman 
11561edba515SAndy Fiddaman 			opts += TCPOPT_MD5_LEN;
11571edba515SAndy Fiddaman 			break;
11581edba515SAndy Fiddaman 		}
11591edba515SAndy Fiddaman 
11600870f17bSKacheong Poon 		default:
11610870f17bSKacheong Poon 			mdb_printf(" Opts=<val=%u,len=%u>", *opts,
11620870f17bSKacheong Poon 			    opts[1]);
11630870f17bSKacheong Poon 			opts += opts[1];
11640870f17bSKacheong Poon 			break;
11650870f17bSKacheong Poon 		}
11660870f17bSKacheong Poon 	}
11670870f17bSKacheong Poon 	mdb_printf("\n");
11680870f17bSKacheong Poon }
11690870f17bSKacheong Poon 
11707c478bd9Sstevel@tonic-gate static void
tcphdr_print(struct tcphdr * tcph)11717c478bd9Sstevel@tonic-gate tcphdr_print(struct tcphdr *tcph)
11727c478bd9Sstevel@tonic-gate {
11737c478bd9Sstevel@tonic-gate 	in_port_t	sport, dport;
11747c478bd9Sstevel@tonic-gate 	tcp_seq		seq, ack;
11757c478bd9Sstevel@tonic-gate 	uint16_t	win, urp;
11767c478bd9Sstevel@tonic-gate 
11777c478bd9Sstevel@tonic-gate 	mdb_printf("%<b>TCP header%</b>\n");
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&sport, &tcph->th_sport, sizeof (sport));
11807c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&dport, &tcph->th_dport, sizeof (dport));
11817c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&seq, &tcph->th_seq, sizeof (seq));
11827c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&ack, &tcph->th_ack, sizeof (ack));
11837c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&win, &tcph->th_win, sizeof (win));
11847c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&urp, &tcph->th_urp, sizeof (urp));
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	mdb_printf("%<u>%6s %6s %10s %10s %4s %5s %5s %5s %-15s%</u>\n",
11877c478bd9Sstevel@tonic-gate 	    "SPORT", "DPORT", "SEQ", "ACK", "HLEN", "WIN", "CSUM", "URP",
11887c478bd9Sstevel@tonic-gate 	    "FLAGS");
11897c478bd9Sstevel@tonic-gate 	mdb_printf("%6hu %6hu %10u %10u %4d %5hu %5hu %5hu <%b>\n",
11907c478bd9Sstevel@tonic-gate 	    sport, dport, seq, ack, tcph->th_off << 2, win,
11917c478bd9Sstevel@tonic-gate 	    tcph->th_sum, urp, tcph->th_flags, tcp_flags);
11927c478bd9Sstevel@tonic-gate 	mdb_printf("0x%04x 0x%04x 0x%08x 0x%08x\n\n",
11937c478bd9Sstevel@tonic-gate 	    sport, dport, seq, ack);
11947c478bd9Sstevel@tonic-gate }
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate /* ARGSUSED */
11977c478bd9Sstevel@tonic-gate static int
tcphdr(uintptr_t addr,uint_t flags,int ac,const mdb_arg_t * av)11987c478bd9Sstevel@tonic-gate tcphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
11997c478bd9Sstevel@tonic-gate {
12007c478bd9Sstevel@tonic-gate 	struct tcphdr	tcph;
12010870f17bSKacheong Poon 	uint32_t	opt_len;
12027c478bd9Sstevel@tonic-gate 
12037c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
12047c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) {
12077c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read TCP header at %p", addr);
12087c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
12097c478bd9Sstevel@tonic-gate 	}
12107c478bd9Sstevel@tonic-gate 	tcphdr_print(&tcph);
12110870f17bSKacheong Poon 
12120870f17bSKacheong Poon 	/* If there are options, print them out also. */
12130870f17bSKacheong Poon 	opt_len = (tcph.th_off << 2) - TCP_MIN_HEADER_LENGTH;
12140870f17bSKacheong Poon 	if (opt_len > 0) {
12150870f17bSKacheong Poon 		uint8_t *opts, *opt_buf;
12160870f17bSKacheong Poon 
12170870f17bSKacheong Poon 		opt_buf = mdb_alloc(opt_len, UM_SLEEP);
12180870f17bSKacheong Poon 		opts = (uint8_t *)addr + sizeof (tcph);
12190870f17bSKacheong Poon 		if (mdb_vread(opt_buf, opt_len, (uintptr_t)opts) == -1) {
12200870f17bSKacheong Poon 			mdb_warn("failed to read TCP options at %p", opts);
12210870f17bSKacheong Poon 			return (DCMD_ERR);
12220870f17bSKacheong Poon 		}
12230870f17bSKacheong Poon 		tcphdr_print_options(opt_buf, opt_len);
12240870f17bSKacheong Poon 		mdb_free(opt_buf, opt_len);
12250870f17bSKacheong Poon 	}
12260870f17bSKacheong Poon 
12277c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
12287c478bd9Sstevel@tonic-gate }
12297c478bd9Sstevel@tonic-gate 
12307c478bd9Sstevel@tonic-gate static void
udphdr_print(struct udphdr * udph)12317c478bd9Sstevel@tonic-gate udphdr_print(struct udphdr *udph)
12327c478bd9Sstevel@tonic-gate {
12337c478bd9Sstevel@tonic-gate 	in_port_t	sport, dport;
12347c478bd9Sstevel@tonic-gate 	uint16_t	hlen;
12357c478bd9Sstevel@tonic-gate 
12367c478bd9Sstevel@tonic-gate 	mdb_printf("%<b>UDP header%</b>\n");
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&sport, &udph->uh_sport, sizeof (sport));
12397c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&dport, &udph->uh_dport, sizeof (dport));
12407c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&hlen, &udph->uh_ulen, sizeof (hlen));
12417c478bd9Sstevel@tonic-gate 
12427c478bd9Sstevel@tonic-gate 	mdb_printf("%<u>%14s %14s %5s %6s%</u>\n",
12437c478bd9Sstevel@tonic-gate 	    "SPORT", "DPORT", "LEN", "CSUM");
12447c478bd9Sstevel@tonic-gate 	mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %5hu 0x%04hx\n\n", sport, sport,
12457c478bd9Sstevel@tonic-gate 	    dport, dport, hlen, udph->uh_sum);
12467c478bd9Sstevel@tonic-gate }
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate /* ARGSUSED */
12497c478bd9Sstevel@tonic-gate static int
udphdr(uintptr_t addr,uint_t flags,int ac,const mdb_arg_t * av)12507c478bd9Sstevel@tonic-gate udphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
12517c478bd9Sstevel@tonic-gate {
12527c478bd9Sstevel@tonic-gate 	struct udphdr	udph;
12537c478bd9Sstevel@tonic-gate 
12547c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
12557c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
12567c478bd9Sstevel@tonic-gate 
12577c478bd9Sstevel@tonic-gate 	if (mdb_vread(&udph, sizeof (udph), addr) == -1) {
12587c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read UDP header at %p", addr);
12597c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
12607c478bd9Sstevel@tonic-gate 	}
12617c478bd9Sstevel@tonic-gate 	udphdr_print(&udph);
12627c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
12637c478bd9Sstevel@tonic-gate }
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate static void
sctphdr_print(sctp_hdr_t * sctph)12667c478bd9Sstevel@tonic-gate sctphdr_print(sctp_hdr_t *sctph)
12677c478bd9Sstevel@tonic-gate {
12687c478bd9Sstevel@tonic-gate 	in_port_t sport, dport;
12697c478bd9Sstevel@tonic-gate 
12707c478bd9Sstevel@tonic-gate 	mdb_printf("%<b>SCTP header%</b>\n");
12717c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&sport, &sctph->sh_sport, sizeof (sport));
12727c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&dport, &sctph->sh_dport, sizeof (dport));
12737c478bd9Sstevel@tonic-gate 
12747c478bd9Sstevel@tonic-gate 	mdb_printf("%<u>%14s %14s %10s %10s%</u>\n",
12757c478bd9Sstevel@tonic-gate 	    "SPORT", "DPORT", "VTAG", "CHKSUM");
12767c478bd9Sstevel@tonic-gate 	mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %10u 0x%08x\n\n", sport, sport,
12777c478bd9Sstevel@tonic-gate 	    dport, dport, sctph->sh_verf, sctph->sh_chksum);
12787c478bd9Sstevel@tonic-gate }
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate /* ARGSUSED */
12817c478bd9Sstevel@tonic-gate static int
sctphdr(uintptr_t addr,uint_t flags,int ac,const mdb_arg_t * av)12827c478bd9Sstevel@tonic-gate sctphdr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
12837c478bd9Sstevel@tonic-gate {
12847c478bd9Sstevel@tonic-gate 	sctp_hdr_t sctph;
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
12877c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) {
12907c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read SCTP header at %p", addr);
12917c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
12927c478bd9Sstevel@tonic-gate 	}
12937c478bd9Sstevel@tonic-gate 
12947c478bd9Sstevel@tonic-gate 	sctphdr_print(&sctph);
12957c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
12967c478bd9Sstevel@tonic-gate }
12977c478bd9Sstevel@tonic-gate 
12987c478bd9Sstevel@tonic-gate static int
transport_hdr(int proto,uintptr_t addr)12997c478bd9Sstevel@tonic-gate transport_hdr(int proto, uintptr_t addr)
13007c478bd9Sstevel@tonic-gate {
13017c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
13027c478bd9Sstevel@tonic-gate 	switch (proto) {
13037c478bd9Sstevel@tonic-gate 	case IPPROTO_TCP: {
13047c478bd9Sstevel@tonic-gate 		struct tcphdr tcph;
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 		if (mdb_vread(&tcph, sizeof (tcph), addr) == -1) {
13077c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read TCP header at %p", addr);
13087c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
13097c478bd9Sstevel@tonic-gate 		}
13107c478bd9Sstevel@tonic-gate 		tcphdr_print(&tcph);
13117c478bd9Sstevel@tonic-gate 		break;
13127c478bd9Sstevel@tonic-gate 	}
13137c478bd9Sstevel@tonic-gate 	case IPPROTO_UDP:  {
13147c478bd9Sstevel@tonic-gate 		struct udphdr udph;
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 		if (mdb_vread(&udph, sizeof (udph), addr) == -1) {
13177c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read UDP header at %p", addr);
13187c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
13197c478bd9Sstevel@tonic-gate 		}
13207c478bd9Sstevel@tonic-gate 		udphdr_print(&udph);
13217c478bd9Sstevel@tonic-gate 		break;
13227c478bd9Sstevel@tonic-gate 	}
13237c478bd9Sstevel@tonic-gate 	case IPPROTO_SCTP: {
13247c478bd9Sstevel@tonic-gate 		sctp_hdr_t sctph;
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 		if (mdb_vread(&sctph, sizeof (sctph), addr) == -1) {
13277c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read SCTP header at %p", addr);
13287c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
13297c478bd9Sstevel@tonic-gate 		}
13307c478bd9Sstevel@tonic-gate 		sctphdr_print(&sctph);
13317c478bd9Sstevel@tonic-gate 		break;
13327c478bd9Sstevel@tonic-gate 	}
13337c478bd9Sstevel@tonic-gate 	default:
13347c478bd9Sstevel@tonic-gate 		break;
13357c478bd9Sstevel@tonic-gate 	}
13367c478bd9Sstevel@tonic-gate 
13377c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
13387c478bd9Sstevel@tonic-gate }
13397c478bd9Sstevel@tonic-gate 
13407c478bd9Sstevel@tonic-gate static const mdb_bitmask_t ip_flags[] = {
13417c478bd9Sstevel@tonic-gate 	{ "DF",	IPH_DF, IPH_DF	},
13427c478bd9Sstevel@tonic-gate 	{ "MF", IPH_MF,	IPH_MF	},
13437c478bd9Sstevel@tonic-gate 	{ NULL, 0,	0	}
13447c478bd9Sstevel@tonic-gate };
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate /* ARGSUSED */
13477c478bd9Sstevel@tonic-gate static int
iphdr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13487c478bd9Sstevel@tonic-gate iphdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13497c478bd9Sstevel@tonic-gate {
13507c478bd9Sstevel@tonic-gate 	uint_t		verbose = FALSE, force = FALSE;
13517c478bd9Sstevel@tonic-gate 	ipha_t		iph[1];
13527c478bd9Sstevel@tonic-gate 	uint16_t	ver, totlen, hdrlen, ipid, off, csum;
13537c478bd9Sstevel@tonic-gate 	uintptr_t	nxt_proto;
13547c478bd9Sstevel@tonic-gate 	char		exp_csum[8];
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
13577c478bd9Sstevel@tonic-gate 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
13587c478bd9Sstevel@tonic-gate 	    'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc)
13597c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
13607c478bd9Sstevel@tonic-gate 
13617c478bd9Sstevel@tonic-gate 	if (mdb_vread(iph, sizeof (*iph), addr) == -1) {
13627c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read IPv4 header at %p", addr);
13637c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13647c478bd9Sstevel@tonic-gate 	}
13657c478bd9Sstevel@tonic-gate 
13667c478bd9Sstevel@tonic-gate 	ver = (iph->ipha_version_and_hdr_length & 0xf0) >> 4;
13677c478bd9Sstevel@tonic-gate 	if (ver != IPV4_VERSION) {
13687c478bd9Sstevel@tonic-gate 		if (ver == IPV6_VERSION) {
13697c478bd9Sstevel@tonic-gate 			return (ip6hdr(addr, flags, argc, argv));
13707c478bd9Sstevel@tonic-gate 		} else if (!force) {
13717c478bd9Sstevel@tonic-gate 			mdb_warn("unknown IP version: %d\n", ver);
13727c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
13737c478bd9Sstevel@tonic-gate 		}
13747c478bd9Sstevel@tonic-gate 	}
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate 	mdb_printf("%<b>IPv4 header%</b>\n");
13777c478bd9Sstevel@tonic-gate 	mdb_printf("%-34s %-34s\n"
13787c478bd9Sstevel@tonic-gate 	    "%<u>%-4s %-4s %-5s %-5s %-6s %-5s %-5s %-6s %-8s %-6s%</u>\n",
13797c478bd9Sstevel@tonic-gate 	    "SRC", "DST",
13807c478bd9Sstevel@tonic-gate 	    "HLEN", "TOS", "LEN", "ID", "OFFSET", "TTL", "PROTO", "CHKSUM",
13817c478bd9Sstevel@tonic-gate 	    "EXP-CSUM", "FLGS");
13827c478bd9Sstevel@tonic-gate 
13837c478bd9Sstevel@tonic-gate 	hdrlen = (iph->ipha_version_and_hdr_length & 0x0f) << 2;
13847c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&totlen, &iph->ipha_length, sizeof (totlen));
13857c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&ipid, &iph->ipha_ident, sizeof (ipid));
13867c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&off, &iph->ipha_fragment_offset_and_flags, sizeof (off));
13877c478bd9Sstevel@tonic-gate 	if (hdrlen == IP_SIMPLE_HDR_LENGTH) {
13887c478bd9Sstevel@tonic-gate 		if ((csum = ipcksum(iph, sizeof (*iph))) != 0)
13897c478bd9Sstevel@tonic-gate 			csum = ~(~csum + ~iph->ipha_hdr_checksum);
13907c478bd9Sstevel@tonic-gate 		else
13917c478bd9Sstevel@tonic-gate 			csum = iph->ipha_hdr_checksum;
13927c478bd9Sstevel@tonic-gate 		mdb_snprintf(exp_csum, 8, "%u", csum);
13937c478bd9Sstevel@tonic-gate 	} else {
13947c478bd9Sstevel@tonic-gate 		mdb_snprintf(exp_csum, 8, "<n/a>");
13957c478bd9Sstevel@tonic-gate 	}
13967c478bd9Sstevel@tonic-gate 
13977c478bd9Sstevel@tonic-gate 	mdb_printf("%-34I %-34I%\n"
13987c478bd9Sstevel@tonic-gate 	    "%-4d %-4d %-5hu %-5hu %-6hu %-5hu %-5hu %-6u %-8s <%5hb>\n",
13997c478bd9Sstevel@tonic-gate 	    iph->ipha_src, iph->ipha_dst,
14007c478bd9Sstevel@tonic-gate 	    hdrlen, iph->ipha_type_of_service, totlen, ipid,
14017c478bd9Sstevel@tonic-gate 	    (off << 3) & 0xffff, iph->ipha_ttl, iph->ipha_protocol,
14027c478bd9Sstevel@tonic-gate 	    iph->ipha_hdr_checksum, exp_csum, off, ip_flags);
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 	if (verbose) {
14057c478bd9Sstevel@tonic-gate 		nxt_proto = addr + hdrlen;
14067c478bd9Sstevel@tonic-gate 		return (transport_hdr(iph->ipha_protocol, nxt_proto));
14077c478bd9Sstevel@tonic-gate 	} else {
14087c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
14097c478bd9Sstevel@tonic-gate 	}
14107c478bd9Sstevel@tonic-gate }
14117c478bd9Sstevel@tonic-gate 
14127c478bd9Sstevel@tonic-gate /* ARGSUSED */
14137c478bd9Sstevel@tonic-gate static int
ip6hdr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)14147c478bd9Sstevel@tonic-gate ip6hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14157c478bd9Sstevel@tonic-gate {
14167c478bd9Sstevel@tonic-gate 	uint_t		verbose = FALSE, force = FALSE;
14177c478bd9Sstevel@tonic-gate 	ip6_t		iph[1];
14187c478bd9Sstevel@tonic-gate 	int		ver, class, flow;
14197c478bd9Sstevel@tonic-gate 	uint16_t	plen;
14207c478bd9Sstevel@tonic-gate 	uintptr_t	nxt_proto;
14217c478bd9Sstevel@tonic-gate 
14227c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
14237c478bd9Sstevel@tonic-gate 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
14247c478bd9Sstevel@tonic-gate 	    'f', MDB_OPT_SETBITS, TRUE, &force, NULL) != argc)
14257c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 	if (mdb_vread(iph, sizeof (*iph), addr) == -1) {
14287c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read IPv6 header at %p", addr);
14297c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
14307c478bd9Sstevel@tonic-gate 	}
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate 	ver = (iph->ip6_vfc & 0xf0) >> 4;
14337c478bd9Sstevel@tonic-gate 	if (ver != IPV6_VERSION) {
14347c478bd9Sstevel@tonic-gate 		if (ver == IPV4_VERSION) {
14357c478bd9Sstevel@tonic-gate 			return (iphdr(addr, flags, argc, argv));
14367c478bd9Sstevel@tonic-gate 		} else if (!force) {
14377c478bd9Sstevel@tonic-gate 			mdb_warn("unknown IP version: %d\n", ver);
14387c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
14397c478bd9Sstevel@tonic-gate 		}
14407c478bd9Sstevel@tonic-gate 	}
14417c478bd9Sstevel@tonic-gate 
14427c478bd9Sstevel@tonic-gate 	mdb_printf("%<b>IPv6 header%</b>\n");
14437c478bd9Sstevel@tonic-gate 	mdb_printf("%<u>%-26s %-26s %4s %7s %5s %3s %3s%</u>\n",
14447c478bd9Sstevel@tonic-gate 	    "SRC", "DST", "TCLS", "FLOW-ID", "PLEN", "NXT", "HOP");
14457c478bd9Sstevel@tonic-gate 
1446*c7685b3bSBill Sommerfeld 	class = iph->ip6_vcf & IPV6_FLOWINFO_TCLASS;
14477c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&class, &class, sizeof (class));
1448*c7685b3bSBill Sommerfeld 	class >>= 20;
14497c478bd9Sstevel@tonic-gate 	flow = iph->ip6_vcf & IPV6_FLOWINFO_FLOWLABEL;
14507c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&flow, &flow, sizeof (flow));
14517c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&plen, &iph->ip6_plen, sizeof (plen));
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate 	mdb_printf("%-26N %-26N %4d %7d %5hu %3d %3d\n",
14547c478bd9Sstevel@tonic-gate 	    &iph->ip6_src, &iph->ip6_dst,
14557c478bd9Sstevel@tonic-gate 	    class, flow, plen, iph->ip6_nxt, iph->ip6_hlim);
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate 	if (verbose) {
14587c478bd9Sstevel@tonic-gate 		nxt_proto = addr + sizeof (ip6_t);
14597c478bd9Sstevel@tonic-gate 		return (transport_hdr(iph->ip6_nxt, nxt_proto));
14607c478bd9Sstevel@tonic-gate 	} else {
14617c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
14627c478bd9Sstevel@tonic-gate 	}
14637c478bd9Sstevel@tonic-gate }
14647c478bd9Sstevel@tonic-gate 
14657c478bd9Sstevel@tonic-gate int
nce(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1466bd670b35SErik Nordmark nce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1467bd670b35SErik Nordmark {
1468bd670b35SErik Nordmark 	nce_t nce;
1469bd670b35SErik Nordmark 	nce_cbdata_t nce_cb;
1470bd670b35SErik Nordmark 	int ipversion = 0;
147169fc1db8SCody Peter Mello 	const char *opt_P = NULL, *opt_ill = NULL;
1472bd670b35SErik Nordmark 
1473bd670b35SErik Nordmark 	if (mdb_getopts(argc, argv,
1474bd670b35SErik Nordmark 	    'i', MDB_OPT_STR, &opt_ill,
1475bd670b35SErik Nordmark 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
1476bd670b35SErik Nordmark 		return (DCMD_USAGE);
1477bd670b35SErik Nordmark 
1478bd670b35SErik Nordmark 	if (opt_P != NULL) {
1479bd670b35SErik Nordmark 		if (strcmp("v4", opt_P) == 0) {
1480bd670b35SErik Nordmark 			ipversion = IPV4_VERSION;
1481bd670b35SErik Nordmark 		} else if (strcmp("v6", opt_P) == 0) {
1482bd670b35SErik Nordmark 			ipversion = IPV6_VERSION;
1483bd670b35SErik Nordmark 		} else {
1484bd670b35SErik Nordmark 			mdb_warn("invalid protocol '%s'\n", opt_P);
1485bd670b35SErik Nordmark 			return (DCMD_USAGE);
1486bd670b35SErik Nordmark 		}
1487bd670b35SErik Nordmark 	}
1488bd670b35SErik Nordmark 
1489bd670b35SErik Nordmark 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
1490bd670b35SErik Nordmark 		mdb_printf("%<u>%?s %5s %18s %?s %s %s %</u>\n",
1491bd670b35SErik Nordmark 		    "ADDR", "INTF", "LLADDR", "FP_MP", "REFCNT",
1492bd670b35SErik Nordmark 		    "NCE_ADDR");
1493bd670b35SErik Nordmark 	}
1494bd670b35SErik Nordmark 
1495bd670b35SErik Nordmark 	bzero(&nce_cb, sizeof (nce_cb));
1496bd670b35SErik Nordmark 	if (opt_ill != NULL) {
1497bd670b35SErik Nordmark 		strcpy(nce_cb.nce_ill_name, opt_ill);
1498bd670b35SErik Nordmark 	}
1499bd670b35SErik Nordmark 	nce_cb.nce_ipversion = ipversion;
1500bd670b35SErik Nordmark 
1501bd670b35SErik Nordmark 	if (flags & DCMD_ADDRSPEC) {
1502bd670b35SErik Nordmark 		(void) mdb_vread(&nce, sizeof (nce_t), addr);
1503bd670b35SErik Nordmark 		(void) nce_format(addr, &nce, &nce_cb);
1504bd670b35SErik Nordmark 	} else if (mdb_walk("nce", (mdb_walk_cb_t)nce_format, &nce_cb) == -1) {
1505bd670b35SErik Nordmark 		mdb_warn("failed to walk ire table");
1506bd670b35SErik Nordmark 		return (DCMD_ERR);
1507bd670b35SErik Nordmark 	}
1508bd670b35SErik Nordmark 
1509bd670b35SErik Nordmark 	return (DCMD_OK);
1510bd670b35SErik Nordmark }
1511bd670b35SErik Nordmark 
1512bd670b35SErik Nordmark /* ARGSUSED */
1513bd670b35SErik Nordmark static int
dce_format(uintptr_t addr,const dce_t * dcep,void * dce_cb_arg)1514bd670b35SErik Nordmark dce_format(uintptr_t addr, const dce_t *dcep, void *dce_cb_arg)
1515bd670b35SErik Nordmark {
1516bd670b35SErik Nordmark 	static const mdb_bitmask_t dmasks[] = {
1517bd670b35SErik Nordmark 		{ "D",	DCEF_DEFAULT,		DCEF_DEFAULT },
1518bd670b35SErik Nordmark 		{ "P",	DCEF_PMTU,		DCEF_PMTU },
1519bd670b35SErik Nordmark 		{ "U",	DCEF_UINFO,		DCEF_UINFO },
1520bd670b35SErik Nordmark 		{ "S",	DCEF_TOO_SMALL_PMTU,	DCEF_TOO_SMALL_PMTU },
1521bd670b35SErik Nordmark 		{ NULL,	0,			0		}
1522bd670b35SErik Nordmark 	};
1523bd670b35SErik Nordmark 	char flagsbuf[2 * A_CNT(dmasks)];
1524bd670b35SErik Nordmark 	int ipversion = *(int *)dce_cb_arg;
1525bd670b35SErik Nordmark 	boolean_t condemned = dcep->dce_generation == DCE_GENERATION_CONDEMNED;
1526bd670b35SErik Nordmark 
1527bd670b35SErik Nordmark 	if (ipversion != 0 && ipversion != dcep->dce_ipversion)
1528bd670b35SErik Nordmark 		return (WALK_NEXT);
1529bd670b35SErik Nordmark 
1530bd670b35SErik Nordmark 	mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%b", dcep->dce_flags,
1531bd670b35SErik Nordmark 	    dmasks);
1532bd670b35SErik Nordmark 
1533bd670b35SErik Nordmark 	switch (dcep->dce_ipversion) {
1534bd670b35SErik Nordmark 	case IPV4_VERSION:
1535bd670b35SErik Nordmark 		mdb_printf("%<u>%?p%3s %8s %8d %30I %</u>\n", addr, condemned ?
1536bd670b35SErik Nordmark 		    "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v4addr);
1537bd670b35SErik Nordmark 		break;
1538bd670b35SErik Nordmark 	case IPV6_VERSION:
1539bd670b35SErik Nordmark 		mdb_printf("%<u>%?p%3s %8s %8d %30N %</u>\n", addr, condemned ?
1540bd670b35SErik Nordmark 		    "(C)" : "", flagsbuf, dcep->dce_pmtu, &dcep->dce_v6addr);
1541bd670b35SErik Nordmark 		break;
1542bd670b35SErik Nordmark 	default:
1543bd670b35SErik Nordmark 		mdb_printf("%<u>%?p%3s %8s %8d %30s %</u>\n", addr, condemned ?
1544bd670b35SErik Nordmark 		    "(C)" : "", flagsbuf, dcep->dce_pmtu, "");
1545bd670b35SErik Nordmark 	}
1546bd670b35SErik Nordmark 
1547bd670b35SErik Nordmark 	return (WALK_NEXT);
1548bd670b35SErik Nordmark }
1549bd670b35SErik Nordmark 
1550bd670b35SErik Nordmark int
dce(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1551bd670b35SErik Nordmark dce(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1552bd670b35SErik Nordmark {
1553bd670b35SErik Nordmark 	dce_t dce;
1554bd670b35SErik Nordmark 	const char *opt_P = NULL;
1555bd670b35SErik Nordmark 	const char *zone_name = NULL;
1556bd670b35SErik Nordmark 	ip_stack_t *ipst = NULL;
1557bd670b35SErik Nordmark 	int ipversion = 0;
1558bd670b35SErik Nordmark 
1559bd670b35SErik Nordmark 	if (mdb_getopts(argc, argv,
1560bd670b35SErik Nordmark 	    's', MDB_OPT_STR, &zone_name,
1561bd670b35SErik Nordmark 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
1562bd670b35SErik Nordmark 		return (DCMD_USAGE);
1563bd670b35SErik Nordmark 
1564bd670b35SErik Nordmark 	/* Follow the specified zone name to find a ip_stack_t*. */
1565bd670b35SErik Nordmark 	if (zone_name != NULL) {
1566bd670b35SErik Nordmark 		ipst = zone_to_ips(zone_name);
1567bd670b35SErik Nordmark 		if (ipst == NULL)
1568bd670b35SErik Nordmark 			return (DCMD_USAGE);
1569bd670b35SErik Nordmark 	}
1570bd670b35SErik Nordmark 
1571bd670b35SErik Nordmark 	if (opt_P != NULL) {
1572bd670b35SErik Nordmark 		if (strcmp("v4", opt_P) == 0) {
1573bd670b35SErik Nordmark 			ipversion = IPV4_VERSION;
1574bd670b35SErik Nordmark 		} else if (strcmp("v6", opt_P) == 0) {
1575bd670b35SErik Nordmark 			ipversion = IPV6_VERSION;
1576bd670b35SErik Nordmark 		} else {
1577bd670b35SErik Nordmark 			mdb_warn("invalid protocol '%s'\n", opt_P);
1578bd670b35SErik Nordmark 			return (DCMD_USAGE);
1579bd670b35SErik Nordmark 		}
1580bd670b35SErik Nordmark 	}
1581bd670b35SErik Nordmark 
1582bd670b35SErik Nordmark 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
1583bd670b35SErik Nordmark 		mdb_printf("%<u>%?s%3s %8s %8s %30s %</u>\n",
1584bd670b35SErik Nordmark 		    "ADDR", "", "FLAGS", "PMTU", "DST_ADDR");
1585bd670b35SErik Nordmark 	}
1586bd670b35SErik Nordmark 
1587bd670b35SErik Nordmark 	if (flags & DCMD_ADDRSPEC) {
1588bd670b35SErik Nordmark 		(void) mdb_vread(&dce, sizeof (dce_t), addr);
1589bd670b35SErik Nordmark 		(void) dce_format(addr, &dce, &ipversion);
1590bd670b35SErik Nordmark 	} else if (mdb_pwalk("dce", (mdb_walk_cb_t)dce_format, &ipversion,
1591bd670b35SErik Nordmark 	    (uintptr_t)ipst) == -1) {
1592bd670b35SErik Nordmark 		mdb_warn("failed to walk dce cache");
1593bd670b35SErik Nordmark 		return (DCMD_ERR);
1594bd670b35SErik Nordmark 	}
1595bd670b35SErik Nordmark 
1596bd670b35SErik Nordmark 	return (DCMD_OK);
1597bd670b35SErik Nordmark }
1598bd670b35SErik Nordmark 
1599bd670b35SErik Nordmark int
ire(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)16007c478bd9Sstevel@tonic-gate ire(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
16017c478bd9Sstevel@tonic-gate {
16027c478bd9Sstevel@tonic-gate 	uint_t verbose = FALSE;
16037c478bd9Sstevel@tonic-gate 	ire_t ire;
1604ffaa671aSsowmini 	ire_cbdata_t ire_cb;
1605ffaa671aSsowmini 	int ipversion = 0;
1606ffaa671aSsowmini 	const char *opt_P = NULL;
1607bd670b35SErik Nordmark 	const char *zone_name = NULL;
1608bd670b35SErik Nordmark 	ip_stack_t *ipst = NULL;
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
1611ffaa671aSsowmini 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
1612bd670b35SErik Nordmark 	    's', MDB_OPT_STR, &zone_name,
1613ffaa671aSsowmini 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
16147c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
16157c478bd9Sstevel@tonic-gate 
1616bd670b35SErik Nordmark 	/* Follow the specified zone name to find a ip_stack_t*. */
1617bd670b35SErik Nordmark 	if (zone_name != NULL) {
1618bd670b35SErik Nordmark 		ipst = zone_to_ips(zone_name);
1619bd670b35SErik Nordmark 		if (ipst == NULL)
1620bd670b35SErik Nordmark 			return (DCMD_USAGE);
1621bd670b35SErik Nordmark 	}
1622bd670b35SErik Nordmark 
1623ffaa671aSsowmini 	if (opt_P != NULL) {
1624ffaa671aSsowmini 		if (strcmp("v4", opt_P) == 0) {
1625ffaa671aSsowmini 			ipversion = IPV4_VERSION;
1626ffaa671aSsowmini 		} else if (strcmp("v6", opt_P) == 0) {
1627ffaa671aSsowmini 			ipversion = IPV6_VERSION;
1628ffaa671aSsowmini 		} else {
1629ffaa671aSsowmini 			mdb_warn("invalid protocol '%s'\n", opt_P);
1630ffaa671aSsowmini 			return (DCMD_USAGE);
1631ffaa671aSsowmini 		}
1632ffaa671aSsowmini 	}
1633ffaa671aSsowmini 
16347c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
16357c478bd9Sstevel@tonic-gate 
16367c478bd9Sstevel@tonic-gate 		if (verbose) {
16377c478bd9Sstevel@tonic-gate 			mdb_printf("%?s %40s %-20s%\n"
16387c478bd9Sstevel@tonic-gate 			    "%?s %40s %-20s%\n"
1639bd670b35SErik Nordmark 			    "%<u>%?s %40s %4s %-20s %s%</u>\n",
16407c478bd9Sstevel@tonic-gate 			    "ADDR", "SRC", "TYPE",
16417c478bd9Sstevel@tonic-gate 			    "", "DST", "MARKS",
1642bd670b35SErik Nordmark 			    "", "STACK", "ZONE", "FLAGS", "INTF");
16437c478bd9Sstevel@tonic-gate 		} else {
1644bd670b35SErik Nordmark 			mdb_printf("%<u>%?s %30s %30s %5s %4s %s%</u>\n",
1645bd670b35SErik Nordmark 			    "ADDR", "SRC", "DST", "STACK", "ZONE", "INTF");
16467c478bd9Sstevel@tonic-gate 		}
16477c478bd9Sstevel@tonic-gate 	}
16487c478bd9Sstevel@tonic-gate 
1649ffaa671aSsowmini 	ire_cb.verbose = (verbose == TRUE);
1650ffaa671aSsowmini 	ire_cb.ire_ipversion = ipversion;
1651ffaa671aSsowmini 
16527c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
16537c478bd9Sstevel@tonic-gate 		(void) mdb_vread(&ire, sizeof (ire_t), addr);
1654ffaa671aSsowmini 		(void) ire_format(addr, &ire, &ire_cb);
1655bd670b35SErik Nordmark 	} else if (mdb_pwalk("ire", (mdb_walk_cb_t)ire_format, &ire_cb,
1656bd670b35SErik Nordmark 	    (uintptr_t)ipst) == -1) {
16577c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk ire table");
16587c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
16597c478bd9Sstevel@tonic-gate 	}
16607c478bd9Sstevel@tonic-gate 
16617c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
16627c478bd9Sstevel@tonic-gate }
16637c478bd9Sstevel@tonic-gate 
16647c478bd9Sstevel@tonic-gate static size_t
mi_osize(const queue_t * q)16657c478bd9Sstevel@tonic-gate mi_osize(const queue_t *q)
16667c478bd9Sstevel@tonic-gate {
16677c478bd9Sstevel@tonic-gate 	/*
16687c478bd9Sstevel@tonic-gate 	 * The code in common/inet/mi.c allocates an extra word to store the
16697c478bd9Sstevel@tonic-gate 	 * size of the allocation.  An mi_o_s is thus a size_t plus an mi_o_s.
16707c478bd9Sstevel@tonic-gate 	 */
16717c478bd9Sstevel@tonic-gate 	struct mi_block {
16727c478bd9Sstevel@tonic-gate 		size_t mi_nbytes;
16737c478bd9Sstevel@tonic-gate 		struct mi_o_s mi_o;
16747c478bd9Sstevel@tonic-gate 	} m;
16757c478bd9Sstevel@tonic-gate 
16767c478bd9Sstevel@tonic-gate 	if (mdb_vread(&m, sizeof (m), (uintptr_t)q->q_ptr -
16777c478bd9Sstevel@tonic-gate 	    sizeof (m)) == sizeof (m))
16787c478bd9Sstevel@tonic-gate 		return (m.mi_nbytes - sizeof (m));
16797c478bd9Sstevel@tonic-gate 
16807c478bd9Sstevel@tonic-gate 	return (0);
16817c478bd9Sstevel@tonic-gate }
16827c478bd9Sstevel@tonic-gate 
16837c478bd9Sstevel@tonic-gate static void
ip_ill_qinfo(const queue_t * q,char * buf,size_t nbytes)16847c478bd9Sstevel@tonic-gate ip_ill_qinfo(const queue_t *q, char *buf, size_t nbytes)
16857c478bd9Sstevel@tonic-gate {
16867c478bd9Sstevel@tonic-gate 	char name[32];
16877c478bd9Sstevel@tonic-gate 	ill_t ill;
16887c478bd9Sstevel@tonic-gate 
16897c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ill, sizeof (ill),
16907c478bd9Sstevel@tonic-gate 	    (uintptr_t)q->q_ptr) == sizeof (ill) &&
16917c478bd9Sstevel@tonic-gate 	    mdb_readstr(name, sizeof (name), (uintptr_t)ill.ill_name) > 0)
16927c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(buf, nbytes, "if: %s", name);
16937c478bd9Sstevel@tonic-gate }
16947c478bd9Sstevel@tonic-gate 
16957c478bd9Sstevel@tonic-gate void
ip_qinfo(const queue_t * q,char * buf,size_t nbytes)16967c478bd9Sstevel@tonic-gate ip_qinfo(const queue_t *q, char *buf, size_t nbytes)
16977c478bd9Sstevel@tonic-gate {
16987c478bd9Sstevel@tonic-gate 	size_t size = mi_osize(q);
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate 	if (size == sizeof (ill_t))
17017c478bd9Sstevel@tonic-gate 		ip_ill_qinfo(q, buf, nbytes);
17027c478bd9Sstevel@tonic-gate }
17037c478bd9Sstevel@tonic-gate 
17047c478bd9Sstevel@tonic-gate uintptr_t
ip_rnext(const queue_t * q)17057c478bd9Sstevel@tonic-gate ip_rnext(const queue_t *q)
17067c478bd9Sstevel@tonic-gate {
17077c478bd9Sstevel@tonic-gate 	size_t size = mi_osize(q);
17087c478bd9Sstevel@tonic-gate 	ill_t ill;
17097c478bd9Sstevel@tonic-gate 
17107c478bd9Sstevel@tonic-gate 	if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill),
17117c478bd9Sstevel@tonic-gate 	    (uintptr_t)q->q_ptr) == sizeof (ill))
17127c478bd9Sstevel@tonic-gate 		return ((uintptr_t)ill.ill_rq);
17137c478bd9Sstevel@tonic-gate 
1714892ad162SToomas Soome 	return (0);
17157c478bd9Sstevel@tonic-gate }
17167c478bd9Sstevel@tonic-gate 
17177c478bd9Sstevel@tonic-gate uintptr_t
ip_wnext(const queue_t * q)17187c478bd9Sstevel@tonic-gate ip_wnext(const queue_t *q)
17197c478bd9Sstevel@tonic-gate {
17207c478bd9Sstevel@tonic-gate 	size_t size = mi_osize(q);
17217c478bd9Sstevel@tonic-gate 	ill_t ill;
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate 	if (size == sizeof (ill_t) && mdb_vread(&ill, sizeof (ill),
17247c478bd9Sstevel@tonic-gate 	    (uintptr_t)q->q_ptr) == sizeof (ill))
17257c478bd9Sstevel@tonic-gate 		return ((uintptr_t)ill.ill_wq);
17267c478bd9Sstevel@tonic-gate 
1727892ad162SToomas Soome 	return (0);
17287c478bd9Sstevel@tonic-gate }
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate /*
17317c478bd9Sstevel@tonic-gate  * Print the core fields in an squeue_t.  With the "-v" argument,
17327c478bd9Sstevel@tonic-gate  * provide more verbose output.
17337c478bd9Sstevel@tonic-gate  */
17347c478bd9Sstevel@tonic-gate static int
squeue(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)17357c478bd9Sstevel@tonic-gate squeue(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
17367c478bd9Sstevel@tonic-gate {
17377c478bd9Sstevel@tonic-gate 	unsigned int	i;
17387c478bd9Sstevel@tonic-gate 	unsigned int	verbose = FALSE;
17397c478bd9Sstevel@tonic-gate 	const int	SQUEUE_STATEDELT = (int)(sizeof (uintptr_t) + 9);
17407c478bd9Sstevel@tonic-gate 	boolean_t	arm;
17417c478bd9Sstevel@tonic-gate 	squeue_t	squeue;
17427c478bd9Sstevel@tonic-gate 
17437c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
17447c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("genunix`squeue_cache", "ip`squeue",
17457c478bd9Sstevel@tonic-gate 		    argc, argv) == -1) {
17467c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk squeue cache");
17477c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
17487c478bd9Sstevel@tonic-gate 		}
17497c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
17507c478bd9Sstevel@tonic-gate 	}
17517c478bd9Sstevel@tonic-gate 
17527c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL)
17537c478bd9Sstevel@tonic-gate 	    != argc)
17547c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
17557c478bd9Sstevel@tonic-gate 
17567c478bd9Sstevel@tonic-gate 	if (!DCMD_HDRSPEC(flags) && verbose)
17577c478bd9Sstevel@tonic-gate 		mdb_printf("\n\n");
17587c478bd9Sstevel@tonic-gate 
17597c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags) || verbose) {
17607c478bd9Sstevel@tonic-gate 		mdb_printf("%?s %-5s %-3s %?s %?s %?s\n",
17617c478bd9Sstevel@tonic-gate 		    "ADDR", "STATE", "CPU",
17627c478bd9Sstevel@tonic-gate 		    "FIRST", "LAST", "WORKER");
17637c478bd9Sstevel@tonic-gate 	}
17647c478bd9Sstevel@tonic-gate 
17657c478bd9Sstevel@tonic-gate 	if (mdb_vread(&squeue, sizeof (squeue_t), addr) == -1) {
17667c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read squeue_t at %p", addr);
17677c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
17687c478bd9Sstevel@tonic-gate 	}
17697c478bd9Sstevel@tonic-gate 
17707c478bd9Sstevel@tonic-gate 	mdb_printf("%0?p %05x %3d %0?p %0?p %0?p\n",
17717c478bd9Sstevel@tonic-gate 	    addr, squeue.sq_state, squeue.sq_bind,
17727c478bd9Sstevel@tonic-gate 	    squeue.sq_first, squeue.sq_last, squeue.sq_worker);
17737c478bd9Sstevel@tonic-gate 
17747c478bd9Sstevel@tonic-gate 	if (!verbose)
17757c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
17767c478bd9Sstevel@tonic-gate 
17777c478bd9Sstevel@tonic-gate 	arm = B_TRUE;
17787c478bd9Sstevel@tonic-gate 	for (i = 0; squeue_states[i].bit_name != NULL; i++) {
17797c478bd9Sstevel@tonic-gate 		if (((squeue.sq_state) & (1 << i)) == 0)
17807c478bd9Sstevel@tonic-gate 			continue;
17817c478bd9Sstevel@tonic-gate 
17827c478bd9Sstevel@tonic-gate 		if (arm) {
17837c478bd9Sstevel@tonic-gate 			mdb_printf("%*s|\n", SQUEUE_STATEDELT, "");
17847c478bd9Sstevel@tonic-gate 			mdb_printf("%*s+-->  ", SQUEUE_STATEDELT, "");
17857c478bd9Sstevel@tonic-gate 			arm = B_FALSE;
17867c478bd9Sstevel@tonic-gate 		} else
17877c478bd9Sstevel@tonic-gate 			mdb_printf("%*s      ", SQUEUE_STATEDELT, "");
17887c478bd9Sstevel@tonic-gate 
17897c478bd9Sstevel@tonic-gate 		mdb_printf("%-12s %s\n", squeue_states[i].bit_name,
17907c478bd9Sstevel@tonic-gate 		    squeue_states[i].bit_descr);
17917c478bd9Sstevel@tonic-gate 	}
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
17947c478bd9Sstevel@tonic-gate }
17957c478bd9Sstevel@tonic-gate 
17967c478bd9Sstevel@tonic-gate static void
ip_squeue_help(void)17977c478bd9Sstevel@tonic-gate ip_squeue_help(void)
17987c478bd9Sstevel@tonic-gate {
17997c478bd9Sstevel@tonic-gate 	mdb_printf("Print the core information for a given NCA squeue_t.\n\n");
18007c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
18017c478bd9Sstevel@tonic-gate 	mdb_printf("\t-v\tbe verbose (more descriptive)\n");
18027c478bd9Sstevel@tonic-gate }
18037c478bd9Sstevel@tonic-gate 
18046a8288c7Scarlsonj /*
18056a8288c7Scarlsonj  * This is called by ::th_trace (via a callback) when walking the th_hash
18066a8288c7Scarlsonj  * list.  It calls modent to find the entries.
18076a8288c7Scarlsonj  */
18086a8288c7Scarlsonj /* ARGSUSED */
18096a8288c7Scarlsonj static int
modent_summary(uintptr_t addr,const void * data,void * private)18106a8288c7Scarlsonj modent_summary(uintptr_t addr, const void *data, void *private)
18116a8288c7Scarlsonj {
18126a8288c7Scarlsonj 	th_walk_data_t *thw = private;
18136a8288c7Scarlsonj 	const struct mod_hash_entry *mhe = data;
18146a8288c7Scarlsonj 	th_trace_t th;
18156a8288c7Scarlsonj 
18166a8288c7Scarlsonj 	if (mdb_vread(&th, sizeof (th), (uintptr_t)mhe->mhe_val) == -1) {
18176a8288c7Scarlsonj 		mdb_warn("failed to read th_trace_t %p", mhe->mhe_val);
18186a8288c7Scarlsonj 		return (WALK_ERR);
18196a8288c7Scarlsonj 	}
18206a8288c7Scarlsonj 
18216a8288c7Scarlsonj 	if (th.th_refcnt == 0 && thw->thw_non_zero_only)
18226a8288c7Scarlsonj 		return (WALK_NEXT);
18236a8288c7Scarlsonj 
18246a8288c7Scarlsonj 	if (!thw->thw_match) {
18256a8288c7Scarlsonj 		mdb_printf("%?p %?p %?p %8d %?p\n", thw->thw_ipst, mhe->mhe_key,
18266a8288c7Scarlsonj 		    mhe->mhe_val, th.th_refcnt, th.th_id);
18276a8288c7Scarlsonj 	} else if (thw->thw_matchkey == (uintptr_t)mhe->mhe_key) {
18286a8288c7Scarlsonj 		int i, j, k;
18296a8288c7Scarlsonj 		tr_buf_t *tr;
18306a8288c7Scarlsonj 
18316a8288c7Scarlsonj 		mdb_printf("Object %p in IP stack %p:\n", mhe->mhe_key,
18326a8288c7Scarlsonj 		    thw->thw_ipst);
18336a8288c7Scarlsonj 		i = th.th_trace_lastref;
18346a8288c7Scarlsonj 		mdb_printf("\tThread %p refcnt %d:\n", th.th_id,
18356a8288c7Scarlsonj 		    th.th_refcnt);
18366a8288c7Scarlsonj 		for (j = TR_BUF_MAX; j > 0; j--) {
18376a8288c7Scarlsonj 			tr = th.th_trbuf + i;
18386a8288c7Scarlsonj 			if (tr->tr_depth == 0 || tr->tr_depth > TR_STACK_DEPTH)
18396a8288c7Scarlsonj 				break;
18406a8288c7Scarlsonj 			mdb_printf("\t  T%+ld:\n", tr->tr_time -
18416a8288c7Scarlsonj 			    thw->thw_lbolt);
18426a8288c7Scarlsonj 			for (k = 0; k < tr->tr_depth; k++)
18436a8288c7Scarlsonj 				mdb_printf("\t\t%a\n", tr->tr_stack[k]);
18446a8288c7Scarlsonj 			if (--i < 0)
18456a8288c7Scarlsonj 				i = TR_BUF_MAX - 1;
18466a8288c7Scarlsonj 		}
18476a8288c7Scarlsonj 	}
18486a8288c7Scarlsonj 	return (WALK_NEXT);
18496a8288c7Scarlsonj }
18506a8288c7Scarlsonj 
18516a8288c7Scarlsonj /*
18526a8288c7Scarlsonj  * This is called by ::th_trace (via a callback) when walking the th_hash
18536a8288c7Scarlsonj  * list.  It calls modent to find the entries.
18546a8288c7Scarlsonj  */
18556a8288c7Scarlsonj /* ARGSUSED */
18566a8288c7Scarlsonj static int
th_hash_summary(uintptr_t addr,const void * data,void * private)18576a8288c7Scarlsonj th_hash_summary(uintptr_t addr, const void *data, void *private)
18586a8288c7Scarlsonj {
18596a8288c7Scarlsonj 	const th_hash_t *thh = data;
18606a8288c7Scarlsonj 	th_walk_data_t *thw = private;
18616a8288c7Scarlsonj 
18626a8288c7Scarlsonj 	thw->thw_ipst = (uintptr_t)thh->thh_ipst;
18636a8288c7Scarlsonj 	return (mdb_pwalk("modent", modent_summary, private,
18646a8288c7Scarlsonj 	    (uintptr_t)thh->thh_hash));
18656a8288c7Scarlsonj }
18666a8288c7Scarlsonj 
18676a8288c7Scarlsonj /*
18686a8288c7Scarlsonj  * Print or summarize the th_trace_t structures.
18696a8288c7Scarlsonj  */
18706a8288c7Scarlsonj static int
th_trace(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)18716a8288c7Scarlsonj th_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
18726a8288c7Scarlsonj {
18736a8288c7Scarlsonj 	th_walk_data_t thw;
18746a8288c7Scarlsonj 
18756a8288c7Scarlsonj 	(void) memset(&thw, 0, sizeof (thw));
18766a8288c7Scarlsonj 
18776a8288c7Scarlsonj 	if (mdb_getopts(argc, argv,
18786a8288c7Scarlsonj 	    'n', MDB_OPT_SETBITS, TRUE, &thw.thw_non_zero_only,
18796a8288c7Scarlsonj 	    NULL) != argc)
18806a8288c7Scarlsonj 		return (DCMD_USAGE);
18816a8288c7Scarlsonj 
18826a8288c7Scarlsonj 	if (!(flags & DCMD_ADDRSPEC)) {
18836a8288c7Scarlsonj 		/*
18846a8288c7Scarlsonj 		 * No address specified.  Walk all of the th_hash_t in the
18856a8288c7Scarlsonj 		 * system, and summarize the th_trace_t entries in each.
18866a8288c7Scarlsonj 		 */
18876a8288c7Scarlsonj 		mdb_printf("%?s %?s %?s %8s %?s\n",
18886a8288c7Scarlsonj 		    "IPSTACK", "OBJECT", "TRACE", "REFCNT", "THREAD");
18896a8288c7Scarlsonj 		thw.thw_match = B_FALSE;
18906a8288c7Scarlsonj 	} else {
18916a8288c7Scarlsonj 		thw.thw_match = B_TRUE;
18926a8288c7Scarlsonj 		thw.thw_matchkey = addr;
1893d3d50737SRafael Vanoni 
1894d3d50737SRafael Vanoni 		if ((thw.thw_lbolt = (clock_t)mdb_get_lbolt()) == -1) {
18956a8288c7Scarlsonj 			mdb_warn("failed to read lbolt");
18966a8288c7Scarlsonj 			return (DCMD_ERR);
18976a8288c7Scarlsonj 		}
18986a8288c7Scarlsonj 	}
1899892ad162SToomas Soome 	if (mdb_pwalk("th_hash", th_hash_summary, &thw, 0) == -1) {
19006a8288c7Scarlsonj 		mdb_warn("can't walk th_hash entries");
19016a8288c7Scarlsonj 		return (DCMD_ERR);
19026a8288c7Scarlsonj 	}
19036a8288c7Scarlsonj 	return (DCMD_OK);
19046a8288c7Scarlsonj }
19056a8288c7Scarlsonj 
19066a8288c7Scarlsonj static void
th_trace_help(void)19076a8288c7Scarlsonj th_trace_help(void)
19086a8288c7Scarlsonj {
1909bd670b35SErik Nordmark 	mdb_printf("If given an address of an ill_t, ipif_t, ire_t, or ncec_t, "
19106a8288c7Scarlsonj 	    "print the\n"
19116a8288c7Scarlsonj 	    "corresponding th_trace_t structure in detail.  Otherwise, if no "
19126a8288c7Scarlsonj 	    "address is\n"
19136a8288c7Scarlsonj 	    "given, then summarize all th_trace_t structures.\n\n");
19146a8288c7Scarlsonj 	mdb_printf("Options:\n"
19156a8288c7Scarlsonj 	    "\t-n\tdisplay only entries with non-zero th_refcnt\n");
19166a8288c7Scarlsonj }
19176a8288c7Scarlsonj 
19187c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
1919d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "conn_status", ":",
1920d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "display connection structures from ipcl hash tables",
1921d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    conn_status, conn_status_help },
1922d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "srcid_status", ":",
1923d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "display connection structures from ipcl hash tables",
1924d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    srcid_status },
1925bd670b35SErik Nordmark 	{ "ill", "?[-v] [-P v4 | v6] [-s exclusive-ip-zone-name]",
1926bd670b35SErik Nordmark 	    "display ill_t structures", ill, ill_help },
19277c478bd9Sstevel@tonic-gate 	{ "illif", "?[-P v4 | v6]",
19287c478bd9Sstevel@tonic-gate 	    "display or filter IP Lower Level InterFace structures", illif,
19297c478bd9Sstevel@tonic-gate 	    illif_help },
19307c478bd9Sstevel@tonic-gate 	{ "iphdr", ":[-vf]", "display an IPv4 header", iphdr },
19317c478bd9Sstevel@tonic-gate 	{ "ip6hdr", ":[-vf]", "display an IPv6 header", ip6hdr },
1932d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "ipif", "?[-v] [-P v4 | v6]", "display ipif structures",
1933d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    ipif, ipif_help },
1934bd670b35SErik Nordmark 	{ "ire", "?[-v] [-P v4|v6] [-s exclusive-ip-zone-name]",
1935ffaa671aSsowmini 	    "display Internet Route Entry structures", ire },
1936bd670b35SErik Nordmark 	{ "nce", "?[-P v4|v6] [-i <interface>]",
1937bd670b35SErik Nordmark 	    "display interface-specific Neighbor Cache structures", nce },
1938bd670b35SErik Nordmark 	{ "ncec", "?[-P v4 | v6]", "display Neighbor Cache Entry structures",
1939bd670b35SErik Nordmark 	    ncec },
1940bd670b35SErik Nordmark 	{ "dce", "?[-P v4|v6] [-s exclusive-ip-zone-name]",
1941bd670b35SErik Nordmark 	    "display Destination Cache Entry structures", dce },
19427c478bd9Sstevel@tonic-gate 	{ "squeue", ":[-v]", "print core squeue_t info", squeue,
19437c478bd9Sstevel@tonic-gate 	    ip_squeue_help },
19447c478bd9Sstevel@tonic-gate 	{ "tcphdr", ":", "display a TCP header", tcphdr },
19457c478bd9Sstevel@tonic-gate 	{ "udphdr", ":", "display an UDP header", udphdr },
19467c478bd9Sstevel@tonic-gate 	{ "sctphdr", ":", "display an SCTP header", sctphdr },
19476a8288c7Scarlsonj 	{ "th_trace", "?[-n]", "display th_trace_t structures", th_trace,
19486a8288c7Scarlsonj 	    th_trace_help },
19497c478bd9Sstevel@tonic-gate 	{ NULL }
19507c478bd9Sstevel@tonic-gate };
19517c478bd9Sstevel@tonic-gate 
19527c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
1953d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "conn_status", "walk list of conn_t structures",
1954d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ip_stacks_common_walk_init, conn_status_walk_step, NULL },
1955f4b3ec61Sdh155122 	{ "illif", "walk list of ill interface types for all stacks",
1956ffaa671aSsowmini 		ip_stacks_common_walk_init, illif_walk_step, NULL },
1957f4b3ec61Sdh155122 	{ "illif_stack", "walk list of ill interface types",
1958f4b3ec61Sdh155122 		illif_stack_walk_init, illif_stack_walk_step,
1959f4b3ec61Sdh155122 		illif_stack_walk_fini },
1960bd670b35SErik Nordmark 	{ "ill", "walk active ill_t structures for all stacks",
1961d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ill_walk_init, ill_walk_step, NULL },
1962d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "ipif", "walk list of ipif structures for all stacks",
1963d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipif_walk_init, ipif_walk_step, NULL },
1964d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "ipif_list", "walk the linked list of ipif structures "
1965d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		"for a given ill",
1966d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ip_list_walk_init, ip_list_walk_step,
1967d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ip_list_walk_fini, &ipif_walk_arg },
1968d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "srcid", "walk list of srcid_map structures for all stacks",
1969d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ip_stacks_common_walk_init, srcid_walk_step, NULL },
1970d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "srcid_list", "walk list of srcid_map structures for a stack",
1971d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ip_list_walk_init, ip_list_walk_step, ip_list_walk_fini,
1972d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		&srcid_walk_arg },
19737c478bd9Sstevel@tonic-gate 	{ "ire", "walk active ire_t structures",
19747c478bd9Sstevel@tonic-gate 		ire_walk_init, ire_walk_step, NULL },
1975f4b3ec61Sdh155122 	{ "ire_next", "walk ire_t structures in the ctable",
1976f4b3ec61Sdh155122 		ire_next_walk_init, ire_next_walk_step, NULL },
1977bd670b35SErik Nordmark 	{ "nce", "walk active nce_t structures",
1978bd670b35SErik Nordmark 		nce_walk_init, nce_walk_step, NULL },
1979bd670b35SErik Nordmark 	{ "dce", "walk active dce_t structures",
1980bd670b35SErik Nordmark 		dce_walk_init, dce_walk_step, NULL },
1981f4b3ec61Sdh155122 	{ "ip_stacks", "walk all the ip_stack_t",
1982721fffe3SKacheong Poon 		ns_walk_init, ip_stacks_walk_step, NULL },
1983721fffe3SKacheong Poon 	{ "tcp_stacks", "walk all the tcp_stack_t",
1984721fffe3SKacheong Poon 		ns_walk_init, tcp_stacks_walk_step, NULL },
1985721fffe3SKacheong Poon 	{ "sctp_stacks", "walk all the sctp_stack_t",
1986721fffe3SKacheong Poon 		ns_walk_init, sctp_stacks_walk_step, NULL },
1987721fffe3SKacheong Poon 	{ "udp_stacks", "walk all the udp_stack_t",
1988721fffe3SKacheong Poon 		ns_walk_init, udp_stacks_walk_step, NULL },
19896a8288c7Scarlsonj 	{ "th_hash", "walk all the th_hash_t entries",
19906a8288c7Scarlsonj 		th_hash_walk_init, th_hash_walk_step, NULL },
1991bd670b35SErik Nordmark 	{ "ncec", "walk list of ncec structures for all stacks",
1992bd670b35SErik Nordmark 		ip_stacks_common_walk_init, ncec_walk_step, NULL },
1993bd670b35SErik Nordmark 	{ "ncec_stack", "walk list of ncec structures",
1994bd670b35SErik Nordmark 		ncec_stack_walk_init, ncec_stack_walk_step,
1995bd670b35SErik Nordmark 		ncec_stack_walk_fini},
1996d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "udp_hash", "walk list of conn_t structures in ips_ipcl_udp_fanout",
1997d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_init, ipcl_hash_walk_step,
1998d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_fini, &udp_hash_arg},
1999d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "conn_hash", "walk list of conn_t structures in ips_ipcl_conn_fanout",
2000d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_init, ipcl_hash_walk_step,
2001d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_fini, &conn_hash_arg},
2002d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "bind_hash", "walk list of conn_t structures in ips_ipcl_bind_fanout",
2003d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_init, ipcl_hash_walk_step,
2004d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_fini, &bind_hash_arg},
2005d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "proto_hash", "walk list of conn_t structures in "
2006d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "ips_ipcl_proto_fanout",
2007d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_init, ipcl_hash_walk_step,
2008d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_fini, &proto_hash_arg},
2009d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	{ "proto_v6_hash", "walk list of conn_t structures in "
2010d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "ips_ipcl_proto_fanout_v6",
2011d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_init, ipcl_hash_walk_step,
2012d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipcl_hash_walk_fini, &proto_v6_hash_arg},
2013721fffe3SKacheong Poon 	{ "ilb_stacks", "walk all ilb_stack_t",
2014721fffe3SKacheong Poon 		ns_walk_init, ilb_stacks_walk_step, NULL },
2015dbed73cbSSangeeta Misra 	{ "ilb_rules", "walk ilb rules in a given ilb_stack_t",
2016dbed73cbSSangeeta Misra 		ilb_rules_walk_init, ilb_rules_walk_step, NULL },
2017dbed73cbSSangeeta Misra 	{ "ilb_servers", "walk server in a given ilb_rule_t",
2018dbed73cbSSangeeta Misra 		ilb_servers_walk_init, ilb_servers_walk_step, NULL },
2019dbed73cbSSangeeta Misra 	{ "ilb_nat_src", "walk NAT source table of a given ilb_stack_t",
2020dbed73cbSSangeeta Misra 		ilb_nat_src_walk_init, ilb_nat_src_walk_step,
2021dbed73cbSSangeeta Misra 		ilb_common_walk_fini },
2022dbed73cbSSangeeta Misra 	{ "ilb_conns", "walk NAT table of a given ilb_stack_t",
2023dbed73cbSSangeeta Misra 		ilb_conn_walk_init, ilb_conn_walk_step, ilb_common_walk_fini },
2024dbed73cbSSangeeta Misra 	{ "ilb_stickys", "walk sticky table of a given ilb_stack_t",
2025dbed73cbSSangeeta Misra 		ilb_sticky_walk_init, ilb_sticky_walk_step,
2026dbed73cbSSangeeta Misra 		ilb_common_walk_fini },
2027721fffe3SKacheong Poon 	{ "tcps_sc", "walk all the per CPU stats counters of a tcp_stack_t",
2028721fffe3SKacheong Poon 		tcps_sc_walk_init, tcps_sc_walk_step, NULL },
20297c478bd9Sstevel@tonic-gate 	{ NULL }
20307c478bd9Sstevel@tonic-gate };
20317c478bd9Sstevel@tonic-gate 
20320c1b95beSRichard Lowe static const mdb_qops_t ip_qops = {
20330c1b95beSRichard Lowe 	.q_info = ip_qinfo,
20340c1b95beSRichard Lowe 	.q_rnext = ip_rnext,
20350c1b95beSRichard Lowe 	.q_wnext = ip_wnext
20360c1b95beSRichard Lowe };
20370c1b95beSRichard Lowe 
20387c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)20417c478bd9Sstevel@tonic-gate _mdb_init(void)
20427c478bd9Sstevel@tonic-gate {
20437c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
20447c478bd9Sstevel@tonic-gate 
204569bb4bb4Scarlsonj 	if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0)
20467c478bd9Sstevel@tonic-gate 		mdb_qops_install(&ip_qops, (uintptr_t)sym.st_value);
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate 	return (&modinfo);
20497c478bd9Sstevel@tonic-gate }
20507c478bd9Sstevel@tonic-gate 
20517c478bd9Sstevel@tonic-gate void
_mdb_fini(void)20527c478bd9Sstevel@tonic-gate _mdb_fini(void)
20537c478bd9Sstevel@tonic-gate {
20547c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
20557c478bd9Sstevel@tonic-gate 
205669bb4bb4Scarlsonj 	if (mdb_lookup_by_obj("ip", "ipwinit", &sym) == 0)
20577c478bd9Sstevel@tonic-gate 		mdb_qops_remove(&ip_qops, (uintptr_t)sym.st_value);
20587c478bd9Sstevel@tonic-gate }
2059ffaa671aSsowmini 
2060ffaa671aSsowmini static char *
ncec_state(int ncec_state)2061bd670b35SErik Nordmark ncec_state(int ncec_state)
2062ffaa671aSsowmini {
2063bd670b35SErik Nordmark 	switch (ncec_state) {
2064ffaa671aSsowmini 	case ND_UNCHANGED:
2065ffaa671aSsowmini 		return ("unchanged");
2066ffaa671aSsowmini 	case ND_INCOMPLETE:
2067ffaa671aSsowmini 		return ("incomplete");
2068ffaa671aSsowmini 	case ND_REACHABLE:
2069ffaa671aSsowmini 		return ("reachable");
2070ffaa671aSsowmini 	case ND_STALE:
2071ffaa671aSsowmini 		return ("stale");
2072ffaa671aSsowmini 	case ND_DELAY:
2073ffaa671aSsowmini 		return ("delay");
2074ffaa671aSsowmini 	case ND_PROBE:
2075ffaa671aSsowmini 		return ("probe");
2076ffaa671aSsowmini 	case ND_UNREACHABLE:
2077ffaa671aSsowmini 		return ("unreach");
2078ffaa671aSsowmini 	case ND_INITIAL:
2079ffaa671aSsowmini 		return ("initial");
2080ffaa671aSsowmini 	default:
2081ffaa671aSsowmini 		return ("??");
2082ffaa671aSsowmini 	}
2083ffaa671aSsowmini }
2084ffaa671aSsowmini 
2085ffaa671aSsowmini static char *
ncec_l2_addr(const ncec_t * ncec,const ill_t * ill)2086bd670b35SErik Nordmark ncec_l2_addr(const ncec_t *ncec, const ill_t *ill)
2087bd670b35SErik Nordmark {
2088bd670b35SErik Nordmark 	uchar_t *h;
2089bd670b35SErik Nordmark 	static char addr_buf[L2MAXADDRSTRLEN];
2090bd670b35SErik Nordmark 
2091bd670b35SErik Nordmark 	if (ncec->ncec_lladdr == NULL) {
2092bd670b35SErik Nordmark 		return ("None");
2093bd670b35SErik Nordmark 	}
2094bd670b35SErik Nordmark 
2095bd670b35SErik Nordmark 	if (ill->ill_net_type == IRE_IF_RESOLVER) {
2096bd670b35SErik Nordmark 
2097bd670b35SErik Nordmark 		if (ill->ill_phys_addr_length == 0)
2098bd670b35SErik Nordmark 			return ("None");
2099bd670b35SErik Nordmark 		h = mdb_zalloc(ill->ill_phys_addr_length, UM_SLEEP);
2100bd670b35SErik Nordmark 		if (mdb_vread(h, ill->ill_phys_addr_length,
2101bd670b35SErik Nordmark 		    (uintptr_t)ncec->ncec_lladdr) == -1) {
2102bd670b35SErik Nordmark 			mdb_warn("failed to read hwaddr at %p",
2103bd670b35SErik Nordmark 			    ncec->ncec_lladdr);
2104bd670b35SErik Nordmark 			return ("Unknown");
2105bd670b35SErik Nordmark 		}
2106bd670b35SErik Nordmark 		mdb_mac_addr(h, ill->ill_phys_addr_length,
2107bd670b35SErik Nordmark 		    addr_buf, sizeof (addr_buf));
2108bd670b35SErik Nordmark 	} else {
2109bd670b35SErik Nordmark 		return ("None");
2110bd670b35SErik Nordmark 	}
2111bd670b35SErik Nordmark 	mdb_free(h, ill->ill_phys_addr_length);
2112bd670b35SErik Nordmark 	return (addr_buf);
2113bd670b35SErik Nordmark }
2114bd670b35SErik Nordmark 
2115bd670b35SErik Nordmark static char *
nce_l2_addr(const nce_t * nce,const ill_t * ill)2116ffaa671aSsowmini nce_l2_addr(const nce_t *nce, const ill_t *ill)
2117ffaa671aSsowmini {
2118ffaa671aSsowmini 	uchar_t *h;
2119ffaa671aSsowmini 	static char addr_buf[L2MAXADDRSTRLEN];
2120ffaa671aSsowmini 	mblk_t mp;
2121ffaa671aSsowmini 	size_t mblen;
2122ffaa671aSsowmini 
2123bd670b35SErik Nordmark 	if (nce->nce_dlur_mp == NULL)
2124ffaa671aSsowmini 		return ("None");
2125ffaa671aSsowmini 
2126ffaa671aSsowmini 	if (ill->ill_net_type == IRE_IF_RESOLVER) {
2127ffaa671aSsowmini 		if (mdb_vread(&mp, sizeof (mblk_t),
2128bd670b35SErik Nordmark 		    (uintptr_t)nce->nce_dlur_mp) == -1) {
2129bd670b35SErik Nordmark 			mdb_warn("failed to read nce_dlur_mp at %p",
2130bd670b35SErik Nordmark 			    nce->nce_dlur_mp);
2131bd670b35SErik Nordmark 			return ("None");
2132ffaa671aSsowmini 		}
2133bd670b35SErik Nordmark 		if (ill->ill_phys_addr_length == 0)
2134ffaa671aSsowmini 			return ("None");
2135ffaa671aSsowmini 		mblen = mp.b_wptr - mp.b_rptr;
2136ffaa671aSsowmini 		if (mblen > (sizeof (dl_unitdata_req_t) + MAX_SAP_LEN) ||
2137bd670b35SErik Nordmark 		    ill->ill_phys_addr_length > MAX_SAP_LEN ||
2138bd670b35SErik Nordmark 		    (NCE_LL_ADDR_OFFSET(ill) +
2139bd670b35SErik Nordmark 		    ill->ill_phys_addr_length) > mblen) {
2140bd670b35SErik Nordmark 			return ("Unknown");
2141ffaa671aSsowmini 		}
2142ffaa671aSsowmini 		h = mdb_zalloc(mblen, UM_SLEEP);
2143ffaa671aSsowmini 		if (mdb_vread(h, mblen, (uintptr_t)(mp.b_rptr)) == -1) {
2144ffaa671aSsowmini 			mdb_warn("failed to read hwaddr at %p",
2145ffaa671aSsowmini 			    mp.b_rptr + NCE_LL_ADDR_OFFSET(ill));
2146ffaa671aSsowmini 			return ("Unknown");
2147ffaa671aSsowmini 		}
2148bd670b35SErik Nordmark 		mdb_mac_addr(h + NCE_LL_ADDR_OFFSET(ill),
2149bd670b35SErik Nordmark 		    ill->ill_phys_addr_length, addr_buf, sizeof (addr_buf));
2150ffaa671aSsowmini 	} else {
2151ffaa671aSsowmini 		return ("None");
2152ffaa671aSsowmini 	}
2153ffaa671aSsowmini 	mdb_free(h, mblen);
2154ffaa671aSsowmini 	return (addr_buf);
2155ffaa671aSsowmini }
2156ffaa671aSsowmini 
2157ffaa671aSsowmini static void
ncec_header(uint_t flags)2158bd670b35SErik Nordmark ncec_header(uint_t flags)
2159ffaa671aSsowmini {
2160ffaa671aSsowmini 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
2161ffaa671aSsowmini 
2162ffaa671aSsowmini 		mdb_printf("%<u>%?s %-20s %-10s %-8s %-5s %s%</u>\n",
2163ffaa671aSsowmini 		    "ADDR", "HW_ADDR", "STATE", "FLAGS", "ILL", "IP ADDR");
2164ffaa671aSsowmini 	}
2165ffaa671aSsowmini }
2166ffaa671aSsowmini 
2167ffaa671aSsowmini int
ncec(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2168bd670b35SErik Nordmark ncec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2169ffaa671aSsowmini {
2170bd670b35SErik Nordmark 	ncec_t ncec;
2171bd670b35SErik Nordmark 	ncec_cbdata_t id;
2172ffaa671aSsowmini 	int ipversion = 0;
2173ffaa671aSsowmini 	const char *opt_P = NULL;
2174ffaa671aSsowmini 
2175ffaa671aSsowmini 	if (mdb_getopts(argc, argv,
2176ffaa671aSsowmini 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
2177ffaa671aSsowmini 		return (DCMD_USAGE);
2178ffaa671aSsowmini 
2179ffaa671aSsowmini 	if (opt_P != NULL) {
2180ffaa671aSsowmini 		if (strcmp("v4", opt_P) == 0) {
2181ffaa671aSsowmini 			ipversion = IPV4_VERSION;
2182ffaa671aSsowmini 		} else if (strcmp("v6", opt_P) == 0) {
2183ffaa671aSsowmini 			ipversion = IPV6_VERSION;
2184ffaa671aSsowmini 		} else {
2185ffaa671aSsowmini 			mdb_warn("invalid protocol '%s'\n", opt_P);
2186ffaa671aSsowmini 			return (DCMD_USAGE);
2187ffaa671aSsowmini 		}
2188ffaa671aSsowmini 	}
2189ffaa671aSsowmini 
2190ffaa671aSsowmini 	if (flags & DCMD_ADDRSPEC) {
2191ffaa671aSsowmini 
2192bd670b35SErik Nordmark 		if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) {
2193bd670b35SErik Nordmark 			mdb_warn("failed to read ncec at %p\n", addr);
2194ffaa671aSsowmini 			return (DCMD_ERR);
2195ffaa671aSsowmini 		}
2196bd670b35SErik Nordmark 		if (ipversion != 0 && ncec.ncec_ipversion != ipversion) {
2197ffaa671aSsowmini 			mdb_printf("IP Version mismatch\n");
2198ffaa671aSsowmini 			return (DCMD_ERR);
2199ffaa671aSsowmini 		}
2200bd670b35SErik Nordmark 		ncec_header(flags);
2201bd670b35SErik Nordmark 		return (ncec_format(addr, &ncec, ipversion));
2202ffaa671aSsowmini 
2203ffaa671aSsowmini 	} else {
2204bd670b35SErik Nordmark 		id.ncec_addr = addr;
2205bd670b35SErik Nordmark 		id.ncec_ipversion = ipversion;
2206bd670b35SErik Nordmark 		ncec_header(flags);
2207bd670b35SErik Nordmark 		if (mdb_walk("ncec", (mdb_walk_cb_t)ncec_cb, &id) == -1) {
2208bd670b35SErik Nordmark 			mdb_warn("failed to walk ncec table\n");
2209ffaa671aSsowmini 			return (DCMD_ERR);
2210ffaa671aSsowmini 		}
2211ffaa671aSsowmini 	}
2212ffaa671aSsowmini 	return (DCMD_OK);
2213ffaa671aSsowmini }
2214ffaa671aSsowmini 
2215ffaa671aSsowmini static int
ncec_format(uintptr_t addr,const ncec_t * ncec,int ipversion)2216bd670b35SErik Nordmark ncec_format(uintptr_t addr, const ncec_t *ncec, int ipversion)
2217ffaa671aSsowmini {
2218bd670b35SErik Nordmark 	static const mdb_bitmask_t ncec_flags[] = {
2219bd670b35SErik Nordmark 		{ "P",	NCE_F_NONUD,		NCE_F_NONUD },
2220ffaa671aSsowmini 		{ "R",	NCE_F_ISROUTER,		NCE_F_ISROUTER	},
2221ffaa671aSsowmini 		{ "N",	NCE_F_NONUD,		NCE_F_NONUD	},
2222ffaa671aSsowmini 		{ "A",	NCE_F_ANYCAST,		NCE_F_ANYCAST	},
2223ffaa671aSsowmini 		{ "C",	NCE_F_CONDEMNED,	NCE_F_CONDEMNED	},
2224ffaa671aSsowmini 		{ "U",	NCE_F_UNSOL_ADV,	NCE_F_UNSOL_ADV },
2225ffaa671aSsowmini 		{ "B",	NCE_F_BCAST,		NCE_F_BCAST	},
2226ffaa671aSsowmini 		{ NULL,	0,			0		}
2227ffaa671aSsowmini 	};
2228bd670b35SErik Nordmark #define	NCE_MAX_FLAGS	(sizeof (ncec_flags) / sizeof (mdb_bitmask_t))
2229ffaa671aSsowmini 	struct in_addr nceaddr;
2230ffaa671aSsowmini 	ill_t ill;
2231ffaa671aSsowmini 	char ill_name[LIFNAMSIZ];
2232ffaa671aSsowmini 	char flagsbuf[NCE_MAX_FLAGS];
2233ffaa671aSsowmini 
2234bd670b35SErik Nordmark 	if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ncec->ncec_ill) == -1) {
2235bd670b35SErik Nordmark 		mdb_warn("failed to read ncec_ill at %p",
2236bd670b35SErik Nordmark 		    ncec->ncec_ill);
2237ffaa671aSsowmini 		return (DCMD_ERR);
2238ffaa671aSsowmini 	}
2239ffaa671aSsowmini 
2240ffaa671aSsowmini 	(void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill.ill_name_length),
2241ffaa671aSsowmini 	    (uintptr_t)ill.ill_name);
2242ffaa671aSsowmini 
2243ffaa671aSsowmini 	mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%hb",
2244bd670b35SErik Nordmark 	    ncec->ncec_flags, ncec_flags);
2245ffaa671aSsowmini 
2246bd670b35SErik Nordmark 	if (ipversion != 0 && ncec->ncec_ipversion != ipversion)
2247ffaa671aSsowmini 		return (DCMD_OK);
2248ffaa671aSsowmini 
2249bd670b35SErik Nordmark 	if (ncec->ncec_ipversion == IPV4_VERSION) {
2250bd670b35SErik Nordmark 		IN6_V4MAPPED_TO_INADDR(&ncec->ncec_addr, &nceaddr);
2251ffaa671aSsowmini 		mdb_printf("%?p %-20s %-10s "
2252ffaa671aSsowmini 		    "%-8s "
2253ffaa671aSsowmini 		    "%-5s %I\n",
2254bd670b35SErik Nordmark 		    addr, ncec_l2_addr(ncec, &ill),
2255bd670b35SErik Nordmark 		    ncec_state(ncec->ncec_state),
2256ffaa671aSsowmini 		    flagsbuf,
2257ffaa671aSsowmini 		    ill_name, nceaddr.s_addr);
2258ffaa671aSsowmini 	} else {
2259ffaa671aSsowmini 		mdb_printf("%?p %-20s %-10s %-8s %-5s %N\n",
2260bd670b35SErik Nordmark 		    addr,  ncec_l2_addr(ncec, &ill),
2261bd670b35SErik Nordmark 		    ncec_state(ncec->ncec_state),
2262ffaa671aSsowmini 		    flagsbuf,
2263bd670b35SErik Nordmark 		    ill_name, &ncec->ncec_addr);
2264ffaa671aSsowmini 	}
2265ffaa671aSsowmini 
2266ffaa671aSsowmini 	return (DCMD_OK);
2267ffaa671aSsowmini }
2268ffaa671aSsowmini 
2269ffaa671aSsowmini static uintptr_t
ncec_get_next_hash_tbl(uintptr_t start,int * index,struct ndp_g_s ndp)2270bd670b35SErik Nordmark ncec_get_next_hash_tbl(uintptr_t start, int *index, struct ndp_g_s ndp)
2271ffaa671aSsowmini {
2272ffaa671aSsowmini 	uintptr_t addr = start;
2273ffaa671aSsowmini 	int i = *index;
2274ffaa671aSsowmini 
2275892ad162SToomas Soome 	while (addr == 0) {
2276ffaa671aSsowmini 
2277ffaa671aSsowmini 		if (++i >= NCE_TABLE_SIZE)
2278ffaa671aSsowmini 			break;
2279ffaa671aSsowmini 		addr = (uintptr_t)ndp.nce_hash_tbl[i];
2280ffaa671aSsowmini 	}
2281ffaa671aSsowmini 	*index = i;
2282ffaa671aSsowmini 	return (addr);
2283ffaa671aSsowmini }
2284ffaa671aSsowmini 
2285ffaa671aSsowmini static int
ncec_walk_step(mdb_walk_state_t * wsp)2286bd670b35SErik Nordmark ncec_walk_step(mdb_walk_state_t *wsp)
2287ffaa671aSsowmini {
2288ffaa671aSsowmini 	uintptr_t kaddr4, kaddr6;
2289ffaa671aSsowmini 
2290ffaa671aSsowmini 	kaddr4 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp4);
2291ffaa671aSsowmini 	kaddr6 = wsp->walk_addr + OFFSETOF(ip_stack_t, ips_ndp6);
2292ffaa671aSsowmini 
2293ffaa671aSsowmini 	if (mdb_vread(&kaddr4, sizeof (kaddr4), kaddr4) == -1) {
2294ffaa671aSsowmini 		mdb_warn("can't read ips_ip_cache_table at %p", kaddr4);
2295ffaa671aSsowmini 		return (WALK_ERR);
2296ffaa671aSsowmini 	}
2297ffaa671aSsowmini 	if (mdb_vread(&kaddr6, sizeof (kaddr6), kaddr6) == -1) {
2298ffaa671aSsowmini 		mdb_warn("can't read ips_ip_cache_table at %p", kaddr6);
2299ffaa671aSsowmini 		return (WALK_ERR);
2300ffaa671aSsowmini 	}
2301bd670b35SErik Nordmark 	if (mdb_pwalk("ncec_stack", wsp->walk_callback, wsp->walk_cbdata,
2302ffaa671aSsowmini 	    kaddr4) == -1) {
2303bd670b35SErik Nordmark 		mdb_warn("couldn't walk 'ncec_stack' for ips_ndp4 %p",
2304ffaa671aSsowmini 		    kaddr4);
2305ffaa671aSsowmini 		return (WALK_ERR);
2306ffaa671aSsowmini 	}
2307bd670b35SErik Nordmark 	if (mdb_pwalk("ncec_stack", wsp->walk_callback,
2308ffaa671aSsowmini 	    wsp->walk_cbdata, kaddr6) == -1) {
2309bd670b35SErik Nordmark 		mdb_warn("couldn't walk 'ncec_stack' for ips_ndp6 %p",
2310ffaa671aSsowmini 		    kaddr6);
2311ffaa671aSsowmini 		return (WALK_ERR);
2312ffaa671aSsowmini 	}
2313ffaa671aSsowmini 	return (WALK_NEXT);
2314ffaa671aSsowmini }
2315ffaa671aSsowmini 
2316d5b6ed4bSVasumathi Sundaram - Sun Microsystems static uintptr_t
ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t * iw)2317d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t *iw)
2318d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2319d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	struct connf_s connf;
2320892ad162SToomas Soome 	uintptr_t addr = 0, next;
2321d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int index = iw->connf_tbl_index;
2322d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2323d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	do {
2324d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		next = iw->hash_tbl + index * sizeof (struct connf_s);
2325d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (++index >= iw->hash_tbl_size) {
2326892ad162SToomas Soome 			addr = 0;
2327d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			break;
2328d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2329d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_vread(&connf, sizeof (struct connf_s), next) == -1)  {
2330d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to read conn_t at %p", next);
2331892ad162SToomas Soome 			return (0);
2332d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2333d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		addr = (uintptr_t)connf.connf_head;
2334892ad162SToomas Soome 	} while (addr == 0);
2335d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	iw->connf_tbl_index = index;
2336d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (addr);
2337d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2338d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2339d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipcl_hash_walk_init(mdb_walk_state_t * wsp)2340d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipcl_hash_walk_init(mdb_walk_state_t *wsp)
2341d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2342d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	const hash_walk_arg_t *arg = wsp->walk_arg;
2343d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipcl_hash_walk_data_t *iw;
2344d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t tbladdr;
2345d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t sizeaddr;
2346d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2347d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	iw = mdb_alloc(sizeof (ipcl_hash_walk_data_t), UM_SLEEP);
2348d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	iw->conn = mdb_alloc(sizeof (conn_t), UM_SLEEP);
2349d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	tbladdr = wsp->walk_addr + arg->tbl_off;
2350d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	sizeaddr = wsp->walk_addr + arg->size_off;
2351d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2352d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&iw->hash_tbl, sizeof (uintptr_t), tbladdr) == -1) {
2353d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't read fanout table addr at %p", tbladdr);
2354d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_free(iw->conn, sizeof (conn_t));
2355d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_free(iw, sizeof (ipcl_hash_walk_data_t));
2356d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2357d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2358bd670b35SErik Nordmark 	if (arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v4) ||
2359d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    arg->tbl_off == OFFSETOF(ip_stack_t, ips_ipcl_proto_fanout_v6)) {
2360d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		iw->hash_tbl_size = IPPROTO_MAX;
2361d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2362d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_vread(&iw->hash_tbl_size, sizeof (int),
2363d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sizeaddr) == -1) {
2364d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("can't read fanout table size addr at %p",
2365d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			    sizeaddr);
2366d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_free(iw->conn, sizeof (conn_t));
2367d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_free(iw, sizeof (ipcl_hash_walk_data_t));
2368d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_ERR);
2369d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2370d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2371d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	iw->connf_tbl_index = 0;
2372d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw);
2373d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	wsp->walk_data = iw;
2374d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2375892ad162SToomas Soome 	if (wsp->walk_addr != 0)
2376d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_NEXT);
2377d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	else
2378d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_DONE);
2379d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2380d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2381d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipcl_hash_walk_step(mdb_walk_state_t * wsp)2382d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipcl_hash_walk_step(mdb_walk_state_t *wsp)
2383d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2384d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t addr = wsp->walk_addr;
2385d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipcl_hash_walk_data_t *iw = wsp->walk_data;
2386d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	conn_t *conn = iw->conn;
2387d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int ret = WALK_DONE;
2388d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2389892ad162SToomas Soome 	while (addr != 0) {
2390d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_vread(conn, sizeof (conn_t), addr) == -1) {
2391d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to read conn_t at %p", addr);
2392d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_ERR);
2393d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2394d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ret = wsp->walk_callback(addr, iw, wsp->walk_cbdata);
2395d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (ret != WALK_NEXT)
2396d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			break;
2397d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		addr = (uintptr_t)conn->conn_next;
2398d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2399d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (ret == WALK_NEXT) {
2400d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		wsp->walk_addr = ipcl_hash_get_next_connf_tbl(iw);
2401d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2402892ad162SToomas Soome 		if (wsp->walk_addr != 0)
2403d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_NEXT);
2404d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		else
2405d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_DONE);
2406d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2407d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2408d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (ret);
2409d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2410d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2411d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
ipcl_hash_walk_fini(mdb_walk_state_t * wsp)2412d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipcl_hash_walk_fini(mdb_walk_state_t *wsp)
2413d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2414d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipcl_hash_walk_data_t *iw = wsp->walk_data;
2415d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2416d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_free(iw->conn, sizeof (conn_t));
2417d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_free(iw, sizeof (ipcl_hash_walk_data_t));
2418d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2419d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2420ffaa671aSsowmini /*
2421ffaa671aSsowmini  * Called with walk_addr being the address of ips_ndp{4,6}
2422ffaa671aSsowmini  */
2423ffaa671aSsowmini static int
ncec_stack_walk_init(mdb_walk_state_t * wsp)2424bd670b35SErik Nordmark ncec_stack_walk_init(mdb_walk_state_t *wsp)
2425ffaa671aSsowmini {
2426bd670b35SErik Nordmark 	ncec_walk_data_t *nw;
2427ffaa671aSsowmini 
2428892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
2429bd670b35SErik Nordmark 		mdb_warn("ncec_stack requires ndp_g_s address\n");
2430ffaa671aSsowmini 		return (WALK_ERR);
2431ffaa671aSsowmini 	}
2432ffaa671aSsowmini 
2433bd670b35SErik Nordmark 	nw = mdb_alloc(sizeof (ncec_walk_data_t), UM_SLEEP);
2434ffaa671aSsowmini 
2435bd670b35SErik Nordmark 	if (mdb_vread(&nw->ncec_ip_ndp, sizeof (struct ndp_g_s),
2436ffaa671aSsowmini 	    wsp->walk_addr) == -1) {
2437ffaa671aSsowmini 		mdb_warn("failed to read 'ip_ndp' at %p",
2438ffaa671aSsowmini 		    wsp->walk_addr);
2439bd670b35SErik Nordmark 		mdb_free(nw, sizeof (ncec_walk_data_t));
2440ffaa671aSsowmini 		return (WALK_ERR);
2441ffaa671aSsowmini 	}
2442ffaa671aSsowmini 
2443bd670b35SErik Nordmark 	/*
2444bd670b35SErik Nordmark 	 * ncec_get_next_hash_tbl() starts at ++i , so initialize index to -1
2445bd670b35SErik Nordmark 	 */
2446bd670b35SErik Nordmark 	nw->ncec_hash_tbl_index = -1;
2447892ad162SToomas Soome 	wsp->walk_addr = ncec_get_next_hash_tbl(0,
2448bd670b35SErik Nordmark 	    &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp);
2449ffaa671aSsowmini 	wsp->walk_data = nw;
2450ffaa671aSsowmini 
2451ffaa671aSsowmini 	return (WALK_NEXT);
2452ffaa671aSsowmini }
2453ffaa671aSsowmini 
2454ffaa671aSsowmini static int
ncec_stack_walk_step(mdb_walk_state_t * wsp)2455bd670b35SErik Nordmark ncec_stack_walk_step(mdb_walk_state_t *wsp)
2456ffaa671aSsowmini {
2457ffaa671aSsowmini 	uintptr_t addr = wsp->walk_addr;
2458bd670b35SErik Nordmark 	ncec_walk_data_t *nw = wsp->walk_data;
2459ffaa671aSsowmini 
2460892ad162SToomas Soome 	if (addr == 0)
2461ffaa671aSsowmini 		return (WALK_DONE);
2462ffaa671aSsowmini 
2463bd670b35SErik Nordmark 	if (mdb_vread(&nw->ncec, sizeof (ncec_t), addr) == -1) {
2464bd670b35SErik Nordmark 		mdb_warn("failed to read ncec_t at %p", addr);
2465ffaa671aSsowmini 		return (WALK_ERR);
2466ffaa671aSsowmini 	}
2467ffaa671aSsowmini 
2468bd670b35SErik Nordmark 	wsp->walk_addr = (uintptr_t)nw->ncec.ncec_next;
2469ffaa671aSsowmini 
2470bd670b35SErik Nordmark 	wsp->walk_addr = ncec_get_next_hash_tbl(wsp->walk_addr,
2471bd670b35SErik Nordmark 	    &nw->ncec_hash_tbl_index, nw->ncec_ip_ndp);
2472ffaa671aSsowmini 
2473ffaa671aSsowmini 	return (wsp->walk_callback(addr, nw, wsp->walk_cbdata));
2474ffaa671aSsowmini }
2475ffaa671aSsowmini 
2476ffaa671aSsowmini static void
ncec_stack_walk_fini(mdb_walk_state_t * wsp)2477bd670b35SErik Nordmark ncec_stack_walk_fini(mdb_walk_state_t *wsp)
2478ffaa671aSsowmini {
2479bd670b35SErik Nordmark 	mdb_free(wsp->walk_data, sizeof (ncec_walk_data_t));
2480ffaa671aSsowmini }
2481ffaa671aSsowmini 
2482ffaa671aSsowmini /* ARGSUSED */
2483ffaa671aSsowmini static int
ncec_cb(uintptr_t addr,const ncec_walk_data_t * iw,ncec_cbdata_t * id)2484bd670b35SErik Nordmark ncec_cb(uintptr_t addr, const ncec_walk_data_t *iw, ncec_cbdata_t *id)
2485ffaa671aSsowmini {
2486bd670b35SErik Nordmark 	ncec_t ncec;
2487ffaa671aSsowmini 
2488bd670b35SErik Nordmark 	if (mdb_vread(&ncec, sizeof (ncec_t), addr) == -1) {
2489bd670b35SErik Nordmark 		mdb_warn("failed to read ncec at %p", addr);
2490ffaa671aSsowmini 		return (WALK_NEXT);
2491ffaa671aSsowmini 	}
2492bd670b35SErik Nordmark 	(void) ncec_format(addr, &ncec, id->ncec_ipversion);
2493ffaa671aSsowmini 	return (WALK_NEXT);
2494ffaa671aSsowmini }
2495d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2496d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ill_walk_init(mdb_walk_state_t * wsp)2497d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill_walk_init(mdb_walk_state_t *wsp)
2498d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2499d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_layered_walk("illif", wsp) == -1) {
2500d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't walk 'illif'");
2501d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2502d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2503d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2504d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2505d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2506d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ill_walk_step(mdb_walk_state_t * wsp)2507d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill_walk_step(mdb_walk_state_t *wsp)
2508d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2509d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_if_t ill_if;
2510d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2511d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&ill_if, sizeof (ill_if_t), wsp->walk_addr) == -1) {
2512d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't read ill_if_t at %p", wsp->walk_addr);
2513d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2514d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2515d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	wsp->walk_addr = (uintptr_t)(wsp->walk_addr +
2516d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    offsetof(ill_if_t, illif_avl_by_ppa));
2517d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_pwalk("avl", wsp->walk_callback, wsp->walk_cbdata,
2518d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    wsp->walk_addr) == -1) {
2519d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't walk 'avl'");
2520d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2521d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2522d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2523d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2524d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2525d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2526d5b6ed4bSVasumathi Sundaram - Sun Microsystems /* ARGSUSED */
2527d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ill_cb(uintptr_t addr,const ill_walk_data_t * iw,ill_cbdata_t * id)2528d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill_cb(uintptr_t addr, const ill_walk_data_t *iw, ill_cbdata_t *id)
2529d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2530d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_t ill;
2531d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2532d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&ill, sizeof (ill_t), (uintptr_t)addr) == -1) {
2533d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read ill at %p", addr);
2534d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_NEXT);
2535d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2536bd670b35SErik Nordmark 
2537bd670b35SErik Nordmark 	/* If ip_stack_t is specified, skip ILLs that don't belong to it. */
2538bd670b35SErik Nordmark 	if (id->ill_ipst != NULL && ill.ill_ipst != id->ill_ipst)
2539bd670b35SErik Nordmark 		return (WALK_NEXT);
2540bd670b35SErik Nordmark 
2541d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (ill_format((uintptr_t)addr, &ill, id));
2542d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2543d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2544d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
ill_header(boolean_t verbose)2545d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill_header(boolean_t verbose)
2546d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2547d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (verbose) {
2548d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?s %-8s %3s %-10s %-?s %-?s %-10s%</u>\n",
2549d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "ADDR", "NAME", "VER", "TYPE", "WQ", "IPST", "FLAGS");
2550d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?s %4s%4s %-?s\n",
2551d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "PHYINT", "CNT", "", "GROUP");
2552d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%<u>%80s%</u>\n", "");
2553d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2554d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%<u>%-?s %-8s %-3s %-10s %4s %-?s %-10s%</u>\n",
2555d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "ADDR", "NAME", "VER", "TYPE", "CNT", "WQ", "FLAGS");
2556d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2557d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2558d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2559d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ill_format(uintptr_t addr,const void * illptr,void * ill_cb_arg)2560d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill_format(uintptr_t addr, const void *illptr, void *ill_cb_arg)
2561d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2562d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_t *ill = (ill_t *)illptr;
2563d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_cbdata_t *illcb = ill_cb_arg;
2564d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	boolean_t verbose = illcb->verbose;
2565d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	phyint_t phyi;
2566d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	static const mdb_bitmask_t fmasks[] = {
2567d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "R",		PHYI_RUNNING,		PHYI_RUNNING	},
2568d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "P",		PHYI_PROMISC,		PHYI_PROMISC	},
2569d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "V",		PHYI_VIRTUAL,		PHYI_VIRTUAL	},
2570d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "I",		PHYI_IPMP,		PHYI_IPMP	},
2571d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "f",		PHYI_FAILED,		PHYI_FAILED	},
2572d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "S",		PHYI_STANDBY,		PHYI_STANDBY	},
2573d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "i",		PHYI_INACTIVE,		PHYI_INACTIVE	},
2574d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "O",		PHYI_OFFLINE,		PHYI_OFFLINE	},
2575d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "T",		ILLF_NOTRAILERS,	ILLF_NOTRAILERS },
2576d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "A",		ILLF_NOARP,		ILLF_NOARP	},
2577d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "M",		ILLF_MULTICAST,		ILLF_MULTICAST	},
2578d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "F",		ILLF_ROUTER,		ILLF_ROUTER	},
2579d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "D",		ILLF_NONUD,		ILLF_NONUD	},
2580d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "X",		ILLF_NORTEXCH,		ILLF_NORTEXCH	},
2581d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ NULL,		0,			0		}
2582d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	};
2583d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	static const mdb_bitmask_t v_fmasks[] = {
2584d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "RUNNING",	PHYI_RUNNING,		PHYI_RUNNING	},
2585d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "PROMISC",	PHYI_PROMISC,		PHYI_PROMISC	},
2586d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "VIRTUAL",	PHYI_VIRTUAL,		PHYI_VIRTUAL	},
2587d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "IPMP",	PHYI_IPMP,		PHYI_IPMP	},
2588d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "FAILED",	PHYI_FAILED,		PHYI_FAILED	},
2589d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "STANDBY",	PHYI_STANDBY,		PHYI_STANDBY	},
2590d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "INACTIVE",	PHYI_INACTIVE,		PHYI_INACTIVE	},
2591d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "OFFLINE",	PHYI_OFFLINE,		PHYI_OFFLINE	},
2592d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NOTRAILER",	ILLF_NOTRAILERS,	ILLF_NOTRAILERS },
2593d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NOARP",	ILLF_NOARP,		ILLF_NOARP	},
2594d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "MULTICAST",	ILLF_MULTICAST,		ILLF_MULTICAST	},
2595d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "ROUTER",	ILLF_ROUTER,		ILLF_ROUTER	},
2596d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NONUD",	ILLF_NONUD,		ILLF_NONUD	},
2597d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NORTEXCH",	ILLF_NORTEXCH,		ILLF_NORTEXCH	},
2598d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ NULL,		0,			0		}
2599d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	};
2600d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char ill_name[LIFNAMSIZ];
2601d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int cnt;
2602d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char *typebuf;
2603d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char sbuf[DEFCOLS];
2604d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int ipver = illcb->ill_ipversion;
2605d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2606d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (ipver != 0) {
2607d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if ((ipver == IPV4_VERSION && ill->ill_isv6) ||
2608d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    (ipver == IPV6_VERSION && !ill->ill_isv6)) {
2609d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_NEXT);
2610d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2611d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2612d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&phyi, sizeof (phyint_t),
2613d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    (uintptr_t)ill->ill_phyint) == -1) {
2614d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read ill_phyint at %p",
2615d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    (uintptr_t)ill->ill_phyint);
2616d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_NEXT);
2617d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2618d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) mdb_readstr(ill_name, MIN(LIFNAMSIZ, ill->ill_name_length),
2619d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    (uintptr_t)ill->ill_name);
2620d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2621d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	switch (ill->ill_type) {
2622d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	case 0:
2623d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		typebuf = "LOOPBACK";
2624d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		break;
2625d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	case IFT_ETHER:
2626d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		typebuf = "ETHER";
2627d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		break;
2628d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	case IFT_OTHER:
2629d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		typebuf = "OTHER";
2630d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		break;
2631d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	default:
2632d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		typebuf = NULL;
2633d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		break;
2634d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2635d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	cnt = ill->ill_refcnt + ill->ill_ire_cnt + ill->ill_nce_cnt +
2636bd670b35SErik Nordmark 	    ill->ill_ilm_cnt + ill->ill_ncec_cnt;
2637d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%-?p %-8s %-3s ",
2638d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    addr, ill_name, ill->ill_isv6 ? "v6" : "v4");
2639d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (typebuf != NULL)
2640d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-10s ", typebuf);
2641d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	else
2642d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-10x ", ill->ill_type);
2643d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (verbose) {
2644d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?p %-?p %-llb\n",
2645d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    ill->ill_wq, ill->ill_ipst,
2646d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    ill->ill_flags | phyi.phyint_flags, v_fmasks);
2647d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?p %4d%4s %-?p\n",
2648d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    ill->ill_phyint, cnt, "", ill->ill_grp);
2649d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(sbuf, sizeof (sbuf), "%*s %3s",
2650d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sizeof (uintptr_t) * 2, "", "");
2651d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%s|\n%s+--> %3d %-18s "
2652d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "references from active threads\n",
2653d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sbuf, sbuf, ill->ill_refcnt, "ill_refcnt");
2654d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%*s %7d %-18s ires referencing this ill\n",
2655d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    strlen(sbuf), "", ill->ill_ire_cnt, "ill_ire_cnt");
2656d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%*s %7d %-18s nces referencing this ill\n",
2657d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    strlen(sbuf), "", ill->ill_nce_cnt, "ill_nce_cnt");
2658bd670b35SErik Nordmark 		mdb_printf("%*s %7d %-18s ncecs referencing this ill\n",
2659bd670b35SErik Nordmark 		    strlen(sbuf), "", ill->ill_ncec_cnt, "ill_ncec_cnt");
2660d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%*s %7d %-18s ilms referencing this ill\n",
2661d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    strlen(sbuf), "", ill->ill_ilm_cnt, "ill_ilm_cnt");
2662d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2663d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%4d %-?p %-llb\n",
2664d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    cnt, ill->ill_wq,
2665d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    ill->ill_flags | phyi.phyint_flags, fmasks);
2666d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2667d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2668d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2669d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2670d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ill(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2671d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2672d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2673d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_t ill_data;
2674d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_cbdata_t id;
2675d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int ipversion = 0;
2676bd670b35SErik Nordmark 	const char *zone_name = NULL;
2677d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	const char *opt_P = NULL;
2678d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uint_t verbose = FALSE;
2679bd670b35SErik Nordmark 	ip_stack_t *ipst = NULL;
2680d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2681d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_getopts(argc, argv,
2682d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
2683bd670b35SErik Nordmark 	    's', MDB_OPT_STR, &zone_name,
2684d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
2685d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (DCMD_USAGE);
2686d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2687bd670b35SErik Nordmark 	/* Follow the specified zone name to find a ip_stack_t*. */
2688bd670b35SErik Nordmark 	if (zone_name != NULL) {
2689bd670b35SErik Nordmark 		ipst = zone_to_ips(zone_name);
2690bd670b35SErik Nordmark 		if (ipst == NULL)
2691bd670b35SErik Nordmark 			return (DCMD_USAGE);
2692bd670b35SErik Nordmark 	}
2693bd670b35SErik Nordmark 
2694d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (opt_P != NULL) {
2695d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (strcmp("v4", opt_P) == 0) {
2696d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			ipversion = IPV4_VERSION;
2697d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		} else if (strcmp("v6", opt_P) == 0) {
2698d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			ipversion = IPV6_VERSION;
2699d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		} else {
2700d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("invalid protocol '%s'\n", opt_P);
2701d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_USAGE);
2702d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2703d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2704d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2705d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	id.verbose = verbose;
2706d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	id.ill_addr = addr;
2707d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	id.ill_ipversion = ipversion;
2708bd670b35SErik Nordmark 	id.ill_ipst = ipst;
2709d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2710d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ill_header(verbose);
2711d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (flags & DCMD_ADDRSPEC) {
2712d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_vread(&ill_data, sizeof (ill_t), addr) == -1) {
2713d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to read ill at %p\n", addr);
2714d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_ERR);
2715d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2716d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		(void) ill_format(addr, &ill_data, &id);
2717d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2718d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_walk("ill", (mdb_walk_cb_t)ill_cb, &id) == -1) {
2719d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to walk ills\n");
2720d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_ERR);
2721d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2722d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2723d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (DCMD_OK);
2724d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2725d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2726d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
ill_help(void)2727d5b6ed4bSVasumathi Sundaram - Sun Microsystems ill_help(void)
2728d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2729d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("Prints the following fields: ill ptr, name, "
2730d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "IP version, count, ill type and ill flags.\n"
2731d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "The count field is a sum of individual refcnts and is expanded "
2732d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "with the -v option.\n\n");
2733d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("Options:\n");
2734d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("\t-P v4 | v6"
2735d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\tfilter ill structures for the specified protocol\n");
2736d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2737d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2738d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ip_list_walk_init(mdb_walk_state_t * wsp)2739d5b6ed4bSVasumathi Sundaram - Sun Microsystems ip_list_walk_init(mdb_walk_state_t *wsp)
2740d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2741d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	const ip_list_walk_arg_t *arg = wsp->walk_arg;
2742d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ip_list_walk_data_t *iw;
2743d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t addr = (uintptr_t)(wsp->walk_addr + arg->off);
2744d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2745892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
2746d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("only local walks supported\n");
2747d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2748d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2749d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t),
2750d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    addr) == -1) {
2751d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read list head at %p", addr);
2752d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2753d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2754d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	iw = mdb_alloc(sizeof (ip_list_walk_data_t), UM_SLEEP);
2755d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	iw->nextoff = arg->nextp_off;
2756d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	wsp->walk_data = iw;
2757d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2758d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2759d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2760d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2761d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ip_list_walk_step(mdb_walk_state_t * wsp)2762d5b6ed4bSVasumathi Sundaram - Sun Microsystems ip_list_walk_step(mdb_walk_state_t *wsp)
2763d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2764d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ip_list_walk_data_t *iw = wsp->walk_data;
2765d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t addr = wsp->walk_addr;
2766d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2767892ad162SToomas Soome 	if (addr == 0)
2768d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_DONE);
2769d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	wsp->walk_addr = addr + iw->nextoff;
2770d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t),
2771d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    wsp->walk_addr) == -1) {
2772d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read list node at %p", addr);
2773d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2774d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2775d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (wsp->walk_callback(addr, iw, wsp->walk_cbdata));
2776d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2777d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2778d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
ip_list_walk_fini(mdb_walk_state_t * wsp)2779d5b6ed4bSVasumathi Sundaram - Sun Microsystems ip_list_walk_fini(mdb_walk_state_t *wsp)
2780d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2781d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_free(wsp->walk_data, sizeof (ip_list_walk_data_t));
2782d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2783d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2784d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipif_walk_init(mdb_walk_state_t * wsp)2785d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif_walk_init(mdb_walk_state_t *wsp)
2786d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2787d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_layered_walk("ill", wsp) == -1) {
2788d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't walk 'ills'");
2789d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2790d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2791d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2792d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2793d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2794d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipif_walk_step(mdb_walk_state_t * wsp)2795d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif_walk_step(mdb_walk_state_t *wsp)
2796d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2797d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_pwalk("ipif_list", wsp->walk_callback, wsp->walk_cbdata,
2798d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    wsp->walk_addr) == -1) {
2799d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't walk 'ipif_list'");
2800d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
2801d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2802d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2803d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2804d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2805d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2806d5b6ed4bSVasumathi Sundaram - Sun Microsystems /* ARGSUSED */
2807d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipif_cb(uintptr_t addr,const ipif_walk_data_t * iw,ipif_cbdata_t * id)2808d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif_cb(uintptr_t addr, const ipif_walk_data_t *iw, ipif_cbdata_t *id)
2809d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2810d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipif_t ipif;
2811d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2812d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&ipif, sizeof (ipif_t), (uintptr_t)addr) == -1) {
2813d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read ipif at %p", addr);
2814d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_NEXT);
2815d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2816d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&id->ill, sizeof (ill_t),
2817d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    (uintptr_t)ipif.ipif_ill) == -1) {
2818d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read ill at %p", ipif.ipif_ill);
2819d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_NEXT);
2820d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2821d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) ipif_format((uintptr_t)addr, &ipif, id);
2822d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2823d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2824d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2825d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
ipif_header(boolean_t verbose)2826d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif_header(boolean_t verbose)
2827d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2828d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (verbose) {
2829d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?s %-10s %-3s %-?s %-8s %-30s\n",
2830d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS");
2831d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%s\n%s\n",
2832d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "LCLADDR", "BROADCAST");
2833d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%<u>%80s%</u>\n", "");
2834d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2835d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?s %-10s %6s %-?s %-8s %-30s\n",
2836d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS");
2837d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%s\n%<u>%80s%</u>\n", "LCLADDR", "");
2838d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2839d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2840d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2841d5b6ed4bSVasumathi Sundaram - Sun Microsystems #ifdef _BIG_ENDIAN
2842d5b6ed4bSVasumathi Sundaram - Sun Microsystems #define	ip_ntohl_32(x)	((x) & 0xffffffff)
2843d5b6ed4bSVasumathi Sundaram - Sun Microsystems #else
2844d5b6ed4bSVasumathi Sundaram - Sun Microsystems #define	ip_ntohl_32(x)	(((uint32_t)(x) << 24) | \
2845d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			(((uint32_t)(x) << 8) & 0xff0000) | \
2846d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			(((uint32_t)(x) >> 8) & 0xff00) | \
2847d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			((uint32_t)(x)  >> 24))
2848d5b6ed4bSVasumathi Sundaram - Sun Microsystems #endif
2849d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2850d5b6ed4bSVasumathi Sundaram - Sun Microsystems int
mask_to_prefixlen(int af,const in6_addr_t * addr)2851d5b6ed4bSVasumathi Sundaram - Sun Microsystems mask_to_prefixlen(int af, const in6_addr_t *addr)
2852d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2853d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int len = 0;
2854d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int i;
2855d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uint_t mask = 0;
2856d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2857d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (af == AF_INET6) {
2858d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		for (i = 0; i < 4; i++) {
2859d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			if (addr->s6_addr32[i] == 0xffffffff) {
2860d5b6ed4bSVasumathi Sundaram - Sun Microsystems 				len += 32;
2861d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			} else {
2862d5b6ed4bSVasumathi Sundaram - Sun Microsystems 				mask = addr->s6_addr32[i];
2863d5b6ed4bSVasumathi Sundaram - Sun Microsystems 				break;
2864d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			}
2865d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2866d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2867d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mask = V4_PART_OF_V6((*addr));
2868d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2869d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mask > 0)
2870d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		len += (33 - mdb_ffs(ip_ntohl_32(mask)));
2871d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (len);
2872d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2873d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2874d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipif_format(uintptr_t addr,const void * ipifptr,void * ipif_cb_arg)2875d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif_format(uintptr_t addr, const void *ipifptr, void *ipif_cb_arg)
2876d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2877d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	const ipif_t *ipif = ipifptr;
2878d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipif_cbdata_t *ipifcb = ipif_cb_arg;
2879d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	boolean_t verbose = ipifcb->verbose;
2880d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char ill_name[LIFNAMSIZ];
2881d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char buf[LIFNAMSIZ];
2882d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int cnt;
2883d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	static const mdb_bitmask_t sfmasks[] = {
2884d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "CO",		IPIF_CONDEMNED,		IPIF_CONDEMNED},
2885d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "CH",		IPIF_CHANGING,		IPIF_CHANGING},
2886d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "SL",		IPIF_SET_LINKLOCAL,	IPIF_SET_LINKLOCAL},
2887d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ NULL,		0,			0		}
2888d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	};
2889d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	static const mdb_bitmask_t fmasks[] = {
2890d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "UP",		IPIF_UP,		IPIF_UP		},
2891d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "UNN",	IPIF_UNNUMBERED,	IPIF_UNNUMBERED},
2892d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "DHCP",	IPIF_DHCPRUNNING,	IPIF_DHCPRUNNING},
2893d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "PRIV",	IPIF_PRIVATE,		IPIF_PRIVATE},
2894d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NOXMT",	IPIF_NOXMIT,		IPIF_NOXMIT},
2895d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NOLCL",	IPIF_NOLOCAL,		IPIF_NOLOCAL},
2896d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "DEPR",	IPIF_DEPRECATED,	IPIF_DEPRECATED},
2897d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "PREF",	IPIF_PREFERRED,		IPIF_PREFERRED},
2898d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "TEMP",	IPIF_TEMPORARY,		IPIF_TEMPORARY},
2899d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "ACONF",	IPIF_ADDRCONF,		IPIF_ADDRCONF},
2900d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "ANY",	IPIF_ANYCAST,		IPIF_ANYCAST},
2901d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ "NFAIL",	IPIF_NOFAILOVER,	IPIF_NOFAILOVER},
2902d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		{ NULL,		0,			0		}
2903d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	};
2904d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char flagsbuf[2 * A_CNT(fmasks)];
2905d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char bitfields[A_CNT(fmasks)];
2906d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char sflagsbuf[A_CNT(sfmasks)];
2907d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char sbuf[DEFCOLS], addrstr[INET6_ADDRSTRLEN];
2908d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int ipver = ipifcb->ipif_ipversion;
2909d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int af;
2910d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2911d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (ipver != 0) {
2912d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if ((ipver == IPV4_VERSION && ipifcb->ill.ill_isv6) ||
2913d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    (ipver == IPV6_VERSION && !ipifcb->ill.ill_isv6)) {
2914d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_NEXT);
2915d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2916d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2917d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if ((mdb_readstr(ill_name, MIN(LIFNAMSIZ,
2918d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    ipifcb->ill.ill_name_length),
2919d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    (uintptr_t)ipifcb->ill.ill_name)) == -1) {
2920d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read ill_name of ill %p\n", ipifcb->ill);
2921d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_NEXT);
2922d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2923d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (ipif->ipif_id != 0) {
2924d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(buf, LIFNAMSIZ, "%s:%d",
2925d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    ill_name, ipif->ipif_id);
2926d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2927d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(buf, LIFNAMSIZ, "%s", ill_name);
2928d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2929d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_snprintf(bitfields, sizeof (bitfields), "%s",
2930d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    ipif->ipif_addr_ready ? ",ADR" : "",
2931d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    ipif->ipif_was_up ? ",WU" : "",
2932bd670b35SErik Nordmark 	    ipif->ipif_was_dup ? ",WD" : "");
2933d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_snprintf(flagsbuf, sizeof (flagsbuf), "%llb%s",
2934d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    ipif->ipif_flags, fmasks, bitfields);
2935d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_snprintf(sflagsbuf, sizeof (sflagsbuf), "%b",
2936d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    ipif->ipif_state_flags, sfmasks);
2937d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2938bd670b35SErik Nordmark 	cnt = ipif->ipif_refcnt;
2939d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2940d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (ipifcb->ill.ill_isv6) {
2941d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(addrstr, sizeof (addrstr), "%N",
2942d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    &ipif->ipif_v6lcl_addr);
2943d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		af = AF_INET6;
2944d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2945d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(addrstr, sizeof (addrstr), "%I",
2946d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    V4_PART_OF_V6((ipif->ipif_v6lcl_addr)));
2947d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		af = AF_INET;
2948d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2949d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2950d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (verbose) {
2951d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?p %-10s %3d %-?p %-8s %-30s\n",
2952d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    addr, buf, cnt, ipif->ipif_ill,
2953d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sflagsbuf, flagsbuf);
2954d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(sbuf, sizeof (sbuf), "%*s %12s",
2955d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sizeof (uintptr_t) * 2, "", "");
2956d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%s |\n%s +---> %4d %-15s "
2957d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    "Active consistent reader cnt\n",
2958d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sbuf, sbuf, ipif->ipif_refcnt, "ipif_refcnt");
2959d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-s/%d\n",
2960d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask));
2961d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (ipifcb->ill.ill_isv6) {
2962d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_printf("%-N\n", &ipif->ipif_v6brd_addr);
2963d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		} else {
2964d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_printf("%-I\n",
2965d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			    V4_PART_OF_V6((ipif->ipif_v6brd_addr)));
2966d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
2967d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
2968d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-?p %-10s %6d %-?p %-8s %-30s\n",
2969d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    addr, buf, cnt, ipif->ipif_ill,
2970d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    sflagsbuf, flagsbuf);
2971d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_printf("%-s/%d\n",
2972d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    addrstr, mask_to_prefixlen(af, &ipif->ipif_v6net_mask));
2973d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
2974d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2975d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
2976d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
2977d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2978d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
ipif(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2979d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2980d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
2981d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipif_t ipif;
2982d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	ipif_cbdata_t id;
2983d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	int ipversion = 0;
2984d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	const char *opt_P = NULL;
2985d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uint_t verbose = FALSE;
2986d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2987d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_getopts(argc, argv,
2988d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
2989d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    'P', MDB_OPT_STR, &opt_P, NULL) != argc)
2990d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (DCMD_USAGE);
2991d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
2992d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (opt_P != NULL) {
2993d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (strcmp("v4", opt_P) == 0) {
2994d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			ipversion = IPV4_VERSION;
2995d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		} else if (strcmp("v6", opt_P) == 0) {
2996d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			ipversion = IPV6_VERSION;
2997d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		} else {
2998d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("invalid protocol '%s'\n", opt_P);
2999d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_USAGE);
3000d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
3001d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3002d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3003d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	id.verbose = verbose;
3004d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	id.ipif_ipversion = ipversion;
3005d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3006d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (flags & DCMD_ADDRSPEC) {
3007d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_vread(&ipif, sizeof (ipif_t), addr) == -1) {
3008d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to read ipif at %p\n", addr);
3009d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_ERR);
3010d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
3011d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipif_header(verbose);
3012d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_vread(&id.ill, sizeof (ill_t),
3013d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    (uintptr_t)ipif.ipif_ill) == -1) {
3014d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to read ill at %p", ipif.ipif_ill);
3015d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (WALK_NEXT);
3016d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
3017d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (ipif_format(addr, &ipif, &id));
3018d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
3019d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		ipif_header(verbose);
3020d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_walk("ipif", (mdb_walk_cb_t)ipif_cb, &id) == -1) {
3021d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to walk ipifs\n");
3022d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_ERR);
3023d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
3024d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3025d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (DCMD_OK);
3026d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3027d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3028d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
ipif_help(void)3029d5b6ed4bSVasumathi Sundaram - Sun Microsystems ipif_help(void)
3030d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3031d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("Prints the following fields: ipif ptr, name, "
3032d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "count, ill ptr, state flags and ipif flags.\n"
3033d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "The count field is a sum of individual refcnts and is expanded "
3034d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "with the -v option.\n"
3035d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "The flags field shows the following:"
3036d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tUNN -> UNNUMBERED, DHCP -> DHCPRUNNING, PRIV -> PRIVATE, "
3037d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tNOXMT -> NOXMIT, NOLCL -> NOLOCAL, DEPR -> DEPRECATED, "
3038d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tPREF -> PREFERRED, TEMP -> TEMPORARY, ACONF -> ADDRCONF, "
3039d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tANY -> ANYCAST, NFAIL -> NOFAILOVER, "
3040d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tADR -> ipif_addr_ready, MU -> ipif_multicast_up, "
3041d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tWU -> ipif_was_up, WD -> ipif_was_dup, "
3042d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "JA -> ipif_joined_allhosts.\n\n");
3043d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("Options:\n");
3044d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("\t-P v4 | v6"
3045d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\tfilter ipif structures on ills for the specified protocol\n");
3046d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3047d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3048d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
conn_status_walk_fanout(uintptr_t addr,mdb_walk_state_t * wsp,const char * walkname)3049d5b6ed4bSVasumathi Sundaram - Sun Microsystems conn_status_walk_fanout(uintptr_t addr, mdb_walk_state_t *wsp,
3050d5b6ed4bSVasumathi Sundaram - Sun Microsystems     const char *walkname)
3051d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3052d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_pwalk(walkname, wsp->walk_callback, wsp->walk_cbdata,
3053d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    addr) == -1) {
3054d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("couldn't walk '%s' at %p", walkname, addr);
3055d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
3056d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3057d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
3058d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3059d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3060d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
conn_status_walk_step(mdb_walk_state_t * wsp)3061d5b6ed4bSVasumathi Sundaram - Sun Microsystems conn_status_walk_step(mdb_walk_state_t *wsp)
3062d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3063d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	uintptr_t addr = wsp->walk_addr;
3064d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3065d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) conn_status_walk_fanout(addr, wsp, "udp_hash");
3066d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) conn_status_walk_fanout(addr, wsp, "conn_hash");
3067d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) conn_status_walk_fanout(addr, wsp, "bind_hash");
3068d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) conn_status_walk_fanout(addr, wsp, "proto_hash");
3069d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	(void) conn_status_walk_fanout(addr, wsp, "proto_v6_hash");
3070d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
3071d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3072d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3073d5b6ed4bSVasumathi Sundaram - Sun Microsystems /* ARGSUSED */
3074d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
conn_status_cb(uintptr_t addr,const void * walk_data,void * private)307571b76ee3SYuri Pankov conn_status_cb(uintptr_t addr, const void *walk_data, void *private)
3076d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3077d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	netstack_t nss;
3078d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char src_addrstr[INET6_ADDRSTRLEN];
3079d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	char rem_addrstr[INET6_ADDRSTRLEN];
3080d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	const ipcl_hash_walk_data_t *iw = walk_data;
3081f6eb544aSAndy Fiddaman 	conn_t c, *conn = &c;
308271b76ee3SYuri Pankov 	in_port_t lport, fport;
3083d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3084f6eb544aSAndy Fiddaman 	if (iw != NULL)
3085f6eb544aSAndy Fiddaman 		conn = iw->conn;
3086f6eb544aSAndy Fiddaman 	else if (mdb_vread(conn, sizeof (conn_t), addr) == -1) {
3087d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read conn_t at %p", addr);
3088d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
3089d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3090d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&nss, sizeof (nss),
3091d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    (uintptr_t)conn->conn_netstack) == -1) {
3092d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read netstack_t %p",
3093d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    conn->conn_netstack);
3094d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
3095d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3096d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%-?p %-?p %?d %?d\n", addr, conn->conn_wq,
3097d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    nss.netstack_stackid, conn->conn_zoneid);
3098d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3099bd670b35SErik Nordmark 	if (conn->conn_family == AF_INET6) {
3100d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(src_addrstr, sizeof (rem_addrstr), "%N",
3101bd670b35SErik Nordmark 		    &conn->conn_laddr_v6);
3102d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%N",
3103bd670b35SErik Nordmark 		    &conn->conn_faddr_v6);
3104d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
3105d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(src_addrstr, sizeof (src_addrstr), "%I",
3106bd670b35SErik Nordmark 		    V4_PART_OF_V6((conn->conn_laddr_v6)));
3107d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_snprintf(rem_addrstr, sizeof (rem_addrstr), "%I",
3108bd670b35SErik Nordmark 		    V4_PART_OF_V6((conn->conn_faddr_v6)));
3109d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
311071b76ee3SYuri Pankov 	mdb_nhconvert(&lport, &conn->conn_lport, sizeof (lport));
311171b76ee3SYuri Pankov 	mdb_nhconvert(&fport, &conn->conn_fport, sizeof (fport));
3112d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%s:%-5d\n%s:%-5d\n",
311371b76ee3SYuri Pankov 	    src_addrstr, lport, rem_addrstr, fport);
3114d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
3115d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3116d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3117d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
conn_header(void)3118d5b6ed4bSVasumathi Sundaram - Sun Microsystems conn_header(void)
3119d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3120d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%-?s %-?s %?s %?s\n%s\n%s\n",
3121d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "ADDR", "WQ", "STACK", "ZONE", "SRC:PORT", "DEST:PORT");
3122d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%<u>%80s%</u>\n", "");
3123d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3124d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3125d5b6ed4bSVasumathi Sundaram - Sun Microsystems /*ARGSUSED*/
3126d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
conn_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3127d5b6ed4bSVasumathi Sundaram - Sun Microsystems conn_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3128d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3129d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	conn_header();
3130d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (flags & DCMD_ADDRSPEC) {
3131d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		(void) conn_status_cb(addr, NULL, NULL);
3132d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
3133d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_walk("conn_status", (mdb_walk_cb_t)conn_status_cb,
3134d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    NULL) == -1) {
3135d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to walk conn_fanout");
3136d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_ERR);
3137d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
3138d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3139d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (DCMD_OK);
3140d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3141d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3142d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
conn_status_help(void)3143d5b6ed4bSVasumathi Sundaram - Sun Microsystems conn_status_help(void)
3144d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3145d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("Prints conn_t structures from the following hash tables: "
3146d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tips_ipcl_udp_fanout\n\tips_ipcl_bind_fanout"
3147bd670b35SErik Nordmark 	    "\n\tips_ipcl_conn_fanout\n\tips_ipcl_proto_fanout_v4"
3148d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "\n\tips_ipcl_proto_fanout_v6\n");
3149d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3150d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3151d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
srcid_walk_step(mdb_walk_state_t * wsp)3152d5b6ed4bSVasumathi Sundaram - Sun Microsystems srcid_walk_step(mdb_walk_state_t *wsp)
3153d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3154d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_pwalk("srcid_list", wsp->walk_callback, wsp->walk_cbdata,
3155d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    wsp->walk_addr) == -1) {
3156d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("can't walk 'srcid_list'");
3157d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
3158d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3159d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
3160d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3161d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3162d5b6ed4bSVasumathi Sundaram - Sun Microsystems /* ARGSUSED */
3163d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
srcid_status_cb(uintptr_t addr,const void * walk_data,void * private)3164d5b6ed4bSVasumathi Sundaram - Sun Microsystems srcid_status_cb(uintptr_t addr, const void *walk_data,
3165d5b6ed4bSVasumathi Sundaram - Sun Microsystems     void *private)
3166d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3167d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	srcid_map_t smp;
3168d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3169d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (mdb_vread(&smp, sizeof (srcid_map_t), addr) == -1) {
3170d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		mdb_warn("failed to read srcid_map at %p", addr);
3171d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		return (WALK_ERR);
3172d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3173d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%-?p %3d %4d %6d %N\n",
3174d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    addr, smp.sm_srcid, smp.sm_zoneid, smp.sm_refcnt,
3175d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    &smp.sm_addr);
3176d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (WALK_NEXT);
3177d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3178d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3179d5b6ed4bSVasumathi Sundaram - Sun Microsystems static void
srcid_header(void)3180d5b6ed4bSVasumathi Sundaram - Sun Microsystems srcid_header(void)
3181d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3182d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%-?s %3s %4s %6s %s\n",
3183d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	    "ADDR", "ID", "ZONE", "REFCNT", "IPADDR");
3184d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	mdb_printf("%<u>%80s%</u>\n", "");
3185d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3186d5b6ed4bSVasumathi Sundaram - Sun Microsystems 
3187d5b6ed4bSVasumathi Sundaram - Sun Microsystems /*ARGSUSED*/
3188d5b6ed4bSVasumathi Sundaram - Sun Microsystems static int
srcid_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3189d5b6ed4bSVasumathi Sundaram - Sun Microsystems srcid_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3190d5b6ed4bSVasumathi Sundaram - Sun Microsystems {
3191d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	srcid_header();
3192d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	if (flags & DCMD_ADDRSPEC) {
3193d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		(void) srcid_status_cb(addr, NULL, NULL);
3194d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	} else {
3195d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		if (mdb_walk("srcid", (mdb_walk_cb_t)srcid_status_cb,
3196d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		    NULL) == -1) {
3197d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			mdb_warn("failed to walk srcid_map");
3198d5b6ed4bSVasumathi Sundaram - Sun Microsystems 			return (DCMD_ERR);
3199d5b6ed4bSVasumathi Sundaram - Sun Microsystems 		}
3200d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	}
3201d5b6ed4bSVasumathi Sundaram - Sun Microsystems 	return (DCMD_OK);
3202d5b6ed4bSVasumathi Sundaram - Sun Microsystems }
3203dbed73cbSSangeeta Misra 
3204dbed73cbSSangeeta Misra static int
ilb_stacks_walk_step(mdb_walk_state_t * wsp)3205dbed73cbSSangeeta Misra ilb_stacks_walk_step(mdb_walk_state_t *wsp)
3206dbed73cbSSangeeta Misra {
3207721fffe3SKacheong Poon 	return (ns_walk_step(wsp, NS_ILB));
3208dbed73cbSSangeeta Misra }
3209dbed73cbSSangeeta Misra 
3210dbed73cbSSangeeta Misra static int
ilb_rules_walk_init(mdb_walk_state_t * wsp)3211dbed73cbSSangeeta Misra ilb_rules_walk_init(mdb_walk_state_t *wsp)
3212dbed73cbSSangeeta Misra {
3213dbed73cbSSangeeta Misra 	ilb_stack_t ilbs;
3214dbed73cbSSangeeta Misra 
3215892ad162SToomas Soome 	if (wsp->walk_addr == 0)
3216dbed73cbSSangeeta Misra 		return (WALK_ERR);
3217dbed73cbSSangeeta Misra 
3218dbed73cbSSangeeta Misra 	if (mdb_vread(&ilbs, sizeof (ilbs), wsp->walk_addr) == -1) {
3219dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
3220dbed73cbSSangeeta Misra 		return (WALK_ERR);
3221dbed73cbSSangeeta Misra 	}
3222892ad162SToomas Soome 	if ((wsp->walk_addr = (uintptr_t)ilbs.ilbs_rule_head) != 0)
3223dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3224dbed73cbSSangeeta Misra 	else
3225dbed73cbSSangeeta Misra 		return (WALK_DONE);
3226dbed73cbSSangeeta Misra }
3227dbed73cbSSangeeta Misra 
3228dbed73cbSSangeeta Misra static int
ilb_rules_walk_step(mdb_walk_state_t * wsp)3229dbed73cbSSangeeta Misra ilb_rules_walk_step(mdb_walk_state_t *wsp)
3230dbed73cbSSangeeta Misra {
3231dbed73cbSSangeeta Misra 	ilb_rule_t rule;
3232dbed73cbSSangeeta Misra 	int status;
3233dbed73cbSSangeeta Misra 
3234dbed73cbSSangeeta Misra 	if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) {
3235dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr);
3236dbed73cbSSangeeta Misra 		return (WALK_ERR);
3237dbed73cbSSangeeta Misra 	}
3238dbed73cbSSangeeta Misra 	status = wsp->walk_callback(wsp->walk_addr, &rule, wsp->walk_cbdata);
3239dbed73cbSSangeeta Misra 	if (status != WALK_NEXT)
3240dbed73cbSSangeeta Misra 		return (status);
3241892ad162SToomas Soome 	if ((wsp->walk_addr = (uintptr_t)rule.ir_next) == 0)
3242dbed73cbSSangeeta Misra 		return (WALK_DONE);
3243dbed73cbSSangeeta Misra 	else
3244dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3245dbed73cbSSangeeta Misra }
3246dbed73cbSSangeeta Misra 
3247dbed73cbSSangeeta Misra static int
ilb_servers_walk_init(mdb_walk_state_t * wsp)3248dbed73cbSSangeeta Misra ilb_servers_walk_init(mdb_walk_state_t *wsp)
3249dbed73cbSSangeeta Misra {
3250dbed73cbSSangeeta Misra 	ilb_rule_t rule;
3251dbed73cbSSangeeta Misra 
3252892ad162SToomas Soome 	if (wsp->walk_addr == 0)
3253dbed73cbSSangeeta Misra 		return (WALK_ERR);
3254dbed73cbSSangeeta Misra 
3255dbed73cbSSangeeta Misra 	if (mdb_vread(&rule, sizeof (rule), wsp->walk_addr) == -1) {
3256dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_rule_t at %p", wsp->walk_addr);
3257dbed73cbSSangeeta Misra 		return (WALK_ERR);
3258dbed73cbSSangeeta Misra 	}
3259892ad162SToomas Soome 	if ((wsp->walk_addr = (uintptr_t)rule.ir_servers) != 0)
3260dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3261dbed73cbSSangeeta Misra 	else
3262dbed73cbSSangeeta Misra 		return (WALK_DONE);
3263dbed73cbSSangeeta Misra }
3264dbed73cbSSangeeta Misra 
3265dbed73cbSSangeeta Misra static int
ilb_servers_walk_step(mdb_walk_state_t * wsp)3266dbed73cbSSangeeta Misra ilb_servers_walk_step(mdb_walk_state_t *wsp)
3267dbed73cbSSangeeta Misra {
3268dbed73cbSSangeeta Misra 	ilb_server_t server;
3269dbed73cbSSangeeta Misra 	int status;
3270dbed73cbSSangeeta Misra 
3271dbed73cbSSangeeta Misra 	if (mdb_vread(&server, sizeof (server), wsp->walk_addr) == -1) {
3272dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_server_t at %p", wsp->walk_addr);
3273dbed73cbSSangeeta Misra 		return (WALK_ERR);
3274dbed73cbSSangeeta Misra 	}
3275dbed73cbSSangeeta Misra 	status = wsp->walk_callback(wsp->walk_addr, &server, wsp->walk_cbdata);
3276dbed73cbSSangeeta Misra 	if (status != WALK_NEXT)
3277dbed73cbSSangeeta Misra 		return (status);
3278892ad162SToomas Soome 	if ((wsp->walk_addr = (uintptr_t)server.iser_next) == 0)
3279dbed73cbSSangeeta Misra 		return (WALK_DONE);
3280dbed73cbSSangeeta Misra 	else
3281dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3282dbed73cbSSangeeta Misra }
3283dbed73cbSSangeeta Misra 
3284dbed73cbSSangeeta Misra /*
3285dbed73cbSSangeeta Misra  * Helper structure for ilb_nat_src walker.  It stores the current index of the
3286dbed73cbSSangeeta Misra  * nat src table.
3287dbed73cbSSangeeta Misra  */
3288dbed73cbSSangeeta Misra typedef struct {
3289dbed73cbSSangeeta Misra 	ilb_stack_t ilbs;
3290dbed73cbSSangeeta Misra 	int idx;
3291dbed73cbSSangeeta Misra } ilb_walk_t;
3292dbed73cbSSangeeta Misra 
3293dbed73cbSSangeeta Misra /* Copy from list.c */
3294dbed73cbSSangeeta Misra #define	list_object(a, node)	((void *)(((char *)node) - (a)->list_offset))
3295dbed73cbSSangeeta Misra 
3296dbed73cbSSangeeta Misra static int
ilb_nat_src_walk_init(mdb_walk_state_t * wsp)3297dbed73cbSSangeeta Misra ilb_nat_src_walk_init(mdb_walk_state_t *wsp)
3298dbed73cbSSangeeta Misra {
3299dbed73cbSSangeeta Misra 	int i;
3300dbed73cbSSangeeta Misra 	ilb_walk_t *ns_walk;
3301dbed73cbSSangeeta Misra 	ilb_nat_src_entry_t *entry = NULL;
3302dbed73cbSSangeeta Misra 
3303892ad162SToomas Soome 	if (wsp->walk_addr == 0)
3304dbed73cbSSangeeta Misra 		return (WALK_ERR);
3305dbed73cbSSangeeta Misra 
3306dbed73cbSSangeeta Misra 	ns_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP);
3307dbed73cbSSangeeta Misra 	if (mdb_vread(&ns_walk->ilbs, sizeof (ns_walk->ilbs),
3308dbed73cbSSangeeta Misra 	    wsp->walk_addr) == -1) {
3309dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
3310dbed73cbSSangeeta Misra 		mdb_free(ns_walk, sizeof (ilb_walk_t));
3311dbed73cbSSangeeta Misra 		return (WALK_ERR);
3312dbed73cbSSangeeta Misra 	}
3313dbed73cbSSangeeta Misra 
3314dbed73cbSSangeeta Misra 	if (ns_walk->ilbs.ilbs_nat_src == NULL) {
3315dbed73cbSSangeeta Misra 		mdb_free(ns_walk, sizeof (ilb_walk_t));
3316dbed73cbSSangeeta Misra 		return (WALK_DONE);
3317dbed73cbSSangeeta Misra 	}
3318dbed73cbSSangeeta Misra 
3319dbed73cbSSangeeta Misra 	wsp->walk_data = ns_walk;
3320dbed73cbSSangeeta Misra 	for (i = 0; i < ns_walk->ilbs.ilbs_nat_src_hash_size; i++) {
3321dbed73cbSSangeeta Misra 		list_t head;
3322dbed73cbSSangeeta Misra 		char  *khead;
3323dbed73cbSSangeeta Misra 
3324dbed73cbSSangeeta Misra 		/* Read in the nsh_head in the i-th element of the array. */
3325dbed73cbSSangeeta Misra 		khead = (char *)ns_walk->ilbs.ilbs_nat_src + i *
3326dbed73cbSSangeeta Misra 		    sizeof (ilb_nat_src_hash_t);
3327dbed73cbSSangeeta Misra 		if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
3328dbed73cbSSangeeta Misra 			mdb_warn("failed to read ilbs_nat_src at %p\n", khead);
3329dbed73cbSSangeeta Misra 			return (WALK_ERR);
3330dbed73cbSSangeeta Misra 		}
3331dbed73cbSSangeeta Misra 
3332dbed73cbSSangeeta Misra 		/*
3333dbed73cbSSangeeta Misra 		 * Note that list_next points to a kernel address and we need
3334dbed73cbSSangeeta Misra 		 * to compare list_next with the kernel address of the list
3335dbed73cbSSangeeta Misra 		 * head.  So we need to calculate the address manually.
3336dbed73cbSSangeeta Misra 		 */
3337dbed73cbSSangeeta Misra 		if ((char *)head.list_head.list_next != khead +
3338dbed73cbSSangeeta Misra 		    offsetof(list_t, list_head)) {
3339dbed73cbSSangeeta Misra 			entry = list_object(&head, head.list_head.list_next);
3340dbed73cbSSangeeta Misra 			break;
3341dbed73cbSSangeeta Misra 		}
3342dbed73cbSSangeeta Misra 	}
3343dbed73cbSSangeeta Misra 
3344dbed73cbSSangeeta Misra 	if (entry == NULL)
3345dbed73cbSSangeeta Misra 		return (WALK_DONE);
3346dbed73cbSSangeeta Misra 
3347dbed73cbSSangeeta Misra 	wsp->walk_addr = (uintptr_t)entry;
3348dbed73cbSSangeeta Misra 	ns_walk->idx = i;
3349dbed73cbSSangeeta Misra 	return (WALK_NEXT);
3350dbed73cbSSangeeta Misra }
3351dbed73cbSSangeeta Misra 
3352dbed73cbSSangeeta Misra static int
ilb_nat_src_walk_step(mdb_walk_state_t * wsp)3353dbed73cbSSangeeta Misra ilb_nat_src_walk_step(mdb_walk_state_t *wsp)
3354dbed73cbSSangeeta Misra {
3355dbed73cbSSangeeta Misra 	int status;
3356dbed73cbSSangeeta Misra 	ilb_nat_src_entry_t entry, *next_entry;
3357dbed73cbSSangeeta Misra 	ilb_walk_t *ns_walk;
3358dbed73cbSSangeeta Misra 	ilb_stack_t *ilbs;
3359dbed73cbSSangeeta Misra 	list_t head;
3360dbed73cbSSangeeta Misra 	char *khead;
3361dbed73cbSSangeeta Misra 	int i;
3362dbed73cbSSangeeta Misra 
3363dbed73cbSSangeeta Misra 	if (mdb_vread(&entry, sizeof (ilb_nat_src_entry_t),
3364dbed73cbSSangeeta Misra 	    wsp->walk_addr) == -1) {
3365dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_nat_src_entry_t at %p",
3366dbed73cbSSangeeta Misra 		    wsp->walk_addr);
3367dbed73cbSSangeeta Misra 		return (WALK_ERR);
3368dbed73cbSSangeeta Misra 	}
3369dbed73cbSSangeeta Misra 	status = wsp->walk_callback(wsp->walk_addr, &entry, wsp->walk_cbdata);
3370dbed73cbSSangeeta Misra 	if (status != WALK_NEXT)
3371dbed73cbSSangeeta Misra 		return (status);
3372dbed73cbSSangeeta Misra 
3373dbed73cbSSangeeta Misra 	ns_walk = (ilb_walk_t *)wsp->walk_data;
3374dbed73cbSSangeeta Misra 	ilbs = &ns_walk->ilbs;
3375dbed73cbSSangeeta Misra 	i = ns_walk->idx;
3376dbed73cbSSangeeta Misra 
3377dbed73cbSSangeeta Misra 	/* Read in the nsh_head in the i-th element of the array. */
3378dbed73cbSSangeeta Misra 	khead = (char *)ilbs->ilbs_nat_src + i * sizeof (ilb_nat_src_hash_t);
3379dbed73cbSSangeeta Misra 	if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
3380dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilbs_nat_src at %p\n", khead);
3381dbed73cbSSangeeta Misra 		return (WALK_ERR);
3382dbed73cbSSangeeta Misra 	}
3383dbed73cbSSangeeta Misra 
3384dbed73cbSSangeeta Misra 	/*
3385dbed73cbSSangeeta Misra 	 * Check if there is still entry in the current list.
3386dbed73cbSSangeeta Misra 	 *
3387dbed73cbSSangeeta Misra 	 * Note that list_next points to a kernel address and we need to
3388dbed73cbSSangeeta Misra 	 * compare list_next with the kernel address of the list head.
3389dbed73cbSSangeeta Misra 	 * So we need to calculate the address manually.
3390dbed73cbSSangeeta Misra 	 */
3391dbed73cbSSangeeta Misra 	if ((char *)entry.nse_link.list_next != khead + offsetof(list_t,
3392dbed73cbSSangeeta Misra 	    list_head)) {
3393dbed73cbSSangeeta Misra 		wsp->walk_addr = (uintptr_t)list_object(&head,
3394dbed73cbSSangeeta Misra 		    entry.nse_link.list_next);
3395dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3396dbed73cbSSangeeta Misra 	}
3397dbed73cbSSangeeta Misra 
3398dbed73cbSSangeeta Misra 	/* Start with the next bucket in the array. */
3399dbed73cbSSangeeta Misra 	next_entry = NULL;
3400dbed73cbSSangeeta Misra 	for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) {
3401dbed73cbSSangeeta Misra 		khead = (char *)ilbs->ilbs_nat_src + i *
3402dbed73cbSSangeeta Misra 		    sizeof (ilb_nat_src_hash_t);
3403dbed73cbSSangeeta Misra 		if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
3404dbed73cbSSangeeta Misra 			mdb_warn("failed to read ilbs_nat_src at %p\n", khead);
3405dbed73cbSSangeeta Misra 			return (WALK_ERR);
3406dbed73cbSSangeeta Misra 		}
3407dbed73cbSSangeeta Misra 
3408dbed73cbSSangeeta Misra 		if ((char *)head.list_head.list_next != khead +
3409dbed73cbSSangeeta Misra 		    offsetof(list_t, list_head)) {
3410dbed73cbSSangeeta Misra 			next_entry = list_object(&head,
3411dbed73cbSSangeeta Misra 			    head.list_head.list_next);
3412dbed73cbSSangeeta Misra 			break;
3413dbed73cbSSangeeta Misra 		}
3414dbed73cbSSangeeta Misra 	}
3415dbed73cbSSangeeta Misra 
3416dbed73cbSSangeeta Misra 	if (next_entry == NULL)
3417dbed73cbSSangeeta Misra 		return (WALK_DONE);
3418dbed73cbSSangeeta Misra 
3419dbed73cbSSangeeta Misra 	wsp->walk_addr = (uintptr_t)next_entry;
3420dbed73cbSSangeeta Misra 	ns_walk->idx = i;
3421dbed73cbSSangeeta Misra 	return (WALK_NEXT);
3422dbed73cbSSangeeta Misra }
3423dbed73cbSSangeeta Misra 
3424dbed73cbSSangeeta Misra static void
ilb_common_walk_fini(mdb_walk_state_t * wsp)3425dbed73cbSSangeeta Misra ilb_common_walk_fini(mdb_walk_state_t *wsp)
3426dbed73cbSSangeeta Misra {
3427dbed73cbSSangeeta Misra 	ilb_walk_t *walk;
3428dbed73cbSSangeeta Misra 
3429dbed73cbSSangeeta Misra 	walk = (ilb_walk_t *)wsp->walk_data;
3430dbed73cbSSangeeta Misra 	if (walk == NULL)
3431dbed73cbSSangeeta Misra 		return;
3432dbed73cbSSangeeta Misra 	mdb_free(walk, sizeof (ilb_walk_t *));
3433dbed73cbSSangeeta Misra }
3434dbed73cbSSangeeta Misra 
3435dbed73cbSSangeeta Misra static int
ilb_conn_walk_init(mdb_walk_state_t * wsp)3436dbed73cbSSangeeta Misra ilb_conn_walk_init(mdb_walk_state_t *wsp)
3437dbed73cbSSangeeta Misra {
3438dbed73cbSSangeeta Misra 	int i;
3439dbed73cbSSangeeta Misra 	ilb_walk_t *conn_walk;
3440dbed73cbSSangeeta Misra 	ilb_conn_hash_t head;
3441dbed73cbSSangeeta Misra 
3442892ad162SToomas Soome 	if (wsp->walk_addr == 0)
3443dbed73cbSSangeeta Misra 		return (WALK_ERR);
3444dbed73cbSSangeeta Misra 
3445dbed73cbSSangeeta Misra 	conn_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP);
3446dbed73cbSSangeeta Misra 	if (mdb_vread(&conn_walk->ilbs, sizeof (conn_walk->ilbs),
3447dbed73cbSSangeeta Misra 	    wsp->walk_addr) == -1) {
3448dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
3449dbed73cbSSangeeta Misra 		mdb_free(conn_walk, sizeof (ilb_walk_t));
3450dbed73cbSSangeeta Misra 		return (WALK_ERR);
3451dbed73cbSSangeeta Misra 	}
3452dbed73cbSSangeeta Misra 
3453dbed73cbSSangeeta Misra 	if (conn_walk->ilbs.ilbs_c2s_conn_hash == NULL) {
3454dbed73cbSSangeeta Misra 		mdb_free(conn_walk, sizeof (ilb_walk_t));
3455dbed73cbSSangeeta Misra 		return (WALK_DONE);
3456dbed73cbSSangeeta Misra 	}
3457dbed73cbSSangeeta Misra 
3458dbed73cbSSangeeta Misra 	wsp->walk_data = conn_walk;
3459dbed73cbSSangeeta Misra 	for (i = 0; i < conn_walk->ilbs.ilbs_conn_hash_size; i++) {
3460dbed73cbSSangeeta Misra 		char *khead;
3461dbed73cbSSangeeta Misra 
3462dbed73cbSSangeeta Misra 		/* Read in the nsh_head in the i-th element of the array. */
3463dbed73cbSSangeeta Misra 		khead = (char *)conn_walk->ilbs.ilbs_c2s_conn_hash + i *
3464dbed73cbSSangeeta Misra 		    sizeof (ilb_conn_hash_t);
3465dbed73cbSSangeeta Misra 		if (mdb_vread(&head, sizeof (ilb_conn_hash_t),
3466dbed73cbSSangeeta Misra 		    (uintptr_t)khead) == -1) {
3467dbed73cbSSangeeta Misra 			mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n",
3468dbed73cbSSangeeta Misra 			    khead);
3469dbed73cbSSangeeta Misra 			return (WALK_ERR);
3470dbed73cbSSangeeta Misra 		}
3471dbed73cbSSangeeta Misra 
3472dbed73cbSSangeeta Misra 		if (head.ilb_connp != NULL)
3473dbed73cbSSangeeta Misra 			break;
3474dbed73cbSSangeeta Misra 	}
3475dbed73cbSSangeeta Misra 
3476dbed73cbSSangeeta Misra 	if (head.ilb_connp == NULL)
3477dbed73cbSSangeeta Misra 		return (WALK_DONE);
3478dbed73cbSSangeeta Misra 
3479dbed73cbSSangeeta Misra 	wsp->walk_addr = (uintptr_t)head.ilb_connp;
3480dbed73cbSSangeeta Misra 	conn_walk->idx = i;
3481dbed73cbSSangeeta Misra 	return (WALK_NEXT);
3482dbed73cbSSangeeta Misra }
3483dbed73cbSSangeeta Misra 
3484dbed73cbSSangeeta Misra static int
ilb_conn_walk_step(mdb_walk_state_t * wsp)3485dbed73cbSSangeeta Misra ilb_conn_walk_step(mdb_walk_state_t *wsp)
3486dbed73cbSSangeeta Misra {
3487dbed73cbSSangeeta Misra 	int status;
3488dbed73cbSSangeeta Misra 	ilb_conn_t conn;
3489dbed73cbSSangeeta Misra 	ilb_walk_t *conn_walk;
3490dbed73cbSSangeeta Misra 	ilb_stack_t *ilbs;
3491dbed73cbSSangeeta Misra 	ilb_conn_hash_t head;
3492dbed73cbSSangeeta Misra 	char *khead;
3493dbed73cbSSangeeta Misra 	int i;
3494dbed73cbSSangeeta Misra 
3495dbed73cbSSangeeta Misra 	if (mdb_vread(&conn, sizeof (ilb_conn_t), wsp->walk_addr) == -1) {
3496dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_conn_t at %p", wsp->walk_addr);
3497dbed73cbSSangeeta Misra 		return (WALK_ERR);
3498dbed73cbSSangeeta Misra 	}
3499dbed73cbSSangeeta Misra 
3500dbed73cbSSangeeta Misra 	status = wsp->walk_callback(wsp->walk_addr, &conn, wsp->walk_cbdata);
3501dbed73cbSSangeeta Misra 	if (status != WALK_NEXT)
3502dbed73cbSSangeeta Misra 		return (status);
3503dbed73cbSSangeeta Misra 
3504dbed73cbSSangeeta Misra 	conn_walk = (ilb_walk_t *)wsp->walk_data;
3505dbed73cbSSangeeta Misra 	ilbs = &conn_walk->ilbs;
3506dbed73cbSSangeeta Misra 	i = conn_walk->idx;
3507dbed73cbSSangeeta Misra 
3508dbed73cbSSangeeta Misra 	/* Check if there is still entry in the current list. */
3509dbed73cbSSangeeta Misra 	if (conn.conn_c2s_next != NULL) {
3510dbed73cbSSangeeta Misra 		wsp->walk_addr = (uintptr_t)conn.conn_c2s_next;
3511dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3512dbed73cbSSangeeta Misra 	}
3513dbed73cbSSangeeta Misra 
3514dbed73cbSSangeeta Misra 	/* Start with the next bucket in the array. */
3515dbed73cbSSangeeta Misra 	for (i++; i < ilbs->ilbs_conn_hash_size; i++) {
3516dbed73cbSSangeeta Misra 		khead = (char *)ilbs->ilbs_c2s_conn_hash + i *
3517dbed73cbSSangeeta Misra 		    sizeof (ilb_conn_hash_t);
3518dbed73cbSSangeeta Misra 		if (mdb_vread(&head, sizeof (ilb_conn_hash_t),
3519dbed73cbSSangeeta Misra 		    (uintptr_t)khead) == -1) {
3520dbed73cbSSangeeta Misra 			mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n",
3521dbed73cbSSangeeta Misra 			    khead);
3522dbed73cbSSangeeta Misra 			return (WALK_ERR);
3523dbed73cbSSangeeta Misra 		}
3524dbed73cbSSangeeta Misra 
3525dbed73cbSSangeeta Misra 		if (head.ilb_connp != NULL)
3526dbed73cbSSangeeta Misra 			break;
3527dbed73cbSSangeeta Misra 	}
3528dbed73cbSSangeeta Misra 
3529dbed73cbSSangeeta Misra 	if (head.ilb_connp == NULL)
3530dbed73cbSSangeeta Misra 		return (WALK_DONE);
3531dbed73cbSSangeeta Misra 
3532dbed73cbSSangeeta Misra 	wsp->walk_addr = (uintptr_t)head.ilb_connp;
3533dbed73cbSSangeeta Misra 	conn_walk->idx = i;
3534dbed73cbSSangeeta Misra 	return (WALK_NEXT);
3535dbed73cbSSangeeta Misra }
3536dbed73cbSSangeeta Misra 
3537dbed73cbSSangeeta Misra static int
ilb_sticky_walk_init(mdb_walk_state_t * wsp)3538dbed73cbSSangeeta Misra ilb_sticky_walk_init(mdb_walk_state_t *wsp)
3539dbed73cbSSangeeta Misra {
3540dbed73cbSSangeeta Misra 	int i;
3541dbed73cbSSangeeta Misra 	ilb_walk_t *sticky_walk;
3542dbed73cbSSangeeta Misra 	ilb_sticky_t *st = NULL;
3543dbed73cbSSangeeta Misra 
3544892ad162SToomas Soome 	if (wsp->walk_addr == 0)
3545dbed73cbSSangeeta Misra 		return (WALK_ERR);
3546dbed73cbSSangeeta Misra 
3547dbed73cbSSangeeta Misra 	sticky_walk = mdb_alloc(sizeof (ilb_walk_t), UM_SLEEP);
3548dbed73cbSSangeeta Misra 	if (mdb_vread(&sticky_walk->ilbs, sizeof (sticky_walk->ilbs),
3549dbed73cbSSangeeta Misra 	    wsp->walk_addr) == -1) {
3550dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_stack_t at %p", wsp->walk_addr);
3551dbed73cbSSangeeta Misra 		mdb_free(sticky_walk, sizeof (ilb_walk_t));
3552dbed73cbSSangeeta Misra 		return (WALK_ERR);
3553dbed73cbSSangeeta Misra 	}
3554dbed73cbSSangeeta Misra 
3555dbed73cbSSangeeta Misra 	if (sticky_walk->ilbs.ilbs_sticky_hash == NULL) {
3556dbed73cbSSangeeta Misra 		mdb_free(sticky_walk, sizeof (ilb_walk_t));
3557dbed73cbSSangeeta Misra 		return (WALK_DONE);
3558dbed73cbSSangeeta Misra 	}
3559dbed73cbSSangeeta Misra 
3560dbed73cbSSangeeta Misra 	wsp->walk_data = sticky_walk;
3561dbed73cbSSangeeta Misra 	for (i = 0; i < sticky_walk->ilbs.ilbs_sticky_hash_size; i++) {
3562dbed73cbSSangeeta Misra 		list_t head;
3563dbed73cbSSangeeta Misra 		char *khead;
3564dbed73cbSSangeeta Misra 
3565dbed73cbSSangeeta Misra 		/* Read in the nsh_head in the i-th element of the array. */
3566dbed73cbSSangeeta Misra 		khead = (char *)sticky_walk->ilbs.ilbs_sticky_hash + i *
3567dbed73cbSSangeeta Misra 		    sizeof (ilb_sticky_hash_t);
3568dbed73cbSSangeeta Misra 		if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
3569dbed73cbSSangeeta Misra 			mdb_warn("failed to read ilbs_sticky_hash at %p\n",
3570dbed73cbSSangeeta Misra 			    khead);
3571dbed73cbSSangeeta Misra 			return (WALK_ERR);
3572dbed73cbSSangeeta Misra 		}
3573dbed73cbSSangeeta Misra 
3574dbed73cbSSangeeta Misra 		/*
3575dbed73cbSSangeeta Misra 		 * Note that list_next points to a kernel address and we need
3576dbed73cbSSangeeta Misra 		 * to compare list_next with the kernel address of the list
3577dbed73cbSSangeeta Misra 		 * head.  So we need to calculate the address manually.
3578dbed73cbSSangeeta Misra 		 */
3579dbed73cbSSangeeta Misra 		if ((char *)head.list_head.list_next != khead +
3580dbed73cbSSangeeta Misra 		    offsetof(list_t, list_head)) {
3581dbed73cbSSangeeta Misra 			st = list_object(&head, head.list_head.list_next);
3582dbed73cbSSangeeta Misra 			break;
3583dbed73cbSSangeeta Misra 		}
3584dbed73cbSSangeeta Misra 	}
3585dbed73cbSSangeeta Misra 
3586dbed73cbSSangeeta Misra 	if (st == NULL)
3587dbed73cbSSangeeta Misra 		return (WALK_DONE);
3588dbed73cbSSangeeta Misra 
3589dbed73cbSSangeeta Misra 	wsp->walk_addr = (uintptr_t)st;
3590dbed73cbSSangeeta Misra 	sticky_walk->idx = i;
3591dbed73cbSSangeeta Misra 	return (WALK_NEXT);
3592dbed73cbSSangeeta Misra }
3593dbed73cbSSangeeta Misra 
3594dbed73cbSSangeeta Misra static int
ilb_sticky_walk_step(mdb_walk_state_t * wsp)3595dbed73cbSSangeeta Misra ilb_sticky_walk_step(mdb_walk_state_t *wsp)
3596dbed73cbSSangeeta Misra {
3597dbed73cbSSangeeta Misra 	int status;
3598dbed73cbSSangeeta Misra 	ilb_sticky_t st, *st_next;
3599dbed73cbSSangeeta Misra 	ilb_walk_t *sticky_walk;
3600dbed73cbSSangeeta Misra 	ilb_stack_t *ilbs;
3601dbed73cbSSangeeta Misra 	list_t head;
3602dbed73cbSSangeeta Misra 	char *khead;
3603dbed73cbSSangeeta Misra 	int i;
3604dbed73cbSSangeeta Misra 
3605dbed73cbSSangeeta Misra 	if (mdb_vread(&st, sizeof (ilb_sticky_t), wsp->walk_addr) == -1) {
3606dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilb_sticky_t at %p", wsp->walk_addr);
3607dbed73cbSSangeeta Misra 		return (WALK_ERR);
3608dbed73cbSSangeeta Misra 	}
3609dbed73cbSSangeeta Misra 
3610dbed73cbSSangeeta Misra 	status = wsp->walk_callback(wsp->walk_addr, &st, wsp->walk_cbdata);
3611dbed73cbSSangeeta Misra 	if (status != WALK_NEXT)
3612dbed73cbSSangeeta Misra 		return (status);
3613dbed73cbSSangeeta Misra 
3614dbed73cbSSangeeta Misra 	sticky_walk = (ilb_walk_t *)wsp->walk_data;
3615dbed73cbSSangeeta Misra 	ilbs = &sticky_walk->ilbs;
3616dbed73cbSSangeeta Misra 	i = sticky_walk->idx;
3617dbed73cbSSangeeta Misra 
3618dbed73cbSSangeeta Misra 	/* Read in the nsh_head in the i-th element of the array. */
3619dbed73cbSSangeeta Misra 	khead = (char *)ilbs->ilbs_sticky_hash + i * sizeof (ilb_sticky_hash_t);
3620dbed73cbSSangeeta Misra 	if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
3621dbed73cbSSangeeta Misra 		mdb_warn("failed to read ilbs_sticky_hash at %p\n", khead);
3622dbed73cbSSangeeta Misra 		return (WALK_ERR);
3623dbed73cbSSangeeta Misra 	}
3624dbed73cbSSangeeta Misra 
3625dbed73cbSSangeeta Misra 	/*
3626dbed73cbSSangeeta Misra 	 * Check if there is still entry in the current list.
3627dbed73cbSSangeeta Misra 	 *
3628dbed73cbSSangeeta Misra 	 * Note that list_next points to a kernel address and we need to
3629dbed73cbSSangeeta Misra 	 * compare list_next with the kernel address of the list head.
3630dbed73cbSSangeeta Misra 	 * So we need to calculate the address manually.
3631dbed73cbSSangeeta Misra 	 */
3632dbed73cbSSangeeta Misra 	if ((char *)st.list.list_next != khead + offsetof(list_t,
3633dbed73cbSSangeeta Misra 	    list_head)) {
3634dbed73cbSSangeeta Misra 		wsp->walk_addr = (uintptr_t)list_object(&head,
3635dbed73cbSSangeeta Misra 		    st.list.list_next);
3636dbed73cbSSangeeta Misra 		return (WALK_NEXT);
3637dbed73cbSSangeeta Misra 	}
3638dbed73cbSSangeeta Misra 
3639dbed73cbSSangeeta Misra 	/* Start with the next bucket in the array. */
3640dbed73cbSSangeeta Misra 	st_next = NULL;
3641dbed73cbSSangeeta Misra 	for (i++; i < ilbs->ilbs_nat_src_hash_size; i++) {
3642dbed73cbSSangeeta Misra 		khead = (char *)ilbs->ilbs_sticky_hash + i *
3643dbed73cbSSangeeta Misra 		    sizeof (ilb_sticky_hash_t);
3644dbed73cbSSangeeta Misra 		if (mdb_vread(&head, sizeof (list_t), (uintptr_t)khead) == -1) {
3645dbed73cbSSangeeta Misra 			mdb_warn("failed to read ilbs_sticky_hash at %p\n",
3646dbed73cbSSangeeta Misra 			    khead);
3647dbed73cbSSangeeta Misra 			return (WALK_ERR);
3648dbed73cbSSangeeta Misra 		}
3649dbed73cbSSangeeta Misra 
3650dbed73cbSSangeeta Misra 		if ((char *)head.list_head.list_next != khead +
3651dbed73cbSSangeeta Misra 		    offsetof(list_t, list_head)) {
3652dbed73cbSSangeeta Misra 			st_next = list_object(&head,
3653dbed73cbSSangeeta Misra 			    head.list_head.list_next);
3654dbed73cbSSangeeta Misra 			break;
3655dbed73cbSSangeeta Misra 		}
3656dbed73cbSSangeeta Misra 	}
3657dbed73cbSSangeeta Misra 
3658dbed73cbSSangeeta Misra 	if (st_next == NULL)
3659dbed73cbSSangeeta Misra 		return (WALK_DONE);
3660dbed73cbSSangeeta Misra 
3661dbed73cbSSangeeta Misra 	wsp->walk_addr = (uintptr_t)st_next;
3662dbed73cbSSangeeta Misra 	sticky_walk->idx = i;
3663dbed73cbSSangeeta Misra 	return (WALK_NEXT);
3664dbed73cbSSangeeta Misra }
3665