summaryrefslogtreecommitdiff
path: root/usr/src/cmd/mdb/common/modules/genunix/netstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/mdb/common/modules/genunix/netstack.c')
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/netstack.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/usr/src/cmd/mdb/common/modules/genunix/netstack.c b/usr/src/cmd/mdb/common/modules/genunix/netstack.c
new file mode 100644
index 0000000000..588bd6dbf3
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/genunix/netstack.c
@@ -0,0 +1,123 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <mdb/mdb_modapi.h>
+#include <mdb/mdb_ks.h>
+#include <mdb/mdb_ctf.h>
+#include <sys/types.h>
+#include <sys/netstack.h>
+
+int
+netstack_walk_init(mdb_walk_state_t *wsp)
+{
+ GElf_Sym sym;
+ uintptr_t addr;
+
+ if (mdb_lookup_by_name("netstack_head", &sym) == -1) {
+ mdb_warn("couldn't find netstack_head");
+ return (WALK_ERR);
+ }
+ addr = (uintptr_t)sym.st_value;
+
+ if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), addr) == -1) {
+ mdb_warn("failed to read address of initial netstack "
+ "at %p", addr);
+ return (WALK_ERR);
+ }
+ return (WALK_NEXT);
+}
+
+int
+netstack_walk_step(mdb_walk_state_t *wsp)
+{
+ int status;
+ netstack_t nss;
+
+ if (wsp->walk_addr == NULL)
+ return (WALK_DONE);
+
+ if (mdb_vread(&nss, sizeof (netstack_t), wsp->walk_addr) == -1) {
+ mdb_warn("failed to read netstack at %p", wsp->walk_addr);
+ return (WALK_ERR);
+ }
+
+ status = wsp->walk_callback(wsp->walk_addr, &nss,
+ wsp->walk_cbdata);
+
+ if (status != WALK_NEXT)
+ return (status);
+
+ wsp->walk_addr = (uintptr_t)nss.netstack_next;
+ return (status);
+}
+
+/*ARGSUSED*/
+int
+netstack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ netstack_t nss;
+ uint_t quiet = FALSE;
+ uint_t verbose = FALSE;
+
+ if (!(flags & DCMD_ADDRSPEC)) {
+ if (mdb_walk_dcmd("genunix`netstack", "genunix`netstack",
+ argc, argv) == -1) {
+ mdb_warn("failed to walk netstack");
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
+ }
+ if (mdb_getopts(argc, argv,
+ 'v', MDB_OPT_SETBITS, TRUE, &verbose,
+ 'q', MDB_OPT_SETBITS, TRUE, &quiet,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ if (DCMD_HDRSPEC(flags) && !quiet) {
+ mdb_printf("%?s %-7s %6s\n",
+ "ADDR", "STACKID", "FLAGS");
+ }
+
+ if (mdb_vread(&nss, sizeof (nss), addr) == -1) {
+ mdb_warn("couldn't read netstack at %p", addr);
+ return (DCMD_ERR);
+ }
+
+ /*
+ * Options are specified for filtering, so If any option is specified on
+ * the command line, just print address and exit.
+ */
+ if (quiet) {
+ mdb_printf("%0?p\n", addr);
+ return (DCMD_OK);
+ }
+
+ mdb_printf("%0?p %6d %06x\n",
+ addr, nss.netstack_stackid, nss.netstack_flags);
+
+ return (DCMD_OK);
+}