1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
2141610d10SYuri Pankov 
22da6c28aaSamw /*
23148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
240292c176SMatt Barden  * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
25*2cf6b79fSGordon Ross  * Copyright 2022 RackTop Systems, Inc.
26da6c28aaSamw  */
27da6c28aaSamw 
28148c5f43SAlan Wright #include <mdb/mdb_modapi.h>
29148c5f43SAlan Wright #include <mdb/mdb_ks.h>
30bd49ed45SGordon Ross #include <mdb/mdb_ctf.h>
31bd49ed45SGordon Ross #include <sys/note.h>
32fc724630SAlan Wright #include <sys/thread.h>
33b819cea2SGordon Ross #include <sys/taskq.h>
34da6c28aaSamw #include <smbsrv/smb_vops.h>
35da6c28aaSamw #include <smbsrv/smb.h>
36faa1795aSjb #include <smbsrv/smb_ktypes.h>
37bd49ed45SGordon Ross #include <smbsrv/smb_token.h>
3894047d49SGordon Ross #include <smbsrv/smb_oplock.h>
39da6c28aaSamw 
40764c8bd8SGordon Ross #ifndef _KMDB
41764c8bd8SGordon Ross #include "smbsrv_pcap.h"
42764c8bd8SGordon Ross #endif
43764c8bd8SGordon Ross 
44b819cea2SGordon Ross #ifdef _KERNEL
45b819cea2SGordon Ross #define	SMBSRV_OBJNAME	"smbsrv"
46b819cea2SGordon Ross #else
47b819cea2SGordon Ross #define	SMBSRV_OBJNAME	"libfksmbsrv.so.1"
48b819cea2SGordon Ross #endif
49b819cea2SGordon Ross 
50bd49ed45SGordon Ross #define	SMBSRV_SCOPE	SMBSRV_OBJNAME "`"
51bd49ed45SGordon Ross 
526537f381Sas #define	SMB_DCMD_INDENT		2
536537f381Sas #define	ACE_TYPE_TABLEN		(ACE_ALL_TYPES + 1)
546537f381Sas #define	ACE_TYPE_ENTRY(_v_)	{_v_, #_v_}
556537f381Sas #define	SMB_COM_ENTRY(_v_, _x_)	{#_v_, _x_}
566537f381Sas 
5794047d49SGordon Ross #define	SMB_MDB_MAX_OPTS	10
586537f381Sas 
596537f381Sas #define	SMB_OPT_SERVER		0x00000001
60148c5f43SAlan Wright #define	SMB_OPT_SESSION		0x00000002
61148c5f43SAlan Wright #define	SMB_OPT_REQUEST		0x00000004
62148c5f43SAlan Wright #define	SMB_OPT_USER		0x00000008
63148c5f43SAlan Wright #define	SMB_OPT_TREE		0x00000010
64148c5f43SAlan Wright #define	SMB_OPT_OFILE		0x00000020
65148c5f43SAlan Wright #define	SMB_OPT_ODIR		0x00000040
666537f381Sas #define	SMB_OPT_WALK		0x00000100
676537f381Sas #define	SMB_OPT_VERBOSE		0x00000200
686537f381Sas #define	SMB_OPT_ALL_OBJ		0x000000FF
69da6c28aaSamw 
70bd49ed45SGordon Ross /*
71bd49ed45SGordon Ross  * Use CTF to set var = OFFSETOF(typ, mem) if possible, otherwise
72bd49ed45SGordon Ross  * fall back to just OFFSETOF.  The fall back is more convenient
73bd49ed45SGordon Ross  * than trying to return an error where this is used, and also
74bd49ed45SGordon Ross  * let's us find out at compile time if we're referring to any
75bd49ed45SGordon Ross  * typedefs or member names that don't exist.  Without that
76bd49ed45SGordon Ross  * OFFSETOF fall back, we'd only find out at run time.
77bd49ed45SGordon Ross  */
78bd49ed45SGordon Ross #define	GET_OFFSET(var, typ, mem) do {				\
79bd49ed45SGordon Ross 	var = mdb_ctf_offsetof_by_name(#typ, #mem);		\
80bd49ed45SGordon Ross 	if (var < 0) {						\
81bd49ed45SGordon Ross 		mdb_warn("cannot lookup: " #typ " ." #mem);	\
82bd49ed45SGordon Ross 		var = (int)OFFSETOF(typ, mem);			\
83bd49ed45SGordon Ross 	}							\
84bd49ed45SGordon Ross _NOTE(CONSTCOND) } while (0)
85bd49ed45SGordon Ross 
866537f381Sas /*
876537f381Sas  * Structure associating an ACE type to a string.
886537f381Sas  */
896537f381Sas typedef struct {
906537f381Sas 	uint8_t		ace_type_value;
916537f381Sas 	const char	*ace_type_sting;
926537f381Sas } ace_type_entry_t;
93da6c28aaSamw 
94da6c28aaSamw /*
956537f381Sas  * Structure containing strings describing an SMB command.
96da6c28aaSamw  */
976537f381Sas typedef struct {
986537f381Sas 	const char	*smb_com;
996537f381Sas 	const char	*smb_andx;
1006537f381Sas } smb_com_entry_t;
1016537f381Sas 
1026537f381Sas /*
1036537f381Sas  * Structure describing an object to be expanded (displayed).
1046537f381Sas  */
1056537f381Sas typedef struct {
1066537f381Sas 	uint_t		ex_mask;
107*2cf6b79fSGordon Ross 	const char	*ex_walker;
10894047d49SGordon Ross 	int		(*ex_offset)(void);
1096537f381Sas 	const char	*ex_dcmd;
1106537f381Sas 	const char	*ex_name;
1116537f381Sas } smb_exp_t;
1126537f381Sas 
1136537f381Sas /*
1146537f381Sas  * List of supported options. Ther order has the match the bits SMB_OPT_xxx.
1156537f381Sas  */
116148c5f43SAlan Wright typedef struct smb_mdb_opts {
117148c5f43SAlan Wright 	char		*o_name;
118148c5f43SAlan Wright 	uint32_t	o_value;
119148c5f43SAlan Wright } smb_mdb_opts_t;
120148c5f43SAlan Wright 
121148c5f43SAlan Wright static smb_mdb_opts_t smb_opts[SMB_MDB_MAX_OPTS] =
122da6c28aaSamw {
123148c5f43SAlan Wright 	{ "-s", SMB_OPT_SERVER	},
124148c5f43SAlan Wright 	{ "-e", SMB_OPT_SESSION	},
125148c5f43SAlan Wright 	{ "-r", SMB_OPT_REQUEST	},
126148c5f43SAlan Wright 	{ "-u", SMB_OPT_USER	},
127148c5f43SAlan Wright 	{ "-t", SMB_OPT_TREE	},
128148c5f43SAlan Wright 	{ "-f", SMB_OPT_OFILE	},
129148c5f43SAlan Wright 	{ "-d", SMB_OPT_ODIR	},
130148c5f43SAlan Wright 	{ "-w", SMB_OPT_WALK	},
131148c5f43SAlan Wright 	{ "-v", SMB_OPT_VERBOSE	}
1326537f381Sas };
1336537f381Sas 
134bd49ed45SGordon Ross /*
135bd49ed45SGordon Ross  * These access mask bits are generic enough they could move into the
136bd49ed45SGordon Ross  * genunix mdb module or somewhere so they could be shared.
137bd49ed45SGordon Ross  */
138bd49ed45SGordon Ross static const mdb_bitmask_t
139bd49ed45SGordon Ross nt_access_bits[] = {
140bd49ed45SGordon Ross 	{ "READ_DATA",
141bd49ed45SGordon Ross 	    FILE_READ_DATA,
142bd49ed45SGordon Ross 	    FILE_READ_DATA },
143bd49ed45SGordon Ross 	{ "WRITE_DATA",
144bd49ed45SGordon Ross 	    FILE_WRITE_DATA,
145bd49ed45SGordon Ross 	    FILE_WRITE_DATA },
146bd49ed45SGordon Ross 	{ "APPEND_DATA",
147bd49ed45SGordon Ross 	    FILE_APPEND_DATA,
148bd49ed45SGordon Ross 	    FILE_APPEND_DATA },
149bd49ed45SGordon Ross 	{ "READ_EA",
150bd49ed45SGordon Ross 	    FILE_READ_EA,
151bd49ed45SGordon Ross 	    FILE_READ_EA },
152bd49ed45SGordon Ross 	{ "WRITE_EA",
153bd49ed45SGordon Ross 	    FILE_WRITE_EA,
154bd49ed45SGordon Ross 	    FILE_WRITE_EA },
155bd49ed45SGordon Ross 	{ "EXECUTE",
156bd49ed45SGordon Ross 	    FILE_EXECUTE,
157bd49ed45SGordon Ross 	    FILE_EXECUTE },
158bd49ed45SGordon Ross 	{ "DELETE_CHILD",
159bd49ed45SGordon Ross 	    FILE_DELETE_CHILD,
160bd49ed45SGordon Ross 	    FILE_DELETE_CHILD },
161bd49ed45SGordon Ross 	{ "READ_ATTR",
162bd49ed45SGordon Ross 	    FILE_READ_ATTRIBUTES,
163bd49ed45SGordon Ross 	    FILE_READ_ATTRIBUTES },
164bd49ed45SGordon Ross 	{ "WRITE_ATTR",
165bd49ed45SGordon Ross 	    FILE_WRITE_ATTRIBUTES,
166bd49ed45SGordon Ross 	    FILE_WRITE_ATTRIBUTES },
167bd49ed45SGordon Ross 	{ "DELETE",
168bd49ed45SGordon Ross 	    DELETE,
169bd49ed45SGordon Ross 	    DELETE },
170bd49ed45SGordon Ross 	{ "READ_CTRL",
171bd49ed45SGordon Ross 	    READ_CONTROL,
172bd49ed45SGordon Ross 	    READ_CONTROL },
173bd49ed45SGordon Ross 	{ "WRITE_DAC",
174bd49ed45SGordon Ross 	    WRITE_DAC,
175bd49ed45SGordon Ross 	    WRITE_DAC },
176bd49ed45SGordon Ross 	{ "WRITE_OWNER",
177bd49ed45SGordon Ross 	    WRITE_OWNER,
178bd49ed45SGordon Ross 	    WRITE_OWNER },
179bd49ed45SGordon Ross 	{ "SYNCH",
180bd49ed45SGordon Ross 	    SYNCHRONIZE,
181bd49ed45SGordon Ross 	    SYNCHRONIZE },
182bd49ed45SGordon Ross 	{ "ACC_SEC",
183bd49ed45SGordon Ross 	    ACCESS_SYSTEM_SECURITY,
184bd49ed45SGordon Ross 	    ACCESS_SYSTEM_SECURITY },
185bd49ed45SGordon Ross 	{ "MAX_ALLOWED",
186bd49ed45SGordon Ross 	    MAXIMUM_ALLOWED,
187bd49ed45SGordon Ross 	    MAXIMUM_ALLOWED },
188bd49ed45SGordon Ross 	{ "GEN_X",
189bd49ed45SGordon Ross 	    GENERIC_EXECUTE,
190bd49ed45SGordon Ross 	    GENERIC_EXECUTE },
191bd49ed45SGordon Ross 	{ "GEN_W",
192bd49ed45SGordon Ross 	    GENERIC_WRITE,
193bd49ed45SGordon Ross 	    GENERIC_WRITE },
194bd49ed45SGordon Ross 	{ "GEN_R",
195bd49ed45SGordon Ross 	    GENERIC_READ,
196bd49ed45SGordon Ross 	    GENERIC_READ },
197bd49ed45SGordon Ross 	{ NULL, 0, 0 }
198bd49ed45SGordon Ross };
199bd49ed45SGordon Ross 
2006537f381Sas static smb_com_entry_t	smb_com[256] =
2016537f381Sas {
2026537f381Sas 	SMB_COM_ENTRY(SMB_COM_CREATE_DIRECTORY, "No"),
2036537f381Sas 	SMB_COM_ENTRY(SMB_COM_DELETE_DIRECTORY, "No"),
2046537f381Sas 	SMB_COM_ENTRY(SMB_COM_OPEN, "No"),
2056537f381Sas 	SMB_COM_ENTRY(SMB_COM_CREATE, "No"),
2066537f381Sas 	SMB_COM_ENTRY(SMB_COM_CLOSE, "No"),
2076537f381Sas 	SMB_COM_ENTRY(SMB_COM_FLUSH, "No"),
2086537f381Sas 	SMB_COM_ENTRY(SMB_COM_DELETE, "No"),
2096537f381Sas 	SMB_COM_ENTRY(SMB_COM_RENAME, "No"),
2106537f381Sas 	SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION, "No"),
2116537f381Sas 	SMB_COM_ENTRY(SMB_COM_SET_INFORMATION, "No"),
2126537f381Sas 	SMB_COM_ENTRY(SMB_COM_READ, "No"),
2136537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE, "No"),
2146537f381Sas 	SMB_COM_ENTRY(SMB_COM_LOCK_BYTE_RANGE, "No"),
2156537f381Sas 	SMB_COM_ENTRY(SMB_COM_UNLOCK_BYTE_RANGE, "No"),
2166537f381Sas 	SMB_COM_ENTRY(SMB_COM_CREATE_TEMPORARY, "No"),
2176537f381Sas 	SMB_COM_ENTRY(SMB_COM_CREATE_NEW, "No"),
2186537f381Sas 	SMB_COM_ENTRY(SMB_COM_CHECK_DIRECTORY, "No"),
2196537f381Sas 	SMB_COM_ENTRY(SMB_COM_PROCESS_EXIT, "No"),
2206537f381Sas 	SMB_COM_ENTRY(SMB_COM_SEEK, "No"),
2216537f381Sas 	SMB_COM_ENTRY(SMB_COM_LOCK_AND_READ, "No"),
2226537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_AND_UNLOCK, "No"),
2236537f381Sas 	SMB_COM_ENTRY(0x15, "?"),
2246537f381Sas 	SMB_COM_ENTRY(0x16, "?"),
2256537f381Sas 	SMB_COM_ENTRY(0x17, "?"),
2266537f381Sas 	SMB_COM_ENTRY(0x18, "?"),
2276537f381Sas 	SMB_COM_ENTRY(0x19, "?"),
2286537f381Sas 	SMB_COM_ENTRY(SMB_COM_READ_RAW, "No"),
2296537f381Sas 	SMB_COM_ENTRY(SMB_COM_READ_MPX, "No"),
2306537f381Sas 	SMB_COM_ENTRY(SMB_COM_READ_MPX_SECONDARY, "No"),
2316537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_RAW, "No"),
2326537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_MPX, "No"),
2336537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_MPX_SECONDARY, "No"),
2346537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_COMPLETE, "No"),
2356537f381Sas 	SMB_COM_ENTRY(SMB_COM_QUERY_SERVER, "No"),
2366537f381Sas 	SMB_COM_ENTRY(SMB_COM_SET_INFORMATION2, "No"),
2376537f381Sas 	SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION2, "No"),
2386537f381Sas 	SMB_COM_ENTRY(SMB_COM_LOCKING_ANDX, "No"),
2396537f381Sas 	SMB_COM_ENTRY(SMB_COM_TRANSACTION, "No"),
2406537f381Sas 	SMB_COM_ENTRY(SMB_COM_TRANSACTION_SECONDARY, "No"),
2416537f381Sas 	SMB_COM_ENTRY(SMB_COM_IOCTL, "No"),
2426537f381Sas 	SMB_COM_ENTRY(SMB_COM_IOCTL_SECONDARY, "No"),
2436537f381Sas 	SMB_COM_ENTRY(SMB_COM_COPY, "No"),
2446537f381Sas 	SMB_COM_ENTRY(SMB_COM_MOVE, "No"),
2456537f381Sas 	SMB_COM_ENTRY(SMB_COM_ECHO, "No"),
2466537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_AND_CLOSE, "No"),
2476537f381Sas 	SMB_COM_ENTRY(SMB_COM_OPEN_ANDX, "No"),
2486537f381Sas 	SMB_COM_ENTRY(SMB_COM_READ_ANDX, "No"),
2496537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_ANDX, "No"),
2506537f381Sas 	SMB_COM_ENTRY(SMB_COM_NEW_FILE_SIZE, "No"),
2516537f381Sas 	SMB_COM_ENTRY(SMB_COM_CLOSE_AND_TREE_DISC, "No"),
2526537f381Sas 	SMB_COM_ENTRY(SMB_COM_TRANSACTION2, "No"),
2536537f381Sas 	SMB_COM_ENTRY(SMB_COM_TRANSACTION2_SECONDARY, "No"),
2546537f381Sas 	SMB_COM_ENTRY(SMB_COM_FIND_CLOSE2, "No"),
2556537f381Sas 	SMB_COM_ENTRY(SMB_COM_FIND_NOTIFY_CLOSE, "No"),
2566537f381Sas 	SMB_COM_ENTRY(0x36, "?"),
2576537f381Sas 	SMB_COM_ENTRY(0x37, "?"),
2586537f381Sas 	SMB_COM_ENTRY(0x38, "?"),
2596537f381Sas 	SMB_COM_ENTRY(0x39, "?"),
2606537f381Sas 	SMB_COM_ENTRY(0x3A, "?"),
2616537f381Sas 	SMB_COM_ENTRY(0x3B, "?"),
2626537f381Sas 	SMB_COM_ENTRY(0x3C, "?"),
2636537f381Sas 	SMB_COM_ENTRY(0x3D, "?"),
2646537f381Sas 	SMB_COM_ENTRY(0x3E, "?"),
2656537f381Sas 	SMB_COM_ENTRY(0x3F, "?"),
2666537f381Sas 	SMB_COM_ENTRY(0x40, "?"),
2676537f381Sas 	SMB_COM_ENTRY(0x41, "?"),
2686537f381Sas 	SMB_COM_ENTRY(0x42, "?"),
2696537f381Sas 	SMB_COM_ENTRY(0x43, "?"),
2706537f381Sas 	SMB_COM_ENTRY(0x44, "?"),
2716537f381Sas 	SMB_COM_ENTRY(0x45, "?"),
2726537f381Sas 	SMB_COM_ENTRY(0x46, "?"),
2736537f381Sas 	SMB_COM_ENTRY(0x47, "?"),
2746537f381Sas 	SMB_COM_ENTRY(0x48, "?"),
2756537f381Sas 	SMB_COM_ENTRY(0x49, "?"),
2766537f381Sas 	SMB_COM_ENTRY(0x4A, "?"),
2776537f381Sas 	SMB_COM_ENTRY(0x4B, "?"),
2786537f381Sas 	SMB_COM_ENTRY(0x4C, "?"),
2796537f381Sas 	SMB_COM_ENTRY(0x4D, "?"),
2806537f381Sas 	SMB_COM_ENTRY(0x4E, "?"),
2816537f381Sas 	SMB_COM_ENTRY(0x4F, "?"),
2826537f381Sas 	SMB_COM_ENTRY(0x50, "?"),
2836537f381Sas 	SMB_COM_ENTRY(0x51, "?"),
2846537f381Sas 	SMB_COM_ENTRY(0x52, "?"),
2856537f381Sas 	SMB_COM_ENTRY(0x53, "?"),
2866537f381Sas 	SMB_COM_ENTRY(0x54, "?"),
2876537f381Sas 	SMB_COM_ENTRY(0x55, "?"),
2886537f381Sas 	SMB_COM_ENTRY(0x56, "?"),
2896537f381Sas 	SMB_COM_ENTRY(0x57, "?"),
2906537f381Sas 	SMB_COM_ENTRY(0x58, "?"),
2916537f381Sas 	SMB_COM_ENTRY(0x59, "?"),
2926537f381Sas 	SMB_COM_ENTRY(0x5A, "?"),
2936537f381Sas 	SMB_COM_ENTRY(0x5B, "?"),
2946537f381Sas 	SMB_COM_ENTRY(0x5C, "?"),
2956537f381Sas 	SMB_COM_ENTRY(0x5D, "?"),
2966537f381Sas 	SMB_COM_ENTRY(0x5E, "?"),
2976537f381Sas 	SMB_COM_ENTRY(0x5F, "?"),
2986537f381Sas 	SMB_COM_ENTRY(0x60, "?"),
2996537f381Sas 	SMB_COM_ENTRY(0x61, "?"),
3006537f381Sas 	SMB_COM_ENTRY(0x62, "?"),
3016537f381Sas 	SMB_COM_ENTRY(0x63, "?"),
3026537f381Sas 	SMB_COM_ENTRY(0x64, "?"),
3036537f381Sas 	SMB_COM_ENTRY(0x65, "?"),
3046537f381Sas 	SMB_COM_ENTRY(0x66, "?"),
3056537f381Sas 	SMB_COM_ENTRY(0x67, "?"),
3066537f381Sas 	SMB_COM_ENTRY(0x68, "?"),
3076537f381Sas 	SMB_COM_ENTRY(0x69, "?"),
3086537f381Sas 	SMB_COM_ENTRY(0x6A, "?"),
3096537f381Sas 	SMB_COM_ENTRY(0x6B, "?"),
3106537f381Sas 	SMB_COM_ENTRY(0x6C, "?"),
3116537f381Sas 	SMB_COM_ENTRY(0x6D, "?"),
3126537f381Sas 	SMB_COM_ENTRY(0x6E, "?"),
3136537f381Sas 	SMB_COM_ENTRY(0x6F, "?"),
3146537f381Sas 	SMB_COM_ENTRY(SMB_COM_TREE_CONNECT, "No"),
3156537f381Sas 	SMB_COM_ENTRY(SMB_COM_TREE_DISCONNECT, "No"),
3166537f381Sas 	SMB_COM_ENTRY(SMB_COM_NEGOTIATE, "No"),
3176537f381Sas 	SMB_COM_ENTRY(SMB_COM_SESSION_SETUP_ANDX, "No"),
3186537f381Sas 	SMB_COM_ENTRY(SMB_COM_LOGOFF_ANDX, "No"),
3196537f381Sas 	SMB_COM_ENTRY(SMB_COM_TREE_CONNECT_ANDX, "No"),
3206537f381Sas 	SMB_COM_ENTRY(0x76, "?"),
3216537f381Sas 	SMB_COM_ENTRY(0x77, "?"),
3226537f381Sas 	SMB_COM_ENTRY(0x78, "?"),
3236537f381Sas 	SMB_COM_ENTRY(0x79, "?"),
3246537f381Sas 	SMB_COM_ENTRY(0x7A, "?"),
3256537f381Sas 	SMB_COM_ENTRY(0x7B, "?"),
3266537f381Sas 	SMB_COM_ENTRY(0x7C, "?"),
3276537f381Sas 	SMB_COM_ENTRY(0x7D, "?"),
3286537f381Sas 	SMB_COM_ENTRY(0x7E, "?"),
3296537f381Sas 	SMB_COM_ENTRY(0x7F, "?"),
3306537f381Sas 	SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION_DISK, "No"),
3316537f381Sas 	SMB_COM_ENTRY(SMB_COM_SEARCH, "No"),
3326537f381Sas 	SMB_COM_ENTRY(SMB_COM_FIND, "No"),
3336537f381Sas 	SMB_COM_ENTRY(SMB_COM_FIND_UNIQUE, "No"),
3346537f381Sas 	SMB_COM_ENTRY(SMB_COM_FIND_CLOSE, "No"),
3356537f381Sas 	SMB_COM_ENTRY(0x85, "?"),
3366537f381Sas 	SMB_COM_ENTRY(0x86, "?"),
3376537f381Sas 	SMB_COM_ENTRY(0x87, "?"),
3386537f381Sas 	SMB_COM_ENTRY(0x88, "?"),
3396537f381Sas 	SMB_COM_ENTRY(0x89, "?"),
3406537f381Sas 	SMB_COM_ENTRY(0x8A, "?"),
3416537f381Sas 	SMB_COM_ENTRY(0x8B, "?"),
3426537f381Sas 	SMB_COM_ENTRY(0x8C, "?"),
3436537f381Sas 	SMB_COM_ENTRY(0x8D, "?"),
3446537f381Sas 	SMB_COM_ENTRY(0x8E, "?"),
3456537f381Sas 	SMB_COM_ENTRY(0x8F, "?"),
3466537f381Sas 	SMB_COM_ENTRY(0x90, "?"),
3476537f381Sas 	SMB_COM_ENTRY(0x91, "?"),
3486537f381Sas 	SMB_COM_ENTRY(0x92, "?"),
3496537f381Sas 	SMB_COM_ENTRY(0x93, "?"),
3506537f381Sas 	SMB_COM_ENTRY(0x94, "?"),
3516537f381Sas 	SMB_COM_ENTRY(0x95, "?"),
3526537f381Sas 	SMB_COM_ENTRY(0x96, "?"),
3536537f381Sas 	SMB_COM_ENTRY(0x97, "?"),
3546537f381Sas 	SMB_COM_ENTRY(0x98, "?"),
3556537f381Sas 	SMB_COM_ENTRY(0x99, "?"),
3566537f381Sas 	SMB_COM_ENTRY(0x9A, "?"),
3576537f381Sas 	SMB_COM_ENTRY(0x9B, "?"),
3586537f381Sas 	SMB_COM_ENTRY(0x9C, "?"),
3596537f381Sas 	SMB_COM_ENTRY(0x9D, "?"),
3606537f381Sas 	SMB_COM_ENTRY(0x9E, "?"),
3616537f381Sas 	SMB_COM_ENTRY(0x9F, "?"),
3626537f381Sas 	SMB_COM_ENTRY(SMB_COM_NT_TRANSACT, "No"),
3636537f381Sas 	SMB_COM_ENTRY(SMB_COM_NT_TRANSACT_SECONDARY, "No"),
3646537f381Sas 	SMB_COM_ENTRY(SMB_COM_NT_CREATE_ANDX, "No"),
365fc724630SAlan Wright 	SMB_COM_ENTRY(0xA3, "?"),
3666537f381Sas 	SMB_COM_ENTRY(SMB_COM_NT_CANCEL, "No"),
3676537f381Sas 	SMB_COM_ENTRY(SMB_COM_NT_RENAME, "No"),
3686537f381Sas 	SMB_COM_ENTRY(0xA6, "?"),
3696537f381Sas 	SMB_COM_ENTRY(0xA7, "?"),
3706537f381Sas 	SMB_COM_ENTRY(0xA8, "?"),
3716537f381Sas 	SMB_COM_ENTRY(0xA9, "?"),
3726537f381Sas 	SMB_COM_ENTRY(0xAA, "?"),
3736537f381Sas 	SMB_COM_ENTRY(0xAB, "?"),
3746537f381Sas 	SMB_COM_ENTRY(0xAC, "?"),
3756537f381Sas 	SMB_COM_ENTRY(0xAD, "?"),
3766537f381Sas 	SMB_COM_ENTRY(0xAE, "?"),
3776537f381Sas 	SMB_COM_ENTRY(0xAF, "?"),
3786537f381Sas 	SMB_COM_ENTRY(0xB0, "?"),
3796537f381Sas 	SMB_COM_ENTRY(0xB1, "?"),
3806537f381Sas 	SMB_COM_ENTRY(0xB2, "?"),
3816537f381Sas 	SMB_COM_ENTRY(0xB3, "?"),
3826537f381Sas 	SMB_COM_ENTRY(0xB4, "?"),
3836537f381Sas 	SMB_COM_ENTRY(0xB5, "?"),
3846537f381Sas 	SMB_COM_ENTRY(0xB6, "?"),
3856537f381Sas 	SMB_COM_ENTRY(0xB7, "?"),
3866537f381Sas 	SMB_COM_ENTRY(0xB8, "?"),
3876537f381Sas 	SMB_COM_ENTRY(0xB9, "?"),
3886537f381Sas 	SMB_COM_ENTRY(0xBA, "?"),
3896537f381Sas 	SMB_COM_ENTRY(0xBB, "?"),
3906537f381Sas 	SMB_COM_ENTRY(0xBC, "?"),
3916537f381Sas 	SMB_COM_ENTRY(0xBD, "?"),
3926537f381Sas 	SMB_COM_ENTRY(0xBE, "?"),
3936537f381Sas 	SMB_COM_ENTRY(0xBF, "?"),
3946537f381Sas 	SMB_COM_ENTRY(SMB_COM_OPEN_PRINT_FILE, "No"),
3956537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_PRINT_FILE, "No"),
3966537f381Sas 	SMB_COM_ENTRY(SMB_COM_CLOSE_PRINT_FILE, "No"),
3976537f381Sas 	SMB_COM_ENTRY(SMB_COM_GET_PRINT_QUEUE, "No"),
3986537f381Sas 	SMB_COM_ENTRY(0xC4, "?"),
3996537f381Sas 	SMB_COM_ENTRY(0xC5, "?"),
4006537f381Sas 	SMB_COM_ENTRY(0xC6, "?"),
4016537f381Sas 	SMB_COM_ENTRY(0xC7, "?"),
4026537f381Sas 	SMB_COM_ENTRY(0xC8, "?"),
4036537f381Sas 	SMB_COM_ENTRY(0xC9, "?"),
4046537f381Sas 	SMB_COM_ENTRY(0xCA, "?"),
4056537f381Sas 	SMB_COM_ENTRY(0xCB, "?"),
4066537f381Sas 	SMB_COM_ENTRY(0xCC, "?"),
4076537f381Sas 	SMB_COM_ENTRY(0xCD, "?"),
4086537f381Sas 	SMB_COM_ENTRY(0xCE, "?"),
4096537f381Sas 	SMB_COM_ENTRY(0xCF, "?"),
4106537f381Sas 	SMB_COM_ENTRY(0xD0, "?"),
4116537f381Sas 	SMB_COM_ENTRY(0xD1, "?"),
4126537f381Sas 	SMB_COM_ENTRY(0xD2, "?"),
4136537f381Sas 	SMB_COM_ENTRY(0xD3, "?"),
4146537f381Sas 	SMB_COM_ENTRY(0xD4, "?"),
4156537f381Sas 	SMB_COM_ENTRY(0xD5, "?"),
4166537f381Sas 	SMB_COM_ENTRY(0xD6, "?"),
4176537f381Sas 	SMB_COM_ENTRY(0xD7, "?"),
4186537f381Sas 	SMB_COM_ENTRY(SMB_COM_READ_BULK, "No"),
4196537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_BULK, "No"),
4206537f381Sas 	SMB_COM_ENTRY(SMB_COM_WRITE_BULK_DATA, "No"),
4216537f381Sas 	SMB_COM_ENTRY(0xDB, "?"),
4226537f381Sas 	SMB_COM_ENTRY(0xDC, "?"),
423fc724630SAlan Wright 	SMB_COM_ENTRY(0xDD, "?"),
4246537f381Sas 	SMB_COM_ENTRY(0xDE, "?"),
4256537f381Sas 	SMB_COM_ENTRY(0xDF, "?"),
4266537f381Sas 	SMB_COM_ENTRY(0xE0, "?"),
4276537f381Sas 	SMB_COM_ENTRY(0xE1, "?"),
4286537f381Sas 	SMB_COM_ENTRY(0xE2, "?"),
4296537f381Sas 	SMB_COM_ENTRY(0xE3, "?"),
4306537f381Sas 	SMB_COM_ENTRY(0xE4, "?"),
4316537f381Sas 	SMB_COM_ENTRY(0xE5, "?"),
4326537f381Sas 	SMB_COM_ENTRY(0xE6, "?"),
4336537f381Sas 	SMB_COM_ENTRY(0xE7, "?"),
4346537f381Sas 	SMB_COM_ENTRY(0xE8, "?"),
4356537f381Sas 	SMB_COM_ENTRY(0xE9, "?"),
4366537f381Sas 	SMB_COM_ENTRY(0xEA, "?"),
4376537f381Sas 	SMB_COM_ENTRY(0xEB, "?"),
4386537f381Sas 	SMB_COM_ENTRY(0xEC, "?"),
4396537f381Sas 	SMB_COM_ENTRY(0xED, "?"),
4406537f381Sas 	SMB_COM_ENTRY(0xEE, "?"),
4416537f381Sas 	SMB_COM_ENTRY(0xEF, "?"),
4426537f381Sas 	SMB_COM_ENTRY(0xF0, "?"),
4436537f381Sas 	SMB_COM_ENTRY(0xF1, "?"),
4446537f381Sas 	SMB_COM_ENTRY(0xF2, "?"),
4456537f381Sas 	SMB_COM_ENTRY(0xF3, "?"),
4466537f381Sas 	SMB_COM_ENTRY(0xF4, "?"),
4476537f381Sas 	SMB_COM_ENTRY(0xF5, "?"),
4486537f381Sas 	SMB_COM_ENTRY(0xF6, "?"),
4496537f381Sas 	SMB_COM_ENTRY(0xF7, "?"),
4506537f381Sas 	SMB_COM_ENTRY(0xF8, "?"),
4516537f381Sas 	SMB_COM_ENTRY(0xF9, "?"),
4526537f381Sas 	SMB_COM_ENTRY(0xFA, "?"),
4536537f381Sas 	SMB_COM_ENTRY(0xFB, "?"),
4546537f381Sas 	SMB_COM_ENTRY(0xFC, "?"),
4556537f381Sas 	SMB_COM_ENTRY(0xFD, "?"),
4566537f381Sas 	SMB_COM_ENTRY(0xFE, "?"),
4576537f381Sas 	SMB_COM_ENTRY(0xFF, "?")
4586537f381Sas };
4596537f381Sas 
460a90cf9f2SGordon Ross static const char *smb2_cmd_names[SMB2__NCMDS] = {
461a90cf9f2SGordon Ross 	"smb2_negotiate",
462a90cf9f2SGordon Ross 	"smb2_session_setup",
463a90cf9f2SGordon Ross 	"smb2_logoff",
464a90cf9f2SGordon Ross 	"smb2_tree_connect",
465a90cf9f2SGordon Ross 	"smb2_tree_disconn",
466a90cf9f2SGordon Ross 	"smb2_create",
467a90cf9f2SGordon Ross 	"smb2_close",
468a90cf9f2SGordon Ross 	"smb2_flush",
469a90cf9f2SGordon Ross 	"smb2_read",
470a90cf9f2SGordon Ross 	"smb2_write",
471a90cf9f2SGordon Ross 	"smb2_lock",
472a90cf9f2SGordon Ross 	"smb2_ioctl",
473a90cf9f2SGordon Ross 	"smb2_cancel",
474a90cf9f2SGordon Ross 	"smb2_echo",
475a90cf9f2SGordon Ross 	"smb2_query_dir",
476a90cf9f2SGordon Ross 	"smb2_change_notify",
477a90cf9f2SGordon Ross 	"smb2_query_info",
478a90cf9f2SGordon Ross 	"smb2_set_info",
479a90cf9f2SGordon Ross 	"smb2_oplock_break",
480a90cf9f2SGordon Ross 	"smb2_invalid_cmd"
481a90cf9f2SGordon Ross };
482a90cf9f2SGordon Ross 
48394047d49SGordon Ross struct mdb_smb_oplock;
48494047d49SGordon Ross 
4856537f381Sas static int smb_sid_print(uintptr_t);
4866537f381Sas static int smb_dcmd_getopt(uint_t *, int, const mdb_arg_t *);
4876537f381Sas static int smb_dcmd_setopt(uint_t, int, mdb_arg_t *);
4886537f381Sas static int smb_obj_expand(uintptr_t, uint_t, const smb_exp_t *, ulong_t);
4896537f381Sas static int smb_obj_list(const char *, uint_t, uint_t);
490fc724630SAlan Wright static int smb_worker_findstack(uintptr_t);
49194047d49SGordon Ross static int smb_node_get_oplock(uintptr_t, struct mdb_smb_oplock **);
49294047d49SGordon Ross static int smb_node_oplock_cnt(struct mdb_smb_oplock *);
493764c8bd8SGordon Ross static void smb_inaddr_ntop(smb_inaddr_t *, char *, size_t);
494bd49ed45SGordon Ross static void get_enum(char *, size_t, const char *, int, const char *);
495764c8bd8SGordon Ross 
496764c8bd8SGordon Ross typedef int (*dump_func_t)(struct mbuf_chain *, int32_t,
497764c8bd8SGordon Ross     smb_inaddr_t *, uint16_t, smb_inaddr_t *, uint16_t,
498764c8bd8SGordon Ross     hrtime_t, boolean_t);
499764c8bd8SGordon Ross static int smb_req_dump(struct mbuf_chain *, int32_t,
500764c8bd8SGordon Ross     smb_inaddr_t *, uint16_t, smb_inaddr_t *, uint16_t,
501764c8bd8SGordon Ross     hrtime_t, boolean_t);
502764c8bd8SGordon Ross static int smb_req_dump_m(uintptr_t, const void *, void *);
503da6c28aaSamw 
5046537f381Sas /*
5056537f381Sas  * *****************************************************************************
5066537f381Sas  * ****************************** Top level DCMD *******************************
5076537f381Sas  * *****************************************************************************
5086537f381Sas  */
5096537f381Sas 
5106537f381Sas static void
smblist_help(void)5112b8c497cSGordon Ross smblist_help(void)
512faa1795aSjb {
5136537f381Sas 	mdb_printf(
5146537f381Sas 	    "Displays the list of objects using an indented tree format.\n"
5156537f381Sas 	    "If no option is specified the entire tree is displayed\n\n");
5166537f381Sas 	(void) mdb_dec_indent(2);
5176537f381Sas 	mdb_printf("%<b>OPTIONS%</b>\n");
5186537f381Sas 	(void) mdb_inc_indent(2);
5196537f381Sas 	mdb_printf(
5206537f381Sas 	    "-v\tDisplay verbose information\n"
5216537f381Sas 	    "-s\tDisplay the list of servers\n"
5226537f381Sas 	    "-e\tDisplay the list of sessions\n"
5236537f381Sas 	    "-r\tDisplay the list of smb requests\n"
5246537f381Sas 	    "-u\tDisplay the list of users\n"
5256537f381Sas 	    "-t\tDisplay the list of trees\n"
5266537f381Sas 	    "-f\tDisplay the list of open files\n"
5276537f381Sas 	    "-d\tDisplay the list of open searches\n");
528faa1795aSjb }
529faa1795aSjb 
5306537f381Sas /*
5316537f381Sas  * ::smblist
5326537f381Sas  *
5336537f381Sas  * This function lists the objects specified on the command line. If no object
5346537f381Sas  * is specified the entire tree (server through ofile and odir) is displayed.
5356537f381Sas  *
5366537f381Sas  */
5376537f381Sas /*ARGSUSED*/
538faa1795aSjb static int
smblist_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5392b8c497cSGordon Ross smblist_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
540faa1795aSjb {
5416537f381Sas 	GElf_Sym	sym;
5426537f381Sas 	uint_t		opts = 0;
5436537f381Sas 	int		new_argc;
5446537f381Sas 	mdb_arg_t	new_argv[SMB_MDB_MAX_OPTS];
545bd49ed45SGordon Ross 	int		ll_off;
5466537f381Sas 
5476537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
5486537f381Sas 		return (DCMD_USAGE);
5496537f381Sas 
5506537f381Sas 	if (!(opts & ~(SMB_OPT_WALK | SMB_OPT_VERBOSE)))
5516537f381Sas 		opts |= SMB_OPT_ALL_OBJ;
5526537f381Sas 
5536537f381Sas 	opts |= SMB_OPT_WALK;
5546537f381Sas 
5556537f381Sas 	new_argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, new_argv);
5566537f381Sas 
557b819cea2SGordon Ross 	if (mdb_lookup_by_obj(SMBSRV_OBJNAME, "smb_servers", &sym) == -1) {
5586537f381Sas 		mdb_warn("failed to find symbol smb_servers");
5596537f381Sas 		return (DCMD_ERR);
5606537f381Sas 	}
5616537f381Sas 
562bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
563bd49ed45SGordon Ross 	addr = (uintptr_t)sym.st_value + ll_off;
5646537f381Sas 
565b819cea2SGordon Ross 	if (mdb_pwalk_dcmd("list", "smbsrv", new_argc, new_argv, addr)) {
566b819cea2SGordon Ross 		mdb_warn("cannot walk smb_server list");
5676537f381Sas 		return (DCMD_ERR);
568b819cea2SGordon Ross 	}
5696537f381Sas 	return (DCMD_OK);
570faa1795aSjb }
571faa1795aSjb 
5726537f381Sas /*
5736537f381Sas  * *****************************************************************************
5746537f381Sas  * ***************************** smb_server_t **********************************
5756537f381Sas  * *****************************************************************************
5766537f381Sas  */
5776537f381Sas 
578bd49ed45SGordon Ross typedef struct mdb_smb_server {
579bd49ed45SGordon Ross 	smb_server_state_t	sv_state;
580bd49ed45SGordon Ross 	zoneid_t		sv_zid;
581811599a4SMatt Barden 	smb_hash_t		*sv_persistid_ht;
582bd49ed45SGordon Ross } mdb_smb_server_t;
583bd49ed45SGordon Ross 
584811599a4SMatt Barden static int
smb_server_exp_off_sv_list(void)585811599a4SMatt Barden smb_server_exp_off_sv_list(void)
586811599a4SMatt Barden {
587811599a4SMatt Barden 	int svl_off, ll_off;
588811599a4SMatt Barden 
589811599a4SMatt Barden 	/* OFFSETOF(smb_server_t, sv_session_list.ll_list); */
590811599a4SMatt Barden 	GET_OFFSET(svl_off, smb_server_t, sv_session_list);
591811599a4SMatt Barden 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
592811599a4SMatt Barden 	return (svl_off + ll_off);
593811599a4SMatt Barden }
594811599a4SMatt Barden 
595bd49ed45SGordon Ross static int
smb_server_exp_off_nbt_list(void)596bd49ed45SGordon Ross smb_server_exp_off_nbt_list(void)
5976537f381Sas {
598bd49ed45SGordon Ross 	int svd_off, lds_off, ll_off;
599bd49ed45SGordon Ross 
600bd49ed45SGordon Ross 	/* OFFSETOF(smb_server_t, sv_nbt_daemon.ld_session_list.ll_list); */
601bd49ed45SGordon Ross 	GET_OFFSET(svd_off, smb_server_t, sv_nbt_daemon);
602811599a4SMatt Barden 	/*
603811599a4SMatt Barden 	 * We can't do OFFSETOF() because the member doesn't exist,
604811599a4SMatt Barden 	 * but we want backwards compatibility to old cores
605811599a4SMatt Barden 	 */
606811599a4SMatt Barden 	lds_off = mdb_ctf_offsetof_by_name("smb_listener_daemon_t",
607811599a4SMatt Barden 	    "ld_session_list");
608811599a4SMatt Barden 	if (lds_off < 0) {
609811599a4SMatt Barden 		mdb_warn("cannot lookup: "
61094047d49SGordon Ross 		    "smb_listener_daemon_t .ld_session_list");
611811599a4SMatt Barden 		return (-1);
612811599a4SMatt Barden 	}
613bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
614bd49ed45SGordon Ross 	return (svd_off + lds_off + ll_off);
615bd49ed45SGordon Ross }
616bd49ed45SGordon Ross 
617bd49ed45SGordon Ross static int
smb_server_exp_off_tcp_list(void)618bd49ed45SGordon Ross smb_server_exp_off_tcp_list(void)
619bd49ed45SGordon Ross {
620bd49ed45SGordon Ross 	int svd_off, lds_off, ll_off;
621bd49ed45SGordon Ross 
622bd49ed45SGordon Ross 	/* OFFSETOF(smb_server_t, sv_tcp_daemon.ld_session_list.ll_list); */
623bd49ed45SGordon Ross 	GET_OFFSET(svd_off, smb_server_t, sv_tcp_daemon);
624811599a4SMatt Barden 	/*
625811599a4SMatt Barden 	 * We can't do OFFSETOF() because the member doesn't exist,
626811599a4SMatt Barden 	 * but we want backwards compatibility to old cores
627811599a4SMatt Barden 	 */
628811599a4SMatt Barden 	lds_off = mdb_ctf_offsetof_by_name("smb_listener_daemon_t",
629811599a4SMatt Barden 	    "ld_session_list");
630811599a4SMatt Barden 	if (lds_off < 0) {
631811599a4SMatt Barden 		mdb_warn("cannot lookup: "
63294047d49SGordon Ross 		    "smb_listener_daemon_t .ld_session_list");
633811599a4SMatt Barden 		return (-1);
634811599a4SMatt Barden 	}
635bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
636bd49ed45SGordon Ross 	return (svd_off + lds_off + ll_off);
637bd49ed45SGordon Ross }
6386537f381Sas 
6396537f381Sas /*
6406537f381Sas  * List of objects that can be expanded under a server structure.
6416537f381Sas  */
6426537f381Sas static const smb_exp_t smb_server_exp[] =
643811599a4SMatt Barden {
644*2cf6b79fSGordon Ross 	{ SMB_OPT_ALL_OBJ, "list",
645811599a4SMatt Barden 	    smb_server_exp_off_sv_list,
646811599a4SMatt Barden 	    "smbsess", "smb_session"},
647*2cf6b79fSGordon Ross 	{ 0 }
648811599a4SMatt Barden };
649811599a4SMatt Barden 
650811599a4SMatt Barden /* for backwards compatibility only */
651811599a4SMatt Barden static const smb_exp_t smb_server_exp_old[] =
6526537f381Sas {
653*2cf6b79fSGordon Ross 	{ SMB_OPT_ALL_OBJ, "list",
654bd49ed45SGordon Ross 	    smb_server_exp_off_nbt_list,
6556537f381Sas 	    "smbsess", "smb_session"},
656*2cf6b79fSGordon Ross 	{ SMB_OPT_ALL_OBJ, "list",
657bd49ed45SGordon Ross 	    smb_server_exp_off_tcp_list,
6586537f381Sas 	    "smbsess", "smb_session"},
659*2cf6b79fSGordon Ross 	{ 0 }
6606537f381Sas };
6616537f381Sas 
6626537f381Sas /*
6636537f381Sas  * ::smbsrv
6646537f381Sas  *
6656537f381Sas  * smbsrv dcmd - Print out smb_server structures.
6666537f381Sas  */
6676537f381Sas /*ARGSUSED*/
668faa1795aSjb static int
smbsrv_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6692b8c497cSGordon Ross smbsrv_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
670faa1795aSjb {
6716537f381Sas 	uint_t		opts;
6726537f381Sas 	ulong_t		indent = 0;
673811599a4SMatt Barden 	const smb_exp_t	*sv_exp;
674811599a4SMatt Barden 	mdb_ctf_id_t id;
675811599a4SMatt Barden 	ulong_t off;
6766537f381Sas 
6776537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
6786537f381Sas 		return (DCMD_USAGE);
6796537f381Sas 
6806537f381Sas 	if (!(flags & DCMD_ADDRSPEC))
6816537f381Sas 		return (smb_obj_list("smb_server", opts | SMB_OPT_SERVER,
6826537f381Sas 		    flags));
6836537f381Sas 
6846537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SERVER)) ||
6856537f381Sas 	    !(opts & SMB_OPT_WALK)) {
686bd49ed45SGordon Ross 		mdb_smb_server_t *sv;
687bd49ed45SGordon Ross 		char state[40];
6886537f381Sas 
689bd49ed45SGordon Ross 		sv = mdb_zalloc(sizeof (*sv), UM_SLEEP | UM_GC);
690bd49ed45SGordon Ross 		if (mdb_ctf_vread(sv, SMBSRV_SCOPE "smb_server_t",
691bd49ed45SGordon Ross 		    "mdb_smb_server_t", addr, 0) < 0) {
6926537f381Sas 			mdb_warn("failed to read smb_server at %p", addr);
6936537f381Sas 			return (DCMD_ERR);
6946537f381Sas 		}
6956537f381Sas 
6966537f381Sas 		indent = SMB_DCMD_INDENT;
6976537f381Sas 
6986537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
6996537f381Sas 			mdb_arg_t	argv;
7006537f381Sas 
7016537f381Sas 			argv.a_type = MDB_TYPE_STRING;
7026537f381Sas 			argv.a_un.a_str = "smb_server_t";
7036537f381Sas 			if (mdb_call_dcmd("print", addr, flags, 1, &argv))
7046537f381Sas 				return (DCMD_ERR);
7056537f381Sas 		} else {
7066537f381Sas 			if (DCMD_HDRSPEC(flags))
7076537f381Sas 				mdb_printf(
7086537f381Sas 				    "%<b>%<u>%-?s% "
7096537f381Sas 				    "%-4s% "
7106537f381Sas 				    "%-32s% "
711148c5f43SAlan Wright 				    "%</u>%</b>\n",
712148c5f43SAlan Wright 				    "SERVER", "ZONE", "STATE");
7136537f381Sas 
714bd49ed45SGordon Ross 			get_enum(state, sizeof (state),
715bd49ed45SGordon Ross 			    "smb_server_state_t", sv->sv_state,
716bd49ed45SGordon Ross 			    "SMB_SERVER_STATE_");
7176537f381Sas 
718148c5f43SAlan Wright 			mdb_printf("%-?p %-4d %-32s \n",
719148c5f43SAlan Wright 			    addr, sv->sv_zid, state);
7206537f381Sas 		}
7216537f381Sas 	}
722811599a4SMatt Barden 
723811599a4SMatt Barden 	/* if we can't look up the type name, just error out */
724811599a4SMatt Barden 	if (mdb_ctf_lookup_by_name("smb_server_t", &id) == -1)
725811599a4SMatt Barden 		return (DCMD_ERR);
726811599a4SMatt Barden 
727811599a4SMatt Barden 	if (mdb_ctf_offsetof(id, "sv_session_list", &off) == -1)
728811599a4SMatt Barden 		/* sv_session_list doesn't exist; old core */
729811599a4SMatt Barden 		sv_exp = smb_server_exp_old;
730811599a4SMatt Barden 	else
731811599a4SMatt Barden 		sv_exp = smb_server_exp;
732811599a4SMatt Barden 
733811599a4SMatt Barden 	if (smb_obj_expand(addr, opts, sv_exp, indent))
7346537f381Sas 		return (DCMD_ERR);
7356537f381Sas 	return (DCMD_OK);
736faa1795aSjb }
737faa1795aSjb 
7386537f381Sas /*
7396537f381Sas  * *****************************************************************************
7406537f381Sas  * ***************************** smb_session_t *********************************
7416537f381Sas  * *****************************************************************************
7426537f381Sas  */
7436537f381Sas 
7443cc23d49SGordon Ross /*
7453cc23d49SGordon Ross  * After some changes merged from upstream, "::smblist" was failing with
7463cc23d49SGordon Ross  * "inexact match for union au_addr (au_addr)" because the CTF data for
7473cc23d49SGordon Ross  * the target vs mdb were apparently not exactly the same (unknown why).
7483cc23d49SGordon Ross  *
7493cc23d49SGordon Ross  * As described above mdb_ctf_vread(), the recommended way to read a
7503cc23d49SGordon Ross  * union is to use an mdb struct with only the union "arm" appropriate
7513cc23d49SGordon Ross  * to the given type instance.  That's difficult in this case, so we
7523cc23d49SGordon Ross  * use a local union with only the in6_addr_t union arm (otherwise
7533cc23d49SGordon Ross  * identical to smb_inaddr_t) and just cast it to an smb_inaddr_t
7543cc23d49SGordon Ross  */
7553cc23d49SGordon Ross 
7563cc23d49SGordon Ross typedef struct mdb_smb_inaddr {
7573cc23d49SGordon Ross 	union {
7583cc23d49SGordon Ross #if 0	/* The real smb_inaddr_t has these too. */
7593cc23d49SGordon Ross 		in_addr_t au_ipv4;
7603cc23d49SGordon Ross 		in6_addr_t au_ipv6;
7613cc23d49SGordon Ross #endif
7623cc23d49SGordon Ross 		in6_addr_t au_ip;
7633cc23d49SGordon Ross 	} au_addr;
7643cc23d49SGordon Ross 	int a_family;
7653cc23d49SGordon Ross } mdb_smb_inaddr_t;
7663cc23d49SGordon Ross 
767bd49ed45SGordon Ross typedef struct mdb_smb_session {
768bd49ed45SGordon Ross 	uint64_t		s_kid;
769bd49ed45SGordon Ross 	smb_session_state_t	s_state;
770bd49ed45SGordon Ross 	uint32_t		s_flags;
771bd49ed45SGordon Ross 	uint16_t		s_local_port;
772bd49ed45SGordon Ross 	uint16_t		s_remote_port;
7733cc23d49SGordon Ross 	mdb_smb_inaddr_t	ipaddr;
7743cc23d49SGordon Ross 	mdb_smb_inaddr_t	local_ipaddr;
775bd49ed45SGordon Ross 	int			dialect;
776bd49ed45SGordon Ross 
777bd49ed45SGordon Ross 	smb_slist_t		s_req_list;
778bd49ed45SGordon Ross 	smb_llist_t		s_xa_list;
779bd49ed45SGordon Ross 	smb_llist_t		s_user_list;
780bd49ed45SGordon Ross 	smb_llist_t		s_tree_list;
781bd49ed45SGordon Ross 
782bd49ed45SGordon Ross 	volatile uint32_t	s_tree_cnt;
783bd49ed45SGordon Ross 	volatile uint32_t	s_file_cnt;
784bd49ed45SGordon Ross 	volatile uint32_t	s_dir_cnt;
785bd49ed45SGordon Ross 
78694047d49SGordon Ross 	char			workstation[SMB_PI_MAX_HOST];
787bd49ed45SGordon Ross } mdb_smb_session_t;
788bd49ed45SGordon Ross 
789bd49ed45SGordon Ross static int
smb_session_exp_off_req_list(void)790bd49ed45SGordon Ross smb_session_exp_off_req_list(void)
7916537f381Sas {
792bd49ed45SGordon Ross 	int rl_off, sl_off;
793bd49ed45SGordon Ross 
794bd49ed45SGordon Ross 	/* OFFSETOF(smb_session_t, s_req_list.sl_list); */
795bd49ed45SGordon Ross 	GET_OFFSET(rl_off, smb_session_t, s_req_list);
796bd49ed45SGordon Ross 	GET_OFFSET(sl_off, smb_slist_t, sl_list);
797bd49ed45SGordon Ross 	return (rl_off + sl_off);
798bd49ed45SGordon Ross }
799bd49ed45SGordon Ross 
800bd49ed45SGordon Ross static int
smb_session_exp_off_user_list(void)801bd49ed45SGordon Ross smb_session_exp_off_user_list(void)
802bd49ed45SGordon Ross {
803bd49ed45SGordon Ross 	int ul_off, ll_off;
804bd49ed45SGordon Ross 
805bd49ed45SGordon Ross 	/* OFFSETOF(smb_session_t, s_user_list.ll_list); */
806bd49ed45SGordon Ross 	GET_OFFSET(ul_off, smb_session_t, s_user_list);
807bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
808bd49ed45SGordon Ross 	return (ul_off + ll_off);
809bd49ed45SGordon Ross }
810bd49ed45SGordon Ross 
811bd49ed45SGordon Ross static int
smb_session_exp_off_tree_list(void)812bd49ed45SGordon Ross smb_session_exp_off_tree_list(void)
813bd49ed45SGordon Ross {
814bd49ed45SGordon Ross 	int tl_off, ll_off;
815bd49ed45SGordon Ross 
816bd49ed45SGordon Ross 	/* OFFSETOF(smb_session_t, s_tree_list.ll_list); */
817bd49ed45SGordon Ross 	GET_OFFSET(tl_off, smb_session_t, s_tree_list);
818bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
819bd49ed45SGordon Ross 	return (tl_off + ll_off);
820bd49ed45SGordon Ross }
8216537f381Sas 
8226537f381Sas /*
8236537f381Sas  * List of objects that can be expanded under a session structure.
8246537f381Sas  */
8256537f381Sas static const smb_exp_t smb_session_exp[] =
8266537f381Sas {
827*2cf6b79fSGordon Ross 	{ SMB_OPT_USER, "list",
828bd49ed45SGordon Ross 	    smb_session_exp_off_user_list,
8296537f381Sas 	    "smbuser", "smb_user"},
830*2cf6b79fSGordon Ross 	{ SMB_OPT_TREE | SMB_OPT_OFILE | SMB_OPT_ODIR, "list",
831bd49ed45SGordon Ross 	    smb_session_exp_off_tree_list,
8323b13a1efSThomas Keiser 	    "smbtree", "smb_tree"},
833*2cf6b79fSGordon Ross 	{ SMB_OPT_REQUEST, "list",
834bd49ed45SGordon Ross 	    smb_session_exp_off_req_list,
835bd49ed45SGordon Ross 	    "smbreq", "smb_request"},
836*2cf6b79fSGordon Ross 	{ 0 }
8376537f381Sas };
8386537f381Sas 
8396537f381Sas static void
smbsess_help(void)8402b8c497cSGordon Ross smbsess_help(void)
8416537f381Sas {
8426537f381Sas 	mdb_printf(
8436537f381Sas 	    "Display the contents of smb_session_t, with optional"
8446537f381Sas 	    " filtering.\n\n");
8456537f381Sas 	(void) mdb_dec_indent(2);
8466537f381Sas 	mdb_printf("%<b>OPTIONS%</b>\n");
8476537f381Sas 	(void) mdb_inc_indent(2);
8486537f381Sas 	mdb_printf(
8496537f381Sas 	    "-v\tDisplay verbose smb_session information\n"
8506537f381Sas 	    "-r\tDisplay the list of smb requests attached\n"
8516537f381Sas 	    "-u\tDisplay the list of users attached\n");
852da6c28aaSamw }
853da6c28aaSamw 
8546537f381Sas /*
8556537f381Sas  * ::smbsess
8566537f381Sas  *
8576537f381Sas  * smbsess dcmd - Print out the smb_session structure.
8586537f381Sas  */
859da6c28aaSamw static int
smbsess_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8602b8c497cSGordon Ross smbsess_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
861da6c28aaSamw {
8626537f381Sas 	uint_t		opts;
8636537f381Sas 	ulong_t		indent = 0;
8646537f381Sas 
8656537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
8666537f381Sas 		return (DCMD_USAGE);
8676537f381Sas 
8686537f381Sas 	if (!(flags & DCMD_ADDRSPEC)) {
8696537f381Sas 		opts |= SMB_OPT_SESSION;
8706537f381Sas 		opts &= ~SMB_OPT_SERVER;
8716537f381Sas 		return (smb_obj_list("smb_session", opts, flags));
8726537f381Sas 	}
8736537f381Sas 
8746537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SESSION)) ||
8756537f381Sas 	    !(opts & SMB_OPT_WALK)) {
876a90cf9f2SGordon Ross 		char	cipaddr[INET6_ADDRSTRLEN];
877a90cf9f2SGordon Ross 		char	lipaddr[INET6_ADDRSTRLEN];
878764c8bd8SGordon Ross 		int	ipaddrstrlen = INET6_ADDRSTRLEN;
879bd49ed45SGordon Ross 		mdb_smb_session_t *se;
880bd49ed45SGordon Ross 		char	state[40];
8816537f381Sas 
8826537f381Sas 		indent = SMB_DCMD_INDENT;
8836537f381Sas 
884bd49ed45SGordon Ross 		se = mdb_zalloc(sizeof (*se), UM_SLEEP | UM_GC);
885bd49ed45SGordon Ross 		if (mdb_ctf_vread(se, SMBSRV_SCOPE "smb_session_t",
886bd49ed45SGordon Ross 		    "mdb_smb_session_t", addr, 0) < 0) {
8876537f381Sas 			mdb_warn("failed to read smb_session at %p", addr);
8886537f381Sas 			return (DCMD_ERR);
8896537f381Sas 		}
890bd49ed45SGordon Ross 
891bd49ed45SGordon Ross 		get_enum(state, sizeof (state),
892bd49ed45SGordon Ross 		    "smb_session_state_t", se->s_state,
893bd49ed45SGordon Ross 		    "SMB_SESSION_STATE_");
8946537f381Sas 
8953cc23d49SGordon Ross 		smb_inaddr_ntop((smb_inaddr_t *)&se->ipaddr,
8963cc23d49SGordon Ross 		    cipaddr, ipaddrstrlen);
8973cc23d49SGordon Ross 		smb_inaddr_ntop((smb_inaddr_t *)&se->local_ipaddr,
8983cc23d49SGordon Ross 		    lipaddr, ipaddrstrlen);
899a90cf9f2SGordon Ross 
9006537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
9016537f381Sas 			mdb_printf("%<b>%<u>SMB session information "
9026537f381Sas 			    "(%p): %</u>%</b>\n", addr);
903a90cf9f2SGordon Ross 			mdb_printf("Client IP address: %s %d\n",
904a90cf9f2SGordon Ross 			    cipaddr, se->s_remote_port);
905a90cf9f2SGordon Ross 			mdb_printf("Local IP Address: %s %d\n",
906a90cf9f2SGordon Ross 			    lipaddr, se->s_local_port);
9076537f381Sas 			mdb_printf("Session KID: %u\n", se->s_kid);
9086537f381Sas 			mdb_printf("Workstation Name: %s\n",
9096537f381Sas 			    se->workstation);
9106537f381Sas 			mdb_printf("Session state: %u (%s)\n", se->s_state,
9116537f381Sas 			    state);
912a90cf9f2SGordon Ross 			mdb_printf("Session dialect: %#x\n", se->dialect);
9136537f381Sas 			mdb_printf("Number of Users: %u\n",
9146537f381Sas 			    se->s_user_list.ll_count);
9156537f381Sas 			mdb_printf("Number of Trees: %u\n", se->s_tree_cnt);
9166537f381Sas 			mdb_printf("Number of Files: %u\n", se->s_file_cnt);
9176537f381Sas 			mdb_printf("Number of Shares: %u\n", se->s_dir_cnt);
9186537f381Sas 			mdb_printf("Number of active Transact.: %u\n\n",
9196537f381Sas 			    se->s_xa_list.ll_count);
9206537f381Sas 		} else {
92146050536SGordon Ross 			/*
92246050536SGordon Ross 			 * Use a reasonable mininum field width for the
92346050536SGordon Ross 			 * IP addr so the summary (usually) won't wrap.
92446050536SGordon Ross 			 */
92546050536SGordon Ross 			int ipwidth = 22;
92646050536SGordon Ross 
92741610d10SYuri Pankov 			if (DCMD_HDRSPEC(flags)) {
9286537f381Sas 				mdb_printf(
929a90cf9f2SGordon Ross 			"%<b>%<u>%-?s %-*s %-8s %-8s %-12s%</u>%</b>\n",
93046050536SGordon Ross 				    "SESSION", ipwidth, "IP_ADDR",
931a90cf9f2SGordon Ross 				    "PORT", "DIALECT", "STATE");
93241610d10SYuri Pankov 			}
933a90cf9f2SGordon Ross 			mdb_printf("%-?p %-*s %-8d %-8#x %s\n",
93446050536SGordon Ross 			    addr, ipwidth, cipaddr,
935a90cf9f2SGordon Ross 			    se->s_remote_port, se->dialect, state);
9366537f381Sas 		}
9376537f381Sas 	}
9386537f381Sas 	if (smb_obj_expand(addr, opts, smb_session_exp, indent))
9396537f381Sas 		return (DCMD_ERR);
94094047d49SGordon Ross 
9416537f381Sas 	return (DCMD_OK);
942da6c28aaSamw }
943da6c28aaSamw 
944da6c28aaSamw /*
9456537f381Sas  * *****************************************************************************
9466537f381Sas  * **************************** smb_request_t **********************************
9476537f381Sas  * *****************************************************************************
948da6c28aaSamw  */
9496537f381Sas 
950bd49ed45SGordon Ross typedef struct mdb_smb_request {
951bd49ed45SGordon Ross 	smb_req_state_t		sr_state;
952bd49ed45SGordon Ross 	smb_session_t		*session;
953bd49ed45SGordon Ross 	struct mbuf_chain	command;
954bd49ed45SGordon Ross 	struct mbuf_chain	reply;
955bd49ed45SGordon Ross 
956bd49ed45SGordon Ross 	unsigned char		first_smb_com;
957bd49ed45SGordon Ross 	unsigned char		smb_com;
958bd49ed45SGordon Ross 
959bd49ed45SGordon Ross 	uint16_t		smb_tid;
960bd49ed45SGordon Ross 	uint32_t		smb_pid;
961bd49ed45SGordon Ross 	uint16_t		smb_uid;
962bd49ed45SGordon Ross 	uint16_t		smb_mid;
963bd49ed45SGordon Ross 	uint16_t		smb_fid;
964bd49ed45SGordon Ross 
965811599a4SMatt Barden 	uint16_t		smb2_cmd_code;
966811599a4SMatt Barden 	uint64_t		smb2_messageid;
967811599a4SMatt Barden 	uint64_t		smb2_ssnid;
968811599a4SMatt Barden 
969bd49ed45SGordon Ross 	struct smb_tree		*tid_tree;
970bd49ed45SGordon Ross 	struct smb_ofile	*fid_ofile;
971bd49ed45SGordon Ross 	smb_user_t		*uid_user;
972bd49ed45SGordon Ross 
973bd49ed45SGordon Ross 	kthread_t		*sr_worker;
974bd49ed45SGordon Ross 	hrtime_t		sr_time_submitted;
975bd49ed45SGordon Ross 	hrtime_t		sr_time_active;
976bd49ed45SGordon Ross 	hrtime_t		sr_time_start;
977bd49ed45SGordon Ross 
978bd49ed45SGordon Ross } mdb_smb_request_t;
9796537f381Sas 
980148c5f43SAlan Wright #define	SMB_REQUEST_BANNER	\
981bd49ed45SGordon Ross 	"%<b>%<u>%-?s %-14s %-?s %-16s %-16s%</u>%</b>\n"
982148c5f43SAlan Wright #define	SMB_REQUEST_FORMAT	\
983bd49ed45SGordon Ross 	"%-?p 0x%-12llx %-?p %-16s %s\n"
984148c5f43SAlan Wright 
985bd49ed45SGordon Ross /*
986bd49ed45SGordon Ross  * ::smbreq
987bd49ed45SGordon Ross  *
988bd49ed45SGordon Ross  * smbreq dcmd - Print out smb_request_t
989bd49ed45SGordon Ross  */
990da6c28aaSamw static int
smbreq_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)9912b8c497cSGordon Ross smbreq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
992da6c28aaSamw {
9936537f381Sas 	uint_t		opts;
994da6c28aaSamw 
9956537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
9966537f381Sas 		return (DCMD_USAGE);
9976537f381Sas 
9986537f381Sas 	if (!(flags & DCMD_ADDRSPEC)) {
9996537f381Sas 		opts |= SMB_OPT_REQUEST;
10006537f381Sas 		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_USER);
10016537f381Sas 		return (smb_obj_list("smb_request", opts, flags));
10026537f381Sas 	}
10036537f381Sas 
10046537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_REQUEST)) ||
10056537f381Sas 	    !(opts & SMB_OPT_WALK)) {
1006bd49ed45SGordon Ross 		mdb_smb_request_t *sr;
1007bd49ed45SGordon Ross 		char		state[40];
1008a90cf9f2SGordon Ross 		const char	*cur_cmd_name;
1009a90cf9f2SGordon Ross 		uint_t		cur_cmd_code;
1010bd49ed45SGordon Ross 		uint64_t	msg_id;
10116537f381Sas 
1012bd49ed45SGordon Ross 		sr = mdb_zalloc(sizeof (*sr), UM_SLEEP | UM_GC);
1013bd49ed45SGordon Ross 		if (mdb_ctf_vread(sr, SMBSRV_SCOPE "smb_request_t",
1014bd49ed45SGordon Ross 		    "mdb_smb_request_t", addr, 0) < 0) {
10156537f381Sas 			mdb_warn("failed to read smb_request at %p", addr);
10166537f381Sas 			return (DCMD_ERR);
10176537f381Sas 		}
10186537f381Sas 
1019bd49ed45SGordon Ross 		get_enum(state, sizeof (state),
1020bd49ed45SGordon Ross 		    "smb_req_state_t", sr->sr_state,
1021bd49ed45SGordon Ross 		    "SMB_REQ_STATE_");
10226537f381Sas 
1023a90cf9f2SGordon Ross 		if (sr->smb2_cmd_code != 0) {
1024a90cf9f2SGordon Ross 			/* SMB2 request */
1025a90cf9f2SGordon Ross 			cur_cmd_code = sr->smb2_cmd_code;
1026a90cf9f2SGordon Ross 			if (cur_cmd_code > SMB2_INVALID_CMD)
1027a90cf9f2SGordon Ross 				cur_cmd_code = SMB2_INVALID_CMD;
1028a90cf9f2SGordon Ross 			cur_cmd_name = smb2_cmd_names[cur_cmd_code];
1029bd49ed45SGordon Ross 			msg_id = sr->smb2_messageid;
1030a90cf9f2SGordon Ross 		} else {
1031a90cf9f2SGordon Ross 			/* SMB1 request */
1032a90cf9f2SGordon Ross 			cur_cmd_code = sr->smb_com & 0xFF;
1033a90cf9f2SGordon Ross 			cur_cmd_name = smb_com[cur_cmd_code].smb_com;
1034bd49ed45SGordon Ross 			msg_id = sr->smb_mid;
1035a90cf9f2SGordon Ross 		}
1036a90cf9f2SGordon Ross 
10376537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
10386537f381Sas 			mdb_printf(
1039fc724630SAlan Wright 			    "%</b>%</u>SMB request information (%p):"
10406537f381Sas 			    "%</u>%</b>\n\n", addr);
1041148c5f43SAlan Wright 
1042a90cf9f2SGordon Ross 			if (sr->smb2_cmd_code == 0) {
1043a90cf9f2SGordon Ross 				/* SMB1 request */
1044a90cf9f2SGordon Ross 				mdb_printf(
1045a90cf9f2SGordon Ross 				    "first SMB COM: %u (%s)\n",
1046a90cf9f2SGordon Ross 				    sr->first_smb_com,
1047a90cf9f2SGordon Ross 				    smb_com[sr->first_smb_com].smb_com);
1048a90cf9f2SGordon Ross 			}
1049a90cf9f2SGordon Ross 
1050a90cf9f2SGordon Ross 			mdb_printf(
1051a90cf9f2SGordon Ross 			    "current SMB COM: %u (%s)\n",
1052a90cf9f2SGordon Ross 			    cur_cmd_code, cur_cmd_name);
1053a90cf9f2SGordon Ross 
1054a90cf9f2SGordon Ross 			mdb_printf(
1055a90cf9f2SGordon Ross 			    "state: %u (%s)\n",
1056a90cf9f2SGordon Ross 			    sr->sr_state, state);
1057a90cf9f2SGordon Ross 
1058811599a4SMatt Barden 			if (sr->smb2_ssnid != 0) {
1059811599a4SMatt Barden 				mdb_printf(
1060811599a4SMatt Barden 				    "SSNID(user): 0x%llx (%p)\n",
1061811599a4SMatt Barden 				    sr->smb2_ssnid, sr->uid_user);
1062811599a4SMatt Barden 			} else {
1063811599a4SMatt Barden 				mdb_printf(
1064811599a4SMatt Barden 				    "UID(user): %u (%p)\n",
1065811599a4SMatt Barden 				    sr->smb_uid, sr->uid_user);
1066811599a4SMatt Barden 			}
1067811599a4SMatt Barden 
1068a90cf9f2SGordon Ross 			mdb_printf(
1069a90cf9f2SGordon Ross 			    "TID(tree): %u (%p)\n",
1070a90cf9f2SGordon Ross 			    sr->smb_tid, sr->tid_tree);
1071a90cf9f2SGordon Ross 
1072a90cf9f2SGordon Ross 			mdb_printf(
1073a90cf9f2SGordon Ross 			    "FID(file): %u (%p)\n",
1074a90cf9f2SGordon Ross 			    sr->smb_fid, sr->fid_ofile);
1075a90cf9f2SGordon Ross 
1076a90cf9f2SGordon Ross 			mdb_printf(
1077a90cf9f2SGordon Ross 			    "PID: %u\n",
1078a90cf9f2SGordon Ross 			    sr->smb_pid);
1079a90cf9f2SGordon Ross 
1080bd49ed45SGordon Ross 			mdb_printf(
1081bd49ed45SGordon Ross 			    "MID: 0x%llx\n",
1082bd49ed45SGordon Ross 			    msg_id);
1083bd49ed45SGordon Ross 
1084bd49ed45SGordon Ross 			/*
1085bd49ed45SGordon Ross 			 * Note: mdb_gethrtime() is only available in kmdb
1086bd49ed45SGordon Ross 			 */
1087bd49ed45SGordon Ross #ifdef	_KERNEL
1088bd49ed45SGordon Ross 			if (sr->sr_time_submitted != 0) {
1089bd49ed45SGordon Ross 				uint64_t	waiting = 0;
1090bd49ed45SGordon Ross 				uint64_t	running = 0;
1091bd49ed45SGordon Ross 
1092bd49ed45SGordon Ross 				if (sr->sr_time_active != 0) {
1093bd49ed45SGordon Ross 					waiting = sr->sr_time_active -
1094bd49ed45SGordon Ross 					    sr->sr_time_submitted;
1095bd49ed45SGordon Ross 					running = mdb_gethrtime() -
1096bd49ed45SGordon Ross 					    sr->sr_time_active;
1097bd49ed45SGordon Ross 				} else {
1098bd49ed45SGordon Ross 					waiting = mdb_gethrtime() -
1099bd49ed45SGordon Ross 					    sr->sr_time_submitted;
1100bd49ed45SGordon Ross 				}
1101bd49ed45SGordon Ross 				waiting /= NANOSEC;
1102bd49ed45SGordon Ross 				running /= NANOSEC;
1103bd49ed45SGordon Ross 
1104a90cf9f2SGordon Ross 				mdb_printf(
1105bd49ed45SGordon Ross 				    "waiting time: %lld\n",
1106bd49ed45SGordon Ross 				    waiting);
1107bd49ed45SGordon Ross 
1108a90cf9f2SGordon Ross 				mdb_printf(
1109bd49ed45SGordon Ross 				    "running time: %lld\n",
1110bd49ed45SGordon Ross 				    running);
1111a90cf9f2SGordon Ross 			}
1112bd49ed45SGordon Ross #endif	/* _KERNEL */
1113148c5f43SAlan Wright 
1114a90cf9f2SGordon Ross 			mdb_printf(
1115a90cf9f2SGordon Ross 			    "worker thread: %p\n",
1116a90cf9f2SGordon Ross 			    sr->sr_worker);
1117d8adf402SGordon Ross 			if (sr->sr_worker != NULL) {
1118d8adf402SGordon Ross 				smb_worker_findstack((uintptr_t)sr->sr_worker);
1119d8adf402SGordon Ross 			}
11206537f381Sas 		} else {
11216537f381Sas 			if (DCMD_HDRSPEC(flags))
11226537f381Sas 				mdb_printf(
1123148c5f43SAlan Wright 				    SMB_REQUEST_BANNER,
1124bd49ed45SGordon Ross 				    "REQUEST",
1125bd49ed45SGordon Ross 				    "MSG_ID",
1126148c5f43SAlan Wright 				    "WORKER",
1127148c5f43SAlan Wright 				    "STATE",
1128148c5f43SAlan Wright 				    "COMMAND");
1129148c5f43SAlan Wright 
1130a90cf9f2SGordon Ross 			mdb_printf(
1131a90cf9f2SGordon Ross 			    SMB_REQUEST_FORMAT,
1132148c5f43SAlan Wright 			    addr,
1133bd49ed45SGordon Ross 			    msg_id,
1134148c5f43SAlan Wright 			    sr->sr_worker,
1135148c5f43SAlan Wright 			    state,
1136a90cf9f2SGordon Ross 			    cur_cmd_name);
1137da6c28aaSamw 		}
1138da6c28aaSamw 	}
11396537f381Sas 	return (DCMD_OK);
11406537f381Sas }
1141da6c28aaSamw 
1142764c8bd8SGordon Ross static void
smbreq_dump_help(void)1143764c8bd8SGordon Ross smbreq_dump_help(void)
1144764c8bd8SGordon Ross {
1145764c8bd8SGordon Ross 	mdb_printf(
1146764c8bd8SGordon Ross 	    "Dump the network data for an smb_request_t, either"
1147764c8bd8SGordon Ross 	    " command, reply, or (by default) both.  Optionally"
1148764c8bd8SGordon Ross 	    " append data to a pcap file (mdb only, not kmdb).\n\n");
1149764c8bd8SGordon Ross 	(void) mdb_dec_indent(2);
1150764c8bd8SGordon Ross 	mdb_printf("%<b>OPTIONS%</b>\n");
1151764c8bd8SGordon Ross 	(void) mdb_inc_indent(2);
1152764c8bd8SGordon Ross 	mdb_printf(
1153764c8bd8SGordon Ross 	    "-c\tDump only the SMB command message\n"
1154764c8bd8SGordon Ross 	    "-r\tDump only the SMB reply message (if present)\n"
1155764c8bd8SGordon Ross 	    "-o FILE\tOutput to FILE (append) in pcap format\n");
1156764c8bd8SGordon Ross }
1157764c8bd8SGordon Ross 
1158764c8bd8SGordon Ross #define	SMB_RDOPT_COMMAND	1
1159764c8bd8SGordon Ross #define	SMB_RDOPT_REPLY		2
1160764c8bd8SGordon Ross #define	SMB_RDOPT_OUTFILE	4
1161764c8bd8SGordon Ross 
1162764c8bd8SGordon Ross /*
1163764c8bd8SGordon Ross  * Like "smbreq" but just dump the command/reply messages.
1164764c8bd8SGordon Ross  * With the output file option, append to a pcap file.
1165764c8bd8SGordon Ross  */
1166764c8bd8SGordon Ross static int
smbreq_dump_dcmd(uintptr_t rqaddr,uint_t flags,int argc,const mdb_arg_t * argv)1167764c8bd8SGordon Ross smbreq_dump_dcmd(uintptr_t rqaddr, uint_t flags, int argc,
1168764c8bd8SGordon Ross     const mdb_arg_t *argv)
1169764c8bd8SGordon Ross {
1170bd49ed45SGordon Ross 	mdb_smb_session_t *ssn;
1171bd49ed45SGordon Ross 	mdb_smb_request_t *sr;
1172764c8bd8SGordon Ross 	char		*outfile = NULL;
1173764c8bd8SGordon Ross 	dump_func_t	dump_func;
1174764c8bd8SGordon Ross 	uint64_t	msgid;
1175764c8bd8SGordon Ross 	uintptr_t	ssnaddr;
1176764c8bd8SGordon Ross 	uint_t		opts = 0;
1177764c8bd8SGordon Ross 	int		rc = DCMD_OK;
1178764c8bd8SGordon Ross 
1179764c8bd8SGordon Ross 	if (!(flags & DCMD_ADDRSPEC))
1180764c8bd8SGordon Ross 		return (DCMD_USAGE);
1181764c8bd8SGordon Ross 
1182764c8bd8SGordon Ross 	if (mdb_getopts(argc, argv,
1183764c8bd8SGordon Ross 	    'c', MDB_OPT_SETBITS, SMB_RDOPT_COMMAND, &opts,
1184764c8bd8SGordon Ross 	    'r', MDB_OPT_SETBITS, SMB_RDOPT_REPLY, &opts,
1185764c8bd8SGordon Ross 	    'o', MDB_OPT_STR, &outfile,
1186764c8bd8SGordon Ross 	    NULL) != argc)
1187764c8bd8SGordon Ross 		return (DCMD_USAGE);
1188764c8bd8SGordon Ross #ifdef	_KMDB
1189764c8bd8SGordon Ross 	if (outfile != NULL) {
1190764c8bd8SGordon Ross 		mdb_warn("smbreq_dump -o option not supported in kmdb\n");
1191764c8bd8SGordon Ross 		return (DCMD_ERR);
1192764c8bd8SGordon Ross 	}
1193764c8bd8SGordon Ross #endif	/* _KMDB */
1194764c8bd8SGordon Ross 
1195764c8bd8SGordon Ross 	/*
1196764c8bd8SGordon Ross 	 * Default without -c or -r is to dump both.
1197764c8bd8SGordon Ross 	 */
1198764c8bd8SGordon Ross 	if ((opts & (SMB_RDOPT_COMMAND | SMB_RDOPT_REPLY)) == 0)
1199764c8bd8SGordon Ross 		opts |= SMB_RDOPT_COMMAND | SMB_RDOPT_REPLY;
1200764c8bd8SGordon Ross 
1201764c8bd8SGordon Ross 	/*
1202764c8bd8SGordon Ross 	 * Get the smb_request_t, for the cmd/reply messages.
1203764c8bd8SGordon Ross 	 */
1204bd49ed45SGordon Ross 	sr = mdb_zalloc(sizeof (*sr), UM_SLEEP | UM_GC);
1205bd49ed45SGordon Ross 	if (mdb_ctf_vread(sr, SMBSRV_SCOPE "smb_request_t",
1206bd49ed45SGordon Ross 	    "mdb_smb_request_t", rqaddr, 0) < 0) {
1207764c8bd8SGordon Ross 		mdb_warn("failed to read smb_request at %p", rqaddr);
1208764c8bd8SGordon Ross 		return (DCMD_ERR);
1209764c8bd8SGordon Ross 	}
1210764c8bd8SGordon Ross 
1211764c8bd8SGordon Ross 	/*
1212764c8bd8SGordon Ross 	 * Get the session too, for the IP addresses & ports.
1213764c8bd8SGordon Ross 	 */
1214764c8bd8SGordon Ross 	ssnaddr = (uintptr_t)sr->session;
1215bd49ed45SGordon Ross 	ssn = mdb_zalloc(sizeof (*ssn), UM_SLEEP | UM_GC);
1216bd49ed45SGordon Ross 	if (mdb_ctf_vread(ssn, SMBSRV_SCOPE "smb_session_t",
1217bd49ed45SGordon Ross 	    "mdb_smb_session_t", ssnaddr, 0) < 0) {
1218764c8bd8SGordon Ross 		mdb_warn("failed to read smb_request at %p", ssnaddr);
1219764c8bd8SGordon Ross 		return (DCMD_ERR);
1220764c8bd8SGordon Ross 	}
1221764c8bd8SGordon Ross 
1222764c8bd8SGordon Ross #ifndef	_KMDB
1223764c8bd8SGordon Ross 	if (outfile != NULL) {
1224764c8bd8SGordon Ross 		rc = smbsrv_pcap_open(outfile);
1225764c8bd8SGordon Ross 		if (rc != DCMD_OK)
1226764c8bd8SGordon Ross 			return (rc);
1227764c8bd8SGordon Ross 		dump_func = smbsrv_pcap_dump;
1228764c8bd8SGordon Ross 	} else
1229764c8bd8SGordon Ross #endif	/* _KMDB */
1230764c8bd8SGordon Ross 	{
1231764c8bd8SGordon Ross 		dump_func = smb_req_dump;
1232764c8bd8SGordon Ross 	}
1233764c8bd8SGordon Ross 
1234764c8bd8SGordon Ross 	if (sr->smb2_messageid != 0)
1235764c8bd8SGordon Ross 		msgid = sr->smb2_messageid;
1236764c8bd8SGordon Ross 	else
1237764c8bd8SGordon Ross 		msgid = sr->smb_mid;
1238764c8bd8SGordon Ross 	mdb_printf("Dumping request %-?p, Msg_ID 0x%llx\n",
1239764c8bd8SGordon Ross 	    rqaddr, msgid);
1240764c8bd8SGordon Ross 
1241764c8bd8SGordon Ross 	if (opts & SMB_RDOPT_COMMAND) {
1242764c8bd8SGordon Ross 		/*
1243764c8bd8SGordon Ross 		 * Dump the command, length=max_bytes
1244764c8bd8SGordon Ross 		 * src=remote, dst=local
1245764c8bd8SGordon Ross 		 */
1246764c8bd8SGordon Ross 		rc = dump_func(&sr->command, sr->command.max_bytes,
12473cc23d49SGordon Ross 		    (smb_inaddr_t *)&ssn->ipaddr, ssn->s_remote_port,
12483cc23d49SGordon Ross 		    (smb_inaddr_t *)&ssn->local_ipaddr, ssn->s_local_port,
1249764c8bd8SGordon Ross 		    sr->sr_time_submitted, B_FALSE);
1250764c8bd8SGordon Ross 	}
1251764c8bd8SGordon Ross 
1252764c8bd8SGordon Ross 	if ((opts & SMB_RDOPT_REPLY) != 0 &&
1253764c8bd8SGordon Ross 	    rc == DCMD_OK) {
1254764c8bd8SGordon Ross 		/*
1255764c8bd8SGordon Ross 		 * Dump the reply, length=chain_offset
1256764c8bd8SGordon Ross 		 * src=local, dst=remote
1257764c8bd8SGordon Ross 		 */
1258764c8bd8SGordon Ross 		rc = dump_func(&sr->reply, sr->reply.chain_offset,
12593cc23d49SGordon Ross 		    (smb_inaddr_t *)&ssn->local_ipaddr, ssn->s_local_port,
12603cc23d49SGordon Ross 		    (smb_inaddr_t *)&ssn->ipaddr, ssn->s_remote_port,
1261764c8bd8SGordon Ross 		    sr->sr_time_start, B_TRUE);
1262764c8bd8SGordon Ross 	}
1263764c8bd8SGordon Ross 
1264764c8bd8SGordon Ross #ifndef	_KMDB
1265764c8bd8SGordon Ross 	if (outfile != NULL) {
1266764c8bd8SGordon Ross 		smbsrv_pcap_close();
1267764c8bd8SGordon Ross 	}
1268764c8bd8SGordon Ross #endif
1269764c8bd8SGordon Ross 
1270764c8bd8SGordon Ross 	return (DCMD_OK);
1271764c8bd8SGordon Ross }
1272764c8bd8SGordon Ross 
1273764c8bd8SGordon Ross struct req_dump_state {
1274764c8bd8SGordon Ross 	int32_t rem_len;
1275764c8bd8SGordon Ross };
1276764c8bd8SGordon Ross 
1277764c8bd8SGordon Ross static int
smb_req_dump(struct mbuf_chain * mbc,int32_t smb_len,smb_inaddr_t * src_ip,uint16_t src_port,smb_inaddr_t * dst_ip,uint16_t dst_port,hrtime_t rqtime,boolean_t is_reply)1278764c8bd8SGordon Ross smb_req_dump(struct mbuf_chain *mbc, int32_t smb_len,
1279764c8bd8SGordon Ross     smb_inaddr_t *src_ip, uint16_t src_port,
1280764c8bd8SGordon Ross     smb_inaddr_t *dst_ip, uint16_t dst_port,
1281764c8bd8SGordon Ross     hrtime_t rqtime, boolean_t is_reply)
1282764c8bd8SGordon Ross {
1283764c8bd8SGordon Ross 	char	src_buf[INET6_ADDRSTRLEN];
1284764c8bd8SGordon Ross 	char	dst_buf[INET6_ADDRSTRLEN];
1285764c8bd8SGordon Ross 	struct req_dump_state dump_state;
1286764c8bd8SGordon Ross 	_NOTE(ARGUNUSED(rqtime));
1287764c8bd8SGordon Ross 
1288764c8bd8SGordon Ross 	if (smb_len < 4)
1289764c8bd8SGordon Ross 		return (DCMD_OK);
1290764c8bd8SGordon Ross 	if (mbc->chain == NULL)
1291764c8bd8SGordon Ross 		return (DCMD_ERR);
1292764c8bd8SGordon Ross 
1293764c8bd8SGordon Ross 	smb_inaddr_ntop(src_ip, src_buf, sizeof (src_buf));
1294764c8bd8SGordon Ross 	smb_inaddr_ntop(dst_ip, dst_buf, sizeof (dst_buf));
1295764c8bd8SGordon Ross 
1296764c8bd8SGordon Ross 	mdb_printf("%-8s SRC: %s/%u  DST: %s/%u  LEN: %u\n",
1297764c8bd8SGordon Ross 	    (is_reply) ? "Reply:" : "Call:",
1298764c8bd8SGordon Ross 	    src_buf, src_port, dst_buf, dst_port, smb_len);
1299764c8bd8SGordon Ross 
1300764c8bd8SGordon Ross 	/*
1301764c8bd8SGordon Ross 	 * Calling "smb_mbuf_dump" with a wrapper function
1302764c8bd8SGordon Ross 	 * so we can set its length arg, and decrement
1303764c8bd8SGordon Ross 	 * req_dump_state.rem_len as it goes.
1304764c8bd8SGordon Ross 	 */
1305764c8bd8SGordon Ross 	dump_state.rem_len = smb_len;
1306764c8bd8SGordon Ross 	if (mdb_pwalk("smb_mbuf_walker", smb_req_dump_m,
1307764c8bd8SGordon Ross 	    &dump_state, (uintptr_t)mbc->chain) == -1) {
1308764c8bd8SGordon Ross 		mdb_warn("cannot walk smb_req mbuf_chain");
1309764c8bd8SGordon Ross 		return (DCMD_ERR);
1310764c8bd8SGordon Ross 	}
1311764c8bd8SGordon Ross 	return (DCMD_OK);
1312764c8bd8SGordon Ross }
1313764c8bd8SGordon Ross 
1314764c8bd8SGordon Ross static int
smb_req_dump_m(uintptr_t m_addr,const void * data,void * arg)1315764c8bd8SGordon Ross smb_req_dump_m(uintptr_t m_addr, const void *data, void *arg)
1316764c8bd8SGordon Ross {
1317764c8bd8SGordon Ross 	struct req_dump_state *st = arg;
1318764c8bd8SGordon Ross 	const struct mbuf *m = data;
1319764c8bd8SGordon Ross 	mdb_arg_t	argv;
1320764c8bd8SGordon Ross 	int cnt;
1321764c8bd8SGordon Ross 
1322764c8bd8SGordon Ross 	cnt = st->rem_len;
1323764c8bd8SGordon Ross 	if (cnt > m->m_len)
1324764c8bd8SGordon Ross 		cnt = m->m_len;
1325764c8bd8SGordon Ross 	if (cnt <= 0)
1326764c8bd8SGordon Ross 		return (WALK_DONE);
1327764c8bd8SGordon Ross 
1328764c8bd8SGordon Ross 	argv.a_type = MDB_TYPE_IMMEDIATE;
1329764c8bd8SGordon Ross 	argv.a_un.a_val = cnt;
1330764c8bd8SGordon Ross 	if (mdb_call_dcmd("smb_mbuf_dump", m_addr, 0, 1, &argv) < 0) {
1331764c8bd8SGordon Ross 		mdb_warn("%p::smb_mbuf_dump failed\n", m_addr);
1332764c8bd8SGordon Ross 		return (WALK_ERR);
1333764c8bd8SGordon Ross 	}
1334764c8bd8SGordon Ross 
1335764c8bd8SGordon Ross 	st->rem_len -= cnt;
1336764c8bd8SGordon Ross 	return (WALK_NEXT);
1337764c8bd8SGordon Ross }
1338764c8bd8SGordon Ross 
13396537f381Sas /*
13406537f381Sas  * *****************************************************************************
13416537f381Sas  * ****************************** smb_user_t ***********************************
13426537f381Sas  * *****************************************************************************
13436537f381Sas  */
1344bd49ed45SGordon Ross typedef struct mdb_smb_user {
1345bd49ed45SGordon Ross 	smb_user_state_t	u_state;
1346bd49ed45SGordon Ross 
1347bd49ed45SGordon Ross 	struct smb_server	*u_server;
1348bd49ed45SGordon Ross 	smb_session_t		*u_session;
1349bd49ed45SGordon Ross 
1350bd49ed45SGordon Ross 	uint16_t		u_name_len;
1351bd49ed45SGordon Ross 	char			*u_name;
1352bd49ed45SGordon Ross 	uint16_t		u_domain_len;
1353bd49ed45SGordon Ross 	char			*u_domain;
1354bd49ed45SGordon Ross 	time_t			u_logon_time;
1355bd49ed45SGordon Ross 	cred_t			*u_cred;
1356bd49ed45SGordon Ross 	cred_t			*u_privcred;
1357bd49ed45SGordon Ross 
1358811599a4SMatt Barden 	uint64_t		u_ssnid;
1359bd49ed45SGordon Ross 	uint32_t		u_refcnt;
1360bd49ed45SGordon Ross 	uint32_t		u_flags;
1361bd49ed45SGordon Ross 	uint32_t		u_privileges;
1362bd49ed45SGordon Ross 	uint16_t		u_uid;
1363bd49ed45SGordon Ross } mdb_smb_user_t;
1364bd49ed45SGordon Ross 
1365bd49ed45SGordon Ross static const mdb_bitmask_t
1366bd49ed45SGordon Ross user_flag_bits[] = {
1367bd49ed45SGordon Ross 	{ "ANON",
1368bd49ed45SGordon Ross 	    SMB_USER_FLAG_ANON,
1369bd49ed45SGordon Ross 	    SMB_USER_FLAG_ANON },
1370bd49ed45SGordon Ross 	{ "GUEST",
1371bd49ed45SGordon Ross 	    SMB_USER_FLAG_GUEST,
1372bd49ed45SGordon Ross 	    SMB_USER_FLAG_GUEST },
1373bd49ed45SGordon Ross 	{ "POWER_USER",
1374bd49ed45SGordon Ross 	    SMB_USER_FLAG_POWER_USER,
1375bd49ed45SGordon Ross 	    SMB_USER_FLAG_POWER_USER },
1376bd49ed45SGordon Ross 	{ "BACKUP_OP",
1377bd49ed45SGordon Ross 	    SMB_USER_FLAG_BACKUP_OPERATOR,
1378bd49ed45SGordon Ross 	    SMB_USER_FLAG_BACKUP_OPERATOR },
1379bd49ed45SGordon Ross 	{ "ADMIN",
1380bd49ed45SGordon Ross 	    SMB_USER_FLAG_ADMIN,
1381bd49ed45SGordon Ross 	    SMB_USER_FLAG_ADMIN },
1382bd49ed45SGordon Ross 	{ NULL, 0, 0 }
1383bd49ed45SGordon Ross };
13846537f381Sas 
1385bd49ed45SGordon Ross static const mdb_bitmask_t
1386bd49ed45SGordon Ross user_priv_bits[] = {
1387cc3780e6SGordon Ross 	/*
1388cc3780e6SGordon Ross 	 * Old definitions of these bits, for when we're
1389cc3780e6SGordon Ross 	 * looking at an older core file.  These happen to
1390cc3780e6SGordon Ross 	 * have no overlap with the current definitions.
1391cc3780e6SGordon Ross 	 */
1392cc3780e6SGordon Ross 	{ "TAKE_OWNER",	1, 1 },
1393cc3780e6SGordon Ross 	{ "BACKUP",	2, 2 },
1394cc3780e6SGordon Ross 	{ "RESTORE",	4, 4 },
1395cc3780e6SGordon Ross 	{ "SECURITY",	8, 8 },
1396cc3780e6SGordon Ross 	/*
1397cc3780e6SGordon Ross 	 * Current definitions
1398cc3780e6SGordon Ross 	 */
1399cc3780e6SGordon Ross 	{ "SECURITY",
1400cc3780e6SGordon Ross 	    SMB_USER_PRIV_SECURITY,
1401cc3780e6SGordon Ross 	    SMB_USER_PRIV_SECURITY },
1402bd49ed45SGordon Ross 	{ "TAKE_OWNER",
1403bd49ed45SGordon Ross 	    SMB_USER_PRIV_TAKE_OWNERSHIP,
1404bd49ed45SGordon Ross 	    SMB_USER_PRIV_TAKE_OWNERSHIP },
1405bd49ed45SGordon Ross 	{ "BACKUP",
1406bd49ed45SGordon Ross 	    SMB_USER_PRIV_BACKUP,
1407bd49ed45SGordon Ross 	    SMB_USER_PRIV_BACKUP },
1408bd49ed45SGordon Ross 	{ "RESTORE",
1409bd49ed45SGordon Ross 	    SMB_USER_PRIV_RESTORE,
1410bd49ed45SGordon Ross 	    SMB_USER_PRIV_RESTORE },
1411cc3780e6SGordon Ross 	{ "CHANGE_NOTIFY",
1412cc3780e6SGordon Ross 	    SMB_USER_PRIV_CHANGE_NOTIFY,
1413cc3780e6SGordon Ross 	    SMB_USER_PRIV_CHANGE_NOTIFY },
14140292c176SMatt Barden 	{ "READ_FILE",
14150292c176SMatt Barden 	    SMB_USER_PRIV_READ_FILE,
14160292c176SMatt Barden 	    SMB_USER_PRIV_READ_FILE },
14170292c176SMatt Barden 	{ "WRITE_FILE",
14180292c176SMatt Barden 	    SMB_USER_PRIV_WRITE_FILE,
14190292c176SMatt Barden 	    SMB_USER_PRIV_WRITE_FILE },
1420bd49ed45SGordon Ross 	{ NULL, 0, 0 }
14216537f381Sas };
14226537f381Sas 
14236537f381Sas static void
smbuser_help(void)14242b8c497cSGordon Ross smbuser_help(void)
14256537f381Sas {
14266537f381Sas 	mdb_printf(
14276537f381Sas 	    "Display the contents of smb_user_t, with optional filtering.\n\n");
14286537f381Sas 	(void) mdb_dec_indent(2);
14296537f381Sas 	mdb_printf("%<b>OPTIONS%</b>\n");
14306537f381Sas 	(void) mdb_inc_indent(2);
14316537f381Sas 	mdb_printf(
14323b13a1efSThomas Keiser 	    "-v\tDisplay verbose smb_user information\n");
14336537f381Sas }
14346537f381Sas 
14356537f381Sas static int
smbuser_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)14362b8c497cSGordon Ross smbuser_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14376537f381Sas {
14386537f381Sas 	uint_t		opts;
14396537f381Sas 
14406537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
14416537f381Sas 		return (DCMD_USAGE);
14426537f381Sas 
14436537f381Sas 	if (!(flags & DCMD_ADDRSPEC)) {
14446537f381Sas 		opts |= SMB_OPT_USER;
14456537f381Sas 		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST);
14466537f381Sas 		return (smb_obj_list("smb_user", opts, flags));
14476537f381Sas 	}
14486537f381Sas 
14496537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_USER)) ||
14506537f381Sas 	    !(opts & SMB_OPT_WALK)) {
1451bd49ed45SGordon Ross 		mdb_smb_user_t	*user;
14526537f381Sas 		char		*account;
14536537f381Sas 
1454bd49ed45SGordon Ross 		user = mdb_zalloc(sizeof (*user), UM_SLEEP | UM_GC);
1455bd49ed45SGordon Ross 		if (mdb_ctf_vread(user, SMBSRV_SCOPE "smb_user_t",
1456bd49ed45SGordon Ross 		    "mdb_smb_user_t", addr, 0) < 0) {
14576537f381Sas 			mdb_warn("failed to read smb_user at %p", addr);
14586537f381Sas 			return (DCMD_ERR);
14596537f381Sas 		}
14606537f381Sas 		account = mdb_zalloc(user->u_domain_len + user->u_name_len + 2,
14616537f381Sas 		    UM_SLEEP | UM_GC);
14626537f381Sas 
14636537f381Sas 		if (user->u_domain_len)
14646537f381Sas 			(void) mdb_vread(account, user->u_domain_len,
14656537f381Sas 			    (uintptr_t)user->u_domain);
14666537f381Sas 
14676537f381Sas 		strcat(account, "\\");
14686537f381Sas 
14696537f381Sas 		if (user->u_name_len)
14706537f381Sas 			(void) mdb_vread(account + strlen(account),
14716537f381Sas 			    user->u_name_len, (uintptr_t)user->u_name);
14726537f381Sas 
14736537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
1474bd49ed45SGordon Ross 			char		state[40];
14756537f381Sas 
1476bd49ed45SGordon Ross 			get_enum(state, sizeof (state),
1477bd49ed45SGordon Ross 			    "smb_user_state_t", user->u_state,
1478bd49ed45SGordon Ross 			    "SMB_USER_STATE_");
14796537f381Sas 
14806537f381Sas 			mdb_printf("%<b>%<u>SMB user information (%p):"
14816537f381Sas 			    "%</u>%</b>\n", addr);
14826537f381Sas 			mdb_printf("UID: %u\n", user->u_uid);
1483811599a4SMatt Barden 			mdb_printf("SSNID: %llx\n", user->u_ssnid);
14846537f381Sas 			mdb_printf("State: %d (%s)\n", user->u_state, state);
1485bd49ed45SGordon Ross 			mdb_printf("Flags: 0x%08x <%b>\n", user->u_flags,
1486bd49ed45SGordon Ross 			    user->u_flags, user_flag_bits);
1487bd49ed45SGordon Ross 			mdb_printf("Privileges: 0x%08x <%b>\n",
1488bd49ed45SGordon Ross 			    user->u_privileges,
1489bd49ed45SGordon Ross 			    user->u_privileges, user_priv_bits);
14906537f381Sas 			mdb_printf("Credential: %p\n", user->u_cred);
14916537f381Sas 			mdb_printf("Reference Count: %d\n", user->u_refcnt);
14926537f381Sas 			mdb_printf("User Account: %s\n\n", account);
14936537f381Sas 		} else {
14946537f381Sas 			if (DCMD_HDRSPEC(flags))
14956537f381Sas 				mdb_printf(
14966537f381Sas 				    "%<b>%<u>%?-s "
14976537f381Sas 				    "%-5s "
1498811599a4SMatt Barden 				    "%-16s "
14996537f381Sas 				    "%-32s%</u>%</b>\n",
1500811599a4SMatt Barden 				    "USER", "UID", "SSNID", "ACCOUNT");
15016537f381Sas 
1502811599a4SMatt Barden 			mdb_printf("%-?p %-5u %-16llx %-32s\n",
1503811599a4SMatt Barden 			    addr, user->u_uid, user->u_ssnid, account);
1504da6c28aaSamw 		}
1505da6c28aaSamw 	}
15066537f381Sas 	return (DCMD_OK);
15076537f381Sas }
1508da6c28aaSamw 
15096537f381Sas /*
15106537f381Sas  * *****************************************************************************
15116537f381Sas  * ****************************** smb_tree_t ***********************************
15126537f381Sas  * *****************************************************************************
15136537f381Sas  */
15146537f381Sas 
1515bd49ed45SGordon Ross typedef struct mdb_smb_tree {
1516bd49ed45SGordon Ross 	smb_tree_state_t	t_state;
1517bd49ed45SGordon Ross 
1518bd49ed45SGordon Ross 	smb_node_t		*t_snode;
1519*2cf6b79fSGordon Ross 	smb_lavl_t		t_ofile_list;
1520bd49ed45SGordon Ross 	smb_llist_t		t_odir_list;
1521bd49ed45SGordon Ross 
1522bd49ed45SGordon Ross 	uint32_t		t_refcnt;
1523bd49ed45SGordon Ross 	uint32_t		t_flags;
1524bd49ed45SGordon Ross 	int32_t			t_res_type;
1525bd49ed45SGordon Ross 	uint16_t		t_tid;
1526bd49ed45SGordon Ross 	uint16_t		t_umask;
1527bd49ed45SGordon Ross 	char			t_sharename[MAXNAMELEN];
1528bd49ed45SGordon Ross 	char			t_resource[MAXPATHLEN];
1529bd49ed45SGordon Ross 	char			t_typename[SMB_TYPENAMELEN];
1530bd49ed45SGordon Ross 	char			t_volume[SMB_VOLNAMELEN];
1531bd49ed45SGordon Ross } mdb_smb_tree_t;
1532bd49ed45SGordon Ross 
1533bd49ed45SGordon Ross static int
smb_tree_exp_off_ofile_avl(void)1534*2cf6b79fSGordon Ross smb_tree_exp_off_ofile_avl(void)
15356537f381Sas {
1536*2cf6b79fSGordon Ross 	int tf_off, la_off;
1537bd49ed45SGordon Ross 
1538bd49ed45SGordon Ross 	/* OFFSETOF(smb_tree_t, t_ofile_list.ll_list); */
1539bd49ed45SGordon Ross 	GET_OFFSET(tf_off, smb_tree_t, t_ofile_list);
1540*2cf6b79fSGordon Ross 	GET_OFFSET(la_off, smb_lavl_t, la_tree);
1541*2cf6b79fSGordon Ross 	return (tf_off + la_off);
1542bd49ed45SGordon Ross }
1543bd49ed45SGordon Ross 
1544bd49ed45SGordon Ross static int
smb_tree_exp_off_odir_list(void)1545bd49ed45SGordon Ross smb_tree_exp_off_odir_list(void)
1546bd49ed45SGordon Ross {
1547bd49ed45SGordon Ross 	int td_off, ll_off;
1548bd49ed45SGordon Ross 
1549bd49ed45SGordon Ross 	/* OFFSETOF(smb_tree_t, t_odir_list.ll_list); */
1550bd49ed45SGordon Ross 	GET_OFFSET(td_off, smb_tree_t, t_odir_list);
1551bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
1552bd49ed45SGordon Ross 	return (td_off + ll_off);
1553bd49ed45SGordon Ross }
15546537f381Sas 
15556537f381Sas /*
15566537f381Sas  * List of objects that can be expanded under a tree structure.
15576537f381Sas  */
15586537f381Sas static const smb_exp_t smb_tree_exp[] =
15596537f381Sas {
1560*2cf6b79fSGordon Ross 	{ SMB_OPT_OFILE, "avl",
1561*2cf6b79fSGordon Ross 	    smb_tree_exp_off_ofile_avl,
15626537f381Sas 	    "smbofile", "smb_ofile"},
1563*2cf6b79fSGordon Ross 	{ SMB_OPT_ODIR, "list",
1564bd49ed45SGordon Ross 	    smb_tree_exp_off_odir_list,
15656537f381Sas 	    "smbodir", "smb_odir"},
1566*2cf6b79fSGordon Ross 	{ 0 }
15676537f381Sas };
15686537f381Sas 
1569bd49ed45SGordon Ross static const mdb_bitmask_t
1570bd49ed45SGordon Ross tree_flag_bits[] = {
1571bd49ed45SGordon Ross 	{ "RO",
1572bd49ed45SGordon Ross 	    SMB_TREE_READONLY,
1573bd49ed45SGordon Ross 	    SMB_TREE_READONLY },
1574bd49ed45SGordon Ross 	{ "ACLS",
1575bd49ed45SGordon Ross 	    SMB_TREE_SUPPORTS_ACLS,
1576bd49ed45SGordon Ross 	    SMB_TREE_SUPPORTS_ACLS },
1577bd49ed45SGordon Ross 	{ "STREAMS",
1578bd49ed45SGordon Ross 	    SMB_TREE_STREAMS,
1579bd49ed45SGordon Ross 	    SMB_TREE_STREAMS },
1580bd49ed45SGordon Ross 	{ "CI",
1581bd49ed45SGordon Ross 	    SMB_TREE_CASEINSENSITIVE,
1582bd49ed45SGordon Ross 	    SMB_TREE_CASEINSENSITIVE },
1583bd49ed45SGordon Ross 	{ "NO_CS",
1584bd49ed45SGordon Ross 	    SMB_TREE_NO_CASESENSITIVE,
1585bd49ed45SGordon Ross 	    SMB_TREE_NO_CASESENSITIVE },
1586bd49ed45SGordon Ross 	{ "NO_EXPORT",
1587bd49ed45SGordon Ross 	    SMB_TREE_NO_EXPORT,
1588bd49ed45SGordon Ross 	    SMB_TREE_NO_EXPORT },
1589bd49ed45SGordon Ross 	{ "OPLOCKS",
1590bd49ed45SGordon Ross 	    SMB_TREE_OPLOCKS,
1591bd49ed45SGordon Ross 	    SMB_TREE_OPLOCKS },
1592bd49ed45SGordon Ross 	{ "SHORTNAMES",
1593bd49ed45SGordon Ross 	    SMB_TREE_SHORTNAMES,
1594bd49ed45SGordon Ross 	    SMB_TREE_SHORTNAMES },
1595bd49ed45SGordon Ross 	{ "XVATTR",
1596bd49ed45SGordon Ross 	    SMB_TREE_XVATTR,
1597bd49ed45SGordon Ross 	    SMB_TREE_XVATTR },
1598bd49ed45SGordon Ross 	{ "DIRENTFLAGS",
1599bd49ed45SGordon Ross 	    SMB_TREE_DIRENTFLAGS,
1600bd49ed45SGordon Ross 	    SMB_TREE_DIRENTFLAGS },
1601bd49ed45SGordon Ross 	{ "ACL_CR",
1602bd49ed45SGordon Ross 	    SMB_TREE_ACLONCREATE,
1603bd49ed45SGordon Ross 	    SMB_TREE_ACLONCREATE },
1604bd49ed45SGordon Ross 	{ "ACEMASK",
1605bd49ed45SGordon Ross 	    SMB_TREE_ACEMASKONACCESS,
1606bd49ed45SGordon Ross 	    SMB_TREE_ACEMASKONACCESS },
1607bd49ed45SGordon Ross 	{ "NFS_MNT",
1608bd49ed45SGordon Ross 	    SMB_TREE_NFS_MOUNTED,
1609bd49ed45SGordon Ross 	    SMB_TREE_NFS_MOUNTED },
1610bd49ed45SGordon Ross 	{ "UNICODE",
1611bd49ed45SGordon Ross 	    SMB_TREE_UNICODE_ON_DISK,
1612bd49ed45SGordon Ross 	    SMB_TREE_UNICODE_ON_DISK },
1613bd49ed45SGordon Ross 	{ "CATIA",
1614bd49ed45SGordon Ross 	    SMB_TREE_CATIA,
1615bd49ed45SGordon Ross 	    SMB_TREE_CATIA },
1616bd49ed45SGordon Ross 	{ "ABE",
1617bd49ed45SGordon Ross 	    SMB_TREE_ABE,
1618bd49ed45SGordon Ross 	    SMB_TREE_ABE },
1619bd49ed45SGordon Ross 	{ "QUOTA",
1620bd49ed45SGordon Ross 	    SMB_TREE_QUOTA,
1621bd49ed45SGordon Ross 	    SMB_TREE_QUOTA },
1622bd49ed45SGordon Ross 	{ "DFSROOT",
1623bd49ed45SGordon Ross 	    SMB_TREE_DFSROOT,
1624bd49ed45SGordon Ross 	    SMB_TREE_DFSROOT },
1625bd49ed45SGordon Ross 	{ "SPARSE",
1626bd49ed45SGordon Ross 	    SMB_TREE_SPARSE,
1627bd49ed45SGordon Ross 	    SMB_TREE_SPARSE },
162894047d49SGordon Ross 	{ "XMOUNTS",
1629bd49ed45SGordon Ross 	    SMB_TREE_TRAVERSE_MOUNTS,
1630bd49ed45SGordon Ross 	    SMB_TREE_TRAVERSE_MOUNTS },
163194047d49SGordon Ross 	{ "FORCE_L2_OPLOCK",
163294047d49SGordon Ross 	    SMB_TREE_FORCE_L2_OPLOCK,
163394047d49SGordon Ross 	    SMB_TREE_FORCE_L2_OPLOCK },
16348d94f651SGordon Ross 	{ "CA",
16358d94f651SGordon Ross 	    SMB_TREE_CA,
16368d94f651SGordon Ross 	    SMB_TREE_CA },
1637bd49ed45SGordon Ross 	{ NULL, 0, 0 }
1638bd49ed45SGordon Ross };
1639bd49ed45SGordon Ross 
16406537f381Sas static void
smbtree_help(void)16412b8c497cSGordon Ross smbtree_help(void)
16426537f381Sas {
16436537f381Sas 	mdb_printf(
16446537f381Sas 	    "Display the contents of smb_tree_t, with optional filtering.\n\n");
16456537f381Sas 	(void) mdb_dec_indent(2);
16466537f381Sas 	mdb_printf("%<b>OPTIONS%</b>\n");
16476537f381Sas 	(void) mdb_inc_indent(2);
16486537f381Sas 	mdb_printf(
16496537f381Sas 	    "-v\tDisplay verbose smb_tree information\n"
16506537f381Sas 	    "-d\tDisplay the list of smb_odirs attached\n"
16516537f381Sas 	    "-f\tDisplay the list of smb_ofiles attached\n");
1652da6c28aaSamw }
1653da6c28aaSamw 
1654da6c28aaSamw static int
smbtree_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)16552b8c497cSGordon Ross smbtree_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1656da6c28aaSamw {
16576537f381Sas 	uint_t		opts;
16586537f381Sas 	ulong_t		indent = 0;
16596537f381Sas 
16606537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
16616537f381Sas 		return (DCMD_USAGE);
16626537f381Sas 
16636537f381Sas 	if (!(flags & DCMD_ADDRSPEC)) {
16646537f381Sas 		opts |= SMB_OPT_TREE;
16656537f381Sas 		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
16666537f381Sas 		    SMB_OPT_USER);
16676537f381Sas 		return (smb_obj_list("smb_tree", opts, flags));
16686537f381Sas 	}
16696537f381Sas 
16706537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_TREE)) ||
16716537f381Sas 	    !(opts & SMB_OPT_WALK)) {
1672bd49ed45SGordon Ross 		mdb_smb_tree_t *tree;
16736537f381Sas 
16746537f381Sas 		indent = SMB_DCMD_INDENT;
16756537f381Sas 
1676bd49ed45SGordon Ross 		tree = mdb_zalloc(sizeof (*tree), UM_SLEEP | UM_GC);
1677bd49ed45SGordon Ross 		if (mdb_ctf_vread(tree, SMBSRV_SCOPE "smb_tree_t",
1678bd49ed45SGordon Ross 		    "mdb_smb_tree_t", addr, 0) < 0) {
16796537f381Sas 			mdb_warn("failed to read smb_tree at %p", addr);
16806537f381Sas 			return (DCMD_ERR);
16816537f381Sas 		}
16826537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
1683bd49ed45SGordon Ross 			char		state[40];
16846537f381Sas 
1685bd49ed45SGordon Ross 			get_enum(state, sizeof (state),
1686bd49ed45SGordon Ross 			    "smb_tree_state_t", tree->t_state,
1687bd49ed45SGordon Ross 			    "SMB_TREE_STATE_");
16886537f381Sas 
16896537f381Sas 			mdb_printf("%<b>%<u>SMB tree information (%p):"
16906537f381Sas 			    "%</u>%</b>\n\n", addr);
16916537f381Sas 			mdb_printf("TID: %04x\n", tree->t_tid);
16926537f381Sas 			mdb_printf("State: %d (%s)\n", tree->t_state, state);
1693c8ec8eeaSjose borrego 			mdb_printf("Share: %s\n", tree->t_sharename);
16946537f381Sas 			mdb_printf("Resource: %s\n", tree->t_resource);
1695c8ec8eeaSjose borrego 			mdb_printf("Type: %s\n", tree->t_typename);
1696c8ec8eeaSjose borrego 			mdb_printf("Volume: %s\n", tree->t_volume);
16976537f381Sas 			mdb_printf("Umask: %04x\n", tree->t_umask);
1698bd49ed45SGordon Ross 			mdb_printf("Flags: %08x <%b>\n", tree->t_flags,
1699bd49ed45SGordon Ross 			    tree->t_flags, tree_flag_bits);
17006537f381Sas 			mdb_printf("SMB Node: %llx\n", tree->t_snode);
17016537f381Sas 			mdb_printf("Reference Count: %d\n\n", tree->t_refcnt);
17026537f381Sas 		} else {
17036537f381Sas 			if (DCMD_HDRSPEC(flags))
17046537f381Sas 				mdb_printf(
17056537f381Sas 				    "%<b>%<u>%-?s %-5s %-16s %-32s%</u>%</b>\n",
17066537f381Sas 				    "TREE", "TID", "SHARE NAME", "RESOURCE");
17076537f381Sas 
17086537f381Sas 			mdb_printf("%-?p %-5u %-16s %-32s\n", addr,
17096537f381Sas 			    tree->t_tid, tree->t_sharename, tree->t_resource);
17106537f381Sas 		}
17116537f381Sas 	}
17126537f381Sas 	if (smb_obj_expand(addr, opts, smb_tree_exp, indent))
17136537f381Sas 		return (DCMD_ERR);
17146537f381Sas 	return (DCMD_OK);
1715da6c28aaSamw }
1716da6c28aaSamw 
1717da6c28aaSamw /*
17186537f381Sas  * *****************************************************************************
17196537f381Sas  * ****************************** smb_odir_t ***********************************
17206537f381Sas  * *****************************************************************************
1721da6c28aaSamw  */
17226537f381Sas 
1723bd49ed45SGordon Ross typedef struct mdb_smb_odir {
1724bd49ed45SGordon Ross 	smb_odir_state_t	d_state;
1725bd49ed45SGordon Ross 	smb_session_t		*d_session;
1726bd49ed45SGordon Ross 	smb_user_t		*d_user;
1727bd49ed45SGordon Ross 	smb_tree_t		*d_tree;
1728bd49ed45SGordon Ross 	smb_node_t		*d_dnode;
1729bd49ed45SGordon Ross 	uint16_t		d_odid;
1730bd49ed45SGordon Ross 	uint32_t		d_refcnt;
1731bd49ed45SGordon Ross 	char			d_pattern[MAXNAMELEN];
1732bd49ed45SGordon Ross } mdb_smb_odir_t;
1733da6c28aaSamw 
17346537f381Sas static int
smbodir_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)17352b8c497cSGordon Ross smbodir_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
17366537f381Sas {
17376537f381Sas 	uint_t		opts;
1738da6c28aaSamw 
17396537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
1740da6c28aaSamw 		return (DCMD_USAGE);
1741da6c28aaSamw 
17426537f381Sas 	if (!(flags & DCMD_ADDRSPEC)) {
17436537f381Sas 		opts |= SMB_OPT_ODIR;
17446537f381Sas 		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
17456537f381Sas 		    SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_OFILE);
17466537f381Sas 		return (smb_obj_list("smb_odir", opts, flags));
1747faa1795aSjb 	}
1748da6c28aaSamw 
17496537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_ODIR)) ||
17506537f381Sas 	    !(opts & SMB_OPT_WALK)) {
1751bd49ed45SGordon Ross 		mdb_smb_odir_t *od;
1752faa1795aSjb 
1753bd49ed45SGordon Ross 		od = mdb_zalloc(sizeof (*od), UM_SLEEP | UM_GC);
1754bd49ed45SGordon Ross 		if (mdb_ctf_vread(od, SMBSRV_SCOPE "smb_odir_t",
1755bd49ed45SGordon Ross 		    "mdb_smb_odir_t", addr, 0) < 0) {
17566537f381Sas 			mdb_warn("failed to read smb_odir at %p", addr);
17576537f381Sas 			return (DCMD_ERR);
17586537f381Sas 		}
17596537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
1760bd49ed45SGordon Ross 			char		state[40];
1761da6c28aaSamw 
1762bd49ed45SGordon Ross 			get_enum(state, sizeof (state),
1763bd49ed45SGordon Ross 			    "smb_odir_state_t", od->d_state,
1764bd49ed45SGordon Ross 			    "SMB_ODIR_STATE_");
17656537f381Sas 
17666537f381Sas 			mdb_printf(
17676537f381Sas 			    "%<b>%<u>SMB odir information (%p):%</u>%</b>\n\n",
17686537f381Sas 			    addr);
17696537f381Sas 			mdb_printf("State: %d (%s)\n", od->d_state, state);
17707f667e74Sjose borrego 			mdb_printf("SID: %u\n", od->d_odid);
17713b13a1efSThomas Keiser 			mdb_printf("User: %p\n", od->d_user);
17723b13a1efSThomas Keiser 			mdb_printf("Tree: %p\n", od->d_tree);
17736537f381Sas 			mdb_printf("Reference Count: %d\n", od->d_refcnt);
17746537f381Sas 			mdb_printf("Pattern: %s\n", od->d_pattern);
17757f667e74Sjose borrego 			mdb_printf("SMB Node: %p\n\n", od->d_dnode);
17766537f381Sas 		} else {
17776537f381Sas 			if (DCMD_HDRSPEC(flags))
17786537f381Sas 				mdb_printf(
1779e3f2c991SKeyur Desai 				    "%<b>%<u>%-?s "
17806537f381Sas 				    "%-5s "
17816537f381Sas 				    "%-?s "
1782e3f2c991SKeyur Desai 				    "%-16s%</u>%</b>\n",
17836537f381Sas 				    "ODIR", "SID", "VNODE", "PATTERN");
17846537f381Sas 
1785e3f2c991SKeyur Desai 			mdb_printf("%?p %-5u %-16p %s\n",
17867f667e74Sjose borrego 			    addr, od->d_odid, od->d_dnode, od->d_pattern);
17876537f381Sas 		}
1788da6c28aaSamw 	}
1789da6c28aaSamw 	return (DCMD_OK);
1790da6c28aaSamw }
1791da6c28aaSamw 
17926537f381Sas /*
17936537f381Sas  * *****************************************************************************
17946537f381Sas  * ****************************** smb_ofile_t **********************************
17956537f381Sas  * *****************************************************************************
17966537f381Sas  */
17976537f381Sas 
1798bd49ed45SGordon Ross typedef struct mdb_smb_ofile {
1799bd49ed45SGordon Ross 	smb_ofile_state_t	f_state;
1800bd49ed45SGordon Ross 
1801bd49ed45SGordon Ross 	struct smb_server	*f_server;
1802bd49ed45SGordon Ross 	smb_session_t		*f_session;
1803bd49ed45SGordon Ross 	smb_user_t		*f_user;
1804bd49ed45SGordon Ross 	smb_tree_t		*f_tree;
1805bd49ed45SGordon Ross 	smb_node_t		*f_node;
1806bd49ed45SGordon Ross 	smb_odir_t		*f_odir;
1807bd49ed45SGordon Ross 	smb_opipe_t		*f_pipe;
1808bd49ed45SGordon Ross 
1809bd49ed45SGordon Ross 	uint32_t		f_uniqid;
1810bd49ed45SGordon Ross 	uint32_t		f_refcnt;
1811bd49ed45SGordon Ross 	uint32_t		f_flags;
1812bd49ed45SGordon Ross 	uint32_t		f_granted_access;
1813bd49ed45SGordon Ross 	uint32_t		f_share_access;
1814bd49ed45SGordon Ross 
1815bd49ed45SGordon Ross 	uint16_t		f_fid;
1816bd49ed45SGordon Ross 	uint16_t		f_ftype;
1817bd49ed45SGordon Ross 	uint64_t		f_llf_pos;
1818bd49ed45SGordon Ross 	int			f_mode;
1819bd49ed45SGordon Ross 	cred_t			*f_cr;
1820bd49ed45SGordon Ross 	pid_t			f_pid;
182194047d49SGordon Ross 	uintptr_t		f_lease;
1822811599a4SMatt Barden 	smb_dh_vers_t		dh_vers;
1823bd49ed45SGordon Ross } mdb_smb_ofile_t;
1824bd49ed45SGordon Ross 
1825bd49ed45SGordon Ross static const mdb_bitmask_t
1826bd49ed45SGordon Ross ofile_flag_bits[] = {
18275cb2894aSGordon Ross 	{ "RO", 1, 1 }, /* old SMB_OFLAGS_READONLY */
1828bd49ed45SGordon Ross 	{ "EXEC",
1829bd49ed45SGordon Ross 	    SMB_OFLAGS_EXECONLY,
1830bd49ed45SGordon Ross 	    SMB_OFLAGS_EXECONLY },
1831bd49ed45SGordon Ross 	{ "DELETE",
1832bd49ed45SGordon Ross 	    SMB_OFLAGS_SET_DELETE_ON_CLOSE,
1833bd49ed45SGordon Ross 	    SMB_OFLAGS_SET_DELETE_ON_CLOSE },
1834bd49ed45SGordon Ross 	{ "POS_VALID",
1835bd49ed45SGordon Ross 	    SMB_OFLAGS_LLF_POS_VALID,
1836bd49ed45SGordon Ross 	    SMB_OFLAGS_LLF_POS_VALID },
1837bd49ed45SGordon Ross 	{ NULL, 0, 0}
1838bd49ed45SGordon Ross };
1839bd49ed45SGordon Ross 
1840bd49ed45SGordon Ross static const mdb_bitmask_t
1841bd49ed45SGordon Ross smb_sharemode_bits[] = {
1842bd49ed45SGordon Ross 	{ "READ",
1843bd49ed45SGordon Ross 	    FILE_SHARE_READ,
1844bd49ed45SGordon Ross 	    FILE_SHARE_READ },
1845bd49ed45SGordon Ross 	{ "WRITE",
1846bd49ed45SGordon Ross 	    FILE_SHARE_WRITE,
1847bd49ed45SGordon Ross 	    FILE_SHARE_WRITE },
1848bd49ed45SGordon Ross 	{ "DELETE",
1849bd49ed45SGordon Ross 	    FILE_SHARE_DELETE,
1850bd49ed45SGordon Ross 	    FILE_SHARE_DELETE },
1851bd49ed45SGordon Ross 	{ NULL, 0, 0}
18526537f381Sas };
18536537f381Sas 
18546537f381Sas static int
smbofile_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)18552b8c497cSGordon Ross smbofile_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1856da6c28aaSamw {
18576537f381Sas 	uint_t		opts;
18586537f381Sas 
18596537f381Sas 	if (smb_dcmd_getopt(&opts, argc, argv))
18606537f381Sas 		return (DCMD_USAGE);
1861da6c28aaSamw 
18626537f381Sas 	if (!(flags & DCMD_ADDRSPEC)) {
18636537f381Sas 		opts |= SMB_OPT_OFILE;
18646537f381Sas 		opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
18656537f381Sas 		    SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_ODIR);
18666537f381Sas 		return (smb_obj_list("smb_ofile", opts, flags));
1867da6c28aaSamw 	}
1868da6c28aaSamw 
18696537f381Sas 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_OFILE)) ||
18706537f381Sas 	    !(opts & SMB_OPT_WALK)) {
1871bd49ed45SGordon Ross 		mdb_smb_ofile_t *of;
18726537f381Sas 
1873bd49ed45SGordon Ross 		of = mdb_zalloc(sizeof (*of), UM_SLEEP | UM_GC);
1874bd49ed45SGordon Ross 		if (mdb_ctf_vread(of, SMBSRV_SCOPE "smb_ofile_t",
1875bd49ed45SGordon Ross 		    "mdb_smb_ofile_t", addr, 0) < 0) {
18766537f381Sas 			mdb_warn("failed to read smb_ofile at %p", addr);
18776537f381Sas 			return (DCMD_ERR);
18786537f381Sas 		}
18796537f381Sas 		if (opts & SMB_OPT_VERBOSE) {
1880bd49ed45SGordon Ross 			char		state[40];
1881811599a4SMatt Barden 			char		durable[40];
18826537f381Sas 
1883bd49ed45SGordon Ross 			get_enum(state, sizeof (state),
1884bd49ed45SGordon Ross 			    "smb_ofile_state_t", of->f_state,
1885bd49ed45SGordon Ross 			    "SMB_OFILE_STATE_");
18866537f381Sas 
1887811599a4SMatt Barden 			get_enum(durable, sizeof (durable),
1888811599a4SMatt Barden 			    "smb_dh_vers_t", of->dh_vers,
1889811599a4SMatt Barden 			    "SMB2_");
1890811599a4SMatt Barden 
18916537f381Sas 			mdb_printf(
18926537f381Sas 			    "%<b>%<u>SMB ofile information (%p):%</u>%</b>\n\n",
18936537f381Sas 			    addr);
18946537f381Sas 			mdb_printf("FID: %u\n", of->f_fid);
18956537f381Sas 			mdb_printf("State: %d (%s)\n", of->f_state, state);
1896811599a4SMatt Barden 			mdb_printf("DH Type: %d (%s)\n", of->dh_vers,
1897811599a4SMatt Barden 			    durable);
189894047d49SGordon Ross 			mdb_printf("Lease: %p\n", of->f_lease);
18996537f381Sas 			mdb_printf("SMB Node: %p\n", of->f_node);
19006537f381Sas 			mdb_printf("LLF Offset: 0x%llx (%s)\n",
19016537f381Sas 			    of->f_llf_pos,
19026537f381Sas 			    ((of->f_flags & SMB_OFLAGS_LLF_POS_VALID) ?
19036537f381Sas 			    "Valid" : "Invalid"));
1904bd49ed45SGordon Ross 			mdb_printf("Flags: 0x%08x <%b>\n", of->f_flags,
1905bd49ed45SGordon Ross 			    of->f_flags, ofile_flag_bits);
1906bd49ed45SGordon Ross 			mdb_printf("Granted Acc.: 0x%08x <%b>\n",
1907bd49ed45SGordon Ross 			    of->f_granted_access,
1908bd49ed45SGordon Ross 			    of->f_granted_access, nt_access_bits);
1909bd49ed45SGordon Ross 			mdb_printf("Share Mode: 0x%08x <%b>\n",
1910bd49ed45SGordon Ross 			    of->f_share_access,
1911bd49ed45SGordon Ross 			    of->f_share_access, smb_sharemode_bits);
19123b13a1efSThomas Keiser 			mdb_printf("User: %p\n", of->f_user);
19133b13a1efSThomas Keiser 			mdb_printf("Tree: %p\n", of->f_tree);
19146537f381Sas 			mdb_printf("Credential: %p\n\n", of->f_cr);
19156537f381Sas 		} else {
19166537f381Sas 			if (DCMD_HDRSPEC(flags))
19176537f381Sas 				mdb_printf(
19186537f381Sas 				    "%<b>%<u>%-?s "
19196537f381Sas 				    "%-5s "
19206537f381Sas 				    "%-?s "
192194047d49SGordon Ross 				    "%-?s "
192294047d49SGordon Ross 				    "%-?s "
192394047d49SGordon Ross 				    "%</u>%</b>\n",
192494047d49SGordon Ross 				    "OFILE",
192594047d49SGordon Ross 				    "FID",
192694047d49SGordon Ross 				    "NODE",
192794047d49SGordon Ross 				    "CRED",
192894047d49SGordon Ross 				    "LEASE");
192994047d49SGordon Ross 
193094047d49SGordon Ross 			mdb_printf("%?p %-5u %-p %-p %-p\n", addr,
193194047d49SGordon Ross 			    of->f_fid, of->f_node, of->f_cr, of->f_lease);
1932da6c28aaSamw 		}
1933da6c28aaSamw 	}
19346537f381Sas 	return (DCMD_OK);
1935da6c28aaSamw }
1936da6c28aaSamw 
1937811599a4SMatt Barden static int
smbdurable_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1938811599a4SMatt Barden smbdurable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1939811599a4SMatt Barden {
1940811599a4SMatt Barden 	mdb_smb_server_t *sv;
1941811599a4SMatt Barden 
1942811599a4SMatt Barden 	if (!(flags & DCMD_ADDRSPEC)) {
1943811599a4SMatt Barden 		mdb_printf("require address of an smb_server_t\n");
1944811599a4SMatt Barden 		return (WALK_ERR);
1945811599a4SMatt Barden 	}
1946811599a4SMatt Barden 
1947811599a4SMatt Barden 	sv = mdb_zalloc(sizeof (*sv), UM_SLEEP | UM_GC);
1948811599a4SMatt Barden 	if (mdb_ctf_vread(sv, SMBSRV_SCOPE "smb_server_t",
1949811599a4SMatt Barden 	    "mdb_smb_server_t", addr, 0) < 0) {
1950811599a4SMatt Barden 		mdb_warn("failed to read smb_server at %p", addr);
1951811599a4SMatt Barden 		return (DCMD_ERR);
1952811599a4SMatt Barden 	}
1953811599a4SMatt Barden 
1954811599a4SMatt Barden 	if (mdb_pwalk_dcmd("smb_hash_walker", "smbofile",
1955811599a4SMatt Barden 	    argc, argv, (uintptr_t)sv->sv_persistid_ht) == -1) {
1956811599a4SMatt Barden 		mdb_warn("failed to walk 'smb_ofile'");
1957811599a4SMatt Barden 		return (DCMD_ERR);
1958811599a4SMatt Barden 	}
1959811599a4SMatt Barden 	return (DCMD_OK);
1960811599a4SMatt Barden }
1961811599a4SMatt Barden 
1962811599a4SMatt Barden static int
smb_hash_walk_init(mdb_walk_state_t * wsp)1963811599a4SMatt Barden smb_hash_walk_init(mdb_walk_state_t *wsp)
1964811599a4SMatt Barden {
1965811599a4SMatt Barden 	smb_hash_t hash;
1966811599a4SMatt Barden 	int ll_off, sll_off, i;
1967811599a4SMatt Barden 	uintptr_t addr = wsp->walk_addr;
1968811599a4SMatt Barden 
1969cc3780e6SGordon Ross 	if (addr == 0) {
1970811599a4SMatt Barden 		mdb_printf("require address of an smb_hash_t\n");
1971811599a4SMatt Barden 		return (WALK_ERR);
1972811599a4SMatt Barden 	}
1973811599a4SMatt Barden 
1974811599a4SMatt Barden 	GET_OFFSET(sll_off, smb_bucket_t, b_list);
1975811599a4SMatt Barden 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
1976811599a4SMatt Barden 
1977811599a4SMatt Barden 	if (mdb_vread(&hash, sizeof (hash), addr) == -1) {
1978811599a4SMatt Barden 		mdb_warn("failed to read smb_hash_t at %p", addr);
1979811599a4SMatt Barden 		return (WALK_ERR);
1980811599a4SMatt Barden 	}
1981811599a4SMatt Barden 
1982811599a4SMatt Barden 	for (i = 0; i < hash.num_buckets; i++) {
1983811599a4SMatt Barden 		wsp->walk_addr = (uintptr_t)hash.buckets +
1984811599a4SMatt Barden 		    (i * sizeof (smb_bucket_t)) + sll_off + ll_off;
1985811599a4SMatt Barden 		if (mdb_layered_walk("list", wsp) == -1) {
1986811599a4SMatt Barden 			mdb_warn("failed to walk 'list'");
1987811599a4SMatt Barden 			return (WALK_ERR);
1988811599a4SMatt Barden 		}
1989811599a4SMatt Barden 	}
1990811599a4SMatt Barden 
1991811599a4SMatt Barden 	return (WALK_NEXT);
1992811599a4SMatt Barden }
1993811599a4SMatt Barden 
1994811599a4SMatt Barden static int
smb_hash_walk_step(mdb_walk_state_t * wsp)1995811599a4SMatt Barden smb_hash_walk_step(mdb_walk_state_t *wsp)
1996811599a4SMatt Barden {
1997811599a4SMatt Barden 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
1998811599a4SMatt Barden 	    wsp->walk_cbdata));
1999811599a4SMatt Barden }
2000811599a4SMatt Barden 
2001811599a4SMatt Barden static int
smbhashstat_cb(uintptr_t addr,const void * data,void * varg)2002811599a4SMatt Barden smbhashstat_cb(uintptr_t addr, const void *data, void *varg)
2003811599a4SMatt Barden {
2004811599a4SMatt Barden 	_NOTE(ARGUNUSED(varg))
2005811599a4SMatt Barden 	const smb_bucket_t *bucket = data;
2006811599a4SMatt Barden 
2007811599a4SMatt Barden 	mdb_printf("%-?p ", addr);	/* smb_bucket_t */
2008811599a4SMatt Barden 	mdb_printf("%-6u ", bucket->b_list.ll_count);
2009811599a4SMatt Barden 	mdb_printf("%-16u", bucket->b_max_seen);
2010811599a4SMatt Barden 	mdb_printf("%-u\n", (bucket->b_list.ll_wrop +
2011811599a4SMatt Barden 	    bucket->b_list.ll_count) / 2);
2012811599a4SMatt Barden 	return (WALK_NEXT);
2013811599a4SMatt Barden }
2014811599a4SMatt Barden 
2015811599a4SMatt Barden static int
smbhashstat_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2016811599a4SMatt Barden smbhashstat_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2017811599a4SMatt Barden {
2018811599a4SMatt Barden 	_NOTE(ARGUNUSED(argc, argv))
2019811599a4SMatt Barden 	if (!(flags & DCMD_ADDRSPEC)) {
2020811599a4SMatt Barden 		mdb_printf("require address of an smb_hash_t\n");
2021811599a4SMatt Barden 		return (DCMD_USAGE);
2022811599a4SMatt Barden 	}
2023811599a4SMatt Barden 
2024811599a4SMatt Barden 	if (DCMD_HDRSPEC(flags)) {
2025811599a4SMatt Barden 		mdb_printf(
2026811599a4SMatt Barden 		    "%<b>%<u>"
2027811599a4SMatt Barden 		    "%-?s "
2028811599a4SMatt Barden 		    "%-6s "
2029811599a4SMatt Barden 		    "%-16s"
2030811599a4SMatt Barden 		    "%-s"
2031811599a4SMatt Barden 		    "%</u>%</b>\n",
2032811599a4SMatt Barden 		    "smb_bucket_t", "count", "largest seen", "inserts");
2033811599a4SMatt Barden 	}
2034811599a4SMatt Barden 
2035811599a4SMatt Barden 	if (mdb_pwalk("smb_hashstat_walker", smbhashstat_cb,
2036811599a4SMatt Barden 	    NULL, addr) == -1) {
2037811599a4SMatt Barden 		mdb_warn("failed to walk 'smb_ofile'");
2038811599a4SMatt Barden 		return (DCMD_ERR);
2039811599a4SMatt Barden 	}
2040811599a4SMatt Barden 	return (DCMD_OK);
2041811599a4SMatt Barden }
2042811599a4SMatt Barden 
2043811599a4SMatt Barden typedef struct smb_hash_wd {
2044811599a4SMatt Barden 	smb_bucket_t	*bucket;
2045811599a4SMatt Barden 	smb_bucket_t	*end;
2046811599a4SMatt Barden } smb_hash_wd_t;
2047811599a4SMatt Barden 
2048811599a4SMatt Barden static int
smb_hashstat_walk_init(mdb_walk_state_t * wsp)2049811599a4SMatt Barden smb_hashstat_walk_init(mdb_walk_state_t *wsp)
2050811599a4SMatt Barden {
2051811599a4SMatt Barden 	int sll_off, ll_off;
2052811599a4SMatt Barden 	smb_hash_t hash;
2053811599a4SMatt Barden 	smb_bucket_t *buckets;
2054811599a4SMatt Barden 	uintptr_t addr = wsp->walk_addr;
2055811599a4SMatt Barden 	uint32_t arr_sz;
2056811599a4SMatt Barden 	smb_hash_wd_t *wd;
2057811599a4SMatt Barden 
2058cc3780e6SGordon Ross 	if (addr == 0) {
2059811599a4SMatt Barden 		mdb_printf("require address of an smb_hash_t\n");
2060811599a4SMatt Barden 		return (WALK_ERR);
2061811599a4SMatt Barden 	}
2062811599a4SMatt Barden 
2063811599a4SMatt Barden 	GET_OFFSET(sll_off, smb_bucket_t, b_list);
2064811599a4SMatt Barden 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
2065811599a4SMatt Barden 
2066811599a4SMatt Barden 	if (mdb_vread(&hash, sizeof (hash), addr) == -1) {
2067811599a4SMatt Barden 		mdb_warn("failed to read smb_hash_t at %p", addr);
2068811599a4SMatt Barden 		return (WALK_ERR);
2069811599a4SMatt Barden 	}
2070811599a4SMatt Barden 
2071811599a4SMatt Barden 	arr_sz = hash.num_buckets * sizeof (smb_bucket_t);
2072811599a4SMatt Barden 	buckets = mdb_alloc(arr_sz, UM_SLEEP | UM_GC);
2073811599a4SMatt Barden 	if (mdb_vread(buckets, arr_sz, (uintptr_t)hash.buckets) == -1) {
2074811599a4SMatt Barden 		mdb_warn("failed to read smb_bucket_t array at %p",
2075811599a4SMatt Barden 		    hash.buckets);
2076811599a4SMatt Barden 		return (WALK_ERR);
2077811599a4SMatt Barden 	}
2078811599a4SMatt Barden 
2079811599a4SMatt Barden 	wd = mdb_alloc(sizeof (*wd), UM_SLEEP | UM_GC);
2080811599a4SMatt Barden 	wd->bucket = buckets;
2081811599a4SMatt Barden 	wd->end = buckets + hash.num_buckets;
2082811599a4SMatt Barden 
2083811599a4SMatt Barden 	wsp->walk_addr = (uintptr_t)hash.buckets;
2084811599a4SMatt Barden 	wsp->walk_data = wd;
2085811599a4SMatt Barden 
2086811599a4SMatt Barden 	return (WALK_NEXT);
2087811599a4SMatt Barden }
2088811599a4SMatt Barden 
2089811599a4SMatt Barden static int
smb_hashstat_walk_step(mdb_walk_state_t * wsp)2090811599a4SMatt Barden smb_hashstat_walk_step(mdb_walk_state_t *wsp)
2091811599a4SMatt Barden {
2092811599a4SMatt Barden 	int rc;
2093811599a4SMatt Barden 	smb_hash_wd_t *wd = wsp->walk_data;
2094811599a4SMatt Barden 
2095811599a4SMatt Barden 	if (wd->bucket >= wd->end)
2096811599a4SMatt Barden 		return (WALK_DONE);
2097811599a4SMatt Barden 
2098811599a4SMatt Barden 	rc = wsp->walk_callback(wsp->walk_addr, wd->bucket++,
2099811599a4SMatt Barden 	    wsp->walk_cbdata);
2100811599a4SMatt Barden 
2101811599a4SMatt Barden 	wsp->walk_addr += sizeof (smb_bucket_t);
2102811599a4SMatt Barden 	return (rc);
2103811599a4SMatt Barden }
2104811599a4SMatt Barden 
210594047d49SGordon Ross /*
210694047d49SGordon Ross  * smbsrv_leases
210794047d49SGordon Ross  */
210894047d49SGordon Ross static int
smbsrv_leases_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)210994047d49SGordon Ross smbsrv_leases_dcmd(uintptr_t addr, uint_t flags, int argc,
211094047d49SGordon Ross     const mdb_arg_t *argv)
211194047d49SGordon Ross {
211294047d49SGordon Ross 	uint_t		opts;
211394047d49SGordon Ross 	int		ht_off;
211494047d49SGordon Ross 	uintptr_t	ht_addr;
211594047d49SGordon Ross 
211694047d49SGordon Ross 	if (smb_dcmd_getopt(&opts, argc, argv))
211794047d49SGordon Ross 		return (DCMD_USAGE);
211894047d49SGordon Ross 
211994047d49SGordon Ross 	if (!(flags & DCMD_ADDRSPEC)) {
212094047d49SGordon Ross 		mdb_printf("require address of an smb_server_t\n");
212194047d49SGordon Ross 		return (DCMD_USAGE);
212294047d49SGordon Ross 	}
212394047d49SGordon Ross 
212494047d49SGordon Ross 	ht_off = mdb_ctf_offsetof_by_name("smb_server_t", "sv_lease_ht");
212594047d49SGordon Ross 	if (ht_off < 0) {
212694047d49SGordon Ross 		mdb_warn("No .sv_lease_ht in server (old kernel?)");
212794047d49SGordon Ross 		return (DCMD_ERR);
212894047d49SGordon Ross 	}
212994047d49SGordon Ross 	addr += ht_off;
213094047d49SGordon Ross 
213194047d49SGordon Ross 	if (mdb_vread(&ht_addr, sizeof (ht_addr), addr) <= 0) {
213294047d49SGordon Ross 		mdb_warn("failed to read server .sv_lease_ht");
213394047d49SGordon Ross 		return (DCMD_ERR);
213494047d49SGordon Ross 	}
213594047d49SGordon Ross 
213694047d49SGordon Ross 	if (mdb_pwalk_dcmd("smb_hash_walker", "smblease",
213794047d49SGordon Ross 	    argc, argv, ht_addr) == -1) {
213894047d49SGordon Ross 		mdb_warn("failed to walk 'smb_lease'");
213994047d49SGordon Ross 		return (DCMD_ERR);
214094047d49SGordon Ross 	}
214194047d49SGordon Ross 	return (DCMD_OK);
214294047d49SGordon Ross }
214394047d49SGordon Ross 
214494047d49SGordon Ross typedef struct mdb_smb_lease {
214594047d49SGordon Ross 	struct smb_node		*ls_node;
214694047d49SGordon Ross 	uint32_t		ls_refcnt;
21476f8336c5SGordon Ross 	uint32_t		ls_state;
214894047d49SGordon Ross 	uint16_t		ls_epoch;
214994047d49SGordon Ross 	uint8_t			ls_key[SMB_LEASE_KEY_SZ];
215094047d49SGordon Ross } mdb_smb_lease_t;
215194047d49SGordon Ross 
21526f8336c5SGordon Ross static const mdb_bitmask_t oplock_bits[];
21536f8336c5SGordon Ross 
215494047d49SGordon Ross static int
smblease_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)215594047d49SGordon Ross smblease_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
215694047d49SGordon Ross {
215794047d49SGordon Ross 	mdb_smb_lease_t *ls;
215894047d49SGordon Ross 	uint_t opts;
215994047d49SGordon Ross 	int i;
216094047d49SGordon Ross 
216194047d49SGordon Ross 	if (smb_dcmd_getopt(&opts, argc, argv))
216294047d49SGordon Ross 		return (DCMD_USAGE);
216394047d49SGordon Ross 
216494047d49SGordon Ross 	if (!(flags & DCMD_ADDRSPEC)) {
216594047d49SGordon Ross 		mdb_printf("require address of an smb_lease_t\n");
216694047d49SGordon Ross 		return (DCMD_USAGE);
216794047d49SGordon Ross 	}
216894047d49SGordon Ross 
216994047d49SGordon Ross 	if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_OFILE)) ||
217094047d49SGordon Ross 	    !(opts & SMB_OPT_WALK)) {
217194047d49SGordon Ross 
217294047d49SGordon Ross 		ls = mdb_zalloc(sizeof (*ls), UM_SLEEP | UM_GC);
217394047d49SGordon Ross 		if (mdb_ctf_vread(ls, SMBSRV_SCOPE "smb_lease_t",
217494047d49SGordon Ross 		    "mdb_smb_lease_t", addr, 0) < 0) {
217594047d49SGordon Ross 			mdb_warn("failed to read smb_lease_t at %p", addr);
217694047d49SGordon Ross 			return (DCMD_ERR);
217794047d49SGordon Ross 		}
217894047d49SGordon Ross 		if (opts & SMB_OPT_VERBOSE) {
217994047d49SGordon Ross 
218094047d49SGordon Ross 			mdb_printf(
218194047d49SGordon Ross 			    "%<b>%<u>SMB lease (%p):%</u>%</b>\n\n", addr);
218294047d49SGordon Ross 
218394047d49SGordon Ross 			mdb_printf("SMB Node: %p\n", ls->ls_node);
218494047d49SGordon Ross 			mdb_printf("Refcount: %u\n", ls->ls_refcnt);
218594047d49SGordon Ross 			mdb_printf("Epoch: %u\n", ls->ls_epoch);
21866f8336c5SGordon Ross 			mdb_printf("State: 0x%x <%b>\n",
21876f8336c5SGordon Ross 			    ls->ls_state, ls->ls_state, oplock_bits);
218894047d49SGordon Ross 
218994047d49SGordon Ross 			mdb_printf("Key: [");
219094047d49SGordon Ross 			for (i = 0; i < SMB_LEASE_KEY_SZ; i++) {
219194047d49SGordon Ross 				mdb_printf(" %02x", ls->ls_key[i] & 0xFF);
219294047d49SGordon Ross 				if ((i & 3) == 3)
219394047d49SGordon Ross 					mdb_printf(" ");
219494047d49SGordon Ross 			}
219594047d49SGordon Ross 			mdb_printf(" ]\n");
219694047d49SGordon Ross 		} else {
219794047d49SGordon Ross 			if (DCMD_HDRSPEC(flags))
219894047d49SGordon Ross 				mdb_printf(
219994047d49SGordon Ross 				    "%<b>%<u>"
22006f8336c5SGordon Ross 				    "%-?s %-?s %-?s %-?s"
22016f8336c5SGordon Ross 				    "%</u>%</b>\n",
22026f8336c5SGordon Ross 				    "LEASE", "SMB NODE", "STATE", "KEY");
22036f8336c5SGordon Ross 
22046f8336c5SGordon Ross 			mdb_printf("%?p ", addr);
22056f8336c5SGordon Ross 			mdb_printf("%-?p ", ls->ls_node);
22066f8336c5SGordon Ross 			mdb_printf("%#-?x ", ls->ls_state);
220794047d49SGordon Ross 
22086f8336c5SGordon Ross 			mdb_printf("[");
220994047d49SGordon Ross 			for (i = 0; i < 8; i++) {
221094047d49SGordon Ross 				mdb_printf(" %02x", ls->ls_key[i] & 0xFF);
221194047d49SGordon Ross 			}
221294047d49SGordon Ross 			mdb_printf(" ...]\n");
221394047d49SGordon Ross 		}
221494047d49SGordon Ross 	}
221594047d49SGordon Ross 
221694047d49SGordon Ross 	return (DCMD_OK);
221794047d49SGordon Ross }
221894047d49SGordon Ross 
22195a6c34e6SGordon Ross /*
22205a6c34e6SGordon Ross  * *****************************************************************************
22215a6c34e6SGordon Ross  * ******************************** smb_kshare_t *******************************
22225a6c34e6SGordon Ross  * *****************************************************************************
22235a6c34e6SGordon Ross  */
22245a6c34e6SGordon Ross 
22252b8c497cSGordon Ross struct smb_kshare_cb_args {
22262b8c497cSGordon Ross 	uint_t		opts;
22272b8c497cSGordon Ross 	char name[MAXNAMELEN];
22282b8c497cSGordon Ross 	char path[MAXPATHLEN];
22292b8c497cSGordon Ross };
22302b8c497cSGordon Ross 
22315a6c34e6SGordon Ross static int
smb_kshare_cb(uintptr_t addr,const void * data,void * varg)22322b8c497cSGordon Ross smb_kshare_cb(uintptr_t addr, const void *data, void *varg)
22335a6c34e6SGordon Ross {
22342b8c497cSGordon Ross 	struct smb_kshare_cb_args *args = varg;
22352b8c497cSGordon Ross 	const smb_kshare_t *shr = data;
22365a6c34e6SGordon Ross 
22372b8c497cSGordon Ross 	if (args->opts & SMB_OPT_VERBOSE) {
22385a6c34e6SGordon Ross 		mdb_arg_t	argv;
22395a6c34e6SGordon Ross 
22405a6c34e6SGordon Ross 		argv.a_type = MDB_TYPE_STRING;
22415a6c34e6SGordon Ross 		argv.a_un.a_str = "smb_kshare_t";
22425a6c34e6SGordon Ross 		/* Don't fail the walk if this fails. */
22432b8c497cSGordon Ross 		mdb_printf("%-?p ", addr);
22445a6c34e6SGordon Ross 		mdb_call_dcmd("print", addr, 0, 1, &argv);
22452b8c497cSGordon Ross 		return (WALK_NEXT);
22465a6c34e6SGordon Ross 	}
22475a6c34e6SGordon Ross 
22482b8c497cSGordon Ross 	/*
22492b8c497cSGordon Ross 	 * Summary line for an smb_kshare_t
22502b8c497cSGordon Ross 	 * Don't fail the walk if any of these fail.
22512b8c497cSGordon Ross 	 *
22522b8c497cSGordon Ross 	 * Get the shr_name and shr_path strings.
22532b8c497cSGordon Ross 	 */
22542b8c497cSGordon Ross 	if (mdb_readstr(args->name, sizeof (args->name),
22552b8c497cSGordon Ross 	    (uintptr_t)shr->shr_name) <= 0)
22562b8c497cSGordon Ross 		strcpy(args->name, "?");
22572b8c497cSGordon Ross 
22582b8c497cSGordon Ross 	if (mdb_readstr(args->path, sizeof (args->path),
22592b8c497cSGordon Ross 	    (uintptr_t)shr->shr_path) <= 0)
22602b8c497cSGordon Ross 		strcpy(args->path, "?");
22612b8c497cSGordon Ross 
22622b8c497cSGordon Ross 	mdb_printf("%-?p ", addr);	/* smb_kshare_t */
22632b8c497cSGordon Ross 	mdb_printf("%-16s ", args->name);
22642b8c497cSGordon Ross 	mdb_printf("%-s\n", args->path);
22652b8c497cSGordon Ross 
22665a6c34e6SGordon Ross 	return (WALK_NEXT);
22675a6c34e6SGordon Ross }
22685a6c34e6SGordon Ross 
22695a6c34e6SGordon Ross /*
22702b8c497cSGordon Ross  * ::smbshare
22715a6c34e6SGordon Ross  *
22722b8c497cSGordon Ross  * smbshare dcmd - Print out smb_kshare structures.
22738622ec45SGordon Ross  *	requires addr of an smb_server_t
22745a6c34e6SGordon Ross  */
22755a6c34e6SGordon Ross /*ARGSUSED*/
22765a6c34e6SGordon Ross static int
smbshare_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)22772b8c497cSGordon Ross smbshare_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
22785a6c34e6SGordon Ross {
22792b8c497cSGordon Ross 	struct smb_kshare_cb_args *args;
22805a6c34e6SGordon Ross 
22812b8c497cSGordon Ross 	args = mdb_zalloc(sizeof (*args), UM_SLEEP | UM_GC);
22825a6c34e6SGordon Ross 	if (mdb_getopts(argc, argv,
22832b8c497cSGordon Ross 	    'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, &args->opts,
22845a6c34e6SGordon Ross 	    NULL) != argc)
22855a6c34e6SGordon Ross 		return (DCMD_USAGE);
22865a6c34e6SGordon Ross 
22878622ec45SGordon Ross 	if (!(flags & DCMD_ADDRSPEC))
22888622ec45SGordon Ross 		return (DCMD_USAGE);
22895a6c34e6SGordon Ross 
22905a6c34e6SGordon Ross 	if (DCMD_HDRSPEC(flags)) {
22912b8c497cSGordon Ross 		if ((args->opts & SMB_OPT_VERBOSE) != 0) {
22922b8c497cSGordon Ross 			mdb_printf("%<b>%<u>SMB kshares list:%</u>%</b>\n");
22932b8c497cSGordon Ross 		} else {
22942b8c497cSGordon Ross 			mdb_printf(
22952b8c497cSGordon Ross 			    "%<b>%<u>"
22962b8c497cSGordon Ross 			    "%-?s "
22972b8c497cSGordon Ross 			    "%-16s "
22982b8c497cSGordon Ross 			    "%-s"
22992b8c497cSGordon Ross 			    "%</u>%</b>\n",
23002b8c497cSGordon Ross 			    "smb_kshare_t", "name", "path");
23012b8c497cSGordon Ross 		}
23025a6c34e6SGordon Ross 	}
23035a6c34e6SGordon Ross 
23042b8c497cSGordon Ross 	if (mdb_pwalk("smbshare_walker", smb_kshare_cb, args, addr) == -1) {
23055a6c34e6SGordon Ross 		mdb_warn("cannot walk smb_kshare avl");
23065a6c34e6SGordon Ross 		return (DCMD_ERR);
23075a6c34e6SGordon Ross 	}
23085a6c34e6SGordon Ross 
23095a6c34e6SGordon Ross 	return (DCMD_OK);
23105a6c34e6SGordon Ross }
23115a6c34e6SGordon Ross 
23122b8c497cSGordon Ross /*
23132b8c497cSGordon Ross  * Initialize the smb_kshare_t walker to point to the smb_export
23142b8c497cSGordon Ross  * in the specified smb_server_t instance.  (no global walks)
23152b8c497cSGordon Ross  */
23162b8c497cSGordon Ross static int
smb_kshare_walk_init(mdb_walk_state_t * wsp)23172b8c497cSGordon Ross smb_kshare_walk_init(mdb_walk_state_t *wsp)
23182b8c497cSGordon Ross {
2319bd49ed45SGordon Ross 	int sv_exp_off, ex_sha_off, avl_tr_off;
23202b8c497cSGordon Ross 
2321cc3780e6SGordon Ross 	if (wsp->walk_addr == 0) {
23222b8c497cSGordon Ross 		mdb_printf("require address of an smb_server_t\n");
23232b8c497cSGordon Ross 		return (WALK_ERR);
23242b8c497cSGordon Ross 	}
23252b8c497cSGordon Ross 
2326bd49ed45SGordon Ross 	/*
2327bd49ed45SGordon Ross 	 * Using CTF to get the equivalent of:
2328bd49ed45SGordon Ross 	 * OFFSETOF(smb_server_t, sv_export.e_share_avl.avl_tree);
2329bd49ed45SGordon Ross 	 */
2330bd49ed45SGordon Ross 	GET_OFFSET(sv_exp_off, smb_server_t, sv_export);
2331bd49ed45SGordon Ross 	GET_OFFSET(ex_sha_off, smb_export_t, e_share_avl);
2332bd49ed45SGordon Ross 	GET_OFFSET(avl_tr_off, smb_avl_t, avl_tree);
2333bd49ed45SGordon Ross 	wsp->walk_addr += (sv_exp_off + ex_sha_off + avl_tr_off);
23342b8c497cSGordon Ross 
23352b8c497cSGordon Ross 	if (mdb_layered_walk("avl", wsp) == -1) {
23362b8c497cSGordon Ross 		mdb_warn("failed to walk list of smb_kshare_t");
23372b8c497cSGordon Ross 		return (WALK_ERR);
23382b8c497cSGordon Ross 	}
23392b8c497cSGordon Ross 
23402b8c497cSGordon Ross 	return (WALK_NEXT);
23412b8c497cSGordon Ross }
23422b8c497cSGordon Ross 
23432b8c497cSGordon Ross static int
smb_kshare_walk_step(mdb_walk_state_t * wsp)23442b8c497cSGordon Ross smb_kshare_walk_step(mdb_walk_state_t *wsp)
23452b8c497cSGordon Ross {
23462b8c497cSGordon Ross 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
23472b8c497cSGordon Ross 	    wsp->walk_cbdata));
23482b8c497cSGordon Ross }
23492b8c497cSGordon Ross 
2350148c5f43SAlan Wright /*
2351148c5f43SAlan Wright  * *****************************************************************************
2352148c5f43SAlan Wright  * ******************************** smb_vfs_t **********************************
2353148c5f43SAlan Wright  * *****************************************************************************
2354148c5f43SAlan Wright  */
2355148c5f43SAlan Wright 
23568d94f651SGordon Ross typedef struct mdb_smb_vfs {
23578d94f651SGordon Ross 	list_node_t		sv_lnd;
23588d94f651SGordon Ross 	uint32_t		sv_magic;
23598d94f651SGordon Ross 	uint32_t		sv_refcnt;
23608d94f651SGordon Ross 	vfs_t			*sv_vfsp;
23618d94f651SGordon Ross 	vnode_t			*sv_rootvp;
23628d94f651SGordon Ross } mdb_smb_vfs_t;
23638d94f651SGordon Ross 
23642b8c497cSGordon Ross struct smb_vfs_cb_args {
23652b8c497cSGordon Ross 	uint_t		opts;
23662b8c497cSGordon Ross 	vnode_t		vn;
23672b8c497cSGordon Ross 	char		path[MAXPATHLEN];
23682b8c497cSGordon Ross };
23692b8c497cSGordon Ross 
23708d94f651SGordon Ross /*ARGSUSED*/
23712b8c497cSGordon Ross static int
smb_vfs_cb(uintptr_t addr,const void * data,void * varg)23722b8c497cSGordon Ross smb_vfs_cb(uintptr_t addr, const void *data, void *varg)
23732b8c497cSGordon Ross {
23742b8c497cSGordon Ross 	struct smb_vfs_cb_args *args = varg;
23758d94f651SGordon Ross 	mdb_smb_vfs_t sf;
23762b8c497cSGordon Ross 
23772b8c497cSGordon Ross 	if (args->opts & SMB_OPT_VERBOSE) {
23782b8c497cSGordon Ross 		mdb_arg_t	argv;
23792b8c497cSGordon Ross 
23802b8c497cSGordon Ross 		argv.a_type = MDB_TYPE_STRING;
23812b8c497cSGordon Ross 		argv.a_un.a_str = "smb_vfs_t";
23822b8c497cSGordon Ross 		/* Don't fail the walk if this fails. */
23832b8c497cSGordon Ross 		mdb_printf("%-?p ", addr);
23842b8c497cSGordon Ross 		mdb_call_dcmd("print", addr, 0, 1, &argv);
23852b8c497cSGordon Ross 		return (WALK_NEXT);
23862b8c497cSGordon Ross 	}
23872b8c497cSGordon Ross 
23882b8c497cSGordon Ross 	/*
23892b8c497cSGordon Ross 	 * Summary line for an smb_vfs_t
23902b8c497cSGordon Ross 	 * Don't fail the walk if any of these fail.
23912b8c497cSGordon Ross 	 *
23922b8c497cSGordon Ross 	 * Get the vnode v_path string if we can.
23932b8c497cSGordon Ross 	 */
23948d94f651SGordon Ross 	if (mdb_ctf_vread(&sf, SMBSRV_SCOPE "smb_vfs_t",
23958d94f651SGordon Ross 	    "mdb_smb_vfs_t", addr, 0) < 0) {
23968d94f651SGordon Ross 		mdb_warn("failed to read struct smb_vfs at %p", addr);
23978d94f651SGordon Ross 		return (DCMD_ERR);
23988d94f651SGordon Ross 	}
23992b8c497cSGordon Ross 	strcpy(args->path, "?");
24002b8c497cSGordon Ross 	if (mdb_vread(&args->vn, sizeof (args->vn),
24018d94f651SGordon Ross 	    (uintptr_t)sf.sv_rootvp) == sizeof (args->vn))
24022b8c497cSGordon Ross 		(void) mdb_readstr(args->path, sizeof (args->path),
24032b8c497cSGordon Ross 		    (uintptr_t)args->vn.v_path);
24042b8c497cSGordon Ross 
24052b8c497cSGordon Ross 	mdb_printf("%-?p ", addr);
24068d94f651SGordon Ross 	mdb_printf("%-10d ", sf.sv_refcnt);
24078d94f651SGordon Ross 	mdb_printf("%-?p ", sf.sv_vfsp);
24088d94f651SGordon Ross 	mdb_printf("%-?p ", sf.sv_rootvp);
24092b8c497cSGordon Ross 	mdb_printf("%-s\n", args->path);
24102b8c497cSGordon Ross 
24112b8c497cSGordon Ross 	return (WALK_NEXT);
24122b8c497cSGordon Ross }
24132b8c497cSGordon Ross 
2414148c5f43SAlan Wright /*
2415148c5f43SAlan Wright  * ::smbvfs
2416148c5f43SAlan Wright  *
2417148c5f43SAlan Wright  * smbvfs dcmd - Prints out smb_vfs structures.
24182b8c497cSGordon Ross  *	requires addr of an smb_server_t
2419148c5f43SAlan Wright  */
2420148c5f43SAlan Wright /*ARGSUSED*/
2421148c5f43SAlan Wright static int
smbvfs_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)24222b8c497cSGordon Ross smbvfs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2423148c5f43SAlan Wright {
24242b8c497cSGordon Ross 	struct smb_vfs_cb_args *args;
2425148c5f43SAlan Wright 
24262b8c497cSGordon Ross 	args = mdb_zalloc(sizeof (*args), UM_SLEEP | UM_GC);
2427148c5f43SAlan Wright 	if (mdb_getopts(argc, argv,
24282b8c497cSGordon Ross 	    'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, &args->opts,
2429148c5f43SAlan Wright 	    NULL) != argc)
2430148c5f43SAlan Wright 		return (DCMD_USAGE);
2431148c5f43SAlan Wright 
24322b8c497cSGordon Ross 	if (!(flags & DCMD_ADDRSPEC))
24332b8c497cSGordon Ross 		return (DCMD_USAGE);
2434148c5f43SAlan Wright 
2435148c5f43SAlan Wright 	if (DCMD_HDRSPEC(flags)) {
24362b8c497cSGordon Ross 		if ((args->opts & SMB_OPT_VERBOSE) != 0) {
24372b8c497cSGordon Ross 			mdb_printf("%<b>%<u>SMB VFS list:%</u>%</b>\n");
24382b8c497cSGordon Ross 		} else {
24392b8c497cSGordon Ross 			mdb_printf(
24402b8c497cSGordon Ross 			    "%<b>%<u>"
24412b8c497cSGordon Ross 			    "%-?s "
24422b8c497cSGordon Ross 			    "%-10s "
24432b8c497cSGordon Ross 			    "%-16s "
24442b8c497cSGordon Ross 			    "%-16s"
24452b8c497cSGordon Ross 			    "%-s"
24462b8c497cSGordon Ross 			    "%</u>%</b>\n",
24472b8c497cSGordon Ross 			    "SMB_VFS", "REFCNT", "VFS", "VNODE", "ROOT");
24482b8c497cSGordon Ross 		}
2449148c5f43SAlan Wright 	}
2450148c5f43SAlan Wright 
24512b8c497cSGordon Ross 	if (mdb_pwalk("smbvfs_walker", smb_vfs_cb, args, addr) == -1) {
24522b8c497cSGordon Ross 		mdb_warn("cannot walk smb_vfs list");
2453148c5f43SAlan Wright 		return (DCMD_ERR);
2454148c5f43SAlan Wright 	}
2455148c5f43SAlan Wright 
2456148c5f43SAlan Wright 	return (DCMD_OK);
2457148c5f43SAlan Wright }
2458148c5f43SAlan Wright 
2459148c5f43SAlan Wright /*
24608622ec45SGordon Ross  * Initialize the smb_vfs_t walker to point to the smb_export
24618622ec45SGordon Ross  * in the specified smb_server_t instance.  (no global walks)
2462148c5f43SAlan Wright  */
2463148c5f43SAlan Wright static int
smb_vfs_walk_init(mdb_walk_state_t * wsp)2464148c5f43SAlan Wright smb_vfs_walk_init(mdb_walk_state_t *wsp)
2465148c5f43SAlan Wright {
2466bd49ed45SGordon Ross 	int sv_exp_off, ex_vfs_off, ll_off;
2467148c5f43SAlan Wright 
2468cc3780e6SGordon Ross 	if (wsp->walk_addr == 0) {
24698622ec45SGordon Ross 		mdb_printf("require address of an smb_server_t\n");
2470148c5f43SAlan Wright 		return (WALK_ERR);
2471148c5f43SAlan Wright 	}
2472148c5f43SAlan Wright 
2473bd49ed45SGordon Ross 	/*
2474bd49ed45SGordon Ross 	 * Using CTF to get the equivalent of:
2475bd49ed45SGordon Ross 	 * OFFSETOF(smb_server_t, sv_export.e_vfs_list.ll_list);
2476bd49ed45SGordon Ross 	 */
2477bd49ed45SGordon Ross 	GET_OFFSET(sv_exp_off, smb_server_t, sv_export);
24788d94f651SGordon Ross 	/* GET_OFFSET(ex_vfs_off, smb_export_t, e_vfs_list); */
24798d94f651SGordon Ross 	ex_vfs_off = mdb_ctf_offsetof_by_name("smb_export_t", "e_vfs_list");
24808d94f651SGordon Ross 	if (ex_vfs_off < 0) {
24818d94f651SGordon Ross 		mdb_warn("cannot lookup: smb_export_t .e_vfs_list");
24828d94f651SGordon Ross 		return (WALK_ERR);
24838d94f651SGordon Ross 	}
2484bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
2485bd49ed45SGordon Ross 	wsp->walk_addr += (sv_exp_off + ex_vfs_off + ll_off);
2486148c5f43SAlan Wright 
2487148c5f43SAlan Wright 	if (mdb_layered_walk("list", wsp) == -1) {
24882b8c497cSGordon Ross 		mdb_warn("failed to walk list of smb_vfs_t");
2489148c5f43SAlan Wright 		return (WALK_ERR);
2490148c5f43SAlan Wright 	}
2491148c5f43SAlan Wright 
2492148c5f43SAlan Wright 	return (WALK_NEXT);
2493148c5f43SAlan Wright }
2494148c5f43SAlan Wright 
2495148c5f43SAlan Wright static int
smb_vfs_walk_step(mdb_walk_state_t * wsp)2496148c5f43SAlan Wright smb_vfs_walk_step(mdb_walk_state_t *wsp)
2497148c5f43SAlan Wright {
2498148c5f43SAlan Wright 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
2499148c5f43SAlan Wright 	    wsp->walk_cbdata));
2500148c5f43SAlan Wright }
2501148c5f43SAlan Wright 
25026537f381Sas /*
25036537f381Sas  * *****************************************************************************
25046537f381Sas  * ******************************* smb_node_t **********************************
25056537f381Sas  * *****************************************************************************
25066537f381Sas  */
25076537f381Sas 
2508bd49ed45SGordon Ross typedef struct mdb_smb_node {
2509bd49ed45SGordon Ross 	smb_node_state_t	n_state;
2510bd49ed45SGordon Ross 	uint32_t		n_refcnt;
2511bd49ed45SGordon Ross 	uint32_t		n_open_count;
2512bd49ed45SGordon Ross 	uint32_t		n_opening_count;
2513bd49ed45SGordon Ross 	smb_llist_t		n_ofile_list;
2514bd49ed45SGordon Ross 	smb_llist_t		n_lock_list;
2515bd49ed45SGordon Ross 	volatile int		flags;
2516bd49ed45SGordon Ross 	struct smb_node		*n_dnode;
2517bd49ed45SGordon Ross 	struct smb_node		*n_unode;
2518bd49ed45SGordon Ross 	char			od_name[MAXNAMELEN];
2519bd49ed45SGordon Ross 	vnode_t			*vp;
2520bd49ed45SGordon Ross 	smb_audit_buf_node_t	*n_audit_buf;
25210897f7fbSGordon Ross 	/* Newer members (not in old kernels) - keep last! */
25220897f7fbSGordon Ross 	smb_llist_t		n_wlock_list;
2523bd49ed45SGordon Ross } mdb_smb_node_t;
25240897f7fbSGordon Ross typedef struct mdb_smb_node_old {
25250897f7fbSGordon Ross 	/* Note: MUST be layout as above! */
25260897f7fbSGordon Ross 	smb_node_state_t	n_state;
25270897f7fbSGordon Ross 	uint32_t		n_refcnt;
25280897f7fbSGordon Ross 	uint32_t		n_open_count;
25290897f7fbSGordon Ross 	uint32_t		n_opening_count;
25300897f7fbSGordon Ross 	smb_llist_t		n_ofile_list;
25310897f7fbSGordon Ross 	smb_llist_t		n_lock_list;
25320897f7fbSGordon Ross 	volatile int		flags;
25330897f7fbSGordon Ross 	struct smb_node		*n_dnode;
25340897f7fbSGordon Ross 	struct smb_node		*n_unode;
25350897f7fbSGordon Ross 	char			od_name[MAXNAMELEN];
25360897f7fbSGordon Ross 	vnode_t			*vp;
25370897f7fbSGordon Ross 	smb_audit_buf_node_t	*n_audit_buf;
25380897f7fbSGordon Ross 	/* Newer members omitted from _old */
25390897f7fbSGordon Ross } mdb_smb_node_old_t;
2540bd49ed45SGordon Ross 
2541da6c28aaSamw static void
smbnode_help(void)25422b8c497cSGordon Ross smbnode_help(void)
2543da6c28aaSamw {
2544da6c28aaSamw 	mdb_printf(
2545da6c28aaSamw 	    "Display the contents of smb_node_t, with optional filtering.\n\n");
25466537f381Sas 	(void) mdb_dec_indent(2);
2547da6c28aaSamw 	mdb_printf("%<b>OPTIONS%</b>\n");
25486537f381Sas 	(void) mdb_inc_indent(2);
2549da6c28aaSamw 	mdb_printf(
2550da6c28aaSamw 	    "-v\tDisplay verbose smb_node information\n"
2551da6c28aaSamw 	    "-p\tDisplay the full path of the vnode associated\n"
2552da6c28aaSamw 	    "-s\tDisplay the stack of the last 16 calls that modified the "
2553da6c28aaSamw 	    "reference\n\tcount\n");
2554da6c28aaSamw }
2555da6c28aaSamw 
2556da6c28aaSamw /*
25576537f381Sas  * ::smbnode
2558da6c28aaSamw  *
2559da6c28aaSamw  * smb_node dcmd - Print out smb_node structure.
2560da6c28aaSamw  */
2561da6c28aaSamw static int
smbnode_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)25622b8c497cSGordon Ross smbnode_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2563da6c28aaSamw {
25640897f7fbSGordon Ross 	static smb_llist_t zero_llist = {0};
2565bd49ed45SGordon Ross 	mdb_smb_node_t	node;
2566cb174861Sjoyce mcintosh 	int		rc;
2567da6c28aaSamw 	int		verbose = FALSE;
2568da6c28aaSamw 	int		print_full_path = FALSE;
2569da6c28aaSamw 	int		stack_trace = FALSE;
257094047d49SGordon Ross 	int		ol_cnt = 0;
2571da6c28aaSamw 	vnode_t		vnode;
2572da6c28aaSamw 	char		od_name[MAXNAMELEN];
2573da6c28aaSamw 	char		path_name[1024];
257494047d49SGordon Ross 	uintptr_t	list_addr;
257594047d49SGordon Ross 	struct mdb_smb_oplock *node_oplock;
2576da6c28aaSamw 
2577da6c28aaSamw 	if (mdb_getopts(argc, argv,
2578da6c28aaSamw 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
2579da6c28aaSamw 	    'p', MDB_OPT_SETBITS, TRUE, &print_full_path,
2580da6c28aaSamw 	    's', MDB_OPT_SETBITS, TRUE, &stack_trace,
2581da6c28aaSamw 	    NULL) != argc)
2582da6c28aaSamw 		return (DCMD_USAGE);
2583da6c28aaSamw 
2584da6c28aaSamw 	/*
2585da6c28aaSamw 	 * If no smb_node address was specified on the command line, we can
2586da6c28aaSamw 	 * print out all smb nodes by invoking the smb_node walker, using
2587da6c28aaSamw 	 * this dcmd itself as the callback.
2588da6c28aaSamw 	 */
2589da6c28aaSamw 	if (!(flags & DCMD_ADDRSPEC)) {
25906537f381Sas 		if (mdb_walk_dcmd("smbnode_walker", "smbnode",
2591da6c28aaSamw 		    argc, argv) == -1) {
2592da6c28aaSamw 			mdb_warn("failed to walk 'smb_node'");
2593da6c28aaSamw 			return (DCMD_ERR);
2594da6c28aaSamw 		}
2595da6c28aaSamw 		return (DCMD_OK);
2596da6c28aaSamw 	}
2597da6c28aaSamw 
2598da6c28aaSamw 	/*
25996537f381Sas 	 * For each smb_node, we just need to read the smb_node_t struct, read
26006537f381Sas 	 * and then print out the following fields.
2601da6c28aaSamw 	 */
2602bd49ed45SGordon Ross 	if (mdb_ctf_vread(&node, SMBSRV_SCOPE "smb_node_t",
2603bd49ed45SGordon Ross 	    "mdb_smb_node_t", addr, 0) < 0) {
26040897f7fbSGordon Ross 		/*
26050897f7fbSGordon Ross 		 * Fall-back handling for mdb_smb_node_old_t
26060897f7fbSGordon Ross 		 * Should remove after a while.
26070897f7fbSGordon Ross 		 */
26080897f7fbSGordon Ross 		if (mdb_ctf_vread(&node, SMBSRV_SCOPE "smb_node_t",
26090897f7fbSGordon Ross 		    "mdb_smb_node_old_t", addr, 0) < 0) {
26100897f7fbSGordon Ross 			mdb_warn("failed to read struct smb_node at %p", addr);
26110897f7fbSGordon Ross 			return (DCMD_ERR);
26120897f7fbSGordon Ross 		}
26130897f7fbSGordon Ross 		node.n_wlock_list = zero_llist;
2614bd49ed45SGordon Ross 	}
2615bd49ed45SGordon Ross 
2616bd49ed45SGordon Ross 	(void) mdb_snprintf(od_name, sizeof (od_name), "%s",
2617bd49ed45SGordon Ross 	    node.od_name);
2618bd49ed45SGordon Ross 	if (print_full_path) {
2619bd49ed45SGordon Ross 		if (mdb_vread(&vnode, sizeof (vnode_t),
2620bd49ed45SGordon Ross 		    (uintptr_t)node.vp) == sizeof (vnode_t)) {
2621bd49ed45SGordon Ross 			if (mdb_readstr(path_name, sizeof (path_name),
26223cc23d49SGordon Ross 			    (uintptr_t)vnode.v_path) <= 0) {
26233cc23d49SGordon Ross 				(void) mdb_snprintf(path_name,
26243cc23d49SGordon Ross 				    sizeof (path_name), "N/A");
2625da6c28aaSamw 			}
2626da6c28aaSamw 		}
2627bd49ed45SGordon Ross 	}
262894047d49SGordon Ross 
262994047d49SGordon Ross 	rc = smb_node_get_oplock(addr, &node_oplock);
263094047d49SGordon Ross 	if (rc != DCMD_OK)
263194047d49SGordon Ross 		return (rc);
263294047d49SGordon Ross 	ol_cnt = smb_node_oplock_cnt(node_oplock);
263394047d49SGordon Ross 
2634bd49ed45SGordon Ross 	if (verbose) {
263594047d49SGordon Ross 		int nol_off, nll_off, wll_off, ll_off;
2636bd49ed45SGordon Ross 
263794047d49SGordon Ross 		GET_OFFSET(nol_off, smb_node_t, n_ofile_list);
2638bd49ed45SGordon Ross 		GET_OFFSET(nll_off, smb_node_t, n_lock_list);
2639bd49ed45SGordon Ross 		GET_OFFSET(ll_off, smb_llist_t, ll_list);
26400897f7fbSGordon Ross 		/* This one is optional (for now). */
26410897f7fbSGordon Ross 		/* GET_OFFSET(wll_off, smb_node_t, n_wlock_list); */
26420897f7fbSGordon Ross 		wll_off = mdb_ctf_offsetof_by_name(
26430897f7fbSGordon Ross 		    "smb_node_t", "n_wlock_list");
2644bd49ed45SGordon Ross 
26450897f7fbSGordon Ross 		mdb_printf("%<b>%<u>SMB node information "
26460897f7fbSGordon Ross 		    "(%p):%</u>%</b>\n", addr);
2647bd49ed45SGordon Ross 		mdb_printf("VP: %p\n", node.vp);
2648bd49ed45SGordon Ross 		mdb_printf("Name: %s\n", od_name);
2649bd49ed45SGordon Ross 		if (print_full_path)
2650bd49ed45SGordon Ross 			mdb_printf("V-node Path: %s\n", path_name);
265194047d49SGordon Ross 		mdb_printf("Reference Count: %u\n", node.n_refcnt);
2652bd49ed45SGordon Ross 		mdb_printf("Ofiles: %u\n", node.n_ofile_list.ll_count);
265394047d49SGordon Ross 		if (node.n_ofile_list.ll_count != 0 && nol_off != -1) {
265494047d49SGordon Ross 			(void) mdb_inc_indent(SMB_DCMD_INDENT);
265594047d49SGordon Ross 			list_addr = addr + nol_off + ll_off;
265694047d49SGordon Ross 			if (mdb_pwalk_dcmd("list", "smbofile", 0,
265794047d49SGordon Ross 			    NULL, list_addr)) {
265894047d49SGordon Ross 				mdb_warn("failed to walk node's ofiles");
265994047d49SGordon Ross 			}
266094047d49SGordon Ross 			(void) mdb_dec_indent(SMB_DCMD_INDENT);
266194047d49SGordon Ross 		}
266294047d49SGordon Ross 
26630897f7fbSGordon Ross 		mdb_printf("Granted Locks: %u\n",
2664bd49ed45SGordon Ross 		    node.n_lock_list.ll_count);
2665bd49ed45SGordon Ross 		if (node.n_lock_list.ll_count != 0) {
2666bd49ed45SGordon Ross 			(void) mdb_inc_indent(SMB_DCMD_INDENT);
2667bd49ed45SGordon Ross 			list_addr = addr + nll_off + ll_off;
2668bd49ed45SGordon Ross 			if (mdb_pwalk_dcmd("list", "smblock", 0,
2669bd49ed45SGordon Ross 			    NULL, list_addr)) {
26700897f7fbSGordon Ross 				mdb_warn("failed to walk node's granted"
26710897f7fbSGordon Ross 				    " locks");
26720897f7fbSGordon Ross 			}
26730897f7fbSGordon Ross 			(void) mdb_dec_indent(SMB_DCMD_INDENT);
26740897f7fbSGordon Ross 		}
26750897f7fbSGordon Ross 		mdb_printf("Waiting Locks: %u\n",
26760897f7fbSGordon Ross 		    node.n_wlock_list.ll_count);
26770897f7fbSGordon Ross 		if (node.n_wlock_list.ll_count != 0 && wll_off != -1) {
26780897f7fbSGordon Ross 			(void) mdb_inc_indent(SMB_DCMD_INDENT);
26790897f7fbSGordon Ross 			list_addr = addr + wll_off + ll_off;
26800897f7fbSGordon Ross 			if (mdb_pwalk_dcmd("list", "smblock", 0,
26810897f7fbSGordon Ross 			    NULL, list_addr)) {
26820897f7fbSGordon Ross 				mdb_warn("failed to walk node's waiting"
2683bd49ed45SGordon Ross 				    " locks");
2684cb174861Sjoyce mcintosh 			}
2685bd49ed45SGordon Ross 			(void) mdb_dec_indent(SMB_DCMD_INDENT);
2686bd49ed45SGordon Ross 		}
268794047d49SGordon Ross 		if (ol_cnt == 0) {
268894047d49SGordon Ross 			mdb_printf("Opportunistic Locks: (none)\n");
2689da6c28aaSamw 		} else {
269094047d49SGordon Ross 			mdb_printf("Opportunistic Locks:\n");
269194047d49SGordon Ross 			(void) mdb_inc_indent(SMB_DCMD_INDENT);
269294047d49SGordon Ross 			/* Takes node address */
269394047d49SGordon Ross 			rc = mdb_call_dcmd("smbnode_oplock", addr,
2694bd49ed45SGordon Ross 			    flags, argc, argv);
269594047d49SGordon Ross 			(void) mdb_dec_indent(SMB_DCMD_INDENT);
2696bd49ed45SGordon Ross 			if (rc != DCMD_OK)
2697bd49ed45SGordon Ross 				return (rc);
2698da6c28aaSamw 		}
2699bd49ed45SGordon Ross 	} else {
27000897f7fbSGordon Ross 		if (DCMD_HDRSPEC(flags)) {
27010897f7fbSGordon Ross 			mdb_printf(
27020897f7fbSGordon Ross 			    "%<b>%<u>%-?s "
27030897f7fbSGordon Ross 			    "%-?s "
27040897f7fbSGordon Ross 			    "%-18s "
27050897f7fbSGordon Ross 			    "%-6s "
27060897f7fbSGordon Ross 			    "%-6s "
27070897f7fbSGordon Ross 			    "%-8s "
27080897f7fbSGordon Ross 			    "%-8s "
27090897f7fbSGordon Ross 			    "%-6s%</u>%</b>\n",
27100897f7fbSGordon Ross 			    "ADDR", "VP", "NODE-NAME", "OFILES", "LOCKS",
27110897f7fbSGordon Ross 			    "WLOCKS", "OPLOCK", "REF");
27120897f7fbSGordon Ross 		}
27130897f7fbSGordon Ross 
27140897f7fbSGordon Ross 		mdb_printf("%-?p %-?p %-18s %-6d %-6d %-8d %-8d %-6d ",
2715bd49ed45SGordon Ross 		    addr, node.vp, od_name, node.n_ofile_list.ll_count,
27160897f7fbSGordon Ross 		    node.n_lock_list.ll_count, node.n_wlock_list.ll_count,
271794047d49SGordon Ross 		    ol_cnt, node.n_refcnt);
2718da6c28aaSamw 
2719bd49ed45SGordon Ross 		if (print_full_path)
2720bd49ed45SGordon Ross 			mdb_printf("\t%s\n", path_name);
2721bd49ed45SGordon Ross 	}
2722bd49ed45SGordon Ross 	if (stack_trace && node.n_audit_buf) {
2723bd49ed45SGordon Ross 		int ctr;
2724bd49ed45SGordon Ross 		smb_audit_buf_node_t *anb;
2725da6c28aaSamw 
2726bd49ed45SGordon Ross 		anb = mdb_alloc(sizeof (smb_audit_buf_node_t),
2727bd49ed45SGordon Ross 		    UM_SLEEP | UM_GC);
2728da6c28aaSamw 
2729bd49ed45SGordon Ross 		if (mdb_vread(anb, sizeof (*anb),
2730bd49ed45SGordon Ross 		    (uintptr_t)node.n_audit_buf) != sizeof (*anb)) {
2731bd49ed45SGordon Ross 			mdb_warn("failed to read audit buffer");
2732bd49ed45SGordon Ross 			return (DCMD_ERR);
2733bd49ed45SGordon Ross 		}
2734bd49ed45SGordon Ross 		ctr = anb->anb_max_index + 1;
2735bd49ed45SGordon Ross 		anb->anb_index--;
2736bd49ed45SGordon Ross 		anb->anb_index &= anb->anb_max_index;
2737bd49ed45SGordon Ross 
2738bd49ed45SGordon Ross 		while (ctr) {
2739bd49ed45SGordon Ross 			smb_audit_record_node_t	*anr;
2740bd49ed45SGordon Ross 
2741bd49ed45SGordon Ross 			anr = anb->anb_records + anb->anb_index;
2742bd49ed45SGordon Ross 
2743bd49ed45SGordon Ross 			if (anr->anr_depth) {
2744bd49ed45SGordon Ross 				char c[MDB_SYM_NAMLEN];
2745bd49ed45SGordon Ross 				GElf_Sym sym;
2746bd49ed45SGordon Ross 				int i;
2747bd49ed45SGordon Ross 
2748bd49ed45SGordon Ross 				mdb_printf("\nRefCnt: %u\t",
2749bd49ed45SGordon Ross 				    anr->anr_refcnt);
2750bd49ed45SGordon Ross 
2751bd49ed45SGordon Ross 				for (i = 0;
2752bd49ed45SGordon Ross 				    i < anr->anr_depth;
2753bd49ed45SGordon Ross 				    i++) {
2754bd49ed45SGordon Ross 					if (mdb_lookup_by_addr(
2755bd49ed45SGordon Ross 					    anr->anr_stack[i],
2756bd49ed45SGordon Ross 					    MDB_SYM_FUZZY,
2757bd49ed45SGordon Ross 					    c, sizeof (c),
2758bd49ed45SGordon Ross 					    &sym) == -1) {
2759bd49ed45SGordon Ross 						continue;
2760da6c28aaSamw 					}
2761bd49ed45SGordon Ross 					mdb_printf("%s+0x%1x",
2762bd49ed45SGordon Ross 					    c,
2763bd49ed45SGordon Ross 					    anr->anr_stack[i] -
2764bd49ed45SGordon Ross 					    (uintptr_t)sym.st_value);
2765bd49ed45SGordon Ross 					++i;
2766bd49ed45SGordon Ross 					break;
2767bd49ed45SGordon Ross 				}
2768da6c28aaSamw 
2769bd49ed45SGordon Ross 				while (i < anr->anr_depth) {
2770bd49ed45SGordon Ross 					if (mdb_lookup_by_addr(
2771bd49ed45SGordon Ross 					    anr->anr_stack[i],
2772bd49ed45SGordon Ross 					    MDB_SYM_FUZZY,
2773bd49ed45SGordon Ross 					    c, sizeof (c),
2774bd49ed45SGordon Ross 					    &sym) == -1) {
2775da6c28aaSamw 						++i;
2776bd49ed45SGordon Ross 						continue;
2777da6c28aaSamw 					}
2778bd49ed45SGordon Ross 					mdb_printf("\n\t\t%s+0x%1x",
2779bd49ed45SGordon Ross 					    c,
2780bd49ed45SGordon Ross 					    anr->anr_stack[i] -
2781bd49ed45SGordon Ross 					    (uintptr_t)sym.st_value);
2782bd49ed45SGordon Ross 					++i;
2783da6c28aaSamw 				}
2784bd49ed45SGordon Ross 				mdb_printf("\n");
2785da6c28aaSamw 			}
2786bd49ed45SGordon Ross 			anb->anb_index--;
2787bd49ed45SGordon Ross 			anb->anb_index &= anb->anb_max_index;
2788bd49ed45SGordon Ross 			ctr--;
2789da6c28aaSamw 		}
2790da6c28aaSamw 	}
2791da6c28aaSamw 
2792da6c28aaSamw 	return (DCMD_OK);
2793da6c28aaSamw }
2794da6c28aaSamw 
2795da6c28aaSamw /*
27966537f381Sas  * Initialize the smb_node_t walker by reading the value of smb_node_hash_table
27976537f381Sas  * in the kernel's symbol table. Only global walk supported.
2798da6c28aaSamw  */
2799da6c28aaSamw static int
smb_node_walk_init(mdb_walk_state_t * wsp)28006537f381Sas smb_node_walk_init(mdb_walk_state_t *wsp)
2801da6c28aaSamw {
28026537f381Sas 	GElf_Sym	sym;
28036537f381Sas 	uintptr_t	node_hash_table_addr;
2804bd49ed45SGordon Ross 	int		ll_off;
2805bd49ed45SGordon Ross 	int		i;
2806faa1795aSjb 
2807cc3780e6SGordon Ross 	if (wsp->walk_addr == 0) {
2808b819cea2SGordon Ross 		if (mdb_lookup_by_obj(SMBSRV_OBJNAME, "smb_node_hash_table",
2809b819cea2SGordon Ross 		    &sym) == -1) {
28106537f381Sas 			mdb_warn("failed to find 'smb_node_hash_table'");
28116537f381Sas 			return (WALK_ERR);
2812da6c28aaSamw 		}
28136537f381Sas 		node_hash_table_addr = (uintptr_t)sym.st_value;
2814da6c28aaSamw 	} else {
28156537f381Sas 		mdb_printf("smb_node walk only supports global walks\n");
28166537f381Sas 		return (WALK_ERR);
2817da6c28aaSamw 	}
2818da6c28aaSamw 
2819bd49ed45SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
2820bd49ed45SGordon Ross 
28216537f381Sas 	for (i = 0; i < SMBND_HASH_MASK + 1; i++) {
28226537f381Sas 		wsp->walk_addr = node_hash_table_addr +
2823bd49ed45SGordon Ross 		    (i * sizeof (smb_llist_t)) + ll_off;
28246537f381Sas 		if (mdb_layered_walk("list", wsp) == -1) {
28256537f381Sas 			mdb_warn("failed to walk 'list'");
28266537f381Sas 			return (WALK_ERR);
2827da6c28aaSamw 		}
2828da6c28aaSamw 	}
2829da6c28aaSamw 
28306537f381Sas 	return (WALK_NEXT);
2831da6c28aaSamw }
2832da6c28aaSamw 
2833da6c28aaSamw static int
smb_node_walk_step(mdb_walk_state_t * wsp)28346537f381Sas smb_node_walk_step(mdb_walk_state_t *wsp)
2835da6c28aaSamw {
28366537f381Sas 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
28376537f381Sas 	    wsp->walk_cbdata));
2838da6c28aaSamw }
2839da6c28aaSamw 
28406537f381Sas /*
28416537f381Sas  * *****************************************************************************
28426537f381Sas  * ****************************** smb_lock_t ***********************************
28436537f381Sas  * *****************************************************************************
28446537f381Sas  */
28456537f381Sas 
2846bd49ed45SGordon Ross typedef struct mdb_smb_lock {
2847bd49ed45SGordon Ross 	smb_ofile_t		*l_file;
28480897f7fbSGordon Ross 	struct smb_lock		*l_blocked_by;
28490897f7fbSGordon Ross 	uint64_t		l_start;
28500897f7fbSGordon Ross 	uint64_t		l_length;
2851bd49ed45SGordon Ross 	uint32_t		l_pid;
2852bd49ed45SGordon Ross 	uint32_t		l_type;
28530897f7fbSGordon Ross 	uint32_t		l_flags;
28540897f7fbSGordon Ross 	/* Newer members (not in old kernels) - keep last! */
28550897f7fbSGordon Ross 	uint32_t		l_conflicts;
28560897f7fbSGordon Ross } mdb_smb_lock_t;
28570897f7fbSGordon Ross typedef struct mdb_smb_lock_old {
28580897f7fbSGordon Ross 	/* Note: MUST be same layout as above! */
28590897f7fbSGordon Ross 	smb_ofile_t		*l_file;
28600897f7fbSGordon Ross 	struct smb_lock		*l_blocked_by;
2861bd49ed45SGordon Ross 	uint64_t		l_start;
2862bd49ed45SGordon Ross 	uint64_t		l_length;
28630897f7fbSGordon Ross 	uint32_t		l_pid;
28640897f7fbSGordon Ross 	uint32_t		l_type;
28650897f7fbSGordon Ross 	uint32_t		l_flags;
28660897f7fbSGordon Ross 	/* Newer members omitted from _old */
28670897f7fbSGordon Ross } mdb_smb_lock_old_t;
2868bd49ed45SGordon Ross 
2869da6c28aaSamw static int
smblock_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)28702b8c497cSGordon Ross smblock_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2871da6c28aaSamw {
2872bd49ed45SGordon Ross 	mdb_smb_lock_t	lock;
2873da6c28aaSamw 	int		verbose = FALSE;
2874da6c28aaSamw 	char		*lock_type;
2875da6c28aaSamw 
2876da6c28aaSamw 	if (mdb_getopts(argc, argv,
2877da6c28aaSamw 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
2878da6c28aaSamw 	    NULL) != argc)
2879da6c28aaSamw 		return (DCMD_USAGE);
2880da6c28aaSamw 
2881da6c28aaSamw 	/*
2882da6c28aaSamw 	 * An smb_lock_t address must be specified.
2883da6c28aaSamw 	 */
2884da6c28aaSamw 	if (!(flags & DCMD_ADDRSPEC))
2885da6c28aaSamw 		return (DCMD_USAGE);
2886da6c28aaSamw 
2887bd49ed45SGordon Ross 	if (mdb_ctf_vread(&lock, SMBSRV_SCOPE "smb_lock_t",
2888bd49ed45SGordon Ross 	    "mdb_smb_lock_t", addr, 0) < 0) {
28890897f7fbSGordon Ross 		/*
28900897f7fbSGordon Ross 		 * Fall-back handling for mdb_smb_lock_old_t
28910897f7fbSGordon Ross 		 * Should remove after a while.
28920897f7fbSGordon Ross 		 */
28930897f7fbSGordon Ross 		if (mdb_ctf_vread(&lock, SMBSRV_SCOPE "smb_lock_t",
28940897f7fbSGordon Ross 		    "mdb_smb_lock_old_t", addr, 0) < 0) {
28950897f7fbSGordon Ross 			mdb_warn("failed to read struct smb_lock at %p", addr);
28960897f7fbSGordon Ross 			return (DCMD_ERR);
28970897f7fbSGordon Ross 		}
28980897f7fbSGordon Ross 		lock.l_conflicts = 0;
2899bd49ed45SGordon Ross 	}
2900bd49ed45SGordon Ross 
2901bd49ed45SGordon Ross 	switch (lock.l_type) {
2902bd49ed45SGordon Ross 	case SMB_LOCK_TYPE_READWRITE:
2903bd49ed45SGordon Ross 		lock_type = "RW";
2904bd49ed45SGordon Ross 		break;
2905bd49ed45SGordon Ross 	case SMB_LOCK_TYPE_READONLY:
2906bd49ed45SGordon Ross 		lock_type = "RO";
2907bd49ed45SGordon Ross 		break;
2908bd49ed45SGordon Ross 	default:
29090897f7fbSGordon Ross 		lock_type = "?";
2910bd49ed45SGordon Ross 		break;
2911bd49ed45SGordon Ross 	}
2912bd49ed45SGordon Ross 	if (verbose) {
29130897f7fbSGordon Ross 		mdb_printf("%<b>%<u>SMB lock information "
29140897f7fbSGordon Ross 		    "(%p):%</u>%</b>\n", addr);
2915bd49ed45SGordon Ross 
2916bd49ed45SGordon Ross 		mdb_printf("Type             :\t%s (%u)\n",
2917bd49ed45SGordon Ross 		    lock_type, lock.l_type);
29180897f7fbSGordon Ross 		mdb_printf("Start            :\t%llu\n",
2919bd49ed45SGordon Ross 		    lock.l_start);
29200897f7fbSGordon Ross 		mdb_printf("Length           :\t%llu\n",
2921bd49ed45SGordon Ross 		    lock.l_length);
29220897f7fbSGordon Ross 		mdb_printf("OFile            :\t%p\n",
2923bd49ed45SGordon Ross 		    lock.l_file);
2924bd49ed45SGordon Ross 		mdb_printf("Process ID       :\t%u\n",
2925bd49ed45SGordon Ross 		    lock.l_pid);
2926bd49ed45SGordon Ross 		mdb_printf("Conflicts        :\t%u\n",
29270897f7fbSGordon Ross 		    lock.l_conflicts);
2928bd49ed45SGordon Ross 		mdb_printf("Blocked by       :\t%p\n",
2929bd49ed45SGordon Ross 		    lock.l_blocked_by);
2930bd49ed45SGordon Ross 		mdb_printf("Flags            :\t0x%x\n",
2931bd49ed45SGordon Ross 		    lock.l_flags);
2932bd49ed45SGordon Ross 		mdb_printf("\n");
2933da6c28aaSamw 	} else {
29340897f7fbSGordon Ross 		if (DCMD_HDRSPEC(flags)) {
29350897f7fbSGordon Ross 			mdb_printf("%<u>%-?s %4s %16s %8s %9s %-?s%</u>\n",
29360897f7fbSGordon Ross 			    "Locks: ", "TYPE", "START", "LENGTH",
29370897f7fbSGordon Ross 			    "CONFLICTS", "BLOCKED-BY");
29380897f7fbSGordon Ross 		}
29390897f7fbSGordon Ross 		mdb_printf("%?p %4s %16llx %08llx %9u %?p",
29400897f7fbSGordon Ross 		    addr, lock_type, lock.l_start, lock.l_length,
29410897f7fbSGordon Ross 		    lock.l_conflicts, lock.l_blocked_by);
2942da6c28aaSamw 	}
2943da6c28aaSamw 
2944da6c28aaSamw 	return (DCMD_OK);
2945da6c28aaSamw }
2946da6c28aaSamw 
2947cb174861Sjoyce mcintosh /*
2948cb174861Sjoyce mcintosh  * *****************************************************************************
2949cb174861Sjoyce mcintosh  * ************************** smb_oplock_grant_t *******************************
2950cb174861Sjoyce mcintosh  * *****************************************************************************
2951cb174861Sjoyce mcintosh  */
2952bd49ed45SGordon Ross 
2953bd49ed45SGordon Ross typedef struct mdb_smb_oplock_grant {
295494047d49SGordon Ross 	uint32_t		og_state;	/* latest sent to client */
295594047d49SGordon Ross 	uint8_t			onlist_II;
295694047d49SGordon Ross 	uint8_t			onlist_R;
295794047d49SGordon Ross 	uint8_t			onlist_RH;
295894047d49SGordon Ross 	uint8_t			onlist_RHBQ;
295994047d49SGordon Ross 	uint8_t			BreakingToRead;
2960bd49ed45SGordon Ross } mdb_smb_oplock_grant_t;
2961bd49ed45SGordon Ross 
296294047d49SGordon Ross static const mdb_bitmask_t
296394047d49SGordon Ross oplock_bits[] = {
296494047d49SGordon Ross 	{  "READ_CACHING",
296594047d49SGordon Ross 	    READ_CACHING,
296694047d49SGordon Ross 	    READ_CACHING },
296794047d49SGordon Ross 	{  "HANDLE_CACHING",
296894047d49SGordon Ross 	    HANDLE_CACHING,
296994047d49SGordon Ross 	    HANDLE_CACHING },
297094047d49SGordon Ross 	{  "WRITE_CACHING",
297194047d49SGordon Ross 	    WRITE_CACHING,
297294047d49SGordon Ross 	    WRITE_CACHING },
297394047d49SGordon Ross 	{  "EXCLUSIVE",
297494047d49SGordon Ross 	    EXCLUSIVE,
297594047d49SGordon Ross 	    EXCLUSIVE },
297694047d49SGordon Ross 	{  "MIXED_R_AND_RH",
297794047d49SGordon Ross 	    MIXED_R_AND_RH,
297894047d49SGordon Ross 	    MIXED_R_AND_RH },
297994047d49SGordon Ross 	{  "LEVEL_TWO_OPLOCK",
298094047d49SGordon Ross 	    LEVEL_TWO_OPLOCK,
298194047d49SGordon Ross 	    LEVEL_TWO_OPLOCK },
298294047d49SGordon Ross 	{  "LEVEL_ONE_OPLOCK",
298394047d49SGordon Ross 	    LEVEL_ONE_OPLOCK,
298494047d49SGordon Ross 	    LEVEL_ONE_OPLOCK },
298594047d49SGordon Ross 	{  "BATCH_OPLOCK",
298694047d49SGordon Ross 	    BATCH_OPLOCK,
298794047d49SGordon Ross 	    BATCH_OPLOCK },
298894047d49SGordon Ross 	{  "BREAK_TO_TWO",
298994047d49SGordon Ross 	    BREAK_TO_TWO,
299094047d49SGordon Ross 	    BREAK_TO_TWO },
299194047d49SGordon Ross 	{  "BREAK_TO_NONE",
299294047d49SGordon Ross 	    BREAK_TO_NONE,
299394047d49SGordon Ross 	    BREAK_TO_NONE },
299494047d49SGordon Ross 	{  "BREAK_TO_TWO_TO_NONE",
299594047d49SGordon Ross 	    BREAK_TO_TWO_TO_NONE,
299694047d49SGordon Ross 	    BREAK_TO_TWO_TO_NONE },
299794047d49SGordon Ross 	{  "BREAK_TO_READ_CACHING",
299894047d49SGordon Ross 	    BREAK_TO_READ_CACHING,
299994047d49SGordon Ross 	    BREAK_TO_READ_CACHING },
300094047d49SGordon Ross 	{  "BREAK_TO_HANDLE_CACHING",
300194047d49SGordon Ross 	    BREAK_TO_HANDLE_CACHING,
300294047d49SGordon Ross 	    BREAK_TO_HANDLE_CACHING },
300394047d49SGordon Ross 	{  "BREAK_TO_WRITE_CACHING",
300494047d49SGordon Ross 	    BREAK_TO_WRITE_CACHING,
300594047d49SGordon Ross 	    BREAK_TO_WRITE_CACHING },
300694047d49SGordon Ross 	{  "BREAK_TO_NO_CACHING",
300794047d49SGordon Ross 	    BREAK_TO_NO_CACHING,
300894047d49SGordon Ross 	    BREAK_TO_NO_CACHING },
300994047d49SGordon Ross 	{  "NO_OPLOCK",
301094047d49SGordon Ross 	    NO_OPLOCK,
301194047d49SGordon Ross 	    NO_OPLOCK },
301294047d49SGordon Ross 	{  NULL, 0, 0 }
301394047d49SGordon Ross };
301494047d49SGordon Ross 
301594047d49SGordon Ross /*
301694047d49SGordon Ross  * Show smb_ofile_t oplock info
301794047d49SGordon Ross  * address is the ofile
301894047d49SGordon Ross  */
301994047d49SGordon Ross 
3020cb174861Sjoyce mcintosh /*ARGSUSED*/
3021cb174861Sjoyce mcintosh static int
smbofile_oplock_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)302294047d49SGordon Ross smbofile_oplock_dcmd(uintptr_t addr, uint_t flags, int argc,
30232b8c497cSGordon Ross     const mdb_arg_t *argv)
3024cb174861Sjoyce mcintosh {
302594047d49SGordon Ross 	mdb_smb_oplock_grant_t	og;
302694047d49SGordon Ross 	int verbose = FALSE;
302794047d49SGordon Ross 	static int og_off;
302894047d49SGordon Ross 
302994047d49SGordon Ross 	if (mdb_getopts(argc, argv,
303094047d49SGordon Ross 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
303194047d49SGordon Ross 	    NULL) != argc)
303294047d49SGordon Ross 		return (DCMD_USAGE);
3033cb174861Sjoyce mcintosh 
3034cb174861Sjoyce mcintosh 	if (!(flags & DCMD_ADDRSPEC))
3035cb174861Sjoyce mcintosh 		return (DCMD_USAGE);
3036cb174861Sjoyce mcintosh 
303794047d49SGordon Ross 	if (og_off <= 0) {
303894047d49SGordon Ross 		og_off = mdb_ctf_offsetof_by_name(
303994047d49SGordon Ross 		    "smb_ofile_t", "f_oplock");
304094047d49SGordon Ross 		if (og_off < 0) {
304194047d49SGordon Ross 			mdb_warn("cannot lookup: smb_ofile_t .f_oplock");
304294047d49SGordon Ross 			return (DCMD_ERR);
304394047d49SGordon Ross 		}
3044cb174861Sjoyce mcintosh 	}
3045cb174861Sjoyce mcintosh 
304694047d49SGordon Ross 	if (mdb_ctf_vread(&og, SMBSRV_SCOPE "smb_oplock_grant_t",
304794047d49SGordon Ross 	    "mdb_smb_oplock_grant_t", addr + og_off, 0) < 0) {
304894047d49SGordon Ross 		mdb_warn("failed to read oplock grant in ofile at %p", addr);
3049bd49ed45SGordon Ross 		return (DCMD_ERR);
3050bd49ed45SGordon Ross 	}
3051cb174861Sjoyce mcintosh 
305294047d49SGordon Ross 	if (verbose) {
305394047d49SGordon Ross 		mdb_printf("%<b>%<u>SMB ofile (oplock_grant) "
305494047d49SGordon Ross 		    "(%p):%</u>%</b>\n", addr);
305594047d49SGordon Ross 		mdb_printf("State: 0x%x <%b>\n",
305694047d49SGordon Ross 		    og.og_state,
305794047d49SGordon Ross 		    og.og_state,
305894047d49SGordon Ross 		    oplock_bits);
305994047d49SGordon Ross 		mdb_printf("OnList_II: %d\n", og.onlist_II);
306094047d49SGordon Ross 		mdb_printf("OnList_R: %d\n", og.onlist_R);
306194047d49SGordon Ross 		mdb_printf("OnList_RH: %d\n", og.onlist_RH);
306294047d49SGordon Ross 		mdb_printf("OnList_RHBQ: %d\n", og.onlist_RHBQ);
306394047d49SGordon Ross 		mdb_printf("BrkToRead: %d\n", og.BreakingToRead);
306494047d49SGordon Ross 
306594047d49SGordon Ross 	} else {
306694047d49SGordon Ross 
306794047d49SGordon Ross 		if (DCMD_HDRSPEC(flags)) {
306894047d49SGordon Ross 			mdb_printf("%<u>%-16s %-10s %-16s%</u>\n",
306994047d49SGordon Ross 			    "OFILE", "STATE", "OnList...");
307094047d49SGordon Ross 		}
307194047d49SGordon Ross 
307294047d49SGordon Ross 		mdb_printf("%-16p", addr);
307394047d49SGordon Ross 		mdb_printf(" 0x%x", og.og_state);
307494047d49SGordon Ross 		if (og.onlist_II)
307594047d49SGordon Ross 			mdb_printf(" II");
307694047d49SGordon Ross 		if (og.onlist_R)
307794047d49SGordon Ross 			mdb_printf(" R");
307894047d49SGordon Ross 		if (og.onlist_RH)
307994047d49SGordon Ross 			mdb_printf(" RH");
308094047d49SGordon Ross 		if (og.onlist_RHBQ)
308194047d49SGordon Ross 			mdb_printf(" RHBQ");
308294047d49SGordon Ross 		if (og.BreakingToRead)
308394047d49SGordon Ross 			mdb_printf(" BrkToRd");
308494047d49SGordon Ross 		mdb_printf("\n");
3085cb174861Sjoyce mcintosh 	}
3086bd49ed45SGordon Ross 
3087cb174861Sjoyce mcintosh 	return (DCMD_OK);
3088cb174861Sjoyce mcintosh }
3089cb174861Sjoyce mcintosh 
3090cb174861Sjoyce mcintosh /*
3091cb174861Sjoyce mcintosh  * *****************************************************************************
3092cb174861Sjoyce mcintosh  * ***************************** smb_oplock_t **********************************
3093cb174861Sjoyce mcintosh  * *****************************************************************************
3094cb174861Sjoyce mcintosh  */
3095bd49ed45SGordon Ross 
3096bd49ed45SGordon Ross typedef struct mdb_smb_oplock {
309794047d49SGordon Ross 	struct smb_ofile	*excl_open;
309894047d49SGordon Ross 	uint32_t		ol_state;
309994047d49SGordon Ross 	int32_t			cnt_II;
310094047d49SGordon Ross 	int32_t			cnt_R;
310194047d49SGordon Ross 	int32_t			cnt_RH;
310294047d49SGordon Ross 	int32_t			cnt_RHBQ;
310394047d49SGordon Ross 	int32_t			waiters;
3104bd49ed45SGordon Ross } mdb_smb_oplock_t;
3105bd49ed45SGordon Ross 
310694047d49SGordon Ross /*
310794047d49SGordon Ross  * Helpers for smbnode_dcmd and smbnode_oplock_dcmd
310894047d49SGordon Ross  */
310994047d49SGordon Ross 
311094047d49SGordon Ross /*
311194047d49SGordon Ross  * Read the smb_oplock_t part of the node
311294047d49SGordon Ross  * addr is the smb_node
311394047d49SGordon Ross  */
311494047d49SGordon Ross static int
smb_node_get_oplock(uintptr_t addr,struct mdb_smb_oplock ** ol_ret)311594047d49SGordon Ross smb_node_get_oplock(uintptr_t addr, struct mdb_smb_oplock **ol_ret)
311694047d49SGordon Ross {
311794047d49SGordon Ross 	mdb_smb_oplock_t *ol;
311894047d49SGordon Ross 	static int ol_off;
311994047d49SGordon Ross 
312094047d49SGordon Ross 	if (ol_off <= 0) {
312194047d49SGordon Ross 		ol_off = mdb_ctf_offsetof_by_name(
312294047d49SGordon Ross 		    "smb_node_t", "n_oplock");
312394047d49SGordon Ross 		if (ol_off < 0) {
312494047d49SGordon Ross 			mdb_warn("cannot lookup: smb_node_t .n_oplock");
312594047d49SGordon Ross 			return (DCMD_ERR);
312694047d49SGordon Ross 		}
312794047d49SGordon Ross 	}
312894047d49SGordon Ross 
312994047d49SGordon Ross 	ol = mdb_alloc(sizeof (*ol), UM_SLEEP | UM_GC);
313094047d49SGordon Ross 
313194047d49SGordon Ross 	if (mdb_ctf_vread(ol, SMBSRV_SCOPE "smb_oplock_t",
313294047d49SGordon Ross 	    "mdb_smb_oplock_t", addr + ol_off, 0) < 0) {
313394047d49SGordon Ross 		mdb_warn("failed to read smb_oplock in node at %p", addr);
313494047d49SGordon Ross 		return (DCMD_ERR);
313594047d49SGordon Ross 	}
313694047d49SGordon Ross 
313794047d49SGordon Ross 	*ol_ret = ol;
313894047d49SGordon Ross 	return (DCMD_OK);
313994047d49SGordon Ross }
314094047d49SGordon Ross 
314194047d49SGordon Ross /*
314294047d49SGordon Ross  * Return the oplock count
314394047d49SGordon Ross  */
314494047d49SGordon Ross static int
smb_node_oplock_cnt(struct mdb_smb_oplock * ol)314594047d49SGordon Ross smb_node_oplock_cnt(struct mdb_smb_oplock *ol)
314694047d49SGordon Ross {
314794047d49SGordon Ross 	int ol_cnt = 0;
314894047d49SGordon Ross 
314994047d49SGordon Ross 	/* Compute total oplock count. */
315094047d49SGordon Ross 	if (ol->excl_open != NULL)
315194047d49SGordon Ross 		ol_cnt++;
315294047d49SGordon Ross 	ol_cnt += ol->cnt_II;
315394047d49SGordon Ross 	ol_cnt += ol->cnt_R;
315494047d49SGordon Ross 	ol_cnt += ol->cnt_RH;
315594047d49SGordon Ross 
315694047d49SGordon Ross 	return (ol_cnt);
315794047d49SGordon Ross }
315894047d49SGordon Ross 
315994047d49SGordon Ross /*
316094047d49SGordon Ross  * Show smb_node_t oplock info, and optionally the
316194047d49SGordon Ross  * list of ofiles with oplocks on this node.
316294047d49SGordon Ross  * Address is the smb_node_t.
316394047d49SGordon Ross  */
316494047d49SGordon Ross 
3165cb174861Sjoyce mcintosh /*ARGSUSED*/
3166cb174861Sjoyce mcintosh static int
smbnode_oplock_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)316794047d49SGordon Ross smbnode_oplock_dcmd(uintptr_t addr, uint_t flags, int argc,
316894047d49SGordon Ross     const mdb_arg_t *argv)
3169cb174861Sjoyce mcintosh {
317094047d49SGordon Ross 	mdb_smb_oplock_t *ol;
317194047d49SGordon Ross 	int verbose = FALSE;
317294047d49SGordon Ross 	int ol_cnt, rc;
317394047d49SGordon Ross 	int fl_off, ll_off;
317494047d49SGordon Ross 
317594047d49SGordon Ross 	if (mdb_getopts(argc, argv,
317694047d49SGordon Ross 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
317794047d49SGordon Ross 	    NULL) != argc)
317894047d49SGordon Ross 		return (DCMD_USAGE);
3179cb174861Sjoyce mcintosh 
3180cb174861Sjoyce mcintosh 	if (!(flags & DCMD_ADDRSPEC))
3181cb174861Sjoyce mcintosh 		return (DCMD_USAGE);
3182cb174861Sjoyce mcintosh 
318394047d49SGordon Ross 	rc = smb_node_get_oplock(addr, &ol);
318494047d49SGordon Ross 	if (rc != DCMD_OK)
318594047d49SGordon Ross 		return (rc);
318694047d49SGordon Ross 	ol_cnt = smb_node_oplock_cnt(ol);
318794047d49SGordon Ross 
318894047d49SGordon Ross 	if (verbose) {
318994047d49SGordon Ross 		mdb_printf("%<b>%<u>SMB node (oplock) "
319094047d49SGordon Ross 		    "(%p):%</u>%</b>\n", addr);
319194047d49SGordon Ross 		mdb_printf("State: 0x%x <%b>\n",
319294047d49SGordon Ross 		    ol->ol_state,
319394047d49SGordon Ross 		    ol->ol_state,
319494047d49SGordon Ross 		    oplock_bits);
319594047d49SGordon Ross 		mdb_printf("Exclusive Open: %p\n", ol->excl_open);
319694047d49SGordon Ross 		mdb_printf("cnt_II: %d\n", ol->cnt_II);
319794047d49SGordon Ross 		mdb_printf("cnt_R: %d\n", ol->cnt_R);
319894047d49SGordon Ross 		mdb_printf("cnt_RH: %d\n", ol->cnt_RH);
319994047d49SGordon Ross 		mdb_printf("cnt_RHBQ: %d\n", ol->cnt_RHBQ);
320094047d49SGordon Ross 		mdb_printf("waiters: %d\n", ol->waiters);
320194047d49SGordon Ross 	} else {
320294047d49SGordon Ross 		if (DCMD_HDRSPEC(flags)) {
320394047d49SGordon Ross 			mdb_printf("%<u>%-16s %-10s %-16s%</u>\n",
320494047d49SGordon Ross 			    "NODE", "STATE", "OPLOCKS");
320594047d49SGordon Ross 		}
320694047d49SGordon Ross 		mdb_printf("%-16p 0x%x %d\n",
320794047d49SGordon Ross 		    addr, ol->ol_state, ol_cnt);
3208cb174861Sjoyce mcintosh 	}
3209cb174861Sjoyce mcintosh 
321094047d49SGordon Ross 	if (ol_cnt == 0)
3211cb174861Sjoyce mcintosh 		return (DCMD_OK);
3212cb174861Sjoyce mcintosh 
321394047d49SGordon Ross 	GET_OFFSET(fl_off, smb_node_t, n_ofile_list);
321494047d49SGordon Ross 	GET_OFFSET(ll_off, smb_llist_t, ll_list);
3215cb174861Sjoyce mcintosh 
321694047d49SGordon Ross 	(void) mdb_inc_indent(SMB_DCMD_INDENT);
3217cb174861Sjoyce mcintosh 
321894047d49SGordon Ross 	if (mdb_pwalk_dcmd("list", "smbofile_oplock",
321994047d49SGordon Ross 	    argc, argv, addr + fl_off + ll_off)) {
322094047d49SGordon Ross 		mdb_warn("failed to walk ofile oplocks");
3221cb174861Sjoyce mcintosh 	}
3222cb174861Sjoyce mcintosh 
3223cb174861Sjoyce mcintosh 	(void) mdb_dec_indent(SMB_DCMD_INDENT);
3224cb174861Sjoyce mcintosh 
3225cb174861Sjoyce mcintosh 	return (DCMD_OK);
3226cb174861Sjoyce mcintosh }
3227cb174861Sjoyce mcintosh 
32286537f381Sas /*
3229764c8bd8SGordon Ross  * *******************************************************************
3230764c8bd8SGordon Ross  * (smb) mbuf_t
3231764c8bd8SGordon Ross  *
3232764c8bd8SGordon Ross  * ::smb_mbuf_dump [max_len]
3233764c8bd8SGordon Ross  * dcmd to dump the data portion of an mbuf_t
3234764c8bd8SGordon Ross  * stop at max_len
3235764c8bd8SGordon Ross  */
3236764c8bd8SGordon Ross static int
smb_mbuf_dump_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3237764c8bd8SGordon Ross smb_mbuf_dump_dcmd(uintptr_t addr, uint_t flags, int argc,
3238764c8bd8SGordon Ross     const mdb_arg_t *argv)
3239764c8bd8SGordon Ross {
3240764c8bd8SGordon Ross 	struct m_hdr mh;
3241764c8bd8SGordon Ross 	uintptr_t mdata;
3242764c8bd8SGordon Ross 	int len, max_len;
3243764c8bd8SGordon Ross 	int dumpptr_flags;
3244764c8bd8SGordon Ross 
3245764c8bd8SGordon Ross 	if (mdb_vread(&mh, sizeof (mh), addr) < 0) {
3246764c8bd8SGordon Ross 		mdb_warn("failed to read mbuf at %p", addr);
3247764c8bd8SGordon Ross 		return (DCMD_ERR);
3248764c8bd8SGordon Ross 	}
3249764c8bd8SGordon Ross 	len = mh.mh_len;
3250764c8bd8SGordon Ross 	mdata = (uintptr_t)mh.mh_data;
3251764c8bd8SGordon Ross 
3252764c8bd8SGordon Ross 	if (argc > 0) {
3253764c8bd8SGordon Ross 		if (argv[0].a_type == MDB_TYPE_IMMEDIATE)
3254764c8bd8SGordon Ross 			max_len = argv[0].a_un.a_val;
3255764c8bd8SGordon Ross 		else
3256764c8bd8SGordon Ross 			max_len = mdb_strtoull(argv[0].a_un.a_str);
3257764c8bd8SGordon Ross 		if (len > max_len)
3258764c8bd8SGordon Ross 			len = max_len;
3259764c8bd8SGordon Ross 	}
3260764c8bd8SGordon Ross 	if (len <= 0)
3261764c8bd8SGordon Ross 		return (DCMD_OK);
3262764c8bd8SGordon Ross 
3263764c8bd8SGordon Ross 	if (DCMD_HDRSPEC(flags)) {
3264764c8bd8SGordon Ross 		mdb_printf("%<u>%-16s %-16s %-12s%</u>\n",
3265764c8bd8SGordon Ross 		    "mbuf_t", "m_data", "m_len");
3266764c8bd8SGordon Ross 	}
3267764c8bd8SGordon Ross 	mdb_printf("%-16p %-16p %-12u\n",
3268764c8bd8SGordon Ross 	    addr, mdata, mh.mh_len);
3269764c8bd8SGordon Ross 
3270764c8bd8SGordon Ross 	dumpptr_flags = MDB_DUMP_RELATIVE | MDB_DUMP_ASCII | MDB_DUMP_HEADER;
3271cf01ae8aSToomas Soome 	if (mdb_dumpptr(mdata, len, dumpptr_flags, NULL, NULL) < 0)
3272764c8bd8SGordon Ross 		return (DCMD_ERR);
3273764c8bd8SGordon Ross 
3274764c8bd8SGordon Ross 	return (DCMD_OK);
3275764c8bd8SGordon Ross }
3276764c8bd8SGordon Ross 
3277764c8bd8SGordon Ross static int
smb_mbuf_walk_init(mdb_walk_state_t * wsp)3278764c8bd8SGordon Ross smb_mbuf_walk_init(mdb_walk_state_t *wsp)
3279764c8bd8SGordon Ross {
3280764c8bd8SGordon Ross 	mbuf_t *m;
3281764c8bd8SGordon Ross 
3282cc3780e6SGordon Ross 	if (wsp->walk_addr == 0) {
3283764c8bd8SGordon Ross 		mdb_printf("require address of an mbuf_t\n");
3284764c8bd8SGordon Ross 		return (WALK_ERR);
3285764c8bd8SGordon Ross 	}
3286764c8bd8SGordon Ross 	m = mdb_alloc(sizeof (*m), UM_SLEEP | UM_GC);
3287764c8bd8SGordon Ross 	wsp->walk_data = m;
3288764c8bd8SGordon Ross 	return (WALK_NEXT);
3289764c8bd8SGordon Ross }
3290764c8bd8SGordon Ross 
3291764c8bd8SGordon Ross static int
smb_mbuf_walk_step(mdb_walk_state_t * wsp)3292764c8bd8SGordon Ross smb_mbuf_walk_step(mdb_walk_state_t *wsp)
3293764c8bd8SGordon Ross {
3294764c8bd8SGordon Ross 	uintptr_t addr = wsp->walk_addr;
3295764c8bd8SGordon Ross 	mbuf_t *m = wsp->walk_data;
3296764c8bd8SGordon Ross 	int rc;
3297764c8bd8SGordon Ross 
3298cc3780e6SGordon Ross 	if (wsp->walk_addr == 0)
3299764c8bd8SGordon Ross 		return (WALK_DONE);
3300764c8bd8SGordon Ross 
3301764c8bd8SGordon Ross 	if (mdb_vread(m, sizeof (*m), addr) == -1) {
3302764c8bd8SGordon Ross 		mdb_warn("failed to read mbuf_t at %p", addr);
3303764c8bd8SGordon Ross 		return (WALK_ERR);
3304764c8bd8SGordon Ross 	}
3305764c8bd8SGordon Ross 
3306764c8bd8SGordon Ross 	rc = wsp->walk_callback(addr, m, wsp->walk_cbdata);
3307764c8bd8SGordon Ross 	wsp->walk_addr = (uintptr_t)m->m_next;
3308764c8bd8SGordon Ross 
3309764c8bd8SGordon Ross 	return (rc);
3310764c8bd8SGordon Ross }
3311764c8bd8SGordon Ross 
33126537f381Sas /*
33136537f381Sas  * *****************************************************************************
33146537f381Sas  * ******************************** smb_ace_t **********************************
33156537f381Sas  * *****************************************************************************
33166537f381Sas  */
33176537f381Sas static const ace_type_entry_t	ace_types[ACE_TYPE_TABLEN] =
33186537f381Sas {
33196537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_ACE_TYPE),
33206537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_ACE_TYPE),
33216537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_ACE_TYPE),
33226537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_ACE_TYPE),
33236537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE),
33246537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE),
33256537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_OBJECT_ACE_TYPE),
33266537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE),
33276537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE),
33286537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE),
33296537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE),
33306537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE),
33316537f381Sas 	ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE),
33326537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE),
33336537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE),
33346537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE),
33356537f381Sas 	ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE),
33366537f381Sas 	ACE_TYPE_ENTRY(0x11),
33376537f381Sas 	ACE_TYPE_ENTRY(0x12),
33386537f381Sas 	ACE_TYPE_ENTRY(0x13),
33396537f381Sas 	ACE_TYPE_ENTRY(0x14),
33406537f381Sas 	ACE_TYPE_ENTRY(0x15),
33416537f381Sas 	ACE_TYPE_ENTRY(0x16),
33426537f381Sas 	ACE_TYPE_ENTRY(0x17),
33436537f381Sas 	ACE_TYPE_ENTRY(0x18),
33446537f381Sas 	ACE_TYPE_ENTRY(0x19),
33456537f381Sas 	ACE_TYPE_ENTRY(0x1A),
33466537f381Sas 	ACE_TYPE_ENTRY(0x1B),
33476537f381Sas 	ACE_TYPE_ENTRY(0x1C),
33486537f381Sas 	ACE_TYPE_ENTRY(0x1D),
33496537f381Sas 	ACE_TYPE_ENTRY(0x1E),
33506537f381Sas 	ACE_TYPE_ENTRY(0x1F)
33516537f381Sas };
33526537f381Sas 
33536537f381Sas static const mdb_bitmask_t ace_flag_bits[] = {
33546537f381Sas 	{ "OBJECT_INHERIT_ACE", OBJECT_INHERIT_ACE, OBJECT_INHERIT_ACE },
33556537f381Sas 	{ "CONTAINER_INHERIT_ACE", CONTAINER_INHERIT_ACE,
33566537f381Sas 	    CONTAINER_INHERIT_ACE },
33576537f381Sas 	{ "NO_PROPOGATE_INHERIT_ACE", NO_PROPOGATE_INHERIT_ACE,
33586537f381Sas 	    NO_PROPOGATE_INHERIT_ACE },
33596537f381Sas 	{ "INHERIT_ONLY_ACE", INHERIT_ONLY_ACE, INHERIT_ONLY_ACE },
33606537f381Sas 	{ "INHERITED_ACE", INHERITED_ACE, INHERITED_ACE },
33616537f381Sas 	{ "SUCCESSFUL_ACCESS_ACE_FLAG", SUCCESSFUL_ACCESS_ACE_FLAG,
33626537f381Sas 	    SUCCESSFUL_ACCESS_ACE_FLAG },
33636537f381Sas 	{ "FAILED_ACCESS_ACE_FLAG", FAILED_ACCESS_ACE_FLAG,
33646537f381Sas 	    FAILED_ACCESS_ACE_FLAG },
33656537f381Sas 	{ NULL, 0, 0 }
33666537f381Sas };
33676537f381Sas 
33686537f381Sas /*
33696537f381Sas  * ::smbace
33706537f381Sas  */
3371da6c28aaSamw static int
smbace_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)33722b8c497cSGordon Ross smbace_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3373da6c28aaSamw {
33746537f381Sas 	smb_ace_t	ace;
3375da6c28aaSamw 	int		verbose = FALSE;
33766537f381Sas 	const char	*ptr;
33776537f381Sas 	int		rc;
3378da6c28aaSamw 
33796537f381Sas 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose,
3380da6c28aaSamw 	    NULL) != argc)
3381da6c28aaSamw 		return (DCMD_USAGE);
3382da6c28aaSamw 
3383da6c28aaSamw 	/*
33846537f381Sas 	 * An smb_ace address is required.
3385da6c28aaSamw 	 */
3386da6c28aaSamw 	if (!(flags & DCMD_ADDRSPEC))
3387da6c28aaSamw 		return (DCMD_USAGE);
3388da6c28aaSamw 
33896537f381Sas 	if (mdb_vread(&ace, sizeof (ace), addr) != sizeof (ace)) {
33906537f381Sas 		mdb_warn("failed to read struct smb_ace at %p", addr);
3391da6c28aaSamw 		return (DCMD_ERR);
3392da6c28aaSamw 	}
3393da6c28aaSamw 
33946537f381Sas 	if (verbose) {
33956537f381Sas 		if (ace.se_hdr.se_type < ACE_TYPE_TABLEN)
33966537f381Sas 			ptr = ace_types[ace.se_hdr.se_type].ace_type_sting;
33976537f381Sas 		else
33986537f381Sas 			ptr = "Unknown";
33996537f381Sas 
34006537f381Sas 		mdb_printf("ACE Type: 0x%02x (%s)\n", ace.se_hdr.se_type, ptr);
34016537f381Sas 		mdb_printf("ACE Flags: %b\n", (int)ace.se_hdr.se_flags,
34026537f381Sas 		    ace_flag_bits);
34036537f381Sas 		mdb_printf("ACE Wire Size: 0x%04x\n", ace.se_hdr.se_bsize);
34046537f381Sas 		mdb_printf("ACE Mask: 0x%08x\n", ace.se_mask);
34056537f381Sas 		mdb_printf("ACE SID: ");
34066537f381Sas 	} else {
34076537f381Sas 		if (DCMD_HDRSPEC(flags))
34086537f381Sas 			mdb_printf(
34096537f381Sas 			    "%<b>%<u>%?-s %-4s %-4s %-8s %s%</u>%</b>\n",
34106537f381Sas 			    "ACE", "TYPE", "FLAGS", "MASK", "SID");
34116537f381Sas 		mdb_printf("%?p 0x%02x 0x%02x 0x%08x ", addr,
34126537f381Sas 		    ace.se_hdr.se_type, ace.se_hdr.se_flags, ace.se_mask);
3413da6c28aaSamw 	}
34146537f381Sas 	rc = smb_sid_print((uintptr_t)ace.se_sid);
34156537f381Sas 	mdb_printf("\n");
34166537f381Sas 	return (rc);
34176537f381Sas }
3418da6c28aaSamw 
34196537f381Sas static int
smb_ace_walk_init(mdb_walk_state_t * wsp)34206537f381Sas smb_ace_walk_init(mdb_walk_state_t *wsp)
34216537f381Sas {
3422bd49ed45SGordon Ross 	int sal_off;
3423bd49ed45SGordon Ross 
3424cc3780e6SGordon Ross 	if (wsp->walk_addr == 0) {
34256537f381Sas 		mdb_printf("smb_ace walk only supports local walks\n");
34266537f381Sas 		return (WALK_ERR);
3427da6c28aaSamw 	}
3428da6c28aaSamw 
3429bd49ed45SGordon Ross 	GET_OFFSET(sal_off, smb_acl_t, sl_sorted);
3430bd49ed45SGordon Ross 	wsp->walk_addr += sal_off;
34316537f381Sas 
34326537f381Sas 	if (mdb_layered_walk("list", wsp) == -1) {
34336537f381Sas 		mdb_warn("failed to walk list of ACEs");
34346537f381Sas 		return (WALK_ERR);
3435da6c28aaSamw 	}
3436da6c28aaSamw 
34376537f381Sas 	return (WALK_NEXT);
3438da6c28aaSamw }
3439da6c28aaSamw 
34406537f381Sas static int
smb_ace_walk_step(mdb_walk_state_t * wsp)34416537f381Sas smb_ace_walk_step(mdb_walk_state_t *wsp)
3442da6c28aaSamw {
34436537f381Sas 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
34446537f381Sas 	    wsp->walk_cbdata));
3445da6c28aaSamw }
3446da6c28aaSamw 
34476537f381Sas /*
34486537f381Sas  * *****************************************************************************
34496537f381Sas  * ******************************** smb_acl_t **********************************
34506537f381Sas  * *****************************************************************************
34516537f381Sas  */
34526537f381Sas 
34536537f381Sas /*
34546537f381Sas  * ::smbacl
34556537f381Sas  */
3456da6c28aaSamw static int
smbacl_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)34572b8c497cSGordon Ross smbacl_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3458da6c28aaSamw {
34596537f381Sas 	smb_acl_t	acl;
3460da6c28aaSamw 
34616537f381Sas 	/* An smb_acl address is required. */
3462da6c28aaSamw 	if (!(flags & DCMD_ADDRSPEC))
3463da6c28aaSamw 		return (DCMD_USAGE);
3464da6c28aaSamw 
34656537f381Sas 	if (mdb_vread(&acl, sizeof (acl), addr) != sizeof (acl)) {
34666537f381Sas 		mdb_warn("failed to read struct smb_acl at %p", addr);
34676537f381Sas 		return (DCMD_ERR);
34686537f381Sas 	}
34696537f381Sas 
34706537f381Sas 	mdb_printf("ACL Revision: %d\n", acl.sl_revision);
34716537f381Sas 	mdb_printf("ACL Size on Wire: %d\n", acl.sl_bsize);
34726537f381Sas 	mdb_printf("ACL Number of ACEs: %d\n", acl.sl_acecnt);
34736537f381Sas 
34746537f381Sas 	(void) mdb_inc_indent(SMB_DCMD_INDENT);
34756537f381Sas 	if (mdb_pwalk_dcmd("smbace_walker", "smbace", argc, argv, addr)) {
34766537f381Sas 		(void) mdb_dec_indent(SMB_DCMD_INDENT);
34776537f381Sas 		mdb_warn("failed to walk list of ACEs for ACL %p", addr);
34786537f381Sas 		return (DCMD_ERR);
3479da6c28aaSamw 	}
34806537f381Sas 	(void) mdb_dec_indent(SMB_DCMD_INDENT);
34816537f381Sas 	return (DCMD_OK);
34826537f381Sas }
34836537f381Sas 
34846537f381Sas /*
34856537f381Sas  * *****************************************************************************
34866537f381Sas  * ********************************* smb_sd_t **********************************
34876537f381Sas  * *****************************************************************************
34886537f381Sas  */
34896537f381Sas 
34906537f381Sas /*
34916537f381Sas  * ::smbsd
34926537f381Sas  */
34936537f381Sas static int
smbsd_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)34942b8c497cSGordon Ross smbsd_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
34956537f381Sas {
34966537f381Sas 	smb_sd_t	sd;
34976537f381Sas 	int		rc;
3498da6c28aaSamw 
3499da6c28aaSamw 	/*
35006537f381Sas 	 * An smb_sid address is required.
3501da6c28aaSamw 	 */
35026537f381Sas 	if (!(flags & DCMD_ADDRSPEC))
35036537f381Sas 		return (DCMD_USAGE);
35046537f381Sas 
35056537f381Sas 	if (mdb_vread(&sd, sizeof (sd), addr) != sizeof (sd)) {
35066537f381Sas 		mdb_warn("failed to read struct smb_sd at %p", addr);
3507da6c28aaSamw 		return (DCMD_ERR);
3508da6c28aaSamw 	}
3509da6c28aaSamw 
35106537f381Sas 	mdb_printf("SD Revision: %d\n", sd.sd_revision);
35116537f381Sas 	mdb_printf("SD Control: %04x\n", sd.sd_control);
35126537f381Sas 	if (sd.sd_control & SE_OWNER_DEFAULTED)
35136537f381Sas 		mdb_printf("\t    SE_OWNER_DEFAULTED\n");
35146537f381Sas 	if (sd.sd_control & SE_GROUP_DEFAULTED)
35156537f381Sas 		mdb_printf("\t    SE_GROUP_DEFAULTED\n");
35166537f381Sas 	if (sd.sd_control & SE_DACL_PRESENT)
35176537f381Sas 		mdb_printf("\t    SE_DACL_PRESENT\n");
35186537f381Sas 	if (sd.sd_control & SE_DACL_DEFAULTED)
35196537f381Sas 		mdb_printf("\t    SE_DACL_DEFAULTED\n");
35206537f381Sas 	if (sd.sd_control & SE_SACL_PRESENT)
35216537f381Sas 		mdb_printf("\t    SE_SACL_PRESENT\n");
35226537f381Sas 	if (sd.sd_control & SE_SACL_DEFAULTED)
35236537f381Sas 		mdb_printf("\t    SE_SACL_DEFAULTED\n");
35246537f381Sas 	if (sd.sd_control & SE_DACL_AUTO_INHERIT_REQ)
35256537f381Sas 		mdb_printf("\t    SE_DACL_AUTO_INHERIT_REQ\n");
35266537f381Sas 	if (sd.sd_control & SE_SACL_AUTO_INHERIT_REQ)
35276537f381Sas 		mdb_printf("\t    SE_SACL_AUTO_INHERIT_REQ\n");
35286537f381Sas 	if (sd.sd_control & SE_DACL_AUTO_INHERITED)
35296537f381Sas 		mdb_printf("\t    SE_DACL_AUTO_INHERITED\n");
35306537f381Sas 	if (sd.sd_control & SE_SACL_AUTO_INHERITED)
35316537f381Sas 		mdb_printf("\t    SE_SACL_AUTO_INHERITED\n");
35326537f381Sas 	if (sd.sd_control & SE_DACL_PROTECTED)
35336537f381Sas 		mdb_printf("\t    SE_DACL_PROTECTED\n");
35346537f381Sas 	if (sd.sd_control & SE_SACL_PROTECTED)
35356537f381Sas 		mdb_printf("\t    SE_SACL_PROTECTED\n");
35366537f381Sas 	if (sd.sd_control & SE_SELF_RELATIVE)
35376537f381Sas 		mdb_printf("\t    SE_SELF_RELATIVE\n");
35386537f381Sas 
35396537f381Sas 	mdb_printf("SID of Owner: ");
35406537f381Sas 	rc = smb_sid_print((uintptr_t)sd.sd_owner);
35416537f381Sas 	if (rc != DCMD_OK)
35426537f381Sas 		return (rc);
35436537f381Sas 	mdb_printf("\nSID of Group: ");
35446537f381Sas 	rc = smb_sid_print((uintptr_t)sd.sd_group);
35456537f381Sas 	if (rc != DCMD_OK)
35466537f381Sas 		return (rc);
35476537f381Sas 	mdb_printf("\n");
35486537f381Sas 
35496537f381Sas 	if (sd.sd_control & SE_SACL_PRESENT && sd.sd_sacl) {
35506537f381Sas 		mdb_printf("%<b>%<u>System ACL%</u>%</b>\n");
3551da6c28aaSamw 		(void) mdb_inc_indent(SMB_DCMD_INDENT);
35526537f381Sas 		rc = mdb_call_dcmd("smbacl", (uintptr_t)sd.sd_sacl, flags,
35536537f381Sas 		    argc, argv);
3554da6c28aaSamw 		(void) mdb_dec_indent(SMB_DCMD_INDENT);
35556537f381Sas 		if (rc != DCMD_OK)
35566537f381Sas 			return (rc);
3557da6c28aaSamw 	}
35586537f381Sas 	if (sd.sd_control & SE_DACL_PRESENT && sd.sd_dacl) {
35596537f381Sas 		mdb_printf("%<b>%<u>Discretionary ACL%</u>%</b>\n");
3560da6c28aaSamw 		(void) mdb_inc_indent(SMB_DCMD_INDENT);
35616537f381Sas 		rc = mdb_call_dcmd("smbacl", (uintptr_t)sd.sd_dacl, flags,
35626537f381Sas 		    argc, argv);
3563da6c28aaSamw 		(void) mdb_dec_indent(SMB_DCMD_INDENT);
35646537f381Sas 		if (rc != DCMD_OK)
35656537f381Sas 			return (rc);
3566da6c28aaSamw 	}
3567da6c28aaSamw 
3568da6c28aaSamw 	return (DCMD_OK);
3569da6c28aaSamw }
3570da6c28aaSamw 
35716537f381Sas /*
35726537f381Sas  * *****************************************************************************
35736537f381Sas  * ********************************* smb_sid_t *********************************
35746537f381Sas  * *****************************************************************************
35756537f381Sas  */
35766537f381Sas 
35776537f381Sas /*
35786537f381Sas  * ::smbsid
35796537f381Sas  */
35806537f381Sas /*ARGSUSED*/
3581da6c28aaSamw static int
smbsid_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)35822b8c497cSGordon Ross smbsid_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3583da6c28aaSamw {
3584da6c28aaSamw 	/*
35856537f381Sas 	 * An smb_sid address is required.
3586da6c28aaSamw 	 */
3587da6c28aaSamw 	if (!(flags & DCMD_ADDRSPEC))
3588da6c28aaSamw 		return (DCMD_USAGE);
3589da6c28aaSamw 
35906537f381Sas 	return (smb_sid_print(addr));
35916537f381Sas }
35926537f381Sas 
35936537f381Sas /*
35946537f381Sas  * smb_sid_print
35956537f381Sas  */
35966537f381Sas static int
smb_sid_print(uintptr_t addr)35976537f381Sas smb_sid_print(uintptr_t addr)
35986537f381Sas {
35996537f381Sas 	smb_sid_t	sid;
36006537f381Sas 	smb_sid_t	*psid;
36016537f381Sas 	size_t		sid_size;
36026537f381Sas 	uint64_t	authority;
3603bd49ed45SGordon Ross 	int		ssa_off;
3604bd49ed45SGordon Ross 	int		i;
36056537f381Sas 
3606bd49ed45SGordon Ross 	GET_OFFSET(ssa_off, smb_sid_t, sid_subauth);
3607bd49ed45SGordon Ross 	sid_size = ssa_off;
36086537f381Sas 
36096537f381Sas 	if (mdb_vread(&sid, sid_size, addr) != sid_size) {
36106537f381Sas 		mdb_warn("failed to read struct smb_sid at %p", addr);
36116537f381Sas 		return (DCMD_ERR);
3612da6c28aaSamw 	}
3613da6c28aaSamw 
36146537f381Sas 	sid_size += sid.sid_subauthcnt * sizeof (sid.sid_subauth[0]);
36156537f381Sas 
36166537f381Sas 	psid = mdb_zalloc(sid_size, UM_SLEEP | UM_GC);
36176537f381Sas 	if (mdb_vread(psid, sid_size, addr) != sid_size) {
36186537f381Sas 		mdb_warn("failed to read struct smb_sid at %p", addr);
3619da6c28aaSamw 		return (DCMD_ERR);
3620da6c28aaSamw 	}
3621da6c28aaSamw 
36226537f381Sas 	mdb_printf("S-%d", psid->sid_revision);
36236537f381Sas 	authority = 0;
36246537f381Sas 	for (i = 0; i < NT_SID_AUTH_MAX; i++) {
36256537f381Sas 		authority += ((uint64_t)psid->sid_authority[i]) <<
36266537f381Sas 		    (8 * (NT_SID_AUTH_MAX - 1) - i);
36276537f381Sas 	}
36286537f381Sas 	mdb_printf("-%ll", authority);
36296537f381Sas 
36306537f381Sas 	for (i = 0; i < psid->sid_subauthcnt; i++)
36316537f381Sas 		mdb_printf("-%d", psid->sid_subauth[i]);
36326537f381Sas 
3633da6c28aaSamw 	return (DCMD_OK);
3634da6c28aaSamw }
3635da6c28aaSamw 
36366537f381Sas /*
36376537f381Sas  * *****************************************************************************
36386537f381Sas  * ********************************* smb_fssd_t ********************************
36396537f381Sas  * *****************************************************************************
36406537f381Sas  */
36416537f381Sas 
36426537f381Sas /*
36436537f381Sas  * ::smbfssd
36446537f381Sas  */
3645da6c28aaSamw static int
smbfssd_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)36462b8c497cSGordon Ross smbfssd_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3647da6c28aaSamw {
36486537f381Sas 	smb_fssd_t	fssd;
36496537f381Sas 	int		rc;
3650da6c28aaSamw 
3651da6c28aaSamw 	/*
36526537f381Sas 	 * An smb_fssd address is required.
3653da6c28aaSamw 	 */
3654da6c28aaSamw 	if (!(flags & DCMD_ADDRSPEC))
3655da6c28aaSamw 		return (DCMD_USAGE);
3656da6c28aaSamw 
36576537f381Sas 	if (mdb_vread(&fssd, sizeof (fssd), addr) != sizeof (fssd)) {
36586537f381Sas 		mdb_warn("failed to read struct smb_fssd at %p", addr);
36596537f381Sas 		return (DCMD_ERR);
3660da6c28aaSamw 	}
3661da6c28aaSamw 
36626537f381Sas 	mdb_printf("FSSD secinfo: 0x%x\n", fssd.sd_secinfo);
36636537f381Sas 	if (fssd.sd_secinfo & SMB_OWNER_SECINFO)
36646537f381Sas 		mdb_printf("FSSD uid: %d\n", fssd.sd_uid);
36656537f381Sas 	if (fssd.sd_secinfo & SMB_GROUP_SECINFO)
36666537f381Sas 		mdb_printf("FSSD gid: %d\n", fssd.sd_gid);
36676537f381Sas 	if (fssd.sd_secinfo & SMB_SACL_SECINFO && fssd.sd_zsacl) {
36686537f381Sas 		mdb_printf("%<b>%<u>System ACL%</u>%</b>\n");
36696537f381Sas 		(void) mdb_inc_indent(SMB_DCMD_INDENT);
36706537f381Sas 		rc = mdb_call_dcmd("smbacl", (uintptr_t)fssd.sd_zsacl, flags,
36716537f381Sas 		    argc, argv);
36726537f381Sas 		(void) mdb_dec_indent(SMB_DCMD_INDENT);
36736537f381Sas 		if (rc != DCMD_OK)
36746537f381Sas 			return (rc);
36756537f381Sas 	}
36766537f381Sas 	if (fssd.sd_secinfo & SMB_DACL_SECINFO && fssd.sd_zdacl) {
36776537f381Sas 		mdb_printf("%<b>%<u>Discretionary ACL%</u>%</b>\n");
36786537f381Sas 		(void) mdb_inc_indent(SMB_DCMD_INDENT);
36796537f381Sas 		rc = mdb_call_dcmd("smbacl", (uintptr_t)fssd.sd_zdacl, flags,
36806537f381Sas 		    argc, argv);
36816537f381Sas 		(void) mdb_dec_indent(SMB_DCMD_INDENT);
36826537f381Sas 		if (rc != DCMD_OK)
36836537f381Sas 			return (rc);
3684da6c28aaSamw 	}
3685da6c28aaSamw 
3686da6c28aaSamw 	return (DCMD_OK);
3687da6c28aaSamw }
3688da6c28aaSamw 
36896537f381Sas /*
36906537f381Sas  * *****************************************************************************
36916537f381Sas  * **************************** Utility Funcions *******************************
36926537f381Sas  * *****************************************************************************
36936537f381Sas  */
3694da6c28aaSamw 
3695da6c28aaSamw /*
36966537f381Sas  * smb_dcmd_getopt
3697da6c28aaSamw  *
36986537f381Sas  * This function analyzes the arguments passed in and sets the bit corresponding
36996537f381Sas  * to the options found in the opts variable.
37006537f381Sas  *
37016537f381Sas  * Return Value
37026537f381Sas  *
37036537f381Sas  *	-1	An error occured during the decoding
37046537f381Sas  *	0	The decoding was successful
3705da6c28aaSamw  */
3706da6c28aaSamw static int
smb_dcmd_getopt(uint_t * opts,int argc,const mdb_arg_t * argv)37076537f381Sas smb_dcmd_getopt(uint_t *opts, int argc, const mdb_arg_t *argv)
3708da6c28aaSamw {
37096537f381Sas 	*opts = 0;
3710da6c28aaSamw 
37116537f381Sas 	if (mdb_getopts(argc, argv,
37126537f381Sas 	    's', MDB_OPT_SETBITS, SMB_OPT_SERVER, opts,
37136537f381Sas 	    'e', MDB_OPT_SETBITS, SMB_OPT_SESSION, opts,
37146537f381Sas 	    'r', MDB_OPT_SETBITS, SMB_OPT_REQUEST, opts,
37156537f381Sas 	    'u', MDB_OPT_SETBITS, SMB_OPT_USER, opts,
37166537f381Sas 	    't', MDB_OPT_SETBITS, SMB_OPT_TREE, opts,
37176537f381Sas 	    'f', MDB_OPT_SETBITS, SMB_OPT_OFILE, opts,
37186537f381Sas 	    'd', MDB_OPT_SETBITS, SMB_OPT_ODIR, opts,
37196537f381Sas 	    'w', MDB_OPT_SETBITS, SMB_OPT_WALK, opts,
37206537f381Sas 	    'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, opts,
37216537f381Sas 	    NULL) != argc)
37226537f381Sas 		return (-1);
3723da6c28aaSamw 
37246537f381Sas 	return (0);
37256537f381Sas }
3726da6c28aaSamw 
37276537f381Sas /*
37286537f381Sas  * smb_dcmd_setopt
37296537f381Sas  *
37306537f381Sas  * This function set the arguments corresponding to the bits set in opts.
37316537f381Sas  *
37326537f381Sas  * Return Value
37336537f381Sas  *
37346537f381Sas  *	Number of arguments set.
37356537f381Sas  */
37366537f381Sas static int
smb_dcmd_setopt(uint_t opts,int max_argc,mdb_arg_t * argv)37376537f381Sas smb_dcmd_setopt(uint_t opts, int max_argc, mdb_arg_t *argv)
37386537f381Sas {
37396537f381Sas 	int	i;
37406537f381Sas 	int	argc = 0;
37416537f381Sas 
37426537f381Sas 	for (i = 0; i < SMB_MDB_MAX_OPTS; i++) {
3743148c5f43SAlan Wright 		if ((opts & smb_opts[i].o_value) && (argc < max_argc)) {
37446537f381Sas 			argv->a_type = MDB_TYPE_STRING;
3745148c5f43SAlan Wright 			argv->a_un.a_str = smb_opts[i].o_name;
37466537f381Sas 			argc++;
37476537f381Sas 			argv++;
37486537f381Sas 		}
3749da6c28aaSamw 	}
37506537f381Sas 	return (argc);
37516537f381Sas }
3752da6c28aaSamw 
37536537f381Sas /*
37546537f381Sas  * smb_obj_expand
37556537f381Sas  */
37566537f381Sas static int
smb_obj_expand(uintptr_t addr,uint_t opts,const smb_exp_t * x,ulong_t indent)37576537f381Sas smb_obj_expand(uintptr_t addr, uint_t opts, const smb_exp_t *x, ulong_t indent)
37586537f381Sas {
37596537f381Sas 	int		rc = 0;
3760bd49ed45SGordon Ross 	int		ex_off;
37616537f381Sas 	int		argc;
37626537f381Sas 	mdb_arg_t	argv[SMB_MDB_MAX_OPTS];
37636537f381Sas 
37646537f381Sas 	argc = smb_dcmd_setopt(opts | SMB_OPT_WALK, SMB_MDB_MAX_OPTS, argv);
37656537f381Sas 
37666537f381Sas 	(void) mdb_inc_indent(indent);
37676537f381Sas 	while (x->ex_dcmd) {
37686537f381Sas 		if (x->ex_mask & opts) {
3769bd49ed45SGordon Ross 			ex_off = (x->ex_offset)();
3770811599a4SMatt Barden 			if (ex_off < 0) {
3771811599a4SMatt Barden 				mdb_warn("failed to get the list offset for %s",
3772811599a4SMatt Barden 				    x->ex_name);
3773811599a4SMatt Barden 				rc = ex_off;
3774811599a4SMatt Barden 				break;
3775811599a4SMatt Barden 			}
3776811599a4SMatt Barden 
3777*2cf6b79fSGordon Ross 			rc = mdb_pwalk_dcmd(x->ex_walker, x->ex_dcmd,
3778*2cf6b79fSGordon Ross 			    argc, argv, addr + ex_off);
37796537f381Sas 
37806537f381Sas 			if (rc) {
37816537f381Sas 				mdb_warn("failed to walk the list of %s in %p",
3782bd49ed45SGordon Ross 				    x->ex_name, addr + ex_off);
37836537f381Sas 				break;
37846537f381Sas 			}
37856537f381Sas 		}
37866537f381Sas 		x++;
3787da6c28aaSamw 	}
37886537f381Sas 	(void) mdb_dec_indent(indent);
37896537f381Sas 	return (rc);
3790da6c28aaSamw }
3791da6c28aaSamw 
3792da6c28aaSamw /*
37936537f381Sas  * smb_obj_list
3794da6c28aaSamw  *
37956537f381Sas  * Function called by the DCMDs when no address is provided. It expands the
37966537f381Sas  * tree under the object type associated with the calling DCMD (based on the
37976537f381Sas  * flags passed in).
37986537f381Sas  *
37996537f381Sas  * Return Value
38006537f381Sas  *
38016537f381Sas  *	DCMD_OK
38026537f381Sas  *	DCMD_ERR
3803da6c28aaSamw  */
38046537f381Sas static int
smb_obj_list(const char * name,uint_t opts,uint_t flags)38056537f381Sas smb_obj_list(const char *name, uint_t opts, uint_t flags)
38066537f381Sas {
38076537f381Sas 	int		argc;
38086537f381Sas 	mdb_arg_t	argv[SMB_MDB_MAX_OPTS];
3809da6c28aaSamw 
38106537f381Sas 	argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, argv);
3811da6c28aaSamw 
38126537f381Sas 	if (mdb_call_dcmd("smblist", 0, flags, argc, argv)) {
38136537f381Sas 		mdb_warn("failed to list %s", name);
38146537f381Sas 		return (DCMD_ERR);
38156537f381Sas 	}
38166537f381Sas 	return (DCMD_OK);
3817da6c28aaSamw }
3818fc724630SAlan Wright 
3819fc724630SAlan Wright static int
smb_worker_findstack(uintptr_t addr)3820fc724630SAlan Wright smb_worker_findstack(uintptr_t addr)
3821fc724630SAlan Wright {
3822fc724630SAlan Wright 	char		cmd[80];
3823fc724630SAlan Wright 	mdb_arg_t	cmdarg;
3824fc724630SAlan Wright 
3825fc724630SAlan Wright 	mdb_inc_indent(2);
3826fc724630SAlan Wright 	mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", 16);
3827fc724630SAlan Wright 	cmdarg.a_type = MDB_TYPE_STRING;
3828fc724630SAlan Wright 	cmdarg.a_un.a_str = cmd;
3829fc724630SAlan Wright 	(void) mdb_call_dcmd("findstack", addr, DCMD_ADDRSPEC, 1, &cmdarg);
3830fc724630SAlan Wright 	mdb_dec_indent(2);
3831fc724630SAlan Wright 	mdb_printf("\n");
3832fc724630SAlan Wright 	return (DCMD_OK);
3833fc724630SAlan Wright }
38342b8c497cSGordon Ross 
3835764c8bd8SGordon Ross static void
smb_inaddr_ntop(smb_inaddr_t * ina,char * buf,size_t sz)3836764c8bd8SGordon Ross smb_inaddr_ntop(smb_inaddr_t *ina, char *buf, size_t sz)
3837764c8bd8SGordon Ross {
3838764c8bd8SGordon Ross 
3839764c8bd8SGordon Ross 	switch (ina->a_family) {
3840764c8bd8SGordon Ross 	case AF_INET:
3841764c8bd8SGordon Ross 		(void) mdb_snprintf(buf, sz, "%I", ina->a_ipv4);
3842764c8bd8SGordon Ross 		break;
3843764c8bd8SGordon Ross 	case AF_INET6:
384446050536SGordon Ross 		(void) mdb_snprintf(buf, sz, "%N", &ina->a_ipv6);
3845764c8bd8SGordon Ross 		break;
3846764c8bd8SGordon Ross 	default:
3847764c8bd8SGordon Ross 		(void) mdb_snprintf(buf, sz, "(?)");
3848764c8bd8SGordon Ross 		break;
3849764c8bd8SGordon Ross 	}
3850764c8bd8SGordon Ross }
3851764c8bd8SGordon Ross 
3852bd49ed45SGordon Ross /*
3853bd49ed45SGordon Ross  * Get the name for an enum value
3854bd49ed45SGordon Ross  */
3855bd49ed45SGordon Ross static void
get_enum(char * out,size_t size,const char * type_str,int val,const char * prefix)3856bd49ed45SGordon Ross get_enum(char *out, size_t size, const char *type_str, int val,
3857bd49ed45SGordon Ross     const char *prefix)
3858bd49ed45SGordon Ross {
3859bd49ed45SGordon Ross 	mdb_ctf_id_t type_id;
3860bd49ed45SGordon Ross 	const char *cp;
3861bd49ed45SGordon Ross 
3862bd49ed45SGordon Ross 	if (mdb_ctf_lookup_by_name(type_str, &type_id) != 0)
3863bd49ed45SGordon Ross 		goto errout;
3864bd49ed45SGordon Ross 	if (mdb_ctf_type_resolve(type_id, &type_id) != 0)
3865bd49ed45SGordon Ross 		goto errout;
3866bd49ed45SGordon Ross 	if ((cp = mdb_ctf_enum_name(type_id, val)) == NULL)
3867bd49ed45SGordon Ross 		goto errout;
3868bd49ed45SGordon Ross 	if (prefix != NULL) {
3869bd49ed45SGordon Ross 		size_t len = strlen(prefix);
3870bd49ed45SGordon Ross 		if (strncmp(cp, prefix, len) == 0)
3871bd49ed45SGordon Ross 			cp += len;
3872bd49ed45SGordon Ross 	}
3873bd49ed45SGordon Ross 	(void) strncpy(out, cp, size);
3874bd49ed45SGordon Ross 	return;
3875bd49ed45SGordon Ross 
3876bd49ed45SGordon Ross errout:
3877bd49ed45SGordon Ross 	mdb_snprintf(out, size, "? (%d)", val);
3878bd49ed45SGordon Ross }
3879bd49ed45SGordon Ross 
38802b8c497cSGordon Ross /*
38812b8c497cSGordon Ross  * MDB module linkage information:
38822b8c497cSGordon Ross  *
38832b8c497cSGordon Ross  * We declare a list of structures describing our dcmds, a list of structures
38842b8c497cSGordon Ross  * describing our walkers and a function named _mdb_init to return a pointer
38852b8c497cSGordon Ross  * to our module information.
38862b8c497cSGordon Ross  */
38872b8c497cSGordon Ross static const mdb_dcmd_t dcmds[] = {
38882b8c497cSGordon Ross 	{   "smblist",
38892b8c497cSGordon Ross 	    "[-seutfdwv]",
38902b8c497cSGordon Ross 	    "print tree of SMB objects",
38912b8c497cSGordon Ross 	    smblist_dcmd,
38922b8c497cSGordon Ross 	    smblist_help },
38932b8c497cSGordon Ross 	{   "smbsrv",
38942b8c497cSGordon Ross 	    "[-seutfdwv]",
38952b8c497cSGordon Ross 	    "print smb_server information",
38962b8c497cSGordon Ross 	    smbsrv_dcmd },
38972b8c497cSGordon Ross 	{   "smbshare",
38982b8c497cSGordon Ross 	    ":[-v]",
38992b8c497cSGordon Ross 	    "print smb_kshare_t information",
39002b8c497cSGordon Ross 	    smbshare_dcmd },
39012b8c497cSGordon Ross 	{   "smbvfs",
39022b8c497cSGordon Ross 	    ":[-v]",
39032b8c497cSGordon Ross 	    "print smb_vfs information",
39042b8c497cSGordon Ross 	    smbvfs_dcmd },
39052b8c497cSGordon Ross 	{   "smbnode",
39062b8c497cSGordon Ross 	    "?[-vps]",
39072b8c497cSGordon Ross 	    "print smb_node_t information",
39082b8c497cSGordon Ross 	    smbnode_dcmd,
39092b8c497cSGordon Ross 	    smbnode_help },
39102b8c497cSGordon Ross 	{   "smbsess",
39112b8c497cSGordon Ross 	    "[-utfdwv]",
39122b8c497cSGordon Ross 	    "print smb_session_t information",
39132b8c497cSGordon Ross 	    smbsess_dcmd,
39142b8c497cSGordon Ross 	    smbsess_help},
39152b8c497cSGordon Ross 	{   "smbreq",
39162b8c497cSGordon Ross 	    ":[-v]",
39172b8c497cSGordon Ross 	    "print smb_request_t information",
39182b8c497cSGordon Ross 	    smbreq_dcmd },
3919764c8bd8SGordon Ross 	{   "smbreq_dump",
3920764c8bd8SGordon Ross 	    ":[-cr] [-o outfile]",
3921764c8bd8SGordon Ross 	    "dump smb_request_t packets (cmd/reply)",
3922764c8bd8SGordon Ross 	    smbreq_dump_dcmd,
3923764c8bd8SGordon Ross 	    smbreq_dump_help,
3924764c8bd8SGordon Ross 	},
39252b8c497cSGordon Ross 	{   "smblock", ":[-v]",
39262b8c497cSGordon Ross 	    "print smb_lock_t information",
39272b8c497cSGordon Ross 	    smblock_dcmd },
39282b8c497cSGordon Ross 	{   "smbuser",
39292b8c497cSGordon Ross 	    ":[-vdftq]",
39302b8c497cSGordon Ross 	    "print smb_user_t information",
39312b8c497cSGordon Ross 	    smbuser_dcmd,
39322b8c497cSGordon Ross 	    smbuser_help },
39332b8c497cSGordon Ross 	{   "smbtree",
39342b8c497cSGordon Ross 	    ":[-vdf]",
39352b8c497cSGordon Ross 	    "print smb_tree_t information",
39362b8c497cSGordon Ross 	    smbtree_dcmd,
39372b8c497cSGordon Ross 	    smbtree_help },
39382b8c497cSGordon Ross 	{   "smbodir",
39392b8c497cSGordon Ross 	    ":[-v]",
39402b8c497cSGordon Ross 	    "print smb_odir_t information",
39412b8c497cSGordon Ross 	    smbodir_dcmd },
39422b8c497cSGordon Ross 	{   "smbofile",
39432b8c497cSGordon Ross 	    "[-v]",
39442b8c497cSGordon Ross 	    "print smb_file_t information",
39452b8c497cSGordon Ross 	    smbofile_dcmd },
394694047d49SGordon Ross 	{   "smbsrv_leases",
394794047d49SGordon Ross 	    "[-v]",
394894047d49SGordon Ross 	    "print lease table for a server",
394994047d49SGordon Ross 	    smbsrv_leases_dcmd },
395094047d49SGordon Ross 	{   "smblease",
395194047d49SGordon Ross 	    "[-v]",
395294047d49SGordon Ross 	    "print smb_lease_t information",
395394047d49SGordon Ross 	    smblease_dcmd },
395494047d49SGordon Ross 	{   "smbnode_oplock", NULL,
395594047d49SGordon Ross 	    "print smb_node_t oplock information",
395694047d49SGordon Ross 	    smbnode_oplock_dcmd },
395794047d49SGordon Ross 	{   "smbofile_oplock", NULL,
395894047d49SGordon Ross 	    "print smb_ofile_t oplock information",
395994047d49SGordon Ross 	    smbofile_oplock_dcmd },
39602b8c497cSGordon Ross 	{   "smbace", "[-v]",
39612b8c497cSGordon Ross 	    "print smb_ace_t information",
39622b8c497cSGordon Ross 	    smbace_dcmd },
39632b8c497cSGordon Ross 	{   "smbacl", "[-v]",
39642b8c497cSGordon Ross 	    "print smb_acl_t information",
39652b8c497cSGordon Ross 	    smbacl_dcmd },
39662b8c497cSGordon Ross 	{   "smbsid", "[-v]",
39672b8c497cSGordon Ross 	    "print smb_sid_t information",
39682b8c497cSGordon Ross 	    smbsid_dcmd },
39692b8c497cSGordon Ross 	{   "smbsd", "[-v]",
39702b8c497cSGordon Ross 	    "print smb_sd_t information",
39712b8c497cSGordon Ross 	    smbsd_dcmd },
39722b8c497cSGordon Ross 	{   "smbfssd", "[-v]",
39732b8c497cSGordon Ross 	    "print smb_fssd_t information",
39742b8c497cSGordon Ross 	    smbfssd_dcmd },
3975764c8bd8SGordon Ross 	{   "smb_mbuf_dump", ":[max_len]",
3976764c8bd8SGordon Ross 	    "print mbuf_t data",
3977764c8bd8SGordon Ross 	    smb_mbuf_dump_dcmd },
3978811599a4SMatt Barden 	{   "smbdurable",
3979811599a4SMatt Barden 	    "[-v]",
3980811599a4SMatt Barden 	    "list ofiles on sv->sv_persistid_ht",
3981811599a4SMatt Barden 	    smbdurable_dcmd },
3982811599a4SMatt Barden 	{   "smbhashstat",
3983811599a4SMatt Barden 	    "[-v]",
3984811599a4SMatt Barden 	    "list stats from an smb_hash_t structure",
3985811599a4SMatt Barden 	    smbhashstat_dcmd },
3986811599a4SMatt Barden 
39872b8c497cSGordon Ross 	{ NULL }
39882b8c497cSGordon Ross };
39892b8c497cSGordon Ross 
39902b8c497cSGordon Ross static const mdb_walker_t walkers[] = {
39912b8c497cSGordon Ross 	{   "smbnode_walker",
39922b8c497cSGordon Ross 	    "walk list of smb_node_t structures",
39932b8c497cSGordon Ross 	    smb_node_walk_init,
39942b8c497cSGordon Ross 	    smb_node_walk_step,
39952b8c497cSGordon Ross 	    NULL,
39962b8c497cSGordon Ross 	    NULL },
39972b8c497cSGordon Ross 	{   "smbshare_walker",
39982b8c497cSGordon Ross 	    "walk list of smb_kshare_t structures",
39992b8c497cSGordon Ross 	    smb_kshare_walk_init,
40002b8c497cSGordon Ross 	    smb_kshare_walk_step,
40012b8c497cSGordon Ross 	    NULL,
40022b8c497cSGordon Ross 	    NULL },
40032b8c497cSGordon Ross 	{   "smbvfs_walker",
40042b8c497cSGordon Ross 	    "walk list of smb_vfs_t structures",
40052b8c497cSGordon Ross 	    smb_vfs_walk_init,
40062b8c497cSGordon Ross 	    smb_vfs_walk_step,
40072b8c497cSGordon Ross 	    NULL,
40082b8c497cSGordon Ross 	    NULL },
40092b8c497cSGordon Ross 	{   "smbace_walker",
40102b8c497cSGordon Ross 	    "walk list of smb_ace_t structures",
40112b8c497cSGordon Ross 	    smb_ace_walk_init,
40122b8c497cSGordon Ross 	    smb_ace_walk_step,
40132b8c497cSGordon Ross 	    NULL,
40142b8c497cSGordon Ross 	    NULL },
4015764c8bd8SGordon Ross 	{   "smb_mbuf_walker",
4016764c8bd8SGordon Ross 	    "walk list of mbuf_t structures",
4017764c8bd8SGordon Ross 	    smb_mbuf_walk_init,
4018764c8bd8SGordon Ross 	    smb_mbuf_walk_step,
4019764c8bd8SGordon Ross 	    NULL,
4020764c8bd8SGordon Ross 	    NULL },
4021811599a4SMatt Barden 	{   "smb_hash_walker",
4022811599a4SMatt Barden 	    "walk an smb_hash_t structure",
4023811599a4SMatt Barden 	    smb_hash_walk_init,
4024811599a4SMatt Barden 	    smb_hash_walk_step,
4025811599a4SMatt Barden 	    NULL,
4026811599a4SMatt Barden 	    NULL },
4027811599a4SMatt Barden 	{   "smb_hashstat_walker",
4028811599a4SMatt Barden 	    "walk the buckets from an smb_hash_t structure",
4029811599a4SMatt Barden 	    smb_hashstat_walk_init,
4030811599a4SMatt Barden 	    smb_hashstat_walk_step,
4031811599a4SMatt Barden 	    NULL,
4032811599a4SMatt Barden 	    NULL },
4033811599a4SMatt Barden 
40342b8c497cSGordon Ross 	{ NULL }
40352b8c497cSGordon Ross };
40362b8c497cSGordon Ross 
40372b8c497cSGordon Ross static const mdb_modinfo_t modinfo = {
40382b8c497cSGordon Ross 	MDB_API_VERSION, dcmds, walkers
40392b8c497cSGordon Ross };
40402b8c497cSGordon Ross 
40412b8c497cSGordon Ross const mdb_modinfo_t *
_mdb_init(void)40422b8c497cSGordon Ross _mdb_init(void)
40432b8c497cSGordon Ross {
40442b8c497cSGordon Ross 	return (&modinfo);
40452b8c497cSGordon Ross }
4046