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