xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_smb.c (revision 7280:2367302f7ecf)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7280Sblu  * Common Development and Distribution License (the "License").
6*7280Sblu  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*7280Sblu  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7280Sblu  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * References used throughout this code:
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * [CIFS/1.0] : A Common Internet File System (CIFS/1.0) Protocol
320Sstevel@tonic-gate  *		Internet Engineering Task Force (IETF) draft
330Sstevel@tonic-gate  *		Paul J. Leach, Microsoft, Dec. 1997
340Sstevel@tonic-gate  *
350Sstevel@tonic-gate  * [X/Open-SMB] : X/Open CAE Specification;
360Sstevel@tonic-gate  *		Protocols for X/Open PC Interworking: SMB, Version 2
370Sstevel@tonic-gate  *		X/Open Document Number: C209
380Sstevel@tonic-gate  */
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include <fcntl.h>
410Sstevel@tonic-gate #include <stdio.h>
420Sstevel@tonic-gate #include <stdlib.h>
430Sstevel@tonic-gate #include <string.h>
440Sstevel@tonic-gate 
450Sstevel@tonic-gate #include "snoop.h"
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /* some macros just for compactness */
480Sstevel@tonic-gate #define	GETLINE get_line(0, 0)
490Sstevel@tonic-gate #define	DECARGS int flags, uchar_t *data, int len, char *extrainfo
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate  * SMB Format (header)
530Sstevel@tonic-gate  * [X/Open-SMB, Sec. 5.1]
540Sstevel@tonic-gate  */
550Sstevel@tonic-gate struct smb {
560Sstevel@tonic-gate 	uchar_t idf[4]; /*  identifier, contains 0xff, 'SMB'  */
570Sstevel@tonic-gate 	uchar_t com;    /*  command code  */
580Sstevel@tonic-gate 	uchar_t rcls;   /*  error class  */
590Sstevel@tonic-gate 	uchar_t res;
600Sstevel@tonic-gate 	uchar_t err[2]; /*  error code  */
610Sstevel@tonic-gate 	uchar_t flags;
620Sstevel@tonic-gate 	uchar_t flags2[2];
630Sstevel@tonic-gate 	uchar_t re[12];
640Sstevel@tonic-gate 	uchar_t tid[2];
650Sstevel@tonic-gate 	uchar_t pid[2];
660Sstevel@tonic-gate 	uchar_t uid[2];
670Sstevel@tonic-gate 	uchar_t mid[2];
680Sstevel@tonic-gate 	/*
690Sstevel@tonic-gate 	 * immediately after the above 32 byte header:
700Sstevel@tonic-gate 	 *   unsigned char  WordCount;
710Sstevel@tonic-gate 	 *   unsigned short ParameterWords[ WordCount ];
720Sstevel@tonic-gate 	 *   unsigned short ByteCount;
730Sstevel@tonic-gate 	 *   unsigned char  ParameterBytes[ ByteCount ];
740Sstevel@tonic-gate 	 */
750Sstevel@tonic-gate };
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /* smb flags */
780Sstevel@tonic-gate #define	SERVER_RESPONSE	0x80
790Sstevel@tonic-gate 
800Sstevel@tonic-gate static void interpret_sesssetupX(DECARGS);
810Sstevel@tonic-gate static void interpret_tconX(DECARGS);
820Sstevel@tonic-gate static void interpret_trans(DECARGS);
830Sstevel@tonic-gate static void interpret_trans2(DECARGS);
840Sstevel@tonic-gate static void interpret_negprot(DECARGS);
850Sstevel@tonic-gate static void interpret_default(DECARGS);
860Sstevel@tonic-gate 
870Sstevel@tonic-gate /*
880Sstevel@tonic-gate  * Trans2 subcommand codes
890Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.1.7]
900Sstevel@tonic-gate  */
910Sstevel@tonic-gate #define	TRANS2_OPEN 0x00
920Sstevel@tonic-gate #define	TRANS2_FIND_FIRST 0x01
930Sstevel@tonic-gate #define	TRANS2_FIND_NEXT2 0x02
940Sstevel@tonic-gate #define	TRANS2_QUERY_FS_INFORMATION 0x03
950Sstevel@tonic-gate #define	TRANS2_QUERY_PATH_INFORMATION 0x05
960Sstevel@tonic-gate #define	TRANS2_SET_PATH_INFORMATION 0x06
970Sstevel@tonic-gate #define	TRANS2_QUERY_FILE_INFORMATION 0x07
980Sstevel@tonic-gate #define	TRANS2_SET_FILE_INFORMATION 0x08
990Sstevel@tonic-gate #define	TRANS2_CREATE_DIRECTORY 0x0D
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate struct decode {
1030Sstevel@tonic-gate 	char *name;
1040Sstevel@tonic-gate 	void (*func)(DECARGS);
1050Sstevel@tonic-gate 	char *callfmt;
1060Sstevel@tonic-gate 	char *replyfmt;
1070Sstevel@tonic-gate };
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate /*
1100Sstevel@tonic-gate  * SMB command codes (function names)
1110Sstevel@tonic-gate  * [X/Open-SMB, Sec. 5.2]
1120Sstevel@tonic-gate  */
1130Sstevel@tonic-gate static struct decode SMBtable[256] = {
1140Sstevel@tonic-gate 	/* 0x00 */
1150Sstevel@tonic-gate 	{ "mkdir", 0, 0, 0 },
1160Sstevel@tonic-gate 	{ "rmdir", 0, 0, 0 },
1170Sstevel@tonic-gate 	{ "open", 0, 0, 0 },
1180Sstevel@tonic-gate 	{ "create", 0, 0, 0 },
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	{
1210Sstevel@tonic-gate 		"close", 0,
1220Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 7.10] */
1230Sstevel@tonic-gate 		"WFileID\0lLastModTime\0wByteCount\0\0",
1240Sstevel@tonic-gate 		"wByteCount\0\0"
1250Sstevel@tonic-gate 	},
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	{ "flush", 0, 0, 0 },
1280Sstevel@tonic-gate 	{ "unlink", 0, 0, 0 },
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	{
1310Sstevel@tonic-gate 		"mv", 0,
1320Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 7.11] */
1330Sstevel@tonic-gate 		"wFileAttributes\0wByteCount\0"
1340Sstevel@tonic-gate 		"r\0UFileName\0r\0UNewPath\0\0",
1350Sstevel@tonic-gate 		"wByteCount\0\0"
1360Sstevel@tonic-gate 	},
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	{
1390Sstevel@tonic-gate 		"getatr", 0,
1400Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 8.4] */
1410Sstevel@tonic-gate 		"dBytecount\0r\0UFileName\0\0",
1420Sstevel@tonic-gate 		"wFileAttributes\0lTime\0lSize\0R\0R\0R\0"
1430Sstevel@tonic-gate 		"R\0R\0wByteCount\0\0"
1440Sstevel@tonic-gate 	},
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	{ "setatr", 0, 0, 0 },
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	{
1490Sstevel@tonic-gate 		"read", 0,
1500Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 7.4] */
1510Sstevel@tonic-gate 		"WFileID\0wI/0 Bytes\0LFileOffset\0"
1520Sstevel@tonic-gate 		"WBytesLeft\0wByteCount\0\0",
1530Sstevel@tonic-gate 		"WDataLength\0R\0R\0R\0R\0wByteCount\0\0"
1540Sstevel@tonic-gate 	},
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	{
1570Sstevel@tonic-gate 		"write", 0,
1580Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 7.5] */
1590Sstevel@tonic-gate 		"WFileID\0wI/0 Bytes\0LFileOffset\0WBytesLeft\0"
1600Sstevel@tonic-gate 		"wByteCount\0\0",
1610Sstevel@tonic-gate 		"WDataLength\0wByteCount\0\0"
1620Sstevel@tonic-gate 	},
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	{ "lock", 0, 0, 0 },
1650Sstevel@tonic-gate 	{ "unlock", 0, 0, 0 },
1660Sstevel@tonic-gate 	{ "ctemp", 0, 0, 0 },
1670Sstevel@tonic-gate 	{ "mknew", 0, 0, 0 },
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	/* 0x10 */
1700Sstevel@tonic-gate 	{
1710Sstevel@tonic-gate 		"chkpth", 0,
1720Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 8.7] */
1730Sstevel@tonic-gate 		"wByteCount\0r\0UFile\0\0",
1740Sstevel@tonic-gate 		"wByteCount\0\0"
1750Sstevel@tonic-gate 	},
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	{ "exit", 0, 0, 0 },
1780Sstevel@tonic-gate 	{ "lseek", 0, 0, 0 },
1790Sstevel@tonic-gate 	{ "lockread", 0, 0, 0 },
1800Sstevel@tonic-gate 	{ "writeunlock", 0, 0, 0 },
1810Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
1820Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
1830Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
1840Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
1850Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	{
1880Sstevel@tonic-gate 		"readbraw", 0,
1890Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 10.1] */
1900Sstevel@tonic-gate 		"WFileID\0LFileOffset\0wMaxCount\0"
1910Sstevel@tonic-gate 		"wMinCount\0lTimeout\0R\0wByteCount\0\0", 0
1920Sstevel@tonic-gate 	},
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	{ "readbmpx", 0, 0, 0 },
1950Sstevel@tonic-gate 	{ "readbs", 0, 0, 0 },
1960Sstevel@tonic-gate 	{ "writebraw", 0, 0, 0 },
1970Sstevel@tonic-gate 	{ "writebmpx", 0, 0, 0 },
1980Sstevel@tonic-gate 	{ "writebs", 0, 0, 0 },
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 	/* 0x20 */
2010Sstevel@tonic-gate 	{ "writec", 0, 0, 0 },
2020Sstevel@tonic-gate 	{ "qrysrv", 0, 0, 0 },
2030Sstevel@tonic-gate 	{ "setattrE", 0, 0, 0 },
2040Sstevel@tonic-gate 	{ "getattrE", 0, 0, 0 },
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	{
2070Sstevel@tonic-gate 		"lockingX", 0,
2080Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 12.2] */
2090Sstevel@tonic-gate 		"wChainedCommand\0wNextOffset\0WFileID\0"
2100Sstevel@tonic-gate 		"wLockType\0lOpenTimeout\0"
2110Sstevel@tonic-gate 		"W#Unlocks\0W#Locks\0wByteCount\0\0", 0
2120Sstevel@tonic-gate 	},
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	{ "trans", interpret_trans, 0, 0 },
2150Sstevel@tonic-gate 	{ "transs", 0, 0, 0 },
2160Sstevel@tonic-gate 	{ "ioctl", 0, 0, 0 },
2170Sstevel@tonic-gate 	{ "ioctls", 0, 0, 0 },
2180Sstevel@tonic-gate 	{ "copy", 0, 0, 0 },
2190Sstevel@tonic-gate 	{ "move", 0, 0, 0 },
2200Sstevel@tonic-gate 	{ "echo", 0, 0, 0 },
2210Sstevel@tonic-gate 	{ "writeclose", 0, 0, 0 },
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	{
2240Sstevel@tonic-gate 		"openX", 0,
2250Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 12.1] */
2260Sstevel@tonic-gate 		"wChainedCommand\0wNextOffset\0wFlags\0"
2270Sstevel@tonic-gate 		"wMode\0wSearchAttributes\0wFileAttributes\0"
2280Sstevel@tonic-gate 		"lTime\0wOpenFunction\0lFileSize\0lOpenTimeout\0"
2290Sstevel@tonic-gate 		"R\0R\0wByteCount\0r\0UFileName\0\0",
2300Sstevel@tonic-gate 		"wChainedCommand\0wNextOffset\0WFileID\0"
2310Sstevel@tonic-gate 		"wAttributes\0lTime\0LSize\0wOpenMode\0"
2320Sstevel@tonic-gate 		"wFileType\0wDeviceState\0wActionTaken\0"
2330Sstevel@tonic-gate 		"lUniqueFileID\0R\0wBytecount\0\0"
2340Sstevel@tonic-gate 	},
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	{ "readX", 0, 0, 0 },
2370Sstevel@tonic-gate 	{ "writeX", 0, 0, 0 },
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	/* 0x30 */
2400Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2410Sstevel@tonic-gate 	{ "closeTD", 0, 0, 0 },
2420Sstevel@tonic-gate 	{ "trans2", interpret_trans2, 0, 0 },
2430Sstevel@tonic-gate 	{ "trans2s", 0, 0, 0 },
2440Sstevel@tonic-gate 	{
2450Sstevel@tonic-gate 		"findclose", 0,
2460Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 15.4 ] */
2470Sstevel@tonic-gate 		"WFileID\0wByteCount\0\0",
2480Sstevel@tonic-gate 		"wByteCount\0\0"
2490Sstevel@tonic-gate 	},
2500Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2510Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2520Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2530Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2540Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2550Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2560Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2570Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2580Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2590Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2600Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	/* 0x40 */
2630Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2640Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2650Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2660Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2670Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2680Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2690Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2700Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2710Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2720Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2730Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2740Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2750Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2760Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2770Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2780Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 	/* 0x50 */
2810Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2820Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2830Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2840Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2850Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2860Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2870Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2880Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2890Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2900Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2910Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2920Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2930Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2940Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2950Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2960Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate 	/* 0x60 */
2990Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3000Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3010Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3020Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3030Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3040Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3050Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3060Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3070Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3080Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3090Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3100Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3110Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3120Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3130Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3140Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	/* 0x70 */
3170Sstevel@tonic-gate 	{ "tcon", 0, 0, 0 },
3180Sstevel@tonic-gate 	{
3190Sstevel@tonic-gate 		"tdis", 0,
3200Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 6.3] */
3210Sstevel@tonic-gate 		"wByteCount\0\0",
3220Sstevel@tonic-gate 		"wByteCount\0\0"
3230Sstevel@tonic-gate 	},
3240Sstevel@tonic-gate 	{ "negprot", interpret_negprot, 0, 0 },
3250Sstevel@tonic-gate 	{ "sesssetupX", interpret_sesssetupX, 0, 0 },
3260Sstevel@tonic-gate 	{
3270Sstevel@tonic-gate 		"uloggoffX", 0,
3280Sstevel@tonic-gate 		/* [X/Open-SMB, Sec. 15.5] */
3290Sstevel@tonic-gate 		"wChainedCommand\0wNextOffset\0\0",
3300Sstevel@tonic-gate 		"wChainedCommnad\0wNextOffset\0\0" },
3310Sstevel@tonic-gate 	{ "tconX", interpret_tconX, 0, 0 },
3320Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3330Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3340Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3350Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3360Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3370Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3380Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3390Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3400Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3410Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 	/* 0x80 */
3440Sstevel@tonic-gate 	{ "dskattr", 0, 0, 0 },
3450Sstevel@tonic-gate 	{ "search", 0, 0, 0 },
3460Sstevel@tonic-gate 	{ "ffirst", 0, 0, 0 },
3470Sstevel@tonic-gate 	{ "funique", 0, 0, 0 },
3480Sstevel@tonic-gate 	{ "fclose", 0, 0, 0 },
3490Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3500Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3510Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3520Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3530Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3540Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3550Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3560Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3570Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3580Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3590Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	/* 0x90 */
3620Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3630Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3640Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3650Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3660Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3670Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3680Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3690Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3700Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3710Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3720Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3730Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3740Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3750Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3760Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3770Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 	/* 0xa0 */
3800Sstevel@tonic-gate 	/*
3810Sstevel@tonic-gate 	 * Command codes 0xa0 to 0xa7 are from
3820Sstevel@tonic-gate 	 * [CIFS/1.0, Sec. 5.1]
3830Sstevel@tonic-gate 	 */
3840Sstevel@tonic-gate 	{ " NT_Trans", 0, 0, 0 },
3850Sstevel@tonic-gate 	{ " NT_Trans2", 0, 0, 0 },
3860Sstevel@tonic-gate 	{
3870Sstevel@tonic-gate 		" NT_CreateX", 0,
3880Sstevel@tonic-gate 		/* [CIFS/1.0, Sec. 4.2.1] */
3890Sstevel@tonic-gate 		"wChainedCommand\0wNextOffset\0r\0"
3900Sstevel@tonic-gate 		"wNameLength\0lCreateFlags\0lRootDirFID\0"
3910Sstevel@tonic-gate 		"lDesiredAccess\0R\0R\0R\0R\0"
3920Sstevel@tonic-gate 		"lNTFileAttributes\0lFileShareAccess\0"
3930Sstevel@tonic-gate 		"R\0R\0lCreateOption\0lImpersonationLevel\0"
3940Sstevel@tonic-gate 		"bSecurityFlags\0wByteCount\0r\0"
3950Sstevel@tonic-gate 		"UFileName\0\0",
3960Sstevel@tonic-gate 		"wChainedCommand\0wNextOffset\0"
3970Sstevel@tonic-gate 		"bOplockLevel\0WFileID\0lCreateAction\0\0"
3980Sstevel@tonic-gate 	},
3990Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4000Sstevel@tonic-gate 	{
4010Sstevel@tonic-gate 		" NT_Cancel", 0,
4020Sstevel@tonic-gate 		/* [CIFS/1.0, Sec. 4.1.8] */
4030Sstevel@tonic-gate 		"wByteCount\0", 0
4040Sstevel@tonic-gate 	},
4050Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4060Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4070Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4080Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4090Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4100Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4110Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4120Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4130Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4140Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4150Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	/* 0xb0 */
4180Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4190Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4200Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4210Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4220Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4230Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4240Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4250Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4260Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4270Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4280Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4290Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4300Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4310Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4320Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4330Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	/* 0xc0 */
4360Sstevel@tonic-gate 	{ "splopen", 0, 0, 0 },
4370Sstevel@tonic-gate 	{ "splwr", 0, 0, 0 },
4380Sstevel@tonic-gate 	{ "splclose", 0, 0, 0 },
4390Sstevel@tonic-gate 	{ "splretq", 0, 0, 0 },
4400Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4410Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4420Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4430Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4440Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4450Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4460Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4470Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4480Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4490Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4500Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4510Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 	/* 0xd0 */
4540Sstevel@tonic-gate 	{ "sends", 0, 0, 0 },
4550Sstevel@tonic-gate 	{ "sendb", 0, 0, 0 },
4560Sstevel@tonic-gate 	{ "fwdname", 0, 0, 0 },
4570Sstevel@tonic-gate 	{ "cancelf", 0, 0, 0 },
4580Sstevel@tonic-gate 	{ "getmac", 0, 0, 0 },
4590Sstevel@tonic-gate 	{ "sendstrt", 0, 0, 0 },
4600Sstevel@tonic-gate 	{ "sendend", 0, 0, 0 },
4610Sstevel@tonic-gate 	{ "sendtxt", 0, 0, 0 },
4620Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4630Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4640Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4650Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4660Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4670Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4680Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4690Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	/* 0xe0 */
4720Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4730Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4740Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4750Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4760Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4770Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4780Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4790Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4800Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4810Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4820Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4830Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4840Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4850Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4860Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4870Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4880Sstevel@tonic-gate 
4890Sstevel@tonic-gate 	/* 0xf0 */
4900Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4910Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4920Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4930Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4940Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4950Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4960Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4970Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4980Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
4990Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
5000Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
5010Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
5020Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
5030Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
5040Sstevel@tonic-gate 	{ 0, 0, 0, 0 },
5050Sstevel@tonic-gate 	{ 0, 0, 0, 0 }
5060Sstevel@tonic-gate };
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate /* Helpers to get short and int values in Intel order. */
5090Sstevel@tonic-gate static ushort_t
get2(uchar_t * p)5100Sstevel@tonic-gate get2(uchar_t *p) {
5110Sstevel@tonic-gate 	return (p[0] + (p[1]<<8));
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate static uint_t
get4(uchar_t * p)5140Sstevel@tonic-gate get4(uchar_t *p) {
5150Sstevel@tonic-gate 	return (p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24));
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate /*
5190Sstevel@tonic-gate  * This is called by snoop_netbios.c.
5200Sstevel@tonic-gate  * This is the external entry point.
5210Sstevel@tonic-gate  */
5220Sstevel@tonic-gate void
interpret_smb(int flags,uchar_t * data,int len)5230Sstevel@tonic-gate interpret_smb(int flags, uchar_t *data, int len)
5240Sstevel@tonic-gate {
5250Sstevel@tonic-gate 	struct smb *smb;
5260Sstevel@tonic-gate 	char *call_reply_detail, *call_reply_sum;
5270Sstevel@tonic-gate 	struct decode *decoder;
5280Sstevel@tonic-gate 	char xtra[300];
5290Sstevel@tonic-gate 	char *line;
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate 	smb = (struct smb *)data;
5320Sstevel@tonic-gate 	decoder = &SMBtable[smb->com & 255];
5330Sstevel@tonic-gate 	if (smb->flags & SERVER_RESPONSE) {
5340Sstevel@tonic-gate 		call_reply_detail = "SERVER RESPONSE";
5350Sstevel@tonic-gate 		call_reply_sum = "R";
5360Sstevel@tonic-gate 	} else {
5370Sstevel@tonic-gate 		call_reply_detail =	"CLIENT REQUEST";
5380Sstevel@tonic-gate 		call_reply_sum = "C";
5390Sstevel@tonic-gate 	}
5400Sstevel@tonic-gate 	xtra[0] = '\0';
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	/*
5430Sstevel@tonic-gate 	 * SMB Header description
5440Sstevel@tonic-gate 	 * [X/Open-SMB, Sec. 5.1]
5450Sstevel@tonic-gate 	 */
5460Sstevel@tonic-gate 	if (flags & F_DTAIL) {
5470Sstevel@tonic-gate 		show_header("SMB:  ", "SMB Header", len);
5480Sstevel@tonic-gate 		show_space();
5490Sstevel@tonic-gate 		sprintf(GETLINE, "%s", call_reply_detail);
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 		(void) sprintf(GETLINE, "Command code = 0x%x",
5520Sstevel@tonic-gate 				smb->com);
5530Sstevel@tonic-gate 		if (decoder->name)
5540Sstevel@tonic-gate 			(void) sprintf(GETLINE,
5550Sstevel@tonic-gate 				"Command name =  SMB%s", decoder->name);
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 		show_space();
5580Sstevel@tonic-gate 		sprintf(GETLINE, "SMB Status:");
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 		/* Error classes [X/Open-SMB, Sec. 5.6] */
5610Sstevel@tonic-gate 		switch (smb->rcls) {
5620Sstevel@tonic-gate 		case 0x00:
5630Sstevel@tonic-gate 			sprintf(GETLINE,
5640Sstevel@tonic-gate 				"   - Error class = No error");
5650Sstevel@tonic-gate 			break;
5660Sstevel@tonic-gate 		case 0x01:
5670Sstevel@tonic-gate 			sprintf(GETLINE,
5680Sstevel@tonic-gate 				"   - Error class = Operating System");
5690Sstevel@tonic-gate 			break;
5700Sstevel@tonic-gate 		case 0x02:
5710Sstevel@tonic-gate 			sprintf(GETLINE,
5720Sstevel@tonic-gate 				"   - Error class = LMX server");
5730Sstevel@tonic-gate 			break;
5740Sstevel@tonic-gate 		case 0x03:
5750Sstevel@tonic-gate 			sprintf(GETLINE,
5760Sstevel@tonic-gate 				"   - Error class = Hardware");
5770Sstevel@tonic-gate 			break;
5780Sstevel@tonic-gate 		case 0xff:
5790Sstevel@tonic-gate 		default:
5800Sstevel@tonic-gate 			sprintf(GETLINE,
5810Sstevel@tonic-gate 				"   - Error class = Incorrect format.");
5820Sstevel@tonic-gate 			break;
5830Sstevel@tonic-gate 		}
5840Sstevel@tonic-gate 
5850Sstevel@tonic-gate 		if (smb->err[0] != 0x00) {
5860Sstevel@tonic-gate 			sprintf(GETLINE,
5870Sstevel@tonic-gate 				"   - Error code = %x", smb->err[0]);
5880Sstevel@tonic-gate 		} else
5890Sstevel@tonic-gate 			sprintf(GETLINE, "   - Error code = No error");
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 		show_space();
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 		sprintf(GETLINE, "Header:");
5940Sstevel@tonic-gate 		sprintf(GETLINE, "   - Tree ID      (TID) = 0x%.4x",
5950Sstevel@tonic-gate 			get2(smb->tid));
5960Sstevel@tonic-gate 		sprintf(GETLINE, "   - Process ID   (PID) = 0x%.4x",
5970Sstevel@tonic-gate 			get2(smb->pid));
5980Sstevel@tonic-gate 		sprintf(GETLINE, "   - User ID      (UID) = 0x%.4x",
5990Sstevel@tonic-gate 			get2(smb->uid));
6000Sstevel@tonic-gate 		sprintf(GETLINE, "   - Multiplex ID (MID) = 0x%.4x",
6010Sstevel@tonic-gate 			get2(smb->mid));
6020Sstevel@tonic-gate 		sprintf(GETLINE, "   - Flags summary = 0x%.2x",
6030Sstevel@tonic-gate 					smb->flags);
6040Sstevel@tonic-gate 		sprintf(GETLINE, "   - Flags2 summary = 0x%.4x",
6050Sstevel@tonic-gate 					get2(smb->flags2));
6060Sstevel@tonic-gate 		show_space();
6070Sstevel@tonic-gate 	}
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate 	if (decoder->func)
6100Sstevel@tonic-gate 		(decoder->func)(flags, (uchar_t *)data, len, xtra);
6110Sstevel@tonic-gate 	else
6120Sstevel@tonic-gate 		interpret_default(flags, (uchar_t *)data, len, xtra);
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate 	if (flags & F_SUM) {
6150Sstevel@tonic-gate 		line = get_sum_line();
6160Sstevel@tonic-gate 		if (decoder->name)
6170Sstevel@tonic-gate 			sprintf(line,
6180Sstevel@tonic-gate 			"SMB %s Code=0x%x Name=SMB%s %sError=%x ",
6190Sstevel@tonic-gate 			call_reply_sum, smb->com, decoder->name, xtra,
6200Sstevel@tonic-gate 			smb->err[0]);
6210Sstevel@tonic-gate 
6220Sstevel@tonic-gate 		else sprintf(line, "SMB %s Code=0x%x Error=%x ",
6230Sstevel@tonic-gate 					call_reply_sum, smb->com, smb->err[0]);
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate 		line += strlen(line);
6260Sstevel@tonic-gate 	}
6270Sstevel@tonic-gate 
6280Sstevel@tonic-gate 	if (flags & F_DTAIL)
6290Sstevel@tonic-gate 		show_trailer();
6300Sstevel@tonic-gate }
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate static void
output_bytes(uchar_t * data,int bytecount)6330Sstevel@tonic-gate output_bytes(uchar_t *data, int bytecount)
6340Sstevel@tonic-gate {
6350Sstevel@tonic-gate 	int i;
6360Sstevel@tonic-gate 	char buff[80];
6370Sstevel@tonic-gate 	char word[10];
6380Sstevel@tonic-gate 
6390Sstevel@tonic-gate 	buff[0] = word[0] = '\0';
6400Sstevel@tonic-gate 	sprintf(GETLINE, "Byte values (in hex):");
6410Sstevel@tonic-gate 	for (i = 0; i < bytecount; i++) {
6420Sstevel@tonic-gate 		sprintf(word, "%.2x ", data[i]);
6430Sstevel@tonic-gate 		strcat(buff, word);
6440Sstevel@tonic-gate 		if ((i+1)%16 == 0 || i == (bytecount-1)) {
6450Sstevel@tonic-gate 			sprintf(GETLINE, "%s", buff);
6460Sstevel@tonic-gate 			strcpy(buff, "");
6470Sstevel@tonic-gate 		}
6480Sstevel@tonic-gate 	}
6490Sstevel@tonic-gate }
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate /*
6520Sstevel@tonic-gate  * Based on the Unicode Standard,  http://www.unicode.org/
6530Sstevel@tonic-gate  * "The Unicode Standard: A Technical Introduction", June 1998
6540Sstevel@tonic-gate  */
6550Sstevel@tonic-gate static int
unicode2ascii(char * outstr,int outlen,uchar_t * instr,int inlen)6560Sstevel@tonic-gate unicode2ascii(char *outstr, int outlen, uchar_t *instr, int inlen)
6570Sstevel@tonic-gate {
6580Sstevel@tonic-gate 	int i = 0, j = 0;
6590Sstevel@tonic-gate 	char c;
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	while (i < inlen && j < (outlen-1)) {
6620Sstevel@tonic-gate 		/* Show unicode chars >= 256 as '?' */
6630Sstevel@tonic-gate 		if (instr[i+1])
6640Sstevel@tonic-gate 			c = '?';
6650Sstevel@tonic-gate 		else
6660Sstevel@tonic-gate 			c = instr[i];
6670Sstevel@tonic-gate 		if (c == '\0')
6680Sstevel@tonic-gate 			break;
6690Sstevel@tonic-gate 		outstr[j] = c;
6700Sstevel@tonic-gate 		i += 2;
6710Sstevel@tonic-gate 		j++;
6720Sstevel@tonic-gate 	}
6730Sstevel@tonic-gate 	outstr[j] = '\0';
6740Sstevel@tonic-gate 	return (j);
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate 
6770Sstevel@tonic-gate /*
6780Sstevel@tonic-gate  * TRANS2 information levels
6790Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.1.6]
6800Sstevel@tonic-gate  */
6810Sstevel@tonic-gate static void
get_info_level(char * outstr,int value)6820Sstevel@tonic-gate get_info_level(char *outstr, int value)
6830Sstevel@tonic-gate {
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 	switch (value) {
6860Sstevel@tonic-gate 	case 1:
6870Sstevel@tonic-gate 		sprintf(outstr, "Standard"); break;
6880Sstevel@tonic-gate 	case 2:
6890Sstevel@tonic-gate 		sprintf(outstr, "Query EA Size"); break;
6900Sstevel@tonic-gate 	case 3:
6910Sstevel@tonic-gate 		sprintf(outstr, "Query EAS from List"); break;
6920Sstevel@tonic-gate 	case 0x101:
6930Sstevel@tonic-gate 		sprintf(outstr, "Directory Info"); break;
6940Sstevel@tonic-gate 	case 0x102:
6950Sstevel@tonic-gate 		sprintf(outstr, "Full Directory Info"); break;
6960Sstevel@tonic-gate 	case 0x103:
6970Sstevel@tonic-gate 		sprintf(outstr, "Names Info"); break;
6980Sstevel@tonic-gate 	case 0x104:
6990Sstevel@tonic-gate 		sprintf(outstr, "Both Directory Info"); break;
7000Sstevel@tonic-gate 	default:
7010Sstevel@tonic-gate 		sprintf(outstr, "Unknown"); break;
7020Sstevel@tonic-gate 	}
7030Sstevel@tonic-gate }
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate /*
7060Sstevel@tonic-gate  * Interpret TRANS2_QUERY_PATH subcommand
7070Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.7]
7080Sstevel@tonic-gate  */
7090Sstevel@tonic-gate /* ARGSUSED */
7100Sstevel@tonic-gate static void
output_trans2_querypath(int flags,uchar_t * data,char * xtra)7110Sstevel@tonic-gate output_trans2_querypath(int flags, uchar_t *data, char *xtra)
7120Sstevel@tonic-gate {
7130Sstevel@tonic-gate 	int length;
7140Sstevel@tonic-gate 	char filename[256];
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 	if (flags & F_SUM) {
7170Sstevel@tonic-gate 		length = sprintf(xtra, "QueryPathInfo ");
7180Sstevel@tonic-gate 		xtra += length;
7190Sstevel@tonic-gate 		data += 6;
7200Sstevel@tonic-gate 		(void) unicode2ascii(filename, 256, data, 512);
7210Sstevel@tonic-gate 		sprintf(xtra, "File=%s ", filename);
7220Sstevel@tonic-gate 	}
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate 	if (flags & F_DTAIL) {
7250Sstevel@tonic-gate 		sprintf(GETLINE, "FunctionName = QueryPathInfo");
7260Sstevel@tonic-gate 		sprintf(GETLINE, "InfoLevel = 0x%.4x",
7270Sstevel@tonic-gate 			get2(data));
7280Sstevel@tonic-gate 		data += 6;
7290Sstevel@tonic-gate 		(void) unicode2ascii(filename, 256, data, 512);
7300Sstevel@tonic-gate 		sprintf(GETLINE, "FileName = %s",
7310Sstevel@tonic-gate 			filename);
7320Sstevel@tonic-gate 	}
7330Sstevel@tonic-gate }
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate /*
7360Sstevel@tonic-gate  * Interpret TRANS2_QUERY_FILE subcommand
7370Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.9]
7380Sstevel@tonic-gate  */
7390Sstevel@tonic-gate /* ARGSUSED */
7400Sstevel@tonic-gate static void
output_trans2_queryfile(int flags,uchar_t * data,char * xtra)7410Sstevel@tonic-gate output_trans2_queryfile(int flags, uchar_t *data, char *xtra)
7420Sstevel@tonic-gate {
7430Sstevel@tonic-gate 	int length;
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 	if (flags & F_SUM) {
7460Sstevel@tonic-gate 		length = sprintf(xtra, "QueryFileInfo ");
7470Sstevel@tonic-gate 		xtra += length;
7480Sstevel@tonic-gate 		sprintf(xtra, "FileID=0x%x ", get2(data));
7490Sstevel@tonic-gate 	}
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	if (flags & F_DTAIL) {
7520Sstevel@tonic-gate 		sprintf(GETLINE, "FunctionName = QueryFileInfo");
7530Sstevel@tonic-gate 		sprintf(GETLINE, "FileID = 0x%.4x",
7540Sstevel@tonic-gate 			get2(data));
7550Sstevel@tonic-gate 		data += 2;
7560Sstevel@tonic-gate 		sprintf(GETLINE, "InfoLevel = 0x%.4x",
7570Sstevel@tonic-gate 			get2(data));
7580Sstevel@tonic-gate 	}
7590Sstevel@tonic-gate }
7600Sstevel@tonic-gate 
7610Sstevel@tonic-gate /*
7620Sstevel@tonic-gate  * Interpret TRANS2_SET_FILE subcommand
7630Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.10]
7640Sstevel@tonic-gate  */
7650Sstevel@tonic-gate /* ARGSUSED */
7660Sstevel@tonic-gate static void
output_trans2_setfile(int flags,uchar_t * data,char * xtra)7670Sstevel@tonic-gate output_trans2_setfile(int flags, uchar_t *data, char *xtra)
7680Sstevel@tonic-gate {
7690Sstevel@tonic-gate 	int length;
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate 	if (flags & F_SUM) {
7720Sstevel@tonic-gate 		length = sprintf(xtra, "SetFileInfo ");
7730Sstevel@tonic-gate 		xtra += length;
7740Sstevel@tonic-gate 		sprintf(xtra, "FileID=0x%x ", get2(data));
7750Sstevel@tonic-gate 	}
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	if (flags & F_DTAIL) {
7780Sstevel@tonic-gate 		sprintf(GETLINE, "FunctionName = SetFileInfo");
7790Sstevel@tonic-gate 		sprintf(GETLINE, "FileID = 0x%.4x",
7800Sstevel@tonic-gate 			get2(data));
7810Sstevel@tonic-gate 		data += 2;
7820Sstevel@tonic-gate 		sprintf(GETLINE, "InfoLevel = 0x%.4x",
7830Sstevel@tonic-gate 			get2(data));
7840Sstevel@tonic-gate 	}
7850Sstevel@tonic-gate }
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate /*
7880Sstevel@tonic-gate  * Interpret TRANS2_FIND_FIRST subcommand
7890Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.3]
7900Sstevel@tonic-gate  */
7910Sstevel@tonic-gate /* ARGSUSED */
7920Sstevel@tonic-gate static void
output_trans2_findfirst(int flags,uchar_t * data,char * xtra)7930Sstevel@tonic-gate output_trans2_findfirst(int flags, uchar_t *data, char *xtra)
7940Sstevel@tonic-gate {
7950Sstevel@tonic-gate 	int length;
7960Sstevel@tonic-gate 	char filename[256];
7970Sstevel@tonic-gate 	char infolevel[100];
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 	if (flags & F_SUM) {
8000Sstevel@tonic-gate 		length = sprintf(xtra, "Findfirst ");
8010Sstevel@tonic-gate 		xtra += length;
8020Sstevel@tonic-gate 		data += 12;
8030Sstevel@tonic-gate 		(void) unicode2ascii(filename, 256, data, 512);
8040Sstevel@tonic-gate 		sprintf(xtra, "File=%s ", filename);
8050Sstevel@tonic-gate 	}
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 	if (flags & F_DTAIL) {
8080Sstevel@tonic-gate 		sprintf(GETLINE, "FunctionName = Findfirst");
8090Sstevel@tonic-gate 		sprintf(GETLINE, "SearchAttributes = 0x%.4x",
8100Sstevel@tonic-gate 			get2(data));
8110Sstevel@tonic-gate 		data += 2;
8120Sstevel@tonic-gate 		sprintf(GETLINE, "FindCount = 0x%.4x",
8130Sstevel@tonic-gate 			get2(data));
8140Sstevel@tonic-gate 		data += 2;
8150Sstevel@tonic-gate 		sprintf(GETLINE, "FindFlags = 0x%.4x",
8160Sstevel@tonic-gate 			get2(data));
8170Sstevel@tonic-gate 		data += 2;
8180Sstevel@tonic-gate 		get_info_level(infolevel, get2(data));
8190Sstevel@tonic-gate 		sprintf(GETLINE, "InfoLevel = %s",
8200Sstevel@tonic-gate 			infolevel);
8210Sstevel@tonic-gate 		data += 6;
8220Sstevel@tonic-gate 		(void) unicode2ascii(filename, 256, data, 512);
8230Sstevel@tonic-gate 		sprintf(GETLINE, "FileName = %s",
8240Sstevel@tonic-gate 			filename);
8250Sstevel@tonic-gate 	}
8260Sstevel@tonic-gate }
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 
8290Sstevel@tonic-gate /*
8300Sstevel@tonic-gate  * Interpret TRANS2_FIND_NEXT subcommand
8310Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16.4]
8320Sstevel@tonic-gate  */
8330Sstevel@tonic-gate /* ARGSUSED */
8340Sstevel@tonic-gate static void
output_trans2_findnext(int flags,uchar_t * data,char * xtra)8350Sstevel@tonic-gate output_trans2_findnext(int flags, uchar_t *data, char *xtra)
8360Sstevel@tonic-gate {
8370Sstevel@tonic-gate 	int length;
8380Sstevel@tonic-gate 	char filename[256];
8390Sstevel@tonic-gate 	char infolevel[100];
8400Sstevel@tonic-gate 
8410Sstevel@tonic-gate 	if (flags & F_SUM) {
8420Sstevel@tonic-gate 		length = sprintf(xtra, "Findnext ");
8430Sstevel@tonic-gate 		xtra += length;
8440Sstevel@tonic-gate 		data += 12;
8450Sstevel@tonic-gate 		(void) unicode2ascii(filename, 256, data, 512);
8460Sstevel@tonic-gate 		sprintf(xtra, "File=%s ", filename);
8470Sstevel@tonic-gate 	}
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 	if (flags & F_DTAIL) {
8500Sstevel@tonic-gate 		sprintf(GETLINE, "FunctionName = Findnext");
8510Sstevel@tonic-gate 		sprintf(GETLINE, "FileID = 0x%.4x",
8520Sstevel@tonic-gate 			get2(data));
8530Sstevel@tonic-gate 		data += 2;
8540Sstevel@tonic-gate 		sprintf(GETLINE, "FindCount = 0x%.4x",
8550Sstevel@tonic-gate 			get2(data));
8560Sstevel@tonic-gate 		data += 2;
8570Sstevel@tonic-gate 		get_info_level(infolevel, get2(data));
8580Sstevel@tonic-gate 		sprintf(GETLINE, "InfoLevel = %s",
8590Sstevel@tonic-gate 			infolevel);
8600Sstevel@tonic-gate 		data += 2;
8610Sstevel@tonic-gate 		sprintf(GETLINE, "FindKey = 0x%.8x",
8620Sstevel@tonic-gate 			get4(data));
8630Sstevel@tonic-gate 		data += 4;
8640Sstevel@tonic-gate 		sprintf(GETLINE, "FindFlags = 0x%.4x",
8650Sstevel@tonic-gate 			get2(data));
8660Sstevel@tonic-gate 		data += 2;
8670Sstevel@tonic-gate 		(void) unicode2ascii(filename, 256, data, 512);
8680Sstevel@tonic-gate 		sprintf(GETLINE, "FileName = %s",
8690Sstevel@tonic-gate 			filename);
8700Sstevel@tonic-gate 	}
8710Sstevel@tonic-gate }
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate /*
8740Sstevel@tonic-gate  * Interpret a "Negprot" SMB
8750Sstevel@tonic-gate  * [X/Open-SMB, Sec. 6.1]
8760Sstevel@tonic-gate  */
8770Sstevel@tonic-gate /* ARGSUSED */
8780Sstevel@tonic-gate static void
interpret_negprot(int flags,uchar_t * data,int len,char * xtra)8790Sstevel@tonic-gate interpret_negprot(int flags, uchar_t *data, int len, char *xtra)
8800Sstevel@tonic-gate {
8810Sstevel@tonic-gate 	int length;
8820Sstevel@tonic-gate 	int bytecount;
8830Sstevel@tonic-gate 	char dialect[256];
8840Sstevel@tonic-gate 	struct smb *smbdata;
8850Sstevel@tonic-gate 	uchar_t *protodata;
8860Sstevel@tonic-gate 
8870Sstevel@tonic-gate 	smbdata  = (struct smb *)data;
8880Sstevel@tonic-gate 	protodata = (uchar_t *)data + sizeof (struct smb);
8890Sstevel@tonic-gate 	protodata++;			/* skip wordcount */
8900Sstevel@tonic-gate 
8910Sstevel@tonic-gate 	if (smbdata->flags & SERVER_RESPONSE) {
8920Sstevel@tonic-gate 		if (flags & F_SUM) {
8930Sstevel@tonic-gate 			sprintf(xtra, "Dialect#=%d ", protodata[0]);
8940Sstevel@tonic-gate 		}
8950Sstevel@tonic-gate 		if (flags & F_DTAIL) {
8960Sstevel@tonic-gate 			sprintf(GETLINE, "Protocol Index = %d",
8970Sstevel@tonic-gate 					protodata[0]);
8980Sstevel@tonic-gate 		}
8990Sstevel@tonic-gate 	} else {
9000Sstevel@tonic-gate 		/*
9010Sstevel@tonic-gate 		 * request packet:
9020Sstevel@tonic-gate 		 * short bytecount;
9030Sstevel@tonic-gate 		 * struct { char fmt; char name[]; } dialects
9040Sstevel@tonic-gate 		 */
9050Sstevel@tonic-gate 		bytecount = get2(protodata);
9060Sstevel@tonic-gate 		protodata += 2;
9070Sstevel@tonic-gate 		if (flags & F_SUM) {
9080Sstevel@tonic-gate 			while (bytecount > 1) {
909*7280Sblu 				length = snprintf(dialect, sizeof (dialect),
910*7280Sblu 				    "%s", (char *)protodata+1);
9110Sstevel@tonic-gate 				protodata += (length+2);
912*7280Sblu 				if (protodata >= data+len)
913*7280Sblu 					break;
9140Sstevel@tonic-gate 				bytecount -= (length+2);
9150Sstevel@tonic-gate 			}
9160Sstevel@tonic-gate 			sprintf(xtra, "LastDialect=%s ", dialect);
9170Sstevel@tonic-gate 		}
9180Sstevel@tonic-gate 		if (flags & F_DTAIL) {
9190Sstevel@tonic-gate 			sprintf(GETLINE, "ByteCount = %d", bytecount);
9200Sstevel@tonic-gate 			while (bytecount > 1) {
921*7280Sblu 				length = snprintf(dialect, sizeof (dialect),
922*7280Sblu 				    "%s", (char *)protodata+1);
9230Sstevel@tonic-gate 				sprintf(GETLINE, "Dialect String = %s",
924*7280Sblu 				    dialect);
9250Sstevel@tonic-gate 				protodata += (length+2);
926*7280Sblu 				if (protodata >= data+len)
927*7280Sblu 					break;
9280Sstevel@tonic-gate 				bytecount -= (length+2);
9290Sstevel@tonic-gate 			}
9300Sstevel@tonic-gate 		}
9310Sstevel@tonic-gate 	}
9320Sstevel@tonic-gate }
9330Sstevel@tonic-gate 
9340Sstevel@tonic-gate /*
9350Sstevel@tonic-gate  * LAN Manager remote admin function names.
9360Sstevel@tonic-gate  * [X/Open-SMB, Appendix B.8]
9370Sstevel@tonic-gate  */
9380Sstevel@tonic-gate static const char *apinames[] = {
9390Sstevel@tonic-gate 	"RNetShareEnum",
9400Sstevel@tonic-gate 	"RNetShareGetInfo",
9410Sstevel@tonic-gate 	"NetShareSetInfo",
9420Sstevel@tonic-gate 	"NetShareAdd",
9430Sstevel@tonic-gate 	"NetShareDel",
9440Sstevel@tonic-gate 	"NetShareCheck",
9450Sstevel@tonic-gate 	"NetSessionEnum",
9460Sstevel@tonic-gate 	"NetSessionGetInfo",
9470Sstevel@tonic-gate 	"NetSessionDel",
9480Sstevel@tonic-gate 	"NetConnectionEnum",
9490Sstevel@tonic-gate 	"NetFileEnum",
9500Sstevel@tonic-gate 	"NetFileGetInfo",
9510Sstevel@tonic-gate 	"NetFileClose",
9520Sstevel@tonic-gate 	"RNetServerGetInfo",
9530Sstevel@tonic-gate 	"NetServerSetInfo",
9540Sstevel@tonic-gate 	"NetServerDiskEnum",
9550Sstevel@tonic-gate 	"NetServerAdminCommand",
9560Sstevel@tonic-gate 	"NetAuditOpen",
9570Sstevel@tonic-gate 	"NetAuditClear",
9580Sstevel@tonic-gate 	"NetErrorLogOpen",
9590Sstevel@tonic-gate 	"NetErrorLogClear",
9600Sstevel@tonic-gate 	"NetCharDevEnum",
9610Sstevel@tonic-gate 	"NetCharDevGetInfo",
9620Sstevel@tonic-gate 	"NetCharDevControl",
9630Sstevel@tonic-gate 	"NetCharDevQEnum",
9640Sstevel@tonic-gate 	"NetCharDevQGetInfo",
9650Sstevel@tonic-gate 	"NetCharDevQSetInfo",
9660Sstevel@tonic-gate 	"NetCharDevQPurge",
9670Sstevel@tonic-gate 	"RNetCharDevQPurgeSelf",
9680Sstevel@tonic-gate 	"NetMessageNameEnum",
9690Sstevel@tonic-gate 	"NetMessageNameGetInfo",
9700Sstevel@tonic-gate 	"NetMessageNameAdd",
9710Sstevel@tonic-gate 	"NetMessageNameDel",
9720Sstevel@tonic-gate 	"NetMessageNameFwd",
9730Sstevel@tonic-gate 	"NetMessageNameUnFwd",
9740Sstevel@tonic-gate 	"NetMessageBufferSend",
9750Sstevel@tonic-gate 	"NetMessageFileSend",
9760Sstevel@tonic-gate 	"NetMessageLogFileSet",
9770Sstevel@tonic-gate 	"NetMessageLogFileGet",
9780Sstevel@tonic-gate 	"NetServiceEnum",
9790Sstevel@tonic-gate 	"RNetServiceInstall",
9800Sstevel@tonic-gate 	"RNetServiceControl",
9810Sstevel@tonic-gate 	"RNetAccessEnum",
9820Sstevel@tonic-gate 	"RNetAccessGetInfo",
9830Sstevel@tonic-gate 	"RNetAccessSetInfo",
9840Sstevel@tonic-gate 	"RNetAccessAdd",
9850Sstevel@tonic-gate 	"RNetAccessDel",
9860Sstevel@tonic-gate 	"NetGroupEnum",
9870Sstevel@tonic-gate 	"NetGroupAdd",
9880Sstevel@tonic-gate 	"NetGroupDel",
9890Sstevel@tonic-gate 	"NetGroupAddUser",
9900Sstevel@tonic-gate 	"NetGroupDelUser",
9910Sstevel@tonic-gate 	"NetGroupGetUsers",
9920Sstevel@tonic-gate 	"NetUserEnum",
9930Sstevel@tonic-gate 	"RNetUserAdd",
9940Sstevel@tonic-gate 	"NetUserDel",
9950Sstevel@tonic-gate 	"NetUserGetInfo",
9960Sstevel@tonic-gate 	"RNetUserSetInfo",
9970Sstevel@tonic-gate 	"RNetUserPasswordSet",
9980Sstevel@tonic-gate 	"NetUserGetGroups",
9990Sstevel@tonic-gate 	"NetWkstaLogon",
10000Sstevel@tonic-gate 	"NetWkstaLogoff",
10010Sstevel@tonic-gate 	"NetWkstaSetUID",
10020Sstevel@tonic-gate 	"NetWkstaGetInfo",
10030Sstevel@tonic-gate 	"NetWkstaSetInfo",
10040Sstevel@tonic-gate 	"NetUseEnum",
10050Sstevel@tonic-gate 	"NetUseAdd",
10060Sstevel@tonic-gate 	"NetUseDel",
10070Sstevel@tonic-gate 	"NetUseGetInfo",
10080Sstevel@tonic-gate 	"DosPrintQEnum",
10090Sstevel@tonic-gate 	"DosPrintQGetInfo",
10100Sstevel@tonic-gate 	"DosPrintQSetInfo",
10110Sstevel@tonic-gate 	"DosPrintQAdd",
10120Sstevel@tonic-gate 	"DosPrintQDel",
10130Sstevel@tonic-gate 	"DosPrintQPause",
10140Sstevel@tonic-gate 	"DosPrintQContinue",
10150Sstevel@tonic-gate 	"DosPrintJobEnum",
10160Sstevel@tonic-gate 	"DosPrintJobGetInfo",
10170Sstevel@tonic-gate 	"RDosPrintJobSetInfo",
10180Sstevel@tonic-gate 	"DosPrintJobAdd",
10190Sstevel@tonic-gate 	"DosPrintJobSchedule",
10200Sstevel@tonic-gate 	"RDosPrintJobDel",
10210Sstevel@tonic-gate 	"RDosPrintJobPause",
10220Sstevel@tonic-gate 	"RDosPrintJobContinue",
10230Sstevel@tonic-gate 	"DosPrintDestEnum",
10240Sstevel@tonic-gate 	"DosPrintDestGetInfo",
10250Sstevel@tonic-gate 	"DosPrintDestControl",
10260Sstevel@tonic-gate 	"NetProfileSave",
10270Sstevel@tonic-gate 	"NetProfileLoad",
10280Sstevel@tonic-gate 	"NetStatisticsGet",
10290Sstevel@tonic-gate 	"NetStatisticsClear",
10300Sstevel@tonic-gate 	"NetRemoteTOD",
10310Sstevel@tonic-gate 	"NetBiosEnum",
10320Sstevel@tonic-gate 	"NetBiosGetInfo",
10330Sstevel@tonic-gate 	"NetServerEnum",
10340Sstevel@tonic-gate 	"I_NetServerEnum",
10350Sstevel@tonic-gate 	"NetServiceGetInfo",
10360Sstevel@tonic-gate 	"NetSplQmAbort",
10370Sstevel@tonic-gate 	"NetSplQmClose",
10380Sstevel@tonic-gate 	"NetSplQmEndDoc",
10390Sstevel@tonic-gate 	"NetSplQmOpen",
10400Sstevel@tonic-gate 	"NetSplQmStartDoc",
10410Sstevel@tonic-gate 	"NetSplQmWrite",
10420Sstevel@tonic-gate 	"DosPrintQPurge",
10430Sstevel@tonic-gate 	"NetServerEnum2"
10440Sstevel@tonic-gate };
10450Sstevel@tonic-gate static const int apimax = (
10460Sstevel@tonic-gate 	sizeof (apinames) /
10470Sstevel@tonic-gate 	sizeof (apinames[0]));
10480Sstevel@tonic-gate 
10490Sstevel@tonic-gate /*
10500Sstevel@tonic-gate  * Interpret a "trans" SMB
10510Sstevel@tonic-gate  * [X/Open-SMB, Appendix B]
10520Sstevel@tonic-gate  *
10530Sstevel@tonic-gate  * This is very much like "trans2" below.
10540Sstevel@tonic-gate  */
10550Sstevel@tonic-gate /* ARGSUSED */
10560Sstevel@tonic-gate static void
interpret_trans(int flags,uchar_t * data,int len,char * xtra)10570Sstevel@tonic-gate interpret_trans(int flags, uchar_t *data, int len, char *xtra)
10580Sstevel@tonic-gate {
10590Sstevel@tonic-gate 	struct smb *smb;
10600Sstevel@tonic-gate 	uchar_t *vwv; /* word parameters */
10610Sstevel@tonic-gate 	int wordcount;
10620Sstevel@tonic-gate 	uchar_t *byteparms;
10630Sstevel@tonic-gate 	int bytecount;
10640Sstevel@tonic-gate 	int parambytes;
10650Sstevel@tonic-gate 	int paramoffset;
10660Sstevel@tonic-gate 	int setupcount;
10670Sstevel@tonic-gate 	int subcode;
10680Sstevel@tonic-gate 	uchar_t *setupdata;
10690Sstevel@tonic-gate 	uchar_t *params;
10700Sstevel@tonic-gate 	int apinum;
10710Sstevel@tonic-gate 	int isunicode;
10720Sstevel@tonic-gate 	char filename[256];
10730Sstevel@tonic-gate 
10740Sstevel@tonic-gate 	smb  = (struct smb *)data;
10750Sstevel@tonic-gate 	vwv = (uchar_t *)data + sizeof (struct smb);
10760Sstevel@tonic-gate 	wordcount = *vwv++;
10770Sstevel@tonic-gate 
10780Sstevel@tonic-gate 	byteparms = vwv + (2 * wordcount);
10790Sstevel@tonic-gate 	bytecount = get2(byteparms);
10800Sstevel@tonic-gate 	byteparms += 2;
10810Sstevel@tonic-gate 
10820Sstevel@tonic-gate 	/*
10830Sstevel@tonic-gate 	 * Print the lengths before we (potentially) bail out
10840Sstevel@tonic-gate 	 * due to lack of data (so the user knows why we did).
10850Sstevel@tonic-gate 	 */
10860Sstevel@tonic-gate 	if (flags & F_DTAIL) {
10870Sstevel@tonic-gate 		sprintf(GETLINE, "WordCount = %d", wordcount);
10880Sstevel@tonic-gate 		sprintf(GETLINE, "ByteCount = %d", bytecount);
10890Sstevel@tonic-gate 	}
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	/* Get length and location of params and setup data. */
10920Sstevel@tonic-gate 	if (!(smb->flags & SERVER_RESPONSE)) {
10930Sstevel@tonic-gate 		/* CALL */
10940Sstevel@tonic-gate 		if (wordcount < 14)
10950Sstevel@tonic-gate 			return;
10960Sstevel@tonic-gate 		parambytes  = get2(vwv + (2 *  9));
10970Sstevel@tonic-gate 		paramoffset = get2(vwv + (2 * 10));
10980Sstevel@tonic-gate 		setupcount = *(vwv + (2 * 13));
10990Sstevel@tonic-gate 		setupdata  =   vwv + (2 * 14);
11000Sstevel@tonic-gate 	} else {
11010Sstevel@tonic-gate 		/* REPLY */
11020Sstevel@tonic-gate 		if (wordcount < 10)
11030Sstevel@tonic-gate 			return;
11040Sstevel@tonic-gate 		parambytes  = get2(vwv + (2 * 3));
11050Sstevel@tonic-gate 		paramoffset = get2(vwv + (2 * 4));
11060Sstevel@tonic-gate 		setupcount = *(vwv + (2 *  9));
11070Sstevel@tonic-gate 		setupdata  =   vwv + (2 * 10);
11080Sstevel@tonic-gate 	}
11090Sstevel@tonic-gate 	if (setupcount > 0)
11100Sstevel@tonic-gate 		subcode = get2(setupdata);
11110Sstevel@tonic-gate 	else
11120Sstevel@tonic-gate 		subcode = -1; /* invalid */
11130Sstevel@tonic-gate 
11140Sstevel@tonic-gate 	/* The parameters are offset from the SMB header. */
11150Sstevel@tonic-gate 	params = data + paramoffset;
11160Sstevel@tonic-gate 	if (parambytes > 0)
11170Sstevel@tonic-gate 		apinum = params[0];
11180Sstevel@tonic-gate 	else
11190Sstevel@tonic-gate 		apinum = -1; /* invalid */
11200Sstevel@tonic-gate 
11210Sstevel@tonic-gate 	/* Is the pathname in unicode? */
11220Sstevel@tonic-gate 	isunicode = smb->flags2[1] & 0x80;
11230Sstevel@tonic-gate 
11240Sstevel@tonic-gate 	if (flags & F_DTAIL && !(smb->flags & SERVER_RESPONSE)) {
11250Sstevel@tonic-gate 		/* This is a CALL. */
11260Sstevel@tonic-gate 		/* print the word parameters */
11270Sstevel@tonic-gate 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
11280Sstevel@tonic-gate 		sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
11290Sstevel@tonic-gate 		sprintf(GETLINE, "MaxParamBytes = %d", get2(vwv+4));
11300Sstevel@tonic-gate 		sprintf(GETLINE, "MaxDataBytes = %d", get2(vwv+6));
11310Sstevel@tonic-gate 		sprintf(GETLINE, "MaxSetupWords = %d", vwv[8]);
11320Sstevel@tonic-gate 		sprintf(GETLINE, "TransFlags = 0x%.4x", get2(vwv+10));
11330Sstevel@tonic-gate 		sprintf(GETLINE, "Timeout = 0x%.8x", get4(vwv+12));
11340Sstevel@tonic-gate 		/* skip Reserved2 */
11350Sstevel@tonic-gate 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
11360Sstevel@tonic-gate 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
11370Sstevel@tonic-gate 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+22));
11380Sstevel@tonic-gate 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+24));
11390Sstevel@tonic-gate 		sprintf(GETLINE, "SetupWords = %d", setupcount);
11400Sstevel@tonic-gate 
11410Sstevel@tonic-gate 		/* That finishes the VWV, now the misc. stuff. */
11420Sstevel@tonic-gate 		if (subcode >= 0)
11430Sstevel@tonic-gate 			sprintf(GETLINE, "Setup[0] = %d", subcode);
11440Sstevel@tonic-gate 		if (apinum >= 0)
11450Sstevel@tonic-gate 			sprintf(GETLINE, "APIcode = %d", apinum);
11460Sstevel@tonic-gate 		if (0 <= apinum && apinum < apimax)
11470Sstevel@tonic-gate 			sprintf(GETLINE, "APIname = %s", apinames[apinum]);
11480Sstevel@tonic-gate 
11490Sstevel@tonic-gate 		/* Finally, print the byte parameters. */
11500Sstevel@tonic-gate 		if (isunicode) {
11510Sstevel@tonic-gate 			byteparms += 1;  /* alignment padding */
11520Sstevel@tonic-gate 			(void) unicode2ascii(
11530Sstevel@tonic-gate 				filename, 256, byteparms, bytecount);
11540Sstevel@tonic-gate 		} else {
1155*7280Sblu 			strlcpy(filename, (char *)byteparms, sizeof (filename));
11560Sstevel@tonic-gate 		}
11570Sstevel@tonic-gate 		sprintf(GETLINE, "FileName = %s", filename);
11580Sstevel@tonic-gate 	}
11590Sstevel@tonic-gate 
11600Sstevel@tonic-gate 	if (flags & F_DTAIL && smb->flags & SERVER_RESPONSE) {
11610Sstevel@tonic-gate 		/* This is a REPLY. */
11620Sstevel@tonic-gate 		/* print the word parameters */
11630Sstevel@tonic-gate 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
11640Sstevel@tonic-gate 		sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
11650Sstevel@tonic-gate 		/* skip Reserved */
11660Sstevel@tonic-gate 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
11670Sstevel@tonic-gate 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
11680Sstevel@tonic-gate 		sprintf(GETLINE, "ParamDispl. = 0x%.4x", get2(vwv+10));
11690Sstevel@tonic-gate 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+12));
11700Sstevel@tonic-gate 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+14));
11710Sstevel@tonic-gate 		sprintf(GETLINE, "DataDispl. = 0x%.4x", get2(vwv+16));
11720Sstevel@tonic-gate 		sprintf(GETLINE, "SetupWords = %d", setupcount);
11730Sstevel@tonic-gate 
11740Sstevel@tonic-gate 		output_bytes(byteparms, bytecount);
11750Sstevel@tonic-gate 	}
11760Sstevel@tonic-gate }
11770Sstevel@tonic-gate 
11780Sstevel@tonic-gate /*
11790Sstevel@tonic-gate  * Interpret a "TconX" SMB
11800Sstevel@tonic-gate  * [X/Open-SMB, Sec. 11.4]
11810Sstevel@tonic-gate  */
11820Sstevel@tonic-gate /* ARGSUSED */
11830Sstevel@tonic-gate static void
interpret_tconX(int flags,uchar_t * data,int len,char * xtra)11840Sstevel@tonic-gate interpret_tconX(int flags, uchar_t *data, int len, char *xtra)
11850Sstevel@tonic-gate {
11860Sstevel@tonic-gate 	int length;
11870Sstevel@tonic-gate 	int bytecount;
11880Sstevel@tonic-gate 	int passwordlength;
11890Sstevel@tonic-gate 	int wordcount;
11900Sstevel@tonic-gate 	char tempstring[256];
11910Sstevel@tonic-gate 	struct smb *smbdata;
11920Sstevel@tonic-gate 	uchar_t *tcondata;
11930Sstevel@tonic-gate 
11940Sstevel@tonic-gate 	smbdata  = (struct smb *)data;
11950Sstevel@tonic-gate 	tcondata = (uchar_t *)data + sizeof (struct smb);
11960Sstevel@tonic-gate 	wordcount = *tcondata++;
11970Sstevel@tonic-gate 
11980Sstevel@tonic-gate 	if (flags & F_SUM && !(smbdata->flags & SERVER_RESPONSE)) {
11990Sstevel@tonic-gate 		tcondata += 6;
12000Sstevel@tonic-gate 		passwordlength = get2(tcondata);
12010Sstevel@tonic-gate 		tcondata = tcondata + 4 + passwordlength;
1202*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1203*7280Sblu 		    (char *)tcondata);
12040Sstevel@tonic-gate 		sprintf(xtra, "Share=%s ", tempstring);
12050Sstevel@tonic-gate 	}
12060Sstevel@tonic-gate 
12070Sstevel@tonic-gate 	if (flags & F_SUM && smbdata->flags & SERVER_RESPONSE) {
12080Sstevel@tonic-gate 		tcondata += 8;
1209*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1210*7280Sblu 		    (char *)tcondata);
12110Sstevel@tonic-gate 		sprintf(xtra, "Type=%s ", tempstring);
12120Sstevel@tonic-gate 	}
12130Sstevel@tonic-gate 
12140Sstevel@tonic-gate 	if (flags & F_DTAIL && !(smbdata->flags & SERVER_RESPONSE)) {
12150Sstevel@tonic-gate 		sprintf(GETLINE, "WordCount = %d", wordcount);
12160Sstevel@tonic-gate 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
12170Sstevel@tonic-gate 			tcondata[0]);
12180Sstevel@tonic-gate 		tcondata += 2;
12190Sstevel@tonic-gate 		sprintf(GETLINE, "NextOffset = 0x%.4x",
12200Sstevel@tonic-gate 			get2(tcondata));
12210Sstevel@tonic-gate 		tcondata += 2;
12220Sstevel@tonic-gate 		sprintf(GETLINE, "DisconnectFlag = 0x%.4x",
12230Sstevel@tonic-gate 			get2(tcondata));
12240Sstevel@tonic-gate 		tcondata += 2;
12250Sstevel@tonic-gate 		passwordlength = get2(tcondata);
12260Sstevel@tonic-gate 		sprintf(GETLINE, "PasswordLength = 0x%.4x",
12270Sstevel@tonic-gate 			passwordlength);
12280Sstevel@tonic-gate 		tcondata += 2;
12290Sstevel@tonic-gate 		bytecount = get2(tcondata);
12300Sstevel@tonic-gate 		sprintf(GETLINE, "ByteCount = %d", bytecount);
12310Sstevel@tonic-gate 		tcondata = tcondata + 2 + passwordlength;
1232*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1233*7280Sblu 		    (char *)tcondata);
12340Sstevel@tonic-gate 		tcondata += (length+1);
12350Sstevel@tonic-gate 		sprintf(GETLINE, "FileName = %s", tempstring);
1236*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1237*7280Sblu 		    (char *)tcondata);
12380Sstevel@tonic-gate 		tcondata += (length+1);
12390Sstevel@tonic-gate 		sprintf(GETLINE, "ServiceName = %s", tempstring);
12400Sstevel@tonic-gate 	}
12410Sstevel@tonic-gate 
12420Sstevel@tonic-gate 	if (flags & F_DTAIL && smbdata->flags & SERVER_RESPONSE) {
12430Sstevel@tonic-gate 		sprintf(GETLINE, "WordCount = %d", wordcount);
12440Sstevel@tonic-gate 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
12450Sstevel@tonic-gate 			tcondata[0]);
12460Sstevel@tonic-gate 		tcondata += 2;
12470Sstevel@tonic-gate 		sprintf(GETLINE, "NextOffset = 0x%.4x",
12480Sstevel@tonic-gate 			get2(tcondata));
12490Sstevel@tonic-gate 		tcondata += 2;
12500Sstevel@tonic-gate 		sprintf(GETLINE, "OptionalSupport = 0x%.4x",
12510Sstevel@tonic-gate 			get2(tcondata));
12520Sstevel@tonic-gate 		tcondata += 2;
12530Sstevel@tonic-gate 		bytecount = get2(tcondata);
12540Sstevel@tonic-gate 		sprintf(GETLINE, "ByteCount = %d", bytecount);
12550Sstevel@tonic-gate 		tcondata += 2;
1256*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1257*7280Sblu 		    (char *)tcondata);
12580Sstevel@tonic-gate 		tcondata += (length+1);
12590Sstevel@tonic-gate 		sprintf(GETLINE, "ServiceName = %s", tempstring);
1260*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1261*7280Sblu 		    (char *)tcondata);
12620Sstevel@tonic-gate 		tcondata += (length+1);
12630Sstevel@tonic-gate 		sprintf(GETLINE, "NativeFS = %s", tempstring);
12640Sstevel@tonic-gate 	}
12650Sstevel@tonic-gate }
12660Sstevel@tonic-gate 
12670Sstevel@tonic-gate /*
12680Sstevel@tonic-gate  * Interpret a "SesssetupX" SMB
12690Sstevel@tonic-gate  * [X/Open-SMB, Sec. 11.3]
12700Sstevel@tonic-gate  */
12710Sstevel@tonic-gate /* ARGSUSED */
12720Sstevel@tonic-gate static void
interpret_sesssetupX(int flags,uchar_t * data,int len,char * xtra)12730Sstevel@tonic-gate interpret_sesssetupX(int flags, uchar_t *data, int len, char *xtra)
12740Sstevel@tonic-gate {
12750Sstevel@tonic-gate 	int length;
12760Sstevel@tonic-gate 	int bytecount;
12770Sstevel@tonic-gate 	int passwordlength;
12780Sstevel@tonic-gate 	int isunicode;
12790Sstevel@tonic-gate 	int upasswordlength;
12800Sstevel@tonic-gate 	int wordcount;
12810Sstevel@tonic-gate 	int cap;
12820Sstevel@tonic-gate 	char tempstring[256];
12830Sstevel@tonic-gate 	struct smb *smbdata;
12840Sstevel@tonic-gate 	uchar_t *setupdata;
12850Sstevel@tonic-gate 
12860Sstevel@tonic-gate 	smbdata  = (struct smb *)data;
12870Sstevel@tonic-gate 	setupdata = (uchar_t *)data + sizeof (struct smb);
12880Sstevel@tonic-gate 	wordcount = *setupdata++;
12890Sstevel@tonic-gate 
12900Sstevel@tonic-gate 	isunicode = smbdata->flags2[1] & 0x80;
12910Sstevel@tonic-gate 
12920Sstevel@tonic-gate 	if (flags & F_SUM && !(smbdata->flags & SERVER_RESPONSE)) {
12930Sstevel@tonic-gate 		if (wordcount != 13)
12940Sstevel@tonic-gate 			return;
12950Sstevel@tonic-gate 		setupdata += 14;
12960Sstevel@tonic-gate 		passwordlength = get2(setupdata);
12970Sstevel@tonic-gate 		setupdata += 2;
12980Sstevel@tonic-gate 		upasswordlength = get2(setupdata);
12990Sstevel@tonic-gate 		setupdata += 6;
13000Sstevel@tonic-gate 		cap = get4(setupdata);
13010Sstevel@tonic-gate 		setupdata = setupdata + 6 + passwordlength + upasswordlength;
13020Sstevel@tonic-gate 		if (isunicode) {
13030Sstevel@tonic-gate 			setupdata += 1;
13040Sstevel@tonic-gate 			(void) unicode2ascii(tempstring, 256, setupdata, 256);
13050Sstevel@tonic-gate 			sprintf(xtra, "Username=%s ", tempstring);
13060Sstevel@tonic-gate 		} else {
1307*7280Sblu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
1308*7280Sblu 			    (char *)setupdata);
13090Sstevel@tonic-gate 			sprintf(xtra, "Username=%s ", tempstring);
13100Sstevel@tonic-gate 		}
13110Sstevel@tonic-gate 	}
13120Sstevel@tonic-gate 
13130Sstevel@tonic-gate 	if (flags & F_DTAIL && !(smbdata->flags & SERVER_RESPONSE)) {
13140Sstevel@tonic-gate 		if (wordcount != 13)
13150Sstevel@tonic-gate 			return;
13160Sstevel@tonic-gate 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
13170Sstevel@tonic-gate 			setupdata[0]);
13180Sstevel@tonic-gate 		setupdata += 2;
13190Sstevel@tonic-gate 		sprintf(GETLINE, "NextOffset = 0x%.4x",
13200Sstevel@tonic-gate 			get2(setupdata));
13210Sstevel@tonic-gate 		setupdata += 2;
13220Sstevel@tonic-gate 		sprintf(GETLINE, "MaxBufferSize = 0x%.4x",
13230Sstevel@tonic-gate 			get2(setupdata));
13240Sstevel@tonic-gate 		setupdata += 2;
13250Sstevel@tonic-gate 		sprintf(GETLINE, "MaxMPXRequests = %d",
13260Sstevel@tonic-gate 			get2(setupdata));
13270Sstevel@tonic-gate 		setupdata += 2;
13280Sstevel@tonic-gate 		sprintf(GETLINE, "VCNumber = %d",
13290Sstevel@tonic-gate 			get2(setupdata));
13300Sstevel@tonic-gate 		setupdata += 2;
13310Sstevel@tonic-gate 		sprintf(GETLINE, "SessionKey = %d",
13320Sstevel@tonic-gate 			get4(setupdata));
13330Sstevel@tonic-gate 		setupdata += 4;
13340Sstevel@tonic-gate 		passwordlength = get2(setupdata);
13350Sstevel@tonic-gate 		sprintf(GETLINE, "PasswordLength = 0x%.4x",
13360Sstevel@tonic-gate 			passwordlength);
13370Sstevel@tonic-gate 		setupdata += 2;
13380Sstevel@tonic-gate 		upasswordlength = get2(setupdata);
13390Sstevel@tonic-gate 		sprintf(GETLINE, "UnicodePasswordLength = 0x%.4x",
13400Sstevel@tonic-gate 			upasswordlength);
13410Sstevel@tonic-gate 		setupdata += 6;
13420Sstevel@tonic-gate 		cap = get4(setupdata);
13430Sstevel@tonic-gate 		sprintf(GETLINE, "Capabilities = 0x%0.8x", cap);
13440Sstevel@tonic-gate 		setupdata += 4;
13450Sstevel@tonic-gate 		bytecount = get2(setupdata);
13460Sstevel@tonic-gate 		sprintf(GETLINE, "ByteCount = %d", bytecount);
13470Sstevel@tonic-gate 		setupdata = setupdata + 2 + passwordlength + upasswordlength;
13480Sstevel@tonic-gate 		if (isunicode) {
13490Sstevel@tonic-gate 			setupdata++;
13500Sstevel@tonic-gate 			length = 2*unicode2ascii(
13510Sstevel@tonic-gate 				tempstring, 256, setupdata, 256);
13520Sstevel@tonic-gate 			if (length == 2) {
13530Sstevel@tonic-gate 				sprintf(GETLINE,
13540Sstevel@tonic-gate 						"AccountName = %s", tempstring);
13550Sstevel@tonic-gate 				sprintf(GETLINE,
13560Sstevel@tonic-gate 						"DomainName = %s", tempstring);
13570Sstevel@tonic-gate 				setupdata += 3;
13580Sstevel@tonic-gate 			} else {
13590Sstevel@tonic-gate 				setupdata += length;
13600Sstevel@tonic-gate 				sprintf(GETLINE,
13610Sstevel@tonic-gate 						"AccountName = %s", tempstring);
13620Sstevel@tonic-gate 				length = 2*unicode2ascii(
13630Sstevel@tonic-gate 					tempstring, 256, setupdata, 256);
13640Sstevel@tonic-gate 				setupdata += length;
13650Sstevel@tonic-gate 				sprintf(GETLINE,
13660Sstevel@tonic-gate 						"DomainName = %s", tempstring);
13670Sstevel@tonic-gate 			}
13680Sstevel@tonic-gate 			length = 2*unicode2ascii(
13690Sstevel@tonic-gate 				tempstring, 256, setupdata, 256);
13700Sstevel@tonic-gate 			setupdata += (length+2);
13710Sstevel@tonic-gate 			sprintf(GETLINE,
13720Sstevel@tonic-gate 					"NativeOS = %s", tempstring);
13730Sstevel@tonic-gate 			length = 2*unicode2ascii(
13740Sstevel@tonic-gate 				tempstring, 256, setupdata, 256);
13750Sstevel@tonic-gate 			sprintf(GETLINE,
13760Sstevel@tonic-gate 					"NativeLanman = %s", tempstring);
13770Sstevel@tonic-gate 		} else {
1378*7280Sblu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
1379*7280Sblu 			    (char *)setupdata);
13800Sstevel@tonic-gate 			setupdata += (length+1);
13810Sstevel@tonic-gate 			sprintf(GETLINE, "AccountName = %s", tempstring);
1382*7280Sblu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
1383*7280Sblu 			    (char *)setupdata);
13840Sstevel@tonic-gate 			setupdata += (length+1);
13850Sstevel@tonic-gate 			sprintf(GETLINE, "DomainName = %s", tempstring);
1386*7280Sblu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
1387*7280Sblu 			    (char *)setupdata);
13880Sstevel@tonic-gate 			setupdata += (length+1);
13890Sstevel@tonic-gate 			sprintf(GETLINE, "NativeOS = %s", tempstring);
1390*7280Sblu 			snprintf(tempstring, sizeof (tempstring), "%s",
1391*7280Sblu 			    (char *)setupdata);
13920Sstevel@tonic-gate 			sprintf(GETLINE, "NativeLanman = %s", tempstring);
13930Sstevel@tonic-gate 		}
13940Sstevel@tonic-gate 	}
13950Sstevel@tonic-gate 
13960Sstevel@tonic-gate 	if (flags & F_DTAIL && smbdata->flags & SERVER_RESPONSE) {
13970Sstevel@tonic-gate 		if (wordcount != 3)
13980Sstevel@tonic-gate 			return;
13990Sstevel@tonic-gate 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
14000Sstevel@tonic-gate 			setupdata[0]);
14010Sstevel@tonic-gate 		setupdata += 2;
14020Sstevel@tonic-gate 		sprintf(GETLINE, "NextOffset = 0x%.4x",
14030Sstevel@tonic-gate 			get2(setupdata));
14040Sstevel@tonic-gate 		setupdata += 2;
14050Sstevel@tonic-gate 		sprintf(GETLINE, "SetupAction = 0x%.4x",
14060Sstevel@tonic-gate 			get2(setupdata));
14070Sstevel@tonic-gate 		setupdata += 2;
14080Sstevel@tonic-gate 		bytecount = get2(setupdata);
14090Sstevel@tonic-gate 		sprintf(GETLINE, "ByteCount = %d", bytecount);
14100Sstevel@tonic-gate 		setupdata += 2;
1411*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1412*7280Sblu 		    (char *)setupdata);
14130Sstevel@tonic-gate 		setupdata += (length+1);
14140Sstevel@tonic-gate 		sprintf(GETLINE, "NativeOS = %s", tempstring);
1415*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1416*7280Sblu 		    (char *)setupdata);
14170Sstevel@tonic-gate 		setupdata += (length+1);
14180Sstevel@tonic-gate 		sprintf(GETLINE, "NativeLanman = %s", tempstring);
1419*7280Sblu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
1420*7280Sblu 		    (char *)setupdata);
14210Sstevel@tonic-gate 		sprintf(GETLINE, "DomainName = %s", tempstring);
14220Sstevel@tonic-gate 	}
14230Sstevel@tonic-gate }
14240Sstevel@tonic-gate 
14250Sstevel@tonic-gate /*
14260Sstevel@tonic-gate  * Interpret "Trans2" SMB
14270Sstevel@tonic-gate  * [X/Open-SMB, Sec. 16]
14280Sstevel@tonic-gate  *
14290Sstevel@tonic-gate  * This is very much like "trans" above.
14300Sstevel@tonic-gate  */
14310Sstevel@tonic-gate /* ARGSUSED */
14320Sstevel@tonic-gate static void
interpret_trans2(int flags,uchar_t * data,int len,char * xtra)14330Sstevel@tonic-gate interpret_trans2(int flags, uchar_t *data, int len, char *xtra)
14340Sstevel@tonic-gate {
14350Sstevel@tonic-gate 	struct smb *smb;
14360Sstevel@tonic-gate 	uchar_t *vwv; /* word parameters */
14370Sstevel@tonic-gate 	int wordcount;
14380Sstevel@tonic-gate 	uchar_t *byteparms;
14390Sstevel@tonic-gate 	int bytecount;
14400Sstevel@tonic-gate 	int parambytes;
14410Sstevel@tonic-gate 	int paramoffset;
14420Sstevel@tonic-gate 	int setupcount;
14430Sstevel@tonic-gate 	int subcode;
14440Sstevel@tonic-gate 	uchar_t *setupdata;
14450Sstevel@tonic-gate 	uchar_t *params;
14460Sstevel@tonic-gate 	char *name;
14470Sstevel@tonic-gate 
14480Sstevel@tonic-gate 	smb  = (struct smb *)data;
14490Sstevel@tonic-gate 	vwv = (uchar_t *)data + sizeof (struct smb);
14500Sstevel@tonic-gate 	wordcount = *vwv++;
14510Sstevel@tonic-gate 
14520Sstevel@tonic-gate 	byteparms = vwv + (2 * wordcount);
14530Sstevel@tonic-gate 	bytecount = get2(byteparms);
14540Sstevel@tonic-gate 	byteparms += 2;
14550Sstevel@tonic-gate 
14560Sstevel@tonic-gate 	/*
14570Sstevel@tonic-gate 	 * Print the lengths before we (potentially) bail out
14580Sstevel@tonic-gate 	 * due to lack of data (so the user knows why we did).
14590Sstevel@tonic-gate 	 */
14600Sstevel@tonic-gate 	if (flags & F_DTAIL) {
14610Sstevel@tonic-gate 		sprintf(GETLINE, "WordCount = %d", wordcount);
14620Sstevel@tonic-gate 		sprintf(GETLINE, "ByteCount = %d", bytecount);
14630Sstevel@tonic-gate 	}
14640Sstevel@tonic-gate 
14650Sstevel@tonic-gate 	/* Get length and location of params and setup data. */
14660Sstevel@tonic-gate 	if (!(smb->flags & SERVER_RESPONSE)) {
14670Sstevel@tonic-gate 		/* CALL */
14680Sstevel@tonic-gate 		if (wordcount < 14)
14690Sstevel@tonic-gate 			return;
14700Sstevel@tonic-gate 		parambytes  = get2(vwv + (2 *  9));
14710Sstevel@tonic-gate 		paramoffset = get2(vwv + (2 * 10));
14720Sstevel@tonic-gate 		setupcount = *(vwv + (2 * 13));
14730Sstevel@tonic-gate 		setupdata  =   vwv + (2 * 14);
14740Sstevel@tonic-gate 	} else {
14750Sstevel@tonic-gate 		/* REPLY */
14760Sstevel@tonic-gate 		if (wordcount < 10)
14770Sstevel@tonic-gate 			return;
14780Sstevel@tonic-gate 		parambytes  = get2(vwv + (2 * 3));
14790Sstevel@tonic-gate 		paramoffset = get2(vwv + (2 * 4));
14800Sstevel@tonic-gate 		setupcount = *(vwv + (2 *  9));
14810Sstevel@tonic-gate 		setupdata  =   vwv + (2 * 10);
14820Sstevel@tonic-gate 	}
14830Sstevel@tonic-gate 	if (setupcount > 0)
14840Sstevel@tonic-gate 		subcode = get2(setupdata);
14850Sstevel@tonic-gate 	else
14860Sstevel@tonic-gate 		subcode = -1; /* invalid */
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate 	/* The parameters are offset from the SMB header. */
14890Sstevel@tonic-gate 	params = data + paramoffset;
14900Sstevel@tonic-gate 
14910Sstevel@tonic-gate 	if (flags & F_DTAIL && !(smb->flags & SERVER_RESPONSE)) {
14920Sstevel@tonic-gate 		/* This is a CALL. */
14930Sstevel@tonic-gate 		/* print the word parameters */
14940Sstevel@tonic-gate 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
14950Sstevel@tonic-gate 		sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
14960Sstevel@tonic-gate 		sprintf(GETLINE, "MaxParamBytes = %d", get2(vwv+4));
14970Sstevel@tonic-gate 		sprintf(GETLINE, "MaxDataBytes = %d", get2(vwv+6));
14980Sstevel@tonic-gate 		sprintf(GETLINE, "MaxSetupWords = %d", vwv[8]);
14990Sstevel@tonic-gate 		sprintf(GETLINE, "TransFlags = 0x%.4x", get2(vwv+10));
15000Sstevel@tonic-gate 		sprintf(GETLINE, "Timeout = 0x%.8x", get4(vwv+12));
15010Sstevel@tonic-gate 		/* skip Reserved2 */
15020Sstevel@tonic-gate 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
15030Sstevel@tonic-gate 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
15040Sstevel@tonic-gate 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+22));
15050Sstevel@tonic-gate 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+24));
15060Sstevel@tonic-gate 		sprintf(GETLINE, "SetupWords = %d", setupcount);
15070Sstevel@tonic-gate 
15080Sstevel@tonic-gate 		/* That finishes the VWV, now the misc. stuff. */
15090Sstevel@tonic-gate 		sprintf(GETLINE, "FunctionCode = %d", subcode);
15100Sstevel@tonic-gate 	}
15110Sstevel@tonic-gate 
15120Sstevel@tonic-gate 	if (!(smb->flags & SERVER_RESPONSE)) {
15130Sstevel@tonic-gate 		/* This is a CALL.  Do sub-function. */
15140Sstevel@tonic-gate 		switch (subcode) {
15150Sstevel@tonic-gate 		case TRANS2_OPEN:
15160Sstevel@tonic-gate 			name = "Open";
15170Sstevel@tonic-gate 			goto name_only;
15180Sstevel@tonic-gate 		case TRANS2_FIND_FIRST:
15190Sstevel@tonic-gate 			output_trans2_findfirst(flags, params, xtra);
15200Sstevel@tonic-gate 			break;
15210Sstevel@tonic-gate 		case TRANS2_FIND_NEXT2:
15220Sstevel@tonic-gate 			output_trans2_findnext(flags, params, xtra);
15230Sstevel@tonic-gate 			break;
15240Sstevel@tonic-gate 		case TRANS2_QUERY_FS_INFORMATION:
15250Sstevel@tonic-gate 			name = "QueryFSInfo";
15260Sstevel@tonic-gate 			goto name_only;
15270Sstevel@tonic-gate 		case TRANS2_QUERY_PATH_INFORMATION:
15280Sstevel@tonic-gate 			output_trans2_querypath(flags, params, xtra);
15290Sstevel@tonic-gate 			break;
15300Sstevel@tonic-gate 		case TRANS2_SET_PATH_INFORMATION:
15310Sstevel@tonic-gate 			name = "SetPathInfo";
15320Sstevel@tonic-gate 			goto name_only;
15330Sstevel@tonic-gate 		case TRANS2_QUERY_FILE_INFORMATION:
15340Sstevel@tonic-gate 			output_trans2_queryfile(flags, params, xtra);
15350Sstevel@tonic-gate 			break;
15360Sstevel@tonic-gate 		case TRANS2_SET_FILE_INFORMATION:
15370Sstevel@tonic-gate 			output_trans2_setfile(flags, params, xtra);
15380Sstevel@tonic-gate 			break;
15390Sstevel@tonic-gate 		case TRANS2_CREATE_DIRECTORY:
15400Sstevel@tonic-gate 			name = "CreateDir";
15410Sstevel@tonic-gate 			goto name_only;
15420Sstevel@tonic-gate 
15430Sstevel@tonic-gate 		default:
15440Sstevel@tonic-gate 			name = "Unknown";
15450Sstevel@tonic-gate 			/* fall through */
15460Sstevel@tonic-gate 		name_only:
15470Sstevel@tonic-gate 			if (flags & F_SUM)
15480Sstevel@tonic-gate 				sprintf(xtra, "%s ", name);
15490Sstevel@tonic-gate 			if (flags & F_DTAIL)
15500Sstevel@tonic-gate 				sprintf(GETLINE, "FunctionName = %s", name);
15510Sstevel@tonic-gate 			break;
15520Sstevel@tonic-gate 		}
15530Sstevel@tonic-gate 	}
15540Sstevel@tonic-gate 
15550Sstevel@tonic-gate 	if (flags & F_DTAIL && smb->flags & SERVER_RESPONSE) {
15560Sstevel@tonic-gate 		/* This is a REPLY. */
15570Sstevel@tonic-gate 		/* print the word parameters */
15580Sstevel@tonic-gate 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
15590Sstevel@tonic-gate 		sprintf(GETLINE, "TotalDataBytes = %d",  get2(vwv+2));
15600Sstevel@tonic-gate 		/* skip Reserved */
15610Sstevel@tonic-gate 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
15620Sstevel@tonic-gate 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
15630Sstevel@tonic-gate 		sprintf(GETLINE, "ParamDispl. = 0x%.4x", get2(vwv+10));
15640Sstevel@tonic-gate 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+12));
15650Sstevel@tonic-gate 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+14));
15660Sstevel@tonic-gate 		sprintf(GETLINE, "DataDispl. = 0x%.4x", get2(vwv+16));
15670Sstevel@tonic-gate 		sprintf(GETLINE, "SetupWords = %d", setupcount);
15680Sstevel@tonic-gate 
15690Sstevel@tonic-gate 		output_bytes(byteparms, bytecount);
15700Sstevel@tonic-gate 	}
15710Sstevel@tonic-gate }
15720Sstevel@tonic-gate 
15730Sstevel@tonic-gate 
15740Sstevel@tonic-gate static void
interpret_default(int flags,uchar_t * data,int len,char * xtra)15750Sstevel@tonic-gate interpret_default(int flags, uchar_t *data, int len, char *xtra)
15760Sstevel@tonic-gate {
15770Sstevel@tonic-gate 	int slength;
15780Sstevel@tonic-gate 	int i;
15790Sstevel@tonic-gate 	int printit;
15800Sstevel@tonic-gate 	int wordcount;
15810Sstevel@tonic-gate 	char *outstr;
15820Sstevel@tonic-gate 	char *prfmt;
15830Sstevel@tonic-gate 	char *format;
15840Sstevel@tonic-gate 	char valuetype;
15850Sstevel@tonic-gate 	char word[10];
15860Sstevel@tonic-gate 	char *label;
15870Sstevel@tonic-gate 	char tempstring[256];
15880Sstevel@tonic-gate 	uchar_t *comdata, *limit;
15890Sstevel@tonic-gate 	char buff[80];
15900Sstevel@tonic-gate 	struct smb *smbdata;
15910Sstevel@tonic-gate 	struct decode *decoder;
15920Sstevel@tonic-gate 
15930Sstevel@tonic-gate 	smbdata  = (struct smb *)data;
15940Sstevel@tonic-gate 	comdata = (uchar_t *)data + sizeof (struct smb);
15950Sstevel@tonic-gate 	wordcount = *comdata++;
15960Sstevel@tonic-gate 	limit = data + len;
15970Sstevel@tonic-gate 
15980Sstevel@tonic-gate 	decoder = &SMBtable[smbdata->com & 255];
15990Sstevel@tonic-gate 
16000Sstevel@tonic-gate 	if (smbdata->flags & SERVER_RESPONSE)
16010Sstevel@tonic-gate 		format = decoder->replyfmt;
16020Sstevel@tonic-gate 	else
16030Sstevel@tonic-gate 		format = decoder->callfmt;
16040Sstevel@tonic-gate 
16050Sstevel@tonic-gate 	if (!format || strlen(format) == 0) {
16060Sstevel@tonic-gate 		if (wordcount == 0 || flags & F_SUM)
16070Sstevel@tonic-gate 			return;
16080Sstevel@tonic-gate 		sprintf(GETLINE, "WordCount = %d", wordcount);
16090Sstevel@tonic-gate 		sprintf(GETLINE, "Word values (in hex):");
16100Sstevel@tonic-gate 		for (i = 0; i < wordcount; i++) {
16110Sstevel@tonic-gate 			sprintf(word, "%.4x ", get2(comdata));
16120Sstevel@tonic-gate 			comdata += 2;
16130Sstevel@tonic-gate 			if (comdata >= limit)
16140Sstevel@tonic-gate 				wordcount = i+1; /* terminate */
16150Sstevel@tonic-gate 			strcat(buff, word);
16160Sstevel@tonic-gate 			if (((i+1) & 7) == 0 || i == (wordcount-1)) {
16170Sstevel@tonic-gate 				sprintf(GETLINE, "%s", buff);
16180Sstevel@tonic-gate 				strcpy(buff, "");
16190Sstevel@tonic-gate 			}
16200Sstevel@tonic-gate 		}
16210Sstevel@tonic-gate 		return;
16220Sstevel@tonic-gate 	}
16230Sstevel@tonic-gate 
16240Sstevel@tonic-gate 
16250Sstevel@tonic-gate 	valuetype = format[0];
16260Sstevel@tonic-gate 	while (valuetype != '\0') {
16270Sstevel@tonic-gate 		if (comdata >= limit)
16280Sstevel@tonic-gate 			break;
16290Sstevel@tonic-gate 		if ((flags & F_DTAIL) && valuetype != 'r' && valuetype != 'R')
16300Sstevel@tonic-gate 			outstr = GETLINE;
16310Sstevel@tonic-gate 		else
16320Sstevel@tonic-gate 			outstr = xtra + strlen(xtra);
16330Sstevel@tonic-gate 		label = format+1;
16340Sstevel@tonic-gate 		printit = (flags & F_DTAIL) || (valuetype <= 'Z');
16350Sstevel@tonic-gate 
16360Sstevel@tonic-gate 		switch (valuetype) {
16370Sstevel@tonic-gate 		case 'W':
16380Sstevel@tonic-gate 		case 'w':
16390Sstevel@tonic-gate 			prfmt = (flags & F_DTAIL) ? "%s = 0x%.4x" : "%s=0x%x ";
16400Sstevel@tonic-gate 			if (printit)
16410Sstevel@tonic-gate 				sprintf(outstr, prfmt, label, get2(comdata));
16420Sstevel@tonic-gate 			comdata += 2;
16430Sstevel@tonic-gate 			break;
16440Sstevel@tonic-gate 		case 'D':
16450Sstevel@tonic-gate 		case 'd':
16460Sstevel@tonic-gate 			prfmt = (flags & F_DTAIL) ? "%s = %d" : "%s=%d ";
16470Sstevel@tonic-gate 			if (printit)
16480Sstevel@tonic-gate 				sprintf(outstr, prfmt, label, get2(comdata));
16490Sstevel@tonic-gate 			comdata += 2;
16500Sstevel@tonic-gate 			break;
16510Sstevel@tonic-gate 		case 'L':
16520Sstevel@tonic-gate 		case 'l':
16530Sstevel@tonic-gate 			prfmt = (flags & F_DTAIL) ? "%s = 0x%.8x" : "%s=0x%x ";
16540Sstevel@tonic-gate 			if (printit)
16550Sstevel@tonic-gate 				sprintf(outstr, prfmt, label, get4(comdata));
16560Sstevel@tonic-gate 			comdata += 4;
16570Sstevel@tonic-gate 			break;
16580Sstevel@tonic-gate 		case 'B':
16590Sstevel@tonic-gate 		case 'b':
16600Sstevel@tonic-gate 			prfmt = (flags & F_DTAIL) ? "%s = 0x%.2x" : "%s=0x%x ";
16610Sstevel@tonic-gate 			if (printit)
16620Sstevel@tonic-gate 				sprintf(outstr, prfmt, label, comdata[0]);
16630Sstevel@tonic-gate 			comdata += 1;
16640Sstevel@tonic-gate 			break;
16650Sstevel@tonic-gate 		case 'r':
16660Sstevel@tonic-gate 			comdata++;
16670Sstevel@tonic-gate 			break;
16680Sstevel@tonic-gate 		case 'R':
16690Sstevel@tonic-gate 			comdata += 2;
16700Sstevel@tonic-gate 			break;
16710Sstevel@tonic-gate 		case 'U':
16720Sstevel@tonic-gate 		case 'u':
16730Sstevel@tonic-gate 			prfmt = (flags & F_DTAIL) ? "%s = %s" : "%s=%s ";
16740Sstevel@tonic-gate 			slength = unicode2ascii(tempstring, 256, comdata, 256);
16750Sstevel@tonic-gate 			if (printit)
16760Sstevel@tonic-gate 				sprintf(outstr, prfmt, label, tempstring);
16770Sstevel@tonic-gate 			comdata +=  (slength*2 + 1);
16780Sstevel@tonic-gate 			break;
16790Sstevel@tonic-gate 		case 'S':
16800Sstevel@tonic-gate 		case 's':
16810Sstevel@tonic-gate 			prfmt = (flags & F_DTAIL) ? "%s = %s" : "%s=%s ";
1682*7280Sblu 			slength = snprintf(tempstring, sizeof (tempstring),
1683*7280Sblu 			    "%s", (char *)comdata);
16840Sstevel@tonic-gate 			if (printit)
16850Sstevel@tonic-gate 				sprintf(outstr, prfmt, label, tempstring);
16860Sstevel@tonic-gate 			comdata += (slength+1);
16870Sstevel@tonic-gate 			break;
16880Sstevel@tonic-gate 		}
16890Sstevel@tonic-gate 		format += (strlen(format) + 1);
16900Sstevel@tonic-gate 		valuetype = format[0];
16910Sstevel@tonic-gate 	}
16920Sstevel@tonic-gate }
1693