de32e43babd49fb50db562fbfb9dc35a00886ebe
[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  * For documentation of this protocol, see:
6  *
7  * http://wiki.wireshark.org/SMB2
8  * http://msdn.microsoft.com/en-us/library/cc246482(PROT.10).aspx
9  *
10  * If you edit this file, keep the wiki updated as well.
11  *
12  * $Id$
13  *
14  * Wireshark - Network traffic analyzer
15  * By Gerald Combs <gerald@wireshark.org>
16  * Copyright 1998 Gerald Combs
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include <epan/packet.h>
38 #include <epan/conversation.h>
39 #include <epan/tap.h>
40 #include <epan/emem.h>
41
42 #include "packet-smb2.h"
43 #include "packet-dcerpc.h"
44 #include "packet-ntlmssp.h"
45 #include "packet-windows-common.h"
46 #include "packet-smb-common.h"
47 #include "packet-smb.h"
48 #include "packet-dcerpc-nt.h"
49 #include <string.h>
50
51
52
53 static int proto_smb2 = -1;
54 static int hf_smb2_cmd = -1;
55 static int hf_smb2_nt_status = -1;
56 static int hf_smb2_response_to = -1;
57 static int hf_smb2_response_in = -1;
58 static int hf_smb2_time = -1;
59 static int hf_smb2_header_len = -1;
60 static int hf_smb2_seqnum = -1;
61 static int hf_smb2_pid = -1;
62 static int hf_smb2_tid = -1;
63 static int hf_smb2_aid = -1;
64 static int hf_smb2_sesid = -1;
65 static int hf_smb2_previous_sesid = -1;
66 static int hf_smb2_flags_response = -1;
67 static int hf_smb2_flags_async_cmd = -1;
68 static int hf_smb2_flags_dfs_op = -1;
69 static int hf_smb2_flags_chained = -1;
70 static int hf_smb2_flags_signature = -1;
71 static int hf_smb2_chain_offset = -1;
72 static int hf_smb2_response_buffer_offset = -1;
73 static int hf_smb2_security_blob_offset = -1;
74 static int hf_smb2_security_blob_len = -1;
75 static int hf_smb2_security_blob = -1;
76 static int hf_smb2_ioctl_in_data = -1;
77 static int hf_smb2_ioctl_out_data = -1;
78 static int hf_smb2_unknown = -1;
79 static int hf_smb2_twrp_timestamp = -1;
80 static int hf_smb2_mxac_timestamp = -1;
81 static int hf_smb2_mxac_status = -1;
82 static int hf_smb2_qfid_fid = -1;
83 static int hf_smb2_create_timestamp = -1;
84 static int hf_smb2_oplock = -1;
85 static int hf_smb2_close_flags = -1;
86 static int hf_smb2_notify_flags = -1;
87 static int hf_smb2_last_access_timestamp = -1;
88 static int hf_smb2_last_write_timestamp = -1;
89 static int hf_smb2_last_change_timestamp = -1;
90 static int hf_smb2_current_time = -1;
91 static int hf_smb2_boot_time = -1;
92 static int hf_smb2_filename = -1;
93 static int hf_smb2_filename_len = -1;
94 static int hf_smb2_nlinks = -1;
95 static int hf_smb2_delete_pending = -1;
96 static int hf_smb2_is_directory = -1;
97 static int hf_smb2_file_id = -1;
98 static int hf_smb2_allocation_size = -1;
99 static int hf_smb2_end_of_file = -1;
100 static int hf_smb2_tree = -1;
101 static int hf_smb2_find_pattern = -1;
102 static int hf_smb2_find_info_level = -1;
103 static int hf_smb2_find_info_blob = -1;
104 static int hf_smb2_client_guid = -1;
105 static int hf_smb2_server_guid = -1;
106 static int hf_smb2_object_id = -1;
107 static int hf_smb2_birth_volume_id = -1;
108 static int hf_smb2_birth_object_id = -1;
109 static int hf_smb2_domain_id = -1;
110 static int hf_smb2_class = -1;
111 static int hf_smb2_infolevel = -1;
112 static int hf_smb2_infolevel_file_info = -1;
113 static int hf_smb2_infolevel_fs_info = -1;
114 static int hf_smb2_infolevel_sec_info = -1;
115 static int hf_smb2_max_response_size = -1;
116 static int hf_smb2_max_ioctl_in_size = -1;
117 static int hf_smb2_max_ioctl_out_size = -1;
118 static int hf_smb2_required_buffer_size = -1;
119 static int hf_smb2_response_size = -1;
120 static int hf_smb2_setinfo_size = -1;
121 static int hf_smb2_setinfo_offset = -1;
122 static int hf_smb2_file_basic_info = -1;
123 static int hf_smb2_file_standard_info = -1;
124 static int hf_smb2_file_internal_info = -1;
125 static int hf_smb2_file_ea_info = -1;
126 static int hf_smb2_file_access_info = -1;
127 static int hf_smb2_file_rename_info = -1;
128 static int hf_smb2_file_disposition_info = -1;
129 static int hf_smb2_file_position_info = -1;
130 static int hf_smb2_file_info_0f = -1;
131 static int hf_smb2_file_mode_info = -1;
132 static int hf_smb2_file_alignment_info = -1;
133 static int hf_smb2_file_all_info = -1;
134 static int hf_smb2_file_allocation_info = -1;
135 static int hf_smb2_file_endoffile_info = -1;
136 static int hf_smb2_file_alternate_name_info = -1;
137 static int hf_smb2_file_stream_info = -1;
138 static int hf_smb2_file_pipe_info = -1;
139 static int hf_smb2_file_compression_info = -1;
140 static int hf_smb2_file_network_open_info = -1;
141 static int hf_smb2_file_attribute_tag_info = -1;
142 static int hf_smb2_fs_info_01 = -1;
143 static int hf_smb2_fs_info_03 = -1;
144 static int hf_smb2_fs_info_04 = -1;
145 static int hf_smb2_fs_info_05 = -1;
146 static int hf_smb2_fs_info_06 = -1;
147 static int hf_smb2_fs_info_07 = -1;
148 static int hf_smb2_fs_objectid_info = -1;
149 static int hf_smb2_sec_info_00 = -1;
150 static int hf_smb2_fid = -1;
151 static int hf_smb2_write_length = -1;
152 static int hf_smb2_write_data = -1;
153 static int hf_smb2_write_flags = -1;
154 static int hf_smb2_write_flags_write_through = -1;
155 static int hf_smb2_write_count = -1;
156 static int hf_smb2_write_remaining = -1;
157 static int hf_smb2_read_length = -1;
158 static int hf_smb2_read_remaining = -1;
159 static int hf_smb2_file_offset = -1;
160 static int hf_smb2_read_data = -1;
161 static int hf_smb2_disposition_delete_on_close = -1;
162 static int hf_smb2_create_disposition = -1;
163 static int hf_smb2_create_chain_offset = -1;
164 static int hf_smb2_create_chain_data = -1;
165 static int hf_smb2_data_offset = -1;
166 static int hf_smb2_data_length = -1;
167 static int hf_smb2_extrainfo = -1;
168 static int hf_smb2_create_action = -1;
169 static int hf_smb2_next_offset = -1;
170 static int hf_smb2_ea_size = -1;
171 static int hf_smb2_ea_flags = -1;
172 static int hf_smb2_ea_name_len = -1;
173 static int hf_smb2_ea_data_len = -1;
174 static int hf_smb2_ea_name = -1;
175 static int hf_smb2_ea_data = -1;
176 static int hf_smb2_buffer_code_len = -1;
177 static int hf_smb2_buffer_code_flags_dyn = -1;
178 static int hf_smb2_olb_offset = -1;
179 static int hf_smb2_olb_length = -1;
180 static int hf_smb2_tag = -1;
181 static int hf_smb2_impersonation_level = -1;
182 static int hf_smb2_ioctl_function = -1;
183 static int hf_smb2_ioctl_function_device = -1;
184 static int hf_smb2_ioctl_function_access = -1;
185 static int hf_smb2_ioctl_function_function = -1;
186 static int hf_smb2_ioctl_function_method = -1;
187 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
188 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
189 static int hf_smb2_ioctl_shadow_copy_count = -1;
190 static int hf_smb2_ioctl_shadow_copy_label = -1;
191 static int hf_smb2_compression_format = -1;
192 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
193 static int hf_smb2_acct_name = -1;
194 static int hf_smb2_domain_name = -1;
195 static int hf_smb2_host_name = -1;
196 static int hf_smb2_auth_frame = -1;
197 static int hf_smb2_tcon_frame = -1;
198 static int hf_smb2_share_type = -1;
199 static int hf_smb2_signature = -1;
200 static int hf_smb2_credit_charge = -1;
201 static int hf_smb2_credits_requested = -1;
202 static int hf_smb2_credits_granted = -1;
203 static int hf_smb2_dialect_count = -1;
204 static int hf_smb2_security_mode = -1;
205 static int hf_smb2_secmode_flags_sign_required = -1;
206 static int hf_smb2_secmode_flags_sign_enabled = -1;
207 static int hf_smb2_capabilities = -1;
208 static int hf_smb2_cap_dfs = -1;
209 static int hf_smb2_cap_leasing = -1;
210 static int hf_smb2_cap_large_mtu = -1;
211 static int hf_smb2_dialect = -1;
212 static int hf_smb2_max_trans_size = -1;
213 static int hf_smb2_max_read_size = -1;
214 static int hf_smb2_max_write_size = -1;
215 static int hf_smb2_vcnum = -1;
216 static int hf_smb2_channel = -1;
217 static int hf_smb2_session_flags = -1;
218 static int hf_smb2_ses_flags_guest = -1;
219 static int hf_smb2_ses_flags_null = -1;
220 static int hf_smb2_share_flags = -1;
221 static int hf_smb2_share_flags_dfs = -1;
222 static int hf_smb2_share_flags_dfs_root = -1;
223 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
224 static int hf_smb2_share_flags_force_shared_delete = -1;
225 static int hf_smb2_share_flags_allow_namespace_caching = -1;
226 static int hf_smb2_share_flags_access_based_dir_enum = -1;
227 static int hf_smb2_share_flags_force_levelii_oplock = -1;
228 static int hf_smb2_share_flags_enable_hash = -1;
229 static int hf_smb2_share_caching = -1;
230 static int hf_smb2_share_caps = -1;
231 static int hf_smb2_share_caps_dfs = -1;
232 static int hf_smb2_create_flags = -1;
233 static int hf_smb2_lock_count = -1;
234 static int hf_smb2_min_count = -1;
235 static int hf_smb2_remaining_bytes = -1;
236 static int hf_smb2_channel_info_offset = -1;
237 static int hf_smb2_channel_info_length = -1;
238 static int hf_smb2_ioctl_flags = -1;
239 static int hf_smb2_ioctl_is_fsctl = -1;
240 static int hf_smb2_close_pq_attrib = -1;
241 static int hf_smb2_notify_watch_tree = -1;
242 static int hf_smb2_output_buffer_len = -1;
243 static int hf_smb2_notify_out_data = -1;
244 static int hf_smb2_find_flags = -1;
245 static int hf_smb2_find_flags_restart_scans = -1;
246 static int hf_smb2_find_flags_single_entry = -1;
247 static int hf_smb2_find_flags_index_specified = -1;
248 static int hf_smb2_find_flags_reopen = -1;
249 static int hf_smb2_file_index = -1;
250 static int hf_smb2_file_directory_info = -1;
251 static int hf_smb2_both_directory_info = -1;
252 static int hf_smb2_short_name_len = -1;
253 static int hf_smb2_short_name = -1;
254 static int hf_smb2_id_both_directory_info = -1;
255 static int hf_smb2_full_directory_info = -1;
256 static int hf_smb2_file_name_info = -1;
257 static int hf_smb2_lock_info = -1;
258 static int hf_smb2_lock_length = -1;
259 static int hf_smb2_lock_flags = -1;
260 static int hf_smb2_lock_flags_shared = -1;
261 static int hf_smb2_lock_flags_exclusive = -1;
262 static int hf_smb2_lock_flags_unlock = -1;
263 static int hf_smb2_lock_flags_fail_immediately = -1;
264 static int hf_smb2_dhnq_buffer_reserved = -1;
265 static int hf_smb2_error_byte_count = -1;
266 static int hf_smb2_error_data = -1;
267 static int hf_smb2_error_reserved = -1;
268 static int hf_smb2_reserved = -1;
269
270 static gint ett_smb2 = -1;
271 static gint ett_smb2_olb = -1;
272 static gint ett_smb2_ea = -1;
273 static gint ett_smb2_header = -1;
274 static gint ett_smb2_command = -1;
275 static gint ett_smb2_secblob = -1;
276 static gint ett_smb2_file_basic_info = -1;
277 static gint ett_smb2_file_standard_info = -1;
278 static gint ett_smb2_file_internal_info = -1;
279 static gint ett_smb2_file_ea_info = -1;
280 static gint ett_smb2_file_access_info = -1;
281 static gint ett_smb2_file_position_info = -1;
282 static gint ett_smb2_file_mode_info = -1;
283 static gint ett_smb2_file_alignment_info = -1;
284 static gint ett_smb2_file_all_info = -1;
285 static gint ett_smb2_file_allocation_info = -1;
286 static gint ett_smb2_file_endoffile_info = -1;
287 static gint ett_smb2_file_alternate_name_info = -1;
288 static gint ett_smb2_file_stream_info = -1;
289 static gint ett_smb2_file_pipe_info = -1;
290 static gint ett_smb2_file_compression_info = -1;
291 static gint ett_smb2_file_network_open_info = -1;
292 static gint ett_smb2_file_attribute_tag_info = -1;
293 static gint ett_smb2_file_rename_info = -1;
294 static gint ett_smb2_file_disposition_info = -1;
295 static gint ett_smb2_file_info_0f = -1;
296 static gint ett_smb2_fs_info_01 = -1;
297 static gint ett_smb2_fs_info_03 = -1;
298 static gint ett_smb2_fs_info_04 = -1;
299 static gint ett_smb2_fs_info_05 = -1;
300 static gint ett_smb2_fs_info_06 = -1;
301 static gint ett_smb2_fs_info_07 = -1;
302 static gint ett_smb2_fs_objectid_info = -1;
303 static gint ett_smb2_sec_info_00 = -1;
304 static gint ett_smb2_tid_tree = -1;
305 static gint ett_smb2_sesid_tree = -1;
306 static gint ett_smb2_create_chain_element = -1;
307 static gint ett_smb2_MxAc_buffer = -1;
308 static gint ett_smb2_QFid_buffer = -1;
309 static gint ett_smb2_ioctl_function = -1;
310 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
311 static gint ett_smb2_flags = -1;
312 static gint ett_smb2_sec_mode = -1;
313 static gint ett_smb2_capabilities = -1;
314 static gint ett_smb2_ses_flags = -1;
315 static gint ett_smb2_share_flags = -1;
316 static gint ett_smb2_share_caps = -1;
317 static gint ett_smb2_ioctl_flags = -1;
318 static gint ett_smb2_close_flags = -1;
319 static gint ett_smb2_notify_flags = -1;
320 static gint ett_smb2_write_flags = -1;
321 static gint ett_smb2_find_flags = -1;
322 static gint ett_smb2_file_directory_info = -1;
323 static gint ett_smb2_both_directory_info = -1;
324 static gint ett_smb2_id_both_directory_info = -1;
325 static gint ett_smb2_full_directory_info = -1;
326 static gint ett_smb2_file_name_info = -1;
327 static gint ett_smb2_lock_info = -1;
328 static gint ett_smb2_lock_flags = -1;
329
330 static int smb2_tap = -1;
331
332 static dissector_handle_t gssapi_handle = NULL;
333 static dissector_handle_t ntlmssp_handle = NULL;
334
335 static heur_dissector_list_t smb2_heur_subdissector_list;
336
337 #define SMB2_CLASS_FILE_INFO    0x01
338 #define SMB2_CLASS_FS_INFO      0x02
339 #define SMB2_CLASS_SEC_INFO     0x03
340 static const value_string smb2_class_vals[] = {
341         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
342         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
343         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
344         { 0, NULL }
345 };
346
347 #define SMB2_SHARE_TYPE_DISK    0x01
348 #define SMB2_SHARE_TYPE_PIPE    0x02
349 #define SMB2_SHARE_TYPE_PRINT   0x03
350 static const value_string smb2_share_type_vals[] = {
351         { SMB2_SHARE_TYPE_DISK,         "Physical disk" },
352         { SMB2_SHARE_TYPE_PIPE,         "Named pipe" },
353         { SMB2_SHARE_TYPE_PRINT,        "Printer" },
354         { 0, NULL }
355 };
356
357
358 #define SMB2_FILE_BASIC_INFO    0x04
359 #define SMB2_FILE_STANDARD_INFO 0x05
360 #define SMB2_FILE_INTERNAL_INFO 0x06
361 #define SMB2_FILE_EA_INFO       0x07
362 #define SMB2_FILE_ACCESS_INFO   0x08
363 #define SMB2_FILE_RENAME_INFO   0x0a
364 #define SMB2_FILE_DISPOSITION_INFO      0x0d
365 #define SMB2_FILE_POSITION_INFO 0x0e
366 #define SMB2_FILE_INFO_0f       0x0f
367 #define SMB2_FILE_MODE_INFO     0x10
368 #define SMB2_FILE_ALIGNMENT_INFO        0x11
369 #define SMB2_FILE_ALL_INFO      0x12
370 #define SMB2_FILE_ALLOCATION_INFO       0x13
371 #define SMB2_FILE_ENDOFFILE_INFO        0x14
372 #define SMB2_FILE_ALTERNATE_NAME_INFO   0x15
373 #define SMB2_FILE_STREAM_INFO           0x16
374 #define SMB2_FILE_PIPE_INFO             0x17
375 #define SMB2_FILE_COMPRESSION_INFO      0x1c
376 #define SMB2_FILE_NETWORK_OPEN_INFO     0x22
377 #define SMB2_FILE_ATTRIBUTE_TAG_INFO    0x23
378 static const value_string smb2_file_info_levels[] = {
379         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
380         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
381         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
382         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
383         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
384         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
385         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
386         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
387         {SMB2_FILE_INFO_0f,             "SMB2_FILE_INFO_0f" },
388         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
389         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
390         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
391         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
392         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
393         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
394         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
395         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
396         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
397         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
398         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
399         { 0, NULL }
400 };
401
402
403
404 #define SMB2_FS_INFO_01         0x01
405 #define SMB2_FS_INFO_03         0x03
406 #define SMB2_FS_INFO_04         0x04
407 #define SMB2_FS_INFO_05         0x05
408 #define SMB2_FS_INFO_06         0x06
409 #define SMB2_FS_INFO_07         0x07
410 #define SMB2_FS_OBJECTID_INFO   0x08
411 static const value_string smb2_fs_info_levels[] = {
412         {SMB2_FS_INFO_01,       "SMB2_FS_INFO_01" },
413         {SMB2_FS_INFO_03,       "SMB2_FS_INFO_03" },
414         {SMB2_FS_INFO_04,       "SMB2_FS_INFO_04" },
415         {SMB2_FS_INFO_05,       "SMB2_FS_INFO_05" },
416         {SMB2_FS_INFO_06,       "SMB2_FS_INFO_06" },
417         {SMB2_FS_INFO_07,       "SMB2_FS_INFO_07" },
418         {SMB2_FS_OBJECTID_INFO, "SMB2_FS_OBJECTID_INFO" },
419         { 0, NULL }
420 };
421
422 #define SMB2_SEC_INFO_00        0x00
423 static const value_string smb2_sec_info_levels[] = {
424         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
425         { 0, NULL }
426 };
427
428 #define SMB2_FIND_DIRECTORY_INFO         0x01
429 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
430 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
431 #define SMB2_FIND_INDEX_SPECIFIED        0x04
432 #define SMB2_FIND_NAME_INFO              0x0C
433 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
434 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
435 static const value_string smb2_find_info_levels[] = {
436         { SMB2_FIND_DIRECTORY_INFO,             "SMB2_FIND_DIRECTORY_INFO" },
437         { SMB2_FIND_FULL_DIRECTORY_INFO,        "SMB2_FIND_FULL_DIRECTORY_INFO" },
438         { SMB2_FIND_BOTH_DIRECTORY_INFO,        "SMB2_FIND_BOTH_DIRECTORY_INFO" },
439         { SMB2_FIND_INDEX_SPECIFIED,            "SMB2_FIND_INDEX_SPECIFIED" },
440         { SMB2_FIND_NAME_INFO,                  "SMB2_FIND_NAME_INFO" },
441         { SMB2_FIND_ID_BOTH_DIRECTORY_INFO,     "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
442         { SMB2_FIND_ID_FULL_DIRECTORY_INFO,     "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
443         { 0, NULL }
444 };
445
446 /* unmatched smb_saved_info structures.
447    For unmatched smb_saved_info structures we store the smb_saved_info
448    structure using the SEQNUM field.
449 */
450 static gint
451 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
452 {
453         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
454         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
455         return key1->seqnum==key2->seqnum;
456 }
457 static guint
458 smb2_saved_info_hash_unmatched(gconstpointer k)
459 {
460         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
461         guint32 hash;
462
463         hash=(guint32) (key->seqnum&0xffffffff);
464         return hash;
465 }
466
467 /* matched smb_saved_info structures.
468    For matched smb_saved_info structures we store the smb_saved_info
469    structure using the SEQNUM field.
470 */
471 static gint
472 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
473 {
474         smb2_saved_info_t *key1 = (smb2_saved_info_t *)k1;
475         smb2_saved_info_t *key2 = (smb2_saved_info_t *)k2;
476         return key1->seqnum==key2->seqnum;
477 }
478 static guint
479 smb2_saved_info_hash_matched(gconstpointer k)
480 {
481         smb2_saved_info_t *key = (smb2_saved_info_t *)k;
482         guint32 hash;
483
484         hash=(guint32) (key->seqnum&0xffffffff);
485         return hash;
486 }
487
488 /* For Tids of a specific conversation.
489    This keeps track of tid->sharename mappings and other information about the
490    tid.
491    qqq
492    We might need to refine this if it occurs that tids are reused on a single
493    conversation.   we dont worry about that yet for simplicity
494 */
495 static gint
496 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
497 {
498         smb2_tid_info_t *key1 = (smb2_tid_info_t *)k1;
499         smb2_tid_info_t *key2 = (smb2_tid_info_t *)k2;
500         return key1->tid==key2->tid;
501 }
502 static guint
503 smb2_tid_info_hash(gconstpointer k)
504 {
505         smb2_tid_info_t *key = (smb2_tid_info_t *)k;
506         guint32 hash;
507
508         hash=key->tid;
509         return hash;
510 }
511
512 /* For Uids of a specific conversation.
513    This keeps track of uid->acct_name mappings and other information about the
514    uid.
515    qqq
516    We might need to refine this if it occurs that uids are reused on a single
517    conversation.   we dont worry about that yet for simplicity
518 */
519 static gint
520 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
521 {
522         smb2_sesid_info_t *key1 = (smb2_sesid_info_t *)k1;
523         smb2_sesid_info_t *key2 = (smb2_sesid_info_t *)k2;
524         return key1->sesid==key2->sesid;
525 }
526 static guint
527 smb2_sesid_info_hash(gconstpointer k)
528 {
529         smb2_sesid_info_t *key = (smb2_sesid_info_t *)k;
530         guint32 hash;
531
532         hash=(guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
533         return hash;
534 }
535
536 static int dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
537
538
539 /* This is a helper to dissect the common string type
540  * uint16 offset
541  * uint16 length
542  * ...
543  * char *string
544  *
545  * This function is called twice, first to decode the offset/length and
546  * second time to dissect the actual string.
547  * It is done this way since there is no guarantee that we have the full packet and we dont
548  * want to abort dissection too early if the packet ends somewhere between the
549  * length/offset and the actual buffer.
550  *
551  */
552 enum offset_length_buffer_offset_size {
553         OLB_O_UINT16_S_UINT16,
554         OLB_O_UINT16_S_UINT32,
555         OLB_O_UINT32_S_UINT32,
556         OLB_S_UINT32_O_UINT32
557 };
558 typedef struct _offset_length_buffer_t {
559         guint32 off;
560         guint32 len;
561         int off_offset;
562         int len_offset;
563         enum offset_length_buffer_offset_size offset_size;
564         int hfindex;
565 } offset_length_buffer_t;
566 static int
567 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
568                                enum offset_length_buffer_offset_size offset_size, int hfindex)
569 {
570         olb->hfindex=hfindex;
571         olb->offset_size=offset_size;
572         switch(offset_size){
573         case OLB_O_UINT16_S_UINT16:
574                 olb->off=tvb_get_letohs(tvb, offset);
575                 olb->off_offset=offset;
576                 offset += 2;
577                 olb->len=tvb_get_letohs(tvb, offset);
578                 olb->len_offset=offset;
579                 offset += 2;
580                 break;
581         case OLB_O_UINT16_S_UINT32:
582                 olb->off=tvb_get_letohs(tvb, offset);
583                 olb->off_offset=offset;
584                 offset += 2;
585                 olb->len=tvb_get_letohl(tvb, offset);
586                 olb->len_offset=offset;
587                 offset += 4;
588                 break;
589         case OLB_O_UINT32_S_UINT32:
590                 olb->off=tvb_get_letohl(tvb, offset);
591                 olb->off_offset=offset;
592                 offset += 4;
593                 olb->len=tvb_get_letohl(tvb, offset);
594                 olb->len_offset=offset;
595                 offset += 4;
596                 break;
597         case OLB_S_UINT32_O_UINT32:
598                 olb->len=tvb_get_letohl(tvb, offset);
599                 olb->len_offset=offset;
600                 offset += 4;
601                 olb->off=tvb_get_letohl(tvb, offset);
602                 olb->off_offset=offset;
603                 offset += 4;
604                 break;
605         }
606
607         return offset;
608 }
609
610 #define OLB_TYPE_UNICODE_STRING         0x01
611 #define OLB_TYPE_ASCII_STRING           0x02
612 static const char *
613 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
614 {
615         int len, off;
616         proto_item *item=NULL;
617         proto_tree *tree=NULL;
618         const char *name=NULL;
619         guint16 bc;
620         int offset;
621
622         offset=olb->off;
623         len=olb->len;
624         off=olb->off;
625         bc=tvb_length_remaining(tvb, offset);
626
627
628         /* sanity check */
629         tvb_ensure_bytes_exist(tvb, off, len);
630         if(((off+len)<off)
631         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
632                 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
633                                     "Invalid offset/length. Malformed packet");
634
635                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
636
637                 return NULL;
638         }
639
640
641         switch(type){
642         case OLB_TYPE_UNICODE_STRING:
643                 name = get_unicode_or_ascii_string(tvb, &off,
644                         TRUE, &len, TRUE, TRUE, &bc);
645                 if(!name){
646                         name="";
647                 }
648                 if(parent_tree){
649                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
650                         tree = proto_item_add_subtree(item, ett_smb2_olb);
651                 }
652                 break;
653         case OLB_TYPE_ASCII_STRING:
654                 name = get_unicode_or_ascii_string(tvb, &off,
655                         FALSE, &len, TRUE, TRUE, &bc);
656                 if(!name){
657                         name="";
658                 }
659                 if(parent_tree){
660                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
661                         tree = proto_item_add_subtree(item, ett_smb2_olb);
662                 }
663                 break;
664         }
665
666         switch(olb->offset_size){
667         case OLB_O_UINT16_S_UINT16:
668                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
669                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
670                 break;
671         case OLB_O_UINT16_S_UINT32:
672                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
673                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
674                 break;
675         case OLB_O_UINT32_S_UINT32:
676                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
677                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
678                 break;
679         case OLB_S_UINT32_O_UINT32:
680                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
681                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
682                 break;
683         }
684
685         return name;
686 }
687
688 static void
689 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
690                         offset_length_buffer_t *olb, smb2_info_t *si,
691                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
692 {
693         int len, off;
694         proto_item *sub_item=NULL;
695         proto_tree *sub_tree=NULL;
696         tvbuff_t *sub_tvb=NULL;
697         guint16 bc;
698         int offset;
699
700         offset=olb->off;
701         len=olb->len;
702         off=olb->off;
703         bc=tvb_length_remaining(tvb, offset);
704
705         /* sanity check */
706         tvb_ensure_bytes_exist(tvb, off, len);
707         if(((off+len)<off)
708         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))){
709                 proto_tree_add_text(parent_tree, tvb, offset, tvb_length_remaining(tvb, offset),
710                                     "Invalid offset/length. Malformed packet");
711
712                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
713
714                 return;
715         }
716
717         /* if we dont want/need a subtree */
718         if(olb->hfindex==-1){
719                 sub_item=parent_tree;
720                 sub_tree=parent_tree;
721         } else {
722                 if(parent_tree){
723                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, TRUE);
724                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
725                 }
726         }
727
728         switch(olb->offset_size){
729         case OLB_O_UINT16_S_UINT16:
730                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
731                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, TRUE);
732                 break;
733         case OLB_O_UINT16_S_UINT32:
734                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, TRUE);
735                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
736                 break;
737         case OLB_O_UINT32_S_UINT32:
738                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
739                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
740                 break;
741         case OLB_S_UINT32_O_UINT32:
742                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, TRUE);
743                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, TRUE);
744                 break;
745         }
746
747         if (off == 0 || len == 0) {
748                 proto_item_append_text(sub_item, ": NO DATA");
749                 return;
750         }
751
752         if (!dissector) {
753                 return;
754         }
755
756         sub_tvb=tvb_new_subset(tvb, off, MIN((int)len, tvb_length_remaining(tvb, off)), len);
757
758         dissector(sub_tvb, pinfo, sub_tree, si);
759
760         return;
761 }
762
763 static int
764 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
765 {
766         if (olb->off == 0) {
767                 return offset;
768         }
769         return MAX(offset, (int)(olb->off + olb->len));
770 }
771
772 typedef struct _smb2_function {
773        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
774        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
775 } smb2_function;
776
777 static const true_false_string tfs_flags_response = {
778         "This is a RESPONSE",
779         "This is a REQUEST"
780 };
781
782 static const true_false_string tfs_flags_async_cmd = {
783         "This is an ASYNC command",
784         "This is a SYNC command"
785 };
786
787 static const true_false_string tfs_flags_dfs_op = {
788         "This is a DFS OPERATION",
789         "This is a normal operation"
790 };
791
792 static const true_false_string tfs_flags_chained = {
793         "This pdu a CHAINED command",
794         "This pdu is NOT a chained command"
795 };
796
797 static const true_false_string tfs_flags_signature = {
798         "This pdu is SIGNED",
799         "This pdu is NOT signed"
800 };
801
802 static const true_false_string tfs_cap_dfs = {
803         "This host supports DFS",
804         "This host does NOT support DFS"
805 };
806
807 static const true_false_string tfs_cap_leasing = {
808         "This host supports LEASING",
809         "This host does NOT support LEASING"
810 };
811
812 static const true_false_string tfs_cap_large_mtu = {
813         "This host supports LARGE_MTU",
814         "This host does NOT support LARGE_MTU"
815 };
816
817 static const value_string compression_format_vals[] = {
818   { 0, "COMPRESSION_FORMAT_NONE" },
819   { 1, "COMPRESSION_FORMAT_DEFAULT" },
820   { 2, "COMPRESSION_FORMAT_LZNT1" },
821   { 0, NULL }
822 };
823
824
825 static const value_string smb2_ioctl_vals[] = {
826   /* dissector implemented */
827   {0x0011c017, "IOCTL_DO_DCERPC"},
828   {0x00144064, "FSCTL_GET_SHADOW_COPY_DATA"},
829   {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},
830   {0x0009009C, "FSCTL_GET_OBJECT_ID"},
831   {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
832   {0x00098098, "FSCTL_SET_OBJECT_ID"},
833   {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},
834   {0x0009003C, "FSCTL_GET_COMPRESSION"},
835   {0x0009C040, "FSCTL_SET_COMPRESSION"},
836
837   /* dissector not yet implemented */
838   {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
839   {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
840   {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
841   {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
842   {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
843   {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
844   {0x00090018, "FSCTL_LOCK_VOLUME"},
845   {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
846   {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
847   {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
848   {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
849   {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
850   {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
851   {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
852   {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
853   {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
854   {0x00090058, "FSCTL_QUERY_FAT_BPB"},
855   {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
856   {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
857   {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
858   {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
859   {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
860   {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
861   {0x00090074, "FSCTL_MOVE_FILE"},
862   {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
863   {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
864   {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
865   {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
866   {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
867   {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
868   {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
869   {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
870   {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
871   {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
872   {0x000940B3, "FSCTL_ENUM_USN_DATA"},
873   {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
874   {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
875   {0x000980C4, "FSCTL_SET_SPARSE"},
876   {0x000980C8, "FSCTL_SET_ZERO_DATA"},
877   {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},
878   {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
879   {0x000900D4, "FSCTL_SET_ENCRYPTION"},
880   {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
881   {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
882   {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
883   {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
884   {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
885   {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
886   {0x000900F0, "FSCTL_EXTEND_VOLUME"},
887   { 0, NULL }
888 };
889
890
891 static const value_string smb2_ioctl_device_vals[] = {
892   { 0x0001, "BEEP" },
893   { 0x0002, "CD_ROM" },
894   { 0x0003, "CD_ROM_FILE_SYSTEM" },
895   { 0x0004, "CONTROLLER" },
896   { 0x0005, "DATALINK" },
897   { 0x0006, "DFS" },
898   { 0x0007, "DISK" },
899   { 0x0008, "DISK_FILE_SYSTEM" },
900   { 0x0009, "FILE_SYSTEM" },
901   { 0x000a, "INPORT_PORT" },
902   { 0x000b, "KEYBOARD" },
903   { 0x000c, "MAILSLOT" },
904   { 0x000d, "MIDI_IN" },
905   { 0x000e, "MIDI_OUT" },
906   { 0x000f, "MOUSE" },
907   { 0x0010, "MULTI_UNC_PROVIDER" },
908   { 0x0011, "NAMED_PIPE" },
909   { 0x0012, "NETWORK" },
910   { 0x0013, "NETWORK_BROWSER" },
911   { 0x0014, "NETWORK_FILE_SYSTEM" },
912   { 0x0015, "NULL" },
913   { 0x0016, "PARALLEL_PORT" },
914   { 0x0017, "PHYSICAL_NETCARD" },
915   { 0x0018, "PRINTER" },
916   { 0x0019, "SCANNER" },
917   { 0x001a, "SERIAL_MOUSE_PORT" },
918   { 0x001b, "SERIAL_PORT" },
919   { 0x001c, "SCREEN" },
920   { 0x001d, "SOUND" },
921   { 0x001e, "STREAMS" },
922   { 0x001f, "TAPE" },
923   { 0x0020, "TAPE_FILE_SYSTEM" },
924   { 0x0021, "TRANSPORT" },
925   { 0x0022, "UNKNOWN" },
926   { 0x0023, "VIDEO" },
927   { 0x0024, "VIRTUAL_DISK" },
928   { 0x0025, "WAVE_IN" },
929   { 0x0026, "WAVE_OUT" },
930   { 0x0027, "8042_PORT" },
931   { 0x0028, "NETWORK_REDIRECTOR" },
932   { 0x0029, "BATTERY" },
933   { 0x002a, "BUS_EXTENDER" },
934   { 0x002b, "MODEM" },
935   { 0x002c, "VDM" },
936   { 0x002d, "MASS_STORAGE" },
937   { 0x002e, "SMB" },
938   { 0x002f, "KS" },
939   { 0x0030, "CHANGER" },
940   { 0x0031, "SMARTCARD" },
941   { 0x0032, "ACPI" },
942   { 0x0033, "DVD" },
943   { 0x0034, "FULLSCREEN_VIDEO" },
944   { 0x0035, "DFS_FILE_SYSTEM" },
945   { 0x0036, "DFS_VOLUME" },
946   { 0x0037, "SERENUM" },
947   { 0x0038, "TERMSRV" },
948   { 0x0039, "KSEC" },
949   { 0, NULL }
950 };
951
952 static const value_string smb2_ioctl_access_vals[] = {
953   { 0x00, "FILE_ANY_ACCESS" },
954   { 0x01, "FILE_READ_ACCESS" },
955   { 0x02, "FILE_WRITE_ACCESS" },
956   { 0x03, "FILE_READ_WRITE_ACCESS" },
957   { 0, NULL }
958 };
959
960 static const value_string smb2_ioctl_method_vals[] = {
961   { 0x00, "METHOD_BUFFERED" },
962   { 0x01, "METHOD_IN_DIRECT" },
963   { 0x02, "METHOD_OUT_DIRECT" },
964   { 0x03, "METHOD_NEITHER" },
965   { 0, NULL }
966 };
967
968 /* this is called from both smb and smb2. */
969 int
970 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
971 {
972         proto_item *item=NULL;
973         proto_tree *tree=NULL;
974         guint32 ioctl_function;
975
976         if(parent_tree){
977                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, TRUE);
978                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
979         }
980
981         ioctl_function=tvb_get_letohl(tvb, offset);
982         if (ioctlfunc)
983                 *ioctlfunc=ioctl_function;
984         if(ioctl_function){
985                 /* device */
986                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, TRUE);
987                 if (check_col(pinfo->cinfo, COL_INFO)){
988                         col_append_fstr(
989                                 pinfo->cinfo, COL_INFO, " %s",
990                                 val_to_str((ioctl_function>>16)&0xffff, smb2_ioctl_device_vals,
991                                 "Unknown (0x%08X)"));
992                 }
993
994                 /* access */
995                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, TRUE);
996
997                 /* function */
998                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, TRUE);
999                 if (check_col(pinfo->cinfo, COL_INFO)){
1000                         col_append_fstr(
1001                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
1002                                 (ioctl_function>>2)&0x0fff);
1003                 }
1004
1005                 /* method */
1006                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, TRUE);
1007         }
1008
1009         offset += 4;
1010
1011         return offset;
1012 }
1013
1014 /* fake the dce/rpc support structures so we can piggy back on
1015  * dissect_nt_policy_hnd()   since this will allow us
1016  * a cheap way to track where FIDs are opened, closed
1017  * and fid->filename mappings
1018  * if we want to do those things in the future.
1019  */
1020 #define FID_MODE_OPEN           0
1021 #define FID_MODE_CLOSE          1
1022 #define FID_MODE_USE            2
1023 #define FID_MODE_DHNQ           3
1024 #define FID_MODE_DHNC           4
1025 static int
1026 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
1027 {
1028         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1029         static dcerpc_info di;  /* fake dcerpc_info struct */
1030         static dcerpc_call_value call_data;
1031         void *old_private_data;
1032         e_ctx_hnd policy_hnd;
1033         proto_item *hnd_item=NULL;
1034         char *fid_name;
1035         guint32 open_frame = 0, close_frame = 0;
1036
1037         di.conformant_run=0;
1038         /* we need di->call_data->flags.NDR64 == 0 */
1039         di.call_data=&call_data;
1040         old_private_data=pinfo->private_data;
1041         pinfo->private_data=&di;
1042
1043         switch(mode){
1044         case FID_MODE_OPEN:
1045                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1046                 if(!pinfo->fd->flags.visited){
1047                         if(si->saved && si->saved->extra_info_type==SMB2_EI_FILENAME){
1048                                 fid_name = se_strdup_printf("File: %s", (char *)si->saved->extra_info);
1049                         } else {
1050                                 fid_name = se_strdup_printf("File: ");
1051                         }
1052                         dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1053                                                   fid_name);
1054                 }
1055                 break;
1056         case FID_MODE_CLOSE:
1057                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
1058                 break;
1059         case FID_MODE_USE:
1060         case FID_MODE_DHNQ:
1061         case FID_MODE_DHNC:
1062                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
1063                 break;
1064         }
1065
1066         pinfo->private_data=old_private_data;
1067
1068
1069         /* put the filename in col_info */
1070         if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num)) {
1071                 if(fid_name){
1072                         if(hnd_item){
1073                                 proto_item_append_text(hnd_item, " %s", fid_name);
1074                         }
1075                         if (check_col(pinfo->cinfo, COL_INFO)){
1076                                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", fid_name);
1077                         }
1078                 }
1079         }
1080
1081         return offset;
1082 }
1083
1084
1085 /* this info level is unique to SMB2 and differst from the corresponding
1086  * SMB_FILE_ALL_INFO in SMB
1087  */
1088 static int
1089 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1090 {
1091         proto_item *item=NULL;
1092         proto_tree *tree=NULL;
1093         int length;
1094         const char *name="";
1095         guint16 bc;
1096
1097         if(parent_tree){
1098                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, TRUE);
1099                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
1100         }
1101
1102         /* create time */
1103         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1104
1105         /* last access */
1106         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1107
1108         /* last write */
1109         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1110
1111         /* last change */
1112         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1113
1114         /* File Attributes */
1115         offset = dissect_file_ext_attr(tvb, tree, offset);
1116
1117         /* some unknown bytes */
1118         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1119         offset += 4;
1120
1121         /* allocation size */
1122         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
1123         offset += 8;
1124
1125         /* end of file */
1126         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
1127         offset += 8;
1128
1129         /* number of links */
1130         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, TRUE);
1131         offset += 4;
1132
1133         /* delete pending */
1134         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, TRUE);
1135         offset += 1;
1136
1137         /* is directory */
1138         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, TRUE);
1139         offset += 1;
1140
1141         /* padding */
1142         offset += 2;
1143
1144         /* file id */
1145         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
1146         offset += 8;
1147
1148         /* ea size */
1149         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
1150         offset += 4;
1151
1152         /* access mask */
1153         offset = dissect_smb_access_mask(tvb, tree, offset);
1154
1155         /* some unknown bytes */
1156         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1157         offset += 16;
1158
1159         /* file name length */
1160         length=tvb_get_letohs(tvb, offset);
1161         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1162         offset += 2;
1163
1164         /* some unknown bytes */
1165         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1166         offset += 2;
1167
1168         /* file name */
1169         if(length){
1170                 bc=tvb_length_remaining(tvb, offset);
1171                 name = get_unicode_or_ascii_string(tvb, &offset,
1172                         TRUE, &length, TRUE, TRUE, &bc);
1173                 if(name){
1174                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1175                                 offset, length, name);
1176                 }
1177
1178         }
1179         offset += length;
1180
1181
1182         return offset;
1183 }
1184
1185
1186 static int
1187 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1188 {
1189         proto_item *item=NULL;
1190         proto_tree *tree=NULL;
1191         guint16 bc;
1192         gboolean trunc;
1193
1194         if(parent_tree){
1195                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, TRUE);
1196                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1197         }
1198
1199         bc=tvb_length_remaining(tvb, offset);
1200         offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1201
1202         return offset;
1203 }
1204
1205 static int
1206 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1207 {
1208         proto_item *item=NULL;
1209         proto_tree *tree=NULL;
1210         guint16 bc;
1211         gboolean trunc;
1212
1213         if(parent_tree){
1214                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, TRUE);
1215                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1216         }
1217
1218         bc=tvb_length_remaining(tvb, offset);
1219         offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1220
1221         return offset;
1222 }
1223
1224 static int
1225 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1226 {
1227         proto_item *item=NULL;
1228         proto_tree *tree=NULL;
1229         guint16 bc;
1230         gboolean trunc;
1231
1232         if(parent_tree){
1233                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, TRUE);
1234                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1235         }
1236
1237         bc=tvb_length_remaining(tvb, offset);
1238         offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1239
1240         return offset;
1241 }
1242
1243
1244 static int
1245 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1246 {
1247         proto_item *item=NULL;
1248         proto_tree *tree=NULL;
1249
1250         if(parent_tree){
1251                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, TRUE);
1252                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1253         }
1254
1255         /* create time */
1256         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1257
1258         /* last access */
1259         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1260
1261         /* last write */
1262         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1263
1264         /* last change */
1265         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1266
1267         /* File Attributes */
1268         offset = dissect_file_ext_attr(tvb, tree, offset);
1269
1270         /* some unknown bytes */
1271         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1272         offset += 4;
1273
1274         return offset;
1275 }
1276
1277 static int
1278 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1279 {
1280         proto_item *item=NULL;
1281         proto_tree *tree=NULL;
1282         guint16 bc;
1283         gboolean trunc;
1284
1285         if(parent_tree){
1286                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, TRUE);
1287                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
1288         }
1289
1290         bc=tvb_length_remaining(tvb, offset);
1291         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1292
1293         return offset;
1294 }
1295 static int
1296 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1297 {
1298         proto_item *item=NULL;
1299         proto_tree *tree=NULL;
1300         guint16 bc;
1301         gboolean trunc;
1302
1303         if(parent_tree){
1304                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, TRUE);
1305                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
1306         }
1307
1308         bc=tvb_length_remaining(tvb, offset);
1309         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1310
1311         return offset;
1312 }
1313 static int
1314 dissect_smb2_file_mode_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_mode_info, tvb, offset, -1, TRUE);
1323                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
1324         }
1325
1326         bc=tvb_length_remaining(tvb, offset);
1327         offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1328
1329         return offset;
1330 }
1331 static int
1332 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1333 {
1334         proto_item *item=NULL;
1335         proto_tree *tree=NULL;
1336         guint16 bc;
1337         gboolean trunc;
1338
1339         if(parent_tree){
1340                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, TRUE);
1341                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
1342         }
1343
1344         bc=tvb_length_remaining(tvb, offset);
1345         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1346
1347         return offset;
1348 }
1349 static int
1350 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1351 {
1352         proto_item *item=NULL;
1353         proto_tree *tree=NULL;
1354         guint16 bc;
1355         gboolean trunc;
1356
1357         if(parent_tree){
1358                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, TRUE);
1359                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
1360         }
1361
1362         bc=tvb_length_remaining(tvb, offset);
1363         offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1364
1365         return offset;
1366 }
1367
1368 static int
1369 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1370 {
1371         proto_item *item=NULL;
1372         proto_tree *tree=NULL;
1373
1374         if(parent_tree){
1375                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, TRUE);
1376                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
1377         }
1378
1379         /* access mask */
1380         offset = dissect_smb_access_mask(tvb, tree, offset);
1381
1382         return offset;
1383 }
1384
1385 static int
1386 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1387 {
1388         proto_item *item=NULL;
1389         proto_tree *tree=NULL;
1390         guint16 bc;
1391         gboolean trunc;
1392
1393         if(parent_tree){
1394                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, TRUE);
1395                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
1396         }
1397
1398         bc=tvb_length_remaining(tvb, offset);
1399         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1400
1401         return offset;
1402 }
1403
1404 static int
1405 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1406 {
1407         proto_item *item=NULL;
1408         proto_tree *tree=NULL;
1409         guint16 bc;
1410         gboolean trunc;
1411
1412         if(parent_tree){
1413                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, TRUE);
1414                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
1415         }
1416
1417         bc=tvb_length_remaining(tvb, offset);
1418         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
1419
1420         return offset;
1421 }
1422
1423 static int
1424 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1425 {
1426         proto_item *item=NULL;
1427         proto_tree *tree=NULL;
1428         guint16 bc;
1429         gboolean trunc;
1430
1431         if(parent_tree){
1432                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, TRUE);
1433                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
1434         }
1435
1436         bc=tvb_length_remaining(tvb, offset);
1437         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1438
1439         return offset;
1440 }
1441
1442 static int
1443 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1444 {
1445         proto_item *item=NULL;
1446         proto_tree *tree=NULL;
1447         guint16 bc;
1448         gboolean trunc;
1449
1450         if(parent_tree){
1451                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, TRUE);
1452                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
1453         }
1454
1455         bc=tvb_length_remaining(tvb, offset);
1456         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1457
1458         return offset;
1459 }
1460
1461 static int
1462 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1463 {
1464         proto_item *item=NULL;
1465         proto_tree *tree=NULL;
1466         guint16 bc;
1467         gboolean trunc;
1468
1469         if(parent_tree){
1470                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, TRUE);
1471                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
1472         }
1473
1474
1475         bc=tvb_length_remaining(tvb, offset);
1476         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1477
1478         return offset;
1479 }
1480
1481 static int
1482 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1483 {
1484         proto_item *item=NULL;
1485         proto_tree *tree=NULL;
1486         guint16 bc;
1487         gboolean trunc;
1488
1489         if(parent_tree){
1490                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, TRUE);
1491                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
1492         }
1493
1494
1495         bc=tvb_length_remaining(tvb, offset);
1496         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1497
1498         return offset;
1499 }
1500
1501 static const true_false_string tfs_disposition_delete_on_close = {
1502         "DELETE this file when closed",
1503         "Normal access, do not delete on close"
1504 };
1505
1506 static int
1507 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1508 {
1509         proto_item *item=NULL;
1510         proto_tree *tree=NULL;
1511
1512         if(parent_tree){
1513                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, TRUE);
1514                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
1515         }
1516
1517         /* file disposition */
1518         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, TRUE);
1519
1520         return offset;
1521 }
1522
1523 static int
1524 dissect_smb2_file_info_0f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1525 {
1526         proto_item *item=NULL;
1527         proto_tree *tree=NULL;
1528         guint32 next_offset;
1529         guint8 ea_name_len, ea_data_len;
1530
1531         if(parent_tree){
1532                 item = proto_tree_add_item(parent_tree, hf_smb2_file_info_0f, tvb, offset, -1, TRUE);
1533                 tree = proto_item_add_subtree(item, ett_smb2_file_info_0f);
1534         }
1535
1536         while(1){
1537                 int length;
1538                 const char *name="";
1539                 const char *data="";
1540                 guint16 bc;
1541                 int start_offset=offset;
1542                 proto_item *ea_item=NULL;
1543                 proto_tree *ea_tree=NULL;
1544
1545                 if(tree){
1546                         ea_item = proto_tree_add_text(tree, tvb, offset, -1, "EA:");
1547                         ea_tree = proto_item_add_subtree(ea_item, ett_smb2_ea);
1548                 }
1549
1550                 /* next offset */
1551                 next_offset=tvb_get_letohl(tvb, offset);
1552                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
1553                 offset += 4;
1554
1555                 /* EA flags */
1556                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, TRUE);
1557                 offset += 1;
1558
1559                 /* EA Name Length */
1560                 ea_name_len=tvb_get_guint8(tvb, offset);
1561                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, TRUE);
1562                 offset += 1;
1563
1564                 /* EA Data Length */
1565                 ea_data_len=tvb_get_guint8(tvb, offset);
1566                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 1, TRUE);
1567                 offset += 1;
1568
1569                 /* some unknown bytes */
1570                 proto_tree_add_item(ea_tree, hf_smb2_unknown, tvb, offset, 1, TRUE);
1571                 offset += 1;
1572
1573                 /* ea name */
1574                 length=ea_name_len;
1575                 if(length){
1576                         bc=tvb_length_remaining(tvb, offset);
1577                         name = get_unicode_or_ascii_string(tvb, &offset,
1578                                 FALSE, &length, TRUE, TRUE, &bc);
1579                         if(name){
1580                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
1581                                         offset, length, name);
1582                         }
1583                 }
1584                 offset += ea_name_len;
1585
1586                 /* separator byte */
1587                 offset += 1;
1588
1589                 /* ea data */
1590                 length=ea_data_len;
1591                 if(length){
1592                         bc=tvb_length_remaining(tvb, offset);
1593                         data = get_unicode_or_ascii_string(tvb, &offset,
1594                                 FALSE, &length, TRUE, TRUE, &bc);
1595                         if(data){
1596                                 proto_tree_add_string(ea_tree, hf_smb2_ea_data, tvb,
1597                                         offset, length, data);
1598                         }
1599                 }
1600                 offset += ea_data_len;
1601
1602
1603                 if(ea_item){
1604                         proto_item_append_text(ea_item, " %s := %s", name, data);
1605                 }
1606                 proto_item_set_len(ea_item, offset-start_offset);
1607
1608
1609                 if(!next_offset){
1610                         break;
1611                 }
1612                 if(next_offset>256){
1613                         break;
1614                 }
1615
1616                 offset = start_offset+next_offset;
1617         }
1618
1619         return offset;
1620 }
1621
1622 static int
1623 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1624 {
1625         proto_item *item=NULL;
1626         proto_tree *tree=NULL;
1627         int length;
1628         const char *name="";
1629         guint16 bc;
1630
1631
1632         if(parent_tree){
1633                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, TRUE);
1634                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
1635         }
1636
1637         /* some unknown bytes */
1638         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, FALSE);
1639         offset += 16;
1640
1641         /* file name length */
1642         length=tvb_get_letohs(tvb, offset);
1643         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, TRUE);
1644         offset += 2;
1645
1646         /* some unknown bytes */
1647         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, FALSE);
1648         offset += 2;
1649
1650         /* file name */
1651         if(length){
1652                 bc=tvb_length_remaining(tvb, offset);
1653                 name = get_unicode_or_ascii_string(tvb, &offset,
1654                         TRUE, &length, TRUE, TRUE, &bc);
1655                 if(name){
1656                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1657                                 offset, length, name);
1658                 }
1659
1660                 if (check_col(pinfo->cinfo, COL_INFO)){
1661                         col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s",
1662                         name);
1663                 }
1664         }
1665         offset += length;
1666
1667         /* some unknown bytes */
1668         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
1669         offset += 4;
1670
1671         return offset;
1672 }
1673
1674 static int
1675 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1676 {
1677         proto_item *item=NULL;
1678         proto_tree *tree=NULL;
1679
1680         if(parent_tree){
1681                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, TRUE);
1682                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
1683         }
1684
1685         /* security descriptor */
1686         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_length_remaining(tvb, offset), NULL);
1687
1688         return offset;
1689 }
1690
1691 static int
1692 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1693 {
1694         proto_item *item=NULL;
1695         proto_tree *tree=NULL;
1696         guint16 bc;
1697
1698         if(parent_tree){
1699                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, TRUE);
1700                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
1701         }
1702
1703         bc=tvb_length_remaining(tvb, offset);
1704         offset=dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1705
1706         return offset;
1707 }
1708
1709 static int
1710 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1711 {
1712         proto_item *item=NULL;
1713         proto_tree *tree=NULL;
1714         guint16 bc;
1715
1716         if(parent_tree){
1717                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, TRUE);
1718                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
1719         }
1720
1721         bc=tvb_length_remaining(tvb, offset);
1722         offset=dissect_nt_quota(tvb, tree, offset, &bc);
1723
1724         return offset;
1725 }
1726
1727 static int
1728 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1729 {
1730         proto_item *item=NULL;
1731         proto_tree *tree=NULL;
1732
1733         if(parent_tree){
1734                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, TRUE);
1735                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
1736         }
1737
1738         /* FILE_OBJECTID_BUFFER */
1739         offset=dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
1740
1741         return offset;
1742 }
1743
1744 static int
1745 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1746 {
1747         proto_item *item=NULL;
1748         proto_tree *tree=NULL;
1749         guint16 bc;
1750
1751         if(parent_tree){
1752                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, TRUE);
1753                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
1754         }
1755
1756         bc=tvb_length_remaining(tvb, offset);
1757         offset=dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1758
1759         return offset;
1760 }
1761
1762 static int
1763 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1764 {
1765         proto_item *item=NULL;
1766         proto_tree *tree=NULL;
1767         guint16 bc;
1768
1769         if(parent_tree){
1770                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, TRUE);
1771                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
1772         }
1773
1774
1775         bc=tvb_length_remaining(tvb, offset);
1776         offset=dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
1777
1778         return offset;
1779 }
1780
1781 static int
1782 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1783 {
1784         proto_item *item=NULL;
1785         proto_tree *tree=NULL;
1786         guint16 bc;
1787
1788         if(parent_tree){
1789                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, TRUE);
1790                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
1791         }
1792
1793
1794         bc=tvb_length_remaining(tvb, offset);
1795         offset=dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
1796
1797         return offset;
1798 }
1799
1800 static int
1801 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1802 {
1803         proto_item *item=NULL;
1804         proto_tree *tree=NULL;
1805         guint16 bc;
1806
1807         if(parent_tree){
1808                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, TRUE);
1809                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
1810         }
1811
1812
1813         bc=tvb_length_remaining(tvb, offset);
1814         offset=dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
1815
1816         return offset;
1817 }
1818
1819 static const value_string oplock_vals[] = {
1820         { 0x00, "No oplock" },
1821         { 0x01, "Level2 oplock" },
1822         { 0x08, "Exclusive oplock" },
1823         { 0x09, "Batch oplock" },
1824         { 0, NULL }
1825 };
1826
1827 static int
1828 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1829 {
1830         proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, TRUE);
1831
1832         offset += 1;
1833         return offset;
1834 }
1835
1836 static int
1837 dissect_smb2_buffercode(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 *length)
1838 {
1839         guint16 buffer_code;
1840
1841         /* dissect the first 2 bytes of the command PDU */
1842         buffer_code = tvb_get_letohs(tvb, offset);
1843         proto_tree_add_uint(tree, hf_smb2_buffer_code_len, tvb, offset, 2, buffer_code&0xfffe);
1844         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, TRUE);
1845         offset += 2;
1846
1847         if(length){
1848                 *length=buffer_code&0xfffe;
1849         }
1850
1851         return offset;
1852 }
1853
1854 #define NEGPROT_CAP_DFS         0x00000001
1855 #define NEGPROT_CAP_LEASING     0x00000002
1856 #define NEGPROT_CAP_LARGE_MTU   0x00000004
1857 static int
1858 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1859 {
1860         guint32 cap;
1861         proto_item *item=NULL;
1862         proto_tree *tree=NULL;
1863
1864         cap = tvb_get_letohl(tvb, offset);
1865
1866         item = proto_tree_add_item(parent_tree, hf_smb2_capabilities, tvb, offset, 4, TRUE);
1867         tree = proto_item_add_subtree(item, ett_smb2_capabilities);
1868
1869
1870         proto_tree_add_boolean(tree, hf_smb2_cap_dfs, tvb, offset, 4, cap);
1871         proto_tree_add_boolean(tree, hf_smb2_cap_leasing, tvb, offset, 4, cap);
1872         proto_tree_add_boolean(tree, hf_smb2_cap_large_mtu, tvb, offset, 4, cap);
1873
1874
1875         offset += 4;
1876
1877         return offset;
1878 }
1879
1880
1881
1882 #define NEGPROT_SIGN_REQ        0x0002
1883 #define NEGPROT_SIGN_ENABLED    0x0001
1884
1885 static int
1886 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1887 {
1888         guint8 sm;
1889         proto_item *item=NULL;
1890         proto_tree *tree=NULL;
1891
1892         sm = tvb_get_guint8(tvb, offset);
1893
1894         item = proto_tree_add_item(parent_tree, hf_smb2_security_mode, tvb, offset, 1, TRUE);
1895         tree = proto_item_add_subtree(item, ett_smb2_sec_mode);
1896
1897
1898         proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_required, tvb, offset, 1, sm);
1899         proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_enabled, tvb, offset, 1, sm);
1900
1901
1902         offset += 1;
1903
1904         return offset;
1905 }
1906
1907 #define SES_FLAGS_GUEST         0x0001
1908 #define SES_FLAGS_NULL          0x0002
1909
1910 static int
1911 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1912 {
1913         guint16 sf;
1914         proto_item *item=NULL;
1915         proto_tree *tree=NULL;
1916
1917         sf = tvb_get_letohs(tvb, offset);
1918
1919         item = proto_tree_add_item(parent_tree, hf_smb2_session_flags, tvb, offset, 2, TRUE);
1920         tree = proto_item_add_subtree(item, ett_smb2_ses_flags);
1921
1922
1923         proto_tree_add_boolean(tree, hf_smb2_ses_flags_null, tvb, offset, 2, sf);
1924         proto_tree_add_boolean(tree, hf_smb2_ses_flags_guest, tvb, offset, 2, sf);
1925
1926
1927         offset += 2;
1928
1929         return offset;
1930 }
1931
1932 #define SHARE_FLAGS_manual_caching              0x00000000
1933 #define SHARE_FLAGS_auto_caching                0x00000010
1934 #define SHARE_FLAGS_vdo_caching                 0x00000020
1935 #define SHARE_FLAGS_no_caching                  0x00000030
1936
1937 static const value_string share_cache_vals[] = {
1938         { SHARE_FLAGS_manual_caching,   "Manual caching" },
1939         { SHARE_FLAGS_auto_caching,     "Auto caching" },
1940         { SHARE_FLAGS_vdo_caching,      "VDO caching" },
1941         { SHARE_FLAGS_no_caching,       "No caching" },
1942         { 0, NULL }
1943 };
1944
1945 #define SHARE_FLAGS_dfs                         0x00000001
1946 #define SHARE_FLAGS_dfs_root                    0x00000002
1947 #define SHARE_FLAGS_restrict_exclusive_opens    0x00000100
1948 #define SHARE_FLAGS_force_shared_delete         0x00000200
1949 #define SHARE_FLAGS_allow_namespace_caching     0x00000400
1950 #define SHARE_FLAGS_access_based_dir_enum       0x00000800
1951 #define SHARE_FLAGS_force_levelii_oplock        0x00001000
1952 #define SHARE_FLAGS_enable_hash                 0x00002000
1953
1954 static int
1955 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
1956 {
1957         static const int *sf_fields[] = {
1958                 &hf_smb2_share_flags_dfs,
1959                 &hf_smb2_share_flags_dfs_root,
1960                 &hf_smb2_share_flags_restrict_exclusive_opens,
1961                 &hf_smb2_share_flags_force_shared_delete,
1962                 &hf_smb2_share_flags_allow_namespace_caching,
1963                 &hf_smb2_share_flags_access_based_dir_enum,
1964                 &hf_smb2_share_flags_force_levelii_oplock,
1965                 &hf_smb2_share_flags_enable_hash,
1966                 NULL
1967         };
1968         proto_item *item;
1969         guint32 cp;
1970
1971         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, TRUE);
1972
1973         cp = tvb_get_letohl(tvb, offset);
1974         cp &= 0x00000030;
1975         proto_tree_add_uint_format(item, hf_smb2_share_caching, tvb, offset, 4, cp, "Caching policy: %s (%08x)", val_to_str(cp, share_cache_vals, "Unknown:%u"), cp);
1976
1977
1978         offset += 4;
1979
1980         return offset;
1981 }
1982
1983 #define SHARE_CAPS_DFS          0x00000008
1984
1985 static int
1986 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
1987 {
1988         static const int *sc_fields[] = {
1989                 &hf_smb2_share_caps_dfs,
1990                 NULL
1991         };
1992
1993         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, TRUE);
1994
1995         offset += 4;
1996
1997         return offset;
1998 }
1999
2000 static void
2001 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
2002 {
2003         if( (tvb_length(tvb)>=7)
2004         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))){
2005                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
2006         } else {
2007                 call_dissector(gssapi_handle, tvb, pinfo, tree);
2008         }
2009         return;
2010 }
2011
2012 static int
2013 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2014 {
2015         offset_length_buffer_t s_olb;
2016         const ntlmssp_header_t *ntlmssph;
2017         static int ntlmssp_tap_id = 0;
2018         int idx;
2019
2020         if(!ntlmssp_tap_id){
2021                 GString *error_string;
2022                 /* We dont specify any callbacks at all.
2023                  * Instead we manually fetch the tapped data after the
2024                  * security blob has been fully dissected and before
2025                  * we exit from this dissector.
2026                  */
2027                 error_string=register_tap_listener("ntlmssp", NULL, NULL,
2028                     TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
2029                 if(!error_string){
2030                         ntlmssp_tap_id=find_tap_id("ntlmssp");
2031                 }
2032         }
2033
2034
2035         /* buffer code */
2036         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2037         /* some unknown bytes */
2038
2039         /* num vcs */
2040         proto_tree_add_item(tree, hf_smb2_vcnum, tvb, offset, 1, TRUE);
2041         offset += 1;
2042
2043         /* security mode */
2044         offset = dissect_smb2_secmode(tree, tvb, offset);
2045
2046         /* capabilities */
2047         offset = dissect_smb2_capabilities(tree, tvb, offset);
2048
2049         /* channel */
2050         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, TRUE);
2051         offset += 4;
2052
2053         /* security blob offset/length */
2054         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2055
2056         /* previous session id */
2057         proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, TRUE);
2058         offset += 8;
2059
2060
2061         /* the security blob itself */
2062         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2063
2064         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2065
2066         /* If we have found a uid->acct_name mapping, store it */
2067         if(!pinfo->fd->flags.visited){
2068                 idx=0;
2069                 while((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
2070                         if(ntlmssph && ntlmssph->type==3){
2071                                 smb2_sesid_info_t *sesid;
2072                                 sesid=se_alloc(sizeof(smb2_sesid_info_t));
2073                                 sesid->sesid=si->sesid;
2074                                 sesid->acct_name=se_strdup(ntlmssph->acct_name);
2075                                 sesid->domain_name=se_strdup(ntlmssph->domain_name);
2076                                 sesid->host_name=se_strdup(ntlmssph->host_name);
2077                                 sesid->auth_frame=pinfo->fd->num;
2078                                 sesid->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2079                                 g_hash_table_insert(si->conv->sesids, sesid, sesid);
2080                         }
2081                 }
2082         }
2083
2084         return offset;
2085 }
2086
2087 static int
2088 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2089 {
2090         gint byte_count;
2091
2092         /* buffer code */
2093         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2094
2095
2096         /* Reserved (2 bytes) */
2097         proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 2, TRUE);
2098         offset += 2;
2099
2100         /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
2101         byte_count = tvb_get_ntohl(tvb, offset);
2102         proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, TRUE);
2103         offset += 4;
2104
2105         /* If the ByteCount field is zero then the server MUST supply an ErrorData field
2106            that is one byte in length */
2107         if (byte_count == 0) byte_count = 1;
2108
2109         /* ErrorData (variable): A variable-length data field that contains extended
2110            error information.*/
2111         proto_tree_add_item(tree, hf_smb2_error_data, tvb, offset, byte_count, TRUE);
2112         offset += byte_count;
2113
2114         return offset;
2115 }
2116
2117 static int
2118 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2119 {
2120         offset_length_buffer_t s_olb;
2121
2122         /* session_setup is special and we don't use dissect_smb2_error_response() here! */
2123
2124         /* buffer code */
2125         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2126
2127         /* session flags */
2128         offset = dissect_smb2_ses_flags(tree, tvb, offset);
2129
2130         /* security blob offset/length */
2131         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2132
2133         /* the security blob itself */
2134         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2135
2136         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2137
2138         return offset;
2139 }
2140
2141 static int
2142 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2143 {
2144         offset_length_buffer_t olb;
2145         const char *buf;
2146
2147         /* buffer code */
2148         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2149
2150         /* reserved */
2151         offset += 2;
2152
2153         /* tree  offset/length */
2154         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
2155
2156         /* tree string */
2157         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2158
2159         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2160
2161         /* treelen  +1 is overkill here if the string is unicode,
2162          * but who ever has more than a handful of TCON in a trace anyways
2163          */
2164         if(!pinfo->fd->flags.visited && si->saved && buf && olb.len){
2165                 si->saved->extra_info_type=SMB2_EI_TREENAME;
2166                 si->saved->extra_info=se_alloc(olb.len+1);
2167                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2168         }
2169
2170         if (check_col(pinfo->cinfo, COL_INFO)){
2171                 col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
2172         }
2173
2174
2175         return offset;
2176 }
2177 static int
2178 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2179 {
2180         guint16 share_type;
2181
2182         switch (si->status) {
2183         case 0x00000000: break;
2184         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2185         }
2186
2187         /* buffer code */
2188         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2189
2190         /* share type */
2191         share_type = tvb_get_letohs(tvb, offset);
2192         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, TRUE);
2193         /* Next byte is reserved  and must be set to zero */
2194         offset += 2;
2195
2196         if(!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type==SMB2_EI_TREENAME && si->session) {
2197                 smb2_tid_info_t *tid, tid_key;
2198
2199                 tid_key.tid=si->tid;
2200                 tid=g_hash_table_lookup(si->session->tids, &tid_key);
2201                 if(tid){
2202                         g_hash_table_remove(si->session->tids, &tid_key);
2203                 }
2204                 tid=se_alloc(sizeof(smb2_tid_info_t));
2205                 tid->tid=si->tid;
2206                 tid->name=(char *)si->saved->extra_info;
2207                 tid->connect_frame=pinfo->fd->num;
2208                 tid->share_type=share_type;
2209
2210                 g_hash_table_insert(si->session->tids, tid, tid);
2211
2212                 si->saved->extra_info_type=SMB2_EI_NONE;
2213                 si->saved->extra_info=NULL;
2214         }
2215
2216         /* share flags */
2217         offset = dissect_smb2_share_flags(tree, tvb, offset);
2218
2219         /* share capabilities */
2220         offset = dissect_smb2_share_caps(tree, tvb, offset);
2221
2222         /* this is some sort of access mask */
2223         offset = dissect_smb_access_mask(tvb, tree, offset);
2224
2225         return offset;
2226 }
2227
2228 static int
2229 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2230 {
2231         /* buffer code */
2232         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2233
2234         /* reserved */
2235         offset += 2;
2236
2237         return offset;
2238 }
2239
2240 static int
2241 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2242 {
2243         switch (si->status) {
2244         case 0x00000000: break;
2245         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2246         }
2247
2248         /* buffer code */
2249         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2250
2251         /* reserved */
2252         offset += 2;
2253
2254         return offset;
2255 }
2256
2257 static int
2258 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2259 {
2260         /* buffer code */
2261         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2262
2263         /* reserved bytes */
2264         offset += 2;
2265
2266         return offset;
2267 }
2268
2269 static int
2270 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2271 {
2272         switch (si->status) {
2273         case 0x00000000: break;
2274         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2275         }
2276
2277         /* buffer code */
2278         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2279
2280         /* reserved bytes */
2281         offset += 2;
2282
2283         return offset;
2284 }
2285
2286 static int
2287 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2288 {
2289         /* buffer code */
2290         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2291
2292         /* some unknown bytes */
2293         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2294         offset += 2;
2295
2296         return offset;
2297 }
2298
2299 static int
2300 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2301 {
2302         switch (si->status) {
2303         case 0x00000000: break;
2304         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2305         }
2306
2307         /* buffer code */
2308         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2309
2310         /* some unknown bytes */
2311         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
2312         offset += 2;
2313
2314         return offset;
2315 }
2316
2317 static int
2318 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2319 {
2320         proto_tree *flags_tree = NULL;
2321         proto_item *flags_item = NULL;
2322
2323         /* buffer code */
2324         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2325
2326         /* notify flags */
2327         if (tree) {
2328                 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, TRUE);
2329                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
2330         }
2331         proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, TRUE);
2332         offset += 2;
2333
2334         /* output buffer length */
2335         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, TRUE);
2336         offset += 4;
2337
2338         /* fid */
2339         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2340
2341         /* completion filter */
2342         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
2343
2344         /* reserved */
2345         offset += 4;
2346
2347         return offset;
2348 }
2349
2350 static void
2351 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
2352 {
2353         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), TRUE);
2354 }
2355
2356 static int
2357 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
2358 {
2359         offset_length_buffer_t olb;
2360
2361         switch (si->status) {
2362         case 0x00000000: break;
2363         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2364         }
2365
2366         /* buffer code */
2367         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2368
2369         /* out buffer offset/length */
2370         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
2371
2372         /* out buffer */
2373         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
2374         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2375
2376         return offset;
2377 }
2378
2379 #define SMB2_FIND_FLAG_RESTART_SCANS            0x01
2380 #define SMB2_FIND_FLAG_SINGLE_ENTRY             0x02
2381 #define SMB2_FIND_FLAG_INDEX_SPECIFIED          0x04
2382 #define SMB2_FIND_FLAG_REOPEN                   0x10
2383
2384 static int
2385 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2386 {
2387         offset_length_buffer_t olb;
2388         const char *buf;
2389         guint8 il;
2390         static const int *f_fields[] = {
2391                 &hf_smb2_find_flags_restart_scans,
2392                 &hf_smb2_find_flags_single_entry,
2393                 &hf_smb2_find_flags_index_specified,
2394                 &hf_smb2_find_flags_reopen,
2395                 NULL
2396         };
2397
2398         /* buffer code */
2399         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2400
2401         il=tvb_get_guint8(tvb, offset);
2402         if(si->saved){
2403                 si->saved->infolevel=il;
2404         }
2405
2406         /* infolevel */
2407         proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
2408         offset += 1;
2409
2410         /* find flags */
2411         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, TRUE);
2412         offset += 1;
2413
2414         /* file index */
2415         proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2416         offset += 4;
2417
2418         /* fid */
2419         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2420
2421         /* search pattern  offset/length */
2422         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
2423
2424         /* output buffer length */
2425         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, TRUE);
2426         offset += 4;
2427
2428         /* search pattern */
2429         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2430
2431         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2432
2433         if(!pinfo->fd->flags.visited && si->saved && olb.len){
2434                 si->saved->extra_info_type=SMB2_EI_FINDPATTERN;
2435                 si->saved->extra_info=g_malloc(olb.len+1);
2436                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2437         }
2438
2439         if (check_col(pinfo->cinfo, COL_INFO)){
2440                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2441                         val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
2442                         buf);
2443         }
2444
2445         return offset;
2446 }
2447
2448 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2449 {
2450         int offset = 0;
2451         proto_item *item=NULL;
2452         proto_tree *tree=NULL;
2453         const char *name=NULL;
2454         guint16 bc;
2455
2456         while(tvb_length_remaining(tvb, offset) > 4){
2457                 int old_offset = offset;
2458                 int next_offset;
2459                 int file_name_len;
2460
2461                 if(parent_tree){
2462                         item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, TRUE);
2463                         tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
2464                 }
2465
2466                 /* next offset */
2467                 next_offset = tvb_get_letohl(tvb, offset);
2468                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2469                 offset += 4;
2470
2471                 /* file index */
2472                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2473                 offset += 4;
2474
2475                 /* create time */
2476                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2477
2478                 /* last access */
2479                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2480
2481                 /* last write */
2482                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2483
2484                 /* last change */
2485                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2486
2487                 /* end of file */
2488                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2489                 offset += 8;
2490
2491                 /* allocation size */
2492                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2493                 offset += 8;
2494
2495                 /* File Attributes */
2496                 offset = dissect_file_ext_attr(tvb, tree, offset);
2497
2498                 /* file name length */
2499                 file_name_len=tvb_get_letohl(tvb, offset);
2500                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2501                 offset += 4;
2502
2503                 /* file name */
2504                 if(file_name_len){
2505                         bc=file_name_len;
2506                         name = get_unicode_or_ascii_string(tvb, &offset,
2507                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2508                         if(name){
2509                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2510                                         offset, file_name_len, name);
2511                                 proto_item_append_text(item, ": %s", name);
2512
2513                         }
2514                 }
2515
2516                 proto_item_set_len(item, offset-old_offset);
2517
2518                 if (next_offset == 0){
2519                         return;
2520                 }
2521
2522                 offset = old_offset+next_offset;
2523                 if (offset < old_offset) {
2524                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2525                                     "Invalid offset/length. Malformed packet");
2526                         return;
2527                 }
2528         }
2529         return;
2530 }
2531
2532 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2533 {
2534         int offset = 0;
2535         proto_item *item=NULL;
2536         proto_tree *tree=NULL;
2537         const char *name=NULL;
2538         guint16 bc;
2539
2540         while(tvb_length_remaining(tvb, offset) > 4){
2541                 int old_offset = offset;
2542                 int next_offset;
2543                 int file_name_len;
2544
2545                 if(parent_tree){
2546                         item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, TRUE);
2547                         tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
2548                 }
2549
2550                 /* next offset */
2551                 next_offset = tvb_get_letohl(tvb, offset);
2552                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2553                 offset += 4;
2554
2555                 /* file index */
2556                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2557                 offset += 4;
2558
2559                 /* create time */
2560                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2561
2562                 /* last access */
2563                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2564
2565                 /* last write */
2566                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2567
2568                 /* last change */
2569                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2570
2571                 /* end of file */
2572                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2573                 offset += 8;
2574
2575                 /* allocation size */
2576                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2577                 offset += 8;
2578
2579                 /* File Attributes */
2580                 offset = dissect_file_ext_attr(tvb, tree, offset);
2581
2582                 /* file name length */
2583                 file_name_len=tvb_get_letohl(tvb, offset);
2584                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2585                 offset += 4;
2586
2587                 /* ea size */
2588                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2589                 offset += 4;
2590
2591                 /* file name */
2592                 if(file_name_len){
2593                         bc=file_name_len;
2594                         name = get_unicode_or_ascii_string(tvb, &offset,
2595                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2596                         if(name){
2597                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2598                                         offset, file_name_len, name);
2599                                 proto_item_append_text(item, ": %s", name);
2600
2601                         }
2602                 }
2603
2604                 proto_item_set_len(item, offset-old_offset);
2605
2606                 if (next_offset == 0){
2607                         return;
2608                 }
2609
2610                 offset = old_offset+next_offset;
2611                 if (offset < old_offset) {
2612                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2613                                     "Invalid offset/length. Malformed packet");
2614                         return;
2615                 }
2616         }
2617         return;
2618 }
2619
2620 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2621 {
2622         int offset = 0;
2623         proto_item *item=NULL;
2624         proto_tree *tree=NULL;
2625         const char *name=NULL;
2626         guint16 bc;
2627
2628         while(tvb_length_remaining(tvb, offset) > 4){
2629                 int old_offset = offset;
2630                 int next_offset;
2631                 int file_name_len;
2632                 int ea_size;
2633                 int short_name_len;
2634
2635                 if(parent_tree){
2636                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, TRUE);
2637                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
2638                 }
2639
2640                 /* next offset */
2641                 next_offset = tvb_get_letohl(tvb, offset);
2642                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2643                 offset += 4;
2644
2645                 /* file index */
2646                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2647                 offset += 4;
2648
2649                 /* create time */
2650                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2651
2652                 /* last access */
2653                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2654
2655                 /* last write */
2656                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2657
2658                 /* last change */
2659                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2660
2661                 /* end of file */
2662                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2663                 offset += 8;
2664
2665                 /* allocation size */
2666                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2667                 offset += 8;
2668
2669                 /* File Attributes */
2670                 offset = dissect_file_ext_attr(tvb, tree, offset);
2671
2672                 /* file name length */
2673                 file_name_len=tvb_get_letohl(tvb, offset);
2674                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2675                 offset += 4;
2676
2677                 /* ea size */
2678                 ea_size=tvb_get_letohl(tvb, offset);
2679                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2680                 offset += 4;
2681
2682                 /* short name length */
2683                 short_name_len=tvb_get_guint8(tvb, offset);
2684                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, TRUE);
2685                 offset += 1;
2686
2687                 /* reserved */
2688                 offset += 1;
2689
2690                 /* short name */
2691                 if(short_name_len){
2692                         bc=short_name_len;
2693                         name = get_unicode_or_ascii_string(tvb, &offset,
2694                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
2695                         if(name){
2696                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
2697                                         offset, short_name_len, name);
2698                         }
2699                 }
2700                 offset += 24;
2701
2702                 /* file name */
2703                 if(file_name_len){
2704                         bc=file_name_len;
2705                         name = get_unicode_or_ascii_string(tvb, &offset,
2706                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2707                         if(name){
2708                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2709                                         offset, file_name_len, name);
2710                                 proto_item_append_text(item, ": %s", name);
2711
2712                         }
2713                 }
2714
2715                 proto_item_set_len(item, offset-old_offset);
2716
2717                 if (next_offset == 0){
2718                         return;
2719                 }
2720
2721                 offset = old_offset+next_offset;
2722                 if (offset < old_offset) {
2723                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2724                                     "Invalid offset/length. Malformed packet");
2725                         return;
2726                 }
2727         }
2728         return;
2729 }
2730
2731 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2732 {
2733         int offset = 0;
2734         proto_item *item=NULL;
2735         proto_tree *tree=NULL;
2736         const char *name=NULL;
2737         guint16 bc;
2738
2739         while(tvb_length_remaining(tvb, offset) > 4){
2740                 int old_offset = offset;
2741                 int next_offset;
2742                 int file_name_len;
2743
2744                 if(parent_tree){
2745                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, TRUE);
2746                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
2747                 }
2748
2749                 /* next offset */
2750                 next_offset = tvb_get_letohl(tvb, offset);
2751                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2752                 offset += 4;
2753
2754                 /* file index */
2755                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2756                 offset += 4;
2757
2758                 /* file name length */
2759                 file_name_len=tvb_get_letohl(tvb, offset);
2760                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2761                 offset += 4;
2762
2763                 /* file name */
2764                 if(file_name_len){
2765                         bc=file_name_len;
2766                         name = get_unicode_or_ascii_string(tvb, &offset,
2767                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2768                         if(name){
2769                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2770                                         offset, file_name_len, name);
2771                                 proto_item_append_text(item, ": %s", name);
2772
2773                         }
2774                 }
2775
2776                 proto_item_set_len(item, offset-old_offset);
2777
2778                 if (next_offset == 0){
2779                         return;
2780                 }
2781
2782                 offset = old_offset+next_offset;
2783                 if (offset < old_offset) {
2784                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2785                                     "Invalid offset/length. Malformed packet");
2786                         return;
2787                 }
2788         }
2789         return;
2790 }
2791
2792 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2793 {
2794         int offset = 0;
2795         proto_item *item=NULL;
2796         proto_tree *tree=NULL;
2797         const char *name=NULL;
2798         guint16 bc;
2799
2800         while(tvb_length_remaining(tvb, offset) > 4){
2801                 int old_offset = offset;
2802                 int next_offset;
2803                 int file_name_len;
2804                 int ea_size;
2805                 int short_name_len;
2806
2807                 if(parent_tree){
2808                         item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, TRUE);
2809                         tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
2810                 }
2811
2812                 /* next offset */
2813                 next_offset = tvb_get_letohl(tvb, offset);
2814                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, TRUE);
2815                 offset += 4;
2816
2817                 /* file index */
2818                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, TRUE);
2819                 offset += 4;
2820
2821                 /* create time */
2822                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2823
2824                 /* last access */
2825                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2826
2827                 /* last write */
2828                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2829
2830                 /* last change */
2831                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2832
2833                 /* end of file */
2834                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
2835                 offset += 8;
2836
2837                 /* allocation size */
2838                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
2839                 offset += 8;
2840
2841                 /* File Attributes */
2842                 offset = dissect_file_ext_attr(tvb, tree, offset);
2843
2844                 /* file name length */
2845                 file_name_len=tvb_get_letohl(tvb, offset);
2846                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, TRUE);
2847                 offset += 4;
2848
2849                 /* ea size */
2850                 ea_size=tvb_get_letohl(tvb, offset);
2851                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, TRUE);
2852                 offset += 4;
2853
2854                 /* short name length */
2855                 short_name_len=tvb_get_guint8(tvb, offset);
2856                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, TRUE);
2857                 offset += 1;
2858
2859                 /* reserved */
2860                 offset += 1;
2861
2862                 /* short name */
2863                 if(short_name_len){
2864                         bc=short_name_len;
2865                         name = get_unicode_or_ascii_string(tvb, &offset,
2866                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
2867                         if(name){
2868                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
2869                                         offset, short_name_len, name);
2870                         }
2871                 }
2872                 offset += 24;
2873
2874                 /* reserved */
2875                 offset += 2;
2876
2877                 /* file id */
2878                 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, TRUE);
2879                 offset += 8;
2880
2881                 /* file name */
2882                 if(file_name_len){
2883                         bc=file_name_len;
2884                         name = get_unicode_or_ascii_string(tvb, &offset,
2885                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
2886                         if(name){
2887                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2888                                         offset, file_name_len, name);
2889                                 proto_item_append_text(item, ": %s", name);
2890
2891                         }
2892                 }
2893
2894                 proto_item_set_len(item, offset-old_offset);
2895
2896                 if (next_offset == 0){
2897                         return;
2898                 }
2899
2900                 offset = old_offset+next_offset;
2901                 if (offset < old_offset) {
2902                         proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2903                                     "Invalid offset/length. Malformed packet");
2904                         return;
2905                 }
2906         }
2907         return;
2908 }
2909
2910
2911 typedef struct _smb2_find_dissector_t {
2912         guint32 level;
2913         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
2914 } smb2_find_dissector_t;
2915
2916 smb2_find_dissector_t smb2_find_dissectors[] = {
2917         {SMB2_FIND_DIRECTORY_INFO,      dissect_smb2_file_directory_info},
2918         {SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
2919         {SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
2920         {SMB2_FIND_NAME_INFO,           dissect_smb2_file_name_info},
2921         {SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
2922         {0, NULL}
2923 };
2924
2925 static void
2926 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
2927 {
2928         smb2_find_dissector_t *dis = smb2_find_dissectors;
2929
2930         while(dis->dissector){
2931                 if(si && si->saved && si->saved){
2932                         if(dis->level ==si->saved->infolevel){
2933                                 dis->dissector(tvb, pinfo, tree, si);
2934                                 return;
2935                         }
2936                 }
2937                 dis++;
2938         }
2939
2940         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), FALSE);
2941         return;
2942 }
2943
2944 static int
2945 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2946 {
2947         offset_length_buffer_t olb;
2948         proto_item *item=NULL;
2949
2950         if(si->saved){
2951                 /* infolevel */
2952                 item=proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
2953                 PROTO_ITEM_SET_GENERATED(item);
2954         }
2955
2956         if(!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type==SMB2_EI_FINDPATTERN) {
2957                 if (check_col(pinfo->cinfo, COL_INFO)){
2958                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2959                                 val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
2960                                 (const char *)si->saved->extra_info);
2961                 }
2962
2963                 g_free(si->saved->extra_info);
2964                 si->saved->extra_info_type=SMB2_EI_NONE;
2965                 si->saved->extra_info=NULL;
2966         }
2967
2968         switch (si->status) {
2969         case 0x00000000: break;
2970         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2971         }
2972
2973         /* buffer code */
2974         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2975
2976         /* findinfo offset */
2977         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
2978
2979         /* the buffer */
2980         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
2981
2982         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2983
2984         return offset;
2985 }
2986
2987 static int
2988 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2989 {
2990         guint16 dc;
2991
2992         /* buffer code */
2993         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2994
2995         /* dialect count */
2996         dc = tvb_get_letohs(tvb, offset);
2997         proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, TRUE);
2998         offset += 2;
2999
3000         /* security mode, skip second byte */
3001         offset = dissect_smb2_secmode(tree, tvb, offset);
3002         offset++;
3003
3004
3005         /* reserved */
3006         offset += 2;
3007
3008         /* capabilities */
3009         offset = dissect_smb2_capabilities(tree, tvb, offset);
3010
3011         /* client guid */
3012         proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, TRUE);
3013         offset += 16;
3014
3015         /* client boot time */
3016         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3017         offset += 8;
3018
3019         for(;dc>0;dc--){
3020                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, TRUE);
3021                 offset += 2;
3022         }
3023
3024         return offset;
3025 }
3026
3027 static int
3028 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3029 {
3030         offset_length_buffer_t s_olb;
3031
3032         switch (si->status) {
3033         case 0x00000000: break;
3034         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3035         }
3036
3037         /* buffer code */
3038         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3039
3040         /* security mode, skip second byte */
3041         offset = dissect_smb2_secmode(tree, tvb, offset);
3042         offset++;
3043
3044         /* dialect picked */
3045         proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, TRUE);
3046         offset += 2;
3047
3048         /* reserved */
3049         offset += 2;
3050
3051         /* server GUID */
3052         proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, TRUE);
3053         offset += 16;
3054
3055         /* capabilities */
3056         offset = dissect_smb2_capabilities(tree, tvb, offset);
3057
3058         /* max trans size */
3059         proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, TRUE);
3060         offset += 4;
3061
3062         /* max read size */
3063         proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, TRUE);
3064         offset += 4;
3065
3066         /* max write size */
3067         proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, TRUE);
3068         offset += 4;
3069
3070         /* current time */
3071         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
3072         offset += 8;
3073
3074         /* boot time */
3075         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3076         offset += 8;
3077
3078         /* security blob offset/length */
3079         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3080
3081         /* the security blob itself */
3082         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3083
3084         /* reserved */
3085         offset += 4;
3086
3087         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3088
3089         return offset;
3090 }
3091
3092 static void
3093 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3094 {
3095         switch(si->saved->class){
3096         case SMB2_CLASS_FILE_INFO:
3097                 switch(si->saved->infolevel){
3098                 default:
3099                         /* we dont handle this infolevel yet */
3100                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3101                         offset += tvb_length_remaining(tvb, offset);
3102                 }
3103                 break;
3104         case SMB2_CLASS_FS_INFO:
3105                 switch(si->saved->infolevel){
3106                 default:
3107                         /* we dont handle this infolevel yet */
3108                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3109                         offset += tvb_length_remaining(tvb, offset);
3110                 }
3111                 break;
3112         case SMB2_CLASS_SEC_INFO:
3113                 switch(si->saved->infolevel){
3114                 case SMB2_SEC_INFO_00:
3115                         dissect_security_information_mask(tvb, tree, offset+8);
3116                         break;
3117                 default:
3118                         /* we dont handle this infolevel yet */
3119                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3120                         offset += tvb_length_remaining(tvb, offset);
3121                 }
3122                 break;
3123         default:
3124                 /* we dont handle this class yet */
3125                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3126         }
3127 }
3128
3129
3130 static int
3131 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
3132 {
3133         char cl, il;
3134         proto_item *item;
3135         int hfindex;
3136         static const value_string dummy_value_string[] = {
3137                 { 0, NULL }
3138         };
3139         const value_string *vs;
3140
3141         if(si->flags & SMB2_FLAGS_RESPONSE){
3142                 if(!si->saved){
3143                         return offset;
3144                 }
3145                 cl=si->saved->class;
3146                 il=si->saved->infolevel;
3147         } else {
3148                 cl=tvb_get_guint8(tvb, offset);
3149                 il=tvb_get_guint8(tvb, offset+1);
3150                 if(si->saved){
3151                         si->saved->class=cl;
3152                         si->saved->infolevel=il;
3153                 }
3154         }
3155
3156
3157         switch(cl){
3158         case SMB2_CLASS_FILE_INFO:
3159                 hfindex=hf_smb2_infolevel_file_info;
3160                 vs=smb2_file_info_levels;
3161                 break;
3162         case SMB2_CLASS_FS_INFO:
3163                 hfindex=hf_smb2_infolevel_fs_info;
3164                 vs=smb2_fs_info_levels;
3165                 break;
3166         case SMB2_CLASS_SEC_INFO:
3167                 hfindex=hf_smb2_infolevel_sec_info;
3168                 vs=smb2_sec_info_levels;
3169                 break;
3170         default:
3171                 hfindex=hf_smb2_infolevel;
3172                 vs=dummy_value_string;
3173         }
3174
3175
3176         /* class */
3177         item=proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
3178         if(si->flags & SMB2_FLAGS_RESPONSE){
3179                 PROTO_ITEM_SET_GENERATED(item);
3180         }
3181         /* infolevel */
3182         item=proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
3183         if(si->flags & SMB2_FLAGS_RESPONSE){
3184                 PROTO_ITEM_SET_GENERATED(item);
3185         }
3186         offset += 2;
3187
3188         if(!(si->flags & SMB2_FLAGS_RESPONSE)){
3189                 /* Only update COL_INFO for requests. It clutters the
3190                  * display ab bit too much if we do it for replies
3191                  * as well.
3192                  */
3193                 if (check_col(pinfo->cinfo, COL_INFO)){
3194                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
3195                                 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
3196                                 val_to_str(il, vs, "(Level:0x%02x)"));
3197                 }
3198         }
3199
3200         return offset;
3201 }
3202
3203 static int
3204 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3205 {
3206         /* buffer code */
3207         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3208
3209         /* class and info level */
3210         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3211
3212         /* max response size */
3213         proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, TRUE);
3214         offset += 4;
3215
3216         /* parameters */
3217         if(si->saved){
3218                 dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
3219         } else {
3220                 /* some unknown bytes */
3221                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, TRUE);
3222         }
3223         offset += 16;
3224
3225         /* fid */
3226         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3227
3228         return offset;
3229 }
3230
3231 static void
3232 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 class, guint8 infolevel)
3233 {
3234         int old_offset = offset;
3235
3236         switch(class){
3237         case SMB2_CLASS_FILE_INFO:
3238                 switch(infolevel){
3239                 case SMB2_FILE_BASIC_INFO:
3240                         dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
3241                         break;
3242                 case SMB2_FILE_STANDARD_INFO:
3243                         dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
3244                         break;
3245                 case SMB2_FILE_INTERNAL_INFO:
3246                         dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
3247                         break;
3248                 case SMB2_FILE_EA_INFO:
3249                         dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
3250                         break;
3251                 case SMB2_FILE_ACCESS_INFO:
3252                         dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
3253                         break;
3254                 case SMB2_FILE_RENAME_INFO:
3255                         dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
3256                         break;
3257                 case SMB2_FILE_DISPOSITION_INFO:
3258                         dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
3259                         break;
3260                 case SMB2_FILE_POSITION_INFO:
3261                         dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
3262                         break;
3263                 case SMB2_FILE_INFO_0f:
3264                         dissect_smb2_file_info_0f(tvb, pinfo, tree, offset, si);
3265                         break;
3266                 case SMB2_FILE_MODE_INFO:
3267                         dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
3268                         break;
3269                 case SMB2_FILE_ALIGNMENT_INFO:
3270                         dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
3271                         break;
3272                 case SMB2_FILE_ALL_INFO:
3273                         dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
3274                         break;
3275                 case SMB2_FILE_ALLOCATION_INFO:
3276                         dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
3277                         break;
3278                 case SMB2_FILE_ENDOFFILE_INFO:
3279                         dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
3280                         break;
3281                 case SMB2_FILE_ALTERNATE_NAME_INFO:
3282                         dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
3283                         break;
3284                 case SMB2_FILE_STREAM_INFO:
3285                         dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
3286                         break;
3287                 case SMB2_FILE_PIPE_INFO:
3288                         dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
3289                         break;
3290                 case SMB2_FILE_COMPRESSION_INFO:
3291                         dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
3292                         break;
3293                 case SMB2_FILE_NETWORK_OPEN_INFO:
3294                         dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
3295                         break;
3296                 case SMB2_FILE_ATTRIBUTE_TAG_INFO:
3297                         dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
3298                         break;
3299                 default:
3300                         /* we dont handle this infolevel yet */
3301                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3302                         offset += tvb_length_remaining(tvb, offset);
3303                 }
3304                 break;
3305         case SMB2_CLASS_FS_INFO:
3306                 switch(infolevel){
3307                 case SMB2_FS_INFO_01:
3308                         dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
3309                         break;
3310                 case SMB2_FS_INFO_03:
3311                         dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
3312                         break;
3313                 case SMB2_FS_INFO_04:
3314                         dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
3315                         break;
3316                 case SMB2_FS_INFO_05:
3317                         dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
3318                         break;
3319                 case SMB2_FS_INFO_06:
3320                         dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
3321                         break;
3322                 case SMB2_FS_INFO_07:
3323                         dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
3324                         break;
3325                 case SMB2_FS_OBJECTID_INFO:
3326                         dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
3327                         break;
3328                 default:
3329                         /* we dont handle this infolevel yet */
3330                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3331                         offset += tvb_length_remaining(tvb, offset);
3332                 }
3333                 break;
3334         case SMB2_CLASS_SEC_INFO:
3335                 switch(infolevel){
3336                 case SMB2_SEC_INFO_00:
3337                         dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
3338                         break;
3339                 default:
3340                         /* we dont handle this infolevel yet */
3341                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3342                         offset += tvb_length_remaining(tvb, offset);
3343                 }
3344                 break;
3345         default:
3346                 /* we dont handle this class yet */
3347                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
3348         }
3349
3350         /* if we get BUFFER_OVERFLOW there will be truncated data */
3351         if (si->status == 0x80000005) {
3352                 proto_item *item;
3353                 item=proto_tree_add_text(tree, tvb, old_offset, 0, "Truncated...");
3354                 PROTO_ITEM_SET_GENERATED(item);
3355         }
3356 }
3357
3358 static void
3359 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3360 {
3361         /* data */
3362         if(si->saved){
3363                 dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->class, si->saved->infolevel);
3364         } else {
3365                 /* some unknown bytes */
3366                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), FALSE);
3367         }
3368
3369         return;
3370 }
3371
3372
3373 static int
3374 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3375 {
3376         offset_length_buffer_t olb;
3377
3378         /* class/infolevel */
3379         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3380
3381         switch (si->status) {
3382         case 0x00000000: break;
3383         /* if we get BUFFER_OVERFLOW there will be truncated data */
3384         case 0x80000005: break;
3385         /* if we get BUFFER_TOO_SMALL there will not be any data there, only
3386          * a guin32 specifying how big the buffer needs to be
3387          */
3388         case 0xc0000023:
3389                 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3390                 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
3391                 proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, TRUE);
3392                 offset += 4;
3393
3394                 return offset;
3395         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3396         }
3397
3398
3399         /* buffer code */
3400         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3401          /* response buffer offset  and size */
3402         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
3403
3404         /* response data*/
3405         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
3406
3407         return offset;
3408 }
3409
3410 static int
3411 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3412 {
3413         proto_tree *flags_tree = NULL;
3414         proto_item *flags_item = NULL;
3415
3416         /* buffer code */
3417         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3418
3419         /* close flags */
3420         if (tree) {
3421                 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, TRUE);
3422                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
3423         }
3424         proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, TRUE);
3425         offset += 2;
3426
3427         /* padding */
3428         offset += 4;
3429
3430         /* fid */
3431         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
3432
3433         return offset;
3434 }
3435
3436 static int
3437 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3438 {
3439         proto_tree *flags_tree = NULL;
3440         proto_item *flags_item = NULL;
3441
3442         switch (si->status) {
3443         case 0x00000000: break;
3444         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3445         }
3446
3447         /* buffer code */
3448         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3449
3450         /* close flags */
3451         if (tree) {
3452                 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, TRUE);
3453                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
3454         }
3455         proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, TRUE);
3456         offset += 2;
3457
3458         /* reserved */
3459         offset += 4;
3460
3461         /* create time */
3462         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3463
3464         /* last access */
3465         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3466
3467         /* last write */
3468         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3469
3470         /* last change */
3471         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3472
3473         /* allocation size */
3474         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, TRUE);
3475         offset += 8;
3476
3477         /* end of file */
3478         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, TRUE);
3479         offset += 8;
3480
3481         /* File Attributes */
3482         offset = dissect_file_ext_attr(tvb, tree, offset);
3483
3484         return offset;
3485 }
3486
3487 static int
3488 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3489 {
3490         /* buffer code */
3491         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3492
3493         /* some unknown bytes */
3494         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, TRUE);
3495         offset += 6;
3496
3497         /* fid */
3498         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3499
3500         return offset;
3501 }
3502
3503 static int
3504 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3505 {
3506         switch (si->status) {
3507         case 0x00000000: break;
3508         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3509         }
3510
3511         /* buffer code */
3512         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3513
3514         /* some unknown bytes */
3515         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3516         offset += 2;
3517
3518         return offset;
3519 }
3520
3521
3522 static int
3523 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3524 {
3525         guint16 lock_count;
3526
3527         /* buffer code */
3528         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3529
3530         /* lock count */
3531         lock_count = tvb_get_letohs(tvb, offset);
3532         proto_tree_add_item(tree, hf_smb2_lock_count, tvb, offset, 2, TRUE);
3533         offset += 2;
3534
3535         /* reserved */
3536         offset += 4;
3537
3538         /* fid */
3539         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3540
3541         while (lock_count--) {
3542                 proto_item *lock_item=NULL;
3543                 proto_tree *lock_tree=NULL;
3544                 static const int *lf_fields[] = {
3545                         &hf_smb2_lock_flags_shared,
3546                         &hf_smb2_lock_flags_exclusive,
3547                         &hf_smb2_lock_flags_unlock,
3548                         &hf_smb2_lock_flags_fail_immediately,
3549                         NULL
3550                 };
3551
3552                 if(tree){
3553                         lock_item = proto_tree_add_item(tree, hf_smb2_lock_info, tvb, offset, 24, TRUE);
3554                         lock_tree = proto_item_add_subtree(lock_item, ett_smb2_lock_info);
3555                 }
3556
3557                 /* offset */
3558                 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, TRUE);
3559                 offset += 8;
3560
3561                 /* count */
3562                 proto_tree_add_item(lock_tree, hf_smb2_lock_length, tvb, offset, 8, TRUE);
3563                 offset += 8;
3564
3565                 /* flags */
3566                 proto_tree_add_bitmask(lock_tree, tvb, offset, hf_smb2_lock_flags, ett_smb2_lock_flags, lf_fields, TRUE);
3567                 offset += 4;
3568
3569                 /* reserved */
3570                 offset += 4;
3571         }
3572
3573         return offset;
3574 }
3575
3576 static int
3577 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3578 {
3579         switch (si->status) {
3580         case 0x00000000: break;
3581         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3582         }
3583
3584         /* buffer code */
3585         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3586
3587         /* some unknown bytes */
3588         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, TRUE);
3589         offset += 2;
3590
3591         return offset;
3592 }
3593 static int
3594 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
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         return offset;
3604 }
3605
3606
3607 static int
3608 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, proto_tree *top_tree)
3609 {
3610         int tvblen;
3611         int result;
3612
3613         tvbuff_t *dcerpc_tvb;
3614         tvblen = tvb_length_remaining(tvb, offset);
3615         dcerpc_tvb = tvb_new_subset(tvb, offset, MIN((int)datalen, tvb_length_remaining(tvb, offset)), datalen);
3616
3617         /* dissect the full PDU */
3618         result = dissector_try_heuristic(smb2_heur_subdissector_list, dcerpc_tvb, pinfo, top_tree);
3619
3620
3621         offset += datalen;
3622
3623         return offset;
3624 }
3625
3626 #define SMB2_WRITE_FLAG_WRITE_THROUGH           0x00000001
3627
3628 static int
3629 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3630 {
3631         guint32 length;
3632         guint64 off;
3633         static const int *f_fields[] = {
3634                 &hf_smb2_write_flags_write_through,
3635                 NULL
3636         };
3637
3638         /* buffer code */
3639         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3640
3641         /* data offset */
3642         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, TRUE);
3643         offset += 2;
3644
3645         /* length */
3646         length=tvb_get_letohl(tvb, offset);
3647         proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, TRUE);
3648         offset += 4;
3649
3650         /* offset */
3651         off=tvb_get_letoh64(tvb, offset);
3652         proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, TRUE);
3653         offset += 8;
3654
3655         if (check_col(pinfo->cinfo, COL_INFO)){
3656                 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", length, off);
3657         }
3658
3659         /* fid */
3660         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3661
3662         /* channel */
3663         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, TRUE);
3664         offset += 4;
3665
3666         /* remaining bytes */
3667         proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, TRUE);
3668         offset += 4;
3669
3670         /* write channel info offset */
3671         proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, TRUE);
3672         offset += 2;
3673
3674         /* write channel info length */
3675         proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, TRUE);
3676         offset += 2;
3677
3678         /* flags */
3679         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_write_flags, ett_smb2_write_flags, f_fields, TRUE);
3680         offset += 4;
3681
3682         /* data or dcerpc ?*/
3683         if(length && si->tree && si->tree->share_type == SMB2_SHARE_TYPE_PIPE){
3684                 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si->top_tree);
3685                 return offset;
3686         }
3687
3688         /* just ordinary data */
3689         proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, TRUE);
3690         offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
3691
3692         return offset;
3693 }
3694
3695
3696 static int
3697 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3698 {
3699         switch (si->status) {
3700         case 0x00000000: break;
3701         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3702         }
3703
3704         /* buffer code */
3705         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3706
3707         /* reserved */
3708         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, TRUE);
3709         offset += 2;
3710
3711         /* count */
3712         proto_tree_add_item(tree, hf_smb2_write_count, tvb, offset, 4, TRUE);
3713         offset += 4;
3714
3715         /* remaining, must be set to 0 */
3716         proto_tree_add_item(tree, hf_smb2_write_remaining, tvb, offset, 4, TRUE);
3717         offset += 4;
3718
3719         /* write channel info offset */
3720         proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, TRUE);
3721         offset += 2;
3722
3723         /* write channel info length */
3724         proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, TRUE);
3725         offset += 2;
3726
3727         return offset;
3728 }
3729
3730 static void
3731 dissect_smb2_IOCTL_DO_DCERPC(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *top_tree, gboolean data_in _U_)
3732 {
3733         dissect_file_data_dcerpc(tvb, pinfo, tree, offset, tvb_length_remaining(tvb, offset), top_tree);
3734
3735         return;
3736 }
3737
3738 static void
3739 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
3740 {
3741         guint32 num_volumes, num_labels;
3742
3743         /* There is no in data */
3744         if(data_in){
3745                 return;
3746         }
3747
3748         /* num volumes */
3749         num_volumes=tvb_get_letohl(tvb, offset);
3750         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_volumes, tvb, offset, 4, TRUE);
3751         offset += 4;
3752
3753         /* num labels */
3754         num_labels=tvb_get_letohl(tvb, offset);
3755         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_labels, tvb, offset, 4, TRUE);
3756         offset += 4;
3757
3758         /* count */
3759         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_count, tvb, offset, 4, TRUE);
3760         offset += 4;