1 /****************************************************************************
2  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3  * Copyright (C) 2008-2013 Sourcefire, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License Version 2 as
7  * published by the Free Software Foundation.  You may not use, modify or
8  * distribute this program under any other version of the GNU General
9  * Public License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  *
20  ****************************************************************************
21  *
22  ****************************************************************************/
23 
24 #ifndef _SMB_H_
25 #define _SMB_H_
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"  /* For WORDS_BIGENDIAN */
29 #endif
30 
31 #include "snort_debug.h"   /* For inline */
32 #include "sf_types.h"
33 
34 /********************************************************************
35  * Macros
36  ********************************************************************/
37 #define NBSS_SESSION_TYPE__MESSAGE            0x00
38 #define NBSS_SESSION_TYPE__REQUEST            0x81
39 #define NBSS_SESSION_TYPE__POS_RESPONSE       0x82
40 #define NBSS_SESSION_TYPE__NEG_RESPONSE       0x83
41 #define NBSS_SESSION_TYPE__RETARGET_RESPONSE  0x84
42 #define NBSS_SESSION_TYPE__KEEP_ALIVE         0x85
43 
44 // SMB dialects
45 #define SMB_DIALECT_PCLAN10         "PCLAN1.0"  // Core Protocol
46 #define SMB_DIALECT_PC_NET_PROG10   "PC NETWORK PROGRAM 1.0" // Core Protocol
47 #define SMB_DIALECT_XENIX11         "xenix1.1"  // Xenix Extensions
48 #define SMB_DIALECT_XENIX_CORE      "XENIX CORE"  // Xenix Extensions
49 #define SMB_DIALECT_MS_NET103       "MICROSOFT NETWORKS 1.03"  // CorePlus
50 #define SMB_DIALECT_LANMAN10        "LANMAN1.0"  // LAN Manager 1.0
51 #define SMB_DIALECT_MS_NET30        "MICROSOFT NETWORKS 3.0"   // DOS LAN Manager 1.0
52 #define SMB_DIALECT_WIN_FOR_WKGS31a "Windows for Workgroups 3.1a"  // Not documented in MS-CIFS but always used
53 #define SMB_DIALECT_LANMAN12        "LANMAN1.2"  // LAN Manager 1.2
54 #define SMB_DIALECT_DOS_LM12X002    "DOS LM1.2X002"  // DOS LAN Manager 2.0
55 #define SMB_DIALECT_LM12X002        "LM1.2X002"  // LAN Manager 2.0
56 #define SMB_DIALECT_DOS_LANMAN21    "DOS LANMAN2.1"  // DOS LAN Manager 2.1
57 #define SMB_DIALECT_LANMAN21        "LANMAN2.1"  // LAN Manager 2.1
58 #define SMB_DIALECT_SAMBA           "Samba"  // Some Samba specific thing
59 #define SMB_DIALECT_NT_LANMAN10     "NT LANMAN 1.0"  // Only seen with Samba
60 #define SMB_DIALECT_NT_LM_012       "NT LM 0.12"  // NT LAN Manager
61 #define SMB_DIALECT_SMB_2002        "SMB 2.002"  // SMB 2.002
62 #define SMB_DIALECT_SMB_212         "SMB 2.???"  // SMB 2.1 or 2.2
63 
64 #define SMB_FLG__TYPE  0x80
65 #define SMB_TYPE__REQUEST   0
66 #define SMB_TYPE__RESPONSE  1
67 
68 #define SMB_FLG2__UNICODE      0x8000
69 #define SMB_FLG2__NT_CODES     0x4000
70 
71 #define SMB_NT_STATUS_SEVERITY__SUCCESS        0
72 #define SMB_NT_STATUS_SEVERITY__INFORMATIONAL  1
73 #define SMB_NT_STATUS_SEVERITY__WARNING        2
74 #define SMB_NT_STATUS_SEVERITY__ERROR          3
75 
76 #define SMB_NT_STATUS__SUCCESS                0x00000000
77 #define SMB_NT_STATUS__INVALID_DEVICE_REQUEST 0xc0000010
78 #define SMB_NT_STATUS__RANGE_NOT_LOCKED       0xc000007e
79 #define SMB_NT_STATUS__PIPE_BROKEN            0xc000014b
80 #define SMB_NT_STATUS__PIPE_DISCONNECTED      0xc00000b0
81 
82 #define SMB_ERROR_CLASS__SUCCESS  0x00
83 #define SMB_ERROR_CLASS__ERRDOS   0x01
84 #define SMB_ERROR_CLASS__ERRSRV   0x02
85 #define SMB_ERROR_CLASS__ERRHRD   0x03
86 #define SMB_ERROR_CLASS__ERRXOS   0x04
87 #define SMB_ERROR_CLASS__ERRMX1   0xe1
88 #define SMB_ERROR_CLASS__ERRMX2   0xe2
89 #define SMB_ERROR_CLASS__ERRMX3   0xe3
90 #define SMB_ERROR_CLASS__ERRCMD   0xff
91 
92 #define SMB_ERRSRV__INVALID_DEVICE      0x0007
93 #define SMB_ERRDOS__NOT_LOCKED          0x009e
94 #define SMB_ERRDOS__BAD_PIPE            0x00e6
95 #define SMB_ERRDOS__PIPE_NOT_CONNECTED  0x00e9
96 #define SMB_ERRDOS__MORE_DATA           0x00ea
97 
98 
99 /* SMB formats (smb_fmt) Dialect, Pathname and ASCII are all
100  * NULL terminated ASCII strings unless Unicode is specified
101  * in the NT LM 1.0 SMB header in which case they are NULL
102  * terminated unicode strings
103  */
104 #define SMB_FMT__DATA_BLOCK  1
105 #define SMB_FMT__DIALECT     2
106 #define SMB_FMT__ASCII       4
107 
SmbFmtDataBlock(const uint8_t fmt)108 static inline bool SmbFmtDataBlock(const uint8_t fmt)
109 {
110     return fmt == SMB_FMT__DATA_BLOCK ? true : false;
111 }
112 
SmbFmtDialect(const uint8_t fmt)113 static inline bool SmbFmtDialect(const uint8_t fmt)
114 {
115     return fmt == SMB_FMT__DIALECT ? true : false;
116 }
117 
SmbFmtAscii(const uint8_t fmt)118 static inline bool SmbFmtAscii(const uint8_t fmt)
119 {
120     return fmt == SMB_FMT__ASCII ? true : false;
121 }
122 
123 /* SMB command codes */
124 #define SMB_COM_CREATE_DIRECTORY 0x00
125 #define SMB_COM_DELETE_DIRECTORY 0x01
126 #define SMB_COM_OPEN 0x02
127 #define SMB_COM_CREATE 0x03
128 #define SMB_COM_CLOSE 0x04
129 #define SMB_COM_FLUSH 0x05
130 #define SMB_COM_DELETE 0x06
131 #define SMB_COM_RENAME 0x07
132 #define SMB_COM_QUERY_INFORMATION 0x08
133 #define SMB_COM_SET_INFORMATION 0x09
134 #define SMB_COM_READ 0x0A
135 #define SMB_COM_WRITE 0x0B
136 #define SMB_COM_LOCK_BYTE_RANGE 0x0C
137 #define SMB_COM_UNLOCK_BYTE_RANGE 0x0D
138 #define SMB_COM_CREATE_TEMPORARY 0x0E
139 #define SMB_COM_CREATE_NEW 0x0F
140 #define SMB_COM_CHECK_DIRECTORY 0x10
141 #define SMB_COM_PROCESS_EXIT 0x11
142 #define SMB_COM_SEEK 0x12
143 #define SMB_COM_LOCK_AND_READ 0x13
144 #define SMB_COM_WRITE_AND_UNLOCK 0x14
145 #define SMB_COM_READ_RAW 0x1A
146 #define SMB_COM_READ_MPX 0x1B
147 #define SMB_COM_READ_MPX_SECONDARY 0x1C
148 #define SMB_COM_WRITE_RAW 0x1D
149 #define SMB_COM_WRITE_MPX 0x1E
150 #define SMB_COM_WRITE_MPX_SECONDARY 0x1F
151 #define SMB_COM_WRITE_COMPLETE 0x20
152 #define SMB_COM_QUERY_SERVER 0x21
153 #define SMB_COM_SET_INFORMATION2 0x22
154 #define SMB_COM_QUERY_INFORMATION2 0x23
155 #define SMB_COM_LOCKING_ANDX 0x24
156 #define SMB_COM_TRANSACTION 0x25
157 #define SMB_COM_TRANSACTION_SECONDARY 0x26
158 #define SMB_COM_IOCTL 0x27
159 #define SMB_COM_IOCTL_SECONDARY 0x28
160 #define SMB_COM_COPY 0x29
161 #define SMB_COM_MOVE 0x2A
162 #define SMB_COM_ECHO 0x2B
163 #define SMB_COM_WRITE_AND_CLOSE 0x2C
164 #define SMB_COM_OPEN_ANDX 0x2D
165 #define SMB_COM_READ_ANDX 0x2E
166 #define SMB_COM_WRITE_ANDX 0x2F
167 #define SMB_COM_NEW_FILE_SIZE 0x30
168 #define SMB_COM_CLOSE_AND_TREE_DISC 0x31
169 #define SMB_COM_TRANSACTION2 0x32
170 #define SMB_COM_TRANSACTION2_SECONDARY 0x33
171 #define SMB_COM_FIND_CLOSE2 0x34
172 #define SMB_COM_FIND_NOTIFY_CLOSE 0x35
173 #define SMB_COM_TREE_CONNECT 0x70
174 #define SMB_COM_TREE_DISCONNECT 0x71
175 #define SMB_COM_NEGOTIATE 0x72
176 #define SMB_COM_SESSION_SETUP_ANDX 0x73
177 #define SMB_COM_LOGOFF_ANDX 0x74
178 #define SMB_COM_TREE_CONNECT_ANDX 0x75
179 #define SMB_COM_SECURITY_PACKAGE_ANDX 0x7E
180 #define SMB_COM_QUERY_INFORMATION_DISK 0x80
181 #define SMB_COM_SEARCH 0x81
182 #define SMB_COM_FIND 0x82
183 #define SMB_COM_FIND_UNIQUE 0x83
184 #define SMB_COM_FIND_CLOSE 0x84
185 #define SMB_COM_NT_TRANSACT 0xA0
186 #define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
187 #define SMB_COM_NT_CREATE_ANDX 0xA2
188 #define SMB_COM_NT_CANCEL 0xA4
189 #define SMB_COM_NT_RENAME 0xA5
190 #define SMB_COM_OPEN_PRINT_FILE 0xC0
191 #define SMB_COM_WRITE_PRINT_FILE 0xC1
192 #define SMB_COM_CLOSE_PRINT_FILE 0xC2
193 #define SMB_COM_GET_PRINT_QUEUE 0xC3
194 #define SMB_COM_READ_BULK 0xD8
195 #define SMB_COM_WRITE_BULK 0xD9
196 #define SMB_COM_WRITE_BULK_DATA 0xDA
197 #define SMB_COM_INVALID 0xFE
198 #define SMB_COM_NO_ANDX_COMMAND 0xFF
199 
200 #define SMB_MAX_NUM_COMS   256
201 
202 /* Size of word count field + Word count * 2 bytes + Size of byte count field */
203 #define SMB_COM_SIZE(wct)  (sizeof(uint8_t) + ((wct) * sizeof(uint16_t)) + sizeof(uint16_t))
204 
205 #define SMB_FILE_TYPE_DISK               0x0000
206 #define SMB_FILE_TYPE_BYTE_MODE_PIPE     0x0001
207 #define SMB_FILE_TYPE_MESSAGE_MODE_PIPE  0x0002
208 #define SMB_FILE_TYPE_PRINTER            0x0003
209 #define SMB_FILE_TYPE_COMMON_DEVICE      0x0004
210 
211 #define SMB_FILE_ATTRIBUTE_NORMAL       0x0000
212 #define SMB_FILE_ATTRIBUTE_READONLY     0x0001
213 #define SMB_FILE_ATTRIBUTE_HIDDEN       0x0002
214 #define SMB_FILE_ATTRIBUTE_SYSTEM       0x0004
215 #define SMB_FILE_ATTRIBUTE_VOLUME       0x0008
216 #define SMB_FILE_ATTRIBUTE_DIRECTORY    0x0010
217 #define SMB_FILE_ATTRIBUTE_ARCHIVE      0x0020
218 #define SMB_SEARCH_ATTRIBUTE_READONLY   0x0100
219 #define SMB_SEARCH_ATTRIBUTE_HIDDEN     0x0200
220 #define SMB_SEARCH_ATTRIBUTE_SYSTEM     0x0400
221 #define SMB_SEARCH_ATTRIBUTE_DIRECTORY  0x1000
222 #define SMB_SEARCH_ATTRIBUTE_ARCHIVE    0x2000
223 #define SMB_FILE_ATTRIBUTE_OTHER        0xC8C0   // Reserved
224 
225 #define SMB_EXT_FILE_ATTR_READONLY    0x00000001
226 #define SMB_EXT_FILE_ATTR_HIDDEN      0x00000002
227 #define SMB_EXT_FILE_ATTR_SYSTEM      0x00000004
228 #define SMB_EXT_FILE_ATTR_DIRECTORY   0x00000010
229 #define SMB_EXT_FILE_ATTR_ARCHIVE     0x00000020
230 #define SMB_EXT_FILE_ATTR_NORMAL      0x00000080
231 #define SMB_EXT_FILE_ATTR_TEMPORARY   0x00000100
232 #define SMB_EXT_FILE_ATTR_COMPRESSED  0x00000800
233 #define SMB_EXT_FILE_POSIX_SEMANTICS  0x01000000
234 #define SMB_EXT_FILE_BACKUP_SEMANTICS 0x02000000
235 #define SMB_EXT_FILE_DELETE_ON_CLOSE  0x04000000
236 #define SMB_EXT_FILE_SEQUENTIAL_SCAN  0x08000000
237 #define SMB_EXT_FILE_RANDOM_ACCESS    0x10000000
238 #define SMB_EXT_FILE_NO_BUFFERING     0x20000000
239 #define SMB_EXT_FILE_WRITE_THROUGH    0x80000000
240 
241 /********************************************************************
242  * Enums
243  ********************************************************************/
244 typedef enum _SmbAndXCom
245 {
246     SMB_ANDX_COM__NONE,
247     SMB_ANDX_COM__OPEN_ANDX,
248     SMB_ANDX_COM__READ_ANDX,
249     SMB_ANDX_COM__WRITE_ANDX,
250     SMB_ANDX_COM__TREE_CONNECT_ANDX,
251     SMB_ANDX_COM__SESSION_SETUP_ANDX,
252     SMB_ANDX_COM__LOGOFF_ANDX,
253     SMB_ANDX_COM__NT_CREATE_ANDX,
254     SMB_ANDX_COM__MAX
255 
256 } SmbAndXCom;
257 
258 typedef enum _SmbTransactionSubcommand
259 {
260     TRANS_UNKNOWN_0000             = 0x0000,
261     TRANS_SET_NMPIPE_STATE         = 0x0001,
262     TRANS_UNKNOWN_0002             = 0x0002,
263     TRANS_UNKNOWN_0003             = 0x0003,
264     TRANS_UNKNOWN_0004             = 0x0004,
265     TRANS_UNKNOWN_0005             = 0x0005,
266     TRANS_UNKNOWN_0006             = 0x0006,
267     TRANS_UNKNOWN_0007             = 0x0007,
268     TRANS_UNKNOWN_0008             = 0x0008,
269     TRANS_UNKNOWN_0009             = 0x0009,
270     TRANS_UNKNOWN_000A             = 0x000A,
271     TRANS_UNKNOWN_000B             = 0x000B,
272     TRANS_UNKNOWN_000C             = 0x000C,
273     TRANS_UNKNOWN_000D             = 0x000D,
274     TRANS_UNKNOWN_000E             = 0x000E,
275     TRANS_UNKNOWN_000F             = 0x000F,
276     TRANS_UNKNOWN_0010             = 0x0010,
277     TRANS_RAW_READ_NMPIPE          = 0x0011,
278     TRANS_UNKNOWN_0012             = 0x0012,
279     TRANS_UNKNOWN_0013             = 0x0013,
280     TRANS_UNKNOWN_0014             = 0x0014,
281     TRANS_UNKNOWN_0015             = 0x0015,
282     TRANS_UNKNOWN_0016             = 0x0016,
283     TRANS_UNKNOWN_0017             = 0x0017,
284     TRANS_UNKNOWN_0018             = 0x0018,
285     TRANS_UNKNOWN_0019             = 0x0019,
286     TRANS_UNKNOWN_001A             = 0x001A,
287     TRANS_UNKNOWN_001B             = 0x001B,
288     TRANS_UNKNOWN_001C             = 0x001C,
289     TRANS_UNKNOWN_001D             = 0x001D,
290     TRANS_UNKNOWN_001E             = 0x001E,
291     TRANS_UNKNOWN_001F             = 0x001F,
292     TRANS_UNKNOWN_0020             = 0x0020,
293     TRANS_QUERY_NMPIPE_STATE       = 0x0021,
294     TRANS_QUERY_NMPIPE_INFO        = 0x0022,
295     TRANS_PEEK_NMPIPE              = 0x0023,
296     TRANS_UNKNOWN_0024             = 0x0024,
297     TRANS_UNKNOWN_0025             = 0x0025,
298     TRANS_TRANSACT_NMPIPE          = 0x0026,
299     TRANS_UNKNOWN_0027             = 0x0027,
300     TRANS_UNKNOWN_0028             = 0x0028,
301     TRANS_UNKNOWN_0029             = 0x0029,
302     TRANS_UNKNOWN_002A             = 0x002A,
303     TRANS_UNKNOWN_002B             = 0x002B,
304     TRANS_UNKNOWN_002C             = 0x002C,
305     TRANS_UNKNOWN_002D             = 0x002D,
306     TRANS_UNKNOWN_002E             = 0x002E,
307     TRANS_UNKNOWN_002F             = 0x002F,
308     TRANS_UNKNOWN_0030             = 0x0030,
309     TRANS_RAW_WRITE_NMPIPE         = 0x0031,
310     TRANS_UNKNOWN_0032             = 0x0032,
311     TRANS_UNKNOWN_0033             = 0x0033,
312     TRANS_UNKNOWN_0034             = 0x0034,
313     TRANS_UNKNOWN_0035             = 0x0035,
314     TRANS_READ_NMPIPE              = 0x0036,
315     TRANS_WRITE_NMPIPE             = 0x0037,
316     TRANS_UNKNOWN_0038             = 0x0038,
317     TRANS_UNKNOWN_0039             = 0x0039,
318     TRANS_UNKNOWN_003A             = 0x003A,
319     TRANS_UNKNOWN_003B             = 0x003B,
320     TRANS_UNKNOWN_003C             = 0x003C,
321     TRANS_UNKNOWN_003D             = 0x003D,
322     TRANS_UNKNOWN_003E             = 0x003E,
323     TRANS_UNKNOWN_003F             = 0x003F,
324     TRANS_UNKNOWN_0040             = 0x0040,
325     TRANS_UNKNOWN_0041             = 0x0041,
326     TRANS_UNKNOWN_0042             = 0x0042,
327     TRANS_UNKNOWN_0043             = 0x0043,
328     TRANS_UNKNOWN_0044             = 0x0044,
329     TRANS_UNKNOWN_0045             = 0x0045,
330     TRANS_UNKNOWN_0046             = 0x0046,
331     TRANS_UNKNOWN_0047             = 0x0047,
332     TRANS_UNKNOWN_0048             = 0x0048,
333     TRANS_UNKNOWN_0049             = 0x0049,
334     TRANS_UNKNOWN_004A             = 0x004A,
335     TRANS_UNKNOWN_004B             = 0x004B,
336     TRANS_UNKNOWN_004C             = 0x004C,
337     TRANS_UNKNOWN_004D             = 0x004D,
338     TRANS_UNKNOWN_004E             = 0x004E,
339     TRANS_UNKNOWN_004F             = 0x004F,
340     TRANS_UNKNOWN_0050             = 0x0050,
341     TRANS_UNKNOWN_0051             = 0x0051,
342     TRANS_UNKNOWN_0052             = 0x0052,
343     TRANS_WAIT_NMPIPE              = 0x0053,
344     TRANS_CALL_NMPIPE              = 0x0054,
345     TRANS_SUBCOM_MAX               = 0x0055
346 
347 } SmbTransactionSubcommand;
348 
349 typedef enum _SmbTransaction2Subcommand
350 {
351     TRANS2_OPEN2                        = 0x0000,
352     TRANS2_FIND_FIRST2                  = 0x0001,
353     TRANS2_FIND_NEXT2                   = 0x0002,
354     TRANS2_QUERY_FS_INFORMATION         = 0x0003,
355     TRANS2_SET_FS_INFORMATION           = 0x0004,
356     TRANS2_QUERY_PATH_INFORMATION       = 0x0005,
357     TRANS2_SET_PATH_INFORMATION         = 0x0006,
358     TRANS2_QUERY_FILE_INFORMATION       = 0x0007,
359     TRANS2_SET_FILE_INFORMATION         = 0x0008,
360     TRANS2_FSCTL                        = 0x0009,
361     TRANS2_IOCTL2                       = 0x000A,
362     TRANS2_FIND_NOTIFY_FIRST            = 0x000B,
363     TRANS2_FIND_NOTIFY_NEXT             = 0x000C,
364     TRANS2_CREATE_DIRECTORY             = 0x000D,
365     TRANS2_SESSION_SETUP                = 0x000E,
366     TRANS2_UNKNOWN_000F                 = 0x000F,
367     TRANS2_GET_DFS_REFERRAL             = 0x0010,
368     TRANS2_REPORT_DFS_INCONSISTENCY     = 0x0011,
369     TRANS2_SUBCOM_MAX                   = 0x0012
370 
371 } SmbTransaction2Subcommand;
372 
373 typedef enum _SmbNtTransactSubcommand
374 {
375     NT_TRANSACT_UNKNOWN_0000            = 0x0000,
376     NT_TRANSACT_CREATE                  = 0x0001,
377     NT_TRANSACT_IOCTL                   = 0x0002,
378     NT_TRANSACT_SET_SECURITY_DESC       = 0x0003,
379     NT_TRANSACT_NOTIFY_CHANGE           = 0x0004,
380     NT_TRANSACT_RENAME                  = 0x0005,
381     NT_TRANSACT_QUERY_SECURITY_DESC     = 0x0006,
382     NT_TRANSACT_SUBCOM_MAX              = 0x0007
383 
384 } SmbNtTransactSubcommand;
385 
386 
387 /********************************************************************
388  * Structures and inline accessor functions
389  ********************************************************************/
390 /* Pack the structs since we'll be laying them on top of packet data */
391 #ifdef WIN32
392 #pragma pack(push,smb_hdrs,1)
393 #else
394 #pragma pack(1)
395 #endif
396 
397 /********************************************************************
398  * NetBIOS Session Service header
399  ********************************************************************/
400 typedef struct _NbssHdr
401 {
402     uint8_t  type;
403     uint8_t  flags;  /* Treat flags as the upper byte to length */
404     uint16_t length;
405 
406 } NbssHdr;
407 
408 /*NbssLen should be used by SMB1 */
NbssLen(const NbssHdr * nb)409 static inline uint32_t NbssLen(const NbssHdr *nb)
410 {
411     /* Treat first bit of flags as the upper byte to length
412      * [MS-SMB] 2.1 Transport - Length can be maximum 0x1FFFF*/
413     return ((nb->flags & 0x01) << 16) | ntohs(nb->length);
414 }
415 
416 /*NbssLen2 should be used by SMB2/SMB3 */
NbssLen2(const NbssHdr * nb)417 static inline uint32_t NbssLen2(const NbssHdr *nb)
418 {
419     /*The Length is 3 bytes. [MS-SMB2] 2.1 Transport*/
420     return ((nb->flags << 16) | ntohs(nb->length));
421 }
422 
NbssType(const NbssHdr * nb)423 static inline uint8_t NbssType(const NbssHdr *nb)
424 {
425     return nb->type;
426 }
427 
428 /********************************************************************
429  * SMB headers
430  *
431  * Length of header is always 32 but meaning of fields differs
432  *  according to dialect
433  ********************************************************************/
434 typedef struct _SmbCoreHdr
435 {
436     uint8_t  smb_idf[4];  /* contains 0xFF, 'SMB' */
437     uint8_t  smb_com;     /* command code */
438     uint8_t  smb_rcls;    /* error code class */
439     uint8_t  smb_reh;     /* reserved (contains AH if DOS INT-24 ERR) */
440     uint16_t smb_err;     /* error code */
441     uint8_t  smb_reb;     /* reserved */
442     uint16_t smb_res[7];  /* reserved */
443     uint16_t smb_tid;     /* tree id # */
444     uint16_t smb_pid;     /* caller's process id # */
445     uint16_t smb_uid;     /* user id # */
446     uint16_t smb_mid;     /* multiplex id # */
447 #if 0
448     uint8_t  smb_wct;     /* count of parameter words */
449     uint16_t smb_vwv[];   /* variable # words of params */
450     uint16_t smb_bcc;     /* # bytes of data following */
451     uint8_t  smb_data[];  /* data bytes */
452 #endif
453 } SmbCoreHdr;
454 
455 typedef struct _SmbLm10Hdr
456 {
457     uint8_t  smb_idf[4];    /* contains 0xFF, 'SMB' */
458     uint8_t  smb_com;       /* command code */
459     uint8_t  smb_rcls;      /* error class */
460     uint8_t  smb_reh;       /* reserved for future */
461     uint16_t smb_err;       /* error code */
462     uint8_t  smb_flg;       /* flags */
463     uint16_t smb_res[7];    /* reserved for future */
464     uint16_t smb_tid;       /* authenticated resource identifier */
465     uint16_t smb_pid;       /* caller's process id */
466     uint16_t smb_uid;       /* unauthenticated user id */
467     uint16_t smb_mid;       /* multiplex id */
468 #if 0
469     uint8_t  smb_wct;       /* count of 16-bit words that follow */
470     uint16_t smb_vwv[];     /* variable number of 16-bit words */
471     uint16_t smb_bcc;       /* count of bytes that follow */
472     uint8_t  smb_buf[];     /* variable number of bytes */
473 #endif
474 } SmbLm10Hdr;
475 
476 typedef struct _SmbLm20Hdr
477 {
478     uint8_t  smb_idf[4];    /* contains 0xFF,’SMB’ */
479     uint8_t  smb_com;       /* command code */
480     uint8_t  smb_rcls;      /* error class */
481     uint8_t  smb_reh;       /* reserved for future */
482     uint16_t smb_err;       /* error code */
483     uint8_t  smb_flg;       /* flags */
484     uint16_t smb_flg2;      /* flags */
485     uint16_t smb_res[6];    /* reserved for future */
486     uint16_t smb_tid;       /* authenticated resource identifier */
487     uint16_t smb_pid;       /* caller’s process id */
488     uint16_t smb_uid;       /* authenticated user id */
489     uint16_t smb_mid;       /* multiplex id */
490 #if 0
491     uint8_t  smb_wct;       /* count of 16-bit words that follow */
492     uint16_t smb_vwv[];     /* variable number of 16-bit words */
493     uint16_t smb_bcc;       /* count of bytes that follow */
494     uint8_t  smb_buf[];     /* variable number of bytes */
495 #endif
496 } SmbLm20Hdr;
497 
498 typedef struct _SmbNtHdr
499 {
500     uint8_t  smb_idf[4];            /* contains 0xFF, 'SMB' */
501     uint8_t  smb_com;               /* command code */
502     union {
503         struct {
504             uint8_t  smb_class;     /* dos error class */
505             uint8_t  smb_res;       /* reserved for future */
506             uint16_t smb_code;      /* dos error code */
507         } smb_status;
508         uint32_t nt_status;         /* nt status */
509     } smb_status;
510     uint8_t  smb_flg;               /* flags */
511     uint16_t smb_flg2;              /* flags */
512     uint16_t smb_pid_high;
513     uint64_t smb_signature;
514     uint16_t smb_res;               /* reserved for future */
515     uint16_t smb_tid;               /* tree id */
516     uint16_t smb_pid;               /* caller's process id */
517     uint16_t smb_uid;               /* authenticated user id */
518     uint16_t smb_mid;               /* multiplex id */
519 #if 0
520     uint8_t  smb_wct;       /* count of 16-bit words that follow */
521     uint16_t smb_vwv[];     /* variable number of 16-bit words */
522     uint16_t smb_bcc;       /* count of bytes that follow */
523     uint8_t  smb_buf[];     /* variable number of bytes */
524 #endif
525 } SmbNtHdr;
526 
SmbNtohs(const uint16_t * ptr)527 static inline uint16_t SmbNtohs(const uint16_t *ptr)
528 {
529     uint16_t value;
530 
531     if (ptr == NULL)
532         return 0;
533 
534 #ifdef WORDS_MUSTALIGN
535     value = *((uint8_t *)ptr) << 8 | *((uint8_t *)ptr + 1);
536 #else
537     value = *ptr;
538 #endif  /* WORDS_MUSTALIGN */
539 
540 #ifdef WORDS_BIGENDIAN
541     return ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8);
542 #else
543     return value;
544 #endif  /* WORDS_BIGENDIAN */
545 }
546 
SmbHtons(const uint16_t * ptr)547 static inline uint16_t SmbHtons(const uint16_t *ptr)
548 {
549     return SmbNtohs(ptr);
550 }
551 
SmbNtohl(const uint32_t * ptr)552 static inline uint32_t SmbNtohl(const uint32_t *ptr)
553 {
554     uint32_t value;
555 
556     if (ptr == NULL)
557         return 0;
558 
559 #ifdef WORDS_MUSTALIGN
560     value = *((uint8_t *)ptr)     << 24 | *((uint8_t *)ptr + 1) << 16 |
561             *((uint8_t *)ptr + 2) << 8  | *((uint8_t *)ptr + 3);
562 #else
563     value = *ptr;
564 #endif  /* WORDS_MUSTALIGN */
565 
566 #ifdef WORDS_BIGENDIAN
567     return ((value & 0xff000000) >> 24) | ((value & 0x00ff0000) >> 8)  |
568            ((value & 0x0000ff00) << 8)  | ((value & 0x000000ff) << 24);
569 #else
570     return value;
571 #endif  /* WORDS_BIGENDIAN */
572 }
573 
SmbHtonl(const uint32_t * ptr)574 static inline uint32_t SmbHtonl(const uint32_t *ptr)
575 {
576     return SmbNtohl(ptr);
577 }
578 
SmbNtohq(const uint64_t * ptr)579 static inline uint64_t SmbNtohq(const uint64_t *ptr)
580 {
581     uint64_t value;
582 
583     if (ptr == NULL)
584         return 0;
585 
586 #ifdef WORDS_MUSTALIGN
587     value = *((uint8_t *)ptr)     << 56 | *((uint8_t *)ptr + 1) << 48 |
588             *((uint8_t *)ptr + 2) << 40 | *((uint8_t *)ptr + 3) << 32 |
589             *((uint8_t *)ptr + 4) << 24 | *((uint8_t *)ptr + 5) << 16 |
590             *((uint8_t *)ptr + 6) << 8  | *((uint8_t *)ptr + 7);
591 #else
592     value = *ptr;
593 #endif  /* WORDS_MUSTALIGN */
594 
595 #ifdef WORDS_BIGENDIAN
596     return ((value & 0xff00000000000000) >> 56) | ((value & 0x00ff000000000000) >> 40) |
597            ((value & 0x0000ff0000000000) >> 24) | ((value & 0x000000ff00000000) >> 8)  |
598            ((value & 0x00000000ff000000) << 8)  | ((value & 0x0000000000ff0000) << 24) |
599            ((value & 0x000000000000ff00) << 40) | ((value & 0x00000000000000ff) << 56);
600 #else
601     return value;
602 #endif  /* WORDS_BIGENDIAN */
603 }
604 
SmbHtonq(const uint64_t * ptr)605 static inline uint64_t SmbHtonq(const uint64_t *ptr)
606 {
607     return SmbNtohq(ptr);
608 }
609 
SmbId(const SmbNtHdr * hdr)610 static inline uint32_t SmbId(const SmbNtHdr *hdr)
611 {
612 #ifdef WORDS_MUSTALIGN
613     uint8_t *idf = (uint8_t *)hdr->smb_idf;
614     return *idf << 24 | *(idf + 1) << 16 | *(idf + 2) << 8 | *(idf + 3);
615 #else
616     uint32_t *tmp = (uint32_t *)hdr->smb_idf;
617     return ntohl(*tmp);
618 #endif  /* WORDS_MUSTALIGN */
619 }
620 
SmbCom(const SmbNtHdr * hdr)621 static inline uint8_t SmbCom(const SmbNtHdr *hdr)
622 {
623     return hdr->smb_com;
624 }
625 
626 #if 0   // So no compiler warning for being unused
627 // Refers to older pre-NT status codes
628 static bool SmbStatusSmbCodes(const SmbNtHdr *hdr)
629 {
630     if (SmbNtohs(&hdr->smb_flg2) & SMB_FLG2__NT_CODES)
631         return false;
632     return true;
633 }
634 #endif
635 
SmbStatusNtCodes(const SmbNtHdr * hdr)636 static bool SmbStatusNtCodes(const SmbNtHdr *hdr)
637 {
638     if (SmbNtohs(&hdr->smb_flg2) & SMB_FLG2__NT_CODES)
639         return true;
640     return false;
641 }
642 
SmbNtStatus(const SmbNtHdr * hdr)643 static inline uint32_t SmbNtStatus(const SmbNtHdr *hdr)
644 {
645     return SmbNtohl(&hdr->smb_status.nt_status);
646 }
647 
SmbNtStatusSeverity(const SmbNtHdr * hdr)648 static inline uint8_t SmbNtStatusSeverity(const SmbNtHdr *hdr)
649 {
650     return (uint8_t)(SmbNtStatus(hdr) >> 30);
651 }
652 
SmbStatusClass(const SmbNtHdr * hdr)653 static inline uint8_t SmbStatusClass(const SmbNtHdr *hdr)
654 {
655     return hdr->smb_status.smb_status.smb_class;
656 }
657 
SmbStatusCode(const SmbNtHdr * hdr)658 static inline uint16_t SmbStatusCode(const SmbNtHdr *hdr)
659 {
660     return SmbNtohs(&hdr->smb_status.smb_status.smb_code);
661 }
662 
663 // This function is obviously deficient.  Need to do a lot more
664 // testing, research and reading MS-CIFS, MS-SMB and MS-ERREF.
SmbError(const SmbNtHdr * hdr)665 static inline bool SmbError(const SmbNtHdr *hdr)
666 {
667     if (SmbStatusNtCodes(hdr))
668     {
669         /* Nt status codes are being used.  First 2 bits indicate
670          * severity. */
671         switch (SmbNtStatusSeverity(hdr))
672         {
673             case SMB_NT_STATUS_SEVERITY__SUCCESS:
674             case SMB_NT_STATUS_SEVERITY__INFORMATIONAL:
675             case SMB_NT_STATUS_SEVERITY__WARNING:
676                 return false;
677             case SMB_NT_STATUS_SEVERITY__ERROR:
678             default:
679                 break;
680         }
681     }
682     else
683     {
684         switch (SmbStatusClass(hdr))
685         {
686             case SMB_ERROR_CLASS__SUCCESS:
687                 return false;
688             case SMB_ERROR_CLASS__ERRDOS:
689                 if (SmbStatusCode(hdr) == SMB_ERRDOS__MORE_DATA)
690                     return false;
691                 break;
692             case SMB_ERROR_CLASS__ERRSRV:
693             case SMB_ERROR_CLASS__ERRHRD:
694             case SMB_ERROR_CLASS__ERRCMD:
695             default:
696                 break;
697         }
698     }
699 
700     return true;
701 }
702 
SmbBrokenPipe(const SmbNtHdr * hdr)703 static inline bool SmbBrokenPipe(const SmbNtHdr *hdr)
704 {
705     if (SmbStatusNtCodes(hdr))
706     {
707         uint32_t nt_status = SmbNtStatus(hdr);
708         if ((nt_status == SMB_NT_STATUS__PIPE_BROKEN)
709                 || (nt_status == SMB_NT_STATUS__PIPE_DISCONNECTED))
710             return true;
711     }
712     else
713     {
714         if (SmbStatusClass(hdr) == SMB_ERROR_CLASS__ERRDOS)
715         {
716             uint16_t smb_status = SmbStatusCode(hdr);
717             if ((smb_status == SMB_ERRDOS__BAD_PIPE)
718                     || (smb_status == SMB_ERRDOS__PIPE_NOT_CONNECTED))
719                 return true;
720         }
721     }
722 
723     return false;
724 }
725 
SmbErrorInvalidDeviceRequest(const SmbNtHdr * hdr)726 static inline bool SmbErrorInvalidDeviceRequest(const SmbNtHdr *hdr)
727 {
728     if (SmbStatusNtCodes(hdr))
729     {
730         if (SmbNtStatus(hdr) == SMB_NT_STATUS__INVALID_DEVICE_REQUEST)
731             return true;
732     }
733     else
734     {
735         if ((SmbStatusClass(hdr) == SMB_ERROR_CLASS__ERRSRV)
736                 && (SmbStatusCode(hdr) == SMB_ERRSRV__INVALID_DEVICE))
737             return true;
738     }
739 
740     return false;
741 }
742 
SmbErrorRangeNotLocked(const SmbNtHdr * hdr)743 static inline bool SmbErrorRangeNotLocked(const SmbNtHdr *hdr)
744 {
745     if (SmbStatusNtCodes(hdr))
746     {
747         if (SmbNtStatus(hdr) == SMB_NT_STATUS__RANGE_NOT_LOCKED)
748             return true;
749     }
750     else
751     {
752         if ((SmbStatusClass(hdr) == SMB_ERROR_CLASS__ERRDOS)
753                 && (SmbStatusCode(hdr) == SMB_ERRDOS__NOT_LOCKED))
754             return true;
755     }
756 
757     return false;
758 }
759 
SmbType(const SmbNtHdr * hdr)760 static inline int SmbType(const SmbNtHdr *hdr)
761 {
762     if (hdr->smb_flg & SMB_FLG__TYPE)
763         return SMB_TYPE__RESPONSE;
764 
765     return SMB_TYPE__REQUEST;
766 }
767 
SmbUnicode(const SmbNtHdr * hdr)768 static inline bool SmbUnicode(const SmbNtHdr *hdr)
769 {
770     return (SmbNtohs(&hdr->smb_flg2) & SMB_FLG2__UNICODE) ? true : false;
771 }
772 
SmbUid(const SmbNtHdr * hdr)773 static inline uint16_t SmbUid(const SmbNtHdr *hdr)
774 {
775     return SmbNtohs(&hdr->smb_uid);
776 }
777 
SmbTid(const SmbNtHdr * hdr)778 static inline uint16_t SmbTid(const SmbNtHdr *hdr)
779 {
780     return SmbNtohs(&hdr->smb_tid);
781 }
782 
783 // PidHigh doesn't seem to matter ever
SmbPid(const SmbNtHdr * hdr)784 static inline uint16_t SmbPid(const SmbNtHdr *hdr)
785 {
786     return SmbNtohs(&hdr->smb_pid);
787 }
788 
SmbMid(const SmbNtHdr * hdr)789 static inline uint16_t SmbMid(const SmbNtHdr *hdr)
790 {
791     return SmbNtohs(&hdr->smb_mid);
792 }
793 
794 /********************************************************************
795  * Common fields to all commands
796  ********************************************************************/
797 typedef struct _SmbCommon
798 {
799     uint8_t smb_wct;
800 
801 } SmbCommon;
802 
SmbWct(const SmbCommon * hdr)803 static inline uint8_t SmbWct(const SmbCommon *hdr)
804 {
805     return hdr->smb_wct;
806 }
807 
808 /* Common fields to all AndX commands */
809 typedef struct _SmbAndXCommon
810 {
811     uint8_t  smb_wct;
812     uint8_t  smb_com2;     /* secondary (X) command, 0xFF = none */
813     uint8_t  smb_reh2;     /* reserved (must be zero) */
814     uint16_t smb_off2;     /* offset (from SMB hdr start) to next cmd (@smb_wct) */
815 
816 } SmbAndXCommon;
817 
SmbAndXCom2(const SmbAndXCommon * andx)818 static inline uint8_t SmbAndXCom2(const SmbAndXCommon *andx)
819 {
820     return andx->smb_com2;
821 }
822 
SmbAndXOff2(const SmbAndXCommon * andx)823 static inline uint16_t SmbAndXOff2(const SmbAndXCommon *andx)
824 {
825     return SmbNtohs(&andx->smb_off2);
826 }
827 
828 /* For server empty respones indicating client error or interim response */
829 typedef struct _SmbEmptyCom
830 {
831     uint8_t  smb_wct;    /* value = 0 */
832     uint16_t smb_bcc;    /* value = 0 */
833 
834 } SmbEmptyCom;
835 
SmbEmptyComWct(const SmbEmptyCom * ec)836 static inline uint8_t SmbEmptyComWct(const SmbEmptyCom *ec)
837 {
838     return ec->smb_wct;
839 }
840 
SmbEmptyComBcc(const SmbEmptyCom * ec)841 static inline uint16_t SmbEmptyComBcc(const SmbEmptyCom *ec)
842 {
843     return SmbNtohs(&ec->smb_bcc);
844 }
845 
SmbBcc(const uint8_t * ptr,uint16_t com_size)846 static inline uint16_t SmbBcc(const uint8_t *ptr, uint16_t com_size)
847 {
848     /* com_size must be at least the size of the command encasing */
849     if (com_size < sizeof(SmbEmptyCom))
850         return 0;
851 
852     return SmbNtohs((uint16_t *)(ptr + com_size - sizeof(uint16_t)));
853 }
854 
855 /********************************************************************
856  * SMB_COM_OPEN
857  ********************************************************************/
858 typedef struct _SmbOpenReq   /* smb_wct = 2 */
859 {
860     uint8_t  smb_wct;     /* count of 16-bit words that follow */
861     uint16_t smb_mode;    /* r/w/share */
862     uint16_t smb_attr;    /* attribute */
863     uint16_t smb_bcc;     /* min = 2 */
864 
865 #if 0
866     uint8_t  smb_fmt;     /* ASCII -- 04 */
867     uint8_t  smb_buf[];   /* file pathname */
868 #endif
869 } SmbOpenReq;
870 
871 typedef struct _SmbOpenResp   /* smb_wct = 7 */
872 {
873     uint8_t  smb_wct;     /* count of 16-bit words that follow */
874     uint16_t smb_fid;     /* file handle */
875     uint16_t smb_attr;    /* attribute */
876     uint32_t smb_time;    /* time1 low */
877     uint32_t smb_file_size;   /* file size low */
878     uint16_t smb_access;  /* access allowed */
879     uint16_t smb_bcc;     /* must be 0 */
880 
881 } SmbOpenResp;
882 
883 #define SMB_OPEN_ACCESS_MODE__READ        0x0000
884 #define SMB_OPEN_ACCESS_MODE__WRITE       0x0001
885 #define SMB_OPEN_ACCESS_MODE__READ_WRITE  0x0002
886 #define SMB_OPEN_ACCESS_MODE__EXECUTE     0x0003
887 
SmbOpenRespFid(const SmbOpenResp * resp)888 static inline uint16_t SmbOpenRespFid(const SmbOpenResp *resp)
889 {
890     return SmbNtohs(&resp->smb_fid);
891 }
892 
SmbOpenRespFileSize(const SmbOpenResp * resp)893 static inline uint32_t SmbOpenRespFileSize(const SmbOpenResp *resp)
894 {
895     return SmbNtohl(&resp->smb_file_size);
896 }
897 
SmbOpenRespFileAttrs(const SmbOpenResp * resp)898 static inline uint16_t SmbOpenRespFileAttrs(const SmbOpenResp *resp)
899 {
900     return SmbNtohs(&resp->smb_attr);
901 }
902 
SmbFileAttrsDirectory(const uint16_t file_attrs)903 static inline bool SmbFileAttrsDirectory(const uint16_t file_attrs)
904 {
905     if (file_attrs & SMB_FILE_ATTRIBUTE_DIRECTORY)
906         return true;
907     return false;
908 }
909 
SmbOpenRespAccessMode(const SmbOpenResp * resp)910 static inline uint16_t SmbOpenRespAccessMode(const SmbOpenResp *resp)
911 {
912     return SmbNtohs(&resp->smb_access);
913 }
914 
SmbOpenForWriting(const uint16_t access_mode)915 static inline bool SmbOpenForWriting(const uint16_t access_mode)
916 {
917     return access_mode == SMB_OPEN_ACCESS_MODE__WRITE;
918 }
919 
920 /********************************************************************
921  * SMB_COM_CREATE
922  ********************************************************************/
923 typedef struct _SmbCreateReq   /* smb_wct = 3 */
924 {
925     uint8_t  smb_wct;
926     uint16_t smb_file_attrs;
927     uint32_t smb_creation_time;
928     uint16_t smb_bcc;
929 #if 0
930     uint8_t  smb_fmt;     /* ASCII -- 04 */
931     uint8_t  smb_buf[];   /* file pathname */
932 #endif
933 } SmbCreateReq;
934 
935 typedef struct _SmbCreateResp   /* smb_wct = 1 */
936 {
937     uint8_t  smb_wct;
938     uint16_t smb_fid;
939     uint16_t smb_bcc;
940 
941 } SmbCreateResp;
942 
SmbCreateReqFileAttrs(const SmbCreateReq * req)943 static inline uint16_t SmbCreateReqFileAttrs(const SmbCreateReq *req)
944 {
945     return SmbNtohs(&req->smb_file_attrs);
946 }
947 
SmbAttrDirectory(const uint16_t file_attrs)948 static inline bool SmbAttrDirectory(const uint16_t file_attrs)
949 {
950     if (file_attrs & SMB_FILE_ATTRIBUTE_DIRECTORY)
951         return true;
952     return false;
953 }
954 
SmbAttrHidden(const uint16_t file_attrs)955 static inline bool SmbAttrHidden(const uint16_t file_attrs)
956 {
957     if (file_attrs & SMB_FILE_ATTRIBUTE_HIDDEN)
958         return true;
959     return false;
960 }
961 
SmbAttrSystem(const uint16_t file_attrs)962 static inline bool SmbAttrSystem(const uint16_t file_attrs)
963 {
964     if (file_attrs & SMB_FILE_ATTRIBUTE_SYSTEM)
965         return true;
966     return false;
967 }
968 
SmbCreateRespFid(const SmbCreateResp * resp)969 static inline uint16_t SmbCreateRespFid(const SmbCreateResp *resp)
970 {
971     return SmbNtohs(&resp->smb_fid);
972 }
973 
974 /********************************************************************
975  * SMB_COM_CLOSE
976  ********************************************************************/
977 typedef struct _SmbCloseReq   /* smb_wct = 3 */
978 {
979     uint8_t  smb_wct;     /* count of 16-bit words that follow */
980     uint16_t smb_fid;     /* file handle */
981     uint16_t smb_tlow;    /* time low */
982     uint16_t smb_thigh;   /* time high */
983     uint16_t smb_bcc;     /* must be 0 */
984 
985 } SmbCloseReq;
986 
987 typedef struct _SmbCloseResp   /* smb_wct = 0 */
988 {
989     uint8_t  smb_wct;     /* count of 16-bit words that follow */
990     uint16_t smb_bcc;     /* must be 0 */
991 
992 } SmbCloseResp;
993 
SmbCloseReqFid(const SmbCloseReq * req)994 static inline uint16_t SmbCloseReqFid(const SmbCloseReq *req)
995 {
996     return SmbNtohs(&req->smb_fid);
997 }
998 
999 /********************************************************************
1000  * SMB_COM_DELETE
1001  ********************************************************************/
1002 typedef struct _SmbDeleteReq  /* smb_wct = 1 */
1003 {
1004     uint8_t  smb_wct;
1005     uint16_t smb_search_attrs;
1006     uint16_t smb_bcc;
1007 #if 0
1008     uint8_t  smb_fmt;       /* ASCII -- 04 */
1009     uint8_t  smb_buf[];     /* filename */
1010 #endif
1011 } SmbDeleteReq;
1012 
1013 typedef struct _SmbDeleteResp  /* smb_wct = 0 */
1014 {
1015     uint8_t  smb_wct;
1016     uint16_t smb_bcc;
1017 
1018 } SmbDeleteResp;
1019 
1020 /********************************************************************
1021  * SMB_COM_RENAME
1022  ********************************************************************/
1023 typedef struct _SmbRenameReq  /* smb_wct = 1 */
1024 {
1025     uint8_t  smb_wct;
1026     uint16_t smb_attrs;
1027     uint16_t smb_bcc;
1028 #if 0
1029     uint8_t  smb_fmt;       /* ASCII -- 04 */
1030     uint8_t  smb_buf[];     /* old filename */
1031     uint8_t  smb_fmt2;      /* ASCII -- 04 */
1032     uint8_t  smb_buf2[];    /* new filename */
1033 #endif
1034 } SmbRenameReq;
1035 
1036 typedef struct _SmbRenameResp  /* smb_wct = 0 */
1037 {
1038     uint8_t  smb_wct;
1039     uint16_t smb_bcc;
1040 
1041 } SmbRenameResp;
1042 
1043 /********************************************************************
1044  * SMB_COM_READ
1045  ********************************************************************/
1046 typedef struct _SmbReadReq   /* smb_wct = 5 */
1047 {
1048     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1049     uint16_t smb_fid;     /* file handle */
1050     uint16_t smb_cnt;     /* count of bytes */
1051     uint32_t smb_off;     /* offset */
1052     uint16_t smb_left;    /* count left */
1053     uint16_t smb_bcc;     /* must be 0 */
1054 
1055 } SmbReadReq;
1056 
1057 typedef struct _SmbReadResp   /* smb_wct = 5 */
1058 {
1059     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1060     uint16_t smb_cnt;     /* count */
1061     uint16_t smb_res[4];  /* reserved (MBZ) */
1062     uint16_t smb_bcc;     /* length of data + 3 */
1063 
1064 #if 0
1065     uint8_t  smb_fmt;     /* Data Block -- 01 */
1066     uint16_t smb_dlen;    /* length of data */
1067     uint8_t  smb_buf[];   /* data */
1068 #endif
1069 } SmbReadResp;
1070 
SmbReadReqFid(const SmbReadReq * req)1071 static inline uint16_t SmbReadReqFid(const SmbReadReq *req)
1072 {
1073     return SmbNtohs(&req->smb_fid);
1074 }
1075 
SmbReadReqOffset(const SmbReadReq * req)1076 static inline uint32_t SmbReadReqOffset(const SmbReadReq *req)
1077 {
1078     return SmbNtohl(&req->smb_off);
1079 }
1080 
SmbReadRespCount(const SmbReadResp * resp)1081 static inline uint16_t SmbReadRespCount(const SmbReadResp *resp)
1082 {
1083     return SmbNtohs(&resp->smb_cnt);
1084 }
1085 
1086 /********************************************************************
1087  * SMB_COM_WRITE
1088  ********************************************************************/
1089 typedef struct _SmbWriteReq   /* smb_wct = 5 */
1090 {
1091     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1092     uint16_t smb_fid;     /* file handle */
1093     uint16_t smb_cnt;     /* count of bytes */
1094     uint32_t smb_offset;  /* file offset in bytes */
1095     uint16_t smb_left;    /* count left */
1096     uint16_t smb_bcc;     /* length of data + 3 */
1097 
1098 #if 0
1099     uint16_t smb_fmt;     /* Data Block -- 01 */
1100     uint16_t smb_dlen;    /* length of data */
1101     uint8_t smb_buf[];    /* data */
1102 #endif
1103 } SmbWriteReq;
1104 
1105 typedef struct _SmbWriteResp   /* smb_wct = 1 */
1106 {
1107     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1108     uint16_t smb_cnt;     /* count */
1109     uint16_t smb_bcc;     /* must be 0 */
1110 
1111 } SmbWriteResp;
1112 
SmbWriteReqFid(const SmbWriteReq * req)1113 static inline uint16_t SmbWriteReqFid(const SmbWriteReq *req)
1114 {
1115     return SmbNtohs(&req->smb_fid);
1116 }
1117 
SmbWriteReqCount(const SmbWriteReq * req)1118 static inline uint16_t SmbWriteReqCount(const SmbWriteReq *req)
1119 {
1120     return SmbNtohs(&req->smb_cnt);
1121 }
1122 
SmbWriteReqOffset(const SmbWriteReq * req)1123 static inline uint32_t SmbWriteReqOffset(const SmbWriteReq *req)
1124 {
1125     return SmbNtohl(&req->smb_offset);
1126 }
1127 
SmbWriteRespCount(const SmbWriteResp * resp)1128 static inline uint16_t SmbWriteRespCount(const SmbWriteResp *resp)
1129 {
1130     return SmbNtohs(&resp->smb_cnt);
1131 }
1132 
1133 /********************************************************************
1134  * SMB_COM_CREATE_NEW
1135  ********************************************************************/
1136 typedef struct _SmbCreateNewReq   /* smb_wct = 3 */
1137 {
1138     uint8_t  smb_wct;
1139     uint16_t smb_file_attrs;
1140     uint32_t smb_creation_time;
1141     uint16_t smb_bcc;
1142 #if 0
1143     uint8_t  smb_fmt;     /* ASCII -- 04 */
1144     uint8_t  smb_buf[];   /* file pathname */
1145 #endif
1146 } SmbCreateNewReq;
1147 
1148 typedef struct _SmbCreateNewResp   /* smb_wct = 1 */
1149 {
1150     uint8_t  smb_wct;
1151     uint16_t smb_fid;
1152     uint16_t smb_bcc;
1153 
1154 } SmbCreateNewResp;
1155 
SmbCreateNewReqFileAttrs(const SmbCreateNewReq * req)1156 static inline uint16_t SmbCreateNewReqFileAttrs(const SmbCreateNewReq *req)
1157 {
1158     return SmbNtohs(&req->smb_file_attrs);
1159 }
1160 
SmbCreateNewRespFid(const SmbCreateNewResp * resp)1161 static inline uint16_t SmbCreateNewRespFid(const SmbCreateNewResp *resp)
1162 {
1163     return SmbNtohs(&resp->smb_fid);
1164 }
1165 
1166 /********************************************************************
1167  * SMB_COM_LOCK_AND_READ
1168  ********************************************************************/
1169 typedef struct _SmbLockAndReadReq   /* smb_wct = 5 */
1170 {
1171     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1172     uint16_t smb_fid;
1173     uint16_t smb_cnt;
1174     uint32_t smb_read_offset;
1175     uint16_t smb_remaining;
1176     uint16_t smb_bcc;     /* must be 0 */
1177 
1178 } SmbLockAndReadReq;
1179 
1180 typedef struct _SmbLockAndReadResp   /* smb_wct = 5 */
1181 {
1182     uint8_t  smb_wct;
1183     uint16_t smb_cnt;
1184     uint16_t reserved[4];
1185     uint16_t smb_bcc;
1186 #if 0
1187     uint16_t smb_fmt;     /* Data Block -- 01 */
1188     uint16_t smb_dlen;    /* length of data */
1189     uint8_t smb_buf[];    /* data */
1190 #endif
1191 } SmbLockAndReadResp;
1192 
SmbLockAndReadReqFid(const SmbLockAndReadReq * req)1193 static inline uint16_t SmbLockAndReadReqFid(const SmbLockAndReadReq *req)
1194 {
1195     return SmbNtohs(&req->smb_fid);
1196 }
1197 
SmbLockAndReadReqOffset(const SmbLockAndReadReq * req)1198 static inline uint32_t SmbLockAndReadReqOffset(const SmbLockAndReadReq *req)
1199 {
1200     return SmbNtohl(&req->smb_read_offset);
1201 }
1202 
SmbLockAndReadRespCount(const SmbLockAndReadResp * resp)1203 static inline uint16_t SmbLockAndReadRespCount(const SmbLockAndReadResp *resp)
1204 {
1205     return SmbNtohs(&resp->smb_cnt);
1206 }
1207 
1208 /********************************************************************
1209  * SMB_COM_WRITE_AND_UNLOCK
1210  ********************************************************************/
1211 typedef struct _SmbWriteAndUnlockReq
1212 {
1213     uint8_t  smb_wct;
1214     uint16_t smb_fid;
1215     uint16_t smb_cnt;
1216     uint32_t smb_write_offset;
1217     uint16_t smb_estimate_of_remaining;
1218     uint16_t smb_bcc;
1219 #if 0
1220     uint16_t smb_fmt;     /* Data Block -- 01 */
1221     uint16_t smb_dlen;    /* length of data */
1222     uint8_t smb_buf[];    /* data */
1223 #endif
1224 } SmbWriteAndUnlockReq;
1225 
1226 typedef struct _SmbWriteAndUnlockResp   /* smb_wct = 1 */
1227 {
1228     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1229     uint16_t smb_cnt;     /* count */
1230     uint16_t smb_bcc;     /* must be 0 */
1231 
1232 } SmbWriteAndUnlockResp;
1233 
SmbWriteAndUnlockReqFid(const SmbWriteAndUnlockReq * req)1234 static inline uint16_t SmbWriteAndUnlockReqFid(const SmbWriteAndUnlockReq *req)
1235 {
1236     return SmbNtohs(&req->smb_fid);
1237 }
1238 
SmbWriteAndUnlockReqCount(const SmbWriteAndUnlockReq * req)1239 static inline uint16_t SmbWriteAndUnlockReqCount(const SmbWriteAndUnlockReq *req)
1240 {
1241     return SmbNtohs(&req->smb_cnt);
1242 }
1243 
SmbWriteAndUnlockReqOffset(const SmbWriteAndUnlockReq * req)1244 static inline uint32_t SmbWriteAndUnlockReqOffset(const SmbWriteAndUnlockReq *req)
1245 {
1246     return SmbNtohl(&req->smb_write_offset);
1247 }
1248 
1249 /********************************************************************
1250  * SMB_COM_READ_RAW
1251  ********************************************************************/
1252 typedef struct _SmbReadRawReq   /* smb_wct = 8 */
1253 {
1254     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1255     uint16_t smb_fid;        /* file handle */
1256     uint32_t smb_offset;     /* offset in file to begin read */
1257     uint16_t smb_maxcnt;     /* max number of bytes to return (max 65,535) */
1258     uint16_t smb_mincnt;     /* min number of bytes to return (normally 0) */
1259     uint32_t smb_timeout;    /* number of milliseconds to wait for completion */
1260     uint16_t smb_rsvd;       /* reserved */
1261     uint16_t smb_bcc;        /* value = 0 */
1262 
1263 } SmbReadRawReq;
1264 
1265 typedef struct _SmbReadRawExtReq   /* smb_wct = 10 */
1266 {
1267     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1268     uint16_t smb_fid;        /* file handle */
1269     uint32_t smb_offset;     /* offset in file to begin read */
1270     uint16_t smb_maxcnt;     /* max number of bytes to return (max 65,535) */
1271     uint16_t smb_mincnt;     /* min number of bytes to return (normally 0) */
1272     uint32_t smb_timeout;    /* number of milliseconds to wait for completion */
1273     uint16_t smb_rsvd;       /* reserved */
1274     uint32_t smb_off_high;   /* high offset in file to begin write */
1275     uint16_t smb_bcc;        /* value = 0 */
1276 
1277 } SmbReadRawExtReq;
1278 
1279 /* Read Raw response is raw data wrapped in NetBIOS header */
1280 
SmbReadRawReqFid(const SmbReadRawReq * req)1281 static inline uint16_t SmbReadRawReqFid(const SmbReadRawReq *req)
1282 {
1283     return SmbNtohs(&req->smb_fid);
1284 }
1285 
SmbReadRawReqOffset(const SmbReadRawExtReq * req)1286 static inline uint64_t SmbReadRawReqOffset(const SmbReadRawExtReq *req)
1287 {
1288     if (req->smb_wct == 8)
1289         return (uint64_t)SmbNtohl(&req->smb_offset);
1290     return (uint64_t)SmbNtohl(&req->smb_off_high) << 32 | (uint64_t)SmbNtohl(&req->smb_offset);
1291 }
1292 
1293 /********************************************************************
1294  * SMB_COM_WRITE_RAW
1295  ********************************************************************/
1296 typedef struct _SmbWriteRawReq
1297 {
1298     uint8_t  smb_wct;      /* value = 12 */
1299     uint16_t smb_fid;      /* file handle */
1300     uint16_t smb_tcount;   /* total bytes (including this buf, 65,535 max ) */
1301     uint16_t smb_rsvd;     /* reserved */
1302     uint32_t smb_offset;   /* offset in file to begin write */
1303     uint32_t smb_timeout;  /* number of milliseconds to wait for completion */
1304     uint16_t smb_wmode;    /* write mode:
1305                               bit0 - complete write to disk and send final result response
1306                               bit1 - return smb_remaining (pipes/devices only) */
1307     uint32_t smb_rsvd2;    /* reserved */
1308     uint16_t smb_dsize;    /* number of data bytes this buffer (min value = 0) */
1309     uint16_t smb_doff;     /* offset (from start of SMB hdr) to data bytes */
1310     uint16_t smb_bcc;      /* total bytes (including pad bytes) following */
1311 #if 0
1312     uint8_t  smb_pad[];    /* (optional) to pad to word or dword boundary */
1313     uint8_t  smb_data[*];  /* data bytes (* = value of smb_dsize) */
1314 #endif
1315 } SmbWriteRawReq;
1316 
1317 typedef struct _SmbWriteRawExtReq
1318 {
1319     uint8_t  smb_wct;      /* value = 14 */
1320     uint16_t smb_fid;      /* file handle */
1321     uint16_t smb_tcount;   /* total bytes (including this buf, 65,535 max ) */
1322     uint16_t smb_rsvd;     /* reserved */
1323     uint32_t smb_offset;   /* offset in file to begin write */
1324     uint32_t smb_timeout;  /* number of milliseconds to wait for completion */
1325     uint16_t smb_wmode;    /* write mode:
1326                               bit0 - complete write to disk and send final result response
1327                               bit1 - return smb_remaining (pipes/devices only) */
1328     uint32_t smb_rsvd2;    /* reserved */
1329     uint16_t smb_dsize;    /* number of data bytes this buffer (min value = 0) */
1330     uint16_t smb_doff;     /* offset (from start of SMB hdr) to data bytes */
1331     uint32_t smb_off_high; /* high offset in file to begin write */
1332     uint16_t smb_bcc;      /* total bytes (including pad bytes) following */
1333 #if 0
1334     uint8_t  smb_pad[];    /* (optional) to pad to word or dword boundary */
1335     uint8_t  smb_data[*];  /* data bytes (* = value of smb_dsize) */
1336 #endif
1337 } SmbWriteRawExtReq;
1338 
1339 typedef struct _SmbWriteRawInterimResp
1340 {
1341     uint8_t  smb_wct;        /* value = 1 */
1342     uint16_t smb_remaining;  /* bytes remaining to be read (pipes/devices only) */
1343     uint16_t smb_bcc;        /* value = 0 */
1344 
1345 } SmbWriteRawInterimResp;
1346 
SmbWriteRawReqTotalCount(const SmbWriteRawReq * req)1347 static inline uint16_t SmbWriteRawReqTotalCount(const SmbWriteRawReq *req)
1348 {
1349     return SmbNtohs(&req->smb_tcount);
1350 }
1351 
SmbWriteRawReqWriteThrough(const SmbWriteRawReq * req)1352 static inline bool SmbWriteRawReqWriteThrough(const SmbWriteRawReq *req)
1353 {
1354     return SmbNtohs(&req->smb_wmode) & 0x0001;
1355 }
1356 
SmbWriteRawReqFid(const SmbWriteRawReq * req)1357 static inline uint16_t SmbWriteRawReqFid(const SmbWriteRawReq *req)
1358 {
1359     return SmbNtohs(&req->smb_fid);
1360 }
1361 
SmbWriteRawReqDataOff(const SmbWriteRawReq * req)1362 static inline uint16_t SmbWriteRawReqDataOff(const SmbWriteRawReq *req)
1363 {
1364     return SmbNtohs(&req->smb_doff);
1365 }
1366 
SmbWriteRawReqDataCnt(const SmbWriteRawReq * req)1367 static inline uint16_t SmbWriteRawReqDataCnt(const SmbWriteRawReq *req)
1368 {
1369     return SmbNtohs(&req->smb_dsize);
1370 }
1371 
SmbWriteRawReqOffset(const SmbWriteRawExtReq * req)1372 static inline uint64_t SmbWriteRawReqOffset(const SmbWriteRawExtReq *req)
1373 {
1374     if (req->smb_wct == 12)
1375         return (uint64_t)SmbNtohl(&req->smb_offset);
1376     return (uint64_t)SmbNtohl(&req->smb_off_high) << 32 | (uint64_t)SmbNtohl(&req->smb_offset);
1377 }
1378 
SmbWriteRawInterimRespRemaining(const SmbWriteRawInterimResp * resp)1379 static inline uint16_t SmbWriteRawInterimRespRemaining(const SmbWriteRawInterimResp *resp)
1380 {
1381     return SmbNtohs(&resp->smb_remaining);
1382 }
1383 
1384 /********************************************************************
1385  * SMB_COM_WRITE_COMPLETE - final response to an SMB_COM_WRITE_RAW
1386  ********************************************************************/
1387 typedef struct _SmbWriteCompleteResp
1388 {
1389     uint8_t  smb_wct;    /* value = 1 */
1390     uint16_t smb_count;  /* total number of bytes written */
1391     uint16_t smb_bcc;    /* value = 0 */
1392 
1393 } SmbWriteCompleteResp;
1394 
SmbWriteCompleteRespCount(const SmbWriteCompleteResp * resp)1395 static inline uint16_t SmbWriteCompleteRespCount(const SmbWriteCompleteResp *resp)
1396 {
1397     return SmbNtohs(&resp->smb_count);
1398 }
1399 
1400 /********************************************************************
1401  * SMB_COM_TRANSACTION
1402  ********************************************************************/
1403 typedef struct _SmbTransactionReq   /* smb_wct = 14 + value of smb_suwcnt */
1404 {
1405     /* Note all subcommands use a setup count of 2 */
1406     uint8_t  smb_wct;      /* count of 16-bit words that follow */
1407     uint16_t smb_tpscnt;   /* total number of parameter bytes being sent */
1408     uint16_t smb_tdscnt;   /* total number of data bytes being sent */
1409     uint16_t smb_mprcnt;   /* max number of parameter bytes to return */
1410     uint16_t smb_mdrcnt;   /* max number of data bytes to return */
1411     uint8_t  smb_msrcnt;   /* max number of setup words to return */
1412     uint8_t  smb_rsvd;     /* reserved (pad above to word) */
1413     uint16_t smb_flags;    /* additional information:
1414                               bit 0 - if set, also disconnect TID in smb_tid
1415                               bit 1 - if set, transaction is one way (no final response) */
1416     uint32_t smb_timeout;  /* number of milliseconds to wait for completion */
1417     uint16_t smb_rsvd1;    /* reserved */
1418     uint16_t smb_pscnt;    /* number of parameter bytes being sent this buffer */
1419     uint16_t smb_psoff;    /* offset (from start of SMB hdr) to parameter bytes */
1420     uint16_t smb_dscnt;    /* number of data bytes being sent this buffer */
1421     uint16_t smb_dsoff;    /* offset (from start of SMB hdr) to data bytes */
1422     uint8_t  smb_suwcnt;   /* set up word count */
1423     uint8_t  smb_rsvd2;    /* reserved (pad above to word) */
1424     uint16_t smb_setup1;   /* function (see below)
1425                                 TRANS_SET_NM_PIPE_STATE   = 0x0001
1426                                 TRANS_RAW_READ_NMPIPE     = 0x0011
1427                                 TRANS_QUERY_NMPIPE_STATE  = 0x0021
1428                                 TRANS_QUERY_NMPIPE_INFO   = 0x0022
1429                                 TRANS_PEEK_NMPIPE         = 0x0023
1430                                 TRANS_TRANSACT_NMPIPE     = 0x0026
1431                                 TRANS_RAW_WRITE_NMPIPE    = 0x0031
1432                                 TRANS_READ_NMPIPE         = 0x0036
1433                                 TRANS_WRITE_NMPIPE        = 0x0037
1434                                 TRANS_WAIT_NMPIPE         = 0x0053
1435                                 TRANS_CALL_NMPIPE         = 0x0054  */
1436     uint16_t smb_setup2;   /* FID (handle) of pipe (if needed), or priority */
1437     uint16_t smb_bcc;      /* total bytes (including pad bytes) following */
1438 #if 0
1439     uint8_t  smb_name[];   /* name of transaction */
1440     uint8_t  smb_pad[];    /* (optional) to pad to word or dword boundary */
1441     uint8_t  smb_param[*]; /* param bytes (* = value of smb_pscnt) */
1442     uint8_t  smb_pad1[];   /* (optional) to pad to word or dword boundary */
1443     uint8_t  smb_data[*];  /* data bytes (* = value of smb_dscnt) */
1444 #endif
1445 } SmbTransactionReq;
1446 
1447 typedef struct _SmbTransactionInterimResp    /* smb_wct = 0 */
1448 {
1449     uint8_t   smb_wct;      /* count of 16-bit words that follow */
1450     uint16_t  smb_bcc;      /* must be 0 */
1451 
1452 } SmbTransactionInterimResp;
1453 
1454 typedef struct _SmbTransactionResp   /* smb_wct = 10 + value of smb_suwcnt */
1455 {
1456     /* Note all subcommands use a setup count of 0 */
1457     uint8_t  smb_wct;      /* count of 16-bit words that follow */
1458     uint16_t smb_tprcnt;   /* total number of parameter bytes being returned */
1459     uint16_t smb_tdrcnt;   /* total number of data bytes being returned */
1460     uint16_t smb_rsvd;     /* reserved */
1461     uint16_t smb_prcnt;    /* number of parameter bytes being returned this buf */
1462     uint16_t smb_proff;    /* offset (from start of SMB hdr) to parameter bytes */
1463     uint16_t smb_prdisp;   /* byte displacement for these parameter bytes */
1464     uint16_t smb_drcnt;    /* number of data bytes being returned this buffer */
1465     uint16_t smb_droff;    /* offset (from start of SMB hdr) to data bytes */
1466     uint16_t smb_drdisp;   /* byte displacement for these data bytes */
1467     uint8_t  smb_suwcnt;   /* set up return word count */
1468     uint8_t  smb_rsvd1;    /* reserved (pad above to word) */
1469     uint16_t smb_bcc;      /* total bytes (including pad bytes) following */
1470 #if 0
1471     uint8_t  smb_pad[];    /* (optional) to pad to word or dword boundary */
1472     uint8_t  smb_param[*]; /* param bytes (* = value of smb_prcnt) */
1473     uint8_t  smb_pad1[];   /* (optional) to pad to word or dword boundary */
1474     uint8_t  smb_data[*];  /* data bytes (* = value of smb_drcnt) */
1475 #endif
1476 } SmbTransactionResp;
1477 
SmbTransactionReqSubCom(const SmbTransactionReq * req)1478 static inline uint16_t SmbTransactionReqSubCom(const SmbTransactionReq *req)
1479 {
1480     return SmbNtohs(&req->smb_setup1);
1481 }
1482 
SmbTransactionReqFid(const SmbTransactionReq * req)1483 static inline uint16_t SmbTransactionReqFid(const SmbTransactionReq *req)
1484 {
1485     return SmbNtohs(&req->smb_setup2);
1486 }
1487 
SmbTransactionReqDisconnectTid(const SmbTransactionReq * req)1488 static inline bool SmbTransactionReqDisconnectTid(const SmbTransactionReq *req)
1489 {
1490     return SmbNtohs(&req->smb_flags) & 0x0001 ? true : false;
1491 }
1492 
SmbTransactionReqOneWay(const SmbTransactionReq * req)1493 static inline bool SmbTransactionReqOneWay(const SmbTransactionReq *req)
1494 {
1495     return SmbNtohs(&req->smb_flags) & 0x0002 ? true : false;
1496 }
1497 
SmbTransactionReqSetupCnt(const SmbTransactionReq * req)1498 static inline uint8_t SmbTransactionReqSetupCnt(const SmbTransactionReq *req)
1499 {
1500     return req->smb_suwcnt;
1501 }
1502 
SmbTransactionReqTotalDataCnt(const SmbTransactionReq * req)1503 static inline uint16_t SmbTransactionReqTotalDataCnt(const SmbTransactionReq *req)
1504 {
1505     return SmbNtohs(&req->smb_tdscnt);
1506 }
1507 
SmbTransactionReqDataCnt(const SmbTransactionReq * req)1508 static inline uint16_t SmbTransactionReqDataCnt(const SmbTransactionReq *req)
1509 {
1510     return SmbNtohs(&req->smb_dscnt);
1511 }
1512 
SmbTransactionReqDataOff(const SmbTransactionReq * req)1513 static inline uint16_t SmbTransactionReqDataOff(const SmbTransactionReq *req)
1514 {
1515     return SmbNtohs(&req->smb_dsoff);
1516 }
1517 
SmbTransactionReqTotalParamCnt(const SmbTransactionReq * req)1518 static inline uint16_t SmbTransactionReqTotalParamCnt(const SmbTransactionReq *req)
1519 {
1520     return SmbNtohs(&req->smb_tpscnt);
1521 }
1522 
SmbTransactionReqParamCnt(const SmbTransactionReq * req)1523 static inline uint16_t SmbTransactionReqParamCnt(const SmbTransactionReq *req)
1524 {
1525     return SmbNtohs(&req->smb_pscnt);
1526 }
1527 
SmbTransactionReqParamOff(const SmbTransactionReq * req)1528 static inline uint16_t SmbTransactionReqParamOff(const SmbTransactionReq *req)
1529 {
1530     return SmbNtohs(&req->smb_psoff);
1531 }
1532 
SmbTransactionRespTotalDataCnt(const SmbTransactionResp * resp)1533 static inline uint16_t SmbTransactionRespTotalDataCnt(const SmbTransactionResp *resp)
1534 {
1535     return SmbNtohs(&resp->smb_tdrcnt);
1536 }
1537 
SmbTransactionRespDataCnt(const SmbTransactionResp * resp)1538 static inline uint16_t SmbTransactionRespDataCnt(const SmbTransactionResp *resp)
1539 {
1540     return SmbNtohs(&resp->smb_drcnt);
1541 }
1542 
SmbTransactionRespDataOff(const SmbTransactionResp * resp)1543 static inline uint16_t SmbTransactionRespDataOff(const SmbTransactionResp *resp)
1544 {
1545     return SmbNtohs(&resp->smb_droff);
1546 }
1547 
SmbTransactionRespDataDisp(const SmbTransactionResp * resp)1548 static inline uint16_t SmbTransactionRespDataDisp(const SmbTransactionResp *resp)
1549 {
1550     return SmbNtohs(&resp->smb_drdisp);
1551 }
1552 
SmbTransactionRespTotalParamCnt(const SmbTransactionResp * resp)1553 static inline uint16_t SmbTransactionRespTotalParamCnt(const SmbTransactionResp *resp)
1554 {
1555     return SmbNtohs(&resp->smb_tprcnt);
1556 }
1557 
SmbTransactionRespParamCnt(const SmbTransactionResp * resp)1558 static inline uint16_t SmbTransactionRespParamCnt(const SmbTransactionResp *resp)
1559 {
1560     return SmbNtohs(&resp->smb_prcnt);
1561 }
1562 
SmbTransactionRespParamOff(const SmbTransactionResp * resp)1563 static inline uint16_t SmbTransactionRespParamOff(const SmbTransactionResp *resp)
1564 {
1565     return SmbNtohs(&resp->smb_proff);
1566 }
1567 
SmbTransactionRespParamDisp(const SmbTransactionResp * resp)1568 static inline uint16_t SmbTransactionRespParamDisp(const SmbTransactionResp *resp)
1569 {
1570     return SmbNtohs(&resp->smb_prdisp);
1571 }
1572 
1573 // Flags for TRANS_SET_NMPIPE_STATE parameters
1574 #define PIPE_STATE_NON_BLOCKING  0x8000
1575 #define PIPE_STATE_MESSAGE_MODE  0x0100
1576 
1577 /********************************************************************
1578  * SMB_COM_TRANSACTION_SECONDARY
1579  *  Continuation command for SMB_COM_TRANSACTION requests if all
1580  *  data wasn't sent.
1581  ********************************************************************/
1582 typedef struct _SmbTransactionSecondaryReq   /* smb_wct = 8 */
1583 {
1584     uint8_t  smb_wct;      /* count of 16-bit words that follow */
1585     uint16_t smb_tpscnt;   /* total number of parameter bytes being sent */
1586     uint16_t smb_tdscnt;   /* total number of data bytes being sent */
1587     uint16_t smb_pscnt;    /* number of parameter bytes being sent this buffer */
1588     uint16_t smb_psoff;    /* offset (from start of SMB hdr) to parameter bytes */
1589     uint16_t smb_psdisp;   /* byte displacement for these parameter bytes */
1590     uint16_t smb_dscnt;    /* number of data bytes being sent this buffer */
1591     uint16_t smb_dsoff;    /* offset (from start of SMB hdr) to data bytes */
1592     uint16_t smb_dsdisp;   /* byte displacement for these data bytes */
1593     uint16_t smb_bcc;      /* total bytes (including pad bytes) following */
1594 #if 0
1595     uint8_t  smb_pad[];    /* (optional) to pad to word or dword boundary */
1596     uint8_t  smb_param[*]; /* param bytes (* = value of smb_pscnt) */
1597     uint8_t  smb_pad1[];   /* (optional) to pad to word or dword boundary */
1598     uint8_t  smb_data[*];  /* data bytes (* = value of smb_dscnt) */
1599 #endif
1600 } SmbTransactionSecondaryReq;
1601 
SmbTransactionSecondaryReqTotalDataCnt(const SmbTransactionSecondaryReq * req)1602 static inline uint16_t SmbTransactionSecondaryReqTotalDataCnt(const SmbTransactionSecondaryReq *req)
1603 {
1604     return SmbNtohs(&req->smb_tdscnt);
1605 }
1606 
SmbTransactionSecondaryReqDataCnt(const SmbTransactionSecondaryReq * req)1607 static inline uint16_t SmbTransactionSecondaryReqDataCnt(const SmbTransactionSecondaryReq *req)
1608 {
1609     return SmbNtohs(&req->smb_dscnt);
1610 }
1611 
SmbTransactionSecondaryReqDataOff(const SmbTransactionSecondaryReq * req)1612 static inline uint16_t SmbTransactionSecondaryReqDataOff(const SmbTransactionSecondaryReq *req)
1613 {
1614     return SmbNtohs(&req->smb_dsoff);
1615 }
1616 
SmbTransactionSecondaryReqDataDisp(const SmbTransactionSecondaryReq * req)1617 static inline uint16_t SmbTransactionSecondaryReqDataDisp(const SmbTransactionSecondaryReq *req)
1618 {
1619     return SmbNtohs(&req->smb_dsdisp);
1620 }
1621 
SmbTransactionSecondaryReqTotalParamCnt(const SmbTransactionSecondaryReq * req)1622 static inline uint16_t SmbTransactionSecondaryReqTotalParamCnt(const SmbTransactionSecondaryReq *req)
1623 {
1624     return SmbNtohs(&req->smb_tpscnt);
1625 }
1626 
SmbTransactionSecondaryReqParamCnt(const SmbTransactionSecondaryReq * req)1627 static inline uint16_t SmbTransactionSecondaryReqParamCnt(const SmbTransactionSecondaryReq *req)
1628 {
1629     return SmbNtohs(&req->smb_pscnt);
1630 }
1631 
SmbTransactionSecondaryReqParamOff(const SmbTransactionSecondaryReq * req)1632 static inline uint16_t SmbTransactionSecondaryReqParamOff(const SmbTransactionSecondaryReq *req)
1633 {
1634     return SmbNtohs(&req->smb_psoff);
1635 }
1636 
SmbTransactionSecondaryReqParamDisp(const SmbTransactionSecondaryReq * req)1637 static inline uint16_t SmbTransactionSecondaryReqParamDisp(const SmbTransactionSecondaryReq *req)
1638 {
1639     return SmbNtohs(&req->smb_psdisp);
1640 }
1641 
1642 /********************************************************************
1643  * SMB_COM_WRITE_AND_CLOSE
1644  ********************************************************************/
1645 typedef struct _SmbWriteAndCloseReq   /* smb_wct = 6 */
1646 {
1647     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1648     uint16_t smb_fid;     /* file handle (close after write) */
1649     uint16_t smb_count;   /* number of bytes to write */
1650     uint32_t smb_offset;  /* offset in file to begin write */
1651     uint32_t smb_mtime;   /* modification time */
1652     uint16_t smb_bcc;     /* 1 (for pad) + value of smb_count */
1653 #if 0
1654     uint8_t  smb_pad;     /* force data to dword boundary */
1655     uint8_t  smb_data[];  /* data */
1656 #endif
1657 } SmbWriteAndCloseReq;
1658 
1659 typedef struct _SmbWriteAndCloseExtReq   /* smb_wct = 12 */
1660 {
1661     uint8_t  smb_wct;     /* count of 16-bit words that follow */
1662     uint16_t smb_fid;     /* file handle (close after write) */
1663     uint16_t smb_count;   /* number of bytes to write */
1664     uint32_t smb_offset;  /* offset in file to begin write */
1665     uint32_t smb_mtime;   /* modification time */
1666     uint32_t smb_rsvd1;   /* Optional */
1667     uint32_t smb_rsvd2;   /* Optional */
1668     uint32_t smb_rsvd3;   /* Optional */
1669     uint16_t smb_bcc;     /* 1 (for pad) + value of smb_count */
1670 #if 0
1671     uint8_t  smb_pad;     /* force data to dword boundary */
1672     uint8_t  smb_data[];  /* data */
1673 #endif
1674 } SmbWriteAndCloseExtReq;
1675 
1676 typedef struct _SmbWriteAndCloseResp   /* smb_wct = 1 */
1677 {
1678     uint8_t  smb_wct;    /* count of 16-bit words that follow */
1679     uint16_t smb_count;  /* number of bytes written */
1680     uint16_t smb_bcc;    /* must be 0 */
1681 
1682 } SmbWriteAndCloseResp;
1683 
SmbWriteAndCloseReqFid(const SmbWriteAndCloseReq * req)1684 static inline uint16_t SmbWriteAndCloseReqFid(const SmbWriteAndCloseReq *req)
1685 {
1686     return SmbNtohs(&req->smb_fid);
1687 }
1688 
SmbWriteAndCloseReqCount(const SmbWriteAndCloseReq * req)1689 static inline uint16_t SmbWriteAndCloseReqCount(const SmbWriteAndCloseReq *req)
1690 {
1691     return SmbNtohs(&req->smb_count);
1692 }
1693 
SmbWriteAndCloseReqOffset(const SmbWriteAndCloseReq * req)1694 static inline uint32_t SmbWriteAndCloseReqOffset(const SmbWriteAndCloseReq *req)
1695 {
1696     return SmbNtohl(&req->smb_offset);
1697 }
1698 
SmbWriteAndCloseRespCount(const SmbWriteAndCloseResp * resp)1699 static inline uint16_t SmbWriteAndCloseRespCount(const SmbWriteAndCloseResp *resp)
1700 {
1701     return SmbNtohs(&resp->smb_count);
1702 }
1703 
1704 /********************************************************************
1705  * SMB_COM_OPEN_ANDX
1706  ********************************************************************/
1707 typedef struct _SmbOpenAndXReq   /* smb_wct = 15 */
1708 {
1709     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1710     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1711     uint8_t  smb_reh2;       /* reserved (must be zero) */
1712     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1713     uint16_t smb_flags;      /* additional information:
1714                                 bit 0 - if set, return additional information
1715                                 bit 1 - if set, set single user total file lock (if only access)
1716                                 bit 2 - if set, the server should notify the consumer on any
1717                                         action which can modify the file (delete, setattrib,
1718                                         rename, etc.). if not set, the server need only notify
1719                                         the consumer on another open request. This bit only has
1720                                         meaning if bit 1 is set. */
1721     uint16_t smb_mode;       /* file open mode */
1722     uint16_t smb_sattr;      /* search attributes */
1723     uint16_t smb_attr;       /* file attributes (for create) */
1724     uint32_t smb_time;       /* create time */
1725     uint16_t smb_ofun;       /* open function */
1726     uint32_t smb_size;       /* bytes to reserve on "create" or "truncate" */
1727     uint32_t smb_timeout;    /* max milliseconds to wait for resource to open */
1728     uint32_t smb_rsvd;       /* reserved (must be zero) */
1729     uint16_t smb_bcc;        /* minimum value = 1 */
1730 #if 0
1731     uint8_t  smb_pathname[]; /* file pathname */
1732 #endif
1733 } SmbOpenAndXReq;
1734 
1735 typedef struct _SmbOpenAndXResp   /* smb_wct = 15 */
1736 {
1737     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1738     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1739     uint8_t  smb_res2;       /* reserved (pad to word) */
1740     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1741     uint16_t smb_fid;        /* file handle */
1742     uint16_t smb_attribute;  /* attributes of file or device */
1743     uint32_t smb_time;       /* last modification time */
1744     uint32_t smb_size;       /* current file size */
1745     uint16_t smb_access;     /* access permissions actually allowed */
1746     uint16_t smb_type;       /* file type */
1747     uint16_t smb_state;      /* state of IPC device (e.g. pipe) */
1748     uint16_t smb_action;     /* action taken */
1749     uint32_t smb_fileid;     /* server unique file id */
1750     uint16_t smb_rsvd;       /* reserved */
1751     uint16_t smb_bcc;        /* value = 0 */
1752 
1753 } SmbOpenAndXResp;
1754 
SmbOpenAndXReqAllocSize(const SmbOpenAndXReq * req)1755 static inline uint32_t SmbOpenAndXReqAllocSize(const SmbOpenAndXReq *req)
1756 {
1757     return SmbNtohl(&req->smb_size);
1758 }
1759 
SmbOpenAndXReqFileAttrs(const SmbOpenAndXReq * req)1760 static inline uint16_t SmbOpenAndXReqFileAttrs(const SmbOpenAndXReq *req)
1761 {
1762     return SmbNtohs(&req->smb_attr);
1763 }
1764 
SmbOpenAndXRespFid(const SmbOpenAndXResp * resp)1765 static inline uint16_t SmbOpenAndXRespFid(const SmbOpenAndXResp *resp)
1766 {
1767     return SmbNtohs(&resp->smb_fid);
1768 }
1769 
SmbOpenAndXRespFileAttrs(const SmbOpenAndXResp * resp)1770 static inline uint16_t SmbOpenAndXRespFileAttrs(const SmbOpenAndXResp *resp)
1771 {
1772     return SmbNtohs(&resp->smb_attribute);
1773 }
1774 
SmbOpenAndXRespFileSize(const SmbOpenAndXResp * resp)1775 static inline uint32_t SmbOpenAndXRespFileSize(const SmbOpenAndXResp *resp)
1776 {
1777     return SmbNtohl(&resp->smb_size);
1778 }
1779 
SmbOpenAndXRespResourceType(const SmbOpenAndXResp * resp)1780 static inline uint16_t SmbOpenAndXRespResourceType(const SmbOpenAndXResp *resp)
1781 {
1782     return SmbNtohs(&resp->smb_type);
1783 }
1784 
1785 #define SMB_OPEN_RESULT__EXISTED    0x0001
1786 #define SMB_OPEN_RESULT__CREATED    0x0002
1787 #define SMB_OPEN_RESULT__TRUNCATED  0x0003
1788 
SmbOpenAndXRespOpenResults(const SmbOpenAndXResp * resp)1789 static inline uint16_t SmbOpenAndXRespOpenResults(const SmbOpenAndXResp *resp)
1790 {
1791     return SmbNtohs(&resp->smb_action);
1792 }
1793 
SmbOpenResultRead(const uint16_t open_results)1794 static inline bool SmbOpenResultRead(const uint16_t open_results)
1795 {
1796     return ((open_results & 0x00FF) == SMB_OPEN_RESULT__EXISTED);
1797 }
1798 
SmbResourceTypeDisk(const uint16_t resource_type)1799 static inline bool SmbResourceTypeDisk(const uint16_t resource_type)
1800 {
1801     return resource_type == SMB_FILE_TYPE_DISK;
1802 }
1803 
1804 /********************************************************************
1805  * SMB_COM_READ_ANDX
1806  ********************************************************************/
1807 typedef struct _SmbReadAndXReq   /* smb_wct = 10 */
1808 {
1809     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1810     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1811     uint8_t  smb_reh2;       /* reserved (must be zero) */
1812     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1813     uint16_t smb_fid;        /* file handle */
1814     uint32_t smb_offset;     /* offset in file to begin read */
1815     uint16_t smb_maxcnt;     /* max number of bytes to return */
1816     uint16_t smb_mincnt;     /* min number of bytes to return */
1817     uint32_t smb_timeout;    /* number of milliseconds to wait for completion */
1818     uint16_t smb_countleft;  /* bytes remaining to satisfy user’s request */
1819     uint16_t smb_bcc;        /* value = 0 */
1820 
1821 } SmbReadAndXReq;
1822 
1823 typedef struct _SmbReadAndXExtReq   /* smb_wct = 12 */
1824 {
1825     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1826     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1827     uint8_t  smb_reh2;       /* reserved (must be zero) */
1828     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1829     uint16_t smb_fid;        /* file handle */
1830     uint32_t smb_offset;     /* low offset in file to begin read */
1831     uint16_t smb_maxcnt;     /* max number of bytes to return */
1832     uint16_t smb_mincnt;     /* min number of bytes to return */
1833     uint32_t smb_timeout;    /* number of milliseconds to wait for completion */
1834     uint16_t smb_countleft;  /* bytes remaining to satisfy user’s request */
1835     uint32_t smb_off_high;   /* high offset in file to begin read */
1836     uint16_t smb_bcc;        /* value = 0 */
1837 
1838 } SmbReadAndXExtReq;
1839 
1840 typedef struct _SmbReadAndXResp    /* smb_wct = 12 */
1841 {
1842     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1843     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1844     uint8_t  smb_res2;       /* reserved (pad to word) */
1845     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1846     uint16_t smb_remaining;  /* bytes remaining to be read (pipes/devices only) */
1847     uint32_t smb_rsvd;       /* reserved */
1848     uint16_t smb_dsize;      /* number of data bytes (minimum value = 0) */
1849     uint16_t smb_doff;       /* offset (from start of SMB hdr) to data bytes */
1850     uint16_t smb_dsize_high; /* high bytes of data size */
1851     uint32_t smb_rsvd1;      /* reserved */
1852     uint32_t smb_rsvd2;      /* reserved */
1853     uint16_t smb_bcc;        /* total bytes (including pad bytes) following */
1854 #if 0
1855     uint8_t  smb_pad[];      /* (optional) to pad to word or dword boundary */
1856     uint8_t  smb_data[*];    /* data bytes (* = value of smb_dsize) */
1857 #endif
1858 } SmbReadAndXResp;
1859 
SmbReadAndXReqFid(const SmbReadAndXReq * req)1860 static inline uint16_t SmbReadAndXReqFid(const SmbReadAndXReq *req)
1861 {
1862     return SmbNtohs(&req->smb_fid);
1863 }
1864 
SmbReadAndXReqOffset(const SmbReadAndXExtReq * req)1865 static inline uint64_t SmbReadAndXReqOffset(const SmbReadAndXExtReq *req)
1866 {
1867     if (req->smb_wct == 10)
1868         return (uint64_t)SmbNtohl(&req->smb_offset);
1869     return (uint64_t)SmbNtohl(&req->smb_off_high) << 32 | (uint64_t)SmbNtohl(&req->smb_offset);
1870 }
1871 
SmbReadAndXRespDataOff(const SmbReadAndXResp * req)1872 static inline uint16_t SmbReadAndXRespDataOff(const SmbReadAndXResp *req)
1873 {
1874     return SmbNtohs(&req->smb_doff);
1875 }
1876 
SmbReadAndXRespDataCnt(const SmbReadAndXResp * resp)1877 static inline uint32_t SmbReadAndXRespDataCnt(const SmbReadAndXResp *resp)
1878 {
1879     return (uint32_t)SmbNtohs(&resp->smb_dsize_high) << 16 | (uint32_t)SmbNtohs(&resp->smb_dsize);
1880 }
1881 
1882 /********************************************************************
1883  * SMB_COM_WRITE_ANDX
1884  ********************************************************************/
1885 typedef struct _SmbWriteAndXReq   /* smb_wct = 12 */
1886 {
1887     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1888     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1889     uint8_t  smb_reh2;       /* reserved (must be zero) */
1890     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1891     uint16_t smb_fid;        /* file handle */
1892     uint32_t smb_offset;     /* offset in file to begin write */
1893     uint32_t smb_timeout;    /* number of milliseconds to wait for completion */
1894     uint16_t smb_wmode;      /* write mode:
1895                                 bit0 - complete write before return (write through)
1896                                 bit1 - return smb_remaining (pipes/devices only)
1897                                 bit2 - use WriteRawNamedPipe (pipes only)
1898                                 bit3 - this is the start of a message (pipes only) */
1899     uint16_t smb_countleft;  /* bytes remaining to write to satisfy user’s request */
1900     uint16_t smb_dsize_high; /* high bytes of data size */
1901     uint16_t smb_dsize;      /* number of data bytes in buffer (min value = 0) */
1902     uint16_t smb_doff;       /* offset (from start of SMB hdr) to data bytes */
1903     uint16_t smb_bcc;        /* total bytes (including pad bytes) following */
1904 #if 0
1905     uint8_t  smb_pad[];      /* (optional) to pad to word or dword boundary */
1906     uint8_t  smb_data[*];    /* data bytes (* = value of smb_dsize) */
1907 #endif
1908 } SmbWriteAndXReq;
1909 
1910 typedef struct _SmbWriteAndXExtReq   /* smb_wct = 14 */
1911 {
1912     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1913     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1914     uint8_t  smb_reh2;       /* reserved (must be zero) */
1915     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1916     uint16_t smb_fid;        /* file handle */
1917     uint32_t smb_offset;     /* low offset in file to begin write */
1918     uint32_t smb_timeout;    /* number of milliseconds to wait for completion */
1919     uint16_t smb_wmode;      /* write mode:
1920                                 bit0 - complete write before return (write through)
1921                                 bit1 - return smb_remaining (pipes/devices only)
1922                                 bit2 - use WriteRawNamedPipe (pipes only)
1923                                 bit3 - this is the start of a message (pipes only) */
1924     uint16_t smb_countleft;  /* bytes remaining to write to satisfy user’s request */
1925     uint16_t smb_dsize_high; /* high bytes of data size */
1926     uint16_t smb_dsize;      /* number of data bytes in buffer (min value = 0) */
1927     uint16_t smb_doff;       /* offset (from start of SMB hdr) to data bytes */
1928     uint32_t smb_off_high;   /* high offset in file to begin write */
1929     uint16_t smb_bcc;        /* total bytes (including pad bytes) following */
1930 #if 0
1931     uint8_t  smb_pad[];      /* (optional) to pad to word or dword boundary */
1932     uint8_t  smb_data[*];    /* data bytes (* = value of smb_dsize) */
1933 #endif
1934 } SmbWriteAndXExtReq;
1935 
1936 typedef struct _SmbWriteAndXResp   /* smb_wct = 6 */
1937 {
1938     uint8_t  smb_wct;        /* count of 16-bit words that follow */
1939     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
1940     uint8_t  smb_res2;       /* reserved (pad to word) */
1941     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
1942     uint16_t smb_count;      /* number of bytes written */
1943     uint16_t smb_remaining;  /* bytes remaining to be read (pipes/devices only) */
1944     uint16_t smb_count_high; /* high order bytes of data count */
1945     uint16_t smb_rsvd;       /* reserved */
1946     uint16_t smb_bcc;        /* value = 0 */
1947 
1948 } SmbWriteAndXResp;
1949 
SmbWriteAndXReqFid(const SmbWriteAndXReq * req)1950 static inline uint16_t SmbWriteAndXReqFid(const SmbWriteAndXReq *req)
1951 {
1952     return SmbNtohs(&req->smb_fid);
1953 }
1954 
SmbWriteAndXReqDataOff(const SmbWriteAndXReq * req)1955 static inline uint16_t SmbWriteAndXReqDataOff(const SmbWriteAndXReq *req)
1956 {
1957     return SmbNtohs(&req->smb_doff);
1958 }
1959 
SmbWriteAndXReqRemaining(const SmbWriteAndXReq * req)1960 static inline uint16_t SmbWriteAndXReqRemaining(const SmbWriteAndXReq *req)
1961 {
1962     return SmbNtohs(&req->smb_countleft);
1963 }
1964 
SmbWriteAndXReqOffset(const SmbWriteAndXExtReq * req)1965 static inline uint64_t SmbWriteAndXReqOffset(const SmbWriteAndXExtReq *req)
1966 {
1967     if (req->smb_wct == 12)
1968         return (uint64_t)SmbNtohl(&req->smb_offset);
1969     return (uint64_t)SmbNtohl(&req->smb_off_high) << 32 | (uint64_t)SmbNtohl(&req->smb_offset);
1970 }
1971 
SmbWriteAndXReqDataCnt(const SmbWriteAndXReq * req)1972 static inline uint32_t SmbWriteAndXReqDataCnt(const SmbWriteAndXReq *req)
1973 {
1974     return (uint32_t)SmbNtohs(&req->smb_dsize_high) << 16 | (uint32_t)SmbNtohs(&req->smb_dsize);
1975 }
1976 
SmbWriteAndXReqWriteMode(const SmbWriteAndXReq * req)1977 static inline uint16_t SmbWriteAndXReqWriteMode(const SmbWriteAndXReq *req)
1978 {
1979     return SmbNtohs(&req->smb_wmode);
1980 }
1981 
SmbWriteAndXReqStartRaw(const SmbWriteAndXReq * req)1982 static inline bool SmbWriteAndXReqStartRaw(const SmbWriteAndXReq *req)
1983 {
1984     return ((SmbNtohs(&req->smb_wmode) & 0x000c) == 0x000c) ? true : false;
1985 }
1986 
SmbWriteAndXReqRaw(const SmbWriteAndXReq * req)1987 static inline bool SmbWriteAndXReqRaw(const SmbWriteAndXReq *req)
1988 {
1989     return ((SmbNtohs(&req->smb_wmode) & 0x000c) == 0x0004) ? true : false;
1990 }
1991 
SmbWriteAndXRespCnt(const SmbWriteAndXResp * resp)1992 static inline uint16_t SmbWriteAndXRespCnt(const SmbWriteAndXResp *resp)
1993 {
1994     return SmbNtohs(&resp->smb_count);
1995 }
1996 
1997 /********************************************************************
1998  * SMB_COM_TRANSACTION2
1999  ********************************************************************/
2000 typedef struct _SmbTransaction2Req
2001 {
2002     uint8_t  smb_wct;
2003     uint16_t smb_total_param_count;
2004     uint16_t smb_total_data_count;
2005     uint16_t smb_max_param_count;
2006     uint16_t smb_max_data_count;
2007     uint8_t  smb_max_setup_count;
2008     uint8_t  smb_res;
2009     uint16_t smb_flags;
2010     uint32_t smb_timeout;
2011     uint16_t smb_res2;
2012     uint16_t smb_param_count;
2013     uint16_t smb_param_offset;
2014     uint16_t smb_data_count;
2015     uint16_t smb_data_offset;
2016     uint8_t  smb_setup_count;   /* Should be 1 for all subcommands */
2017     uint8_t  smb_res3;
2018     uint16_t smb_setup;  /* This is the subcommand */
2019     uint16_t smb_bcc;
2020 #if 0
2021     uint8_t smb_name[];  /* ASCII or Unicode depending on smb header flags */
2022     uint8_t pad1[];
2023     uint8_t smb_trans2_params[smb_param_count];
2024     uint8_t pad2[];
2025     uint8_t smb_trans2_data[smb_data_count];
2026 #endif
2027 } SmbTransaction2Req;
2028 
2029 typedef struct _SmbTransaction2InterimResp
2030 {
2031     uint8_t  smb_wct;
2032     uint16_t smb_bcc;
2033 
2034 } SmbTransaction2InterimResp;
2035 
2036 typedef struct _SmbTransaction2Resp
2037 {
2038     uint8_t  smb_wct;
2039     uint16_t smb_total_param_count;
2040     uint16_t smb_total_data_count;
2041     uint16_t smb_res;
2042     uint16_t smb_param_count;
2043     uint16_t smb_param_offset;
2044     uint16_t smb_param_disp;
2045     uint16_t smb_data_count;
2046     uint16_t smb_data_offset;
2047     uint16_t smb_data_disp;
2048     uint16_t smb_setup_count;  /* 0 or 1 word */
2049     uint8_t  smb_res2;
2050 #if 0
2051     uint16_t smb_setup[smb_setup_count];
2052     uint16_t smb_bcc;
2053     uint8_t pad1[];
2054     uint8_t smb_trans2_params[smb_param_count];
2055     uint8_t pad2[];
2056     uint8_t smb_trans2_data[smb_data_count];
2057 #endif
2058 } SmbTransaction2Resp;
2059 
SmbTransaction2ReqSubCom(const SmbTransaction2Req * req)2060 static inline uint16_t SmbTransaction2ReqSubCom(const SmbTransaction2Req *req)
2061 {
2062     return SmbNtohs(&req->smb_setup);
2063 }
2064 
SmbTransaction2ReqTotalParamCnt(const SmbTransaction2Req * req)2065 static inline uint16_t SmbTransaction2ReqTotalParamCnt(const SmbTransaction2Req *req)
2066 {
2067     return SmbNtohs(&req->smb_total_param_count);
2068 }
2069 
SmbTransaction2ReqParamCnt(const SmbTransaction2Req * req)2070 static inline uint16_t SmbTransaction2ReqParamCnt(const SmbTransaction2Req *req)
2071 {
2072     return SmbNtohs(&req->smb_param_count);
2073 }
2074 
SmbTransaction2ReqParamOff(const SmbTransaction2Req * req)2075 static inline uint16_t SmbTransaction2ReqParamOff(const SmbTransaction2Req *req)
2076 {
2077     return SmbNtohs(&req->smb_param_offset);
2078 }
2079 
SmbTransaction2ReqTotalDataCnt(const SmbTransaction2Req * req)2080 static inline uint16_t SmbTransaction2ReqTotalDataCnt(const SmbTransaction2Req *req)
2081 {
2082     return SmbNtohs(&req->smb_total_data_count);
2083 }
2084 
SmbTransaction2ReqDataCnt(const SmbTransaction2Req * req)2085 static inline uint16_t SmbTransaction2ReqDataCnt(const SmbTransaction2Req *req)
2086 {
2087     return SmbNtohs(&req->smb_data_count);
2088 }
2089 
SmbTransaction2ReqDataOff(const SmbTransaction2Req * req)2090 static inline uint16_t SmbTransaction2ReqDataOff(const SmbTransaction2Req *req)
2091 {
2092     return SmbNtohs(&req->smb_data_offset);
2093 }
2094 
SmbTransaction2ReqSetupCnt(const SmbTransaction2Req * req)2095 static inline uint8_t SmbTransaction2ReqSetupCnt(const SmbTransaction2Req *req)
2096 {
2097     return req->smb_setup_count;
2098 }
2099 
SmbTransaction2RespTotalParamCnt(const SmbTransaction2Resp * resp)2100 static inline uint16_t SmbTransaction2RespTotalParamCnt(const SmbTransaction2Resp *resp)
2101 {
2102     return SmbNtohs(&resp->smb_total_param_count);
2103 }
2104 
SmbTransaction2RespParamCnt(const SmbTransaction2Resp * resp)2105 static inline uint16_t SmbTransaction2RespParamCnt(const SmbTransaction2Resp *resp)
2106 {
2107     return SmbNtohs(&resp->smb_param_count);
2108 }
2109 
SmbTransaction2RespParamOff(const SmbTransaction2Resp * resp)2110 static inline uint16_t SmbTransaction2RespParamOff(const SmbTransaction2Resp *resp)
2111 {
2112     return SmbNtohs(&resp->smb_param_offset);
2113 }
2114 
SmbTransaction2RespParamDisp(const SmbTransaction2Resp * resp)2115 static inline uint16_t SmbTransaction2RespParamDisp(const SmbTransaction2Resp *resp)
2116 {
2117     return SmbNtohs(&resp->smb_param_disp);
2118 }
2119 
SmbTransaction2RespTotalDataCnt(const SmbTransaction2Resp * resp)2120 static inline uint16_t SmbTransaction2RespTotalDataCnt(const SmbTransaction2Resp *resp)
2121 {
2122     return SmbNtohs(&resp->smb_total_data_count);
2123 }
2124 
SmbTransaction2RespDataCnt(const SmbTransaction2Resp * resp)2125 static inline uint16_t SmbTransaction2RespDataCnt(const SmbTransaction2Resp *resp)
2126 {
2127     return SmbNtohs(&resp->smb_data_count);
2128 }
2129 
SmbTransaction2RespDataOff(const SmbTransaction2Resp * resp)2130 static inline uint16_t SmbTransaction2RespDataOff(const SmbTransaction2Resp *resp)
2131 {
2132     return SmbNtohs(&resp->smb_data_offset);
2133 }
2134 
SmbTransaction2RespDataDisp(const SmbTransaction2Resp * resp)2135 static inline uint16_t SmbTransaction2RespDataDisp(const SmbTransaction2Resp *resp)
2136 {
2137     return SmbNtohs(&resp->smb_data_disp);
2138 }
2139 
2140 typedef struct _SmbTrans2Open2ReqParams
2141 {
2142     uint16_t Flags;
2143     uint16_t AccessMode;
2144     uint16_t Reserved1;
2145     uint16_t FileAttributes;
2146     uint32_t CreationTime;
2147     uint16_t OpenMode;
2148     uint32_t AllocationSize;
2149     uint16_t Reserved[5];
2150 #if 0
2151     SMB_STRING FileName;
2152 #endif
2153 } SmbTrans2Open2ReqParams;
2154 
2155 typedef SmbTransaction2Req SmbTrans2Open2Req;
2156 
SmbTrans2Open2ReqAccessMode(const SmbTrans2Open2ReqParams * req)2157 static inline uint16_t SmbTrans2Open2ReqAccessMode(const SmbTrans2Open2ReqParams *req)
2158 {
2159     return SmbNtohs(&req->AccessMode);
2160 }
2161 
SmbTrans2Open2ReqFileAttrs(const SmbTrans2Open2ReqParams * req)2162 static inline uint16_t SmbTrans2Open2ReqFileAttrs(const SmbTrans2Open2ReqParams *req)
2163 {
2164     return SmbNtohs(&req->FileAttributes);
2165 }
2166 
SmbTrans2Open2ReqOpenMode(const SmbTrans2Open2ReqParams * req)2167 static inline uint16_t SmbTrans2Open2ReqOpenMode(const SmbTrans2Open2ReqParams *req)
2168 {
2169     return SmbNtohs(&req->OpenMode);
2170 }
2171 
SmbTrans2Open2ReqAllocSize(const SmbTrans2Open2ReqParams * req)2172 static inline uint32_t SmbTrans2Open2ReqAllocSize(const SmbTrans2Open2ReqParams *req)
2173 {
2174     return SmbNtohl(&req->AllocationSize);
2175 }
2176 
2177 typedef struct _SmbTrans2Open2RespParams
2178 {
2179     uint16_t smb_fid;
2180     uint16_t file_attributes;
2181     uint32_t creation_time;
2182     uint32_t file_data_size;
2183     uint16_t access_mode;
2184     uint16_t resource_type;
2185     uint16_t nm_pipe_status;
2186     uint16_t action_taken;
2187     uint32_t reserved;
2188     uint16_t extended_attribute_error_offset;
2189     uint32_t extended_attribute_length;
2190 
2191 } SmbTrans2Open2RespParams;
2192 
SmbTrans2Open2RespFid(const SmbTrans2Open2RespParams * resp)2193 static inline uint16_t SmbTrans2Open2RespFid(const SmbTrans2Open2RespParams *resp)
2194 {
2195     return SmbNtohs(&resp->smb_fid);
2196 }
2197 
SmbTrans2Open2RespFileAttrs(const SmbTrans2Open2RespParams * resp)2198 static inline uint16_t SmbTrans2Open2RespFileAttrs(const SmbTrans2Open2RespParams *resp)
2199 {
2200     return SmbNtohs(&resp->file_attributes);
2201 }
2202 
SmbTrans2Open2RespFileDataSize(const SmbTrans2Open2RespParams * resp)2203 static inline uint32_t SmbTrans2Open2RespFileDataSize(const SmbTrans2Open2RespParams *resp)
2204 {
2205     return SmbNtohl(&resp->file_data_size);
2206 }
2207 
SmbTrans2Open2RespResourceType(const SmbTrans2Open2RespParams * resp)2208 static inline uint16_t SmbTrans2Open2RespResourceType(const SmbTrans2Open2RespParams *resp)
2209 {
2210     return SmbNtohs(&resp->resource_type);
2211 }
2212 
SmbTrans2Open2RespActionTaken(const SmbTrans2Open2RespParams * resp)2213 static inline uint16_t SmbTrans2Open2RespActionTaken(const SmbTrans2Open2RespParams *resp)
2214 {
2215     return SmbNtohs(&resp->action_taken);
2216 }
2217 
2218 typedef struct _SmbTrans2Open2Resp
2219 {
2220     uint8_t  smb_wct;
2221     uint16_t smb_total_param_count;
2222     uint16_t smb_total_data_count;
2223     uint16_t smb_res;
2224     uint16_t smb_param_count;
2225     uint16_t smb_param_offset;
2226     uint16_t smb_param_disp;
2227     uint16_t smb_data_count;
2228     uint16_t smb_data_offset;
2229     uint16_t smb_data_disp;
2230     uint16_t smb_setup_count;  /* 0 */
2231     uint8_t  smb_res2;
2232     uint16_t smb_bcc;
2233 #if 0
2234     uint8_t pad1[];
2235     uint8_t smb_trans2_params[smb_param_count];
2236     uint8_t pad2[];
2237     uint8_t smb_trans2_data[smb_data_count];
2238 #endif
2239 } SmbTrans2Open2Resp;
2240 
2241 // See MS-CIFS Section 2.2.2.3.3
2242 #define SMB_INFO_STANDARD               0x0001
2243 #define SMB_INFO_QUERY_EA_SIZE          0x0002
2244 #define SMB_INFO_QUERY_EAS_FROM_LIST    0x0003
2245 #define SMB_INFO_QUERY_ALL_EAS          0x0004
2246 #define SMB_INFO_IS_NAME_VALID          0x0006
2247 #define SMB_QUERY_FILE_BASIC_INFO       0x0101
2248 #define SMB_QUERY_FILE_STANDARD_INFO    0x0102
2249 #define SMB_QUERY_FILE_EA_INFO          0x0103
2250 #define SMB_QUERY_FILE_NAME_INFO        0x0104
2251 #define SMB_QUERY_FILE_ALL_INFO         0x0107
2252 #define SMB_QUERY_FILE_ALT_NAME_INFO    0x0108
2253 #define SMB_QUERY_FILE_STREAM_INFO      0x0109
2254 #define SMB_QUERY_FILE_COMPRESSION_INFO 0x010b
2255 
2256 // See MS-SMB Section 2.2.2.3.5
2257 // For added value, see below from MS-FSCC
2258 #define SMB_INFO_PASSTHROUGH  0x03e8
2259 #define SMB_INFO_PT_FILE_STANDARD_INFO  SMB_INFO_PASSTHROUGH+5
2260 #define SMB_INFO_PT_FILE_ALL_INFO       SMB_INFO_PASSTHROUGH+18
2261 #define SMB_INFO_PT_FILE_STREAM_INFO    SMB_INFO_PASSTHROUGH+22
2262 #define SMB_INFO_PT_NETWORK_OPEN_INFO   SMB_INFO_PASSTHROUGH+34
2263 
2264 #if 0
2265 
2266 See MS-FSCC Section 2.4 File Information Classes
2267 
2268 FileDirectoryInformation 1 //Query
2269 FileFullDirectoryInformation 2 //Query
2270 FileBothDirectoryInformation 3 //Query
2271 FileBasicInformation 4 //Query, Set
2272 FileStandardInformation 5 //Query
2273 FileInternalInformation 6 //Query
2274 FileEaInformation 7 //Query
2275 FileAccessInformation 8 //Query
2276 FileNameInformation 9 //LOCAL<71>
2277 FileRenameInformation 10 //Set
2278 FileLinkInformation 11 //Set
2279 FileNamesInformation 12 //Query
2280 FileDispositionInformation 13 //Set
2281 FilePositionInformation 14 //Query, Set
2282 FileFullEaInformation 15 //Query, Set
2283 FileModeInformation 16 //Query, Set<69>
2284 FileAlignmentInformation 17 //Query
2285 FileAllInformation 18 //Query
2286 FileAllocationInformation 19 //Set
2287 FileEndOfFileInformation 20 //Set
2288 FileAlternateNameInformation 21 //Query
2289 FileStreamInformation 22 //Query
2290 FilePipeInformation 23 //Query, Set
2291 FilePipeLocalInformation 24 //Query
2292 FilePipeRemoteInformation 25 //Query
2293 FileMailslotQueryInformation 26 //LOCAL<67>
2294 FileMailslotSetInformation 27 //LOCAL<68>
2295 FileCompressionInformation 28 //Query
2296 FileObjectIdInformation 29 //LOCAL<73>
2297 
2298 FileMoveClusterInformation 31 //<70>
2299 FileQuotaInformation 32 //Query, Set<74>
2300 FileReparsePointInformation 33 //LOCAL<75>
2301 FileNetworkOpenInformation 34 //Query
2302 FileAttributeTagInformation 35 //Query
2303 FileTrackingInformation 36 //LOCAL<79>
2304 FileIdBothDirectoryInformation 37 //Query
2305 FileIdFullDirectoryInformation 38 //Query
2306 FileValidDataLengthInformation 39 //Set
2307 FileShortNameInformation 40 //Set
2308 
2309 FileSfioReserveInformation 44 //LOCAL<76>
2310 FileSfioVolumeInformation 45 //<77>
2311 FileHardLinkInformation 46 //LOCAL<65>
2312 
2313 FileNormalizedNameInformation 48 //<72>
2314 
2315 FileIdGlobalTxDirectoryInformation 50 //LOCAL<66>
2316 FileStandardLinkInformation 54 //LOCAL<78>
2317 #endif
2318 
2319 typedef struct _SmbTrans2QueryFileInfoReqParams
2320 {
2321     uint16_t fid;
2322     uint16_t information_level;
2323 
2324 } SmbTrans2QueryFileInfoReqParams;
2325 
SmbTrans2QueryFileInfoReqFid(const SmbTrans2QueryFileInfoReqParams * req)2326 static inline uint16_t SmbTrans2QueryFileInfoReqFid(const SmbTrans2QueryFileInfoReqParams *req)
2327 {
2328     return SmbNtohs(&req->fid);
2329 }
2330 
SmbTrans2QueryFileInfoReqInfoLevel(const SmbTrans2QueryFileInfoReqParams * req)2331 static inline uint16_t SmbTrans2QueryFileInfoReqInfoLevel(const SmbTrans2QueryFileInfoReqParams *req)
2332 {
2333     return SmbNtohs(&req->information_level);
2334 }
2335 
2336 typedef struct _SmbQueryInfoStandard
2337 {
2338     uint16_t CreationDate;
2339     uint16_t CreationTime;
2340     uint16_t LastAccessDate;
2341     uint16_t LastAccessTime;
2342     uint16_t LastWriteDate;
2343     uint16_t LastWriteTime;
2344     uint32_t FileDataSize;
2345     uint32_t AllocationSize;
2346     uint16_t Attributes;
2347 
2348 } SmbQueryInfoStandard;
2349 
SmbQueryInfoStandardFileDataSize(const SmbQueryInfoStandard * q)2350 static inline uint32_t SmbQueryInfoStandardFileDataSize(const SmbQueryInfoStandard *q)
2351 {
2352     return SmbNtohl(&q->FileDataSize);
2353 }
2354 
2355 typedef struct _SmbQueryInfoQueryEaSize
2356 {
2357     uint16_t CreationDate;
2358     uint16_t CreationTime;
2359     uint16_t LastAccessDate;
2360     uint16_t LastAccessTime;
2361     uint16_t LastWriteDate;
2362     uint16_t LastWriteTime;
2363     uint32_t FileDataSize;
2364     uint32_t AllocationSize;
2365     uint16_t Attributes;
2366     uint32_t EaSize;
2367 
2368 } SmbQueryInfoQueryEaSize;
2369 
SmbQueryInfoQueryEaSizeFileDataSize(const SmbQueryInfoQueryEaSize * q)2370 static inline uint32_t SmbQueryInfoQueryEaSizeFileDataSize(const SmbQueryInfoQueryEaSize *q)
2371 {
2372     return SmbNtohl(&q->FileDataSize);
2373 }
2374 
2375 typedef struct _SmbQueryFileStandardInfo
2376 {
2377     uint64_t AllocationSize;
2378     uint64_t EndOfFile;
2379     uint32_t NumberOfLinks;
2380     uint8_t DeletePending;
2381     uint8_t Directory;
2382     uint16_t Reserved;
2383 
2384 } SmbQueryFileStandardInfo;
2385 
SmbQueryFileStandardInfoEndOfFile(const SmbQueryFileStandardInfo * q)2386 static inline uint64_t SmbQueryFileStandardInfoEndOfFile(const SmbQueryFileStandardInfo *q)
2387 {
2388     return SmbNtohq(&q->EndOfFile);
2389 }
2390 
2391 typedef struct _SmbQueryFileAllInfo
2392 {
2393     // Basic Info
2394     uint64_t CreationTime;
2395     uint64_t LastAccessTime;
2396     uint64_t LastWriteTime;
2397     uint64_t LastChangeTime;
2398     uint32_t ExtFileAttributes;
2399     uint32_t Reserved1;
2400     uint64_t AllocationSize;
2401     uint64_t EndOfFile;
2402     uint32_t NumberOfLinks;
2403     uint8_t DeletePending;
2404     uint8_t Directory;
2405     uint16_t Reserved2;
2406     uint32_t EaSize;
2407     uint32_t FileNameLength;
2408 #if 0
2409     uint16_t FileName[FileNameLength/2];
2410 #endif
2411 
2412 } SmbQueryFileAllInfo;
2413 
SmbQueryFileAllInfoEndOfFile(const SmbQueryFileAllInfo * q)2414 static inline uint64_t SmbQueryFileAllInfoEndOfFile(const SmbQueryFileAllInfo *q)
2415 {
2416     return SmbNtohq(&q->EndOfFile);
2417 }
2418 
2419 typedef struct _SmbQueryPTFileAllInfo
2420 {
2421     // Basic Info
2422     uint64_t CreationTime;
2423     uint64_t LastAccessTime;
2424     uint64_t LastWriteTime;
2425     uint64_t LastChangeTime;
2426     uint32_t ExtFileAttributes;
2427     uint32_t Reserved1;
2428 
2429     // Standard Info
2430     uint64_t AllocationSize;
2431     uint64_t EndOfFile;
2432     uint32_t NumberOfLinks;
2433     uint8_t DeletePending;
2434     uint8_t Directory;
2435     uint16_t Reserved2;
2436 
2437     // Internal Info
2438     uint64_t IndexNumber;
2439 
2440     // EA Info
2441     uint32_t EaSize;
2442 
2443     // Access Info
2444     uint32_t AccessFlags;
2445 
2446     // Position Info
2447     uint64_t CurrentByteOffset;
2448 
2449     // Mode Info
2450     uint32_t Mode;
2451 
2452     // Alignment Info
2453     uint32_t AlignmentRequirement;
2454 
2455     // Name Info
2456     uint32_t FileNameLength;
2457 #if 0
2458     uint16_t FileName[FileNameLength/2];
2459 #endif
2460 
2461 } SmbQueryPTFileAllInfo;
2462 
SmbQueryPTFileAllInfoEndOfFile(const SmbQueryPTFileAllInfo * q)2463 static inline uint64_t SmbQueryPTFileAllInfoEndOfFile(const SmbQueryPTFileAllInfo *q)
2464 {
2465     return SmbNtohq(&q->EndOfFile);
2466 }
2467 
2468 typedef struct _SmbQueryPTNetworkOpenInfo
2469 {
2470     uint64_t CreationTime;
2471     uint64_t LastAccessTime;
2472     uint64_t LastWriteTime;
2473     uint64_t LastChangeTime;
2474     uint64_t AllocationSize;
2475     uint64_t EndOfFile;
2476     uint32_t FileAttributes;
2477     uint32_t Reserved;
2478 
2479 } SmbQueryPTNetworkOpenInfo;
2480 
SmbQueryPTNetworkOpenInfoEndOfFile(const SmbQueryPTNetworkOpenInfo * q)2481 static inline uint64_t SmbQueryPTNetworkOpenInfoEndOfFile(const SmbQueryPTNetworkOpenInfo *q)
2482 {
2483     return SmbNtohq(&q->EndOfFile);
2484 }
2485 
2486 typedef struct _SmbQueryPTFileStreamInfo
2487 {
2488     uint32_t NextEntryOffset;
2489     uint32_t StreamNameLength;
2490     uint64_t StreamSize;
2491     uint64_t StreamAllocationSize;
2492 #if 0
2493     StreamName (variable)
2494 #endif
2495 } SmbQueryPTFileStreamInfo;
2496 
SmbQueryPTFileStreamInfoStreamSize(const SmbQueryPTFileStreamInfo * q)2497 static inline uint64_t SmbQueryPTFileStreamInfoStreamSize(const SmbQueryPTFileStreamInfo *q)
2498 {
2499     return SmbNtohq(&q->StreamSize);
2500 }
2501 
2502 typedef struct _SmbTrans2QueryFileInformationResp
2503 {
2504     uint8_t  smb_wct;
2505     uint16_t smb_total_param_count;
2506     uint16_t smb_total_data_count;
2507     uint16_t smb_res;
2508     uint16_t smb_param_count;
2509     uint16_t smb_param_offset;
2510     uint16_t smb_param_disp;
2511     uint16_t smb_data_count;
2512     uint16_t smb_data_offset;
2513     uint16_t smb_data_disp;
2514     uint16_t smb_setup_count;  /* 0 */
2515     uint8_t  smb_res2;
2516     uint16_t smb_bcc;
2517 #if 0
2518     uint8_t pad1[];
2519     uint8_t smb_trans2_params[smb_param_count];
2520     uint8_t pad2[];
2521     // Will be one of the SmbQuery* structures above
2522     uint8_t smb_trans2_data[smb_data_count];
2523 #endif
2524 
2525 } SmbTrans2QueryFileInformationResp;
2526 
2527 #define SMB_INFO_SET_EAS               0x0002
2528 #define SMB_SET_FILE_BASIC_INFO        0x0101
2529 #define SMB_SET_FILE_DISPOSITION_INFO  0x0102
2530 #define SMB_SET_FILE_ALLOCATION_INFO   0x0103
2531 #define SMB_SET_FILE_END_OF_FILE_INFO  0x0104
2532 
2533 // For added value, see above File Information Classes
2534 #define SMB_INFO_PT_SET_FILE_BASIC_FILE_INFO   SMB_INFO_PASSTHROUGH+4
2535 #define SMB_INFO_PT_SET_FILE_END_OF_FILE_INFO  SMB_INFO_PASSTHROUGH+20
2536 
2537 typedef struct _SmbTrans2SetFileInfoReqParams
2538 {
2539     uint16_t fid;
2540     uint16_t information_level;
2541     uint16_t reserved;
2542 
2543 } SmbTrans2SetFileInfoReqParams;
2544 
SmbTrans2SetFileInfoReqFid(const SmbTrans2SetFileInfoReqParams * req)2545 static inline uint16_t SmbTrans2SetFileInfoReqFid(const SmbTrans2SetFileInfoReqParams *req)
2546 {
2547     return SmbNtohs(&req->fid);
2548 }
2549 
SmbTrans2SetFileInfoReqInfoLevel(const SmbTrans2SetFileInfoReqParams * req)2550 static inline uint16_t SmbTrans2SetFileInfoReqInfoLevel(const SmbTrans2SetFileInfoReqParams *req)
2551 {
2552     return SmbNtohs(&req->information_level);
2553 }
2554 
SmbSetFileInfoEndOfFile(const uint16_t info_level)2555 static inline bool SmbSetFileInfoEndOfFile(const uint16_t info_level)
2556 {
2557     return ((info_level == SMB_SET_FILE_END_OF_FILE_INFO)
2558             || (info_level == SMB_INFO_PT_SET_FILE_END_OF_FILE_INFO));
2559 }
2560 
2561 typedef struct _SmbSetFileBasicInfo
2562 {
2563     uint64_t CreationTime;
2564     uint64_t LastAccessTime;
2565     uint64_t LastWriteTime;
2566     uint64_t ChangeTime;
2567     uint32_t ExtFileAttributes;
2568     uint32_t Reserved;
2569 
2570 } SmbSetFileBasicInfo;
2571 
SmbSetFileInfoExtFileAttrs(const SmbSetFileBasicInfo * info)2572 static inline uint32_t SmbSetFileInfoExtFileAttrs(const SmbSetFileBasicInfo *info)
2573 {
2574     return SmbNtohl(&info->ExtFileAttributes);
2575 }
2576 
SmbSetFileInfoSetFileBasicInfo(const uint16_t info_level)2577 static inline bool SmbSetFileInfoSetFileBasicInfo(const uint16_t info_level)
2578 {
2579     return ((info_level == SMB_SET_FILE_BASIC_INFO)
2580             || (info_level == SMB_INFO_PT_SET_FILE_BASIC_FILE_INFO));
2581 }
2582 
SmbExtAttrReadOnly(const uint32_t ext_file_attrs)2583 static inline bool SmbExtAttrReadOnly(const uint32_t ext_file_attrs)
2584 {
2585     if (ext_file_attrs & SMB_EXT_FILE_ATTR_SYSTEM)
2586         return true;
2587     return false;
2588 }
2589 
SmbExtAttrHidden(const uint32_t ext_file_attrs)2590 static inline bool SmbExtAttrHidden(const uint32_t ext_file_attrs)
2591 {
2592     if (ext_file_attrs & SMB_EXT_FILE_ATTR_HIDDEN)
2593         return true;
2594     return false;
2595 }
2596 
SmbExtAttrSystem(const uint32_t ext_file_attrs)2597 static inline bool SmbExtAttrSystem(const uint32_t ext_file_attrs)
2598 {
2599     if (ext_file_attrs & SMB_EXT_FILE_ATTR_SYSTEM)
2600         return true;
2601     return false;
2602 }
2603 
SmbEvasiveFileAttrs(const uint32_t ext_file_attrs)2604 static inline bool SmbEvasiveFileAttrs(const uint32_t ext_file_attrs)
2605 {
2606     return (SmbExtAttrReadOnly(ext_file_attrs)
2607             && SmbExtAttrHidden(ext_file_attrs)
2608             && SmbExtAttrSystem(ext_file_attrs));
2609 }
2610 
2611 /********************************************************************
2612  * SMB_COM_TRANSACTION2_SECONDARY
2613  *  Continuation command for SMB_COM_TRANSACTION2 requests if all
2614  *  data wasn't sent.
2615  ********************************************************************/
2616 typedef struct _SmbTransaction2SecondaryReq
2617 {
2618     uint8_t  smb_wct;
2619     uint16_t smb_total_param_count;
2620     uint16_t smb_total_data_count;
2621     uint16_t smb_param_count;
2622     uint16_t smb_param_offset;
2623     uint16_t smb_param_disp;
2624     uint16_t smb_data_count;
2625     uint16_t smb_data_offset;
2626     uint16_t smb_data_disp;
2627     uint16_t smb_fid;
2628     uint16_t smb_bcc;
2629 #if 0
2630     uint8_t pad1[];
2631     uint8_t smb_trans2_params[smb_param_count];
2632     uint8_t pad2[];
2633     uint8_t smb_trans2_data[smb_data_count];
2634 #endif
2635 } SmbTransaction2SecondaryReq;
2636 
SmbTransaction2SecondaryReqTotalParamCnt(const SmbTransaction2SecondaryReq * req)2637 static inline uint16_t SmbTransaction2SecondaryReqTotalParamCnt(const SmbTransaction2SecondaryReq *req)
2638 {
2639     return SmbNtohs(&req->smb_total_param_count);
2640 }
2641 
SmbTransaction2SecondaryReqParamCnt(const SmbTransaction2SecondaryReq * req)2642 static inline uint16_t SmbTransaction2SecondaryReqParamCnt(const SmbTransaction2SecondaryReq *req)
2643 {
2644     return SmbNtohs(&req->smb_param_count);
2645 }
2646 
SmbTransaction2SecondaryReqParamOff(const SmbTransaction2SecondaryReq * req)2647 static inline uint16_t SmbTransaction2SecondaryReqParamOff(const SmbTransaction2SecondaryReq *req)
2648 {
2649     return SmbNtohs(&req->smb_param_offset);
2650 }
2651 
SmbTransaction2SecondaryReqParamDisp(const SmbTransaction2SecondaryReq * req)2652 static inline uint16_t SmbTransaction2SecondaryReqParamDisp(const SmbTransaction2SecondaryReq *req)
2653 {
2654     return SmbNtohs(&req->smb_param_disp);
2655 }
2656 
SmbTransaction2SecondaryReqTotalDataCnt(const SmbTransaction2SecondaryReq * req)2657 static inline uint16_t SmbTransaction2SecondaryReqTotalDataCnt(const SmbTransaction2SecondaryReq *req)
2658 {
2659     return SmbNtohs(&req->smb_total_data_count);
2660 }
2661 
SmbTransaction2SecondaryReqDataCnt(const SmbTransaction2SecondaryReq * req)2662 static inline uint16_t SmbTransaction2SecondaryReqDataCnt(const SmbTransaction2SecondaryReq *req)
2663 {
2664     return SmbNtohs(&req->smb_data_count);
2665 }
2666 
SmbTransaction2SecondaryReqDataOff(const SmbTransaction2SecondaryReq * req)2667 static inline uint16_t SmbTransaction2SecondaryReqDataOff(const SmbTransaction2SecondaryReq *req)
2668 {
2669     return SmbNtohs(&req->smb_data_offset);
2670 }
2671 
SmbTransaction2SecondaryReqDataDisp(const SmbTransaction2SecondaryReq * req)2672 static inline uint16_t SmbTransaction2SecondaryReqDataDisp(const SmbTransaction2SecondaryReq *req)
2673 {
2674     return SmbNtohs(&req->smb_data_disp);
2675 }
2676 
2677 /*********************************************************************
2678  * SMB_COM_TREE_CONNECT
2679  *********************************************************************/
2680 typedef struct _SmbTreeConnectReq  /* smb_wct = 0 */
2681 {
2682     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2683     uint16_t smb_bcc;     /* min = 4 */
2684 
2685 #if 0
2686     uint8_t  smb_fmt;     /* ASCII -- 04 */
2687     uint8_t  smb_buf[];   /* path/username */
2688     uint8_t  smb_fmt2;    /* ASCII -- 04 */
2689     uint8_t  smb_buf2[];  /* password */
2690     uint8_t  smb_fmt3;    /* ASCII -- 04 */
2691     uint8_t  smb_buf3[];  /* dev name (<device> or LPT1) */
2692 #endif
2693 } SmbTreeConnectReq;
2694 
2695 typedef struct _SmbTreeConnectResp  /* smb_wct = 2 */
2696 {
2697     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2698     uint16_t smb_xmit;    /* max xmit size */
2699     uint16_t smb_tid;     /* tree id */
2700     uint16_t smb_bcc;
2701 
2702 } SmbTreeConnectResp;
2703 
2704 /********************************************************************
2705  * SMB_COM_TREE_DISCONNECT
2706  ********************************************************************/
2707 typedef struct _SmbTreeDisconnectReq   /* smb_wct = 0 */
2708 {
2709     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2710     uint16_t smb_bcc;     /* must be 0 */
2711 
2712 } SmbTreeDisconnectReq;
2713 
2714 typedef struct _SmbTreeDisconnectResp   /* smb_wct = 0 */
2715 {
2716     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2717     uint16_t smb_bcc;     /* must be 0 */
2718 
2719 } SmbTreeDisconnectResp;
2720 
2721 /********************************************************************
2722  * SMB_COM_NEGOTIATE
2723  ********************************************************************/
2724 typedef struct _SmbNegotiateReq   /* smb_wct = 0 */
2725 {
2726     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2727     uint16_t smb_bcc;     /* min = 2 */
2728 
2729 #if 0
2730     uint8_t  smb_fmt;     /* Dialect -- 02 */
2731     uint8_t  smb_buf[];   /* dialect0 */
2732             .
2733             .
2734             .
2735     uint8_t  smb_fmt;     /* Dialect -- 02 */
2736     uint8_t  smb_bufn[];  /* dialectn*/
2737 #endif
2738 } SmbCore_NegotiateProtocolReq;
2739 
2740 /* This is the Core Protocol response */
2741 typedef struct _SmbCore_NegotiateProtocolResp    /* smb_wct = 1 */
2742 {
2743     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2744     uint16_t smb_index;   /* index */
2745     uint16_t smb_bcc;     /* must be 0 */
2746 
2747 } SmbCore_NegotiateProtocolResp;
2748 
2749 /* This is the Lanman response */
2750 typedef struct _SmbLm10_NegotiateProtocolResp   /* smb_wct = 13 */
2751 {
2752     uint8_t  smb_wct;       /* count of 16-bit words that follow */
2753     uint16_t smb_index;     /* index identifying dialect selected */
2754     uint16_t smb_secmode;   /* security mode:
2755                                bit 0, 1 = User level, 0 = Share level
2756                                bit 1, 1 = encrypt passwords, 0 = do not encrypt passwords */
2757     uint16_t smb_maxxmt;    /* max transmit buffer size server supports, 1K min */
2758     uint16_t smb_maxmux;    /* max pending multiplexed requests server supports */
2759     uint16_t smb_maxvcs;    /* max VCs per server/consumer session supported */
2760     uint16_t smb_blkmode;   /* block read/write mode support:
2761                                bit 0, Read Block Raw supported (65535 bytes max)
2762                                bit 1, Write Block Raw supported (65535 bytes max) */
2763     uint32_t smb_sesskey;   /* Session Key (unique token identifying session) */
2764     uint16_t smb_srv_time;  /* server's current time (hhhhh mmmmmm xxxxx) */
2765     uint16_t smb_srv_tzone; /* server's current data (yyyyyyy mmmm ddddd) */
2766     uint32_t smb_rsvd;      /* reserved */
2767     uint16_t smb_bcc;       /* value = (size of smb_cryptkey) */
2768 #if 0
2769     uint8_t  smb_cryptkey[];  /* Key used for password encryption */
2770 #endif
2771 } SmbLm10_NegotiateProtocolResp;
2772 
2773 /* This is the Lanman 2.1 response */
2774 typedef struct _SmbLm21_NegotiateProtocolResp     /* smb_wct = 13 */
2775 {
2776     uint8_t  smb_wct;         /* count of 16-bit words that follow */
2777     uint16_t smb_index;       /* index identifying dialect selected */
2778     uint16_t smb_secmode;     /* security mode:
2779                                  bit 0, 1 = User level, 0 = Share level
2780                                  bit 1, 1 = encrypt passwords, 0 = do not encrypt passwords */
2781     uint16_t smb_maxxmt;      /* max transmit buffer size server supports, 1K min */
2782     uint16_t smb_maxmux;      /* max pending multiplexed requests server supports */
2783     uint16_t smb_maxvcs;      /* max VCs per server/consumer session supported */
2784     uint16_t smb_blkmode;     /* block read/write mode support:
2785                                  bit 0, Read Block Raw supported (65535 bytes max)
2786                                  bit 1, Write Block Raw supported (65535 bytes max) */
2787     uint32_t smb_sesskey;     /* Session Key (unique token identifying session) */
2788     uint16_t smb_srv_time;    /* server's current time (hhhhh mmmmmm xxxxx) */
2789     uint16_t smb_srv_tzone;   /* server's current data (yyyyyyy mmmm ddddd) */
2790     uint16_t smb_cryptkeylen; /* length of smb_cryptkey */
2791     uint16_t smb_rsvd;        /* reserved */
2792     uint16_t smb_bcc;       /* value = (size of smb_cryptkey) */
2793 #if 0
2794     uint8_t  smb_cryptkey[];  /* Key used for password encryption */
2795     uint8_t  smb_domain[]     /* Null terminated server domain */
2796 #endif
2797 } SmbLm21_NegotiateProtocolResp;
2798 
2799 /* This is the NT response */
2800 typedef struct _SmbNt_NegotiateProtocolResp     /* smb_wct = 17 */
2801 {
2802     uint8_t  smb_wct;           /* count of 16-bit words that follow */
2803     uint16_t smb_index;         /* index identifying dialect selected */
2804     uint8_t  smb_secmode;       /* security mode:
2805                                    bit 0, 1 = User level, 0 = Share level
2806                                    bit 1, 1 = encrypt passwords, 0 = do not encrypt passwords */
2807     uint16_t smb_maxmux;        /* max pending multiplexed requests server supports */
2808     uint16_t smb_maxvcs;        /* max VCs per server/consumer session supported */
2809     uint32_t smb_maxbuf;        /* maximum buffer size supported */
2810     uint32_t smb_maxraw;        /* maximum raw buffer size supported */
2811     uint32_t smb_sesskey;       /* Session Key (unique token identifying session) */
2812     uint32_t smb_cap;           /* capabilities */
2813     struct {
2814         uint32_t low_time;
2815         int32_t  high_time;
2816     } smb_srv_time;             /* server time */
2817     uint16_t smb_srv_tzone;     /* server's current data (yyyyyyy mmmm ddddd) */
2818     uint8_t  smb_challenge_len; /* Challenge length */
2819     uint16_t smb_bcc;           /* value = (size of smb_cryptkey) */
2820 #if 0
2821     uint8_t  smb_challenge[];  /* challenge used for password encryption */
2822     uint8_t  smb_domain[];     /* domain name */
2823     uint8_t  smb_server[];     /* server name */
2824     // or
2825     uint8_t  smb_server_guid[16];
2826     uint8_t  smb_security_blob[];
2827 #endif
2828 } SmbNt_NegotiateProtocolResp;
2829 
SmbNegotiateRespDialectIndex(const SmbCore_NegotiateProtocolResp * resp)2830 static inline uint16_t SmbNegotiateRespDialectIndex(const SmbCore_NegotiateProtocolResp *resp)
2831 {
2832     return SmbNtohs(&resp->smb_index);
2833 }
2834 
SmbLm_NegotiateRespMaxMultiplex(const SmbLm10_NegotiateProtocolResp * resp)2835 static inline uint16_t SmbLm_NegotiateRespMaxMultiplex(const SmbLm10_NegotiateProtocolResp *resp)
2836 {
2837     return SmbNtohs(&resp->smb_maxmux);
2838 }
2839 
SmbNt_NegotiateRespMaxMultiplex(const SmbNt_NegotiateProtocolResp * resp)2840 static inline uint16_t SmbNt_NegotiateRespMaxMultiplex(const SmbNt_NegotiateProtocolResp *resp)
2841 {
2842     return SmbNtohs(&resp->smb_maxmux);
2843 }
2844 
2845 /********************************************************************
2846  * SMB_COM_SESSION_SETUP_ANDX
2847  ********************************************************************/
2848 typedef struct _SmbLm10_SessionSetupAndXReq   /* smb_wct = 10 */
2849 {
2850     uint8_t  smb_wct;      /* count of 16-bit words that follow */
2851     uint8_t  smb_com2;     /* secondary (X) command, 0xFF = none */
2852     uint8_t  smb_reh2;     /* reserved (must be zero) */
2853     uint16_t smb_off2;     /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2854     uint16_t smb_bufsize;  /* the consumers max buffer size */
2855     uint16_t smb_mpxmax;   /* actual maximum multiplexed pending requests */
2856     uint16_t smb_vc_num;   /* 0 = first (only), non zero - additional VC number */
2857     uint32_t smb_sesskey;  /* Session Key (valid only if smb_vc_num != 0) */
2858     uint16_t smb_apasslen; /* size of account password (smb_apasswd) */
2859     uint32_t smb_rsvd;     /* reserved */
2860     uint16_t smb_bcc;      /* minimum value = 0 */
2861 #if 0
2862     uint8_t  smb_apasswd[*];  /* account password (* = smb_apasslen value) */
2863     uint8_t  smb_aname[];     /* account name string */
2864 #endif
2865 } SmbLm10_SessionSetupAndXReq;
2866 
2867 typedef struct _SmbLm10_SessionSetupAndXResp   /* smb_wct = 3 */
2868 {
2869     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2870     uint8_t  smb_com2;    /* secondary (X) command, 0xFF = none */
2871     uint8_t  smb_res2;    /* reserved (pad to word) */
2872     uint16_t smb_off2;    /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2873     uint16_t smb_action;  /* request mode:
2874                              bit0 = Logged in successfully - BUT as GUEST */
2875     uint16_t smb_bcc;     /* value = 0 */
2876 
2877 } SmbLm10_SessionSetupAndXResp;
2878 
2879 /* Extended request as defined in LM 2.0 document */
2880 typedef struct _SmbLm20_SessionSetupAndXReq   /* smb_wct = 10 */
2881 {
2882     uint8_t  smb_wct;         /* count of 16-bit words that follow */
2883     uint8_t  smb_com2;        /* secondary (X) command, 0xFF = none */
2884     uint8_t  smb_reh2;        /* reserved (must be zero) */
2885     uint16_t smb_off2;        /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2886     uint16_t smb_bufsize;     /* the consumers max buffer size */
2887     uint16_t smb_mpxmax;      /* actual maximum multiplexed pending requests */
2888     uint16_t smb_vc_num;      /* 0 = first (only), non zero - additional VC number */
2889     uint32_t smb_sesskey;     /* Session Key (valid only if smb_vc_num != 0) */
2890     uint16_t smb_apasslen;    /* size of account password (smb_apasswd) */
2891     uint16_t smb_encryptlen;  /* size of encryption key (smb_encrypt) */
2892     uint16_t smb_encryptoff;  /* offet (from SMB hdr start) to smb_encrypt */
2893     uint16_t smb_bcc;         /* minimum value = 0 */
2894 #if 0
2895     uint8_t  smb_apasswd[*];  /* account password (* = smb_apasslen value) */
2896     uint8_t  smb_aname[];     /* account name string */
2897     uint8_t  smb_encrypt[*];  /* encryption key. (* = smb_encryptlen value) */
2898 #endif
2899 } SmbLm20_SessionSetupAndXReq;
2900 
2901 /* Extended response as defined in LM 2.0 document */
2902 typedef struct _SmbLm20_SessionSetupAndXResp   /* smb_wct = 3 */
2903 {
2904     uint8_t  smb_wct;     /* count of 16-bit words that follow */
2905     uint8_t  smb_com2;    /* secondary (X) command, 0xFF = none */
2906     uint8_t  smb_res2;    /* reserved (pad to word) */
2907     uint16_t smb_off2;    /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2908     uint16_t smb_action;  /* request mode:
2909                              bit0 = Logged in successfully - BUT as GUEST */
2910     uint16_t smb_bcc;     /* min value = 0 */
2911 #if 0
2912     smb_encresp[];        /* server response to request encryption key */
2913 #endif
2914 } SmbLm20_SessionSetupAndXResp;
2915 
2916 /* Extended request as defined in LM 2.1 document */
2917 typedef struct _SmbLm21_SessionSetupAndXReq   /* smb_wct = 10 */
2918 {
2919     uint8_t  smb_wct;         /* count of 16-bit words that follow */
2920     uint8_t  smb_com2;        /* secondary (X) command, 0xFF = none */
2921     uint8_t  smb_reh2;        /* reserved (must be zero) */
2922     uint16_t smb_off2;        /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2923     uint16_t smb_bufsize;     /* the consumers max buffer size */
2924     uint16_t smb_mpxmax;      /* actual maximum multiplexed pending requests */
2925     uint16_t smb_vc_num;      /* 0 = first (only), non zero - additional VC number */
2926     uint32_t smb_sesskey;     /* Session Key (valid only if smb_vc_num != 0) */
2927     uint16_t smb_apasslen;    /* size of account password (smb_apasswd) */
2928     uint32_t smb_rsvd;        /* reserved */
2929     uint16_t smb_bcc;         /* minimum value = 0 */
2930 #if 0
2931     uint8_t  smb_apasswd[*];  /* account password (* = smb_apasslen value) */
2932     uint8_t  smb_aname[];     /* account name string */
2933     uint8_t  smb_domain[];    /* name of domain that client was authenticated on */
2934     uint8_t  smb_mativeos[];  /* native operation system of client */
2935     uint8_t  smb_nativelm[];  /* native LAN Manager type */
2936 #endif
2937 } SmbLm21_SessionSetupAndXReq;
2938 
2939 /* Extended response as defined in LM 2.1 document */
2940 typedef struct _SmbLm21_SessionSetupAndXResp   /* smb_wct = 3 */
2941 {
2942     uint8_t  smb_wct;        /* count of 16-bit words that follow */
2943     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
2944     uint8_t  smb_res2;       /* reserved (pad to word) */
2945     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2946     uint16_t smb_action;     /* request mode:
2947                                 bit0 = Logged in successfully - BUT as GUEST */
2948     uint16_t smb_bcc;        /* min value = 0 */
2949 #if 0
2950     uint8_t smb_nativeos[];  /* server's native operating system */
2951     uint8_t smb_nativelm[];  /* server's native LM type */
2952 #endif
2953 } SmbLm21_SessionSetupAndXResp;
2954 
2955 /* Extended request as defined in NT LM 1.0 document */
2956 typedef struct _SmbNt10_SessionSetupAndXReq   /* smb_wct = 13 */
2957 {
2958     uint8_t  smb_wct;             /* count of 16-bit words that follow */
2959     uint8_t  smb_com2;            /* secondary (X) command, 0xFF = none */
2960     uint8_t  smb_reh2;            /* reserved (must be zero) */
2961     uint16_t smb_off2;            /* offset (from SMB hdr start) to next cmd (@smb_wct) */
2962     uint16_t smb_bufsize;         /* the consumers max buffer size */
2963     uint16_t smb_mpxmax;          /* actual maximum multiplexed pending requests */
2964     uint16_t smb_vc_num;          /* 0 = first (only), non zero - additional VC number */
2965     uint32_t smb_sesskey;         /* Session Key (valid only if smb_vc_num != 0) */
2966     uint16_t smb_oem_passlen;     /* case insensitive password length */
2967     uint16_t smb_unicode_passlen; /* case sensitive password length */
2968     uint32_t smb_rsvd;            /* reserved */
2969     uint32_t smb_cap;             /* capabilities */
2970     uint16_t smb_bcc;             /* minimum value = 0 */
2971 #if 0
2972     uint8_t  smb_oem_passwd[*];     /* case insensitive password (* = smb_ci_passlen) */
2973     uint8_t  smb_unicode_passwd[*]; /* case sensitive password (* = smb_cs_passlen) */
2974     uint8_t  pad[];                 /* if unicode to align */
2975     uint8_t  smb_aname[];           /* ascii or unicode account name string */
2976     uint8_t  smb_domain[];          /* ascii or unicode name of domain that client was authenticated on */
2977     uint8_t  smb_nativeos[];        /* ascii or unicode native operation system of client */
2978     uint8_t  smb_nativelm[];        /* ascii or unicode native LAN Manager type */
2979 #endif
2980 } SmbNt10_SessionSetupAndXReq;
2981 
SmbSessionSetupAndXReqMaxMultiplex(const SmbLm10_SessionSetupAndXReq * req)2982 static inline uint16_t SmbSessionSetupAndXReqMaxMultiplex(const SmbLm10_SessionSetupAndXReq *req)
2983 {
2984     return SmbNtohs(&req->smb_mpxmax);
2985 }
2986 
SmbNt10SessionSetupAndXReqOemPassLen(const SmbNt10_SessionSetupAndXReq * req)2987 static inline uint16_t SmbNt10SessionSetupAndXReqOemPassLen(const SmbNt10_SessionSetupAndXReq *req)
2988 {
2989     return SmbNtohs(&req->smb_oem_passlen);
2990 }
2991 
SmbNt10SessionSetupAndXReqUnicodePassLen(const SmbNt10_SessionSetupAndXReq * req)2992 static inline uint16_t SmbNt10SessionSetupAndXReqUnicodePassLen(const SmbNt10_SessionSetupAndXReq *req)
2993 {
2994     return SmbNtohs(&req->smb_unicode_passlen);
2995 }
2996 
2997 /* Extended request for security blob */
2998 typedef struct _SmbNt10_SessionSetupAndXExtReq   /* smb_wct = 12 */
2999 {
3000     uint8_t  smb_wct;         /* count of 16-bit words that follow */
3001     uint8_t  smb_com2;        /* secondary (X) command, 0xFF = none */
3002     uint8_t  smb_reh2;        /* reserved (must be zero) */
3003     uint16_t smb_off2;        /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3004     uint16_t smb_bufsize;     /* the consumers max buffer size */
3005     uint16_t smb_mpxmax;      /* actual maximum multiplexed pending requests */
3006     uint16_t smb_vc_num;      /* 0 = first (only), non zero - additional VC number */
3007     uint32_t smb_sesskey;     /* Session Key (valid only if smb_vc_num != 0) */
3008     uint16_t smb_blob_len;    /* length of security blob */
3009     uint32_t smb_rsvd;        /* reserved */
3010     uint32_t smb_cap;         /* capabilities */
3011     uint16_t smb_bcc;         /* minimum value = 0 */
3012 #if 0
3013     uint8_t  smb_blob[];        /* security blob */
3014     uint8_t  smb_nativeos[];    /* ascii or unicode native operation system of client */
3015     uint8_t  smb_nativelm[];    /* ascii or unicode native LAN Manager type */
3016 #endif
3017 } SmbNt10_SessionSetupAndXExtReq;
3018 
SmbSessionSetupAndXReqBlobLen(const SmbNt10_SessionSetupAndXExtReq * req)3019 static inline uint16_t SmbSessionSetupAndXReqBlobLen(const SmbNt10_SessionSetupAndXExtReq *req)
3020 {
3021     return SmbNtohs(&req->smb_blob_len);
3022 }
3023 
3024 /* Response as defined in NT LM 1.0 document */
3025 typedef struct _SmbNt10_SessionSetupAndXResp   /* smb_wct = 3 */
3026 {
3027     uint8_t  smb_wct;        /* count of 16-bit words that follow */
3028     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
3029     uint8_t  smb_res2;       /* reserved (pad to word) */
3030     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3031     uint16_t smb_action;     /* request mode:
3032                                 bit0 = Logged in successfully - BUT as GUEST */
3033     uint16_t smb_bcc;        /* min value = 0 */
3034 #if 0
3035     uint8_t  pad[];           /* if unicode is used to align */
3036     uint8_t  smb_nativeos[];  /* ascii or unicode server's native operating system */
3037     uint8_t  smb_nativelm[];  /* ascii or unicode server's native LM type */
3038     uint8_t  smb_domain[];    /* ascii or unicode logon domain of the user */
3039 #endif
3040 } SmbNt10_SessionSetupAndXResp;
3041 
3042 /* Extended response for security blob */
3043 typedef struct _SmbNt10_SessionSetupAndXExtResp   /* smb_wct = 4 */
3044 {
3045     uint8_t  smb_wct;        /* count of 16-bit words that follow */
3046     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
3047     uint8_t  smb_res2;       /* reserved (pad to word) */
3048     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3049     uint16_t smb_action;     /* request mode:
3050                                 bit0 = Logged in successfully - BUT as GUEST */
3051     uint16_t smb_blob_len;   /* length of security blob */
3052     uint16_t smb_bcc;        /* min value = 0 */
3053 #if 0
3054     uint8_t  smb_blob[];      /* security blob */
3055     uint8_t  smb_nativeos[];  /* ascii or unicode server's native operating system */
3056     uint8_t  smb_nativelm[];  /* ascii or unicode server's native LM type */
3057 #endif
3058 } SmbNt10_SessionSetupAndXExtResp;
3059 
SmbSessionSetupAndXRespBlobLen(const SmbNt10_SessionSetupAndXExtResp * resp)3060 static inline uint16_t SmbSessionSetupAndXRespBlobLen(const SmbNt10_SessionSetupAndXExtResp *resp)
3061 {
3062     return SmbNtohs(&resp->smb_blob_len);
3063 }
3064 
3065 /********************************************************************
3066  * SMB_COM_LOGOFF_ANDX
3067  ********************************************************************/
3068 typedef struct _SmbLogoffAndXReq    /* smb_wct = 2 */
3069 {
3070     uint8_t  smb_wct;    /* count of 16-bit words that follow */
3071     uint8_t  smb_com2;   /* secondary (X) command, 0xFF = none */
3072     uint8_t  smb_reh2;   /* reserved (must be zero) */
3073     uint16_t smb_off2;   /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3074     uint16_t smb_bcc;    /* value = 0 */
3075 
3076 } SmbLogoffAndXReq;
3077 
3078 typedef struct _SmbLogoffAndXResp    /* smb_wct = 2 */
3079 {
3080     uint8_t  smb_wct;    /* count of 16-bit words that follow */
3081     uint8_t  smb_com2;   /* secondary (X) command, 0xFF = none */
3082     uint8_t  smb_res2;   /* reserved (pad to word) */
3083     uint16_t smb_off2;   /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3084     uint16_t smb_bcc;    /* value = 0 */
3085 
3086 } SmbLogoffAndXResp;
3087 
3088 /*********************************************************************
3089  * SMB_COM_TREE_CONNECT_ANDX
3090  *********************************************************************/
3091 typedef struct _SmbTreeConnectAndXReq   /* smb_wct = 4 */
3092 {
3093     uint8_t  smb_wct;        /* count of 16-bit words that follow */
3094     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
3095     uint8_t  smb_reh2;       /* reserved (must be zero) */
3096     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3097     uint16_t smb_flags;      /* additional information:
3098                                 bit 0 - if set, disconnect TID in current smb_tid */
3099     uint16_t smb_spasslen;   /* length of smb_spasswd */
3100     uint16_t smb_bcc;        /* minimum value = 3 */
3101 #if 0
3102     uint8_t  smb_spasswd[*]; /* net-name password (* = smb_spasslen value) */
3103     uint8_t  pad[];          /* if unicode to align */
3104     uint8_t  smb_path[];     /* server name and net-name */
3105     uint8_t  smb_service[];  /* service name string */
3106 #endif
3107 } SmbTreeConnectAndXReq;
3108 
3109 typedef struct _SmbLm10_TreeConnectAndXResp    /* smb_wct = 2 */
3110 {
3111     uint8_t  smb_wct;       /* count of 16-bit words that follow */
3112     uint8_t  smb_com2;      /* secondary (X) command, 0xFF = none */
3113     uint8_t  smb_res2;      /* reserved (pad to word) */
3114     uint16_t smb_off2;      /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3115     uint16_t smb_bcc;       /* min value = 3 */
3116 #if 0
3117     uint8_t  smb_service[]; /* service type connected to (string) */
3118 #endif
3119 } SmbLm10_TreeConnectAndXResp;
3120 
3121 typedef struct _SmbTreeConnectAndXResp    /* smb_wct = 3 */
3122 {
3123     uint8_t  smb_wct;        /* count of 16-bit words that follow */
3124     uint8_t  smb_com2;       /* secondary (X) command, 0xFF = none */
3125     uint8_t  smb_res2;       /* reserved (pad to word) */
3126     uint16_t smb_off2;       /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3127     uint16_t smb_optsupp;    /* bit mask indicating advanced OS features available
3128                                 bit0 = 1, exclusive search bits supported */
3129     uint16_t smb_bcc;        /* min value = 3 */
3130 #if 0
3131     uint8_t  smb_service[];  /* service type connected to - ASCII */
3132     uint8_t  pad[];          /* if unicode to align */
3133     uint8_t  smb_nativefs[]; /* native file system for this connection */
3134 #endif
3135 } SmbTreeConnectAndXResp;
3136 
3137 typedef struct _SmbTreeConnectAndXExtResp    /* smb_wct = 7 */
3138 {
3139     uint8_t  smb_wct;          /* count of 16-bit words that follow */
3140     uint8_t  smb_com2;         /* secondary (X) command, 0xFF = none */
3141     uint8_t  smb_res2;         /* reserved (pad to word) */
3142     uint16_t smb_off2;         /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3143     uint16_t smb_optsupp;      /* bit mask indicating advanced OS features available */
3144     uint32_t smb_share_access; /* maximal share access rights */
3145     uint32_t smb_guest_access; /* guest maximal share access rights */
3146     uint16_t smb_bcc;          /* min value = 3 */
3147 #if 0
3148     uint8_t  smb_service[];  /* service type connected to - ASCII */
3149     uint8_t  pad[];          /* if unicode to align */
3150     uint8_t  smb_nativefs[]; /* native file system for this connection */
3151 #endif
3152 } SmbTreeConnectAndXExtResp;
3153 
SmbTreeConnectAndXReqPassLen(const SmbTreeConnectAndXReq * req)3154 static inline uint16_t SmbTreeConnectAndXReqPassLen(const SmbTreeConnectAndXReq *req)
3155 {
3156     return SmbNtohs(&req->smb_spasslen);
3157 }
3158 
3159 /********************************************************************
3160  * SMB_COM_NT_TRANSACT
3161  ********************************************************************/
3162 #define SMB_CREATE_OPTIONS__FILE_SEQUENTIAL_ONLY     0x00000004
3163 
3164 typedef struct _SmbNtTransactReq
3165 {
3166     uint8_t  smb_wct;
3167     uint8_t  smb_max_setup_count;
3168     uint16_t smb_res;
3169     uint32_t smb_total_param_count;
3170     uint32_t smb_total_data_count;
3171     uint32_t smb_max_param_count;
3172     uint32_t smb_max_data_count;
3173     uint32_t smb_param_count;
3174     uint32_t smb_param_offset;
3175     uint32_t smb_data_count;
3176     uint32_t smb_data_offset;
3177     uint8_t  smb_setup_count;
3178     uint16_t smb_function;
3179 #if 0
3180     uint16_t smb_setup[smb_setup_count];
3181     uint16_t smb_bcc;
3182     uint8_t pad1[];
3183     uint8_t smb_nt_trans_params[smb_param_count];
3184     uint8_t pad2[];
3185     uint8_t smb_nt_trans_data[smb_data_count];
3186 #endif
3187 } SmbNtTransactReq;
3188 
3189 typedef struct _SmbNtTransactInterimResp
3190 {
3191     uint8_t  smb_wct;
3192     uint16_t smb_bcc;
3193 
3194 } SmbNtTransactInterimResp;
3195 
3196 typedef struct _SmbNtTransactResp
3197 {
3198     uint8_t  smb_wct;
3199     uint8_t  smb_res[3];
3200     uint32_t smb_total_param_count;
3201     uint32_t smb_total_data_count;
3202     uint32_t smb_param_count;
3203     uint32_t smb_param_offset;
3204     uint32_t smb_param_disp;
3205     uint32_t smb_data_count;
3206     uint32_t smb_data_offset;
3207     uint32_t smb_data_disp;
3208     uint8_t  smb_setup_count;
3209 #if 0
3210     uint16_t smb_setup[smb_setup_count];
3211     uint16_t smb_bcc;
3212     uint8_t pad1[];
3213     uint8_t smb_nt_trans_params[smb_param_count];
3214     uint8_t pad2[];
3215     uint8_t smb_nt_trans_data[smb_data_count];
3216 #endif
3217 } SmbNtTransactResp;
3218 
SmbNtTransactReqSubCom(const SmbNtTransactReq * req)3219 static inline uint16_t SmbNtTransactReqSubCom(const SmbNtTransactReq *req)
3220 {
3221     return SmbNtohs(&req->smb_function);
3222 }
3223 
SmbNtTransactReqSetupCnt(const SmbNtTransactReq * req)3224 static inline uint8_t SmbNtTransactReqSetupCnt(const SmbNtTransactReq *req)
3225 {
3226     return req->smb_setup_count;
3227 }
3228 
SmbNtTransactReqTotalParamCnt(const SmbNtTransactReq * req)3229 static inline uint32_t SmbNtTransactReqTotalParamCnt(const SmbNtTransactReq *req)
3230 {
3231     return SmbNtohl(&req->smb_total_param_count);
3232 }
3233 
SmbNtTransactReqParamCnt(const SmbNtTransactReq * req)3234 static inline uint32_t SmbNtTransactReqParamCnt(const SmbNtTransactReq *req)
3235 {
3236     return SmbNtohl(&req->smb_param_count);
3237 }
3238 
SmbNtTransactReqParamOff(const SmbNtTransactReq * req)3239 static inline uint32_t SmbNtTransactReqParamOff(const SmbNtTransactReq *req)
3240 {
3241     return SmbNtohl(&req->smb_param_offset);
3242 }
3243 
SmbNtTransactReqTotalDataCnt(const SmbNtTransactReq * req)3244 static inline uint32_t SmbNtTransactReqTotalDataCnt(const SmbNtTransactReq *req)
3245 {
3246     return SmbNtohl(&req->smb_total_data_count);
3247 }
3248 
SmbNtTransactReqDataCnt(const SmbNtTransactReq * req)3249 static inline uint32_t SmbNtTransactReqDataCnt(const SmbNtTransactReq *req)
3250 {
3251     return SmbNtohl(&req->smb_data_count);
3252 }
3253 
SmbNtTransactReqDataOff(const SmbNtTransactReq * req)3254 static inline uint32_t SmbNtTransactReqDataOff(const SmbNtTransactReq *req)
3255 {
3256     return SmbNtohl(&req->smb_data_offset);
3257 }
3258 
SmbNtTransactRespTotalParamCnt(const SmbNtTransactResp * resp)3259 static inline uint32_t SmbNtTransactRespTotalParamCnt(const SmbNtTransactResp *resp)
3260 {
3261     return SmbNtohl(&resp->smb_total_param_count);
3262 }
3263 
SmbNtTransactRespParamCnt(const SmbNtTransactResp * resp)3264 static inline uint32_t SmbNtTransactRespParamCnt(const SmbNtTransactResp *resp)
3265 {
3266     return SmbNtohl(&resp->smb_param_count);
3267 }
3268 
SmbNtTransactRespParamOff(const SmbNtTransactResp * resp)3269 static inline uint32_t SmbNtTransactRespParamOff(const SmbNtTransactResp *resp)
3270 {
3271     return SmbNtohl(&resp->smb_param_offset);
3272 }
3273 
SmbNtTransactRespParamDisp(const SmbNtTransactResp * resp)3274 static inline uint32_t SmbNtTransactRespParamDisp(const SmbNtTransactResp *resp)
3275 {
3276     return SmbNtohl(&resp->smb_param_disp);
3277 }
3278 
SmbNtTransactRespTotalDataCnt(const SmbNtTransactResp * resp)3279 static inline uint32_t SmbNtTransactRespTotalDataCnt(const SmbNtTransactResp *resp)
3280 {
3281     return SmbNtohl(&resp->smb_total_data_count);
3282 }
3283 
SmbNtTransactRespDataCnt(const SmbNtTransactResp * resp)3284 static inline uint32_t SmbNtTransactRespDataCnt(const SmbNtTransactResp *resp)
3285 {
3286     return SmbNtohl(&resp->smb_data_count);
3287 }
3288 
SmbNtTransactRespDataOff(const SmbNtTransactResp * resp)3289 static inline uint32_t SmbNtTransactRespDataOff(const SmbNtTransactResp *resp)
3290 {
3291     return SmbNtohl(&resp->smb_data_offset);
3292 }
3293 
SmbNtTransactRespDataDisp(const SmbNtTransactResp * resp)3294 static inline uint32_t SmbNtTransactRespDataDisp(const SmbNtTransactResp *resp)
3295 {
3296     return SmbNtohl(&resp->smb_data_disp);
3297 }
3298 
3299 typedef struct _SmbNtTransactCreateReqParams
3300 {
3301     uint32_t flags;
3302     uint32_t root_dir_fid;
3303     uint32_t desired_access;
3304     uint64_t allocation_size;
3305     uint32_t ext_file_attributes;
3306     uint32_t share_access;
3307     uint32_t create_disposition;
3308     uint32_t create_options;
3309     uint32_t security_descriptor_length;
3310     uint32_t ea_length;
3311     uint32_t name_length;
3312     uint32_t impersonation_level;
3313     uint8_t  security_flags;
3314 #if 0
3315     uint8_t  name[name_length];
3316 #endif
3317 } SmbNtTransactCreateReqParams;
3318 
3319 #if 0
3320 // Not used now
3321 typedef struct _SmbNtTransactCreateReqData
3322 {
3323     uint8_t security_descriptor[security_descriptor_length];
3324     uint8_t extended_attributes[ea_length];
3325 
3326 } SmbNtTransactCreateReqData;
3327 #endif
3328 
SmbNtTransactCreateReqAllocSize(const SmbNtTransactCreateReqParams * req)3329 static inline uint64_t SmbNtTransactCreateReqAllocSize(const SmbNtTransactCreateReqParams *req)
3330 {
3331     return SmbNtohq(&req->allocation_size);
3332 }
3333 
SmbNtTransactCreateReqFileNameLength(const SmbNtTransactCreateReqParams * req)3334 static inline uint32_t SmbNtTransactCreateReqFileNameLength(const SmbNtTransactCreateReqParams *req)
3335 {
3336     return SmbNtohl(&req->name_length);
3337 }
3338 
SmbNtTransactCreateReqFileAttrs(const SmbNtTransactCreateReqParams * req)3339 static inline uint32_t SmbNtTransactCreateReqFileAttrs(const SmbNtTransactCreateReqParams *req)
3340 {
3341     return SmbNtohl(&req->ext_file_attributes);
3342 }
3343 
SmbNtTransactCreateReqSequentialOnly(const SmbNtTransactCreateReqParams * req)3344 static inline bool SmbNtTransactCreateReqSequentialOnly(const SmbNtTransactCreateReqParams *req)
3345 {
3346     return (SmbNtohl(&req->create_options) & SMB_CREATE_OPTIONS__FILE_SEQUENTIAL_ONLY);
3347 }
3348 
3349 typedef struct _SmbNtTransactCreateReq
3350 {
3351     uint8_t  smb_wct;
3352     uint8_t  smb_max_setup_count;
3353     uint16_t smb_res;
3354     uint32_t smb_total_param_count;
3355     uint32_t smb_total_data_count;
3356     uint32_t smb_max_param_count;
3357     uint32_t smb_max_data_count;
3358     uint32_t smb_param_count;
3359     uint32_t smb_param_offset;
3360     uint32_t smb_data_count;
3361     uint32_t smb_data_offset;
3362     uint8_t  smb_setup_count;   /* Must be 0x00 */
3363     uint16_t smb_function;      /* NT_TRANSACT_CREATE */
3364     uint16_t smb_bcc;
3365 #if 0
3366     uint8_t pad1[];
3367     uint8_t smb_nt_trans_params[smb_param_count];  /* SmbNtTransCreateParams */
3368     uint8_t pad2[];
3369     uint8_t smb_nt_trans_data[smb_data_count];
3370 #endif
3371 } SmbNtTransactCreateReq;
3372 
3373 typedef struct _SmbNtTransactCreateRespParams
3374 {
3375     uint8_t  op_lock_level;
3376     uint8_t  reserved;
3377     uint16_t smb_fid;
3378     uint32_t create_action;
3379     uint32_t ea_error_offset;
3380     uint64_t creation_time;
3381     uint64_t last_access_time;
3382     uint64_t last_write_time;
3383     uint64_t last_change_time;
3384     uint32_t ext_file_attributes;
3385     uint64_t allocation_size;
3386     uint64_t end_of_file;
3387     uint16_t resource_type;
3388     uint16_t nm_pipe_status;
3389     uint8_t  directory;
3390 
3391 } SmbNtTransactCreateRespParams;
3392 
SmbNtTransactCreateRespFid(const SmbNtTransactCreateRespParams * resp)3393 static inline uint16_t SmbNtTransactCreateRespFid(const SmbNtTransactCreateRespParams *resp)
3394 {
3395     return SmbNtohs(&resp->smb_fid);
3396 }
3397 
SmbNtTransactCreateRespCreateAction(const SmbNtTransactCreateRespParams * resp)3398 static inline uint32_t SmbNtTransactCreateRespCreateAction(const SmbNtTransactCreateRespParams *resp)
3399 {
3400     return SmbNtohl(&resp->create_action);
3401 }
3402 
SmbNtTransactCreateRespEndOfFile(const SmbNtTransactCreateRespParams * resp)3403 static inline uint64_t SmbNtTransactCreateRespEndOfFile(const SmbNtTransactCreateRespParams *resp)
3404 {
3405     return SmbNtohq(&resp->end_of_file);
3406 }
3407 
SmbNtTransactCreateRespResourceType(const SmbNtTransactCreateRespParams * resp)3408 static inline uint16_t SmbNtTransactCreateRespResourceType(const SmbNtTransactCreateRespParams *resp)
3409 {
3410     return SmbNtohs(&resp->resource_type);
3411 }
3412 
SmbNtTransactCreateRespDirectory(const SmbNtTransactCreateRespParams * resp)3413 static inline bool SmbNtTransactCreateRespDirectory(const SmbNtTransactCreateRespParams *resp)
3414 {
3415     return (resp->directory ? true : false);
3416 }
3417 
3418 typedef struct _SmbNtTransactCreateResp
3419 {
3420     uint8_t  smb_wct;
3421     uint8_t  smb_res[3];
3422     uint32_t smb_total_param_count;
3423     uint32_t smb_total_data_count;
3424     uint32_t smb_param_count;
3425     uint32_t smb_param_offset;
3426     uint32_t smb_param_disp;
3427     uint32_t smb_data_count;
3428     uint32_t smb_data_offset;
3429     uint32_t smb_data_disp;
3430     uint8_t  smb_setup_count;   /* 0x00 */
3431     uint16_t smb_bcc;
3432 #if 0
3433     uint8_t pad1[];
3434     uint8_t smb_nt_trans_params[smb_param_count];
3435     uint8_t pad2[];
3436     uint8_t smb_nt_trans_data[smb_data_count];
3437 #endif
3438 } SmbNtTransactCreateResp;
3439 
3440 /********************************************************************
3441  * SMB_COM_NT_TRANSACT_SECONDARY
3442  ********************************************************************/
3443 typedef struct _SmbNtTransactSecondaryReq
3444 {
3445     uint8_t  smb_wct;
3446     uint8_t  smb_res[3];
3447     uint32_t smb_total_param_count;
3448     uint32_t smb_total_data_count;
3449     uint32_t smb_param_count;
3450     uint32_t smb_param_offset;
3451     uint32_t smb_param_disp;
3452     uint32_t smb_data_count;
3453     uint32_t smb_data_offset;
3454     uint32_t smb_data_disp;
3455     uint8_t  smb_res2;
3456 #if 0
3457     uint8_t pad1[];
3458     uint8_t smb_nt_trans_params[smb_param_count];
3459     uint8_t pad2[];
3460     uint8_t smb_nt_trans_data[smb_data_count];
3461 #endif
3462 
3463 } SmbNtTransactSecondaryReq;
3464 
SmbNtTransactSecondaryReqTotalParamCnt(const SmbNtTransactSecondaryReq * req)3465 static inline uint32_t SmbNtTransactSecondaryReqTotalParamCnt(const SmbNtTransactSecondaryReq *req)
3466 {
3467     return SmbNtohl(&req->smb_total_param_count);
3468 }
3469 
SmbNtTransactSecondaryReqParamCnt(const SmbNtTransactSecondaryReq * req)3470 static inline uint32_t SmbNtTransactSecondaryReqParamCnt(const SmbNtTransactSecondaryReq *req)
3471 {
3472     return SmbNtohl(&req->smb_param_count);
3473 }
3474 
SmbNtTransactSecondaryReqParamOff(const SmbNtTransactSecondaryReq * req)3475 static inline uint32_t SmbNtTransactSecondaryReqParamOff(const SmbNtTransactSecondaryReq *req)
3476 {
3477     return SmbNtohl(&req->smb_param_offset);
3478 }
3479 
SmbNtTransactSecondaryReqParamDisp(const SmbNtTransactSecondaryReq * req)3480 static inline uint32_t SmbNtTransactSecondaryReqParamDisp(const SmbNtTransactSecondaryReq *req)
3481 {
3482     return SmbNtohl(&req->smb_param_disp);
3483 }
3484 
SmbNtTransactSecondaryReqTotalDataCnt(const SmbNtTransactSecondaryReq * req)3485 static inline uint32_t SmbNtTransactSecondaryReqTotalDataCnt(const SmbNtTransactSecondaryReq *req)
3486 {
3487     return SmbNtohl(&req->smb_total_data_count);
3488 }
3489 
SmbNtTransactSecondaryReqDataCnt(const SmbNtTransactSecondaryReq * req)3490 static inline uint32_t SmbNtTransactSecondaryReqDataCnt(const SmbNtTransactSecondaryReq *req)
3491 {
3492     return SmbNtohl(&req->smb_data_count);
3493 }
3494 
SmbNtTransactSecondaryReqDataOff(const SmbNtTransactSecondaryReq * req)3495 static inline uint32_t SmbNtTransactSecondaryReqDataOff(const SmbNtTransactSecondaryReq *req)
3496 {
3497     return SmbNtohl(&req->smb_data_offset);
3498 }
3499 
SmbNtTransactSecondaryReqDataDisp(const SmbNtTransactSecondaryReq * req)3500 static inline uint32_t SmbNtTransactSecondaryReqDataDisp(const SmbNtTransactSecondaryReq *req)
3501 {
3502     return SmbNtohl(&req->smb_data_disp);
3503 }
3504 
3505 /********************************************************************
3506  * SMB_COM_NT_CREATE_ANDX
3507  ********************************************************************/
3508 #define SMB_CREATE_DISPOSITSION__FILE_SUPERCEDE      0x00000000
3509 #define SMB_CREATE_DISPOSITSION__FILE_OPEN           0x00000001
3510 #define SMB_CREATE_DISPOSITSION__FILE_CREATE         0x00000002
3511 #define SMB_CREATE_DISPOSITSION__FILE_OPEN_IF        0x00000003
3512 #define SMB_CREATE_DISPOSITSION__FILE_OVERWRITE      0x00000004
3513 #define SMB_CREATE_DISPOSITSION__FILE_OVERWRITE_IF   0x00000005
3514 
3515 typedef struct _SmbNtCreateAndXReq   /* smb_wct = 24 */
3516 {
3517     uint8_t  smb_wct;           /* count of 16-bit words that follow */
3518     uint8_t  smb_com2;          /* secondary (X) command, 0xFF = none */
3519     uint8_t  smb_res2;          /* reserved (pad to word) */
3520     uint16_t smb_off2;          /* offset (from SMB hdr start) to next cmd (@smb_wct) */
3521     uint8_t  smb_res;           /* reserved */
3522     uint16_t smb_name_len;      /* length of name of file */
3523     uint32_t smb_flags;         /* flags */
3524     uint32_t smb_root_fid;      /* fid for previously opened directory */
3525     uint32_t smb_access;        /* specifies the type of file access */
3526     uint64_t smb_alloc_size;    /* initial allocation size of the file */
3527     uint32_t smb_file_attrs;    /* specifies the file attributes for the file */
3528     uint32_t smb_share_access;  /* the type of share access */
3529     uint32_t smb_create_disp;   /* actions to take if file does or does not exist */
3530     uint32_t smb_create_opts;   /* options used when creating or opening file */
3531     uint32_t smb_impersonation_level;  /* security impersonation level */
3532     uint8_t  smb_security_flags;  /* security flags */
3533     uint16_t smb_bcc;           /* byte count */
3534 #if 0
3535     uint8_t * file_name[];    /* name of file to open - ascii or unicode */
3536 #endif
3537 } SmbNtCreateAndXReq;
3538 
3539 typedef struct _SmbNtCreateAndXResp    /* smb_wct = 34 */
3540 {
3541     uint8_t  smb_wct;
3542     uint8_t  smb_com2;
3543     uint8_t  smb_res2;
3544     uint16_t smb_off2;
3545     uint8_t  smb_oplock_level;
3546     uint16_t smb_fid;
3547     uint32_t smb_create_disposition;
3548     uint64_t smb_creation_time;
3549     uint64_t smb_last_access_time;
3550     uint64_t smb_last_write_time;
3551     uint64_t smb_change_time;
3552     uint32_t smb_file_attrs;
3553     uint64_t smb_alloc_size;
3554     uint64_t smb_eof;
3555     uint16_t smb_resource_type;
3556     uint16_t smb_nm_pipe_state;
3557     uint8_t  smb_directory;
3558     uint16_t smb_bcc;
3559 
3560 } SmbNtCreateAndXResp;
3561 
3562 // Word count is always set to 42 though there are actually 50 words
3563 typedef struct _SmbNtCreateAndXExtResp    /* smb_wct = 42 */
3564 {
3565     uint8_t  smb_wct;
3566     uint8_t  smb_com2;
3567     uint8_t  smb_res2;
3568     uint16_t smb_off2;
3569     uint8_t  smb_oplock_level;
3570     uint16_t smb_fid;
3571     uint32_t smb_create_disposition;
3572     uint64_t smb_creation_time;
3573     uint64_t smb_last_access_time;
3574     uint64_t smb_last_write_time;
3575     uint64_t smb_change_time;
3576     uint32_t smb_file_attrs;
3577     uint64_t smb_alloc_size;
3578     uint64_t smb_eof;
3579     uint16_t smb_resource_type;
3580     uint16_t smb_nm_pipe_state;
3581     uint8_t  smb_directory;
3582     uint8_t  smb_volume_guid[16];
3583     uint64_t smb_fileid;
3584     uint32_t smb_max_access_rights;
3585     uint32_t smb_guest_access_rights;
3586     uint16_t smb_bcc;
3587 
3588 } SmbNtCreateAndXExtResp;
3589 
SmbNtCreateAndXReqFileNameLen(const SmbNtCreateAndXReq * req)3590 static inline uint16_t SmbNtCreateAndXReqFileNameLen(const SmbNtCreateAndXReq *req)
3591 {
3592     return SmbNtohs(&req->smb_name_len);
3593 }
3594 
SmbNtCreateAndXReqCreateDisposition(const SmbNtCreateAndXReq * req)3595 static inline uint32_t SmbNtCreateAndXReqCreateDisposition(const SmbNtCreateAndXReq *req)
3596 {
3597     return SmbNtohl(&req->smb_create_disp);
3598 }
3599 
SmbCreateDispositionRead(const uint32_t create_disposition)3600 static inline bool SmbCreateDispositionRead(const uint32_t create_disposition)
3601 {
3602     return (create_disposition == SMB_CREATE_DISPOSITSION__FILE_OPEN)
3603         || (create_disposition > SMB_CREATE_DISPOSITSION__FILE_OVERWRITE_IF);
3604 }
3605 
SmbNtCreateAndXReqAllocSize(const SmbNtCreateAndXReq * req)3606 static inline uint64_t SmbNtCreateAndXReqAllocSize(const SmbNtCreateAndXReq *req)
3607 {
3608     return SmbNtohq(&req->smb_alloc_size);
3609 }
3610 
SmbNtCreateAndXReqSequentialOnly(const SmbNtCreateAndXReq * req)3611 static inline bool SmbNtCreateAndXReqSequentialOnly(const SmbNtCreateAndXReq *req)
3612 {
3613     return (SmbNtohl(&req->smb_create_opts) & SMB_CREATE_OPTIONS__FILE_SEQUENTIAL_ONLY);
3614 }
3615 
SmbNtCreateAndXReqFileAttrs(const SmbNtCreateAndXReq * req)3616 static inline uint32_t SmbNtCreateAndXReqFileAttrs(const SmbNtCreateAndXReq *req)
3617 {
3618     return SmbNtohl(&req->smb_file_attrs);
3619 }
3620 
SmbNtCreateAndXRespFid(const SmbNtCreateAndXResp * resp)3621 static inline uint16_t SmbNtCreateAndXRespFid(const SmbNtCreateAndXResp *resp)
3622 {
3623     return SmbNtohs(&resp->smb_fid);
3624 }
3625 
SmbNtCreateAndXRespCreateDisposition(const SmbNtCreateAndXResp * resp)3626 static inline uint32_t SmbNtCreateAndXRespCreateDisposition(const SmbNtCreateAndXResp *resp)
3627 {
3628     return SmbNtohl(&resp->smb_create_disposition);
3629 }
3630 
SmbNtCreateAndXRespDirectory(const SmbNtCreateAndXResp * resp)3631 static inline bool SmbNtCreateAndXRespDirectory(const SmbNtCreateAndXResp *resp)
3632 {
3633     return (resp->smb_directory ? true : false);
3634 }
3635 
SmbNtCreateAndXRespResourceType(const SmbNtCreateAndXResp * resp)3636 static inline uint16_t SmbNtCreateAndXRespResourceType(const SmbNtCreateAndXResp *resp)
3637 {
3638     return SmbNtohs(&resp->smb_resource_type);
3639 }
3640 
SmbNtCreateAndXRespEndOfFile(const SmbNtCreateAndXResp * resp)3641 static inline uint64_t SmbNtCreateAndXRespEndOfFile(const SmbNtCreateAndXResp *resp)
3642 {
3643     return SmbNtohq(&resp->smb_eof);
3644 }
3645 
3646 #ifdef WIN32
3647 #pragma pack(pop,smb_hdrs)
3648 #else
3649 #pragma pack()
3650 #endif
3651 
3652 #endif /* _SMB_H_ */
3653 
3654