some compilers dont like unnamed unions and structs
[obnox/wireshark/wip.git] / epan / dissectors / packet-smb2.c
1 /* packet-smb2.c
2  * Routines for smb2 packet dissection
3  * Ronnie Sahlberg 2005
4  *
5  * See http://wiki.wireshark.org/SMB2  for documentation of
6  * this protocol.
7  * If you edit this file, keep the wiki updated as well.
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <epan/packet.h>
35 #include <epan/conversation.h>
36 #include <epan/prefs.h>
37 #include <epan/reassemble.h>
38 #include <epan/tap.h>
39 #include <epan/emem.h>
40
41 #include "packet-smb2.h"
42 #include "packet-dcerpc.h"
43 #include "packet-ntlmssp.h"
44 #include "packet-windows-common.h"
45 #include "packet-smb-common.h"
46 #include "packet-smb.h"
47 #include "packet-dcerpc-nt.h"
48 #include <string.h>
49
50
51
52 static int proto_smb2 = -1;
53 static int hf_smb2_cmd = -1;
54 static int hf_smb2_nt_status = -1;
55 static int hf_smb2_response_to = -1;
56 static int hf_smb2_response_in = -1;
57 static int hf_smb2_time = -1;
58 static int hf_smb2_header_len = -1;
59 static int hf_smb2_seqnum = -1;
60 static int hf_smb2_pid = -1;
61 static int hf_smb2_tid = -1;
62 static int hf_smb2_uid = -1;
63 static int hf_smb2_flags_response = -1;
64 static int hf_smb2_flags_pid_valid = -1;
65 static int hf_smb2_flags_signature = -1;
66 static int hf_smb2_response_buffer_offset = -1;
67 static int hf_smb2_security_blob_offset = -1;
68 static int hf_smb2_security_blob_len = -1;
69 static int hf_smb2_security_blob = -1;
70 static int hf_smb2_ioctl_in_data = -1;
71 static int hf_smb2_ioctl_out_data = -1;
72 static int hf_smb2_unknown = -1;
73 static int hf_smb2_unknown_timestamp = -1;
74 static int hf_smb2_create_timestamp = -1;
75 static int hf_smb2_create_flags = -1;
76 static int hf_smb2_create_flags_request_oplock = -1;
77 static int hf_smb2_create_flags_request_exclusive_oplock = -1;
78 static int hf_smb2_create_flags_grant_oplock = -1;
79 static int hf_smb2_create_flags_grant_exclusive_oplock = -1;
80 static int hf_smb2_close_flags = -1;
81 static int hf_smb2_last_access_timestamp = -1;
82 static int hf_smb2_last_write_timestamp = -1;
83 static int hf_smb2_last_change_timestamp = -1;
84 static int hf_smb2_current_time = -1;
85 static int hf_smb2_boot_time = -1;
86 static int hf_smb2_filename = -1;
87 static int hf_smb2_filename_len = -1;
88 static int hf_smb2_nlinks = -1;
89 static int hf_smb2_delete_pending = -1;
90 static int hf_smb2_is_directory = -1;
91 static int hf_smb2_file_id = -1;
92 static int hf_smb2_allocation_size = -1;
93 static int hf_smb2_end_of_file = -1;
94 static int hf_smb2_tree = -1;
95 static int hf_smb2_search = -1;
96 static int hf_smb2_find_response_size = -1;
97 static int hf_smb2_server_guid = -1;
98 static int hf_smb2_object_id = -1;
99 static int hf_smb2_birth_volume_id = -1;
100 static int hf_smb2_birth_object_id = -1;
101 static int hf_smb2_domain_id = -1;
102 static int hf_smb2_class = -1;
103 static int hf_smb2_infolevel = -1;
104 static int hf_smb2_infolevel_file_info = -1;
105 static int hf_smb2_infolevel_fs_info = -1;
106 static int hf_smb2_infolevel_sec_info = -1;
107 static int hf_smb2_max_response_size = -1;
108 static int hf_smb2_max_ioctl_out_size = -1;
109 static int hf_smb2_required_buffer_size = -1;
110 static int hf_smb2_response_size = -1;
111 static int hf_smb2_setinfo_size = -1;
112 static int hf_smb2_setinfo_offset = -1;
113 static int hf_smb2_file_basic_info = -1;
114 static int hf_smb2_file_standard_info = -1;
115 static int hf_smb2_file_internal_info = -1;
116 static int hf_smb2_file_ea_info = -1;
117 static int hf_smb2_file_access_info = -1;
118 static int hf_smb2_file_rename_info = -1;
119 static int hf_smb2_file_disposition_info = -1;
120 static int hf_smb2_file_position_info = -1;
121 static int hf_smb2_file_info_0f = -1;
122 static int hf_smb2_file_mode_info = -1;
123 static int hf_smb2_file_alignment_info = -1;
124 static int hf_smb2_file_all_info = -1;
125 static int hf_smb2_file_allocation_info = -1;
126 static int hf_smb2_file_endoffile_info = -1;
127 static int hf_smb2_file_alternate_name_info = -1;
128 static int hf_smb2_file_stream_info = -1;
129 static int hf_smb2_file_pipe_info = -1;
130 static int hf_smb2_file_compression_info = -1;
131 static int hf_smb2_file_network_open_info = -1;
132 static int hf_smb2_file_attribute_tag_info = -1;
133 static int hf_smb2_fs_info_01 = -1;
134 static int hf_smb2_fs_info_03 = -1;
135 static int hf_smb2_fs_info_04 = -1;
136 static int hf_smb2_fs_info_05 = -1;
137 static int hf_smb2_fs_info_06 = -1;
138 static int hf_smb2_fs_info_07 = -1;
139 static int hf_smb2_fs_objectid_info = -1;
140 static int hf_smb2_sec_info_00 = -1;
141 static int hf_smb2_fid = -1;
142 static int hf_smb2_write_length = -1;
143 static int hf_smb2_write_offset = -1;
144 static int hf_smb2_write_data = -1;
145 static int hf_smb2_read_length = -1;
146 static int hf_smb2_read_offset = -1;
147 static int hf_smb2_read_data = -1;
148 static int hf_smb2_disposition_delete_on_close = -1;
149 static int hf_smb2_create_disposition = -1;
150 static int hf_smb2_chain_offset = -1;
151 static int hf_smb2_chain_data = -1;
152 static int hf_smb2_data_offset = -1;
153 static int hf_smb2_data_length = -1;
154 static int hf_smb2_extrainfo = -1;
155 static int hf_smb2_create_action = -1;
156 static int hf_smb2_next_offset = -1;
157 static int hf_smb2_ea_size = -1;
158 static int hf_smb2_ea_flags = -1;
159 static int hf_smb2_ea_name_len = -1;
160 static int hf_smb2_ea_data_len = -1;
161 static int hf_smb2_ea_name = -1;
162 static int hf_smb2_ea_data = -1;
163 static int hf_smb2_buffer_code_len = -1;
164 static int hf_smb2_buffer_code_flags_dyn = -1;
165 static int hf_smb2_olb_offset = -1;
166 static int hf_smb2_olb_length = -1;
167 static int hf_smb2_tag = -1;
168 static int hf_smb2_impersonation_level = -1;
169 static int hf_smb2_ioctl_function = -1;
170 static int hf_smb2_ioctl_function_device = -1;
171 static int hf_smb2_ioctl_function_access = -1;
172 static int hf_smb2_ioctl_function_function = -1;
173 static int hf_smb2_ioctl_function_method = -1;
174 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
175 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
176 static int hf_smb2_ioctl_shadow_copy_count = -1;
177 static int hf_smb2_ioctl_shadow_copy_label = -1;
178 static int hf_smb2_compression_format = -1;
179 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
180 static int hf_smb2_acct_name = -1;
181 static int hf_smb2_domain_name = -1;
182 static int hf_smb2_host_name = -1;
183 static int hf_smb2_auth_frame = -1;
184 static int hf_smb2_tcon_frame = -1;
185 static int hf_smb2_share_type = -1;
186 static int hf_smb2_signature = -1;
187
188 static gint ett_smb2 = -1;
189 static gint ett_smb2_olb = -1;
190 static gint ett_smb2_ea = -1;
191 static gint ett_smb2_header = -1;
192 static gint ett_smb2_command = -1;
193 static gint ett_smb2_secblob = -1;
194 static gint ett_smb2_file_basic_info = -1;
195 static gint ett_smb2_file_standard_info = -1;
196 static gint ett_smb2_file_internal_info = -1;
197 static gint ett_smb2_file_ea_info = -1;
198 static gint ett_smb2_file_access_info = -1;
199 static gint ett_smb2_file_position_info = -1;
200 static gint ett_smb2_file_mode_info = -1;
201 static gint ett_smb2_file_alignment_info = -1;
202 static gint ett_smb2_file_all_info = -1;
203 static gint ett_smb2_file_allocation_info = -1;
204 static gint ett_smb2_file_endoffile_info = -1;
205 static gint ett_smb2_file_alternate_name_info = -1;
206 static gint ett_smb2_file_stream_info = -1;
207 static gint ett_smb2_file_pipe_info = -1;
208 static gint ett_smb2_file_compression_info = -1;
209 static gint ett_smb2_file_network_open_info = -1;
210 static gint ett_smb2_file_attribute_tag_info = -1;
211 static gint ett_smb2_file_rename_info = -1;
212 static gint ett_smb2_file_disposition_info = -1;
213 static gint ett_smb2_file_info_0f = -1;
214 static gint ett_smb2_fs_info_01 = -1;
215 static gint ett_smb2_fs_info_03 = -1;
216 static gint ett_smb2_fs_info_04 = -1;
217 static gint ett_smb2_fs_info_05 = -1;
218 static gint ett_smb2_fs_info_06 = -1;
219 static gint ett_smb2_fs_info_07 = -1;
220 static gint ett_smb2_fs_objectid_info = -1;
221 static gint ett_smb2_sec_info_00 = -1;
222 static gint ett_smb2_tid_tree = -1;
223 static gint ett_smb2_uid_tree = -1;
224 static gint ett_smb2_create_flags = -1;
225 static gint ett_smb2_chain_element = -1;
226 static gint ett_smb2_MxAc_buffer = -1;
227 static gint ett_smb2_ioctl_function = -1;
228 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
229 static gint ett_smb2_flags = -1;
230
231 static int smb2_tap = -1;
232
233 static dissector_handle_t gssapi_handle = NULL;
234 static dissector_handle_t ntlmssp_handle = NULL;
235
236 static heur_dissector_list_t smb2_heur_subdissector_list;
237
238 #define SMB2_CLASS_FILE_INFO    0x01
239 #define SMB2_CLASS_FS_INFO      0x02
240 #define SMB2_CLASS_SEC_INFO     0x03
241 static const value_string smb2_class_vals[] = {
242         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
243         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
244         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
245         { 0, NULL }
246 };
247
248 #define SMB2_SHARE_TYPE_FILE    0x0001
249 #define SMB2_SHARE_TYPE_IPC     0x0002
250 #define SMB2_SHARE_TYPE_PRINT   0x0003
251 static const value_string smb2_share_type_vals[] = {
252         { SMB2_SHARE_TYPE_FILE,         "File Share" },
253         { SMB2_SHARE_TYPE_IPC,          "IPC share" },
254         { SMB2_SHARE_TYPE_PRINT,        "Print Share" },
255         { 0, NULL }
256 };
257
258
259 #define SMB2_FILE_BASIC_INFO    0x04
260 #define SMB2_FILE_STANDARD_INFO 0x05
261 #define SMB2_FILE_INTERNAL_INFO 0x06
262 #define SMB2_FILE_EA_INFO       0x07
263 #define SMB2_FILE_ACCESS_INFO   0x08
264 #define SMB2_FILE_RENAME_INFO   0x0a
265 #define SMB2_FILE_DISPOSITION_INFO      0x0d
266 #define SMB2_FILE_POSITION_INFO 0x0e
267 #define SMB2_FILE_INFO_0f       0x0f
268 #define SMB2_FILE_MODE_INFO     0x10
269 #define SMB2_FILE_ALIGNMENT_INFO        0x11
270 #define SMB2_FILE_ALL_INFO      0x12
271 #define SMB2_FILE_ALLOCATION_INFO       0x13
272 #define SMB2_FILE_ENDOFFILE_INFO        0x14
273 #define SMB2_FILE_ALTERNATE_NAME_INFO   0x15
274 #define SMB2_FILE_STREAM_INFO           0x16
275 #define SMB2_FILE_PIPE_INFO             0x17
276 #define SMB2_FILE_COMPRESSION_INFO      0x1c
277 #define SMB2_FILE_NETWORK_OPEN_INFO     0x22
278 #define SMB2_FILE_ATTRIBUTE_TAG_INFO    0x23
279 static const value_string smb2_file_info_levels[] = {
280         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
281         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
282         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
283         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
284         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
285         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
286         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
287         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
288         {SMB2_FILE_INFO_0f,             "SMB2_FILE_INFO_0f" },
289         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
290         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
291         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
292         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
293         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
294         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
295         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
296         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
297         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
298         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
299         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
300         { 0, NULL }
301 };
302
303
304
305 #define SMB2_FS_INFO_01         0x01
306 #define SMB2_FS_INFO_03         0x03
307 #define SMB2_FS_INFO_04         0x04
308 #define SMB2_FS_INFO_05         0x05
309 #define SMB2_FS_INFO_06         0x06
310 #define SMB2_FS_INFO_07         0x07
311 #define SMB2_FS_OBJECTID_INFO   0x08
312 static const value_string smb2_fs_info_levels[] = {
313         {SMB2_FS_INFO_01,       "SMB2_FS_INFO_01" },
314         {SMB2_FS_INFO_03,       "SMB2_FS_INFO_03" },
315         {SMB2_FS_INFO_04,       "SMB2_FS_INFO_04" },
316         {SMB2_FS_INFO_05,       "SMB2_FS_INFO_05" },
317         {SMB2_FS_INFO_06,       "SMB2_FS_INFO_06" },
318         {SMB2_FS_INFO_07,       "SMB2_FS_INFO_07" },
319         {SMB2_FS_OBJECTID_INFO, "SMB2_FS_OBJECTID_INFO" },
320         { 0, NULL }
321 };
322
323 #define SMB2_SEC_INFO_00        0x00
324 static const value_string smb2_sec_info_levels[] = {
325         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
326         { 0, NULL }
327 };
328
329 /* unmatched smb_saved_info structures.
330    For unmatched smb_saved_info structures we store the smb_saved_info
331    structure using the SEQNUM field.
332 */
333 static gint
334 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
335 {
336         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
337         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
338         return key1->seqnum==key2->seqnum;
339 }
340 static guint
341 smb2_saved_info_hash_unmatched(gconstpointer k)
342 {
343         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
344         guint32 hash;
345
346         hash=key->seqnum&0xffffffff;
347         return hash;
348 }
349
350 /* matched smb_saved_info structures.
351    For matched smb_saved_info structures we store the smb_saved_info
352    structure using the SEQNUM field.
353 */
354 static gint
355 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
356 {
357         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
358         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
359         return key1->seqnum==key2->seqnum;
360 }
361 static guint
362 smb2_saved_info_hash_matched(gconstpointer k)
363 {
364         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
365         guint32 hash;
366
367         hash=key->seqnum&0xffffffff;
368         return hash;
369 }
370
371 /* For Tids of a specific conversation.
372    This keeps track of tid->sharename mappings and other information about the
373    tid.
374    qqq
375    We might need to refine this if it occurs that tids are reused on a single
376    conversation.   we dont worry about that yet for simplicity
377 */
378 static gint
379 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
380 {
381         smb2_tid_info_t *key1 = (smb2_tid_info_t *)k1;
382         smb2_tid_info_t *key2 = (smb2_tid_info_t *)k2;
383         return key1->tid==key2->tid;
384 }
385 static guint
386 smb2_tid_info_hash(gconstpointer k)
387 {
388         smb2_tid_info_t *key = (smb2_tid_info_t *)k;
389         guint32 hash;
390
391         hash=key->tid;
392         return hash;
393 }
394
395 /* For Uids of a specific conversation.
396    This keeps track of uid->acct_name mappings and other information about the
397    uid.
398    qqq
399    We might need to refine this if it occurs that uids are reused on a single
400    conversation.   we dont worry about that yet for simplicity
401 */
402 static gint
403 smb2_uid_info_equal(gconstpointer k1, gconstpointer k2)
404 {
405         smb2_uid_info_t *key1 = (smb2_uid_info_t *)k1;
406         smb2_uid_info_t *key2 = (smb2_uid_info_t *)k2;
407         return key1->uid==key2->uid;
408 }
409 static guint
410 smb2_uid_info_hash(gconstpointer k)
411 {
412         smb2_uid_info_t *key = (smb2_uid_info_t *)k;
413         guint32 hash;
414
415         hash=((key->uid>>32)&&0xffffffff)+((key->uid)&&0xffffffff);
416         return hash;
417 }
418
419 static int dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
420
421
422 /* This is a helper to dissect the common string type
423  * uint16 offset
424  * uint16 length
425  * ...
426  * char *string
427  *
428  * This function is called twice, first to decode the offset/length and
429  * second time to dissect the actual string.
430  * It is done this way since there is no guarantee that we have the full packet and we dont
431  * want to abort dissection too early if the packet ends somewhere between the
432  * length/offset and the actual buffer.
433  *
434  */
435 enum offset_length_buffer_offset_size {
436         OLB_O_UINT16_S_UINT16,
437         OLB_O_UINT16_S_UINT32,
438         OLB_O_UINT32_S_UINT32,
439         OLB_S_UINT32_O_UINT32
440 };
441 typedef struct _offset_length_buffer_t {
442         guint32 off;
443         guint32 len;
444         int off_offset;
445         int len_offset;
446         enum offset_length_buffer_offset_size offset_size;
447         int hfindex;
448 } offset_length_buffer_t;
449 static int
450 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
451                                enum offset_length_buffer_offset_size offset_size, int hfindex)
452 {
453         olb->hfindex=hfindex;
454         olb->offset_size=offset_size;
455         switch(offset_size){
456         case OLB_O_UINT16_S_UINT16:
457                 olb->off=tvb_get_letohs(tvb, offset);
458                 olb->off_offset=offset;
459                 offset += 2;
460                 olb->len=tvb_get_letohs(tvb, offset);
461                 olb->len_offset=offset;
462                 offset += 2;
463                 break;
464         case OLB_O_UINT16_S_UINT32:
465                 olb->off=tvb_get_letohs(tvb, offset);
466                 olb->off_offset=offset;
467                 offset += 2;
468                 olb->len=tvb_get_letohl(tvb, offset);
469                 olb->len_offset=offset;
470                 offset += 4;
471                 break;
472         case OLB_O_UINT32_S_UINT32:
473                 olb->off=tvb_get_letohl(tvb, offset);
474                 olb->off_offset=offset;
475                 offset += 4;
476                 olb->len=tvb_get_letohl(tvb, offset);
477                 olb->len_offset=offset;
478                 offset += 4;
479                 break;
480         case OLB_S_UINT32_O_UINT32:
481                 olb->len=tvb_get_letohl(tvb, offset);
482                 olb->len_offset=offset;
483                 offset += 4;
484                 olb->off=tvb_get_letohl(tvb, offset);
485                 olb->off_offset=offset;
486                 offset += 4;
487                 break;
488         }
489
490         return offset;
491 }
492
493 #define OLB_TYPE_UNICODE_STRING         0x01
494 #define OLB_TYPE_ASCII_STRING           0x02
495 static const char *
496 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
497 {
498         int len, off;
499         proto_item *item=NULL;
500         proto_tree *tree=NULL;
501         const char *name=NULL;
502         guint16 bc;
503         int offset;
504
505         offset=olb->off;
506         len=olb->len;
507         off=olb->off;
508         bc=tvb_length_remaining(tvb, offset);
509
510
511         /* sanity check */
512         tvb_ensure_bytes_exist(tvb, off, len);
513         if(((off+len)<off)
514         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
515                 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
516                                     "Invalid offset/length. Malformed packet");
517
518                 if (check_col(pinfo->cinfo, COL_INFO)){
519                         col_append_fstr(pinfo->cinfo, COL_INFO, " [Malformed packet]");
520                 }
521
522                 return NULL;
523         }
524
525
526         switch(type){
527         case OLB_TYPE_UNICODE_STRING:
528                 name = get_unicode_or_ascii_string(tvb, &off,
529                         TRUE, &len, TRUE, TRUE, &bc);
530                 if(!name){
531                         name="";
532                 }
533                 if(parent_tree){
534                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
535                         tree = proto_item_add_subtree(item, ett_smb2_olb);
536                 }
537                 break;
538         case OLB_TYPE_ASCII_STRING:
539                 name = get_unicode_or_ascii_string(tvb, &off,
540                         FALSE, &len, TRUE, TRUE, &bc);
541                 if(!name){
542                         name="";
543                 }
544                 if(parent_tree){
545                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
546                         tree = proto_item_add_subtree(item, ett_smb2_olb);
547                 }
548                 break;
549         }
550
551         switch(olb->offset_size){
552         case OLB_O_UINT16_S_UINT16:
553                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
554                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
555                 break;
556         case OLB_O_UINT16_S_UINT32:
557                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
558                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
559                 break;
560         case OLB_O_UINT32_S_UINT32:
561                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
562                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
563                 break;
564         case OLB_S_UINT32_O_UINT32:
565                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
566                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
567                 break;
568         }
569
570         return name;
571 }
572
573 static void
574 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
575                         offset_length_buffer_t *olb, smb2_info_t *si,
576                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
577 {
578         int len, off;
579         proto_item *sub_item=NULL;
580         proto_tree *sub_tree=NULL;
581         tvbuff_t *sub_tvb=NULL;
582         guint16 bc;
583         int offset;
584
585         offset=olb->off;
586         len=olb->len;
587         off=olb->off;
588         bc=tvb_length_remaining(tvb, offset);
589
590         /* sanity check */
591         tvb_ensure_bytes_exist(tvb, off, len);
592         if(((off+len)<off)
593         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
594                 proto_tree_add_text(parent_tree, tvb, offset, tvb_length_remaining(tvb, offset),
595                                     "Invalid offset/length. Malformed packet");
596
597                 if (check_col(pinfo->cinfo, COL_INFO)){
598                         col_append_fstr(pinfo->cinfo, COL_INFO, " [Malformed packet]");
599                 }
600
601                 return;
602         }
603
604         /* if we dont want/need a subtree */
605         if(olb->hfindex==-1){
606                 sub_item=parent_tree;
607                 sub_tree=parent_tree;
608         } else {
609                 if(parent_tree){
610                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, TRUE);
611                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
612                 }
613         }
614
615         switch(olb->offset_size){
616         case OLB_O_UINT16_S_UINT16:
617                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
618                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
619                 break;
620         case OLB_O_UINT16_S_UINT32:
621                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
622                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
623                 break;
624         case OLB_O_UINT32_S_UINT32:
625                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
626                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
627                 break;
628         case OLB_S_UINT32_O_UINT32:
629                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
630                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
631                 break;
632         }
633
634         if (off == 0 || len == 0) {
635                 proto_item_append_text(sub_item, ": NO DATA");
636                 return;
637         }
638
639         if (!dissector) {
640                 return;
641         }
642
643         sub_tvb=tvb_new_subset(tvb, off, MIN((int)len, tvb_length_remaining(tvb, off)), len);
644
645         dissector(sub_tvb, pinfo, sub_tree, si);
646
647         return;
648 }
649
650 static int
651 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
652 {
653         if (olb->off == 0) {
654                 return offset;
655         }
656         return MAX(offset, (int)(olb->off + olb->len));
657 }
658
659 typedef struct _smb2_function {
660        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
661        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
662 } smb2_function;
663
664 static const true_false_string tfs_flags_response = {
665         "This is a RESPONSE",
666         "This is a REQUEST"
667 };
668
669 static const true_false_string tfs_flags_pid_valid = {
670         "The PID field is VALID",
671         "The pid field if NOT valid"
672 };
673
674 static const true_false_string tfs_flags_signature = {
675         "This pdu is SIGNED",
676         "This pdu is NOT signed"
677 };
678
679 static const value_string compression_format_vals[] = {
680   { 0, "COMPRESSION_FORMAT_NONE" },
681   { 1, "COMPRESSION_FORMAT_DEFAULT" },
682   { 2, "COMPRESSION_FORMAT_LZNT1" },
683   { 0, NULL }
684 };
685
686
687 static const value_string smb2_ioctl_vals[] = {
688   /* dissector implemented */
689   {0x0011c017, "IOCTL_DO_DCERPC"},
690   {0x00144064, "FSCTL_GET_SHADOW_COPY_DATA"},
691   {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},
692   {0x0009009C, "FSCTL_GET_OBJECT_ID"},
693   {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
694   {0x00098098, "FSCTL_SET_OBJECT_ID"},
695   {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},
696   {0x0009003C, "FSCTL_GET_COMPRESSION"},
697   {0x0009C040, "FSCTL_SET_COMPRESSION"},
698
699   /* dissector not yet implemented */
700   {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
701   {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
702   {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
703   {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
704   {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
705   {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
706   {0x00090018, "FSCTL_LOCK_VOLUME"},
707   {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
708   {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
709   {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
710   {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
711   {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
712   {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
713   {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
714   {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
715   {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
716   {0x00090058, "FSCTL_QUERY_FAT_BPB"},
717   {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
718   {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
719   {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
720   {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
721   {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
722   {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
723   {0x00090074, "FSCTL_MOVE_FILE"},
724   {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
725   {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
726   {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
727   {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
728   {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
729   {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
730   {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
731   {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
732   {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
733   {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
734   {0x000940B3, "FSCTL_ENUM_USN_DATA"},
735   {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
736   {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
737   {0x000980C4, "FSCTL_SET_SPARSE"},
738   {0x000980C8, "FSCTL_SET_ZERO_DATA"},
739   {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},
740   {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
741   {0x000900D4, "FSCTL_SET_ENCRYPTION"},
742   {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
743   {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
744   {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
745   {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
746   {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
747   {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
748   {0x000900F0, "FSCTL_EXTEND_VOLUME"},
749   { 0, NULL }
750 };
751
752
753 static const value_string smb2_ioctl_device_vals[] = {
754   { 0x0001, "BEEP" },
755   { 0x0002, "CD_ROM" },
756   { 0x0003, "CD_ROM_FILE_SYSTEM" },
757   { 0x0004, "CONTROLLER" },
758   { 0x0005, "DATALINK" },
759   { 0x0006, "DFS" },
760   { 0x0007, "DISK" },
761   { 0x0008, "DISK_FILE_SYSTEM" },
762   { 0x0009, "FILE_SYSTEM" },
763   { 0x000a, "INPORT_PORT" },
764   { 0x000b, "KEYBOARD" },
765   { 0x000c, "MAILSLOT" },
766   { 0x000d, "MIDI_IN" },
767   { 0x000e, "MIDI_OUT" },
768   { 0x000f, "MOUSE" },
769   { 0x0010, "MULTI_UNC_PROVIDER" },
770   { 0x0011, "NAMED_PIPE" },
771   { 0x0012, "NETWORK" },
772   { 0x0013, "NETWORK_BROWSER" },
773   { 0x0014, "NETWORK_FILE_SYSTEM" },
774   { 0x0015, "NULL" },
775   { 0x0016, "PARALLEL_PORT" },
776   { 0x0017, "PHYSICAL_NETCARD" },
777   { 0x0018, "PRINTER" },
778   { 0x0019, "SCANNER" },
779   { 0x001a, "SERIAL_MOUSE_PORT" },
780   { 0x001b, "SERIAL_PORT" },
781   { 0x001c, "SCREEN" },
782   { 0x001d, "SOUND" },
783   { 0x001e, "STREAMS" },
784   { 0x001f, "TAPE" },
785   { 0x0020, "TAPE_FILE_SYSTEM" },
786   { 0x0021, "TRANSPORT" },
787   { 0x0022, "UNKNOWN" },
788   { 0x0023, "VIDEO" },
789   { 0x0024, "VIRTUAL_DISK" },
790   { 0x0025, "WAVE_IN" },
791   { 0x0026, "WAVE_OUT" },
792   { 0x0027, "8042_PORT" },
793   { 0x0028, "NETWORK_REDIRECTOR" },
794   { 0x0029, "BATTERY" },
795   { 0x002a, "BUS_EXTENDER" },
796   { 0x002b, "MODEM" },
797   { 0x002c, "VDM" },
798   { 0x002d, "MASS_STORAGE" },
799   { 0x002e, "SMB" },
800   { 0x002f, "KS" },
801   { 0x0030, "CHANGER" },
802   { 0x0031, "SMARTCARD" },
803   { 0x0032, "ACPI" },
804   { 0x0033, "DVD" },
805   { 0x0034, "FULLSCREEN_VIDEO" },
806   { 0x0035, "DFS_FILE_SYSTEM" },
807   { 0x0036, "DFS_VOLUME" },
808   { 0x0037, "SERENUM" },
809   { 0x0038, "TERMSRV" },
810   { 0x0039, "KSEC" },
811   { 0, NULL }
812 };
813
814 static const value_string smb2_ioctl_access_vals[] = {
815   { 0x00, "FILE_ANY_ACCESS" },
816   { 0x01, "FILE_READ_ACCESS" },
817   { 0x02, "FILE_WRITE_ACCESS" },
818   { 0x03, "FILE_READ_WRITE_ACCESS" },
819   { 0, NULL }
820 };
821
822 static const value_string smb2_ioctl_method_vals[] = {
823   { 0x00, "METHOD_BUFFERED" },
824   { 0x01, "METHOD_IN_DIRECT" },
825   { 0x02, "METHOD_OUT_DIRECT" },
826   { 0x03, "METHOD_NEITHER" },
827   { 0, NULL }
828 };
829
830 static int
831 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si)
832 {
833         proto_item *item=NULL;
834         proto_tree *tree=NULL;
835
836         if(parent_tree){
837                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, TRUE);
838                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
839         }
840
841         si->ioctl_function=tvb_get_letohl(tvb, offset);
842         if(si->ioctl_function){
843                 /* device */
844                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, TRUE);
845                 if (check_col(pinfo->cinfo, COL_INFO)){
846                         col_append_fstr(
847                                 pinfo->cinfo, COL_INFO, " %s",
848                                 val_to_str((si->ioctl_function>>16)&0xffff, smb2_ioctl_device_vals,
849                                 "Unknown (0x%08X)"));
850                 }
851
852                 /* access */
853                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, TRUE);
854
855                 /* function */
856                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, TRUE);
857                 if (check_col(pinfo->cinfo, COL_INFO)){
858                         col_append_fstr(
859                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
860                                 (si->ioctl_function>>2)&0x0fff);
861                 }
862
863                 /* method */
864                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, TRUE);
865         }
866
867         offset += 4;
868
869         return offset;
870 }
871
872 /* fake the dce/rpc support structures so we can piggy back on
873  * dissect_nt_policy_hnd()   since this will allow us
874  * a cheap way to track where FIDs are opened, closed
875  * and fid->filename mappings
876  * if we want to do those things in the future.
877  */
878 #define FID_MODE_OPEN           0
879 #define FID_MODE_CLOSE          1
880 #define FID_MODE_USE            2
881 static int
882 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
883 {
884         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
885         dcerpc_info di; /* fake dcerpc_info struct */
886         void *old_private_data;
887         e_ctx_hnd policy_hnd;
888         proto_item *hnd_item=NULL;
889         char *fid_name;
890         guint32 open_frame = 0, close_frame = 0;
891
892         di.conformant_run=0;
893         di.call_data=NULL;
894         old_private_data=pinfo->private_data;
895         pinfo->private_data=&di;
896
897         switch(mode){
898         case FID_MODE_OPEN:
899                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
900                 if(!pinfo->fd->flags.visited){
901                         if(si->saved && si->saved->private_data){
902                                 fid_name = se_strdup_printf("File:%s", (char *)si->saved->private_data);
903                         } else {
904                                 fid_name = se_strdup_printf("File: ");
905                         }
906                         dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
907                                                   fid_name);
908                 }
909                 break;
910         case FID_MODE_CLOSE:
911                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
912                 break;
913         case FID_MODE_USE:
914                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
915                 break;
916         }
917
918         pinfo->private_data=old_private_data;
919
920
921         /* put the filename in col_info */
922         if (dcerpc_smb_fetch_pol(&policy_hnd, &fid_name, &open_frame, &close_frame, pinfo->fd->num)) {
923                 if(fid_name){
924                         if(hnd_item){
925                                 proto_item_append_text(hnd_item, " %s", fid_name);
926                         }
927                         if (check_col(pinfo->cinfo, COL_INFO)){
928                                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", fid_name);
929                         }
930                 }
931         }
932
933         return offset;
934 }
935
936
937 /* this info level is unique to SMB2 and differst from the corresponding
938  * SMB_FILE_ALL_INFO in SMB
939  */
940 static int
941 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
942 {
943         proto_item *item=NULL;
944         proto_tree *tree=NULL;
945         int length;
946         const char *name="";
947         guint16 bc;
948
949         if(parent_tree){
950                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, TRUE);
951                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
952         }
953
954         /* create time */
955         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
956
957         /* last access */
958         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
959
960         /* last write */
961         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
962
963         /* last change */
964         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
965
966         /* File Attributes */
967         offset = dissect_file_attributes(tvb, tree, offset, 4);
968
969         /* some unknown bytes */
970         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
971         offset += 4;
972
973         /* allocation size */
974         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
975         offset += 8;
976
977         /* end of file */
978         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
979         offset += 8;
980
981         /* number of links */
982         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, TRUE);
983         offset += 4;
984
985         /* delete pending */
986         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, TRUE);
987         offset += 1;
988
989         /* is directory */
990         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, TRUE);
991         offset += 1;
992
993         /* padding */
994         offset += 2;
995
996         /* file id */
997         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
998         offset += 8;
999
1000         /* ea size */
1001         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
1002         offset += 4;
1003
1004         /* access mask */
1005         offset = dissect_smb_access_mask(tvb, tree, offset);
1006
1007         /* some unknown bytes */
1008         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1009         offset += 16;
1010
1011         /* file name length */
1012         length=tvb_get_letohs(tvb, offset);
1013         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1014         offset += 2;
1015
1016         /* some unknown bytes */
1017         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1018         offset += 2;
1019
1020         /* file name */
1021         if(length){
1022                 bc=tvb_length_remaining(tvb, offset);
1023                 name = get_unicode_or_ascii_string(tvb, &offset,
1024                         TRUE, &length, TRUE, TRUE, &bc);
1025                 if(name){
1026                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1027                                 offset, length, name);
1028                 }
1029
1030         }
1031         offset += length;
1032
1033
1034         return offset;
1035 }
1036
1037
1038 static int
1039 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1040 {
1041         proto_item *item=NULL;
1042         proto_tree *tree=NULL;
1043         guint16 bc;
1044         gboolean trunc;
1045
1046         if(parent_tree){
1047                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, TRUE);
1048                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1049         }
1050
1051         bc=tvb_length_remaining(tvb, offset);
1052         offset = dissect_qfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1053
1054         return offset;
1055 }
1056
1057 static int
1058 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1059 {
1060         proto_item *item=NULL;
1061         proto_tree *tree=NULL;
1062         guint16 bc;
1063         gboolean trunc;
1064
1065         if(parent_tree){
1066                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, TRUE);
1067                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1068         }
1069
1070         bc=tvb_length_remaining(tvb, offset);
1071         offset = dissect_qfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1072
1073         return offset;
1074 }
1075
1076 static int
1077 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1078 {
1079         proto_item *item=NULL;
1080         proto_tree *tree=NULL;
1081         guint16 bc;
1082         gboolean trunc;
1083
1084         if(parent_tree){
1085                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, TRUE);
1086                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1087         }
1088
1089         bc=tvb_length_remaining(tvb, offset);
1090         offset = dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1091
1092         return offset;
1093 }
1094
1095
1096 static int
1097 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1098 {
1099         proto_item *item=NULL;
1100         proto_tree *tree=NULL;
1101
1102         if(parent_tree){
1103                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, TRUE);
1104                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1105         }
1106
1107         /* create time */
1108         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1109
1110         /* last access */
1111         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1112
1113         /* last write */
1114         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1115
1116         /* last change */
1117         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1118
1119         /* File Attributes */
1120         offset = dissect_file_attributes(tvb, tree, offset, 4);
1121
1122         /* some unknown bytes */
1123         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1124         offset += 4;
1125
1126         return offset;
1127 }
1128
1129 static int
1130 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1131 {
1132         proto_item *item=NULL;
1133         proto_tree *tree=NULL;
1134         guint16 bc;
1135         gboolean trunc;
1136
1137         if(parent_tree){
1138                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, TRUE);
1139                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
1140         }
1141
1142         bc=tvb_length_remaining(tvb, offset);
1143         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1144
1145         return offset;
1146 }
1147 static int
1148 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1149 {
1150         proto_item *item=NULL;
1151         proto_tree *tree=NULL;
1152         guint16 bc;
1153         gboolean trunc;
1154
1155         if(parent_tree){
1156                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, TRUE);
1157                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
1158         }
1159
1160         bc=tvb_length_remaining(tvb, offset);
1161         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1162
1163         return offset;
1164 }
1165 static int
1166 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1167 {
1168         proto_item *item=NULL;
1169         proto_tree *tree=NULL;
1170         guint16 bc;
1171         gboolean trunc;
1172
1173         if(parent_tree){
1174                 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, TRUE);
1175                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
1176         }
1177
1178         bc=tvb_length_remaining(tvb, offset);
1179         offset = dissect_qfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1180
1181         return offset;
1182 }
1183 static int
1184 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1185 {
1186         proto_item *item=NULL;
1187         proto_tree *tree=NULL;
1188         guint16 bc;
1189         gboolean trunc;
1190
1191         if(parent_tree){
1192                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, TRUE);
1193                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
1194         }
1195
1196         bc=tvb_length_remaining(tvb, offset);
1197         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1198
1199         return offset;
1200 }
1201 static int
1202 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1203 {
1204         proto_item *item=NULL;
1205         proto_tree *tree=NULL;
1206         guint16 bc;
1207         gboolean trunc;
1208
1209         if(parent_tree){
1210                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, TRUE);
1211                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
1212         }
1213
1214         bc=tvb_length_remaining(tvb, offset);
1215         offset = dissect_qfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1216
1217         return offset;
1218 }
1219
1220 static int
1221 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1222 {
1223         proto_item *item=NULL;
1224         proto_tree *tree=NULL;
1225
1226         if(parent_tree){
1227                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, TRUE);
1228                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
1229         }
1230
1231         /* access mask */
1232         offset = dissect_smb_access_mask(tvb, tree, offset);
1233
1234         return offset;
1235 }
1236
1237 static int
1238 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1239 {
1240         proto_item *item=NULL;
1241         proto_tree *tree=NULL;
1242         guint16 bc;
1243         gboolean trunc;
1244
1245         if(parent_tree){
1246                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, TRUE);
1247                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
1248         }
1249
1250         bc=tvb_length_remaining(tvb, offset);
1251         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1252
1253         return offset;
1254 }
1255
1256 static int
1257 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1258 {
1259         proto_item *item=NULL;
1260         proto_tree *tree=NULL;
1261         guint16 bc;
1262         gboolean trunc;
1263
1264         if(parent_tree){
1265                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, TRUE);
1266                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
1267         }
1268
1269         bc=tvb_length_remaining(tvb, offset);
1270         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
1271
1272         return offset;
1273 }
1274
1275 static int
1276 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1277 {
1278         proto_item *item=NULL;
1279         proto_tree *tree=NULL;
1280         guint16 bc;
1281         gboolean trunc;
1282
1283         if(parent_tree){
1284                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, TRUE);
1285                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
1286         }
1287
1288         bc=tvb_length_remaining(tvb, offset);
1289         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1290
1291         return offset;
1292 }
1293
1294 static int
1295 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1296 {
1297         proto_item *item=NULL;
1298         proto_tree *tree=NULL;
1299         guint16 bc;
1300         gboolean trunc;
1301
1302         if(parent_tree){
1303                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, TRUE);
1304                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
1305         }
1306
1307         bc=tvb_length_remaining(tvb, offset);
1308         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1309
1310         return offset;
1311 }
1312
1313 static int
1314 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1315 {
1316         proto_item *item=NULL;
1317         proto_tree *tree=NULL;
1318         guint16 bc;
1319         gboolean trunc;
1320
1321         if(parent_tree){
1322                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, TRUE);
1323                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
1324         }
1325
1326
1327         bc=tvb_length_remaining(tvb, offset);
1328         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1329
1330         return offset;
1331 }
1332
1333 static int
1334 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1335 {
1336         proto_item *item=NULL;
1337         proto_tree *tree=NULL;
1338         guint16 bc;
1339         gboolean trunc;
1340
1341         if(parent_tree){
1342                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, TRUE);
1343                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
1344         }
1345
1346
1347         bc=tvb_length_remaining(tvb, offset);
1348         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1349
1350         return offset;
1351 }
1352
1353 static const true_false_string tfs_disposition_delete_on_close = {
1354         "DELETE this file when closed",
1355         "Normal access, do not delete on close"
1356 };
1357
1358 static int
1359 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1360 {
1361         proto_item *item=NULL;
1362         proto_tree *tree=NULL;
1363
1364         if(parent_tree){
1365                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, TRUE);
1366                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
1367         }
1368
1369         /* file disposition */
1370         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, TRUE);
1371
1372         return offset;
1373 }
1374
1375 static int
1376 dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1377 {
1378         proto_item *item=NULL;
1379         proto_tree *tree=NULL;
1380         guint32 next_offset;
1381         guint8 ea_name_len, ea_data_len;
1382
1383         if(parent_tree){
1384                 item = proto_tree_add_item(parent_tree, hf_smb2_file_info_0f, tvb, offset, -1, TRUE);
1385                 tree = proto_item_add_subtree(item, ett_smb2_file_info_0f);
1386         }
1387
1388         while(1){
1389                 int length;
1390                 const char *name="";
1391                 const char *data="";
1392                 guint16 bc;
1393                 int start_offset=offset;
1394                 proto_item *ea_item=NULL;
1395                 proto_tree *ea_tree=NULL;
1396
1397                 if(tree){
1398                         ea_item = proto_tree_add_text(tree, tvb, offset, -1, "EA:");
1399                         ea_tree = proto_item_add_subtree(ea_item, ett_smb2_ea);
1400                 }
1401
1402                 /* next offset */
1403                 next_offset=tvb_get_letohl(tvb, offset);
1404                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
1405                 offset += 4;
1406
1407                 /* EA flags */
1408                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, TRUE);
1409                 offset += 1;
1410
1411                 /* EA Name Length */
1412                 ea_name_len=tvb_get_guint8(tvb, offset);
1413                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, TRUE);
1414                 offset += 1;
1415
1416                 /* EA Data Length */
1417                 ea_data_len=tvb_get_guint8(tvb, offset);
1418                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 1, TRUE);
1419                 offset += 1;
1420
1421                 /* some unknown bytes */
1422                 proto_tree_add_item(ea_tree, hf_smb2_unknown, tvb, offset, 1, TRUE);
1423                 offset += 1;
1424
1425                 /* ea name */
1426                 length=ea_name_len;
1427                 if(length){
1428                         bc=tvb_length_remaining(tvb, offset);
1429                         name = get_unicode_or_ascii_string(tvb, &offset,
1430                                 FALSE, &length, TRUE, TRUE, &bc);
1431                         if(name){
1432                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
1433                                         offset, length, name);
1434                         }
1435                 }
1436                 offset += ea_name_len;
1437
1438                 /* separator byte */
1439                 offset += 1;
1440
1441                 /* ea data */
1442                 length=ea_data_len;
1443                 if(length){
1444                         bc=tvb_length_remaining(tvb, offset);
1445                         data = get_unicode_or_ascii_string(tvb, &offset,
1446                                 FALSE, &length, TRUE, TRUE, &bc);
1447                         if(data){
1448                                 proto_tree_add_string(ea_tree, hf_smb2_ea_data, tvb,
1449                                         offset, length, data);
1450                         }
1451                 }
1452                 offset += ea_data_len;
1453
1454
1455                 if(ea_item){
1456                         proto_item_append_text(ea_item, " %s := %s", name, data);
1457                 }
1458                 proto_item_set_len(ea_item, offset-start_offset);
1459
1460
1461                 if(!next_offset){
1462                         break;
1463                 }
1464                 if(next_offset>256){
1465                         break;
1466                 }
1467
1468                 offset = start_offset+next_offset;
1469         }
1470
1471         return offset;
1472 }
1473
1474 static int
1475 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1476 {
1477         proto_item *item=NULL;
1478         proto_tree *tree=NULL;
1479         int length;
1480         const char *name="";
1481         guint16 bc;
1482
1483
1484         if(parent_tree){
1485                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, TRUE);
1486                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
1487         }
1488
1489         /* some unknown bytes */
1490         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1491         offset += 16;
1492
1493         /* file name length */
1494         length=tvb_get_letohs(tvb, offset);
1495         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1496         offset += 2;
1497
1498         /* some unknown bytes */
1499         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1500         offset += 2;
1501
1502         /* file name */
1503         if(length){
1504                 bc=tvb_length_remaining(tvb, offset);
1505                 name = get_unicode_or_ascii_string(tvb, &offset,
1506                         TRUE, &length, TRUE, TRUE, &bc);
1507                 if(name){
1508                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1509                                 offset, length, name);
1510                 }
1511
1512                 if (check_col(pinfo->cinfo, COL_INFO)){
1513                         col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s",
1514                         name);
1515                 }
1516         }
1517         offset += length;
1518
1519         /* some unknown bytes */
1520         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1521         offset += 4;
1522
1523         return offset;
1524 }
1525
1526 static int
1527 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1528 {
1529         proto_item *item=NULL;
1530         proto_tree *tree=NULL;
1531
1532         if(parent_tree){
1533                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, TRUE);
1534                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
1535         }
1536
1537         /* security descriptor */
1538         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_length_remaining(tvb, offset), NULL);
1539
1540         return offset;
1541 }
1542
1543 static int
1544 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1545 {
1546         proto_item *item=NULL;
1547         proto_tree *tree=NULL;
1548         guint16 bc;
1549
1550         if(parent_tree){
1551                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, TRUE);
1552                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
1553         }
1554
1555         bc=tvb_length_remaining(tvb, offset);
1556         offset=dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1557
1558         return offset;
1559 }
1560
1561 static int
1562 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1563 {
1564         proto_item *item=NULL;
1565         proto_tree *tree=NULL;
1566         guint16 bc;
1567
1568         if(parent_tree){
1569                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, TRUE);
1570                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
1571         }
1572
1573         bc=tvb_length_remaining(tvb, offset);
1574         offset=dissect_nt_quota(tvb, tree, offset, &bc);
1575
1576         return offset;
1577 }
1578
1579 static int
1580 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1581 {
1582         proto_item *item=NULL;
1583         proto_tree *tree=NULL;
1584
1585         if(parent_tree){
1586                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, TRUE);
1587                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
1588         }
1589
1590         /* FILE_OBJECTID_BUFFER */
1591         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
1592
1593         return offset;
1594 }
1595
1596 static int
1597 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1598 {
1599         proto_item *item=NULL;
1600         proto_tree *tree=NULL;
1601         guint16 bc;
1602
1603         if(parent_tree){
1604                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, TRUE);
1605                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
1606         }
1607
1608         bc=tvb_length_remaining(tvb, offset);
1609         offset=dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1610
1611         return offset;
1612 }
1613
1614 static int
1615 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1616 {
1617         proto_item *item=NULL;
1618         proto_tree *tree=NULL;
1619         guint16 bc;
1620
1621         if(parent_tree){
1622                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, TRUE);
1623                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
1624         }
1625
1626
1627         bc=tvb_length_remaining(tvb, offset);
1628         offset=dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1629
1630         return offset;
1631 }
1632
1633 static int
1634 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1635 {
1636         proto_item *item=NULL;
1637         proto_tree *tree=NULL;
1638         guint16 bc;
1639
1640         if(parent_tree){
1641                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, TRUE);
1642                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
1643         }
1644
1645
1646         bc=tvb_length_remaining(tvb, offset);
1647         offset=dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1648
1649         return offset;
1650 }
1651
1652 static int
1653 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1654 {
1655         proto_item *item=NULL;
1656         proto_tree *tree=NULL;
1657         guint16 bc;
1658
1659         if(parent_tree){
1660                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, TRUE);
1661                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
1662         }
1663
1664
1665         bc=tvb_length_remaining(tvb, offset);
1666         offset=dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
1667
1668         return offset;
1669 }
1670
1671 static int
1672 dissect_smb2_create_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1673 {
1674         proto_item *item=NULL;
1675         proto_tree *tree=NULL;
1676
1677         if(parent_tree){
1678                 item = proto_tree_add_item(parent_tree, hf_smb2_create_flags, tvb, offset, 2, TRUE);
1679                 tree = proto_item_add_subtree(item, ett_smb2_create_flags);
1680         }
1681
1682         proto_tree_add_item(tree, hf_smb2_create_flags_request_exclusive_oplock, tvb, offset, 2, TRUE);
1683         proto_tree_add_item(tree, hf_smb2_create_flags_request_oplock, tvb, offset, 2, TRUE);
1684         proto_tree_add_item(tree, hf_smb2_create_flags_grant_exclusive_oplock, tvb, offset, 2, TRUE);
1685         proto_tree_add_item(tree, hf_smb2_create_flags_grant_oplock, tvb, offset, 2, TRUE);
1686
1687
1688         offset += 2;
1689         return offset;
1690 }
1691
1692 static int
1693 dissect_smb2_buffercode(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 *length)
1694 {
1695         guint16 buffer_code;
1696
1697         /* dissect the first 2 bytes of the command PDU */
1698         buffer_code = tvb_get_letohs(tvb, offset);
1699         proto_tree_add_uint(tree, hf_smb2_buffer_code_len, tvb, offset, 2, buffer_code&0xfffe);
1700         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, TRUE);
1701         offset += 2;
1702
1703         if(length){
1704                 *length=buffer_code&0xfffe;
1705         }
1706
1707         return offset;
1708 }
1709
1710 static void
1711 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
1712 {
1713         if( (tvb_length(tvb)>=7)
1714         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))){
1715                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
1716         } else {
1717                 call_dissector(gssapi_handle, tvb, pinfo, tree);
1718         }
1719         return;
1720 }
1721
1722 static int
1723 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
1724 {
1725         offset_length_buffer_t s_olb;
1726         ntlmssp_header_t *ntlmssph;
1727         static int ntlmssp_tap_id = 0;
1728         int idx;
1729
1730         if(!ntlmssp_tap_id){
1731                 GString *error_string;
1732                 /* We dont specify any callbacks at all.
1733                  * Instead we manually fetch the tapped data after the
1734                  * security blob has been fully dissected and before
1735                  * we exit from this dissector.
1736                  */
1737                 error_string=register_tap_listener("ntlmssp", NULL, NULL, NULL, NULL, NULL);
1738                 if(!error_string){
1739                         ntlmssp_tap_id=find_tap_id("ntlmssp");
1740                 }
1741         }
1742
1743
1744         /* buffer code */
1745         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1746         /* some unknown bytes */
1747         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1748         offset += 2;
1749
1750         /* some unknown bytes */
1751         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, FALSE);
1752         offset += 8;
1753
1754         /* security blob offset/length */
1755         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
1756
1757         /* the security blob itself */
1758         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
1759
1760         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
1761
1762         /* If we have found a uid->acct_name mapping, store it */
1763         if(!pinfo->fd->flags.visited){
1764                 idx=0;
1765                 while((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
1766                         if(ntlmssph && ntlmssph->type==3){
1767                                 smb2_uid_info_t *uid;
1768                                 uid=se_alloc(sizeof(smb2_uid_info_t));
1769                                 uid->uid=si->uid;
1770                                 uid->acct_name=se_strdup(ntlmssph->acct_name);
1771                                 uid->domain_name=se_strdup(ntlmssph->domain_name);
1772                                 uid->host_name=se_strdup(ntlmssph->host_name);
1773                                 uid->auth_frame=pinfo->fd->num;
1774                                 uid->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
1775                                 g_hash_table_insert(si->conv->uids, uid, uid);
1776                         }
1777                 }
1778         }
1779
1780         return offset;
1781 }
1782
1783 static int
1784 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
1785 {
1786         offset_length_buffer_t s_olb;
1787
1788         /* buffer code */
1789         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1790         /* some unknown bytes */
1791         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1792         offset += 2;
1793
1794         /* security blob offset/length */
1795         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
1796
1797         /* the security blob itself */
1798         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
1799
1800         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
1801
1802         return offset;
1803 }
1804
1805 static int
1806 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
1807 {
1808         offset_length_buffer_t olb;
1809         const char *buf;
1810
1811         /* buffer code */
1812         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1813
1814         /* some unknown bytes */
1815         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1816         offset += 2;
1817
1818         /* tree  offset/length */
1819         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
1820
1821         /* tree string */
1822         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
1823
1824         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
1825
1826         /* treelen  +1 is overkill here if the string is unicode,
1827          * but who ever has more than a handful of TCON in a trace anyways
1828          */
1829         if(!pinfo->fd->flags.visited && si->saved && buf && olb.len){
1830                 si->saved->private_data=se_alloc(olb.len+1);
1831                 g_snprintf((char *)si->saved->private_data,olb.len+1,"%s",buf);
1832         }
1833
1834         if (check_col(pinfo->cinfo, COL_INFO)){
1835                 col_append_fstr(pinfo->cinfo, COL_INFO, " Tree:%s", buf);
1836         }
1837
1838
1839         return offset;
1840 }
1841 static int
1842 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
1843 {
1844         guint16 share_type;
1845
1846         /* buffer code */
1847         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1848
1849         /* share type */
1850         share_type = tvb_get_letohs(tvb, offset);
1851         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 2, TRUE);
1852         offset += 2;
1853
1854         if(!pinfo->fd->flags.visited && si->saved && si->saved->private_data && si->session) {
1855                 smb2_tid_info_t *tid, tid_key;
1856
1857                 tid_key.tid=si->tid;
1858                 tid=g_hash_table_lookup(si->session->tids, &tid_key);
1859                 if(tid){
1860                         g_hash_table_remove(si->session->tids, &tid_key);
1861                 }
1862                 tid=se_alloc(sizeof(smb2_tid_info_t));
1863                 tid->tid=si->tid;
1864                 tid->name=(char *)si->saved->private_data;
1865                 tid->connect_frame=pinfo->fd->num;
1866                 tid->share_type=share_type;
1867
1868                 g_hash_table_insert(si->session->tids, tid, tid);
1869
1870                 si->saved->private_data=NULL;
1871         }
1872
1873         /* some unknown bytes */
1874         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
1875         offset += 8;
1876
1877         /* this is some sort of access mask */
1878         offset = dissect_smb_access_mask(tvb, tree, offset);
1879
1880         return offset;
1881 }
1882
1883 static int
1884 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
1885 {
1886         /* buffer code */
1887         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1888
1889         /* some unknown bytes */
1890         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1891         offset += 2;
1892
1893         return offset;
1894 }
1895
1896 static int
1897 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
1898 {
1899         /* buffer code */
1900         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1901
1902         /* some unknown bytes */
1903         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1904         offset += 2;
1905
1906         return offset;
1907 }
1908
1909 static int
1910 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
1911 {
1912         /* buffer code */
1913         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1914
1915         /* some unknown bytes */
1916         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1917         offset += 2;
1918
1919         return offset;
1920 }
1921
1922 static int
1923 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
1924 {
1925         /* buffer code */
1926         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1927
1928         /* some unknown bytes */
1929         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1930         offset += 2;
1931
1932         return offset;
1933 }
1934
1935 static int
1936 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
1937 {
1938         /* buffer code */
1939         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1940
1941         /* some unknown bytes */
1942         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1943         offset += 2;
1944
1945         return offset;
1946 }
1947
1948 static int
1949 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
1950 {
1951         /* buffer code */
1952         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1953
1954         /* some unknown bytes */
1955         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1956         offset += 2;
1957
1958         return offset;
1959 }
1960
1961 static int
1962 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
1963 {
1964         /* buffer code */
1965         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1966         /* some unknown bytes */
1967         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1968         offset += 2;
1969
1970         /* some unknown bytes */
1971         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
1972         offset += 4;
1973
1974         /* fid */
1975         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
1976
1977         /* completion filter */
1978         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
1979
1980         /* some unknown bytes */
1981         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
1982         offset += 4;
1983
1984         return offset;
1985 }
1986
1987 static int
1988 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
1989 {
1990         /* buffer code */
1991         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
1992
1993         /* some unknown bytes */
1994         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
1995         offset += 2;
1996
1997         switch(si->status){
1998         case 0x00000103: /* STATUS_PENDING */
1999         case 0xc0000120: /* STATUS_CANCELLED */
2000                 /* some unknown bytes */
2001                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2002                 offset += 4;
2003                 /* bug */
2004                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 1, TRUE);
2005                 offset += 1;
2006                 return offset;
2007         case 0x0000010c: /* STATUS_NOTIFY_ENUM_DIR */
2008                 /* some unknown bytes */
2009                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2010                 offset += 4;
2011                 return offset;
2012         }
2013
2014         /* we dont know what this is */
2015         /* some unknown bytes */
2016         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
2017         offset += tvb_length_remaining(tvb, offset);
2018         return offset;
2019 }
2020
2021 static int
2022 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2023 {
2024         offset_length_buffer_t olb;
2025         const char *buf;
2026
2027         /* buffer code */
2028         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2029         /* some unknown bytes */
2030         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2031         offset += 2;
2032
2033         /* some unknown bytes */
2034         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2035         offset += 4;
2036
2037         /* fid */
2038         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2039
2040         /* search pattern  offset/length */
2041         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_search);
2042
2043         /* some unknown bytes */
2044         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2045         offset += 4;
2046
2047         /* search pattern */
2048         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2049         if (check_col(pinfo->cinfo, COL_INFO)){
2050                 col_append_fstr(pinfo->cinfo, COL_INFO, " Pattern:%s",buf);
2051         }
2052
2053         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2054
2055         return offset;
2056 }
2057
2058 static int
2059 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2060 {
2061         guint32 len;
2062
2063         /* buffer code */
2064         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2065
2066         /* response buffer offset */
2067         proto_tree_add_item(tree, hf_smb2_response_buffer_offset, tvb, offset, 2, TRUE);
2068         offset += 2;
2069
2070         /* length of response data */
2071         len=tvb_get_letohl(tvb, offset);
2072         proto_tree_add_item(tree, hf_smb2_find_response_size, tvb, offset, 4, TRUE);
2073         offset += 4;
2074
2075 /*qqq*/
2076         return offset;
2077 }
2078
2079 static int
2080 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2081 {
2082         /* buffer code */
2083         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2084
2085         /* some unknown bytes */
2086         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 0x24, TRUE);
2087         offset += 0x24;
2088
2089         return offset;
2090 }
2091
2092 static int
2093 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2094 {
2095         offset_length_buffer_t s_olb;
2096
2097         /* buffer code */
2098         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2099         /* some unknown bytes */
2100         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2101         offset += 2;
2102
2103
2104         /* some unknown bytes */
2105         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2106         offset += 4;
2107
2108         /* server GUID */
2109         proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, TRUE);
2110         offset += 16;
2111
2112         /* some unknown bytes */
2113         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2114         offset += 16;
2115
2116         /* current time */
2117         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
2118         offset += 8;
2119
2120         /* boot time */
2121         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
2122         offset += 8;
2123
2124         /* security blob offset/length */
2125         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2126
2127         /* the security blob itself */
2128         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2129
2130         /* some unknown bytes */
2131         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2132         offset += 4;
2133
2134         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2135
2136         return offset;
2137 }
2138
2139 static void
2140 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
2141 {
2142         switch(si->saved->class){
2143         case SMB2_CLASS_FILE_INFO:
2144                 switch(si->saved->infolevel){
2145                 default:
2146                         /* we dont handle this infolevel yet */
2147                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2148                         offset += tvb_length_remaining(tvb, offset);
2149                 }
2150                 break;
2151         case SMB2_CLASS_FS_INFO:
2152                 switch(si->saved->infolevel){
2153                 default:
2154                         /* we dont handle this infolevel yet */
2155                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2156                         offset += tvb_length_remaining(tvb, offset);
2157                 }
2158                 break;
2159         case SMB2_CLASS_SEC_INFO:
2160                 switch(si->saved->infolevel){
2161                 case SMB2_SEC_INFO_00:
2162                         dissect_security_information_mask(tvb, tree, offset+8);
2163                         break;
2164                 default:
2165                         /* we dont handle this infolevel yet */
2166                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2167                         offset += tvb_length_remaining(tvb, offset);
2168                 }
2169                 break;
2170         default:
2171                 /* we dont handle this class yet */
2172                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2173         }
2174 }
2175
2176
2177 static int
2178 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
2179 {
2180         char cl, il;
2181         proto_item *item;
2182         int hfindex;
2183         static const value_string dummy_value_string[] = {
2184                 { 0, NULL }
2185         };
2186         const value_string *vs;
2187
2188         if(si->flags & SMB2_FLAGS_RESPONSE){
2189                 if(!si->saved){
2190                         return offset;
2191                 }
2192                 cl=si->saved->class;
2193                 il=si->saved->infolevel;
2194         } else {
2195                 cl=tvb_get_guint8(tvb, offset);
2196                 il=tvb_get_guint8(tvb, offset+1);
2197                 if(si->saved){
2198                         si->saved->class=cl;
2199                         si->saved->infolevel=il;
2200                 }
2201         }
2202
2203
2204         switch(cl){
2205         case SMB2_CLASS_FILE_INFO:
2206                 hfindex=hf_smb2_infolevel_file_info;
2207                 vs=smb2_file_info_levels;
2208                 break;
2209         case SMB2_CLASS_FS_INFO:
2210                 hfindex=hf_smb2_infolevel_fs_info;
2211                 vs=smb2_fs_info_levels;
2212                 break;
2213         case SMB2_CLASS_SEC_INFO:
2214                 hfindex=hf_smb2_infolevel_sec_info;
2215                 vs=smb2_sec_info_levels;
2216                 break;
2217         default:
2218                 hfindex=hf_smb2_infolevel;
2219                 vs=dummy_value_string;
2220         }
2221
2222
2223         /* class */
2224         item=proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
2225         if(si->flags & SMB2_FLAGS_RESPONSE){
2226                 PROTO_ITEM_SET_GENERATED(item);
2227         }
2228         /* infolevel */
2229         item=proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
2230         if(si->flags & SMB2_FLAGS_RESPONSE){
2231                 PROTO_ITEM_SET_GENERATED(item);
2232         }
2233         offset += 2;
2234
2235         if(!si->flags & SMB2_FLAGS_RESPONSE){
2236                 /* Only update COL_INFO for requests. It clutters the
2237                  * display ab bit too much if we do it for replies
2238                  * as well.
2239                  */
2240                 if (check_col(pinfo->cinfo, COL_INFO)){
2241                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
2242                                 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
2243                                 val_to_str(il, vs, "(Level:0x%02x)"));
2244                 }
2245         }
2246
2247         return offset;
2248 }
2249
2250 static int
2251 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2252 {
2253         /* buffer code */
2254         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2255
2256         /* class and info level */
2257         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
2258
2259         /* max response size */
2260         proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, TRUE);
2261         offset += 4;
2262
2263         /* parameters */
2264         if(si->saved){
2265                 dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
2266         } else {
2267                 /* some unknown bytes */
2268                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2269         }
2270         offset += 16;
2271
2272         /* fid */
2273         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2274
2275         return offset;
2276 }
2277
2278 static void
2279 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 class, guint8 infolevel)
2280 {
2281
2282         switch(class){
2283         case SMB2_CLASS_FILE_INFO:
2284                 switch(infolevel){
2285                 case SMB2_FILE_BASIC_INFO:
2286                         dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
2287                         break;
2288                 case SMB2_FILE_STANDARD_INFO:
2289                         dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
2290                         break;
2291                 case SMB2_FILE_INTERNAL_INFO:
2292                         dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
2293                         break;
2294                 case SMB2_FILE_EA_INFO:
2295                         dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
2296                         break;
2297                 case SMB2_FILE_ACCESS_INFO:
2298                         dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
2299                         break;
2300                 case SMB2_FILE_RENAME_INFO:
2301                         dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
2302                         break;
2303                 case SMB2_FILE_DISPOSITION_INFO:
2304                         dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
2305                         break;
2306                 case SMB2_FILE_POSITION_INFO:
2307                         dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
2308                         break;
2309                 case SMB2_FILE_INFO_0f:
2310                         dissect_smb2_file_info_0f(tvb, pinfo, tree, offset, si);
2311                         break;
2312                 case SMB2_FILE_MODE_INFO:
2313                         dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
2314                         break;
2315                 case SMB2_FILE_ALIGNMENT_INFO:
2316                         dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
2317                         break;
2318                 case SMB2_FILE_ALL_INFO:
2319                         dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
2320                         break;
2321                 case SMB2_FILE_ALLOCATION_INFO:
2322                         dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
2323                         break;
2324                 case SMB2_FILE_ENDOFFILE_INFO:
2325                         dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
2326                         break;
2327                 case SMB2_FILE_ALTERNATE_NAME_INFO:
2328                         dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
2329                         break;
2330                 case SMB2_FILE_STREAM_INFO:
2331                         dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
2332                         break;
2333                 case SMB2_FILE_PIPE_INFO:
2334                         dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
2335                         break;
2336                 case SMB2_FILE_COMPRESSION_INFO:
2337                         dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
2338                         break;
2339                 case SMB2_FILE_NETWORK_OPEN_INFO:
2340                         dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
2341                         break;
2342                 case SMB2_FILE_ATTRIBUTE_TAG_INFO:
2343                         dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
2344                         break;
2345                 default:
2346                         /* we dont handle this infolevel yet */
2347                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
2348                         offset += tvb_length_remaining(tvb, offset);
2349                 }
2350                 break;
2351         case SMB2_CLASS_FS_INFO:
2352                 switch(infolevel){
2353                 case SMB2_FS_INFO_01:
2354                         dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
2355                         break;
2356                 case SMB2_FS_INFO_03:
2357                         dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
2358                         break;
2359                 case SMB2_FS_INFO_04:
2360                         dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
2361                         break;
2362                 case SMB2_FS_INFO_05:
2363                         dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
2364                         break;
2365                 case SMB2_FS_INFO_06:
2366                         dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
2367                         break;
2368                 case SMB2_FS_INFO_07:
2369                         dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
2370                         break;
2371                 case SMB2_FS_OBJECTID_INFO:
2372                         dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
2373                         break;
2374                 default:
2375                         /* we dont handle this infolevel yet */
2376                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
2377                         offset += tvb_length_remaining(tvb, offset);
2378                 }
2379                 break;
2380         case SMB2_CLASS_SEC_INFO:
2381                 switch(infolevel){
2382                 case SMB2_SEC_INFO_00:
2383                         dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
2384                         break;
2385                 default:
2386                         /* we dont handle this infolevel yet */
2387                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
2388                         offset += tvb_length_remaining(tvb, offset);
2389                 }
2390                 break;
2391         default:
2392                 /* we dont handle this class yet */
2393                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
2394         }
2395 }
2396
2397 static void
2398 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
2399 {
2400         /* data */
2401         if(si->saved){
2402                 dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->class, si->saved->infolevel);
2403         } else {
2404                 /* some unknown bytes */
2405                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), FALSE);
2406         }
2407
2408         return;
2409 }
2410
2411
2412 static int
2413 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2414 {
2415         guint16 len;
2416         offset_length_buffer_t olb;
2417
2418         /* class/infolevel */
2419         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
2420
2421         /* buffer code */
2422         offset = dissect_smb2_buffercode(tree, tvb, offset, &len);
2423
2424         /* response buffer offset  and size */
2425         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
2426
2427         /* if we get BUFFER_TOO_SMALL there will not be any data there, only
2428          * a guin32 specifying how big the buffer needs to be
2429          */
2430         if(si->status==0xc0000023){
2431                 proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, TRUE);
2432                 offset += 4;
2433
2434                 return offset;
2435         }
2436
2437
2438         /* response data*/
2439         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
2440
2441         return offset;
2442 }
2443
2444 static int
2445 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2446 {
2447         /* buffer code */
2448         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2449
2450         /* close flags */
2451         proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, TRUE);
2452         offset += 2;
2453
2454         /* padding */
2455         offset += 4;
2456
2457         /* fid */
2458         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
2459
2460         return offset;
2461 }
2462
2463 static int
2464 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2465 {
2466         guint16 len;
2467
2468         /* buffer code */
2469         offset = dissect_smb2_buffercode(tree, tvb, offset, &len);
2470
2471         /* close flags */
2472         proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, TRUE);
2473         offset += 2;
2474
2475         /* some unknown bytes */
2476         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2477         offset += 4;
2478
2479         /* If there was an error, the response will be just 8 bytes */
2480         if((len==8)&&(si->status)){
2481                 return offset;
2482         }
2483
2484
2485         /* create time */
2486         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2487
2488         /* last access */
2489         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2490
2491         /* last write */
2492         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2493
2494         /* last change */
2495         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2496
2497         /* allocation size */
2498         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2499         offset += 8;
2500
2501         /* end of file */
2502         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2503         offset += 8;
2504
2505         /* File Attributes */
2506         offset = dissect_file_attributes(tvb, tree, offset, 4);
2507
2508         return offset;
2509 }
2510
2511 static int
2512 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2513 {
2514         /* buffer code */
2515         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2516
2517         /* some unknown bytes */
2518         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
2519         offset += 6;
2520
2521         /* fid */
2522         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2523
2524         return offset;
2525 }
2526
2527 static int
2528 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2529 {
2530         /* buffer code */
2531         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2532
2533         /* some unknown bytes */
2534         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2535         offset += 2;
2536
2537         return offset;
2538 }
2539
2540
2541 static int
2542 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2543 {
2544         /* buffer code */
2545         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2546
2547         /* some unknown bytes */
2548         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
2549         offset += 6;
2550
2551         /* fid */
2552         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2553
2554         /* some unknown bytes */
2555         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2556         offset += 16;
2557
2558         /* some unknown bytes */
2559         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
2560         offset += 8;
2561
2562         return offset;
2563 }
2564
2565 static int
2566 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2567 {
2568         /* buffer code */
2569         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2570
2571         /* some unknown bytes */
2572         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2573         offset += 2;
2574
2575         return offset;
2576 }
2577 static int
2578 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2579 {
2580         /* buffer code */
2581         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2582
2583         /* some unknown bytes */
2584         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2585         offset += 2;
2586
2587         return offset;
2588 }
2589
2590
2591 static int
2592 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, smb2_info_t *si)
2593 {
2594         int tvblen;
2595         int result;
2596
2597         tvbuff_t *dcerpc_tvb;
2598         tvblen = tvb_length_remaining(tvb, offset);
2599         dcerpc_tvb = tvb_new_subset(tvb, offset, MIN((int)datalen, tvb_length_remaining(tvb, offset)), datalen);
2600
2601         /* dissect the full PDU */
2602         result = dissector_try_heuristic(smb2_heur_subdissector_list, dcerpc_tvb, pinfo, si->top_tree);
2603
2604
2605         offset += datalen;
2606
2607         return offset;
2608 }
2609
2610
2611 static int
2612 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2613 {
2614         guint32 length;
2615         guint64 off;
2616
2617         /* buffer code */
2618         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2619
2620         /* data offset */
2621         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, TRUE);
2622         offset += 2;
2623
2624         /* length */
2625         length=tvb_get_letohl(tvb, offset);
2626         proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, TRUE);
2627         offset += 4;
2628
2629         /* offset */
2630         off=tvb_get_letoh64(tvb, offset);
2631         proto_tree_add_item(tree, hf_smb2_write_offset, tvb, offset, 8, TRUE);
2632         offset += 8;
2633
2634         if (check_col(pinfo->cinfo, COL_INFO)){
2635                 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" PRIu64, length, off);
2636         }
2637
2638         /* fid */
2639         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2640
2641         /* some unknown bytes */
2642         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
2643         offset += 16;
2644
2645
2646         /* data or dcerpc ?*/
2647         if(length && si->tree && si->tree->share_type == SMB2_SHARE_TYPE_IPC){
2648                 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si);
2649                 return offset;
2650         }
2651
2652         /* just ordinary data */
2653         proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, TRUE);
2654         offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
2655
2656         return offset;
2657 }
2658
2659
2660 static int
2661 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2662 {
2663         /* buffer code */
2664         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2665         /* some unknown bytes */
2666         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2667         offset += 2;
2668
2669         /* length */
2670         proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, TRUE);
2671         offset += 4;
2672
2673         /* some unknown bytes */
2674         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 9, TRUE);
2675         offset += 9;
2676
2677         return offset;
2678 }
2679
2680 static void
2681 dissect_smb2_IOCTL_DO_DCERPC(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, gboolean data_in _U_)
2682 {
2683         dissect_file_data_dcerpc(tvb, pinfo, tree, offset, tvb_length_remaining(tvb, offset), si);
2684
2685         return;
2686 }
2687
2688 static void
2689 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_, gboolean data_in)
2690 {
2691         guint32 num_volumes, num_labels;
2692
2693         /* There is no in data */
2694         if(data_in){
2695                 return;
2696         }
2697
2698         /* num volumes */
2699         num_volumes=tvb_get_letohl(tvb, offset);
2700         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_volumes, tvb, offset, 4, TRUE);
2701         offset += 4;
2702
2703         /* num labels */
2704         num_labels=tvb_get_letohl(tvb, offset);
2705         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_labels, tvb, offset, 4, TRUE);
2706         offset += 4;
2707
2708         /* count */
2709         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_count, tvb, offset, 4, TRUE);
2710         offset += 4;
2711
2712         while(num_volumes--){
2713                 const char *name;
2714                 guint16 bc;
2715                 int len=0;
2716                 int old_offset=offset;
2717
2718                 bc=tvb_length_remaining(tvb, offset);
2719                 name = get_unicode_or_ascii_string(tvb, &offset,
2720                         TRUE, &len, TRUE, FALSE, &bc);
2721                 proto_tree_add_string(tree, hf_smb2_ioctl_shadow_copy_label, tvb, old_offset, len, name);
2722
2723                 offset = old_offset+len;
2724
2725                 if(!len){
2726                         break;
2727                 }
2728         }
2729
2730         return;
2731 }
2732
2733 int
2734 dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
2735 {
2736         proto_item *item=NULL;
2737         proto_tree *tree=NULL;
2738
2739         /* FILE_OBJECTID_BUFFER */
2740         if(parent_tree){
2741                 item = proto_tree_add_item(parent_tree, hf_smb2_FILE_OBJECTID_BUFFER, tvb, offset, 64, TRUE);
2742                 tree = proto_item_add_subtree(item, ett_smb2_FILE_OBJECTID_BUFFER);
2743         }
2744
2745         /* Object ID */
2746         proto_tree_add_item(tree, hf_smb2_object_id, tvb, offset, 16, TRUE);
2747         offset += 16;
2748
2749         /* Birth Volume ID */
2750         proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, TRUE);
2751         offset += 16;
2752
2753         /* Birth Object ID */
2754         proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, TRUE);
2755         offset += 16;
2756
2757         /* Domain ID */
2758         proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, TRUE);
2759         offset += 16;
2760
2761         return offset;
2762 }
2763
2764 static void
2765 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_, gboolean data_in)
2766 {
2767
2768         /* There is no in data */
2769         if(data_in){
2770                 return;
2771         }
2772
2773         /* FILE_OBJECTID_BUFFER */
2774         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2775
2776         return;
2777 }
2778
2779 static void
2780 dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_, gboolean data_in)
2781 {
2782
2783         /* There is no in data */
2784         if(data_in){
2785                 return;
2786         }
2787
2788         /* compression format */
2789         proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, TRUE);
2790         offset += 2;
2791
2792         return;
2793 }
2794 static void
2795 dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_, gboolean data_in)
2796 {
2797
2798         /* There is no out data */
2799         if(!data_in){
2800                 return;
2801         }
2802
2803         /* compression format */
2804         proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, TRUE);
2805         offset += 2;
2806
2807         return;
2808 }
2809
2810 static void
2811 dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_, gboolean data_in)
2812 {
2813
2814         /* There is no out data */
2815         if(!data_in){
2816                 return;
2817         }
2818
2819         /* FILE_OBJECTID_BUFFER */
2820         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2821
2822         return;
2823 }
2824
2825 static void
2826 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_, gboolean data_in)
2827 {
2828
2829         /* There is no out data */
2830         if(!data_in){
2831                 return;
2832         }
2833
2834         /* FILE_OBJECTID_BUFFER->ExtendedInfo */
2835
2836         /* Birth Volume ID */
2837         proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, TRUE);
2838         offset += 16;
2839
2840         /* Birth Object ID */
2841         proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, TRUE);
2842         offset += 16;
2843
2844         /* Domain ID */
2845         proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, TRUE);
2846         offset += 16;
2847
2848         return;
2849 }
2850
2851 static void
2852 dissect_smb2_ioctl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si, gboolean data_in)
2853 {
2854         switch(si->ioctl_function){
2855         case 0x0011c017:
2856                 dissect_smb2_IOCTL_DO_DCERPC(tvb, pinfo, tree, 0, si, data_in);
2857                 break;
2858         case 0x00144064: /* FSCTL_GET_SHADOW_COPY_DATA */
2859                 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvb, pinfo, tree, 0, si, data_in);
2860                 break;
2861         case 0x0009009C: /* FSCTL_GET_OBJECT_ID */
2862         case 0x000900c0: /* FSCTL_CREATE_OR_GET_OBJECT_ID */
2863                 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvb, pinfo, tree, 0, si, data_in);
2864                 break;
2865         case 0x00098098: /* FSCTL_SET_OBJECT_ID */
2866                 dissect_smb2_FSCTL_SET_OBJECT_ID(tvb, pinfo, tree, 0, si, data_in);
2867                 break;
2868         case 0x000980BC: /* FSCTL_SET_OBJECT_ID_EXTENDED */
2869                 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvb, pinfo, tree, 0, si, data_in);
2870                 break;
2871         case 0x0009003C: /* FSCTL_GET_COMPRESSION */
2872                 dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, si, data_in);
2873                 break;
2874         case 0x0009C040: /* FSCTL_SET_COMPRESSION */
2875                 dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, si, data_in);
2876                 break;
2877         default:
2878                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), TRUE);
2879         }
2880
2881         return;
2882 }
2883
2884 static void
2885 dissect_smb2_ioctl_data_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
2886 {
2887         dissect_smb2_ioctl_data(tvb, pinfo, tree, si, TRUE);
2888 }
2889
2890 static void
2891 dissect_smb2_ioctl_data_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
2892 {
2893         dissect_smb2_ioctl_data(tvb, pinfo, tree, si, FALSE);
2894 }
2895
2896 static int
2897 dissect_smb2_ioctl_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2898 {
2899         offset_length_buffer_t o_olb;
2900         offset_length_buffer_t i_olb;
2901
2902         /* buffer code */
2903         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2904
2905         /* some unknown bytes */
2906         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2907         offset += 2;
2908
2909         /* ioctl function */
2910         offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, si);
2911
2912         /* fid */
2913         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2914
2915         /* in buffer offset/length */
2916         offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
2917
2918         /* some unknown bytes */
2919         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, TRUE);
2920         offset += 4;
2921
2922         /* out buffer offset/length */
2923         offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
2924
2925         /* max ioctl out size */
2926         proto_tree_add_item(tree, hf_smb2_max_ioctl_out_size, tvb, offset, 4, TRUE);
2927         offset += 4;
2928
2929         /* some unknown bytes */
2930         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
2931         offset += 8;
2932
2933         /* try to decode these blobs in the order they were encoded
2934          * so that for "short" packets we will dissect as much as possible
2935          * before aborting with "short packet"
2936          */
2937         if(i_olb.off>o_olb.off){
2938                 /* out buffer */
2939                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
2940                 /* in buffer */
2941                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
2942         } else {
2943                 /* in buffer */
2944                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
2945                 /* out buffer */
2946                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
2947         }
2948
2949         offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
2950         offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
2951
2952         return offset;
2953 }
2954
2955 static int
2956 dissect_smb2_ioctl_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2957 {
2958         offset_length_buffer_t o_olb;
2959         offset_length_buffer_t i_olb;
2960         guint16 len;
2961
2962         /* buffer code */
2963         offset = dissect_smb2_buffercode(tree, tvb, offset, &len);
2964
2965         /* some unknown bytes */
2966         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2967         offset += 2;
2968
2969         /* ioctl function */
2970         offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, si);
2971
2972         /* If there was an error, the response will be just 8 bytes */
2973         if((len==8)&&(si->status)){
2974                 return offset;
2975         }
2976
2977
2978         /* fid */
2979         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2980
2981         /* in buffer offset/length */
2982         offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
2983
2984         /* out buffer offset/length */
2985         offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
2986
2987         /* some unknown bytes */
2988         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
2989         offset += 8;
2990
2991         /* try to decode these blobs in the order they were encoded
2992          * so that for "short" packets we will dissect as much as possible
2993          * before aborting with "short packet"
2994          */
2995         if(i_olb.off>o_olb.off){
2996                 /* out buffer */
2997                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
2998                 /* in buffer */
2999                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
3000         } else {
3001                 /* in buffer */
3002                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
3003                 /* out buffer */
3004                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
3005         }
3006
3007         offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
3008         offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
3009
3010         return offset;
3011 }
3012
3013
3014 static int
3015 dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3016 {
3017         guint32 len;
3018         guint64 off;
3019
3020         /* buffer code */
3021         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3022         /* some unknown bytes */
3023         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3024         offset += 2;
3025
3026         /* length */
3027         len=tvb_get_letohl(tvb, offset);
3028         proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, TRUE);
3029         offset += 4;
3030
3031         /* offset */
3032         off=tvb_get_letoh64(tvb, offset);
3033         proto_tree_add_item(tree, hf_smb2_read_offset, tvb, offset, 8, TRUE);
3034         offset += 8;
3035
3036         if (check_col(pinfo->cinfo, COL_INFO)){
3037                 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" PRIu64, len, off);
3038         }
3039
3040         /* fid */
3041         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3042
3043         /* some unknown bytes */
3044         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3045         offset += 16;
3046
3047         /* some unknown bytes */
3048         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 1, TRUE);
3049         offset += 1;
3050
3051         return offset;
3052 }
3053
3054
3055 static int
3056 dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3057 {
3058         guint32 length;
3059
3060         /* buffer code */
3061         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3062
3063         /* data offset */
3064         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, TRUE);
3065         offset += 2;
3066
3067         /* length  might even be 64bits if they are ambitious*/
3068         length=tvb_get_letohl(tvb, offset);
3069         proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, TRUE);
3070         offset += 4;
3071
3072         /* some unknown bytes */
3073         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
3074         offset += 8;
3075
3076         /* data or dcerpc ?
3077          * If the pidvalid flag is set we assume it is a deferred
3078          * STATUS_PENDING read and thus a named pipe (==dcerpc)
3079          */
3080         if(length && ( (si->tree && si->tree->share_type == SMB2_SHARE_TYPE_IPC)||(si->flags & SMB2_FLAGS_PID_VALID))){
3081                 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si);
3082                 return offset;
3083         }
3084
3085         /* data */
3086         proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, TRUE);
3087         offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
3088
3089         return offset;
3090 }
3091
3092 static void
3093 dissect_smb2_ExtA_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3094 {
3095         proto_item *item=NULL;
3096         if (tree) {
3097                 item = proto_tree_get_parent(tree);
3098                 proto_item_append_text(item, ": SMB2_FILE_INFO_0f");
3099         }
3100         dissect_smb2_file_info_0f(tvb, pinfo, tree, 0, si);
3101         return;
3102 }
3103
3104 static void
3105 dissect_smb2_TWrp_buffer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
3106 {
3107         proto_item *item=NULL;
3108         if (tree) {
3109                 item = proto_tree_get_parent(tree);
3110                 proto_item_append_text(item, ": Timestamp");
3111         }
3112         dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_unknown_timestamp);
3113
3114         return;
3115 }
3116
3117 static void
3118 dissect_smb2_MxAc_buffer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
3119 {
3120         int offset=0;
3121         proto_item *item=NULL;
3122         proto_item *sub_item=NULL;
3123         proto_tree *sub_tree=NULL;
3124
3125         if (tree) {
3126                 item = proto_tree_get_parent(tree);
3127         }
3128
3129         if (tvb_length_remaining(tvb, offset) == 0) {
3130                 if (item) {
3131                         proto_item_append_text(item, ": NO DATA");
3132                 }
3133                 return;
3134         }
3135
3136         if (item) {
3137                 proto_item_append_text(item, ": MxAc INFO");
3138                 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "MxAc INFO");
3139                 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_MxAc_buffer);
3140         }
3141
3142         proto_tree_add_item(sub_tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
3143         offset += 4;
3144
3145         offset = dissect_smb_access_mask(tvb, sub_tree, offset);
3146
3147         return;
3148 }
3149
3150 static void
3151 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
3152 {
3153         offset_length_buffer_t tag_olb;
3154         offset_length_buffer_t data_olb;
3155         const char *tag;
3156         guint16 chain_offset;
3157         int offset=0;
3158         int len=-1;
3159         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
3160         proto_item *sub_item=NULL;
3161         proto_tree *sub_tree=NULL;
3162         proto_item *parent_item=NULL;
3163
3164         chain_offset=tvb_get_letohl(tvb, offset);
3165         if (chain_offset) {
3166                 len = chain_offset;
3167         }
3168
3169         if(parent_tree){
3170                 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Chain Element");
3171                 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_chain_element);
3172                 parent_item = proto_tree_get_parent(parent_tree);
3173         }
3174
3175         /* chain offset */
3176         proto_tree_add_item(sub_tree, hf_smb2_chain_offset, tvb, offset, 4, TRUE);
3177         offset += 4;
3178
3179         /* tag  offset/length */
3180         offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
3181
3182         /* data  offset/length */
3183         offset = dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_chain_data);
3184
3185         /* tag string */
3186         tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
3187
3188         proto_item_append_text(parent_item, " %s", tag);
3189         proto_item_append_text(sub_item, ": %s", tag);
3190
3191         /* data */
3192         dissector = NULL;
3193         if(!strcmp(tag, "ExtA")){
3194                 dissector = dissect_smb2_ExtA_buffer;
3195         } else if(!strcmp(tag, "MxAc")){
3196                 dissector = dissect_smb2_MxAc_buffer;
3197         } else if(!strcmp(tag, "TWrp")){
3198                 dissector = dissect_smb2_TWrp_buffer;
3199         }
3200
3201         dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
3202
3203         if(chain_offset){
3204                 tvbuff_t *chain_tvb;
3205                 chain_tvb=tvb_new_subset(tvb, chain_offset, tvb_length_remaining(tvb, chain_offset), tvb_reported_length_remaining(tvb, chain_offset));
3206
3207                 /* next extra info */
3208                 dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
3209         }
3210         return;
3211 }
3212
3213 static int
3214 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3215 {
3216         offset_length_buffer_t f_olb, e_olb;
3217         const char *fname;
3218
3219         /* buffer code */
3220         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3221
3222         /* create flags */
3223         offset = dissect_smb2_create_flags(tree, tvb, offset);
3224
3225         /* impersonation level */
3226         proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, TRUE);
3227         offset += 4;
3228
3229         /* some unknown bytes */
3230         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
3231         offset += 8;
3232
3233         /* some unknown bytes */
3234         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, TRUE);
3235         offset += 8;
3236
3237         /* access mask */
3238         offset = dissect_smb_access_mask(tvb, tree, offset);
3239
3240         /* File Attributes */
3241         offset = dissect_file_attributes(tvb, tree, offset, 4);
3242
3243         /* share access */
3244         offset = dissect_nt_share_access(tvb, tree, offset);
3245
3246         /* create disposition */
3247         proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, TRUE);
3248         offset += 4;
3249
3250         /* create options */
3251         offset = dissect_nt_create_options(tvb, tree, offset);
3252
3253         /* filename  offset/length */
3254         offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
3255
3256         /* extrainfo offset */
3257         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
3258
3259         /* filename string */
3260         fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
3261         if (check_col(pinfo->cinfo, COL_INFO)){
3262                 col_append_fstr(pinfo->cinfo, COL_INFO, " File:%s", fname);
3263         }
3264
3265         /* save the name if it looks sane */
3266         if(!pinfo->fd->flags.visited){
3267                 if(si->saved && si->saved->private_data){
3268                         g_free(si->saved->private_data);
3269                         si->saved->private_data=NULL;
3270                 }
3271                 if(si->saved && f_olb.len && (f_olb.len<256)){
3272                         si->saved->private_data=g_malloc(f_olb.len+1);
3273                         g_snprintf(si->saved->private_data, f_olb.len+1, "%s", fname);
3274                 }
3275         }
3276
3277
3278         /* If extrainfo_offset is non-null then this points to another
3279          * buffer. The offset is relative to the start of the smb packet
3280          */
3281         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
3282
3283         offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
3284         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
3285
3286         return offset;
3287 }
3288
3289 static int
3290 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3291 {
3292         offset_length_buffer_t e_olb;
3293         guint16 len;
3294
3295         /* buffer code */
3296         offset = dissect_smb2_buffercode(tree, tvb, offset, &len);
3297
3298         /* create flags */
3299         offset = dissect_smb2_create_flags(tree, tvb, offset);
3300
3301         /* create action */
3302         proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, TRUE);
3303         offset += 4;
3304
3305         /* If there was an error, the response will be just 8 bytes */
3306         if((len==8)&&(si->status)){
3307                 return offset;
3308         }
3309
3310
3311         /* create time */
3312         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3313
3314         /* last access */
3315         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3316
3317         /* last write */
3318         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3319
3320         /* last change */
3321         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3322
3323         /* allocation size */
3324         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
3325         offset += 8;
3326
3327         /* end of file */
3328         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
3329         offset += 8;
3330
3331         /* File Attributes */
3332         offset = dissect_file_attributes(tvb, tree, offset, 4);
3333
3334         /* padding */
3335         offset += 4;
3336
3337         /* fid */
3338         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
3339
3340         /* extrainfo offset */
3341         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
3342
3343         /* If extrainfo_offset is non-null then this points to another
3344          * buffer. The offset is relative to the start of the smb packet
3345          */
3346         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
3347
3348         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
3349
3350         /* free si->saved->private_data   we dont need it any more */
3351         if(si->saved && si->saved->private_data){
3352                 g_free(si->saved->private_data);
3353                 si->saved->private_data=NULL;
3354         }
3355
3356         return offset;
3357 }
3358
3359
3360 static int
3361 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3362 {
3363         guint32 setinfo_size;
3364         guint16 setinfo_offset;
3365
3366         /* buffer code */
3367         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3368
3369         /* class and info level */
3370         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3371
3372         /* size */
3373         setinfo_size=tvb_get_letohl(tvb, offset);
3374         proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, TRUE);
3375         offset += 4;
3376
3377         /* offset */
3378         setinfo_offset=tvb_get_letohs(tvb, offset);
3379         proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, TRUE);
3380         offset += 2;
3381
3382         /* some unknown bytes */
3383         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
3384         offset += 6;
3385
3386         /* fid */
3387         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3388
3389         /* data */
3390         if(si->saved)
3391           dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->class, si->saved->infolevel);
3392         offset = setinfo_offset + setinfo_size;
3393
3394         return offset;
3395 }
3396
3397 static int
3398 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3399 {
3400         /* class/infolevel */
3401         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3402
3403         /* buffer code */
3404         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3405
3406         return offset;
3407 }
3408
3409 static int
3410 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3411 {
3412         /* buffer code */
3413         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3414
3415         /* some unknown bytes */
3416         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
3417         offset += 6;
3418
3419         /* fid */
3420         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3421
3422         /* some unknown bytes */
3423         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 24, TRUE);
3424         offset += 24;
3425
3426         return offset;
3427 }
3428
3429 /* names here are just until we find better names for these functions */
3430 const value_string smb2_cmd_vals[] = {
3431   { 0x00, "NegotiateProtocol" },
3432   { 0x01, "SessionSetupAndX" },
3433   { 0x02, "SessionLogoff" },
3434   { 0x03, "TreeConnect" },
3435   { 0x04, "TreeDisconnect" },
3436   { 0x05, "Create" },
3437   { 0x06, "Close" },
3438   { 0x07, "Flush" },
3439   { 0x08, "Read" },
3440   { 0x09, "Write" },
3441   { 0x0A, "Lock" },
3442   { 0x0B, "Ioctl" },
3443   { 0x0C, "Cancel" },
3444   { 0x0D, "KeepAlive" },
3445   { 0x0E, "Find" },
3446   { 0x0F, "Notify" },
3447   { 0x10, "GetInfo" },
3448   { 0x11, "SetInfo" },
3449   { 0x12, "Break" },
3450   { 0x13, "unknown-0x13" },
3451   { 0x14, "unknown-0x14" },
3452   { 0x15, "unknown-0x15" },
3453   { 0x16, "unknown-0x16" },
3454   { 0x17, "unknown-0x17" },
3455   { 0x18, "unknown-0x18" },
3456   { 0x19, "unknown-0x19" },
3457   { 0x1A, "unknown-0x1A" },
3458   { 0x1B, "unknown-0x1B" },
3459   { 0x1C, "unknown-0x1C" },
3460   { 0x1D, "unknown-0x1D" },
3461   { 0x1E, "unknown-0x1E" },
3462   { 0x1F, "unknown-0x1F" },
3463   { 0x20, "unknown-0x20" },
3464   { 0x21, "unknown-0x21" },
3465   { 0x22, "unknown-0x22" },
3466   { 0x23, "unknown-0x23" },
3467   { 0x24, "unknown-0x24" },
3468   { 0x25, "unknown-0x25" },
3469   { 0x26, "unknown-0x26" },
3470   { 0x27, "unknown-0x27" },
3471   { 0x28, "unknown-0x28" },
3472   { 0x29, "unknown-0x29" },
3473   { 0x2A, "unknown-0x2A" },
3474   { 0x2B, "unknown-0x2B" },
3475   { 0x2C, "unknown-0x2C" },
3476   { 0x2D, "unknown-0x2D" },
3477   { 0x2E, "unknown-0x2E" },
3478   { 0x2F, "unknown-0x2F" },
3479   { 0x30, "unknown-0x30" },
3480   { 0x31, "unknown-0x31" },
3481   { 0x32, "unknown-0x32" },
3482   { 0x33, "unknown-0x33" },
3483   { 0x34, "unknown-0x34" },
3484   { 0x35, "unknown-0x35" },
3485   { 0x36, "unknown-0x36" },
3486   { 0x37, "unknown-0x37" },
3487   { 0x38, "unknown-0x38" },
3488   { 0x39, "unknown-0x39" },
3489   { 0x3A, "unknown-0x3A" },
3490   { 0x3B, "unknown-0x3B" },
3491   { 0x3C, "unknown-0x3C" },
3492   { 0x3D, "unknown-0x3D" },
3493   { 0x3E, "unknown-0x3E" },
3494   { 0x3F, "unknown-0x3F" },
3495   { 0x40, "unknown-0x40" },
3496   { 0x41, "unknown-0x41" },
3497   { 0x42, "unknown-0x42" },
3498   { 0x43, "unknown-0x43" },
3499   { 0x44, "unknown-0x44" },
3500   { 0x45, "unknown-0x45" },
3501   { 0x46, "unknown-0x46" },
3502   { 0x47, "unknown-0x47" },
3503   { 0x48, "unknown-0x48" },
3504   { 0x49, "unknown-0x49" },
3505   { 0x4A, "unknown-0x4A" },
3506   { 0x4B, "unknown-0x4B" },
3507   { 0x4C, "unknown-0x4C" },
3508   { 0x4D, "unknown-0x4D" },
3509   { 0x4E, "unknown-0x4E" },
3510   { 0x4F, "unknown-0x4F" },
3511   { 0x50, "unknown-0x50" },
3512   { 0x51, "unknown-0x51" },
3513   { 0x52, "unknown-0x52" },
3514   { 0x53, "unknown-0x53" },
3515   { 0x54, "unknown-0x54" },
3516   { 0x55, "unknown-0x55" },
3517   { 0x56, "unknown-0x56" },
3518   { 0x57, "unknown-0x57" },
3519   { 0x58, "unknown-0x58" },
3520   { 0x59, "unknown-0x59" },
3521   { 0x5A, "unknown-0x5A" },
3522   { 0x5B, "unknown-0x5B" },
3523   { 0x5C, "unknown-0x5C" },
3524   { 0x5D, "unknown-0x5D" },
3525   { 0x5E, "unknown-0x5E" },
3526   { 0x5F, "unknown-0x5F" },
3527   { 0x60, "unknown-0x60" },
3528   { 0x61, "unknown-0x61" },
3529   { 0x62, "unknown-0x62" },
3530   { 0x63, "unknown-0x63" },
3531   { 0x64, "unknown-0x64" },
3532   { 0x65, "unknown-0x65" },
3533   { 0x66, "unknown-0x66" },
3534   { 0x67, "unknown-0x67" },
3535   { 0x68, "unknown-0x68" },
3536   { 0x69, "unknown-0x69" },
3537   { 0x6A, "unknown-0x6A" },
3538   { 0x6B, "unknown-0x6B" },
3539   { 0x6C, "unknown-0x6C" },
3540   { 0x6D, "unknown-0x6D" },
3541   { 0x6E, "unknown-0x6E" },
3542   { 0x6F, "unknown-0x6F" },
3543   { 0x70, "unknown-0x70" },
3544   { 0x71, "unknown-0x71" },
3545   { 0x72, "unknown-0x72" },
3546   { 0x73, "unknown-0x73" },
3547   { 0x74, "unknown-0x74" },
3548   { 0x75, "unknown-0x75" },
3549   { 0x76, "unknown-0x76" },
3550   { 0x77, "unknown-0x77" },
3551   { 0x78, "unknown-0x78" },
3552   { 0x79, "unknown-0x79" },
3553   { 0x7A, "unknown-0x7A" },
3554   { 0x7B, "unknown-0x7B" },
3555   { 0x7C, "unknown-0x7C" },
3556   { 0x7D, "unknown-0x7D" },
3557   { 0x7E, "unknown-0x7E" },
3558   { 0x7F, "unknown-0x7F" },
3559   { 0x80, "unknown-0x80" },
3560   { 0x81, "unknown-0x81" },
3561   { 0x82, "unknown-0x82" },
3562   { 0x83, "unknown-0x83" },
3563   { 0x84, "unknown-0x84" },
3564   { 0x85, "unknown-0x85" },
3565   { 0x86, "unknown-0x86" },
3566   { 0x87, "unknown-0x87" },
3567   { 0x88, "unknown-0x88" },
3568   { 0x89, "unknown-0x89" },
3569   { 0x8A, "unknown-0x8A" },
3570   { 0x8B, "unknown-0x8B" },
3571   { 0x8C, "unknown-0x8C" },
3572   { 0x8D, "unknown-0x8D" },
3573   { 0x8E, "unknown-0x8E" },
3574   { 0x8F, "unknown-0x8F" },
3575   { 0x90, "unknown-0x90" },
3576   { 0x91, "unknown-0x91" },
3577   { 0x92, "unknown-0x92" },
3578   { 0x93, "unknown-0x93" },
3579   { 0x94, "unknown-0x94" },
3580   { 0x95, "unknown-0x95" },
3581   { 0x96, "unknown-0x96" },
3582   { 0x97, "unknown-0x97" },
3583   { 0x98, "unknown-0x98" },
3584   { 0x99, "unknown-0x99" },
3585   { 0x9A, "unknown-0x9A" },
3586   { 0x9B, "unknown-0x9B" },
3587   { 0x9C, "unknown-0x9C" },
3588   { 0x9D, "unknown-0x9D" },
3589   { 0x9E, "unknown-0x9E" },
3590   { 0x9F, "unknown-0x9F" },
3591   { 0xA0, "unknown-0xA0" },
3592   { 0xA1, "unknown-0xA1" },
3593   { 0xA2, "unknown-0xA2" },
3594   { 0xA3, "unknown-0xA3" },
3595   { 0xA4, "unknown-0xA4" },
3596   { 0xA5, "unknown-0xA5" },
3597   { 0xA6, "unknown-0xA6" },
3598   { 0xA7, "unknown-0xA7" },
3599   { 0xA8, "unknown-0xA8" },
3600   { 0xA9, "unknown-0xA9" },
3601   { 0xAA, "unknown-0xAA" },
3602   { 0xAB, "unknown-0xAB" },
3603   { 0xAC, "unknown-0xAC" },
3604   { 0xAD, "unknown-0xAD" },
3605   { 0xAE, "unknown-0xAE" },
3606   { 0xAF, "unknown-0xAF" },
3607   { 0xB0, "unknown-0xB0" },
3608   { 0xB1, "unknown-0xB1" },
3609   { 0xB2, "unknown-0xB2" },
3610   { 0xB3, "unknown-0xB3" },
3611   { 0xB4, "unknown-0xB4" },
3612   { 0xB5, "unknown-0xB5" },
3613   { 0xB6, "unknown-0xB6" },
3614   { 0xB7, "unknown-0xB7" },
3615   { 0xB8, "unknown-0xB8" },
3616   { 0xB9, "unknown-0xB9" },
3617   { 0xBA, "unknown-0xBA" },
3618   { 0xBB, "unknown-0xBB" },
3619   { 0xBC, "unknown-0xBC" },
3620   { 0xBD, "unknown-0xBD" },
3621   { 0xBE, "unknown-0xBE" },
3622   { 0xBF, "unknown-0xBF" },
3623   { 0xC0, "unknown-0xC0" },
3624   { 0xC1, "unknown-0xC1" },
3625   { 0xC2, "unknown-0xC2" },
3626   { 0xC3, "unknown-0xC3" },
3627   { 0xC4, "unknown-0xC4" },
3628   { 0xC5, "unknown-0xC5" },
3629   { 0xC6, "unknown-0xC6" },
3630   { 0xC7, "unknown-0xC7" },
3631   { 0xC8, "unknown-0xC8" },
3632   { 0xC9, "unknown-0xC9" },
3633   { 0xCA, "unknown-0xCA" },
3634   { 0xCB, "unknown-0xCB" },
3635   { 0xCC, "unknown-0xCC" },
3636   { 0xCD, "unknown-0xCD" },
3637   { 0xCE, "unknown-0xCE" },
3638   { 0xCF, "unknown-0xCF" },
3639   { 0xD0, "unknown-0xD0" },
3640   { 0xD1, "unknown-0xD1" },
3641   { 0xD2, "unknown-0xD2" },
3642   { 0xD3, "unknown-0xD3" },
3643   { 0xD4, "unknown-0xD4" },
3644   { 0xD5, "unknown-0xD5" },
3645   { 0xD6, "unknown-0xD6" },
3646   { 0xD7, "unknown-0xD7" },
3647   { 0xD8, "unknown-0xD8" },
3648   { 0xD9, "unknown-0xD9" },
3649   { 0xDA, "unknown-0xDA" },
3650   { 0xDB, "unknown-0xDB" },
3651   { 0xDC, "unknown-0xDC" },
3652   { 0xDD, "unknown-0xDD" },
3653   { 0xDE, "unknown-0xDE" },
3654   { 0xDF, "unknown-0xDF" },
3655   { 0xE0, "unknown-0xE0" },
3656   { 0xE1, "unknown-0xE1" },
3657   { 0xE2, "unknown-0xE2" },
3658   { 0xE3, "unknown-0xE3" },
3659   { 0xE4, "unknown-0xE4" },
3660   { 0xE5, "unknown-0xE5" },
3661   { 0xE6, "unknown-0xE6" },
3662   { 0xE7, "unknown-0xE7" },
3663   { 0xE8, "unknown-0xE8" },
3664   { 0xE9, "unknown-0xE9" },
3665   { 0xEA, "unknown-0xEA" },
3666   { 0xEB, "unknown-0xEB" },
3667   { 0xEC, "unknown-0xEC" },
3668   { 0xED, "unknown-0xED" },
3669   { 0xEE, "unknown-0xEE" },
3670   { 0xEF, "unknown-0xEF" },
3671   { 0xF0, "unknown-0xF0" },
3672   { 0xF1, "unknown-0xF1" },
3673   { 0xF2, "unknown-0xF2" },
3674   { 0xF3, "unknown-0xF3" },
3675   { 0xF4, "unknown-0xF4" },
3676   { 0xF5, "unknown-0xF5" },
3677   { 0xF6, "unknown-0xF6" },
3678   { 0xF7, "unknown-0xF7" },
3679   { 0xF8, "unknown-0xF8" },
3680   { 0xF9, "unknown-0xF9" },
3681   { 0xFA, "unknown-0xFA" },
3682   { 0xFB, "unknown-0xFB" },
3683   { 0xFC, "unknown-0xFC" },
3684   { 0xFD, "unknown-0xFD" },
3685   { 0xFE, "unknown-0xFE" },
3686   { 0xFF, "unknown-0xFF" },
3687   { 0x00, NULL },
3688 };
3689 static const char *decode_smb2_name(guint16 cmd)
3690 {
3691   if (cmd > 0xFF) return "unknown";
3692   return(smb2_cmd_vals[cmd & 0xFF].strptr);
3693 }
3694
3695 static smb2_function smb2_dissector[256] = {
3696   /* 0x00 NegotiateProtocol*/
3697         {dissect_smb2_negotiate_protocol_request,
3698          dissect_smb2_negotiate_protocol_response},
3699   /* 0x01 SessionSetup*/
3700         {dissect_smb2_session_setup_request,
3701          dissect_smb2_session_setup_response},
3702   /* 0x02 SessionLogoff*/
3703         {dissect_smb2_sessionlogoff_request,
3704          dissect_smb2_sessionlogoff_response},
3705   /* 0x03 TreeConnect*/
3706         {dissect_smb2_tree_connect_request,
3707          dissect_smb2_tree_connect_response},
3708   /* 0x04 TreeDisconnect*/
3709         {dissect_smb2_tree_disconnect_request,
3710          dissect_smb2_tree_disconnect_response},
3711   /* 0x05 Create*/
3712         {dissect_smb2_create_request,
3713          dissect_smb2_create_response},
3714   /* 0x06 Close*/
3715         {dissect_smb2_close_request,
3716          dissect_smb2_close_response},
3717   /* 0x07 Flush*/
3718         {dissect_smb2_flush_request,
3719          dissect_smb2_flush_response},
3720   /* 0x08 Read*/
3721         {dissect_smb2_read_request,
3722          dissect_smb2_read_response},
3723   /* 0x09 Writew*/
3724         {dissect_smb2_write_request,
3725          dissect_smb2_write_response},
3726   /* 0x0a Lock */
3727         {dissect_smb2_lock_request,
3728          dissect_smb2_lock_response},
3729   /* 0x0b Ioctl*/
3730         {dissect_smb2_ioctl_request,
3731          dissect_smb2_ioctl_response},
3732   /* 0x0c Cancel*/
3733         {dissect_smb2_cancel_request,
3734          NULL},
3735   /* 0x0d KeepAlive*/
3736         {dissect_smb2_keepalive_request,
3737          dissect_smb2_keepalive_response},
3738   /* 0x0e Find*/
3739         {dissect_smb2_find_request,
3740          dissect_smb2_find_response},
3741   /* 0x0f Notify*/
3742         {dissect_smb2_notify_request,
3743          dissect_smb2_notify_response},
3744   /* 0x10 GetInfo*/
3745         {dissect_smb2_getinfo_request,
3746          dissect_smb2_getinfo_response},
3747   /* 0x11 SetInfo*/
3748         {dissect_smb2_setinfo_request,
3749          dissect_smb2_setinfo_response},
3750   /* 0x12 Break */
3751         {NULL,
3752          dissect_smb2_break_response},
3753   /* 0x13 */  {NULL, NULL},
3754   /* 0x14 */  {NULL, NULL},
3755   /* 0x15 */  {NULL, NULL},
3756   /* 0x16 */  {NULL, NULL},
3757   /* 0x17 */  {NULL, NULL},
3758   /* 0x18 */  {NULL, NULL},
3759   /* 0x19 */  {NULL, NULL},
3760   /* 0x1a */  {NULL, NULL},
3761   /* 0x1b */  {NULL, NULL},
3762   /* 0x1c */  {NULL, NULL},
3763   /* 0x1d */  {NULL, NULL},
3764   /* 0x1e */  {NULL, NULL},
3765   /* 0x1f */  {NULL, NULL},
3766   /* 0x20 */  {NULL, NULL},
3767   /* 0x21 */  {NULL, NULL},
3768   /* 0x22 */  {NULL, NULL},
3769   /* 0x23 */  {NULL, NULL},
3770   /* 0x24 */  {NULL, NULL},
3771   /* 0x25 */  {NULL, NULL},
3772   /* 0x26 */  {NULL, NULL},
3773   /* 0x27 */  {NULL, NULL},
3774   /* 0x28 */  {NULL, NULL},
3775   /* 0x29 */  {NULL, NULL},
3776   /* 0x2a */  {NULL, NULL},
3777   /* 0x2b */  {NULL, NULL},
3778   /* 0x2c */  {NULL, NULL},
3779   /* 0x2d */  {NULL, NULL},
3780   /* 0x2e */  {NULL, NULL},
3781   /* 0x2f */  {NULL, NULL},
3782   /* 0x30 */  {NULL, NULL},
3783   /* 0x31 */  {NULL, NULL},
3784   /* 0x32 */  {NULL, NULL},
3785   /* 0x33 */  {NULL, NULL},
3786   /* 0x34 */  {NULL, NULL},
3787   /* 0x35 */  {NULL, NULL},
3788   /* 0x36 */  {NULL, NULL},
3789   /* 0x37 */  {NULL, NULL},
3790   /* 0x38 */  {NULL, NULL},
3791   /* 0x39 */  {NULL, NULL},
3792   /* 0x3a */  {NULL, NULL},
3793   /* 0x3b */  {NULL, NULL},
3794   /* 0x3c */  {NULL, NULL},
3795   /* 0x3d */  {NULL, NULL},
3796   /* 0x3e */  {NULL, NULL},
3797   /* 0x3f */  {NULL, NULL},
3798   /* 0x40 */  {NULL, NULL},
3799   /* 0x41 */  {NULL, NULL},
3800   /* 0x42 */  {NULL, NULL},
3801   /* 0x43 */  {NULL, NULL},
3802   /* 0x44 */  {NULL, NULL},
3803   /* 0x45 */  {NULL, NULL},
3804   /* 0x46 */  {NULL, NULL},
3805   /* 0x47 */  {NULL, NULL},
3806   /* 0x48 */  {NULL, NULL},
3807   /* 0x49 */  {NULL, NULL},
3808   /* 0x4a */  {NULL, NULL},
3809   /* 0x4b */  {NULL, NULL},
3810   /* 0x4c */  {NULL, NULL},
3811   /* 0x4d */  {NULL, NULL},
3812   /* 0x4e */  {NULL, NULL},
3813   /* 0x4f */  {NULL, NULL},
3814   /* 0x50 */  {NULL, NULL},
3815   /* 0x51 */  {NULL, NULL},
3816   /* 0x52 */  {NULL, NULL},
3817   /* 0x53 */  {NULL, NULL},
3818   /* 0x54 */  {NULL, NULL},
3819   /* 0x55 */  {NULL, NULL},
3820   /* 0x56 */  {NULL, NULL},
3821   /* 0x57 */  {NULL, NULL},
3822   /* 0x58 */  {NULL, NULL},
3823   /* 0x59 */  {NULL, NULL},
3824   /* 0x5a */  {NULL, NULL},
3825   /* 0x5b */  {NULL, NULL},
3826   /* 0x5c */  {NULL, NULL},
3827   /* 0x5d */  {NULL, NULL},
3828   /* 0x5e */  {NULL, NULL},
3829   /* 0x5f */  {NULL, NULL},
3830   /* 0x60 */  {NULL, NULL},
3831   /* 0x61 */  {NULL, NULL},
3832   /* 0x62 */  {NULL, NULL},
3833   /* 0x63 */  {NULL, NULL},
3834   /* 0x64 */  {NULL, NULL},
3835   /* 0x65 */  {NULL, NULL},
3836   /* 0x66 */  {NULL, NULL},
3837   /* 0x67 */  {NULL, NULL},
3838   /* 0x68 */  {NULL, NULL},
3839   /* 0x69 */  {NULL, NULL},
3840   /* 0x6a */  {NULL, NULL},
3841   /* 0x6b */  {NULL, NULL},
3842   /* 0x6c */  {NULL, NULL},
3843   /* 0x6d */  {NULL, NULL},
3844   /* 0x6e */  {NULL, NULL},
3845   /* 0x6f */  {NULL, NULL},
3846   /* 0x70 */  {NULL, NULL},
3847   /* 0x71 */  {NULL, NULL},
3848   /* 0x72 */  {NULL, NULL},
3849   /* 0x73 */  {NULL, NULL},
3850   /* 0x74 */  {NULL, NULL},
3851   /* 0x75 */  {NULL, NULL},
3852   /* 0x76 */  {NULL, NULL},
3853   /* 0x77 */  {NULL, NULL},
3854   /* 0x78 */  {NULL, NULL},
3855   /* 0x79 */  {NULL, NULL},
3856   /* 0x7a */  {NULL, NULL},
3857   /* 0x7b */  {NULL, NULL},
3858   /* 0x7c */  {NULL, NULL},
3859   /* 0x7d */  {NULL, NULL},
3860   /* 0x7e */  {NULL, NULL},
3861   /* 0x7f */  {NULL, NULL},
3862   /* 0x80 */  {NULL, NULL},
3863   /* 0x81 */  {NULL, NULL},
3864   /* 0x82 */  {NULL, NULL},
3865   /* 0x83 */  {NULL, NULL},
3866   /* 0x84 */  {NULL, NULL},
3867   /* 0x85 */  {NULL, NULL},
3868   /* 0x86 */  {NULL, NULL},
3869   /* 0x87 */  {NULL, NULL},
3870   /* 0x88 */  {NULL, NULL},
3871   /* 0x89 */  {NULL, NULL},
3872   /* 0x8a */  {NULL, NULL},
3873   /* 0x8b */  {NULL, NULL},
3874   /* 0x8c */  {NULL, NULL},
3875   /* 0x8d */  {NULL, NULL},
3876   /* 0x8e */  {NULL, NULL},
3877   /* 0x8f */  {NULL, NULL},
3878   /* 0x90 */  {NULL, NULL},
3879   /* 0x91 */  {NULL, NULL},
3880   /* 0x92 */  {NULL, NULL},
3881   /* 0x93 */  {NULL, NULL},
3882   /* 0x94 */  {NULL, NULL},
3883   /* 0x95 */  {NULL, NULL},
3884   /* 0x96 */  {NULL, NULL},
3885   /* 0x97 */  {NULL, NULL},
3886   /* 0x98 */  {NULL, NULL},
3887   /* 0x99 */  {NULL, NULL},
3888   /* 0x9a */  {NULL, NULL},
3889   /* 0x9b */  {NULL, NULL},
3890   /* 0x9c */  {NULL, NULL},
3891   /* 0x9d */  {NULL, NULL},
3892   /* 0x9e */  {NULL, NULL},
3893   /* 0x9f */  {NULL, NULL},
3894   /* 0xa0 */  {NULL, NULL},
3895   /* 0xa1 */  {NULL, NULL},
3896   /* 0xa2 */  {NULL, NULL},
3897   /* 0xa3 */  {NULL, NULL},
3898   /* 0xa4 */  {NULL, NULL},
3899   /* 0xa5 */  {NULL, NULL},
3900   /* 0xa6 */  {NULL, NULL},
3901   /* 0xa7 */  {NULL, NULL},
3902   /* 0xa8 */  {NULL, NULL},
3903   /* 0xa9 */  {NULL, NULL},
3904   /* 0xaa */  {NULL, NULL},
3905   /* 0xab */  {NULL, NULL},
3906   /* 0xac */  {NULL, NULL},
3907   /* 0xad */  {NULL, NULL},
3908   /* 0xae */  {NULL, NULL},
3909   /* 0xaf */  {NULL, NULL},
3910   /* 0xb0 */  {NULL, NULL},
3911   /* 0xb1 */  {NULL, NULL},
3912   /* 0xb2 */  {NULL, NULL},
3913   /* 0xb3 */  {NULL, NULL},
3914   /* 0xb4 */  {NULL, NULL},
3915   /* 0xb5 */  {NULL, NULL},
3916   /* 0xb6 */  {NULL, NULL},
3917   /* 0xb7 */  {NULL, NULL},
3918   /* 0xb8 */  {NULL, NULL},
3919   /* 0xb9 */  {NULL, NULL},
3920   /* 0xba */  {NULL, NULL},
3921   /* 0xbb */  {NULL, NULL},
3922   /* 0xbc */  {NULL, NULL},
3923   /* 0xbd */  {NULL, NULL},
3924   /* 0xbe */  {NULL, NULL},
3925   /* 0xbf */  {NULL, NULL},
3926   /* 0xc0 */  {NULL, NULL},
3927   /* 0xc1 */  {NULL, NULL},
3928   /* 0xc2 */  {NULL, NULL},
3929   /* 0xc3 */  {NULL, NULL},
3930   /* 0xc4 */  {NULL, NULL},
3931   /* 0xc5 */  {NULL, NULL},
3932   /* 0xc6 */  {NULL, NULL},
3933   /* 0xc7 */  {NULL, NULL},
3934   /* 0xc8 */  {NULL, NULL},
3935   /* 0xc9 */  {NULL, NULL},
3936   /* 0xca */  {NULL, NULL},
3937   /* 0xcb */  {NULL, NULL},
3938   /* 0xcc */  {NULL, NULL},
3939   /* 0xcd */  {NULL, NULL},
3940   /* 0xce */  {NULL, NULL},
3941   /* 0xcf */  {NULL, NULL},
3942   /* 0xd0 */  {NULL, NULL},
3943   /* 0xd1 */  {NULL, NULL},
3944   /* 0xd2 */  {NULL, NULL},
3945   /* 0xd3 */  {NULL, NULL},
3946   /* 0xd4 */  {NULL, NULL},
3947   /* 0xd5 */  {NULL, NULL},
3948   /* 0xd6 */  {NULL, NULL},
3949   /* 0xd7 */  {NULL, NULL},
3950   /* 0xd8 */  {NULL, NULL},
3951   /* 0xd9 */  {NULL, NULL},
3952   /* 0xda */  {NULL, NULL},
3953   /* 0xdb */  {NULL, NULL},
3954   /* 0xdc */  {NULL, NULL},
3955   /* 0xdd */  {NULL, NULL},
3956   /* 0xde */  {NULL, NULL},
3957   /* 0xdf */  {NULL, NULL},
3958   /* 0xe0 */  {NULL, NULL},
3959   /* 0xe1 */  {NULL, NULL},
3960   /* 0xe2 */  {NULL, NULL},
3961   /* 0xe3 */  {NULL, NULL},
3962   /* 0xe4 */  {NULL, NULL},
3963   /* 0xe5 */  {NULL, NULL},
3964   /* 0xe6 */  {NULL, NULL},
3965   /* 0xe7 */  {NULL, NULL},
3966   /* 0xe8 */  {NULL, NULL},
3967   /* 0xe9 */  {NULL, NULL},
3968   /* 0xea */  {NULL, NULL},
3969   /* 0xeb */  {NULL, NULL},
3970   /* 0xec */  {NULL, NULL},
3971   /* 0xed */  {NULL, NULL},
3972   /* 0xee */  {NULL, NULL},
3973   /* 0xef */  {NULL, NULL},
3974   /* 0xf0 */  {NULL, NULL},
3975   /* 0xf1 */  {NULL, NULL},
3976   /* 0xf2 */  {NULL, NULL},
3977   /* 0xf3 */  {NULL, NULL},
3978   /* 0xf4 */  {NULL, NULL},
3979   /* 0xf5 */  {NULL, NULL},
3980   /* 0xf6 */  {NULL, NULL},
3981   /* 0xf7 */  {NULL, NULL},
3982   /* 0xf8 */  {NULL, NULL},
3983   /* 0xf9 */  {NULL, NULL},
3984   /* 0xfa */  {NULL, NULL},
3985   /* 0xfb */  {NULL, NULL},
3986   /* 0xfc */  {NULL, NULL},
3987   /* 0xfd */  {NULL, NULL},
3988   /* 0xfe */  {NULL, NULL},
3989   /* 0xff */  {NULL, NULL},
3990 };
3991
3992
3993 static int
3994 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
3995 {
3996         int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
3997         proto_item *cmd_item;
3998         proto_tree *cmd_tree;
3999
4000         cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
4001                         "%s %s (0x%02x)",
4002                         decode_smb2_name(si->opcode),
4003                         (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
4004                         si->opcode);
4005         cmd_tree = proto_item_add_subtree(cmd_item, ett_smb2_command);
4006
4007
4008         cmd_dissector=(si->flags & SMB2_FLAGS_RESPONSE)?
4009                 smb2_dissector[si->opcode&0xff].response:
4010                 smb2_dissector[si->opcode&0xff].request;
4011         if(cmd_dissector){
4012                 offset=(*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
4013         } else {
4014                 proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, FALSE);
4015                 offset=tvb_length(tvb);
4016         }
4017
4018         return offset;
4019 }
4020
4021 static int
4022 dissect_smb2_tid_uid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
4023 {
4024         proto_item *tid_item=NULL;
4025         proto_tree *tid_tree=NULL;
4026         smb2_tid_info_t tid_key;
4027         int tid_offset;
4028         proto_item *uid_item=NULL;
4029         proto_tree *uid_tree=NULL;
4030         smb2_uid_info_t uid_key;
4031         int uid_offset;
4032         proto_item *item;
4033
4034         /* Tree ID */
4035         tid_offset = offset;
4036         si->tid=tvb_get_letohl(tvb, offset);
4037         tid_item=proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, TRUE);
4038         if(tree){
4039                 tid_tree=proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
4040         }
4041         offset += 4;
4042
4043         /* User ID */
4044         uid_offset = offset;
4045         si->uid=tvb_get_letoh64(tvb, offset);
4046         uid_item=proto_tree_add_item(tree, hf_smb2_uid, tvb, offset, 8, TRUE);
4047         if(tree){
4048                 uid_tree=proto_item_add_subtree(uid_item, ett_smb2_uid_tree);
4049         }
4050         offset += 8;
4051
4052         /* now we need to first lookup the uid session */
4053         uid_key.uid=si->uid;
4054         si->session=g_hash_table_lookup(si->conv->uids, &uid_key);
4055         if(!si->session) {
4056                 if (si->opcode != 0x03) return offset;
4057
4058                 /* if we come to a session that is unknown, and the operation is
4059                  * a tree connect, we create a dummy sessison, so we can hang the
4060                  * tree data on it
4061                  */
4062                 si->session=se_alloc(sizeof(smb2_uid_info_t));
4063                 si->session->uid=si->uid;
4064                 si->session->acct_name=NULL;
4065                 si->session->domain_name=NULL;
4066                 si->session->host_name=NULL;
4067                 si->session->auth_frame=(guint32)-1;
4068                 si->session->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
4069                 g_hash_table_insert(si->conv->uids, si->session, si->session);
4070
4071                 return offset;
4072         }
4073
4074         if (si->session->auth_frame != (guint32)-1) {
4075                 item=proto_tree_add_string(uid_tree, hf_smb2_acct_name, tvb, uid_offset, 0, si->session->acct_name);
4076                 PROTO_ITEM_SET_GENERATED(item);
4077                 proto_item_append_text(uid_item, " Acct:%s", si->session->acct_name);
4078
4079                 item=proto_tree_add_string(uid_tree, hf_smb2_domain_name, tvb, uid_offset, 0, si->session->domain_name);
4080                 PROTO_ITEM_SET_GENERATED(item);
4081                 proto_item_append_text(uid_item, " Domain:%s", si->session->domain_name);
4082
4083                 item=proto_tree_add_string(uid_tree, hf_smb2_host_name, tvb, uid_offset, 0, si->session->host_name);
4084                 PROTO_ITEM_SET_GENERATED(item);
4085                 proto_item_append_text(uid_item, " Host:%s", si->session->host_name);
4086
4087                 item=proto_tree_add_uint(uid_tree, hf_smb2_auth_frame, tvb, uid_offset, 0, si->session->auth_frame);
4088                 PROTO_ITEM_SET_GENERATED(item);
4089         }
4090
4091         /* see if we can find the name for this tid */
4092         tid_key.tid=si->tid;
4093         si->tree=g_hash_table_lookup(si->session->tids, &tid_key);
4094         if(!si->tree) return offset;
4095
4096         item=proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
4097         PROTO_ITEM_SET_GENERATED(item);
4098         proto_item_append_text(tid_item, "  %s", si->tree->name);
4099
4100         item=proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
4101         PROTO_ITEM_SET_GENERATED(item);
4102
4103         item=proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
4104         PROTO_ITEM_SET_GENERATED(item);
4105
4106         return offset;
4107 }
4108
4109 static void
4110 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
4111 {
4112         proto_item *seqnum_item;
4113         proto_item *item=NULL;
4114         proto_tree *tree=NULL;
4115         proto_item *header_item=NULL;
4116         proto_tree *header_tree=NULL;
4117         proto_item *flags_item=NULL;
4118         proto_tree *flags_tree=NULL;
4119         int offset=0;
4120         int old_offset;
4121         guint16 header_len;
4122         conversation_t *conversation;
4123         smb2_saved_info_t *ssi=NULL, ssi_key;
4124         smb2_info_t *si;
4125         unsigned int pid;
4126
4127         si=ep_alloc(sizeof(smb2_info_t));
4128         si->conv=NULL;
4129         si->saved=NULL;
4130         si->tree=NULL;
4131         si->top_tree=parent_tree;
4132
4133         /* find which conversation we are part of and get the data for that
4134          * conversation
4135          */
4136         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
4137         if(!conversation){
4138                 /* OK this is a new conversation so lets create it */
4139                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
4140                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
4141         }
4142         si->conv=conversation_get_proto_data(conversation, proto_smb2);
4143         if(!si->conv){
4144                 /* no smb2_into_t structure for this conversation yet,
4145                  * create it.
4146                  */
4147                 si->conv=se_alloc(sizeof(smb2_conv_info_t));
4148                 /* qqq this leaks memory for now since we never free
4149                    the hashtables */
4150                 si->conv->matched= g_hash_table_new(smb2_saved_info_hash_matched,
4151                         smb2_saved_info_equal_matched);
4152                 si->conv->unmatched= g_hash_table_new(smb2_saved_info_hash_unmatched,
4153                         smb2_saved_info_equal_unmatched);
4154                 si->conv->uids= g_hash_table_new(smb2_uid_info_hash,
4155                         smb2_uid_info_equal);
4156
4157                 conversation_add_proto_data(conversation, proto_smb2, si->conv);
4158         }
4159
4160
4161         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
4162                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
4163         }
4164         if (check_col(pinfo->cinfo, COL_INFO)){
4165                 col_clear(pinfo->cinfo, COL_INFO);
4166         }
4167
4168         if (parent_tree) {
4169                 item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset,
4170                         -1, FALSE);
4171                 tree = proto_item_add_subtree(item, ett_smb2);
4172         }
4173
4174
4175         if (tree) {
4176                 header_item = proto_tree_add_text(tree, tvb, offset, -1, "SMB2 Header");
4177                 header_tree = proto_item_add_subtree(header_item, ett_smb2_header);
4178         }
4179         old_offset=offset;
4180
4181         /* Decode the header */
4182         /* SMB2 marker */
4183         proto_tree_add_text(header_tree, tvb, offset, 4, "Server Component: SMB2");
4184         offset += 4;
4185
4186         /* header length */
4187         header_len=tvb_get_letohs(tvb, offset);
4188         proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, TRUE);
4189         offset += 2;
4190
4191         /* padding */
4192         offset += 2;
4193
4194         /* Status Code */
4195         si->status=tvb_get_letohl(tvb, offset);
4196         proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, TRUE);
4197         offset += 4;
4198
4199
4200         /* opcode */
4201         si->opcode=tvb_get_letohs(tvb, offset);
4202         proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, TRUE);
4203         offset += 2;
4204
4205         /* some unknown bytes */
4206         proto_tree_add_item(header_tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
4207         offset += 2;
4208
4209         /* flags */
4210         si->flags=tvb_get_letohl(tvb, offset);
4211         if(header_tree){
4212                 flags_item = proto_tree_add_text(header_tree, tvb, offset, 4,
4213                         "Flags: 0x%08x", si->flags);
4214                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_flags);
4215         }
4216         proto_tree_add_boolean(flags_tree, hf_smb2_flags_signature, tvb, offset, 4, si->flags);
4217         proto_tree_add_boolean(flags_tree, hf_smb2_flags_pid_valid, tvb, offset, 4, si->flags);
4218         proto_tree_add_boolean(flags_tree, hf_smb2_flags_response, tvb, offset, 4, si->flags);
4219
4220         offset += 4;
4221
4222         /* some unknown bytes */
4223         proto_tree_add_item(header_tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
4224         offset += 4;
4225
4226         /* command sequence number*/
4227         si->seqnum=tvb_get_letoh64(tvb, offset);
4228         ssi_key.seqnum=si->seqnum;
4229         seqnum_item=proto_tree_add_item(header_tree, hf_smb2_seqnum, tvb, offset, 8, TRUE);
4230         if(seqnum_item && (si->seqnum==-1)){
4231                 proto_item_append_text(seqnum_item, " (unsolicited response)");
4232         }
4233         offset += 8;
4234
4235         /* Process ID */
4236         pid=tvb_get_letohl(tvb, offset);
4237         proto_tree_add_uint_format(header_tree, hf_smb2_pid, tvb, offset, 4, pid, "Process Id: %08x %s",pid,(si->flags&SMB2_FLAGS_PID_VALID)?"":"(not valid)");
4238         offset += 4;
4239
4240         /* Tree ID and User ID */
4241         offset = dissect_smb2_tid_uid(pinfo, header_tree, tvb, offset, si);
4242
4243         /* Signature */
4244         proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, FALSE);
4245         offset += 16;
4246
4247         proto_item_set_len(header_item, offset-old_offset);
4248
4249
4250
4251         if (check_col(pinfo->cinfo, COL_INFO)){
4252                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
4253                         decode_smb2_name(si->opcode),
4254                         (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
4255                 if(si->status){
4256                         col_append_fstr(
4257                                 pinfo->cinfo, COL_INFO, ", Error: %s",
4258                                 val_to_str(si->status, NT_errors,
4259                                 "Unknown (0x%08X)"));
4260                 }
4261         }
4262
4263
4264         if(!pinfo->fd->flags.visited){
4265                 /* see if we can find this seqnum in the unmatched table */
4266                 ssi=g_hash_table_lookup(si->conv->unmatched, &ssi_key);
4267
4268                 if(!(si->flags & SMB2_FLAGS_RESPONSE)){
4269                         /* This is a request */
4270                         if(ssi){
4271                                 /* this is a request and we already found
4272                                  * an older ssi so just delete the previous
4273                                  * one
4274                                  */
4275                                 g_hash_table_remove(si->conv->unmatched, ssi);
4276                                 ssi=NULL;
4277                         }
4278
4279                         if(!ssi){
4280                                 /* no we couldnt find it, so just add it then
4281                                  * if was a request we are decoding
4282                                  */
4283                                 ssi=se_alloc(sizeof(smb2_saved_info_t));
4284                                 ssi->class=0;
4285                                 ssi->infolevel=0;
4286                                 ssi->seqnum=ssi_key.seqnum;
4287                                 ssi->private_data=NULL;
4288                                 ssi->frame_req=pinfo->fd->num;
4289                                 ssi->frame_res=0;
4290                                 ssi->req_time=pinfo->fd->abs_ts;
4291                                 g_hash_table_insert(si->conv->unmatched, ssi, ssi);
4292                         }
4293                 } else {
4294                         /* This is a response */
4295                         if(ssi){
4296                                 /* just  set the response frame and move it to the matched table */
4297                                 ssi->frame_res=pinfo->fd->num;
4298                                 g_hash_table_remove(si->conv->unmatched, ssi);
4299                                 g_hash_table_insert(si->conv->matched, ssi, ssi);
4300                         }
4301                 }
4302         } else {
4303                 /* see if we can find this seqnum in the matched table */
4304                 ssi=g_hash_table_lookup(si->conv->matched, &ssi_key);
4305                 /* if we couldnt find it in the matched table, it might still
4306                  * be in the unmatched table
4307                  */
4308                 if(!ssi){
4309                         ssi=g_hash_table_lookup(si->conv->unmatched, &ssi_key);
4310                 }
4311         }
4312
4313         if(ssi){
4314                 if(!(si->flags & SMB2_FLAGS_RESPONSE)){
4315                         if(ssi->frame_res){
4316                                 proto_item *tmp_item;
4317                                 tmp_item=proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
4318                                 PROTO_ITEM_SET_GENERATED(tmp_item);
4319                         }
4320                 } else {
4321                         if(ssi->frame_req){
4322                                 proto_item *tmp_item;
4323                                 nstime_t t, deltat;
4324
4325                                 tmp_item=proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
4326                                 PROTO_ITEM_SET_GENERATED(tmp_item);
4327                                 t = pinfo->fd->abs_ts;
4328                                 nstime_delta(&deltat, &t, &ssi->req_time);
4329                                 tmp_item=proto_tree_add_time(header_tree, hf_smb2_time, tvb,
4330                                     0, 0, &deltat);
4331                                 PROTO_ITEM_SET_GENERATED(tmp_item);
4332                         }
4333                 }
4334         }
4335         /* if we dont have ssi yet we must fake it */
4336         /*qqq*/
4337         si->saved=ssi;
4338
4339         tap_queue_packet(smb2_tap, pinfo, si);
4340
4341         /* Decode the payload */
4342         dissect_smb2_command(pinfo, tree, tvb, offset, si);
4343 }
4344
4345 static gboolean
4346 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
4347 {
4348         /* must check that this really is a smb2 packet */
4349         if (!tvb_bytes_exist(tvb, 0, 4))
4350                 return FALSE;
4351
4352         if( (tvb_get_guint8(tvb, 0) != 0xfe)
4353             || (tvb_get_guint8(tvb, 1) != 'S')
4354             || (tvb_get_guint8(tvb, 2) != 'M')
4355             || (tvb_get_guint8(tvb, 3) != 'B') ){
4356                 return FALSE;
4357         }
4358
4359         dissect_smb2(tvb, pinfo, parent_tree);
4360         return TRUE;
4361 }
4362
4363 void
4364 proto_register_smb2(void)
4365 {
4366         static hf_register_info hf[] = {
4367         { &hf_smb2_cmd,
4368                 { "Command", "smb2.cmd", FT_UINT16, BASE_DEC,
4369                 VALS(smb2_cmd_vals), 0, "SMB2 Command Opcode", HFILL }},
4370         { &hf_smb2_response_to,
4371                 { "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
4372                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
4373         { &hf_smb2_response_in,
4374                 { "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
4375                 NULL, 0, "The response to this packet is in this packet", HFILL }},
4376         { &hf_smb2_time,
4377                 { "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
4378                 NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }},
4379         { &hf_smb2_header_len,
4380                 { "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
4381                 NULL, 0, "SMB2 Size of Header", HFILL }},
4382         { &hf_smb2_nt_status,
4383                 { "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX,
4384                 VALS(NT_errors), 0, "NT Status code", HFILL }},
4385         { &hf_smb2_seqnum,
4386                 { "Command Sequence Number", "smb2.seq_num", FT_INT64, BASE_DEC,
4387                 NULL, 0, "SMB2 Command Sequence Number", HFILL }},
4388         { &hf_smb2_tid,
4389                 { "Tree Id", "smb2.tid", FT_UINT32, BASE_DEC,
4390                 NULL, 0, "SMB2 Tree Id", HFILL }},
4391         { &hf_smb2_uid,
4392                 { "User Id", "smb2.uid", FT_UINT64, BASE_HEX,
4393                 NULL, 0, "SMB2 User Id", HFILL }},
4394         { &hf_smb2_end_of_file,
4395                 { "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
4396                 NULL, 0, "SMB2 End Of File/File size", HFILL }},
4397         { &hf_smb2_nlinks,
4398                 { "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
4399                 NULL, 0, "Number of links to this object", HFILL }},
4400         { &hf_smb2_file_id,
4401                 { "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
4402                 NULL, 0, "SMB2 File Id", HFILL }},
4403         { &hf_smb2_allocation_size,
4404                 { "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
4405                 NULL, 0, "SMB2 Allocation Size for this object", HFILL }},
4406         { &hf_smb2_max_response_size,
4407                 { "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
4408                 NULL, 0, "SMB2 Maximum response size", HFILL }},
4409         { &hf_smb2_setinfo_size,
4410                 { "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
4411                 NULL, 0, "SMB2 setinfo size", HFILL }},
4412         { &hf_smb2_setinfo_offset,
4413                 { "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
4414                 NULL, 0, "SMB2 setinfo offset", HFILL }},
4415         { &hf_smb2_max_ioctl_out_size,
4416                 { "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
4417                 NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
4418         { &hf_smb2_response_size,
4419                 { "Response Size", "smb2.response_size", FT_UINT32, BASE_DEC,
4420                 NULL, 0, "SMB2 response size", HFILL }},
4421         { &hf_smb2_required_buffer_size,
4422                 { "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
4423                 NULL, 0, "SMB2 required buffer size", HFILL }},
4424         { &hf_smb2_pid,
4425                 { "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
4426                 NULL, 0, "SMB2 Process Id", HFILL }},
4427         { &hf_smb2_flags_response,
4428                 { "Response", "smb2.flags.response", FT_BOOLEAN, 32,
4429                 TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }},
4430         { &hf_smb2_flags_pid_valid,
4431                 { "PID Valid", "smb2.flags.pid_valid", FT_BOOLEAN, 32,
4432                 TFS(&tfs_flags_pid_valid), SMB2_FLAGS_PID_VALID, "Whether the PID field is valid or not", HFILL }},
4433         { &hf_smb2_flags_signature,
4434                 { "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
4435                 TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }},
4436         { &hf_smb2_tree,
4437                 { "Tree", "smb2.tree", FT_STRING, BASE_NONE,
4438                 NULL, 0, "Name of the Tree/Share", HFILL }},
4439         { &hf_smb2_filename,
4440                 { "Filename", "smb2.filename", FT_STRING, BASE_NONE,
4441                 NULL, 0, "Name of the file", HFILL }},
4442         { &hf_smb2_filename_len,
4443                 { "Filename Length", "smb2.filename.len", FT_UINT16, BASE_DEC,
4444                 NULL, 0, "Length of the file name", HFILL }},
4445
4446         { &hf_smb2_search,
4447                 { "Search Pattern", "smb2.search", FT_STRING, BASE_NONE,
4448                 NULL, 0, "Search pattern", HFILL }},
4449
4450         { &hf_smb2_security_blob_len,
4451                 { "Security Blob Length", "smb2.security_blob_len", FT_UINT16, BASE_DEC,
4452                 NULL, 0, "Security blob length", HFILL }},
4453
4454         { &hf_smb2_security_blob_offset,
4455                 { "Security Blob Offset", "smb2.security_blob_offset", FT_UINT16, BASE_HEX,
4456                 NULL, 0, "Offset into the SMB2 PDU of the blob", HFILL }},
4457
4458         { &hf_smb2_response_buffer_offset,
4459                 { "Response Buffer Offset", "smb2.response_buffer_offset", FT_UINT16, BASE_HEX,
4460                 NULL, 0, "Offset of the response buffer", HFILL }},
4461
4462         { &hf_smb2_data_offset,
4463                 { "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
4464                 NULL, 0, "Offset to data", HFILL }},
4465
4466         { &hf_smb2_find_response_size,
4467                 { "Size of Find Data", "smb2.find.response_size", FT_UINT32, BASE_DEC,
4468                 NULL, 0, "Size of returned Find data", HFILL }},
4469
4470         { &hf_smb2_ea_size,
4471                 { "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
4472                 NULL, 0, "Size of EA data", HFILL }},
4473
4474         { &hf_smb2_class,
4475                 { "Class", "smb2.class", FT_UINT8, BASE_HEX,
4476                 VALS(smb2_class_vals), 0, "Info class", HFILL }},
4477
4478         { &hf_smb2_infolevel,
4479                 { "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
4480                 NULL, 0, "Infolevel", HFILL }},
4481
4482         { &hf_smb2_infolevel_file_info,
4483                 { "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX,
4484                 VALS(smb2_file_info_levels), 0, "File_Info Infolevel", HFILL }},
4485
4486         { &hf_smb2_infolevel_fs_info,
4487                 { "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX,
4488                 VALS(smb2_fs_info_levels), 0, "Fs_Info Infolevel", HFILL }},
4489
4490         { &hf_smb2_infolevel_sec_info,
4491                 { "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX,
4492                 VALS(smb2_sec_info_levels), 0, "Sec_Info Infolevel", HFILL }},
4493
4494         { &hf_smb2_write_length,
4495                 { "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
4496                 NULL, 0, "Amount of data to write", HFILL }},
4497
4498         { &hf_smb2_write_offset,
4499                 { "Write Offset", "smb2.write_offset", FT_UINT64, BASE_DEC,
4500                 NULL, 0, "At which offset to write the data", HFILL }},
4501
4502         { &hf_smb2_read_length,
4503                 { "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
4504                 NULL, 0, "Amount of data to read", HFILL }},
4505
4506         { &hf_smb2_read_offset,
4507                 { "Read Offset", "smb2.read_offset", FT_UINT64, BASE_DEC,
4508                 NULL, 0, "At which offset to read the data", HFILL }},
4509
4510         { &hf_smb2_security_blob,
4511                 { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_HEX,
4512                 NULL, 0, "Security blob", HFILL }},
4513
4514         { &hf_smb2_ioctl_out_data,
4515                 { "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
4516                 NULL, 0, "Ioctl Out", HFILL }},
4517
4518         { &hf_smb2_ioctl_in_data,
4519                 { "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
4520                 NULL, 0, "Ioctl In", HFILL }},
4521
4522         { &hf_smb2_server_guid,
4523           { "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
4524                 NULL, 0, "Server GUID", HFILL }},
4525
4526         { &hf_smb2_object_id,
4527           { "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
4528                 NULL, 0, "ObjectID for this FID", HFILL }},
4529
4530         { &hf_smb2_birth_volume_id,
4531           { "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
4532                 NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }},
4533
4534         { &hf_smb2_birth_object_id,
4535           { "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
4536                 NULL, 0, "ObjectID for this FID when it was originally created", HFILL }},
4537
4538         { &hf_smb2_domain_id,
4539           { "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
4540                 NULL, 0, "", HFILL }},
4541
4542         { &hf_smb2_create_timestamp,
4543                 { "Create", "smb2.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
4544                 NULL, 0, "Time when this object was created", HFILL }},
4545
4546         { &hf_smb2_fid,
4547                 { "File Id", "smb2.fid", FT_GUID, BASE_NONE,
4548                 NULL, 0, "SMB2 File Id", HFILL }},
4549
4550         { &hf_smb2_write_data,
4551                 { "Write Data", "smb2.write_data", FT_BYTES, BASE_HEX,
4552                 NULL, 0, "SMB2 Data to be written", HFILL }},
4553
4554         { &hf_smb2_read_data,
4555                 { "Read Data", "smb2.read_data", FT_BYTES, BASE_HEX,
4556                 NULL, 0, "SMB2 Data that is read", HFILL }},
4557
4558         { &hf_smb2_last_access_timestamp,
4559                 { "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, BASE_NONE,
4560                 NULL, 0, "Time when this object was last accessed", HFILL }},
4561
4562         { &hf_smb2_last_write_timestamp,
4563                 { "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
4564                 NULL, 0, "Time when this object was last written to", HFILL }},
4565
4566         { &hf_smb2_last_change_timestamp,
4567                 { "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, BASE_NONE,
4568                 NULL, 0, "Time when this object was last changed", HFILL }},
4569
4570         { &hf_smb2_file_all_info,
4571                 { "SMB2_FILE_ALL_INFO", "smb2.smb2_file_all_info", FT_NONE, BASE_NONE,
4572                 NULL, 0, "SMB2_FILE_ALL_INFO structure", HFILL }},
4573
4574         { &hf_smb2_file_allocation_info,
4575                 { "SMB2_FILE_ALLOCATION_INFO", "smb2.smb2_file_allocation_info", FT_NONE, BASE_NONE,
4576                 NULL, 0, "SMB2_FILE_ALLOCATION_INFO structure", HFILL }},
4577
4578         { &hf_smb2_file_endoffile_info,
4579                 { "SMB2_FILE_ENDOFFILE_INFO", "smb2.smb2_file_endoffile_info", FT_NONE, BASE_NONE,
4580                 NULL, 0, "SMB2_FILE_ENDOFFILE_INFO structure", HFILL }},
4581
4582         { &hf_smb2_file_alternate_name_info,
4583                 { "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.smb2_file_alternate_name_info", FT_NONE, BASE_NONE,
4584                 NULL, 0, "SMB2_FILE_ALTERNATE_NAME_INFO structure", HFILL }},
4585
4586         { &hf_smb2_file_stream_info,
4587                 { "SMB2_FILE_STREAM_INFO", "smb2.smb2_file_stream_info", FT_NONE, BASE_NONE,
4588                 NULL, 0, "SMB2_FILE_STREAM_INFO structure", HFILL }},
4589
4590         { &hf_smb2_file_pipe_info,
4591                 { "SMB2_FILE_PIPE_INFO", "smb2.smb2_file_pipe_info", FT_NONE, BASE_NONE,
4592                 NULL, 0, "SMB2_FILE_PIPE_INFO structure", HFILL }},
4593
4594         { &hf_smb2_file_compression_info,
4595                 { "SMB2_FILE_COMPRESSION_INFO", "smb2.smb2_file_compression_info", FT_NONE, BASE_NONE,
4596                 NULL, 0, "SMB2_FILE_COMPRESSION_INFO structure", HFILL }},
4597
4598         { &hf_smb2_file_basic_info,
4599                 { "SMB2_FILE_BASIC_INFO", "smb2.smb2_file_basic_info", FT_NONE, BASE_NONE,
4600                 NULL, 0, "SMB2_FILE_BASIC_INFO structure", HFILL }},
4601
4602         { &hf_smb2_file_standard_info,
4603                 { "SMB2_FILE_STANDARD_INFO", "smb2.smb2_file_standard_info", FT_NONE, BASE_NONE,
4604                 NULL, 0, "SMB2_FILE_STANDARD_INFO structure", HFILL }},
4605
4606         { &hf_smb2_file_internal_info,
4607                 { "SMB2_FILE_INTERNAL_INFO", "smb2.smb2_file_internal_info", FT_NONE, BASE_NONE,
4608                 NULL, 0, "SMB2_FILE_INTERNAL_INFO structure", HFILL }},
4609
4610         { &hf_smb2_file_mode_info,
4611                 { "SMB2_FILE_MODE_INFO", "smb2.smb2_file_mode_info", FT_NONE, BASE_NONE,
4612                 NULL, 0, "SMB2_FILE_MODE_INFO structure", HFILL }},
4613
4614         { &hf_smb2_file_alignment_info,
4615                 { "SMB2_FILE_ALIGNMENT_INFO", "smb2.smb2_file_alignment_info", FT_NONE, BASE_NONE,
4616                 NULL, 0, "SMB2_FILE_ALIGNMENT_INFO structure", HFILL }},
4617
4618         { &hf_smb2_file_position_info,
4619                 { "SMB2_FILE_POSITION_INFO", "smb2.smb2_file_position_info", FT_NONE, BASE_NONE,
4620                 NULL, 0, "SMB2_FILE_POSITION_INFO structure", HFILL }},
4621
4622         { &hf_smb2_file_access_info,
4623                 { "SMB2_FILE_ACCESS_INFO", "smb2.smb2_file_access_info", FT_NONE, BASE_NONE,
4624                 NULL, 0, "SMB2_FILE_ACCESS_INFO structure", HFILL }},
4625
4626         { &hf_smb2_file_ea_info,
4627                 { "SMB2_FILE_EA_INFO", "smb2.smb2_file_ea_info", FT_NONE, BASE_NONE,
4628                 NULL, 0, "SMB2_FILE_EA_INFO structure", HFILL }},
4629
4630         { &hf_smb2_file_network_open_info,
4631                 { "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.smb2_file_network_open_info", FT_NONE, BASE_NONE,
4632                 NULL, 0, "SMB2_FILE_NETWORK_OPEN_INFO structure", HFILL }},
4633
4634         { &hf_smb2_file_attribute_tag_info,
4635                 { "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.smb2_file_attribute_tag_info", FT_NONE, BASE_NONE,
4636                 NULL, 0, "SMB2_FILE_ATTRIBUTE_TAG_INFO structure", HFILL }},
4637
4638         { &hf_smb2_file_disposition_info,
4639                 { "SMB2_FILE_DISPOSITION_INFO", "smb2.smb2_file_disposition_info", FT_NONE, BASE_NONE,
4640                 NULL, 0, "SMB2_FILE_DISPOSITION_INFO structure", HFILL }},
4641
4642         { &hf_smb2_file_info_0f,
4643                 { "SMB2_FILE_INFO_0f", "smb2.smb2_file_info_0f", FT_NONE, BASE_NONE,
4644                 NULL, 0, "SMB2_FILE_INFO_0f structure", HFILL }},
4645
4646         { &hf_smb2_file_rename_info,
4647                 { "SMB2_FILE_RENAME_INFO", "smb2.smb2_file_rename_info", FT_NONE, BASE_NONE,
4648                 NULL, 0, "SMB2_FILE_RENAME_INFO structure", HFILL }},
4649
4650         { &hf_smb2_fs_info_01,
4651                 { "SMB2_FS_INFO_01", "smb2.smb2_fs_info_01", FT_NONE, BASE_NONE,
4652                 NULL, 0, "SMB2_FS_INFO_01 structure", HFILL }},
4653
4654         { &hf_smb2_fs_info_03,
4655                 { "SMB2_FS_INFO_03", "smb2.smb2_fs_info_03", FT_NONE, BASE_NONE,
4656                 NULL, 0, "SMB2_FS_INFO_03 structure", HFILL }},
4657
4658         { &hf_smb2_fs_info_04,
4659                 { "SMB2_FS_INFO_04", "smb2.smb2_fs_info_04", FT_NONE, BASE_NONE,
4660                 NULL, 0, "SMB2_FS_INFO_04 structure", HFILL }},
4661
4662         { &hf_smb2_fs_info_05,
4663                 { "SMB2_FS_INFO_05", "smb2.smb2_fs_info_05", FT_NONE, BASE_NONE,
4664                 NULL, 0, "SMB2_FS_INFO_05 structure", HFILL }},
4665
4666         { &hf_smb2_fs_info_06,
4667                 { "SMB2_FS_INFO_06", "smb2.smb2_fs_info_06", FT_NONE, BASE_NONE,
4668                 NULL, 0, "SMB2_FS_INFO_06 structure", HFILL }},
4669
4670         { &hf_smb2_fs_info_07,
4671                 { "SMB2_FS_INFO_07", "smb2.smb2_fs_info_07", FT_NONE, BASE_NONE,
4672                 NULL, 0, "SMB2_FS_INFO_07 structure", HFILL }},
4673
4674         { &hf_smb2_fs_objectid_info,
4675                 { "SMB2_FS_OBJECTID_INFO", "smb2.smb2_fs_objectid_info", FT_NONE, BASE_NONE,
4676                 NULL, 0, "SMB2_FS_OBJECTID_INFO structure", HFILL }},
4677
4678         { &hf_smb2_sec_info_00,
4679                 { "SMB2_SEC_INFO_00", "smb2.smb2_sec_info_00", FT_NONE, BASE_NONE,
4680                 NULL, 0, "SMB2_SEC_INFO_00 structure", HFILL }},
4681
4682         { &hf_smb2_disposition_delete_on_close,
4683           { "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
4684                 TFS(&tfs_disposition_delete_on_close), 0x01, "", HFILL }},
4685
4686
4687         { &hf_smb2_create_disposition,
4688                 { "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
4689                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
4690
4691         { &hf_smb2_create_action,
4692                 { "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
4693                 VALS(oa_open_vals), 0, "Create Action", HFILL }},
4694
4695         { &hf_smb2_extrainfo,
4696                 { "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
4697                 NULL, 0, "Create ExtraInfo", HFILL }},
4698
4699         { &hf_smb2_chain_offset,
4700                 { "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
4701                 NULL, 0, "Offset to next entry in chain or 0", HFILL }},
4702
4703         { &hf_smb2_chain_data,
4704                 { "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
4705                 NULL, 0, "Chain Data", HFILL }},
4706
4707         { &hf_smb2_FILE_OBJECTID_BUFFER,
4708                 { "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
4709                 NULL, 0, "A FILE_OBJECTID_BUFFER structure", HFILL }},
4710
4711         { &hf_smb2_data_length,
4712                 { "Data Length", "smb2.create.data_length", FT_UINT32, BASE_DEC,
4713                 NULL, 0, "Length Data or 0", HFILL }},
4714
4715         { &hf_smb2_next_offset,
4716                 { "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
4717                 NULL, 0, "Offset to next buffer or 0", HFILL }},
4718
4719         { &hf_smb2_current_time,
4720                 { "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, BASE_NONE,
4721                 NULL, 0, "Current Time at server", HFILL }},
4722
4723         { &hf_smb2_boot_time,
4724                 { "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, BASE_NONE,
4725                 NULL, 0, "Boot Time at server", HFILL }},
4726
4727         { &hf_smb2_ea_flags,
4728                 { "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
4729                 NULL, 0, "EA Flags", HFILL }},
4730
4731         { &hf_smb2_ea_name_len,
4732                 { "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
4733                 NULL, 0, "EA Name Length", HFILL }},
4734
4735         { &hf_smb2_ea_data_len,
4736                 { "EA Data Length", "smb2.ea.data_len", FT_UINT8, BASE_DEC,
4737                 NULL, 0, "EA Data Length", HFILL }},
4738
4739         { &hf_smb2_delete_pending,
4740                 { "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
4741                 NULL, 0, "Delete Pending", HFILL }},
4742
4743         { &hf_smb2_is_directory,
4744                 { "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
4745                 NULL, 0, "Is this a directory?", HFILL }},
4746
4747         { &hf_smb2_create_flags,
4748                 { "Create Flags", "smb2.create.flags", FT_UINT16, BASE_HEX,
4749                 NULL, 0, "Create flags", HFILL }},
4750
4751         { &hf_smb2_create_flags_request_oplock,
4752                 { "Request Oplock", "smb2.create_flags.request_oplock", FT_BOOLEAN, 16,
4753                 NULL, 0x0100, "", HFILL }},
4754
4755         { &hf_smb2_create_flags_request_exclusive_oplock,
4756                 { "Request Exclusive Oplock", "smb2.create_flags.request_exclusive_oplock", FT_BOOLEAN, 16,
4757                 NULL, 0x0800, "", HFILL }},
4758
4759         { &hf_smb2_create_flags_grant_oplock,
4760                 { "Grant Oplock", "smb2.create_flags.grant_oplock", FT_BOOLEAN, 16,
4761                 NULL, 0x0001, "", HFILL }},
4762
4763         { &hf_smb2_create_flags_grant_exclusive_oplock,
4764                 { "Grant Exclusive Oplock", "smb2.create_flags.grant_exclusive_oplock", FT_BOOLEAN, 16,
4765                 NULL, 0x0008, "", HFILL }},
4766
4767         { &hf_smb2_close_flags,
4768                 { "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
4769                 NULL, 0, "close flags", HFILL }},
4770
4771         { &hf_smb2_buffer_code_len,
4772                 { "Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
4773                 NULL, 0, "Length of fixed portion of PDU", HFILL }},
4774
4775         { &hf_smb2_olb_length,
4776                 { "Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
4777                 NULL, 0, "Length of the buffer", HFILL }},
4778
4779         { &hf_smb2_olb_offset,
4780                 { "Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
4781                 NULL, 0, "Offset to the buffer", HFILL }},
4782
4783         { &hf_smb2_buffer_code_flags_dyn,
4784                 { "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
4785                 NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }},
4786
4787         { &hf_smb2_ea_data,
4788                 { "EA Data", "smb2.ea.data", FT_STRING, BASE_NONE,
4789                 NULL, 0, "EA Data", HFILL }},
4790
4791         { &hf_smb2_ea_name,
4792                 { "EA Name", "smb2.ea.name", FT_STRING, BASE_NONE,
4793                 NULL, 0, "EA Name", HFILL }},
4794
4795         { &hf_smb2_impersonation_level,
4796                 { "Impersonation", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
4797                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
4798
4799         { &hf_smb2_ioctl_function,
4800                 { "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX,
4801                 VALS(smb2_ioctl_vals), 0, "Ioctl function", HFILL }},
4802
4803         { &hf_smb2_ioctl_function_device,
4804                 { "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX,
4805                 VALS(smb2_ioctl_device_vals), 0xffff0000, "Device for Ioctl", HFILL }},
4806
4807         { &hf_smb2_ioctl_function_access,
4808                 { "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
4809                 VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }},
4810
4811         { &hf_smb2_ioctl_function_function,
4812                 { "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
4813                 NULL, 0x00003ffc, "Function for Ioctl", HFILL }},
4814
4815         { &hf_smb2_ioctl_function_method,
4816                 { "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
4817                 VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }},
4818
4819         { &hf_smb2_ioctl_shadow_copy_num_volumes,
4820                 { "Num Volumes", "smb2.ioctl.shadow_copy.num_volumes", FT_UINT32, BASE_DEC,
4821                 NULL, 0, "Number of shadow copy volumes", HFILL }},
4822
4823         { &hf_smb2_ioctl_shadow_copy_num_labels,
4824                 { "Num Labels", "smb2.ioctl.shadow_copy.num_labels", FT_UINT32, BASE_DEC,
4825                 NULL, 0, "Number of shadow copy labels", HFILL }},
4826
4827         { &hf_smb2_ioctl_shadow_copy_label,
4828                 { "Label", "smb2.ioctl.shadow_copy.label", FT_STRING, BASE_NONE,
4829                 NULL, 0, "Shadow copy label", HFILL }},
4830
4831         { &hf_smb2_compression_format,
4832                 { "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
4833                 VALS(compression_format_vals), 0, "Compression to use", HFILL }},
4834
4835         { &hf_smb2_share_type,
4836                 { "Share Type", "smb2.share_type", FT_UINT16, BASE_DEC,
4837                 VALS(smb2_share_type_vals), 0, "Type of share", HFILL }},
4838
4839         { &hf_smb2_ioctl_shadow_copy_count,
4840                 { "Count", "smb2.ioctl.shadow_copy.count", FT_UINT32, BASE_DEC,
4841                 NULL, 0, "Number of bytes for shadow copy label strings", HFILL }},
4842
4843         { &hf_smb2_auth_frame,
4844                 { "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
4845                 NULL, 0, "Which frame this user was authenticated in", HFILL }},
4846
4847         { &hf_smb2_tcon_frame,
4848                 { "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
4849                 NULL, 0, "Which frame this share was connected in", HFILL }},
4850
4851         { &hf_smb2_tag,
4852                 { "Tag", "smb2.tag", FT_STRING, BASE_NONE,
4853                 NULL, 0, "Tag of chain entry", HFILL }},
4854
4855         { &hf_smb2_acct_name,
4856                 { "Account", "smb2.acct", FT_STRING, BASE_NONE,
4857                 NULL, 0, "Account Name", HFILL }},
4858
4859         { &hf_smb2_domain_name,
4860                 { "Domain", "smb2.domain", FT_STRING, BASE_NONE,
4861                 NULL, 0, "Domain Name", HFILL }},
4862
4863         { &hf_smb2_host_name,
4864                 { "Host", "smb2.host", FT_STRING, BASE_NONE,
4865                 NULL, 0, "Host Name", HFILL }},
4866
4867         { &hf_smb2_signature,
4868                 { "Signature", "smb2.signature", FT_BYTES, BASE_HEX,
4869                 NULL, 0, "Signature", HFILL }},
4870
4871         { &hf_smb2_unknown,
4872                 { "unknown", "smb2.unknown", FT_BYTES, BASE_HEX,
4873                 NULL, 0, "Unknown bytes", HFILL }},
4874
4875         { &hf_smb2_unknown_timestamp,
4876                 { "Timestamp", "smb2.unknown.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
4877                 NULL, 0, "Unknown timestamp", HFILL }},
4878         };
4879
4880         static gint *ett[] = {
4881                 &ett_smb2,
4882                 &ett_smb2_ea,
4883                 &ett_smb2_olb,
4884                 &ett_smb2_header,
4885                 &ett_smb2_command,
4886                 &ett_smb2_secblob,
4887                 &ett_smb2_file_basic_info,
4888                 &ett_smb2_file_standard_info,
4889                 &ett_smb2_file_internal_info,
4890                 &ett_smb2_file_ea_info,
4891                 &ett_smb2_file_access_info,
4892                 &ett_smb2_file_rename_info,
4893                 &ett_smb2_file_disposition_info,
4894                 &ett_smb2_file_position_info,
4895                 &ett_smb2_file_info_0f,
4896                 &ett_smb2_file_mode_info,
4897                 &ett_smb2_file_alignment_info,
4898                 &ett_smb2_file_all_info,
4899                 &ett_smb2_file_allocation_info,
4900                 &ett_smb2_file_endoffile_info,
4901                 &ett_smb2_file_alternate_name_info,
4902                 &ett_smb2_file_stream_info,
4903                 &ett_smb2_file_pipe_info,
4904                 &ett_smb2_file_compression_info,
4905                 &ett_smb2_file_network_open_info,
4906                 &ett_smb2_file_attribute_tag_info,
4907                 &ett_smb2_fs_info_01,
4908                 &ett_smb2_fs_info_03,
4909                 &ett_smb2_fs_info_04,
4910                 &ett_smb2_fs_info_05,
4911                 &ett_smb2_fs_info_06,
4912                 &ett_smb2_fs_info_07,
4913                 &ett_smb2_fs_objectid_info,
4914                 &ett_smb2_sec_info_00,
4915                 &ett_smb2_tid_tree,
4916                 &ett_smb2_uid_tree,
4917                 &ett_smb2_create_flags,
4918                 &ett_smb2_chain_element,
4919                 &ett_smb2_MxAc_buffer,
4920                 &ett_smb2_ioctl_function,
4921                 &ett_smb2_FILE_OBJECTID_BUFFER,
4922                 &ett_smb2_flags,
4923         };
4924
4925         proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
4926             "SMB2", "smb2");
4927         proto_register_subtree_array(ett, array_length(ett));
4928         proto_register_field_array(proto_smb2, hf, array_length(hf));
4929
4930         register_heur_dissector_list("smb2_heur_subdissectors", &smb2_heur_subdissector_list);
4931         smb2_tap = register_tap("smb2");
4932 }
4933
4934 void
4935 proto_reg_handoff_smb2(void)
4936 {
4937         gssapi_handle = find_dissector("gssapi");
4938         ntlmssp_handle = find_dissector("ntlmssp");
4939         heur_dissector_add("netbios", dissect_smb2_heur, proto_smb2);
4940 }