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