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