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