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