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 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/stropts.h>
  28 #include <sys/socket.h>
  29 #include <sys/socketvar.h>
  30 
  31 #include <mdb/mdb_modapi.h>
  32 #include <mdb/mdb_ks.h>
  33 
  34 /*
  35  * Look up the symbol name for the given sockparams list and walk
  36  * all the entries.
  37  */
  38 static boolean_t
  39 sockparams_walk_list(const char *symname, int argc, const mdb_arg_t *argv)
  40 {
  41         GElf_Sym sym;
  42 
  43         if (mdb_lookup_by_name(symname, &sym)) {
  44                 mdb_warn("can't find symbol %s", symname);
  45                 return (B_FALSE);
  46         }
  47 
  48         if (mdb_pwalk_dcmd("list", "sockfs`sockparams", argc, argv,
  49             sym.st_value) != 0) {
  50                 mdb_warn("can't walk %s", symname);
  51                 return (B_FALSE);
  52         }
  53 
  54         return (B_TRUE);
  55 }
  56 
  57 /*
  58  * dcmd to print sockparams info.
  59  *
  60  * If no address is given then the default is to print all sockparams on the
  61  * global list (i.e., installed with soconfig(1)). To also print the ephemeral
  62  * entries the '-e' flag should be used. Only ephemeral entries can be printed
  63  * by specifying the '-E' flag.
  64  */
  65 static int
  66 sockparams_prt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
  67 {
  68         struct sockparams sp;
  69 
  70         if ((flags & DCMD_ADDRSPEC) == 0) {
  71                 uint_t opt_e = 0;
  72                 uint_t opt_E = 0;
  73 
  74                 /*
  75                  * Determine what lists should be printed
  76                  */
  77                 if (mdb_getopts(argc, argv,
  78                     'e', MDB_OPT_SETBITS, 1, &opt_e,
  79                     'E', MDB_OPT_SETBITS, 1, &opt_E) != argc)
  80                         return (DCMD_USAGE);
  81 
  82                 if (!opt_E) {
  83                         if (!sockparams_walk_list("sphead", argc, argv))
  84                                 return (DCMD_ERR);
  85                 }
  86 
  87                 if (opt_e || opt_E) {
  88                         if (!sockparams_walk_list("sp_ephem_list", argc, argv))
  89                                 return (DCMD_ERR);
  90                 }
  91 
  92                 return (DCMD_OK);
  93         }
  94 
  95         /*
  96          * If we are piping the output, then just print out the address,
  97          * otherwise summarize the sockparams info.
  98          */
  99         if ((flags & DCMD_PIPE_OUT) != 0) {
 100                 mdb_printf("%#lr\n", addr);
 101                 return (DCMD_OK);
 102         }
 103 
 104         if (DCMD_HDRSPEC(flags)) {
 105                 mdb_printf("%-?s %3s %3s %3s %15s %15s %6s %6s\n",
 106                     "ADDR", "FAM", "TYP", "PRO", "STRDEV", "SOCKMOD", "REFS",
 107                     "FLGS");
 108         }
 109 
 110         if (mdb_vread(&sp, sizeof (sp), addr) == -1) {
 111                 mdb_warn("failed to read sockparams at %0?p", addr);
 112                 return (DCMD_ERR);
 113         }
 114 
 115         mdb_printf("%0?p %3u %3u %3u %15s %15s %6u %#6x\n",
 116             addr,
 117             sp.sp_family, sp.sp_type, sp.sp_protocol,
 118             (sp.sp_sdev_info.sd_devpath != 0) ?
 119             sp.sp_sdev_info.sd_devpath : "-",
 120             sp.sp_smod_name, sp.sp_refcnt,
 121             sp.sp_flags);
 122 
 123 
 124         return (DCMD_OK);
 125 }
 126 
 127 /*
 128  * Help function
 129  */
 130 void
 131 sockparams_help(void)
 132 {
 133         mdb_printf("Print sockparams information for a give sockparams ptr.\n"
 134             "Without the address, list available sockparams. Default "
 135             "behavior is to list only entries that were installed by the "
 136             "admin (via soconfig(1M)).\n\n"
 137             "Options:\n"
 138             "   -e:\t\tlist ephemeral sockparams\n"
 139             "   -E:\t\tonly list ephemeral sockparams\n");
 140 }
 141 
 142 static const mdb_dcmd_t dcmds[] = {
 143         { "sockparams", "[-eE]", "print sockparams", sockparams_prt,
 144             sockparams_help },
 145         { NULL }
 146 };
 147 
 148 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, NULL };
 149 
 150 const mdb_modinfo_t *
 151 _mdb_init(void)
 152 {
 153         return (&modinfo);
 154 }