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