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