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