1*3448Sdh155122 /*
2*3448Sdh155122 * CDDL HEADER START
3*3448Sdh155122 *
4*3448Sdh155122 * The contents of this file are subject to the terms of the
5*3448Sdh155122 * Common Development and Distribution License (the "License").
6*3448Sdh155122 * You may not use this file except in compliance with the License.
7*3448Sdh155122 *
8*3448Sdh155122 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3448Sdh155122 * or http://www.opensolaris.org/os/licensing.
10*3448Sdh155122 * See the License for the specific language governing permissions
11*3448Sdh155122 * and limitations under the License.
12*3448Sdh155122 *
13*3448Sdh155122 * When distributing Covered Code, include this CDDL HEADER in each
14*3448Sdh155122 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3448Sdh155122 * If applicable, add the following below this CDDL HEADER, with the
16*3448Sdh155122 * fields enclosed by brackets "[]" replaced with your own identifying
17*3448Sdh155122 * information: Portions Copyright [yyyy] [name of copyright owner]
18*3448Sdh155122 *
19*3448Sdh155122 * CDDL HEADER END
20*3448Sdh155122 */
21*3448Sdh155122 /*
22*3448Sdh155122 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23*3448Sdh155122 * Use is subject to license terms.
24*3448Sdh155122 */
25*3448Sdh155122
26*3448Sdh155122 #pragma ident "%Z%%M% %I% %E% SMI"
27*3448Sdh155122
28*3448Sdh155122 #include <mdb/mdb_modapi.h>
29*3448Sdh155122 #include <mdb/mdb_ks.h>
30*3448Sdh155122 #include <mdb/mdb_ctf.h>
31*3448Sdh155122 #include <sys/types.h>
32*3448Sdh155122 #include <sys/netstack.h>
33*3448Sdh155122
34*3448Sdh155122 int
netstack_walk_init(mdb_walk_state_t * wsp)35*3448Sdh155122 netstack_walk_init(mdb_walk_state_t *wsp)
36*3448Sdh155122 {
37*3448Sdh155122 GElf_Sym sym;
38*3448Sdh155122 uintptr_t addr;
39*3448Sdh155122
40*3448Sdh155122 if (mdb_lookup_by_name("netstack_head", &sym) == -1) {
41*3448Sdh155122 mdb_warn("couldn't find netstack_head");
42*3448Sdh155122 return (WALK_ERR);
43*3448Sdh155122 }
44*3448Sdh155122 addr = (uintptr_t)sym.st_value;
45*3448Sdh155122
46*3448Sdh155122 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), addr) == -1) {
47*3448Sdh155122 mdb_warn("failed to read address of initial netstack "
48*3448Sdh155122 "at %p", addr);
49*3448Sdh155122 return (WALK_ERR);
50*3448Sdh155122 }
51*3448Sdh155122 return (WALK_NEXT);
52*3448Sdh155122 }
53*3448Sdh155122
54*3448Sdh155122 int
netstack_walk_step(mdb_walk_state_t * wsp)55*3448Sdh155122 netstack_walk_step(mdb_walk_state_t *wsp)
56*3448Sdh155122 {
57*3448Sdh155122 int status;
58*3448Sdh155122 netstack_t nss;
59*3448Sdh155122
60*3448Sdh155122 if (wsp->walk_addr == NULL)
61*3448Sdh155122 return (WALK_DONE);
62*3448Sdh155122
63*3448Sdh155122 if (mdb_vread(&nss, sizeof (netstack_t), wsp->walk_addr) == -1) {
64*3448Sdh155122 mdb_warn("failed to read netstack at %p", wsp->walk_addr);
65*3448Sdh155122 return (WALK_ERR);
66*3448Sdh155122 }
67*3448Sdh155122
68*3448Sdh155122 status = wsp->walk_callback(wsp->walk_addr, &nss,
69*3448Sdh155122 wsp->walk_cbdata);
70*3448Sdh155122
71*3448Sdh155122 if (status != WALK_NEXT)
72*3448Sdh155122 return (status);
73*3448Sdh155122
74*3448Sdh155122 wsp->walk_addr = (uintptr_t)nss.netstack_next;
75*3448Sdh155122 return (status);
76*3448Sdh155122 }
77*3448Sdh155122
78*3448Sdh155122 /*ARGSUSED*/
79*3448Sdh155122 int
netstack(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)80*3448Sdh155122 netstack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
81*3448Sdh155122 {
82*3448Sdh155122 netstack_t nss;
83*3448Sdh155122 uint_t quiet = FALSE;
84*3448Sdh155122 uint_t verbose = FALSE;
85*3448Sdh155122
86*3448Sdh155122 if (!(flags & DCMD_ADDRSPEC)) {
87*3448Sdh155122 if (mdb_walk_dcmd("genunix`netstack", "genunix`netstack",
88*3448Sdh155122 argc, argv) == -1) {
89*3448Sdh155122 mdb_warn("failed to walk netstack");
90*3448Sdh155122 return (DCMD_ERR);
91*3448Sdh155122 }
92*3448Sdh155122 return (DCMD_OK);
93*3448Sdh155122 }
94*3448Sdh155122 if (mdb_getopts(argc, argv,
95*3448Sdh155122 'v', MDB_OPT_SETBITS, TRUE, &verbose,
96*3448Sdh155122 'q', MDB_OPT_SETBITS, TRUE, &quiet,
97*3448Sdh155122 NULL) != argc)
98*3448Sdh155122 return (DCMD_USAGE);
99*3448Sdh155122
100*3448Sdh155122 if (DCMD_HDRSPEC(flags) && !quiet) {
101*3448Sdh155122 mdb_printf("%?s %-7s %6s\n",
102*3448Sdh155122 "ADDR", "STACKID", "FLAGS");
103*3448Sdh155122 }
104*3448Sdh155122
105*3448Sdh155122 if (mdb_vread(&nss, sizeof (nss), addr) == -1) {
106*3448Sdh155122 mdb_warn("couldn't read netstack at %p", addr);
107*3448Sdh155122 return (DCMD_ERR);
108*3448Sdh155122 }
109*3448Sdh155122
110*3448Sdh155122 /*
111*3448Sdh155122 * Options are specified for filtering, so If any option is specified on
112*3448Sdh155122 * the command line, just print address and exit.
113*3448Sdh155122 */
114*3448Sdh155122 if (quiet) {
115*3448Sdh155122 mdb_printf("%0?p\n", addr);
116*3448Sdh155122 return (DCMD_OK);
117*3448Sdh155122 }
118*3448Sdh155122
119*3448Sdh155122 mdb_printf("%0?p %6d %06x\n",
120*3448Sdh155122 addr, nss.netstack_stackid, nss.netstack_flags);
121*3448Sdh155122
122*3448Sdh155122 return (DCMD_OK);
123*3448Sdh155122 }
124