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