9024be5b27e5d78446842dfb0c6d2ce60a3d3301
[metze/wireshark/wip.git] / epan / dissectors / packet-smb2.c
1 /* packet-smb2.c
2  * Routines for smb2 packet dissection
3  * Ronnie Sahlberg 2005
4  *
5  * For documentation of this protocol, see:
6  *
7  * https://wiki.wireshark.org/SMB2
8  * https://msdn.microsoft.com/en-us/library/cc246482.aspx
9  *
10  * If you edit this file, keep the wiki updated as well.
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29  */
30
31 #include "config.h"
32
33
34 #include <epan/packet.h>
35 #include <epan/prefs.h>
36 #include <epan/expert.h>
37 #include <epan/tap.h>
38 #include <epan/srt_table.h>
39 #include <epan/aftypes.h>
40 #include <epan/to_str.h>
41 #include <epan/asn1.h>
42 #include <epan/reassemble.h>
43
44 #include "packet-smb2.h"
45 #include "packet-ntlmssp.h"
46 #include "packet-kerberos.h"
47 #include "packet-windows-common.h"
48 #include "packet-smb-common.h"
49 #include "packet-dcerpc-nt.h"
50
51 #include <wsutil/wsgcrypt.h>
52
53 #define NT_STATUS_PENDING       0x00000103
54
55 void proto_register_smb2(void);
56 void proto_reg_handoff_smb2(void);
57
58 static const char smb_header_label[] = "SMB2 Header";
59 static const char smb_transform_header_label[] = "SMB2 Transform Header";
60
61 static int proto_smb2 = -1;
62 static int hf_smb2_cmd = -1;
63 static int hf_smb2_nt_status = -1;
64 static int hf_smb2_response_to = -1;
65 static int hf_smb2_response_in = -1;
66 static int hf_smb2_time = -1;
67 static int hf_smb2_header_len = -1;
68 static int hf_smb2_msg_id = -1;
69 static int hf_smb2_pid = -1;
70 static int hf_smb2_tid = -1;
71 static int hf_smb2_aid = -1;
72 static int hf_smb2_sesid = -1;
73 static int hf_smb2_previous_sesid = -1;
74 static int hf_smb2_flags_response = -1;
75 static int hf_smb2_flags_async_cmd = -1;
76 static int hf_smb2_flags_dfs_op = -1;
77 static int hf_smb2_flags_chained = -1;
78 static int hf_smb2_flags_signature = -1;
79 static int hf_smb2_flags_replay_operation = -1;
80 static int hf_smb2_flags_priority_mask = -1;
81 static int hf_smb2_chain_offset = -1;
82 static int hf_smb2_security_blob = -1;
83 static int hf_smb2_ioctl_in_data = -1;
84 static int hf_smb2_ioctl_out_data = -1;
85 static int hf_smb2_unknown = -1;
86 static int hf_smb2_root_directory_mbz = -1;
87 static int hf_smb2_twrp_timestamp = -1;
88 static int hf_smb2_mxac_timestamp = -1;
89 static int hf_smb2_mxac_status = -1;
90 static int hf_smb2_qfid_fid = -1;
91 static int hf_smb2_create_timestamp = -1;
92 static int hf_smb2_oplock = -1;
93 static int hf_smb2_close_flags = -1;
94 static int hf_smb2_notify_flags = -1;
95 static int hf_smb2_last_access_timestamp = -1;
96 static int hf_smb2_last_write_timestamp = -1;
97 static int hf_smb2_last_change_timestamp = -1;
98 static int hf_smb2_current_time = -1;
99 static int hf_smb2_boot_time = -1;
100 static int hf_smb2_filename = -1;
101 static int hf_smb2_filename_len = -1;
102 static int hf_smb2_replace_if = -1;
103 static int hf_smb2_nlinks = -1;
104 static int hf_smb2_delete_pending = -1;
105 static int hf_smb2_is_directory = -1;
106 static int hf_smb2_file_id = -1;
107 static int hf_smb2_allocation_size = -1;
108 static int hf_smb2_end_of_file = -1;
109 static int hf_smb2_tree = -1;
110 static int hf_smb2_find_pattern = -1;
111 static int hf_smb2_find_info_level = -1;
112 static int hf_smb2_find_info_blob = -1;
113 static int hf_smb2_client_guid = -1;
114 static int hf_smb2_server_guid = -1;
115 static int hf_smb2_object_id = -1;
116 static int hf_smb2_birth_volume_id = -1;
117 static int hf_smb2_birth_object_id = -1;
118 static int hf_smb2_domain_id = -1;
119 static int hf_smb2_class = -1;
120 static int hf_smb2_infolevel = -1;
121 static int hf_smb2_infolevel_file_info = -1;
122 static int hf_smb2_infolevel_fs_info = -1;
123 static int hf_smb2_infolevel_sec_info = -1;
124 static int hf_smb2_infolevel_posix_info = -1;
125 static int hf_smb2_max_response_size = -1;
126 static int hf_smb2_max_ioctl_in_size = -1;
127 static int hf_smb2_max_ioctl_out_size = -1;
128 static int hf_smb2_flags = -1;
129 static int hf_smb2_required_buffer_size = -1;
130 static int hf_smb2_setinfo_size = -1;
131 static int hf_smb2_setinfo_offset = -1;
132 static int hf_smb2_file_basic_info = -1;
133 static int hf_smb2_file_standard_info = -1;
134 static int hf_smb2_file_internal_info = -1;
135 static int hf_smb2_file_ea_info = -1;
136 static int hf_smb2_file_access_info = -1;
137 static int hf_smb2_file_rename_info = -1;
138 static int hf_smb2_file_disposition_info = -1;
139 static int hf_smb2_file_position_info = -1;
140 static int hf_smb2_file_full_ea_info = -1;
141 static int hf_smb2_file_mode_info = -1;
142 static int hf_smb2_file_alignment_info = -1;
143 static int hf_smb2_file_all_info = -1;
144 static int hf_smb2_file_allocation_info = -1;
145 static int hf_smb2_file_endoffile_info = -1;
146 static int hf_smb2_file_alternate_name_info = -1;
147 static int hf_smb2_file_stream_info = -1;
148 static int hf_smb2_file_pipe_info = -1;
149 static int hf_smb2_file_compression_info = -1;
150 static int hf_smb2_file_network_open_info = -1;
151 static int hf_smb2_file_attribute_tag_info = -1;
152 static int hf_smb2_fs_info_01 = -1;
153 static int hf_smb2_fs_info_03 = -1;
154 static int hf_smb2_fs_info_04 = -1;
155 static int hf_smb2_fs_info_05 = -1;
156 static int hf_smb2_fs_info_06 = -1;
157 static int hf_smb2_fs_info_07 = -1;
158 static int hf_smb2_fs_objectid_info = -1;
159 static int hf_smb2_sec_info_00 = -1;
160 static int hf_smb2_fid = -1;
161 static int hf_smb2_write_length = -1;
162 static int hf_smb2_write_data = -1;
163 static int hf_smb2_write_flags = -1;
164 static int hf_smb2_write_flags_write_through = -1;
165 static int hf_smb2_write_count = -1;
166 static int hf_smb2_write_remaining = -1;
167 static int hf_smb2_read_length = -1;
168 static int hf_smb2_read_remaining = -1;
169 static int hf_smb2_file_offset = -1;
170 static int hf_smb2_qfr_length = -1;
171 static int hf_smb2_qfr_usage = -1;
172 static int hf_smb2_qfr_flags = -1;
173 static int hf_smb2_qfr_total_region_entry_count = -1;
174 static int hf_smb2_qfr_region_entry_count = -1;
175 static int hf_smb2_read_data = -1;
176 static int hf_smb2_disposition_delete_on_close = -1;
177 static int hf_smb2_create_disposition = -1;
178 static int hf_smb2_create_chain_offset = -1;
179 static int hf_smb2_create_chain_data = -1;
180 static int hf_smb2_data_offset = -1;
181 static int hf_smb2_extrainfo = -1;
182 static int hf_smb2_create_action = -1;
183 static int hf_smb2_create_rep_flags = -1;
184 static int hf_smb2_create_rep_flags_reparse_point = -1;
185 static int hf_smb2_next_offset = -1;
186 static int hf_smb2_negotiate_context_type = -1;
187 static int hf_smb2_negotiate_context_data_length = -1;
188 static int hf_smb2_negotiate_context_offset = -1;
189 static int hf_smb2_negotiate_context_count = -1;
190 static int hf_smb2_ea_size = -1;
191 static int hf_smb2_ea_flags = -1;
192 static int hf_smb2_ea_name_len = -1;
193 static int hf_smb2_ea_data_len = -1;
194 static int hf_smb2_ea_name = -1;
195 static int hf_smb2_ea_data = -1;
196 static int hf_smb2_buffer_code = -1;
197 static int hf_smb2_buffer_code_len = -1;
198 static int hf_smb2_buffer_code_flags_dyn = -1;
199 static int hf_smb2_olb_offset = -1;
200 static int hf_smb2_olb_length = -1;
201 static int hf_smb2_tag = -1;
202 static int hf_smb2_impersonation_level = -1;
203 static int hf_smb2_ioctl_function = -1;
204 static int hf_smb2_ioctl_function_device = -1;
205 static int hf_smb2_ioctl_function_access = -1;
206 static int hf_smb2_ioctl_function_function = -1;
207 static int hf_smb2_fsctl_pipe_wait_timeout = -1;
208 static int hf_smb2_fsctl_pipe_wait_name = -1;
209 static int hf_smb2_fsctl_offload_read_size = -1;
210 static int hf_smb2_fsctl_offload_read_flags = -1;
211 static int hf_smb2_fsctl_offload_read_token_ttl = -1;
212 static int hf_smb2_fsctl_offload_reserved = -1;
213 static int hf_smb2_fsctl_offload_read_file_offset = -1;
214 static int hf_smb2_fsctl_offload_read_copy_length = -1;
215 static int hf_smb2_fsctl_offload_read_transfer_length = -1;
216 static int hf_smb2_fsctl_offload_token = -1;
217 static int hf_smb2_fsctl_sparse_flag = -1;
218 static int hf_smb2_fsctl_range_offset = -1;
219 static int hf_smb2_fsctl_range_length = -1;
220 static int hf_smb2_ioctl_function_method = -1;
221 static int hf_smb2_ioctl_resiliency_timeout = -1;
222 static int hf_smb2_ioctl_resiliency_reserved = -1;
223 static int hf_windows_sockaddr_family = -1;
224 static int hf_windows_sockaddr_port = -1;
225 static int hf_windows_sockaddr_in_addr = -1;
226 static int hf_windows_sockaddr_in6_flowinfo = -1;
227 static int hf_windows_sockaddr_in6_addr = -1;
228 static int hf_windows_sockaddr_in6_scope_id = -1;
229 static int hf_smb2_ioctl_network_interface_next_offset = -1;
230 static int hf_smb2_ioctl_network_interface_index = -1;
231 static int hf_smb2_ioctl_network_interface_rss_queue_count = -1;
232 static int hf_smb2_ioctl_network_interface_capabilities = -1;
233 static int hf_smb2_ioctl_network_interface_capability_rss = -1;
234 static int hf_smb2_ioctl_network_interface_capability_rdma = -1;
235 static int hf_smb2_ioctl_network_interface_link_speed = -1;
236 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
237 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
238 static int hf_smb2_ioctl_shadow_copy_count = -1;
239 static int hf_smb2_ioctl_shadow_copy_label = -1;
240 static int hf_smb2_compression_format = -1;
241 static int hf_smb2_checksum_algorithm = -1;
242 static int hf_smb2_integrity_reserved = -1;
243 static int hf_smb2_integrity_flags = -1;
244 static int hf_smb2_integrity_flags_enforcement_off = -1;
245 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
246 static int hf_smb2_lease_key = -1;
247 static int hf_smb2_lease_state = -1;
248 static int hf_smb2_lease_state_read_caching = -1;
249 static int hf_smb2_lease_state_handle_caching = -1;
250 static int hf_smb2_lease_state_write_caching = -1;
251 static int hf_smb2_lease_flags = -1;
252 static int hf_smb2_lease_flags_break_ack_required = -1;
253 static int hf_smb2_lease_flags_parent_lease_key_set = -1;
254 static int hf_smb2_lease_flags_break_in_progress = -1;
255 static int hf_smb2_lease_duration = -1;
256 static int hf_smb2_parent_lease_key = -1;
257 static int hf_smb2_lease_epoch = -1;
258 static int hf_smb2_lease_reserved = -1;
259 static int hf_smb2_lease_break_reason = -1;
260 static int hf_smb2_lease_access_mask_hint = -1;
261 static int hf_smb2_lease_share_mask_hint = -1;
262 static int hf_smb2_acct_name = -1;
263 static int hf_smb2_domain_name = -1;
264 static int hf_smb2_host_name = -1;
265 static int hf_smb2_auth_frame = -1;
266 static int hf_smb2_tcon_frame = -1;
267 static int hf_smb2_share_type = -1;
268 static int hf_smb2_signature = -1;
269 static int hf_smb2_credit_charge = -1;
270 static int hf_smb2_credits_requested = -1;
271 static int hf_smb2_credits_granted = -1;
272 static int hf_smb2_channel_sequence = -1;
273 static int hf_smb2_dialect_count = -1;
274 static int hf_smb2_security_mode = -1;
275 static int hf_smb2_secmode_flags_sign_required = -1;
276 static int hf_smb2_secmode_flags_sign_enabled = -1;
277 static int hf_smb2_ses_req_flags = -1;
278 static int hf_smb2_ses_req_flags_session_binding = -1;
279 static int hf_smb2_capabilities = -1;
280 static int hf_smb2_cap_dfs = -1;
281 static int hf_smb2_cap_leasing = -1;
282 static int hf_smb2_cap_large_mtu = -1;
283 static int hf_smb2_cap_multi_channel = -1;
284 static int hf_smb2_cap_persistent_handles = -1;
285 static int hf_smb2_cap_directory_leasing = -1;
286 static int hf_smb2_cap_encryption = -1;
287 static int hf_smb2_dialect = -1;
288 static int hf_smb2_max_trans_size = -1;
289 static int hf_smb2_max_read_size = -1;
290 static int hf_smb2_max_write_size = -1;
291 static int hf_smb2_channel = -1;
292 static int hf_smb2_rdma_v1_offset = -1;
293 static int hf_smb2_rdma_v1_token = -1;
294 static int hf_smb2_rdma_v1_length = -1;
295 static int hf_smb2_session_flags = -1;
296 static int hf_smb2_ses_flags_guest = -1;
297 static int hf_smb2_ses_flags_null = -1;
298 static int hf_smb2_share_flags = -1;
299 static int hf_smb2_share_flags_dfs = -1;
300 static int hf_smb2_share_flags_dfs_root = -1;
301 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
302 static int hf_smb2_share_flags_force_shared_delete = -1;
303 static int hf_smb2_share_flags_allow_namespace_caching = -1;
304 static int hf_smb2_share_flags_access_based_dir_enum = -1;
305 static int hf_smb2_share_flags_force_levelii_oplock = -1;
306 static int hf_smb2_share_flags_enable_hash_v1 = -1;
307 static int hf_smb2_share_flags_enable_hash_v2 = -1;
308 static int hf_smb2_share_flags_encrypt_data = -1;
309 static int hf_smb2_share_caching = -1;
310 static int hf_smb2_share_caps = -1;
311 static int hf_smb2_share_caps_dfs = -1;
312 static int hf_smb2_share_caps_continuous_availability = -1;
313 static int hf_smb2_share_caps_scaleout = -1;
314 static int hf_smb2_share_caps_cluster = -1;
315 static int hf_smb2_create_flags = -1;
316 static int hf_smb2_lock_count = -1;
317 static int hf_smb2_min_count = -1;
318 static int hf_smb2_remaining_bytes = -1;
319 static int hf_smb2_channel_info_offset = -1;
320 static int hf_smb2_channel_info_length = -1;
321 static int hf_smb2_channel_info_blob = -1;
322 static int hf_smb2_ioctl_flags = -1;
323 static int hf_smb2_ioctl_is_fsctl = -1;
324 static int hf_smb2_close_pq_attrib = -1;
325 static int hf_smb2_notify_watch_tree = -1;
326 static int hf_smb2_output_buffer_len = -1;
327 static int hf_smb2_notify_out_data = -1;
328 static int hf_smb2_notify_info = -1;
329 static int hf_smb2_notify_next_offset = -1;
330 static int hf_smb2_notify_action = -1;
331 static int hf_smb2_find_flags = -1;
332 static int hf_smb2_find_flags_restart_scans = -1;
333 static int hf_smb2_find_flags_single_entry = -1;
334 static int hf_smb2_find_flags_index_specified = -1;
335 static int hf_smb2_find_flags_reopen = -1;
336 static int hf_smb2_file_index = -1;
337 static int hf_smb2_file_directory_info = -1;
338 static int hf_smb2_both_directory_info = -1;
339 static int hf_smb2_short_name_len = -1;
340 static int hf_smb2_short_name = -1;
341 static int hf_smb2_id_both_directory_info = -1;
342 static int hf_smb2_full_directory_info = -1;
343 static int hf_smb2_lock_info = -1;
344 static int hf_smb2_lock_length = -1;
345 static int hf_smb2_lock_flags = -1;
346 static int hf_smb2_lock_flags_shared = -1;
347 static int hf_smb2_lock_flags_exclusive = -1;
348 static int hf_smb2_lock_flags_unlock = -1;
349 static int hf_smb2_lock_flags_fail_immediately = -1;
350 static int hf_smb2_dhnq_buffer_reserved = -1;
351 static int hf_smb2_dh2x_buffer_timeout = -1;
352 static int hf_smb2_dh2x_buffer_flags = -1;
353 static int hf_smb2_dh2x_buffer_flags_persistent_handle = -1;
354 static int hf_smb2_dh2x_buffer_reserved = -1;
355 static int hf_smb2_dh2x_buffer_create_guid = -1;
356 static int hf_smb2_APP_INSTANCE_buffer_struct_size = -1;
357 static int hf_smb2_APP_INSTANCE_buffer_reserved = -1;
358 static int hf_smb2_APP_INSTANCE_buffer_app_guid = -1;
359 static int hf_smb2_svhdx_open_device_context_version = -1;
360 static int hf_smb2_svhdx_open_device_context_has_initiator_id = -1;
361 static int hf_smb2_svhdx_open_device_context_reserved = -1;
362 static int hf_smb2_svhdx_open_device_context_initiator_id = -1;
363 static int hf_smb2_svhdx_open_device_context_flags = -1;
364 static int hf_smb2_svhdx_open_device_context_originator_flags = -1;
365 static int hf_smb2_svhdx_open_device_context_open_request_id = -1;
366 static int hf_smb2_svhdx_open_device_context_initiator_host_name_len = -1;
367 static int hf_smb2_svhdx_open_device_context_initiator_host_name = -1;
368 static int hf_smb2_posix_v1_version = -1;
369 static int hf_smb2_posix_v1_request = -1;
370 static int hf_smb2_posix_v1_supported_features = -1;
371 static int hf_smb2_posix_v1_posix_lock = -1;
372 static int hf_smb2_posix_v1_posix_file_semantics = -1;
373 static int hf_smb2_posix_v1_posix_utf8_paths = -1;
374 static int hf_smb2_posix_v1_case_sensitive = -1;
375 static int hf_smb2_posix_v1_posix_will_convert_nt_acls = -1;
376 static int hf_smb2_posix_v1_posix_fileinfo = -1;
377 static int hf_smb2_posix_v1_posix_acls = -1;
378 static int hf_smb2_posix_v1_rich_acls = -1;
379 static int hf_smb2_aapl_command_code = -1;
380 static int hf_smb2_aapl_reserved = -1;
381 static int hf_smb2_aapl_server_query_bitmask = -1;
382 static int hf_smb2_aapl_server_query_bitmask_server_caps = -1;
383 static int hf_smb2_aapl_server_query_bitmask_volume_caps = -1;
384 static int hf_smb2_aapl_server_query_bitmask_model_info = -1;
385 static int hf_smb2_aapl_server_query_caps = -1;
386 static int hf_smb2_aapl_server_query_caps_supports_read_dir_attr = -1;
387 static int hf_smb2_aapl_server_query_caps_supports_osx_copyfile = -1;
388 static int hf_smb2_aapl_server_query_caps_unix_based = -1;
389 static int hf_smb2_aapl_server_query_caps_supports_nfs_ace = -1;
390 static int hf_smb2_aapl_server_query_volume_caps = -1;
391 static int hf_smb2_aapl_server_query_volume_caps_support_resolve_id = -1;
392 static int hf_smb2_aapl_server_query_volume_caps_case_sensitive = -1;
393 static int hf_smb2_aapl_server_query_volume_caps_supports_full_sync = -1;
394 static int hf_smb2_aapl_server_query_model_string = -1;
395 static int hf_smb2_aapl_server_query_server_path = -1;
396 static int hf_smb2_error_byte_count = -1;
397 static int hf_smb2_error_data = -1;
398 static int hf_smb2_error_reserved = -1;
399 static int hf_smb2_reserved = -1;
400 static int hf_smb2_reserved_random = -1;
401 static int hf_smb2_transform_signature = -1;
402 static int hf_smb2_transform_nonce = -1;
403 static int hf_smb2_transform_msg_size = -1;
404 static int hf_smb2_transform_reserved = -1;
405 static int hf_smb2_encryption_aes128_ccm = -1;
406 static int hf_smb2_transform_enc_alg = -1;
407 static int hf_smb2_transform_encrypted_data = -1;
408 static int hf_smb2_server_component_smb2 = -1;
409 static int hf_smb2_server_component_smb2_transform = -1;
410 static int hf_smb2_truncated = -1;
411 static int hf_smb2_pipe_fragments = -1;
412 static int hf_smb2_pipe_fragment = -1;
413 static int hf_smb2_pipe_fragment_overlap = -1;
414 static int hf_smb2_pipe_fragment_overlap_conflict = -1;
415 static int hf_smb2_pipe_fragment_multiple_tails = -1;
416 static int hf_smb2_pipe_fragment_too_long_fragment = -1;
417 static int hf_smb2_pipe_fragment_error = -1;
418 static int hf_smb2_pipe_fragment_count = -1;
419 static int hf_smb2_pipe_reassembled_in = -1;
420 static int hf_smb2_pipe_reassembled_length = -1;
421 static int hf_smb2_pipe_reassembled_data = -1;
422 static int hf_smb2_cchunk_resume_key = -1;
423 static int hf_smb2_cchunk_count = -1;
424 static int hf_smb2_cchunk_src_offset = -1;
425 static int hf_smb2_cchunk_dst_offset = -1;
426 static int hf_smb2_cchunk_xfer_len = -1;
427 static int hf_smb2_cchunk_chunks_written = -1;
428 static int hf_smb2_cchunk_bytes_written = -1;
429 static int hf_smb2_cchunk_total_written = -1;
430
431 static gint ett_smb2 = -1;
432 static gint ett_smb2_olb = -1;
433 static gint ett_smb2_ea = -1;
434 static gint ett_smb2_header = -1;
435 static gint ett_smb2_encrypted = -1;
436 static gint ett_smb2_command = -1;
437 static gint ett_smb2_secblob = -1;
438 static gint ett_smb2_negotiate_context_element = -1;
439 static gint ett_smb2_file_basic_info = -1;
440 static gint ett_smb2_file_standard_info = -1;
441 static gint ett_smb2_file_internal_info = -1;
442 static gint ett_smb2_file_ea_info = -1;
443 static gint ett_smb2_file_access_info = -1;
444 static gint ett_smb2_file_position_info = -1;
445 static gint ett_smb2_file_mode_info = -1;
446 static gint ett_smb2_file_alignment_info = -1;
447 static gint ett_smb2_file_all_info = -1;
448 static gint ett_smb2_file_allocation_info = -1;
449 static gint ett_smb2_file_endoffile_info = -1;
450 static gint ett_smb2_file_alternate_name_info = -1;
451 static gint ett_smb2_file_stream_info = -1;
452 static gint ett_smb2_file_pipe_info = -1;
453 static gint ett_smb2_file_compression_info = -1;
454 static gint ett_smb2_file_network_open_info = -1;
455 static gint ett_smb2_file_attribute_tag_info = -1;
456 static gint ett_smb2_file_rename_info = -1;
457 static gint ett_smb2_file_disposition_info = -1;
458 static gint ett_smb2_file_full_ea_info = -1;
459 static gint ett_smb2_fs_info_01 = -1;
460 static gint ett_smb2_fs_info_03 = -1;
461 static gint ett_smb2_fs_info_04 = -1;
462 static gint ett_smb2_fs_info_05 = -1;
463 static gint ett_smb2_fs_info_06 = -1;
464 static gint ett_smb2_fs_info_07 = -1;
465 static gint ett_smb2_fs_objectid_info = -1;
466 static gint ett_smb2_sec_info_00 = -1;
467 static gint ett_smb2_tid_tree = -1;
468 static gint ett_smb2_sesid_tree = -1;
469 static gint ett_smb2_create_chain_element = -1;
470 static gint ett_smb2_MxAc_buffer = -1;
471 static gint ett_smb2_QFid_buffer = -1;
472 static gint ett_smb2_RqLs_buffer = -1;
473 static gint ett_smb2_ioctl_function = -1;
474 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
475 static gint ett_smb2_flags = -1;
476 static gint ett_smb2_sec_mode = -1;
477 static gint ett_smb2_capabilities = -1;
478 static gint ett_smb2_ses_req_flags = -1;
479 static gint ett_smb2_ses_flags = -1;
480 static gint ett_smb2_lease_state = -1;
481 static gint ett_smb2_lease_flags = -1;
482 static gint ett_smb2_share_flags = -1;
483 static gint ett_smb2_create_rep_flags = -1;
484 static gint ett_smb2_share_caps = -1;
485 static gint ett_smb2_ioctl_flags = -1;
486 static gint ett_smb2_ioctl_network_interface = -1;
487 static gint ett_smb2_fsctl_range_data = -1;
488 static gint ett_windows_sockaddr = -1;
489 static gint ett_smb2_close_flags = -1;
490 static gint ett_smb2_notify_info = -1;
491 static gint ett_smb2_notify_flags = -1;
492 static gint ett_smb2_write_flags = -1;
493 static gint ett_smb2_rdma_v1 = -1;
494 static gint ett_smb2_DH2Q_buffer = -1;
495 static gint ett_smb2_DH2C_buffer = -1;
496 static gint ett_smb2_dh2x_flags = -1;
497 static gint ett_smb2_APP_INSTANCE_buffer = -1;
498 static gint ett_smb2_svhdx_open_device_context = -1;
499 static gint ett_smb2_posix_v1_request = -1;
500 static gint ett_smb2_posix_v1_response = -1;
501 static gint ett_smb2_posix_v1_supported_features = -1;
502 static gint ett_smb2_aapl_create_context_request = -1;
503 static gint ett_smb2_aapl_server_query_bitmask = -1;
504 static gint ett_smb2_aapl_server_query_caps = -1;
505 static gint ett_smb2_aapl_create_context_response = -1;
506 static gint ett_smb2_aapl_server_query_volume_caps = -1;
507 static gint ett_smb2_integrity_flags = -1;
508 static gint ett_smb2_find_flags = -1;
509 static gint ett_smb2_file_directory_info = -1;
510 static gint ett_smb2_both_directory_info = -1;
511 static gint ett_smb2_id_both_directory_info = -1;
512 static gint ett_smb2_full_directory_info = -1;
513 static gint ett_smb2_file_name_info = -1;
514 static gint ett_smb2_lock_info = -1;
515 static gint ett_smb2_lock_flags = -1;
516 static gint ett_smb2_transform_enc_alg = -1;
517 static gint ett_smb2_buffercode = -1;
518 static gint ett_smb2_ioctl_network_interface_capabilities = -1;
519 static gint ett_qfr_entry = -1;
520 static gint ett_smb2_pipe_fragment = -1;
521 static gint ett_smb2_pipe_fragments = -1;
522 static gint ett_smb2_cchunk_entry = -1;
523
524 static expert_field ei_smb2_invalid_length = EI_INIT;
525 static expert_field ei_smb2_bad_response = EI_INIT;
526
527 static int smb2_tap = -1;
528 static int smb2_eo_tap = -1;
529
530 static dissector_handle_t gssapi_handle  = NULL;
531 static dissector_handle_t ntlmssp_handle = NULL;
532 static dissector_handle_t rsvd_handle = NULL;
533
534 static heur_dissector_list_t smb2_pipe_subdissector_list;
535
536 static const fragment_items smb2_pipe_frag_items = {
537         &ett_smb2_pipe_fragment,
538         &ett_smb2_pipe_fragments,
539         &hf_smb2_pipe_fragments,
540         &hf_smb2_pipe_fragment,
541         &hf_smb2_pipe_fragment_overlap,
542         &hf_smb2_pipe_fragment_overlap_conflict,
543         &hf_smb2_pipe_fragment_multiple_tails,
544         &hf_smb2_pipe_fragment_too_long_fragment,
545         &hf_smb2_pipe_fragment_error,
546         &hf_smb2_pipe_fragment_count,
547         &hf_smb2_pipe_reassembled_in,
548         &hf_smb2_pipe_reassembled_length,
549         &hf_smb2_pipe_reassembled_data,
550         "Fragments"
551 };
552
553 #define SMB2_CLASS_FILE_INFO    0x01
554 #define SMB2_CLASS_FS_INFO      0x02
555 #define SMB2_CLASS_SEC_INFO     0x03
556 #define SMB2_CLASS_POSIX_INFO   0x80
557 static const value_string smb2_class_vals[] = {
558         { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
559         { SMB2_CLASS_FS_INFO,   "FS_INFO"},
560         { SMB2_CLASS_SEC_INFO,  "SEC_INFO"},
561         { SMB2_CLASS_POSIX_INFO, "POSIX_INFO"},
562         { 0, NULL }
563 };
564
565 #define SMB2_SHARE_TYPE_DISK    0x01
566 #define SMB2_SHARE_TYPE_PIPE    0x02
567 #define SMB2_SHARE_TYPE_PRINT   0x03
568 static const value_string smb2_share_type_vals[] = {
569         { SMB2_SHARE_TYPE_DISK,         "Physical disk" },
570         { SMB2_SHARE_TYPE_PIPE,         "Named pipe" },
571         { SMB2_SHARE_TYPE_PRINT,        "Printer" },
572         { 0, NULL }
573 };
574
575
576 #define SMB2_FILE_BASIC_INFO          0x04
577 #define SMB2_FILE_STANDARD_INFO       0x05
578 #define SMB2_FILE_INTERNAL_INFO       0x06
579 #define SMB2_FILE_EA_INFO             0x07
580 #define SMB2_FILE_ACCESS_INFO         0x08
581 #define SMB2_FILE_RENAME_INFO         0x0a
582 #define SMB2_FILE_DISPOSITION_INFO    0x0d
583 #define SMB2_FILE_POSITION_INFO       0x0e
584 #define SMB2_FILE_FULL_EA_INFO        0x0f
585 #define SMB2_FILE_MODE_INFO           0x10
586 #define SMB2_FILE_ALIGNMENT_INFO      0x11
587 #define SMB2_FILE_ALL_INFO            0x12
588 #define SMB2_FILE_ALLOCATION_INFO     0x13
589 #define SMB2_FILE_ENDOFFILE_INFO      0x14
590 #define SMB2_FILE_ALTERNATE_NAME_INFO 0x15
591 #define SMB2_FILE_STREAM_INFO         0x16
592 #define SMB2_FILE_PIPE_INFO           0x17
593 #define SMB2_FILE_COMPRESSION_INFO    0x1c
594 #define SMB2_FILE_NETWORK_OPEN_INFO   0x22
595 #define SMB2_FILE_ATTRIBUTE_TAG_INFO  0x23
596
597 static const value_string smb2_file_info_levels[] = {
598         {SMB2_FILE_BASIC_INFO,          "SMB2_FILE_BASIC_INFO" },
599         {SMB2_FILE_STANDARD_INFO,       "SMB2_FILE_STANDARD_INFO" },
600         {SMB2_FILE_INTERNAL_INFO,       "SMB2_FILE_INTERNAL_INFO" },
601         {SMB2_FILE_EA_INFO,             "SMB2_FILE_EA_INFO" },
602         {SMB2_FILE_ACCESS_INFO,         "SMB2_FILE_ACCESS_INFO" },
603         {SMB2_FILE_RENAME_INFO,         "SMB2_FILE_RENAME_INFO" },
604         {SMB2_FILE_DISPOSITION_INFO,    "SMB2_FILE_DISPOSITION_INFO" },
605         {SMB2_FILE_POSITION_INFO,       "SMB2_FILE_POSITION_INFO" },
606         {SMB2_FILE_FULL_EA_INFO,        "SMB2_FILE_FULL_EA_INFO" },
607         {SMB2_FILE_MODE_INFO,           "SMB2_FILE_MODE_INFO" },
608         {SMB2_FILE_ALIGNMENT_INFO,      "SMB2_FILE_ALIGNMENT_INFO" },
609         {SMB2_FILE_ALL_INFO,            "SMB2_FILE_ALL_INFO" },
610         {SMB2_FILE_ALLOCATION_INFO,     "SMB2_FILE_ALLOCATION_INFO" },
611         {SMB2_FILE_ENDOFFILE_INFO,      "SMB2_FILE_ENDOFFILE_INFO" },
612         {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
613         {SMB2_FILE_STREAM_INFO,         "SMB2_FILE_STREAM_INFO" },
614         {SMB2_FILE_PIPE_INFO,           "SMB2_FILE_PIPE_INFO" },
615         {SMB2_FILE_COMPRESSION_INFO,    "SMB2_FILE_COMPRESSION_INFO" },
616         {SMB2_FILE_NETWORK_OPEN_INFO,   "SMB2_FILE_NETWORK_OPEN_INFO" },
617         {SMB2_FILE_ATTRIBUTE_TAG_INFO,  "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
618         { 0, NULL }
619 };
620 static value_string_ext smb2_file_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_file_info_levels);
621
622
623
624 #define SMB2_FS_INFO_01                 0x01
625 #define SMB2_FS_LABEL_INFO              0x02
626 #define SMB2_FS_INFO_03                 0x03
627 #define SMB2_FS_INFO_04                 0x04
628 #define SMB2_FS_INFO_05                 0x05
629 #define SMB2_FS_INFO_06                 0x06
630 #define SMB2_FS_INFO_07                 0x07
631 #define SMB2_FS_OBJECTID_INFO           0x08
632 #define SMB2_FS_DRIVER_PATH_INFO        0x09
633 #define SMB2_FS_VOLUME_FLAGS_INFO       0x0a
634 #define SMB2_FS_SECTOR_SIZE_INFO        0x0b
635
636 static const value_string smb2_fs_info_levels[] = {
637         {SMB2_FS_INFO_01,               "FileFsVolumeInformation" },
638         {SMB2_FS_LABEL_INFO,            "FileFsLabelInformation" },
639         {SMB2_FS_INFO_03,               "FileFsSizeInformation" },
640         {SMB2_FS_INFO_04,               "FileFsDeviceInformation" },
641         {SMB2_FS_INFO_05,               "FileFsAttributeInformation" },
642         {SMB2_FS_INFO_06,               "FileFsControlInformation" },
643         {SMB2_FS_INFO_07,               "FileFsFullSizeInformation" },
644         {SMB2_FS_OBJECTID_INFO,         "FileFsObjectIdInformation" },
645         {SMB2_FS_DRIVER_PATH_INFO,      "FileFsDriverPathInformation" },
646         {SMB2_FS_VOLUME_FLAGS_INFO,     "FileFsVolumeFlagsInformation" },
647         {SMB2_FS_SECTOR_SIZE_INFO,      "FileFsSectorSizeInformation" },
648         { 0, NULL }
649 };
650 static value_string_ext smb2_fs_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_fs_info_levels);
651
652 #define SMB2_SEC_INFO_00        0x00
653 static const value_string smb2_sec_info_levels[] = {
654         {SMB2_SEC_INFO_00,      "SMB2_SEC_INFO_00" },
655         { 0, NULL }
656 };
657 static value_string_ext smb2_sec_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_sec_info_levels);
658
659 static const value_string smb2_posix_info_levels[] = {
660         { 0,    "QueryFileUnixBasic" },
661         { 1,    "QueryFileUnixLink" },
662         { 3,    "QueryFileUnixHLink" },
663         { 5,    "QueryFileUnixXAttr" },
664         { 0x0B, "QueryFileUnixInfo2" },
665         { 0, NULL }
666 };
667
668 static value_string_ext smb2_posix_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_posix_info_levels);
669
670 #define SMB2_FIND_DIRECTORY_INFO         0x01
671 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
672 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
673 #define SMB2_FIND_INDEX_SPECIFIED        0x04
674 #define SMB2_FIND_NAME_INFO              0x0C
675 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
676 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
677 static const value_string smb2_find_info_levels[] = {
678         { SMB2_FIND_DIRECTORY_INFO,             "SMB2_FIND_DIRECTORY_INFO" },
679         { SMB2_FIND_FULL_DIRECTORY_INFO,        "SMB2_FIND_FULL_DIRECTORY_INFO" },
680         { SMB2_FIND_BOTH_DIRECTORY_INFO,        "SMB2_FIND_BOTH_DIRECTORY_INFO" },
681         { SMB2_FIND_INDEX_SPECIFIED,            "SMB2_FIND_INDEX_SPECIFIED" },
682         { SMB2_FIND_NAME_INFO,                  "SMB2_FIND_NAME_INFO" },
683         { SMB2_FIND_ID_BOTH_DIRECTORY_INFO,     "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
684         { SMB2_FIND_ID_FULL_DIRECTORY_INFO,     "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
685         { 0, NULL }
686 };
687
688 #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001
689 #define SMB2_ENCRYPTION_CAPABILITIES        0x0002
690 static const value_string smb2_negotiate_context_types[] = {
691         { SMB2_PREAUTH_INTEGRITY_CAPABILITIES,  "SMB2_PREAUTH_INTEGRITY_CAPABILITIES" },
692         { SMB2_ENCRYPTION_CAPABILITIES, "SMB2_ENCRYPTION_CAPABILITIES" },
693         { 0, NULL }
694 };
695
696 #define SMB2_NUM_PROCEDURES     256
697
698 static void
699 smb2stat_init(struct register_srt* srt _U_, GArray* srt_array, srt_gui_init_cb gui_callback, void* gui_data)
700 {
701         srt_stat_table *smb2_srt_table;
702         guint32 i;
703
704         smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", gui_callback, gui_data, NULL);
705         for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
706         {
707                 init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
708         }
709 }
710
711 static int
712 smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
713 {
714         guint i = 0;
715         srt_stat_table *smb2_srt_table;
716         srt_data_t *data = (srt_data_t *)pss;
717         const smb2_info_t *si=(const smb2_info_t *)prv;
718
719         /* we are only interested in response packets */
720         if(!(si->flags&SMB2_FLAGS_RESPONSE)){
721                 return 0;
722         }
723         /* if we haven't seen the request, just ignore it */
724         if(!si->saved){
725                 return 0;
726         }
727
728         /* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
729          * not only add additional (bogus) transactions but also the latency associated with them.
730          * This can greatly inflate the maximum and average SRT stats especially in the case of
731          * retransmissions triggered by the expiry of the rexmit timer (RTOs). Only calculating SRT
732          * for the last received response accomplishes this goal without requiring the TCP pref
733          * "Do not call subdissectors for error packets" to be set. */
734         if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->num))
735                 return 0;
736
737         smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
738         add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
739         return 1;
740 }
741
742
743 static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
744
745 /* ExportObject preferences variable */
746 gboolean eosmb2_take_name_as_fid = FALSE ;
747
748 /* unmatched smb_saved_info structures.
749    For unmatched smb_saved_info structures we store the smb_saved_info
750    structure using the msg_id field.
751 */
752 static gint
753 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
754 {
755         const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
756         const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
757         return key1->msg_id == key2->msg_id;
758 }
759 static guint
760 smb2_saved_info_hash_unmatched(gconstpointer k)
761 {
762         const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
763         guint32 hash;
764
765         hash = (guint32) (key->msg_id&0xffffffff);
766         return hash;
767 }
768
769 /* matched smb_saved_info structures.
770    For matched smb_saved_info structures we store the smb_saved_info
771    structure using the msg_id field.
772 */
773 static gint
774 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
775 {
776         const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
777         const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
778         return key1->msg_id == key2->msg_id;
779 }
780 static guint
781 smb2_saved_info_hash_matched(gconstpointer k)
782 {
783         const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
784         guint32 hash;
785
786         hash = (guint32) (key->msg_id&0xffffffff);
787         return hash;
788 }
789
790 /* For Tids of a specific conversation.
791    This keeps track of tid->sharename mappings and other information about the
792    tid.
793    qqq
794    We might need to refine this if it occurs that tids are reused on a single
795    conversation.   we don't worry about that yet for simplicity
796 */
797 static gint
798 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
799 {
800         const smb2_tid_info_t *key1 = (const smb2_tid_info_t *)k1;
801         const smb2_tid_info_t *key2 = (const smb2_tid_info_t *)k2;
802         return key1->tid == key2->tid;
803 }
804 static guint
805 smb2_tid_info_hash(gconstpointer k)
806 {
807         const smb2_tid_info_t *key = (const smb2_tid_info_t *)k;
808         guint32 hash;
809
810         hash = key->tid;
811         return hash;
812 }
813
814 /* For Uids of a specific conversation.
815    This keeps track of uid->acct_name mappings and other information about the
816    uid.
817    qqq
818    We might need to refine this if it occurs that uids are reused on a single
819    conversation.   we don't worry about that yet for simplicity
820 */
821 static gint
822 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
823 {
824         const smb2_sesid_info_t *key1 = (const smb2_sesid_info_t *)k1;
825         const smb2_sesid_info_t *key2 = (const smb2_sesid_info_t *)k2;
826         return key1->sesid == key2->sesid;
827 }
828 static guint
829 smb2_sesid_info_hash(gconstpointer k)
830 {
831         const smb2_sesid_info_t *key = (const smb2_sesid_info_t *)k;
832         guint32 hash;
833
834         hash = (guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
835         return hash;
836 }
837
838 /*
839  * For File IDs of a specific conversation.
840  * This keeps track of fid to name mapping and application level conversations
841  * over named pipes.
842  *
843  * This handles implementation bugs, where the fid_persitent is 0 or
844  * the fid_persitent/fid_volative is not unique per conversation.
845  */
846 static gint
847 smb2_fid_info_equal(gconstpointer k1, gconstpointer k2)
848 {
849         const smb2_fid_info_t *key1 = (const smb2_fid_info_t *)k1;
850         const smb2_fid_info_t *key2 = (const smb2_fid_info_t *)k2;
851
852         if (key1->fid_persistent != key2->fid_persistent) {
853                 return 0;
854         };
855
856         if (key1->fid_volatile != key2->fid_volatile) {
857                 return 0;
858         };
859
860         if (key1->sesid != key2->sesid) {
861                 return 0;
862         };
863
864         if (key1->tid != key2->tid) {
865                 return 0;
866         };
867
868         return 1;
869 }
870
871 static guint
872 smb2_fid_info_hash(gconstpointer k)
873 {
874         const smb2_fid_info_t *key = (const smb2_fid_info_t *)k;
875         guint32 hash;
876
877         if (key->fid_persistent != 0) {
878                 hash = (guint32)( ((key->fid_persistent>>32)&0xffffffff)+((key->fid_persistent)&0xffffffff) );
879         } else {
880                 hash = (guint32)( ((key->fid_volatile>>32)&0xffffffff)+((key->fid_volatile)&0xffffffff) );
881         }
882
883         return hash;
884 }
885
886 /* Callback for destroying the glib hash tables associated with a conversation
887  * struct. */
888 static gboolean
889 smb2_conv_destroy(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
890                   void *user_data)
891 {
892         smb2_conv_info_t *conv = (smb2_conv_info_t *)user_data;
893
894         g_hash_table_destroy(conv->matched);
895         g_hash_table_destroy(conv->unmatched);
896         g_hash_table_destroy(conv->fids);
897         g_hash_table_destroy(conv->sesids);
898         g_hash_table_destroy(conv->files);
899
900         /* This conversation is gone, return FALSE to indicate we don't
901          * want to be called again for this conversation. */
902         return FALSE;
903 }
904
905 static void smb2_key_derivation(const guint8 *KI _U_, guint32 KI_len _U_,
906                          const guint8 *Label _U_, guint32 Label_len _U_,
907                          const guint8 *Context _U_, guint32 Context_len _U_,
908                          guint8 KO[16])
909 {
910 #ifdef HAVE_LIBGCRYPT
911         gcry_md_hd_t  hd     = NULL;
912         guint8        buf[4];
913         guint8       *digest = NULL;
914
915         /*
916          * a simplified version of
917          * "NIST Special Publication 800-108" section 5.1
918          * using hmac-sha256.
919          */
920         gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
921         gcry_md_setkey(hd, KI, KI_len);
922
923         memset(buf, 0, sizeof(buf));
924         buf[3] = 1;
925         gcry_md_write(hd, buf, sizeof(buf));
926         gcry_md_write(hd, Label, Label_len);
927         gcry_md_write(hd, buf, 1);
928         gcry_md_write(hd, Context, Context_len);
929         buf[3] = 128;
930         gcry_md_write(hd, buf, sizeof(buf));
931
932         digest = gcry_md_read(hd, GCRY_MD_SHA256);
933
934         memcpy(KO, digest, 16);
935
936         gcry_md_close(hd);
937 #else
938         memset(KO, 0, 16);
939 #endif
940 }
941
942 /* for export-object-smb2 */
943 static gchar *policy_hnd_to_file_id(const e_ctx_hnd *hnd) {
944 gchar *file_id;
945         file_id = wmem_strdup_printf(wmem_packet_scope(),
946                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
947                         hnd->uuid.data1,
948                         hnd->uuid.data2,
949                         hnd->uuid.data3,
950                         hnd->uuid.data4[0],
951                         hnd->uuid.data4[1],
952                         hnd->uuid.data4[2],
953                         hnd->uuid.data4[3],
954                         hnd->uuid.data4[4],
955                         hnd->uuid.data4[5],
956                         hnd->uuid.data4[6],
957                         hnd->uuid.data4[7]);
958         return file_id;
959 }
960 static guint smb2_eo_files_hash(gconstpointer k) {
961         return g_str_hash(policy_hnd_to_file_id((const e_ctx_hnd *)k));
962 }
963 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2) {
964 int     are_equal;
965         const e_ctx_hnd *key1 = (const e_ctx_hnd *)k1;
966         const e_ctx_hnd *key2 = (const e_ctx_hnd *)k2;
967
968         are_equal = (key1->uuid.data1==key2->uuid.data1 &&
969                 key1->uuid.data2==key2->uuid.data2 &&
970                 key1->uuid.data3==key2->uuid.data3 &&
971                 key1->uuid.data4[0]==key2->uuid.data4[0] &&
972                 key1->uuid.data4[1]==key2->uuid.data4[1] &&
973                 key1->uuid.data4[2]==key2->uuid.data4[2] &&
974                 key1->uuid.data4[3]==key2->uuid.data4[3] &&
975                 key1->uuid.data4[4]==key2->uuid.data4[4] &&
976                 key1->uuid.data4[5]==key2->uuid.data4[5] &&
977                 key1->uuid.data4[6]==key2->uuid.data4[6] &&
978                 key1->uuid.data4[7]==key2->uuid.data4[7]);
979
980         return are_equal;
981 }
982
983 static void
984 feed_eo_smb2(tvbuff_t * tvb,packet_info *pinfo,smb2_info_t * si, guint16 dataoffset,guint32 length, guint64 file_offset) {
985
986         char       *fid_name = NULL;
987         guint32     open_frame = 0, close_frame = 0;
988         tvbuff_t        *data_tvb = NULL;
989         smb_eo_t        *eo_info;
990         gchar           *file_id;
991         gchar           *auxstring;
992         gchar           **aux_string_v;
993
994         /* Create a new tvb to point to the payload data */
995         data_tvb = tvb_new_subset_length(tvb, dataoffset, length);
996         /* Create the eo_info to pass to the listener */
997         eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
998         /* Fill in eo_info */
999         eo_info->smbversion=2;
1000         /* cmd == opcode */
1001         eo_info->cmd=si->opcode;
1002         /* We don't keep track of uid in SMB v2 */
1003         eo_info->uid=0;
1004
1005         /* Try to get file id and filename */
1006         file_id=policy_hnd_to_file_id(&si->saved->policy_hnd);
1007         dcerpc_fetch_polhnd_data(&si->saved->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num);
1008         if (fid_name && g_strcmp0(fid_name,"File: ")!=0) {
1009                 auxstring=fid_name;
1010                 /* Remove "File: " from filename */
1011                 if (g_str_has_prefix(auxstring, "File: ")) {
1012                         aux_string_v = g_strsplit(auxstring, "File: ", -1);
1013                         eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",aux_string_v[g_strv_length(aux_string_v)-1]);
1014                         g_strfreev(aux_string_v);
1015                 } else {
1016                         if (g_str_has_prefix(auxstring, "\\")) {
1017                                 eo_info->filename = wmem_strdup(wmem_packet_scope(), auxstring);
1018                         } else {
1019                                 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",auxstring);
1020                         }
1021                 }
1022         } else {
1023                 auxstring=wmem_strdup_printf(wmem_packet_scope(), "File_Id_%s", file_id);
1024                 eo_info->filename=auxstring;
1025         }
1026
1027
1028
1029         if (eosmb2_take_name_as_fid) {
1030                 eo_info->fid = g_str_hash(eo_info->filename);
1031         } else {
1032                 eo_info->fid = g_str_hash(file_id);
1033         }
1034
1035         /* tid, hostname, tree_id */
1036         if (si->tree) {
1037                 eo_info->tid=si->tree->tid;
1038                 if (strlen(si->tree->name)>0 && strlen(si->tree->name)<=256) {
1039                         eo_info->hostname = wmem_strdup(wmem_packet_scope(), si->tree->name);
1040                 } else {
1041                         eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,si->opcode),si->tree->tid);
1042                 }
1043         } else {
1044                 eo_info->tid=0;
1045                 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,si->opcode));
1046         }
1047
1048         /* packet number */
1049         eo_info->pkt_num = pinfo->num;
1050
1051         /* fid type */
1052         if (si->eo_file_info->attr_mask & SMB2_FLAGS_ATTR_DIRECTORY) {
1053                 eo_info->fid_type=SMB2_FID_TYPE_DIR;
1054         } else {
1055                 if (si->eo_file_info->attr_mask &
1056                         (SMB2_FLAGS_ATTR_ARCHIVE | SMB2_FLAGS_ATTR_NORMAL |
1057                          SMB2_FLAGS_ATTR_HIDDEN | SMB2_FLAGS_ATTR_READONLY |
1058                          SMB2_FLAGS_ATTR_SYSTEM) ) {
1059                         eo_info->fid_type=SMB2_FID_TYPE_FILE;
1060                 } else {
1061                         eo_info->fid_type=SMB2_FID_TYPE_OTHER;
1062                 }
1063         }
1064
1065         /* end_of_file */
1066         eo_info->end_of_file=si->eo_file_info->end_of_file;
1067
1068         /* data offset and chunk length */
1069         eo_info->smb_file_offset=file_offset;
1070         eo_info->smb_chunk_len=length;
1071         /* XXX is this right? */
1072         if (length<si->saved->bytes_moved) {
1073                 si->saved->file_offset=si->saved->file_offset+length;
1074                 si->saved->bytes_moved=si->saved->bytes_moved-length;
1075         }
1076
1077         /* Payload */
1078         eo_info->payload_len = length;
1079         eo_info->payload_data = tvb_get_ptr(data_tvb, 0, length);
1080
1081         tap_queue_packet(smb2_eo_tap, pinfo, eo_info);
1082
1083 }
1084
1085 static int dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
1086
1087
1088 /* This is a helper to dissect the common string type
1089  * uint16 offset
1090  * uint16 length
1091  * ...
1092  * char *string
1093  *
1094  * This function is called twice, first to decode the offset/length and
1095  * second time to dissect the actual string.
1096  * It is done this way since there is no guarantee that we have the full packet and we don't
1097  * want to abort dissection too early if the packet ends somewhere between the
1098  * length/offset and the actual buffer.
1099  *
1100  */
1101 enum offset_length_buffer_offset_size {
1102         OLB_O_UINT16_S_UINT16,
1103         OLB_O_UINT16_S_UINT32,
1104         OLB_O_UINT32_S_UINT32,
1105         OLB_S_UINT32_O_UINT32
1106 };
1107 typedef struct _offset_length_buffer_t {
1108         guint32 off;
1109         guint32 len;
1110         int off_offset;
1111         int len_offset;
1112         enum offset_length_buffer_offset_size offset_size;
1113         int hfindex;
1114 } offset_length_buffer_t;
1115 static int
1116 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
1117                                enum offset_length_buffer_offset_size offset_size, int hfindex)
1118 {
1119         olb->hfindex = hfindex;
1120         olb->offset_size = offset_size;
1121         switch (offset_size) {
1122         case OLB_O_UINT16_S_UINT16:
1123                 olb->off = tvb_get_letohs(tvb, offset);
1124                 olb->off_offset = offset;
1125                 offset += 2;
1126                 olb->len = tvb_get_letohs(tvb, offset);
1127                 olb->len_offset = offset;
1128                 offset += 2;
1129                 break;
1130         case OLB_O_UINT16_S_UINT32:
1131                 olb->off = tvb_get_letohs(tvb, offset);
1132                 olb->off_offset = offset;
1133                 offset += 2;
1134                 olb->len = tvb_get_letohl(tvb, offset);
1135                 olb->len_offset = offset;
1136                 offset += 4;
1137                 break;
1138         case OLB_O_UINT32_S_UINT32:
1139                 olb->off = tvb_get_letohl(tvb, offset);
1140                 olb->off_offset = offset;
1141                 offset += 4;
1142                 olb->len = tvb_get_letohl(tvb, offset);
1143                 olb->len_offset = offset;
1144                 offset += 4;
1145                 break;
1146         case OLB_S_UINT32_O_UINT32:
1147                 olb->len = tvb_get_letohl(tvb, offset);
1148                 olb->len_offset = offset;
1149                 offset += 4;
1150                 olb->off = tvb_get_letohl(tvb, offset);
1151                 olb->off_offset = offset;
1152                 offset += 4;
1153                 break;
1154         }
1155
1156         return offset;
1157 }
1158
1159 #define OLB_TYPE_UNICODE_STRING         0x01
1160 #define OLB_TYPE_ASCII_STRING           0x02
1161 static const char *
1162 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
1163 {
1164         int         len, off;
1165         proto_item *item = NULL;
1166         proto_tree *tree = NULL;
1167         const char *name = NULL;
1168         guint16     bc;
1169         int         offset;
1170
1171         offset = olb->off;
1172         len = olb->len;
1173         off = olb->off;
1174         bc = tvb_captured_length_remaining(tvb, offset);
1175
1176
1177         /* sanity check */
1178         tvb_ensure_bytes_exist(tvb, off, len);
1179         if (((off+len)<off)
1180         || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1181                 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1182                                     "Invalid offset/length. Malformed packet");
1183
1184                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1185
1186                 return NULL;
1187         }
1188
1189
1190         switch (type) {
1191         case OLB_TYPE_UNICODE_STRING:
1192                 name = get_unicode_or_ascii_string(tvb, &off,
1193                         TRUE, &len, TRUE, TRUE, &bc);
1194                 if (!name) {
1195                         name = "";
1196                 }
1197                 if (parent_tree) {
1198                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
1199                         tree = proto_item_add_subtree(item, ett_smb2_olb);
1200                 }
1201                 break;
1202         case OLB_TYPE_ASCII_STRING:
1203                 name = get_unicode_or_ascii_string(tvb, &off,
1204                         FALSE, &len, TRUE, TRUE, &bc);
1205                 if (!name) {
1206                         name = "";
1207                 }
1208                 if (parent_tree) {
1209                         item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
1210                         tree = proto_item_add_subtree(item, ett_smb2_olb);
1211                 }
1212                 break;
1213         }
1214
1215         switch (olb->offset_size) {
1216         case OLB_O_UINT16_S_UINT16:
1217                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1218                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1219                 break;
1220         case OLB_O_UINT16_S_UINT32:
1221                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1222                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1223                 break;
1224         case OLB_O_UINT32_S_UINT32:
1225                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1226                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1227                 break;
1228         case OLB_S_UINT32_O_UINT32:
1229                 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1230                 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1231                 break;
1232         }
1233
1234         return name;
1235 }
1236
1237 static void
1238 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
1239                         offset_length_buffer_t *olb, smb2_info_t *si,
1240                         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
1241 {
1242         int         len, off;
1243         proto_item *sub_item = NULL;
1244         proto_tree *sub_tree = NULL;
1245         tvbuff_t   *sub_tvb  = NULL;
1246         int         offset;
1247
1248         offset = olb->off;
1249         len    = olb->len;
1250         off    = olb->off;
1251
1252         /* sanity check */
1253         tvb_ensure_bytes_exist(tvb, off, len);
1254         if (((off+len)<off)
1255             || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1256                 proto_tree_add_expert_format(parent_tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1257                                     "Invalid offset/length. Malformed packet");
1258
1259                 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1260
1261                 return;
1262         }
1263
1264         /* if we don't want/need a subtree */
1265         if (olb->hfindex == -1) {
1266                 sub_item = parent_tree;
1267                 sub_tree = parent_tree;
1268         } else {
1269                 if (parent_tree) {
1270                         sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
1271                         sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
1272                 }
1273         }
1274
1275         switch (olb->offset_size) {
1276         case OLB_O_UINT16_S_UINT16:
1277                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1278                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1279                 break;
1280         case OLB_O_UINT16_S_UINT32:
1281                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1282                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1283                 break;
1284         case OLB_O_UINT32_S_UINT32:
1285                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1286                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1287                 break;
1288         case OLB_S_UINT32_O_UINT32:
1289                 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1290                 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1291                 break;
1292         }
1293
1294         if (off == 0 || len == 0) {
1295                 proto_item_append_text(sub_item, ": NO DATA");
1296                 return;
1297         }
1298
1299         if (!dissector) {
1300                 return;
1301         }
1302
1303         sub_tvb = tvb_new_subset(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
1304
1305         dissector(sub_tvb, pinfo, sub_tree, si);
1306 }
1307
1308 static int
1309 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
1310 {
1311         if (olb->off == 0) {
1312                 return offset;
1313         }
1314         return MAX(offset, (int)(olb->off + olb->len));
1315 }
1316
1317 typedef struct _smb2_function {
1318         int (*request) (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1319         int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1320 } smb2_function;
1321
1322 static const true_false_string tfs_smb2_svhdx_has_initiator_id = {
1323         "Has an initiator id",
1324         "Does not have an initiator id"
1325 };
1326
1327 static const true_false_string tfs_flags_response = {
1328         "This is a RESPONSE",
1329         "This is a REQUEST"
1330 };
1331
1332 static const true_false_string tfs_flags_async_cmd = {
1333         "This is an ASYNC command",
1334         "This is a SYNC command"
1335 };
1336
1337 static const true_false_string tfs_flags_dfs_op = {
1338         "This is a DFS OPERATION",
1339         "This is a normal operation"
1340 };
1341
1342 static const true_false_string tfs_flags_chained = {
1343         "This pdu a CHAINED command",
1344         "This pdu is NOT a chained command"
1345 };
1346
1347 static const true_false_string tfs_flags_signature = {
1348         "This pdu is SIGNED",
1349         "This pdu is NOT signed"
1350 };
1351
1352 static const true_false_string tfs_flags_replay_operation = {
1353         "This is a REPLAY OPEARATION",
1354         "This is NOT a replay operation"
1355 };
1356
1357 static const true_false_string tfs_flags_priority_mask = {
1358         "This pdu contains a PRIORITY",
1359         "This pdu does NOT contain a PRIORITY1"
1360 };
1361
1362 static const true_false_string tfs_cap_dfs = {
1363         "This host supports DFS",
1364         "This host does NOT support DFS"
1365 };
1366
1367 static const true_false_string tfs_cap_leasing = {
1368         "This host supports LEASING",
1369         "This host does NOT support LEASING"
1370 };
1371
1372 static const true_false_string tfs_cap_large_mtu = {
1373         "This host supports LARGE_MTU",
1374         "This host does NOT support LARGE_MTU"
1375 };
1376
1377 static const true_false_string tfs_cap_multi_channel = {
1378         "This host supports MULTI CHANNEL",
1379         "This host does NOT support MULTI CHANNEL"
1380 };
1381
1382 static const true_false_string tfs_cap_persistent_handles = {
1383         "This host supports PERSISTENT HANDLES",
1384         "This host does NOT support PERSISTENT HANDLES"
1385 };
1386
1387 static const true_false_string tfs_cap_directory_leasing = {
1388         "This host supports DIRECTORY LEASING",
1389         "This host does NOT support DIRECTORY LEASING"
1390 };
1391
1392 static const true_false_string tfs_cap_encryption = {
1393         "This host supports ENCRYPTION",
1394         "This host does NOT support ENCRYPTION"
1395 };
1396
1397 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rss = {
1398         "This interface supports RSS",
1399         "This interface does not support RSS"
1400 };
1401
1402 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rdma = {
1403         "This interface supports RDMA",
1404         "This interface does not support RDMA"
1405 };
1406
1407 static const value_string file_region_usage_vals[] = {
1408         { 0x00000001, "FILE_REGION_USAGE_VALID_CACHED_DATA" },
1409         { 0, NULL }
1410 };
1411
1412 static const value_string originator_flags_vals[] = {
1413         { 1, "SVHDX_ORIGINATOR_PVHDPARSER" },
1414         { 4, "SVHDX_ORIGINATOR_VHDMP" },
1415         { 0, NULL }
1416 };
1417
1418 static const value_string posix_locks_vals[] = {
1419         { 1, "POSIX_V1_POSIX_LOCK" },
1420         { 0, NULL }
1421 };
1422
1423 static const value_string posix_utf8_paths_vals[] = {
1424         { 1, "POSIX_V1_UTF8_PATHS" },
1425         { 0, NULL }
1426 };
1427
1428 static const value_string posix_file_semantics_vals[] = {
1429         { 1, "POSIX_V1_POSIX_FILE_SEMANTICS" },
1430         { 0, NULL }
1431 };
1432
1433 static const value_string posix_case_sensitive_vals[] = {
1434         { 1, "POSIX_V1_CASE_SENSITIVE" },
1435         { 0, NULL }
1436 };
1437
1438 static const value_string posix_will_convert_ntacls_vals[] = {
1439         { 1, "POSIX_V1_WILL_CONVERT_NT_ACLS" },
1440         { 0, NULL }
1441 };
1442
1443 static const value_string posix_fileinfo_vals[] = {
1444         { 1, "POSIX_V1_POSIX_FILEINFO" },
1445         { 0, NULL }
1446 };
1447
1448 static const value_string posix_acls_vals[] = {
1449         { 1, "POSIX_V1_POSIX_ACLS" },
1450         { 0, NULL }
1451 };
1452
1453 static const value_string posix_rich_acls_vals[] = {
1454         { 1, "POSIX_V1_RICH_ACLS" },
1455         { 0, NULL }
1456 };
1457
1458 static const value_string compression_format_vals[] = {
1459         { 0, "COMPRESSION_FORMAT_NONE" },
1460         { 1, "COMPRESSION_FORMAT_DEFAULT" },
1461         { 2, "COMPRESSION_FORMAT_LZNT1" },
1462         { 0, NULL }
1463 };
1464
1465 static const value_string checksum_algorithm_vals[] = {
1466         { 0x0000, "CHECKSUM_TYPE_NONE" },
1467         { 0x0002, "CHECKSUM_TYPE_CRC64" },
1468         { 0xFFFF, "CHECKSUM_TYPE_UNCHANGED" },
1469         { 0, NULL }
1470 };
1471
1472 /* Note: All uncommented are "dissector not implemented" */
1473 static const value_string smb2_ioctl_vals[] = {
1474         {0x00060194, "FSCTL_DFS_GET_REFERRALS"},                      /* dissector implemented */
1475         {0x000601B0, "FSCTL_DFS_GET_REFERRALS_EX"},
1476         {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
1477         {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
1478         {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
1479         {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
1480         {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
1481         {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
1482         {0x00090018, "FSCTL_LOCK_VOLUME"},
1483         {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
1484         {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
1485         {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
1486         {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
1487         {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
1488         {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
1489         {0x0009003C, "FSCTL_GET_COMPRESSION"},                        /* dissector implemented */
1490         {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
1491         {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
1492         {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
1493         {0x00090058, "FSCTL_QUERY_FAT_BPB"},
1494         {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
1495         {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
1496         {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
1497         {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
1498         {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
1499         {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
1500         {0x00090074, "FSCTL_MOVE_FILE"},
1501         {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
1502         {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
1503         {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
1504         {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
1505         {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
1506         {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
1507         {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
1508         {0x0009009C, "FSCTL_GET_OBJECT_ID"},                          /* dissector implemented */
1509         {0x000900A4, "FSCTL_SET_REPARSE_POINT"},
1510         {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
1511         {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},                /* dissector implemented */
1512         {0x000900C4, "FSCTL_SET_SPARSE"},                             /* dissector implemented */
1513         {0x000900D4, "FSCTL_SET_ENCRYPTION"},
1514         {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
1515         {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
1516         {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
1517         {0x000900F0, "FSCTL_EXTEND_VOLUME"},
1518         {0x0009027C, "FSCTL_GET_INTEGRITY_INFORMATION"},
1519         {0x00090284, "FSCTL_QUERY_FILE_REGIONS"},
1520         {0x00090300, "FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT"},      /* dissector implemented */
1521         {0x00090304, "FSCTL_SVHDX_SYNC_TUNNEL_REQUEST"},              /* dissector implemented */
1522         {0x00090308, "FSCTL_SVHDX_SET_INITIATOR_INFORMATION"},
1523         {0x0009030C, "FSCTL_SET_EXTERNAL_BACKING"},
1524         {0x00090310, "FSCTL_GET_EXTERNAL_BACKING"},
1525         {0x00090314, "FSCTL_DELETE_EXTERNAL_BACKING"},
1526         {0x00090318, "FSCTL_ENUM_EXTERNAL_BACKING"},
1527         {0x0009031F, "FSCTL_ENUM_OVERLAY"},
1528         {0x000940B3, "FSCTL_ENUM_USN_DATA"},
1529         {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
1530         {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
1531         {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},                 /* dissector implemented */
1532         {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
1533         {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
1534         {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
1535         {0x00094264, "FSCTL_OFFLOAD_READ"},
1536         {0x00098098, "FSCTL_SET_OBJECT_ID"},                          /* dissector implemented */
1537         {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
1538         {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
1539         {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
1540         {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},                 /* dissector implemented */
1541         {0x000980C8, "FSCTL_SET_ZERO_DATA"},                          /* dissector implemented */
1542         {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
1543         {0x00098208, "FSCTL_FILE_LEVEL_TRIM"},
1544         {0x0009C040, "FSCTL_SET_COMPRESSION"},                        /* dissector implemented */
1545         {0x0009C280, "FSCTL_SET_INTEGRITY_INFORMATION"},              /* dissector implemented */
1546         {0x00110018, "FSCTL_PIPE_WAIT"},                              /* dissector implemented */
1547         {0x0011400C, "FSCTL_PIPE_PEEK"},
1548         {0x0011C017, "FSCTL_PIPE_TRANSCEIVE"},                        /* dissector implemented */
1549         {0x00140078, "FSCTL_SRV_REQUEST_RESUME_KEY"},
1550         {0x001401D4, "FSCTL_LMR_REQUEST_RESILIENCY"},                 /* dissector implemented */
1551         {0x001401FC, "FSCTL_QUERY_NETWORK_INTERFACE_INFO"},           /* dissector implemented */
1552         {0x00140200, "FSCTL_VALIDATE_NEGOTIATE_INFO_224"},            /* dissector implemented */
1553         {0x00140204, "FSCTL_VALIDATE_NEGOTIATE_INFO"},                /* dissector implemented */
1554         {0x00144064, "FSCTL_SRV_ENUMERATE_SNAPSHOTS"},                /* dissector implemented */
1555         {0x001440F2, "FSCTL_SRV_COPYCHUNK"},
1556         {0x001441bb, "FSCTL_SRV_READ_HASH"},
1557         {0x001480F2, "FSCTL_SRV_COPYCHUNK_WRITE"},
1558         { 0, NULL }
1559 };
1560 static value_string_ext smb2_ioctl_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_vals);
1561
1562 static const value_string smb2_ioctl_device_vals[] = {
1563         { 0x0001, "BEEP" },
1564         { 0x0002, "CD_ROM" },
1565         { 0x0003, "CD_ROM_FILE_SYSTEM" },
1566         { 0x0004, "CONTROLLER" },
1567         { 0x0005, "DATALINK" },
1568         { 0x0006, "DFS" },
1569         { 0x0007, "DISK" },
1570         { 0x0008, "DISK_FILE_SYSTEM" },
1571         { 0x0009, "FILE_SYSTEM" },
1572         { 0x000a, "INPORT_PORT" },
1573         { 0x000b, "KEYBOARD" },
1574         { 0x000c, "MAILSLOT" },
1575         { 0x000d, "MIDI_IN" },
1576         { 0x000e, "MIDI_OUT" },
1577         { 0x000f, "MOUSE" },
1578         { 0x0010, "MULTI_UNC_PROVIDER" },
1579         { 0x0011, "NAMED_PIPE" },
1580         { 0x0012, "NETWORK" },
1581         { 0x0013, "NETWORK_BROWSER" },
1582         { 0x0014, "NETWORK_FILE_SYSTEM" },
1583         { 0x0015, "NULL" },
1584         { 0x0016, "PARALLEL_PORT" },
1585         { 0x0017, "PHYSICAL_NETCARD" },
1586         { 0x0018, "PRINTER" },
1587         { 0x0019, "SCANNER" },
1588         { 0x001a, "SERIAL_MOUSE_PORT" },
1589         { 0x001b, "SERIAL_PORT" },
1590         { 0x001c, "SCREEN" },
1591         { 0x001d, "SOUND" },
1592         { 0x001e, "STREAMS" },
1593         { 0x001f, "TAPE" },
1594         { 0x0020, "TAPE_FILE_SYSTEM" },
1595         { 0x0021, "TRANSPORT" },
1596         { 0x0022, "UNKNOWN" },
1597         { 0x0023, "VIDEO" },
1598         { 0x0024, "VIRTUAL_DISK" },
1599         { 0x0025, "WAVE_IN" },
1600         { 0x0026, "WAVE_OUT" },
1601         { 0x0027, "8042_PORT" },
1602         { 0x0028, "NETWORK_REDIRECTOR" },
1603         { 0x0029, "BATTERY" },
1604         { 0x002a, "BUS_EXTENDER" },
1605         { 0x002b, "MODEM" },
1606         { 0x002c, "VDM" },
1607         { 0x002d, "MASS_STORAGE" },
1608         { 0x002e, "SMB" },
1609         { 0x002f, "KS" },
1610         { 0x0030, "CHANGER" },
1611         { 0x0031, "SMARTCARD" },
1612         { 0x0032, "ACPI" },
1613         { 0x0033, "DVD" },
1614         { 0x0034, "FULLSCREEN_VIDEO" },
1615         { 0x0035, "DFS_FILE_SYSTEM" },
1616         { 0x0036, "DFS_VOLUME" },
1617         { 0x0037, "SERENUM" },
1618         { 0x0038, "TERMSRV" },
1619         { 0x0039, "KSEC" },
1620         { 0, NULL }
1621 };
1622 static value_string_ext smb2_ioctl_device_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_device_vals);
1623
1624 static const value_string smb2_ioctl_access_vals[] = {
1625         { 0x00, "FILE_ANY_ACCESS" },
1626         { 0x01, "FILE_READ_ACCESS" },
1627         { 0x02, "FILE_WRITE_ACCESS" },
1628         { 0x03, "FILE_READ_WRITE_ACCESS" },
1629         { 0, NULL }
1630 };
1631
1632 static const value_string smb2_ioctl_method_vals[] = {
1633         { 0x00, "METHOD_BUFFERED" },
1634         { 0x01, "METHOD_IN_DIRECT" },
1635         { 0x02, "METHOD_OUT_DIRECT" },
1636         { 0x03, "METHOD_NEITHER" },
1637         { 0, NULL }
1638 };
1639
1640 /* this is called from both smb and smb2. */
1641 int
1642 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
1643 {
1644         proto_item *item = NULL;
1645         proto_tree *tree = NULL;
1646         guint32     ioctl_function;
1647
1648         if (parent_tree) {
1649                 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1650                 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
1651         }
1652
1653         ioctl_function = tvb_get_letohl(tvb, offset);
1654         if (ioctlfunc)
1655                 *ioctlfunc = ioctl_function;
1656         if (ioctl_function) {
1657                 const gchar *unknown = "unknown";
1658                 const gchar *ioctl_name = val_to_str_ext_const(ioctl_function,
1659                                                                &smb2_ioctl_vals_ext,
1660                                                                unknown);
1661
1662                 /*
1663                  * val_to_str_const() doesn't work with a unknown == NULL
1664                  */
1665                 if (ioctl_name == unknown) {
1666                         ioctl_name = NULL;
1667                 }
1668
1669                 if (ioctl_name != NULL) {
1670                         col_append_fstr(
1671                                 pinfo->cinfo, COL_INFO, " %s", ioctl_name);
1672                 }
1673
1674                 /* device */
1675                 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1676                 if (ioctl_name == NULL) {
1677                         col_append_fstr(
1678                                 pinfo->cinfo, COL_INFO, " %s",
1679                                 val_to_str_ext((ioctl_function>>16)&0xffff, &smb2_ioctl_device_vals_ext,
1680                                 "Unknown (0x%08X)"));
1681                 }
1682
1683                 /* access */
1684                 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1685
1686                 /* function */
1687                 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1688                 if (ioctl_name == NULL) {
1689                         col_append_fstr(
1690                                 pinfo->cinfo, COL_INFO, " Function:0x%04x",
1691                                 (ioctl_function>>2)&0x0fff);
1692                 }
1693
1694                 /* method */
1695                 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1696         }
1697
1698         offset += 4;
1699
1700         return offset;
1701 }
1702
1703 /* fake the dce/rpc support structures so we can piggy back on
1704  * dissect_nt_policy_hnd()   since this will allow us
1705  * a cheap way to track where FIDs are opened, closed
1706  * and fid->filename mappings
1707  * if we want to do those things in the future.
1708  */
1709 #define FID_MODE_OPEN           0
1710 #define FID_MODE_CLOSE          1
1711 #define FID_MODE_USE            2
1712 #define FID_MODE_DHNQ           3
1713 #define FID_MODE_DHNC           4
1714 static int
1715 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
1716 {
1717         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1718         static dcerpc_info        di; /* fake dcerpc_info struct */
1719         static dcerpc_call_value  call_data;
1720         e_ctx_hnd   policy_hnd;
1721         e_ctx_hnd   *policy_hnd_hashtablekey;
1722         proto_item *hnd_item   = NULL;
1723         char       *fid_name;
1724         guint32     open_frame = 0, close_frame = 0;
1725         smb2_eo_file_info_t     *eo_file_info;
1726         smb2_fid_info_t sfi_key;
1727         smb2_fid_info_t *sfi = NULL;
1728
1729         sfi_key.fid_persistent = tvb_get_letoh64(tvb, offset);
1730         sfi_key.fid_volatile = tvb_get_letoh64(tvb, offset+8);
1731         sfi_key.sesid = si->sesid;
1732         sfi_key.tid = si->tid;
1733         sfi_key.name = NULL;
1734
1735         di.conformant_run = 0;
1736         /* we need di->call_data->flags.NDR64 == 0 */
1737         di.call_data = &call_data;
1738
1739         switch (mode) {
1740         case FID_MODE_OPEN:
1741                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1742                 if (!pinfo->fd->flags.visited) {
1743                         sfi = wmem_new(wmem_file_scope(), smb2_fid_info_t);
1744                         *sfi = sfi_key;
1745                         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1746                                 sfi->name = wmem_strdup(wmem_file_scope(), (char *)si->saved->extra_info);
1747                         } else {
1748                                 sfi->name = wmem_strdup_printf(wmem_file_scope(), "[unknown]");
1749                         }
1750
1751                         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1752                                 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: %s", (char *)si->saved->extra_info);
1753                         } else {
1754                                 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: ");
1755                         }
1756                         dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1757                                                   fid_name);
1758
1759                         g_hash_table_insert(si->conv->fids, sfi, sfi);
1760                         si->file = sfi;
1761
1762                         /* If needed, create the file entry and save the policy hnd */
1763                         if (si->saved) {
1764                                 si->saved->file = sfi;
1765                                 si->saved->policy_hnd = policy_hnd;
1766                         }
1767
1768                         if (si->conv) {
1769                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1770                                 if (!eo_file_info) {
1771                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1772                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1773                                         memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1774                                         eo_file_info->end_of_file=0;
1775                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1776                                 }
1777                                 si->eo_file_info=eo_file_info;
1778                         }
1779                 }
1780                 break;
1781         case FID_MODE_CLOSE:
1782                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
1783                 break;
1784         case FID_MODE_USE:
1785         case FID_MODE_DHNQ:
1786         case FID_MODE_DHNC:
1787                 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
1788                 break;
1789         }
1790
1791         si->file = (smb2_fid_info_t *)g_hash_table_lookup(si->conv->fids, &sfi_key);
1792         if (si->file) {
1793                 if (si->saved) {
1794                         si->saved->file = si->file;
1795                 }
1796                 if (si->file->name) {
1797                         if (hnd_item) {
1798                                 proto_item_append_text(hnd_item, " File: %s", si->file->name);
1799                         }
1800                         col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", si->file->name);
1801                 }
1802         }
1803
1804         if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
1805                 /* look for the eo_file_info */
1806                 if (!si->eo_file_info) {
1807                         if (si->saved) { si->saved->policy_hnd = policy_hnd; }
1808                         if (si->conv) {
1809                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1810                                 if (eo_file_info) {
1811                                         si->eo_file_info=eo_file_info;
1812                                 } else { /* XXX This should never happen */
1813                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1814                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1815                                         memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1816                                         eo_file_info->end_of_file=0;
1817                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1818                                 }
1819                         }
1820
1821                 }
1822         }
1823
1824         return offset;
1825 }
1826
1827
1828 /* this info level is unique to SMB2 and differst from the corresponding
1829  * SMB_FILE_ALL_INFO in SMB
1830  */
1831 static int
1832 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1833 {
1834         proto_item *item = NULL;
1835         proto_tree *tree = NULL;
1836         int         length;
1837         const char *name = "";
1838         guint16     bc;
1839
1840         if (parent_tree) {
1841                 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
1842                 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
1843         }
1844
1845         /* create time */
1846         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1847
1848         /* last access */
1849         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1850
1851         /* last write */
1852         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1853
1854         /* last change */
1855         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1856
1857         /* File Attributes */
1858         offset = dissect_file_ext_attr(tvb, tree, offset);
1859
1860         /* some unknown bytes */
1861         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
1862         offset += 4;
1863
1864         /* allocation size */
1865         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1866         offset += 8;
1867
1868         /* end of file */
1869         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1870         offset += 8;
1871
1872         /* number of links */
1873         proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1874         offset += 4;
1875
1876         /* delete pending */
1877         proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1878         offset += 1;
1879
1880         /* is directory */
1881         proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1882         offset += 1;
1883
1884         /* padding */
1885         offset += 2;
1886
1887         /* file id */
1888         proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1889         offset += 8;
1890
1891         /* ea size */
1892         proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1893         offset += 4;
1894
1895         /* access mask */
1896         offset = dissect_smb_access_mask(tvb, tree, offset);
1897
1898         /* some unknown bytes */
1899         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
1900         offset += 16;
1901
1902         /* file name length */
1903         length = tvb_get_letohs(tvb, offset);
1904         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1905         offset += 4;
1906
1907         /* file name */
1908         if (length) {
1909                 bc = tvb_captured_length_remaining(tvb, offset);
1910                 name = get_unicode_or_ascii_string(tvb, &offset,
1911                         TRUE, &length, TRUE, TRUE, &bc);
1912                 if (name) {
1913                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
1914                                 offset, length, name);
1915                 }
1916
1917         }
1918         offset += length;
1919
1920         return offset;
1921 }
1922
1923
1924 static int
1925 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1926 {
1927         proto_item *item = NULL;
1928         proto_tree *tree = NULL;
1929         guint16     bc;
1930         gboolean    trunc;
1931
1932         if (parent_tree) {
1933                 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, ENC_NA);
1934                 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1935         }
1936
1937         bc = tvb_captured_length_remaining(tvb, offset);
1938         offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1939
1940         return offset;
1941 }
1942
1943 static int
1944 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1945 {
1946         proto_item *item = NULL;
1947         proto_tree *tree = NULL;
1948         guint16     bc;
1949         gboolean    trunc;
1950
1951         if (parent_tree) {
1952                 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, ENC_NA);
1953                 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1954         }
1955
1956         bc = tvb_captured_length_remaining(tvb, offset);
1957         offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1958
1959         return offset;
1960 }
1961
1962 static int
1963 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1964 {
1965         proto_item *item = NULL;
1966         proto_tree *tree = NULL;
1967         guint16     bc;
1968         gboolean    trunc;
1969
1970         if (parent_tree) {
1971                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, ENC_NA);
1972                 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1973         }
1974
1975         bc = tvb_captured_length_remaining(tvb, offset);
1976         offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
1977
1978         return offset;
1979 }
1980
1981
1982 static int
1983 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1984 {
1985         proto_item *item = NULL;
1986         proto_tree *tree = NULL;
1987
1988         if (parent_tree) {
1989                 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, ENC_NA);
1990                 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1991         }
1992
1993         /* create time */
1994         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1995
1996         /* last access */
1997         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1998
1999         /* last write */
2000         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2001
2002         /* last change */
2003         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2004
2005         /* File Attributes */
2006         offset = dissect_file_ext_attr(tvb, tree, offset);
2007
2008         /* some unknown bytes */
2009         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2010         offset += 4;
2011
2012         return offset;
2013 }
2014
2015 static int
2016 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2017 {
2018         proto_item *item = NULL;
2019         proto_tree *tree = NULL;
2020         guint16     bc;
2021         gboolean    trunc;
2022
2023         if (parent_tree) {
2024                 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, ENC_NA);
2025                 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
2026         }
2027
2028         bc = tvb_captured_length_remaining(tvb, offset);
2029         offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2030
2031         return offset;
2032 }
2033 static int
2034 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2035 {
2036         proto_item *item = NULL;
2037         proto_tree *tree = NULL;
2038         guint16     bc;
2039         gboolean    trunc;
2040
2041         if (parent_tree) {
2042                 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, ENC_NA);
2043                 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
2044         }
2045
2046         bc = tvb_captured_length_remaining(tvb, offset);
2047         offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2048
2049         return offset;
2050 }
2051 static int
2052 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2053 {
2054         proto_item *item = NULL;
2055         proto_tree *tree = NULL;
2056         guint16     bc;
2057         gboolean    trunc;
2058
2059         if (parent_tree) {
2060                 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, ENC_NA);
2061                 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
2062         }
2063
2064         bc = tvb_captured_length_remaining(tvb, offset);
2065         offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2066
2067         return offset;
2068 }
2069 static int
2070 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2071 {
2072         proto_item *item = NULL;
2073         proto_tree *tree = NULL;
2074         guint16     bc;
2075         gboolean    trunc;
2076
2077         if (parent_tree) {
2078                 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, ENC_NA);
2079                 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
2080         }
2081
2082         bc = tvb_captured_length_remaining(tvb, offset);
2083         offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2084
2085         return offset;
2086 }
2087 static int
2088 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2089 {
2090         proto_item *item = NULL;
2091         proto_tree *tree = NULL;
2092         guint16     bc;
2093         gboolean    trunc;
2094
2095         if (parent_tree) {
2096                 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, ENC_NA);
2097                 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
2098         }
2099
2100         bc = tvb_captured_length_remaining(tvb, offset);
2101         offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2102
2103         return offset;
2104 }
2105
2106 static int
2107 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2108 {
2109         proto_item *item = NULL;
2110         proto_tree *tree = NULL;
2111
2112         if (parent_tree) {
2113                 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, ENC_NA);
2114                 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
2115         }
2116
2117         /* access mask */
2118         offset = dissect_smb_access_mask(tvb, tree, offset);
2119
2120         return offset;
2121 }
2122
2123 static int
2124 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2125 {
2126         proto_item *item = NULL;
2127         proto_tree *tree = NULL;
2128         guint16     bc;
2129         gboolean    trunc;
2130
2131         if (parent_tree) {
2132                 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, ENC_NA);
2133                 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
2134         }
2135
2136         bc = tvb_captured_length_remaining(tvb, offset);
2137         offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2138
2139         return offset;
2140 }
2141
2142 static int
2143 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2144 {
2145         proto_item *item = NULL;
2146         proto_tree *tree = NULL;
2147         guint16     bc;
2148         gboolean    trunc;
2149
2150         if (parent_tree) {
2151                 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, ENC_NA);
2152                 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
2153         }
2154
2155         bc = tvb_captured_length_remaining(tvb, offset);
2156         offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
2157
2158         return offset;
2159 }
2160
2161 static int
2162 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2163 {
2164         proto_item *item = NULL;
2165         proto_tree *tree = NULL;
2166         guint16     bc;
2167         gboolean    trunc;
2168
2169         if (parent_tree) {
2170                 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, ENC_NA);
2171                 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
2172         }
2173
2174         bc = tvb_captured_length_remaining(tvb, offset);
2175         offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2176
2177         return offset;
2178 }
2179
2180 static int
2181 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2182 {
2183         proto_item *item = NULL;
2184         proto_tree *tree = NULL;
2185         guint16     bc;
2186         gboolean    trunc;
2187
2188         if (parent_tree) {
2189                 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, ENC_NA);
2190                 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
2191         }
2192
2193         bc = tvb_captured_length_remaining(tvb, offset);
2194         offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2195
2196         return offset;
2197 }
2198
2199 static int
2200 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2201 {
2202         proto_item *item = NULL;
2203         proto_tree *tree = NULL;
2204         guint16     bc;
2205         gboolean    trunc;
2206
2207         if (parent_tree) {
2208                 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, ENC_NA);
2209                 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
2210         }
2211
2212
2213         bc = tvb_captured_length_remaining(tvb, offset);
2214         offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2215
2216         return offset;
2217 }
2218
2219 static int
2220 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2221 {
2222         proto_item *item = NULL;
2223         proto_tree *tree = NULL;
2224         guint16     bc;
2225         gboolean    trunc;
2226
2227         if (parent_tree) {
2228                 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, ENC_NA);
2229                 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
2230         }
2231
2232
2233         bc = tvb_captured_length_remaining(tvb, offset);
2234         offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2235
2236         return offset;
2237 }
2238
2239 static const true_false_string tfs_disposition_delete_on_close = {
2240         "DELETE this file when closed",
2241         "Normal access, do not delete on close"
2242 };
2243
2244 static int
2245 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2246 {
2247         proto_item *item = NULL;
2248         proto_tree *tree = NULL;
2249
2250         if (parent_tree) {
2251                 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, ENC_NA);
2252                 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
2253         }
2254
2255         /* file disposition */
2256         proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2257
2258         return offset;
2259 }
2260
2261 static int
2262 dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2263 {
2264         proto_item *item = NULL;
2265         proto_tree *tree = NULL;
2266         guint32     next_offset;
2267         guint8      ea_name_len;
2268         guint16     ea_data_len;
2269
2270         if (parent_tree) {
2271                 item = proto_tree_add_item(parent_tree, hf_smb2_file_full_ea_info, tvb, offset, -1, ENC_NA);
2272                 tree = proto_item_add_subtree(item, ett_smb2_file_full_ea_info);
2273         }
2274
2275         while (1) {
2276                 int length;
2277                 const char *name = "";
2278                 const char *data = "";
2279                 guint16 bc;
2280                 int start_offset = offset;
2281                 proto_item *ea_item;
2282                 proto_tree *ea_tree;
2283
2284                 ea_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_ea, &ea_item, "EA:");
2285
2286                 /* next offset */
2287                 next_offset = tvb_get_letohl(tvb, offset);
2288                 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2289                 offset += 4;
2290
2291                 /* EA flags */
2292                 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2293                 offset += 1;
2294
2295                 /* EA Name Length */
2296                 ea_name_len = tvb_get_guint8(tvb, offset);
2297                 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2298                 offset += 1;
2299
2300                 /* EA Data Length */
2301                 ea_data_len = tvb_get_letohs(tvb, offset);
2302                 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2303                 offset += 2;
2304
2305                 /* ea name */
2306                 length = ea_name_len;
2307                 if (length) {
2308                         bc = tvb_captured_length_remaining(tvb, offset);
2309                         name = get_unicode_or_ascii_string(tvb, &offset,
2310                                 FALSE, &length, TRUE, TRUE, &bc);
2311                         if (name) {
2312                                 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
2313                                         offset, length + 1, name);
2314                         }
2315                 }
2316
2317                 /* The name is terminated with a NULL */
2318                 offset += ea_name_len + 1;
2319
2320                 /* ea data */
2321                 length = ea_data_len;
2322                 if (length) {
2323                         bc = tvb_captured_length_remaining(tvb, offset);
2324                         data = get_unicode_or_ascii_string(tvb, &offset,
2325                                 FALSE, &length, TRUE, TRUE, &bc);
2326                         /*
2327                          * We put the data here ...
2328                          */
2329                         proto_tree_add_item(ea_tree, hf_smb2_ea_data, tvb,
2330                                         offset, length, ENC_NA);
2331                 }
2332                 offset += ea_data_len;
2333
2334
2335                 if (ea_item) {
2336                         proto_item_append_text(ea_item, " %s := %s", name, data);
2337                 }
2338                 proto_item_set_len(ea_item, offset-start_offset);
2339
2340
2341                 if (!next_offset) {
2342                         break;
2343                 }
2344
2345                 offset = start_offset+next_offset;
2346         }
2347
2348         return offset;
2349 }
2350
2351 static const true_false_string tfs_replace_if_exists = {
2352         "Replace the target if it exists",
2353         "Fail if the target exists"
2354 };
2355
2356 static int
2357 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2358 {
2359         proto_item *item = NULL;
2360         proto_tree *tree = NULL;
2361         int         length;
2362         const char *name = "";
2363         guint16     bc;
2364
2365
2366         if (parent_tree) {
2367                 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, ENC_NA);
2368                 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
2369         }
2370
2371         /* ReplaceIfExists */
2372         proto_tree_add_item(tree, hf_smb2_replace_if, tvb, offset, 1, ENC_NA);
2373         offset += 1;
2374
2375         /* reserved */
2376         proto_tree_add_item(tree, hf_smb2_reserved_random, tvb, offset, 7, ENC_NA);
2377         offset += 7;
2378
2379         /* Root Directory Handle, MBZ */
2380         proto_tree_add_item(tree, hf_smb2_root_directory_mbz, tvb, offset, 8, ENC_NA);
2381         offset += 8;
2382
2383         /* file name length */
2384         length = tvb_get_letohs(tvb, offset);
2385         proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2386         offset += 4;
2387
2388         /* file name */
2389         if (length) {
2390                 bc = tvb_captured_length_remaining(tvb, offset);
2391                 name = get_unicode_or_ascii_string(tvb, &offset,
2392                         TRUE, &length, TRUE, TRUE, &bc);
2393                 if (name) {
2394                         proto_tree_add_string(tree, hf_smb2_filename, tvb,
2395                                 offset, length, name);
2396                 }
2397
2398                 col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s", name);
2399         }
2400         offset += length;
2401
2402         return offset;
2403 }
2404
2405 static int
2406 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2407 {
2408         proto_item *item = NULL;
2409         proto_tree *tree = NULL;
2410
2411         if (parent_tree) {
2412                 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, ENC_NA);
2413                 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
2414         }
2415
2416         /* security descriptor */
2417         offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_captured_length_remaining(tvb, offset), NULL);
2418
2419         return offset;
2420 }
2421
2422 static int
2423 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2424 {
2425         proto_item *item = NULL;
2426         proto_tree *tree = NULL;
2427         guint16     bc;
2428
2429         if (parent_tree) {
2430                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, ENC_NA);
2431                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
2432         }
2433
2434         bc = tvb_captured_length_remaining(tvb, offset);
2435         offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2436
2437         return offset;
2438 }
2439
2440 static int
2441 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2442 {
2443         proto_item *item = NULL;
2444         proto_tree *tree = NULL;
2445         guint16     bc;
2446
2447         if (parent_tree) {
2448                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, ENC_NA);
2449                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
2450         }
2451
2452         bc = tvb_captured_length_remaining(tvb, offset);
2453         offset = dissect_nt_quota(tvb, tree, offset, &bc);
2454
2455         return offset;
2456 }
2457
2458 static int
2459 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2460 {
2461         proto_item *item = NULL;
2462         proto_tree *tree = NULL;
2463
2464         if (parent_tree) {
2465                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, ENC_NA);
2466                 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
2467         }
2468
2469         /* FILE_OBJECTID_BUFFER */
2470         offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2471
2472         return offset;
2473 }
2474
2475 static int
2476 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2477 {
2478         proto_item *item = NULL;
2479         proto_tree *tree = NULL;
2480         guint16     bc;
2481
2482         if (parent_tree) {
2483                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, ENC_NA);
2484                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
2485         }
2486
2487         bc = tvb_captured_length_remaining(tvb, offset);
2488         offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2489
2490         return offset;
2491 }
2492
2493 static int
2494 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2495 {
2496         proto_item *item = NULL;
2497         proto_tree *tree = NULL;
2498         guint16     bc;
2499
2500         if (parent_tree) {
2501                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, ENC_NA);
2502                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
2503         }
2504
2505
2506         bc = tvb_captured_length_remaining(tvb, offset);
2507         offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2508
2509         return offset;
2510 }
2511
2512 static int
2513 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2514 {
2515         proto_item *item = NULL;
2516         proto_tree *tree = NULL;
2517         guint16     bc;
2518
2519         if (parent_tree) {
2520                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, ENC_NA);
2521                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
2522         }
2523
2524
2525         bc = tvb_captured_length_remaining(tvb, offset);
2526         offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2527
2528         return offset;
2529 }
2530
2531 static int
2532 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2533 {
2534         proto_item *item = NULL;
2535         proto_tree *tree = NULL;
2536         guint16     bc;
2537
2538         if (parent_tree) {
2539                 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, ENC_NA);
2540                 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
2541         }
2542
2543
2544         bc = tvb_captured_length_remaining(tvb, offset);
2545         offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
2546
2547         return offset;
2548 }
2549
2550 static const value_string oplock_vals[] = {
2551         { 0x00, "No oplock" },
2552         { 0x01, "Level2 oplock" },
2553         { 0x08, "Exclusive oplock" },
2554         { 0x09, "Batch oplock" },
2555         { 0xff, "Lease" },
2556         { 0, NULL }
2557 };
2558
2559 static int
2560 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2561 {
2562         proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2563
2564         offset += 1;
2565         return offset;
2566 }
2567
2568 static int
2569 dissect_smb2_buffercode(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 *length)
2570 {
2571         proto_tree *tree;
2572         proto_item *item;
2573         guint16 buffer_code;
2574
2575         /* dissect the first 2 bytes of the command PDU */
2576         buffer_code = tvb_get_letohs(tvb, offset);
2577         item = proto_tree_add_uint(parent_tree, hf_smb2_buffer_code, tvb, offset, 2, buffer_code);
2578         tree = proto_item_add_subtree(item, ett_smb2_buffercode);
2579         proto_tree_add_item(tree, hf_smb2_buffer_code_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2580         proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2581         offset += 2;
2582
2583         if (length) {
2584                 *length = buffer_code; /*&0xfffe don't mask it here, mask it on caller side */
2585         }
2586
2587         return offset;
2588 }
2589
2590 #define NEGPROT_CAP_DFS         0x00000001
2591 #define NEGPROT_CAP_LEASING     0x00000002
2592 #define NEGPROT_CAP_LARGE_MTU   0x00000004
2593 #define NEGPROT_CAP_MULTI_CHANNEL       0x00000008
2594 #define NEGPROT_CAP_PERSISTENT_HANDLES  0x00000010
2595 #define NEGPROT_CAP_DIRECTORY_LEASING   0x00000020
2596 #define NEGPROT_CAP_ENCRYPTION          0x00000040
2597 static int
2598 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2599 {
2600         static const int * flags[] = {
2601                 &hf_smb2_cap_dfs,
2602                 &hf_smb2_cap_leasing,
2603                 &hf_smb2_cap_large_mtu,
2604                 &hf_smb2_cap_multi_channel,
2605                 &hf_smb2_cap_persistent_handles,
2606                 &hf_smb2_cap_directory_leasing,
2607                 &hf_smb2_cap_encryption,
2608                 NULL
2609         };
2610
2611         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_capabilities, ett_smb2_capabilities, flags, ENC_LITTLE_ENDIAN);
2612         offset += 4;
2613
2614         return offset;
2615 }
2616
2617
2618
2619 #define NEGPROT_SIGN_REQ        0x0002
2620 #define NEGPROT_SIGN_ENABLED    0x0001
2621
2622 static int
2623 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2624 {
2625         static const int * flags[] = {
2626                 &hf_smb2_secmode_flags_sign_enabled,
2627                 &hf_smb2_secmode_flags_sign_required,
2628                 NULL
2629         };
2630
2631         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_security_mode, ett_smb2_sec_mode, flags, ENC_LITTLE_ENDIAN);
2632         offset += 1;
2633
2634         return offset;
2635 }
2636
2637 #define SES_REQ_FLAGS_SESSION_BINDING           0x01
2638
2639 static int
2640 dissect_smb2_ses_req_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2641 {
2642         static const int * flags[] = {
2643                 &hf_smb2_ses_req_flags_session_binding,
2644                 NULL
2645         };
2646
2647         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_ses_req_flags, ett_smb2_ses_req_flags, flags, ENC_LITTLE_ENDIAN);
2648         offset += 1;
2649
2650         return offset;
2651 }
2652
2653 #define SES_FLAGS_GUEST         0x0001
2654 #define SES_FLAGS_NULL          0x0002
2655
2656 static int
2657 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2658 {
2659         static const int * flags[] = {
2660                 &hf_smb2_ses_flags_guest,
2661                 &hf_smb2_ses_flags_null,
2662                 NULL
2663         };
2664
2665         proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_session_flags, ett_smb2_ses_flags, flags, ENC_LITTLE_ENDIAN);
2666         offset += 2;
2667
2668         return offset;
2669 }
2670
2671 #define SHARE_FLAGS_manual_caching              0x00000000
2672 #define SHARE_FLAGS_auto_caching                0x00000010
2673 #define SHARE_FLAGS_vdo_caching                 0x00000020
2674 #define SHARE_FLAGS_no_caching                  0x00000030
2675
2676 static const value_string share_cache_vals[] = {
2677         { SHARE_FLAGS_manual_caching,   "Manual caching" },
2678         { SHARE_FLAGS_auto_caching,     "Auto caching" },
2679         { SHARE_FLAGS_vdo_caching,      "VDO caching" },
2680         { SHARE_FLAGS_no_caching,       "No caching" },
2681         { 0, NULL }
2682 };
2683
2684 #define SHARE_FLAGS_dfs                         0x00000001
2685 #define SHARE_FLAGS_dfs_root                    0x00000002
2686 #define SHARE_FLAGS_restrict_exclusive_opens    0x00000100
2687 #define SHARE_FLAGS_force_shared_delete         0x00000200
2688 #define SHARE_FLAGS_allow_namespace_caching     0x00000400
2689 #define SHARE_FLAGS_access_based_dir_enum       0x00000800
2690 #define SHARE_FLAGS_force_levelii_oplock        0x00001000
2691 #define SHARE_FLAGS_enable_hash_v1              0x00002000
2692 #define SHARE_FLAGS_enable_hash_v2              0x00004000
2693 #define SHARE_FLAGS_encryption_required         0x00008000
2694
2695 static int
2696 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
2697 {
2698         static const int *sf_fields[] = {
2699                 &hf_smb2_share_flags_dfs,
2700                 &hf_smb2_share_flags_dfs_root,
2701                 &hf_smb2_share_flags_restrict_exclusive_opens,
2702                 &hf_smb2_share_flags_force_shared_delete,
2703                 &hf_smb2_share_flags_allow_namespace_caching,
2704                 &hf_smb2_share_flags_access_based_dir_enum,
2705                 &hf_smb2_share_flags_force_levelii_oplock,
2706                 &hf_smb2_share_flags_enable_hash_v1,
2707                 &hf_smb2_share_flags_enable_hash_v2,
2708                 &hf_smb2_share_flags_encrypt_data,
2709                 NULL
2710         };
2711         proto_item *item;
2712         guint32 cp;
2713
2714         item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, ENC_LITTLE_ENDIAN);
2715
2716         cp = tvb_get_letohl(tvb, offset);
2717         cp &= 0x00000030;
2718         proto_tree_add_uint_format(item, hf_smb2_share_caching, tvb, offset, 4, cp, "Caching policy: %s (%08x)", val_to_str(cp, share_cache_vals, "Unknown:%u"), cp);
2719
2720
2721         offset += 4;
2722
2723         return offset;
2724 }
2725
2726 #define SHARE_CAPS_DFS                          0x00000008
2727 #define SHARE_CAPS_CONTINUOUS_AVAILABILITY      0x00000010
2728 #define SHARE_CAPS_SCALEOUT                     0x00000020
2729 #define SHARE_CAPS_CLUSTER                      0x00000040
2730
2731 static int
2732 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
2733 {
2734         static const int *sc_fields[] = {
2735                 &hf_smb2_share_caps_dfs,
2736                 &hf_smb2_share_caps_continuous_availability,
2737                 &hf_smb2_share_caps_scaleout,
2738                 &hf_smb2_share_caps_cluster,
2739                 NULL
2740         };
2741
2742         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, ENC_LITTLE_ENDIAN);
2743
2744         offset += 4;
2745
2746         return offset;
2747 }
2748
2749 static void
2750 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
2751 {
2752         if ((tvb_captured_length(tvb)>=7)
2753         &&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))) {
2754                 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
2755         } else {
2756                 call_dissector(gssapi_handle, tvb, pinfo, tree);
2757         }
2758 }
2759
2760 static int
2761 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2762 {
2763         offset_length_buffer_t  s_olb;
2764         const ntlmssp_header_t *ntlmssph;
2765         static int ntlmssp_tap_id = 0;
2766         int        idx;
2767
2768         if (!ntlmssp_tap_id) {
2769                 GString *error_string;
2770                 /* We don't specify any callbacks at all.
2771                  * Instead we manually fetch the tapped data after the
2772                  * security blob has been fully dissected and before
2773                  * we exit from this dissector.
2774                  */
2775                 error_string = register_tap_listener("ntlmssp", NULL, NULL,
2776                     TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
2777                 if (!error_string) {
2778                         ntlmssp_tap_id = find_tap_id("ntlmssp");
2779                 } else {
2780                         g_string_free(error_string, TRUE);
2781                 }
2782         }
2783
2784
2785         /* buffer code */
2786         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2787         /* some unknown bytes */
2788
2789         /* flags */
2790         offset = dissect_smb2_ses_req_flags(tree, tvb, offset);
2791
2792         /* security mode */
2793         offset = dissect_smb2_secmode(tree, tvb, offset);
2794
2795         /* capabilities */
2796         offset = dissect_smb2_capabilities(tree, tvb, offset);
2797
2798         /* channel */
2799         proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2800         offset += 4;
2801
2802         /* security blob offset/length */
2803         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2804
2805         /* previous session id */
2806         proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2807         offset += 8;
2808
2809
2810         /* the security blob itself */
2811         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2812
2813         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2814
2815         /* If we have found a uid->acct_name mapping, store it */
2816         if (!pinfo->fd->flags.visited) {
2817                 idx = 0;
2818                 while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
2819                         if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
2820                                 smb2_sesid_info_t *sesid;
2821                                 sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
2822                                 sesid->sesid = si->sesid;
2823                                 sesid->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
2824                                 sesid->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
2825                                 sesid->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
2826                                 if (memcmp(ntlmssph->session_key, zeros, NTLMSSP_KEY_LEN) != 0) {
2827                                         smb2_key_derivation(ntlmssph->session_key,
2828                                                             NTLMSSP_KEY_LEN,
2829                                                             "SMB2AESCCM", 11,
2830                                                             "ServerIn ", 10,
2831                                                             sesid->server_decryption_key);
2832                                         smb2_key_derivation(ntlmssph->session_key,
2833                                                             NTLMSSP_KEY_LEN,
2834                                                             "SMB2AESCCM", 11,
2835                                                             "ServerOut", 10,
2836                                                             sesid->client_decryption_key);
2837                                 } else {
2838                                         memset(sesid->server_decryption_key, 0,
2839                                                sizeof(sesid->server_decryption_key));
2840                                         memset(sesid->client_decryption_key, 0,
2841                                                sizeof(sesid->client_decryption_key));
2842                                 }
2843                                 sesid->server_port = pinfo->destport;
2844                                 sesid->auth_frame = pinfo->num;
2845                                 sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2846                                 g_hash_table_insert(si->conv->sesids, sesid, sesid);
2847                         }
2848                 }
2849         }
2850
2851         return offset;
2852 }
2853
2854 /* This needs more fixes for cases when the original header had also the constant value of 9.
2855    This should be fixed on caller side where it decides if it has to call this or not.
2856 */
2857 static int
2858 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_,
2859                                                         gboolean* continue_dissection)
2860 {
2861         gint byte_count;
2862         guint16 length;
2863
2864         /* buffer code */
2865         offset = dissect_smb2_buffercode(tree, tvb, offset, &length);
2866
2867         /* FIX: error response uses this constant, if not then it is not an error response */
2868         if(length != 9)
2869         {
2870                 if(continue_dissection)
2871                         *continue_dissection = TRUE;
2872         } else {
2873                 if(continue_dissection)
2874                         *continue_dissection = FALSE;
2875
2876                 /* Reserved (2 bytes) */
2877                 proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2878                 offset += 2;
2879
2880                 /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
2881                 byte_count = tvb_get_ntohl(tvb, offset);
2882                 proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2883                 offset += 4;
2884
2885                 /* If the ByteCount field is zero then the server MUST supply an ErrorData field
2886                    that is one byte in length */
2887                 if (byte_count == 0) byte_count = 1;
2888
2889                 /* ErrorData (variable): A variable-length data field that contains extended
2890                    error information.*/
2891                 proto_tree_add_item(tree, hf_smb2_error_data, tvb, offset, byte_count, ENC_NA);
2892                 offset += byte_count;
2893         }
2894
2895         return offset;
2896 }
2897
2898 static int
2899 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2900 {
2901         offset_length_buffer_t s_olb;
2902
2903         /* session_setup is special and we don't use dissect_smb2_error_response() here! */
2904
2905         /* buffer code */
2906         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2907
2908         /* session flags */
2909         offset = dissect_smb2_ses_flags(tree, tvb, offset);
2910
2911         /* security blob offset/length */
2912         offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2913
2914         /* the security blob itself */
2915         dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2916
2917         offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2918
2919         /* If we have found a uid->acct_name mapping, store it */
2920 #ifdef HAVE_KERBEROS
2921         if (!pinfo->fd->flags.visited && si->status == 0) {
2922                 enc_key_t *ek;
2923
2924                 if (krb_decrypt) {
2925                         read_keytab_file_from_preferences();
2926                 }
2927
2928                 for (ek=enc_key_list;ek;ek=ek->next) {
2929                         if (ek->fd_num == (int)pinfo->num) {
2930                                 break;
2931                         }
2932                 }
2933
2934                 if (ek != NULL) {
2935                         smb2_sesid_info_t *sesid;
2936                         guint8 session_key[16] = { 0, };
2937
2938                         memcpy(session_key, ek->keyvalue, MIN(ek->keylength, 16));
2939
2940                         sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
2941                         sesid->sesid = si->sesid;
2942                         /* TODO: fill in the correct information */
2943                         sesid->acct_name = NULL;
2944                         sesid->domain_name = NULL;
2945                         sesid->host_name = NULL;
2946                         smb2_key_derivation(session_key, sizeof(session_key),
2947                                             "SMB2AESCCM", 11,
2948                                             "ServerIn ", 10,
2949                                             sesid->server_decryption_key);
2950                         smb2_key_derivation(session_key, sizeof(session_key),
2951                                             "SMB2AESCCM", 11,
2952                                             "ServerOut", 10,
2953                                             sesid->client_decryption_key);
2954                         sesid->server_port = pinfo->srcport;
2955                         sesid->auth_frame = pinfo->num;
2956                         sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2957                         g_hash_table_insert(si->conv->sesids, sesid, sesid);
2958                 }
2959         }
2960 #endif
2961
2962         return offset;
2963 }
2964
2965 static int
2966 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2967 {
2968         offset_length_buffer_t olb;
2969         const char *buf;
2970
2971         /* buffer code */
2972         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2973
2974         /* reserved */
2975         offset += 2;
2976
2977         /* tree  offset/length */
2978         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
2979
2980         /* tree string */
2981         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2982
2983         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2984
2985         /* treelen  +1 is overkill here if the string is unicode,
2986          * but who ever has more than a handful of TCON in a trace anyways
2987          */
2988         if (!pinfo->fd->flags.visited && si->saved && buf && olb.len) {
2989                 si->saved->extra_info_type = SMB2_EI_TREENAME;
2990                 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
2991                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2992         }
2993
2994         col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
2995
2996         return offset;
2997 }
2998 static int
2999 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3000 {
3001         guint16 share_type;
3002         gboolean continue_dissection;
3003
3004         switch (si->status) {
3005         /* buffer code */
3006         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3007         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3008                 if (!continue_dissection) return offset;
3009         }
3010
3011         /* share type */
3012         share_type = tvb_get_letohs(tvb, offset);
3013         proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3014         /* Next byte is reserved  and must be set to zero */
3015         offset += 2;
3016
3017         if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
3018                 smb2_tid_info_t *tid, tid_key;
3019
3020                 tid_key.tid = si->tid;
3021                 tid = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
3022                 if (tid) {
3023                         g_hash_table_remove(si->session->tids, &tid_key);
3024                 }
3025                 tid = wmem_new(wmem_file_scope(), smb2_tid_info_t);
3026                 tid->tid = si->tid;
3027                 tid->name = (char *)si->saved->extra_info;
3028                 tid->connect_frame = pinfo->num;
3029                 tid->share_type = share_type;
3030
3031                 g_hash_table_insert(si->session->tids, tid, tid);
3032
3033                 si->saved->extra_info_type = SMB2_EI_NONE;
3034                 si->saved->extra_info = NULL;
3035         }
3036
3037         /* share flags */
3038         offset = dissect_smb2_share_flags(tree, tvb, offset);
3039
3040         /* share capabilities */
3041         offset = dissect_smb2_share_caps(tree, tvb, offset);
3042
3043         /* this is some sort of access mask */
3044         offset = dissect_smb_access_mask(tvb, tree, offset);
3045
3046         return offset;
3047 }
3048
3049 static int
3050 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3051 {
3052         /* buffer code */
3053         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3054
3055         /* reserved */
3056         offset += 2;
3057
3058         return offset;
3059 }
3060
3061 static int
3062 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3063 {
3064         gboolean continue_dissection;
3065
3066         switch (si->status) {
3067         /* buffer code */
3068         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3069         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3070                 if (!continue_dissection) return offset;
3071         }
3072
3073         /* reserved */
3074         offset += 2;
3075
3076         return offset;
3077 }
3078
3079 static int
3080 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3081 {
3082         /* buffer code */
3083         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3084
3085         /* reserved bytes */
3086         offset += 2;
3087
3088         return offset;
3089 }
3090
3091 static int
3092 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3093 {
3094         gboolean continue_dissection;
3095
3096         switch (si->status) {
3097         /* buffer code */
3098         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3099         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3100                 if (!continue_dissection) return offset;
3101         }
3102
3103         /* reserved bytes */
3104         offset += 2;
3105
3106         return offset;
3107 }
3108
3109 static int
3110 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3111 {
3112         /* buffer code */
3113         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3114
3115         /* some unknown bytes */
3116         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3117         offset += 2;
3118
3119         return offset;
3120 }
3121
3122 static int
3123 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3124 {
3125         gboolean continue_dissection;
3126
3127         switch (si->status) {
3128         /* buffer code */
3129         case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3130         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3131                 if (!continue_dissection) return offset;
3132         }
3133
3134         /* some unknown bytes */
3135         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3136         offset += 2;
3137
3138         return offset;
3139 }
3140
3141 static int
3142 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3143 {
3144         proto_tree *flags_tree = NULL;
3145         proto_item *flags_item = NULL;
3146
3147         /* buffer code */
3148         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3149
3150         /* notify flags */
3151         if (tree) {
3152                 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3153                 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
3154         }
3155         proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3156         offset += 2;
3157
3158         /* output buffer length */
3159         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3160         offset += 4;
3161
3162         /* fid */
3163         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3164
3165         /* completion filter */
3166         offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
3167
3168         /* reserved */
3169         offset += 4;
3170
3171         return offset;
3172 }
3173
3174 static const value_string notify_action_vals[] = {
3175         {0x01, "FILE_ACTION_ADDED"},
3176         {0x02, "FILE_ACTION_REMOVED"},
3177         {0x03, "FILE_ACTION_MODIFIED"},
3178         {0x04, "FILE_ACTION_RENAMED_OLD_NAME"},
3179         {0x05, "FILE_ACTION_RENAMED_NEW_NAME"},
3180         {0x06, "FILE_ACTION_ADDED_STREAM"},
3181         {0x07, "FILE_ACTION_REMOVED_STREAM"},
3182         {0x08, "FILE_ACTION_MODIFIED_STREAM"},
3183         {0x09, "FILE_ACTION_REMOVED_BY_DELETE"},
3184         {0, NULL}
3185 };
3186
3187 static void
3188 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3189 {
3190         proto_tree *tree = NULL;
3191         proto_item *item = NULL;
3192         int offset = 0;
3193
3194         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3195                 guint32 start_offset = offset;
3196                 guint32 next_offset;
3197                 guint32 length;
3198
3199                 if (parent_tree) {
3200                         item = proto_tree_add_item(parent_tree, hf_smb2_notify_info, tvb, offset, -1, ENC_NA);
3201                         tree = proto_item_add_subtree(item, ett_smb2_notify_info);
3202                 }
3203
3204                 /* next offset */
3205                 proto_tree_add_item_ret_uint(tree, hf_smb2_notify_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &next_offset);
3206                 offset += 4;
3207
3208                 proto_tree_add_item(tree, hf_smb2_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3209                 offset += 4;
3210
3211                 /* file name length */
3212                 proto_tree_add_item_ret_uint(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
3213                 offset += 4;
3214
3215                 /* file name */
3216                 if (length) {
3217                         const guchar *name = "";
3218                         guint16     bc;
3219
3220                         bc = tvb_reported_length_remaining(tvb, offset);
3221                         name = get_unicode_or_ascii_string(tvb, &offset,
3222                                         TRUE, &length, TRUE, TRUE, &bc);
3223                         if (name) {
3224                                 proto_tree_add_string(tree, hf_smb2_filename,
3225                                                       tvb, offset, length,
3226                                                       name);
3227                         }
3228
3229                         offset += length;
3230                 }
3231
3232                 if (!next_offset) {
3233                         break;
3234                 }
3235
3236                 offset = start_offset+next_offset;
3237         }
3238 }
3239
3240 static int
3241 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3242 {
3243         offset_length_buffer_t olb;
3244         gboolean continue_dissection;
3245
3246         switch (si->status) {
3247         /* MS-SMB2 3.3.4.4 says STATUS_NOTIFY_ENUM_DIR is not treated as an error */
3248         case 0x0000010c: /* STATUS_NOTIFY_ENUM_DIR */
3249         case 0x00000000: /* buffer code */
3250          offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3251         default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3252                 if (!continue_dissection) return offset;
3253         }
3254
3255         /* out buffer offset/length */
3256         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
3257
3258         /* out buffer */
3259         dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
3260         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3261
3262         return offset;
3263 }
3264
3265 #define SMB2_FIND_FLAG_RESTART_SCANS            0x01
3266 #define SMB2_FIND_FLAG_SINGLE_ENTRY             0x02
3267 #define SMB2_FIND_FLAG_INDEX_SPECIFIED          0x04
3268 #define SMB2_FIND_FLAG_REOPEN                   0x10
3269
3270 static int
3271 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3272 {
3273         offset_length_buffer_t olb;
3274         const char *buf;
3275         guint8      il;
3276         static const int *f_fields[] = {
3277                 &hf_smb2_find_flags_restart_scans,
3278                 &hf_smb2_find_flags_single_entry,
3279                 &hf_smb2_find_flags_index_specified,
3280                 &hf_smb2_find_flags_reopen,
3281                 NULL
3282         };
3283
3284         /* buffer code */
3285         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3286
3287         il = tvb_get_guint8(tvb, offset);
3288         if (si->saved) {
3289                 si->saved->infolevel = il;
3290         }
3291
3292         /* infolevel */
3293         proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
3294         offset += 1;
3295
3296         /* find flags */
3297         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, ENC_LITTLE_ENDIAN);
3298         offset += 1;
3299
3300         /* file index */
3301         proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3302         offset += 4;
3303
3304         /* fid */
3305         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3306
3307         /* search pattern  offset/length */
3308         offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
3309
3310         /* output buffer length */
3311         proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3312         offset += 4;
3313
3314         /* search pattern */
3315         buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
3316
3317         offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3318
3319         if (!pinfo->fd->flags.visited && si->saved && olb.len) {
3320                 si->saved->extra_info_type = SMB2_EI_FINDPATTERN;
3321                 si->saved->extra_info = g_malloc(olb.len+1);
3322                 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
3323         }
3324
3325         col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
3326                         val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
3327                         buf);
3328
3329         return offset;
3330 }
3331
3332 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3333 {
3334         int         offset = 0;
3335         proto_item *item   = NULL;
3336         proto_tree *tree   = NULL;
3337         const char *name   = NULL;
3338         guint16     bc;
3339
3340         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3341                 int old_offset = offset;
3342                 int next_offset;
3343                 int file_name_len;
3344
3345                 if (parent_tree) {
3346                         item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, ENC_NA);
3347                         tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
3348                 }
3349
3350                 /* next offset */
3351                 next_offset = tvb_get_letohl(tvb, offset);
3352                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3353                 offset += 4;
3354
3355                 /* file index */
3356                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3357                 offset += 4;
3358
3359                 /* create time */
3360                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3361
3362                 /* last access */
3363                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3364
3365                 /* last write */
3366                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3367
3368                 /* last change */
3369                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3370
3371                 /* end of file */
3372                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3373                 offset += 8;
3374
3375                 /* allocation size */
3376                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3377                 offset += 8;
3378
3379                 /* File Attributes */
3380                 offset = dissect_file_ext_attr(tvb, tree, offset);
3381
3382                 /* file name length */
3383                 file_name_len = tvb_get_letohl(tvb, offset);
3384                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3385                 offset += 4;
3386
3387                 /* file name */
3388                 if (file_name_len) {
3389                         bc = file_name_len;
3390                         name = get_unicode_or_ascii_string(tvb, &offset,
3391                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3392                         if (name) {
3393                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3394                                         offset, file_name_len, name);
3395                                 proto_item_append_text(item, ": %s", name);
3396
3397                         }
3398                 }
3399
3400                 proto_item_set_len(item, offset-old_offset);
3401
3402                 if (next_offset == 0) {
3403                         return;
3404                 }
3405
3406                 offset = old_offset+next_offset;
3407                 if (offset < old_offset) {
3408                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3409                                     "Invalid offset/length. Malformed packet");
3410                         return;
3411                 }
3412         }
3413 }
3414
3415 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3416 {
3417         int         offset = 0;
3418         proto_item *item   = NULL;
3419         proto_tree *tree   = NULL;
3420         const char *name   = NULL;
3421         guint16     bc;
3422
3423         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3424                 int old_offset = offset;
3425                 int next_offset;
3426                 int file_name_len;
3427
3428                 if (parent_tree) {
3429                         item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, ENC_NA);
3430                         tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
3431                 }
3432
3433                 /* next offset */
3434                 next_offset = tvb_get_letohl(tvb, offset);
3435                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3436                 offset += 4;
3437
3438                 /* file index */
3439                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3440                 offset += 4;
3441
3442                 /* create time */
3443                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3444
3445                 /* last access */
3446                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3447
3448                 /* last write */
3449                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3450
3451                 /* last change */
3452                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3453
3454                 /* end of file */
3455                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3456                 offset += 8;
3457
3458                 /* allocation size */
3459                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3460                 offset += 8;
3461
3462                 /* File Attributes */
3463                 offset = dissect_file_ext_attr(tvb, tree, offset);
3464
3465                 /* file name length */
3466                 file_name_len = tvb_get_letohl(tvb, offset);
3467                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3468                 offset += 4;
3469
3470                 /* ea size */
3471                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3472                 offset += 4;
3473
3474                 /* file name */
3475                 if (file_name_len) {
3476                         bc = file_name_len;
3477                         name = get_unicode_or_ascii_string(tvb, &offset,
3478                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3479                         if (name) {
3480                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3481                                         offset, file_name_len, name);
3482                                 proto_item_append_text(item, ": %s", name);
3483
3484                         }
3485                 }
3486
3487                 proto_item_set_len(item, offset-old_offset);
3488
3489                 if (next_offset == 0) {
3490                         return;
3491                 }
3492
3493                 offset = old_offset+next_offset;
3494                 if (offset < old_offset) {
3495                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3496                                     "Invalid offset/length. Malformed packet");
3497                         return;
3498                 }
3499         }
3500 }
3501
3502 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3503 {
3504         int         offset = 0;
3505         proto_item *item   = NULL;
3506         proto_tree *tree   = NULL;
3507         const char *name   = NULL;
3508         guint16     bc;
3509
3510         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3511                 int old_offset = offset;
3512                 int next_offset;
3513                 int file_name_len;
3514                 int short_name_len;
3515
3516                 if (parent_tree) {
3517                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
3518                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
3519                 }
3520
3521                 /* next offset */
3522                 next_offset = tvb_get_letohl(tvb, offset);
3523                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3524                 offset += 4;
3525
3526                 /* file index */
3527                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3528                 offset += 4;
3529
3530                 /* create time */
3531                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3532
3533                 /* last access */
3534                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3535
3536                 /* last write */
3537                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3538
3539                 /* last change */
3540                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3541
3542                 /* end of file */
3543                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3544                 offset += 8;
3545
3546                 /* allocation size */
3547                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3548                 offset += 8;
3549
3550                 /* File Attributes */
3551                 offset = dissect_file_ext_attr(tvb, tree, offset);
3552
3553                 /* file name length */
3554                 file_name_len = tvb_get_letohl(tvb, offset);
3555                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3556                 offset += 4;
3557
3558                 /* ea size */
3559                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3560                 offset += 4;
3561
3562                 /* short name length */
3563                 short_name_len = tvb_get_guint8(tvb, offset);
3564                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3565                 offset += 1;
3566
3567                 /* reserved */
3568                 offset += 1;
3569
3570                 /* short name */
3571                 if (short_name_len) {
3572                         bc = short_name_len;
3573                         name = get_unicode_or_ascii_string(tvb, &offset,
3574                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
3575                         if (name) {
3576                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
3577                                         offset, short_name_len, name);
3578                         }
3579                 }
3580                 offset += 24;
3581
3582                 /* file name */
3583                 if (file_name_len) {
3584                         bc = file_name_len;
3585                         name = get_unicode_or_ascii_string(tvb, &offset,
3586                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3587                         if (name) {
3588                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3589                                         offset, file_name_len, name);
3590                                 proto_item_append_text(item, ": %s", name);
3591
3592                         }
3593                 }
3594
3595                 proto_item_set_len(item, offset-old_offset);
3596
3597                 if (next_offset == 0) {
3598                         return;
3599                 }
3600
3601                 offset = old_offset+next_offset;
3602                 if (offset < old_offset) {
3603                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3604                                     "Invalid offset/length. Malformed packet");
3605                         return;
3606                 }
3607         }
3608 }
3609
3610 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3611 {
3612         int         offset = 0;
3613         proto_item *item   = NULL;
3614         proto_tree *tree   = NULL;
3615         const char *name   = NULL;
3616         guint16     bc;
3617
3618         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3619                 int old_offset = offset;
3620                 int next_offset;
3621                 int file_name_len;
3622
3623                 if (parent_tree) {
3624                         item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
3625                         tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
3626                 }
3627
3628                 /* next offset */
3629                 next_offset = tvb_get_letohl(tvb, offset);
3630                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3631                 offset += 4;
3632
3633                 /* file index */
3634                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3635                 offset += 4;
3636
3637                 /* file name length */
3638                 file_name_len = tvb_get_letohl(tvb, offset);
3639                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3640                 offset += 4;
3641
3642                 /* file name */
3643                 if (file_name_len) {
3644                         bc = file_name_len;
3645                         name = get_unicode_or_ascii_string(tvb, &offset,
3646                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3647                         if (name) {
3648                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3649                                         offset, file_name_len, name);
3650                                 proto_item_append_text(item, ": %s", name);
3651
3652                         }
3653                 }
3654
3655                 proto_item_set_len(item, offset-old_offset);
3656
3657                 if (next_offset == 0) {
3658                         return;
3659                 }
3660
3661                 offset = old_offset+next_offset;
3662                 if (offset < old_offset) {
3663                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3664                                     "Invalid offset/length. Malformed packet");
3665                         return;
3666                 }
3667         }
3668 }
3669
3670 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3671 {
3672         int         offset = 0;
3673         proto_item *item   = NULL;
3674         proto_tree *tree   = NULL;
3675         const char *name   = NULL;
3676         guint16     bc;
3677
3678         while (tvb_reported_length_remaining(tvb, offset) > 4) {
3679                 int old_offset = offset;
3680                 int next_offset;
3681                 int file_name_len;
3682                 int short_name_len;
3683
3684                 if (parent_tree) {
3685                         item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
3686                         tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
3687                 }
3688
3689                 /* next offset */
3690                 next_offset = tvb_get_letohl(tvb, offset);
3691                 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3692                 offset += 4;
3693
3694                 /* file index */
3695                 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3696                 offset += 4;
3697
3698                 /* create time */
3699                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3700
3701                 /* last access */
3702                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3703
3704                 /* last write */
3705                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3706
3707                 /* last change */
3708                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3709
3710                 /* end of file */
3711                 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3712                 offset += 8;
3713
3714                 /* allocation size */
3715                 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3716                 offset += 8;
3717
3718                 /* File Attributes */
3719                 offset = dissect_file_ext_attr(tvb, tree, offset);
3720
3721                 /* file name length */
3722                 file_name_len = tvb_get_letohl(tvb, offset);
3723                 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3724                 offset += 4;
3725
3726                 /* ea size */
3727                 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3728                 offset += 4;
3729
3730                 /* short name length */
3731                 short_name_len = tvb_get_guint8(tvb, offset);
3732                 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3733                 offset += 1;
3734
3735                 /* reserved */
3736                 offset += 1;
3737
3738                 /* short name */
3739                 if (short_name_len) {
3740                         bc = short_name_len;
3741                         name = get_unicode_or_ascii_string(tvb, &offset,
3742                                 TRUE, &short_name_len, TRUE, TRUE, &bc);
3743                         if (name) {
3744                                 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
3745                                         offset, short_name_len, name);
3746                         }
3747                 }
3748                 offset += 24;
3749
3750                 /* reserved */
3751                 offset += 2;
3752
3753                 /* file id */
3754                 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3755                 offset += 8;
3756
3757                 /* file name */
3758                 if (file_name_len) {
3759                         bc = file_name_len;
3760                         name = get_unicode_or_ascii_string(tvb, &offset,
3761                                 TRUE, &file_name_len, TRUE, TRUE, &bc);
3762                         if (name) {
3763                                 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3764                                         offset, file_name_len, name);
3765                                 proto_item_append_text(item, ": %s", name);
3766
3767                         }
3768                 }
3769
3770                 proto_item_set_len(item, offset-old_offset);
3771
3772                 if (next_offset == 0) {
3773                         return;
3774                 }
3775
3776                 offset = old_offset+next_offset;
3777                 if (offset < old_offset) {
3778                         proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
3779                                     "Invalid offset/length. Malformed packet");
3780                         return;
3781                 }
3782         }
3783 }
3784
3785
3786 typedef struct _smb2_find_dissector_t {
3787         guint32 level;
3788         void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
3789 } smb2_find_dissector_t;
3790
3791 smb2_find_dissector_t smb2_find_dissectors[] = {