Add a tap "finish" callback, called when a listener is removed.
[metze/wireshark/wip.git] / epan / dissectors / packet-smb2.c
1 /* packet-smb2.c
2  * Routines for smb2 packet dissection
3  * Ronnie Sahlberg 2005
4  *
5  * For documentation of this protocol, see:
6  *
7  * https://wiki.wireshark.org/SMB2
8  * https://msdn.microsoft.com/en-us/library/cc246482.aspx
9  *
10  * If you edit this file, keep the wiki updated as well.
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * SPDX-License-Identifier: GPL-2.0-or-later
17  */
18
19 #include "config.h"
20
21
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/expert.h>
25 #include <epan/tap.h>
26 #include <epan/srt_table.h>
27 #include <epan/aftypes.h>
28 #include <epan/to_str.h>
29 #include <epan/asn1.h>
30 #include <epan/reassemble.h>
31 #include <epan/uat.h>
32
33 #include "packet-smb2.h"
34 #include "packet-ntlmssp.h"
35 #include "packet-kerberos.h"
36 #include "packet-windows-common.h"
37 #include "packet-smb-common.h"
38 #include "packet-dcerpc-nt.h"
39
40 #include "read_keytab_file.h"
41
42 #include <wsutil/wsgcrypt.h>
43
44 #define NT_STATUS_PENDING       0x00000103
45
46 void proto_register_smb2(void);
47 void proto_reg_handoff_smb2(void);
48
49 static const char smb_header_label[] = "SMB2 Header";
50 static const char smb_transform_header_label[] = "SMB2 Transform Header";
51
52 static int proto_smb2 = -1;
53 static int hf_smb2_cmd = -1;
54 static int hf_smb2_nt_status = -1;
55 static int hf_smb2_response_to = -1;
56 static int hf_smb2_response_in = -1;
57 static int hf_smb2_time = -1;
58 static int hf_smb2_header_len = -1;
59 static int hf_smb2_msg_id = -1;
60 static int hf_smb2_pid = -1;
61 static int hf_smb2_tid = -1;
62 static int hf_smb2_aid = -1;
63 static int hf_smb2_sesid = -1;
64 static int hf_smb2_previous_sesid = -1;
65 static int hf_smb2_flags_response = -1;
66 static int hf_smb2_flags_async_cmd = -1;
67 static int hf_smb2_flags_dfs_op = -1;
68 static int hf_smb2_flags_chained = -1;
69 static int hf_smb2_flags_signature = -1;
70 static int hf_smb2_flags_replay_operation = -1;
71 static int hf_smb2_flags_priority_mask = -1;
72 static int hf_smb2_chain_offset = -1;
73 static int hf_smb2_security_blob = -1;
74 static int hf_smb2_ioctl_in_data = -1;
75 static int hf_smb2_ioctl_out_data = -1;
76 static int hf_smb2_unknown = -1;
77 static int hf_smb2_root_directory_mbz = -1;
78 static int hf_smb2_twrp_timestamp = -1;
79 static int hf_smb2_mxac_timestamp = -1;
80 static int hf_smb2_mxac_status = -1;
81 static int hf_smb2_qfid_fid = -1;
82 static int hf_smb2_create_timestamp = -1;
83 static int hf_smb2_oplock = -1;
84 static int hf_smb2_close_flags = -1;
85 static int hf_smb2_notify_flags = -1;
86 static int hf_smb2_last_access_timestamp = -1;
87 static int hf_smb2_last_write_timestamp = -1;
88 static int hf_smb2_last_change_timestamp = -1;
89 static int hf_smb2_current_time = -1;
90 static int hf_smb2_boot_time = -1;
91 static int hf_smb2_filename = -1;
92 static int hf_smb2_filename_len = -1;
93 static int hf_smb2_replace_if = -1;
94 static int hf_smb2_nlinks = -1;
95 static int hf_smb2_delete_pending = -1;
96 static int hf_smb2_is_directory = -1;
97 static int hf_smb2_file_id = -1;
98 static int hf_smb2_allocation_size = -1;
99 static int hf_smb2_end_of_file = -1;
100 static int hf_smb2_tree = -1;
101 static int hf_smb2_find_pattern = -1;
102 static int hf_smb2_find_info_level = -1;
103 static int hf_smb2_find_info_blob = -1;
104 static int hf_smb2_client_guid = -1;
105 static int hf_smb2_server_guid = -1;
106 static int hf_smb2_object_id = -1;
107 static int hf_smb2_birth_volume_id = -1;
108 static int hf_smb2_birth_object_id = -1;
109 static int hf_smb2_domain_id = -1;
110 static int hf_smb2_class = -1;
111 static int hf_smb2_infolevel = -1;
112 static int hf_smb2_infolevel_file_info = -1;
113 static int hf_smb2_infolevel_fs_info = -1;
114 static int hf_smb2_infolevel_sec_info = -1;
115 static int hf_smb2_infolevel_posix_info = -1;
116 static int hf_smb2_max_response_size = -1;
117 static int hf_smb2_max_ioctl_in_size = -1;
118 static int hf_smb2_max_ioctl_out_size = -1;
119 static int hf_smb2_flags = -1;
120 static int hf_smb2_required_buffer_size = -1;
121 static int hf_smb2_getinfo_input_size = -1;
122 static int hf_smb2_getinfo_input_offset = -1;
123 static int hf_smb2_getinfo_additional = -1;
124 static int hf_smb2_getinfo_flags = -1;
125 static int hf_smb2_setinfo_size = -1;
126 static int hf_smb2_setinfo_offset = -1;
127 static int hf_smb2_file_basic_info = -1;
128 static int hf_smb2_file_standard_info = -1;
129 static int hf_smb2_file_internal_info = -1;
130 static int hf_smb2_file_ea_info = -1;
131 static int hf_smb2_file_access_info = -1;
132 static int hf_smb2_file_rename_info = -1;
133 static int hf_smb2_file_disposition_info = -1;
134 static int hf_smb2_file_position_info = -1;
135 static int hf_smb2_file_full_ea_info = -1;
136 static int hf_smb2_file_mode_info = -1;
137 static int hf_smb2_file_alignment_info = -1;
138 static int hf_smb2_file_all_info = -1;
139 static int hf_smb2_file_allocation_info = -1;
140 static int hf_smb2_file_endoffile_info = -1;
141 static int hf_smb2_file_alternate_name_info = -1;
142 static int hf_smb2_file_stream_info = -1;
143 static int hf_smb2_file_pipe_info = -1;
144 static int hf_smb2_file_compression_info = -1;
145 static int hf_smb2_file_network_open_info = -1;
146 static int hf_smb2_file_attribute_tag_info = -1;
147 static int hf_smb2_fs_info_01 = -1;
148 static int hf_smb2_fs_info_03 = -1;
149 static int hf_smb2_fs_info_04 = -1;
150 static int hf_smb2_fs_info_05 = -1;
151 static int hf_smb2_fs_info_06 = -1;
152 static int hf_smb2_fs_info_07 = -1;
153 static int hf_smb2_fs_objectid_info = -1;
154 static int hf_smb2_sec_info_00 = -1;
155 static int hf_smb2_quota_info = -1;
156 static int hf_smb2_query_quota_info = -1;
157 static int hf_smb2_qq_single = -1;
158 static int hf_smb2_qq_restart = -1;
159 static int hf_smb2_qq_sidlist_len = -1;
160 static int hf_smb2_qq_start_sid_len = -1;
161 static int hf_smb2_qq_start_sid_offset = -1;
162 static int hf_smb2_fid = -1;
163 static int hf_smb2_write_length = -1;
164 static int hf_smb2_write_data = -1;
165 static int hf_smb2_write_flags = -1;
166 static int hf_smb2_write_flags_write_through = -1;
167 static int hf_smb2_write_count = -1;
168 static int hf_smb2_write_remaining = -1;
169 static int hf_smb2_read_length = -1;
170 static int hf_smb2_read_remaining = -1;
171 static int hf_smb2_file_offset = -1;
172 static int hf_smb2_qfr_length = -1;
173 static int hf_smb2_qfr_usage = -1;
174 static int hf_smb2_qfr_flags = -1;
175 static int hf_smb2_qfr_total_region_entry_count = -1;
176 static int hf_smb2_qfr_region_entry_count = -1;
177 static int hf_smb2_read_data = -1;
178 static int hf_smb2_disposition_delete_on_close = -1;
179 static int hf_smb2_create_disposition = -1;
180 static int hf_smb2_create_chain_offset = -1;
181 static int hf_smb2_create_chain_data = -1;
182 static int hf_smb2_data_offset = -1;
183 static int hf_smb2_extrainfo = -1;
184 static int hf_smb2_create_action = -1;
185 static int hf_smb2_create_rep_flags = -1;
186 static int hf_smb2_create_rep_flags_reparse_point = -1;
187 static int hf_smb2_next_offset = -1;
188 static int hf_smb2_negotiate_context_type = -1;
189 static int hf_smb2_negotiate_context_data_length = -1;
190 static int hf_smb2_negotiate_context_offset = -1;
191 static int hf_smb2_negotiate_context_count = -1;
192 static int hf_smb2_hash_alg_count = -1;
193 static int hf_smb2_hash_algorithm = -1;
194 static int hf_smb2_salt_length = -1;
195 static int hf_smb2_salt = -1;
196 static int hf_smb2_cipher_count = -1;
197 static int hf_smb2_cipher_id = -1;
198 static int hf_smb2_ea_size = -1;
199 static int hf_smb2_ea_flags = -1;
200 static int hf_smb2_ea_name_len = -1;
201 static int hf_smb2_ea_data_len = -1;
202 static int hf_smb2_ea_name = -1;
203 static int hf_smb2_ea_data = -1;
204 static int hf_smb2_position_information = -1;
205 static int hf_smb2_mode_information = -1;
206 static int hf_smb2_mode_file_write_through = -1;
207 static int hf_smb2_mode_file_sequential_only = -1;
208 static int hf_smb2_mode_file_no_intermediate_buffering = -1;
209 static int hf_smb2_mode_file_synchronous_io_alert = -1;
210 static int hf_smb2_mode_file_synchronous_io_nonalert = -1;
211 static int hf_smb2_mode_file_delete_on_close = -1;
212 static int hf_smb2_alignment_information = -1;
213 static int hf_smb2_buffer_code = -1;
214 static int hf_smb2_buffer_code_len = -1;
215 static int hf_smb2_buffer_code_flags_dyn = -1;
216 static int hf_smb2_olb_offset = -1;
217 static int hf_smb2_olb_length = -1;
218 static int hf_smb2_tag = -1;
219 static int hf_smb2_impersonation_level = -1;
220 static int hf_smb2_ioctl_function = -1;
221 static int hf_smb2_ioctl_function_device = -1;
222 static int hf_smb2_ioctl_function_access = -1;
223 static int hf_smb2_ioctl_function_function = -1;
224 static int hf_smb2_fsctl_pipe_wait_timeout = -1;
225 static int hf_smb2_fsctl_pipe_wait_name = -1;
226
227 static int hf_smb2_fsctl_odx_token_type = -1;
228 static int hf_smb2_fsctl_odx_token_idlen = -1;
229 static int hf_smb2_fsctl_odx_token_idraw = -1;
230 static int hf_smb2_fsctl_odx_token_ttl = -1;
231 static int hf_smb2_fsctl_odx_size = -1;
232 static int hf_smb2_fsctl_odx_flags = -1;
233 static int hf_smb2_fsctl_odx_file_offset = -1;
234 static int hf_smb2_fsctl_odx_copy_length = -1;
235 static int hf_smb2_fsctl_odx_xfer_length = -1;
236 static int hf_smb2_fsctl_odx_token_offset = -1;
237
238 static int hf_smb2_fsctl_sparse_flag = -1;
239 static int hf_smb2_fsctl_range_offset = -1;
240 static int hf_smb2_fsctl_range_length = -1;
241 static int hf_smb2_ioctl_function_method = -1;
242 static int hf_smb2_ioctl_resiliency_timeout = -1;
243 static int hf_smb2_ioctl_resiliency_reserved = -1;
244 static int hf_smb2_ioctl_shared_virtual_disk_support = -1;
245 static int hf_smb2_ioctl_shared_virtual_disk_handle_state = -1;
246 static int hf_smb2_ioctl_sqos_protocol_version = -1;
247 static int hf_smb2_ioctl_sqos_reserved = -1;
248 static int hf_smb2_ioctl_sqos_options = -1;
249 static int hf_smb2_ioctl_sqos_op_set_logical_flow_id = -1;
250 static int hf_smb2_ioctl_sqos_op_set_policy = -1;
251 static int hf_smb2_ioctl_sqos_op_probe_policy = -1;
252 static int hf_smb2_ioctl_sqos_op_get_status = -1;
253 static int hf_smb2_ioctl_sqos_op_update_counters = -1;
254 static int hf_smb2_ioctl_sqos_logical_flow_id = -1;
255 static int hf_smb2_ioctl_sqos_policy_id = -1;
256 static int hf_smb2_ioctl_sqos_initiator_id = -1;
257 static int hf_smb2_ioctl_sqos_limit = -1;
258 static int hf_smb2_ioctl_sqos_reservation = -1;
259 static int hf_smb2_ioctl_sqos_initiator_name = -1;
260 static int hf_smb2_ioctl_sqos_initiator_node_name = -1;
261 static int hf_smb2_ioctl_sqos_io_count_increment = -1;
262 static int hf_smb2_ioctl_sqos_normalized_io_count_increment = -1;
263 static int hf_smb2_ioctl_sqos_latency_increment = -1;
264 static int hf_smb2_ioctl_sqos_lower_latency_increment = -1;
265 static int hf_smb2_ioctl_sqos_bandwidth_limit = -1;
266 static int hf_smb2_ioctl_sqos_kilobyte_count_increment = -1;
267 static int hf_smb2_ioctl_sqos_time_to_live = -1;
268 static int hf_smb2_ioctl_sqos_status = -1;
269 static int hf_smb2_ioctl_sqos_maximum_io_rate = -1;
270 static int hf_smb2_ioctl_sqos_minimum_io_rate = -1;
271 static int hf_smb2_ioctl_sqos_base_io_size = -1;
272 static int hf_smb2_ioctl_sqos_reserved2 = -1;
273 static int hf_smb2_ioctl_sqos_maximum_bandwidth = -1;
274 static int hf_windows_sockaddr_family = -1;
275 static int hf_windows_sockaddr_port = -1;
276 static int hf_windows_sockaddr_in_addr = -1;
277 static int hf_windows_sockaddr_in6_flowinfo = -1;
278 static int hf_windows_sockaddr_in6_addr = -1;
279 static int hf_windows_sockaddr_in6_scope_id = -1;
280 static int hf_smb2_ioctl_network_interface_next_offset = -1;
281 static int hf_smb2_ioctl_network_interface_index = -1;
282 static int hf_smb2_ioctl_network_interface_rss_queue_count = -1;
283 static int hf_smb2_ioctl_network_interface_capabilities = -1;
284 static int hf_smb2_ioctl_network_interface_capability_rss = -1;
285 static int hf_smb2_ioctl_network_interface_capability_rdma = -1;
286 static int hf_smb2_ioctl_network_interface_link_speed = -1;
287 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
288 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
289 static int hf_smb2_ioctl_shadow_copy_count = -1;
290 static int hf_smb2_ioctl_shadow_copy_label = -1;
291 static int hf_smb2_compression_format = -1;
292 static int hf_smb2_checksum_algorithm = -1;
293 static int hf_smb2_integrity_reserved = -1;
294 static int hf_smb2_integrity_flags = -1;
295 static int hf_smb2_integrity_flags_enforcement_off = -1;
296 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
297 static int hf_smb2_lease_key = -1;
298 static int hf_smb2_lease_state = -1;
299 static int hf_smb2_lease_state_read_caching = -1;
300 static int hf_smb2_lease_state_handle_caching = -1;
301 static int hf_smb2_lease_state_write_caching = -1;
302 static int hf_smb2_lease_flags = -1;
303 static int hf_smb2_lease_flags_break_ack_required = -1;
304 static int hf_smb2_lease_flags_parent_lease_key_set = -1;
305 static int hf_smb2_lease_flags_break_in_progress = -1;
306 static int hf_smb2_lease_duration = -1;
307 static int hf_smb2_parent_lease_key = -1;
308 static int hf_smb2_lease_epoch = -1;
309 static int hf_smb2_lease_reserved = -1;
310 static int hf_smb2_lease_break_reason = -1;
311 static int hf_smb2_lease_access_mask_hint = -1;
312 static int hf_smb2_lease_share_mask_hint = -1;
313 static int hf_smb2_acct_name = -1;
314 static int hf_smb2_domain_name = -1;
315 static int hf_smb2_host_name = -1;
316 static int hf_smb2_auth_frame = -1;
317 static int hf_smb2_tcon_frame = -1;
318 static int hf_smb2_share_type = -1;
319 static int hf_smb2_signature = -1;
320 static int hf_smb2_credit_charge = -1;
321 static int hf_smb2_credits_requested = -1;
322 static int hf_smb2_credits_granted = -1;
323 static int hf_smb2_channel_sequence = -1;
324 static int hf_smb2_dialect_count = -1;
325 static int hf_smb2_security_mode = -1;
326 static int hf_smb2_secmode_flags_sign_required = -1;
327 static int hf_smb2_secmode_flags_sign_enabled = -1;
328 static int hf_smb2_ses_req_flags = -1;
329 static int hf_smb2_ses_req_flags_session_binding = -1;
330 static int hf_smb2_capabilities = -1;
331 static int hf_smb2_cap_dfs = -1;
332 static int hf_smb2_cap_leasing = -1;
333 static int hf_smb2_cap_large_mtu = -1;
334 static int hf_smb2_cap_multi_channel = -1;
335 static int hf_smb2_cap_persistent_handles = -1;
336 static int hf_smb2_cap_directory_leasing = -1;
337 static int hf_smb2_cap_encryption = -1;
338 static int hf_smb2_dialect = -1;
339 static int hf_smb2_max_trans_size = -1;
340 static int hf_smb2_max_read_size = -1;
341 static int hf_smb2_max_write_size = -1;
342 static int hf_smb2_channel = -1;
343 static int hf_smb2_rdma_v1_offset = -1;
344 static int hf_smb2_rdma_v1_token = -1;
345 static int hf_smb2_rdma_v1_length = -1;
346 static int hf_smb2_session_flags = -1;
347 static int hf_smb2_ses_flags_guest = -1;
348 static int hf_smb2_ses_flags_null = -1;
349 static int hf_smb2_ses_flags_encrypt = -1;
350 static int hf_smb2_share_flags = -1;
351 static int hf_smb2_share_flags_dfs = -1;
352 static int hf_smb2_share_flags_dfs_root = -1;
353 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
354 static int hf_smb2_share_flags_force_shared_delete = -1;
355 static int hf_smb2_share_flags_allow_namespace_caching = -1;
356 static int hf_smb2_share_flags_access_based_dir_enum = -1;
357 static int hf_smb2_share_flags_force_levelii_oplock = -1;
358 static int hf_smb2_share_flags_enable_hash_v1 = -1;
359 static int hf_smb2_share_flags_enable_hash_v2 = -1;
360 static int hf_smb2_share_flags_encrypt_data = -1;
361 static int hf_smb2_share_caching = -1;
362 static int hf_smb2_share_caps = -1;
363 static int hf_smb2_share_caps_dfs = -1;
364 static int hf_smb2_share_caps_continuous_availability = -1;
365 static int hf_smb2_share_caps_scaleout = -1;
366 static int hf_smb2_share_caps_cluster = -1;
367 static int hf_smb2_create_flags = -1;
368 static int hf_smb2_lock_count = -1;
369 static int hf_smb2_min_count = -1;
370 static int hf_smb2_remaining_bytes = -1;
371 static int hf_smb2_channel_info_offset = -1;
372 static int hf_smb2_channel_info_length = -1;
373 static int hf_smb2_channel_info_blob = -1;
374 static int hf_smb2_ioctl_flags = -1;
375 static int hf_smb2_ioctl_is_fsctl = -1;
376 static int hf_smb2_close_pq_attrib = -1;
377 static int hf_smb2_notify_watch_tree = -1;
378 static int hf_smb2_output_buffer_len = -1;
379 static int hf_smb2_notify_out_data = -1;
380 static int hf_smb2_notify_info = -1;
381 static int hf_smb2_notify_next_offset = -1;
382 static int hf_smb2_notify_action = -1;
383 static int hf_smb2_find_flags = -1;
384 static int hf_smb2_find_flags_restart_scans = -1;
385 static int hf_smb2_find_flags_single_entry = -1;
386 static int hf_smb2_find_flags_index_specified = -1;
387 static int hf_smb2_find_flags_reopen = -1;
388 static int hf_smb2_file_index = -1;
389 static int hf_smb2_file_directory_info = -1;
390 static int hf_smb2_both_directory_info = -1;
391 static int hf_smb2_short_name_len = -1;
392 static int hf_smb2_short_name = -1;
393 static int hf_smb2_id_both_directory_info = -1;
394 static int hf_smb2_full_directory_info = -1;
395 static int hf_smb2_lock_info = -1;
396 static int hf_smb2_lock_length = -1;
397 static int hf_smb2_lock_flags = -1;
398 static int hf_smb2_lock_flags_shared = -1;
399 static int hf_smb2_lock_flags_exclusive = -1;
400 static int hf_smb2_lock_flags_unlock = -1;
401 static int hf_smb2_lock_flags_fail_immediately = -1;
402 static int hf_smb2_dhnq_buffer_reserved = -1;
403 static int hf_smb2_dh2x_buffer_timeout = -1;
404 static int hf_smb2_dh2x_buffer_flags = -1;
405 static int hf_smb2_dh2x_buffer_flags_persistent_handle = -1;
406 static int hf_smb2_dh2x_buffer_reserved = -1;
407 static int hf_smb2_dh2x_buffer_create_guid = -1;
408 static int hf_smb2_APP_INSTANCE_buffer_struct_size = -1;
409 static int hf_smb2_APP_INSTANCE_buffer_reserved = -1;
410 static int hf_smb2_APP_INSTANCE_buffer_app_guid = -1;
411 static int hf_smb2_svhdx_open_device_context_version = -1;
412 static int hf_smb2_svhdx_open_device_context_has_initiator_id = -1;
413 static int hf_smb2_svhdx_open_device_context_reserved = -1;
414 static int hf_smb2_svhdx_open_device_context_initiator_id = -1;
415 static int hf_smb2_svhdx_open_device_context_flags = -1;
416 static int hf_smb2_svhdx_open_device_context_originator_flags = -1;
417 static int hf_smb2_svhdx_open_device_context_open_request_id = -1;
418 static int hf_smb2_svhdx_open_device_context_initiator_host_name_len = -1;
419 static int hf_smb2_svhdx_open_device_context_initiator_host_name = -1;
420 static int hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized = -1;
421 static int hf_smb2_svhdx_open_device_context_server_service_version = -1;
422 static int hf_smb2_svhdx_open_device_context_virtual_sector_size = -1;
423 static int hf_smb2_svhdx_open_device_context_physical_sector_size = -1;
424 static int hf_smb2_svhdx_open_device_context_virtual_size = -1;
425 static int hf_smb2_posix_v1_version = -1;
426 static int hf_smb2_posix_v1_request = -1;
427 static int hf_smb2_posix_v1_supported_features = -1;
428 static int hf_smb2_posix_v1_posix_lock = -1;
429 static int hf_smb2_posix_v1_posix_file_semantics = -1;
430 static int hf_smb2_posix_v1_posix_utf8_paths = -1;
431 static int hf_smb2_posix_v1_case_sensitive = -1;
432 static int hf_smb2_posix_v1_posix_will_convert_nt_acls = -1;
433 static int hf_smb2_posix_v1_posix_fileinfo = -1;
434 static int hf_smb2_posix_v1_posix_acls = -1;
435 static int hf_smb2_posix_v1_rich_acls = -1;
436 static int hf_smb2_aapl_command_code = -1;
437 static int hf_smb2_aapl_reserved = -1;
438 static int hf_smb2_aapl_server_query_bitmask = -1;
439 static int hf_smb2_aapl_server_query_bitmask_server_caps = -1;
440 static int hf_smb2_aapl_server_query_bitmask_volume_caps = -1;
441 static int hf_smb2_aapl_server_query_bitmask_model_info = -1;
442 static int hf_smb2_aapl_server_query_caps = -1;
443 static int hf_smb2_aapl_server_query_caps_supports_read_dir_attr = -1;
444 static int hf_smb2_aapl_server_query_caps_supports_osx_copyfile = -1;
445 static int hf_smb2_aapl_server_query_caps_unix_based = -1;
446 static int hf_smb2_aapl_server_query_caps_supports_nfs_ace = -1;
447 static int hf_smb2_aapl_server_query_volume_caps = -1;
448 static int hf_smb2_aapl_server_query_volume_caps_support_resolve_id = -1;
449 static int hf_smb2_aapl_server_query_volume_caps_case_sensitive = -1;
450 static int hf_smb2_aapl_server_query_volume_caps_supports_full_sync = -1;
451 static int hf_smb2_aapl_server_query_model_string = -1;
452 static int hf_smb2_aapl_server_query_server_path = -1;
453 static int hf_smb2_error_context_count = -1;
454 static int hf_smb2_error_reserved = -1;
455 static int hf_smb2_error_byte_count = -1;
456 static int hf_smb2_error_data = -1;
457 static int hf_smb2_reserved = -1;
458 static int hf_smb2_reserved_random = -1;
459 static int hf_smb2_transform_signature = -1;
460 static int hf_smb2_transform_nonce = -1;
461 static int hf_smb2_transform_msg_size = -1;
462 static int hf_smb2_transform_reserved = -1;
463 static int hf_smb2_encryption_aes128_ccm = -1;
464 static int hf_smb2_transform_enc_alg = -1;
465 static int hf_smb2_transform_encrypted_data = -1;
466 static int hf_smb2_server_component_smb2 = -1;
467 static int hf_smb2_server_component_smb2_transform = -1;
468 static int hf_smb2_truncated = -1;
469 static int hf_smb2_pipe_fragments = -1;
470 static int hf_smb2_pipe_fragment = -1;
471 static int hf_smb2_pipe_fragment_overlap = -1;
472 static int hf_smb2_pipe_fragment_overlap_conflict = -1;
473 static int hf_smb2_pipe_fragment_multiple_tails = -1;
474 static int hf_smb2_pipe_fragment_too_long_fragment = -1;
475 static int hf_smb2_pipe_fragment_error = -1;
476 static int hf_smb2_pipe_fragment_count = -1;
477 static int hf_smb2_pipe_reassembled_in = -1;
478 static int hf_smb2_pipe_reassembled_length = -1;
479 static int hf_smb2_pipe_reassembled_data = -1;
480 static int hf_smb2_cchunk_resume_key = -1;
481 static int hf_smb2_cchunk_count = -1;
482 static int hf_smb2_cchunk_src_offset = -1;
483 static int hf_smb2_cchunk_dst_offset = -1;
484 static int hf_smb2_cchunk_xfer_len = -1;
485 static int hf_smb2_cchunk_chunks_written = -1;
486 static int hf_smb2_cchunk_bytes_written = -1;
487 static int hf_smb2_cchunk_total_written = -1;
488 static int hf_smb2_symlink_error_response = -1;
489 static int hf_smb2_symlink_length = -1;
490 static int hf_smb2_symlink_error_tag = -1;
491 static int hf_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER = -1;
492 static int hf_smb2_reparse_tag = -1;
493 static int hf_smb2_reparse_data_length = -1;
494 static int hf_smb2_unparsed_path_length = -1;
495 static int hf_smb2_symlink_substitute_name = -1;
496 static int hf_smb2_symlink_print_name = -1;
497 static int hf_smb2_symlink_flags = -1;
498
499 static gint ett_smb2 = -1;
500 static gint ett_smb2_olb = -1;
501 static gint ett_smb2_ea = -1;
502 static gint ett_smb2_header = -1;
503 static gint ett_smb2_encrypted = -1;
504 static gint ett_smb2_command = -1;
505 static gint ett_smb2_secblob = -1;
506 static gint ett_smb2_negotiate_context_element = -1;
507 static gint ett_smb2_file_basic_info = -1;
508 static gint ett_smb2_file_standard_info = -1;
509 static gint ett_smb2_file_internal_info = -1;
510 static gint ett_smb2_file_ea_info = -1;
511 static gint ett_smb2_file_access_info = -1;
512 static gint ett_smb2_file_position_info = -1;
513 static gint ett_smb2_file_mode_info = -1;
514 static gint ett_smb2_file_alignment_info = -1;
515 static gint ett_smb2_file_all_info = -1;
516 static gint ett_smb2_file_allocation_info = -1;
517 static gint ett_smb2_file_endoffile_info = -1;
518 static gint ett_smb2_file_alternate_name_info = -1;
519 static gint ett_smb2_file_stream_info = -1;
520 static gint ett_smb2_file_pipe_info = -1;
521 static gint ett_smb2_file_compression_info = -1;
522 static gint ett_smb2_file_network_open_info = -1;
523 static gint ett_smb2_file_attribute_tag_info = -1;
524 static gint ett_smb2_file_rename_info = -1;
525 static gint ett_smb2_file_disposition_info = -1;
526 static gint ett_smb2_file_full_ea_info = -1;
527 static gint ett_smb2_fs_info_01 = -1;
528 static gint ett_smb2_fs_info_03 = -1;
529 static gint ett_smb2_fs_info_04 = -1;
530 static gint ett_smb2_fs_info_05 = -1;
531 static gint ett_smb2_fs_info_06 = -1;
532 static gint ett_smb2_fs_info_07 = -1;
533 static gint ett_smb2_fs_objectid_info = -1;
534 static gint ett_smb2_sec_info_00 = -1;
535 static gint ett_smb2_quota_info = -1;
536 static gint ett_smb2_query_quota_info = -1;
537 static gint ett_smb2_tid_tree = -1;
538 static gint ett_smb2_sesid_tree = -1;
539 static gint ett_smb2_create_chain_element = -1;
540 static gint ett_smb2_MxAc_buffer = -1;
541 static gint ett_smb2_QFid_buffer = -1;
542 static gint ett_smb2_RqLs_buffer = -1;
543 static gint ett_smb2_ioctl_function = -1;
544 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
545 static gint ett_smb2_flags = -1;
546 static gint ett_smb2_sec_mode = -1;
547 static gint ett_smb2_capabilities = -1;
548 static gint ett_smb2_ses_req_flags = -1;
549 static gint ett_smb2_ses_flags = -1;
550 static gint ett_smb2_lease_state = -1;
551 static gint ett_smb2_lease_flags = -1;
552 static gint ett_smb2_share_flags = -1;
553 static gint ett_smb2_create_rep_flags = -1;
554 static gint ett_smb2_share_caps = -1;
555 static gint ett_smb2_ioctl_flags = -1;
556 static gint ett_smb2_ioctl_network_interface = -1;
557 static gint ett_smb2_ioctl_sqos_opeations = -1;
558 static gint ett_smb2_fsctl_range_data = -1;
559 static gint ett_windows_sockaddr = -1;
560 static gint ett_smb2_close_flags = -1;
561 static gint ett_smb2_notify_info = -1;
562 static gint ett_smb2_notify_flags = -1;
563 static gint ett_smb2_write_flags = -1;
564 static gint ett_smb2_rdma_v1 = -1;
565 static gint ett_smb2_DH2Q_buffer = -1;
566 static gint ett_smb2_DH2C_buffer = -1;
567 static gint ett_smb2_dh2x_flags = -1;
568 static gint ett_smb2_APP_INSTANCE_buffer = -1;
569 static gint ett_smb2_svhdx_open_device_context = -1;
570 static gint ett_smb2_posix_v1_request = -1;
571 static gint ett_smb2_posix_v1_response = -1;
572 static gint ett_smb2_posix_v1_supported_features = -1;
573 static gint ett_smb2_aapl_create_context_request = -1;
574 static gint ett_smb2_aapl_server_query_bitmask = -1;
575 static gint ett_smb2_aapl_server_query_caps = -1;
576 static gint ett_smb2_aapl_create_context_response = -1;
577 static gint ett_smb2_aapl_server_query_volume_caps = -1;
578 static gint ett_smb2_integrity_flags = -1;
579 static gint ett_smb2_find_flags = -1;
580 static gint ett_smb2_file_directory_info = -1;
581 static gint ett_smb2_both_directory_info = -1;
582 static gint ett_smb2_id_both_directory_info = -1;
583 static gint ett_smb2_full_directory_info = -1;
584 static gint ett_smb2_file_name_info = -1;
585 static gint ett_smb2_lock_info = -1;
586 static gint ett_smb2_lock_flags = -1;
587 static gint ett_smb2_transform_enc_alg = -1;
588 static gint ett_smb2_buffercode = -1;
589 static gint ett_smb2_ioctl_network_interface_capabilities = -1;
590 static gint ett_qfr_entry = -1;
591 static gint ett_smb2_pipe_fragment = -1;
592 static gint ett_smb2_pipe_fragments = -1;
593 static gint ett_smb2_cchunk_entry = -1;
594 static gint ett_smb2_fsctl_odx_token = -1;
595 static gint ett_smb2_symlink_error_response = -1;
596 static gint ett_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER = -1;
597 static gint ett_smb2_error_data = -1;
598
599 static expert_field ei_smb2_invalid_length = EI_INIT;
600 static expert_field ei_smb2_bad_response = EI_INIT;
601 static expert_field ei_smb2_invalid_getinfo_offset = EI_INIT;
602 static expert_field ei_smb2_invalid_getinfo_size = EI_INIT;
603 static expert_field ei_smb2_empty_getinfo_buffer = EI_INIT;
604
605 static int smb2_tap = -1;
606 static int smb2_eo_tap = -1;
607
608 static dissector_handle_t gssapi_handle  = NULL;
609 static dissector_handle_t ntlmssp_handle = NULL;
610 static dissector_handle_t rsvd_handle = NULL;
611
612 static heur_dissector_list_t smb2_pipe_subdissector_list;
613
614 static const fragment_items smb2_pipe_frag_items = {
615         &ett_smb2_pipe_fragment,
616         &ett_smb2_pipe_fragments,
617         &hf_smb2_pipe_fragments,
618         &hf_smb2_pipe_fragment,
619         &hf_smb2_pipe_fragment_overlap,
620         &hf_smb2_pipe_fragment_overlap_conflict,
621         &hf_smb2_pipe_fragment_multiple_tails,
622         &hf_smb2_pipe_fragment_too_long_fragment,
623         &hf_smb2_pipe_fragment_error,
624         &hf_smb2_pipe_fragment_count,
625         &hf_smb2_pipe_reassembled_in,
626         &hf_smb2_pipe_reassembled_length,
627         &hf_smb2_pipe_reassembled_data,
628         "Fragments"
629 };
630
631 #define FILE_BYTE_ALIGNMENT 0x00
632 #define FILE_WORD_ALIGNMENT 0x01
633 #define FILE_LONG_ALIGNMENT 0x03
634 #define FILE_QUAD_ALIGNMENT 0x07
635 #define FILE_OCTA_ALIGNMENT 0x0f
636 #define FILE_32_BYTE_ALIGNMENT 0x1f
637 #define FILE_64_BYTE_ALIGNMENT 0x3f
638 #define FILE_128_BYTE_ALIGNMENT 0x7f
639 #define FILE_256_BYTE_ALIGNMENT 0xff
640 #define FILE_512_BYTE_ALIGNMENT 0x1ff
641 static const value_string smb2_alignment_vals[] = {
642         { FILE_BYTE_ALIGNMENT,     "FILE_BYTE_ALIGNMENT" },
643         { FILE_WORD_ALIGNMENT,     "FILE_WORD_ALIGNMENT" },
644         { FILE_LONG_ALIGNMENT,     "FILE_LONG_ALIGNMENT" },
645         { FILE_OCTA_ALIGNMENT,     "FILE_OCTA_ALIGNMENT" },
646         { FILE_32_BYTE_ALIGNMENT,  "FILE_32_BYTE_ALIGNMENT" },
647         { FILE_64_BYTE_ALIGNMENT,  "FILE_64_BYTE_ALIGNMENT" },
648         { FILE_128_BYTE_ALIGNMENT, "FILE_128_BYTE_ALIGNMENT" },
649         { FILE_256_BYTE_ALIGNMENT, "FILE_256_BYTE_ALIGNMENT" },
650         { FILE_512_BYTE_ALIGNMENT, "FILE_512_BYTE_ALIGNMENT" },
651         { 0, NULL }
652 };
653
654
655 #define SMB2_CLASS_FILE_INFO    0x01
656 #define SMB2_CLASS_FS_INFO      0x02
657 #define SMB2_CLASS_SEC_INFO     0x03
658 #define SMB2_CLASS_QUOTA_INFO   0x04
659 #define SMB2_CLASS_POSIX_INFO   0x80
660 static const value_string smb2_class_vals[] = {
661         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
662         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
663         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
664         { SMB2_CLASS_QUOTA_INFO, "QUOTA_INFO"},
665         { SMB2_CLASS_POSIX_INFO, "POSIX_INFO"},
666         { 0, NULL }
667 };
668
669 #define SMB2_SHARE_TYPE_DISK    0x01
670 #define SMB2_SHARE_TYPE_PIPE    0x02
671 #define SMB2_SHARE_TYPE_PRINT   0x03
672 static const value_string smb2_share_type_vals[] = {
673         { SMB2_SHARE_TYPE_DISK,         "Physical disk" },
674         { SMB2_SHARE_TYPE_PIPE,         "Named pipe" },
675         { SMB2_SHARE_TYPE_PRINT,        "Printer" },
676         { 0, NULL }
677 };
678
679
680 #define SMB2_FILE_BASIC_INFO          0x04
681 #define SMB2_FILE_STANDARD_INFO       0x05
682 #define SMB2_FILE_INTERNAL_INFO       0x06
683 #define SMB2_FILE_EA_INFO             0x07
684 #define SMB2_FILE_ACCESS_INFO         0x08
685 #define SMB2_FILE_RENAME_INFO         0x0a
686 #define SMB2_FILE_DISPOSITION_INFO    0x0d
687 #define SMB2_FILE_POSITION_INFO       0x0e
688 #define SMB2_FILE_FULL_EA_INFO        0x0f
689 #define SMB2_FILE_MODE_INFO           0x10
690 #define SMB2_FILE_ALIGNMENT_INFO      0x11
691 #define SMB2_FILE_ALL_INFO            0x12
692 #define SMB2_FILE_ALLOCATION_INFO     0x13
693 #define SMB2_FILE_ENDOFFILE_INFO      0x14
694 #define SMB2_FILE_ALTERNATE_NAME_INFO 0x15
695 #define SMB2_FILE_STREAM_INFO         0x16
696 #define SMB2_FILE_PIPE_INFO           0x17
697 #define SMB2_FILE_COMPRESSION_INFO    0x1c
698 #define SMB2_FILE_NETWORK_OPEN_INFO   0x22
699 #define SMB2_FILE_ATTRIBUTE_TAG_INFO  0x23
700
701 static const value_string smb2_file_info_levels[] = {
702         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
703         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
704         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
705         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
706         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
707         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
708         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
709         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
710         {SMB2_FILE_FULL_EA_INFO,        "SMB2_FILE_FULL_EA_INFO" },
711         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
712         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
713         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
714         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
715         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
716         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
717         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
718         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
719         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
720         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
721         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
722         { 0, NULL }
723 };
724 static value_string_ext smb2_file_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_file_info_levels);
725
726
727
728 #define SMB2_FS_INFO_01                 0x01
729 #define SMB2_FS_LABEL_INFO              0x02
730 #define SMB2_FS_INFO_03                 0x03
731 #define SMB2_FS_INFO_04                 0x04
732 #define SMB2_FS_INFO_05                 0x05
733 #define SMB2_FS_INFO_06                 0x06
734 #define SMB2_FS_INFO_07                 0x07
735 #define SMB2_FS_OBJECTID_INFO           0x08
736 #define SMB2_FS_DRIVER_PATH_INFO        0x09
737 #define SMB2_FS_VOLUME_FLAGS_INFO       0x0a
738 #define SMB2_FS_SECTOR_SIZE_INFO        0x0b
739
740 static const value_string smb2_fs_info_levels[] = {
741         {SMB2_FS_INFO_01,               "FileFsVolumeInformation" },
742         {SMB2_FS_LABEL_INFO,            "FileFsLabelInformation" },
743         {SMB2_FS_INFO_03,               "FileFsSizeInformation" },
744         {SMB2_FS_INFO_04,               "FileFsDeviceInformation" },
745         {SMB2_FS_INFO_05,               "FileFsAttributeInformation" },
746         {SMB2_FS_INFO_06,               "FileFsControlInformation" },
747         {SMB2_FS_INFO_07,               "FileFsFullSizeInformation" },
748         {SMB2_FS_OBJECTID_INFO,         "FileFsObjectIdInformation" },
749         {SMB2_FS_DRIVER_PATH_INFO,      "FileFsDriverPathInformation" },
750         {SMB2_FS_VOLUME_FLAGS_INFO,     "FileFsVolumeFlagsInformation" },
751         {SMB2_FS_SECTOR_SIZE_INFO,      "FileFsSectorSizeInformation" },
752         { 0, NULL }
753 };
754 static value_string_ext smb2_fs_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_fs_info_levels);
755
756 #define SMB2_SEC_INFO_00        0x00
757 static const value_string smb2_sec_info_levels[] = {
758         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
759         { 0, NULL }
760 };
761 static value_string_ext smb2_sec_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_sec_info_levels);
762
763 static const value_string smb2_posix_info_levels[] = {
764         { 0,    "QueryFileUnixBasic" },
765         { 1,    "QueryFileUnixLink" },
766         { 3,    "QueryFileUnixHLink" },
767         { 5,    "QueryFileUnixXAttr" },
768         { 0x0B, "QueryFileUnixInfo2" },
769         { 0, NULL }
770 };
771
772 static value_string_ext smb2_posix_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_posix_info_levels);
773
774 #define SMB2_FIND_DIRECTORY_INFO         0x01
775 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
776 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
777 #define SMB2_FIND_INDEX_SPECIFIED        0x04
778 #define SMB2_FIND_NAME_INFO              0x0C
779 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
780 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
781 static const value_string smb2_find_info_levels[] = {
782         { SMB2_FIND_DIRECTORY_INFO,             "SMB2_FIND_DIRECTORY_INFO" },
783         { SMB2_FIND_FULL_DIRECTORY_INFO,        "SMB2_FIND_FULL_DIRECTORY_INFO" },
784         { SMB2_FIND_BOTH_DIRECTORY_INFO,        "SMB2_FIND_BOTH_DIRECTORY_INFO" },
785         { SMB2_FIND_INDEX_SPECIFIED,            "SMB2_FIND_INDEX_SPECIFIED" },
786         { SMB2_FIND_NAME_INFO,                  "SMB2_FIND_NAME_INFO" },
787         { SMB2_FIND_ID_BOTH_DIRECTORY_INFO,     "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
788         { SMB2_FIND_ID_FULL_DIRECTORY_INFO,     "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
789         { 0, NULL }
790 };
791
792 #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001
793 #define SMB2_ENCRYPTION_CAPABILITIES        0x0002
794 static const value_string smb2_negotiate_context_types[] = {
795         { SMB2_PREAUTH_INTEGRITY_CAPABILITIES,  "SMB2_PREAUTH_INTEGRITY_CAPABILITIES" },
796         { SMB2_ENCRYPTION_CAPABILITIES, "SMB2_ENCRYPTION_CAPABILITIES" },
797         { 0, NULL }
798 };
799
800 #define SMB2_HASH_ALGORITHM_SHA_512    0x0001
801 static const value_string smb2_hash_algorithm_types[] = {
802         { SMB2_HASH_ALGORITHM_SHA_512, "SHA-512" },
803         { 0, NULL }
804 };
805
806 #define SMB2_CIPHER_AES_128_CCM        0x0001
807 #define SMB2_CIPHER_AES_128_GCM        0x0002
808 static const value_string smb2_cipher_types[] = {
809         { SMB2_CIPHER_AES_128_CCM, "AES-128-CCM" },
810         { SMB2_CIPHER_AES_128_GCM, "AES-128-GCM" },
811         { 0, NULL }
812 };
813
814 static const val64_string unique_unsolicited_response[] = {
815         { 0xffffffffffffffff, "unsolicited response" },
816         { 0, NULL }
817 };
818
819 #define SMB2_NUM_PROCEDURES     256
820
821 static void
822 smb2stat_init(struct register_srt* srt _U_, GArray* srt_array)
823 {
824         srt_stat_table *smb2_srt_table;
825         guint32 i;
826
827         smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", NULL);
828         for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
829         {
830                 init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
831         }
832 }
833
834 static int
835 smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
836 {
837         guint i = 0;
838         srt_stat_table *smb2_srt_table;
839         srt_data_t *data = (srt_data_t *)pss;
840         const smb2_info_t *si=(const smb2_info_t *)prv;
841
842         /* we are only interested in response packets */
843         if(!(si->flags&SMB2_FLAGS_RESPONSE)){
844                 return 0;
845         }
846         /* We should not include cancel and oplock break requests either */
847         if (si->opcode == SMB2_COM_CANCEL || si->opcode == SMB2_COM_BREAK) {
848                 return 0;
849         }
850
851         /* if we haven't seen the request, just ignore it */
852         if(!si->saved){
853                 return 0;
854         }
855
856         /* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
857          * not only add additional (bogus) transactions but also the latency associated with them.
858          * This can greatly inflate the maximum and average SRT stats especially in the case of
859          * retransmissions triggered by the expiry of the rexmit timer (RTOs). Only calculating SRT
860          * for the last received response accomplishes this goal without requiring the TCP pref
861          * "Do not call subdissectors for error packets" to be set. */
862         if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->num))
863                 return 0;
864
865         smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
866         add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
867         return 1;
868 }
869
870 /* Structure for SessionID <=> SessionKey mapping for decryption. */
871 typedef struct _smb2_seskey_field_t {
872         guchar *id;
873         guint id_len;
874         guchar *key;
875         guint key_len;
876 } smb2_seskey_field_t;
877
878 static smb2_seskey_field_t *seskey_list = NULL;
879 static guint num_seskey_list = 0;
880
881 static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
882
883 /* Callbacks for SessionID <=> SessionKey mapping. */
884 UAT_BUFFER_CB_DEF(seskey_list, id, smb2_seskey_field_t, id, id_len)
885 UAT_BUFFER_CB_DEF(seskey_list, key, smb2_seskey_field_t, key, key_len)
886
887 #define SMB_SESSION_ID_SIZE 8
888
889 static gboolean seskey_list_update_cb(void *r, char **err)
890 {
891         smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
892
893         *err = NULL;
894
895         if (rec->id_len != SMB_SESSION_ID_SIZE) {
896                 *err = g_strdup("Session ID must be " G_STRINGIFY(SMB_SESSION_ID_SIZE) " bytes long and in hexadecimal");
897                 return FALSE;
898         }
899
900         if (rec->key_len == 0 || rec->key_len > NTLMSSP_KEY_LEN) {
901                 *err = g_strdup("Session Key must be a non-empty hexadecimal string representing at most " G_STRINGIFY(NTLMSSP_KEY_LEN) " bytes");
902                 return FALSE;
903         }
904
905         return TRUE;
906 }
907
908 static void* seskey_list_copy_cb(void *n, const void *o, size_t siz _U_)
909 {
910         smb2_seskey_field_t *new_rec = (smb2_seskey_field_t *)n;
911         const smb2_seskey_field_t *old_rec = (const smb2_seskey_field_t *)o;
912
913         new_rec->id_len = old_rec->id_len;
914         new_rec->id = old_rec->id ? (guchar *)g_memdup(old_rec->id, old_rec->id_len) : NULL;
915         new_rec->key_len = old_rec->key_len;
916         new_rec->key = old_rec->key ? (guchar *)g_memdup(old_rec->key, old_rec->key_len) : NULL;
917
918         return new_rec;
919 }
920
921 static void seskey_list_free_cb(void *r)
922 {
923         smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
924
925         g_free(rec->id);
926         g_free(rec->key);
927 }
928
929 static gboolean seskey_find_sid_key(guint64 sesid, guint8 *out_key)
930 {
931         guint i;
932
933         for (i = 0; i < num_seskey_list; i++) {
934                 const smb2_seskey_field_t *p = &seskey_list[i];
935                 if (memcmp(&sesid, p->id, SMB_SESSION_ID_SIZE) == 0) {
936                         memset(out_key, 0, NTLMSSP_KEY_LEN);
937                         memcpy(out_key, p->key, p->key_len);
938                         return TRUE;
939                 }
940         }
941
942         return FALSE;
943 }
944
945 /* ExportObject preferences variable */
946 gboolean eosmb2_take_name_as_fid = FALSE ;
947
948 /* unmatched smb_saved_info structures.
949    For unmatched smb_saved_info structures we store the smb_saved_info
950    structure using the msg_id field.
951 */
952 static gint
953 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
954 {
955         const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
956         const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
957         return key1->msg_id == key2->msg_id;
958 }
959 static guint
960 smb2_saved_info_hash_unmatched(gconstpointer k)
961 {
962         const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
963         guint32 hash;
964
965         hash = (guint32) (key->msg_id&0xffffffff);
966         return hash;
967 }
968
969 /* matched smb_saved_info structures.
970    For matched smb_saved_info structures we store the smb_saved_info
971    structure using the msg_id field.
972 */
973 static gint
974 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
975 {
976         const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
977         const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
978         return key1->msg_id == key2->msg_id;
979 }
980 static guint
981 smb2_saved_info_hash_matched(gconstpointer k)
982 {
983         const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
984         guint32 hash;
985
986         hash = (guint32) (key->msg_id&0xffffffff);
987         return hash;
988 }
989
990 /* For Tids of a specific conversation.
991    This keeps track of tid->sharename mappings and other information about the
992    tid.
993    qqq
994    We might need to refine this if it occurs that tids are reused on a single
995    conversation.   we don't worry about that yet for simplicity
996 */
997 static gint
998 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
999 {
1000         const smb2_tid_info_t *key1 = (const smb2_tid_info_t *)k1;
1001         const smb2_tid_info_t *key2 = (const smb2_tid_info_t *)k2;
1002         return key1->tid == key2->tid;
1003 }
1004 static guint
1005 smb2_tid_info_hash(gconstpointer k)
1006 {
1007         const smb2_tid_info_t *key = (const smb2_tid_info_t *)k;
1008         guint32 hash;
1009
1010         hash = key->tid;
1011         return hash;
1012 }
1013
1014 /* For Uids of a specific conversation.
1015    This keeps track of uid->acct_name mappings and other information about the
1016    uid.
1017    qqq
1018    We might need to refine this if it occurs that uids are reused on a single
1019    conversation.   we don't worry about that yet for simplicity
1020 */
1021 static gint
1022 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
1023 {
1024         const smb2_sesid_info_t *key1 = (const smb2_sesid_info_t *)k1;
1025         const smb2_sesid_info_t *key2 = (const smb2_sesid_info_t *)k2;
1026         return key1->sesid == key2->sesid;
1027 }
1028 static guint
1029 smb2_sesid_info_hash(gconstpointer k)
1030 {
1031         const smb2_sesid_info_t *key = (const smb2_sesid_info_t *)k;
1032         guint32 hash;
1033
1034         hash = (guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
1035         return hash;
1036 }
1037
1038 /*
1039  * For File IDs of a specific conversation.
1040  * This keeps track of fid to name mapping and application level conversations
1041  * over named pipes.
1042  *
1043  * This handles implementation bugs, where the fid_persitent is 0 or
1044  * the fid_persitent/fid_volative is not unique per conversation.
1045  */
1046 static gint
1047 smb2_fid_info_equal(gconstpointer k1, gconstpointer k2)
1048 {
1049         const smb2_fid_info_t *key1 = (const smb2_fid_info_t *)k1;
1050         const smb2_fid_info_t *key2 = (const smb2_fid_info_t *)k2;
1051
1052         if (key1->fid_persistent != key2->fid_persistent) {
1053                 return 0;
1054         };
1055
1056         if (key1->fid_volatile != key2->fid_volatile) {
1057                 return 0;
1058         };
1059
1060         if (key1->sesid != key2->sesid) {
1061                 return 0;
1062         };
1063
1064         if (key1->tid != key2->tid) {
1065                 return 0;
1066         };
1067
1068         return 1;
1069 }
1070
1071 static guint
1072 smb2_fid_info_hash(gconstpointer k)
1073 {
1074         const smb2_fid_info_t *key = (const smb2_fid_info_t *)k;
1075         guint32 hash;
1076
1077         if (key->fid_persistent != 0) {
1078                 hash = (guint32)( ((key->fid_persistent>>32)&0xffffffff)+((key->fid_persistent)&0xffffffff) );
1079         } else {
1080                 hash = (guint32)( ((key->fid_volatile>>32)&0xffffffff)+((key->fid_volatile)&0xffffffff) );
1081         }
1082
1083         return hash;
1084 }
1085
1086 /* Callback for destroying the glib hash tables associated with a conversation
1087  * struct. */
1088 static gboolean
1089 smb2_conv_destroy(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
1090                   void *user_data)
1091 {
1092         smb2_conv_info_t *conv = (smb2_conv_info_t *)user_data;
1093
1094         g_hash_table_destroy(conv->matched);
1095         g_hash_table_destroy(conv->unmatched);
1096         g_hash_table_destroy(conv->fids);
1097         g_hash_table_destroy(conv->sesids);
1098         g_hash_table_destroy(conv->files);
1099
1100         /* This conversation is gone, return FALSE to indicate we don't
1101          * want to be called again for this conversation. */
1102         return FALSE;
1103 }
1104
1105 static void smb2_key_derivation(const guint8 *KI, guint32 KI_len,
1106                          const guint8 *Label, guint32 Label_len,
1107                          const guint8 *Context, guint32 Context_len,
1108                          guint8 KO[16])
1109 {
1110         gcry_md_hd_t  hd     = NULL;
1111         guint8        buf[4];
1112         guint8       *digest = NULL;
1113
1114         /*
1115          * a simplified version of
1116          * "NIST Special Publication 800-108" section 5.1
1117          * using hmac-sha256.
1118          */
1119         gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
1120         gcry_md_setkey(hd, KI, KI_len);
1121
1122         memset(buf, 0, sizeof(buf));
1123         buf[3] = 1;
1124         gcry_md_write(hd, buf, sizeof(buf));
1125         gcry_md_write(hd, Label, Label_len);
1126         gcry_md_write(hd, buf, 1);
1127         gcry_md_write(hd, Context, Context_len);
1128         buf[3] = 128;
1129         gcry_md_write(hd, buf, sizeof(buf));
1130
1131         digest = gcry_md_read(hd, GCRY_MD_SHA256);
1132
1133         memcpy(KO, digest, 16);
1134
1135         gcry_md_close(hd);
1136 }
1137
1138 /* for export-object-smb2 */
1139 static gchar *policy_hnd_to_file_id(const e_ctx_hnd *hnd) {
1140 gchar *file_id;
1141         file_id = wmem_strdup_printf(wmem_packet_scope(),
1142                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1143                         hnd->uuid.data1,
1144                         hnd->uuid.data2,
1145                         hnd->uuid.data3,
1146                         hnd->uuid.data4[0],
1147                         hnd->uuid.data4[1],
1148                         hnd->uuid.data4[2],
1149                         hnd->uuid.data4[3],
1150                         hnd->uuid.data4[4],
1151                         hnd->uuid.data4[5],
1152                         hnd->uuid.data4[6],
1153                         hnd->uuid.data4[7]);
1154         return file_id;
1155 }
1156 static guint smb2_eo_files_hash(gconstpointer k) {
1157         return g_str_hash(policy_hnd_to_file_id((const e_ctx_hnd *)k));
1158 }
1159 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2) {
1160 int     are_equal;
1161         const e_ctx_hnd *key1 = (const e_ctx_hnd *)k1;
1162         const e_ctx_hnd *key2 = (const e_ctx_hnd *)k2;
1163
1164         are_equal = (key1->uuid.data1==key2->uuid.data1 &&
1165                 key1->uuid.data2==key2->uuid.data2 &&
1166                 key1->uuid.data3==key2->uuid.data3 &&
1167                 key1->uuid.data4[0]==key2->uuid.data4[0] &&
1168                 key1->uuid.data4[1]==key2->uuid.data4[1] &&
1169                 key1->uuid.data4[2]==key2->uuid.data4[2] &&
1170                 key1->uuid.data4[3]==key2->uuid.data4[3] &&
1171                 key1->uuid.data4[4]==key2->uuid.data4[4] &&
1172                 key1->uuid.data4[5]==key2->uuid.data4[5] &&
1173                 key1->uuid.data4[6]==key2->uuid.data4[6] &&
1174                 key1->uuid.data4[7]==key2->uuid.data4[7]);
1175
1176         return are_equal;
1177 }
1178
1179 static void
1180 feed_eo_smb2(tvbuff_t * tvb,packet_info *pinfo,smb2_info_t * si, guint16 dataoffset,guint32 length, guint64 file_offset) {
1181
1182         char       *fid_name = NULL;
1183         guint32     open_frame = 0, close_frame = 0;
1184         tvbuff_t        *data_tvb = NULL;
1185         smb_eo_t        *eo_info;
1186         gchar           *file_id;
1187         gchar           *auxstring;
1188         gchar           **aux_string_v;
1189
1190         /* Create a new tvb to point to the payload data */
1191         data_tvb = tvb_new_subset_length(tvb, dataoffset, length);
1192         /* Create the eo_info to pass to the listener */
1193         eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
1194         /* Fill in eo_info */
1195         eo_info->smbversion=2;
1196         /* cmd == opcode */
1197         eo_info->cmd=si->opcode;
1198         /* We don't keep track of uid in SMB v2 */
1199         eo_info->uid=0;
1200
1201         /* Try to get file id and filename */
1202         file_id=policy_hnd_to_file_id(&si->saved->policy_hnd);
1203         dcerpc_fetch_polhnd_data(&si->saved->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num);
1204         if (fid_name && g_strcmp0(fid_name,"File: ")!=0) {
1205                 auxstring=fid_name;
1206                 /* Remove "File: " from filename */
1207                 if (g_str_has_prefix(auxstring, "File: ")) {
1208                         aux_string_v = g_strsplit(auxstring, "File: ", -1);
1209                         eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",aux_string_v[g_strv_length(aux_string_v)-1]);
1210                         g_strfreev(aux_string_v);
1211                 } else {
1212                         if (g_str_has_prefix(auxstring, "\\")) {
1213                                 eo_info->filename = wmem_strdup(wmem_packet_scope(), auxstring);
1214                         } else {
1215                                 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",auxstring);
1216                         }
1217                 }
1218         } else {
1219                 auxstring=wmem_strdup_printf(wmem_packet_scope(), "File_Id_%s", file_id);
1220                 eo_info->filename=auxstring;
1221         }
1222
1223
1224
1225         if (eosmb2_take_name_as_fid) {
1226                 eo_info->fid = g_str_hash(eo_info->filename);
1227         } else {
1228                 eo_info->fid = g_str_hash(file_id);
1229         }
1230
1231         /* tid, hostname, tree_id */
1232         if (si->tree) {
1233                 eo_info->tid=si->tree->tid;
1234                 if (strlen(si->tree->name)>0 && strlen(si->tree->name)<=256) {
1235                         eo_info->hostname = wmem_strdup(wmem_packet_scope(), si->tree->name);
1236                 } else {
1237                         eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,si->opcode),si->tree->tid);
1238                 }
1239         } else {
1240                 eo_info->tid=0;
1241                 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,si->opcode));
1242         }
1243
1244         /* packet number */
1245         eo_info->pkt_num = pinfo->num;
1246
1247         /* fid type */
1248         if (si->eo_file_info->attr_mask & SMB2_FLAGS_ATTR_DIRECTORY) {
1249                 eo_info->fid_type=SMB2_FID_TYPE_DIR;
1250         } else {
1251                 if (si->eo_file_info->attr_mask &
1252                         (SMB2_FLAGS_ATTR_ARCHIVE | SMB2_FLAGS_ATTR_NORMAL |
1253                          SMB2_FLAGS_ATTR_HIDDEN | SMB2_FLAGS_ATTR_READONLY |
1254                          SMB2_FLAGS_ATTR_SYSTEM) ) {
1255                         eo_info->fid_type=SMB2_FID_TYPE_FILE;
1256                 } else {
1257                         eo_info->fid_type=SMB2_FID_TYPE_OTHER;
1258                 }
1259         }
1260
1261         /* end_of_file */
1262         eo_info->end_of_file=si->eo_file_info->end_of_file;
1263
1264         /* data offset and chunk length */
1265         eo_info->smb_file_offset=file_offset;
1266         eo_info->smb_chunk_len=length;
1267         /* XXX is this right? */
1268         if (length<si->saved->bytes_moved) {
1269                 si->saved->file_offset=si->saved->file_offset+length;
1270                 si->saved->bytes_moved=si->saved->bytes_moved-length;
1271         }
1272
1273         /* Payload */
1274         eo_info->payload_len = length;
1275         eo_info->payload_data = tvb_get_ptr(data_tvb, 0, length);
1276
1277         tap_queue_packet(smb2_eo_tap, pinfo, eo_info);
1278
1279 }
1280
1281 static int dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
1282
1283
1284 /* This is a helper to dissect the common string type
1285  * uint16 offset
1286  * uint16 length
1287  * ...
1288  * char *string
1289  *
1290  * This function is called twice, first to decode the offset/length and
1291  * second time to dissect the actual string.
1292  * It is done this way since there is no guarantee that we have the full packet and we don't
1293  * want to abort dissection too early if the packet ends somewhere between the
1294  * length/offset and the actual buffer.
1295  *
1296  */
1297 enum offset_length_buffer_offset_size {
1298         OLB_O_UINT16_S_UINT16,
1299         OLB_O_UINT16_S_UINT32,
1300         OLB_O_UINT32_S_UINT32,
1301         OLB_S_UINT32_O_UINT32
1302 };
1303 typedef struct _offset_length_buffer_t {
1304         guint32 off;
1305         guint32 len;
1306         int off_offset;
1307         int len_offset;
1308         enum offset_length_buffer_offset_size offset_size;
1309         int hfindex;
1310 } offset_length_buffer_t;
1311 static int
1312 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
1313                                enum offset_length_buffer_offset_size offset_size, int hfindex)
1314 {
1315         olb->hfindex = hfindex;
1316         olb->offset_size = offset_size;
1317         switch (offset_size) {
1318         case OLB_O_UINT16_S_UINT16:
1319                 olb->off = tvb_get_letohs(tvb, offset);
1320                 olb->off_offset = offset;
1321                 offset += 2;
1322                 olb->len = tvb_get_letohs(tvb, offset);
1323                 olb->len_offset = offset;
1324                 offset += 2;
1325                 break;
1326         case OLB_O_UINT16_S_UINT32:
1327                 olb->off = tvb_get_letohs(tvb, offset);
1328                 olb->off_offset = offset;
1329                 offset += 2;
1330                 olb->len = tvb_get_letohl(tvb, offset);
1331                 olb->len_offset = offset;
1332                 offset += 4;
1333                 break;
1334         case OLB_O_UINT32_S_UINT32:
1335                 olb->off = tvb_get_letohl(tvb, offset);
1336                 olb->off_offset = offset;
1337                 offset += 4;
1338                 olb->len = tvb_get_letohl(tvb, offset);
1339                 olb->len_offset = offset;
1340                 offset += 4;
1341                 break;
1342         case OLB_S_UINT32_O_UINT32:
1343                 olb->len = tvb_get_letohl(tvb, offset);
1344                 olb->len_offset = offset;
1345                 offset += 4;
1346                 olb->off = tvb_get_letohl(tvb, offset);
1347                 olb->off_offset = offset;
1348                 offset += 4;
1349                 break;
1350         }
1351
1352         return offset;
1353 }
1354
1355 #define OLB_TYPE_UNICODE_STRING         0x01
1356 #define OLB_TYPE_ASCII_STRING           0x02
1357 static const char *
1358 dissect_smb2_olb_off_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int base, int type)
1359 {
1360         int         len, off;
1361         proto_item *item = NULL;
1362         proto_tree *tree = NULL;
1363         const char *name = NULL;
1364         guint16     bc;
1365         int         offset;
1366
1367         olb->off += base;
1368
1369         offset = olb->off;
1370         len = olb->len;
1371         off = olb->off;
1372         bc = tvb_captured_length_remaining(tvb, offset);
1373
1374
1375         /* sanity check */
1376         tvb_ensure_bytes_exist(tvb, off, len);
1377         if (((off+len)<off)
1378         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1379                 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1380                                     "Invalid offset/length. Malformed packet");
1381
1382                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1383
1384                 return NULL;
1385         }
1386
1387
1388         switch (type) {
1389         case OLB_TYPE_UNICODE_STRING:
1390                 name = get_unicode_or_ascii_string(tvb, &off,
1391                         TRUE, &len, TRUE, TRUE, &bc);
1392                 if (!name) {
1393                         name = "";
1394                 }
1395                 if (parent_tree) {
1396                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
1397                         tree = proto_item_add_subtree(item, ett_smb2_olb);
1398                 }
1399                 break;
1400         case OLB_TYPE_ASCII_STRING:
1401                 name = get_unicode_or_ascii_string(tvb, &off,
1402                         FALSE, &len, TRUE, TRUE, &bc);
1403                 if (!name) {
1404                         name = "";
1405                 }
1406                 if (parent_tree) {
1407                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
1408                         tree = proto_item_add_subtree(item, ett_smb2_olb);
1409                 }
1410                 break;
1411         }
1412
1413         switch (olb->offset_size) {
1414         case OLB_O_UINT16_S_UINT16:
1415                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1416                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1417                 break;
1418         case OLB_O_UINT16_S_UINT32:
1419                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1420                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1421                 break;
1422         case OLB_O_UINT32_S_UINT32:
1423                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1424                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1425                 break;
1426         case OLB_S_UINT32_O_UINT32:
1427                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1428                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1429                 break;
1430         }
1431
1432         return name;
1433 }
1434
1435 static const char *
1436 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
1437 {
1438         return dissect_smb2_olb_off_string(pinfo, parent_tree, tvb, olb, 0, type);
1439 }
1440
1441 static void
1442 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
1443                         offset_length_buffer_t *olb, smb2_info_t *si,
1444                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
1445 {
1446         int         len, off;
1447         proto_item *sub_item = NULL;
1448         proto_tree *sub_tree = NULL;
1449         tvbuff_t   *sub_tvb  = NULL;
1450         int         offset;
1451
1452         offset = olb->off;
1453         len    = olb->len;
1454         off    = olb->off;
1455
1456         /* sanity check */
1457         tvb_ensure_bytes_exist(tvb, off, len);
1458         if (((off+len)<off)
1459             || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1460                 proto_tree_add_expert_format(parent_tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1461                                     "Invalid offset/length. Malformed packet");
1462
1463                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1464
1465                 return;
1466         }
1467
1468         switch (olb->offset_size) {
1469         case OLB_O_UINT16_S_UINT16:
1470                 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1471                 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1472                 break;
1473         case OLB_O_UINT16_S_UINT32:
1474                 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1475                 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1476                 break;
1477         case OLB_O_UINT32_S_UINT32:
1478                 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1479                 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1480                 break;
1481         case OLB_S_UINT32_O_UINT32:
1482                 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1483                 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1484                 break;
1485         }
1486
1487         /* if we don't want/need a subtree */
1488         if (olb->hfindex == -1) {
1489                 sub_item = parent_tree;
1490                 sub_tree = parent_tree;
1491         } else {
1492                 if (parent_tree) {
1493                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
1494                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
1495                 }
1496         }
1497
1498         if (off == 0 || len == 0) {
1499                 proto_item_append_text(sub_item, ": NO DATA");
1500                 return;
1501         }
1502
1503         if (!dissector) {
1504                 return;
1505         }
1506
1507         sub_tvb = tvb_new_subset_length_caplen(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
1508
1509         dissector(sub_tvb, pinfo, sub_tree, si);
1510 }
1511
1512 static int
1513 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
1514 {
1515         if (olb->off == 0) {
1516                 return offset;
1517         }
1518         return MAX(offset, (int)(olb->off + olb->len));
1519 }
1520
1521 typedef struct _smb2_function {
1522         int (*request) (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1523         int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1524 } smb2_function;
1525
1526 static const true_false_string tfs_smb2_svhdx_has_initiator_id = {
1527         "Has an initiator id",
1528         "Does not have an initiator id"
1529 };
1530
1531 static const true_false_string tfs_flags_response = {
1532         "This is a RESPONSE",
1533         "This is a REQUEST"
1534 };
1535
1536 static const true_false_string tfs_flags_async_cmd = {
1537         "This is an ASYNC command",
1538         "This is a SYNC command"
1539 };
1540
1541 static const true_false_string tfs_flags_dfs_op = {
1542         "This is a DFS OPERATION",
1543         "This is a normal operation"
1544 };
1545
1546 static const true_false_string tfs_flags_chained = {
1547         "This pdu a CHAINED command",
1548         "This pdu is NOT a chained command"
1549 };
1550
1551 static const true_false_string tfs_flags_signature = {
1552         "This pdu is SIGNED",
1553         "This pdu is NOT signed"
1554 };
1555
1556 static const true_false_string tfs_flags_replay_operation = {
1557         "This is a REPLAY OPEARATION",
1558         "This is NOT a replay operation"
1559 };
1560
1561 static const true_false_string tfs_flags_priority_mask = {
1562         "This pdu contains a PRIORITY",
1563         "This pdu does NOT contain a PRIORITY1"
1564 };
1565
1566 static const true_false_string tfs_cap_dfs = {
1567         "This host supports DFS",
1568         "This host does NOT support DFS"
1569 };
1570
1571 static const true_false_string tfs_cap_leasing = {
1572         "This host supports LEASING",
1573         "This host does NOT support LEASING"
1574 };
1575
1576 static const true_false_string tfs_cap_large_mtu = {
1577         "This host supports LARGE_MTU",
1578         "This host does NOT support LARGE_MTU"
1579 };
1580
1581 static const true_false_string tfs_cap_multi_channel = {
1582         "This host supports MULTI CHANNEL",
1583         "This host does NOT support MULTI CHANNEL"
1584 };
1585
1586 static const true_false_string tfs_cap_persistent_handles = {
1587         "This host supports PERSISTENT HANDLES",
1588         "This host does NOT support PERSISTENT HANDLES"
1589 };
1590
1591 static const true_false_string tfs_cap_directory_leasing = {
1592         "This host supports DIRECTORY LEASING",
1593         "This host does NOT support DIRECTORY LEASING"
1594 };
1595
1596 static const true_false_string tfs_cap_encryption = {
1597         "This host supports ENCRYPTION",
1598         "This host does NOT support ENCRYPTION"
1599 };
1600
1601 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rss = {
1602         "This interface supports RSS",
1603         "This interface does not support RSS"
1604 };
1605
1606 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rdma = {
1607         "This interface supports RDMA",
1608         "This interface does not support RDMA"
1609 };
1610
1611 static const value_string file_region_usage_vals[] = {
1612         { 0x00000001, "FILE_REGION_USAGE_VALID_CACHED_DATA" },
1613         { 0, NULL }
1614 };
1615
1616 static const value_string originator_flags_vals[] = {
1617         { 1, "SVHDX_ORIGINATOR_PVHDPARSER" },
1618         { 4, "SVHDX_ORIGINATOR_VHDMP" },
1619         { 0, NULL }
1620 };
1621
1622 static const value_string posix_locks_vals[] = {
1623         { 1, "POSIX_V1_POSIX_LOCK" },
1624         { 0, NULL }
1625 };
1626
1627 static const value_string posix_utf8_paths_vals[] = {
1628         { 1, "POSIX_V1_UTF8_PATHS" },
1629         { 0, NULL }
1630 };
1631
1632 static const value_string posix_file_semantics_vals[] = {
1633         { 1, "POSIX_V1_POSIX_FILE_SEMANTICS" },
1634         { 0, NULL }
1635 };
1636
1637 static const value_string posix_case_sensitive_vals[] = {
1638         { 1, "POSIX_V1_CASE_SENSITIVE" },
1639         { 0, NULL }
1640 };
1641
1642 static const value_string posix_will_convert_ntacls_vals[] = {
1643         { 1, "POSIX_V1_WILL_CONVERT_NT_ACLS" },
1644         { 0, NULL }
1645 };
1646
1647 static const value_string posix_fileinfo_vals[] = {
1648         { 1, "POSIX_V1_POSIX_FILEINFO" },
1649         { 0, NULL }
1650 };
1651
1652 static const value_string posix_acls_vals[] = {
1653         { 1, "POSIX_V1_POSIX_ACLS" },
1654         { 0, NULL }
1655 };
1656
1657 static const value_string posix_rich_acls_vals[] = {
1658         { 1, "POSIX_V1_RICH_ACLS" },
1659         { 0, NULL }
1660 };
1661
1662 static const value_string compression_format_vals[] = {
1663         { 0, "COMPRESSION_FORMAT_NONE" },
1664         { 1, "COMPRESSION_FORMAT_DEFAULT" },
1665         { 2, "COMPRESSION_FORMAT_LZNT1" },
1666         { 0, NULL }
1667 };
1668
1669 static const value_string checksum_algorithm_vals[] = {
1670         { 0x0000, "CHECKSUM_TYPE_NONE" },
1671         { 0x0002, "CHECKSUM_TYPE_CRC64" },
1672         { 0xFFFF, "CHECKSUM_TYPE_UNCHANGED" },
1673         { 0, NULL }
1674 };
1675
1676 /* Note: All uncommented are "dissector not implemented" */
1677 static const value_string smb2_ioctl_vals[] = {
1678         {0x00060194, "FSCTL_DFS_GET_REFERRALS"},                      /* dissector implemented */
1679         {0x000601B0, "FSCTL_DFS_GET_REFERRALS_EX"},
1680         {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
1681         {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
1682         {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
1683         {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
1684         {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
1685         {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
1686         {0x00090018, "FSCTL_LOCK_VOLUME"},
1687         {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
1688         {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
1689         {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
1690         {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
1691         {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
1692         {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
1693         {0x0009003C, "FSCTL_GET_COMPRESSION"},                        /* dissector implemented */
1694         {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
1695         {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
1696         {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
1697         {0x00090058, "FSCTL_QUERY_FAT_BPB"},
1698         {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
1699         {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
1700         {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
1701         {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
1702         {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
1703         {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
1704         {0x00090074, "FSCTL_MOVE_FILE"},
1705         {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
1706         {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
1707         {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
1708         {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
1709         {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
1710         {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
1711         {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
1712         {0x0009009C, "FSCTL_GET_OBJECT_ID"},                          /* dissector implemented */
1713         {0x000900A4, "FSCTL_SET_REPARSE_POINT"},                      /* dissector implemented */
1714         {0x000900A8, "FSCTL_GET_REPARSE_POINT"},                      /* dissector implemented */
1715         {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},                /* dissector implemented */
1716         {0x000900C4, "FSCTL_SET_SPARSE"},                             /* dissector implemented */
1717         {0x000900D4, "FSCTL_SET_ENCRYPTION"},
1718         {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
1719         {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
1720         {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
1721         {0x000900F0, "FSCTL_EXTEND_VOLUME"},
1722         {0x00090244, "FSCTL_CSV_TUNNEL_REQUEST"},
1723         {0x0009027C, "FSCTL_GET_INTEGRITY_INFORMATION"},
1724         {0x00090284, "FSCTL_QUERY_FILE_REGIONS"},                     /* dissector implemented */
1725         {0x000902c8, "FSCTL_CSV_SYNC_TUNNEL_REQUEST"},
1726         {0x00090300, "FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT"},      /* dissector implemented */
1727         {0x00090304, "FSCTL_SVHDX_SYNC_TUNNEL_REQUEST"},              /* dissector implemented */
1728         {0x00090308, "FSCTL_SVHDX_SET_INITIATOR_INFORMATION"},
1729         {0x0009030C, "FSCTL_SET_EXTERNAL_BACKING"},
1730         {0x00090310, "FSCTL_GET_EXTERNAL_BACKING"},
1731         {0x00090314, "FSCTL_DELETE_EXTERNAL_BACKING"},
1732         {0x00090318, "FSCTL_ENUM_EXTERNAL_BACKING"},
1733         {0x0009031F, "FSCTL_ENUM_OVERLAY"},
1734         {0x00090350, "FSCTL_STORAGE_QOS_CONTROL"},                    /* dissector implemented */
1735         {0x00090364, "FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST"},             /* dissector implemented */
1736         {0x000940B3, "FSCTL_ENUM_USN_DATA"},
1737         {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
1738         {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
1739         {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},                 /* dissector implemented */
1740         {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
1741         {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
1742         {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
1743         {0x00094264, "FSCTL_OFFLOAD_READ"},                           /* dissector implemented */
1744         {0x00098098, "FSCTL_SET_OBJECT_ID"},                          /* dissector implemented */
1745         {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
1746         {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
1747         {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
1748         {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},                 /* dissector implemented */
1749         {0x000980C8, "FSCTL_SET_ZERO_DATA"},                          /* dissector implemented */
1750         {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
1751         {0x00098208, "FSCTL_FILE_LEVEL_TRIM"},
1752         {0x00098268, "FSCTL_OFFLOAD_WRITE"},                          /* dissector implemented */
1753         {0x0009C040, "FSCTL_SET_COMPRESSION"},                        /* dissector implemented */
1754         {0x0009C280, "FSCTL_SET_INTEGRITY_INFORMATION"},              /* dissector implemented */
1755         {0x00110018, "FSCTL_PIPE_WAIT"},                              /* dissector implemented */
1756         {0x0011400C, "FSCTL_PIPE_PEEK"},
1757         {0x0011C017, "FSCTL_PIPE_TRANSCEIVE"},                        /* dissector implemented */
1758         {0x00140078, "FSCTL_SRV_REQUEST_RESUME_KEY"},
1759         {0x001401D4, "FSCTL_LMR_REQUEST_RESILIENCY"},                 /* dissector implemented */
1760         {0x001401FC, "FSCTL_QUERY_NETWORK_INTERFACE_INFO"},           /* dissector implemented */
1761         {0x00140200, "FSCTL_VALIDATE_NEGOTIATE_INFO_224"},            /* dissector implemented */
1762         {0x00140204, "FSCTL_VALIDATE_NEGOTIATE_INFO"},                /* dissector implemented */
1763         {0x00144064, "FSCTL_SRV_ENUMERATE_SNAPSHOTS"},                /* dissector implemented */
1764         {0x001440F2, "FSCTL_SRV_COPYCHUNK"},
1765         {0x001441bb, "FSCTL_SRV_READ_HASH"},
1766         {0x001480F2, "FSCTL_SRV_COPYCHUNK_WRITE"},
1767         { 0, NULL }
1768 };
1769 static value_string_ext smb2_ioctl_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_vals);
1770
1771 static const value_string smb2_ioctl_device_vals[] = {
1772         { 0x0001, "BEEP" },
1773         { 0x0002, "CD_ROM" },
1774         { 0x0003, "CD_ROM_FILE_SYSTEM" },
1775         { 0x0004, "CONTROLLER" },
1776         { 0x0005, "DATALINK" },
1777         { 0x0006, "DFS" },
1778         { 0x0007, "DISK" },
1779         { 0x0008, "DISK_FILE_SYSTEM" },
1780         { 0x0009, "FILE_SYSTEM" },
1781         { 0x000a, "INPORT_PORT" },
1782         { 0x000b, "KEYBOARD" },
1783         { 0x000c, "MAILSLOT" },
1784         { 0x000d, "MIDI_IN" },
1785         { 0x000e, "MIDI_OUT" },
1786         { 0x000f, "MOUSE" },
1787         { 0x0010, "MULTI_UNC_PROVIDER" },
1788         { 0x0011, "NAMED_PIPE" },
1789         { 0x0012, "NETWORK" },
1790         { 0x0013, "NETWORK_BROWSER" },
1791         { 0x0014, "NETWORK_FILE_SYSTEM" },
1792         { 0x0015, "NULL" },
1793         { 0x0016, "PARALLEL_PORT" },
1794         { 0x0017, "PHYSICAL_NETCARD" },
1795         { 0x0018, "PRINTER" },
1796         { 0x0019, "SCANNER" },
1797         { 0x001a, "SERIAL_MOUSE_PORT" },
1798         { 0x001b, "SERIAL_PORT" },
1799         { 0x001c, "SCREEN" },
1800         { 0x001d, "SOUND" },
1801         { 0x001e, "STREAMS" },
1802         { 0x001f, "TAPE" },
1803         { 0x0020, "TAPE_FILE_SYSTEM" },
1804         { 0x0021, "TRANSPORT" },
1805         { 0x0022, "UNKNOWN" },
1806         { 0x0023, "VIDEO" },
1807         { 0x0024, "VIRTUAL_DISK" },
1808         { 0x0025, "WAVE_IN" },
1809         { 0x0026, "WAVE_OUT" },
1810         { 0x0027, "8042_PORT" },
1811         { 0x0028, "NETWORK_REDIRECTOR" },
1812         { 0x0029, "BATTERY" },
1813         { 0x002a, "BUS_EXTENDER" },
1814         { 0x002b, "MODEM" },
1815         { 0x002c, "VDM" },
1816         { 0x002d, "MASS_STORAGE" },
1817         { 0x002e, "SMB" },
1818         { 0x002f, "KS" },
1819         { 0x0030, "CHANGER" },
1820         { 0x0031, "SMARTCARD" },
1821         { 0x0032, "ACPI" },
1822         { 0x0033, "DVD" },
1823         { 0x0034, "FULLSCREEN_VIDEO" },
1824         { 0x0035, "DFS_FILE_SYSTEM" },
1825         { 0x0036, "DFS_VOLUME" },
1826         { 0x0037, "SERENUM" },
1827         { 0x0038, "TERMSRV" },
1828         { 0x0039, "KSEC" },
1829         { 0, NULL }
1830 };
1831 static value_string_ext smb2_ioctl_device_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_device_vals);
1832
1833 static const value_string smb2_ioctl_access_vals[] = {
1834         { 0x00, "FILE_ANY_ACCESS" },
1835         { 0x01, "FILE_READ_ACCESS" },
1836         { 0x02, "FILE_WRITE_ACCESS" },
1837         { 0x03, "FILE_READ_WRITE_ACCESS" },
1838         { 0, NULL }
1839 };
1840
1841 static const value_string smb2_ioctl_method_vals[] = {
1842         { 0x00, "METHOD_BUFFERED" },
1843         { 0x01, "METHOD_IN_DIRECT" },
1844         { 0x02, "METHOD_OUT_DIRECT" },
1845         { 0x03, "METHOD_NEITHER" },
1846         { 0, NULL }
1847 };
1848
1849 static const value_string smb2_ioctl_shared_virtual_disk_vals[] = {
1850         { 0x01, "SharedVirtualDisksSupported" },
1851         { 0x07, "SharedVirtualDiskCDPSnapshotsSupported" },
1852         { 0, NULL }
1853 };
1854
1855 static const value_string smb2_ioctl_shared_virtual_disk_hstate_vals[] = {
1856         { 0x00, "HandleStateNone" },
1857         { 0x01, "HandleStateFileShared" },
1858         { 0x03, "HandleStateShared" },
1859         { 0, NULL }
1860 };
1861
1862 /* this is called from both smb and smb2. */
1863 int
1864 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
1865 {
1866         proto_item *item = NULL;
1867         proto_tree *tree = NULL;
1868         guint32     ioctl_function;
1869
1870         if (parent_tree) {
1871                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1872                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
1873         }
1874
1875         ioctl_function = tvb_get_letohl(tvb, offset);
1876         if (ioctlfunc)
1877                 *ioctlfunc = ioctl_function;
1878         if (ioctl_function) {
1879                 const gchar *unknown = "unknown";
1880                 const gchar *ioctl_name = val_to_str_ext_const(ioctl_function,
1881                                                                &smb2_ioctl_vals_ext,
1882                                                                unknown);
1883
1884                 /*
1885                  * val_to_str_const() doesn't work with a unknown == NULL
1886                  */
1887                 if (ioctl_name == unknown) {
1888                         ioctl_name = NULL;
1889                 }
1890
1891                 if (ioctl_name != NULL) {
1892                         col_append_fstr(
1893                                 pinfo->cinfo, COL_INFO, " %s", ioctl_name);
1894                 }
1895
1896                 /* device */
1897                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1898                 if (ioctl_name == NULL) {
1899                         col_append_fstr(
1900                                 pinfo->cinfo, COL_INFO, " %s",
1901                                 val_to_str_ext((ioctl_function>>16)&0xffff, &smb2_ioctl_device_vals_ext,
1902                                 "Unknown (0x%08X)"));
1903                 }
1904
1905                 /* access */
1906                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1907
1908                 /* function */
1909                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1910                 if (ioctl_name == NULL) {
1911                         col_append_fstr(
1912                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
1913                                 (ioctl_function>>2)&0x0fff);
1914                 }
1915
1916                 /* method */
1917                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1918         }
1919
1920         offset += 4;
1921
1922         return offset;
1923 }
1924
1925 /* fake the dce/rpc support structures so we can piggy back on
1926  * dissect_nt_policy_hnd()   since this will allow us
1927  * a cheap way to track where FIDs are opened, closed
1928  * and fid->filename mappings
1929  * if we want to do those things in the future.
1930  */
1931 #define FID_MODE_OPEN           0
1932 #define FID_MODE_CLOSE          1
1933 #define FID_MODE_USE            2
1934 #define FID_MODE_DHNQ           3
1935 #define FID_MODE_DHNC           4
1936 static int
1937 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
1938 {
1939         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1940         static dcerpc_info        di; /* fake dcerpc_info struct */
1941         static dcerpc_call_value  call_data;
1942         e_ctx_hnd   policy_hnd;
1943         e_ctx_hnd   *policy_hnd_hashtablekey;
1944         proto_item *hnd_item   = NULL;
1945         char       *fid_name;
1946         guint32     open_frame = 0, close_frame = 0;
1947         smb2_eo_file_info_t     *eo_file_info;
1948         smb2_fid_info_t sfi_key;
1949         smb2_fid_info_t *sfi = NULL;
1950
1951         sfi_key.fid_persistent = tvb_get_letoh64(tvb, offset);
1952         sfi_key.fid_volatile = tvb_get_letoh64(tvb, offset+8);
1953         sfi_key.sesid = si->sesid;
1954         sfi_key.tid = si->tid;
1955         sfi_key.name = NULL;
1956
1957         di.conformant_run = 0;
1958         /* we need di->call_data->flags.NDR64 == 0 */
1959         di.call_data = &call_data;
1960
1961         switch (mode) {
1962         case FID_MODE_OPEN:
1963                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1964                 if (!pinfo->fd->flags.visited) {
1965                         sfi = wmem_new(wmem_file_scope(), smb2_fid_info_t);
1966                         *sfi = sfi_key;
1967                         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1968                                 sfi->name = wmem_strdup(wmem_file_scope(), (char *)si->saved->extra_info);
1969                         } else {
1970                                 sfi->name = wmem_strdup_printf(wmem_file_scope(), "[unknown]");
1971                         }
1972
1973                         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1974                                 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: %s", (char *)si->saved->extra_info);
1975                         } else {
1976                                 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: ");
1977                         }
1978                         dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1979                                                   fid_name);
1980
1981                         g_hash_table_insert(si->conv->fids, sfi, sfi);
1982                         si->file = sfi;
1983
1984                         /* If needed, create the file entry and save the policy hnd */
1985                         if (si->saved) {
1986                                 si->saved->file = sfi;
1987                                 si->saved->policy_hnd = policy_hnd;
1988                         }
1989
1990                         if (si->conv) {
1991                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1992                                 if (!eo_file_info) {
1993                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1994                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1995                                         memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1996                                         eo_file_info->end_of_file=0;
1997                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1998                                 }
1999                                 si->eo_file_info=eo_file_info;
2000                         }
2001                 }
2002                 break;
2003         case FID_MODE_CLOSE:
2004                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
2005                 break;
2006         case FID_MODE_USE:
2007         case FID_MODE_DHNQ:
2008         case FID_MODE_DHNC:
2009                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
2010                 break;
2011         }
2012
2013         si->file = (smb2_fid_info_t *)g_hash_table_lookup(si->conv->fids, &sfi_key);
2014         if (si->file) {
2015                 if (si->saved) {
2016                         si->saved->file = si->file;
2017                 }
2018                 if (si->file->name) {
2019                         if (hnd_item) {
2020                                 proto_item_append_text(hnd_item, " File: %s", si->file->name);
2021                         }
2022                         col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", si->file->name);
2023                 }
2024         }
2025
2026         if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
2027                 /* look for the eo_file_info */
2028                 if (!si->eo_file_info) {
2029                         if (si->saved) { si->saved->policy_hnd = policy_hnd; }
2030                         if (si->conv) {
2031                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
2032                                 if (eo_file_info) {
2033                                         si->eo_file_info=eo_file_info;
2034                                 } else { /* XXX This should never happen */
2035                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
2036                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
2037                                         memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
2038                                         eo_file_info->end_of_file=0;
2039                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
2040                                 }
2041                         }
2042
2043                 }
2044         }
2045
2046         return offset;
2047 }
2048
2049
2050 /* this info level is unique to SMB2 and differst from the corresponding
2051  * SMB_FILE_ALL_INFO in SMB
2052  */
2053 static int
2054 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2055 {
2056         proto_item *item = NULL;
2057         proto_tree *tree = NULL;
2058         int         length;
2059         const char *name = "";
2060         guint16     bc;
2061         static const int *mode_fields[] = {
2062                 &hf_smb2_mode_file_write_through,
2063                 &hf_smb2_mode_file_sequential_only,
2064                 &hf_smb2_mode_file_no_intermediate_buffering,
2065                 &hf_smb2_mode_file_synchronous_io_alert,
2066                 &hf_smb2_mode_file_synchronous_io_nonalert,
2067                 &hf_smb2_mode_file_delete_on_close,
2068                 NULL,
2069         };
2070
2071         if (parent_tree) {
2072                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
2073                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
2074         }
2075
2076         /* create time */
2077         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2078
2079         /* last access */
2080         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2081
2082         /* last write */
2083         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2084
2085         /* last change */
2086         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2087
2088         /* File Attributes */
2089         offset = dissect_file_ext_attr(tvb, tree, offset);
2090
2091         /* some unknown bytes */
2092         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2093         offset += 4;
2094
2095         /* allocation size */
2096         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2097         offset += 8;
2098
2099         /* end of file */
2100         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2101         offset += 8;
2102
2103         /* number of links */
2104         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2105         offset += 4;
2106
2107         /* delete pending */
2108         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2109         offset += 1;
2110
2111         /* is directory */
2112         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2113         offset += 1;
2114
2115         /* padding */
2116         offset += 2;
2117
2118         /* file id */
2119         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2120         offset += 8;
2121
2122         /* ea size */
2123         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2124         offset += 4;
2125
2126         /* access mask */
2127         offset = dissect_smb_access_mask(tvb, tree, offset);
2128
2129         /* Position Information */
2130         proto_tree_add_item(tree, hf_smb2_position_information, tvb, offset, 8, ENC_NA);
2131         offset += 8;
2132
2133         /* Mode Information */
2134         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_mode_information, ett_smb2_file_mode_info, mode_fields, ENC_LITTLE_ENDIAN);
2135         offset += 4;
2136
2137         /* Alignment Information */
2138         proto_tree_add_item(tree, hf_smb2_alignment_information, tvb, offset, 4, ENC_NA);
2139         offset +=4;
2140
2141         /* file name length */
2142         length = tvb_get_letohs(tvb, offset);
2143         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2144         offset += 4;
2145
2146         /* file name */
2147         if (length) {
2148                 bc = tvb_captured_length_remaining(tvb, offset);
2149                 name = get_unicode_or_ascii_string(tvb, &offset,
2150                         TRUE, &length, TRUE, TRUE, &bc);
2151                 if (name) {
2152                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
2153                                 offset, length, name);
2154                 }
2155
2156         }
2157         offset += length;
2158
2159         return offset;
2160 }
2161
2162
2163 static int
2164 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2165 {
2166         proto_item *item = NULL;
2167         proto_tree *tree = NULL;
2168         guint16     bc;
2169         gboolean    trunc;
2170
2171         if (parent_tree) {
2172                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, ENC_NA);
2173                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
2174         }
2175
2176         bc = tvb_captured_length_remaining(tvb, offset);
2177         offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2178
2179         return offset;
2180 }
2181
2182 static int
2183 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2184 {
2185         proto_item *item = NULL;
2186         proto_tree *tree = NULL;
2187         guint16     bc;
2188         gboolean    trunc;
2189
2190         if (parent_tree) {
2191                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, ENC_NA);
2192                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
2193         }
2194
2195         bc = tvb_captured_length_remaining(tvb, offset);
2196         offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2197
2198         return offset;
2199 }
2200
2201 static int
2202 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2203 {
2204         proto_item *item = NULL;
2205         proto_tree *tree = NULL;
2206         guint16     bc;
2207         gboolean    trunc;
2208
2209         if (parent_tree) {
2210                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, ENC_NA);
2211                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
2212         }
2213
2214         bc = tvb_captured_length_remaining(tvb, offset);
2215         offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
2216
2217         return offset;
2218 }
2219
2220
2221 static int
2222 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2223 {
2224         proto_item *item = NULL;
2225         proto_tree *tree = NULL;
2226
2227         if (parent_tree) {
2228                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, ENC_NA);
2229                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
2230         }
2231
2232         /* create time */
2233         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2234
2235         /* last access */
2236         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2237
2238         /* last write */
2239         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2240
2241         /* last change */
2242         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2243
2244         /* File Attributes */
2245         offset = dissect_file_ext_attr(tvb, tree, offset);
2246
2247         /* some unknown bytes */
2248         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2249         offset += 4;
2250
2251         return offset;
2252 }
2253
2254 static int
2255 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2256 {
2257         proto_item *item = NULL;
2258         proto_tree *tree = NULL;
2259         guint16     bc;
2260         gboolean    trunc;
2261
2262         if (parent_tree) {
2263                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, ENC_NA);
2264                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
2265         }
2266
2267         bc = tvb_captured_length_remaining(tvb, offset);
2268         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2269
2270         return offset;
2271 }
2272 static int
2273 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2274 {
2275         proto_item *item = NULL;
2276         proto_tree *tree = NULL;
2277         guint16     bc;
2278         gboolean    trunc;
2279
2280         if (parent_tree) {
2281                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, ENC_NA);
2282                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
2283         }
2284
2285         bc = tvb_captured_length_remaining(tvb, offset);
2286         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2287
2288         return offset;
2289 }
2290 static int
2291 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2292 {
2293         proto_item *item = NULL;
2294         proto_tree *tree = NULL;
2295         guint16     bc;
2296         gboolean    trunc;
2297
2298         if (parent_tree) {
2299                 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, ENC_NA);
2300                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
2301         }
2302
2303         bc = tvb_captured_length_remaining(tvb, offset);
2304         offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2305
2306         return offset;
2307 }
2308 static int
2309 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2310 {
2311         proto_item *item = NULL;
2312         proto_tree *tree = NULL;
2313         guint16     bc;
2314         gboolean    trunc;
2315
2316         if (parent_tree) {
2317                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, ENC_NA);
2318                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
2319         }
2320
2321         bc = tvb_captured_length_remaining(tvb, offset);
2322         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2323
2324         return offset;
2325 }
2326 static int
2327 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2328 {
2329         proto_item *item = NULL;
2330         proto_tree *tree = NULL;
2331         guint16     bc;
2332         gboolean    trunc;
2333
2334         if (parent_tree) {
2335                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, ENC_NA);
2336                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
2337         }
2338
2339         bc = tvb_captured_length_remaining(tvb, offset);
2340         offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2341
2342         return offset;
2343 }
2344
2345 static int
2346 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2347 {
2348         proto_item *item = NULL;
2349         proto_tree *tree = NULL;
2350
2351         if (parent_tree) {
2352                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, ENC_NA);
2353                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
2354         }
2355
2356         /* access mask */
2357         offset = dissect_smb_access_mask(tvb, tree, offset);
2358
2359         return offset;
2360 }
2361
2362 static int
2363 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2364 {
2365         proto_item *item = NULL;
2366         proto_tree *tree = NULL;
2367         guint16     bc;
2368         gboolean    trunc;
2369
2370         if (parent_tree) {
2371                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, ENC_NA);
2372                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
2373         }
2374
2375         bc = tvb_captured_length_remaining(tvb, offset);
2376         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2377
2378         return offset;
2379 }
2380
2381 static int
2382 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2383 {
2384         proto_item *item = NULL;
2385         proto_tree *tree = NULL;
2386         guint16     bc;
2387         gboolean    trunc;
2388
2389         if (parent_tree) {
2390                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, ENC_NA);
2391                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
2392         }
2393
2394         bc = tvb_captured_length_remaining(tvb, offset);
2395         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
2396
2397         return offset;
2398 }
2399
2400 static int
2401 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2402 {
2403         proto_item *item = NULL;
2404         proto_tree *tree = NULL;
2405         guint16     bc;
2406         gboolean    trunc;
2407
2408         if (parent_tree) {
2409                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, ENC_NA);
2410                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
2411         }
2412
2413         bc = tvb_captured_length_remaining(tvb, offset);
2414         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2415
2416         return offset;
2417 }
2418
2419 static int
2420 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2421 {
2422         proto_item *item = NULL;
2423         proto_tree *tree = NULL;
2424         guint16     bc;
2425         gboolean    trunc;
2426
2427         if (parent_tree) {
2428                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, ENC_NA);
2429                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
2430         }
2431
2432         bc = tvb_captured_length_remaining(tvb, offset);
2433         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2434
2435         return offset;
2436 }
2437
2438 static int
2439 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2440 {
2441         proto_item *item = NULL;
2442         proto_tree *tree = NULL;
2443         guint16     bc;
2444         gboolean    trunc;
2445
2446         if (parent_tree) {
2447                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, ENC_NA);
2448                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
2449         }
2450
2451
2452         bc = tvb_captured_length_remaining(tvb, offset);
2453         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2454
2455         return offset;
2456 }
2457
2458 static int
2459 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2460 {
2461         proto_item *item = NULL;
2462         proto_tree *tree = NULL;
2463         guint16     bc;
2464         gboolean    trunc;
2465
2466         if (parent_tree) {
2467                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, ENC_NA);
2468                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
2469         }
2470
2471
2472         bc = tvb_captured_length_remaining(tvb, offset);
2473         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2474
2475         return offset;
2476 }
2477
2478 static const true_false_string tfs_disposition_delete_on_close = {
2479         "DELETE this file when closed",
2480         "Normal access, do not delete on close"
2481 };
2482
2483 static int
2484 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2485 {
2486         proto_item *item = NULL;
2487         proto_tree *tree = NULL;
2488
2489         if (parent_tree) {
2490                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, ENC_NA);
2491                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
2492         }
2493
2494         /* file disposition */
2495         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2496
2497         return offset;
2498 }
2499
2500 static int
2501 dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2502 {
2503         proto_item *item = NULL;
2504         proto_tree *tree = NULL;
2505         guint32     next_offset;
2506         guint8      ea_name_len;
2507         guint16     ea_data_len;
2508
2509         if (parent_tree) {
2510                 item = proto_tree_add_item(parent_tree, hf_smb2_file_full_ea_info, tvb, offset, -1, ENC_NA);
2511                 tree = proto_item_add_subtree(item, ett_smb2_file_full_ea_info);
2512         }
2513
2514         while (1) {
2515                 int length;
2516                 const char *name = "";
2517                 const char *data = "";
2518                 guint16 bc;
2519                 int start_offset = offset;
2520                 proto_item *ea_item;
2521                 proto_tree *ea_tree;
2522
2523                 ea_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_ea, &ea_item, "EA:");
2524
2525                 /* next offset */
2526                 next_offset = tvb_get_letohl(tvb, offset);
2527                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2528                 offset += 4;
2529
2530                 /* EA flags */
2531                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2532                 offset += 1;
2533
2534                 /* EA Name Length */
2535                 ea_name_len = tvb_get_guint8(tvb, offset);
2536                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2537                 offset += 1;
2538
2539                 /* EA Data Length */
2540                 ea_data_len = tvb_get_letohs(tvb, offset);
2541                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2542                 offset += 2;
2543
2544                 /* ea name */
2545                 length = ea_name_len;
2546                 if (length) {
2547                         bc = tvb_captured_length_remaining(tvb, offset);
2548                         name = get_unicode_or_ascii_string(tvb, &offset,
2549                                 FALSE, &length, TRUE, TRUE, &bc);
2550                         if (name) {
2551                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
2552                                         offset, length + 1, name);
2553                         }
2554                 }
2555
2556                 /* The name is terminated with a NULL */
2557                 offset += ea_name_len + 1;
2558
2559                 /* ea data */
2560                 length = ea_data_len;
2561                 if (length) {
2562                         bc = tvb_captured_length_remaining(tvb, offset);
2563                         data = get_unicode_or_ascii_string(tvb, &offset,
2564                                 FALSE, &length, TRUE, TRUE, &bc);
2565                         /*
2566                          * We put the data here ...
2567                          */
2568                         proto_tree_add_item(ea_tree, hf_smb2_ea_data, tvb,
2569                                         offset, length, ENC_NA);
2570                 }
2571                 offset += ea_data_len;
2572
2573
2574                 if (ea_item) {
2575                         proto_item_append_text(ea_item, " %s := %s", name, data);
2576                 }
2577                 proto_item_set_len(ea_item, offset-start_offset);
2578
2579
2580                 if (!next_offset) {
2581                         break;
2582                 }
2583
2584                 offset = start_offset+next_offset;
2585         }
2586
2587         return offset;
2588 }
2589
2590 static const true_false_string tfs_replace_if_exists = {
2591         "Replace the target if it exists",
2592         "Fail if the target exists"
2593 };
2594
2595 static int
2596 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2597 {
2598         proto_item *item = NULL;
2599         proto_tree *tree = NULL;
2600         int         length;
2601         const char *name = "";
2602         guint16     bc;
2603
2604
2605         if (parent_tree) {
2606                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, ENC_NA);
2607                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
2608         }
2609
2610         /* ReplaceIfExists */
2611         proto_tree_add_item(tree, hf_smb2_replace_if, tvb, offset, 1, ENC_NA);
2612         offset += 1;
2613
2614         /* reserved */
2615         proto_tree_add_item(tree, hf_smb2_reserved_random, tvb, offset, 7, ENC_NA);
2616         offset += 7;
2617
2618         /* Root Directory Handle, MBZ */
2619         proto_tree_add_item(tree, hf_smb2_root_directory_mbz, tvb, offset, 8, ENC_NA);
2620         offset += 8;
2621
2622         /* file name length */
2623         length = tvb_get_letohs(tvb, offset);
2624         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2625         offset += 4;
2626
2627         /* file name */
2628         if (length) {
2629                 bc = tvb_captured_length_remaining(tvb, offset);
2630                 name = get_unicode_or_ascii_string(tvb, &offset,
2631                         TRUE, &length, TRUE, TRUE, &bc);
2632                 if (name) {
2633                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
2634                                 offset, length, name);
2635                 }
2636
2637                 col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s", name);
2638         }
2639         offset += length;
2640
2641         return offset;
2642 }
2643
2644 static int
2645 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2646 {
2647         proto_item *item = NULL;
2648         proto_tree *tree = NULL;
2649
2650         if (parent_tree) {
2651                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, ENC_NA);
2652                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
2653         }
2654
2655         /* security descriptor */
2656         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_captured_length_remaining(tvb, offset), NULL);
2657
2658         return offset;
2659 }
2660
2661 static int
2662 dissect_smb2_quota_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2663 {
2664         proto_item *item = NULL;
2665         proto_tree *tree = NULL;
2666         guint16 bcp;
2667
2668         if (parent_tree) {
2669                 item = proto_tree_add_item(parent_tree, hf_smb2_quota_info, tvb, offset, -1, ENC_NA);
2670                 tree = proto_item_add_subtree(item, ett_smb2_quota_info);
2671         }
2672
2673         bcp = tvb_captured_length_remaining(tvb, offset);
2674         offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
2675
2676         return offset;
2677 }
2678
2679 static int
2680 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2681 {
2682         proto_item *item = NULL;
2683         proto_tree *tree = NULL;
2684         guint16     bc;
2685
2686         if (parent_tree) {
2687                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, ENC_NA);
2688                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
2689         }
2690
2691         bc = tvb_captured_length_remaining(tvb, offset);
2692         offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2693
2694         return offset;
2695 }
2696
2697 static int
2698 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2699 {
2700         proto_item *item = NULL;
2701         proto_tree *tree = NULL;
2702         guint16     bc;
2703
2704         if (parent_tree) {
2705                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, ENC_NA);
2706                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
2707         }
2708
2709         bc = tvb_captured_length_remaining(tvb, offset);
2710         offset = dissect_nt_quota(tvb, tree, offset, &bc);
2711
2712         return offset;
2713 }
2714
2715 static int
2716 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2717 {
2718         proto_item *item = NULL;
2719         proto_tree *tree = NULL;
2720
2721         if (parent_tree) {
2722                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, ENC_NA);
2723                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
2724         }
2725
2726         /* FILE_OBJECTID_BUFFER */
2727         offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2728
2729         return offset;
2730 }
2731
2732 static int
2733 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2734 {
2735         proto_item *item = NULL;
2736         proto_tree *tree = NULL;
2737         guint16     bc;
2738
2739         if (parent_tree) {
2740                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, ENC_NA);
2741                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
2742         }
2743
2744         bc = tvb_captured_length_remaining(tvb, offset);
2745         offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2746
2747         return offset;
2748 }
2749
2750 static int
2751 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2752 {
2753         proto_item *item = NULL;
2754         proto_tree *tree = NULL;
2755         guint16     bc;
2756
2757         if (parent_tree) {
2758                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, ENC_NA);
2759                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
2760         }
2761
2762
2763         bc = tvb_captured_length_remaining(tvb, offset);
2764         offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2765
2766         return offset;
2767 }
2768
2769 static int
2770 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2771 {
2772         proto_item *item = NULL;
2773         proto_tree *tree = NULL;
2774         guint16     bc;
2775
2776         if (parent_tree) {
2777                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, ENC_NA);
2778                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
2779         }
2780
2781
2782         bc = tvb_captured_length_remaining(tvb, offset);
2783         offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2784
2785         return offset;
2786 }
2787
2788 static int
2789 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2790 {
2791         proto_item *item = NULL;
2792         proto_tree *tree = NULL;
2793         guint16     bc;
2794
2795         if (parent_tree) {
2796                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, ENC_NA);
2797                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
2798         }
2799
2800
2801         bc = tvb_captured_length_remaining(tvb, offset);
2802         offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
2803
2804         return offset;
2805 }
2806
2807 static const value_string oplock_vals[] = {
2808         { 0x00, "No oplock" },
2809         { 0x01, "Level2 oplock" },
2810         { 0x08, "Exclusive oplock" },
2811         { 0x09, "Batch oplock" },
2812         { 0xff, "Lease" },
2813         { 0, NULL }
2814 };
2815
2816 static int
2817 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2818 {
2819         proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2820
2821         offset += 1;
2822         return offset;
2823 }
2824
2825 static int
2826 dissect_smb2_buffercode(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 *length)
2827 {
2828         proto_tree *tree;
2829         proto_item *item;
2830         guint16 buffer_code;
2831
2832         /* dissect the first 2 bytes of the command PDU */
2833         buffer_code = tvb_get_letohs(tvb, offset);
2834         item = proto_tree_add_uint(parent_tree, hf_smb2_buffer_code, tvb, offset, 2, buffer_code);
2835         tree = proto_item_add_subtree(item, ett_smb2_buffercode);
2836         proto_tree_add_item(tree, hf_smb2_buffer_code_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2837         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2838         offset += 2;
2839
2840         if (length) {
2841                 *length = buffer_code; /*&0xfffe don't mask it here, mask it on caller side */
2842         }
2843
2844         return offset;
2845 }
2846
2847 #define NEGPROT_CAP_DFS         0x00000001
2848 #define NEGPROT_CAP_LEASING     0x00000002
2849 #define NEGPROT_CAP_LARGE_MTU   0x00000004
2850 #define NEGPROT_CAP_MULTI_CHANNEL       0x00000008
2851 #define NEGPROT_CAP_PERSISTENT_HANDLES  0x00000010
2852 #define NEGPROT_CAP_DIRECTORY_LEASING   0x00000020
2853 #define NEGPROT_CAP_ENCRYPTION          0x00000040
2854 static int
2855 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2856 {
2857         static const int * flags[] = {
2858                 &hf_smb2_cap_dfs,
2859                 &hf_smb2_cap_leasing,
2860                 &hf_smb2_cap_large_mtu,
2861                 &hf_smb2_cap_multi_channel,
2862                 &hf_smb2_cap_persistent_handles,
2863                 &hf_smb2_cap_directory_leasing,
2864                 &hf_smb2_cap_encryption,
2865                 NULL
2866         };
2867
2868         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_capabilities, ett_smb2_capabilities, flags, ENC_LITTLE_ENDIAN);
2869         offset += 4;
2870
2871         return offset;
2872 }
2873
2874
2875
2876 #define NEGPROT_SIGN_REQ        0x0002
2877 #define NEGPROT_SIGN_ENABLED    0x0001
2878
2879 static int
2880 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2881 {
2882         static const int * flags[] = {
2883                 &hf_smb2_secmode_flags_sign_enabled,
2884                 &hf_smb2_secmode_flags_sign_required,
2885                 NULL
2886         };
2887
2888         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_security_mode, ett_smb2_sec_mode, flags, ENC_LITTLE_ENDIAN);
2889         offset += 1;
2890
2891         return offset;
2892 }
2893
2894 #define SES_REQ_FLAGS_SESSION_BINDING           0x01
2895
2896 static int
2897 dissect_smb2_ses_req_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2898 {
2899         static const int * flags[] = {
2900                 &hf_smb2_ses_req_flags_session_binding,
2901                 NULL
2902         };
2903
2904         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_ses_req_flags, ett_smb2_ses_req_flags, flags, ENC_LITTLE_ENDIAN);
2905         offset += 1;
2906
2907         return offset;
2908 }
2909
2910 #define SES_FLAGS_GUEST         0x0001
2911 #define SES_FLAGS_NULL          0x0002
2912 #define SES_FLAGS_ENCRYPT       0x0004
2913
2914 static int
2915 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2916 {
2917         static const int * flags[] = {
2918                 &hf_smb2_ses_flags_guest,
2919                 &hf_smb2_ses_flags_null,
2920                 &hf_smb2_ses_flags_encrypt,
2921                 NULL
2922         };
2923
2924         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_session_flags, ett_smb2_ses_flags, flags, ENC_LITTLE_ENDIAN);
2925         offset += 2;
2926
2927         return offset;
2928 }
2929
2930 #define SHARE_FLAGS_manual_caching              0x00000000
2931 #define SHARE_FLAGS_auto_caching                0x00000010
2932 #define SHARE_FLAGS_vdo_caching                 0x00000020
2933 #define SHARE_FLAGS_no_caching                  0x00000030
2934
2935 static const value_string share_cache_vals[] = {
2936         { SHARE_FLAGS_manual_caching,   "Manual caching" },
2937         { SHARE_FLAGS_auto_caching,     "Auto caching" },
2938         { SHARE_FLAGS_vdo_caching,      "VDO caching" },
2939         { SHARE_FLAGS_no_caching,       "No caching" },
2940         { 0, NULL }
2941 };
2942
2943 #define SHARE_FLAGS_dfs                         0x00000001
2944 #define SHARE_FLAGS_dfs_root                    0x00000002
2945 #define SHARE_FLAGS_restrict_exclusive_opens    0x00000100
2946 #define SHARE_FLAGS_force_shared_delete         0x00000200
2947 #define SHARE_FLAGS_allow_namespace_caching     0x00000400
2948 #define SHARE_FLAGS_access_based_dir_enum       0x00000800
2949 #define SHARE_FLAGS_force_levelii_oplock        0x00001000
2950 #define SHARE_FLAGS_enable_hash_v1              0x00002000
2951 #define SHARE_FLAGS_enable_hash_v2              0x00004000
2952 #define SHARE_FLAGS_encryption_required         0x00008000
2953
2954 static int
2955 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
2956 {
2957         static const int *sf_fields[] = {
2958                 &hf_smb2_share_flags_dfs,
2959                 &hf_smb2_share_flags_dfs_root,
2960                 &hf_smb2_share_flags_restrict_exclusive_opens,
2961                 &hf_smb2_share_flags_force_shared_delete,
2962                 &hf_smb2_share_flags_allow_namespace_caching,
2963                 &hf_smb2_share_flags_access_based_dir_enum,
2964                 &hf_smb2_share_flags_force_levelii_oplock,
2965                 &hf_smb2_share_flags_enable_hash_v1,
2966                 &hf_smb2_share_flags_enable_hash_v2,
2967                 &hf_smb2_share_flags_encrypt_data,
2968                 NULL
2969         };
2970         proto_item *item;
2971         guint32 cp;
2972
2973         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, ENC_LITTLE_ENDIAN);
2974
2975         cp = tvb_get_letohl(tvb, offset);
2976         cp &= 0x00000030;
2977         proto_tree_add_uint_format(item, hf_smb2_share_caching, tvb, offset, 4, cp, "Caching policy: %s (%08x)", val_to_str(cp, share_cache_vals, "Unknown:%u"), cp);
2978
2979
2980         offset += 4;
2981
2982         return offset;
2983 }
2984
2985 #define SHARE_CAPS_DFS                          0x00000008
2986 #define SHARE_CAPS_CONTINUOUS_AVAILABILITY      0x00000010
2987 #define SHARE_CAPS_SCALEOUT                     0x00000020
2988 #define SHARE_CAPS_CLUSTER                      0x00000040
2989
2990 static int
2991 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
2992 {
2993         static const int *sc_fields[] = {
2994                 &hf_smb2_share_caps_dfs,
2995                 &hf_smb2_share_caps_continuous_availability,
2996                 &hf_smb2_share_caps_scaleout,
2997                 &hf_smb2_share_caps_cluster,
2998                 NULL
2999         };
3000
3001         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, ENC_LITTLE_ENDIAN);
3002
3003         offset += 4;
3004
3005         return offset;
3006 }
3007
3008 static void
3009 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
3010 {
3011         if ((tvb_captured_length(tvb)>=7)
3012         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))) {
3013                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
3014         } else {
3015                 call_dissector(gssapi_handle, tvb, pinfo, tree);
3016         }
3017 }
3018
3019 /*
3020  * Derive client and server decryption keys from the secret session key
3021  * and set them in the session object.
3022  */
3023 static void smb2_set_session_keys(smb2_sesid_info_t *sesid, const guint8 *session_key)
3024 {
3025         if (memcmp(session_key, zeros, NTLMSSP_KEY_LEN) != 0) {
3026                 smb2_key_derivation(session_key,
3027                                     NTLMSSP_KEY_LEN,
3028                                     "SMB2AESCCM", 11,
3029                                     "ServerIn ", 10,
3030                                     sesid->server_decryption_key);
3031                 smb2_key_derivation(session_key,
3032                                     NTLMSSP_KEY_LEN,
3033                                     "SMB2AESCCM", 11,
3034                                     "ServerOut", 10,
3035                                     sesid->client_decryption_key);
3036         } else {
3037                 memset(sesid->server_decryption_key, 0,
3038                        sizeof(sesid->server_decryption_key));
3039                 memset(sesid->client_decryption_key, 0,
3040                        sizeof(sesid->client_decryption_key));
3041         }
3042 }
3043
3044 static int
3045 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3046 {
3047         offset_length_buffer_t  s_olb;
3048         const ntlmssp_header_t *ntlmssph;
3049         static int ntlmssp_tap_id = 0;
3050         int        idx;
3051
3052         if (!ntlmssp_tap_id) {
3053                 GString *error_string;
3054                 /* We don't specify any callbacks at all.
3055                  * Instead we manually fetch the tapped data after the
3056                  * security blob has been fully dissected and before
3057                  * we exit from this dissector.
3058                  */
3059                 error_string = register_tap_listener("ntlmssp", NULL, NULL,
3060                     TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL, NULL);
3061                 if (!error_string) {
3062                         ntlmssp_tap_id = find_tap_id("ntlmssp");
3063                 } else {
3064                         g_string_free(error_string, TRUE);
3065                 }
3066         }
3067
3068
3069         /* buffer code */
3070         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3071         /* some unknown bytes */
3072
3073         /* flags */
3074         offset = dissect_smb2_ses_req_flags(tree, tvb, offset);
3075
3076         /* security mode */
3077         offset = dissect_smb2_secmode(tree, tvb, offset);
3078
3079         /* capabilities */
3080         offset = dissect_smb2_capabilities(tree, tvb, offset);
3081
3082         /* channel */
3083         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3084         offset += 4;
3085
3086         /* security blob offset/length */
3087         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3088
3089         /* previous session id */
3090         proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3091         offset += 8;
3092
3093
3094         /* the security blob itself */
3095         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3096
3097         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3098
3099         /* If we have found a uid->acct_name mapping, store it */
3100         if (!pinfo->fd->flags.visited) {
3101                 idx = 0;
3102                 while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
3103                         if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
3104                                 smb2_sesid_info_t *sesid;
3105                                 guint8 custom_seskey[NTLMSSP_KEY_LEN];
3106                                 const guint8 *session_key;
3107
3108                                 sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
3109                                 sesid->sesid = si->sesid;
3110                                 sesid->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
3111                                 sesid->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
3112                                 sesid->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
3113
3114                                 /* Try to see first if we have a
3115                                  * session key set in the pref for
3116                                  * this particular session id */
3117                                 if (seskey_find_sid_key(si->sesid, custom_seskey)) {
3118                                         session_key = custom_seskey;
3119                                 } else {
3120                                         session_key = ntlmssph->session_key;
3121                                 }
3122                                 smb2_set_session_keys(sesid, session_key);
3123                                 sesid->server_port = pinfo->destport;
3124                                 sesid->auth_frame = pinfo->num;
3125                                 sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
3126                                 g_hash_table_insert(si->conv->sesids, sesid, sesid);
3127                         }
3128                 }
3129         }
3130
3131         return offset;
3132 }
3133
3134 static void
3135 dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3136 {
3137         proto_tree *tree;
3138         proto_item *item;
3139
3140         offset_length_buffer_t  s_olb, p_olb;
3141
3142         item = proto_tree_add_item(parent_tree, hf_smb2_symlink_error_response, tvb, offset, -1, ENC_NA);
3143         tree = proto_item_add_subtree(item, ett_smb2_symlink_error_response);
3144
3145         /* symlink length */
3146         proto_tree_add_item(tree, hf_smb2_symlink_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3147         offset += 4;
3148
3149         /* symlink error tag */
3150         proto_tree_add_item(tree, hf_smb2_symlink_error_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3151         offset += 4;
3152
3153         /* reparse tag */
3154         proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3155         offset += 4;
3156
3157         proto_tree_add_item(tree, hf_smb2_reparse_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3158         offset += 2;
3159
3160         proto_tree_add_item(tree, hf_smb2_unparsed_path_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3161         offset += 2;
3162
3163         /* substitute name  offset/length */
3164         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_substitute_name);
3165
3166         /* print name offset/length */
3167         offset = dissect_smb2_olb_length_offset(tvb, offset, &p_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_print_name);
3168
3169         /* flags */
3170         proto_tree_add_item(tree, hf_smb2_symlink_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3171         offset += 4;
3172
3173         /* substitute name string */
3174         dissect_smb2_olb_off_string(pinfo, tree, tvb, &s_olb, offset, OLB_TYPE_UNICODE_STRING);
3175
3176         /* print name string */
3177         dissect_smb2_olb_off_string(pinfo, tree, tvb, &p_olb, offset, OLB_TYPE_UNICODE_STRING);
3178 }
3179
3180 static void
3181 dissect_smb2_error_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int error_context_count, smb2_info_t *si _U_)
3182 {
3183         proto_tree *tree;
3184         proto_item *item;
3185
3186         int offset = 0;
3187
3188         item = proto_tree_add_item(parent_tree, hf_smb2_error_data, tvb, offset, -1, ENC_NA);
3189         tree = proto_item_add_subtree(item, ett_smb2_error_data);
3190
3191         if (error_context_count == 0) {
3192                 switch (si->status) {
3193                 case 0x8000002D: /* STATUS_STOPPED_ON_SYMLINK */
3194                         dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvb, pinfo, tree, offset, si);
3195
3196                         break;
3197                 default:
3198                         break;
3199                 }
3200         } else {
3201                 /* TODO SMB311 supports multiple error contexts */
3202         }
3203 }
3204
3205 /* This needs more fixes for cases when the original header had also the constant value of 9.
3206    This should be fixed on caller side where it decides if it has to call this or not.
3207 */
3208 static int
3209 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si,
3210                                                         gboolean* continue_dissection)
3211 {
3212         gint byte_count;
3213         guint8 error_context_count;
3214         guint16 length;
3215         tvbuff_t *sub_tvb;
3216
3217         /* buffer code */
3218         offset = dissect_smb2_buffercode(tree, tvb, offset, &length);
3219
3220         /* FIX: error response uses this constant, if not then it is not an error response */
3221         if(length != 9)
3222         {
3223                 if(continue_dissection)
3224                         *continue_dissection = TRUE;
3225         } else {
3226                 if(continue_dissection)
3227                         *continue_dissection = FALSE;
3228
3229                 /* ErrorContextCount (1 bytes) */
3230                 error_context_count = tvb_get_guint8(tvb, offset);
3231                 proto_tree_add_item(tree, hf_smb2_error_context_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3232                 offset += 1;
3233
3234                 /* Reserved (1 bytes) */
3235                 proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3236                 offset += 1;
3237
3238                 /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
3239                 byte_count = tvb_get_letohl(tvb, offset);
3240                 proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3241                 offset += 4;
3242
3243                 /* If the ByteCount field is zero then the server MUST supply an ErrorData field
3244                    that is one byte in length */
3245                 if (byte_count == 0) byte_count = 1;
3246
3247                 /* ErrorData (variable): A variable-length data field that contains extended
3248                    error information.*/
3249                 sub_tvb = tvb_new_subset_length(tvb, offset, byte_count);
3250                 offset += byte_count;
3251
3252                 dissect_smb2_error_data(sub_tvb, pinfo, tree, error_context_count, si);
3253         }
3254
3255         return offset;
3256 }
3257
3258 static int
3259 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3260 {
3261         offset_length_buffer_t s_olb;
3262
3263         /* session_setup is special and we don't use dissect_smb2_error_response() here! */
3264
3265         /* buffer code */
3266         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3267
3268         /* session flags */
3269         offset = dissect_smb2_ses_flags(tree, tvb, offset);
3270
3271         /* security blob offset/length */
3272         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3273
3274         /* the security blob itself */
3275         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3276
3277         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3278
3279         /* If we have found a uid->acct_name mapping, store it */
3280 #ifdef HAVE_KERBEROS
3281         if (!pinfo->fd->flags.visited && si->status == 0) {
3282                 enc_key_t *ek;
3283
3284                 if (krb_decrypt) {
3285                         read_keytab_file_from_preferences();
3286                 }
3287
3288                 for (ek=enc_key_list;ek;ek=ek->next) {
3289                         if (ek->fd_num == (int)pinfo->num) {
3290                                 break;
3291                         }
3292                 }
3293
3294                 if (ek != NULL) {
3295                         smb2_sesid_info_t *sesid;
3296                         guint8 custom_seskey[NTLMSSP_KEY_LEN] = { 0, };
3297                         const guint8 *session_key;
3298
3299                         sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
3300                         sesid->sesid = si->sesid;
3301                         /* TODO: fill in the correct information */
3302                         sesid->acct_name = NULL;
3303                         sesid->domain_name = NULL;
3304                         sesid->host_name = NULL;
3305
3306                         if (seskey_find_sid_key(si->sesid, custom_seskey)) {
3307                                 session_key = custom_seskey;
3308                         } else {
3309                                 session_key = ek->keyvalue;
3310                         }
3311                         smb2_set_session_keys(sesid, session_key);
3312                         sesid->server_port = pinfo->srcport;
3313                         sesid->auth_frame = pinfo->num;
3314                         sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
3315                         g_hash_table_insert(si->conv->sesids, sesid, sesid);
3316                 }
3317         }
3318 #endif
3319
3320         return offset;
3321 }
3322
3323 static int
3324 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3325 {
3326         offset_length_buffer_t olb;
3327         const char *buf;
3328
3329         /* buffer code */
3330         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3331
3332         /* reserved */
3333         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3334         offset += 2;
3335
3336         /* tree  offset/length */
3337         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
3338
3339         /* tree string */
3340         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
3341
3342         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3343
3344         /* treelen  +1 is overkill here if the string is unicode,
3345          * but who ever has more than a handful of TCON in a trace anyways
3346          */
3347         if (!pinfo->fd->flags.visited && si->saved && buf && olb.len) {
3348                 si->saved->extra_info_type = SMB2_EI_TREENAME;
3349                 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
3350                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
3351         }
3352
3353         col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
3354
3355         return offset;
3356 }
3357 static int
3358 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3359 {
3360         guint8 share_type;
3361         gboolean continue_dissection;
3362
3363         switch (si->status) {
3364         /* buffer code */
3365         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3366         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3367                 if (!continue_dissection) return offset;
3368         }
3369
3370         /* share type */
3371         share_type = tvb_get_guint8(tvb, offset);
3372         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3373         offset += 1;
3374
3375         /* byte is reserved and must be set to zero */
3376         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
3377         offset += 1;
3378
3379         if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
3380                 smb2_tid_info_t *tid, tid_key;
3381
3382                 tid_key.tid = si->tid;
3383                 tid = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
3384                 if (tid) {
3385                         g_hash_table_remove(si->session->tids, &tid_key);
3386                 }
3387                 tid = wmem_new(wmem_file_scope(), smb2_tid_info_t);
3388                 tid->tid = si->tid;
3389                 tid->name = (char *)si->saved->extra_info;
3390                 tid->connect_frame = pinfo->num;
3391                 tid->share_type = share_type;
3392
3393                 g_hash_table_insert(si->session->tids, tid, tid);
3394
3395                 si->saved->extra_info_type = SMB2_EI_NONE;
3396                 si->saved->extra_info = NULL;
3397         }
3398
3399         /* share flags */
3400         offset = dissect_smb2_share_flags(tree, tvb, offset);
3401
3402         /* share capabilities */
3403         offset = dissect_smb2_share_caps(tree, tvb, offset);
3404
3405         /* this is some sort of access mask */
3406         offset = dissect_smb_access_mask(tvb, tree, offset);
3407
3408         return offset;
3409 }
3410
3411 static int
3412 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3413 {
3414         /* buffer code */
3415         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3416
3417         /* reserved */
3418         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3419         offset += 2;
3420
3421         return offset;
3422 }
3423
3424 static int
3425 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3426 {
3427         gboolean continue_dissection;
3428
3429         switch (si->status) {
3430         /* buffer code */
3431         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3432         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3433                 if (!continue_dissection) return offset;
3434         }
3435
3436         /* reserved */
3437         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3438         offset += 2;
3439
3440         return offset;
3441 }
3442
3443 static int
3444 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3445 {
3446         /* buffer code */
3447         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3448
3449         /* reserved bytes */
3450         offset += 2;
3451
3452         return offset;
3453 }
3454
3455 static int
3456 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3457 {
3458         gboolean continue_dissection;
3459
3460         switch (si->status) {
3461         /* buffer code */
3462         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3463         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3464                 if (!continue_dissection) return offset;
3465         }
3466
3467         /* reserved bytes */
3468         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3469         offset += 2;
3470
3471         return offset;
3472 }
3473
3474 static int
3475 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3476 {
3477         /* buffer code */
3478         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3479
3480         /* some unknown bytes */
3481         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3482         offset += 2;
3483
3484         return offset;
3485 }
3486
3487 static int
3488 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3489 {
3490         gboolean continue_dissection;
3491
3492         switch (si->status) {
3493         /* buffer code */
3494         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3495         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3496                 if (!continue_dissection) return offset;
3497         }
3498
3499         /* some unknown bytes */
3500         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3501         offset += 2;
3502
3503         return offset;
3504 }
3505
3506 static int
3507 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3508 {
3509         proto_tree *flags_tree = NULL;
3510         proto_item *flags_item = NULL;
3511
3512         /* buffer code */
3513         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3514
3515         /* notify flags */
3516         if (tree) {
3517                 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3518                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
3519         }
3520         proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3521         offset += 2;
3522
3523         /* output buffer length */
3524         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3525         offset += 4;
3526
3527         /* fid */
3528         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3529
3530         /* completion filter */
3531         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
3532
3533         /* reserved */
3534         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
3535         offset += 4;
3536
3537         return offset;
3538 }
3539
3540 static const value_string notify_action_vals[] = {
3541         {0x01, "FILE_ACTION_ADDED"},
3542         {0x02, "FILE_ACTION_REMOVED"},
3543         {0x03, "FILE_ACTION_MODIFIED"},
3544         {0x04, "FILE_ACTION_RENAMED_OLD_NAME"},
3545         {0x05, "FILE_ACTION_RENAMED_NEW_NAME"},
3546         {0x06, "FILE_ACTION_ADDED_STREAM"},
3547         {0x07, "FILE_ACTION_REMOVED_STREAM"},
3548         {0x08, "FILE_ACTION_MODIFIED_STREAM"},
3549         {0x09, "FILE_ACTION_REMOVED_BY_DELETE"},
3550         {0, NULL}
3551 };
3552
3553 static void
3554 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3555 {
3556         proto_tree *tree = NULL;
3557         proto_item *item = NULL;
3558         int offset = 0;
3559
3560         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3561                 guint32 start_offset = offset;
3562                 guint32 next_offset;
3563                 guint32 length;
3564
3565                 if (parent_tree) {
3566                         item = proto_tree_add_item(parent_tree, hf_smb2_notify_info, tvb, offset, -1, ENC_NA);
3567                         tree = proto_item_add_subtree(item, ett_smb2_notify_info);
3568                 }
3569
3570                 /* next offset */
3571                 proto_tree_add_item_ret_uint(tree, hf_smb2_notify_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &next_offset);
3572                 offset += 4;
3573
3574                 proto_tree_add_item(tree, hf_smb2_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3575                 offset += 4;
3576
3577                 /* file name length */
3578                 proto_tree_add_item_ret_uint(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
3579                 offset += 4;
3580
3581                 /* file name */
3582                 if (length) {
3583                         const guchar *name = "";
3584                         guint16     bc;
3585
3586                         bc = tvb_reported_length_remaining(tvb, offset);
3587                         name = get_unicode_or_ascii_string(tvb, &offset,
3588                                         TRUE, &length, TRUE, TRUE, &bc);
3589                         if (name) {
3590                                 proto_tree_add_string(tree, hf_smb2_filename,
3591                                                       tvb, offset, length,
3592                                                       name);
3593                         }
3594
3595                         offset += length;
3596                 }
3597
3598                 if (!next_offset) {
3599                         break;
3600                 }
3601
3602                 offset = start_offset+next_offset;
3603         }
3604 }
3605
3606 static int
3607 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3608 {
3609         offset_length_buffer_t olb;
3610         gboolean continue_dissection;
3611
3612         switch (si->status) {
3613         /* MS-SMB2 3.3.4.4 says STATUS_NOTIFY_ENUM_DIR is not treated as an error */
3614         case 0x0000010c: /* STATUS_NOTIFY_ENUM_DIR */
3615         case 0x00000000: /* buffer code */
3616          offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3617         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3618                 if (!continue_dissection) return offset;
3619         }
3620
3621         /* out buffer offset/length */
3622         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
3623
3624         /* out buffer */
3625         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
3626         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3627
3628         return offset;
3629 }
3630
3631 #define SMB2_FIND_FLAG_RESTART_SCANS            0x01
3632 #define SMB2_FIND_FLAG_SINGLE_ENTRY             0x02
3633 #define SMB2_FIND_FLAG_INDEX_SPECIFIED          0x04
3634 #define SMB2_FIND_FLAG_REOPEN                   0x10
3635
3636 static int
3637 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3638 {
3639         offset_length_buffer_t olb;
3640         const char *buf;
3641         guint8      il;
3642         static const int *f_fields[] = {
3643                 &hf_smb2_find_flags_restart_scans,
3644                 &hf_smb2_find_flags_single_entry,
3645                 &hf_smb2_find_flags_index_specified,
3646                 &hf_smb2_find_flags_reopen,
3647                 NULL
3648         };
3649
3650         /* buffer code */
3651         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3652
3653         il = tvb_get_guint8(tvb, offset);
3654         if (si->saved) {
3655                 si->saved->infolevel = il;
3656         }
3657
3658         /* infolevel */
3659         proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
3660         offset += 1;
3661
3662         /* find flags */
3663         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, ENC_LITTLE_ENDIAN);
3664         offset += 1;
3665
3666         /* file index */
3667         proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3668         offset += 4;
3669
3670         /* fid */
3671         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3672
3673         /* search pattern  offset/length */
3674         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
3675
3676         /* output buffer length */
3677         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3678         offset += 4;
3679
3680         /* search pattern */
3681         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
3682
3683         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3684
3685         if (!pinfo->fd->flags.visited && si->saved && olb.len) {
3686                 si->saved->extra_info_type = SMB2_EI_FINDPATTERN;
3687                 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
3688                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
3689         }
3690
3691         col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
3692                         val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
3693                         buf);
3694
3695         return offset;
3696 }
3697
3698 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3699 {
3700         int         offset = 0;
3701         proto_item *item   = NULL;
3702         proto_tree *tree   = NULL;
3703         const char *name   = NULL;
3704         guint16     bc;
3705
3706         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3707                 int old_offset = offset;
3708                 int next_offset;
3709                 int file_name_len;
3710
3711                 if (parent_tree) {
3712                         item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, ENC_NA);
3713                         tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
3714                 }
3715
3716                 /* next offset */
3717                 next_offset = tvb_get_letohl(tvb, offset);
3718                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3719                 offset += 4;
3720
3721                 /* file index */
3722                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3723                 offset += 4;
3724
3725                 /* create time */
3726                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3727
3728                 /* last access */
3729                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3730
3731                 /* last write */
3732                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3733
3734                 /* last change */
3735                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3736
3737                 /* end of file */
3738                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3739                 offset += 8;
3740
3741                 /* allocation size */
3742                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3743                 offset += 8;
3744
3745                 /* File Attributes */
3746                 offset = dissect_file_ext_attr(tvb, tree, offset);
3747
3748                 /* file name length */
3749                 file_name_len = tvb_get_letohl(tvb, offset);
3750                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3751                 offset += 4;
3752
3753                 /* file name */
3754                 if (file_name_len) {
3755                         bc = file_name_len;
3756                         name = get_unicode_or_ascii_string(tvb, &offset,
3757                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3758                         if (name) {
3759                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3760                                         offset, file_name_len, name);
3761                                 proto_item_append_text(item, ": %s", name);
3762
3763                         }
3764                 }
3765
3766                 proto_item_set_len(item, offset-old_offset);
3767
3768                 if (next_offset == 0) {
3769                         return;
3770                 }
3771
3772                 offset = old_offset+next_offset;
3773                 if (offset < old_offset) {
3774                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3775                                     "Invalid offset/length. Malformed packet");
3776                         return;
3777                 }
3778         }
3779 }
3780
3781 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3782 {
3783         int         offset = 0;
3784         proto_item *item   = NULL;
3785         proto_tree *tree   = NULL;
3786         const char *name   = NULL;
3787         guint16     bc;
3788
3789         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3790                 int old_offset = offset;
3791                 int next_offset;
3792                 int file_name_len;
3793
3794                 if (parent_tree) {
3795                         item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, ENC_NA);
3796                         tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
3797                 }
3798
3799                 /* next offset */
3800                 next_offset = tvb_get_letohl(tvb, offset);
3801                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3802                 offset += 4;
3803
3804                 /* file index */
3805                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3806                 offset += 4;
3807
3808                 /* create time */
3809                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3810
3811                 /* last access */
3812                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3813
3814                 /* last write */
3815                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3816
3817                 /* last change */
3818                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3819
3820                 /* end of file */
3821                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3822                 offset += 8;
3823
3824                 /* allocation size */
3825                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3826                 offset += 8;
3827
3828                 /* File Attributes */
3829                 offset = dissect_file_ext_attr(tvb, tree, offset);
3830
3831                 /* file name length */
3832                 file_name_len = tvb_get_letohl(tvb, offset);
3833                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3834                 offset += 4;
3835
3836                 /* ea size */
3837                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3838                 offset += 4;
3839
3840                 /* file name */
3841                 if (file_name_len) {
3842                         bc = file_name_len;
3843                         name = get_unicode_or_ascii_string(tvb, &offset,
3844                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3845                         if (name) {
3846                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3847                                         offset, file_name_len, name);
3848                                 proto_item_append_text(item, ": %s", name);
3849
3850                         }
3851                 }
3852
3853                 proto_item_set_len(item, offset-old_offset);
3854
3855                 if (next_offset == 0) {
3856                         return;
3857                 }
3858
3859                 offset = old_offset+next_offset;
3860                 if (offset < old_offset) {
3861                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3862                                     "Invalid offset/length. Malformed packet");
3863                         return;
3864                 }
3865         }
3866 }
3867
3868 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3869 {
3870         int         offset = 0;
3871         proto_item *item   = NULL;
3872         proto_tree *tree   = NULL;
3873         const char *name   = NULL;
3874         guint16     bc;
3875
3876         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3877                 int old_offset = offset;
3878                 int next_offset;
3879                 int file_name_len;
3880                 int short_name_len;
3881
3882                 if (parent_tree) {
3883                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
3884                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
3885                 }
3886
3887                 /* next offset */
3888                 next_offset = tvb_get_letohl(tvb, offset);
3889                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3890                 offset += 4;
3891
3892                 /* file index */
3893                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3894                 offset += 4;
3895
3896                 /* create time */
3897                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3898
3899                 /* last access */
3900                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3901
3902                 /* last write */
3903                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3904
3905                 /* last change */
3906                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3907
3908                 /* end of file */
3909                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3910                 offset += 8;
3911
3912                 /* allocation size */
3913                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3914                 offset += 8;
3915
3916                 /* File Attributes */
3917                 offset = dissect_file_ext_attr(tvb, tree, offset);
3918
3919                 /* file name length */
3920                 file_name_len = tvb_get_letohl(tvb, offset);
3921                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3922                 offset += 4;
3923
3924                 /* ea size */
3925                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3926                 offset += 4;
3927
3928                 /* short name length */
3929                 short_name_len = tvb_get_guint8(tvb, offset);
3930                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3931                 offset += 1;
3932
3933                 /* reserved */
3934                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
3935                 offset += 1;
3936
3937                 /* short name */
3938                 if (short_name_len) {
3939                         bc = short_name_len;
3940                         name = get_unicode_or_ascii_string(tvb, &offset,
3941                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
3942                         if (name) {
3943                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
3944                                         offset, short_name_len, name);
3945                         }
3946                 }
3947                 offset += 24;
3948
3949                 /* file name */
3950                 if (file_name_len) {
3951                         bc = file_name_len;
3952                         name = get_unicode_or_ascii_string(tvb, &offset,
3953                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3954                         if (name) {
3955                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3956                                         offset, file_name_len, name);
3957                                 proto_item_append_text(item, ": %s", name);
3958
3959                         }
3960                 }
3961
3962                 proto_item_set_len(item, offset-old_offset);
3963
3964                 if (next_offset == 0) {
3965                         return;
3966                 }
3967
3968                 offset = old_offset+next_offset;
3969                 if (offset < old_offset) {
3970                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3971                                     "Invalid offset/length. Malformed packet");
3972                         return;
3973                 }
3974         }
3975 }
3976
3977 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3978 {
3979         int         offset = 0;
3980         proto_item *item   = NULL;
3981         proto_tree *tree   = NULL;
3982         const char *name   = NULL;
3983         guint16     bc;
3984
3985         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3986                 int old_offset = offset;
3987                 int next_offset;
3988                 int file_name_len;
3989
3990                 if (parent_tree) {
3991                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
3992                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
3993                 }
3994
3995                 /* next offset */
3996                 next_offset = tvb_get_letohl(tvb, offset);
3997                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3998                 offset += 4;
3999
4000                 /* file index */
4001                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4002                 offset += 4;
4003
4004                 /* file name length */
4005                 file_name_len = tvb_get_letohl(tvb, offset);
4006                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4007                 offset += 4;
4008
4009                 /* file name */
4010                 if (file_name_len) {
4011                         bc = file_name_len;
4012                         name = get_unicode_or_ascii_string(tvb, &offset,
4013                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
4014                         if (name) {
4015                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
4016                                         offset, file_name_len, name);
4017                                 proto_item_append_text(item, ": %s", name);
4018
4019                         }
4020                 }
4021
4022                 proto_item_set_len(item, offset-old_offset);
4023
4024                 if (next_offset == 0) {
4025                         return;
4026                 }
4027
4028                 offset = old_offset+next_offset;
4029                 if (offset < old_offset) {
4030                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4031                                     "Invalid offset/length. Malformed packet");
4032                         return;
4033                 }
4034         }
4035 }
4036
4037 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4038 {
4039         int         offset = 0;
4040         proto_item *item   = NULL;
4041         proto_tree *tree   = NULL;
4042         const char *name   = NULL;
4043         guint16     bc;
4044
4045         while (tvb_reported_length_remaining(tvb, offset) > 4) {
4046                 int old_offset = offset;
4047                 int next_offset;
4048                 int file_name_len;
4049                 int short_name_len;
4050
4051                 if (parent_tree) {
4052                         item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
4053                         tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
4054                 }
4055
4056                 /* next offset */
4057                 next_offset = tvb_get_letohl(tvb, offset);
4058                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4059                 offset += 4;
4060
4061                 /* file index */
4062                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4063                 offset += 4;
4064
4065                 /* create time */
4066                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4067
4068                 /* last access */
4069                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4070
4071                 /* last write */
4072                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4073
4074                 /* last change */
4075                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4076
4077                 /* end of file */
4078                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4079                 offset += 8;
4080
4081                 /* allocation size */
4082                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4083                 offset += 8;
4084
4085                 /* File Attributes */
4086                 offset = dissect_file_ext_attr(tvb, tree, offset);
4087
4088                 /* file name length */
4089                 file_name_len = tvb_get_letohl(tvb, offset);
4090                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4091                 offset += 4;
4092
4093                 /* ea size */
4094                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4095                 offset += 4;
4096
4097                 /* short name length */
4098                 short_name_len = tvb_get_guint8(tvb, offset);
4099                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4100                 offset += 1;
4101
4102                 /* reserved */
4103                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
4104                 offset += 1;
4105
4106                 /* short name */
4107                 if (short_name_len) {
4108                         bc = short_name_len;
4109                         name = get_unicode_or_ascii_string(tvb, &offset,
4110                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
4111                         if (name) {
4112                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
4113                                         offset, short_name_len, name);
4114                         }
4115                 }
4116                 offset += 24;
4117
4118                 /* reserved */
4119                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4120                 offset += 2;
4121
4122                 /* file id */
4123                 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4124                 offset += 8;
4125
4126                 /* file name */
4127                 if (file_name_len) {
4128                         bc = file_name_len;
4129                         name = get_unicode_or_ascii_string(tvb, &offset,
4130                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
4131                         if (name) {
4132                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
4133                                         offset, file_name_len, name);
4134                                 proto_item_append_text(item, ": %s", name);
4135
4136                         }
4137                 }
4138
4139                 proto_item_set_len(item, offset-old_offset);
4140
4141                 if (next_offset == 0) {
4142                         return;
4143                 }
4144
4145                 offset = old_offset+next_offset;
4146                 if (offset < old_offset) {
4147                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4148                                     "Invalid offset/length. Malformed packet");
4149                         return;
4150                 }
4151         }
4152 }
4153
4154
4155 static void dissect_smb2_id_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4156 {
4157         int         offset = 0;
4158         proto_item *item   = NULL;
4159         proto_tree *tree   = NULL;
4160         const char *name   = NULL;
4161         guint16     bc;
4162
4163         while (tvb_reported_length_remaining(tvb, offset) > 4) {
4164                 int old_offset = offset;
4165                 int next_offset;
4166                 int file_name_len;
4167
4168                 if (parent_tree) {
4169                         item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
4170                         tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
4171                 }
4172
4173                 /* next offset */
4174                 next_offset = tvb_get_letohl(tvb, offset);
4175                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4176                 offset += 4;
4177
4178                 /* file index */
4179                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4180                 offset += 4;
4181
4182                 /* create time */
4183                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4184
4185                 /* last access */
4186                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4187
4188                 /* last write */
4189                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4190
4191                 /* last change */
4192                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4193
4194                 /* end of file */
4195                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4196                 offset += 8;
4197
4198                 /* allocation size */
4199                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4200                 offset += 8;
4201
4202                 /* File Attributes */
4203                 offset = dissect_file_ext_attr(tvb, tree, offset);
4204
4205                 /* file name length */
4206                 file_name_len = tvb_get_letohl(tvb, offset);
4207                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4208                 offset += 4;
4209
4210                 /* ea size */
4211                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4212                 offset += 4;
4213
4214                 /* reserved */
4215                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4216                 offset += 4;
4217
4218                 /* file id */
4219                 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4220                 offset += 8;
4221
4222                 /* file name */
4223                 if (file_name_len) {
4224                         bc = file_name_len;
4225                         name = get_unicode_or_ascii_string(tvb, &offset,
4226                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
4227                         if (name) {
4228                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
4229                                         offset, file_name_len, name);
4230                                 proto_item_append_text(item, ": %s", name);
4231
4232                         }
4233                 }
4234
4235                 proto_item_set_len(item, offset-old_offset);
4236
4237                 if (next_offset == 0) {
4238                         return;
4239                 }
4240
4241                 offset = old_offset+next_offset;
4242                 if (offset < old_offset) {
4243                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4244                                     "Invalid offset/length. Malformed packet");
4245                         return;
4246                 }
4247         }
4248 }
4249
4250
4251 typedef struct _smb2_find_dissector_t {
4252         guint32 level;
4253         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
4254 } smb2_find_dissector_t;
4255
4256 smb2_find_dissector_t smb2_find_dissectors[] = {
4257         {SMB2_FIND_DIRECTORY_INFO,      dissect_smb2_file_directory_info},
4258         {SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
4259         {SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
4260         {SMB2_FIND_NAME_INFO,           dissect_smb2_file_name_info},
4261         {SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
4262         {SMB2_FIND_ID_FULL_DIRECTORY_INFO,dissect_smb2_id_full_directory_info},
4263         {0, NULL}
4264 };
4265
4266 static void
4267 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4268 {
4269         smb2_find_dissector_t *dis = smb2_find_dissectors;
4270
4271         while (dis->dissector) {
4272                 if (si && si->saved) {
4273                         if (dis->level == si->saved->infolevel) {
4274                                 dis->dissector(tvb, pinfo, tree, si);
4275                                 return;
4276                         }
4277                 }
4278                 dis++;
4279         }
4280
4281         proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
4282 }
4283
4284 static int
4285 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4286 {
4287         offset_length_buffer_t olb;
4288         proto_item *item = NULL;
4289         gboolean continue_dissection;
4290
4291         if (si->saved) {
4292                 /* infolevel */
4293                 item = proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
4294                 PROTO_ITEM_SET_GENERATED(item);
4295         }
4296
4297         if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_FINDPATTERN) {
4298                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
4299                                 val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
4300                                 (const char *)si->saved->extra_info);
4301
4302                 wmem_free(wmem_file_scope(), si->saved->extra_info);
4303                 si->saved->extra_info_type = SMB2_EI_NONE;
4304                 si->saved->extra_info = NULL;
4305         }
4306
4307         switch (si->status) {
4308         /* buffer code */
4309         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4310         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4311                 if (!continue_dissection) return offset;
4312         }
4313
4314         /* findinfo offset */
4315         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
4316
4317         /* the buffer */
4318         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
4319
4320         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
4321
4322         return offset;
4323 }
4324
4325 static int
4326 dissect_smb2_negotiate_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
4327 {
4328         guint16 type;
4329         const gchar *type_str;
4330         guint32 i, data_length, salt_length, hash_count, cipher_count;
4331         proto_item *sub_item;
4332         proto_tree *sub_tree;
4333
4334         sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_negotiate_context_element, &sub_item, "Negotiate Context");
4335
4336         /* type */
4337         type = tvb_get_letohl(tvb, offset);
4338         type_str = val_to_str(type, smb2_negotiate_context_types, "Unknown Type: (0x%0x)");
4339         proto_item_append_text(sub_item, ": %s ", type_str);
4340         proto_tree_add_item(sub_tree, hf_smb2_negotiate_context_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4341         offset += 2;
4342
4343         /* data length */
4344         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_negotiate_context_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &data_length);
4345         offset += 2;
4346
4347         /* reserved */
4348         proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4349         offset += 4;
4350
4351         switch (type)
4352         {
4353                 case SMB2_PREAUTH_INTEGRITY_CAPABILITIES:
4354                         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_hash_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &hash_count);
4355                         offset += 2;
4356                         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_salt_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &salt_length);
4357                         offset += 2;
4358
4359                         for (i = 0; i < hash_count; i++)
4360                         {
4361                                 proto_tree_add_item(sub_tree, hf_smb2_hash_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4362                                 offset += 2;
4363                         }
4364
4365                         if (salt_length)
4366                         {
4367                                 proto_tree_add_item(sub_tree, hf_smb2_salt, tvb, offset, salt_length, ENC_NA);
4368                                 offset += salt_length;
4369                         }
4370                         break;
4371
4372                 case SMB2_ENCRYPTION_CAPABILITIES:
4373                         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_cipher_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cipher_count);
4374                         offset += 2;
4375
4376                         for (i = 0; i < cipher_count; i ++)
4377                         {
4378                                 proto_tree_add_item(sub_tree, hf_smb2_cipher_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4379                                 offset += 2;
4380                         }
4381                         break;
4382
4383                 default:
4384                         proto_tree_add_item(sub_tree, hf_smb2_unknown, tvb, offset, data_length, ENC_NA);
4385                         offset += data_length;
4386                         break;
4387         }
4388
4389         return offset;
4390 }
4391
4392 static int
4393 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4394 {
4395         guint16 dc;
4396         guint16 i;
4397         gboolean supports_smb_3_10 = FALSE;
4398         guint32 nco;
4399         guint16 ncc;
4400
4401         /* buffer code */
4402         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4403
4404         /* dialect count */
4405         dc = tvb_get_letohs(tvb, offset);
4406         proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4407         offset += 2;
4408
4409         /* security mode, skip second byte */
4410         offset = dissect_smb2_secmode(tree, tvb, offset);
4411         offset++;
4412
4413
4414         /* reserved */
4415         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4416         offset += 2;
4417
4418         /* capabilities */
4419         offset = dissect_smb2_capabilities(tree, tvb, offset);
4420
4421         /* client guid */
4422         proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4423         offset += 16;
4424
4425         /* negotiate context offset */
4426         nco = tvb_get_letohl(tvb, offset);
4427         proto_tree_add_item(tree, hf_smb2_negotiate_context_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4428         offset += 4;
4429
4430         /* negotiate context count */
4431         ncc = tvb_get_letohs(tvb, offset);
4432         proto_tree_add_item(tree, hf_smb2_negotiate_context_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4433         offset += 2;
4434
4435         /* reserved */
4436         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4437         offset += 2;
4438
4439         for (i = 0 ; i < dc; i++) {
4440                 guint16 d = tvb_get_letohs(tvb, offset);
4441                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4442                 offset += 2;
4443
4444                 if (d >= 0x310) {
4445                         supports_smb_3_10 = TRUE;
4446                 }
4447         }
4448
4449         if (!supports_smb_3_10) {
4450                 ncc = 0;
4451         }
4452
4453         if (nco != 0) {
4454                 guint32 tmp = 0x40 + 36 + dc * 2;
4455
4456                 if (nco >= tmp) {
4457                         offset += nco - tmp;
4458                 } else {
4459                         ncc = 0;
4460                 }
4461         }
4462
4463         for (i = 0; i < ncc; i++) {
4464                 offset = (offset + 7) & ~7;
4465                 offset = dissect_smb2_negotiate_context(tvb, pinfo, tree, offset, si);
4466         }
4467
4468         return offset;
4469 }
4470
4471 static int
4472 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
4473 {
4474         offset_length_buffer_t s_olb;
4475         guint16 d;
4476         guint16 i;
4477         guint32 nco;
4478         guint16 ncc;
4479         gboolean continue_dissection;
4480
4481         switch (si->status) {
4482         /* buffer code */
4483         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4484         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4485                 if (!continue_dissection) return offset;
4486         }
4487
4488         /* security mode, skip second byte */
4489         offset = dissect_smb2_secmode(tree, tvb, offset);
4490         offset++;
4491
4492         /* dialect picked */
4493         d = tvb_get_letohs(tvb, offset);
4494         proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4495         offset += 2;
4496
4497         /* negotiate context count */
4498         ncc = tvb_get_letohs(tvb, offset);
4499         proto_tree_add_item(tree, hf_smb2_negotiate_context_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4500         offset += 2;
4501
4502         /* server GUID */
4503         proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4504         offset += 16;
4505
4506         /* capabilities */
4507         offset = dissect_smb2_capabilities(tree, tvb, offset);
4508
4509         /* max trans size */
4510         proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4511         offset += 4;
4512
4513         /* max read size */
4514         proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4515         offset += 4;
4516
4517         /* max write size */
4518         proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4519         offset += 4;
4520
4521         /* current time */
4522         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
4523         offset += 8;
4524
4525         /* boot time */
4526         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
4527         offset += 8;
4528
4529         /* security blob offset/length */
4530         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
4531
4532         /* the security blob itself */
4533         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
4534
4535         /* negotiate context offset */
4536         nco = tvb_get_letohl(tvb, offset);
4537         proto_tree_add_item(tree, hf_smb2_negotiate_context_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4538         offset += 4;
4539
4540         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
4541
4542         if (d < 0x310) {
4543                 ncc = 0;
4544         }
4545
4546         if (nco != 0) {
4547                 guint32 tmp = 0x40 + 64 + s_olb.len;
4548
4549                 if (nco >= tmp) {
4550                         offset += nco - tmp;
4551                 } else {
4552                         ncc = 0;
4553                 }
4554         }
4555
4556         for (i = 0; i < ncc; i++) {
4557                 offset = (offset + 7) & ~7;
4558                 offset = dissect_smb2_negotiate_context(tvb, pinfo, tree, offset, si);
4559         }
4560
4561         return offset;
4562 }
4563
4564 static int
4565 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
4566 {
4567         /* Additional Info */
4568         switch (si->saved->smb2_class) {
4569         case SMB2_CLASS_SEC_INFO:
4570                 dissect_security_information_mask(tvb, tree, offset);
4571                 break;
4572         default:
4573                 proto_tree_add_item(tree, hf_smb2_getinfo_additional, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4574         }
4575         offset += 4;
4576
4577         /* Flags */
4578         proto_tree_add_item(tree, hf_smb2_getinfo_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4579         offset += 4;
4580
4581         return offset;
4582 }
4583
4584
4585 static int
4586 dissect_smb2_getinfo_buffer_quota(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
4587 {
4588         guint32 sidlist_len = 0;
4589         guint32 startsid_len = 0;
4590         guint32 startsid_offset = 0;
4591
4592         proto_item *item = NULL;
4593         proto_tree *tree = NULL;
4594
4595         if (parent_tree) {
4596                 item = proto_tree_add_item(parent_tree, hf_smb2_query_quota_info, tvb, offset, -1, ENC_NA);
4597                 tree = proto_item_add_subtree(item, ett_smb2_query_quota_info);
4598         }
4599
4600         proto_tree_add_item(tree, hf_smb2_qq_single, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4601         offset += 1;
4602
4603         proto_tree_add_item(tree, hf_smb2_qq_restart, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4604         offset += 1;
4605
4606         /* reserved */
4607         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4608         offset += 2;
4609
4610         proto_tree_add_item_ret_uint(tree, hf_smb2_qq_sidlist_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &sidlist_len);
4611         offset += 4;
4612
4613         proto_tree_add_item_ret_uint(tree, hf_smb2_qq_start_sid_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &startsid_len);
4614         offset += 4;
4615
4616         proto_tree_add_item_ret_uint(tree, hf_smb2_qq_start_sid_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &startsid_offset);
4617         offset += 4;
4618
4619         if (sidlist_len != 0) {
4620                 offset = dissect_nt_get_user_quota(tvb, tree, offset, &sidlist_len);
4621         } else if (startsid_len != 0) {
4622                 offset = dissect_nt_sid(tvb, offset + startsid_offset, tree, "Start SID", NULL, -1);
4623         }
4624
4625         return offset;
4626 }
4627
4628 static int
4629 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
4630 {
4631         guint8            cl, il;
4632         proto_item       *item;
4633         int               hfindex;
4634         value_string_ext *vsx;
4635
4636         if (si->flags & SMB2_FLAGS_RESPONSE) {
4637                 if (!si->saved) {
4638                         return offset;
4639                 }
4640                 cl = si->saved->smb2_class;
4641                 il = si->saved->infolevel;
4642         } else {
4643                 cl = tvb_get_guint8(tvb, offset);
4644                 il = tvb_get_guint8(tvb, offset+1);
4645                 if (si->saved) {
4646                         si->saved->smb2_class = cl;
4647                         si->saved->infolevel = il;
4648                 }
4649         }
4650
4651
4652         switch (cl) {
4653         case SMB2_CLASS_FILE_INFO:
4654                 hfindex = hf_smb2_infolevel_file_info;
4655                 vsx = &smb2_file_info_levels_ext;
4656                 break;
4657         case SMB2_CLASS_FS_INFO:
4658                 hfindex = hf_smb2_infolevel_fs_info;
4659                 vsx = &smb2_fs_info_levels_ext;
4660                 break;
4661         case SMB2_CLASS_SEC_INFO:
4662                 hfindex = hf_smb2_infolevel_sec_info;
4663                 vsx = &smb2_sec_info_levels_ext;
4664                 break;
4665         case SMB2_CLASS_QUOTA_INFO:
4666                 /* infolevel is not being used for quota */
4667                 hfindex = hf_smb2_infolevel;
4668                 vsx = NULL;
4669                 break;
4670         case SMB2_CLASS_POSIX_INFO:
4671                 hfindex = hf_smb2_infolevel_posix_info;
4672                 vsx = &smb2_posix_info_levels_ext;
4673                 break;
4674         default:
4675                 hfindex = hf_smb2_infolevel;
4676                 vsx = NULL;  /* allowed arg to val_to_str_ext() */
4677         }
4678
4679
4680         /* class */
4681         item = proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
4682         if (si->flags & SMB2_FLAGS_RESPONSE) {
4683                 PROTO_ITEM_SET_GENERATED(item);
4684         }
4685         /* infolevel */
4686         item = proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
4687         if (si->flags & SMB2_FLAGS_RESPONSE) {
4688                 PROTO_ITEM_SET_GENERATED(item);
4689         }
4690         offset += 2;
4691
4692         if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
4693                 /* Only update COL_INFO for requests. It clutters the
4694                  * display a bit too much if we do it for replies
4695                  * as well.
4696                  */
4697                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
4698                                 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
4699                                 val_to_str_ext(il, vsx, "(Level:0x%02x)"));
4700         }
4701
4702         return offset;
4703 }
4704
4705 static int
4706 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4707 {
4708         guint32 getinfo_size = 0;
4709         guint32 getinfo_offset = 0;
4710         proto_item *offset_item;
4711
4712         /* buffer code */
4713         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4714
4715         /* class and info level */
4716         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
4717
4718         /* max response size */
4719         proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4720         offset += 4;
4721
4722         /* offset */
4723         offset_item = proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN, &getinfo_offset);
4724         offset += 2;
4725
4726         /* reserved */
4727         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4728         offset += 2;
4729
4730         /* size */
4731         proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &getinfo_size);
4732         offset += 4;
4733
4734         /* parameters */
4735         if (si->saved) {
4736                 offset = dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
4737         } else {
4738                 /* some unknown bytes */
4739                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, ENC_NA);
4740                 offset += 8;
4741         }
4742
4743         /* fid */
4744         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4745
4746         /* buffer */
4747         if (si->saved) {
4748                 if (getinfo_size != 0) {
4749                         /*
4750                          * 2.2.37 says "For quota requests, this MUST be
4751                          * the length of the contained SMB2_QUERY_QUOTA_INFO
4752                          * embedded in the request. For FileFullEaInformation
4753                          * requests, this MUST be set to the length of the
4754                          * user supplied EA list specified in [MS-FSCC]
4755                          * section 2.4.15.1. For other information queries,
4756                          * this field SHOULD be set to 0 and the server MUST
4757                          * ignore it on receipt.
4758                          *
4759                          * This seems to imply that, for requests other
4760                          * than those to types, we should either completely
4761                          * ignore a non-zero getinfo_size or should, at
4762                          * most, add a warning-level expert info at the
4763                          * protocol level saying that it should be zero,
4764                          * but not try and interpret it or check its
4765                          * validity.
4766                          */
4767                         if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO ||
4768                             (si->saved->smb2_class == SMB2_CLASS_FILE_INFO &&
4769                              si->saved->infolevel == SMB2_FILE_FULL_EA_INFO)) {
4770                                 /*
4771                                  * According to 2.2.37 SMB2 QUERY_INFO
4772                                  * Request in the current MS-SMB2 spec,
4773                                  * these are the only info requests that
4774                                  * have an input buffer.
4775                                  */
4776
4777                                 /*
4778                                  * Make sure that the input buffer is after
4779                                  * the fixed-length part of the message.
4780                                  */
4781                                 if (getinfo_offset < (guint)offset) {
4782                                         expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_offset);
4783                                         return offset;
4784                                 }
4785
4786                                 /*
4787                                  * Make sure the input buffer is within the
4788                                  * message, i.e. that it's within the tvbuff.
4789                                  *
4790                                  * We check for offset+length overflowing and
4791                                  * for offset+length being beyond the reported
4792                                  * length of the tvbuff.
4793                                  */
4794                                 if (getinfo_offset + getinfo_size < getinfo_offset ||
4795                                     getinfo_offset + getinfo_size > tvb_reported_length(tvb)) {
4796                                         expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_size);
4797                                         return offset;
4798                                 }
4799
4800                                 if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO) {
4801                                         dissect_smb2_getinfo_buffer_quota(tvb, pinfo, tree, getinfo_offset, si);
4802                                 } else {
4803                                         /*
4804                                          * XXX - handle user supplied EA info.
4805                                          */
4806                                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, getinfo_offset, getinfo_size, ENC_NA);
4807                                 }
4808                                 offset = getinfo_offset + getinfo_size;
4809                         }
4810                 } else {
4811                         /*
4812                          * The buffer size is 0, meaning it's not present.
4813                          *
4814                          * 2.2.37 says "For FileFullEaInformation requests,
4815                          * the input buffer MUST contain the user supplied
4816                          * EA list with zero or more FILE_GET_EA_INFORMATION
4817                          * structures, specified in [MS-FSCC] section
4818                          * 2.4.15.1.", so it seems that, for a "get full
4819                          * EA information" request, the size can be zero -
4820                          * there's no other obvious way for the list to
4821                          * have zero structures.
4822                          *
4823                          * 2.2.37 also says "For quota requests, the input
4824                          * buffer MUST contain an SMB2_QUERY_QUOTA_INFO,
4825                          * as specified in section 2.2.37.1."; that seems
4826                          * to imply that the input buffer must not be empty
4827                          * in that case.
4828                          */
4829                         if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO)
4830                                 expert_add_info(pinfo, offset_item, &ei_smb2_empty_getinfo_buffer);
4831                 }
4832         }
4833
4834         return offset;
4835 }
4836
4837 static int
4838 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 smb2_class, guint8 infolevel)
4839 {
4840         int old_offset = offset;
4841
4842         switch (smb2_class) {
4843         case SMB2_CLASS_FILE_INFO:
4844                 switch (infolevel) {
4845                 case SMB2_FILE_BASIC_INFO:
4846                         offset = dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
4847                         break;
4848                 case SMB2_FILE_STANDARD_INFO:
4849                         offset = dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
4850                         break;
4851                 case SMB2_FILE_INTERNAL_INFO:
4852                         offset = dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
4853                         break;
4854                 case SMB2_FILE_EA_INFO:
4855                         offset = dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
4856                         break;
4857                 case SMB2_FILE_ACCESS_INFO:
4858                         offset = dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
4859                         break;
4860                 case SMB2_FILE_RENAME_INFO:
4861                         offset = dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
4862                         break;
4863                 case SMB2_FILE_DISPOSITION_INFO:
4864                         offset = dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
4865                         break;
4866                 case SMB2_FILE_POSITION_INFO:
4867                         offset = dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
4868                         break;
4869                 case SMB2_FILE_FULL_EA_INFO:
4870                         offset = dissect_smb2_file_full_ea_info(tvb, pinfo, tree, offset, si);
4871                         break;
4872                 case SMB2_FILE_MODE_INFO:
4873                         offset = dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
4874                         break;
4875                 case SMB2_FILE_ALIGNMENT_INFO:
4876                         offset = dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
4877                         break;
4878                 case SMB2_FILE_ALL_INFO:
4879                         offset = dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
4880                         break;
4881                 case SMB2_FILE_ALLOCATION_INFO:
4882                         offset = dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
4883                         break;
4884                 case SMB2_FILE_ENDOFFILE_INFO:
4885                         dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
4886                         break;
4887                 case SMB2_FILE_ALTERNATE_NAME_INFO:
4888                         offset = dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
4889                         break;
4890                 case SMB2_FILE_STREAM_INFO:
4891                         offset = dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
4892                         break;
4893                 case SMB2_FILE_PIPE_INFO:
4894                         offset = dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
4895                         break;
4896                 case SMB2_FILE_COMPRESSION_INFO:
4897                         offset = dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
4898                         break;
4899                 case SMB2_FILE_NETWORK_OPEN_INFO:
4900                         offset = dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
4901                         break;
4902                 case SMB2_FILE_ATTRIBUTE_TAG_INFO:
4903                         offset = dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
4904                         break;
4905                 default:
4906                         /* we don't handle this infolevel yet */
4907                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
4908                         offset += tvb_captured_length_remaining(tvb, offset);
4909                 }
4910                 break;
4911         case SMB2_CLASS_FS_INFO:
4912                 switch (infolevel) {
4913                 case SMB2_FS_INFO_01:
4914                         offset = dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
4915                         break;
4916                 case SMB2_FS_INFO_03:
4917                         offset = dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
4918                         break;
4919                 case SMB2_FS_INFO_04:
4920                         offset = dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
4921                         break;
4922                 case SMB2_FS_INFO_05:
4923                         offset = dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
4924                         break;
4925                 case SMB2_FS_INFO_06:
4926                         offset = dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
4927                         break;
4928                 case SMB2_FS_INFO_07:
4929                         offset = dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
4930                         break;
4931                 case SMB2_FS_OBJECTID_INFO:
4932                         offset = dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
4933                         break;
4934                 default:
4935                         /* we don't handle this infolevel yet */
4936                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
4937                         offset += tvb_captured_length_remaining(tvb, offset);
4938                 }
4939                 break;
4940         case SMB2_CLASS_SEC_INFO:
4941                 switch (infolevel) {
4942                 case SMB2_SEC_INFO_00:
4943                         offset = dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
4944                         break;
4945                 default:
4946                         /* we don't handle this infolevel yet */
4947                         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
4948                         offset += tvb_captured_length_remaining(tvb, offset);
4949                 }
4950                 break;
4951         case SMB2_CLASS_QUOTA_INFO:
4952                 offset = dissect_smb2_quota_info(tvb, pinfo, tree, offset, si);
4953                 break;
4954         default:
4955                 /* we don't handle this class yet */
4956                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
4957                 offset += tvb_captured_length_remaining(tvb, offset);
4958         }
4959
4960         /* if we get BUFFER_OVERFLOW there will be truncated data */
4961         if (si->status == 0x80000005) {
4962                 proto_item *item;
4963                 item = proto_tree_add_item(tree, hf_smb2_truncated, tvb, old_offset, 0, ENC_NA);
4964                 PROTO_ITEM_SET_GENERATED(item);
4965         }
4966         return offset;
4967 }
4968
4969 static void
4970 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4971 {
4972         /* data */
4973         if (si->saved) {
4974                 dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->smb2_class, si->saved->infolevel);
4975         } else {
4976                 /* some unknown bytes */
4977                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
4978         }
4979
4980 }
4981
4982
4983 static int
4984 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4985 {
4986         offset_length_buffer_t olb;
4987         gboolean continue_dissection;
4988
4989         /* class/infolevel */
4990         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
4991
4992         switch (si->status) {
4993         case 0x00000000:
4994         /* if we get BUFFER_OVERFLOW there will be truncated data */
4995         case 0x80000005:
4996         /* if we get BUFFER_TOO_SMALL there will not be any data there, only
4997          * a guin32 specifying how big the buffer needs to be
4998          */
4999                 /* buffer code */
5000                 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5001                 break;
5002         case 0xc0000023:
5003                 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5004                 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
5005                 proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5006                 offset += 4;
5007
5008                 return offset;
5009         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5010                 if (!continue_dissection) return offset;
5011         }
5012
5013          /* response buffer offset  and size */
5014         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
5015
5016         /* response data*/
5017         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
5018
5019         return offset;
5020 }
5021
5022 static int
5023 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5024 {
5025         proto_tree *flags_tree = NULL;
5026         proto_item *flags_item = NULL;
5027
5028         /* buffer code */
5029         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5030
5031         /* close flags */
5032         if (tree) {
5033                 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5034                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
5035         }
5036         proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5037         offset += 2;
5038
5039         /* padding */
5040         offset += 4;
5041
5042         /* fid */
5043         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
5044
5045         return offset;
5046 }
5047
5048 static int
5049 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5050 {
5051         proto_tree *flags_tree = NULL;
5052         proto_item *flags_item = NULL;
5053         gboolean continue_dissection;
5054
5055         switch (si->status) {
5056         /* buffer code */
5057         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5058         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5059                 if (!continue_dissection) return offset;
5060         }
5061
5062         /* close flags */
5063         if (tree) {
5064                 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5065                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
5066         }
5067         proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5068         offset += 2;
5069
5070         /* reserved */
5071         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5072         offset += 4;
5073
5074         /* create time */
5075         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
5076
5077         /* last access */
5078         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
5079
5080         /* last write */
5081         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
5082
5083         /* last change */
5084         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
5085
5086         /* allocation size */
5087         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5088         offset += 8;
5089
5090         /* end of file */
5091         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5092         offset += 8;
5093
5094         /* File Attributes */
5095         offset = dissect_file_ext_attr(tvb, tree, offset);
5096
5097         return offset;
5098 }
5099
5100 static int
5101 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5102 {
5103         /* buffer code */
5104         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5105
5106         /* some unknown bytes */
5107         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
5108         offset += 6;
5109
5110         /* fid */
5111         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5112
5113         return offset;
5114 }
5115
5116 static int
5117 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5118 {
5119         gboolean continue_dissection;
5120
5121         switch (si->status) {
5122         /* buffer code */
5123         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5124         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5125                 if (!continue_dissection) return offset;
5126         }
5127
5128         /* some unknown bytes */
5129         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
5130         offset += 2;
5131
5132         return offset;
5133 }
5134
5135
5136 static int
5137 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5138 {
5139         guint16 lock_count;
5140
5141         /* buffer code */
5142         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5143
5144         /* lock count */
5145         lock_count = tvb_get_letohs(tvb, offset);
5146         proto_tree_add_item(tree, hf_smb2_lock_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5147         offset += 2;
5148
5149         /* reserved */
5150         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5151         offset += 4;
5152
5153         /* fid */
5154         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5155
5156         while (lock_count--) {
5157                 proto_item *lock_item = NULL;
5158                 proto_tree *lock_tree = NULL;
5159                 static const int *lf_fields[] = {
5160                         &hf_smb2_lock_flags_shared,
5161                         &hf_smb2_lock_flags_exclusive,
5162                         &hf_smb2_lock_flags_unlock,
5163                         &hf_smb2_lock_flags_fail_immediately,
5164                         NULL
5165                 };
5166
5167                 if (tree) {
5168                         lock_item = proto_tree_add_item(tree, hf_smb2_lock_info, tvb, offset, 24, ENC_NA);
5169                         lock_tree = proto_item_add_subtree(lock_item, ett_smb2_lock_info);
5170                 }
5171
5172                 /* offset */
5173                 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5174                 offset += 8;
5175
5176                 /* count */
5177                 proto_tree_add_item(lock_tree, hf_smb2_lock_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5178                 offset += 8;
5179
5180                 /* flags */
5181                 proto_tree_add_bitmask(lock_tree, tvb, offset, hf_smb2_lock_flags, ett_smb2_lock_flags, lf_fields, ENC_LITTLE_ENDIAN);
5182                 offset += 4;
5183
5184                 /* reserved */
5185                 proto_tree_add_item(lock_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5186                 offset += 4;
5187         }
5188
5189         return offset;
5190 }
5191
5192 static int
5193 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5194 {
5195         gboolean continue_dissection;
5196
5197         switch (si->status) {
5198         /* buffer code */
5199         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5200         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5201                 if (!continue_dissection) return offset;
5202         }
5203
5204         /* some unknown bytes */
5205         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
5206         offset += 2;
5207
5208         return offset;
5209 }
5210 static int
5211 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5212 {
5213         /* buffer code */
5214         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5215
5216         /* some unknown bytes */
5217         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
5218         offset += 2;
5219
5220         return offset;
5221 }
5222
5223 static const smb2_fid_info_t *
5224 smb2_pipe_get_fid_info(const smb2_info_t *si)
5225 {
5226         smb2_fid_info_t *file = NULL;
5227
5228         if (si == NULL) {
5229                 return NULL;
5230         }
5231         if (si->file != NULL) {
5232                 file = si->file;
5233         } else if (si->saved != NULL) {
5234                 file = si->saved->file;
5235         }
5236         if (file == NULL) {
5237                 return NULL;
5238         }
5239
5240         return file;
5241 }
5242
5243 static void
5244 smb2_pipe_set_file_id(packet_info *pinfo, smb2_info_t *si)
5245 {
5246         guint64 persistent;
5247         const smb2_fid_info_t *file = NULL;
5248
5249         file = smb2_pipe_get_fid_info(si);
5250         if (file == NULL) {
5251                 return;
5252         }
5253
5254         persistent = GPOINTER_TO_UINT(file);
5255
5256         dcerpc_set_transport_salt(persistent, pinfo);
5257 }
5258
5259 static gboolean smb2_pipe_reassembly = TRUE;
5260 static reassembly_table smb2_pipe_reassembly_table;
5261
5262 static int
5263 dissect_file_data_smb2_pipe(tvbuff_t *raw_tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, proto_tree *top_tree, void *data)
5264 {
5265         /*
5266          * Note: si is NULL for some callers from packet-smb.c
5267          */
5268         const smb2_info_t *si = (const smb2_info_t *)data;
5269         gboolean result=0;
5270         gboolean save_fragmented;
5271         gint remaining;
5272         guint reported_len;
5273         const smb2_fid_info_t *file = NULL;
5274         guint32 id;
5275         fragment_head *fd_head;
5276         tvbuff_t *tvb;
5277         tvbuff_t *new_tvb;
5278         proto_item *frag_tree_item;
5279         heur_dtbl_entry_t *hdtbl_entry;
5280
5281         file = smb2_pipe_get_fid_info(si);
5282         id = (guint32)(GPOINTER_TO_UINT(file) & G_MAXUINT32);
5283
5284         remaining = tvb_captured_length_remaining(raw_tvb, offset);
5285
5286         tvb = tvb_new_subset_length_caplen(raw_tvb, offset,
5287                              MIN((int)datalen, remaining),
5288                              datalen);
5289
5290         /*
5291          * Offer desegmentation service to Named Pipe subdissectors (e.g. DCERPC)
5292          * if we have all the data.  Otherwise, reassembly is (probably) impossible.
5293          */
5294         pinfo->can_desegment = 0;
5295         pinfo->desegment_offset = 0;
5296         pinfo->desegment_len = 0;
5297         reported_len = tvb_reported_length(tvb);
5298         if (smb2_pipe_reassembly && tvb_captured_length(tvb) >= reported_len) {
5299                 pinfo->can_desegment = 2;
5300         }
5301
5302         save_fragmented = pinfo->fragmented;
5303
5304         /*
5305          * if we are not offering desegmentation, just try the heuristics
5306          *and bail out
5307          */
5308         if (!pinfo->can_desegment) {
5309                 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5310                                                  tvb, pinfo, top_tree,
5311                                                  &hdtbl_entry, data);
5312                 goto clean_up_and_exit;
5313         }
5314
5315         /* below this line, we know we are doing reassembly */
5316
5317         /*
5318          * this is a new packet, see if we are already reassembling this
5319          * pdu and if not, check if the dissector wants us
5320          * to reassemble it
5321          */
5322         if (!pinfo->fd->flags.visited) {
5323                 /*
5324                  * This is the first pass.
5325                  *
5326                  * Check if we are already reassembling this PDU or not;
5327                  * we check for an in-progress reassembly for this FID
5328                  * in this direction, by searching for its reassembly
5329                  * structure.
5330                  */
5331                 fd_head = fragment_get(&smb2_pipe_reassembly_table,
5332                                        pinfo, id, NULL);
5333                 if (!fd_head) {
5334                         /*
5335                          * No reassembly, so this is a new pdu. check if the
5336                          * dissector wants us to reassemble it or if we
5337                          * already got the full pdu in this tvb.
5338                          */
5339
5340                         /*
5341                          * Try the heuristic dissectors and see if we
5342                          * find someone that recognizes this payload.
5343                          */
5344                         result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5345                                                          tvb, pinfo, top_tree,
5346                                                          &hdtbl_entry, data);
5347
5348                         /* no this didn't look like something we know */
5349                         if (!result) {
5350                                 goto clean_up_and_exit;
5351                         }
5352
5353                         /* did the subdissector want us to reassemble any
5354                            more data ?
5355                         */
5356                         if (pinfo->desegment_len) {
5357                                 fragment_add_check(&smb2_pipe_reassembly_table,
5358                                         tvb, 0, pinfo, id, NULL,
5359                                         0, reported_len, TRUE);
5360                                 fragment_set_tot_len(&smb2_pipe_reassembly_table,
5361                                         pinfo, id, NULL,
5362                                         pinfo->desegment_len+reported_len);
5363                         }
5364                         goto clean_up_and_exit;
5365                 }
5366
5367                 /* OK, we're already doing a reassembly for this FID.
5368                    skip to last segment in the existing reassembly structure
5369                    and add this fragment there
5370
5371                    XXX we might add code here to use any offset values
5372                    we might pick up from the Read/Write calls instead of
5373                    assuming we always get them in the correct order
5374                 */
5375                 while (fd_head->next) {
5376                         fd_head = fd_head->next;
5377                 }
5378                 fd_head = fragment_add_check(&smb2_pipe_reassembly_table,
5379                         tvb, 0, pinfo, id, NULL,
5380                         fd_head->offset+fd_head->len,
5381                         reported_len, TRUE);
5382
5383                 /* if we completed reassembly */
5384                 if (fd_head) {
5385                         new_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
5386                         add_new_data_source(pinfo, new_tvb,
5387                                   "Named Pipe over SMB2");
5388                         pinfo->fragmented=FALSE;
5389
5390                         tvb = new_tvb;
5391
5392                         /* list what segments we have */
5393                         show_fragment_tree(fd_head, &smb2_pipe_frag_items,
5394                                            tree, pinfo, tvb, &frag_tree_item);
5395
5396                         /* dissect the full PDU */
5397                         result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5398                                                          tvb, pinfo, top_tree,
5399                                                          &hdtbl_entry, data);
5400                 }
5401                 goto clean_up_and_exit;
5402         }
5403
5404         /*
5405          * This is not the first pass; see if it's in the table of
5406          * reassembled packets.
5407          *
5408          * XXX - we know that several of the arguments aren't going to
5409          * be used, so we pass bogus variables.  Can we clean this
5410          * up so that we don't have to distinguish between the first
5411          * pass and subsequent passes?
5412          */
5413         fd_head = fragment_add_check(&smb2_pipe_reassembly_table,
5414                                      tvb, 0, pinfo, id, NULL, 0, 0, TRUE);
5415         if (!fd_head) {
5416                 /* we didn't find it, try any of the heuristic dissectors
5417                    and bail out
5418                 */
5419                 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5420                                                  tvb, pinfo, top_tree,
5421                                                  &hdtbl_entry, data);
5422                 goto clean_up_and_exit;
5423         }
5424         if (!(fd_head->flags&FD_DEFRAGMENTED)) {
5425                 /* we don't have a fully reassembled frame */
5426                 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5427                                                  tvb, pinfo, top_tree,
5428                                                  &hdtbl_entry, data);
5429                 goto clean_up_and_exit;
5430         }
5431
5432         /* it is reassembled but it was reassembled in a different frame */
5433         if (pinfo->num != fd_head->reassembled_in) {
5434                 proto_item *item;
5435                 item = proto_tree_add_uint(top_tree, hf_smb2_pipe_reassembled_in,
5436                                            tvb, 0, 0, fd_head->reassembled_in);
5437                 PROTO_ITEM_SET_GENERATED(item);
5438                 goto clean_up_and_exit;
5439         }
5440
5441         /* display the reassembled pdu */
5442         new_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
5443         add_new_data_source(pinfo, new_tvb,
5444                   "Named Pipe over SMB2");
5445         pinfo->fragmented = FALSE;
5446
5447         tvb = new_tvb;
5448
5449         /* list what segments we have */
5450         show_fragment_tree(fd_head, &smb2_pipe_frag_items,
5451                            top_tree, pinfo, tvb, &frag_tree_item);
5452
5453         /* dissect the full PDU */
5454         result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5455                                          tvb, pinfo, top_tree,
5456                                          &hdtbl_entry, data);
5457
5458 clean_up_and_exit:
5459         /* clear out the variables */
5460         pinfo->can_desegment=0;
5461         pinfo->desegment_offset = 0;
5462         pinfo->desegment_len = 0;
5463
5464         if (!result) {
5465                 call_data_dissector(tvb, pinfo, top_tree);
5466         }
5467
5468         pinfo->fragmented = save_fragmented;
5469
5470         offset += datalen;
5471         return offset;
5472 }
5473
5474 #define SMB2_CHANNEL_NONE               0x00000000
5475 #define SMB2_CHANNEL_RDMA_V1            0x00000001
5476 #define SMB2_CHANNEL_RDMA_V1_INVALIDATE 0x00000002
5477
5478 static const value_string smb2_channel_vals[] = {
5479         { SMB2_CHANNEL_NONE,    "None" },
5480         { SMB2_CHANNEL_RDMA_V1, "RDMA V1" },
5481         { SMB2_CHANNEL_RDMA_V1_INVALIDATE,      "RDMA V1_INVALIDATE" },
5482         { 0, NULL }
5483 };
5484
5485 static void
5486 dissect_smb2_rdma_v1_blob(tvbuff_t *tvb, packet_info *pinfo _U_,
5487                           proto_tree *parent_tree, smb2_info_t *si _U_)
5488 {
5489         int         offset      = 0;
5490         int         len;
5491         int         i;
5492         int         num;
5493         proto_tree *sub_tree;
5494         proto_item *parent_item;
5495
5496         parent_item = proto_tree_get_parent(parent_tree);
5497
5498         len = tvb_reported_length(tvb);
5499
5500         num = len / 16;
5501
5502         if (parent_item) {
5503                 proto_item_append_text(parent_item, ": SMBDirect Buffer Descriptor V1: (%d elements)", num);
5504         }
5505
5506         for (i = 0; i < num; i++) {
5507                 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, 8, ett_smb2_rdma_v1, NULL, "RDMA V1");
5508
5509                 proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5510                 offset += 8;
5511
5512                 proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5513                 offset += 4;
5514
5515                 proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5516                 offset += 4;
5517         }
5518 }
5519
5520 #define SMB2_WRITE_FLAG_WRITE_THROUGH           0x00000001
5521
5522 static int
5523 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5524 {
5525         guint16 dataoffset = 0;
5526         guint32 data_tvb_len;
5527         offset_length_buffer_t c_olb;
5528         guint32 channel;
5529         guint32 length;
5530         guint64 off;
5531         static const int *f_fields[] = {
5532                 &hf_smb2_write_flags_write_through,
5533                 NULL
5534         };
5535
5536         /* buffer code */
5537         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5538
5539         /* data offset */
5540         dataoffset=tvb_get_letohs(tvb,offset);
5541         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5542         offset += 2;
5543
5544         /* length */
5545         length = tvb_get_letohl(tvb, offset);
5546         proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5547         offset += 4;
5548
5549         /* offset */
5550         off = tvb_get_letoh64(tvb, offset);
5551         if (si->saved) si->saved->file_offset=off;
5552         proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5553         offset += 8;
5554
5555         col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", length, off);
5556
5557         /* fid */
5558         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5559
5560         /* channel */
5561         channel = tvb_get_letohl(tvb, offset);
5562         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5563         offset += 4;
5564
5565         /* remaining bytes */
5566         proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5567         offset += 4;
5568
5569         /* write channel info blob offset/length */
5570         offset = dissect_smb2_olb_length_offset(tvb, offset, &c_olb, OLB_O_UINT16_S_UINT16, hf_smb2_channel_info_blob);
5571
5572         /* flags */
5573         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_write_flags, ett_smb2_write_flags, f_fields, ENC_LITTLE_ENDIAN);
5574         offset += 4;
5575
5576         /* the write channel info blob itself */
5577         switch (channel) {
5578         case SMB2_CHANNEL_RDMA_V1:
5579         case SMB2_CHANNEL_RDMA_V1_INVALIDATE:
5580                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, dissect_smb2_rdma_v1_blob);
5581                 break;
5582         case SMB2_CHANNEL_NONE:
5583         default:
5584                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, NULL);
5585                 break;
5586         }
5587
5588         data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
5589
5590         /* data or namedpipe ?*/
5591         if (length) {
5592                 int oldoffset = offset;
5593                 smb2_pipe_set_file_id(pinfo, si);
5594                 offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
5595                 if (offset != oldoffset) {
5596                         /* managed to dissect pipe data */
5597                         goto out;
5598                 }
5599         }
5600
5601         /* just ordinary data */
5602         proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, ENC_NA);
5603
5604         offset += MIN(length,(guint32)tvb_captured_length_remaining(tvb, offset));
5605
5606         offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
5607
5608 out:
5609         if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
5610                 if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
5611                         feed_eo_smb2(tvb,pinfo,si,dataoffset,length,off);
5612                 }
5613         }
5614
5615         return offset;
5616 }
5617
5618
5619 static int
5620 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5621 {
5622         gboolean continue_dissection;
5623
5624         switch (si->status) {
5625         /* buffer code */
5626         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5627         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5628                 if (!continue_dissection) return offset;
5629         }
5630
5631         /* reserved */
5632         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5633         offset += 2;
5634
5635         /* count */
5636         proto_tree_add_item(tree, hf_smb2_write_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5637         offset += 4;
5638
5639         /* remaining, must be set to 0 */
5640         proto_tree_add_item(tree, hf_smb2_write_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5641         offset += 4;
5642
5643         /* write channel info offset */
5644         proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5645         offset += 2;
5646
5647         /* write channel info length */
5648         proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5649         offset += 2;
5650
5651         return offset;
5652 }
5653
5654 /* The STORAGE_OFFLOAD_TOKEN is used for "Offload Data Transfer" (ODX) operations,
5655    including FSCTL_OFFLOAD_READ, FSCTL_OFFLOAD_WRITE.  Ref: MS-FSCC 2.3.79
5656    Note: Unlike most of SMB2, the token fields are BIG-endian! */
5657 static int
5658 dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
5659 {
5660         proto_tree *sub_tree;
5661         proto_item *sub_item;
5662         guint32 idlen = 0;
5663         guint32 idtype = 0;
5664
5665         sub_tree = proto_tree_add_subtree(tree, tvb, offset, 512, ett_smb2_fsctl_odx_token, &sub_item, "Token");
5666
5667         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_fsctl_odx_token_type, tvb, offset, 4, ENC_BIG_ENDIAN, &idtype);
5668         offset += 4;
5669
5670         proto_item_append_text(sub_item, " (IdType 0x%x)", idtype);
5671
5672         /* reserved */
5673         proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5674         offset += 2;
5675
5676         /* TokenIdLength */
5677         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_fsctl_odx_token_idlen, tvb, offset, 2, ENC_BIG_ENDIAN, &idlen);
5678         offset += 2;
5679
5680         /* idlen is what the server says is the "meaningful" part of the token.
5681                 However, token ID is always 504 bytes */
5682         proto_tree_add_bytes_format_value(sub_tree, hf_smb2_fsctl_odx_token_idraw, tvb,
5683                                           offset, idlen, NULL, "Opaque Data");
5684         offset += 504;
5685
5686         return (offset);
5687 }
5688
5689 /* MS-FSCC 2.3.77, 2.3.78 */
5690 static void
5691 dissect_smb2_FSCTL_OFFLOAD_READ(tvbuff_t *tvb,
5692                                 packet_info *pinfo _U_,
5693                                 proto_tree *tree,
5694                                 int offset,
5695                                 gboolean in)
5696 {
5697         proto_tree_add_item(tree, hf_smb2_fsctl_odx_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5698         offset += 4;
5699
5700         proto_tree_add_item(tree, hf_smb2_fsctl_odx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5701         offset += 4;
5702
5703         if (in) {
5704                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_token_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5705                 offset += 4;
5706
5707                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5708                 offset += 4;
5709
5710                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5711                 offset += 8;
5712
5713                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_copy_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5714                 /* offset += 8; */
5715         } else {
5716                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_xfer_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5717                 offset += 8;
5718
5719                 (void) dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvb, pinfo, tree, offset);
5720         }
5721 }
5722
5723 /* MS-FSCC 2.3.80, 2.3.81 */
5724 static void
5725 dissect_smb2_FSCTL_OFFLOAD_WRITE(tvbuff_t *tvb,
5726                                 packet_info *pinfo _U_,
5727                                 proto_tree *tree,
5728                                 int offset,
5729                                 gboolean in)
5730 {
5731         proto_tree_add_item(tree, hf_smb2_fsctl_odx_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5732         offset += 4;
5733
5734         proto_tree_add_item(tree, hf_smb2_fsctl_odx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5735         offset += 4;
5736
5737         if (in) {
5738                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5739                 offset += 8;
5740
5741                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_copy_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5742                 offset += 8;
5743
5744                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_token_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5745                 offset += 8;
5746
5747                 dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvb, pinfo, tree, offset);
5748
5749         } else {
5750                 proto_tree_add_item(tree, hf_smb2_fsctl_odx_xfer_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5751                 /* offset += 8; */
5752         }
5753 }
5754
5755 static void
5756 dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *top_tree, gboolean data_in _U_, void *data)
5757 {
5758         dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, tvb_captured_length_remaining(tvb, offset), top_tree, data);
5759 }
5760
5761 static void
5762 dissect_smb2_FSCTL_PIPE_WAIT(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, proto_tree *top_tree, gboolean data_in _U_)
5763 {
5764         guint8 timeout_specified = tvb_get_guint8(tvb, offset + 12);
5765         guint32 name_len = tvb_get_letohs(tvb, offset + 8);
5766         const gchar *name;
5767         int off = offset + 14;
5768         guint16 bc = tvb_captured_length_remaining(tvb, off);
5769         int len = name_len;
5770
5771         /* sanity check */
5772         tvb_ensure_bytes_exist(tvb, off, name_len);
5773
5774         name = get_unicode_or_ascii_string(tvb, &off, TRUE, &len, TRUE, TRUE, &bc);
5775         if (name == NULL) {
5776                 name = "";
5777         }
5778
5779         col_append_fstr(pinfo->cinfo, COL_INFO, " Pipe: %s", name);
5780
5781         if (top_tree) {
5782                 proto_tree_add_string(top_tree, hf_smb2_fsctl_pipe_wait_name, tvb, offset + 14, name_len, name);
5783                 if (timeout_specified) {
5784                         proto_tree_add_item(top_tree, hf_smb2_fsctl_pipe_wait_timeout, tvb, 0, 8, ENC_LITTLE_ENDIAN);
5785                 }
5786         }
5787 }
5788
5789 static int
5790 dissect_smb2_FSCTL_SET_SPARSE(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
5791 {
5792
5793         /* There is no out data */
5794         if (!data_in) {
5795                 return offset;
5796         }
5797
5798         /* sparse flag (optional) */
5799         if (tvb_reported_length_remaining(tvb, offset) >= 1) {
5800                 proto_tree_add_item(tree, hf_smb2_fsctl_sparse_flag, tvb, offset, 1, ENC_NA);
5801                 offset += 1;
5802         }
5803
5804         return offset;
5805 }
5806
5807 static int
5808 dissect_smb2_FSCTL_SET_ZERO_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
5809 {
5810         proto_tree *sub_tree;
5811         proto_item *sub_item;
5812
5813         /* There is no out data */
5814         if (!data_in) {
5815                 return offset;
5816         }
5817
5818         sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
5819
5820         proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5821         offset += 8;
5822
5823         proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5824         offset += 8;
5825
5826         return offset;
5827 }
5828
5829 static void
5830 dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in)
5831 {
5832         proto_tree *sub_tree;
5833         proto_item *sub_item;
5834
5835         if (data_in) {
5836                 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
5837
5838                 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5839                 offset += 8;
5840
5841                 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5842                 offset += 8;
5843         } else {
5844                 /* Zero or more allocated ranges may be reported. */
5845                 while (tvb_reported_length_remaining(tvb, offset) >= 16) {
5846
5847                         sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
5848
5849                         proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5850                         offset += 8;
5851
5852                         proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5853                         offset += 8;
5854                 }
5855         }
5856 }
5857
5858
5859 static void
5860 dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in)
5861 {
5862
5863         if (data_in) {
5864                 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5865                 offset += 8;
5866
5867                 proto_tree_add_item(tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5868                 offset += 8;
5869
5870                 proto_tree_add_item(tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5871                 offset += 4;
5872
5873                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5874                 offset += 4;
5875         } else {
5876                 guint32 entry_count = 0;
5877
5878                 proto_tree_add_item(tree, hf_smb2_qfr_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5879                 offset += 4;
5880
5881                 proto_tree_add_item(tree, hf_smb2_qfr_total_region_entry_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5882                 offset += 4;
5883
5884                 proto_tree_add_item_ret_uint(tree, hf_smb2_qfr_region_entry_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &entry_count);
5885                 offset += 4;
5886
5887                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5888                 offset += 4;
5889
5890                 while (entry_count && tvb_reported_length_remaining(tvb, offset)) {
5891                         proto_tree *sub_tree;
5892                         proto_item *sub_item;
5893
5894                         sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_qfr_entry, &sub_item, "Entry");
5895
5896                         proto_tree_add_item(sub_tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5897                         offset += 8;
5898
5899                         proto_tree_add_item(sub_tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5900                         offset += 8;
5901
5902                         proto_tree_add_item(sub_tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5903                         offset += 4;
5904
5905                         proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5906                         offset += 4;
5907
5908                         entry_count--;
5909                 }
5910         }
5911 }
5912
5913 static void
5914 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
5915 {
5916         /* There is no out data */
5917         if (!data_in) {
5918                 return;
5919         }
5920
5921         /* timeout */
5922         proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5923         offset += 4;
5924
5925         /* reserved */
5926         proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5927 }
5928
5929 static void
5930 dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
5931 {
5932         /* There is no in data */
5933         if (data_in) {
5934                 return;
5935         }
5936
5937         proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_support, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5938         offset += 4;
5939
5940         proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_handle_state, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5941 }
5942
5943 #define STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID 0x00000001
5944 #define STORAGE_QOS_CONTROL_FLAG_SET_POLICY 0x00000002
5945 #define STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY 0x00000004
5946 #define STORAGE_QOS_CONTROL_FLAG_GET_STATUS 0x00000008
5947 #define STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS 0x00000010
5948
5949 static const value_string smb2_ioctl_sqos_protocol_version_vals[] = {
5950         { 0x0100, "Storage QoS Protocol Version 1.0" },
5951         { 0x0101, "Storage QoS Protocol Version 1.1" },
5952         { 0, NULL }
5953 };
5954
5955 static const value_string smb2_ioctl_sqos_status_vals[] = {
5956         { 0x00, "StorageQoSStatusOk" },
5957         { 0x01, "StorageQoSStatusInsufficientThroughput" },
5958         { 0x02, "StorageQoSUnknownPolicyId" },
5959         { 0x04, "StorageQoSStatusConfigurationMismatch" },
5960         { 0x05, "StorageQoSStatusNotAvailable" },
5961         { 0, NULL }
5962 };
5963
5964 static void
5965 dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, gboolean data_in)
5966 {
5967         static const int * operations[] = {
5968                 &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
5969                 &hf_smb2_ioctl_sqos_op_set_policy,
5970                 &hf_smb2_ioctl_sqos_op_probe_policy,
5971                 &hf_smb2_ioctl_sqos_op_get_status,
5972                 &hf_smb2_ioctl_sqos_op_update_counters,
5973                 NULL
5974         };
5975
5976         gint proto_ver;
5977
5978         /* Both request and reply have the same common header */
5979
5980         proto_ver = tvb_get_letohs(tvb, offset);
5981         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_protocol_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5982         offset += 2;
5983
5984         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5985         offset += 2;
5986
5987         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_ioctl_sqos_options,
5988                                                         ett_smb2_ioctl_sqos_opeations, operations, ENC_LITTLE_ENDIAN);
5989         offset += 4;
5990
5991         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_logical_flow_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5992         offset += 16;
5993
5994         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_policy_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5995         offset += 16;
5996
5997         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_initiator_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5998         offset += 16;
5999
6000         if (data_in) {
6001                 offset_length_buffer_t host_olb, node_olb;
6002
6003                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6004                 offset += 8;
6005
6006                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reservation, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6007                 offset += 8;
6008
6009                 offset = dissect_smb2_olb_length_offset(tvb, offset, &host_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_name);
6010
6011                 offset = dissect_smb2_olb_length_offset(tvb, offset, &node_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_node_name);
6012
6013                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6014                 offset += 8;
6015
6016                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_normalized_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6017                 offset += 8;
6018
6019                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6020                 offset += 8;
6021
6022                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_lower_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6023                 offset += 8;
6024
6025                 if (proto_ver > 0x0100) {
6026                         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_bandwidth_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6027                         offset += 8;
6028
6029                         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_kilobyte_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6030                         /*offset += 8;*/
6031                 }
6032
6033                 dissect_smb2_olb_string(pinfo, tree, tvb, &host_olb, OLB_TYPE_UNICODE_STRING);
6034
6035                 dissect_smb2_olb_string(pinfo, tree, tvb, &node_olb, OLB_TYPE_UNICODE_STRING);
6036         } else {
6037                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_time_to_live, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6038                 offset += 4;
6039
6040                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6041                 offset += 4;
6042
6043                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6044                 offset += 8;
6045
6046                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_minimum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6047                 offset += 8;
6048
6049                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_base_io_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6050                 offset += 4;
6051
6052                 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6053
6054                 if (proto_ver > 0x0100) {
6055                         offset += 4;
6056                         proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_bandwidth, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6057                 }
6058         }
6059 }
6060
6061 static void
6062 dissect_windows_sockaddr_in(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
6063 {
6064         proto_item *sub_item;
6065         proto_tree *sub_tree;
6066         proto_item *parent_item;
6067
6068         if (len == -1) {
6069                 len = 16;
6070         }
6071
6072         sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
6073         parent_item = proto_tree_get_parent(parent_tree);
6074
6075         /* family */
6076         proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6077         offset += 2;
6078
6079         /* port */
6080         proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6081         offset += 2;
6082
6083         /* IPv4 address */
6084         proto_tree_add_item(sub_tree, hf_windows_sockaddr_in_addr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6085
6086         proto_item_append_text(sub_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset));
6087         proto_item_append_text(parent_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset));
6088 }
6089
6090 static void
6091 dissect_windows_sockaddr_in6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
6092 {
6093         proto_item        *sub_item;
6094         proto_tree        *sub_tree;
6095         proto_item        *parent_item;
6096
6097         if (len == -1) {
6098                 len = 16;
6099         }
6100
6101         sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
6102         parent_item = proto_tree_get_parent(parent_tree);
6103
6104         /* family */
6105         proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6106         offset += 2;
6107
6108         /* port */
6109         proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6110         offset += 2;
6111
6112         /* sin6_flowinfo */
6113         proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_flowinfo, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6114         offset += 4;
6115
6116         /* IPv4 address */
6117         proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_addr, tvb, offset, 16, ENC_NA);
6118         proto_item_append_text(sub_item, ", IPv6: %s", tvb_ip6_to_str(tvb, offset));
6119         proto_item_append_text(parent_item, ", IPv6: %s", tvb_ip6_to_str(tvb, offset));
6120         offset += 16;
6121
6122         /* sin6_scope_id */
6123         proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_scope_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6124 }
6125
6126 static void
6127 dissect_windows_sockaddr_storage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6128 {
6129         int         len         = 128;
6130         proto_item *sub_item;
6131         proto_tree *sub_tree;
6132         proto_item *parent_item;
6133         guint16     family;
6134
6135         family = tvb_get_letohs(tvb, offset);
6136         switch (family) {
6137         case WINSOCK_AF_INET:
6138                 dissect_windows_sockaddr_in(tvb, pinfo, parent_tree, offset, len);
6139                 return;
6140         case WINSOCK_AF_INET6:
6141                 dissect_windows_sockaddr_in6(tvb, pinfo, parent_tree, offset, len);
6142                 return;
6143         }
6144
6145         sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
6146         parent_item = proto_tree_get_parent(parent_tree);
6147
6148         /* ss_family */
6149         proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6150         proto_item_append_text(sub_item, ", Family: %d (0x%04x)", family, family);
6151         proto_item_append_text(parent_item, ", Family: %d (0x%04x)", family, family);
6152         /*offset += 2;*/
6153
6154         /* unknown */
6155         /*offset += 126;*/
6156 }
6157
6158 #define NETWORK_INTERFACE_CAP_RSS 0x00000001
6159 #define NETWORK_INTERFACE_CAP_RDMA 0x00000002
6160
6161 static void
6162 dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
6163 {
6164         guint32     next_offset;
6165         int         offset   = 0;
6166         int         len      = -1;
6167         proto_item *sub_item;
6168         proto_tree *sub_tree;
6169         proto_item *item;
6170         guint32     capabilities;
6171         guint64     link_speed;
6172         gfloat      val      = 0;
6173         const char *unit     = NULL;
6174         static const int * capability_flags[] = {
6175                 &hf_smb2_ioctl_network_interface_capability_rdma,
6176                 &hf_smb2_ioctl_network_interface_capability_rss,
6177                 NULL
6178         };
6179
6180         next_offset = tvb_get_letohl(tvb, offset);
6181         if (next_offset) {
6182                 len = next_offset;
6183         }
6184
6185         sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_smb2_ioctl_network_interface, &sub_item, "Network Interface");
6186         item = proto_tree_get_parent(parent_tree);
6187
6188         /* next offset */
6189         proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6190         offset += 4;
6191
6192         /* interface index */
6193         proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6194         offset += 4;
6195
6196         /* capabilities */
6197         capabilities = tvb_get_letohl(tvb, offset);
6198         proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_ioctl_network_interface_capabilities, ett_smb2_ioctl_network_interface_capabilities, capability_flags, ENC_LITTLE_ENDIAN);
6199
6200         if (capabilities != 0) {
6201                 proto_item_append_text(item, "%s%s",
6202                                        (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
6203                                        (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
6204                 proto_item_append_text(sub_item, "%s%s",
6205                                        (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
6206                                        (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
6207         }
6208         offset += 4;
6209
6210         /* rss queue count */
6211         proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_rss_queue_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6212         offset += 4;
6213
6214         /* link speed */
6215         link_speed = tvb_get_letoh64(tvb, offset);
6216         item = proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_link_speed, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6217         if (link_speed >= (1000*1000*1000)) {
6218                 val = (gfloat)(link_speed / (1000*1000*1000));
6219                 unit = "G";
6220         } else if (link_speed >= (1000*1000)) {
6221                 val = (gfloat)(link_speed / (1000*1000));
6222                 unit = "M";
6223         } else if (link_speed >= (1000)) {
6224                 val = (gfloat)(link_speed / (1000));
6225                 unit = "K";
6226         } else {
6227                 val = (gfloat)(link_speed);
6228                 unit = "";
6229         }
6230         proto_item_append_text(item, ", %.1f %sBits/s", val, unit);
6231         proto_item_append_text(sub_item, ", %.1f %sBits/s", val, unit);
6232
6233         offset += 8;
6234
6235         /* socket address */
6236         dissect_windows_sockaddr_storage(tvb, pinfo, sub_tree, offset);
6237
6238         if (next_offset) {
6239                 tvbuff_t *next_tvb;
6240                 next_tvb = tvb_new_subset_remaining(tvb, next_offset);
6241
6242                 /* next extra info */
6243                 dissect_smb2_NETWORK_INTERFACE_INFO(next_tvb, pinfo, parent_tree);
6244         }
6245 }
6246
6247 static void
6248 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
6249 {
6250         /* There is no in data */
6251         if (data_in) {
6252                 return;
6253         }
6254
6255         dissect_smb2_NETWORK_INTERFACE_INFO(tvb, pinfo, tree);
6256 }
6257
6258 static void
6259 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
6260 {
6261         /*
6262          * This is only used by Windows 8 beta
6263          */
6264         if (data_in) {
6265                 /* capabilities */
6266                 offset = dissect_smb2_capabilities(tree, tvb, offset);
6267
6268                 /* client guid */
6269                 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6270                 offset += 16;
6271
6272                 /* security mode, skip second byte */
6273                 offset = dissect_smb2_secmode(tree, tvb, offset);
6274                 offset++;
6275
6276                 /* dialect */
6277                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6278                 offset += 2;
6279         } else {
6280                 /* capabilities */
6281                 offset = dissect_smb2_capabilities(tree, tvb, offset);
6282
6283                 /* server guid */
6284                 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6285                 offset += 16;
6286
6287                 /* security mode, skip second byte */
6288                 offset = dissect_smb2_secmode(tree, tvb, offset);
6289                 offset++;
6290
6291                 /* dialect */
6292                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6293                 offset += 2;
6294         }
6295 }
6296
6297 static void
6298 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
6299 {
6300         if (data_in) {
6301                 guint16 dc;
6302
6303                 /* capabilities */
6304                 offset = dissect_smb2_capabilities(tree, tvb, offset);
6305
6306                 /* client guid */
6307                 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6308                 offset += 16;
6309
6310                 /* security mode, skip second byte */
6311                 offset = dissect_smb2_secmode(tree, tvb, offset);
6312                 offset++;
6313
6314                 /* dialect count */
6315                 dc = tvb_get_letohs(tvb, offset);
6316                 proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6317                 offset += 2;
6318
6319                 for ( ; dc>0; dc--) {
6320                         proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6321                         offset += 2;
6322                 }
6323         } else {
6324                 /* capabilities */
6325                 offset = dissect_smb2_capabilities(tree, tvb, offset);
6326
6327                 /* server guid */
6328                 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6329                 offset += 16;
6330
6331                 /* security mode, skip second byte */
6332                 offset = dissect_smb2_secmode(tree, tvb, offset);
6333                 offset++;
6334
6335                 /* dialect */
6336                 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6337                 offset += 2;
6338         }
6339 }
6340
6341 static void
6342 dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6343 {
6344         guint32 num_volumes;
6345
6346         /* There is no in data */
6347         if (data_in) {
6348                 return;
6349         }
6350
6351         /* num volumes */
6352         num_volumes = tvb_get_letohl(tvb, offset);
6353         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_volumes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6354         offset += 4;
6355
6356         /* num labels */
6357         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_labels, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6358         offset += 4;
6359
6360         /* count */
6361         proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6362         offset += 4;
6363
6364         while (num_volumes--) {
6365                 const char *name;
6366                 guint16 bc;
6367                 int len = 0;
6368                 int old_offset = offset;
6369
6370                 bc = tvb_captured_length_remaining(tvb, offset);
6371                 name = get_unicode_or_ascii_string(tvb, &offset,
6372                         TRUE, &len, TRUE, FALSE, &bc);
6373                 proto_tree_add_string(tree, hf_smb2_ioctl_shadow_copy_label, tvb, old_offset, len, name);
6374
6375                 offset = old_offset+len;
6376
6377                 if (!len) {
6378                         break;
6379                 }
6380         }
6381 }
6382
6383 int
6384 dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
6385 {
6386         proto_item *item = NULL;
6387         proto_tree *tree = NULL;
6388
6389         /* FILE_OBJECTID_BUFFER */
6390         if (parent_tree) {
6391                 item = proto_tree_add_item(parent_tree, hf_smb2_FILE_OBJECTID_BUFFER, tvb, offset, 64, ENC_NA);
6392                 tree = proto_item_add_subtree(item, ett_smb2_FILE_OBJECTID_BUFFER);
6393         }
6394
6395         /* Object ID */
6396         proto_tree_add_item(tree, hf_smb2_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6397         offset += 16;
6398
6399         /* Birth Volume ID */
6400         proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6401         offset += 16;
6402
6403         /* Birth Object ID */
6404         proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6405         offset += 16;
6406
6407         /* Domain ID */
6408         proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6409         offset += 16;
6410
6411         return offset;
6412 }
6413
6414 static int
6415 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6416 {
6417
6418         /* There is no in data */
6419         if (data_in) {
6420                 return offset;
6421         }
6422
6423         /* FILE_OBJECTID_BUFFER */
6424         offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
6425
6426         return offset;
6427 }
6428
6429 static int
6430 dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6431 {
6432
6433         /* There is no in data */
6434         if (data_in) {
6435                 return offset;
6436         }
6437
6438         /* compression format */
6439         proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6440         offset += 2;
6441
6442         return offset;
6443 }
6444
6445 static int
6446 dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6447 {
6448
6449         /* There is no out data */
6450         if (!data_in) {
6451                 return offset;
6452         }
6453
6454         /* compression format */
6455         proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6456         offset += 2;
6457
6458         return offset;
6459 }
6460
6461 static int
6462 dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6463 {
6464         const int *integrity_flags[] = {
6465                 &hf_smb2_integrity_flags_enforcement_off,
6466                 NULL
6467         };
6468
6469         /* There is no out data */
6470         if (!data_in) {
6471                 return offset;
6472         }
6473
6474         proto_tree_add_item(tree, hf_smb2_checksum_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6475         offset += 2;
6476
6477         proto_tree_add_item(tree, hf_smb2_integrity_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6478         offset += 2;
6479
6480         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_integrity_flags, ett_smb2_integrity_flags, integrity_flags, ENC_LITTLE_ENDIAN);
6481         offset += 4;
6482
6483         return offset;
6484 }
6485
6486 static int
6487 dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6488 {
6489
6490         /* There is no out data */
6491         if (!data_in) {
6492                 return offset;
6493         }
6494
6495         /* FILE_OBJECTID_BUFFER */
6496         offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
6497
6498         return offset;
6499 }
6500
6501 static int
6502 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6503 {
6504
6505         /* There is no out data */
6506         if (!data_in) {
6507                 return offset;
6508         }
6509
6510         /* FILE_OBJECTID_BUFFER->ExtendedInfo */
6511
6512         /* Birth Volume ID */
6513         proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6514         offset += 16;
6515
6516         /* Birth Object ID */
6517         proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6518         offset += 16;
6519
6520         /* Domain ID */
6521         proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6522         offset += 16;
6523
6524         return offset;
6525 }
6526
6527 static int
6528 dissect_smb2_cchunk_RESUME_KEY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
6529 {
6530
6531         proto_tree_add_bytes_format_value(tree, hf_smb2_cchunk_resume_key, tvb,
6532                                           offset, 24, NULL, "Opaque Data");
6533         offset += 24;
6534
6535         return (offset);
6536 }
6537
6538 static void
6539 dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6540 {
6541
6542         /* There is no in data */
6543         if (data_in) {
6544                 return;
6545         }
6546
6547         offset = dissect_smb2_cchunk_RESUME_KEY(tvb, pinfo, tree, offset);
6548
6549         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6550 }
6551
6552 static void
6553 dissect_smb2_FSCTL_SRV_COPYCHUNK(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6554 {
6555         proto_tree *sub_tree;
6556         proto_item *sub_item;
6557         guint32 chunk_count = 0;
6558
6559         /* Output is simpler - handle that first. */
6560         if (!data_in) {
6561                 proto_tree_add_item(tree, hf_smb2_cchunk_chunks_written, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6562                 proto_tree_add_item(tree, hf_smb2_cchunk_bytes_written, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
6563                 proto_tree_add_item(tree, hf_smb2_cchunk_total_written, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
6564                 return;
6565         }
6566
6567         /* Input data, fixed part */
6568         offset = dissect_smb2_cchunk_RESUME_KEY(tvb, pinfo, tree, offset);
6569         proto_tree_add_item_ret_uint(tree, hf_smb2_cchunk_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &chunk_count);
6570         offset += 4;
6571
6572         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6573         offset += 4;
6574
6575         /* Zero or more allocated ranges may be reported. */
6576         while (chunk_count && tvb_reported_length_remaining(tvb, offset) >= 24) {
6577                 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_smb2_cchunk_entry, &sub_item, "Chunk");
6578
6579                 proto_tree_add_item(sub_tree, hf_smb2_cchunk_src_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6580                 offset += 8;
6581
6582                 proto_tree_add_item(sub_tree, hf_smb2_cchunk_dst_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6583                 offset += 8;
6584
6585                 proto_tree_add_item(sub_tree, hf_smb2_cchunk_xfer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6586                 offset += 4;
6587
6588                 proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6589                 offset += 4;
6590
6591                 chunk_count--;
6592         }
6593 }
6594
6595 static void
6596 dissect_smb2_FSCTL_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
6597 {
6598         proto_item *item = NULL;
6599         proto_tree *tree = NULL;
6600
6601         offset_length_buffer_t  s_olb, p_olb;
6602
6603         /* SYMBOLIC_LINK_REPARSE_DATA_BUFFER */
6604         if (parent_tree) {
6605                 item = proto_tree_add_item(parent_tree, hf_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER, tvb, offset, -1, ENC_NA);
6606                 tree = proto_item_add_subtree(item, ett_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER);
6607         }
6608
6609         /* reparse tag */
6610         proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6611         offset += 4;
6612
6613         proto_tree_add_item(tree, hf_smb2_reparse_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6614         offset += 2;
6615
6616         /* reserved */
6617         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6618         offset += 2;
6619
6620         /* substitute name  offset/length */
6621         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_substitute_name);
6622
6623         /* print name offset/length */
6624         offset = dissect_smb2_olb_length_offset(tvb, offset, &p_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_print_name);
6625
6626         /* flags */
6627         proto_tree_add_item(tree, hf_smb2_symlink_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6628         offset += 4;
6629
6630         /* substitute name string */
6631         dissect_smb2_olb_off_string(pinfo, tree, tvb, &s_olb, offset, OLB_TYPE_UNICODE_STRING);
6632
6633         /* print name string */
6634         dissect_smb2_olb_off_string(pinfo, tree, tvb, &p_olb, offset, OLB_TYPE_UNICODE_STRING);
6635 }
6636
6637 static void
6638 dissect_smb2_FSCTL_SET_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, gboolean data_in)
6639 {
6640         if (!data_in) {
6641                 return;
6642         }
6643
6644         dissect_smb2_FSCTL_REPARSE_POINT(tvb, pinfo, parent_tree, offset);
6645 }
6646
6647 static void
6648 dissect_smb2_FSCTL_GET_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, gboolean data_in)
6649 {
6650         if (data_in) {
6651                 return;
6652         }
6653
6654         dissect_smb2_FSCTL_REPARSE_POINT(tvb, pinfo, parent_tree, offset);
6655 }
6656
6657 void
6658 dissect_smb2_ioctl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *top_tree, guint32 ioctl_function, gboolean data_in, void *private_data _U_)
6659 {
6660         guint16 dc;
6661
6662         dc = tvb_reported_length(tvb);
6663
6664         switch (ioctl_function) {
6665         case 0x00060194: /* FSCTL_DFS_GET_REFERRALS */
6666                 if (data_in) {
6667                         dissect_get_dfs_request_data(tvb, pinfo, tree, 0, &dc, TRUE);
6668                 } else {
6669                         dissect_get_dfs_referral_data(tvb, pinfo, tree, 0, &dc, TRUE);
6670                 }
6671                 break;
6672         case 0x000940CF: /* FSCTL_QUERY_ALLOCATED_RANGES */
6673                 dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvb, pinfo, tree, 0, data_in);
6674                 break;
6675         case 0x00094264: /* FSCTL_OFFLOAD_READ */
6676                 dissect_smb2_FSCTL_OFFLOAD_READ(tvb, pinfo, tree, 0, data_in);
6677                 break;
6678         case 0x00098268: /* FSCTL_OFFLOAD_WRITE */
6679                 dissect_smb2_FSCTL_OFFLOAD_WRITE(tvb, pinfo, tree, 0, data_in);
6680                 break;
6681         case 0x0011c017: /* FSCTL_PIPE_TRANSCEIVE */
6682                 dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvb, pinfo, tree, 0, top_tree, data_in, private_data);
6683                 break;
6684         case 0x00110018: /* FSCTL_PIPE_WAIT */
6685                 dissect_smb2_FSCTL_PIPE_WAIT(tvb, pinfo, tree, 0, top_tree, data_in);
6686                 break;
6687         case 0x00140078: /* FSCTL_SRV_REQUEST_RESUME_KEY */
6688                 dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvb, pinfo, tree, 0, data_in);
6689                 break;
6690         case 0x001401D4: /* FSCTL_LMR_REQUEST_RESILIENCY */
6691                 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvb, pinfo, tree, 0, data_in);
6692                 break;
6693         case 0x001401FC: /* FSCTL_QUERY_NETWORK_INTERFACE_INFO */
6694                 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvb, pinfo, tree, 0, data_in);
6695                 break;
6696         case 0x00140200: /* FSCTL_VALIDATE_NEGOTIATE_INFO_224 */
6697                 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvb, pinfo, tree, 0, data_in);
6698                 break;
6699         case 0x00140204: /* FSCTL_VALIDATE_NEGOTIATE_INFO */
6700                 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvb, pinfo, tree, 0, data_in);
6701                 break;
6702         case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */
6703                 dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvb, pinfo, tree, 0, data_in);
6704                 break;
6705         case 0x001440F2: /* FSCTL_SRV_COPYCHUNK */
6706         case 0x001480F2: /* FSCTL_SRV_COPYCHUNK_WRITE */
6707                 dissect_smb2_FSCTL_SRV_COPYCHUNK(tvb, pinfo, tree, 0, data_in);
6708                 break;
6709         case 0x000900A4: /* FSCTL_SET_REPARSE_POINT */
6710                 dissect_smb2_FSCTL_SET_REPARSE_POINT(tvb, pinfo, tree, 0, data_in);
6711                 break;
6712         case 0x000900A8: /* FSCTL_GET_REPARSE_POINT */
6713                 dissect_smb2_FSCTL_GET_REPARSE_POINT(tvb, pinfo, tree, 0, data_in);
6714                 break;
6715         case 0x0009009C: /* FSCTL_GET_OBJECT_ID */
6716         case 0x000900c0: /* FSCTL_CREATE_OR_GET_OBJECT_ID */
6717                 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
6718                 break;
6719         case 0x000900c4: /* FSCTL_SET_SPARSE */
6720                 dissect_smb2_FSCTL_SET_SPARSE(tvb, pinfo, tree, 0, data_in);
6721                 break;
6722         case 0x00098098: /* FSCTL_SET_OBJECT_ID */
6723                 dissect_smb2_FSCTL_SET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
6724                 break;
6725         case 0x000980BC: /* FSCTL_SET_OBJECT_ID_EXTENDED */
6726                 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvb, pinfo, tree, 0, data_in);
6727                 break;
6728         case 0x000980C8: /* FSCTL_SET_ZERO_DATA */
6729                 dissect_smb2_FSCTL_SET_ZERO_DATA(tvb, pinfo, tree, 0, data_in);
6730                 break;
6731         case 0x0009003C: /* FSCTL_GET_COMPRESSION */
6732                 dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
6733                 break;
6734         case 0x00090300: /* FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT */
6735                 dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvb, pinfo, tree, 0, data_in);
6736                 break;
6737         case 0x00090304: /* FSCTL_SVHDX_SYNC_TUNNEL or response */
6738         case 0x00090364: /* FSCTL_SVHDX_ASYNC_TUNNEL or response */
6739                 call_dissector_with_data(rsvd_handle, tvb, pinfo, top_tree, &data_in);
6740                 break;
6741         case 0x00090350: /* FSCTL_STORAGE_QOS_CONTROL */
6742                 dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvb, pinfo, tree, 0, data_in);
6743                 break;
6744         case 0x0009C040: /* FSCTL_SET_COMPRESSION */
6745                 dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
6746                 break;
6747         case 0x00090284: /* FSCTL_QUERY_FILE_REGIONS */
6748                 dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvb, pinfo, tree, 0, data_in);
6749                 break;
6750         case 0x0009C280: /* FSCTL_SET_INTEGRITY_INFORMATION request or response */
6751                 dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvb, pinfo, tree, 0, data_in);
6752                 break;
6753         default:
6754                 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
6755         }
6756 }
6757
6758 static void
6759 dissect_smb2_ioctl_data_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
6760 {
6761         smb2_pipe_set_file_id(pinfo, si);
6762         dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, TRUE, si);
6763 }
6764
6765 static void
6766 dissect_smb2_ioctl_data_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
6767 {
6768         smb2_pipe_set_file_id(pinfo, si);
6769         dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, FALSE, si);
6770 }
6771
6772 static int
6773 dissect_smb2_ioctl_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
6774 {
6775         offset_length_buffer_t o_olb;
6776         offset_length_buffer_t i_olb;
6777         proto_tree *flags_tree = NULL;
6778         proto_item *flags_item = NULL;
6779
6780         /* buffer code */
6781         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
6782
6783         /* reserved */
6784         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6785         offset += 2;
6786
6787         /* ioctl function */
6788         offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
6789
6790         /* fid */
6791         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
6792
6793         /* in buffer offset/length */
6794         offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
6795
6796         /* max ioctl in size */
6797         proto_tree_add_item(tree, hf_smb2_max_ioctl_in_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6798         offset += 4;
6799
6800         /* out buffer offset/length */
6801         offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
6802
6803         /* max ioctl out size */
6804         proto_tree_add_item(tree, hf_smb2_max_ioctl_out_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6805         offset += 4;
6806
6807         /* flags */
6808         if (tree) {
6809                 flags_item = proto_tree_add_item(tree, hf_smb2_ioctl_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6810                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_ioctl_flags);
6811         }
6812         proto_tree_add_item(flags_tree, hf_smb2_ioctl_is_fsctl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6813         offset += 4;
6814
6815         /* reserved */
6816         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6817         offset += 4;
6818
6819         /* try to decode these blobs in the order they were encoded
6820          * so that for "short" packets we will dissect as much as possible
6821          * before aborting with "short packet"
6822          */
6823         if (i_olb.off>o_olb.off) {
6824                 /* out buffer */
6825                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
6826                 /* in buffer */
6827                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
6828         } else {
6829                 /* in buffer */
6830                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
6831                 /* out buffer */
6832                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
6833         }
6834
6835         offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
6836         offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
6837
6838         return offset;
6839 }
6840
6841 static int
6842 dissect_smb2_ioctl_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
6843 {
6844         offset_length_buffer_t o_olb;
6845         offset_length_buffer_t i_olb;
6846         gboolean continue_dissection;
6847
6848         switch (si->status) {
6849         /* buffer code */
6850         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
6851         case 0x80000005: break;
6852         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
6853                 if (!continue_dissection) return offset;
6854         }
6855
6856         /* some unknown bytes */
6857         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
6858         offset += 2;
6859
6860         /* ioctl function */
6861         offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
6862
6863         /* fid */
6864         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
6865
6866         /* in buffer offset/length */
6867         offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
6868
6869         /* out buffer offset/length */
6870         offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
6871
6872
6873         /* flags: reserved: must be zero */
6874         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6875         offset += 4;
6876
6877         /* reserved */
6878         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6879         offset += 4;
6880
6881         /* try to decode these blobs in the order they were encoded
6882          * so that for "short" packets we will dissect as much as possible
6883          * before aborting with "short packet"
6884          */
6885         if (i_olb.off>o_olb.off) {
6886                 /* out buffer */
6887                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
6888                 /* in buffer */
6889                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
6890         } else {
6891                 /* in buffer */
6892                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
6893                 /* out buffer */
6894                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
6895         }
6896
6897         offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
6898         offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
6899
6900         return offset;
6901 }
6902
6903
6904 static int
6905 dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
6906 {
6907         offset_length_buffer_t c_olb;
6908         guint32 channel;
6909         guint32 len;
6910         guint64 off;
6911
6912         /* buffer code */
6913         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
6914
6915         /* padding and reserved */
6916         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6917         offset += 2;
6918
6919         /* length */
6920         len = tvb_get_letohl(tvb, offset);
6921         proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6922         offset += 4;
6923
6924         /* offset */
6925         off = tvb_get_letoh64(tvb, offset);
6926         proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6927         offset += 8;
6928
6929         col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", len, off);
6930
6931         /* fid */
6932         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
6933
6934         /* minimum count */
6935         proto_tree_add_item(tree, hf_smb2_min_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6936         offset += 4;
6937
6938         /* channel */
6939         channel = tvb_get_letohl(tvb, offset);
6940         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6941         offset += 4;
6942
6943         /* remaining bytes */
6944         proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6945         offset += 4;
6946
6947         /* read channel info blob offset/length */
6948         offset = dissect_smb2_olb_length_offset(tvb, offset, &c_olb, OLB_O_UINT16_S_UINT16, hf_smb2_channel_info_blob);
6949
6950         /* the read channel info blob itself */
6951         switch (channel) {
6952         case SMB2_CHANNEL_RDMA_V1:
6953                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, dissect_smb2_rdma_v1_blob);
6954                 break;
6955         case SMB2_CHANNEL_NONE:
6956         default:
6957                 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, NULL);
6958                 break;
6959         }
6960
6961         offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
6962
6963         /* Store len and offset */
6964         if (si->saved) {
6965                 si->saved->file_offset=off;
6966                 si->saved->bytes_moved=len;
6967         }
6968
6969         return offset;
6970 }
6971
6972
6973 static int
6974 dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
6975 {
6976         guint16 dataoffset = 0;
6977         guint32 data_tvb_len;
6978         guint32 length;
6979         gboolean continue_dissection;
6980
6981         switch (si->status) {
6982         /* buffer code */
6983         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
6984         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
6985                 if (!continue_dissection) return offset;
6986         }
6987
6988         /* data offset */
6989         dataoffset=tvb_get_letohl(tvb,offset);
6990         proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6991         offset += 2;
6992
6993         /* length  might even be 64bits if they are ambitious*/
6994         length = tvb_get_letohl(tvb, offset);
6995         proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6996         offset += 4;
6997
6998         /* remaining */
6999         proto_tree_add_item(tree, hf_smb2_read_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7000         offset += 4;
7001
7002         /* reserved */
7003         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7004         offset += 4;
7005
7006         data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
7007
7008         /* data or namedpipe ?*/
7009         if (length) {
7010                 int oldoffset = offset;
7011                 smb2_pipe_set_file_id(pinfo, si);
7012                 offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
7013                 if (offset != oldoffset) {
7014                         /* managed to dissect pipe data */
7015                         goto out;
7016                 }
7017         }
7018
7019         /* data */
7020         proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, ENC_NA);
7021
7022         offset += MIN(length,data_tvb_len);
7023
7024 out:
7025         if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
7026                 if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
7027                         feed_eo_smb2(tvb,pinfo,si,dataoffset,length,si->saved->file_offset);
7028                 }
7029         }
7030
7031         return offset;
7032 }
7033
7034 static void
7035 report_create_context_malformed_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const char *buffer_desc)
7036 {
7037         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_bad_response, tvb, 0, -1,
7038                             "%s SHOULD NOT be generated", buffer_desc);
7039 }
7040 static void
7041 dissect_smb2_ExtA_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7042 {
7043         proto_item *item = NULL;
7044         if (tree) {
7045                 item = proto_tree_get_parent(tree);
7046                 proto_item_append_text(item, ": SMB2_FILE_FULL_EA_INFO");
7047         }
7048         dissect_smb2_file_full_ea_info(tvb, pinfo, tree, 0, si);
7049 }
7050
7051 static void
7052 dissect_smb2_ExtA_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7053 {
7054         report_create_context_malformed_buffer(tvb, pinfo, tree, "ExtA Response");
7055 }
7056
7057 static void
7058 dissect_smb2_SecD_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7059 {
7060         proto_item *item = NULL;
7061         if (tree) {
7062                 item = proto_tree_get_parent(tree);
7063                 proto_item_append_text(item, ": SMB2_SEC_INFO_00");
7064         }
7065         dissect_smb2_sec_info_00(tvb, pinfo, tree, 0, si);
7066 }
7067
7068 static void
7069 dissect_smb2_SecD_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7070 {
7071         report_create_context_malformed_buffer(tvb, pinfo, tree, "SecD Response");
7072 }
7073
7074 static void
7075 dissect_smb2_TWrp_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7076 {
7077         proto_item *item = NULL;
7078         if (tree) {
7079                 item = proto_tree_get_parent(tree);
7080                 proto_item_append_text(item, ": Timestamp");
7081         }
7082         dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_twrp_timestamp);
7083 }
7084
7085 static void
7086 dissect_smb2_TWrp_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7087 {
7088         report_create_context_malformed_buffer(tvb, pinfo, tree, "TWrp Response");
7089 }
7090
7091 static void
7092 dissect_smb2_QFid_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7093 {
7094         proto_item *item = NULL;
7095
7096         if (tree) {
7097                 item = proto_tree_get_parent(tree);
7098         }
7099
7100         if (item) {
7101                 if (tvb_reported_length(tvb) == 0) {
7102                         proto_item_append_text(item, ": NO DATA");
7103                 } else {
7104                         proto_item_append_text(item, ": QFid request should have no data, malformed packet");
7105                 }
7106         }
7107 }
7108
7109 static void
7110 dissect_smb2_QFid_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7111 {
7112         int         offset   = 0;
7113         proto_item *item;
7114         proto_item *sub_tree;
7115
7116         item = proto_tree_get_parent(tree);
7117
7118         proto_item_append_text(item, ": QFid INFO");
7119         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_QFid_buffer, NULL, "QFid INFO");
7120
7121         proto_tree_add_item(sub_tree, hf_smb2_qfid_fid, tvb, offset, 32, ENC_NA);
7122 }
7123
7124 static void
7125 dissect_smb2_AlSi_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7126 {
7127         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, 0, 8, ENC_LITTLE_ENDIAN);
7128 }
7129
7130 static void
7131 dissect_smb2_AlSi_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7132 {
7133         report_create_context_malformed_buffer(tvb, pinfo, tree, "AlSi Response");
7134 }
7135
7136 static void
7137 dissect_smb2_DHnQ_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7138 {
7139         dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNQ);
7140 }
7141
7142 static void
7143 dissect_smb2_DHnQ_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7144 {
7145         proto_tree_add_item(tree, hf_smb2_dhnq_buffer_reserved, tvb, 0, 8, ENC_LITTLE_ENDIAN);
7146 }
7147
7148 static void
7149 dissect_smb2_DHnC_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7150 {
7151         dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNC);
7152 }
7153
7154 static void
7155 dissect_smb2_DHnC_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7156 {
7157         report_create_context_malformed_buffer(tvb, pinfo, tree, "DHnC Response");
7158 }
7159
7160 /*
7161  * SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2
7162  *  4 - timeout
7163  *  4 - flags
7164  *  8 - reserved
7165  * 16 - create guid
7166  *
7167  * SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2
7168  *  4 - timeout
7169  *  4 - flags
7170  *
7171  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
7172  * 16 - file id
7173  * 16 - create guid
7174  *  4 - flags
7175  *
7176  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
7177  * - nothing -
7178  */
7179 #define SMB2_DH2X_FLAGS_PERSISTENT_HANDLE 0x00000002
7180
7181 static void
7182 dissect_smb2_DH2Q_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7183 {
7184         static const int *dh2x_flags_fields[] = {
7185                 &hf_smb2_dh2x_buffer_flags_persistent_handle,
7186                 NULL
7187         };
7188         int         offset   = 0;
7189         proto_item *item;
7190         proto_item *sub_tree;
7191
7192         item = proto_tree_get_parent(tree);
7193
7194         proto_item_append_text(item, ": DH2Q Request");
7195         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2Q_buffer, NULL, "DH2Q Request");
7196
7197         /* timeout */
7198         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7199         offset += 4;
7200
7201         /* flags */
7202         proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_dh2x_buffer_flags,
7203                                 ett_smb2_dh2x_flags, dh2x_flags_fields, ENC_LITTLE_ENDIAN);
7204         offset += 4;
7205
7206         /* reserved */
7207         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_reserved, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7208         offset += 8;
7209
7210         /* create guid */
7211         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7212 }
7213
7214 static void
7215 dissect_smb2_DH2Q_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7216 {
7217         int         offset   = 0;
7218         proto_item *item;
7219         proto_item *sub_tree;
7220
7221         item = proto_tree_get_parent(tree);
7222
7223         proto_item_append_text(item, ": DH2Q Response");
7224         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2Q_buffer, NULL, "DH2Q Response");
7225
7226         /* timeout */
7227         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7228         offset += 4;
7229
7230         /* flags */
7231         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7232 }
7233
7234 static void
7235 dissect_smb2_DH2C_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7236 {
7237         int         offset   = 0;
7238         proto_item *item;
7239         proto_item *sub_tree;
7240
7241         item = proto_tree_get_parent(tree);
7242
7243         proto_item_append_text(item, ": DH2C Request");
7244         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2C_buffer, NULL, "DH2C Request");
7245
7246         /* file id */
7247         dissect_smb2_fid(tvb, pinfo, sub_tree, offset, si, FID_MODE_DHNC);
7248         offset += 16;
7249
7250         /* create guid */
7251         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7252         offset += 16;
7253
7254         /* flags */
7255         proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7256 }
7257
7258 static void
7259 dissect_smb2_DH2C_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7260 {
7261         report_create_context_malformed_buffer(tvb, pinfo, tree, "DH2C Response");
7262 }
7263
7264 static void
7265 dissect_smb2_MxAc_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7266 {
7267         int         offset = 0;
7268         proto_item *item   = NULL;
7269
7270         if (tree) {
7271                 item = proto_tree_get_parent(tree);
7272         }
7273
7274         if (tvb_reported_length(tvb) == 0) {
7275                 if (item) {
7276                         proto_item_append_text(item, ": NO DATA");
7277                 }
7278                 return;
7279         }
7280
7281         if (item) {
7282                 proto_item_append_text(item, ": Timestamp");
7283         }
7284
7285         dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_mxac_timestamp);
7286 }
7287
7288 static void
7289 dissect_smb2_MxAc_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7290 {
7291         int         offset   = 0;
7292         proto_item *item;
7293         proto_tree *sub_tree;
7294
7295         item = proto_tree_get_parent(tree);
7296
7297         if (tvb_reported_length(tvb) == 0) {
7298                 proto_item_append_text(item, ": NO DATA");
7299                 return;
7300         }
7301
7302         proto_item_append_text(item, ": MxAc INFO");
7303         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_MxAc_buffer, NULL, "MxAc INFO");
7304
7305         proto_tree_add_item(sub_tree, hf_smb2_mxac_status, tvb, offset, 4, ENC_BIG_ENDIAN);
7306         offset += 4;
7307
7308         dissect_smb_access_mask(tvb, sub_tree, offset);
7309 }
7310
7311 /*
7312  * SMB2_CREATE_REQUEST_LEASE 32
7313  * 16 - lease key
7314  *  4 - lease state
7315  *  4 - lease flags
7316  *  8 - lease duration
7317  *
7318  * SMB2_CREATE_REQUEST_LEASE_V2 52
7319  * 16 - lease key
7320  *  4 - lease state
7321  *  4 - lease flags
7322  *  8 - lease duration
7323  * 16 - parent lease key
7324  *  2 - epoch
7325  *  2 - reserved
7326  */
7327 #define SMB2_LEASE_STATE_READ_CACHING   0x00000001
7328 #define SMB2_LEASE_STATE_HANDLE_CACHING 0x00000002
7329 #define SMB2_LEASE_STATE_WRITE_CACHING  0x00000004
7330
7331 #define SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED    0x00000001
7332 #define SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS     0x00000002
7333 #define SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET  0x00000004
7334
7335 static const int *lease_state_fields[] = {
7336         &hf_smb2_lease_state_read_caching,
7337         &hf_smb2_lease_state_handle_caching,
7338         &hf_smb2_lease_state_write_caching,
7339         NULL
7340 };
7341 static const int *lease_flags_fields[] = {
7342         &hf_smb2_lease_flags_break_ack_required,
7343         &hf_smb2_lease_flags_break_in_progress,
7344         &hf_smb2_lease_flags_parent_lease_key_set,
7345         NULL
7346 };
7347
7348 static void
7349 dissect_SMB2_CREATE_LEASE_VX(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
7350 {
7351         int         offset      = 0;
7352         int         len;
7353         proto_tree *sub_tree    = NULL;
7354         proto_item *parent_item;
7355
7356         parent_item = proto_tree_get_parent(parent_tree);
7357
7358         len = tvb_reported_length(tvb);
7359
7360         switch (len) {
7361         case 32: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE */
7362                 proto_item_append_text(parent_item, ": LEASE_V1");
7363                 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_RqLs_buffer, NULL, "LEASE_V1");
7364                 break;
7365         case 52: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE_V2 */
7366                 proto_item_append_text(parent_item, ": LEASE_V2");
7367                 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_RqLs_buffer, NULL, "LEASE_V2");
7368                 break;
7369         default:
7370                 report_create_context_malformed_buffer(tvb, pinfo, parent_tree, "RqLs");
7371                 break;
7372         }
7373
7374         proto_tree_add_item(sub_tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7375         offset += 16;
7376
7377         proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_state,
7378                                ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
7379         offset += 4;
7380
7381         proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_flags,
7382                                ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
7383         offset += 4;
7384
7385         proto_tree_add_item(sub_tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7386         offset += 8;
7387
7388         if (len < 52) {
7389                 return;
7390         }
7391
7392         proto_tree_add_item(sub_tree, hf_smb2_parent_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7393         offset += 16;
7394
7395         proto_tree_add_item(sub_tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7396         offset += 2;
7397
7398         proto_tree_add_item(sub_tree, hf_smb2_lease_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7399 }
7400
7401 static void
7402 dissect_smb2_RqLs_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7403 {
7404         dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
7405 }
7406
7407 static void
7408 dissect_smb2_RqLs_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7409 {
7410         dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
7411 }
7412
7413 /*
7414  * SMB2_CREATE_APP_INSTANCE_ID
7415  *  2 - structure size - 20
7416  *  2 - reserved
7417  * 16 - application guid
7418  */
7419
7420 static void
7421 dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7422 {
7423         int         offset   = 0;
7424         proto_item *item;
7425         proto_item *sub_tree;
7426
7427         item = proto_tree_get_parent(tree);
7428
7429         proto_item_append_text(item, ": CREATE APP INSTANCE ID");
7430         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_APP_INSTANCE_buffer, NULL, "APP INSTANCE ID");
7431
7432         /* struct size */
7433         proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_struct_size,
7434                             tvb, offset, 2, ENC_LITTLE_ENDIAN);
7435         offset += 2;
7436
7437         /* reserved */
7438         proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_reserved,
7439                             tvb, offset, 2, ENC_LITTLE_ENDIAN);
7440         offset += 2;
7441
7442         /* create guid */
7443         proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_app_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7444 }
7445
7446 static void
7447 dissect_smb2_APP_INSTANCE_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7448 {
7449         report_create_context_malformed_buffer(tvb, pinfo, tree, "APP INSTANCE Response");
7450 }
7451
7452 /*
7453  * Dissect the MS-RSVD stuff that turns up when HyperV uses SMB3.x
7454  */
7455 static void
7456 dissect_smb2_svhdx_open_device_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7457 {
7458         int offset = 0;
7459         guint32 version;
7460         proto_item *item;
7461         proto_item *sub_tree;
7462
7463         item = proto_tree_get_parent(tree);
7464
7465         proto_item_append_text(item, ": SVHDX OPEN DEVICE CONTEXT");
7466         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_svhdx_open_device_context, NULL, "SVHDX OPEN DEVICE CONTEXT");
7467
7468         /* Version */
7469         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_svhdx_open_device_context_version,
7470                             tvb, offset, 4, ENC_LITTLE_ENDIAN, &version);
7471         offset += 4;
7472
7473         /* HasInitiatorId */
7474         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_has_initiator_id,
7475                             tvb, offset, 1, ENC_LITTLE_ENDIAN);
7476         offset += 1;
7477
7478         /* Reserved */
7479         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_reserved,
7480                             tvb, offset, 3, ENC_NA);
7481         offset += 3;
7482
7483         /* InitiatorId */
7484         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_id,
7485                             tvb, offset, 16, ENC_LITTLE_ENDIAN);
7486         offset += 16;
7487
7488         /* Flags TODO: Dissect these*/
7489         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_flags,
7490                             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7491         offset += 4;
7492
7493         /* OriginatorFlags */
7494         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_originator_flags,
7495                             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7496         offset += 4;
7497
7498         /* OpenRequestId */
7499         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_open_request_id,
7500                             tvb, offset, 8, ENC_LITTLE_ENDIAN);
7501         offset += 8;
7502
7503         /* InitiatorHostNameLength */
7504         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name_len,
7505                             tvb, offset, 2, ENC_LITTLE_ENDIAN);
7506         offset += 2;
7507
7508         /* InitiatorHostName */
7509         proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name,
7510                             tvb, offset, 126, ENC_ASCII | ENC_NA);
7511         offset += 126;
7512
7513         if (version == 2) {
7514                 /* VirtualDiskPropertiesInitialized */
7515                 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
7516                                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
7517                 offset += 4;
7518
7519                 /* ServerServiceVersion */
7520                 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_server_service_version,
7521                                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
7522                 offset += 4;
7523
7524                 /* VirtualSectorSize */
7525                 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_sector_size,
7526                                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
7527                 offset += 4;
7528
7529                 /* PhysicalSectorSize */
7530                 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_physical_sector_size,
7531                                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
7532                 offset += 4;
7533
7534                 /* VirtualSize */
7535                 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_size,
7536                                         tvb, offset, 8, ENC_LITTLE_ENDIAN);
7537         }
7538 }
7539
7540 static const int *posix_flags_fields[] = {
7541         &hf_smb2_posix_v1_case_sensitive,
7542         &hf_smb2_posix_v1_posix_lock,
7543         &hf_smb2_posix_v1_posix_file_semantics,
7544         &hf_smb2_posix_v1_posix_utf8_paths,
7545         &hf_smb2_posix_v1_posix_will_convert_nt_acls,
7546         &hf_smb2_posix_v1_posix_fileinfo,
7547         &hf_smb2_posix_v1_posix_acls,
7548         &hf_smb2_posix_v1_rich_acls,
7549         NULL
7550 };
7551
7552 static void
7553 dissect_smb2_posix_v1_caps_request(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7554 {
7555         int         offset   = 0;
7556         proto_item *item;
7557         proto_item *sub_tree;
7558
7559         item = proto_tree_get_parent(tree);
7560
7561         proto_item_append_text(item, ": POSIX V1 CAPS request");
7562         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_posix_v1_request, NULL, "POSIX_V1_REQUEST");
7563
7564         /* Version */
7565         proto_tree_add_item(sub_tree, hf_smb2_posix_v1_version,
7566                             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7567         offset += 4;
7568
7569         /* Request */
7570         proto_tree_add_item(sub_tree, hf_smb2_posix_v1_request,
7571                             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7572 }
7573
7574 static void
7575 dissect_smb2_posix_v1_caps_response(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7576 {
7577         int         offset   = 0;
7578         proto_item *item;
7579         proto_item *sub_tree;
7580
7581         item = proto_tree_get_parent(tree);
7582
7583         proto_item_append_text(item, ": POSIX V1 CAPS response");
7584         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_posix_v1_response, NULL, "POSIX_V1_RESPONSE");
7585
7586         /* Version */
7587         proto_tree_add_item(sub_tree, hf_smb2_posix_v1_version,
7588                             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7589         offset += 4;
7590
7591         /* Supported Features */
7592         proto_tree_add_bitmask(sub_tree, tvb, offset,
7593                                hf_smb2_posix_v1_supported_features,
7594                                ett_smb2_posix_v1_supported_features,
7595                                posix_flags_fields, ENC_LITTLE_ENDIAN);
7596
7597 }
7598
7599 #define SMB2_AAPL_SERVER_QUERY  1
7600 #define SMB2_AAPL_RESOLVE_ID    2
7601
7602 static const value_string aapl_command_code_vals[] = {
7603         { SMB2_AAPL_SERVER_QUERY,       "Server query"},
7604         { SMB2_AAPL_RESOLVE_ID,         "Resolve ID"},
7605         { 0, NULL }
7606 };
7607
7608 #define SMB2_AAPL_SERVER_CAPS           0x00000001
7609 #define SMB2_AAPL_VOLUME_CAPS           0x00000002
7610 #define SMB2_AAPL_MODEL_INFO            0x00000004
7611
7612 static const int *aapl_server_query_bitmap_fields[] = {
7613         &hf_smb2_aapl_server_query_bitmask_server_caps,
7614         &hf_smb2_aapl_server_query_bitmask_volume_caps,
7615         &hf_smb2_aapl_server_query_bitmask_model_info,
7616         NULL
7617 };
7618
7619 #define SMB2_AAPL_SUPPORTS_READ_DIR_ATTR        0x00000001
7620 #define SMB2_AAPL_SUPPORTS_OSX_COPYFILE         0x00000002
7621 #define SMB2_AAPL_UNIX_BASED                    0x00000004
7622 #define SMB2_AAPL_SUPPORTS_NFS_ACE              0x00000008
7623
7624 static const int *aapl_server_query_caps_fields[] = {
7625         &hf_smb2_aapl_server_query_caps_supports_read_dir_attr,
7626         &hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
7627         &hf_smb2_aapl_server_query_caps_unix_based,
7628         &hf_smb2_aapl_server_query_caps_supports_nfs_ace,
7629         NULL
7630 };
7631
7632 static void
7633 dissect_smb2_AAPL_buffer_request(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
7634 {
7635         int         offset   = 0;
7636         proto_item *item;
7637         proto_item *sub_tree;
7638         guint32     command_code;
7639
7640         item = proto_tree_get_parent(tree);
7641
7642         proto_item_append_text(item, ": AAPL Create Context request");
7643         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_aapl_create_context_request, NULL, "AAPL Create Context request");
7644
7645         /* Command code */
7646         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_aapl_command_code,
7647             tvb, offset, 4, ENC_LITTLE_ENDIAN, &command_code);
7648         offset += 4;
7649
7650         /* Reserved */
7651         proto_tree_add_item(sub_tree, hf_smb2_aapl_reserved,
7652             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7653         offset += 4;
7654
7655         switch (command_code) {
7656
7657         case SMB2_AAPL_SERVER_QUERY:
7658                 /* Request bitmap */
7659                 proto_tree_add_bitmask(sub_tree, tvb, offset,
7660                                        hf_smb2_aapl_server_query_bitmask,
7661                                        ett_smb2_aapl_server_query_bitmask,
7662                                        aapl_server_query_bitmap_fields,
7663                                        ENC_LITTLE_ENDIAN);
7664                 offset += 8;
7665
7666                 /* Client capabilities */
7667                 proto_tree_add_bitmask(sub_tree, tvb, offset,
7668                                        hf_smb2_aapl_server_query_caps,
7669                                        ett_smb2_aapl_server_query_caps,
7670                                        aapl_server_query_caps_fields,
7671                                        ENC_LITTLE_ENDIAN);
7672                 break;
7673
7674         case SMB2_AAPL_RESOLVE_ID:
7675                 /* file ID */
7676                 proto_tree_add_item(sub_tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7677                 break;
7678
7679         default:
7680                 break;
7681         }
7682 }
7683
7684 #define SMB2_AAPL_SUPPORTS_RESOLVE_ID   0x00000001
7685 #define SMB2_AAPL_CASE_SENSITIVE                0x00000002
7686 #define SMB2_AAPL_SUPPORTS_FULL_SYNC    0x00000004
7687
7688 static const int *aapl_server_query_volume_caps_fields[] = {
7689         &hf_smb2_aapl_server_query_volume_caps_support_resolve_id,
7690         &hf_smb2_aapl_server_query_volume_caps_case_sensitive,
7691         &hf_smb2_aapl_server_query_volume_caps_supports_full_sync,
7692         NULL
7693 };
7694
7695 static void
7696 dissect_smb2_AAPL_buffer_response(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
7697 {
7698         int         offset   = 0;
7699         proto_item *item;
7700         proto_item *sub_tree;
7701         guint32     command_code;
7702         guint64     server_query_bitmask;
7703
7704         item = proto_tree_get_parent(tree);
7705
7706         proto_item_append_text(item, ": AAPL Create Context response");
7707         sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_aapl_create_context_response, NULL, "AAPL Create Context response");
7708
7709         /* Command code */
7710         proto_tree_add_item_ret_uint(sub_tree, hf_smb2_aapl_command_code,
7711             tvb, offset, 4, ENC_LITTLE_ENDIAN, &command_code);
7712         offset += 4;
7713
7714         /* Reserved */
7715         proto_tree_add_item(sub_tree, hf_smb2_aapl_reserved,
7716             tvb, offset, 4, ENC_LITTLE_ENDIAN);
7717         offset += 4;
7718
7719         switch (command_code) {
7720
7721         case SMB2_AAPL_SERVER_QUERY:
7722                 /* Reply bitmap */
7723                 proto_tree_add_bitmask_ret_uint64(sub_tree, tvb, offset,
7724                                                   hf_smb2_aapl_server_query_bitmask,
7725                                                   ett_smb2_aapl_server_query_bitmask,
7726                                                   aapl_server_query_bitmap_fields,
7727                                                   ENC_LITTLE_ENDIAN,
7728                                                   &server_query_bitmask);
7729                 offset += 8;
7730
7731                 if (server_query_bitmask & SMB2_AAPL_SERVER_CAPS) {
7732                         /* Server capabilities */
7733                         proto_tree_add_bitmask(sub_tree, tvb, offset,
7734                                                hf_smb2_aapl_server_query_caps,
7735                                                ett_smb2_aapl_server_query_caps,
7736                                                aapl_server_query_caps_fields,
7737                                                ENC_LITTLE_ENDIAN);
7738                         offset += 8;
7739                 }
7740                 if (server_query_bitmask & SMB2_AAPL_VOLUME_CAPS) {
7741                         /* Volume capabilities */
7742                         proto_tree_add_bitmask(sub_tree, tvb, offset,
7743                                                hf_smb2_aapl_server_query_volume_caps,
7744                                                ett_smb2_aapl_server_query_volume_caps,
7745                                                aapl_server_query_volume_caps_fields,
7746                                                ENC_LITTLE_ENDIAN);
7747                         offset += 8;
7748                 }
7749                 if (server_query_bitmask & SMB2_AAPL_MODEL_INFO) {
7750                         /* Padding */
7751                         offset += 4;
7752
7753                         /* Model string */
7754                         proto_tree_add_item(sub_tree, hf_smb2_aapl_server_query_model_string,
7755                                             tvb, offset, 4,
7756                                             ENC_UTF_16|ENC_LITTLE_ENDIAN);
7757                 }
7758                 break;
7759
7760         case SMB2_AAPL_RESOLVE_ID:
7761                 /* NT status */
7762                 proto_tree_add_item(sub_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7763                 offset += 4;
7764
7765                 /* Server path */
7766                 proto_tree_add_item(sub_tree, hf_smb2_aapl_server_query_server_path,
7767                                     tvb, offset, 4,
7768                                     ENC_UTF_16|ENC_LITTLE_ENDIAN);
7769                 break;
7770
7771         default:
7772                 break;
7773         }
7774 }
7775
7776 typedef void (*create_context_data_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
7777
7778 typedef struct create_context_data_dissectors {
7779         create_context_data_dissector_t request;
7780         create_context_data_dissector_t response;
7781 } create_context_data_dissectors_t;
7782
7783 struct create_context_data_tag_dissectors {
7784         const char *tag;
7785         const char *val;
7786         create_context_data_dissectors_t dissectors;
7787 };
7788
7789 struct create_context_data_tag_dissectors create_context_dissectors_array[] = {
7790         { "ExtA", "SMB2_CREATE_EA_BUFFER",
7791           { dissect_smb2_ExtA_buffer_request, dissect_smb2_ExtA_buffer_response } },
7792         { "SecD", "SMB2_CREATE_SD_BUFFER",
7793           { dissect_smb2_SecD_buffer_request, dissect_smb2_SecD_buffer_response } },
7794         { "AlSi", "SMB2_CREATE_ALLOCATION_SIZE",
7795           { dissect_smb2_AlSi_buffer_request, dissect_smb2_AlSi_buffer_response } },
7796         { "MxAc", "SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST",
7797           { dissect_smb2_MxAc_buffer_request, dissect_smb2_MxAc_buffer_response } },
7798         { "DHnQ", "SMB2_CREATE_DURABLE_HANDLE_REQUEST",
7799           { dissect_smb2_DHnQ_buffer_request, dissect_smb2_DHnQ_buffer_response } },
7800         { "DHnC", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT",
7801           { dissect_smb2_DHnC_buffer_request, dissect_smb2_DHnC_buffer_response } },
7802         { "DH2Q", "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2",
7803           { dissect_smb2_DH2Q_buffer_request, dissect_smb2_DH2Q_buffer_response } },
7804         { "DH2C", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2",
7805           { dissect_smb2_DH2C_buffer_request, dissect_smb2_DH2C_buffer_response } },
7806         { "TWrp", "SMB2_CREATE_TIMEWARP_TOKEN",
7807           { dissect_smb2_TWrp_buffer_request, dissect_smb2_TWrp_buffer_response } },
7808         { "QFid", "SMB2_CREATE_QUERY_ON_DISK_ID",
7809           { dissect_smb2_QFid_buffer_request, dissect_smb2_QFid_buffer_response } },
7810         { "RqLs", "SMB2_CREATE_REQUEST_LEASE",
7811           { dissect_smb2_RqLs_buffer_request, dissect_smb2_RqLs_buffer_response } },
7812         { "744D142E-46FA-0890-4AF7-A7EF6AA6BC45", "SMB2_CREATE_APP_INSTANCE_ID",
7813           { dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
7814         { "6aa6bc45-a7ef-4af7-9008-fa462e144d74", "SMB2_CREATE_APP_INSTANCE_ID",
7815           { dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
7816         { "9ecfcb9c-c104-43e6-980e-158da1f6ec83", "SVHDX_OPEN_DEVICE_CONTEXT",
7817           { dissect_smb2_svhdx_open_device_context, dissect_smb2_svhdx_open_device_context} },
7818         { "34263501-2921-4912-2586-447794114531", "SMB2_POSIX_V1_CAPS",
7819           { dissect_smb2_posix_v1_caps_request, dissect_smb2_posix_v1_caps_response } },
7820         { "AAPL", "SMB2_AAPL_CREATE_CONTEXT",
7821           { dissect_smb2_AAPL_buffer_request, dissect_smb2_AAPL_buffer_response } },
7822 };
7823
7824 static struct create_context_data_tag_dissectors*
7825 get_create_context_data_tag_dissectors(const char *tag)
7826 {
7827         static struct create_context_data_tag_dissectors INVALID = {
7828                 NULL, "<invalid>", { NULL, NULL }
7829         };
7830
7831         size_t i;
7832
7833         for (i = 0; i<array_length(create_context_dissectors_array); i++) {
7834                 if (!strcmp(tag, create_context_dissectors_array[i].tag))
7835                         return &create_context_dissectors_array[i];
7836         }
7837         return &INVALID;
7838 }
7839
7840 static void
7841 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
7842 {
7843         offset_length_buffer_t  tag_olb;
7844         offset_length_buffer_t  data_olb;
7845         const char *tag;
7846         guint16     chain_offset;
7847         int         offset      = 0;
7848         int         len         = -1;
7849         proto_item *sub_item;
7850         proto_tree *sub_tree;
7851         proto_item *parent_item = NULL;
7852         create_context_data_dissectors_t *dissectors = NULL;
7853         create_context_data_dissector_t   dissector  = NULL;
7854         struct create_context_data_tag_dissectors *tag_dissectors;
7855
7856         chain_offset = tvb_get_letohl(tvb, offset);
7857         if (chain_offset) {
7858                 len = chain_offset;
7859         }
7860
7861         sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_smb2_create_chain_element, &sub_item, "Chain Element");
7862         parent_item = proto_tree_get_parent(parent_tree);
7863
7864         /* chain offset */
7865         proto_tree_add_item(sub_tree, hf_smb2_create_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7866         offset += 4;
7867
7868         /* tag  offset/length */
7869         offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
7870
7871         /* data  offset/length */
7872         dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_create_chain_data);
7873
7874         /*
7875          * These things are all either 4-char strings, like DH2C, or GUIDs,
7876          * however, at least one of them appears to be a GUID as a string and
7877          * one appears to be a binary guid. So, check if the the length is
7878          * 16, and if so, pull the GUID and convert it to a string. Otherwise
7879          * call dissect_smb2_olb_string.
7880          */
7881         if (tag_olb.len == 16) {
7882                 e_guid_t tag_guid;
7883                 proto_item *tag_item;
7884                 proto_tree *tag_tree;
7885
7886                 tvb_get_letohguid(tvb, tag_olb.off, &tag_guid);
7887                 tag = guid_to_str(wmem_packet_scope(), &tag_guid);
7888
7889                 tag_item = proto_tree_add_string(sub_tree, tag_olb.hfindex, tvb, tag_olb.off, tag_olb.len, tag);
7890                 tag_tree = proto_item_add_subtree(tag_item, ett_smb2_olb);
7891                 proto_tree_add_item(tag_tree, hf_smb2_olb_offset, tvb, tag_olb.off_offset, 2, ENC_LITTLE_ENDIAN);
7892                 proto_tree_add_item(tag_tree, hf_smb2_olb_length, tvb, tag_olb.len_offset, 2, ENC_LITTLE_ENDIAN);
7893
7894         } else {
7895                 /* tag string */
7896                 tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
7897         }
7898
7899         tag_dissectors = get_create_context_data_tag_dissectors(tag);
7900
7901         proto_item_append_text(parent_item, " %s", tag_dissectors->val);
7902         proto_item_append_text(sub_item, ": %s \"%s\"", tag_dissectors->val, tag);
7903
7904         /* data */
7905         dissectors = &tag_dissectors->dissectors;
7906         if (dissectors)
7907                 dissector = (si->flags & SMB2_FLAGS_RESPONSE) ? dissectors->response : dissectors->request;
7908
7909         dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
7910
7911         if (chain_offset) {
7912                 tvbuff_t *chain_tvb;
7913                 chain_tvb = tvb_new_subset_remaining(tvb, chain_offset);
7914
7915                 /* next extra info */
7916                 dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
7917         }
7918 }
7919
7920 static int
7921 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7922 {
7923         offset_length_buffer_t  f_olb, e_olb;
7924         const char             *fname;
7925
7926         /* buffer code */
7927         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
7928
7929         /* security flags */
7930         offset++;
7931
7932         /* oplock */
7933         offset = dissect_smb2_oplock(tree, tvb, offset);
7934
7935         /* impersonation level */
7936         proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7937         offset += 4;
7938
7939         /* create flags */
7940         proto_tree_add_item(tree, hf_smb2_create_flags, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7941         offset += 8;
7942
7943         /* reserved */
7944         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 8, ENC_NA);
7945         offset += 8;
7946
7947         /* access mask */
7948         offset = dissect_smb_access_mask(tvb, tree, offset);
7949
7950         /* File Attributes */
7951         offset = dissect_file_ext_attr(tvb, tree, offset);
7952
7953         /* share access */
7954         offset = dissect_nt_share_access(tvb, tree, offset);
7955
7956         /* create disposition */
7957         proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7958         offset += 4;
7959
7960         /* create options */
7961         offset = dissect_nt_create_options(tvb, tree, offset);
7962
7963         /* filename  offset/length */
7964         offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
7965
7966         /* extrainfo offset */
7967         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
7968
7969         /* filename string */
7970         fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
7971         col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", fname);
7972
7973         /* save the name if it looks sane */
7974         if (!pinfo->fd->flags.visited) {
7975                 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
7976                         wmem_free(wmem_file_scope(), si->saved->extra_info);
7977                         si->saved->extra_info = NULL;
7978                         si->saved->extra_info_type = SMB2_EI_NONE;
7979                 }
7980                 if (si->saved && f_olb.len < 256) {
7981                         si->saved->extra_info_type = SMB2_EI_FILENAME;
7982                         si->saved->extra_info = (gchar *)wmem_alloc(wmem_file_scope(), f_olb.len+1);
7983                         g_snprintf((gchar *)si->saved->extra_info, f_olb.len+1, "%s", fname);
7984                 }
7985         }
7986
7987         /* If extrainfo_offset is non-null then this points to another
7988          * buffer. The offset is relative to the start of the smb packet
7989          */
7990         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
7991
7992         offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
7993         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
7994
7995         return offset;
7996 }
7997
7998 #define SMB2_CREATE_REP_FLAGS_REPARSE_POINT 0x01
7999
8000 static int
8001 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8002 {
8003         guint64 end_of_file;
8004         guint32 attr_mask;
8005         offset_length_buffer_t e_olb;
8006         static const int *create_rep_flags_fields[] = {
8007                 &hf_smb2_create_rep_flags_reparse_point,
8008                 NULL
8009         };
8010         gboolean continue_dissection;
8011
8012         switch (si->status) {
8013         /* buffer code */
8014         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8015         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8016                 if (!continue_dissection) return offset;
8017         }
8018
8019         /* oplock */
8020         offset = dissect_smb2_oplock(tree, tvb, offset);
8021
8022         /* reserved */
8023         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_create_rep_flags,
8024                                ett_smb2_create_rep_flags, create_rep_flags_fields, ENC_LITTLE_ENDIAN);
8025         offset += 1;
8026
8027         /* create action */
8028         proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8029         offset += 4;
8030
8031         /* create time */
8032         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
8033
8034         /* last access */
8035         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
8036
8037         /* last write */
8038         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
8039
8040         /* last change */
8041         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
8042
8043         /* allocation size */
8044         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8045         offset += 8;
8046
8047         /* end of file */
8048         end_of_file = tvb_get_letoh64(tvb, offset);
8049         if (si->eo_file_info) {
8050                 si->eo_file_info->end_of_file = tvb_get_letoh64(tvb, offset);
8051         }
8052         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8053         offset += 8;
8054
8055         /* File Attributes */
8056         attr_mask=tvb_get_letohl(tvb, offset);
8057         offset = dissect_file_ext_attr(tvb, tree, offset);
8058
8059         /* reserved */
8060         proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8061         offset += 4;
8062
8063         /* fid */
8064         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
8065
8066         /* We save this after dissect_smb2_fid just because it would be
8067         possible to have this response without having the mathing request.
8068         In that case the entry in the file info hash table has been created
8069         in dissect_smb2_fid */
8070         if (si->eo_file_info) {
8071                 si->eo_file_info->end_of_file = end_of_file;
8072                 si->eo_file_info->attr_mask = attr_mask;
8073         }
8074
8075         /* extrainfo offset */
8076         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
8077
8078         /* If extrainfo_offset is non-null then this points to another
8079          * buffer. The offset is relative to the start of the smb packet
8080          */
8081         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
8082
8083         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
8084
8085         /* free si->saved->extra_info   we don't need it any more */
8086         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
8087                 wmem_free(wmem_file_scope(), si->saved->extra_info);
8088                 si->saved->extra_info = NULL;
8089                 si->saved->extra_info_type = SMB2_EI_NONE;
8090         }
8091
8092         return offset;
8093 }
8094
8095
8096 static int
8097 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8098 {
8099         guint32 setinfo_size;
8100         guint16 setinfo_offset;
8101
8102         /* buffer code */
8103         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
8104
8105         /* class and info level */
8106         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
8107
8108         /* size */
8109         setinfo_size = tvb_get_letohl(tvb, offset);
8110         proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8111         offset += 4;
8112
8113         /* offset */
8114         setinfo_offset = tvb_get_letohs(tvb, offset);
8115         proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
8116         offset += 2;
8117
8118         /* some unknown bytes */
8119         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
8120         offset += 6;
8121
8122         /* fid */
8123         dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
8124
8125         /* data */
8126         if (si->saved)
8127           dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->smb2_class, si->saved->infolevel);
8128         offset = setinfo_offset + setinfo_size;
8129
8130         return offset;
8131 }
8132
8133 static int
8134 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8135 {
8136         gboolean continue_dissection;
8137         /* class/infolevel */
8138         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
8139
8140         switch (si->status) {
8141         /* buffer code */
8142         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8143         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8144                 if (!continue_dissection) return offset;
8145         }
8146
8147         return offset;
8148 }
8149
8150 static int
8151 dissect_smb2_break_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8152 {
8153         guint16 buffer_code;
8154
8155         /* buffer code */
8156         buffer_code = tvb_get_letohs(tvb, offset);
8157         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
8158
8159         if (buffer_code == 24) {
8160                 /* OPLOCK Break */
8161
8162                 /* oplock */
8163                 offset = dissect_smb2_oplock(tree, tvb, offset);
8164
8165                 /* reserved */
8166                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
8167                 offset += 1;
8168
8169                 /* reserved */
8170                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8171                 offset += 4;
8172
8173                 /* fid */
8174                 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
8175
8176                 return offset;
8177         }
8178
8179         if (buffer_code == 36) {
8180                 /* Lease Break Acknowledgment */
8181
8182                 /* reserved */
8183                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
8184                 offset +=2;
8185
8186                 /* lease flags */
8187                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
8188                                        ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8189                 offset += 4;
8190
8191                 /* lease key */
8192                 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8193                 offset += 16;
8194
8195                 /* lease state */
8196                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8197                                        ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8198                 offset += 4;
8199
8200                 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8201                 offset += 8;
8202
8203                 return offset;
8204         }
8205
8206         return offset;
8207 }
8208
8209 static int
8210 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8211 {
8212         guint16 buffer_code;
8213         gboolean continue_dissection;
8214
8215         /* buffer code */
8216         buffer_code = tvb_get_letohs(tvb, offset);
8217         switch (si->status) {
8218         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8219         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8220                 if (!continue_dissection) return offset;
8221         }
8222
8223         if (buffer_code == 24) {
8224                 /* OPLOCK Break Notification */
8225
8226                 /* oplock */
8227                 offset = dissect_smb2_oplock(tree, tvb, offset);
8228
8229                 /* reserved */
8230                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
8231                 offset += 1;
8232
8233                 /* reserved */
8234                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8235                 offset += 4;
8236
8237                 /* fid */
8238                 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
8239
8240                 /* in break requests from server to client here're 24 byte zero bytes
8241                  * which are likely a bug in windows (they may use 2* 24 bytes instead of just
8242                  * 1 *24 bytes
8243                  */
8244                 return offset;
8245         }
8246
8247         if (buffer_code == 44) {
8248                 proto_item *item;
8249
8250                 /* Lease Break Notification */
8251
8252                 /* new lease epoch */
8253                 proto_tree_add_item(tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
8254                 offset += 2;
8255
8256                 /* lease flags */
8257                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
8258                                        ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8259                 offset += 4;
8260
8261                 /* lease key */
8262                 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8263                 offset += 16;
8264
8265                 /* current lease state */
8266                 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8267                                               ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8268                 if (item) {
8269                         proto_item_prepend_text(item, "Current ");
8270                 }
8271                 offset += 4;
8272
8273                 /* new lease state */
8274                 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8275                                               ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8276                 if (item) {
8277                         proto_item_prepend_text(item, "New ");
8278                 }
8279                 offset += 4;
8280
8281                 /* break reason - reserved */
8282                 proto_tree_add_item(tree, hf_smb2_lease_break_reason, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8283                 offset += 4;
8284
8285                 /* access mask hint - reserved */
8286                 proto_tree_add_item(tree, hf_smb2_lease_access_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8287                 offset += 4;
8288
8289                 /* share mask hint - reserved */
8290                 proto_tree_add_item(tree, hf_smb2_lease_share_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8291                 offset += 4;
8292
8293                 return offset;
8294         }
8295
8296         if (buffer_code == 36) {
8297                 /* Lease Break Response */
8298
8299                 /* reserved */
8300                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
8301                 offset +=2;
8302
8303                 /* lease flags */
8304                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
8305                                        ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8306                 offset += 4;
8307
8308                 /* lease key */
8309                 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8310                 offset += 16;
8311
8312                 /* lease state */
8313                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8314                                        ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8315                 offset += 4;
8316
8317                 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8318                 offset += 8;
8319
8320                 return offset;
8321         }
8322
8323         return offset;
8324 }
8325
8326 /* names here are just until we find better names for these functions */
8327 static const value_string smb2_cmd_vals[] = {
8328         { 0x00, "Negotiate Protocol" },
8329         { 0x01, "Session Setup" },
8330         { 0x02, "Session Logoff" },
8331         { 0x03, "Tree Connect" },
8332         { 0x04, "Tree Disconnect" },
8333         { 0x05, "Create" },
8334         { 0x06, "Close" },
8335         { 0x07, "Flush" },
8336         { 0x08, "Read" },
8337         { 0x09, "Write" },
8338         { 0x0A, "Lock" },
8339         { 0x0B, "Ioctl" },
8340         { 0x0C, "Cancel" },
8341         { 0x0D, "KeepAlive" },
8342         { 0x0E, "Find" },
8343         { 0x0F, "Notify" },
8344         { 0x10, "GetInfo" },
8345         { 0x11, "SetInfo" },
8346         { 0x12, "Break" },
8347         { 0x13, "unknown-0x13" },
8348         { 0x14, "unknown-0x14" },
8349         { 0x15, "unknown-0x15" },
8350         { 0x16, "unknown-0x16" },
8351         { 0x17, "unknown-0x17" },
8352         { 0x18, "unknown-0x18" },
8353         { 0x19, "unknown-0x19" },
8354         { 0x1A, "unknown-0x1A" },
8355         { 0x1B, "unknown-0x1B" },
8356         { 0x1C, "unknown-0x1C" },
8357         { 0x1D, "unknown-0x1D" },
8358         { 0x1E, "unknown-0x1E" },
8359         { 0x1F, "unknown-0x1F" },
8360         { 0x20, "unknown-0x20" },
8361         { 0x21, "unknown-0x21" },
8362         { 0x22, "unknown-0x22" },
8363         { 0x23, "unknown-0x23" },
8364         { 0x24, "unknown-0x24" },
8365         { 0x25, "unknown-0x25" },
8366         { 0x26, "unknown-0x26" },
8367         { 0x27, "unknown-0x27" },
8368         { 0x28, "unknown-0x28" },
8369         { 0x29, "unknown-0x29" },
8370         { 0x2A, "unknown-0x2A" },
8371         { 0x2B, "unknown-0x2B" },
8372         { 0x2C, "unknown-0x2C" },
8373         { 0x2D, "unknown-0x2D" },
8374         { 0x2E, "unknown-0x2E" },
8375         { 0x2F, "unknown-0x2F" },
8376         { 0x30, "unknown-0x30" },
8377         { 0x31, "unknown-0x31" },
8378         { 0x32, "unknown-0x32" },
8379         { 0x33, "unknown-0x33" },
8380         { 0x34, "unknown-0x34" },
8381         { 0x35, "unknown-0x35" },
8382         { 0x36, "unknown-0x36" },
8383         { 0x37, "unknown-0x37" },
8384         { 0x38, "unknown-0x38" },
8385         { 0x39, "unknown-0x39" },
8386         { 0x3A, "unknown-0x3A" },
8387         { 0x3B, "unknown-0x3B" },
8388         { 0x3C, "unknown-0x3C" },
8389         { 0x3D, "unknown-0x3D" },
8390         { 0x3E, "unknown-0x3E" },
8391         { 0x3F, "unknown-0x3F" },
8392         { 0x40, "unknown-0x40" },
8393         { 0x41, "unknown-0x41" },
8394         { 0x42, "unknown-0x42" },
8395         { 0x43, "unknown-0x43" },
8396         { 0x44, "unknown-0x44" },
8397         { 0x45, "unknown-0x45" },
8398         { 0x46, "unknown-0x46" },
8399         { 0x47, "unknown-0x47" },
8400         { 0x48, "unknown-0x48" },
8401         { 0x49, "unknown-0x49" },
8402         { 0x4A, "unknown-0x4A" },
8403         { 0x4B, "unknown-0x4B" },
8404         { 0x4C, "unknown-0x4C" },
8405         { 0x4D, "unknown-0x4D" },
8406         { 0x4E, "unknown-0x4E" },
8407         { 0x4F, "unknown-0x4F" },
8408         { 0x50, "unknown-0x50" },
8409         { 0x51, "unknown-0x51" },
8410         { 0x52, "unknown-0x52" },
8411         { 0x53, "unknown-0x53" },
8412         { 0x54, "unknown-0x54" },
8413         { 0x55, "unknown-0x55" },
8414         { 0x56, "unknown-0x56" },
8415         { 0x57, "unknown-0x57" },
8416         { 0x58, "unknown-0x58" },
8417         { 0x59, "unknown-0x59" },
8418         { 0x5A, "unknown-0x5A" },
8419         { 0x5B, "unknown-0x5B" },
8420         { 0x5C, "unknown-0x5C" },
8421         { 0x5D, "unknown-0x5D" },
8422         { 0x5E, "unknown-0x5E" },
8423         { 0x5F, "unknown-0x5F" },
8424         { 0x60, "unknown-0x60" },
8425         { 0x61, "unknown-0x61" },
8426         { 0x62, "unknown-0x62" },
8427         { 0x63, "unknown-0x63" },
8428         { 0x64, "unknown-0x64" },
8429         { 0x65, "unknown-0x65" },
8430         { 0x66, "unknown-0x66" },
8431         { 0x67, "unknown-0x67" },
8432         { 0x68, "unknown-0x68" },
8433         { 0x69, "unknown-0x69" },
8434         { 0x6A, "unknown-0x6A" },
8435         { 0x6B, "unknown-0x6B" },
8436         { 0x6C, "unknown-0x6C" },
8437         { 0x6D, "unknown-0x6D" },
8438         { 0x6E, "unknown-0x6E" },
8439         { 0x6F, "unknown-0x6F" },
8440         { 0x70, "unknown-0x70" },
8441         { 0x71, "unknown-0x71" },
8442         { 0x72, "unknown-0x72" },
8443         { 0x73, "unknown-0x73" },
8444         { 0x74, "unknown-0x74" },
8445         { 0x75, "unknown-0x75" },
8446         { 0x76, "unknown-0x76" },
8447         { 0x77, "unknown-0x77" },
8448         { 0x78, "unknown-0x78" },
8449         { 0x79, "unknown-0x79" },
8450         { 0x7A, "unknown-0x7A" },
8451         { 0x7B, "unknown-0x7B" },
8452         { 0x7C, "unknown-0x7C" },
8453         { 0x7D, "unknown-0x7D" },
8454         { 0x7E, "unknown-0x7E" },
8455         { 0x7F, "unknown-0x7F" },
8456         { 0x80, "unknown-0x80" },
8457         { 0x81, "unknown-0x81" },
8458         { 0x82, "unknown-0x82" },
8459         { 0x83, "unknown-0x83" },
8460         { 0x84, "unknown-0x84" },
8461         { 0x85, "unknown-0x85" },
8462         { 0x86, "unknown-0x86" },
8463         { 0x87, "unknown-0x87" },
8464         { 0x88, "unknown-0x88" },
8465         { 0x89, "unknown-0x89" },
8466         { 0x8A, "unknown-0x8A" },
8467         { 0x8B, "unknown-0x8B" },
8468         { 0x8C, "unknown-0x8C" },
8469         { 0x8D, "unknown-0x8D" },
8470         { 0x8E, "unknown-0x8E" },
8471         { 0x8F, "unknown-0x8F" },
8472         { 0x90, "unknown-0x90" },
8473         { 0x91, "unknown-0x91" },
8474         { 0x92, "unknown-0x92" },
8475         { 0x93, "unknown-0x93" },
8476         { 0x94, "unknown-0x94" },
8477         { 0x95, "unknown-0x95" },
8478         { 0x96, "unknown-0x96" },
8479         { 0x97, "unknown-0x97" },
8480         { 0x98, "unknown-0x98" },
8481         { 0x99, "unknown-0x99" },
8482         { 0x9A, "unknown-0x9A" },
8483         { 0x9B, "unknown-0x9B" },
8484         { 0x9C, "unknown-0x9C" },
8485         { 0x9D, "unknown-0x9D" },
8486         { 0x9E, "unknown-0x9E" },
8487         { 0x9F, "unknown-0x9F" },
8488         { 0xA0, "unknown-0xA0" },
8489         { 0xA1, "unknown-0xA1" },
8490         { 0xA2, "unknown-0xA2" },
8491         { 0xA3, "unknown-0xA3" },
8492         { 0xA4, "unknown-0xA4" },
8493         { 0xA5, "unknown-0xA5" },
8494         { 0xA6, "unknown-0xA6" },
8495         { 0xA7, "unknown-0xA7" },
8496         { 0xA8, "unknown-0xA8" },
8497         { 0xA9, "unknown-0xA9" },
8498         { 0xAA, "unknown-0xAA" },
8499         { 0xAB, "unknown-0xAB" },
8500         { 0xAC, "unknown-0xAC" },
8501         { 0xAD, "unknown-0xAD" },
8502         { 0xAE, "unknown-0xAE" },
8503         { 0xAF, "unknown-0xAF" },
8504         { 0xB0, "unknown-0xB0" },
8505         { 0xB1, "unknown-0xB1" },
8506         { 0xB2, "unknown-0xB2" },
8507         { 0xB3, "unknown-0xB3" },
8508         { 0xB4, "unknown-0xB4" },
8509         { 0xB5, "unknown-0xB5" },
8510         { 0xB6, "unknown-0xB6" },
8511         { 0xB7, "unknown-0xB7" },
8512         { 0xB8, "unknown-0xB8" },
8513         { 0xB9, "unknown-0xB9" },
8514         { 0xBA, "unknown-0xBA" },
8515         { 0xBB, "unknown-0xBB" },
8516         { 0xBC, "unknown-0xBC" },
8517         { 0xBD, "unknown-0xBD" },
8518         { 0xBE, "unknown-0xBE" },
8519         { 0xBF, "unknown-0xBF" },
8520         { 0xC0, "unknown-0xC0" },
8521         { 0xC1, "unknown-0xC1" },
8522         { 0xC2, "unknown-0xC2" },
8523         { 0xC3, "unknown-0xC3" },
8524         { 0xC4, "unknown-0xC4" },
8525         { 0xC5, "unknown-0xC5" },
8526         { 0xC6, "unknown-0xC6" },
8527         { 0xC7, "unknown-0xC7" },
8528         { 0xC8, "unknown-0xC8" },
8529         { 0xC9, "unknown-0xC9" },
8530         { 0xCA, "unknown-0xCA" },
8531         { 0xCB, "unknown-0xCB" },
8532         { 0xCC, "unknown-0xCC" },
8533         { 0xCD, "unknown-0xCD" },
8534         { 0xCE, "unknown-0xCE" },
8535         { 0xCF, "unknown-0xCF" },
8536         { 0xD0, "unknown-0xD0" },
8537         { 0xD1, "unknown-0xD1" },
8538         { 0xD2, "unknown-0xD2" },
8539         { 0xD3, "unknown-0xD3" },
8540         { 0xD4, "unknown-0xD4" },
8541         { 0xD5, "unknown-0xD5" },
8542         { 0xD6, "unknown-0xD6" },
8543         { 0xD7, "unknown-0xD7" },
8544         { 0xD8, "unknown-0xD8" },
8545         { 0xD9, "unknown-0xD9" },
8546         { 0xDA, "unknown-0xDA" },
8547         { 0xDB, "unknown-0xDB" },
8548         { 0xDC, "unknown-0xDC" },
8549         { 0xDD, "unknown-0xDD" },
8550         { 0xDE, "unknown-0xDE" },
8551         { 0xDF, "unknown-0xDF" },
8552         { 0xE0, "unknown-0xE0" },
8553         { 0xE1, "unknown-0xE1" },
8554         { 0xE2, "unknown-0xE2" },
8555         { 0xE3, "unknown-0xE3" },
8556         { 0xE4, "unknown-0xE4" },
8557         { 0xE5, "unknown-0xE5" },
8558         { 0xE6, "unknown-0xE6" },
8559         { 0xE7, "unknown-0xE7" },
8560         { 0xE8, "unknown-0xE8" },
8561         { 0xE9, "unknown-0xE9" },
8562         { 0xEA, "unknown-0xEA" },
8563         { 0xEB, "unknown-0xEB" },
8564         { 0xEC, "unknown-0xEC" },
8565         { 0xED, "unknown-0xED" },
8566         { 0xEE, "unknown-0xEE" },
8567         { 0xEF, "unknown-0xEF" },
8568         { 0xF0, "unknown-0xF0" },
8569         { 0xF1, "unknown-0xF1" },
8570         { 0xF2, "unknown-0xF2" },
8571         { 0xF3, "unknown-0xF3" },
8572         { 0xF4, "unknown-0xF4" },
8573         { 0xF5, "unknown-0xF5" },
8574         { 0xF6, "unknown-0xF6" },
8575         { 0xF7, "unknown-0xF7" },
8576         { 0xF8, "unknown-0xF8" },
8577         { 0xF9, "unknown-0xF9" },
8578         { 0xFA, "unknown-0xFA" },
8579         { 0xFB, "unknown-0xFB" },
8580         { 0xFC, "unknown-0xFC" },
8581         { 0xFD, "unknown-0xFD" },
8582         { 0xFE, "unknown-0xFE" },
8583         { 0xFF, "unknown-0xFF" },
8584         { 0x00, NULL },
8585 };
8586 value_string_ext smb2_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb2_cmd_vals);
8587
8588 static const char *decode_smb2_name(guint16 cmd)
8589 {
8590         if (cmd > 0xFF) return "unknown";
8591         return(smb2_cmd_vals[cmd & 0xFF].strptr);
8592 }
8593
8594 static smb2_function smb2_dissector[256] = {
8595   /* 0x00 NegotiateProtocol*/
8596         {dissect_smb2_negotiate_protocol_request,
8597          dissect_smb2_negotiate_protocol_response},
8598   /* 0x01 SessionSetup*/
8599         {dissect_smb2_session_setup_request,
8600          dissect_smb2_session_setup_response},
8601   /* 0x02 SessionLogoff*/
8602         {dissect_smb2_sessionlogoff_request,
8603          dissect_smb2_sessionlogoff_response},
8604   /* 0x03 TreeConnect*/
8605         {dissect_smb2_tree_connect_request,
8606          dissect_smb2_tree_connect_response},
8607   /* 0x04 TreeDisconnect*/
8608         {dissect_smb2_tree_disconnect_request,
8609          dissect_smb2_tree_disconnect_response},
8610   /* 0x05 Create*/
8611         {dissect_smb2_create_request,
8612          dissect_smb2_create_response},
8613   /* 0x06 Close*/
8614         {dissect_smb2_close_request,
8615          dissect_smb2_close_response},
8616   /* 0x07 Flush*/
8617         {dissect_smb2_flush_request,
8618          dissect_smb2_flush_response},
8619   /* 0x08 Read*/
8620         {dissect_smb2_read_request,
8621          dissect_smb2_read_response},
8622   /* 0x09 Writew*/
8623         {dissect_smb2_write_request,
8624          dissect_smb2_write_response},
8625   /* 0x0a Lock */
8626         {dissect_smb2_lock_request,
8627          dissect_smb2_lock_response},
8628   /* 0x0b Ioctl*/
8629         {dissect_smb2_ioctl_request,
8630          dissect_smb2_ioctl_response},
8631   /* 0x0c Cancel*/
8632         {dissect_smb2_cancel_request,
8633          NULL},
8634   /* 0x0d KeepAlive*/
8635         {dissect_smb2_keepalive_request,
8636          dissect_smb2_keepalive_response},
8637   /* 0x0e Find*/
8638         {dissect_smb2_find_request,
8639          dissect_smb2_find_response},
8640   /* 0x0f Notify*/
8641         {dissect_smb2_notify_request,
8642          dissect_smb2_notify_response},
8643   /* 0x10 GetInfo*/
8644         {dissect_smb2_getinfo_request,
8645          dissect_smb2_getinfo_response},
8646   /* 0x11 SetInfo*/
8647         {dissect_smb2_setinfo_request,
8648          dissect_smb2_setinfo_response},
8649   /* 0x12 Break */
8650         {dissect_smb2_break_request,
8651          dissect_smb2_break_response},
8652   /* 0x13 */  {NULL, NULL},
8653   /* 0x14 */  {NULL, NULL},
8654   /* 0x15 */  {NULL, NULL},
8655   /* 0x16 */  {NULL, NULL},
8656   /* 0x17 */  {NULL, NULL},
8657   /* 0x18 */  {NULL, NULL},
8658   /* 0x19 */  {NULL, NULL},
8659   /* 0x1a */  {NULL, NULL},
8660   /* 0x1b */  {NULL, NULL},
8661   /* 0x1c */  {NULL, NULL},
8662   /* 0x1d */  {NULL, NULL},
8663   /* 0x1e */  {NULL, NULL},
8664   /* 0x1f */  {NULL, NULL},
8665   /* 0x20 */  {NULL, NULL},
8666   /* 0x21 */  {NULL, NULL},
8667   /* 0x22 */  {NULL, NULL},
8668   /* 0x23 */  {NULL, NULL},
8669   /* 0x24 */  {NULL, NULL},
8670   /* 0x25 */  {NULL, NULL},
8671   /* 0x26 */  {NULL, NULL},
8672   /* 0x27 */  {NULL, NULL},
8673   /* 0x28 */  {NULL, NULL},
8674   /* 0x29 */  {NULL, NULL},
8675   /* 0x2a */  {NULL, NULL},
8676   /* 0x2b */  {NULL, NULL},
8677   /* 0x2c */  {NULL, NULL},
8678   /* 0x2d */  {NULL, NULL},
8679   /* 0x2e */  {NULL, NULL},
8680   /* 0x2f */  {NULL, NULL},
8681   /* 0x30 */  {NULL, NULL},
8682   /* 0x31 */  {NULL, NULL},
8683   /* 0x32 */  {NULL, NULL},
8684   /* 0x33 */  {NULL, NULL},
8685   /* 0x34 */  {NULL, NULL},
8686   /* 0x35 */  {NULL, NULL},
8687   /* 0x36 */  {NULL, NULL},
8688   /* 0x37 */  {NULL, NULL},
8689   /* 0x38 */  {NULL, NULL},
8690   /* 0x39 */  {NULL, NULL},
8691   /* 0x3a */  {NULL, NULL},
8692   /* 0x3b */  {NULL, NULL},
8693   /* 0x3c */  {NULL, NULL},
8694   /* 0x3d */  {NULL, NULL},
8695   /* 0x3e */  {NULL, NULL},
8696   /* 0x3f */  {NULL, NULL},
8697   /* 0x40 */  {NULL, NULL},
8698   /* 0x41 */  {NULL, NULL},
8699   /* 0x42 */  {NULL, NULL},
8700   /* 0x43 */  {NULL, NULL},
8701   /* 0x44 */  {NULL, NULL},
8702   /* 0x45 */  {NULL, NULL},
8703   /* 0x46 */  {NULL, NULL},
8704   /* 0x47 */  {NULL, NULL},
8705   /* 0x48 */  {NULL, NULL},
8706   /* 0x49 */  {NULL, NULL},
8707   /* 0x4a */  {NULL, NULL},
8708   /* 0x4b */  {NULL, NULL},
8709   /* 0x4c */  {NULL, NULL},
8710   /* 0x4d */  {NULL, NULL},
8711   /* 0x4e */  {NULL, NULL},
8712   /* 0x4f */  {NULL, NULL},
8713   /* 0x50 */  {NULL, NULL},
8714   /* 0x51 */  {NULL, NULL},
8715   /* 0x52 */  {NULL, NULL},
8716   /* 0x53 */  {NULL, NULL},
8717   /* 0x54 */  {NULL, NULL},
8718   /* 0x55 */  {NULL, NULL},
8719   /* 0x56 */  {NULL, NULL},
8720   /* 0x57 */  {NULL, NULL},
8721   /* 0x58 */  {NULL, NULL},
8722   /* 0x59 */  {NULL, NULL},
8723   /* 0x5a */  {NULL, NULL},
8724   /* 0x5b */  {NULL, NULL},
8725   /* 0x5c */  {NULL, NULL},
8726   /* 0x5d */  {NULL, NULL},
8727   /* 0x5e */  {NULL, NULL},
8728   /* 0x5f */  {NULL, NULL},
8729   /* 0x60 */  {NULL, NULL},
8730   /* 0x61 */  {NULL, NULL},
8731   /* 0x62 */  {NULL, NULL},
8732   /* 0x63 */  {NULL, NULL},
8733   /* 0x64 */  {NULL, NULL},
8734   /* 0x65 */  {NULL, NULL},
8735   /* 0x66 */  {NULL, NULL},
8736   /* 0x67 */  {NULL, NULL},
8737   /* 0x68 */  {NULL, NULL},
8738   /* 0x69 */  {NULL, NULL},
8739   /* 0x6a */  {NULL, NULL},
8740   /* 0x6b */  {NULL, NULL},
8741   /* 0x6c */  {NULL, NULL},
8742   /* 0x6d */  {NULL, NULL},
8743   /* 0x6e */  {NULL, NULL},
8744   /* 0x6f */  {NULL, NULL},
8745   /* 0x70 */  {NULL, NULL},
8746   /* 0x71 */  {NULL, NULL},
8747   /* 0x72 */  {NULL, NULL},
8748   /* 0x73 */  {NULL, NULL},
8749   /* 0x74 */  {NULL, NULL},
8750   /* 0x75 */  {NULL, NULL},
8751   /* 0x76 */  {NULL, NULL},
8752   /* 0x77 */  {NULL, NULL},
8753   /* 0x78 */  {NULL, NULL},
8754   /* 0x79 */  {NULL, NULL},
8755   /* 0x7a */  {NULL, NULL},
8756   /* 0x7b */  {NULL, NULL},
8757   /* 0x7c */  {NULL, NULL},
8758   /* 0x7d */  {NULL, NULL},
8759   /* 0x7e */  {NULL, NULL},
8760   /* 0x7f */  {NULL, NULL},
8761   /* 0x80 */  {NULL, NULL},
8762   /* 0x81 */  {NULL, NULL},
8763   /* 0x82 */  {NULL, NULL},
8764   /* 0x83 */  {NULL, NULL},
8765   /* 0x84 */  {NULL, NULL},
8766   /* 0x85 */  {NULL, NULL},
8767   /* 0x86 */  {NULL, NULL},
8768   /* 0x87 */  {NULL, NULL},
8769   /* 0x88 */  {NULL, NULL},
8770   /* 0x89 */  {NULL, NULL},
8771   /* 0x8a */  {NULL, NULL},
8772   /* 0x8b */  {NULL, NULL},
8773   /* 0x8c */  {NULL, NULL},
8774   /* 0x8d */  {NULL, NULL},
8775   /* 0x8e */  {NULL, NULL},
8776   /* 0x8f */  {NULL, NULL},
8777   /* 0x90 */  {NULL, NULL},
8778   /* 0x91 */  {NULL, NULL},
8779   /* 0x92 */  {NULL, NULL},
8780   /* 0x93 */  {NULL, NULL},
8781   /* 0x94 */  {NULL, NULL},
8782   /* 0x95 */  {NULL, NULL},
8783   /* 0x96 */  {NULL, NULL},
8784   /* 0x97 */  {NULL, NULL},
8785   /* 0x98 */  {NULL, NULL},
8786   /* 0x99 */  {NULL, NULL},
8787   /* 0x9a */  {NULL, NULL},
8788   /* 0x9b */  {NULL, NULL},
8789   /* 0x9c */  {NULL, NULL},
8790   /* 0x9d */  {NULL, NULL},
8791   /* 0x9e */  {NULL, NULL},
8792   /* 0x9f */  {NULL, NULL},
8793   /* 0xa0 */  {NULL, NULL},
8794   /* 0xa1 */  {NULL, NULL},
8795   /* 0xa2 */  {NULL, NULL},
8796   /* 0xa3 */  {NULL, NULL},
8797   /* 0xa4 */  {NULL, NULL},
8798   /* 0xa5 */  {NULL, NULL},
8799   /* 0xa6 */  {NULL, NULL},
8800   /* 0xa7 */  {NULL, NULL},
8801   /* 0xa8 */  {NULL, NULL},
8802   /* 0xa9 */  {NULL, NULL},
8803   /* 0xaa */  {NULL, NULL},
8804   /* 0xab */  {NULL, NULL},
8805   /* 0xac */  {NULL, NULL},
8806   /* 0xad */  {NULL, NULL},
8807   /* 0xae */  {NULL, NULL},
8808   /* 0xaf */  {NULL, NULL},
8809   /* 0xb0 */  {NULL, NULL},
8810   /* 0xb1 */  {NULL, NULL},
8811   /* 0xb2 */  {NULL, NULL},
8812   /* 0xb3 */  {NULL, NULL},
8813   /* 0xb4 */  {NULL, NULL},
8814   /* 0xb5 */  {NULL, NULL},
8815   /* 0xb6 */  {NULL, NULL},
8816   /* 0xb7 */  {NULL, NULL},
8817   /* 0xb8 */  {NULL, NULL},
8818   /* 0xb9 */  {NULL, NULL},
8819   /* 0xba */  {NULL, NULL},
8820   /* 0xbb */  {NULL, NULL},
8821   /* 0xbc */  {NULL, NULL},
8822   /* 0xbd */  {NULL, NULL},
8823   /* 0xbe */  {NULL, NULL},
8824   /* 0xbf */  {NULL, NULL},
8825   /* 0xc0 */  {NULL, NULL},
8826   /* 0xc1 */  {NULL, NULL},
8827   /* 0xc2 */  {NULL, NULL},
8828   /* 0xc3 */  {NULL, NULL},
8829   /* 0xc4 */  {NULL, NULL},
8830   /* 0xc5 */  {NULL, NULL},
8831   /* 0xc6 */  {NULL, NULL},
8832   /* 0xc7 */  {NULL, NULL},
8833   /* 0xc8 */  {NULL, NULL},
8834   /* 0xc9 */  {NULL, NULL},
8835   /* 0xca */  {NULL, NULL},
8836   /* 0xcb */  {NULL, NULL},
8837   /* 0xcc */  {NULL, NULL},
8838   /* 0xcd */  {NULL, NULL},
8839   /* 0xce */  {NULL, NULL},
8840   /* 0xcf */  {NULL, NULL},
8841   /* 0xd0 */  {NULL, NULL},
8842   /* 0xd1 */  {NULL, NULL},
8843   /* 0xd2 */  {NULL, NULL},
8844   /* 0xd3 */  {NULL, NULL},
8845   /* 0xd4 */  {NULL, NULL},
8846   /* 0xd5 */  {NULL, NULL},
8847   /* 0xd6 */  {NULL, NULL},
8848   /* 0xd7 */  {NULL, NULL},
8849   /* 0xd8 */  {NULL, NULL},
8850   /* 0xd9 */  {NULL, NULL},
8851   /* 0xda */  {NULL, NULL},
8852   /* 0xdb */  {NULL, NULL},
8853   /* 0xdc */  {NULL, NULL},
8854   /* 0xdd */  {NULL, NULL},
8855   /* 0xde */  {NULL, NULL},
8856   /* 0xdf */  {NULL, NULL},
8857   /* 0xe0 */  {NULL, NULL},
8858   /* 0xe1 */  {NULL, NULL},
8859   /* 0xe2 */  {NULL, NULL},
8860   /* 0xe3 */  {NULL, NULL},
8861   /* 0xe4 */  {NULL, NULL},
8862   /* 0xe5 */  {NULL, NULL},
8863   /* 0xe6 */  {NULL, NULL},
8864   /* 0xe7 */  {NULL, NULL},
8865   /* 0xe8 */  {NULL, NULL},
8866   /* 0xe9 */  {NULL, NULL},
8867   /* 0xea */  {NULL, NULL},
8868   /* 0xeb */  {NULL, NULL},
8869   /* 0xec */  {NULL, NULL},
8870   /* 0xed */  {NULL, NULL},
8871   /* 0xee */  {NULL, NULL},
8872   /* 0xef */  {NULL, NULL},
8873   /* 0xf0 */  {NULL, NULL},
8874   /* 0xf1 */  {NULL, NULL},
8875   /* 0xf2 */  {NULL, NULL},
8876   /* 0xf3 */  {NULL, NULL},
8877   /* 0xf4 */  {NULL, NULL},
8878   /* 0xf5 */  {NULL, NULL},
8879   /* 0xf6 */  {NULL, NULL},
8880   /* 0xf7 */  {NULL, NULL},
8881   /* 0xf8 */  {NULL, NULL},
8882   /* 0xf9 */  {NULL, NULL},
8883   /* 0xfa */  {NULL, NULL},
8884   /* 0xfb */  {NULL, NULL},
8885   /* 0xfc */  {NULL, NULL},
8886   /* 0xfd */  {NULL, NULL},
8887   /* 0xfe */  {NULL, NULL},
8888   /* 0xff */  {NULL, NULL},
8889 };
8890
8891
8892 #define ENC_ALG_aes128_ccm      0x0001
8893
8894 static int
8895 dissect_smb2_transform_header(packet_info *pinfo, proto_tree *tree,
8896                               tvbuff_t *tvb, int offset,
8897                               smb2_transform_info_t *sti,
8898                               tvbuff_t **enc_tvb, tvbuff_t **plain_tvb)
8899 {
8900         proto_item        *sesid_item     = NULL;
8901         proto_tree        *sesid_tree     = NULL;
8902         smb2_sesid_info_t  sesid_key;
8903         int                sesid_offset;
8904         guint8            *plain_data     = NULL;
8905         guint8            *decryption_key = NULL;
8906         proto_item        *item;
8907
8908         static const int *sf_fields[] = {
8909                 &hf_smb2_encryption_aes128_ccm,
8910                 NULL
8911         };
8912
8913         *enc_tvb = NULL;
8914         *plain_tvb = NULL;
8915
8916         /* signature */
8917         proto_tree_add_item(tree, hf_smb2_transform_signature, tvb, offset, 16, ENC_NA);
8918         offset += 16;
8919
8920         /* nonce */
8921         proto_tree_add_item(tree, hf_smb2_transform_nonce, tvb, offset, 16, ENC_NA);
8922         tvb_memcpy(tvb, sti->nonce, offset, 16);
8923         offset += 16;
8924
8925         /* size */
8926         proto_tree_add_item(tree, hf_smb2_transform_msg_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8927         sti->size = tvb_get_letohl(tvb, offset);
8928         offset += 4;
8929
8930         /* reserved */
8931         proto_tree_add_item(tree, hf_smb2_transform_reserved, tvb, offset, 2, ENC_NA);
8932         offset += 2;
8933
8934         /* enc algorithm */
8935         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_transform_enc_alg, ett_smb2_transform_enc_alg, sf_fields, ENC_LITTLE_ENDIAN);
8936         sti->alg = tvb_get_letohs(tvb, offset);
8937         offset += 2;
8938
8939         /* session ID */
8940         sesid_offset = offset;
8941         sti->sesid = tvb_get_letoh64(tvb, offset);
8942         sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8943         sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
8944         offset += 8;
8945
8946         /* now we need to first lookup the uid session */
8947         sesid_key.sesid = sti->sesid;
8948         sti->session = (smb2_sesid_info_t *)g_hash_table_lookup(sti->conv->sesids, &sesid_key);
8949
8950         if (sti->session != NULL && sti->session->auth_frame != (guint32)-1) {
8951                 item = proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, sti->session->acct_name);
8952                 PROTO_ITEM_SET_GENERATED(item);
8953                 proto_item_append_text(sesid_item, " Acct:%s", sti->session->acct_name);
8954
8955                 item = proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, sti->session->domain_name);
8956                 PROTO_ITEM_SET_GENERATED(item);
8957                 proto_item_append_text(sesid_item, " Domain:%s", sti->session->domain_name);
8958
8959                 item = proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, sti->session->host_name);
8960                 PROTO_ITEM_SET_GENERATED(item);
8961                 proto_item_append_text(sesid_item, " Host:%s", sti->session->host_name);
8962
8963                 item = proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, sti->session->auth_frame);
8964                 PROTO_ITEM_SET_GENERATED(item);
8965         }
8966
8967         if (sti->session != NULL && sti->alg == ENC_ALG_aes128_ccm) {
8968                 if (pinfo->destport == sti->session->server_port) {
8969                         decryption_key = sti->session->server_decryption_key;
8970                 } else {
8971                         decryption_key = sti->session->client_decryption_key;
8972                 }
8973
8974                 if (memcmp(decryption_key, zeros, NTLMSSP_KEY_LEN) == 0) {
8975                         decryption_key = NULL;
8976                 }
8977         }
8978
8979         if (decryption_key != NULL) {
8980                 gcry_cipher_hd_t cipher_hd = NULL;
8981                 guint8 A_1[NTLMSSP_KEY_LEN] = {
8982                         3, 0, 0, 0, 0, 0, 0, 0,
8983                         0, 0, 0, 0, 0, 0, 0, 1
8984                 };
8985
8986                 memcpy(&A_1[1], sti->nonce, 15 - 4);
8987
8988                 plain_data = (guint8 *)tvb_memdup(pinfo->pool, tvb, offset, sti->size);
8989
8990                 /* Open the cipher. */
8991                 if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0)) {
8992                         wmem_free(pinfo->pool, plain_data);
8993                         plain_data = NULL;
8994                         goto done_decryption;
8995                 }
8996
8997                 /* Set the key and initial value. */
8998                 if (gcry_cipher_setkey(cipher_hd, decryption_key, NTLMSSP_KEY_LEN)) {
8999                         gcry_cipher_close(cipher_hd);
9000                         wmem_free(pinfo->pool, plain_data);
9001                         plain_data = NULL;
9002                         goto done_decryption;
9003                 }
9004                 if (gcry_cipher_setctr(cipher_hd, A_1, NTLMSSP_KEY_LEN)) {
9005                         gcry_cipher_close(cipher_hd);
9006                         wmem_free(pinfo->pool, plain_data);
9007                         plain_data = NULL;
9008                         goto done_decryption;
9009                 }
9010
9011                 if (gcry_cipher_encrypt(cipher_hd, plain_data, sti->size, NULL, 0)) {
9012                         gcry_cipher_close(cipher_hd);
9013                         wmem_free(pinfo->pool, plain_data);
9014                         plain_data = NULL;
9015                         goto done_decryption;
9016                 }
9017
9018                 /* Done with the cipher. */
9019                 gcry_cipher_close(cipher_hd);
9020         }
9021 done_decryption:
9022         *enc_tvb = tvb_new_subset_length(tvb, offset, sti->size);
9023
9024         if (plain_data != NULL) {
9025                 *plain_tvb = tvb_new_child_real_data(*enc_tvb, plain_data, sti->size, sti->size);
9026                 add_new_data_source(pinfo, *plain_tvb, "Decrypted SMB3");
9027         }
9028
9029         offset += sti->size;
9030         return offset;
9031 }
9032
9033 static int
9034 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
9035 {
9036         int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
9037         proto_item *cmd_item;
9038         proto_tree *cmd_tree;
9039         int         old_offset = offset;
9040
9041         cmd_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
9042                         ett_smb2_command, &cmd_item, "%s %s (0x%02x)",
9043                         decode_smb2_name(si->opcode),
9044                         (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
9045                         si->opcode);
9046
9047         cmd_dissector = (si->flags & SMB2_FLAGS_RESPONSE)?
9048                 smb2_dissector[si->opcode&0xff].response:
9049                 smb2_dissector[si->opcode&0xff].request;
9050         if (cmd_dissector) {
9051                 offset = (*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
9052         } else {
9053                 proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, ENC_NA);
9054                 offset = tvb_captured_length(tvb);
9055         }
9056
9057         proto_item_set_len(cmd_item, offset-old_offset);
9058
9059         return offset;
9060 }
9061
9062 static int
9063 dissect_smb2_tid_sesid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
9064 {
9065         proto_item        *tid_item   = NULL;
9066         proto_tree        *tid_tree   = NULL;
9067         smb2_tid_info_t    tid_key;
9068         int                tid_offset = 0;
9069         proto_item        *sesid_item = NULL;
9070         proto_tree        *sesid_tree = NULL;
9071         smb2_sesid_info_t  sesid_key;
9072         int                sesid_offset;
9073         proto_item        *item;
9074
9075
9076         if (si->flags&SMB2_FLAGS_ASYNC_CMD) {
9077                 proto_tree_add_item(tree, hf_smb2_aid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9078                 offset += 8;
9079         } else {
9080                 /* Process ID */
9081                 proto_tree_add_item(tree, hf_smb2_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9082                 offset += 4;
9083
9084                 /* Tree ID */
9085                 tid_offset = offset;
9086                 si->tid = tvb_get_letohl(tvb, offset);
9087                 tid_item = proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9088                 tid_tree = proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
9089                 offset += 4;
9090         }
9091
9092         /* Session ID */
9093         sesid_offset = offset;
9094         si->sesid = tvb_get_letoh64(tvb, offset);
9095         sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9096         sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
9097         offset += 8;
9098
9099         /* now we need to first lookup the uid session */
9100         sesid_key.sesid = si->sesid;
9101         si->session = (smb2_sesid_info_t *)g_hash_table_lookup(si->conv->sesids, &sesid_key);
9102         if (!si->session) {
9103                 guint8 seskey[NTLMSSP_KEY_LEN] = {0, };
9104
9105                 if (si->opcode != 0x03)
9106                         return offset;
9107
9108
9109                 /* if we come to a session that is unknown, and the operation is
9110                  * a tree connect, we create a dummy sessison, so we can hang the
9111                  * tree data on it
9112                  */
9113                 si->session = wmem_new0(wmem_file_scope(), smb2_sesid_info_t);
9114                 si->session->sesid      = si->sesid;
9115                 si->session->auth_frame = (guint32)-1;
9116                 si->session->tids       = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
9117                 if (si->flags & SMB2_FLAGS_RESPONSE) {
9118                         si->session->server_port = pinfo->srcport;
9119                 } else {
9120                         si->session->server_port = pinfo->destport;
9121                 }
9122                 if (seskey_find_sid_key(si->sesid, seskey)) {
9123                         smb2_set_session_keys(si->session, seskey);
9124                 }
9125
9126                 g_hash_table_insert(si->conv->sesids, si->session, si->session);
9127
9128                 return offset;
9129         }
9130
9131         if (si->session->auth_frame != (guint32)-1) {
9132                 item = proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, si->session->acct_name);
9133                 PROTO_ITEM_SET_GENERATED(item);
9134                 proto_item_append_text(sesid_item, " Acct:%s", si->session->acct_name);
9135
9136                 item = proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, si->session->domain_name);
9137                 PROTO_ITEM_SET_GENERATED(item);
9138                 proto_item_append_text(sesid_item, " Domain:%s", si->session->domain_name);
9139
9140                 item = proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, si->session->host_name);
9141                 PROTO_ITEM_SET_GENERATED(item);
9142                 proto_item_append_text(sesid_item, " Host:%s", si->session->host_name);
9143
9144                 item = proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, si->session->auth_frame);
9145                 PROTO_ITEM_SET_GENERATED(item);
9146         }
9147
9148         if (!(si->flags&SMB2_FLAGS_ASYNC_CMD)) {
9149                 /* see if we can find the name for this tid */
9150                 tid_key.tid = si->tid;
9151                 si->tree = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
9152                 if (!si->tree) return offset;
9153
9154                 item = proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
9155                 PROTO_ITEM_SET_GENERATED(item);
9156                 proto_item_append_text(tid_item, "  %s", si->tree->name);
9157
9158                 item = proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
9159                 PROTO_ITEM_SET_GENERATED(item);
9160
9161                 item = proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
9162                 PROTO_ITEM_SET_GENERATED(item);
9163         }
9164
9165         return offset;
9166 }
9167
9168 static int
9169 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
9170 {
9171         gboolean    smb2_transform_header = FALSE;
9172         proto_item *item                  = NULL;
9173         proto_tree *tree                  = NULL;
9174         proto_item *header_item           = NULL;
9175         proto_tree *header_tree           = NULL;
9176         int         offset                = 0;
9177         int         chain_offset          = 0;
9178         const char *label                 = smb_header_label;
9179         conversation_t    *conversation;
9180         smb2_saved_info_t *ssi          = NULL, ssi_key;
9181         smb2_info_t       *si;
9182         smb2_transform_info_t *sti;
9183         char                *fid_name;
9184         guint32              open_frame,close_frame;
9185         smb2_eo_file_info_t *eo_file_info;
9186         e_ctx_hnd           *policy_hnd_hashtablekey;
9187
9188         sti = wmem_new(wmem_packet_scope(), smb2_transform_info_t);
9189         si  = wmem_new0(wmem_packet_scope(), smb2_info_t);
9190         si->top_tree = parent_tree;
9191
9192         if (tvb_get_guint8(tvb, 0) == 0xfd) {
9193                 smb2_transform_header = TRUE;
9194                 label = smb_transform_header_label;
9195         }
9196         /* find which conversation we are part of and get the data for that
9197          * conversation
9198          */
9199         conversation = find_or_create_conversation(pinfo);
9200         si->conv = (smb2_conv_info_t *)conversation_get_proto_data(conversation, proto_smb2);
9201         if (!si->conv) {
9202                 /* no smb2_into_t structure for this conversation yet,
9203                  * create it.
9204                  */
9205                 si->conv = wmem_new(wmem_file_scope(), smb2_conv_info_t);
9206                 /* qqq this leaks memory for now since we never free
9207                    the hashtables */
9208                 si->conv->matched = g_hash_table_new(smb2_saved_info_hash_matched,
9209                         smb2_saved_info_equal_matched);
9210                 si->conv->unmatched = g_hash_table_new(smb2_saved_info_hash_unmatched,
9211                         smb2_saved_info_equal_unmatched);
9212                 si->conv->sesids = g_hash_table_new(smb2_sesid_info_hash,
9213                         smb2_sesid_info_equal);
9214                 si->conv->fids = g_hash_table_new(smb2_fid_info_hash,
9215                         smb2_fid_info_equal);
9216                 si->conv->files = g_hash_table_new(smb2_eo_files_hash,smb2_eo_files_equal);
9217
9218                 /* Bit of a hack to avoid leaking the hash tables - register a
9219                  * callback to free them. Ideally wmem would implement a simple
9220                  * hash table so we wouldn't have to do this. */
9221                 wmem_register_callback(wmem_file_scope(), smb2_conv_destroy,
9222                                 si->conv);
9223
9224                 conversation_add_proto_data(conversation, proto_smb2, si->conv);
9225         }
9226
9227         sti->conv = si->conv;
9228
9229         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
9230         if (first_in_chain) {
9231                 /* first packet */
9232                 col_clear(pinfo->cinfo, COL_INFO);
9233         } else {
9234                 col_append_str(pinfo->cinfo, COL_INFO, ";");
9235         }
9236
9237         item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset, -1, ENC_NA);
9238         tree = proto_item_add_subtree(item, ett_smb2);
9239
9240         header_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_header, &header_item, label);
9241
9242         /* Decode the header */
9243
9244         if (!smb2_transform_header) {
9245                 /* SMB2 marker */
9246                 proto_tree_add_item(header_tree, hf_smb2_server_component_smb2, tvb, offset, 4, ENC_NA);
9247                 offset += 4;
9248
9249                 /* we need the flags before we know how to parse the credits field */
9250                 si->flags = tvb_get_letohl(tvb, offset+12);
9251
9252                 /* header length */
9253                 proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9254                 offset += 2;
9255
9256                 /* credit charge (previously "epoch" (unused) which has been deprecated as of "SMB 2.1") */
9257                 proto_tree_add_item(header_tree, hf_smb2_credit_charge, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9258                 offset += 2;
9259
9260                 /* Status Code */
9261                 if (si->flags & SMB2_FLAGS_RESPONSE) {
9262                         si->status = tvb_get_letohl(tvb, offset);
9263                         proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9264                         offset += 4;
9265                 } else {
9266                         si->status = 0;
9267                         proto_tree_add_item(header_tree, hf_smb2_channel_sequence, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9268                         offset += 2;
9269                         proto_tree_add_item(header_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
9270                         offset += 2;
9271                 }
9272
9273                 /* opcode */
9274                 si->opcode = tvb_get_letohs(tvb, offset);
9275                 proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9276                 offset += 2;
9277
9278                 /* credits */
9279                 if (si->flags & SMB2_FLAGS_RESPONSE) {
9280                         proto_tree_add_item(header_tree, hf_smb2_credits_granted, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9281                 } else {
9282                         proto_tree_add_item(header_tree, hf_smb2_credits_requested, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9283                 }
9284                 offset += 2;
9285
9286                 /* flags */
9287                 if (header_tree) {
9288                         static const int * flags[] = {
9289                                 &hf_smb2_flags_response,
9290                                 &hf_smb2_flags_async_cmd,
9291                                 &hf_smb2_flags_chained,
9292                                 &hf_smb2_flags_signature,
9293                                 &hf_smb2_flags_priority_mask,
9294                                 &hf_smb2_flags_dfs_op,
9295                                 &hf_smb2_flags_replay_operation,
9296                                 NULL
9297                         };
9298
9299                         proto_tree_add_bitmask(header_tree, tvb, offset, hf_smb2_flags,
9300                                                                         ett_smb2_flags, flags, ENC_LITTLE_ENDIAN);
9301                 }
9302
9303                 offset += 4;
9304
9305                 /* Next Command */
9306                 chain_offset = tvb_get_letohl(tvb, offset);
9307                 proto_tree_add_item(header_tree, hf_smb2_chain_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
9308                 offset += 4;
9309
9310                 /* Message ID */
9311                 si->msg_id = tvb_get_letoh64(tvb, offset);
9312                 ssi_key.msg_id = si->msg_id;
9313                 proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9314                 offset += 8;
9315
9316                 /* Tree ID and Session ID */
9317                 offset = dissect_smb2_tid_sesid(pinfo, header_tree, tvb, offset, si);
9318
9319                 /* Signature */
9320                 proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, ENC_NA);
9321                 offset += 16;
9322
9323                 proto_item_set_len(header_item, offset);
9324
9325
9326                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
9327                                 decode_smb2_name(si->opcode),
9328                                 (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
9329                 if (si->status) {
9330                         col_append_fstr(
9331                                         pinfo->cinfo, COL_INFO, ", Error: %s",
9332                                         val_to_str_ext(si->status, &NT_errors_ext,
9333                                                        "Unknown (0x%08X)"));
9334                 }
9335
9336
9337                 if (!pinfo->fd->flags.visited) {
9338                         /* see if we can find this msg_id in the unmatched table */
9339                         ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
9340
9341                         if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
9342                                 /* This is a request */
9343                                 if (ssi) {
9344                                         /* this is a request and we already found
9345                                         * an older ssi so just delete the previous
9346                                         * one
9347                                         */
9348                                         g_hash_table_remove(si->conv->unmatched, ssi);
9349                                         ssi = NULL;
9350                                 }
9351
9352                                 if (!ssi) {
9353                                         /* no we couldn't find it, so just add it then
9354                                         * if was a request we are decoding
9355                                         */
9356                                         ssi                  = wmem_new0(wmem_file_scope(), smb2_saved_info_t);
9357                                         ssi->msg_id          = ssi_key.msg_id;
9358                                         ssi->frame_req       = pinfo->num;
9359                                         ssi->req_time        = pinfo->abs_ts;
9360                                         ssi->extra_info_type = SMB2_EI_NONE;
9361                                         g_hash_table_insert(si->conv->unmatched, ssi, ssi);
9362                                 }
9363                         } else {
9364                                 /* This is a response */
9365                                 if (!((si->flags & SMB2_FLAGS_ASYNC_CMD)
9366                                         && si->status == NT_STATUS_PENDING)
9367                                         && ssi) {
9368                                         /* just  set the response frame and move it to the matched table */
9369                                         ssi->frame_res = pinfo->num;
9370                                         g_hash_table_remove(si->conv->unmatched, ssi);
9371                                         g_hash_table_insert(si->conv->matched, ssi, ssi);
9372                                 }
9373                         }
9374                 } else {
9375                         /* see if we can find this msg_id in the matched table */
9376                         ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->matched, &ssi_key);
9377                         /* if we couldn't find it in the matched table, it might still
9378                         * be in the unmatched table
9379                         */
9380                         if (!ssi) {
9381                                 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
9382                         }
9383                 }
9384
9385                 if (ssi) {
9386                         if (dcerpc_fetch_polhnd_data(&ssi->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
9387                                 /* If needed, create the file entry and save the policy hnd */
9388                                 if (!si->eo_file_info) {
9389                                         if (si->conv) {
9390                                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&ssi->policy_hnd);
9391                                                 if (!eo_file_info) { /* XXX This should never happen */
9392                                                         /* assert(1==0); */
9393                                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
9394                                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
9395                                                         memcpy(policy_hnd_hashtablekey, &ssi->policy_hnd, sizeof(e_ctx_hnd));
9396                                                         eo_file_info->end_of_file=0;
9397                                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
9398                                                 }
9399                                                 si->eo_file_info=eo_file_info;
9400                                         }
9401                                 }
9402                         }
9403
9404                         if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
9405                                 if (ssi->frame_res) {
9406                                         proto_item *tmp_item;
9407                                         tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
9408                                         PROTO_ITEM_SET_GENERATED(tmp_item);
9409                                 }
9410                         } else {
9411                                 if (ssi->frame_req) {
9412                                         proto_item *tmp_item;
9413                                         nstime_t    t, deltat;
9414
9415                                         tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
9416                                         PROTO_ITEM_SET_GENERATED(tmp_item);
9417                                         t = pinfo->abs_ts;
9418                                         nstime_delta(&deltat, &t, &ssi->req_time);
9419                                         tmp_item = proto_tree_add_time(header_tree, hf_smb2_time, tvb,
9420                                         0, 0, &deltat);
9421                                         PROTO_ITEM_SET_GENERATED(tmp_item);
9422                                 }
9423                         }
9424                         if (si->file != NULL) {
9425                                 ssi->file = si->file;
9426                         } else {
9427                                 si->file = ssi->file;
9428                         }
9429                 }
9430                 /* if we don't have ssi yet we must fake it */
9431                 /*qqq*/
9432                 si->saved = ssi;
9433
9434                 tap_queue_packet(smb2_tap, pinfo, si);
9435
9436                 /* Decode the payload */
9437                 offset                = dissect_smb2_command(pinfo, tree, tvb, offset, si);
9438         } else {
9439                 proto_tree *enc_tree;
9440                 tvbuff_t   *enc_tvb   = NULL;
9441                 tvbuff_t   *plain_tvb = NULL;
9442
9443                 /* SMB2_TRANSFORM marker */
9444                 proto_tree_add_item(header_tree, hf_smb2_server_component_smb2_transform, tvb, offset, 4, ENC_NA);
9445                 offset += 4;
9446
9447                 offset = dissect_smb2_transform_header(pinfo, header_tree, tvb, offset, sti,
9448                                                        &enc_tvb, &plain_tvb);
9449
9450                 enc_tree = proto_tree_add_subtree(tree, enc_tvb, 0, sti->size, ett_smb2_encrypted, NULL, "Encrypted SMB3 data");
9451                 if (plain_tvb != NULL) {
9452                         col_append_str(pinfo->cinfo, COL_INFO, "Decrypted SMB3");
9453                         dissect_smb2(plain_tvb, pinfo, enc_tree, FALSE);
9454                 } else {
9455                         col_append_str(pinfo->cinfo, COL_INFO, "Encrypted SMB3");
9456                         proto_tree_add_item(enc_tree, hf_smb2_transform_encrypted_data,
9457                                             enc_tvb, 0, sti->size, ENC_NA);
9458                 }
9459
9460                 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9461                         chain_offset = offset;
9462                 }
9463         }
9464
9465         if (chain_offset > 0) {
9466                 tvbuff_t *next_tvb;
9467
9468                 proto_item_set_len(item, chain_offset);
9469
9470                 next_tvb = tvb_new_subset_remaining(tvb, chain_offset);
9471                 offset   = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
9472         }
9473
9474         return offset;
9475 }
9476
9477 static gboolean
9478 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
9479 {
9480
9481         /* must check that this really is a smb2 packet */
9482         if (tvb_captured_length(tvb) < 4)
9483                 return FALSE;
9484
9485         if (((tvb_get_guint8(tvb, 0) != 0xfe) && (tvb_get_guint8(tvb, 0) != 0xfd))
9486             || (tvb_get_guint8(tvb, 1) != 'S')
9487             || (tvb_get_guint8(tvb, 2) != 'M')
9488             || (tvb_get_guint8(tvb, 3) != 'B') ) {
9489                 return FALSE;
9490         }
9491
9492         dissect_smb2(tvb, pinfo, parent_tree, TRUE);
9493
9494         return TRUE;
9495 }
9496
9497 void
9498 proto_register_smb2(void)
9499 {
9500         module_t *smb2_module;
9501         static hf_register_info hf[] = {
9502                 { &hf_smb2_cmd,
9503                         { "Command", "smb2.cmd", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
9504                         &smb2_cmd_vals_ext, 0, "SMB2 Command Opcode", HFILL }
9505                 },
9506
9507                 { &hf_smb2_response_to,
9508                         { "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
9509                         FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0, "This packet is a response to the packet in this frame", HFILL }
9510                 },
9511
9512                 { &hf_smb2_response_in,
9513                         { "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
9514                         FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0, "The response to this packet is in this packet", HFILL }
9515                 },
9516
9517                 { &hf_smb2_time,
9518                         { "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
9519                         NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }
9520                 },
9521
9522                 { &hf_smb2_header_len,
9523                         { "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
9524                         NULL, 0, "SMB2 Size of Header", HFILL }
9525                 },
9526
9527                 { &hf_smb2_nt_status,
9528                         { "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
9529                         &NT_errors_ext, 0, "NT Status code", HFILL }
9530                 },
9531
9532                 { &hf_smb2_msg_id,
9533                         { "Message ID", "smb2.msg_id", FT_UINT64, BASE_DEC|BASE_VAL64_STRING|BASE_SPECIAL_VALS,
9534                         VALS64(unique_unsolicited_response), 0, NULL, HFILL }
9535                 },
9536
9537                 { &hf_smb2_tid,
9538                         { "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
9539                         NULL, 0, NULL, HFILL }
9540                 },
9541
9542                 { &hf_smb2_aid,
9543                         { "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
9544                         NULL, 0, NULL, HFILL }
9545                 },
9546
9547                 { &hf_smb2_sesid,
9548                         { "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
9549                         NULL, 0, NULL, HFILL }
9550                 },
9551
9552                 { &hf_smb2_previous_sesid,
9553                         { "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
9554                         NULL, 0, NULL, HFILL }
9555                 },
9556
9557                 { &hf_smb2_chain_offset,
9558                         { "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
9559                         NULL, 0, NULL, HFILL }
9560                 },
9561
9562                 { &hf_smb2_end_of_file,
9563                         { "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
9564                         NULL, 0, "SMB2 End Of File/File size", HFILL }
9565                 },
9566
9567                 { &hf_smb2_nlinks,
9568                         { "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
9569                         NULL, 0, "Number of links to this object", HFILL }
9570                 },
9571
9572                 { &hf_smb2_file_id,
9573                         { "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
9574                         NULL, 0, NULL, HFILL }
9575                 },
9576
9577                 { &hf_smb2_allocation_size,
9578                         { "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
9579                         NULL, 0, NULL, HFILL }
9580                 },
9581
9582                 { &hf_smb2_max_response_size,
9583                         { "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
9584                         NULL, 0, NULL, HFILL }
9585                 },
9586
9587                 { &hf_smb2_getinfo_input_size,
9588                         { "Getinfo Input Size", "smb2.getinfo_input_size", FT_UINT32, BASE_DEC,
9589                         NULL, 0, NULL, HFILL }
9590                 },
9591
9592                 { &hf_smb2_getinfo_input_offset,
9593                         { "Getinfo Input Offset", "smb2.getinfo_input_offset", FT_UINT16, BASE_HEX,
9594                         NULL, 0, NULL, HFILL }
9595                 },
9596
9597                 { &hf_smb2_getinfo_additional,
9598                         { "Additional Info", "smb2.getinfo_additional", FT_UINT32, BASE_HEX,
9599                         NULL, 0, NULL, HFILL }
9600                 },
9601
9602                 { &hf_smb2_getinfo_flags,
9603                         { "Flags", "smb2.getinfo_flags", FT_UINT32, BASE_HEX,
9604                         NULL, 0, NULL, HFILL }
9605                 },
9606
9607                 { &hf_smb2_setinfo_size,
9608                         { "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
9609                         NULL, 0, NULL, HFILL }
9610                 },
9611
9612                 { &hf_smb2_setinfo_offset,
9613                         { "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
9614                         NULL, 0, NULL, HFILL }
9615                 },
9616
9617                 { &hf_smb2_max_ioctl_out_size,
9618                         { "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
9619                         NULL, 0, NULL, HFILL }
9620                 },
9621
9622                 { &hf_smb2_max_ioctl_in_size,
9623                         { "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
9624                         NULL, 0, NULL, HFILL }
9625                 },
9626
9627                 { &hf_smb2_required_buffer_size,
9628                         { "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
9629                         NULL, 0, NULL, HFILL }
9630                 },
9631
9632                 { &hf_smb2_pid,
9633                         { "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
9634                         NULL, 0, NULL, HFILL }
9635                 },
9636
9637
9638                 /* SMB2 header flags  */
9639                 { &hf_smb2_flags,
9640                         { "Flags", "smb2.flags", FT_UINT32, BASE_HEX,
9641                         NULL, 0, "SMB2 flags", HFILL }
9642                 },
9643
9644                 { &hf_smb2_flags_response,
9645                         { "Response", "smb2.flags.response", FT_BOOLEAN, 32,
9646                         TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }
9647                 },
9648
9649                 { &hf_smb2_flags_async_cmd,
9650                         { "Async command", "smb2.flags.async", FT_BOOLEAN, 32,
9651                         TFS(&tfs_flags_async_cmd), SMB2_FLAGS_ASYNC_CMD, NULL, HFILL }
9652                 },
9653
9654                 { &hf_smb2_flags_dfs_op,
9655                         { "DFS operation", "smb2.flags.dfs", FT_BOOLEAN, 32,
9656                         TFS(&tfs_flags_dfs_op), SMB2_FLAGS_DFS_OP, NULL, HFILL }
9657                 },
9658
9659                 { &hf_smb2_flags_chained,
9660                         { "Chained", "smb2.flags.chained", FT_BOOLEAN, 32,
9661                         TFS(&tfs_flags_chained), SMB2_FLAGS_CHAINED, "Whether the pdu continues a chain or not", HFILL }
9662                 },
9663                 { &hf_smb2_flags_signature,
9664                         { "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
9665                         TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }
9666                 },
9667
9668                 { &hf_smb2_flags_replay_operation,
9669                         { "Replay operation", "smb2.flags.replay", FT_BOOLEAN, 32,
9670                         TFS(&tfs_flags_replay_operation), SMB2_FLAGS_REPLAY_OPERATION, "Whether this is a replay operation", HFILL }
9671                 },
9672
9673                 { &hf_smb2_flags_priority_mask,
9674                         { "Priority", "smb2.flags.priority_mask", FT_BOOLEAN, 32,
9675                         TFS(&tfs_flags_priority_mask), SMB2_FLAGS_PRIORITY_MASK, "Priority Mask", HFILL }
9676                 },
9677
9678                 { &hf_smb2_tree,
9679                         { "Tree", "smb2.tree", FT_STRING, BASE_NONE,
9680                         NULL, 0, "Name of the Tree/Share", HFILL }
9681                 },
9682
9683                 { &hf_smb2_filename,
9684                         { "Filename", "smb2.filename", FT_STRING, BASE_NONE,
9685                         NULL, 0, NULL, HFILL }
9686                 },
9687
9688                 { &hf_smb2_filename_len,
9689                         { "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
9690                         NULL, 0, NULL, HFILL }
9691                 },
9692
9693                 { &hf_smb2_replace_if,
9694                         { "Replace If", "smb2.rename.replace_if", FT_BOOLEAN, 8,
9695                         TFS(&tfs_replace_if_exists), 0xFF, "Whether to replace if the target exists", HFILL }
9696                 },
9697
9698                 { &hf_smb2_data_offset,
9699                         { "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
9700                         NULL, 0, "Offset to data", HFILL }
9701                 },
9702
9703                 { &hf_smb2_find_info_level,
9704                         { "Info Level", "smb2.find.infolevel", FT_UINT32, BASE_DEC,
9705                         VALS(smb2_find_info_levels), 0, "Find_Info Infolevel", HFILL }
9706                 },
9707                 { &hf_smb2_find_flags,
9708                         { "Find Flags", "smb2.find.flags", FT_UINT8, BASE_HEX,
9709                         NULL, 0, NULL, HFILL }
9710                 },
9711
9712                 { &hf_smb2_find_pattern,
9713                         { "Search Pattern", "smb2.find.pattern", FT_STRING, BASE_NONE,
9714                         NULL, 0, "Find pattern", HFILL }
9715                 },
9716
9717                 { &hf_smb2_find_info_blob,
9718                         { "Info", "smb2.find.info_blob", FT_BYTES, BASE_NONE,
9719                         NULL, 0, "Find Info", HFILL }
9720                 },
9721
9722                 { &hf_smb2_ea_size,
9723                         { "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
9724                         NULL, 0, "Size of EA data", HFILL }
9725                 },
9726
9727                 { &hf_smb2_position_information,
9728                         { "Position Information", "smb2.position_info", FT_UINT64, BASE_DEC,
9729                         NULL, 0, "Current file position", HFILL }
9730                 },
9731
9732                 { &hf_smb2_mode_information,
9733                         { "Mode Information", "smb2.mode_info", FT_UINT32, BASE_HEX,
9734                         NULL, 0, "File mode informatino", HFILL }
9735                 },
9736
9737                 { &hf_smb2_mode_file_write_through,
9738                         { "FILE_WRITE_THROUGH", "smb2.mode.file_write_through", FT_UINT32, BASE_HEX,
9739                         NULL, 0x02, NULL, HFILL }
9740                 },
9741
9742                 { &hf_smb2_mode_file_sequential_only,
9743                         { "FILE_SEQUENTIAL_ONLY", "smb2.mode.file_sequential_only", FT_UINT32, BASE_HEX,
9744                         NULL, 0x04, NULL, HFILL }
9745                 },
9746
9747                 { &hf_smb2_mode_file_no_intermediate_buffering,
9748                         { "FILE_NO_INTERMEDIATE_BUFFERING", "smb2.mode.file_no_intermediate_buffering", FT_UINT32, BASE_HEX,
9749                         NULL, 0x08, NULL, HFILL }
9750                 },
9751
9752                 { &hf_smb2_mode_file_synchronous_io_alert,
9753                         { "FILE_SYNCHRONOUS_IO_ALERT", "smb2.mode.file_synchronous_io_alert", FT_UINT32, BASE_HEX,
9754                         NULL, 0x10, NULL, HFILL }
9755                 },
9756
9757                 { &hf_smb2_mode_file_synchronous_io_nonalert,
9758                         { "FILE_SYNCHRONOUS_IO_NONALERT", "smb2.mode.file_synchronous_io_nonalert", FT_UINT32, BASE_HEX,
9759                         NULL, 0x20, NULL, HFILL }
9760                 },
9761
9762                 { &hf_smb2_mode_file_delete_on_close,
9763                         { "FILE_DELETE_ON_CLOSE", "smb2.mode.file_delete_on_close", FT_UINT32, BASE_HEX,
9764                         NULL, 0x1000, NULL, HFILL }
9765                 },
9766
9767                 { &hf_smb2_alignment_information,
9768                         { "Alignment Information", "smb2.alignment_info", FT_UINT32, BASE_HEX,
9769                         VALS(smb2_alignment_vals), 0, "File alignment", HFILL}
9770                 },
9771
9772                 { &hf_smb2_class,
9773                         { "Class", "smb2.class", FT_UINT8, BASE_HEX,
9774                         VALS(smb2_class_vals), 0, "Info class", HFILL }
9775                 },
9776
9777                 { &hf_smb2_infolevel,
9778                         { "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
9779                         NULL, 0, NULL, HFILL }
9780                 },
9781
9782                 { &hf_smb2_infolevel_file_info,
9783                         { "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
9784                         &smb2_file_info_levels_ext, 0, "File_Info Infolevel", HFILL }
9785                 },
9786
9787                 { &hf_smb2_infolevel_fs_info,
9788                         { "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
9789                         &smb2_fs_info_levels_ext, 0, "Fs_Info Infolevel", HFILL }
9790                 },
9791
9792                 { &hf_smb2_infolevel_sec_info,
9793                         { "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
9794                         &smb2_sec_info_levels_ext, 0, "Sec_Info Infolevel", HFILL }
9795                 },
9796
9797                 { &hf_smb2_infolevel_posix_info,
9798                         { "InfoLevel", "smb2.posix_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
9799                         &smb2_posix_info_levels_ext, 0, "Posix_Info Infolevel", HFILL }
9800                 },
9801
9802                 { &hf_smb2_write_length,
9803                         { "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
9804                         NULL, 0, "Amount of data to write", HFILL }
9805                 },
9806
9807                 { &hf_smb2_read_length,
9808                         { "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
9809                         NULL, 0, "Amount of data to read", HFILL }
9810                 },
9811
9812                 { &hf_smb2_read_remaining,
9813                         { "Read Remaining", "smb2.read_remaining", FT_UINT32, BASE_DEC,
9814                         NULL, 0, NULL, HFILL }
9815                 },
9816
9817                 { &hf_smb2_create_flags,
9818                         { "Create Flags", "smb2.create_flags", FT_UINT64, BASE_HEX,
9819                         NULL, 0, NULL, HFILL }
9820                 },
9821
9822                 { &hf_smb2_file_offset,
9823                         { "File Offset", "smb2.file_offset", FT_UINT64, BASE_DEC,
9824                         NULL, 0, NULL, HFILL }
9825                 },
9826
9827                 { &hf_smb2_fsctl_range_offset,
9828                         { "File Offset", "smb2.fsctl.range_offset", FT_UINT64, BASE_DEC,
9829                         NULL, 0, NULL, HFILL }
9830                 },
9831
9832                 { &hf_smb2_fsctl_range_length,
9833                         { "Length", "smb2.fsctl.range_length", FT_UINT64, BASE_DEC,
9834                         NULL, 0, NULL, HFILL }
9835                 },
9836
9837                 { &hf_smb2_qfr_length,
9838                         { "Length", "smb2.qfr_length", FT_UINT64, BASE_DEC,
9839                         NULL, 0, NULL, HFILL }
9840                 },
9841
9842                 { &hf_smb2_qfr_usage,
9843                         { "Desired Usage", "smb2.qfr_usage", FT_UINT32, BASE_HEX,
9844                         VALS(file_region_usage_vals), 0, NULL, HFILL }
9845                 },
9846
9847                 { &hf_smb2_qfr_flags,
9848                         { "Flags", "smb2.qfr_flags", FT_UINT32, BASE_HEX,
9849                         NULL, 0, NULL, HFILL }
9850                 },
9851
9852                 { &hf_smb2_qfr_total_region_entry_count,
9853                         { "Total Region Entry Count", "smb2.qfr_tot_region_entry_count", FT_UINT32, BASE_HEX,
9854                         NULL, 0, NULL, HFILL }
9855                 },
9856
9857                 { &hf_smb2_qfr_region_entry_count,
9858                         { "Region Entry Count", "smb2.qfr_region_entry_count", FT_UINT32, BASE_HEX,
9859                         NULL, 0, NULL, HFILL }
9860                 },
9861
9862                 { &hf_smb2_security_blob,
9863                         { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_NONE,
9864                         NULL, 0, NULL, HFILL }
9865                 },
9866
9867                 { &hf_smb2_ioctl_out_data,
9868                         { "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
9869                         NULL, 0, "Ioctl Out", HFILL }
9870                 },
9871
9872                 { &hf_smb2_ioctl_in_data,
9873                         { "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
9874                         NULL, 0, "Ioctl In", HFILL }
9875                 },
9876
9877                 { &hf_smb2_server_guid,
9878                         { "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
9879                         NULL, 0, NULL, HFILL }
9880                 },
9881
9882                 { &hf_smb2_client_guid,
9883                         { "Client Guid", "smb2.client_guid", FT_GUID, BASE_NONE,
9884                         NULL, 0, NULL, HFILL }
9885                 },
9886
9887                 { &hf_smb2_object_id,
9888                         { "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
9889                         NULL, 0, "ObjectID for this FID", HFILL }
9890                 },
9891
9892                 { &hf_smb2_birth_volume_id,
9893                         { "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
9894                         NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }
9895                 },
9896
9897                 { &hf_smb2_birth_object_id,
9898                         { "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
9899                         NULL, 0, "ObjectID for this FID when it was originally created", HFILL }
9900                 },
9901
9902                 { &hf_smb2_domain_id,
9903                         { "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
9904                         NULL, 0, NULL, HFILL }
9905                 },
9906
9907                 { &hf_smb2_create_timestamp,
9908                         { "Create", "smb2.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9909                         NULL, 0, "Time when this object was created", HFILL }
9910                 },
9911
9912                 { &hf_smb2_fid,
9913                         { "File Id", "smb2.fid", FT_GUID, BASE_NONE,
9914                         NULL, 0, "SMB2 File Id", HFILL }
9915                 },
9916
9917                 { &hf_smb2_write_data,
9918                         { "Write Data", "smb2.write_data", FT_BYTES, BASE_NONE,
9919                         NULL, 0, "SMB2 Data to be written", HFILL }
9920                 },
9921
9922                 { &hf_smb2_write_flags,
9923                         { "Write Flags", "smb2.write.flags", FT_UINT32, BASE_HEX,
9924                         NULL, 0, NULL, HFILL }
9925                 },
9926
9927                 { &hf_smb2_write_flags_write_through,
9928                         { "Write through", "smb2.write.flags.write_through", FT_BOOLEAN, 32,
9929                         NULL, SMB2_WRITE_FLAG_WRITE_THROUGH, NULL, HFILL }
9930                 },
9931
9932                 { &hf_smb2_write_count,
9933                         { "Write Count", "smb2.write.count", FT_UINT32, BASE_DEC,
9934                         NULL, 0, NULL, HFILL }
9935                 },
9936
9937                 { &hf_smb2_write_remaining,
9938                         { "Write Remaining", "smb2.write.remaining", FT_UINT32, BASE_DEC,
9939                         NULL, 0, NULL, HFILL }
9940                 },
9941
9942                 { &hf_smb2_read_data,
9943                         { "Read Data", "smb2.read_data", FT_BYTES, BASE_NONE,
9944                         NULL, 0, "SMB2 Data that is read", HFILL }
9945                 },
9946
9947                 { &hf_smb2_last_access_timestamp,
9948                         { "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9949                         NULL, 0, "Time when this object was last accessed", HFILL }
9950                 },
9951
9952                 { &hf_smb2_last_write_timestamp,
9953                         { "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9954                         NULL, 0, "Time when this object was last written to", HFILL }
9955                 },
9956
9957                 { &hf_smb2_last_change_timestamp,
9958                         { "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9959                         NULL, 0, "Time when this object was last changed", HFILL }
9960                 },
9961
9962                 { &hf_smb2_file_all_info,
9963                         { "SMB2_FILE_ALL_INFO", "smb2.file_all_info", FT_NONE, BASE_NONE,
9964                         NULL, 0, NULL, HFILL }
9965                 },
9966
9967                 { &hf_smb2_file_allocation_info,
9968                         { "SMB2_FILE_ALLOCATION_INFO", "smb2.file_allocation_info", FT_NONE, BASE_NONE,
9969                         NULL, 0, NULL, HFILL }
9970                 },
9971
9972                 { &hf_smb2_file_endoffile_info,
9973                         { "SMB2_FILE_ENDOFFILE_INFO", "smb2.file_endoffile_info", FT_NONE, BASE_NONE,
9974                         NULL, 0, NULL, HFILL }
9975                 },
9976
9977                 { &hf_smb2_file_alternate_name_info,
9978                         { "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.file_alternate_name_info", FT_NONE, BASE_NONE,
9979                         NULL, 0, NULL, HFILL }
9980                 },
9981
9982                 { &hf_smb2_file_stream_info,
9983                         { "SMB2_FILE_STREAM_INFO", "smb2.file_stream_info", FT_NONE, BASE_NONE,
9984                         NULL, 0, NULL, HFILL }
9985                 },
9986
9987                 { &hf_smb2_file_pipe_info,
9988                         { "SMB2_FILE_PIPE_INFO", "smb2.file_pipe_info", FT_NONE, BASE_NONE,
9989                         NULL, 0, NULL, HFILL }
9990                 },
9991
9992                 { &hf_smb2_file_compression_info,
9993                         { "SMB2_FILE_COMPRESSION_INFO", "smb2.file_compression_info", FT_NONE, BASE_NONE,
9994                         NULL, 0, NULL, HFILL }
9995                 },
9996
9997                 { &hf_smb2_file_basic_info,
9998                         { "SMB2_FILE_BASIC_INFO", "smb2.file_basic_info", FT_NONE, BASE_NONE,
9999                         NULL, 0, NULL, HFILL }
10000                 },
10001
10002                 { &hf_smb2_file_standard_info,
10003                         { "SMB2_FILE_STANDARD_INFO", "smb2.file_standard_info", FT_NONE, BASE_NONE,
10004                         NULL, 0, NULL, HFILL }
10005                 },
10006
10007                 { &hf_smb2_file_internal_info,
10008                         { "SMB2_FILE_INTERNAL_INFO", "smb2.file_internal_info", FT_NONE, BASE_NONE,
10009                         NULL, 0, NULL, HFILL }
10010                 },
10011
10012                 { &hf_smb2_file_mode_info,
10013                         { "SMB2_FILE_MODE_INFO", "smb2.file_mode_info", FT_NONE, BASE_NONE,
10014                         NULL, 0, NULL, HFILL }
10015                 },
10016
10017                 { &hf_smb2_file_alignment_info,
10018                         { "SMB2_FILE_ALIGNMENT_INFO", "smb2.file_alignment_info", FT_NONE, BASE_NONE,
10019                         NULL, 0, NULL, HFILL }
10020                 },
10021
10022                 { &hf_smb2_file_position_info,
10023                         { "SMB2_FILE_POSITION_INFO", "smb2.file_position_info", FT_NONE, BASE_NONE,
10024                         NULL, 0, NULL, HFILL }
10025                 },
10026
10027                 { &hf_smb2_file_access_info,
10028                         { "SMB2_FILE_ACCESS_INFO", "smb2.file_access_info", FT_NONE, BASE_NONE,
10029                         NULL, 0, NULL, HFILL }
10030                 },
10031
10032                 { &hf_smb2_file_ea_info,
10033                         { "SMB2_FILE_EA_INFO", "smb2.file_ea_info", FT_NONE, BASE_NONE,
10034                         NULL, 0, NULL, HFILL }
10035                 },
10036
10037                 { &hf_smb2_file_network_open_info,
10038                         { "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.file_network_open_info", FT_NONE, BASE_NONE,
10039                         NULL, 0, NULL, HFILL }
10040                 },
10041
10042                 { &hf_smb2_file_attribute_tag_info,
10043                         { "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.file_attribute_tag_info", FT_NONE, BASE_NONE,
10044                         NULL, 0, NULL, HFILL }
10045                 },
10046
10047                 { &hf_smb2_file_disposition_info,
10048                         { "SMB2_FILE_DISPOSITION_INFO", "smb2.file_disposition_info", FT_NONE, BASE_NONE,
10049                         NULL, 0, NULL, HFILL }
10050                 },
10051
10052                 { &hf_smb2_file_full_ea_info,
10053                         { "SMB2_FILE_FULL_EA_INFO", "smb2.file_full_ea_info", FT_NONE, BASE_NONE,
10054                         NULL, 0, NULL, HFILL }
10055                 },
10056
10057                 { &hf_smb2_file_rename_info,
10058                         { "SMB2_FILE_RENAME_INFO", "smb2.file_rename_info", FT_NONE, BASE_NONE,
10059                         NULL, 0, NULL, HFILL }
10060                 },
10061
10062                 { &hf_smb2_fs_info_01,
10063                         { "FileFsVolumeInformation", "smb2.fs_volume_info", FT_NONE, BASE_NONE,
10064                         NULL, 0, NULL, HFILL }
10065                 },
10066
10067                 { &hf_smb2_fs_info_03,
10068                         { "FileFsSizeInformation", "smb2.fs_size_info", FT_NONE, BASE_NONE,
10069                         NULL, 0, NULL, HFILL }
10070                 },
10071
10072                 { &hf_smb2_fs_info_04,
10073                         { "FileFsDeviceInformation", "smb2.fs_device_info", FT_NONE, BASE_NONE,
10074                         NULL, 0, NULL, HFILL }
10075                 },
10076
10077                 { &hf_smb2_fs_info_05,
10078                         { "FileFsAttributeInformation", "smb2.fs_attribute_info", FT_NONE, BASE_NONE,
10079                         NULL, 0, NULL, HFILL }
10080                 },
10081
10082                 { &hf_smb2_fs_info_06,
10083                         { "FileFsControlInformation", "smb2.fs_control_info", FT_NONE, BASE_NONE,
10084                         NULL, 0, NULL, HFILL }
10085                 },
10086
10087                 { &hf_smb2_fs_info_07,
10088                         { "FileFsFullSizeInformation", "smb2.fs_full_size_info", FT_NONE, BASE_NONE,
10089                         NULL, 0, NULL, HFILL }
10090                 },
10091
10092                 { &hf_smb2_fs_objectid_info,
10093                         { "FileFsObjectIdInformation", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
10094                         NULL, 0, NULL, HFILL }
10095                 },
10096
10097                 { &hf_smb2_sec_info_00,
10098                         { "SMB2_SEC_INFO_00", "smb2.sec_info_00", FT_NONE, BASE_NONE,
10099                         NULL, 0, NULL, HFILL }
10100                 },
10101
10102                 { &hf_smb2_quota_info,
10103                         { "SMB2_QUOTA_INFO", "smb2.quota_info", FT_NONE, BASE_NONE,
10104                         NULL, 0, NULL, HFILL }
10105                 },
10106
10107                 { &hf_smb2_query_quota_info,
10108                         { "SMB2_QUERY_QUOTA_INFO", "smb2.query_quota_info", FT_NONE, BASE_NONE,
10109                         NULL, 0, NULL, HFILL }
10110                 },
10111
10112                 { &hf_smb2_qq_single,
10113                         { "ReturnSingle", "smb2.query_quota_info.single", FT_BOOLEAN, 8,
10114                         NULL, 0xff, NULL, HFILL }
10115                 },
10116
10117                 { &hf_smb2_qq_restart,
10118                         { "RestartScan", "smb2.query_quota_info.restart", FT_BOOLEAN, 8,
10119                         NULL, 0xff, NULL, HFILL }
10120                 },
10121
10122                 { &hf_smb2_qq_sidlist_len,
10123                         { "SidListLength", "smb2.query_quota_info.sidlistlen", FT_UINT32, BASE_DEC,
10124                         NULL, 0, NULL, HFILL }
10125                 },
10126
10127                 { &hf_smb2_qq_start_sid_len,
10128                         { "StartSidLength", "smb2.query_quota_info.startsidlen", FT_UINT32, BASE_DEC,
10129                         NULL, 0, NULL, HFILL }
10130                 },
10131
10132                 { &hf_smb2_qq_start_sid_offset,
10133                         { "StartSidOffset", "smb2.query_quota_info.startsidoffset", FT_UINT32, BASE_DEC,
10134                         NULL, 0, NULL, HFILL }
10135                 },
10136
10137                 { &hf_smb2_disposition_delete_on_close,
10138                         { "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
10139                         TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }
10140                 },
10141
10142
10143                 { &hf_smb2_create_disposition,
10144                         { "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
10145                         VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }
10146                 },
10147
10148                 { &hf_smb2_create_action,
10149                         { "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
10150                         VALS(oa_open_vals), 0, NULL, HFILL }
10151                 },
10152
10153                 { &hf_smb2_create_rep_flags,
10154                         { "Response Flags", "smb2.create.rep_flags", FT_UINT8, BASE_HEX,
10155                         NULL, 0, NULL, HFILL }
10156                 },
10157
10158                 { &hf_smb2_create_rep_flags_reparse_point,
10159                         { "ReparsePoint", "smb2.create.rep_flags.reparse_point", FT_BOOLEAN, 8,
10160                         NULL, SMB2_CREATE_REP_FLAGS_REPARSE_POINT, NULL, HFILL }
10161                 },
10162
10163                 { &hf_smb2_extrainfo,
10164                         { "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
10165                         NULL, 0, "Create ExtraInfo", HFILL }
10166                 },
10167
10168                 { &hf_smb2_create_chain_offset,
10169                         { "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
10170                         NULL, 0, "Offset to next entry in chain or 0", HFILL }
10171                 },
10172
10173                 { &hf_smb2_create_chain_data,
10174                         { "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
10175                         NULL, 0, "Chain Data", HFILL }
10176                 },
10177
10178                 { &hf_smb2_FILE_OBJECTID_BUFFER,
10179                         { "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
10180                         NULL, 0, NULL, HFILL }
10181                 },
10182
10183                 { &hf_smb2_lease_key,
10184                         { "Lease Key", "smb2.lease.lease_key", FT_GUID, BASE_NONE,
10185                         NULL, 0, NULL, HFILL }
10186                 },
10187
10188                 { &hf_smb2_lease_state,
10189                         { "Lease State", "smb2.lease.lease_state", FT_UINT32, BASE_HEX,
10190                         NULL, 0, NULL, HFILL }
10191                 },
10192
10193                 { &hf_smb2_lease_state_read_caching,
10194                         { "Read Caching", "smb2.lease.lease_state.read_caching", FT_BOOLEAN, 32,
10195                         NULL, SMB2_LEASE_STATE_READ_CACHING, NULL, HFILL }
10196                 },
10197
10198                 { &hf_smb2_lease_state_handle_caching,
10199                         { "Handle Caching", "smb2.lease.lease_state.handle_caching", FT_BOOLEAN, 32,
10200                         NULL, SMB2_LEASE_STATE_HANDLE_CACHING, NULL, HFILL }
10201                 },
10202
10203                 { &hf_smb2_lease_state_write_caching,
10204                         { "Write Caching", "smb2.lease.lease_state.write_caching", FT_BOOLEAN, 32,
10205                         NULL, SMB2_LEASE_STATE_WRITE_CACHING, NULL, HFILL }
10206                 },
10207
10208                 { &hf_smb2_lease_flags,
10209                         { "Lease Flags", "smb2.lease.lease_flags", FT_UINT32, BASE_HEX,
10210                         NULL, 0, NULL, HFILL }
10211                 },
10212
10213                 { &hf_smb2_lease_flags_break_ack_required,
10214                         { "Break Ack Required", "smb2.lease.lease_state.break_ack_required", FT_BOOLEAN, 32,
10215                         NULL, SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED, NULL, HFILL }
10216                 },
10217
10218                 { &hf_smb2_lease_flags_break_in_progress,
10219                         { "Break In Progress", "smb2.lease.lease_state.break_in_progress", FT_BOOLEAN, 32,
10220                         NULL, SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS, NULL, HFILL }
10221                 },
10222
10223                 { &hf_smb2_lease_flags_parent_lease_key_set,
10224                         { "Parent Lease Key Set", "smb2.lease.lease_state.parent_lease_key_set", FT_BOOLEAN, 32,
10225                         NULL, SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET, NULL, HFILL }
10226                 },
10227
10228                 { &hf_smb2_lease_duration,
10229                         { "Lease Duration", "smb2.lease.lease_duration", FT_UINT64, BASE_HEX,
10230                         NULL, 0, NULL, HFILL }
10231                 },
10232
10233                 { &hf_smb2_parent_lease_key,
10234                         { "Parent Lease Key", "smb2.lease.parent_lease_key", FT_GUID, BASE_NONE,
10235                         NULL, 0, NULL, HFILL }
10236                 },
10237
10238                 { &hf_smb2_lease_epoch,
10239                         { "Lease Epoch", "smb2.lease.lease_oplock", FT_UINT16, BASE_HEX,
10240                         NULL, 0, NULL, HFILL }
10241                 },
10242
10243                 { &hf_smb2_lease_reserved,
10244                         { "Lease Reserved", "smb2.lease.lease_reserved", FT_UINT16, BASE_HEX,
10245                         NULL, 0, NULL, HFILL }
10246                 },
10247
10248                 { &hf_smb2_lease_break_reason,
10249                         { "Lease Break Reason", "smb2.lease.lease_break_reason", FT_UINT32, BASE_HEX,
10250                         NULL, 0, NULL, HFILL }
10251                 },
10252
10253                 { &hf_smb2_lease_access_mask_hint,
10254                         { "Access Mask Hint", "smb2.lease.access_mask_hint", FT_UINT32, BASE_HEX,
10255                         NULL, 0, NULL, HFILL }
10256                 },
10257
10258                 { &hf_smb2_lease_share_mask_hint,
10259                         { "Share Mask Hint", "smb2.lease.share_mask_hint", FT_UINT32, BASE_HEX,
10260                         NULL, 0, NULL, HFILL }
10261                 },
10262
10263                 { &hf_smb2_next_offset,
10264                         { "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
10265                         NULL, 0, "Offset to next buffer or 0", HFILL }
10266                 },
10267
10268                 { &hf_smb2_negotiate_context_type,
10269                         { "Type", "smb2.negotiate_context.type", FT_UINT16, BASE_HEX,
10270                         VALS(smb2_negotiate_context_types), 0, NULL, HFILL }
10271                 },
10272
10273                 { &hf_smb2_negotiate_context_data_length,
10274                         { "DataLength", "smb2.negotiate_context.data_length", FT_UINT16, BASE_DEC,
10275                         NULL, 0, NULL, HFILL }
10276                 },
10277
10278                 { &hf_smb2_negotiate_context_offset,
10279                         { "NegotiateContextOffset", "smb2.negotiate_context.offset", FT_UINT16, BASE_HEX,
10280                         NULL, 0, NULL, HFILL }
10281                 },
10282
10283                 { &hf_smb2_negotiate_context_count,
10284                         { "NegotiateContextCount", "smb2.negotiate_context.count", FT_UINT16, BASE_DEC,
10285                         NULL, 0, NULL, HFILL }
10286                 },
10287
10288                 { &hf_smb2_hash_alg_count,
10289                         { "HashAlgorithmCount", "smb2.negotiate_context.hash_alg_count", FT_UINT16, BASE_DEC,
10290                         NULL, 0, NULL, HFILL }},
10291
10292                 { &hf_smb2_hash_algorithm,
10293                         { "HashAlgorithm", "smb2.negotiate_context.hash_algorithm", FT_UINT16, BASE_HEX,
10294                         VALS(smb2_hash_algorithm_types), 0, NULL, HFILL }},
10295
10296                 { &hf_smb2_salt_length,
10297                         { "SaltLength", "smb2.negotiate_context.salt_length", FT_UINT16, BASE_DEC,
10298                         NULL, 0, NULL, HFILL }},
10299
10300                 { &hf_smb2_salt,
10301                         { "Salt", "smb2.negotiate_context.salt", FT_BYTES, BASE_NONE,
10302                         NULL, 0, NULL, HFILL }},
10303
10304                 { &hf_smb2_cipher_count,
10305                         { "CipherCount", "smb2.negotiate_context.cipher_count", FT_UINT16, BASE_DEC,
10306                         NULL, 0, NULL, HFILL }},
10307
10308                 { &hf_smb2_cipher_id,
10309                         { "CipherId", "smb2.negotiate_context.cipher_id", FT_UINT16, BASE_HEX,
10310                         VALS(smb2_cipher_types), 0, NULL, HFILL }},
10311
10312                 { &hf_smb2_current_time,
10313                         { "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10314                         NULL, 0, "Current Time at server", HFILL }
10315                 },
10316
10317                 { &hf_smb2_boot_time,
10318                         { "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10319                         NULL, 0, "Boot Time at server", HFILL }
10320                 },
10321
10322                 { &hf_smb2_ea_flags,
10323                         { "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
10324                         NULL, 0, NULL, HFILL }
10325                 },
10326
10327                 { &hf_smb2_ea_name_len,
10328                         { "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
10329                         NULL, 0, NULL, HFILL }
10330                 },
10331
10332                 { &hf_smb2_ea_data_len,
10333                         { "EA Data Length", "smb2.ea.data_len", FT_UINT16, BASE_DEC,
10334                         NULL, 0, NULL, HFILL }
10335                 },
10336
10337                 { &hf_smb2_delete_pending,
10338                         { "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
10339                         NULL, 0, NULL, HFILL }
10340                 },
10341
10342                 { &hf_smb2_is_directory,
10343                         { "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
10344                         NULL, 0, "Is this a directory?", HFILL }
10345                 },
10346
10347                 { &hf_smb2_oplock,
10348                         { "Oplock", "smb2.create.oplock", FT_UINT8, BASE_HEX,
10349                         VALS(oplock_vals), 0, "Oplock type", HFILL }
10350                 },
10351
10352                 { &hf_smb2_close_flags,
10353                         { "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
10354                         NULL, 0, NULL, HFILL }
10355                 },
10356
10357                 { &hf_smb2_notify_flags,
10358                         { "Notify Flags", "smb2.notify.flags", FT_UINT16, BASE_HEX,
10359                         NULL, 0, NULL, HFILL }
10360                 },
10361
10362                 { &hf_smb2_buffer_code,
10363                         { "StructureSize", "smb2.buffer_code", FT_UINT16, BASE_HEX,
10364                         NULL, 0, NULL, HFILL }
10365                 },
10366
10367                 { &hf_smb2_buffer_code_len,
10368                         { "Fixed Part Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
10369                         NULL, 0xFFFE, "Length of fixed portion of PDU", HFILL }
10370                 },
10371
10372                 { &hf_smb2_olb_length,
10373                         { "Blob Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
10374                         NULL, 0, "Length of the buffer", HFILL }
10375                 },
10376
10377                 { &hf_smb2_olb_offset,
10378                         { "Blob Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
10379                         NULL, 0, "Offset to the buffer", HFILL }
10380                 },
10381
10382                 { &hf_smb2_buffer_code_flags_dyn,
10383                         { "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
10384                         NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }
10385                 },
10386
10387                 { &hf_smb2_ea_data,
10388                         { "EA Data", "smb2.ea.data", FT_BYTES, BASE_NONE,
10389                         NULL, 0, NULL, HFILL }
10390                 },
10391
10392                 { &hf_smb2_ea_name,
10393                         { "EA Name", "smb2.ea.name", FT_STRING, BASE_NONE,
10394                         NULL, 0, NULL, HFILL }
10395                 },
10396
10397                 { &hf_smb2_impersonation_level,
10398                         { "Impersonation level", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
10399                         VALS(impersonation_level_vals), 0, NULL, HFILL }
10400                 },
10401
10402                 { &hf_smb2_ioctl_function,
10403                         { "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
10404                         &smb2_ioctl_vals_ext, 0, "Ioctl function", HFILL }
10405                 },
10406
10407                 { &hf_smb2_ioctl_function_device,
10408                         { "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
10409                         &smb2_ioctl_device_vals_ext, 0xffff0000, "Device for Ioctl", HFILL }
10410                 },
10411
10412                 { &hf_smb2_ioctl_function_access,
10413                         { "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
10414                         VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }
10415                 },
10416
10417                 { &hf_smb2_ioctl_function_function,
10418                         { "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
10419                         NULL, 0x00003ffc, "Function for Ioctl", HFILL }
10420                 },
10421
10422                 { &hf_smb2_ioctl_function_method,
10423                         { "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
10424                         VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }
10425                 },
10426
10427                 { &hf_smb2_fsctl_pipe_wait_timeout,
10428                         { "Timeout", "smb2.fsctl.wait.timeout", FT_INT64, BASE_DEC,
10429                         NULL, 0, "Wait timeout", HFILL }
10430                 },
10431
10432                 { &hf_smb2_fsctl_pipe_wait_name,
10433                         { "Name", "smb2.fsctl.wait.name", FT_STRING, BASE_NONE,
10434                         NULL, 0, "Pipe name", HFILL }
10435                 },
10436
10437                 { &hf_smb2_fsctl_odx_token_type,
10438                         { "TokenType", "smb2.fsctl.odx.token.type", FT_UINT32, BASE_HEX,
10439                         NULL, 0, NULL, HFILL }
10440                 },
10441
10442                 { &hf_smb2_fsctl_odx_token_idlen,
10443                         { "TokenIdLength", "smb2.fsctl.odx.token.idlen", FT_UINT16, BASE_DEC,
10444                         NULL, 0, NULL, HFILL }
10445                 },
10446
10447                 { &hf_smb2_fsctl_odx_token_idraw,
10448                         { "TokenId", "smb2.fsctl.odx.token.id", FT_BYTES, BASE_NONE,
10449                         NULL, 0, "Token ID (opaque)", HFILL }
10450                 },
10451
10452                 { &hf_smb2_fsctl_odx_token_ttl,
10453                         { "TokenTimeToLive", "smb2.fsctl.odx.token_ttl", FT_UINT32, BASE_DEC,
10454                         NULL, 0, "TTL requested for the token (in milliseconds)", HFILL }
10455                 },
10456
10457                 { &hf_smb2_fsctl_odx_size,
10458                         { "Size", "smb2.fsctl.odx.size", FT_UINT32, BASE_DEC,
10459                         NULL, 0, "Size of this data element", HFILL }
10460                 },
10461
10462                 { &hf_smb2_fsctl_odx_flags,
10463                         { "Flags", "smb2.fsctl.odx.flags", FT_UINT32, BASE_HEX,
10464                         NULL, 0, "Flags for this operation", HFILL }
10465                 },
10466
10467                 { &hf_smb2_fsctl_odx_file_offset,
10468                         { "FileOffset", "smb2.fsctl.odx.file_offset", FT_UINT64, BASE_DEC,
10469                         NULL, 0, NULL, HFILL }
10470                 },
10471
10472                 { &hf_smb2_fsctl_odx_copy_length,
10473                         { "CopyLength", "smb2.fsctl.odx.copy_length", FT_UINT64, BASE_DEC,
10474                         NULL, 0, NULL, HFILL }
10475                 },
10476
10477                 { &hf_smb2_fsctl_odx_xfer_length,
10478                         { "TransferLength", "smb2.fsctl.odx.xfer_length", FT_UINT64, BASE_DEC,
10479                         NULL, 0, NULL, HFILL }
10480                 },
10481
10482                 { &hf_smb2_fsctl_odx_token_offset,
10483                         { "TokenOffset", "smb2.fsctl.odx.token_offset", FT_UINT64, BASE_DEC,
10484                         NULL, 0, "Token Offset (relative to start of token)", HFILL }
10485                 },
10486
10487                 { &hf_smb2_fsctl_sparse_flag,
10488                         { "SetSparse", "smb2.fsctl.set_sparse", FT_BOOLEAN, 8,
10489                         NULL, 0xFF, NULL, HFILL }
10490                 },
10491
10492                 { &hf_smb2_ioctl_resiliency_timeout,
10493                         { "Timeout", "smb2.ioctl.resiliency.timeout", FT_UINT32, BASE_DEC,
10494                         NULL, 0, "Resiliency timeout", HFILL }
10495                 },
10496
10497                 { &hf_smb2_ioctl_resiliency_reserved,
10498                         { "Reserved", "smb2.ioctl.resiliency.reserved", FT_UINT32, BASE_DEC,
10499                         NULL, 0, "Resiliency reserved", HFILL }
10500                 },
10501
10502                 { &hf_smb2_ioctl_shared_virtual_disk_support,
10503                         { "SharedVirtualDiskSupport", "smb2.ioctl.shared_virtual_disk.support", FT_UINT32, BASE_HEX,
10504                         VALS(smb2_ioctl_shared_virtual_disk_vals), 0, "Supported shared capabilities", HFILL }
10505                 },
10506
10507                 { &hf_smb2_ioctl_shared_virtual_disk_handle_state,
10508                         { "SharedVirtualDiskHandleState", "smb2.ioctl.shared_virtual_disk.handle_state", FT_UINT32, BASE_HEX,
10509                         VALS(smb2_ioctl_shared_virtual_disk_hstate_vals), 0, NULL, HFILL }
10510                 },
10511
10512                 { &hf_smb2_ioctl_sqos_protocol_version,
10513                         { "ProtocolVersion", "smb2.ioctl.sqos.protocol_version", FT_UINT16, BASE_HEX,
10514                         VALS(smb2_ioctl_sqos_protocol_version_vals), 0, NULL, HFILL }
10515                 },
10516
10517                 { &hf_smb2_ioctl_sqos_reserved,
10518                         { "Reserved", "smb2.ioctl.sqos.reserved", FT_UINT16, BASE_DEC,
10519                         NULL, 0, NULL, HFILL }
10520                 },
10521
10522                 { &hf_smb2_ioctl_sqos_options,
10523                         { "Operations", "smb2.ioctl.sqos.operations", FT_UINT32, BASE_HEX,
10524                         NULL, 0, "SQOS operations", HFILL }
10525                 },
10526
10527                 { &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
10528                         { "Set Logical Flow ID", "smb2.ioctl.sqos.operations.set_logical_flow_id", FT_BOOLEAN, 32,
10529                         NULL, STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID, "Whether Set Logical Flow ID operation is performed", HFILL }
10530                 },
10531
10532                 { &hf_smb2_ioctl_sqos_op_set_policy,
10533                         { "Set Policy", "smb2.ioctl.sqos.operations.set_policy", FT_BOOLEAN, 32,
10534                         NULL, STORAGE_QOS_CONTROL_FLAG_SET_POLICY, "Whether Set Policy operation is performed", HFILL }
10535                 },
10536
10537                 { &hf_smb2_ioctl_sqos_op_probe_policy,
10538                         { "Probe Policy", "smb2.ioctl.sqos.operations.probe_policy", FT_BOOLEAN, 32,
10539                         NULL, STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY, "Whether Probe Policy operation is performed", HFILL }
10540                 },
10541
10542                 { &hf_smb2_ioctl_sqos_op_get_status,
10543                         { "Get Status", "smb2.ioctl.sqos.operations.get_status", FT_BOOLEAN, 32,
10544                         NULL, STORAGE_QOS_CONTROL_FLAG_GET_STATUS, "Whether Get Status operation is performed", HFILL }
10545                 },
10546
10547                 { &hf_smb2_ioctl_sqos_op_update_counters,
10548                         { "Update Counters", "smb2.ioctl.sqos.operations.update_counters", FT_BOOLEAN, 32,
10549                         NULL, STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS, "Whether Update Counters operation is performed", HFILL }
10550                 },
10551
10552                 { &hf_smb2_ioctl_sqos_logical_flow_id,
10553                         { "LogicalFlowID", "smb2.ioctl.sqos.logical_flow_id", FT_GUID, BASE_NONE,
10554                         NULL, 0, NULL, HFILL }
10555                 },
10556
10557                 { &hf_smb2_ioctl_sqos_policy_id,
10558                         { "PolicyID", "smb2.ioctl.sqos.policy_id", FT_GUID, BASE_NONE,
10559                         NULL, 0, NULL, HFILL }
10560                 },
10561
10562                 { &hf_smb2_ioctl_sqos_initiator_id,
10563                         { "InitiatorID", "smb2.ioctl.sqos.initiator_id", FT_GUID, BASE_NONE,
10564                         NULL, 0, NULL, HFILL }
10565                 },
10566
10567                 { &hf_smb2_ioctl_sqos_limit,
10568                         { "Limit", "smb2.ioctl.sqos.limit", FT_UINT64, BASE_DEC,
10569                         NULL, 0, "Desired maximum throughput for the logical flow, in normalized IOPS", HFILL }
10570                 },
10571
10572                 { &hf_smb2_ioctl_sqos_reservation,
10573                         { "Reservation", "smb2.ioctl.sqos.reservation", FT_UINT64, BASE_DEC,
10574                         NULL, 0, "Desired minimum throughput for the logical flow, in normalized 8KB IOPS", HFILL }
10575                 },
10576
10577                 { &hf_smb2_ioctl_sqos_initiator_name,
10578                         { "InitiatorName", "smb2.ioctl.sqos.initiator_name", FT_STRING, BASE_NONE,
10579                         NULL, 0x0, NULL, HFILL }
10580                 },
10581
10582                 { &hf_smb2_ioctl_sqos_initiator_node_name,
10583                         { "InitiatorNodeName", "smb2.ioctl.sqos.initiator_node_name", FT_STRING, BASE_NONE,
10584                         NULL, 0x0, NULL, HFILL }
10585                 },
10586
10587                 { &hf_smb2_ioctl_sqos_io_count_increment,
10588                         { "IoCountIncrement", "smb2.ioctl.sqos.io_count_increment", FT_UINT64, BASE_DEC,
10589                         NULL, 0, "The total number of I/O requests issued by the initiator on the logical flow", HFILL }
10590                 },
10591
10592                 { &hf_smb2_ioctl_sqos_normalized_io_count_increment,
10593                         { "NormalizedIoCountIncrement", "smb2.ioctl.sqos.normalized_io_count_increment", FT_UINT64, BASE_DEC,
10594                         NULL, 0, "The total number of normalized 8-KB I/O requests issued by the initiator on the logical flow", HFILL }
10595                 },
10596
10597                 { &hf_smb2_ioctl_sqos_latency_increment,
10598                         { "LatencyIncrement", "smb2.ioctl.sqos.latency_increment", FT_UINT64, BASE_DEC,
10599                         NULL, 0, "The total latency (including initiator's queues delays) measured by the initiator", HFILL }
10600                 },
10601
10602                 { &hf_smb2_ioctl_sqos_lower_latency_increment,
10603                         { "LowerLatencyIncrement", "smb2.ioctl.sqos.lower_latency_increment", FT_UINT64, BASE_DEC,
10604                         NULL, 0, "The total latency (excluding initiator's queues delays) measured by the initiator", HFILL }
10605                 },
10606
10607                 { &hf_smb2_ioctl_sqos_bandwidth_limit,
10608                         { "BandwidthLimit", "smb2.ioctl.sqos.bandwidth_limit", FT_UINT64, BASE_DEC,
10609                         NULL, 0, "Desired maximum bandwidth for the logical flow, in kilobytes per second", HFILL }
10610                 },
10611
10612                 { &hf_smb2_ioctl_sqos_kilobyte_count_increment,
10613                         { "KilobyteCountIncrement", "smb2.ioctl.sqos.kilobyte_count_increment", FT_UINT64, BASE_DEC,
10614                         NULL, 0, "The total data transfer length of all I/O requests, in kilobyte units, issued by the initiator on the logical flow", HFILL }
10615                 },
10616
10617                 { &hf_smb2_ioctl_sqos_time_to_live,
10618                         { "TimeToLive", "smb2.ioctl.sqos.time_to_live", FT_UINT32, BASE_DEC,
10619                         NULL, 0, "The expected period of validity of the Status, MaximumIoRate and MinimumIoRate fields, expressed in milliseconds", HFILL }
10620                 },
10621
10622                 { &hf_smb2_ioctl_sqos_status,
10623                         { "Status", "smb2.ioctl.sqos.status", FT_UINT32, BASE_HEX,
10624                         VALS(smb2_ioctl_sqos_status_vals), 0, "The current status of the logical flow", HFILL }
10625                 },
10626
10627                 { &hf_smb2_ioctl_sqos_maximum_io_rate,
10628                         { "MaximumIoRate", "smb2.ioctl.sqos.maximum_io_rate", FT_UINT64, BASE_DEC,
10629                         NULL, 0, "The maximum I/O initiation rate currently assigned to the logical flow, expressed in normalized input/output operations per second (normalized IOPS)", HFILL }
10630                 },
10631
10632                 { &hf_smb2_ioctl_sqos_minimum_io_rate,
10633                         { "MinimumIoRate", "smb2.ioctl.sqos.minimum_io_rate", FT_UINT64, BASE_DEC,
10634                         NULL, 0, "The minimum I/O completion rate currently assigned to the logical flow, expressed in normalized IOPS", HFILL }
10635                 },
10636
10637                 { &hf_smb2_ioctl_sqos_base_io_size,
10638                         { "BaseIoSize", "smb2.ioctl.sqos.base_io_size", FT_UINT32, BASE_DEC,
10639                         NULL, 0, "The base I/O size used to compute the normalized size of an I/O request for the logical flow", HFILL }
10640                 },
10641
10642                 { &hf_smb2_ioctl_sqos_reserved2,
10643                         { "Reserved", "smb2.ioctl.sqos.reserved2", FT_UINT32, BASE_DEC,
10644                         NULL, 0, NULL, HFILL }
10645                 },
10646
10647                 { &hf_smb2_ioctl_sqos_maximum_bandwidth,
10648                         { "MaximumBandwidth", "smb2.ioctl.sqos.maximum_bandwidth", FT_UINT64, BASE_DEC,
10649                         NULL, 0, "The maximum bandwidth currently assigned to the logical flow, expressed in kilobytes per second", HFILL }
10650                 },
10651
10652
10653                 { &hf_windows_sockaddr_family,
10654                         { "Socket Family", "smb2.windows.sockaddr.family", FT_UINT16, BASE_DEC,
10655                         NULL, 0, "The socket address family (on windows)", HFILL }
10656                 },
10657
10658                 { &hf_windows_sockaddr_port,
10659                         { "Socket Port", "smb2.windows.sockaddr.port", FT_UINT16, BASE_DEC,
10660                         NULL, 0, "The socket address port", HFILL }
10661                 },
10662
10663                 { &hf_windows_sockaddr_in_addr,
10664                         { "Socket IPv4", "smb2.windows.sockaddr.in.addr", FT_IPv4, BASE_NONE,
10665                         NULL, 0, "The IPv4 address", HFILL }
10666                 },
10667
10668                 { &hf_windows_sockaddr_in6_flowinfo,
10669                         { "IPv6 Flow Info", "smb2.windows.sockaddr.in6.flow_info", FT_UINT32, BASE_HEX,
10670                         NULL, 0, "The socket IPv6 flow info", HFILL }
10671                 },
10672
10673                 { &hf_windows_sockaddr_in6_addr,
10674                         { "Socket IPv6", "smb2.windows.sockaddr.in6.addr", FT_IPv6, BASE_NONE,
10675                         NULL, 0, "The IPv6 address", HFILL }
10676                 },
10677
10678                 { &hf_windows_sockaddr_in6_scope_id,
10679                         { "IPv6 Scope ID", "smb2.windows.sockaddr.in6.scope_id", FT_UINT32, BASE_DEC,
10680                         NULL, 0, "The socket IPv6 scope id", HFILL }
10681                 },
10682
10683                 { &hf_smb2_ioctl_network_interface_next_offset,
10684                         { "Next Offset", "smb2.ioctl.network_interfaces.next_offset", FT_UINT32, BASE_HEX,
10685                         NULL, 0, "Offset to next entry in chain or 0", HFILL }
10686                 },
10687
10688                 { &hf_smb2_ioctl_network_interface_index,
10689                         { "Interface Index", "smb2.ioctl.network_interfaces.index", FT_UINT32, BASE_DEC,
10690                         NULL, 0, "The index of the interface", HFILL }
10691                 },
10692
10693                 { &hf_smb2_ioctl_network_interface_rss_queue_count,
10694                         { "RSS Queue Count", "smb2.ioctl.network_interfaces.rss_queue_count", FT_UINT32, BASE_DEC,
10695                         NULL, 0, "The RSS queue count", HFILL }
10696                 },
10697
10698                 { &hf_smb2_ioctl_network_interface_capabilities,
10699                         { "Interface Cababilities", "smb2.ioctl.network_interfaces.capabilities", FT_UINT32, BASE_HEX,
10700                         NULL, 0, "The RSS queue count", HFILL }
10701                 },
10702
10703                 { &hf_smb2_ioctl_network_interface_capability_rss,
10704                         { "RSS", "smb2.ioctl.network_interfaces.capabilities.rss", FT_BOOLEAN, 32,
10705                         TFS(&tfs_smb2_ioctl_network_interface_capability_rss), NETWORK_INTERFACE_CAP_RSS, "If the host supports RSS", HFILL }
10706                 },
10707
10708                 { &hf_smb2_ioctl_network_interface_capability_rdma,
10709                         { "RDMA", "smb2.ioctl.network_interfaces.capabilities.rdma", FT_BOOLEAN, 32,
10710                         TFS(&tfs_smb2_ioctl_network_interface_capability_rdma), NETWORK_INTERFACE_CAP_RDMA, "If the host supports RDMA", HFILL }
10711                 },
10712
10713                 { &hf_smb2_ioctl_network_interface_link_speed,
10714                         { "Link Speed", "smb2.ioctl.network_interfaces.link_speed", FT_UINT64, BASE_DEC,
10715                         NULL, 0, "The link speed of the interface", HFILL }
10716                 },
10717
10718                 { &hf_smb2_ioctl_shadow_copy_num_volumes,
10719                         { "Num Volumes", "smb2.ioctl.shadow_copy.num_volumes", FT_UINT32, BASE_DEC,
10720                         NULL, 0, "Number of shadow copy volumes", HFILL }
10721                 },
10722
10723                 { &hf_smb2_ioctl_shadow_copy_num_labels,
10724                         { "Num Labels", "smb2.ioctl.shadow_copy.num_labels", FT_UINT32, BASE_DEC,
10725                         NULL, 0, "Number of shadow copy labels", HFILL }
10726                 },
10727
10728                 { &hf_smb2_ioctl_shadow_copy_label,
10729                         { "Label", "smb2.ioctl.shadow_copy.label", FT_STRING, BASE_NONE,
10730                         NULL, 0, "Shadow copy label", HFILL }
10731                 },
10732
10733                 { &hf_smb2_compression_format,
10734                         { "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
10735                         VALS(compression_format_vals), 0, NULL, HFILL }
10736                 },
10737
10738                 { &hf_smb2_checksum_algorithm,
10739                         { "Checksum Algorithm", "smb2.checksum_algorithm", FT_UINT16, BASE_HEX,
10740                         VALS(checksum_algorithm_vals), 0, NULL, HFILL }
10741                 },
10742
10743                 { &hf_smb2_integrity_reserved,
10744                         { "Reserved", "smb2.integrity_reserved", FT_UINT16, BASE_DEC,
10745                         NULL, 0, NULL, HFILL }
10746                 },
10747
10748                 { &hf_smb2_integrity_flags,
10749                         { "Flags", "smb2.integrity_flags", FT_UINT32, BASE_HEX,
10750                         NULL, 0, NULL, HFILL }
10751                 },
10752
10753                 { &hf_smb2_integrity_flags_enforcement_off,
10754                         { "FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF", "smb2.integrity_flags_enforcement", FT_BOOLEAN, 32,
10755                         NULL, 0x1, "If checksum error enforcement is off", HFILL }
10756                 },
10757
10758                 { &hf_smb2_share_type,
10759                         { "Share Type", "smb2.share_type", FT_UINT8, BASE_HEX,
10760                         VALS(smb2_share_type_vals), 0, "Type of share", HFILL }
10761                 },
10762
10763                 { &hf_smb2_credit_charge,
10764                         { "Credit Charge", "smb2.credit.charge", FT_UINT16, BASE_DEC,
10765                         NULL, 0, NULL, HFILL }
10766                 },
10767
10768                 { &hf_smb2_credits_requested,
10769                         { "Credits requested", "smb2.credits.requested", FT_UINT16, BASE_DEC,
10770                         NULL, 0, NULL, HFILL }
10771                 },
10772
10773                 { &hf_smb2_credits_granted,
10774                         { "Credits granted", "smb2.credits.granted", FT_UINT16, BASE_DEC,
10775                         NULL, 0, NULL, HFILL }
10776                 },
10777
10778                 { &hf_smb2_channel_sequence,
10779                         { "Channel Sequence", "smb2.channel_sequence", FT_UINT16, BASE_DEC,
10780                         NULL, 0, NULL, HFILL }
10781                 },
10782
10783                 { &hf_smb2_dialect_count,
10784                         { "Dialect count", "smb2.dialect_count", FT_UINT16, BASE_DEC,
10785                         NULL, 0, NULL, HFILL }
10786                 },
10787
10788                 { &hf_smb2_dialect,
10789                         { "Dialect", "smb2.dialect", FT_UINT16, BASE_HEX,
10790                         NULL, 0, NULL, HFILL }
10791                 },
10792
10793                 { &hf_smb2_security_mode,
10794                         { "Security mode", "smb2.sec_mode", FT_UINT8, BASE_HEX,
10795                         NULL, 0, NULL, HFILL }
10796                 },
10797
10798                 { &hf_smb2_session_flags,
10799                         { "Session Flags", "smb2.session_flags", FT_UINT16, BASE_HEX,
10800                         NULL, 0, NULL, HFILL }
10801                 },
10802
10803                 { &hf_smb2_lock_count,
10804                         { "Lock Count", "smb2.lock_count", FT_UINT16, BASE_DEC,
10805                         NULL, 0, NULL, HFILL }
10806                 },
10807
10808                 { &hf_smb2_capabilities,
10809                         { "Capabilities", "smb2.capabilities", FT_UINT32, BASE_HEX,
10810                         NULL, 0, NULL, HFILL }
10811                 },
10812
10813                 { &hf_smb2_ioctl_shadow_copy_count,
10814                         { "Count", "smb2.ioctl.shadow_copy.count", FT_UINT32, BASE_DEC,
10815                         NULL, 0, "Number of bytes for shadow copy label strings", HFILL }
10816                 },
10817
10818                 { &hf_smb2_auth_frame,
10819                         { "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
10820                         NULL, 0, "Which frame this user was authenticated in", HFILL }
10821                 },
10822
10823                 { &hf_smb2_tcon_frame,
10824                         { "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
10825                         NULL, 0, "Which frame this share was connected in", HFILL }
10826                 },
10827
10828                 { &hf_smb2_tag,
10829                         { "Tag", "smb2.tag", FT_STRING, BASE_NONE,
10830                         NULL, 0, "Tag of chain entry", HFILL }
10831                 },
10832
10833                 { &hf_smb2_acct_name,
10834                         { "Account", "smb2.acct", FT_STRING, BASE_NONE,
10835                         NULL, 0, "Account Name", HFILL }
10836                 },
10837
10838                 { &hf_smb2_domain_name,
10839                         { "Domain", "smb2.domain", FT_STRING, BASE_NONE,
10840                         NULL, 0, "Domain Name", HFILL }
10841                 },
10842
10843                 { &hf_smb2_host_name,
10844                         { "Host", "smb2.host", FT_STRING, BASE_NONE,
10845                         NULL, 0, "Host Name", HFILL }
10846                 },
10847
10848                 { &hf_smb2_signature,
10849                         { "Signature", "smb2.signature", FT_BYTES, BASE_NONE,
10850                         NULL, 0, NULL, HFILL }
10851                 },
10852
10853                 { &hf_smb2_unknown,
10854                         { "Unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
10855                         NULL, 0, NULL, HFILL }
10856                 },
10857
10858                 { &hf_smb2_twrp_timestamp,
10859                         { "Timestamp", "smb2.twrp_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10860                         NULL, 0, "TWrp timestamp", HFILL }
10861                 },
10862
10863                 { &hf_smb2_mxac_timestamp,
10864                         { "Timestamp", "smb2.mxac_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10865                         NULL, 0, "MxAc timestamp", HFILL }
10866                 },
10867
10868                 { &hf_smb2_mxac_status,
10869                         { "Query Status", "smb2.mxac_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
10870                         &NT_errors_ext, 0, "NT Status code", HFILL }
10871                 },
10872
10873                 { &hf_smb2_qfid_fid,
10874                         { "Opaque File ID", "smb2.qfid_fid", FT_BYTES, BASE_NONE,
10875                         NULL, 0, NULL, HFILL }
10876                 },
10877
10878                 { &hf_smb2_ses_flags_guest,
10879                         { "Guest", "smb2.ses_flags.guest", FT_BOOLEAN, 16,
10880                         NULL, SES_FLAGS_GUEST, NULL, HFILL }
10881                 },
10882
10883                 { &hf_smb2_ses_flags_null,
10884                         { "Null", "smb2.ses_flags.null", FT_BOOLEAN, 16,
10885                         NULL, SES_FLAGS_NULL, NULL, HFILL }
10886                 },
10887
10888                 { &hf_smb2_ses_flags_encrypt,
10889                         { "Encrypt", "smb2.ses_flags.encrypt", FT_BOOLEAN, 16,
10890                         NULL, SES_FLAGS_ENCRYPT, NULL, HFILL }},
10891
10892                 { &hf_smb2_secmode_flags_sign_required,
10893                         { "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
10894                         NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }
10895                 },
10896
10897                 { &hf_smb2_secmode_flags_sign_enabled,
10898                         { "Signing enabled", "smb2.sec_mode.sign_enabled", FT_BOOLEAN, 8,
10899                         NULL, NEGPROT_SIGN_ENABLED, "Is signing enabled", HFILL }
10900                 },
10901
10902                 { &hf_smb2_ses_req_flags,
10903                         { "Flags", "smb2.ses_req_flags", FT_UINT8, BASE_DEC,
10904                         NULL, 0, NULL, HFILL }
10905                 },
10906
10907                 { &hf_smb2_ses_req_flags_session_binding,
10908                         { "Session Binding Request", "smb2.ses_req_flags.session_binding", FT_BOOLEAN, 8,
10909                         NULL, SES_REQ_FLAGS_SESSION_BINDING, "The client wants to bind to an existing session", HFILL }
10910                 },
10911
10912                 { &hf_smb2_cap_dfs,
10913                         { "DFS", "smb2.capabilities.dfs", FT_BOOLEAN, 32,
10914                         TFS(&tfs_cap_dfs), NEGPROT_CAP_DFS, "If the host supports dfs", HFILL }
10915                 },
10916
10917                 { &hf_smb2_cap_leasing,
10918                         { "LEASING", "smb2.capabilities.leasing", FT_BOOLEAN, 32,
10919                         TFS(&tfs_cap_leasing), NEGPROT_CAP_LEASING, "If the host supports leasing", HFILL }
10920                 },
10921
10922                 { &hf_smb2_cap_large_mtu,
10923                         { "LARGE MTU", "smb2.capabilities.large_mtu", FT_BOOLEAN, 32,
10924                         TFS(&tfs_cap_large_mtu), NEGPROT_CAP_LARGE_MTU, "If the host supports LARGE MTU", HFILL }
10925                 },
10926
10927                 { &hf_smb2_cap_multi_channel,
10928                         { "MULTI CHANNEL", "smb2.capabilities.multi_channel", FT_BOOLEAN, 32,
10929                         TFS(&tfs_cap_multi_channel), NEGPROT_CAP_MULTI_CHANNEL, "If the host supports MULTI CHANNEL", HFILL }
10930                 },
10931
10932                 { &hf_smb2_cap_persistent_handles,
10933                         { "PERSISTENT HANDLES", "smb2.capabilities.persistent_handles", FT_BOOLEAN, 32,
10934                         TFS(&tfs_cap_persistent_handles), NEGPROT_CAP_PERSISTENT_HANDLES, "If the host supports PERSISTENT HANDLES", HFILL }
10935                 },
10936
10937                 { &hf_smb2_cap_directory_leasing,
10938                         { "DIRECTORY LEASING", "smb2.capabilities.directory_leasing", FT_BOOLEAN, 32,
10939                         TFS(&tfs_cap_directory_leasing), NEGPROT_CAP_DIRECTORY_LEASING, "If the host supports DIRECTORY LEASING", HFILL }
10940                 },
10941
10942                 { &hf_smb2_cap_encryption,
10943                         { "ENCRYPTION", "smb2.capabilities.encryption", FT_BOOLEAN, 32,
10944                         TFS(&tfs_cap_encryption), NEGPROT_CAP_ENCRYPTION, "If the host supports ENCRYPTION", HFILL }
10945                 },
10946
10947                 { &hf_smb2_max_trans_size,
10948                         { "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
10949                         NULL, 0, NULL, HFILL }
10950                 },
10951
10952                 { &hf_smb2_max_read_size,
10953                         { "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
10954                         NULL, 0, NULL, HFILL }
10955                 },
10956
10957                 { &hf_smb2_max_write_size,
10958                         { "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
10959                         NULL, 0, NULL, HFILL }
10960                 },
10961
10962                 { &hf_smb2_channel,
10963                         { "Channel", "smb2.channel", FT_UINT32, BASE_HEX,
10964                         VALS(smb2_channel_vals), 0, NULL, HFILL }
10965                 },
10966
10967                 { &hf_smb2_rdma_v1_offset,
10968                         { "Offset", "smb2.buffer_descriptor.offset", FT_UINT64, BASE_DEC,
10969                         NULL, 0, NULL, HFILL }
10970                 },
10971
10972                 { &hf_smb2_rdma_v1_token,
10973                         { "Token", "smb2.buffer_descriptor.token", FT_UINT32, BASE_HEX,
10974                         NULL, 0, NULL, HFILL }
10975                 },
10976
10977                 { &hf_smb2_rdma_v1_length,
10978                         { "Length", "smb2.buffer_descriptor.length", FT_UINT32, BASE_DEC,
10979                         NULL, 0, NULL, HFILL }
10980                 },
10981
10982                 { &hf_smb2_share_flags,
10983                         { "Share flags", "smb2.share_flags", FT_UINT32, BASE_HEX,
10984                         NULL, 0, NULL, HFILL }
10985                 },
10986
10987                 { &hf_smb2_share_flags_dfs,
10988                         { "DFS", "smb2.share_flags.dfs", FT_BOOLEAN, 32,
10989                         NULL, SHARE_FLAGS_dfs, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }
10990                 },
10991
10992                 { &hf_smb2_share_flags_dfs_root,
10993                         { "DFS root", "smb2.share_flags.dfs_root", FT_BOOLEAN, 32,
10994                         NULL, SHARE_FLAGS_dfs_root, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }
10995                 },
10996
10997                 { &hf_smb2_share_flags_restrict_exclusive_opens,
10998                         { "Restrict exclusive opens", "smb2.share_flags.restrict_exclusive_opens", FT_BOOLEAN, 32,
10999                         NULL, SHARE_FLAGS_restrict_exclusive_opens, "The specified share disallows exclusive file opens that deny reads to an open file", HFILL }
11000                 },
11001
11002                 { &hf_smb2_share_flags_force_shared_delete,
11003                         { "Force shared delete", "smb2.share_flags.force_shared_delete", FT_BOOLEAN, 32,
11004                         NULL, SHARE_FLAGS_force_shared_delete, "Shared files in the specified share can be forcibly deleted", HFILL }
11005                 },
11006
11007                 { &hf_smb2_share_flags_allow_namespace_caching,
11008                         { "Allow namepsace caching", "smb2.share_flags.allow_namespace_caching", FT_BOOLEAN, 32,
11009                         NULL, SHARE_FLAGS_allow_namespace_caching, "Clients are allowed to cache the namespace of the specified share", HFILL }
11010                 },
11011
11012                 { &hf_smb2_share_flags_access_based_dir_enum,
11013                         { "Access based directory enum", "smb2.share_flags.access_based_dir_enum", FT_BOOLEAN, 32,
11014                         NULL, SHARE_FLAGS_access_based_dir_enum, "The server will filter directory entries based on the access permissions of the client", HFILL }
11015                 },
11016
11017                 { &hf_smb2_share_flags_force_levelii_oplock,
11018                         { "Force level II oplock", "smb2.share_flags.force_levelii_oplock", FT_BOOLEAN, 32,
11019                         NULL, SHARE_FLAGS_force_levelii_oplock, "The server will not issue exclusive caching rights on this share", HFILL }
11020                 },
11021
11022                 { &hf_smb2_share_flags_enable_hash_v1,
11023                         { "Enable hash V1", "smb2.share_flags.enable_hash_v1", FT_BOOLEAN, 32,
11024                         NULL, SHARE_FLAGS_enable_hash_v1, "The share supports hash generation V1 for branch cache retrieval of data (see also section 2.2.31.2 of MS-SMB2)", HFILL }
11025                 },
11026
11027                 { &hf_smb2_share_flags_enable_hash_v2,
11028                         { "Enable hash V2", "smb2.share_flags.enable_hash_v2", FT_BOOLEAN, 32,
11029                         NULL, SHARE_FLAGS_enable_hash_v2, "The share supports hash generation V2 for branch cache retrieval of data (see also section 2.2.31.2 of MS-SMB2)", HFILL }
11030                 },
11031
11032                 { &hf_smb2_share_flags_encrypt_data,
11033                         { "Encrypted data required", "smb2.share_flags.encrypt_data", FT_BOOLEAN, 32,
11034                         NULL, SHARE_FLAGS_encryption_required, "The share require data encryption", HFILL }
11035                 },
11036
11037                 { &hf_smb2_share_caching,
11038                         { "Caching policy", "smb2.share.caching", FT_UINT32, BASE_HEX,
11039                         VALS(share_cache_vals), 0, NULL, HFILL }
11040                 },
11041
11042                 { &hf_smb2_share_caps,
11043                         { "Share Capabilities", "smb2.share_caps", FT_UINT32, BASE_HEX,
11044                         NULL, 0, NULL, HFILL }
11045                 },
11046
11047                 { &hf_smb2_share_caps_dfs,
11048                         { "DFS", "smb2.share_caps.dfs", FT_BOOLEAN, 32,
11049                         NULL, SHARE_CAPS_DFS, "The specified share is present in a DFS tree structure", HFILL }
11050                 },
11051
11052                 { &hf_smb2_share_caps_continuous_availability,
11053                         { "CONTINUOUS AVAILABILITY", "smb2.share_caps.continuous_availability", FT_BOOLEAN, 32,
11054                         NULL, SHARE_CAPS_CONTINUOUS_AVAILABILITY, "The specified share is continuously available", HFILL }
11055                 },
11056
11057                 { &hf_smb2_share_caps_scaleout,
11058                         { "SCALEOUT", "smb2.share_caps.scaleout", FT_BOOLEAN, 32,
11059                         NULL, SHARE_CAPS_SCALEOUT, "The specified share is a scaleout share", HFILL }
11060                 },
11061
11062                 { &hf_smb2_share_caps_cluster,
11063                         { "CLUSTER", "smb2.share_caps.cluster", FT_BOOLEAN, 32,
11064                         NULL, SHARE_CAPS_CLUSTER, "The specified share is a cluster share", HFILL }
11065                 },
11066
11067                 { &hf_smb2_ioctl_flags,
11068                         { "Flags", "smb2.ioctl.flags", FT_UINT32, BASE_HEX,
11069                         NULL, 0, NULL, HFILL }
11070                 },
11071
11072                 { &hf_smb2_min_count,
11073                         { "Min Count", "smb2.min_count", FT_UINT32, BASE_DEC,
11074                         NULL, 0, NULL, HFILL }
11075                 },
11076
11077                 { &hf_smb2_remaining_bytes,
11078                         { "Remaining Bytes", "smb2.remaining_bytes", FT_UINT32, BASE_DEC,
11079                         NULL, 0, NULL, HFILL }
11080                 },
11081
11082                 { &hf_smb2_channel_info_offset,
11083                         { "Channel Info Offset", "smb2.channel_info_offset", FT_UINT16, BASE_DEC,
11084                         NULL, 0, NULL, HFILL }
11085                 },
11086
11087                 { &hf_smb2_channel_info_length,
11088                         { "Channel Info Length", "smb2.channel_info_length", FT_UINT16, BASE_DEC,
11089                         NULL, 0, NULL, HFILL }
11090                 },
11091
11092                 { &hf_smb2_channel_info_blob,
11093                         { "Channel Info Blob", "smb2.channel_info_blob", FT_NONE, BASE_NONE,
11094                         NULL, 0, NULL, HFILL }
11095                 },
11096
11097                 { &hf_smb2_ioctl_is_fsctl,
11098                         { "Is FSCTL", "smb2.ioctl.is_fsctl", FT_BOOLEAN, 32,
11099                         NULL, 0x00000001, NULL, HFILL }
11100                 },
11101
11102                 { &hf_smb2_output_buffer_len,
11103                         { "Output Buffer Length", "smb2.output_buffer_len", FT_UINT16, BASE_DEC,
11104                         NULL, 0, NULL, HFILL }
11105                 },
11106
11107                 { &hf_smb2_close_pq_attrib,
11108                         { "PostQuery Attrib", "smb2.close.pq_attrib", FT_BOOLEAN, 16,
11109                         NULL, 0x0001, NULL, HFILL }
11110                 },
11111
11112                 { &hf_smb2_notify_watch_tree,
11113                         { "Watch Tree", "smb2.notify.watch_tree", FT_BOOLEAN, 16,
11114                         NULL, 0x0001, NULL, HFILL }
11115                 },
11116
11117                 { &hf_smb2_notify_out_data,
11118                         { "Out Data", "smb2.notify.out", FT_NONE, BASE_NONE,
11119                         NULL, 0, NULL, HFILL }
11120                 },
11121
11122                 { &hf_smb2_notify_info,
11123                         { "Notify Info", "smb2.notify.info", FT_NONE, BASE_NONE,
11124                         NULL, 0, NULL, HFILL }
11125                 },
11126
11127                 { &hf_smb2_notify_next_offset,
11128                         { "Next Offset", "smb2.notify.next_offset", FT_UINT32, BASE_HEX,
11129                         NULL, 0, "Offset to next entry in chain or 0", HFILL }
11130                 },
11131
11132                 { &hf_smb2_notify_action,
11133                         { "Action", "smb2.notify.action", FT_UINT32, BASE_HEX,
11134                         VALS(notify_action_vals), 0, "Notify Action", HFILL }
11135                 },
11136
11137
11138                 { &hf_smb2_find_flags_restart_scans,
11139                         { "Restart Scans", "smb2.find.restart_scans", FT_BOOLEAN, 8,
11140                         NULL, SMB2_FIND_FLAG_RESTART_SCANS, NULL, HFILL }
11141                 },
11142
11143                 { &hf_smb2_find_flags_single_entry,
11144                         { "Single Entry", "smb2.find.single_entry", FT_BOOLEAN, 8,
11145                         NULL, SMB2_FIND_FLAG_SINGLE_ENTRY, NULL, HFILL }
11146                 },
11147
11148                 { &hf_smb2_find_flags_index_specified,
11149                         { "Index Specified", "smb2.find.index_specified", FT_BOOLEAN, 8,
11150                         NULL, SMB2_FIND_FLAG_INDEX_SPECIFIED, NULL, HFILL }
11151                 },
11152
11153                 { &hf_smb2_find_flags_reopen,
11154                         { "Reopen", "smb2.find.reopen", FT_BOOLEAN, 8,
11155                         NULL, SMB2_FIND_FLAG_REOPEN, NULL, HFILL }
11156                 },
11157
11158                 { &hf_smb2_file_index,
11159                         { "File Index", "smb2.file_index", FT_UINT32, BASE_HEX,
11160                         NULL, 0, NULL, HFILL }
11161                 },
11162
11163                 { &hf_smb2_file_directory_info,
11164                         { "FileDirectoryInfo", "smb2.find.file_directory_info", FT_NONE, BASE_NONE,
11165                         NULL, 0, NULL, HFILL }
11166                 },
11167
11168                 { &hf_smb2_full_directory_info,
11169                         { "FullDirectoryInfo", "smb2.find.full_directory_info", FT_NONE, BASE_NONE,
11170                         NULL, 0, NULL, HFILL }
11171                 },
11172
11173                 { &hf_smb2_both_directory_info,
11174                         { "FileBothDirectoryInfo", "smb2.find.both_directory_info", FT_NONE, BASE_NONE,
11175                         NULL, 0, NULL, HFILL }
11176                 },
11177
11178                 { &hf_smb2_id_both_directory_info,
11179                         { "FileIdBothDirectoryInfo", "smb2.find.id_both_directory_info", FT_NONE, BASE_NONE,
11180                         NULL, 0, NULL, HFILL }
11181                 },
11182
11183                 { &hf_smb2_short_name_len,
11184                         { "Short Name Length", "smb2.short_name_len", FT_UINT8, BASE_DEC,
11185                         NULL, 0, NULL, HFILL }
11186                 },
11187
11188                 { &hf_smb2_short_name,
11189                         { "Short Name", "smb2.shortname", FT_STRING, BASE_NONE,
11190                         NULL, 0, NULL, HFILL }
11191                 },
11192
11193                 { &hf_smb2_lock_info,
11194                         { "Lock Info", "smb2.lock_info", FT_NONE, BASE_NONE,
11195                         NULL, 0, NULL, HFILL }
11196                 },
11197
11198                 { &hf_smb2_lock_length,
11199                         { "Length", "smb2.lock_length", FT_UINT64, BASE_DEC,
11200                         NULL, 0, NULL, HFILL }
11201                 },
11202
11203                 { &hf_smb2_lock_flags,
11204                         { "Flags", "smb2.lock_flags", FT_UINT32, BASE_HEX,
11205                         NULL, 0, NULL, HFILL }
11206                 },
11207
11208                 { &hf_smb2_lock_flags_shared,
11209                         { "Shared", "smb2.lock_flags.shared", FT_BOOLEAN, 32,
11210                         NULL, 0x00000001, NULL, HFILL }
11211                 },
11212
11213                 { &hf_smb2_lock_flags_exclusive,
11214                         { "Exclusive", "smb2.lock_flags.exclusive", FT_BOOLEAN, 32,
11215                         NULL, 0x00000002, NULL, HFILL }
11216                 },
11217
11218                 { &hf_smb2_lock_flags_unlock,
11219                         { "Unlock", "smb2.lock_flags.unlock", FT_BOOLEAN, 32,
11220                         NULL, 0x00000004, NULL, HFILL }
11221                 },
11222
11223                 { &hf_smb2_lock_flags_fail_immediately,
11224                         { "Fail Immediately", "smb2.lock_flags.fail_immediately", FT_BOOLEAN, 32,
11225                         NULL, 0x00000010, NULL, HFILL }
11226                 },
11227
11228                 { &hf_smb2_error_context_count,
11229                         { "Error Context Count", "smb2.error.context_count", FT_UINT8, BASE_DEC,
11230                         NULL, 0, NULL, HFILL }
11231                 },
11232
11233                 { &hf_smb2_error_reserved,
11234                         { "Reserved", "smb2.error.reserved", FT_UINT8, BASE_HEX,
11235                         NULL, 0, NULL, HFILL }
11236                 },
11237
11238                 { &hf_smb2_error_byte_count,
11239                         { "Byte Count", "smb2.error.byte_count", FT_UINT32, BASE_DEC,
11240                         NULL, 0, NULL, HFILL }
11241                 },
11242
11243                 { &hf_smb2_error_data,
11244                         { "Error Data", "smb2.error.data", FT_BYTES, BASE_NONE,
11245                         NULL, 0, NULL, HFILL }
11246                 },
11247
11248                 { &hf_smb2_reserved,
11249                         { "Reserved", "smb2.reserved", FT_BYTES, BASE_NONE,
11250                         NULL, 0, NULL, HFILL }
11251                 },
11252
11253                 { &hf_smb2_reserved_random,
11254                         { "Reserved (Random)", "smb2.reserved.random", FT_BYTES, BASE_NONE,
11255                         NULL, 0, "Reserved bytes, random data", HFILL }
11256                 },
11257
11258                 { &hf_smb2_root_directory_mbz,
11259                         { "Root Dir Handle (MBZ)", "smb2.root_directory", FT_BYTES, BASE_NONE,
11260                         NULL, 0, NULL, HFILL }
11261                 },
11262
11263                 { &hf_smb2_dhnq_buffer_reserved,
11264                         { "Reserved", "smb2.dhnq_buffer_reserved", FT_UINT64, BASE_HEX,
11265                         NULL, 0, NULL, HFILL }
11266                 },
11267
11268                 { &hf_smb2_dh2x_buffer_timeout,
11269                         { "Timeout", "smb2.dh2x.timeout", FT_UINT32, BASE_DEC,
11270                         NULL, 0, NULL, HFILL }
11271                 },
11272
11273                 { &hf_smb2_dh2x_buffer_flags,
11274                         { "Flags", "smb2.dh2x.flags", FT_UINT32, BASE_HEX,
11275                         NULL, 0, NULL, HFILL }
11276                 },
11277
11278                 { &hf_smb2_dh2x_buffer_flags_persistent_handle,
11279                         { "Persistent Handle", "smb2.dh2x.flags.persistent_handle", FT_BOOLEAN, 32,
11280                         NULL, SMB2_DH2X_FLAGS_PERSISTENT_HANDLE, NULL, HFILL }
11281                 },
11282
11283                 { &hf_smb2_dh2x_buffer_reserved,
11284                         { "Reserved", "smb2.dh2x.reserved", FT_UINT64, BASE_HEX,
11285                         NULL, 0, NULL, HFILL }
11286                 },
11287
11288                 { &hf_smb2_dh2x_buffer_create_guid,
11289                         { "Create Guid", "smb2.dh2x.create_guid", FT_GUID, BASE_NONE,
11290                         NULL, 0, NULL, HFILL }
11291                 },
11292
11293                 { &hf_smb2_APP_INSTANCE_buffer_struct_size,
11294                         { "Struct Size", "smb2.app_instance.struct_size", FT_UINT16, BASE_DEC,
11295                         NULL, 0, NULL, HFILL }
11296                 },
11297
11298                 { &hf_smb2_APP_INSTANCE_buffer_reserved,
11299                         { "Reserved", "smb2.app_instance.reserved", FT_UINT16, BASE_HEX,
11300                         NULL, 0, NULL, HFILL }
11301                 },
11302
11303                 { &hf_smb2_APP_INSTANCE_buffer_app_guid,
11304                         { "Application Guid", "smb2.app_instance.app_guid", FT_GUID, BASE_NONE,
11305                         NULL, 0, NULL, HFILL }
11306                 },
11307
11308                 { &hf_smb2_svhdx_open_device_context_version,
11309                         { "Version", "smb2.svhdx_open_device_context.version", FT_UINT32, BASE_DEC,
11310                         NULL, 0, NULL, HFILL }
11311                 },
11312
11313                 { &hf_smb2_svhdx_open_device_context_has_initiator_id,
11314                         { "HasInitiatorId", "smb2.svhdx_open_device_context.initiator_has_id", FT_BOOLEAN, 8,
11315                         TFS(&tfs_smb2_svhdx_has_initiator_id), 0, "Whether the host has an intiator", HFILL }
11316                 },
11317
11318                 { &hf_smb2_svhdx_open_device_context_reserved,
11319                         { "Reserved", "smb2.svhdx_open_device_context.reserved", FT_BYTES, BASE_NONE,
11320                         NULL, 0, NULL, HFILL }
11321                 },
11322
11323                 { &hf_smb2_svhdx_open_device_context_initiator_id,
11324                         { "InitiatorId", "smb2.svhdx_open_device_context.initiator_id", FT_GUID, BASE_NONE,
11325                         NULL, 0, NULL, HFILL }
11326                 },
11327
11328                 { &hf_smb2_svhdx_open_device_context_flags,
11329                         { "Flags", "smb2.svhdx_open_device_context.flags", FT_UINT32, BASE_HEX,
11330                         NULL, 0, NULL, HFILL }
11331                 },
11332
11333                 { &hf_smb2_svhdx_open_device_context_originator_flags,
11334                         { "OriginatorFlags", "smb2.svhdx_open_device_context.originator_flags", FT_UINT32, BASE_HEX,
11335                         VALS(originator_flags_vals), 0, NULL, HFILL }
11336                 },
11337
11338                 { &hf_smb2_svhdx_open_device_context_open_request_id,
11339                         { "OpenRequestId","smb2.svhxd_open_device_context.open_request_id", FT_UINT64, BASE_HEX,
11340                          NULL, 0, NULL, HFILL }
11341                 },
11342
11343                 { &hf_smb2_svhdx_open_device_context_initiator_host_name_len,
11344                         { "HostNameLength", "smb2.svhxd_open_device_context.initiator_host_name_len", FT_UINT16, BASE_DEC,
11345                          NULL, 0, NULL, HFILL }
11346                 },
11347
11348                 { &hf_smb2_svhdx_open_device_context_initiator_host_name,
11349                         { "HostName", "smb2.svhdx_open_device_context.host_name", FT_STRING, BASE_NONE,
11350                          NULL, 0, NULL, HFILL }
11351                 },
11352
11353                 { &hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
11354                         { "VirtualDiskPropertiesInitialized", "smb2.svhdx_open_device_context.virtual_disk_properties_initialized", FT_BOOLEAN, 32,
11355                         NULL, 0, "Whether VirtualSectorSize, PhysicalSectorSize, and VirtualSize fields are filled", HFILL }
11356                 },
11357
11358                 { &hf_smb2_svhdx_open_device_context_server_service_version,
11359                         { "ServerServiceVersion", "smb2.svhdx_open_device_context.server_service_version", FT_UINT32, BASE_DEC,
11360                         NULL, 0, "The current version of the protocol running on the server", HFILL }
11361                 },
11362
11363                 { &hf_smb2_svhdx_open_device_context_virtual_sector_size,
11364                         { "VirtualSectorSize", "smb2.svhdx_open_device_context.virtual_sector_size", FT_UINT32, BASE_DEC,
11365                         NULL, 0, "The virtual sector size of the virtual disk", HFILL }
11366                 },
11367
11368                 { &hf_smb2_svhdx_open_device_context_physical_sector_size,
11369                         { "PhysicalSectorSize", "smb2.svhdx_open_device_context.physical_sector_size", FT_UINT32, BASE_DEC,
11370                         NULL, 0, "The physical sector size of the virtual disk", HFILL }
11371                 },
11372
11373                 { &hf_smb2_svhdx_open_device_context_virtual_size,
11374                         { "VirtualSize", "smb2.svhdx_open_device_context.virtual_size", FT_UINT64, BASE_DEC,
11375                         NULL, 0, "The current length of the virtual disk, in bytes", HFILL }
11376                 },
11377
11378                 { &hf_smb2_posix_v1_version,
11379                         { "Version", "smb2.posix_v1_version", FT_UINT32, BASE_DEC,
11380                         NULL, 0, NULL, HFILL }
11381                 },
11382
11383                 { &hf_smb2_posix_v1_request,
11384                         { "Request", "smb2.posix_request", FT_UINT32, BASE_HEX,
11385                         NULL, 0, NULL, HFILL }
11386                 },
11387
11388                 { &hf_smb2_posix_v1_case_sensitive,
11389                         { "Posix Case Sensitive File Names", "smb2.posix_case_sensitive", FT_UINT32, BASE_HEX,
11390                         VALS(posix_case_sensitive_vals), 0x01, NULL, HFILL }
11391                 },
11392
11393                 { &hf_smb2_posix_v1_posix_lock,
11394                         { "Posix Byte-Range Locks", "smb2.posix_locks", FT_UINT32, BASE_HEX,
11395                         VALS(posix_locks_vals), 0x02, NULL, HFILL }
11396                 },
11397
11398                 { &hf_smb2_posix_v1_posix_file_semantics,
11399                         { "Posix File Semantics", "smb2.posix_file_semantics", FT_UINT32, BASE_HEX,
11400                         VALS(posix_file_semantics_vals), 0x04, NULL, HFILL }
11401                 },
11402
11403                 { &hf_smb2_posix_v1_posix_utf8_paths,
11404                         { "Posix UTF8 Paths", "smb2.posix_utf8_paths", FT_UINT32, BASE_HEX,
11405                         VALS(posix_utf8_paths_vals), 0x08, NULL, HFILL }
11406                 },
11407
11408                 { &hf_smb2_posix_v1_posix_will_convert_nt_acls,
11409                         { "Posix Will Convert NT ACLs", "smb2.will_convert_NTACLs", FT_UINT32, BASE_HEX,
11410                         VALS(posix_will_convert_ntacls_vals), 0x10, NULL, HFILL }
11411                 },
11412
11413                 { &hf_smb2_posix_v1_posix_fileinfo,
11414                         { "Posix Fileinfo", "smb2.posix_fileinfo", FT_UINT32, BASE_HEX,
11415                         VALS(posix_fileinfo_vals), 0x20, NULL, HFILL }
11416                 },
11417
11418                 { &hf_smb2_posix_v1_posix_acls,
11419                         { "Posix ACLs", "smb2.posix_acls", FT_UINT32, BASE_HEX,
11420                         VALS(posix_acls_vals), 0x40, NULL, HFILL }
11421                 },
11422
11423                 { &hf_smb2_posix_v1_rich_acls,
11424                         { "Rich ACLs", "smb2.rich_acls", FT_UINT32, BASE_HEX,
11425                         VALS(posix_rich_acls_vals), 0x80, NULL, HFILL }
11426                 },
11427
11428                 { &hf_smb2_posix_v1_supported_features,
11429                         { "Supported Features", "smb2.posix_supported_features", FT_UINT32, BASE_HEX,
11430                         NULL, 0, NULL, HFILL }
11431                 },
11432
11433                 { &hf_smb2_aapl_command_code,
11434                         { "Command code", "smb2.aapl.command_code", FT_UINT32, BASE_DEC,
11435                         VALS(aapl_command_code_vals), 0, NULL, HFILL }
11436                 },
11437
11438                 { &hf_smb2_aapl_reserved,
11439                         { "Reserved", "smb2.aapl.reserved", FT_UINT32, BASE_HEX,
11440                         NULL, 0, NULL, HFILL }
11441                 },
11442
11443                 { &hf_smb2_aapl_server_query_bitmask,
11444                         { "Query bitmask", "smb2.aapl.query_bitmask", FT_UINT64, BASE_HEX,
11445                         NULL, 0, NULL, HFILL }
11446                 },
11447
11448                 { &hf_smb2_aapl_server_query_bitmask_server_caps,
11449                         { "Server capabilities", "smb2.aapl.bitmask.server_caps", FT_BOOLEAN, 64,
11450                         NULL, SMB2_AAPL_SERVER_CAPS, NULL, HFILL }
11451                 },
11452
11453                 { &hf_smb2_aapl_server_query_bitmask_volume_caps,
11454                         { "Volume capabilities", "smb2.aapl.bitmask.volume_caps", FT_BOOLEAN, 64,
11455                         NULL, SMB2_AAPL_VOLUME_CAPS, NULL, HFILL }
11456                 },
11457
11458                 { &hf_smb2_aapl_server_query_bitmask_model_info,
11459                         { "Model information", "smb2.aapl.bitmask.model_info", FT_BOOLEAN, 64,
11460                         NULL, SMB2_AAPL_MODEL_INFO, NULL, HFILL }
11461                 },
11462
11463                 { &hf_smb2_aapl_server_query_caps,
11464                         { "Client/Server capabilities", "smb2.aapl.caps", FT_UINT64, BASE_HEX,
11465                         NULL, 0, NULL, HFILL }
11466                 },
11467
11468                 { &hf_smb2_aapl_server_query_caps_supports_read_dir_attr,
11469                         { "Supports READDIRATTR", "smb2.aapl.caps.supports_read_dir_addr", FT_BOOLEAN, 64,
11470                         NULL, SMB2_AAPL_SUPPORTS_READ_DIR_ATTR, NULL, HFILL }
11471                 },
11472
11473                 { &hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
11474                         { "Supports macOS copyfile", "smb2.aapl.caps.supports_osx_copyfile", FT_BOOLEAN, 64,
11475                         NULL, SMB2_AAPL_SUPPORTS_OSX_COPYFILE, NULL, HFILL }
11476                 },
11477
11478                 { &hf_smb2_aapl_server_query_caps_unix_based,
11479                         { "UNIX-based", "smb2.aapl.caps.unix_based", FT_BOOLEAN, 64,
11480                         NULL, SMB2_AAPL_UNIX_BASED, NULL, HFILL }
11481                 },
11482
11483                 { &hf_smb2_aapl_server_query_caps_supports_nfs_ace,
11484                         { "Supports NFS ACE", "smb2.aapl.supports_nfs_ace", FT_BOOLEAN, 64,
11485                         NULL, SMB2_AAPL_SUPPORTS_NFS_ACE, NULL, HFILL }
11486                 },
11487
11488                 { &hf_smb2_aapl_server_query_volume_caps,
11489                         { "Volume capabilities", "smb2.aapl.volume_caps", FT_UINT64, BASE_HEX,
11490                         NULL, 0, NULL, HFILL }
11491                 },
11492
11493                 { &hf_smb2_aapl_server_query_volume_caps_support_resolve_id,
11494                         { "Supports Resolve ID", "smb2.aapl.volume_caps.supports_resolve_id", FT_BOOLEAN, 64,
11495                         NULL, SMB2_AAPL_SUPPORTS_RESOLVE_ID, NULL, HFILL }
11496                 },
11497
11498                 { &hf_smb2_aapl_server_query_volume_caps_case_sensitive,
11499                         { "Case sensitive", "smb2.aapl.volume_caps.case_sensitive", FT_BOOLEAN, 64,
11500                         NULL, SMB2_AAPL_CASE_SENSITIVE, NULL, HFILL }
11501                 },
11502
11503                 { &hf_smb2_aapl_server_query_volume_caps_supports_full_sync,
11504                         { "Supports full sync", "smb2.aapl.volume_caps.supports_full_sync", FT_BOOLEAN, 64,
11505                         NULL, SMB2_AAPL_SUPPORTS_FULL_SYNC, NULL, HFILL }
11506                 },
11507
11508                 { &hf_smb2_aapl_server_query_model_string,
11509                         { "Model string", "smb2.aapl.model_string", FT_UINT_STRING, STR_UNICODE,
11510                         NULL, 0, NULL, HFILL }
11511                 },
11512
11513                 { &hf_smb2_aapl_server_query_server_path,
11514                         { "Server path", "smb2.aapl.server_path", FT_UINT_STRING, STR_UNICODE,
11515                         NULL, 0, NULL, HFILL }
11516                 },
11517
11518                 { &hf_smb2_transform_signature,
11519                         { "Signature", "smb2.header.transform.signature", FT_BYTES, BASE_NONE,
11520                         NULL, 0, NULL, HFILL }
11521                 },
11522
11523                 { &hf_smb2_transform_nonce,
11524                         { "Nonce", "smb2.header.transform.nonce", FT_BYTES, BASE_NONE,
11525                         NULL, 0, NULL, HFILL }
11526                 },
11527
11528                 { &hf_smb2_transform_msg_size,
11529                         { "Message size", "smb2.header.transform.msg_size", FT_UINT32, BASE_DEC,
11530                         NULL, 0, NULL, HFILL }
11531                 },
11532
11533                 { &hf_smb2_transform_reserved,
11534                         { "Reserved", "smb2.header.transform.reserved", FT_BYTES, BASE_NONE,
11535                         NULL, 0, NULL, HFILL }
11536                 },
11537
11538                 { &hf_smb2_transform_enc_alg,
11539                         { "Encryption ALG", "smb2.header.transform.encryption_alg", FT_UINT16, BASE_HEX,
11540                         NULL, 0, NULL, HFILL }
11541                 },
11542
11543                 { &hf_smb2_encryption_aes128_ccm,
11544                         { "SMB2_ENCRYPTION_AES128_CCM", "smb2.header.transform.enc_aes128_ccm", FT_BOOLEAN, 16,
11545                         NULL, ENC_ALG_aes128_ccm, NULL, HFILL }
11546                 },
11547
11548                 { &hf_smb2_transform_encrypted_data,
11549                         { "Data", "smb2.header.transform.enc_data", FT_BYTES, BASE_NONE,
11550                         NULL, 0, NULL, HFILL }
11551                 },
11552
11553                 { &hf_smb2_server_component_smb2,
11554                         { "Server Component: SMB2", "smb2.server_component_smb2", FT_NONE, BASE_NONE,
11555                         NULL, 0, NULL, HFILL }
11556                 },
11557
11558                 { &hf_smb2_server_component_smb2_transform,
11559                         { "Server Component: SMB2_TRANSFORM", "smb2.server_component_smb2_transform", FT_NONE, BASE_NONE,
11560                         NULL, 0, NULL, HFILL }
11561                 },
11562
11563                 { &hf_smb2_truncated,
11564                         { "Truncated...", "smb2.truncated", FT_NONE, BASE_NONE,
11565                         NULL, 0, NULL, HFILL }
11566                 },
11567
11568                 { &hf_smb2_pipe_fragment_overlap,
11569                         { "Fragment overlap", "smb2.pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
11570                         NULL, 0x0, "Fragment overlaps with other fragments", HFILL }
11571                 },
11572
11573                 { &hf_smb2_pipe_fragment_overlap_conflict,
11574                         { "Conflicting data in fragment overlap", "smb2.pipe.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE,
11575                         NULL, 0x0, NULL, HFILL }
11576                 },
11577
11578                 { &hf_smb2_pipe_fragment_multiple_tails,
11579                         { "Multiple tail fragments found", "smb2.pipe.fragment.multipletails", FT_BOOLEAN, BASE_NONE,
11580                         NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }
11581                 },
11582
11583                 { &hf_smb2_pipe_fragment_too_long_fragment,
11584                         { "Fragment too long", "smb2.pipe.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE,
11585                         NULL, 0x0, "Fragment contained data past end of packet", HFILL }
11586                 },
11587
11588                 { &hf_smb2_pipe_fragment_error,
11589                         { "Defragmentation error", "smb2.pipe.fragment.error", FT_FRAMENUM, BASE_NONE,
11590                         NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }
11591                 },
11592
11593                 { &hf_smb2_pipe_fragment_count,
11594                         { "Fragment count", "smb2.pipe.fragment.count", FT_UINT32, BASE_DEC,
11595                         NULL, 0x0, NULL, HFILL }
11596                 },
11597
11598                 { &hf_smb2_pipe_fragment,
11599                         { "Fragment SMB2 Named Pipe", "smb2.pipe.fragment", FT_FRAMENUM, BASE_NONE,
11600                         NULL, 0x0, NULL, HFILL }
11601                 },
11602
11603                 { &hf_smb2_pipe_fragments,
11604                         { "Reassembled SMB2 Named Pipe fragments", "smb2.pipe.fragments", FT_NONE, BASE_NONE,
11605                         NULL, 0x0, NULL, HFILL }
11606                 },
11607
11608                 { &hf_smb2_pipe_reassembled_in,
11609                         { "This SMB2 Named Pipe payload is reassembled in frame", "smb2.pipe.reassembled_in", FT_FRAMENUM, BASE_NONE,
11610                         NULL, 0x0, "The Named Pipe PDU is completely reassembled in this frame", HFILL }
11611                 },
11612
11613                 { &hf_smb2_pipe_reassembled_length,
11614                         { "Reassembled SMB2 Named Pipe length", "smb2.pipe.reassembled.length", FT_UINT32, BASE_DEC,
11615                         NULL, 0x0, "The total length of the reassembled payload", HFILL }
11616                 },
11617
11618                 { &hf_smb2_pipe_reassembled_data,
11619                         { "Reassembled SMB2 Named Pipe Data", "smb2.pipe.reassembled.data", FT_BYTES, BASE_NONE,
11620                         NULL, 0x0, "The reassembled payload", HFILL }
11621                 },
11622
11623                 { &hf_smb2_cchunk_resume_key,
11624                         { "ResumeKey", "smb2.fsctl.cchunk.resume_key", FT_BYTES, BASE_NONE,
11625                         NULL, 0x0, "Opaque data representing source of copy", HFILL }
11626                 },
11627
11628                 { &hf_smb2_cchunk_count,
11629                         { "Chunk Count", "smb2.fsctl.cchunk.count", FT_UINT32, BASE_DEC,
11630                         NULL, 0x0, NULL, HFILL }
11631                 },
11632
11633                 { &hf_smb2_cchunk_src_offset,
11634                         { "Source Offset", "smb2.fsctl.cchunk.src_offset", FT_UINT64, BASE_DEC,
11635                         NULL, 0x0, NULL, HFILL }
11636                 },
11637
11638                 { &hf_smb2_cchunk_dst_offset,
11639                         { "Target Offset", "smb2.fsctl.cchunk.dst_offset", FT_UINT64, BASE_DEC,
11640                         NULL, 0x0, NULL, HFILL }
11641                 },
11642
11643                 { &hf_smb2_cchunk_xfer_len,
11644                         { "Transfer Length", "smb2.fsctl.cchunk.xfer_len", FT_UINT32, BASE_DEC,
11645                         NULL, 0x0, NULL, HFILL }
11646                 },
11647
11648                 { &hf_smb2_cchunk_chunks_written,
11649                         { "Chunks Written", "smb2.fsctl.cchunk.chunks_written", FT_UINT32, BASE_DEC,
11650                         NULL, 0x0, NULL, HFILL }
11651                 },
11652
11653                 { &hf_smb2_cchunk_bytes_written,
11654                         { "Chunk Bytes Written", "smb2.fsctl.cchunk.bytes_written", FT_UINT32, BASE_DEC,
11655                         NULL, 0x0, NULL, HFILL }
11656                 },
11657
11658                 { &hf_smb2_cchunk_total_written,
11659                         { "Total Bytes Written", "smb2.fsctl.cchunk.total_written", FT_UINT32, BASE_DEC,
11660                         NULL, 0x0, NULL, HFILL }
11661                 },
11662
11663                 { &hf_smb2_symlink_error_response,
11664                         { "Symbolic Link Error Response", "smb2.symlink_error_response", FT_NONE, BASE_NONE,
11665                         NULL, 0, NULL, HFILL }
11666                 },
11667
11668                 { &hf_smb2_symlink_length,
11669                         { "SymLink Length", "smb2.symlink.length", FT_UINT32,
11670                         BASE_DEC, NULL, 0x0, NULL, HFILL }
11671                 },
11672
11673                 { &hf_smb2_symlink_error_tag,
11674                         { "SymLink Error Tag", "smb2.symlink.error_tag", FT_UINT32,
11675                         BASE_HEX, NULL, 0x0, NULL, HFILL }
11676                 },
11677
11678                 { &hf_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER,
11679                         { "SYMBOLIC_LINK_REPARSE_DATA_BUFFER", "smb2.SYMBOLIC_LINK_REPARSE_DATA_BUFFER", FT_NONE, BASE_NONE,
11680                         NULL, 0, NULL, HFILL }
11681                 },
11682                 { &hf_smb2_reparse_tag,
11683                         { "Reparse Tag", "smb2.symlink.reparse_tag", FT_UINT32, BASE_HEX,
11684                         NULL, 0x0, NULL, HFILL }
11685                 },
11686                 { &hf_smb2_reparse_data_length,
11687                         { "Reparse Data Length", "smb2.symlink.reparse_data_length", FT_UINT16, BASE_DEC,
11688                         NULL, 0x0, NULL, HFILL }
11689                 },
11690                 { &hf_smb2_unparsed_path_length,
11691                         { "Unparsed Path Length", "smb2.symlink.unparsed_path_length", FT_UINT16, BASE_DEC,
11692                         NULL, 0x0, NULL, HFILL }
11693                 },
11694                 { &hf_smb2_symlink_substitute_name,
11695                         { "Substitute Name", "smb2.symlink.substitute_name", FT_STRING, BASE_NONE,
11696                         NULL, 0x0, NULL, HFILL }
11697                 },
11698                 { &hf_smb2_symlink_print_name,
11699                         { "Print Name", "smb2.symlink.print_name", FT_STRING, BASE_NONE,
11700                         NULL, 0x0, NULL, HFILL }
11701                 },
11702                 { &hf_smb2_symlink_flags,
11703                         { "Flags", "smb2.symlink.flags", FT_UINT32, BASE_DEC,
11704                         NULL, 0x0, NULL, HFILL }
11705                 },
11706         };
11707
11708         static gint *ett[] = {
11709                 &ett_smb2,
11710                 &ett_smb2_ea,
11711                 &ett_smb2_olb,
11712                 &ett_smb2_header,
11713                 &ett_smb2_encrypted,
11714                 &ett_smb2_command,
11715                 &ett_smb2_secblob,
11716                 &ett_smb2_negotiate_context_element,
11717                 &ett_smb2_file_basic_info,
11718                 &ett_smb2_file_standard_info,
11719                 &ett_smb2_file_internal_info,
11720                 &ett_smb2_file_ea_info,
11721                 &ett_smb2_file_access_info,
11722                 &ett_smb2_file_rename_info,
11723                 &ett_smb2_file_disposition_info,
11724                 &ett_smb2_file_position_info,
11725                 &ett_smb2_file_full_ea_info,
11726                 &ett_smb2_file_mode_info,
11727                 &ett_smb2_file_alignment_info,
11728                 &ett_smb2_file_all_info,
11729                 &ett_smb2_file_allocation_info,
11730                 &ett_smb2_file_endoffile_info,
11731                 &ett_smb2_file_alternate_name_info,
11732                 &ett_smb2_file_stream_info,
11733                 &ett_smb2_file_pipe_info,
11734                 &ett_smb2_file_compression_info,
11735                 &ett_smb2_file_network_open_info,
11736                 &ett_smb2_file_attribute_tag_info,
11737                 &ett_smb2_fs_info_01,
11738                 &ett_smb2_fs_info_03,
11739                 &ett_smb2_fs_info_04,
11740                 &ett_smb2_fs_info_05,
11741                 &ett_smb2_fs_info_06,
11742                 &ett_smb2_fs_info_07,
11743                 &ett_smb2_fs_objectid_info,
11744                 &ett_smb2_sec_info_00,
11745                 &ett_smb2_quota_info,
11746                 &ett_smb2_query_quota_info,
11747                 &ett_smb2_tid_tree,
11748                 &ett_smb2_sesid_tree,
11749                 &ett_smb2_create_chain_element,
11750                 &ett_smb2_MxAc_buffer,
11751                 &ett_smb2_QFid_buffer,
11752                 &ett_smb2_RqLs_buffer,
11753                 &ett_smb2_ioctl_function,
11754                 &ett_smb2_FILE_OBJECTID_BUFFER,
11755                 &ett_smb2_flags,
11756                 &ett_smb2_sec_mode,
11757                 &ett_smb2_capabilities,
11758                 &ett_smb2_ses_req_flags,
11759                 &ett_smb2_ses_flags,
11760                 &ett_smb2_create_rep_flags,
11761                 &ett_smb2_lease_state,
11762                 &ett_smb2_lease_flags,
11763                 &ett_smb2_share_flags,
11764                 &ett_smb2_share_caps,
11765                 &ett_smb2_ioctl_flags,
11766                 &ett_smb2_ioctl_network_interface,
11767                 &ett_smb2_ioctl_sqos_opeations,
11768                 &ett_smb2_fsctl_range_data,
11769                 &ett_windows_sockaddr,
11770                 &ett_smb2_close_flags,
11771                 &ett_smb2_notify_info,
11772                 &ett_smb2_notify_flags,
11773                 &ett_smb2_rdma_v1,
11774                 &ett_smb2_write_flags,
11775                 &ett_smb2_find_flags,
11776                 &ett_smb2_file_directory_info,
11777                 &ett_smb2_both_directory_info,
11778                 &ett_smb2_id_both_directory_info,
11779                 &ett_smb2_full_directory_info,
11780                 &ett_smb2_file_name_info,
11781                 &ett_smb2_lock_info,
11782                 &ett_smb2_lock_flags,
11783                 &ett_smb2_DH2Q_buffer,
11784                 &ett_smb2_DH2C_buffer,
11785                 &ett_smb2_dh2x_flags,
11786                 &ett_smb2_APP_INSTANCE_buffer,
11787                 &ett_smb2_svhdx_open_device_context,
11788                 &ett_smb2_posix_v1_request,
11789                 &ett_smb2_posix_v1_response,
11790                 &ett_smb2_posix_v1_supported_features,
11791                 &ett_smb2_aapl_create_context_request,
11792                 &ett_smb2_aapl_server_query_bitmask,
11793                 &ett_smb2_aapl_server_query_caps,
11794                 &ett_smb2_aapl_create_context_response,
11795                 &ett_smb2_aapl_server_query_volume_caps,
11796                 &ett_smb2_integrity_flags,
11797                 &ett_smb2_transform_enc_alg,
11798                 &ett_smb2_buffercode,
11799                 &ett_smb2_ioctl_network_interface_capabilities,
11800                 &ett_qfr_entry,
11801                 &ett_smb2_pipe_fragment,
11802                 &ett_smb2_pipe_fragments,
11803                 &ett_smb2_cchunk_entry,
11804                 &ett_smb2_fsctl_odx_token,
11805                 &ett_smb2_symlink_error_response,
11806                 &ett_smb2_SYMBOLIC_LINK_REPARSE_DATA_BUFFER,
11807                 &ett_smb2_error_data,
11808         };
11809
11810         static ei_register_info ei[] = {
11811                 { &ei_smb2_invalid_length, { "smb2.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
11812                 { &ei_smb2_bad_response, { "smb2.bad_response", PI_MALFORMED, PI_ERROR, "Bad response", EXPFILL }},
11813                 { &ei_smb2_invalid_getinfo_offset, { "smb2.invalid_getinfo_offset", PI_MALFORMED, PI_ERROR, "Input buffer offset isn't past the fixed data in the message", EXPFILL }},
11814                 { &ei_smb2_invalid_getinfo_size, { "smb2.invalid_getinfo_size", PI_MALFORMED, PI_ERROR, "Input buffer length goes past the end of the message", EXPFILL }},
11815                 { &ei_smb2_empty_getinfo_buffer, { "smb2.empty_getinfo_buffer", PI_PROTOCOL, PI_WARN, "Input buffer length is empty for a quota request", EXPFILL }},
11816         };
11817
11818         expert_module_t* expert_smb2;
11819
11820         /* SessionID <=> SessionKey mappings for decryption */
11821         uat_t *seskey_uat;
11822
11823         static uat_field_t seskey_uat_fields[] = {
11824                 UAT_FLD_BUFFER(seskey_list, id, "Session ID", "The session ID buffer, coded as hex string, as it appears on the wire (LE)."),
11825                 UAT_FLD_BUFFER(seskey_list, key, "Session Key", "The secret session key buffer, coded as 16-byte hex string as it appears on the wire (LE)."),
11826                 UAT_END_FIELDS
11827         };
11828
11829         proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
11830                                              "SMB2", "smb2");
11831         proto_register_subtree_array(ett, array_length(ett));
11832         proto_register_field_array(proto_smb2, hf, array_length(hf));
11833         expert_smb2 = expert_register_protocol(proto_smb2);
11834         expert_register_field_array(expert_smb2, ei, array_length(ei));
11835
11836         smb2_module = prefs_register_protocol(proto_smb2, NULL);
11837         prefs_register_bool_preference(smb2_module, "eosmb2_take_name_as_fid",
11838                                        "Use the full file name as File ID when exporting an SMB2 object",
11839                                        "Whether the export object functionality will take the full path file name as file identifier",
11840                                        &eosmb2_take_name_as_fid);
11841
11842         prefs_register_bool_preference(smb2_module, "pipe_reassembly",
11843                 "Reassemble Named Pipes over SMB2",
11844                 "Whether the dissector should reassemble Named Pipes over SMB2 commands",
11845                 &smb2_pipe_reassembly);
11846
11847         seskey_uat = uat_new("Secret session key to use for decryption",
11848                              sizeof(smb2_seskey_field_t),
11849                              "smb2_seskey_list",
11850                              TRUE,
11851                              &seskey_list,
11852                              &num_seskey_list,
11853                              (UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS),
11854                              NULL,
11855                              seskey_list_copy_cb,
11856                              seskey_list_update_cb,
11857                              seskey_list_free_cb,
11858                              NULL,
11859                              NULL,
11860                              seskey_uat_fields);
11861
11862         prefs_register_uat_preference(smb2_module,
11863                                       "seskey_list",
11864                                       "Secret session keys for decryption",
11865                                       "A table of Session ID to Session key mappings used to derive decryption keys.",
11866                                       seskey_uat);
11867
11868         smb2_pipe_subdissector_list = register_heur_dissector_list("smb2_pipe_subdissectors", proto_smb2);
11869         /*
11870          * XXX - addresses_ports_reassembly_table_functions?
11871          * Probably correct for SMB-over-NBT and SMB-over-TCP,
11872          * as stuff from two different connections should
11873          * probably not be combined, but what about other
11874          * transports for SMB, e.g. NBF or Netware?
11875          */
11876         reassembly_table_register(&smb2_pipe_reassembly_table,
11877             &addresses_reassembly_table_functions);
11878
11879         smb2_tap = register_tap("smb2");
11880         smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
11881
11882         register_srt_table(proto_smb2, NULL, 1, smb2stat_packet, smb2stat_init, NULL);
11883 }
11884
11885 void
11886 proto_reg_handoff_smb2(void)
11887 {
11888         gssapi_handle  = find_dissector_add_dependency("gssapi", proto_smb2);
11889         ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_smb2);
11890         rsvd_handle    = find_dissector_add_dependency("rsvd", proto_smb2);
11891         heur_dissector_add("netbios", dissect_smb2_heur, "SMB2 over Netbios", "smb2_netbios", proto_smb2, HEURISTIC_ENABLE);
11892         heur_dissector_add("smb_direct", dissect_smb2_heur, "SMB2 over SMB Direct", "smb2_smb_direct", proto_smb2, HEURISTIC_ENABLE);
11893 }
11894
11895 /*
11896  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
11897  *
11898  * Local variables:
11899  * c-basic-offset: 8
11900  * tab-width: 8
11901  * indent-tabs-mode: t
11902  * End:
11903  *
11904  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
11905  * :indentSize=8:tabSize=8:noTabs=false:
11906  */