Home | History | Annotate | Download | only in snoop
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  7280     blu  * Common Development and Distribution License (the "License").
      6  7280     blu  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21     0  stevel /*
     22  7280     blu  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  7280     blu  * Use is subject to license terms.
     24     0  stevel  */
     25     0  stevel 
     26     0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27     0  stevel 
     28     0  stevel /*
     29     0  stevel  * References used throughout this code:
     30     0  stevel  *
     31     0  stevel  * [CIFS/1.0] : A Common Internet File System (CIFS/1.0) Protocol
     32     0  stevel  *		Internet Engineering Task Force (IETF) draft
     33     0  stevel  *		Paul J. Leach, Microsoft, Dec. 1997
     34     0  stevel  *
     35     0  stevel  * [X/Open-SMB] : X/Open CAE Specification;
     36     0  stevel  *		Protocols for X/Open PC Interworking: SMB, Version 2
     37     0  stevel  *		X/Open Document Number: C209
     38     0  stevel  */
     39     0  stevel 
     40     0  stevel #include <fcntl.h>
     41     0  stevel #include <stdio.h>
     42     0  stevel #include <stdlib.h>
     43     0  stevel #include <string.h>
     44     0  stevel 
     45     0  stevel #include "snoop.h"
     46     0  stevel 
     47     0  stevel /* some macros just for compactness */
     48     0  stevel #define	GETLINE get_line(0, 0)
     49     0  stevel #define	DECARGS int flags, uchar_t *data, int len, char *extrainfo
     50     0  stevel 
     51     0  stevel /*
     52     0  stevel  * SMB Format (header)
     53     0  stevel  * [X/Open-SMB, Sec. 5.1]
     54     0  stevel  */
     55     0  stevel struct smb {
     56     0  stevel 	uchar_t idf[4]; /*  identifier, contains 0xff, 'SMB'  */
     57     0  stevel 	uchar_t com;    /*  command code  */
     58     0  stevel 	uchar_t rcls;   /*  error class  */
     59     0  stevel 	uchar_t res;
     60     0  stevel 	uchar_t err[2]; /*  error code  */
     61     0  stevel 	uchar_t flags;
     62     0  stevel 	uchar_t flags2[2];
     63     0  stevel 	uchar_t re[12];
     64     0  stevel 	uchar_t tid[2];
     65     0  stevel 	uchar_t pid[2];
     66     0  stevel 	uchar_t uid[2];
     67     0  stevel 	uchar_t mid[2];
     68     0  stevel 	/*
     69     0  stevel 	 * immediately after the above 32 byte header:
     70     0  stevel 	 *   unsigned char  WordCount;
     71     0  stevel 	 *   unsigned short ParameterWords[ WordCount ];
     72     0  stevel 	 *   unsigned short ByteCount;
     73     0  stevel 	 *   unsigned char  ParameterBytes[ ByteCount ];
     74     0  stevel 	 */
     75     0  stevel };
     76     0  stevel 
     77     0  stevel /* smb flags */
     78     0  stevel #define	SERVER_RESPONSE	0x80
     79     0  stevel 
     80     0  stevel static void interpret_sesssetupX(DECARGS);
     81     0  stevel static void interpret_tconX(DECARGS);
     82     0  stevel static void interpret_trans(DECARGS);
     83     0  stevel static void interpret_trans2(DECARGS);
     84     0  stevel static void interpret_negprot(DECARGS);
     85     0  stevel static void interpret_default(DECARGS);
     86     0  stevel 
     87     0  stevel /*
     88     0  stevel  * Trans2 subcommand codes
     89     0  stevel  * [X/Open-SMB, Sec. 16.1.7]
     90     0  stevel  */
     91     0  stevel #define	TRANS2_OPEN 0x00
     92     0  stevel #define	TRANS2_FIND_FIRST 0x01
     93     0  stevel #define	TRANS2_FIND_NEXT2 0x02
     94     0  stevel #define	TRANS2_QUERY_FS_INFORMATION 0x03
     95     0  stevel #define	TRANS2_QUERY_PATH_INFORMATION 0x05
     96     0  stevel #define	TRANS2_SET_PATH_INFORMATION 0x06
     97     0  stevel #define	TRANS2_QUERY_FILE_INFORMATION 0x07
     98     0  stevel #define	TRANS2_SET_FILE_INFORMATION 0x08
     99     0  stevel #define	TRANS2_CREATE_DIRECTORY 0x0D
    100     0  stevel 
    101     0  stevel 
    102     0  stevel struct decode {
    103     0  stevel 	char *name;
    104     0  stevel 	void (*func)(DECARGS);
    105     0  stevel 	char *callfmt;
    106     0  stevel 	char *replyfmt;
    107     0  stevel };
    108     0  stevel 
    109     0  stevel /*
    110     0  stevel  * SMB command codes (function names)
    111     0  stevel  * [X/Open-SMB, Sec. 5.2]
    112     0  stevel  */
    113     0  stevel static struct decode SMBtable[256] = {
    114     0  stevel 	/* 0x00 */
    115     0  stevel 	{ "mkdir", 0, 0, 0 },
    116     0  stevel 	{ "rmdir", 0, 0, 0 },
    117     0  stevel 	{ "open", 0, 0, 0 },
    118     0  stevel 	{ "create", 0, 0, 0 },
    119     0  stevel 
    120     0  stevel 	{
    121     0  stevel 		"close", 0,
    122     0  stevel 		/* [X/Open-SMB, Sec. 7.10] */
    123     0  stevel 		"WFileID\0lLastModTime\0wByteCount\0\0",
    124     0  stevel 		"wByteCount\0\0"
    125     0  stevel 	},
    126     0  stevel 
    127     0  stevel 	{ "flush", 0, 0, 0 },
    128     0  stevel 	{ "unlink", 0, 0, 0 },
    129     0  stevel 
    130     0  stevel 	{
    131     0  stevel 		"mv", 0,
    132     0  stevel 		/* [X/Open-SMB, Sec. 7.11] */
    133     0  stevel 		"wFileAttributes\0wByteCount\0"
    134     0  stevel 		"r\0UFileName\0r\0UNewPath\0\0",
    135     0  stevel 		"wByteCount\0\0"
    136     0  stevel 	},
    137     0  stevel 
    138     0  stevel 	{
    139     0  stevel 		"getatr", 0,
    140     0  stevel 		/* [X/Open-SMB, Sec. 8.4] */
    141     0  stevel 		"dBytecount\0r\0UFileName\0\0",
    142     0  stevel 		"wFileAttributes\0lTime\0lSize\0R\0R\0R\0"
    143     0  stevel 		"R\0R\0wByteCount\0\0"
    144     0  stevel 	},
    145     0  stevel 
    146     0  stevel 	{ "setatr", 0, 0, 0 },
    147     0  stevel 
    148     0  stevel 	{
    149     0  stevel 		"read", 0,
    150     0  stevel 		/* [X/Open-SMB, Sec. 7.4] */
    151     0  stevel 		"WFileID\0wI/0 Bytes\0LFileOffset\0"
    152     0  stevel 		"WBytesLeft\0wByteCount\0\0",
    153     0  stevel 		"WDataLength\0R\0R\0R\0R\0wByteCount\0\0"
    154     0  stevel 	},
    155     0  stevel 
    156     0  stevel 	{
    157     0  stevel 		"write", 0,
    158     0  stevel 		/* [X/Open-SMB, Sec. 7.5] */
    159     0  stevel 		"WFileID\0wI/0 Bytes\0LFileOffset\0WBytesLeft\0"
    160     0  stevel 		"wByteCount\0\0",
    161     0  stevel 		"WDataLength\0wByteCount\0\0"
    162     0  stevel 	},
    163     0  stevel 
    164     0  stevel 	{ "lock", 0, 0, 0 },
    165     0  stevel 	{ "unlock", 0, 0, 0 },
    166     0  stevel 	{ "ctemp", 0, 0, 0 },
    167     0  stevel 	{ "mknew", 0, 0, 0 },
    168     0  stevel 
    169     0  stevel 	/* 0x10 */
    170     0  stevel 	{
    171     0  stevel 		"chkpth", 0,
    172     0  stevel 		/* [X/Open-SMB, Sec. 8.7] */
    173     0  stevel 		"wByteCount\0r\0UFile\0\0",
    174     0  stevel 		"wByteCount\0\0"
    175     0  stevel 	},
    176     0  stevel 
    177     0  stevel 	{ "exit", 0, 0, 0 },
    178     0  stevel 	{ "lseek", 0, 0, 0 },
    179     0  stevel 	{ "lockread", 0, 0, 0 },
    180     0  stevel 	{ "writeunlock", 0, 0, 0 },
    181     0  stevel 	{ 0, 0, 0, 0 },
    182     0  stevel 	{ 0, 0, 0, 0 },
    183     0  stevel 	{ 0, 0, 0, 0 },
    184     0  stevel 	{ 0, 0, 0, 0 },
    185     0  stevel 	{ 0, 0, 0, 0 },
    186     0  stevel 
    187     0  stevel 	{
    188     0  stevel 		"readbraw", 0,
    189     0  stevel 		/* [X/Open-SMB, Sec. 10.1] */
    190     0  stevel 		"WFileID\0LFileOffset\0wMaxCount\0"
    191     0  stevel 		"wMinCount\0lTimeout\0R\0wByteCount\0\0", 0
    192     0  stevel 	},
    193     0  stevel 
    194     0  stevel 	{ "readbmpx", 0, 0, 0 },
    195     0  stevel 	{ "readbs", 0, 0, 0 },
    196     0  stevel 	{ "writebraw", 0, 0, 0 },
    197     0  stevel 	{ "writebmpx", 0, 0, 0 },
    198     0  stevel 	{ "writebs", 0, 0, 0 },
    199     0  stevel 
    200     0  stevel 	/* 0x20 */
    201     0  stevel 	{ "writec", 0, 0, 0 },
    202     0  stevel 	{ "qrysrv", 0, 0, 0 },
    203     0  stevel 	{ "setattrE", 0, 0, 0 },
    204     0  stevel 	{ "getattrE", 0, 0, 0 },
    205     0  stevel 
    206     0  stevel 	{
    207     0  stevel 		"lockingX", 0,
    208     0  stevel 		/* [X/Open-SMB, Sec. 12.2] */
    209     0  stevel 		"wChainedCommand\0wNextOffset\0WFileID\0"
    210     0  stevel 		"wLockType\0lOpenTimeout\0"
    211     0  stevel 		"W#Unlocks\0W#Locks\0wByteCount\0\0", 0
    212     0  stevel 	},
    213     0  stevel 
    214     0  stevel 	{ "trans", interpret_trans, 0, 0 },
    215     0  stevel 	{ "transs", 0, 0, 0 },
    216     0  stevel 	{ "ioctl", 0, 0, 0 },
    217     0  stevel 	{ "ioctls", 0, 0, 0 },
    218     0  stevel 	{ "copy", 0, 0, 0 },
    219     0  stevel 	{ "move", 0, 0, 0 },
    220     0  stevel 	{ "echo", 0, 0, 0 },
    221     0  stevel 	{ "writeclose", 0, 0, 0 },
    222     0  stevel 
    223     0  stevel 	{
    224     0  stevel 		"openX", 0,
    225     0  stevel 		/* [X/Open-SMB, Sec. 12.1] */
    226     0  stevel 		"wChainedCommand\0wNextOffset\0wFlags\0"
    227     0  stevel 		"wMode\0wSearchAttributes\0wFileAttributes\0"
    228     0  stevel 		"lTime\0wOpenFunction\0lFileSize\0lOpenTimeout\0"
    229     0  stevel 		"R\0R\0wByteCount\0r\0UFileName\0\0",
    230     0  stevel 		"wChainedCommand\0wNextOffset\0WFileID\0"
    231     0  stevel 		"wAttributes\0lTime\0LSize\0wOpenMode\0"
    232     0  stevel 		"wFileType\0wDeviceState\0wActionTaken\0"
    233     0  stevel 		"lUniqueFileID\0R\0wBytecount\0\0"
    234     0  stevel 	},
    235     0  stevel 
    236     0  stevel 	{ "readX", 0, 0, 0 },
    237     0  stevel 	{ "writeX", 0, 0, 0 },
    238     0  stevel 
    239     0  stevel 	/* 0x30 */
    240     0  stevel 	{ 0, 0, 0, 0 },
    241     0  stevel 	{ "closeTD", 0, 0, 0 },
    242     0  stevel 	{ "trans2", interpret_trans2, 0, 0 },
    243     0  stevel 	{ "trans2s", 0, 0, 0 },
    244     0  stevel 	{
    245     0  stevel 		"findclose", 0,
    246     0  stevel 		/* [X/Open-SMB, Sec. 15.4 ] */
    247     0  stevel 		"WFileID\0wByteCount\0\0",
    248     0  stevel 		"wByteCount\0\0"
    249     0  stevel 	},
    250     0  stevel 	{ 0, 0, 0, 0 },
    251     0  stevel 	{ 0, 0, 0, 0 },
    252     0  stevel 	{ 0, 0, 0, 0 },
    253     0  stevel 	{ 0, 0, 0, 0 },
    254     0  stevel 	{ 0, 0, 0, 0 },
    255     0  stevel 	{ 0, 0, 0, 0 },
    256     0  stevel 	{ 0, 0, 0, 0 },
    257     0  stevel 	{ 0, 0, 0, 0 },
    258     0  stevel 	{ 0, 0, 0, 0 },
    259     0  stevel 	{ 0, 0, 0, 0 },
    260     0  stevel 	{ 0, 0, 0, 0 },
    261     0  stevel 
    262     0  stevel 	/* 0x40 */
    263     0  stevel 	{ 0, 0, 0, 0 },
    264     0  stevel 	{ 0, 0, 0, 0 },
    265     0  stevel 	{ 0, 0, 0, 0 },
    266     0  stevel 	{ 0, 0, 0, 0 },
    267     0  stevel 	{ 0, 0, 0, 0 },
    268     0  stevel 	{ 0, 0, 0, 0 },
    269     0  stevel 	{ 0, 0, 0, 0 },
    270     0  stevel 	{ 0, 0, 0, 0 },
    271     0  stevel 	{ 0, 0, 0, 0 },
    272     0  stevel 	{ 0, 0, 0, 0 },
    273     0  stevel 	{ 0, 0, 0, 0 },
    274     0  stevel 	{ 0, 0, 0, 0 },
    275     0  stevel 	{ 0, 0, 0, 0 },
    276     0  stevel 	{ 0, 0, 0, 0 },
    277     0  stevel 	{ 0, 0, 0, 0 },
    278     0  stevel 	{ 0, 0, 0, 0 },
    279     0  stevel 
    280     0  stevel 	/* 0x50 */
    281     0  stevel 	{ 0, 0, 0, 0 },
    282     0  stevel 	{ 0, 0, 0, 0 },
    283     0  stevel 	{ 0, 0, 0, 0 },
    284     0  stevel 	{ 0, 0, 0, 0 },
    285     0  stevel 	{ 0, 0, 0, 0 },
    286     0  stevel 	{ 0, 0, 0, 0 },
    287     0  stevel 	{ 0, 0, 0, 0 },
    288     0  stevel 	{ 0, 0, 0, 0 },
    289     0  stevel 	{ 0, 0, 0, 0 },
    290     0  stevel 	{ 0, 0, 0, 0 },
    291     0  stevel 	{ 0, 0, 0, 0 },
    292     0  stevel 	{ 0, 0, 0, 0 },
    293     0  stevel 	{ 0, 0, 0, 0 },
    294     0  stevel 	{ 0, 0, 0, 0 },
    295     0  stevel 	{ 0, 0, 0, 0 },
    296     0  stevel 	{ 0, 0, 0, 0 },
    297     0  stevel 
    298     0  stevel 	/* 0x60 */
    299     0  stevel 	{ 0, 0, 0, 0 },
    300     0  stevel 	{ 0, 0, 0, 0 },
    301     0  stevel 	{ 0, 0, 0, 0 },
    302     0  stevel 	{ 0, 0, 0, 0 },
    303     0  stevel 	{ 0, 0, 0, 0 },
    304     0  stevel 	{ 0, 0, 0, 0 },
    305     0  stevel 	{ 0, 0, 0, 0 },
    306     0  stevel 	{ 0, 0, 0, 0 },
    307     0  stevel 	{ 0, 0, 0, 0 },
    308     0  stevel 	{ 0, 0, 0, 0 },
    309     0  stevel 	{ 0, 0, 0, 0 },
    310     0  stevel 	{ 0, 0, 0, 0 },
    311     0  stevel 	{ 0, 0, 0, 0 },
    312     0  stevel 	{ 0, 0, 0, 0 },
    313     0  stevel 	{ 0, 0, 0, 0 },
    314     0  stevel 	{ 0, 0, 0, 0 },
    315     0  stevel 
    316     0  stevel 	/* 0x70 */
    317     0  stevel 	{ "tcon", 0, 0, 0 },
    318     0  stevel 	{
    319     0  stevel 		"tdis", 0,
    320     0  stevel 		/* [X/Open-SMB, Sec. 6.3] */
    321     0  stevel 		"wByteCount\0\0",
    322     0  stevel 		"wByteCount\0\0"
    323     0  stevel 	},
    324     0  stevel 	{ "negprot", interpret_negprot, 0, 0 },
    325     0  stevel 	{ "sesssetupX", interpret_sesssetupX, 0, 0 },
    326     0  stevel 	{
    327     0  stevel 		"uloggoffX", 0,
    328     0  stevel 		/* [X/Open-SMB, Sec. 15.5] */
    329     0  stevel 		"wChainedCommand\0wNextOffset\0\0",
    330     0  stevel 		"wChainedCommnad\0wNextOffset\0\0" },
    331     0  stevel 	{ "tconX", interpret_tconX, 0, 0 },
    332     0  stevel 	{ 0, 0, 0, 0 },
    333     0  stevel 	{ 0, 0, 0, 0 },
    334     0  stevel 	{ 0, 0, 0, 0 },
    335     0  stevel 	{ 0, 0, 0, 0 },
    336     0  stevel 	{ 0, 0, 0, 0 },
    337     0  stevel 	{ 0, 0, 0, 0 },
    338     0  stevel 	{ 0, 0, 0, 0 },
    339     0  stevel 	{ 0, 0, 0, 0 },
    340     0  stevel 	{ 0, 0, 0, 0 },
    341     0  stevel 	{ 0, 0, 0, 0 },
    342     0  stevel 
    343     0  stevel 	/* 0x80 */
    344     0  stevel 	{ "dskattr", 0, 0, 0 },
    345     0  stevel 	{ "search", 0, 0, 0 },
    346     0  stevel 	{ "ffirst", 0, 0, 0 },
    347     0  stevel 	{ "funique", 0, 0, 0 },
    348     0  stevel 	{ "fclose", 0, 0, 0 },
    349     0  stevel 	{ 0, 0, 0, 0 },
    350     0  stevel 	{ 0, 0, 0, 0 },
    351     0  stevel 	{ 0, 0, 0, 0 },
    352     0  stevel 	{ 0, 0, 0, 0 },
    353     0  stevel 	{ 0, 0, 0, 0 },
    354     0  stevel 	{ 0, 0, 0, 0 },
    355     0  stevel 	{ 0, 0, 0, 0 },
    356     0  stevel 	{ 0, 0, 0, 0 },
    357     0  stevel 	{ 0, 0, 0, 0 },
    358     0  stevel 	{ 0, 0, 0, 0 },
    359     0  stevel 	{ 0, 0, 0, 0 },
    360     0  stevel 
    361     0  stevel 	/* 0x90 */
    362     0  stevel 	{ 0, 0, 0, 0 },
    363     0  stevel 	{ 0, 0, 0, 0 },
    364     0  stevel 	{ 0, 0, 0, 0 },
    365     0  stevel 	{ 0, 0, 0, 0 },
    366     0  stevel 	{ 0, 0, 0, 0 },
    367     0  stevel 	{ 0, 0, 0, 0 },
    368     0  stevel 	{ 0, 0, 0, 0 },
    369     0  stevel 	{ 0, 0, 0, 0 },
    370     0  stevel 	{ 0, 0, 0, 0 },
    371     0  stevel 	{ 0, 0, 0, 0 },
    372     0  stevel 	{ 0, 0, 0, 0 },
    373     0  stevel 	{ 0, 0, 0, 0 },
    374     0  stevel 	{ 0, 0, 0, 0 },
    375     0  stevel 	{ 0, 0, 0, 0 },
    376     0  stevel 	{ 0, 0, 0, 0 },
    377     0  stevel 	{ 0, 0, 0, 0 },
    378     0  stevel 
    379     0  stevel 	/* 0xa0 */
    380     0  stevel 	/*
    381     0  stevel 	 * Command codes 0xa0 to 0xa7 are from
    382     0  stevel 	 * [CIFS/1.0, Sec. 5.1]
    383     0  stevel 	 */
    384     0  stevel 	{ " NT_Trans", 0, 0, 0 },
    385     0  stevel 	{ " NT_Trans2", 0, 0, 0 },
    386     0  stevel 	{
    387     0  stevel 		" NT_CreateX", 0,
    388     0  stevel 		/* [CIFS/1.0, Sec. 4.2.1] */
    389     0  stevel 		"wChainedCommand\0wNextOffset\0r\0"
    390     0  stevel 		"wNameLength\0lCreateFlags\0lRootDirFID\0"
    391     0  stevel 		"lDesiredAccess\0R\0R\0R\0R\0"
    392     0  stevel 		"lNTFileAttributes\0lFileShareAccess\0"
    393     0  stevel 		"R\0R\0lCreateOption\0lImpersonationLevel\0"
    394     0  stevel 		"bSecurityFlags\0wByteCount\0r\0"
    395     0  stevel 		"UFileName\0\0",
    396     0  stevel 		"wChainedCommand\0wNextOffset\0"
    397     0  stevel 		"bOplockLevel\0WFileID\0lCreateAction\0\0"
    398     0  stevel 	},
    399     0  stevel 	{ 0, 0, 0, 0 },
    400     0  stevel 	{
    401     0  stevel 		" NT_Cancel", 0,
    402     0  stevel 		/* [CIFS/1.0, Sec. 4.1.8] */
    403     0  stevel 		"wByteCount\0", 0
    404     0  stevel 	},
    405     0  stevel 	{ 0, 0, 0, 0 },
    406     0  stevel 	{ 0, 0, 0, 0 },
    407     0  stevel 	{ 0, 0, 0, 0 },
    408     0  stevel 	{ 0, 0, 0, 0 },
    409     0  stevel 	{ 0, 0, 0, 0 },
    410     0  stevel 	{ 0, 0, 0, 0 },
    411     0  stevel 	{ 0, 0, 0, 0 },
    412     0  stevel 	{ 0, 0, 0, 0 },
    413     0  stevel 	{ 0, 0, 0, 0 },
    414     0  stevel 	{ 0, 0, 0, 0 },
    415     0  stevel 	{ 0, 0, 0, 0 },
    416     0  stevel 
    417     0  stevel 	/* 0xb0 */
    418     0  stevel 	{ 0, 0, 0, 0 },
    419     0  stevel 	{ 0, 0, 0, 0 },
    420     0  stevel 	{ 0, 0, 0, 0 },
    421     0  stevel 	{ 0, 0, 0, 0 },
    422     0  stevel 	{ 0, 0, 0, 0 },
    423     0  stevel 	{ 0, 0, 0, 0 },
    424     0  stevel 	{ 0, 0, 0, 0 },
    425     0  stevel 	{ 0, 0, 0, 0 },
    426     0  stevel 	{ 0, 0, 0, 0 },
    427     0  stevel 	{ 0, 0, 0, 0 },
    428     0  stevel 	{ 0, 0, 0, 0 },
    429     0  stevel 	{ 0, 0, 0, 0 },
    430     0  stevel 	{ 0, 0, 0, 0 },
    431     0  stevel 	{ 0, 0, 0, 0 },
    432     0  stevel 	{ 0, 0, 0, 0 },
    433     0  stevel 	{ 0, 0, 0, 0 },
    434     0  stevel 
    435     0  stevel 	/* 0xc0 */
    436     0  stevel 	{ "splopen", 0, 0, 0 },
    437     0  stevel 	{ "splwr", 0, 0, 0 },
    438     0  stevel 	{ "splclose", 0, 0, 0 },
    439     0  stevel 	{ "splretq", 0, 0, 0 },
    440     0  stevel 	{ 0, 0, 0, 0 },
    441     0  stevel 	{ 0, 0, 0, 0 },
    442     0  stevel 	{ 0, 0, 0, 0 },
    443     0  stevel 	{ 0, 0, 0, 0 },
    444     0  stevel 	{ 0, 0, 0, 0 },
    445     0  stevel 	{ 0, 0, 0, 0 },
    446     0  stevel 	{ 0, 0, 0, 0 },
    447     0  stevel 	{ 0, 0, 0, 0 },
    448     0  stevel 	{ 0, 0, 0, 0 },
    449     0  stevel 	{ 0, 0, 0, 0 },
    450     0  stevel 	{ 0, 0, 0, 0 },
    451     0  stevel 	{ 0, 0, 0, 0 },
    452     0  stevel 
    453     0  stevel 	/* 0xd0 */
    454     0  stevel 	{ "sends", 0, 0, 0 },
    455     0  stevel 	{ "sendb", 0, 0, 0 },
    456     0  stevel 	{ "fwdname", 0, 0, 0 },
    457     0  stevel 	{ "cancelf", 0, 0, 0 },
    458     0  stevel 	{ "getmac", 0, 0, 0 },
    459     0  stevel 	{ "sendstrt", 0, 0, 0 },
    460     0  stevel 	{ "sendend", 0, 0, 0 },
    461     0  stevel 	{ "sendtxt", 0, 0, 0 },
    462     0  stevel 	{ 0, 0, 0, 0 },
    463     0  stevel 	{ 0, 0, 0, 0 },
    464     0  stevel 	{ 0, 0, 0, 0 },
    465     0  stevel 	{ 0, 0, 0, 0 },
    466     0  stevel 	{ 0, 0, 0, 0 },
    467     0  stevel 	{ 0, 0, 0, 0 },
    468     0  stevel 	{ 0, 0, 0, 0 },
    469     0  stevel 	{ 0, 0, 0, 0 },
    470     0  stevel 
    471     0  stevel 	/* 0xe0 */
    472     0  stevel 	{ 0, 0, 0, 0 },
    473     0  stevel 	{ 0, 0, 0, 0 },
    474     0  stevel 	{ 0, 0, 0, 0 },
    475     0  stevel 	{ 0, 0, 0, 0 },
    476     0  stevel 	{ 0, 0, 0, 0 },
    477     0  stevel 	{ 0, 0, 0, 0 },
    478     0  stevel 	{ 0, 0, 0, 0 },
    479     0  stevel 	{ 0, 0, 0, 0 },
    480     0  stevel 	{ 0, 0, 0, 0 },
    481     0  stevel 	{ 0, 0, 0, 0 },
    482     0  stevel 	{ 0, 0, 0, 0 },
    483     0  stevel 	{ 0, 0, 0, 0 },
    484     0  stevel 	{ 0, 0, 0, 0 },
    485     0  stevel 	{ 0, 0, 0, 0 },
    486     0  stevel 	{ 0, 0, 0, 0 },
    487     0  stevel 	{ 0, 0, 0, 0 },
    488     0  stevel 
    489     0  stevel 	/* 0xf0 */
    490     0  stevel 	{ 0, 0, 0, 0 },
    491     0  stevel 	{ 0, 0, 0, 0 },
    492     0  stevel 	{ 0, 0, 0, 0 },
    493     0  stevel 	{ 0, 0, 0, 0 },
    494     0  stevel 	{ 0, 0, 0, 0 },
    495     0  stevel 	{ 0, 0, 0, 0 },
    496     0  stevel 	{ 0, 0, 0, 0 },
    497     0  stevel 	{ 0, 0, 0, 0 },
    498     0  stevel 	{ 0, 0, 0, 0 },
    499     0  stevel 	{ 0, 0, 0, 0 },
    500     0  stevel 	{ 0, 0, 0, 0 },
    501     0  stevel 	{ 0, 0, 0, 0 },
    502     0  stevel 	{ 0, 0, 0, 0 },
    503     0  stevel 	{ 0, 0, 0, 0 },
    504     0  stevel 	{ 0, 0, 0, 0 },
    505     0  stevel 	{ 0, 0, 0, 0 }
    506     0  stevel };
    507     0  stevel 
    508     0  stevel /* Helpers to get short and int values in Intel order. */
    509     0  stevel static ushort_t
    510     0  stevel get2(uchar_t *p) {
    511     0  stevel 	return (p[0] + (p[1]<<8));
    512     0  stevel }
    513     0  stevel static uint_t
    514     0  stevel get4(uchar_t *p) {
    515     0  stevel 	return (p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24));
    516     0  stevel }
    517     0  stevel 
    518     0  stevel /*
    519     0  stevel  * This is called by snoop_netbios.c.
    520     0  stevel  * This is the external entry point.
    521     0  stevel  */
    522     0  stevel void
    523     0  stevel interpret_smb(int flags, uchar_t *data, int len)
    524     0  stevel {
    525     0  stevel 	struct smb *smb;
    526     0  stevel 	char *call_reply_detail, *call_reply_sum;
    527     0  stevel 	struct decode *decoder;
    528     0  stevel 	char xtra[300];
    529     0  stevel 	char *line;
    530     0  stevel 
    531     0  stevel 	smb = (struct smb *)data;
    532     0  stevel 	decoder = &SMBtable[smb->com & 255];
    533     0  stevel 	if (smb->flags & SERVER_RESPONSE) {
    534     0  stevel 		call_reply_detail = "SERVER RESPONSE";
    535     0  stevel 		call_reply_sum = "R";
    536     0  stevel 	} else {
    537     0  stevel 		call_reply_detail =	"CLIENT REQUEST";
    538     0  stevel 		call_reply_sum = "C";
    539     0  stevel 	}
    540     0  stevel 	xtra[0] = '\0';
    541     0  stevel 
    542     0  stevel 	/*
    543     0  stevel 	 * SMB Header description
    544     0  stevel 	 * [X/Open-SMB, Sec. 5.1]
    545     0  stevel 	 */
    546     0  stevel 	if (flags & F_DTAIL) {
    547     0  stevel 		show_header("SMB:  ", "SMB Header", len);
    548     0  stevel 		show_space();
    549     0  stevel 		sprintf(GETLINE, "%s", call_reply_detail);
    550     0  stevel 
    551     0  stevel 		(void) sprintf(GETLINE, "Command code = 0x%x",
    552     0  stevel 				smb->com);
    553     0  stevel 		if (decoder->name)
    554     0  stevel 			(void) sprintf(GETLINE,
    555     0  stevel 				"Command name =  SMB%s", decoder->name);
    556     0  stevel 
    557     0  stevel 		show_space();
    558     0  stevel 		sprintf(GETLINE, "SMB Status:");
    559     0  stevel 
    560     0  stevel 		/* Error classes [X/Open-SMB, Sec. 5.6] */
    561     0  stevel 		switch (smb->rcls) {
    562     0  stevel 		case 0x00:
    563     0  stevel 			sprintf(GETLINE,
    564     0  stevel 				"   - Error class = No error");
    565     0  stevel 			break;
    566     0  stevel 		case 0x01:
    567     0  stevel 			sprintf(GETLINE,
    568     0  stevel 				"   - Error class = Operating System");
    569     0  stevel 			break;
    570     0  stevel 		case 0x02:
    571     0  stevel 			sprintf(GETLINE,
    572     0  stevel 				"   - Error class = LMX server");
    573     0  stevel 			break;
    574     0  stevel 		case 0x03:
    575     0  stevel 			sprintf(GETLINE,
    576     0  stevel 				"   - Error class = Hardware");
    577     0  stevel 			break;
    578     0  stevel 		case 0xff:
    579     0  stevel 		default:
    580     0  stevel 			sprintf(GETLINE,
    581     0  stevel 				"   - Error class = Incorrect format.");
    582     0  stevel 			break;
    583     0  stevel 		}
    584     0  stevel 
    585     0  stevel 		if (smb->err[0] != 0x00) {
    586     0  stevel 			sprintf(GETLINE,
    587     0  stevel 				"   - Error code = %x", smb->err[0]);
    588     0  stevel 		} else
    589     0  stevel 			sprintf(GETLINE, "   - Error code = No error");
    590     0  stevel 
    591     0  stevel 		show_space();
    592     0  stevel 
    593     0  stevel 		sprintf(GETLINE, "Header:");
    594     0  stevel 		sprintf(GETLINE, "   - Tree ID      (TID) = 0x%.4x",
    595     0  stevel 			get2(smb->tid));
    596     0  stevel 		sprintf(GETLINE, "   - Process ID   (PID) = 0x%.4x",
    597     0  stevel 			get2(smb->pid));
    598     0  stevel 		sprintf(GETLINE, "   - User ID      (UID) = 0x%.4x",
    599     0  stevel 			get2(smb->uid));
    600     0  stevel 		sprintf(GETLINE, "   - Multiplex ID (MID) = 0x%.4x",
    601     0  stevel 			get2(smb->mid));
    602     0  stevel 		sprintf(GETLINE, "   - Flags summary = 0x%.2x",
    603     0  stevel 					smb->flags);
    604     0  stevel 		sprintf(GETLINE, "   - Flags2 summary = 0x%.4x",
    605     0  stevel 					get2(smb->flags2));
    606     0  stevel 		show_space();
    607     0  stevel 	}
    608     0  stevel 
    609     0  stevel 	if (decoder->func)
    610     0  stevel 		(decoder->func)(flags, (uchar_t *)data, len, xtra);
    611     0  stevel 	else
    612     0  stevel 		interpret_default(flags, (uchar_t *)data, len, xtra);
    613     0  stevel 
    614     0  stevel 	if (flags & F_SUM) {
    615     0  stevel 		line = get_sum_line();
    616     0  stevel 		if (decoder->name)
    617     0  stevel 			sprintf(line,
    618     0  stevel 			"SMB %s Code=0x%x Name=SMB%s %sError=%x ",
    619     0  stevel 			call_reply_sum, smb->com, decoder->name, xtra,
    620     0  stevel 			smb->err[0]);
    621     0  stevel 
    622     0  stevel 		else sprintf(line, "SMB %s Code=0x%x Error=%x ",
    623     0  stevel 					call_reply_sum, smb->com, smb->err[0]);
    624     0  stevel 
    625     0  stevel 		line += strlen(line);
    626     0  stevel 	}
    627     0  stevel 
    628     0  stevel 	if (flags & F_DTAIL)
    629     0  stevel 		show_trailer();
    630     0  stevel }
    631     0  stevel 
    632     0  stevel static void
    633     0  stevel output_bytes(uchar_t *data, int bytecount)
    634     0  stevel {
    635     0  stevel 	int i;
    636     0  stevel 	char buff[80];
    637     0  stevel 	char word[10];
    638     0  stevel 
    639     0  stevel 	buff[0] = word[0] = '\0';
    640     0  stevel 	sprintf(GETLINE, "Byte values (in hex):");
    641     0  stevel 	for (i = 0; i < bytecount; i++) {
    642     0  stevel 		sprintf(word, "%.2x ", data[i]);
    643     0  stevel 		strcat(buff, word);
    644     0  stevel 		if ((i+1)%16 == 0 || i == (bytecount-1)) {
    645     0  stevel 			sprintf(GETLINE, "%s", buff);
    646     0  stevel 			strcpy(buff, "");
    647     0  stevel 		}
    648     0  stevel 	}
    649     0  stevel }
    650     0  stevel 
    651     0  stevel /*
    652     0  stevel  * Based on the Unicode Standard,  http://www.unicode.org/
    653     0  stevel  * "The Unicode Standard: A Technical Introduction", June 1998
    654     0  stevel  */
    655     0  stevel static int
    656     0  stevel unicode2ascii(char *outstr, int outlen, uchar_t *instr, int inlen)
    657     0  stevel {
    658     0  stevel 	int i = 0, j = 0;
    659     0  stevel 	char c;
    660     0  stevel 
    661     0  stevel 	while (i < inlen && j < (outlen-1)) {
    662     0  stevel 		/* Show unicode chars >= 256 as '?' */
    663     0  stevel 		if (instr[i+1])
    664     0  stevel 			c = '?';
    665     0  stevel 		else
    666     0  stevel 			c = instr[i];
    667     0  stevel 		if (c == '\0')
    668     0  stevel 			break;
    669     0  stevel 		outstr[j] = c;
    670     0  stevel 		i += 2;
    671     0  stevel 		j++;
    672     0  stevel 	}
    673     0  stevel 	outstr[j] = '\0';
    674     0  stevel 	return (j);
    675     0  stevel }
    676     0  stevel 
    677     0  stevel /*
    678     0  stevel  * TRANS2 information levels
    679     0  stevel  * [X/Open-SMB, Sec. 16.1.6]
    680     0  stevel  */
    681     0  stevel static void
    682     0  stevel get_info_level(char *outstr, int value)
    683     0  stevel {
    684     0  stevel 
    685     0  stevel 	switch (value) {
    686     0  stevel 	case 1:
    687     0  stevel 		sprintf(outstr, "Standard"); break;
    688     0  stevel 	case 2:
    689     0  stevel 		sprintf(outstr, "Query EA Size"); break;
    690     0  stevel 	case 3:
    691     0  stevel 		sprintf(outstr, "Query EAS from List"); break;
    692     0  stevel 	case 0x101:
    693     0  stevel 		sprintf(outstr, "Directory Info"); break;
    694     0  stevel 	case 0x102:
    695     0  stevel 		sprintf(outstr, "Full Directory Info"); break;
    696     0  stevel 	case 0x103:
    697     0  stevel 		sprintf(outstr, "Names Info"); break;
    698     0  stevel 	case 0x104:
    699     0  stevel 		sprintf(outstr, "Both Directory Info"); break;
    700     0  stevel 	default:
    701     0  stevel 		sprintf(outstr, "Unknown"); break;
    702     0  stevel 	}
    703     0  stevel }
    704     0  stevel 
    705     0  stevel /*
    706     0  stevel  * Interpret TRANS2_QUERY_PATH subcommand
    707     0  stevel  * [X/Open-SMB, Sec. 16.7]
    708     0  stevel  */
    709     0  stevel /* ARGSUSED */
    710     0  stevel static void
    711     0  stevel output_trans2_querypath(int flags, uchar_t *data, char *xtra)
    712     0  stevel {
    713     0  stevel 	int length;
    714     0  stevel 	char filename[256];
    715     0  stevel 
    716     0  stevel 	if (flags & F_SUM) {
    717     0  stevel 		length = sprintf(xtra, "QueryPathInfo ");
    718     0  stevel 		xtra += length;
    719     0  stevel 		data += 6;
    720     0  stevel 		(void) unicode2ascii(filename, 256, data, 512);
    721     0  stevel 		sprintf(xtra, "File=%s ", filename);
    722     0  stevel 	}
    723     0  stevel 
    724     0  stevel 	if (flags & F_DTAIL) {
    725     0  stevel 		sprintf(GETLINE, "FunctionName = QueryPathInfo");
    726     0  stevel 		sprintf(GETLINE, "InfoLevel = 0x%.4x",
    727     0  stevel 			get2(data));
    728     0  stevel 		data += 6;
    729     0  stevel 		(void) unicode2ascii(filename, 256, data, 512);
    730     0  stevel 		sprintf(GETLINE, "FileName = %s",
    731     0  stevel 			filename);
    732     0  stevel 	}
    733     0  stevel }
    734     0  stevel 
    735     0  stevel /*
    736     0  stevel  * Interpret TRANS2_QUERY_FILE subcommand
    737     0  stevel  * [X/Open-SMB, Sec. 16.9]
    738     0  stevel  */
    739     0  stevel /* ARGSUSED */
    740     0  stevel static void
    741     0  stevel output_trans2_queryfile(int flags, uchar_t *data, char *xtra)
    742     0  stevel {
    743     0  stevel 	int length;
    744     0  stevel 
    745     0  stevel 	if (flags & F_SUM) {
    746     0  stevel 		length = sprintf(xtra, "QueryFileInfo ");
    747     0  stevel 		xtra += length;
    748     0  stevel 		sprintf(xtra, "FileID=0x%x ", get2(data));
    749     0  stevel 	}
    750     0  stevel 
    751     0  stevel 	if (flags & F_DTAIL) {
    752     0  stevel 		sprintf(GETLINE, "FunctionName = QueryFileInfo");
    753     0  stevel 		sprintf(GETLINE, "FileID = 0x%.4x",
    754     0  stevel 			get2(data));
    755     0  stevel 		data += 2;
    756     0  stevel 		sprintf(GETLINE, "InfoLevel = 0x%.4x",
    757     0  stevel 			get2(data));
    758     0  stevel 	}
    759     0  stevel }
    760     0  stevel 
    761     0  stevel /*
    762     0  stevel  * Interpret TRANS2_SET_FILE subcommand
    763     0  stevel  * [X/Open-SMB, Sec. 16.10]
    764     0  stevel  */
    765     0  stevel /* ARGSUSED */
    766     0  stevel static void
    767     0  stevel output_trans2_setfile(int flags, uchar_t *data, char *xtra)
    768     0  stevel {
    769     0  stevel 	int length;
    770     0  stevel 
    771     0  stevel 	if (flags & F_SUM) {
    772     0  stevel 		length = sprintf(xtra, "SetFileInfo ");
    773     0  stevel 		xtra += length;
    774     0  stevel 		sprintf(xtra, "FileID=0x%x ", get2(data));
    775     0  stevel 	}
    776     0  stevel 
    777     0  stevel 	if (flags & F_DTAIL) {
    778     0  stevel 		sprintf(GETLINE, "FunctionName = SetFileInfo");
    779     0  stevel 		sprintf(GETLINE, "FileID = 0x%.4x",
    780     0  stevel 			get2(data));
    781     0  stevel 		data += 2;
    782     0  stevel 		sprintf(GETLINE, "InfoLevel = 0x%.4x",
    783     0  stevel 			get2(data));
    784     0  stevel 	}
    785     0  stevel }
    786     0  stevel 
    787     0  stevel /*
    788     0  stevel  * Interpret TRANS2_FIND_FIRST subcommand
    789     0  stevel  * [X/Open-SMB, Sec. 16.3]
    790     0  stevel  */
    791     0  stevel /* ARGSUSED */
    792     0  stevel static void
    793     0  stevel output_trans2_findfirst(int flags, uchar_t *data, char *xtra)
    794     0  stevel {
    795     0  stevel 	int length;
    796     0  stevel 	char filename[256];
    797     0  stevel 	char infolevel[100];
    798     0  stevel 
    799     0  stevel 	if (flags & F_SUM) {
    800     0  stevel 		length = sprintf(xtra, "Findfirst ");
    801     0  stevel 		xtra += length;
    802     0  stevel 		data += 12;
    803     0  stevel 		(void) unicode2ascii(filename, 256, data, 512);
    804     0  stevel 		sprintf(xtra, "File=%s ", filename);
    805     0  stevel 	}
    806     0  stevel 
    807     0  stevel 	if (flags & F_DTAIL) {
    808     0  stevel 		sprintf(GETLINE, "FunctionName = Findfirst");
    809     0  stevel 		sprintf(GETLINE, "SearchAttributes = 0x%.4x",
    810     0  stevel 			get2(data));
    811     0  stevel 		data += 2;
    812     0  stevel 		sprintf(GETLINE, "FindCount = 0x%.4x",
    813     0  stevel 			get2(data));
    814     0  stevel 		data += 2;
    815     0  stevel 		sprintf(GETLINE, "FindFlags = 0x%.4x",
    816     0  stevel 			get2(data));
    817     0  stevel 		data += 2;
    818     0  stevel 		get_info_level(infolevel, get2(data));
    819     0  stevel 		sprintf(GETLINE, "InfoLevel = %s",
    820     0  stevel 			infolevel);
    821     0  stevel 		data += 6;
    822     0  stevel 		(void) unicode2ascii(filename, 256, data, 512);
    823     0  stevel 		sprintf(GETLINE, "FileName = %s",
    824     0  stevel 			filename);
    825     0  stevel 	}
    826     0  stevel }
    827     0  stevel 
    828     0  stevel 
    829     0  stevel /*
    830     0  stevel  * Interpret TRANS2_FIND_NEXT subcommand
    831     0  stevel  * [X/Open-SMB, Sec. 16.4]
    832     0  stevel  */
    833     0  stevel /* ARGSUSED */
    834     0  stevel static void
    835     0  stevel output_trans2_findnext(int flags, uchar_t *data, char *xtra)
    836     0  stevel {
    837     0  stevel 	int length;
    838     0  stevel 	char filename[256];
    839     0  stevel 	char infolevel[100];
    840     0  stevel 
    841     0  stevel 	if (flags & F_SUM) {
    842     0  stevel 		length = sprintf(xtra, "Findnext ");
    843     0  stevel 		xtra += length;
    844     0  stevel 		data += 12;
    845     0  stevel 		(void) unicode2ascii(filename, 256, data, 512);
    846     0  stevel 		sprintf(xtra, "File=%s ", filename);
    847     0  stevel 	}
    848     0  stevel 
    849     0  stevel 	if (flags & F_DTAIL) {
    850     0  stevel 		sprintf(GETLINE, "FunctionName = Findnext");
    851     0  stevel 		sprintf(GETLINE, "FileID = 0x%.4x",
    852     0  stevel 			get2(data));
    853     0  stevel 		data += 2;
    854     0  stevel 		sprintf(GETLINE, "FindCount = 0x%.4x",
    855     0  stevel 			get2(data));
    856     0  stevel 		data += 2;
    857     0  stevel 		get_info_level(infolevel, get2(data));
    858     0  stevel 		sprintf(GETLINE, "InfoLevel = %s",
    859     0  stevel 			infolevel);
    860     0  stevel 		data += 2;
    861     0  stevel 		sprintf(GETLINE, "FindKey = 0x%.8x",
    862     0  stevel 			get4(data));
    863     0  stevel 		data += 4;
    864     0  stevel 		sprintf(GETLINE, "FindFlags = 0x%.4x",
    865     0  stevel 			get2(data));
    866     0  stevel 		data += 2;
    867     0  stevel 		(void) unicode2ascii(filename, 256, data, 512);
    868     0  stevel 		sprintf(GETLINE, "FileName = %s",
    869     0  stevel 			filename);
    870     0  stevel 	}
    871     0  stevel }
    872     0  stevel 
    873     0  stevel /*
    874     0  stevel  * Interpret a "Negprot" SMB
    875     0  stevel  * [X/Open-SMB, Sec. 6.1]
    876     0  stevel  */
    877     0  stevel /* ARGSUSED */
    878     0  stevel static void
    879     0  stevel interpret_negprot(int flags, uchar_t *data, int len, char *xtra)
    880     0  stevel {
    881     0  stevel 	int length;
    882     0  stevel 	int bytecount;
    883     0  stevel 	char dialect[256];
    884     0  stevel 	struct smb *smbdata;
    885     0  stevel 	uchar_t *protodata;
    886     0  stevel 
    887     0  stevel 	smbdata  = (struct smb *)data;
    888     0  stevel 	protodata = (uchar_t *)data + sizeof (struct smb);
    889     0  stevel 	protodata++;			/* skip wordcount */
    890     0  stevel 
    891     0  stevel 	if (smbdata->flags & SERVER_RESPONSE) {
    892     0  stevel 		if (flags & F_SUM) {
    893     0  stevel 			sprintf(xtra, "Dialect#=%d ", protodata[0]);
    894     0  stevel 		}
    895     0  stevel 		if (flags & F_DTAIL) {
    896     0  stevel 			sprintf(GETLINE, "Protocol Index = %d",
    897     0  stevel 					protodata[0]);
    898     0  stevel 		}
    899     0  stevel 	} else {
    900     0  stevel 		/*
    901     0  stevel 		 * request packet:
    902     0  stevel 		 * short bytecount;
    903     0  stevel 		 * struct { char fmt; char name[]; } dialects
    904     0  stevel 		 */
    905     0  stevel 		bytecount = get2(protodata);
    906     0  stevel 		protodata += 2;
    907     0  stevel 		if (flags & F_SUM) {
    908     0  stevel 			while (bytecount > 1) {
    909  7280     blu 				length = snprintf(dialect, sizeof (dialect),
    910  7280     blu 				    "%s", (char *)protodata+1);
    911     0  stevel 				protodata += (length+2);
    912  7280     blu 				if (protodata >= data+len)
    913  7280     blu 					break;
    914     0  stevel 				bytecount -= (length+2);
    915     0  stevel 			}
    916     0  stevel 			sprintf(xtra, "LastDialect=%s ", dialect);
    917     0  stevel 		}
    918     0  stevel 		if (flags & F_DTAIL) {
    919     0  stevel 			sprintf(GETLINE, "ByteCount = %d", bytecount);
    920     0  stevel 			while (bytecount > 1) {
    921  7280     blu 				length = snprintf(dialect, sizeof (dialect),
    922  7280     blu 				    "%s", (char *)protodata+1);
    923     0  stevel 				sprintf(GETLINE, "Dialect String = %s",
    924  7280     blu 				    dialect);
    925     0  stevel 				protodata += (length+2);
    926  7280     blu 				if (protodata >= data+len)
    927  7280     blu 					break;
    928     0  stevel 				bytecount -= (length+2);
    929     0  stevel 			}
    930     0  stevel 		}
    931     0  stevel 	}
    932     0  stevel }
    933     0  stevel 
    934     0  stevel /*
    935     0  stevel  * LAN Manager remote admin function names.
    936     0  stevel  * [X/Open-SMB, Appendix B.8]
    937     0  stevel  */
    938     0  stevel static const char *apinames[] = {
    939     0  stevel 	"RNetShareEnum",
    940     0  stevel 	"RNetShareGetInfo",
    941     0  stevel 	"NetShareSetInfo",
    942     0  stevel 	"NetShareAdd",
    943     0  stevel 	"NetShareDel",
    944     0  stevel 	"NetShareCheck",
    945     0  stevel 	"NetSessionEnum",
    946     0  stevel 	"NetSessionGetInfo",
    947     0  stevel 	"NetSessionDel",
    948     0  stevel 	"NetConnectionEnum",
    949     0  stevel 	"NetFileEnum",
    950     0  stevel 	"NetFileGetInfo",
    951     0  stevel 	"NetFileClose",
    952     0  stevel 	"RNetServerGetInfo",
    953     0  stevel 	"NetServerSetInfo",
    954     0  stevel 	"NetServerDiskEnum",
    955     0  stevel 	"NetServerAdminCommand",
    956     0  stevel 	"NetAuditOpen",
    957     0  stevel 	"NetAuditClear",
    958     0  stevel 	"NetErrorLogOpen",
    959     0  stevel 	"NetErrorLogClear",
    960     0  stevel 	"NetCharDevEnum",
    961     0  stevel 	"NetCharDevGetInfo",
    962     0  stevel 	"NetCharDevControl",
    963     0  stevel 	"NetCharDevQEnum",
    964     0  stevel 	"NetCharDevQGetInfo",
    965     0  stevel 	"NetCharDevQSetInfo",
    966     0  stevel 	"NetCharDevQPurge",
    967     0  stevel 	"RNetCharDevQPurgeSelf",
    968     0  stevel 	"NetMessageNameEnum",
    969     0  stevel 	"NetMessageNameGetInfo",
    970     0  stevel 	"NetMessageNameAdd",
    971     0  stevel 	"NetMessageNameDel",
    972     0  stevel 	"NetMessageNameFwd",
    973     0  stevel 	"NetMessageNameUnFwd",
    974     0  stevel 	"NetMessageBufferSend",
    975     0  stevel 	"NetMessageFileSend",
    976     0  stevel 	"NetMessageLogFileSet",
    977     0  stevel 	"NetMessageLogFileGet",
    978     0  stevel 	"NetServiceEnum",
    979     0  stevel 	"RNetServiceInstall",
    980     0  stevel 	"RNetServiceControl",
    981     0  stevel 	"RNetAccessEnum",
    982     0  stevel 	"RNetAccessGetInfo",
    983     0  stevel 	"RNetAccessSetInfo",
    984     0  stevel 	"RNetAccessAdd",
    985     0  stevel 	"RNetAccessDel",
    986     0  stevel 	"NetGroupEnum",
    987     0  stevel 	"NetGroupAdd",
    988     0  stevel 	"NetGroupDel",
    989     0  stevel 	"NetGroupAddUser",
    990     0  stevel 	"NetGroupDelUser",
    991     0  stevel 	"NetGroupGetUsers",
    992     0  stevel 	"NetUserEnum",
    993     0  stevel 	"RNetUserAdd",
    994     0  stevel 	"NetUserDel",
    995     0  stevel 	"NetUserGetInfo",
    996     0  stevel 	"RNetUserSetInfo",
    997     0  stevel 	"RNetUserPasswordSet",
    998     0  stevel 	"NetUserGetGroups",
    999     0  stevel 	"NetWkstaLogon",
   1000     0  stevel 	"NetWkstaLogoff",
   1001     0  stevel 	"NetWkstaSetUID",
   1002     0  stevel 	"NetWkstaGetInfo",
   1003     0  stevel 	"NetWkstaSetInfo",
   1004     0  stevel 	"NetUseEnum",
   1005     0  stevel 	"NetUseAdd",
   1006     0  stevel 	"NetUseDel",
   1007     0  stevel 	"NetUseGetInfo",
   1008     0  stevel 	"DosPrintQEnum",
   1009     0  stevel 	"DosPrintQGetInfo",
   1010     0  stevel 	"DosPrintQSetInfo",
   1011     0  stevel 	"DosPrintQAdd",
   1012     0  stevel 	"DosPrintQDel",
   1013     0  stevel 	"DosPrintQPause",
   1014     0  stevel 	"DosPrintQContinue",
   1015     0  stevel 	"DosPrintJobEnum",
   1016     0  stevel 	"DosPrintJobGetInfo",
   1017     0  stevel 	"RDosPrintJobSetInfo",
   1018     0  stevel 	"DosPrintJobAdd",
   1019     0  stevel 	"DosPrintJobSchedule",
   1020     0  stevel 	"RDosPrintJobDel",
   1021     0  stevel 	"RDosPrintJobPause",
   1022     0  stevel 	"RDosPrintJobContinue",
   1023     0  stevel 	"DosPrintDestEnum",
   1024     0  stevel 	"DosPrintDestGetInfo",
   1025     0  stevel 	"DosPrintDestControl",
   1026     0  stevel 	"NetProfileSave",
   1027     0  stevel 	"NetProfileLoad",
   1028     0  stevel 	"NetStatisticsGet",
   1029     0  stevel 	"NetStatisticsClear",
   1030     0  stevel 	"NetRemoteTOD",
   1031     0  stevel 	"NetBiosEnum",
   1032     0  stevel 	"NetBiosGetInfo",
   1033     0  stevel 	"NetServerEnum",
   1034     0  stevel 	"I_NetServerEnum",
   1035     0  stevel 	"NetServiceGetInfo",
   1036     0  stevel 	"NetSplQmAbort",
   1037     0  stevel 	"NetSplQmClose",
   1038     0  stevel 	"NetSplQmEndDoc",
   1039     0  stevel 	"NetSplQmOpen",
   1040     0  stevel 	"NetSplQmStartDoc",
   1041     0  stevel 	"NetSplQmWrite",
   1042     0  stevel 	"DosPrintQPurge",
   1043     0  stevel 	"NetServerEnum2"
   1044     0  stevel };
   1045     0  stevel static const int apimax = (
   1046     0  stevel 	sizeof (apinames) /
   1047     0  stevel 	sizeof (apinames[0]));
   1048     0  stevel 
   1049     0  stevel /*
   1050     0  stevel  * Interpret a "trans" SMB
   1051     0  stevel  * [X/Open-SMB, Appendix B]
   1052     0  stevel  *
   1053     0  stevel  * This is very much like "trans2" below.
   1054     0  stevel  */
   1055     0  stevel /* ARGSUSED */
   1056     0  stevel static void
   1057     0  stevel interpret_trans(int flags, uchar_t *data, int len, char *xtra)
   1058     0  stevel {
   1059     0  stevel 	struct smb *smb;
   1060     0  stevel 	uchar_t *vwv; /* word parameters */
   1061     0  stevel 	int wordcount;
   1062     0  stevel 	uchar_t *byteparms;
   1063     0  stevel 	int bytecount;
   1064     0  stevel 	int parambytes;
   1065     0  stevel 	int paramoffset;
   1066     0  stevel 	int setupcount;
   1067     0  stevel 	int subcode;
   1068     0  stevel 	uchar_t *setupdata;
   1069     0  stevel 	uchar_t *params;
   1070     0  stevel 	int apinum;
   1071     0  stevel 	int isunicode;
   1072     0  stevel 	char filename[256];
   1073     0  stevel 
   1074     0  stevel 	smb  = (struct smb *)data;
   1075     0  stevel 	vwv = (uchar_t *)data + sizeof (struct smb);
   1076     0  stevel 	wordcount = *vwv++;
   1077     0  stevel 
   1078     0  stevel 	byteparms = vwv + (2 * wordcount);
   1079     0  stevel 	bytecount = get2(byteparms);
   1080     0  stevel 	byteparms += 2;
   1081     0  stevel 
   1082     0  stevel 	/*
   1083     0  stevel 	 * Print the lengths before we (potentially) bail out
   1084     0  stevel 	 * due to lack of data (so the user knows why we did).
   1085     0  stevel 	 */
   1086     0  stevel 	if (flags & F_DTAIL) {
   1087     0  stevel 		sprintf(GETLINE, "WordCount = %d", wordcount);
   1088     0  stevel 		sprintf(GETLINE, "ByteCount = %d", bytecount);
   1089     0  stevel 	}
   1090     0  stevel 
   1091     0  stevel 	/* Get length and location of params and setup data. */
   1092     0  stevel 	if (!(smb->flags & SERVER_RESPONSE)) {
   1093     0  stevel 		/* CALL */
   1094     0  stevel 		if (wordcount < 14)
   1095     0  stevel 			return;
   1096     0  stevel 		parambytes  = get2(vwv + (2 *  9));
   1097     0  stevel 		paramoffset = get2(vwv + (2 * 10));
   1098     0  stevel 		setupcount = *(vwv + (2 * 13));
   1099     0  stevel 		setupdata  =   vwv + (2 * 14);
   1100     0  stevel 	} else {
   1101     0  stevel 		/* REPLY */
   1102     0  stevel 		if (wordcount < 10)
   1103     0  stevel 			return;
   1104     0  stevel 		parambytes  = get2(vwv + (2 * 3));
   1105     0  stevel 		paramoffset = get2(vwv + (2 * 4));
   1106     0  stevel 		setupcount = *(vwv + (2 *  9));
   1107     0  stevel 		setupdata  =   vwv + (2 * 10);
   1108     0  stevel 	}
   1109     0  stevel 	if (setupcount > 0)
   1110     0  stevel 		subcode = get2(setupdata);
   1111     0  stevel 	else
   1112     0  stevel 		subcode = -1; /* invalid */
   1113     0  stevel 
   1114     0  stevel 	/* The parameters are offset from the SMB header. */
   1115     0  stevel 	params = data + paramoffset;
   1116     0  stevel 	if (parambytes > 0)
   1117     0  stevel 		apinum = params[0];
   1118     0  stevel 	else
   1119     0  stevel 		apinum = -1; /* invalid */
   1120     0  stevel 
   1121     0  stevel 	/* Is the pathname in unicode? */
   1122     0  stevel 	isunicode = smb->flags2[1] & 0x80;
   1123     0  stevel 
   1124     0  stevel 	if (flags & F_DTAIL && !(smb->flags & SERVER_RESPONSE)) {
   1125     0  stevel 		/* This is a CALL. */
   1126     0  stevel 		/* print the word parameters */
   1127     0  stevel 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
   1128     0  stevel 		sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
   1129     0  stevel 		sprintf(GETLINE, "MaxParamBytes = %d", get2(vwv+4));
   1130     0  stevel 		sprintf(GETLINE, "MaxDataBytes = %d", get2(vwv+6));
   1131     0  stevel 		sprintf(GETLINE, "MaxSetupWords = %d", vwv[8]);
   1132     0  stevel 		sprintf(GETLINE, "TransFlags = 0x%.4x", get2(vwv+10));
   1133     0  stevel 		sprintf(GETLINE, "Timeout = 0x%.8x", get4(vwv+12));
   1134     0  stevel 		/* skip Reserved2 */
   1135     0  stevel 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
   1136     0  stevel 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
   1137     0  stevel 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+22));
   1138     0  stevel 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+24));
   1139     0  stevel 		sprintf(GETLINE, "SetupWords = %d", setupcount);
   1140     0  stevel 
   1141     0  stevel 		/* That finishes the VWV, now the misc. stuff. */
   1142     0  stevel 		if (subcode >= 0)
   1143     0  stevel 			sprintf(GETLINE, "Setup[0] = %d", subcode);
   1144     0  stevel 		if (apinum >= 0)
   1145     0  stevel 			sprintf(GETLINE, "APIcode = %d", apinum);
   1146     0  stevel 		if (0 <= apinum && apinum < apimax)
   1147     0  stevel 			sprintf(GETLINE, "APIname = %s", apinames[apinum]);
   1148     0  stevel 
   1149     0  stevel 		/* Finally, print the byte parameters. */
   1150     0  stevel 		if (isunicode) {
   1151     0  stevel 			byteparms += 1;  /* alignment padding */
   1152     0  stevel 			(void) unicode2ascii(
   1153     0  stevel 				filename, 256, byteparms, bytecount);
   1154     0  stevel 		} else {
   1155  7280     blu 			strlcpy(filename, (char *)byteparms, sizeof (filename));
   1156     0  stevel 		}
   1157     0  stevel 		sprintf(GETLINE, "FileName = %s", filename);
   1158     0  stevel 	}
   1159     0  stevel 
   1160     0  stevel 	if (flags & F_DTAIL && smb->flags & SERVER_RESPONSE) {
   1161     0  stevel 		/* This is a REPLY. */
   1162     0  stevel 		/* print the word parameters */
   1163     0  stevel 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
   1164     0  stevel 		sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
   1165     0  stevel 		/* skip Reserved */
   1166     0  stevel 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
   1167     0  stevel 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
   1168     0  stevel 		sprintf(GETLINE, "ParamDispl. = 0x%.4x", get2(vwv+10));
   1169     0  stevel 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+12));
   1170     0  stevel 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+14));
   1171     0  stevel 		sprintf(GETLINE, "DataDispl. = 0x%.4x", get2(vwv+16));
   1172     0  stevel 		sprintf(GETLINE, "SetupWords = %d", setupcount);
   1173     0  stevel 
   1174     0  stevel 		output_bytes(byteparms, bytecount);
   1175     0  stevel 	}
   1176     0  stevel }
   1177     0  stevel 
   1178     0  stevel /*
   1179     0  stevel  * Interpret a "TconX" SMB
   1180     0  stevel  * [X/Open-SMB, Sec. 11.4]
   1181     0  stevel  */
   1182     0  stevel /* ARGSUSED */
   1183     0  stevel static void
   1184     0  stevel interpret_tconX(int flags, uchar_t *data, int len, char *xtra)
   1185     0  stevel {
   1186     0  stevel 	int length;
   1187     0  stevel 	int bytecount;
   1188     0  stevel 	int passwordlength;
   1189     0  stevel 	int wordcount;
   1190     0  stevel 	char tempstring[256];
   1191     0  stevel 	struct smb *smbdata;
   1192     0  stevel 	uchar_t *tcondata;
   1193     0  stevel 
   1194     0  stevel 	smbdata  = (struct smb *)data;
   1195     0  stevel 	tcondata = (uchar_t *)data + sizeof (struct smb);
   1196     0  stevel 	wordcount = *tcondata++;
   1197     0  stevel 
   1198     0  stevel 	if (flags & F_SUM && !(smbdata->flags & SERVER_RESPONSE)) {
   1199     0  stevel 		tcondata += 6;
   1200     0  stevel 		passwordlength = get2(tcondata);
   1201     0  stevel 		tcondata = tcondata + 4 + passwordlength;
   1202  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1203  7280     blu 		    (char *)tcondata);
   1204     0  stevel 		sprintf(xtra, "Share=%s ", tempstring);
   1205     0  stevel 	}
   1206     0  stevel 
   1207     0  stevel 	if (flags & F_SUM && smbdata->flags & SERVER_RESPONSE) {
   1208     0  stevel 		tcondata += 8;
   1209  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1210  7280     blu 		    (char *)tcondata);
   1211     0  stevel 		sprintf(xtra, "Type=%s ", tempstring);
   1212     0  stevel 	}
   1213     0  stevel 
   1214     0  stevel 	if (flags & F_DTAIL && !(smbdata->flags & SERVER_RESPONSE)) {
   1215     0  stevel 		sprintf(GETLINE, "WordCount = %d", wordcount);
   1216     0  stevel 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
   1217     0  stevel 			tcondata[0]);
   1218     0  stevel 		tcondata += 2;
   1219     0  stevel 		sprintf(GETLINE, "NextOffset = 0x%.4x",
   1220     0  stevel 			get2(tcondata));
   1221     0  stevel 		tcondata += 2;
   1222     0  stevel 		sprintf(GETLINE, "DisconnectFlag = 0x%.4x",
   1223     0  stevel 			get2(tcondata));
   1224     0  stevel 		tcondata += 2;
   1225     0  stevel 		passwordlength = get2(tcondata);
   1226     0  stevel 		sprintf(GETLINE, "PasswordLength = 0x%.4x",
   1227     0  stevel 			passwordlength);
   1228     0  stevel 		tcondata += 2;
   1229     0  stevel 		bytecount = get2(tcondata);
   1230     0  stevel 		sprintf(GETLINE, "ByteCount = %d", bytecount);
   1231     0  stevel 		tcondata = tcondata + 2 + passwordlength;
   1232  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1233  7280     blu 		    (char *)tcondata);
   1234     0  stevel 		tcondata += (length+1);
   1235     0  stevel 		sprintf(GETLINE, "FileName = %s", tempstring);
   1236  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1237  7280     blu 		    (char *)tcondata);
   1238     0  stevel 		tcondata += (length+1);
   1239     0  stevel 		sprintf(GETLINE, "ServiceName = %s", tempstring);
   1240     0  stevel 	}
   1241     0  stevel 
   1242     0  stevel 	if (flags & F_DTAIL && smbdata->flags & SERVER_RESPONSE) {
   1243     0  stevel 		sprintf(GETLINE, "WordCount = %d", wordcount);
   1244     0  stevel 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
   1245     0  stevel 			tcondata[0]);
   1246     0  stevel 		tcondata += 2;
   1247     0  stevel 		sprintf(GETLINE, "NextOffset = 0x%.4x",
   1248     0  stevel 			get2(tcondata));
   1249     0  stevel 		tcondata += 2;
   1250     0  stevel 		sprintf(GETLINE, "OptionalSupport = 0x%.4x",
   1251     0  stevel 			get2(tcondata));
   1252     0  stevel 		tcondata += 2;
   1253     0  stevel 		bytecount = get2(tcondata);
   1254     0  stevel 		sprintf(GETLINE, "ByteCount = %d", bytecount);
   1255     0  stevel 		tcondata += 2;
   1256  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1257  7280     blu 		    (char *)tcondata);
   1258     0  stevel 		tcondata += (length+1);
   1259     0  stevel 		sprintf(GETLINE, "ServiceName = %s", tempstring);
   1260  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1261  7280     blu 		    (char *)tcondata);
   1262     0  stevel 		tcondata += (length+1);
   1263     0  stevel 		sprintf(GETLINE, "NativeFS = %s", tempstring);
   1264     0  stevel 	}
   1265     0  stevel }
   1266     0  stevel 
   1267     0  stevel /*
   1268     0  stevel  * Interpret a "SesssetupX" SMB
   1269     0  stevel  * [X/Open-SMB, Sec. 11.3]
   1270     0  stevel  */
   1271     0  stevel /* ARGSUSED */
   1272     0  stevel static void
   1273     0  stevel interpret_sesssetupX(int flags, uchar_t *data, int len, char *xtra)
   1274     0  stevel {
   1275     0  stevel 	int length;
   1276     0  stevel 	int bytecount;
   1277     0  stevel 	int passwordlength;
   1278     0  stevel 	int isunicode;
   1279     0  stevel 	int upasswordlength;
   1280     0  stevel 	int wordcount;
   1281     0  stevel 	int cap;
   1282     0  stevel 	char tempstring[256];
   1283     0  stevel 	struct smb *smbdata;
   1284     0  stevel 	uchar_t *setupdata;
   1285     0  stevel 
   1286     0  stevel 	smbdata  = (struct smb *)data;
   1287     0  stevel 	setupdata = (uchar_t *)data + sizeof (struct smb);
   1288     0  stevel 	wordcount = *setupdata++;
   1289     0  stevel 
   1290     0  stevel 	isunicode = smbdata->flags2[1] & 0x80;
   1291     0  stevel 
   1292     0  stevel 	if (flags & F_SUM && !(smbdata->flags & SERVER_RESPONSE)) {
   1293     0  stevel 		if (wordcount != 13)
   1294     0  stevel 			return;
   1295     0  stevel 		setupdata += 14;
   1296     0  stevel 		passwordlength = get2(setupdata);
   1297     0  stevel 		setupdata += 2;
   1298     0  stevel 		upasswordlength = get2(setupdata);
   1299     0  stevel 		setupdata += 6;
   1300     0  stevel 		cap = get4(setupdata);
   1301     0  stevel 		setupdata = setupdata + 6 + passwordlength + upasswordlength;
   1302     0  stevel 		if (isunicode) {
   1303     0  stevel 			setupdata += 1;
   1304     0  stevel 			(void) unicode2ascii(tempstring, 256, setupdata, 256);
   1305     0  stevel 			sprintf(xtra, "Username=%s ", tempstring);
   1306     0  stevel 		} else {
   1307  7280     blu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
   1308  7280     blu 			    (char *)setupdata);
   1309     0  stevel 			sprintf(xtra, "Username=%s ", tempstring);
   1310     0  stevel 		}
   1311     0  stevel 	}
   1312     0  stevel 
   1313     0  stevel 	if (flags & F_DTAIL && !(smbdata->flags & SERVER_RESPONSE)) {
   1314     0  stevel 		if (wordcount != 13)
   1315     0  stevel 			return;
   1316     0  stevel 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
   1317     0  stevel 			setupdata[0]);
   1318     0  stevel 		setupdata += 2;
   1319     0  stevel 		sprintf(GETLINE, "NextOffset = 0x%.4x",
   1320     0  stevel 			get2(setupdata));
   1321     0  stevel 		setupdata += 2;
   1322     0  stevel 		sprintf(GETLINE, "MaxBufferSize = 0x%.4x",
   1323     0  stevel 			get2(setupdata));
   1324     0  stevel 		setupdata += 2;
   1325     0  stevel 		sprintf(GETLINE, "MaxMPXRequests = %d",
   1326     0  stevel 			get2(setupdata));
   1327     0  stevel 		setupdata += 2;
   1328     0  stevel 		sprintf(GETLINE, "VCNumber = %d",
   1329     0  stevel 			get2(setupdata));
   1330     0  stevel 		setupdata += 2;
   1331     0  stevel 		sprintf(GETLINE, "SessionKey = %d",
   1332     0  stevel 			get4(setupdata));
   1333     0  stevel 		setupdata += 4;
   1334     0  stevel 		passwordlength = get2(setupdata);
   1335     0  stevel 		sprintf(GETLINE, "PasswordLength = 0x%.4x",
   1336     0  stevel 			passwordlength);
   1337     0  stevel 		setupdata += 2;
   1338     0  stevel 		upasswordlength = get2(setupdata);
   1339     0  stevel 		sprintf(GETLINE, "UnicodePasswordLength = 0x%.4x",
   1340     0  stevel 			upasswordlength);
   1341     0  stevel 		setupdata += 6;
   1342     0  stevel 		cap = get4(setupdata);
   1343     0  stevel 		sprintf(GETLINE, "Capabilities = 0x%0.8x", cap);
   1344     0  stevel 		setupdata += 4;
   1345     0  stevel 		bytecount = get2(setupdata);
   1346     0  stevel 		sprintf(GETLINE, "ByteCount = %d", bytecount);
   1347     0  stevel 		setupdata = setupdata + 2 + passwordlength + upasswordlength;
   1348     0  stevel 		if (isunicode) {
   1349     0  stevel 			setupdata++;
   1350     0  stevel 			length = 2*unicode2ascii(
   1351     0  stevel 				tempstring, 256, setupdata, 256);
   1352     0  stevel 			if (length == 2) {
   1353     0  stevel 				sprintf(GETLINE,
   1354     0  stevel 						"AccountName = %s", tempstring);
   1355     0  stevel 				sprintf(GETLINE,
   1356     0  stevel 						"DomainName = %s", tempstring);
   1357     0  stevel 				setupdata += 3;
   1358     0  stevel 			} else {
   1359     0  stevel 				setupdata += length;
   1360     0  stevel 				sprintf(GETLINE,
   1361     0  stevel 						"AccountName = %s", tempstring);
   1362     0  stevel 				length = 2*unicode2ascii(
   1363     0  stevel 					tempstring, 256, setupdata, 256);
   1364     0  stevel 				setupdata += length;
   1365     0  stevel 				sprintf(GETLINE,
   1366     0  stevel 						"DomainName = %s", tempstring);
   1367     0  stevel 			}
   1368     0  stevel 			length = 2*unicode2ascii(
   1369     0  stevel 				tempstring, 256, setupdata, 256);
   1370     0  stevel 			setupdata += (length+2);
   1371     0  stevel 			sprintf(GETLINE,
   1372     0  stevel 					"NativeOS = %s", tempstring);
   1373     0  stevel 			length = 2*unicode2ascii(
   1374     0  stevel 				tempstring, 256, setupdata, 256);
   1375     0  stevel 			sprintf(GETLINE,
   1376     0  stevel 					"NativeLanman = %s", tempstring);
   1377     0  stevel 		} else {
   1378  7280     blu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
   1379  7280     blu 			    (char *)setupdata);
   1380     0  stevel 			setupdata += (length+1);
   1381     0  stevel 			sprintf(GETLINE, "AccountName = %s", tempstring);
   1382  7280     blu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
   1383  7280     blu 			    (char *)setupdata);
   1384     0  stevel 			setupdata += (length+1);
   1385     0  stevel 			sprintf(GETLINE, "DomainName = %s", tempstring);
   1386  7280     blu 			length = snprintf(tempstring, sizeof (tempstring), "%s",
   1387  7280     blu 			    (char *)setupdata);
   1388     0  stevel 			setupdata += (length+1);
   1389     0  stevel 			sprintf(GETLINE, "NativeOS = %s", tempstring);
   1390  7280     blu 			snprintf(tempstring, sizeof (tempstring), "%s",
   1391  7280     blu 			    (char *)setupdata);
   1392     0  stevel 			sprintf(GETLINE, "NativeLanman = %s", tempstring);
   1393     0  stevel 		}
   1394     0  stevel 	}
   1395     0  stevel 
   1396     0  stevel 	if (flags & F_DTAIL && smbdata->flags & SERVER_RESPONSE) {
   1397     0  stevel 		if (wordcount != 3)
   1398     0  stevel 			return;
   1399     0  stevel 		sprintf(GETLINE, "ChainedCommand = 0x%.2x",
   1400     0  stevel 			setupdata[0]);
   1401     0  stevel 		setupdata += 2;
   1402     0  stevel 		sprintf(GETLINE, "NextOffset = 0x%.4x",
   1403     0  stevel 			get2(setupdata));
   1404     0  stevel 		setupdata += 2;
   1405     0  stevel 		sprintf(GETLINE, "SetupAction = 0x%.4x",
   1406     0  stevel 			get2(setupdata));
   1407     0  stevel 		setupdata += 2;
   1408     0  stevel 		bytecount = get2(setupdata);
   1409     0  stevel 		sprintf(GETLINE, "ByteCount = %d", bytecount);
   1410     0  stevel 		setupdata += 2;
   1411  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1412  7280     blu 		    (char *)setupdata);
   1413     0  stevel 		setupdata += (length+1);
   1414     0  stevel 		sprintf(GETLINE, "NativeOS = %s", tempstring);
   1415  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1416  7280     blu 		    (char *)setupdata);
   1417     0  stevel 		setupdata += (length+1);
   1418     0  stevel 		sprintf(GETLINE, "NativeLanman = %s", tempstring);
   1419  7280     blu 		length = snprintf(tempstring, sizeof (tempstring), "%s",
   1420  7280     blu 		    (char *)setupdata);
   1421     0  stevel 		sprintf(GETLINE, "DomainName = %s", tempstring);
   1422     0  stevel 	}
   1423     0  stevel }
   1424     0  stevel 
   1425     0  stevel /*
   1426     0  stevel  * Interpret "Trans2" SMB
   1427     0  stevel  * [X/Open-SMB, Sec. 16]
   1428     0  stevel  *
   1429     0  stevel  * This is very much like "trans" above.
   1430     0  stevel  */
   1431     0  stevel /* ARGSUSED */
   1432     0  stevel static void
   1433     0  stevel interpret_trans2(int flags, uchar_t *data, int len, char *xtra)
   1434     0  stevel {
   1435     0  stevel 	struct smb *smb;
   1436     0  stevel 	uchar_t *vwv; /* word parameters */
   1437     0  stevel 	int wordcount;
   1438     0  stevel 	uchar_t *byteparms;
   1439     0  stevel 	int bytecount;
   1440     0  stevel 	int parambytes;
   1441     0  stevel 	int paramoffset;
   1442     0  stevel 	int setupcount;
   1443     0  stevel 	int subcode;
   1444     0  stevel 	uchar_t *setupdata;
   1445     0  stevel 	uchar_t *params;
   1446     0  stevel 	char *name;
   1447     0  stevel 
   1448     0  stevel 	smb  = (struct smb *)data;
   1449     0  stevel 	vwv = (uchar_t *)data + sizeof (struct smb);
   1450     0  stevel 	wordcount = *vwv++;
   1451     0  stevel 
   1452     0  stevel 	byteparms = vwv + (2 * wordcount);
   1453     0  stevel 	bytecount = get2(byteparms);
   1454     0  stevel 	byteparms += 2;
   1455     0  stevel 
   1456     0  stevel 	/*
   1457     0  stevel 	 * Print the lengths before we (potentially) bail out
   1458     0  stevel 	 * due to lack of data (so the user knows why we did).
   1459     0  stevel 	 */
   1460     0  stevel 	if (flags & F_DTAIL) {
   1461     0  stevel 		sprintf(GETLINE, "WordCount = %d", wordcount);
   1462     0  stevel 		sprintf(GETLINE, "ByteCount = %d", bytecount);
   1463     0  stevel 	}
   1464     0  stevel 
   1465     0  stevel 	/* Get length and location of params and setup data. */
   1466     0  stevel 	if (!(smb->flags & SERVER_RESPONSE)) {
   1467     0  stevel 		/* CALL */
   1468     0  stevel 		if (wordcount < 14)
   1469     0  stevel 			return;
   1470     0  stevel 		parambytes  = get2(vwv + (2 *  9));
   1471     0  stevel 		paramoffset = get2(vwv + (2 * 10));
   1472     0  stevel 		setupcount = *(vwv + (2 * 13));
   1473     0  stevel 		setupdata  =   vwv + (2 * 14);
   1474     0  stevel 	} else {
   1475     0  stevel 		/* REPLY */
   1476     0  stevel 		if (wordcount < 10)
   1477     0  stevel 			return;
   1478     0  stevel 		parambytes  = get2(vwv + (2 * 3));
   1479     0  stevel 		paramoffset = get2(vwv + (2 * 4));
   1480     0  stevel 		setupcount = *(vwv + (2 *  9));
   1481     0  stevel 		setupdata  =   vwv + (2 * 10);
   1482     0  stevel 	}
   1483     0  stevel 	if (setupcount > 0)
   1484     0  stevel 		subcode = get2(setupdata);
   1485     0  stevel 	else
   1486     0  stevel 		subcode = -1; /* invalid */
   1487     0  stevel 
   1488     0  stevel 	/* The parameters are offset from the SMB header. */
   1489     0  stevel 	params = data + paramoffset;
   1490     0  stevel 
   1491     0  stevel 	if (flags & F_DTAIL && !(smb->flags & SERVER_RESPONSE)) {
   1492     0  stevel 		/* This is a CALL. */
   1493     0  stevel 		/* print the word parameters */
   1494     0  stevel 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
   1495     0  stevel 		sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
   1496     0  stevel 		sprintf(GETLINE, "MaxParamBytes = %d", get2(vwv+4));
   1497     0  stevel 		sprintf(GETLINE, "MaxDataBytes = %d", get2(vwv+6));
   1498     0  stevel 		sprintf(GETLINE, "MaxSetupWords = %d", vwv[8]);
   1499     0  stevel 		sprintf(GETLINE, "TransFlags = 0x%.4x", get2(vwv+10));
   1500     0  stevel 		sprintf(GETLINE, "Timeout = 0x%.8x", get4(vwv+12));
   1501     0  stevel 		/* skip Reserved2 */
   1502     0  stevel 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
   1503     0  stevel 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
   1504     0  stevel 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+22));
   1505     0  stevel 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+24));
   1506     0  stevel 		sprintf(GETLINE, "SetupWords = %d", setupcount);
   1507     0  stevel 
   1508     0  stevel 		/* That finishes the VWV, now the misc. stuff. */
   1509     0  stevel 		sprintf(GETLINE, "FunctionCode = %d", subcode);
   1510     0  stevel 	}
   1511     0  stevel 
   1512     0  stevel 	if (!(smb->flags & SERVER_RESPONSE)) {
   1513     0  stevel 		/* This is a CALL.  Do sub-function. */
   1514     0  stevel 		switch (subcode) {
   1515     0  stevel 		case TRANS2_OPEN:
   1516     0  stevel 			name = "Open";
   1517     0  stevel 			goto name_only;
   1518     0  stevel 		case TRANS2_FIND_FIRST:
   1519     0  stevel 			output_trans2_findfirst(flags, params, xtra);
   1520     0  stevel 			break;
   1521     0  stevel 		case TRANS2_FIND_NEXT2:
   1522     0  stevel 			output_trans2_findnext(flags, params, xtra);
   1523     0  stevel 			break;
   1524     0  stevel 		case TRANS2_QUERY_FS_INFORMATION:
   1525     0  stevel 			name = "QueryFSInfo";
   1526     0  stevel 			goto name_only;
   1527     0  stevel 		case TRANS2_QUERY_PATH_INFORMATION:
   1528     0  stevel 			output_trans2_querypath(flags, params, xtra);
   1529     0  stevel 			break;
   1530     0  stevel 		case TRANS2_SET_PATH_INFORMATION:
   1531     0  stevel 			name = "SetPathInfo";
   1532     0  stevel 			goto name_only;
   1533     0  stevel 		case TRANS2_QUERY_FILE_INFORMATION:
   1534     0  stevel 			output_trans2_queryfile(flags, params, xtra);
   1535     0  stevel 			break;
   1536     0  stevel 		case TRANS2_SET_FILE_INFORMATION:
   1537     0  stevel 			output_trans2_setfile(flags, params, xtra);
   1538     0  stevel 			break;
   1539     0  stevel 		case TRANS2_CREATE_DIRECTORY:
   1540     0  stevel 			name = "CreateDir";
   1541     0  stevel 			goto name_only;
   1542     0  stevel 
   1543     0  stevel 		default:
   1544     0  stevel 			name = "Unknown";
   1545     0  stevel 			/* fall through */
   1546     0  stevel 		name_only:
   1547     0  stevel 			if (flags & F_SUM)
   1548     0  stevel 				sprintf(xtra, "%s ", name);
   1549     0  stevel 			if (flags & F_DTAIL)
   1550     0  stevel 				sprintf(GETLINE, "FunctionName = %s", name);
   1551     0  stevel 			break;
   1552     0  stevel 		}
   1553     0  stevel 	}
   1554     0  stevel 
   1555     0  stevel 	if (flags & F_DTAIL && smb->flags & SERVER_RESPONSE) {
   1556     0  stevel 		/* This is a REPLY. */
   1557     0  stevel 		/* print the word parameters */
   1558     0  stevel 		sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
   1559     0  stevel 		sprintf(GETLINE, "TotalDataBytes = %d",  get2(vwv+2));
   1560     0  stevel 		/* skip Reserved */
   1561     0  stevel 		sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
   1562     0  stevel 		sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
   1563     0  stevel 		sprintf(GETLINE, "ParamDispl. = 0x%.4x", get2(vwv+10));
   1564     0  stevel 		sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+12));
   1565     0  stevel 		sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+14));
   1566     0  stevel 		sprintf(GETLINE, "DataDispl. = 0x%.4x", get2(vwv+16));
   1567     0  stevel 		sprintf(GETLINE, "SetupWords = %d", setupcount);
   1568     0  stevel 
   1569     0  stevel 		output_bytes(byteparms, bytecount);
   1570     0  stevel 	}
   1571     0  stevel }
   1572     0  stevel 
   1573     0  stevel 
   1574     0  stevel static void
   1575     0  stevel interpret_default(int flags, uchar_t *data, int len, char *xtra)
   1576     0  stevel {
   1577     0  stevel 	int slength;
   1578     0  stevel 	int i;
   1579     0  stevel 	int printit;
   1580     0  stevel 	int wordcount;
   1581     0  stevel 	char *outstr;
   1582     0  stevel 	char *prfmt;
   1583     0  stevel 	char *format;
   1584     0  stevel 	char valuetype;
   1585     0  stevel 	char word[10];
   1586     0  stevel 	char *label;
   1587     0  stevel 	char tempstring[256];
   1588     0  stevel 	uchar_t *comdata, *limit;
   1589     0  stevel 	char buff[80];
   1590     0  stevel 	struct smb *smbdata;
   1591     0  stevel 	struct decode *decoder;
   1592     0  stevel 
   1593     0  stevel 	smbdata  = (struct smb *)data;
   1594     0  stevel 	comdata = (uchar_t *)data + sizeof (struct smb);
   1595     0  stevel 	wordcount = *comdata++;
   1596     0  stevel 	limit = data + len;
   1597     0  stevel 
   1598     0  stevel 	decoder = &SMBtable[smbdata->com & 255];
   1599     0  stevel 
   1600     0  stevel 	if (smbdata->flags & SERVER_RESPONSE)
   1601     0  stevel 		format = decoder->replyfmt;
   1602     0  stevel 	else
   1603     0  stevel 		format = decoder->callfmt;
   1604     0  stevel 
   1605     0  stevel 	if (!format || strlen(format) == 0) {
   1606     0  stevel 		if (wordcount == 0 || flags & F_SUM)
   1607     0  stevel 			return;
   1608     0  stevel 		sprintf(GETLINE, "WordCount = %d", wordcount);
   1609     0  stevel 		sprintf(GETLINE, "Word values (in hex):");
   1610     0  stevel 		for (i = 0; i < wordcount; i++) {
   1611     0  stevel 			sprintf(word, "%.4x ", get2(comdata));
   1612     0  stevel 			comdata += 2;
   1613     0  stevel 			if (comdata >= limit)
   1614     0  stevel 				wordcount = i+1; /* terminate */
   1615     0  stevel 			strcat(buff, word);
   1616     0  stevel 			if (((i+1) & 7) == 0 || i == (wordcount-1)) {
   1617     0  stevel 				sprintf(GETLINE, "%s", buff);
   1618     0  stevel 				strcpy(buff, "");
   1619     0  stevel 			}
   1620     0  stevel 		}
   1621     0  stevel 		return;
   1622     0  stevel 	}
   1623     0  stevel 
   1624     0  stevel 
   1625     0  stevel 	valuetype = format[0];
   1626     0  stevel 	while (valuetype != '\0') {
   1627     0  stevel 		if (comdata >= limit)
   1628     0  stevel 			break;
   1629     0  stevel 		if ((flags & F_DTAIL) && valuetype != 'r' && valuetype != 'R')
   1630     0  stevel 			outstr = GETLINE;
   1631     0  stevel 		else
   1632     0  stevel 			outstr = xtra + strlen(xtra);
   1633     0  stevel 		label = format+1;
   1634     0  stevel 		printit = (flags & F_DTAIL) || (valuetype <= 'Z');
   1635     0  stevel 
   1636     0  stevel 		switch (valuetype) {
   1637     0  stevel 		case 'W':
   1638     0  stevel 		case 'w':
   1639     0  stevel 			prfmt = (flags & F_DTAIL) ? "%s = 0x%.4x" : "%s=0x%x ";
   1640     0  stevel 			if (printit)
   1641     0  stevel 				sprintf(outstr, prfmt, label, get2(comdata));
   1642     0  stevel 			comdata += 2;
   1643     0  stevel 			break;
   1644     0  stevel 		case 'D':
   1645     0  stevel 		case 'd':
   1646     0  stevel 			prfmt = (flags & F_DTAIL) ? "%s = %d" : "%s=%d ";
   1647     0  stevel 			if (printit)
   1648     0  stevel 				sprintf(outstr, prfmt, label, get2(comdata));
   1649     0  stevel 			comdata += 2;
   1650     0  stevel 			break;
   1651     0  stevel 		case 'L':
   1652     0  stevel 		case 'l':
   1653     0  stevel 			prfmt = (flags & F_DTAIL) ? "%s = 0x%.8x" : "%s=0x%x ";
   1654     0  stevel 			if (printit)
   1655     0  stevel 				sprintf(outstr, prfmt, label, get4(comdata));
   1656     0  stevel 			comdata += 4;
   1657     0  stevel 			break;
   1658     0  stevel 		case 'B':
   1659     0  stevel 		case 'b':
   1660     0  stevel 			prfmt = (flags & F_DTAIL) ? "%s = 0x%.2x" : "%s=0x%x ";
   1661     0  stevel 			if (printit)
   1662     0  stevel 				sprintf(outstr, prfmt, label, comdata[0]);
   1663     0  stevel 			comdata += 1;
   1664     0  stevel 			break;
   1665     0  stevel 		case 'r':
   1666     0  stevel 			comdata++;
   1667     0  stevel 			break;
   1668     0  stevel 		case 'R':
   1669     0  stevel 			comdata += 2;
   1670     0  stevel 			break;
   1671     0  stevel 		case 'U':
   1672     0  stevel 		case 'u':
   1673     0  stevel 			prfmt = (flags & F_DTAIL) ? "%s = %s" : "%s=%s ";
   1674     0  stevel 			slength = unicode2ascii(tempstring, 256, comdata, 256);
   1675     0  stevel 			if (printit)
   1676     0  stevel 				sprintf(outstr, prfmt, label, tempstring);
   1677     0  stevel 			comdata +=  (slength*2 + 1);
   1678     0  stevel 			break;
   1679     0  stevel 		case 'S':
   1680     0  stevel 		case 's':
   1681     0  stevel 			prfmt = (flags & F_DTAIL) ? "%s = %s" : "%s=%s ";
   1682  7280     blu 			slength = snprintf(tempstring, sizeof (tempstring),
   1683  7280     blu 			    "%s", (char *)comdata);
   1684     0  stevel 			if (printit)
   1685     0  stevel 				sprintf(outstr, prfmt, label, tempstring);
   1686     0  stevel 			comdata += (slength+1);
   1687     0  stevel 			break;
   1688     0  stevel 		}
   1689     0  stevel 		format += (strlen(format) + 1);
   1690     0  stevel 		valuetype = format[0];
   1691     0  stevel 	}
   1692     0  stevel }
   1693