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