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