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