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