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