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