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         char strdev[MAXPATHLEN];
  70         char sockmod[MODMAXNAMELEN];
  71 
  72         if ((flags & DCMD_ADDRSPEC) == 0) {
  73                 uint_t opt_e = 0;
  74                 uint_t opt_E = 0;
  75 
  76                 /*
  77                  * Determine what lists should be printed
  78                  */
  79                 if (mdb_getopts(argc, argv,
  80                     'e', MDB_OPT_SETBITS, 1, &opt_e,
  81                     'E', MDB_OPT_SETBITS, 1, &opt_E) != argc)
  82                         return (DCMD_USAGE);
  83 
  84                 if (!opt_E) {
  85                         if (!sockparams_walk_list("sphead", argc, argv))
  86                                 return (DCMD_ERR);
  87                 }
  88 
  89                 if (opt_e || opt_E) {
  90                         if (!sockparams_walk_list("sp_ephem_list", argc, argv))
  91                                 return (DCMD_ERR);
  92                 }
  93 
  94                 return (DCMD_OK);
  95         }
  96 
  97         /*
  98          * If we are piping the output, then just print out the address,
  99          * otherwise summarize the sockparams info.
 100          */
 101         if ((flags & DCMD_PIPE_OUT) != 0) {
 102                 mdb_printf("%#lr\n", addr);
 103                 return (DCMD_OK);
 104         }
 105 
 106         if (DCMD_HDRSPEC(flags)) {
 107                 mdb_printf("%-?s %3s %3s %3s %15s %15s %6s %6s\n",
 108                     "ADDR", "FAM", "TYP", "PRO", "STRDEV", "SOCKMOD", "REFS",
 109                     "FLGS");
 110         }
 111 
 112         if (mdb_vread(&sp, sizeof (sp), addr) == -1) {
 113                 mdb_warn("failed to read sockparams at %0?p", addr);
 114                 return (DCMD_ERR);
 115         }
 116 
 117         if ((sp.sp_sdev_info.sd_devpath == NULL) || 
 118             (mdb_readstr(strdev, sizeof (strdev), 
 119              (uintptr_t)sp.sp_sdev_info.sd_devpath) <= 0))
 120                 strcpy(strdev, "-");
 121         if (mdb_readstr(sockmod, sizeof (sockmod), 
 122             (uintptr_t)sp.sp_smod_name) <= 0)
 123                 strcpy(sockmod, "");
 124 
 125         mdb_printf("%0?p %3u %3u %3u %15s %15s %6u %#6x\n",
 126             addr,
 127             sp.sp_family, sp.sp_type, sp.sp_protocol,
 128             strdev, sockmod, sp.sp_refcnt,
 129             sp.sp_flags);
 130 
 131 
 132         return (DCMD_OK);
 133 }
 134 
 135 /*
 136  * Help function
 137  */
 138 void
 139 sockparams_help(void)
 140 {
 141         mdb_printf("Print sockparams information for a give sockparams ptr.\n"
 142             "Without the address, list available sockparams. Default "
 143             "behavior is to list only entries that were installed by the "
 144             "admin (via soconfig(1M)).\n\n"
 145             "Options:\n"
 146             "   -e:\t\tlist ephemeral sockparams\n"
 147             "   -E:\t\tonly list ephemeral sockparams\n");
 148 }
 149 
 150 static const mdb_dcmd_t dcmds[] = {
 151         { "sockparams", "[-eE]", "print sockparams", sockparams_prt,
 152             sockparams_help },
 153         { NULL }
 154 };
 155 
 156 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, NULL };
 157 
 158 const mdb_modinfo_t *
 159 _mdb_init(void)
 160 {
 161         return (&modinfo);
 162 }