SMB2 ioctl FSCTL_OFFLOAD_WRITE
[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
435 static gint ett_smb2 = -1;
436 static gint ett_smb2_olb = -1;
437 static gint ett_smb2_ea = -1;
438 static gint ett_smb2_header = -1;
439 static gint ett_smb2_encrypted = -1;
440 static gint ett_smb2_command = -1;
441 static gint ett_smb2_secblob = -1;
442 static gint ett_smb2_negotiate_context_element = -1;
443 static gint ett_smb2_file_basic_info = -1;
444 static gint ett_smb2_file_standard_info = -1;
445 static gint ett_smb2_file_internal_info = -1;
446 static gint ett_smb2_file_ea_info = -1;
447 static gint ett_smb2_file_access_info = -1;
448 static gint ett_smb2_file_position_info = -1;
449 static gint ett_smb2_file_mode_info = -1;
450 static gint ett_smb2_file_alignment_info = -1;
451 static gint ett_smb2_file_all_info = -1;
452 static gint ett_smb2_file_allocation_info = -1;
453 static gint ett_smb2_file_endoffile_info = -1;
454 static gint ett_smb2_file_alternate_name_info = -1;
455 static gint ett_smb2_file_stream_info = -1;
456 static gint ett_smb2_file_pipe_info = -1;
457 static gint ett_smb2_file_compression_info = -1;
458 static gint ett_smb2_file_network_open_info = -1;
459 static gint ett_smb2_file_attribute_tag_info = -1;
460 static gint ett_smb2_file_rename_info = -1;
461 static gint ett_smb2_file_disposition_info = -1;
462 static gint ett_smb2_file_full_ea_info = -1;
463 static gint ett_smb2_fs_info_01 = -1;
464 static gint ett_smb2_fs_info_03 = -1;
465 static gint ett_smb2_fs_info_04 = -1;
466 static gint ett_smb2_fs_info_05 = -1;
467 static gint ett_smb2_fs_info_06 = -1;
468 static gint ett_smb2_fs_info_07 = -1;
469 static gint ett_smb2_fs_objectid_info = -1;
470 static gint ett_smb2_sec_info_00 = -1;
471 static gint ett_smb2_tid_tree = -1;
472 static gint ett_smb2_sesid_tree = -1;
473 static gint ett_smb2_create_chain_element = -1;
474 static gint ett_smb2_MxAc_buffer = -1;
475 static gint ett_smb2_QFid_buffer = -1;
476 static gint ett_smb2_RqLs_buffer = -1;
477 static gint ett_smb2_ioctl_function = -1;
478 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
479 static gint ett_smb2_flags = -1;
480 static gint ett_smb2_sec_mode = -1;
481 static gint ett_smb2_capabilities = -1;
482 static gint ett_smb2_ses_req_flags = -1;
483 static gint ett_smb2_ses_flags = -1;
484 static gint ett_smb2_lease_state = -1;
485 static gint ett_smb2_lease_flags = -1;
486 static gint ett_smb2_share_flags = -1;
487 static gint ett_smb2_create_rep_flags = -1;
488 static gint ett_smb2_share_caps = -1;
489 static gint ett_smb2_ioctl_flags = -1;
490 static gint ett_smb2_ioctl_network_interface = -1;
491 static gint ett_smb2_fsctl_range_data = -1;
492 static gint ett_windows_sockaddr = -1;
493 static gint ett_smb2_close_flags = -1;
494 static gint ett_smb2_notify_info = -1;
495 static gint ett_smb2_notify_flags = -1;
496 static gint ett_smb2_write_flags = -1;
497 static gint ett_smb2_rdma_v1 = -1;
498 static gint ett_smb2_DH2Q_buffer = -1;
499 static gint ett_smb2_DH2C_buffer = -1;
500 static gint ett_smb2_dh2x_flags = -1;
501 static gint ett_smb2_APP_INSTANCE_buffer = -1;
502 static gint ett_smb2_svhdx_open_device_context = -1;
503 static gint ett_smb2_posix_v1_request = -1;
504 static gint ett_smb2_posix_v1_response = -1;
505 static gint ett_smb2_posix_v1_supported_features = -1;
506 static gint ett_smb2_aapl_create_context_request = -1;
507 static gint ett_smb2_aapl_server_query_bitmask = -1;
508 static gint ett_smb2_aapl_server_query_caps = -1;
509 static gint ett_smb2_aapl_create_context_response = -1;
510 static gint ett_smb2_aapl_server_query_volume_caps = -1;
511 static gint ett_smb2_integrity_flags = -1;
512 static gint ett_smb2_find_flags = -1;
513 static gint ett_smb2_file_directory_info = -1;
514 static gint ett_smb2_both_directory_info = -1;
515 static gint ett_smb2_id_both_directory_info = -1;
516 static gint ett_smb2_full_directory_info = -1;
517 static gint ett_smb2_file_name_info = -1;
518 static gint ett_smb2_lock_info = -1;
519 static gint ett_smb2_lock_flags = -1;
520 static gint ett_smb2_transform_enc_alg = -1;
521 static gint ett_smb2_buffercode = -1;
522 static gint ett_smb2_ioctl_network_interface_capabilities = -1;
523 static gint ett_qfr_entry = -1;
524 static gint ett_smb2_pipe_fragment = -1;
525 static gint ett_smb2_pipe_fragments = -1;
526 static gint ett_smb2_cchunk_entry = -1;
527 static gint ett_smb2_fsctl_odx_token = -1;
528
529 static expert_field ei_smb2_invalid_length = EI_INIT;
530 static expert_field ei_smb2_bad_response = EI_INIT;
531
532 static int smb2_tap = -1;
533 static int smb2_eo_tap = -1;
534
535 static dissector_handle_t gssapi_handle  = NULL;
536 static dissector_handle_t ntlmssp_handle = NULL;
537 static dissector_handle_t rsvd_handle = NULL;
538
539 static heur_dissector_list_t smb2_pipe_subdissector_list;
540
541 static const fragment_items smb2_pipe_frag_items = {
542         &ett_smb2_pipe_fragment,
543         &ett_smb2_pipe_fragments,
544         &hf_smb2_pipe_fragments,
545         &hf_smb2_pipe_fragment,
546         &hf_smb2_pipe_fragment_overlap,
547         &hf_smb2_pipe_fragment_overlap_conflict,
548         &hf_smb2_pipe_fragment_multiple_tails,
549         &hf_smb2_pipe_fragment_too_long_fragment,
550         &hf_smb2_pipe_fragment_error,
551         &hf_smb2_pipe_fragment_count,
552         &hf_smb2_pipe_reassembled_in,
553         &hf_smb2_pipe_reassembled_length,
554         &hf_smb2_pipe_reassembled_data,
555         "Fragments"
556 };
557
558 #define SMB2_CLASS_FILE_INFO    0x01
559 #define SMB2_CLASS_FS_INFO      0x02
560 #define SMB2_CLASS_SEC_INFO     0x03
561 #define SMB2_CLASS_POSIX_INFO   0x80
562 static const value_string smb2_class_vals[] = {
563         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
564         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
565         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
566         { SMB2_CLASS_POSIX_INFO, "POSIX_INFO"},
567         { 0, NULL }
568 };
569
570 #define SMB2_SHARE_TYPE_DISK    0x01
571 #define SMB2_SHARE_TYPE_PIPE    0x02
572 #define SMB2_SHARE_TYPE_PRINT   0x03
573 static const value_string smb2_share_type_vals[] = {
574         { SMB2_SHARE_TYPE_DISK,         "Physical disk" },
575         { SMB2_SHARE_TYPE_PIPE,         "Named pipe" },
576         { SMB2_SHARE_TYPE_PRINT,        "Printer" },
577         { 0, NULL }
578 };
579
580
581 #define SMB2_FILE_BASIC_INFO          0x04
582 #define SMB2_FILE_STANDARD_INFO       0x05
583 #define SMB2_FILE_INTERNAL_INFO       0x06
584 #define SMB2_FILE_EA_INFO             0x07
585 #define SMB2_FILE_ACCESS_INFO         0x08
586 #define SMB2_FILE_RENAME_INFO         0x0a
587 #define SMB2_FILE_DISPOSITION_INFO    0x0d
588 #define SMB2_FILE_POSITION_INFO       0x0e
589 #define SMB2_FILE_FULL_EA_INFO        0x0f
590 #define SMB2_FILE_MODE_INFO           0x10
591 #define SMB2_FILE_ALIGNMENT_INFO      0x11
592 #define SMB2_FILE_ALL_INFO            0x12
593 #define SMB2_FILE_ALLOCATION_INFO     0x13
594 #define SMB2_FILE_ENDOFFILE_INFO      0x14
595 #define SMB2_FILE_ALTERNATE_NAME_INFO 0x15
596 #define SMB2_FILE_STREAM_INFO         0x16
597 #define SMB2_FILE_PIPE_INFO           0x17
598 #define SMB2_FILE_COMPRESSION_INFO    0x1c
599 #define SMB2_FILE_NETWORK_OPEN_INFO   0x22
600 #define SMB2_FILE_ATTRIBUTE_TAG_INFO  0x23
601
602 static const value_string smb2_file_info_levels[] = {
603         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
604         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
605         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
606         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
607         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
608         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
609         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
610         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
611         {SMB2_FILE_FULL_EA_INFO,        "SMB2_FILE_FULL_EA_INFO" },
612         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
613         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
614         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
615         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
616         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
617         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
618         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
619         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
620         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
621         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
622         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
623         { 0, NULL }
624 };
625 static value_string_ext smb2_file_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_file_info_levels);
626
627
628
629 #define SMB2_FS_INFO_01                 0x01
630 #define SMB2_FS_LABEL_INFO              0x02
631 #define SMB2_FS_INFO_03                 0x03
632 #define SMB2_FS_INFO_04                 0x04
633 #define SMB2_FS_INFO_05                 0x05
634 #define SMB2_FS_INFO_06                 0x06
635 #define SMB2_FS_INFO_07                 0x07
636 #define SMB2_FS_OBJECTID_INFO           0x08
637 #define SMB2_FS_DRIVER_PATH_INFO        0x09
638 #define SMB2_FS_VOLUME_FLAGS_INFO       0x0a
639 #define SMB2_FS_SECTOR_SIZE_INFO        0x0b
640
641 static const value_string smb2_fs_info_levels[] = {
642         {SMB2_FS_INFO_01,               "FileFsVolumeInformation" },
643         {SMB2_FS_LABEL_INFO,            "FileFsLabelInformation" },
644         {SMB2_FS_INFO_03,               "FileFsSizeInformation" },
645         {SMB2_FS_INFO_04,               "FileFsDeviceInformation" },
646         {SMB2_FS_INFO_05,               "FileFsAttributeInformation" },
647         {SMB2_FS_INFO_06,               "FileFsControlInformation" },
648         {SMB2_FS_INFO_07,               "FileFsFullSizeInformation" },
649         {SMB2_FS_OBJECTID_INFO,         "FileFsObjectIdInformation" },
650         {SMB2_FS_DRIVER_PATH_INFO,      "FileFsDriverPathInformation" },
651         {SMB2_FS_VOLUME_FLAGS_INFO,     "FileFsVolumeFlagsInformation" },
652         {SMB2_FS_SECTOR_SIZE_INFO,      "FileFsSectorSizeInformation" },
653         { 0, NULL }
654 };
655 static value_string_ext smb2_fs_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_fs_info_levels);
656
657 #define SMB2_SEC_INFO_00        0x00
658 static const value_string smb2_sec_info_levels[] = {
659         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
660         { 0, NULL }
661 };
662 static value_string_ext smb2_sec_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_sec_info_levels);
663
664 static const value_string smb2_posix_info_levels[] = {
665         { 0,    "QueryFileUnixBasic" },
666         { 1,    "QueryFileUnixLink" },
667         { 3,    "QueryFileUnixHLink" },
668         { 5,    "QueryFileUnixXAttr" },
669         { 0x0B, "QueryFileUnixInfo2" },
670         { 0, NULL }
671 };
672
673 static value_string_ext smb2_posix_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_posix_info_levels);
674
675 #define SMB2_FIND_DIRECTORY_INFO         0x01
676 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
677 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
678 #define SMB2_FIND_INDEX_SPECIFIED        0x04
679 #define SMB2_FIND_NAME_INFO              0x0C
680 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
681 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
682 static const value_string smb2_find_info_levels[] = {
683         { SMB2_FIND_DIRECTORY_INFO,             "SMB2_FIND_DIRECTORY_INFO" },
684         { SMB2_FIND_FULL_DIRECTORY_INFO,        "SMB2_FIND_FULL_DIRECTORY_INFO" },
685         { SMB2_FIND_BOTH_DIRECTORY_INFO,        "SMB2_FIND_BOTH_DIRECTORY_INFO" },
686         { SMB2_FIND_INDEX_SPECIFIED,            "SMB2_FIND_INDEX_SPECIFIED" },
687         { SMB2_FIND_NAME_INFO,                  "SMB2_FIND_NAME_INFO" },
688         { SMB2_FIND_ID_BOTH_DIRECTORY_INFO,     "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
689         { SMB2_FIND_ID_FULL_DIRECTORY_INFO,     "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
690         { 0, NULL }
691 };
692
693 #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001
694 #define SMB2_ENCRYPTION_CAPABILITIES        0x0002
695 static const value_string smb2_negotiate_context_types[] = {
696         { SMB2_PREAUTH_INTEGRITY_CAPABILITIES,  "SMB2_PREAUTH_INTEGRITY_CAPABILITIES" },
697         { SMB2_ENCRYPTION_CAPABILITIES, "SMB2_ENCRYPTION_CAPABILITIES" },
698         { 0, NULL }
699 };
700
701 #define SMB2_NUM_PROCEDURES     256
702
703 static void
704 smb2stat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
705 {
706         srt_stat_table *smb2_srt_table;
707         guint32 i;
708
709         smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", gui_callback, gui_data, NULL);
710         for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
711         {
712                 init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
713         }
714 }
715
716 static int
717 smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
718 {
719         guint i = 0;
720         srt_stat_table *smb2_srt_table;
721         srt_data_t *data = (srt_data_t *)pss;
722         const smb2_info_t *si=(const smb2_info_t *)prv;
723
724         /* we are only interested in response packets */
725         if(!(si->flags&SMB2_FLAGS_RESPONSE)){
726                 return 0;
727         }
728         /* if we haven't seen the request, just ignore it */
729         if(!si->saved){
730                 return 0;
731         }
732
733         /* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
734          * not only add additional (bogus) transactions but also the latency associated with them.
735          * This can greatly inflate the maximum and average SRT stats especially in the case of
736          * retransmissions triggered by the expiry of the rexmit timer (RTOs). Only calculating SRT
737          * for the last received response accomplishes this goal without requiring the TCP pref
738          * "Do not call subdissectors for error packets" to be set. */
739         if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->num))
740                 return 0;
741
742         smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
743         add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
744         return 1;
745 }
746
747
748 static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
749
750 /* ExportObject preferences variable */
751 gboolean eosmb2_take_name_as_fid = FALSE ;
752
753 /* unmatched smb_saved_info structures.
754    For unmatched smb_saved_info structures we store the smb_saved_info
755    structure using the msg_id field.
756 */
757 static gint
758 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
759 {
760         const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
761         const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
762         return key1->msg_id == key2->msg_id;
763 }
764 static guint
765 smb2_saved_info_hash_unmatched(gconstpointer k)
766 {
767         const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
768         guint32 hash;
769
770         hash = (guint32) (key->msg_id&0xffffffff);
771         return hash;
772 }
773
774 /* matched smb_saved_info structures.
775    For matched smb_saved_info structures we store the smb_saved_info
776    structure using the msg_id field.
777 */
778 static gint
779 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
780 {
781         const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
782         const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
783         return key1->msg_id == key2->msg_id;
784 }
785 static guint
786 smb2_saved_info_hash_matched(gconstpointer k)
787 {
788         const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
789         guint32 hash;
790
791         hash = (guint32) (key->msg_id&0xffffffff);
792         return hash;
793 }
794
795 /* For Tids of a specific conversation.
796    This keeps track of tid->sharename mappings and other information about the
797    tid.
798    qqq
799    We might need to refine this if it occurs that tids are reused on a single
800    conversation.   we don't worry about that yet for simplicity
801 */
802 static gint
803 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
804 {
805         const smb2_tid_info_t *key1 = (const smb2_tid_info_t *)k1;
806         const smb2_tid_info_t *key2 = (const smb2_tid_info_t *)k2;
807         return key1->tid == key2->tid;
808 }
809 static guint
810 smb2_tid_info_hash(gconstpointer k)
811 {
812         const smb2_tid_info_t *key = (const smb2_tid_info_t *)k;
813         guint32 hash;
814
815         hash = key->tid;
816         return hash;
817 }
818
819 /* For Uids of a specific conversation.
820    This keeps track of uid->acct_name mappings and other information about the
821    uid.
822    qqq
823    We might need to refine this if it occurs that uids are reused on a single
824    conversation.   we don't worry about that yet for simplicity
825 */
826 static gint
827 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
828 {
829         const smb2_sesid_info_t *key1 = (const smb2_sesid_info_t *)k1;
830         const smb2_sesid_info_t *key2 = (const smb2_sesid_info_t *)k2;
831         return key1->sesid == key2->sesid;
832 }
833 static guint
834 smb2_sesid_info_hash(gconstpointer k)
835 {
836         const smb2_sesid_info_t *key = (const smb2_sesid_info_t *)k;
837         guint32 hash;
838
839         hash = (guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
840         return hash;
841 }
842
843 /*
844  * For File IDs of a specific conversation.
845  * This keeps track of fid to name mapping and application level conversations
846  * over named pipes.
847  *
848  * This handles implementation bugs, where the fid_persitent is 0 or
849  * the fid_persitent/fid_volative is not unique per conversation.
850  */
851 static gint
852 smb2_fid_info_equal(gconstpointer k1, gconstpointer k2)
853 {
854         const smb2_fid_info_t *key1 = (const smb2_fid_info_t *)k1;
855         const smb2_fid_info_t *key2 = (const smb2_fid_info_t *)k2;
856
857         if (key1->fid_persistent != key2->fid_persistent) {
858                 return 0;
859         };
860
861         if (key1->fid_volatile != key2->fid_volatile) {
862                 return 0;
863         };
864
865         if (key1->sesid != key2->sesid) {
866                 return 0;
867         };
868
869         if (key1->tid != key2->tid) {
870                 return 0;
871         };
872
873         return 1;
874 }
875
876 static guint
877 smb2_fid_info_hash(gconstpointer k)
878 {
879         const smb2_fid_info_t *key = (const smb2_fid_info_t *)k;
880         guint32 hash;
881
882         if (key->fid_persistent != 0) {
883                 hash = (guint32)( ((key->fid_persistent>>32)&0xffffffff)+((key->fid_persistent)&0xffffffff) );
884         } else {
885                 hash = (guint32)( ((key->fid_volatile>>32)&0xffffffff)+((key->fid_volatile)&0xffffffff) );
886         }
887
888         return hash;
889 }
890
891 /* Callback for destroying the glib hash tables associated with a conversation
892  * struct. */
893 static gboolean
894 smb2_conv_destroy(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
895                   void *user_data)
896 {
897         smb2_conv_info_t *conv = (smb2_conv_info_t *)user_data;
898
899         g_hash_table_destroy(conv->matched);
900         g_hash_table_destroy(conv->unmatched);
901         g_hash_table_destroy(conv->fids);
902         g_hash_table_destroy(conv->sesids);
903         g_hash_table_destroy(conv->files);
904
905         /* This conversation is gone, return FALSE to indicate we don't
906          * want to be called again for this conversation. */
907         return FALSE;
908 }
909
910 static void smb2_key_derivation(const guint8 *KI _U_, guint32 KI_len _U_,
911                          const guint8 *Label _U_, guint32 Label_len _U_,
912                          const guint8 *Context _U_, guint32 Context_len _U_,
913                          guint8 KO[16])
914 {
915 #ifdef HAVE_LIBGCRYPT
916         gcry_md_hd_t  hd     = NULL;
917         guint8        buf[4];
918         guint8       *digest = NULL;
919
920         /*
921          * a simplified version of
922          * "NIST Special Publication 800-108" section 5.1
923          * using hmac-sha256.
924          */
925         gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
926         gcry_md_setkey(hd, KI, KI_len);
927
928         memset(buf, 0, sizeof(buf));
929         buf[3] = 1;
930         gcry_md_write(hd, buf, sizeof(buf));
931         gcry_md_write(hd, Label, Label_len);
932         gcry_md_write(hd, buf, 1);
933         gcry_md_write(hd, Context, Context_len);
934         buf[3] = 128;
935         gcry_md_write(hd, buf, sizeof(buf));
936
937         digest = gcry_md_read(hd, GCRY_MD_SHA256);
938
939         memcpy(KO, digest, 16);
940
941         gcry_md_close(hd);
942 #else
943         memset(KO, 0, 16);
944 #endif
945 }
946
947 /* for export-object-smb2 */
948 static gchar *policy_hnd_to_file_id(const e_ctx_hnd *hnd) {
949 gchar *file_id;
950         file_id = wmem_strdup_printf(wmem_packet_scope(),
951                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
952                         hnd->uuid.data1,
953                         hnd->uuid.data2,
954                         hnd->uuid.data3,
955                         hnd->uuid.data4[0],
956                         hnd->uuid.data4[1],
957                         hnd->uuid.data4[2],
958                         hnd->uuid.data4[3],
959                         hnd->uuid.data4[4],
960                         hnd->uuid.data4[5],
961                         hnd->uuid.data4[6],
962                         hnd->uuid.data4[7]);
963         return file_id;
964 }
965 static guint smb2_eo_files_hash(gconstpointer k) {
966         return g_str_hash(policy_hnd_to_file_id((const e_ctx_hnd *)k));
967 }
968 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2) {
969 int     are_equal;
970         const e_ctx_hnd *key1 = (const e_ctx_hnd *)k1;
971         const e_ctx_hnd *key2 = (const e_ctx_hnd *)k2;
972
973         are_equal = (key1->uuid.data1==key2->uuid.data1 &&
974                 key1->uuid.data2==key2->uuid.data2 &&
975                 key1->uuid.data3==key2->uuid.data3 &&
976                 key1->uuid.data4[0]==key2->uuid.data4[0] &&
977                 key1->uuid.data4[1]==key2->uuid.data4[1] &&
978                 key1->uuid.data4[2]==key2->uuid.data4[2] &&
979                 key1->uuid.data4[3]==key2->uuid.data4[3] &&
980                 key1->uuid.data4[4]==key2->uuid.data4[4] &&
981                 key1->uuid.data4[5]==key2->uuid.data4[5] &&
982                 key1->uuid.data4[6]==key2->uuid.data4[6] &&
983                 key1->uuid.data4[7]==key2->uuid.data4[7]);
984
985         return are_equal;
986 }
987
988 static void
989 feed_eo_smb2(tvbuff_t * tvb,packet_info *pinfo,smb2_info_t * si, guint16 dataoffset,guint32 length, guint64 file_offset) {
990
991         char       *fid_name = NULL;
992         guint32     open_frame = 0, close_frame = 0;
993         tvbuff_t        *data_tvb = NULL;
994         smb_eo_t        *eo_info;
995         gchar           *file_id;
996         gchar           *auxstring;
997         gchar           **aux_string_v;
998
999         /* Create a new tvb to point to the payload data */
1000         data_tvb = tvb_new_subset_length(tvb, dataoffset, length);
1001         /* Create the eo_info to pass to the listener */
1002         eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
1003         /* Fill in eo_info */
1004         eo_info->smbversion=2;
1005         /* cmd == opcode */
1006         eo_info->cmd=si->opcode;
1007         /* We don't keep track of uid in SMB v2 */
1008         eo_info->uid=0;
1009
1010         /* Try to get file id and filename */
1011         file_id=policy_hnd_to_file_id(&si->saved->policy_hnd);
1012         dcerpc_fetch_polhnd_data(&si->saved->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num);
1013         if (fid_name && g_strcmp0(fid_name,"File: ")!=0) {
1014                 auxstring=fid_name;
1015                 /* Remove "File: " from filename */
1016                 if (g_str_has_prefix(auxstring, "File: ")) {
1017                         aux_string_v = g_strsplit(auxstring, "File: ", -1);
1018                         eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",aux_string_v[g_strv_length(aux_string_v)-1]);
1019                         g_strfreev(aux_string_v);
1020                 } else {
1021                         if (g_str_has_prefix(auxstring, "\\")) {
1022                                 eo_info->filename = wmem_strdup(wmem_packet_scope(), auxstring);
1023                         } else {
1024                                 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",auxstring);
1025                         }
1026                 }
1027         } else {
1028                 auxstring=wmem_strdup_printf(wmem_packet_scope(), "File_Id_%s", file_id);
1029                 eo_info->filename=auxstring;
1030         }
1031
1032
1033
1034         if (eosmb2_take_name_as_fid) {
1035                 eo_info->fid = g_str_hash(eo_info->filename);
1036         } else {
1037                 eo_info->fid = g_str_hash(file_id);
1038         }
1039
1040         /* tid, hostname, tree_id */
1041         if (si->tree) {
1042                 eo_info->tid=si->tree->tid;
1043                 if (strlen(si->tree->name)>0 && strlen(si->tree->name)<=256) {
1044                         eo_info->hostname = wmem_strdup(wmem_packet_scope(), si->tree->name);
1045                 } else {
1046                         eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,si->opcode),si->tree->tid);
1047                 }
1048         } else {
1049                 eo_info->tid=0;
1050                 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,si->opcode));
1051         }
1052
1053         /* packet number */
1054         eo_info->pkt_num = pinfo->num;
1055
1056         /* fid type */
1057         if (si->eo_file_info->attr_mask & SMB2_FLAGS_ATTR_DIRECTORY) {
1058                 eo_info->fid_type=SMB2_FID_TYPE_DIR;
1059         } else {
1060                 if (si->eo_file_info->attr_mask &
1061                         (SMB2_FLAGS_ATTR_ARCHIVE | SMB2_FLAGS_ATTR_NORMAL |
1062                          SMB2_FLAGS_ATTR_HIDDEN | SMB2_FLAGS_ATTR_READONLY |
1063                          SMB2_FLAGS_ATTR_SYSTEM) ) {
1064                         eo_info->fid_type=SMB2_FID_TYPE_FILE;
1065                 } else {
1066                         eo_info->fid_type=SMB2_FID_TYPE_OTHER;
1067                 }
1068         }
1069
1070         /* end_of_file */
1071         eo_info->end_of_file=si->eo_file_info->end_of_file;
1072
1073         /* data offset and chunk length */
1074         eo_info->smb_file_offset=file_offset;
1075         eo_info->smb_chunk_len=length;
1076         /* XXX is this right? */
1077         if (length<si->saved->bytes_moved) {
1078                 si->saved->file_offset=si->saved->file_offset+length;
1079                 si->saved->bytes_moved=si->saved->bytes_moved-length;
1080         }
1081
1082         /* Payload */
1083         eo_info->payload_len = length;
1084         eo_info->payload_data = tvb_get_ptr(data_tvb, 0, length);
1085
1086         tap_queue_packet(smb2_eo_tap, pinfo, eo_info);
1087
1088 }
1089
1090 static int dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
1091
1092
1093 /* This is a helper to dissect the common string type
1094  * uint16 offset
1095  * uint16 length
1096  * ...
1097  * char *string
1098  *
1099  * This function is called twice, first to decode the offset/length and
1100  * second time to dissect the actual string.
1101  * It is done this way since there is no guarantee that we have the full packet and we don't
1102  * want to abort dissection too early if the packet ends somewhere between the
1103  * length/offset and the actual buffer.
1104  *
1105  */
1106 enum offset_length_buffer_offset_size {
1107         OLB_O_UINT16_S_UINT16,
1108         OLB_O_UINT16_S_UINT32,
1109         OLB_O_UINT32_S_UINT32,
1110         OLB_S_UINT32_O_UINT32
1111 };
1112 typedef struct _offset_length_buffer_t {
1113         guint32 off;
1114         guint32 len;
1115         int off_offset;
1116         int len_offset;
1117         enum offset_length_buffer_offset_size offset_size;
1118         int hfindex;
1119 } offset_length_buffer_t;
1120 static int
1121 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
1122                                enum offset_length_buffer_offset_size offset_size, int hfindex)
1123 {
1124         olb->hfindex = hfindex;
1125         olb->offset_size = offset_size;
1126         switch (offset_size) {
1127         case OLB_O_UINT16_S_UINT16:
1128                 olb->off = tvb_get_letohs(tvb, offset);
1129                 olb->off_offset = offset;
1130                 offset += 2;
1131                 olb->len = tvb_get_letohs(tvb, offset);
1132                 olb->len_offset = offset;
1133                 offset += 2;
1134                 break;
1135         case OLB_O_UINT16_S_UINT32:
1136                 olb->off = tvb_get_letohs(tvb, offset);
1137                 olb->off_offset = offset;
1138                 offset += 2;
1139                 olb->len = tvb_get_letohl(tvb, offset);
1140                 olb->len_offset = offset;
1141                 offset += 4;
1142                 break;
1143         case OLB_O_UINT32_S_UINT32:
1144                 olb->off = tvb_get_letohl(tvb, offset);
1145                 olb->off_offset = offset;
1146                 offset += 4;
1147                 olb->len = tvb_get_letohl(tvb, offset);
1148                 olb->len_offset = offset;
1149                 offset += 4;
1150                 break;
1151         case OLB_S_UINT32_O_UINT32:
1152                 olb->len = tvb_get_letohl(tvb, offset);
1153                 olb->len_offset = offset;
1154                 offset += 4;
1155                 olb->off = tvb_get_letohl(tvb, offset);
1156                 olb->off_offset = offset;
1157                 offset += 4;
1158                 break;
1159         }
1160
1161         return offset;
1162 }
1163
1164 #define OLB_TYPE_UNICODE_STRING         0x01
1165 #define OLB_TYPE_ASCII_STRING           0x02
1166 static const char *
1167 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
1168 {
1169         int         len, off;
1170         proto_item *item = NULL;
1171         proto_tree *tree = NULL;
1172         const char *name = NULL;
1173         guint16     bc;
1174         int         offset;
1175
1176         offset = olb->off;
1177         len = olb->len;
1178         off = olb->off;
1179         bc = tvb_captured_length_remaining(tvb, offset);
1180
1181
1182         /* sanity check */
1183         tvb_ensure_bytes_exist(tvb, off, len);
1184         if (((off+len)<off)
1185         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1186                 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1187                                     "Invalid offset/length. Malformed packet");
1188
1189                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1190
1191                 return NULL;
1192         }
1193
1194
1195         switch (type) {
1196         case OLB_TYPE_UNICODE_STRING:
1197                 name = get_unicode_or_ascii_string(tvb, &off,
1198                         TRUE, &len, TRUE, TRUE, &bc);
1199                 if (!name) {
1200                         name = "";
1201                 }
1202                 if (parent_tree) {
1203                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
1204                         tree = proto_item_add_subtree(item, ett_smb2_olb);
1205                 }
1206                 break;
1207         case OLB_TYPE_ASCII_STRING:
1208                 name = get_unicode_or_ascii_string(tvb, &off,
1209                         FALSE, &len, TRUE, TRUE, &bc);
1210                 if (!name) {
1211                         name = "";
1212                 }
1213                 if (parent_tree) {
1214                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
1215                         tree = proto_item_add_subtree(item, ett_smb2_olb);
1216                 }
1217                 break;
1218         }
1219
1220         switch (olb->offset_size) {
1221         case OLB_O_UINT16_S_UINT16:
1222                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1223                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1224                 break;
1225         case OLB_O_UINT16_S_UINT32:
1226                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1227                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1228                 break;
1229         case OLB_O_UINT32_S_UINT32:
1230                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1231                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1232                 break;
1233         case OLB_S_UINT32_O_UINT32:
1234                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1235                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1236                 break;
1237         }
1238
1239         return name;
1240 }
1241
1242 static void
1243 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
1244                         offset_length_buffer_t *olb, smb2_info_t *si,
1245                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
1246 {
1247         int         len, off;
1248         proto_item *sub_item = NULL;
1249         proto_tree *sub_tree = NULL;
1250         tvbuff_t   *sub_tvb  = NULL;
1251         int         offset;
1252
1253         offset = olb->off;
1254         len    = olb->len;
1255         off    = olb->off;
1256
1257         /* sanity check */
1258         tvb_ensure_bytes_exist(tvb, off, len);
1259         if (((off+len)<off)
1260             || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1261                 proto_tree_add_expert_format(parent_tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1262                                     "Invalid offset/length. Malformed packet");
1263
1264                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1265
1266                 return;
1267         }
1268
1269         /* if we don't want/need a subtree */
1270         if (olb->hfindex == -1) {
1271                 sub_item = parent_tree;
1272                 sub_tree = parent_tree;
1273         } else {
1274                 if (parent_tree) {
1275                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
1276                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
1277                 }
1278         }
1279
1280         switch (olb->offset_size) {
1281         case OLB_O_UINT16_S_UINT16:
1282                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1283                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1284                 break;
1285         case OLB_O_UINT16_S_UINT32:
1286                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1287                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1288                 break;
1289         case OLB_O_UINT32_S_UINT32:
1290                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1291                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1292                 break;
1293         case OLB_S_UINT32_O_UINT32:
1294                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1295                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1296                 break;
1297         }
1298
1299         if (off == 0 || len == 0) {
1300                 proto_item_append_text(sub_item, ": NO DATA");
1301                 return;
1302         }
1303
1304         if (!dissector) {
1305                 return;
1306         }
1307
1308         sub_tvb = tvb_new_subset(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
1309
1310         dissector(sub_tvb, pinfo, sub_tree, si);
1311 }
1312
1313 static int
1314 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
1315 {
1316         if (olb->off == 0) {
1317                 return offset;
1318         }
1319         return MAX(offset, (int)(olb->off + olb->len));
1320 }
1321
1322 typedef struct _smb2_function {
1323         int (*request) (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1324         int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1325 } smb2_function;
1326
1327 static const true_false_string tfs_smb2_svhdx_has_initiator_id = {
1328         "Has an initiator id",
1329         "Does not have an initiator id"
1330 };
1331
1332 static const true_false_string tfs_flags_response = {
1333         "This is a RESPONSE",
1334         "This is a REQUEST"
1335 };
1336
1337 static const true_false_string tfs_flags_async_cmd = {
1338         "This is an ASYNC command",
1339         "This is a SYNC command"
1340 };
1341
1342 static const true_false_string tfs_flags_dfs_op = {
1343         "This is a DFS OPERATION",
1344         "This is a normal operation"
1345 };
1346
1347 static const true_false_string tfs_flags_chained = {
1348         "This pdu a CHAINED command",
1349         "This pdu is NOT a chained command"
1350 };
1351
1352 static const true_false_string tfs_flags_signature = {
1353         "This pdu is SIGNED",
1354         "This pdu is NOT signed"
1355 };
1356
1357 static const true_false_string tfs_flags_replay_operation = {
1358         "This is a REPLAY OPEARATION",
1359         "This is NOT a replay operation"
1360 };
1361
1362 static const true_false_string tfs_flags_priority_mask = {
1363         "This pdu contains a PRIORITY",
1364         "This pdu does NOT contain a PRIORITY1"
1365 };
1366
1367 static const true_false_string tfs_cap_dfs = {
1368         "This host supports DFS",
1369         "This host does NOT support DFS"
1370 };
1371
1372 static const true_false_string tfs_cap_leasing = {
1373         "This host supports LEASING",
1374         "This host does NOT support LEASING"
1375 };
1376
1377 static const true_false_string tfs_cap_large_mtu = {
1378         "This host supports LARGE_MTU",
1379         "This host does NOT support LARGE_MTU"
1380 };
1381
1382 static const true_false_string tfs_cap_multi_channel = {
1383         "This host supports MULTI CHANNEL",
1384         "This host does NOT support MULTI CHANNEL"
1385 };
1386
1387 static const true_false_string tfs_cap_persistent_handles = {
1388         "This host supports PERSISTENT HANDLES",
1389         "This host does NOT support PERSISTENT HANDLES"
1390 };
1391
1392 static const true_false_string tfs_cap_directory_leasing = {
1393         "This host supports DIRECTORY LEASING",
1394         "This host does NOT support DIRECTORY LEASING"
1395 };
1396
1397 static const true_false_string tfs_cap_encryption = {
1398         "This host supports ENCRYPTION",
1399         "This host does NOT support ENCRYPTION"
1400 };
1401
1402 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rss = {
1403         "This interface supports RSS",
1404         "This interface does not support RSS"
1405 };
1406
1407 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rdma = {
1408         "This interface supports RDMA",
1409         "This interface does not support RDMA"
1410 };
1411
1412 static const value_string file_region_usage_vals[] = {
1413         { 0x00000001, "FILE_REGION_USAGE_VALID_CACHED_DATA" },
1414         { 0, NULL }
1415 };
1416
1417 static const value_string originator_flags_vals[] = {
1418         { 1, "SVHDX_ORIGINATOR_PVHDPARSER" },
1419         { 4, "SVHDX_ORIGINATOR_VHDMP" },
1420         { 0, NULL }
1421 };
1422
1423 static const value_string posix_locks_vals[] = {
1424         { 1, "POSIX_V1_POSIX_LOCK" },
1425         { 0, NULL }
1426 };
1427
1428 static const value_string posix_utf8_paths_vals[] = {
1429         { 1, "POSIX_V1_UTF8_PATHS" },
1430         { 0, NULL }
1431 };
1432
1433 static const value_string posix_file_semantics_vals[] = {
1434         { 1, "POSIX_V1_POSIX_FILE_SEMANTICS" },
1435         { 0, NULL }
1436 };
1437
1438 static const value_string posix_case_sensitive_vals[] = {
1439         { 1, "POSIX_V1_CASE_SENSITIVE" },
1440         { 0, NULL }
1441 };
1442
1443 static const value_string posix_will_convert_ntacls_vals[] = {
1444         { 1, "POSIX_V1_WILL_CONVERT_NT_ACLS" },
1445         { 0, NULL }
1446 };
1447
1448 static const value_string posix_fileinfo_vals[] = {
1449         { 1, "POSIX_V1_POSIX_FILEINFO" },
1450         { 0, NULL }
1451 };
1452
1453 static const value_string posix_acls_vals[] = {
1454         { 1, "POSIX_V1_POSIX_ACLS" },
1455         { 0, NULL }
1456 };
1457
1458 static const value_string posix_rich_acls_vals[] = {
1459         { 1, "POSIX_V1_RICH_ACLS" },
1460         { 0, NULL }
1461 };
1462
1463 static const value_string compression_format_vals[] = {
1464         { 0, "COMPRESSION_FORMAT_NONE" },
1465         { 1, "COMPRESSION_FORMAT_DEFAULT" },
1466         { 2, "COMPRESSION_FORMAT_LZNT1" },
1467         { 0, NULL }
1468 };
1469
1470 static const value_string checksum_algorithm_vals[] = {
1471         { 0x0000, "CHECKSUM_TYPE_NONE" },
1472         { 0x0002, "CHECKSUM_TYPE_CRC64" },
1473         { 0xFFFF, "CHECKSUM_TYPE_UNCHANGED" },
1474         { 0, NULL }
1475 };
1476
1477 /* Note: All uncommented are "dissector not implemented" */
1478 static const value_string smb2_ioctl_vals[] = {
1479         {0x00060194, "FSCTL_DFS_GET_REFERRALS"},                      /* dissector implemented */
1480         {0x000601B0, "FSCTL_DFS_GET_REFERRALS_EX"},
1481         {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
1482         {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
1483         {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
1484         {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
1485         {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
1486         {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
1487         {0x00090018, "FSCTL_LOCK_VOLUME"},
1488         {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
1489         {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
1490         {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
1491         {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
1492         {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
1493         {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
1494         {0x0009003C, "FSCTL_GET_COMPRESSION"},                        /* dissector implemented */
1495         {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
1496         {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
1497         {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
1498         {0x00090058, "FSCTL_QUERY_FAT_BPB"},
1499         {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
1500         {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
1501         {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
1502         {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
1503         {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
1504         {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
1505         {0x00090074, "FSCTL_MOVE_FILE"},
1506         {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
1507         {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
1508         {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
1509         {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
1510         {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
1511         {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
1512         {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
1513         {0x0009009C, "FSCTL_GET_OBJECT_ID"},                          /* dissector implemented */
1514         {0x000900A4, "FSCTL_SET_REPARSE_POINT"},
1515         {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
1516         {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},                /* dissector implemented */
1517         {0x000900C4, "FSCTL_SET_SPARSE"},                             /* dissector implemented */
1518         {0x000900D4, "FSCTL_SET_ENCRYPTION"},
1519         {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
1520         {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
1521         {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
1522         {0x000900F0, "FSCTL_EXTEND_VOLUME"},
1523         {0x0009027C, "FSCTL_GET_INTEGRITY_INFORMATION"},
1524         {0x00090284, "FSCTL_QUERY_FILE_REGIONS"},
1525         {0x00090300, "FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT"},      /* dissector implemented */
1526         {0x00090304, "FSCTL_SVHDX_SYNC_TUNNEL_REQUEST"},              /* dissector implemented */
1527         {0x00090308, "FSCTL_SVHDX_SET_INITIATOR_INFORMATION"},
1528         {0x0009030C, "FSCTL_SET_EXTERNAL_BACKING"},
1529         {0x00090310, "FSCTL_GET_EXTERNAL_BACKING"},
1530         {0x00090314, "FSCTL_DELETE_EXTERNAL_BACKING"},
1531         {0x00090318, "FSCTL_ENUM_EXTERNAL_BACKING"},
1532         {0x0009031F, "FSCTL_ENUM_OVERLAY"},
1533         {0x000940B3, "FSCTL_ENUM_USN_DATA"},
1534         {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
1535         {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
1536         {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},                 /* dissector implemented */
1537         {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
1538         {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
1539         {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
1540         {0x00094264, "FSCTL_OFFLOAD_READ"},                           /* dissector implemented */
1541         {0x00098098, "FSCTL_SET_OBJECT_ID"},                          /* dissector implemented */
1542         {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
1543         {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
1544         {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
1545         {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},                 /* dissector implemented */
1546         {0x000980C8, "FSCTL_SET_ZERO_DATA"},                          /* dissector implemented */
1547         {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
1548         {0x00098208, "FSCTL_FILE_LEVEL_TRIM"},
1549         {0x00098268, "FSCTL_OFFLOAD_WRITE"},                          /* dissector implemented */
1550         {0x0009C040, "FSCTL_SET_COMPRESSION"},                        /* dissector implemented */
1551         {0x0009C280, "FSCTL_SET_INTEGRITY_INFORMATION"},              /* dissector implemented */
1552         {0x00110018, "FSCTL_PIPE_WAIT"},                              /* dissector implemented */
1553         {0x0011400C, "FSCTL_PIPE_PEEK"},
1554         {0x0011C017, "FSCTL_PIPE_TRANSCEIVE"},                        /* dissector implemented */
1555         {0x00140078, "FSCTL_SRV_REQUEST_RESUME_KEY"},
1556         {0x001401D4, "FSCTL_LMR_REQUEST_RESILIENCY"},                 /* dissector implemented */
1557         {0x001401FC, "FSCTL_QUERY_NETWORK_INTERFACE_INFO"},           /* dissector implemented */
1558         {0x00140200, "FSCTL_VALIDATE_NEGOTIATE_INFO_224"},            /* dissector implemented */
1559         {0x00140204, "FSCTL_VALIDATE_NEGOTIATE_INFO"},                /* dissector implemented */
1560         {0x00144064, "FSCTL_SRV_ENUMERATE_SNAPSHOTS"},                /* dissector implemented */
1561         {0x001440F2, "FSCTL_SRV_COPYCHUNK"},
1562         {0x001441bb, "FSCTL_SRV_READ_HASH"},
1563         {0x001480F2, "FSCTL_SRV_COPYCHUNK_WRITE"},
1564         { 0, NULL }
1565 };
1566 static value_string_ext smb2_ioctl_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_vals);
1567
1568 static const value_string smb2_ioctl_device_vals[] = {
1569         { 0x0001, "BEEP" },
1570         { 0x0002, "CD_ROM" },
1571         { 0x0003, "CD_ROM_FILE_SYSTEM" },
1572         { 0x0004, "CONTROLLER" },
1573         { 0x0005, "DATALINK" },
1574         { 0x0006, "DFS" },
1575         { 0x0007, "DISK" },
1576         { 0x0008, "DISK_FILE_SYSTEM" },
1577         { 0x0009, "FILE_SYSTEM" },
1578         { 0x000a, "INPORT_PORT" },
1579         { 0x000b, "KEYBOARD" },
1580         { 0x000c, "MAILSLOT" },
1581         { 0x000d, "MIDI_IN" },
1582         { 0x000e, "MIDI_OUT" },
1583         { 0x000f, "MOUSE" },
1584         { 0x0010, "MULTI_UNC_PROVIDER" },
1585         { 0x0011, "NAMED_PIPE" },
1586         { 0x0012, "NETWORK" },
1587         { 0x0013, "NETWORK_BROWSER" },
1588         { 0x0014, "NETWORK_FILE_SYSTEM" },
1589         { 0x0015, "NULL" },
1590         { 0x0016, "PARALLEL_PORT" },
1591         { 0x0017, "PHYSICAL_NETCARD" },
1592         { 0x0018, "PRINTER" },
1593         { 0x0019, "SCANNER" },
1594         { 0x001a, "SERIAL_MOUSE_PORT" },
1595         { 0x001b, "SERIAL_PORT" },
1596         { 0x001c, "SCREEN" },
1597         { 0x001d, "SOUND" },
1598         { 0x001e, "STREAMS" },
1599         { 0x001f, "TAPE" },
1600         { 0x0020, "TAPE_FILE_SYSTEM" },
1601         { 0x0021, "TRANSPORT" },
1602         { 0x0022, "UNKNOWN" },
1603         { 0x0023, "VIDEO" },
1604         { 0x0024, "VIRTUAL_DISK" },
1605         { 0x0025, "WAVE_IN" },
1606         { 0x0026, "WAVE_OUT" },
1607         { 0x0027, "8042_PORT" },
1608         { 0x0028, "NETWORK_REDIRECTOR" },
1609         { 0x0029, "BATTERY" },
1610         { 0x002a, "BUS_EXTENDER" },
1611         { 0x002b, "MODEM" },
1612         { 0x002c, "VDM" },
1613         { 0x002d, "MASS_STORAGE" },
1614         { 0x002e, "SMB" },
1615         { 0x002f, "KS" },
1616         { 0x0030, "CHANGER" },
1617         { 0x0031, "SMARTCARD" },
1618         { 0x0032, "ACPI" },
1619         { 0x0033, "DVD" },
1620         { 0x0034, "FULLSCREEN_VIDEO" },
1621         { 0x0035, "DFS_FILE_SYSTEM" },
1622         { 0x0036, "DFS_VOLUME" },
1623         { 0x0037, "SERENUM" },
1624         { 0x0038, "TERMSRV" },
1625         { 0x0039, "KSEC" },
1626         { 0, NULL }
1627 };
1628 static value_string_ext smb2_ioctl_device_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_device_vals);
1629
1630 static const value_string smb2_ioctl_access_vals[] = {
1631         { 0x00, "FILE_ANY_ACCESS" },
1632         { 0x01, "FILE_READ_ACCESS" },
1633         { 0x02, "FILE_WRITE_ACCESS" },
1634         { 0x03, "FILE_READ_WRITE_ACCESS" },
1635         { 0, NULL }
1636 };
1637
1638 static const value_string smb2_ioctl_method_vals[] = {
1639         { 0x00, "METHOD_BUFFERED" },
1640         { 0x01, "METHOD_IN_DIRECT" },
1641         { 0x02, "METHOD_OUT_DIRECT" },
1642         { 0x03, "METHOD_NEITHER" },
1643         { 0, NULL }
1644 };
1645
1646 /* this is called from both smb and smb2. */
1647 int
1648 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
1649 {
1650         proto_item *item = NULL;
1651         proto_tree *tree = NULL;
1652         guint32     ioctl_function;
1653
1654         if (parent_tree) {
1655                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1656                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
1657         }
1658
1659         ioctl_function = tvb_get_letohl(tvb, offset);
1660         if (ioctlfunc)
1661                 *ioctlfunc = ioctl_function;
1662         if (ioctl_function) {
1663                 const gchar *unknown = "unknown";
1664                 const gchar *ioctl_name = val_to_str_ext_const(ioctl_function,
1665                                                                &smb2_ioctl_vals_ext,
1666                                                                unknown);
1667
1668                 /*
1669                  * val_to_str_const() doesn't work with a unknown == NULL
1670                  */
1671                 if (ioctl_name == unknown) {
1672                         ioctl_name = NULL;
1673                 }
1674
1675                 if (ioctl_name != NULL) {
1676                         col_append_fstr(
1677                                 pinfo->cinfo, COL_INFO, " %s", ioctl_name);
1678                 }
1679
1680                 /* device */
1681                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1682                 if (ioctl_name == NULL) {
1683                         col_append_fstr(
1684                                 pinfo->cinfo, COL_INFO, " %s",
1685                                 val_to_str_ext((ioctl_function>>16)&0xffff, &smb2_ioctl_device_vals_ext,
1686                                 "Unknown (0x%08X)"));
1687                 }
1688
1689                 /* access */
1690                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1691
1692                 /* function */
1693                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1694                 if (ioctl_name == NULL) {
1695                         col_append_fstr(
1696                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
1697                                 (ioctl_function>>2)&0x0fff);
1698                 }
1699
1700                 /* method */
1701                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1702         }
1703
1704         offset += 4;
1705
1706         return offset;
1707 }
1708
1709 /* fake the dce/rpc support structures so we can piggy back on
1710  * dissect_nt_policy_hnd()   since this will allow us
1711  * a cheap way to track where FIDs are opened, closed
1712  * and fid->filename mappings
1713  * if we want to do those things in the future.
1714  */
1715 #define FID_MODE_OPEN           0
1716 #define FID_MODE_CLOSE          1
1717 #define FID_MODE_USE            2
1718 #define FID_MODE_DHNQ           3
1719 #define FID_MODE_DHNC           4
1720 static int
1721 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
1722 {
1723         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1724         static dcerpc_info        di; /* fake dcerpc_info struct */
1725         static dcerpc_call_value  call_data;
1726         e_ctx_hnd   policy_hnd;
1727         e_ctx_hnd   *policy_hnd_hashtablekey;
1728         proto_item *hnd_item   = NULL;
1729         char       *fid_name;
1730         guint32     open_frame = 0, close_frame = 0;
1731         smb2_eo_file_info_t     *eo_file_info;
1732         smb2_fid_info_t sfi_key;
1733         smb2_fid_info_t *sfi = NULL;
1734
1735         sfi_key.fid_persistent = tvb_get_letoh64(tvb, offset);
1736         sfi_key.fid_volatile = tvb_get_letoh64(tvb, offset+8);
1737         sfi_key.sesid = si->sesid;
1738         sfi_key.tid = si->tid;
1739         sfi_key.name = NULL;
1740
1741         di.conformant_run = 0;
1742         /* we need di->call_data->flags.NDR64 == 0 */
1743         di.call_data = &call_data;
1744
1745         switch (mode) {
1746         case FID_MODE_OPEN:
1747                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1748                 if (!pinfo->fd->flags.visited) {
1749                         sfi = wmem_new(wmem_file_scope(), smb2_fid_info_t);
1750                         *sfi = sfi_key;
1751                         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1752                                 sfi->name = wmem_strdup(wmem_file_scope(), (char *)si->saved->extra_info);
1753                         } else {
1754                                 sfi->name = wmem_strdup_printf(wmem_file_scope(), "[unknown]");
1755                         }
1756
1757                         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1758                                 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: %s", (char *)si->saved->extra_info);
1759                         } else {
1760                                 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: ");
1761                         }
1762                         dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1763                                                   fid_name);
1764
1765                         g_hash_table_insert(si->conv->fids, sfi, sfi);
1766                         si->file = sfi;
1767
1768                         /* If needed, create the file entry and save the policy hnd */
1769                         if (si->saved) {
1770                                 si->saved->file = sfi;
1771                                 si->saved->policy_hnd = policy_hnd;
1772                         }
1773
1774                         if (si->conv) {
1775                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1776                                 if (!eo_file_info) {
1777                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1778                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1779                                         memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1780                                         eo_file_info->end_of_file=0;
1781                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1782                                 }
1783                                 si->eo_file_info=eo_file_info;
1784                         }
1785                 }
1786                 break;
1787         case FID_MODE_CLOSE:
1788                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
1789                 break;
1790         case FID_MODE_USE:
1791         case FID_MODE_DHNQ:
1792         case FID_MODE_DHNC:
1793                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
1794                 break;
1795         }
1796
1797         si->file = (smb2_fid_info_t *)g_hash_table_lookup(si->conv->fids, &sfi_key);
1798         if (si->file) {
1799                 if (si->saved) {
1800                         si->saved->file = si->file;
1801                 }
1802                 if (si->file->name) {
1803                         if (hnd_item) {
1804                                 proto_item_append_text(hnd_item, " File: %s", si->file->name);
1805                         }
1806                         col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", si->file->name);
1807                 }
1808         }
1809
1810         if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
1811                 /* look for the eo_file_info */
1812                 if (!si->eo_file_info) {
1813                         if (si->saved) { si->saved->policy_hnd = policy_hnd; }
1814                         if (si->conv) {
1815                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1816                                 if (eo_file_info) {
1817                                         si->eo_file_info=eo_file_info;
1818                                 } else { /* XXX This should never happen */
1819                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1820                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1821                                         memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1822                                         eo_file_info->end_of_file=0;
1823                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1824                                 }
1825                         }
1826
1827                 }
1828         }
1829
1830         return offset;
1831 }
1832
1833
1834 /* this info level is unique to SMB2 and differst from the corresponding
1835  * SMB_FILE_ALL_INFO in SMB
1836  */
1837 static int
1838 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1839 {
1840         proto_item *item = NULL;
1841         proto_tree *tree = NULL;
1842         int         length;
1843         const char *name = "";
1844         guint16     bc;
1845
1846         if (parent_tree) {
1847                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
1848                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
1849         }
1850
1851         /* create time */
1852         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1853
1854         /* last access */
1855         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1856
1857         /* last write */
1858         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1859
1860         /* last change */
1861         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1862
1863         /* File Attributes */
1864         offset = dissect_file_ext_attr(tvb, tree, offset);
1865
1866         /* some unknown bytes */
1867         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
1868         offset += 4;
1869
1870         /* allocation size */
1871         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1872         offset += 8;
1873
1874         /* end of file */
1875         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1876         offset += 8;
1877
1878         /* number of links */
1879         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1880         offset += 4;
1881
1882         /* delete pending */
1883         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1884         offset += 1;
1885
1886         /* is directory */
1887         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1888         offset += 1;
1889
1890         /* padding */
1891         offset += 2;
1892
1893         /* file id */
1894         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1895         offset += 8;
1896
1897         /* ea size */
1898         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1899         offset += 4;
1900
1901         /* access mask */
1902         offset = dissect_smb_access_mask(tvb, tree, offset);
1903
1904         /* some unknown bytes */
1905         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
1906         offset += 16;
1907
1908         /* file name length */
1909         length = tvb_get_letohs(tvb, offset);
1910         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1911         offset += 4;
1912
1913         /* file name */
1914         if (length) {
1915                 bc = tvb_captured_length_remaining(tvb, offset);
1916                 name = get_unicode_or_ascii_string(tvb, &offset,
1917                         TRUE, &length, TRUE, TRUE, &bc);
1918                 if (name) {
1919                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1920                                 offset, length, name);
1921                 }
1922
1923         }
1924         offset += length;
1925
1926         return offset;
1927 }
1928
1929
1930 static int
1931 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1932 {
1933         proto_item *item = NULL;
1934         proto_tree *tree = NULL;
1935         guint16     bc;
1936         gboolean    trunc;
1937
1938         if (parent_tree) {
1939                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, ENC_NA);
1940                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1941         }
1942
1943         bc = tvb_captured_length_remaining(tvb, offset);
1944         offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1945
1946         return offset;
1947 }
1948
1949 static int
1950 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1951 {
1952         proto_item *item = NULL;
1953         proto_tree *tree = NULL;
1954         guint16     bc;
1955         gboolean    trunc;
1956
1957         if (parent_tree) {
1958                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, ENC_NA);
1959                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1960         }
1961
1962         bc = tvb_captured_length_remaining(tvb, offset);
1963         offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1964
1965         return offset;
1966 }
1967
1968 static int
1969 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1970 {
1971         proto_item *item = NULL;
1972         proto_tree *tree = NULL;
1973         guint16     bc;
1974         gboolean    trunc;
1975
1976         if (parent_tree) {
1977                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, ENC_NA);
1978                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1979         }
1980
1981         bc = tvb_captured_length_remaining(tvb, offset);
1982         offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
1983
1984         return offset;
1985 }
1986
1987
1988 static int
1989 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1990 {
1991         proto_item *item = NULL;
1992         proto_tree *tree = NULL;
1993
1994         if (parent_tree) {
1995                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, ENC_NA);
1996                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1997         }
1998
1999         /* create time */
2000         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2001
2002         /* last access */
2003         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2004
2005         /* last write */
2006         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2007
2008         /* last change */
2009         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2010
2011         /* File Attributes */
2012         offset = dissect_file_ext_attr(tvb, tree, offset);
2013
2014         /* some unknown bytes */
2015         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2016         offset += 4;
2017
2018         return offset;
2019 }
2020
2021 static int
2022 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2023 {
2024         proto_item *item = NULL;
2025         proto_tree *tree = NULL;
2026         guint16     bc;
2027         gboolean    trunc;
2028
2029         if (parent_tree) {
2030                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, ENC_NA);
2031                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
2032         }
2033
2034         bc = tvb_captured_length_remaining(tvb, offset);
2035         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2036
2037         return offset;
2038 }
2039 static int
2040 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2041 {
2042         proto_item *item = NULL;
2043         proto_tree *tree = NULL;
2044         guint16     bc;
2045         gboolean    trunc;
2046
2047         if (parent_tree) {
2048                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, ENC_NA);
2049                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
2050         }
2051
2052         bc = tvb_captured_length_remaining(tvb, offset);
2053         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2054
2055         return offset;
2056 }
2057 static int
2058 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2059 {
2060         proto_item *item = NULL;
2061         proto_tree *tree = NULL;
2062         guint16     bc;
2063         gboolean    trunc;
2064
2065         if (parent_tree) {
2066                 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, ENC_NA);
2067                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
2068         }
2069
2070         bc = tvb_captured_length_remaining(tvb, offset);
2071         offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2072
2073         return offset;
2074 }
2075 static int
2076 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2077 {
2078         proto_item *item = NULL;
2079         proto_tree *tree = NULL;
2080         guint16     bc;
2081         gboolean    trunc;
2082
2083         if (parent_tree) {
2084                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, ENC_NA);
2085                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
2086         }
2087
2088         bc = tvb_captured_length_remaining(tvb, offset);
2089         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2090
2091         return offset;
2092 }
2093 static int
2094 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2095 {
2096         proto_item *item = NULL;
2097         proto_tree *tree = NULL;
2098         guint16     bc;
2099         gboolean    trunc;
2100
2101         if (parent_tree) {
2102                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, ENC_NA);
2103                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
2104         }
2105
2106         bc = tvb_captured_length_remaining(tvb, offset);
2107         offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2108
2109         return offset;
2110 }
2111
2112 static int
2113 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2114 {
2115         proto_item *item = NULL;
2116         proto_tree *tree = NULL;
2117
2118         if (parent_tree) {
2119                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, ENC_NA);
2120                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
2121         }
2122
2123         /* access mask */
2124         offset = dissect_smb_access_mask(tvb, tree, offset);
2125
2126         return offset;
2127 }
2128
2129 static int
2130 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2131 {
2132         proto_item *item = NULL;
2133         proto_tree *tree = NULL;
2134         guint16     bc;
2135         gboolean    trunc;
2136
2137         if (parent_tree) {
2138                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, ENC_NA);
2139                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
2140         }
2141
2142         bc = tvb_captured_length_remaining(tvb, offset);
2143         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2144
2145         return offset;
2146 }
2147
2148 static int
2149 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2150 {
2151         proto_item *item = NULL;
2152         proto_tree *tree = NULL;
2153         guint16     bc;
2154         gboolean    trunc;
2155
2156         if (parent_tree) {
2157                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, ENC_NA);
2158                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
2159         }
2160
2161         bc = tvb_captured_length_remaining(tvb, offset);
2162         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
2163
2164         return offset;
2165 }
2166
2167 static int
2168 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2169 {
2170         proto_item *item = NULL;
2171         proto_tree *tree = NULL;
2172         guint16     bc;
2173         gboolean    trunc;
2174
2175         if (parent_tree) {
2176                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, ENC_NA);
2177                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
2178         }
2179
2180         bc = tvb_captured_length_remaining(tvb, offset);
2181         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2182
2183         return offset;
2184 }
2185
2186 static int
2187 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2188 {
2189         proto_item *item = NULL;
2190         proto_tree *tree = NULL;
2191         guint16     bc;
2192         gboolean    trunc;
2193
2194         if (parent_tree) {
2195                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, ENC_NA);
2196                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
2197         }
2198
2199         bc = tvb_captured_length_remaining(tvb, offset);
2200         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2201
2202         return offset;
2203 }
2204
2205 static int
2206 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2207 {
2208         proto_item *item = NULL;
2209         proto_tree *tree = NULL;
2210         guint16     bc;
2211         gboolean    trunc;
2212
2213         if (parent_tree) {
2214                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, ENC_NA);
2215                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
2216         }
2217
2218
2219         bc = tvb_captured_length_remaining(tvb, offset);
2220         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2221
2222         return offset;
2223 }
2224
2225 static int
2226 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2227 {
2228         proto_item *item = NULL;
2229         proto_tree *tree = NULL;
2230         guint16     bc;
2231         gboolean    trunc;
2232
2233         if (parent_tree) {
2234                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, ENC_NA);
2235                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
2236         }
2237
2238
2239         bc = tvb_captured_length_remaining(tvb, offset);
2240         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2241
2242         return offset;
2243 }
2244
2245 static const true_false_string tfs_disposition_delete_on_close = {
2246         "DELETE this file when closed",
2247         "Normal access, do not delete on close"
2248 };
2249
2250 static int
2251 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2252 {
2253         proto_item *item = NULL;
2254         proto_tree *tree = NULL;
2255
2256         if (parent_tree) {
2257                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, ENC_NA);
2258                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
2259         }
2260
2261         /* file disposition */
2262         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2263
2264         return offset;
2265 }
2266
2267 static int
2268 dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2269 {
2270         proto_item *item = NULL;
2271         proto_tree *tree = NULL;
2272         guint32     next_offset;
2273         guint8      ea_name_len;
2274         guint16     ea_data_len;
2275
2276         if (parent_tree) {
2277                 item = proto_tree_add_item(parent_tree, hf_smb2_file_full_ea_info, tvb, offset, -1, ENC_NA);
2278                 tree = proto_item_add_subtree(item, ett_smb2_file_full_ea_info);
2279         }
2280
2281         while (1) {
2282                 int length;
2283                 const char *name = "";
2284                 const char *data = "";
2285                 guint16 bc;
2286                 int start_offset = offset;
2287                 proto_item *ea_item;
2288                 proto_tree *ea_tree;
2289
2290                 ea_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_ea, &ea_item, "EA:");
2291
2292                 /* next offset */
2293                 next_offset = tvb_get_letohl(tvb, offset);
2294                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2295                 offset += 4;
2296
2297                 /* EA flags */
2298                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2299                 offset += 1;
2300
2301                 /* EA Name Length */
2302                 ea_name_len = tvb_get_guint8(tvb, offset);
2303                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2304                 offset += 1;
2305
2306                 /* EA Data Length */
2307                 ea_data_len = tvb_get_letohs(tvb, offset);
2308                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2309                 offset += 2;
2310
2311                 /* ea name */
2312                 length = ea_name_len;
2313                 if (length) {
2314                         bc = tvb_captured_length_remaining(tvb, offset);
2315                         name = get_unicode_or_ascii_string(tvb, &offset,
2316                                 FALSE, &length, TRUE, TRUE, &bc);
2317                         if (name) {
2318                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
2319                                         offset, length + 1, name);
2320                         }
2321                 }
2322
2323                 /* The name is terminated with a NULL */
2324                 offset += ea_name_len + 1;
2325
2326                 /* ea data */
2327                 length = ea_data_len;
2328                 if (length) {
2329                         bc = tvb_captured_length_remaining(tvb, offset);
2330                         data = get_unicode_or_ascii_string(tvb, &offset,
2331                                 FALSE, &length, TRUE, TRUE, &bc);
2332                         /*
2333                          * We put the data here ...
2334                          */
2335                         proto_tree_add_item(ea_tree, hf_smb2_ea_data, tvb,
2336                                         offset, length, ENC_NA);
2337                 }
2338                 offset += ea_data_len;
2339
2340
2341                 if (ea_item) {
2342                         proto_item_append_text(ea_item, " %s := %s", name, data);
2343                 }
2344                 proto_item_set_len(ea_item, offset-start_offset);
2345
2346
2347                 if (!next_offset) {
2348                         break;
2349                 }
2350
2351                 offset = start_offset+next_offset;
2352         }
2353
2354         return offset;
2355 }
2356
2357 static const true_false_string tfs_replace_if_exists = {
2358         "Replace the target if it exists",
2359         "Fail if the target exists"
2360 };
2361
2362 static int
2363 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2364 {
2365         proto_item *item = NULL;
2366         proto_tree *tree = NULL;
2367         int         length;
2368         const char *name = "";
2369         guint16     bc;
2370
2371
2372         if (parent_tree) {
2373                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, ENC_NA);
2374                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
2375         }
2376
2377         /* ReplaceIfExists */
2378         proto_tree_add_item(tree, hf_smb2_replace_if, tvb, offset, 1, ENC_NA);
2379         offset += 1;
2380
2381         /* reserved */
2382         proto_tree_add_item(tree, hf_smb2_reserved_random, tvb, offset, 7, ENC_NA);
2383         offset += 7;
2384
2385         /* Root Directory Handle, MBZ */
2386         proto_tree_add_item(tree, hf_smb2_root_directory_mbz, tvb, offset, 8, ENC_NA);
2387         offset += 8;
2388
2389         /* file name length */
2390         length = tvb_get_letohs(tvb, offset);
2391         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2392         offset += 4;
2393
2394         /* file name */
2395         if (length) {
2396                 bc = tvb_captured_length_remaining(tvb, offset);
2397                 name = get_unicode_or_ascii_string(tvb, &offset,
2398                         TRUE, &length, TRUE, TRUE, &bc);
2399                 if (name) {
2400                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
2401                                 offset, length, name);
2402                 }
2403
2404                 col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s", name);
2405         }
2406         offset += length;
2407
2408         return offset;
2409 }
2410
2411 static int
2412 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2413 {
2414         proto_item *item = NULL;
2415         proto_tree *tree = NULL;
2416
2417         if (parent_tree) {
2418                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, ENC_NA);
2419                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
2420         }
2421
2422         /* security descriptor */
2423         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_captured_length_remaining(tvb, offset), NULL);
2424
2425         return offset;
2426 }
2427
2428 static int
2429 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2430 {
2431         proto_item *item = NULL;
2432         proto_tree *tree = NULL;
2433         guint16     bc;
2434
2435         if (parent_tree) {
2436                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, ENC_NA);
2437                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
2438         }
2439
2440         bc = tvb_captured_length_remaining(tvb, offset);
2441         offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2442
2443         return offset;
2444 }
2445
2446 static int
2447 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2448 {
2449         proto_item *item = NULL;
2450         proto_tree *tree = NULL;
2451         guint16     bc;
2452
2453         if (parent_tree) {
2454                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, ENC_NA);
2455                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
2456         }
2457
2458         bc = tvb_captured_length_remaining(tvb, offset);
2459         offset = dissect_nt_quota(tvb, tree, offset, &bc);
2460
2461         return offset;
2462 }
2463
2464 static int
2465 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2466 {
2467         proto_item *item = NULL;
2468         proto_tree *tree = NULL;
2469
2470         if (parent_tree) {
2471                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, ENC_NA);
2472                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
2473         }
2474
2475         /* FILE_OBJECTID_BUFFER */
2476         offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2477
2478         return offset;
2479 }
2480
2481 static int
2482 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2483 {
2484         proto_item *item = NULL;
2485         proto_tree *tree = NULL;
2486         guint16     bc;
2487
2488         if (parent_tree) {
2489                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, ENC_NA);
2490                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
2491         }
2492
2493         bc = tvb_captured_length_remaining(tvb, offset);
2494         offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2495
2496         return offset;
2497 }
2498
2499 static int
2500 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2501 {
2502         proto_item *item = NULL;
2503         proto_tree *tree = NULL;
2504         guint16     bc;
2505
2506         if (parent_tree) {
2507                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, ENC_NA);
2508                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
2509         }
2510
2511
2512         bc = tvb_captured_length_remaining(tvb, offset);
2513         offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2514
2515         return offset;
2516 }
2517
2518 static int
2519 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2520 {
2521         proto_item *item = NULL;
2522         proto_tree *tree = NULL;
2523         guint16     bc;
2524
2525         if (parent_tree) {
2526                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, ENC_NA);
2527                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
2528         }
2529
2530
2531         bc = tvb_captured_length_remaining(tvb, offset);
2532         offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2533
2534         return offset;
2535 }
2536
2537 static int
2538 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2539 {
2540         proto_item *item = NULL;
2541         proto_tree *tree = NULL;
2542         guint16     bc;
2543
2544         if (parent_tree) {
2545                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, ENC_NA);
2546                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
2547         }
2548
2549
2550         bc = tvb_captured_length_remaining(tvb, offset);
2551         offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
2552
2553         return offset;
2554 }
2555
2556 static const value_string oplock_vals[] = {
2557         { 0x00, "No oplock" },
2558         { 0x01, "Level2 oplock" },
2559         { 0x08, "Exclusive oplock" },
2560         { 0x09, "Batch oplock" },
2561         { 0xff, "Lease" },
2562         { 0, NULL }
2563 };
2564
2565 static int
2566 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2567 {
2568         proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2569
2570         offset += 1;
2571         return offset;
2572 }
2573
2574 static int
2575 dissect_smb2_buffercode(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 *length)
2576 {
2577         proto_tree *tree;
2578         proto_item *item;
2579         guint16 buffer_code;
2580
2581         /* dissect the first 2 bytes of the command PDU */
2582         buffer_code = tvb_get_letohs(tvb, offset);
2583         item = proto_tree_add_uint(parent_tree, hf_smb2_buffer_code, tvb, offset, 2, buffer_code);
2584         tree = proto_item_add_subtree(item, ett_smb2_buffercode);
2585         proto_tree_add_item(tree, hf_smb2_buffer_code_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2586         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2587         offset += 2;
2588
2589         if (length) {
2590                 *length = buffer_code; /*&0xfffe don't mask it here, mask it on caller side */
2591         }
2592
2593         return offset;
2594 }
2595
2596 #define NEGPROT_CAP_DFS         0x00000001
2597 #define NEGPROT_CAP_LEASING     0x00000002
2598 #define NEGPROT_CAP_LARGE_MTU   0x00000004
2599 #define NEGPROT_CAP_MULTI_CHANNEL       0x00000008
2600 #define NEGPROT_CAP_PERSISTENT_HANDLES  0x00000010
2601 #define NEGPROT_CAP_DIRECTORY_LEASING   0x00000020
2602 #define NEGPROT_CAP_ENCRYPTION          0x00000040
2603 static int
2604 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2605 {
2606         static const int * flags[] = {
2607                 &hf_smb2_cap_dfs,
2608                 &hf_smb2_cap_leasing,
2609                 &hf_smb2_cap_large_mtu,
2610                 &hf_smb2_cap_multi_channel,
2611                 &hf_smb2_cap_persistent_handles,
2612                 &hf_smb2_cap_directory_leasing,
2613                 &hf_smb2_cap_encryption,
2614                 NULL
2615         };
2616
2617         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_capabilities, ett_smb2_capabilities, flags, ENC_LITTLE_ENDIAN);
2618         offset += 4;
2619
2620         return offset;
2621 }
2622
2623
2624
2625 #define NEGPROT_SIGN_REQ        0x0002
2626 #define NEGPROT_SIGN_ENABLED    0x0001
2627
2628 static int
2629 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2630 {
2631         static const int * flags[] = {
2632                 &hf_smb2_secmode_flags_sign_enabled,
2633                 &hf_smb2_secmode_flags_sign_required,
2634                 NULL
2635         };
2636
2637         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_security_mode, ett_smb2_sec_mode, flags, ENC_LITTLE_ENDIAN);
2638         offset += 1;
2639
2640         return offset;
2641 }
2642
2643 #define SES_REQ_FLAGS_SESSION_BINDING           0x01
2644
2645 static int
2646 dissect_smb2_ses_req_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2647 {
2648         static const int * flags[] = {
2649                 &hf_smb2_ses_req_flags_session_binding,
2650                 NULL
2651         };
2652
2653         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_ses_req_flags, ett_smb2_ses_req_flags, flags, ENC_LITTLE_ENDIAN);
2654         offset += 1;
2655
2656         return offset;
2657 }
2658
2659 #define SES_FLAGS_GUEST         0x0001
2660 #define SES_FLAGS_NULL          0x0002
2661
2662 static int
2663 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2664 {
2665         static const int * flags[] = {
2666                 &hf_smb2_ses_flags_guest,
2667                 &hf_smb2_ses_flags_null,
2668                 NULL
2669         };
2670
2671         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_session_flags, ett_smb2_ses_flags, flags, ENC_LITTLE_ENDIAN);
2672         offset += 2;
2673
2674         return offset;
2675 }
2676
2677 #define SHARE_FLAGS_manual_caching              0x00000000
2678 #define SHARE_FLAGS_auto_caching                0x00000010
2679 #define SHARE_FLAGS_vdo_caching                 0x00000020
2680 #define SHARE_FLAGS_no_caching                  0x00000030
2681
2682 static const value_string share_cache_vals[] = {
2683         { SHARE_FLAGS_manual_caching,   "Manual caching" },
2684         { SHARE_FLAGS_auto_caching,     "Auto caching" },
2685         { SHARE_FLAGS_vdo_caching,      "VDO caching" },
2686         { SHARE_FLAGS_no_caching,       "No caching" },
2687         { 0, NULL }
2688 };
2689
2690 #define SHARE_FLAGS_dfs                         0x00000001
2691 #define SHARE_FLAGS_dfs_root                    0x00000002
2692 #define SHARE_FLAGS_restrict_exclusive_opens    0x00000100
2693 #define SHARE_FLAGS_force_shared_delete         0x00000200
2694 #define SHARE_FLAGS_allow_namespace_caching     0x00000400
2695 #define SHARE_FLAGS_access_based_dir_enum       0x00000800
2696 #define SHARE_FLAGS_force_levelii_oplock        0x00001000
2697 #define SHARE_FLAGS_enable_hash_v1              0x00002000
2698 #define SHARE_FLAGS_enable_hash_v2              0x00004000
2699 #define SHARE_FLAGS_encryption_required         0x00008000
2700
2701 static int
2702 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
2703 {
2704         static const int *sf_fields[] = {
2705                 &hf_smb2_share_flags_dfs,
2706                 &hf_smb2_share_flags_dfs_root,
2707                 &hf_smb2_share_flags_restrict_exclusive_opens,
2708                 &hf_smb2_share_flags_force_shared_delete,
2709                 &hf_smb2_share_flags_allow_namespace_caching,
2710                 &hf_smb2_share_flags_access_based_dir_enum,
2711                 &hf_smb2_share_flags_force_levelii_oplock,
2712                 &hf_smb2_share_flags_enable_hash_v1,
2713                 &hf_smb2_share_flags_enable_hash_v2,
2714                 &hf_smb2_share_flags_encrypt_data,
2715                 NULL
2716         };
2717         proto_item *item;
2718         guint32 cp;
2719
2720         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, ENC_LITTLE_ENDIAN);
2721
2722         cp = tvb_get_letohl(tvb, offset);
2723         cp &= 0x00000030;
2724         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);
2725
2726
2727         offset += 4;
2728
2729         return offset;
2730 }
2731
2732 #define SHARE_CAPS_DFS                          0x00000008
2733 #define SHARE_CAPS_CONTINUOUS_AVAILABILITY      0x00000010
2734 #define SHARE_CAPS_SCALEOUT                     0x00000020
2735 #define SHARE_CAPS_CLUSTER                      0x00000040
2736
2737 static int
2738 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
2739 {
2740         static const int *sc_fields[] = {
2741                 &hf_smb2_share_caps_dfs,
2742                 &hf_smb2_share_caps_continuous_availability,
2743                 &hf_smb2_share_caps_scaleout,
2744                 &hf_smb2_share_caps_cluster,
2745                 NULL
2746         };
2747
2748         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, ENC_LITTLE_ENDIAN);
2749
2750         offset += 4;
2751
2752         return offset;
2753 }
2754
2755 static void
2756 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
2757 {
2758         if ((tvb_captured_length(tvb)>=7)
2759         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))) {
2760                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
2761         } else {
2762                 call_dissector(gssapi_handle, tvb, pinfo, tree);
2763         }
2764 }
2765
2766 static int
2767 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2768 {
2769         offset_length_buffer_t  s_olb;
2770         const ntlmssp_header_t *ntlmssph;
2771         static int ntlmssp_tap_id = 0;
2772         int        idx;
2773
2774         if (!ntlmssp_tap_id) {
2775                 GString *error_string;
2776                 /* We don't specify any callbacks at all.
2777                  * Instead we manually fetch the tapped data after the
2778                  * security blob has been fully dissected and before
2779                  * we exit from this dissector.
2780                  */
2781                 error_string = register_tap_listener("ntlmssp", NULL, NULL,
2782                     TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
2783                 if (!error_string) {
2784                         ntlmssp_tap_id = find_tap_id("ntlmssp");
2785                 } else {
2786                         g_string_free(error_string, TRUE);
2787                 }
2788         }
2789
2790
2791         /* buffer code */
2792         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2793         /* some unknown bytes */
2794
2795         /* flags */
2796         offset = dissect_smb2_ses_req_flags(tree, tvb, offset);
2797
2798         /* security mode */
2799         offset = dissect_smb2_secmode(tree, tvb, offset);
2800
2801         /* capabilities */
2802         offset = dissect_smb2_capabilities(tree, tvb, offset);
2803
2804         /* channel */
2805         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2806         offset += 4;
2807
2808         /* security blob offset/length */
2809         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2810
2811         /* previous session id */
2812         proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2813         offset += 8;
2814
2815
2816         /* the security blob itself */
2817         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2818
2819         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2820
2821         /* If we have found a uid->acct_name mapping, store it */
2822         if (!pinfo->fd->flags.visited) {
2823                 idx = 0;
2824                 while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
2825                         if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
2826                                 smb2_sesid_info_t *sesid;
2827                                 sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
2828                                 sesid->sesid = si->sesid;
2829                                 sesid->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
2830                                 sesid->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
2831                                 sesid->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
2832                                 if (memcmp(ntlmssph->session_key, zeros, NTLMSSP_KEY_LEN) != 0) {
2833                                         smb2_key_derivation(ntlmssph->session_key,
2834                                                             NTLMSSP_KEY_LEN,
2835                                                             "SMB2AESCCM", 11,
2836                                                             "ServerIn ", 10,
2837                                                             sesid->server_decryption_key);
2838                                         smb2_key_derivation(ntlmssph->session_key,
2839                                                             NTLMSSP_KEY_LEN,
2840                                                             "SMB2AESCCM", 11,
2841                                                             "ServerOut", 10,
2842                                                             sesid->client_decryption_key);
2843                                 } else {
2844                                         memset(sesid->server_decryption_key, 0,
2845                                                sizeof(sesid->server_decryption_key));
2846                                         memset(sesid->client_decryption_key, 0,
2847                                                sizeof(sesid->client_decryption_key));
2848                                 }
2849                                 sesid->server_port = pinfo->destport;
2850                                 sesid->auth_frame = pinfo->num;
2851                                 sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2852                                 g_hash_table_insert(si->conv->sesids, sesid, sesid);
2853                         }
2854                 }
2855         }
2856
2857         return offset;
2858 }
2859
2860 /* This needs more fixes for cases when the original header had also the constant value of 9.
2861    This should be fixed on caller side where it decides if it has to call this or not.
2862 */
2863 static int
2864 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_,
2865                                                         gboolean* continue_dissection)
2866 {
2867         gint byte_count;
2868         guint16 length;
2869
2870         /* buffer code */
2871         offset = dissect_smb2_buffercode(tree, tvb, offset, &length);
2872
2873         /* FIX: error response uses this constant, if not then it is not an error response */
2874         if(length != 9)
2875         {
2876                 if(continue_dissection)
2877                         *continue_dissection = TRUE;
2878         } else {
2879                 if(continue_dissection)
2880                         *continue_dissection = FALSE;
2881
2882                 /* Reserved (2 bytes) */
2883                 proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2884                 offset += 2;
2885
2886                 /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
2887                 byte_count = tvb_get_ntohl(tvb, offset);
2888                 proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2889                 offset += 4;
2890
2891                 /* If the ByteCount field is zero then the server MUST supply an ErrorData field
2892                    that is one byte in length */
2893                 if (byte_count == 0) byte_count = 1;
2894
2895                 /* ErrorData (variable): A variable-length data field that contains extended
2896                    error information.*/
2897                 proto_tree_add_item(tree, hf_smb2_error_data, tvb, offset, byte_count, ENC_NA);
2898                 offset += byte_count;
2899         }
2900
2901         return offset;
2902 }
2903
2904 static int
2905 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2906 {
2907         offset_length_buffer_t s_olb;
2908
2909         /* session_setup is special and we don't use dissect_smb2_error_response() here! */
2910
2911         /* buffer code */
2912         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2913
2914         /* session flags */
2915         offset = dissect_smb2_ses_flags(tree, tvb, offset);
2916
2917         /* security blob offset/length */
2918         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2919
2920         /* the security blob itself */
2921         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2922
2923         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2924
2925         /* If we have found a uid->acct_name mapping, store it */
2926 #ifdef HAVE_KERBEROS
2927         if (!pinfo->fd->flags.visited && si->status == 0) {
2928                 enc_key_t *ek;
2929
2930                 if (krb_decrypt) {
2931                         read_keytab_file_from_preferences();
2932                 }
2933
2934                 for (ek=enc_key_list;ek;ek=ek->next) {
2935                         if (ek->fd_num == (int)pinfo->num) {
2936                                 break;
2937                         }
2938                 }
2939
2940                 if (ek != NULL) {
2941                         smb2_sesid_info_t *sesid;
2942                         guint8 session_key[16] = { 0, };
2943
2944                         memcpy(session_key, ek->keyvalue, MIN(ek->keylength, 16));
2945
2946                         sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
2947                         sesid->sesid = si->sesid;
2948                         /* TODO: fill in the correct information */
2949                         sesid->acct_name = NULL;
2950                         sesid->domain_name = NULL;
2951                         sesid->host_name = NULL;
2952                         smb2_key_derivation(session_key, sizeof(session_key),
2953                                             "SMB2AESCCM", 11,
2954                                             "ServerIn ", 10,
2955                                             sesid->server_decryption_key);
2956                         smb2_key_derivation(session_key, sizeof(session_key),
2957                                             "SMB2AESCCM", 11,
2958                                             "ServerOut", 10,
2959                                             sesid->client_decryption_key);
2960                         sesid->server_port = pinfo->srcport;
2961                         sesid->auth_frame = pinfo->num;
2962                         sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2963                         g_hash_table_insert(si->conv->sesids, sesid, sesid);
2964                 }
2965         }
2966 #endif
2967
2968         return offset;
2969 }
2970
2971 static int
2972 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2973 {
2974         offset_length_buffer_t olb;
2975         const char *buf;
2976
2977         /* buffer code */
2978         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2979
2980         /* reserved */
2981         offset += 2;
2982
2983         /* tree  offset/length */
2984         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
2985
2986         /* tree string */
2987         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2988
2989         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2990
2991         /* treelen  +1 is overkill here if the string is unicode,
2992          * but who ever has more than a handful of TCON in a trace anyways
2993          */
2994         if (!pinfo->fd->flags.visited && si->saved && buf && olb.len) {
2995                 si->saved->extra_info_type = SMB2_EI_TREENAME;
2996                 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
2997                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2998         }
2999
3000         col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
3001
3002         return offset;
3003 }
3004 static int
3005 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3006 {
3007         guint16 share_type;
3008         gboolean continue_dissection;
3009
3010         switch (si->status) {
3011         /* buffer code */
3012         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3013         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3014                 if (!continue_dissection) return offset;
3015         }
3016
3017         /* share type */
3018         share_type = tvb_get_letohs(tvb, offset);
3019         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3020         /* Next byte is reserved  and must be set to zero */
3021         offset += 2;
3022
3023         if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
3024                 smb2_tid_info_t *tid, tid_key;
3025
3026                 tid_key.tid = si->tid;
3027                 tid = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
3028                 if (tid) {
3029                         g_hash_table_remove(si->session->tids, &tid_key);
3030                 }
3031                 tid = wmem_new(wmem_file_scope(), smb2_tid_info_t);
3032                 tid->tid = si->tid;
3033                 tid->name = (char *)si->saved->extra_info;
3034                 tid->connect_frame = pinfo->num;
3035                 tid->share_type = share_type;
3036
3037                 g_hash_table_insert(si->session->tids, tid, tid);
3038
3039                 si->saved->extra_info_type = SMB2_EI_NONE;
3040                 si->saved->extra_info = NULL;
3041         }
3042
3043         /* share flags */
3044         offset = dissect_smb2_share_flags(tree, tvb, offset);
3045
3046         /* share capabilities */
3047         offset = dissect_smb2_share_caps(tree, tvb, offset);
3048
3049         /* this is some sort of access mask */
3050         offset = dissect_smb_access_mask(tvb, tree, offset);
3051
3052         return offset;
3053 }
3054
3055 static int
3056 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3057 {
3058         /* buffer code */
3059         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3060
3061         /* reserved */
3062         offset += 2;
3063
3064         return offset;
3065 }
3066
3067 static int
3068 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3069 {
3070         gboolean continue_dissection;
3071
3072         switch (si->status) {
3073         /* buffer code */
3074         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3075         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3076                 if (!continue_dissection) return offset;
3077         }
3078
3079         /* reserved */
3080         offset += 2;
3081
3082         return offset;
3083 }
3084
3085 static int
3086 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3087 {
3088         /* buffer code */
3089         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3090
3091         /* reserved bytes */
3092         offset += 2;
3093
3094         return offset;
3095 }
3096
3097 static int
3098 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3099 {
3100         gboolean continue_dissection;
3101
3102         switch (si->status) {
3103         /* buffer code */
3104         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3105         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3106                 if (!continue_dissection) return offset;
3107         }
3108
3109         /* reserved bytes */
3110         offset += 2;
3111
3112         return offset;
3113 }
3114
3115 static int
3116 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3117 {
3118         /* buffer code */
3119         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3120
3121         /* some unknown bytes */
3122         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3123         offset += 2;
3124
3125         return offset;
3126 }
3127
3128 static int
3129 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3130 {
3131         gboolean continue_dissection;
3132
3133         switch (si->status) {
3134         /* buffer code */
3135         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3136         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3137                 if (!continue_dissection) return offset;
3138         }
3139
3140         /* some unknown bytes */
3141         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3142         offset += 2;
3143
3144         return offset;
3145 }
3146
3147 static int
3148 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3149 {
3150         proto_tree *flags_tree = NULL;
3151         proto_item *flags_item = NULL;
3152
3153         /* buffer code */
3154         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3155
3156         /* notify flags */
3157         if (tree) {
3158                 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3159                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
3160         }
3161         proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3162         offset += 2;
3163
3164         /* output buffer length */
3165         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3166         offset += 4;
3167
3168         /* fid */
3169         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3170
3171         /* completion filter */
3172         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
3173
3174         /* reserved */
3175         offset += 4;
3176
3177         return offset;
3178 }
3179
3180 static const value_string notify_action_vals[] = {
3181         {0x01, "FILE_ACTION_ADDED"},
3182         {0x02, "FILE_ACTION_REMOVED"},
3183         {0x03, "FILE_ACTION_MODIFIED"},
3184         {0x04, "FILE_ACTION_RENAMED_OLD_NAME"},
3185         {0x05, "FILE_ACTION_RENAMED_NEW_NAME"},
3186         {0x06, "FILE_ACTION_ADDED_STREAM"},
3187         {0x07, "FILE_ACTION_REMOVED_STREAM"},
3188         {0x08, "FILE_ACTION_MODIFIED_STREAM"},
3189         {0x09, "FILE_ACTION_REMOVED_BY_DELETE"},
3190         {0, NULL}
3191 };
3192
3193 static void
3194 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3195 {
3196         proto_tree *tree = NULL;
3197         proto_item *item = NULL;
3198         int offset = 0;
3199
3200         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3201                 guint32 start_offset = offset;
3202                 guint32 next_offset;
3203                 guint32 length;
3204
3205                 if (parent_tree) {
3206                         item = proto_tree_add_item(parent_tree, hf_smb2_notify_info, tvb, offset, -1, ENC_NA);
3207                         tree = proto_item_add_subtree(item, ett_smb2_notify_info);
3208                 }
3209
3210                 /* next offset */
3211                 proto_tree_add_item_ret_uint(tree, hf_smb2_notify_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &next_offset);
3212                 offset += 4;
3213
3214                 proto_tree_add_item(tree, hf_smb2_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3215                 offset += 4;
3216
3217                 /* file name length */
3218                 proto_tree_add_item_ret_uint(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
3219                 offset += 4;
3220
3221                 /* file name */
3222                 if (length) {
3223                         const guchar *name = "";
3224                         guint16     bc;
3225
3226                         bc = tvb_reported_length_remaining(tvb, offset);
3227                         name = get_unicode_or_ascii_string(tvb, &offset,
3228                                         TRUE, &length, TRUE, TRUE, &bc);
3229                         if (name) {
3230                                 proto_tree_add_string(tree, hf_smb2_filename,
3231                                                       tvb, offset, length,
3232                                                       name);
3233                         }
3234
3235                         offset += length;
3236                 }
3237
3238                 if (!next_offset) {
3239                         break;
3240                 }
3241
3242                 offset = start_offset+next_offset;
3243         }
3244 }
3245
3246 static int
3247 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3248 {
3249         offset_length_buffer_t olb;
3250         gboolean continue_dissection;
3251
3252         switch (si->status) {
3253         /* MS-SMB2 3.3.4.4 says STATUS_NOTIFY_ENUM_DIR is not treated as an error */
3254         case 0x0000010c: /* STATUS_NOTIFY_ENUM_DIR */
3255         case 0x00000000: /* buffer code */
3256          offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3257         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3258                 if (!continue_dissection) return offset;
3259         }
3260
3261         /* out buffer offset/length */
3262         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
3263
3264         /* out buffer */
3265         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
3266         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3267
3268         return offset;
3269 }
3270
3271 #define SMB2_FIND_FLAG_RESTART_SCANS            0x01
3272 #define SMB2_FIND_FLAG_SINGLE_ENTRY             0x02
3273 #define SMB2_FIND_FLAG_INDEX_SPECIFIED          0x04
3274 #define SMB2_FIND_FLAG_REOPEN                   0x10
3275
3276 static int
3277 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3278 {
3279         offset_length_buffer_t olb;
3280         const char *buf;
3281         guint8      il;
3282         static const int *f_fields[] = {
3283                 &hf_smb2_find_flags_restart_scans,
3284                 &hf_smb2_find_flags_single_entry,
3285                 &hf_smb2_find_flags_index_specified,
3286                 &hf_smb2_find_flags_reopen,
3287                 NULL
3288         };
3289
3290         /* buffer code */
3291         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3292
3293         il = tvb_get_guint8(tvb, offset);
3294         if (si->saved) {
3295                 si->saved->infolevel = il;
3296         }
3297
3298         /* infolevel */
3299         proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
3300         offset += 1;
3301
3302         /* find flags */
3303         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, ENC_LITTLE_ENDIAN);
3304         offset += 1;
3305
3306         /* file index */