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