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