packet-smb2: fix lease epoch fields
[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         offset += 2;
5348 }
5349
5350 static void
5351 dissect_smb2_RqLs_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5352 {
5353         dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
5354 }
5355
5356 static void
5357 dissect_smb2_RqLs_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5358 {
5359         dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
5360 }
5361
5362 /*
5363  * SMB2_CREATE_APP_INSTANCE_ID
5364  *  2 - structure size - 20
5365  *  2 - reserved
5366  * 16 - application guid
5367  */
5368
5369 static void
5370 dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5371 {
5372         int         offset   = 0;
5373         proto_item *item     = NULL;
5374         proto_item *sub_item = NULL;
5375         proto_item *sub_tree = NULL;
5376
5377         if (tree) {
5378                 item = proto_tree_get_parent(tree);
5379         }
5380
5381         if (item) {
5382                 proto_item_append_text(item, ": APP INSTANCE ID");
5383                 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "APP INSTANCE ID");
5384                 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_APP_INSTANCE_buffer);
5385         }
5386
5387         /* struct size */
5388         proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_struct_size,
5389                             tvb, offset, 2, ENC_LITTLE_ENDIAN);
5390         offset += 2;
5391
5392         /* reserved */
5393         proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_reserved,
5394                             tvb, offset, 2, ENC_LITTLE_ENDIAN);
5395         offset += 2;
5396
5397         /* create guid */
5398         proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_app_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5399 }
5400
5401 static void
5402 dissect_smb2_APP_INSTANCE_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5403 {
5404         report_create_context_malformed_buffer(tvb, pinfo, tree, "APP INSTANCE Response");
5405 }
5406
5407 typedef void (*create_context_data_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
5408
5409 typedef struct create_context_data_dissectors {
5410         create_context_data_dissector_t request;
5411         create_context_data_dissector_t response;
5412 } create_context_data_dissectors_t;
5413
5414 struct create_context_data_tag_dissectors {
5415         const char *tag;
5416         const char *val;
5417         create_context_data_dissectors_t dissectors;
5418 };
5419
5420 struct create_context_data_tag_dissectors create_context_dissectors_array[] = {
5421         { "ExtA", "SMB2_CREATE_EA_BUFFER",
5422           { dissect_smb2_ExtA_buffer_request, dissect_smb2_ExtA_buffer_response } },
5423         { "SecD", "SMB2_CREATE_SD_BUFFER",
5424           { dissect_smb2_SecD_buffer_request, dissect_smb2_SecD_buffer_response } },
5425         { "AlSi", "SMB2_CREATE_ALLOCATION_SIZE",
5426           { dissect_smb2_AlSi_buffer_request, dissect_smb2_AlSi_buffer_response } },
5427         { "MxAc", "SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST",
5428           { dissect_smb2_MxAc_buffer_request, dissect_smb2_MxAc_buffer_response } },
5429         { "DHnQ", "SMB2_CREATE_DURABLE_HANDLE_REQUEST",
5430           { dissect_smb2_DHnQ_buffer_request, dissect_smb2_DHnQ_buffer_response } },
5431         { "DHnC", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT",
5432           { dissect_smb2_DHnC_buffer_request, dissect_smb2_DHnC_buffer_response } },
5433         { "DH2Q", "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2",
5434           { dissect_smb2_DH2Q_buffer_request, dissect_smb2_DH2Q_buffer_response } },
5435         { "DH2C", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2",
5436           { dissect_smb2_DH2C_buffer_request, dissect_smb2_DH2C_buffer_response } },
5437         { "TWrp", "SMB2_CREATE_TIMEWARP_TOKEN",
5438           { dissect_smb2_TWrp_buffer_request, dissect_smb2_TWrp_buffer_response } },
5439         { "QFid", "SMB2_CREATE_QUERY_ON_DISK_ID",
5440           { dissect_smb2_QFid_buffer_request, dissect_smb2_QFid_buffer_response } },
5441         { "RqLs", "SMB2_CREATE_REQUEST_LEASE",
5442           { dissect_smb2_RqLs_buffer_request, dissect_smb2_RqLs_buffer_response } },
5443         { "744D142E-46FA-0890-4AF7-A7EF6AA6BC45", "SMB2_CREATE_APP_INSTANCE_ID",
5444                 { dissect_smb2_APP_INSTANCE_buffer_request,
5445                   dissect_smb2_APP_INSTANCE_buffer_response } }
5446 };
5447
5448 static struct create_context_data_tag_dissectors*
5449 get_create_context_data_tag_dissectors(const char *tag)
5450 {
5451         static struct create_context_data_tag_dissectors INVALID = {
5452                 NULL, "<invalid>", { NULL, NULL }
5453         };
5454
5455         size_t i;
5456         for (i = 0; i<array_length(create_context_dissectors_array); i++) {
5457                 if (!strcmp(tag, create_context_dissectors_array[i].tag))
5458                         return &create_context_dissectors_array[i];
5459         }
5460         return &INVALID;
5461 }
5462
5463 static void
5464 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
5465 {
5466         offset_length_buffer_t  tag_olb;
5467         offset_length_buffer_t  data_olb;
5468         const char *tag;
5469         guint16     chain_offset;
5470         int         offset      = 0;
5471         int         len         = -1;
5472         proto_item *sub_item    = NULL;
5473         proto_tree *sub_tree    = NULL;
5474         proto_item *parent_item = NULL;
5475         create_context_data_dissectors_t *dissectors = NULL;
5476         create_context_data_dissector_t   dissector  = NULL;
5477         struct create_context_data_tag_dissectors *tag_dissectors;
5478
5479         chain_offset = tvb_get_letohl(tvb, offset);
5480         if (chain_offset) {
5481                 len = chain_offset;
5482         }
5483
5484         if (parent_tree) {
5485                 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Chain Element");
5486                 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_create_chain_element);
5487                 parent_item = proto_tree_get_parent(parent_tree);
5488         }
5489
5490         /* chain offset */
5491         proto_tree_add_item(sub_tree, hf_smb2_create_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5492         offset += 4;
5493
5494         /* tag  offset/length */
5495         offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
5496
5497         /* data  offset/length */
5498         dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_create_chain_data);
5499
5500         /* tag string */
5501         tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
5502
5503         tag_dissectors = get_create_context_data_tag_dissectors(tag);
5504
5505         proto_item_append_text(parent_item, " %s", tag);
5506         proto_item_append_text(sub_item, ": %s \"%s\"", tag_dissectors->val, tag);
5507
5508         /* data */
5509         dissectors = &tag_dissectors->dissectors;
5510         if (dissectors)
5511                 dissector = (si->flags & SMB2_FLAGS_RESPONSE) ? dissectors->response : dissectors->request;
5512
5513         dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
5514
5515         if (chain_offset) {
5516                 tvbuff_t *chain_tvb;
5517                 chain_tvb = tvb_new_subset_remaining(tvb, chain_offset);
5518
5519                 /* next extra info */
5520                 dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
5521         }
5522 }
5523
5524 static int
5525 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5526 {
5527         offset_length_buffer_t  f_olb, e_olb;
5528         const char             *fname;
5529
5530         /* buffer code */
5531         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5532
5533         /* security flags */
5534         offset++;
5535
5536         /* oplock */
5537         offset = dissect_smb2_oplock(tree, tvb, offset);
5538
5539         /* impersonation level */
5540         proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5541         offset += 4;
5542
5543         /* create flags */
5544         proto_tree_add_item(tree, hf_smb2_create_flags, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5545         offset += 8;
5546
5547         /* reserved */
5548         offset += 8;
5549
5550         /* access mask */
5551         offset = dissect_smb_access_mask(tvb, tree, offset);
5552
5553         /* File Attributes */
5554         offset = dissect_file_ext_attr(tvb, tree, offset);
5555
5556         /* share access */
5557         offset = dissect_nt_share_access(tvb, tree, offset);
5558
5559         /* create disposition */
5560         proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5561         offset += 4;
5562
5563         /* create options */
5564         offset = dissect_nt_create_options(tvb, tree, offset);
5565
5566         /* filename  offset/length */
5567         offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
5568
5569         /* extrainfo offset */
5570         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
5571
5572         /* filename string */
5573         fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
5574         col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", fname);
5575
5576         /* save the name if it looks sane */
5577         if (!pinfo->fd->flags.visited) {
5578                 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
5579                         g_free(si->saved->extra_info);
5580                         si->saved->extra_info = NULL;
5581                         si->saved->extra_info_type = SMB2_EI_NONE;
5582                 }
5583                 if (si->saved && f_olb.len && f_olb.len<256) {
5584                         si->saved->extra_info_type = SMB2_EI_FILENAME;
5585                         si->saved->extra_info = (gchar *)g_malloc(f_olb.len+1);
5586                         g_snprintf((gchar *)si->saved->extra_info, f_olb.len+1, "%s", fname);
5587                 }
5588         }
5589
5590         /* If extrainfo_offset is non-null then this points to another
5591          * buffer. The offset is relative to the start of the smb packet
5592          */
5593         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
5594
5595         offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
5596         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
5597
5598         return offset;
5599 }
5600
5601 #define SMB2_CREATE_REP_FLAGS_REPARSE_POINT 0x01
5602
5603 static int
5604 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5605 {
5606         guint64 end_of_file;
5607         guint32 attr_mask;
5608         offset_length_buffer_t e_olb;
5609         static const int *create_rep_flags_fields[] = {
5610                 &hf_smb2_create_rep_flags_reparse_point,
5611                 NULL
5612         };
5613
5614         switch (si->status) {
5615         case 0x00000000: break;
5616         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
5617         }
5618
5619         /* buffer code */
5620         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5621
5622         /* oplock */
5623         offset = dissect_smb2_oplock(tree, tvb, offset);
5624
5625         /* reserved */
5626         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_create_rep_flags,
5627                                ett_smb2_create_rep_flags, create_rep_flags_fields, ENC_LITTLE_ENDIAN);
5628         offset += 1;
5629
5630         /* create action */
5631         proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5632         offset += 4;
5633
5634         /* create time */
5635         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
5636
5637         /* last access */
5638         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
5639
5640         /* last write */
5641         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
5642
5643         /* last change */
5644         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
5645
5646         /* allocation size */
5647         proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5648         offset += 8;
5649
5650         /* end of file */
5651         end_of_file = tvb_get_letoh64(tvb, offset);
5652         if (si->eo_file_info) {
5653                 si->eo_file_info->end_of_file = tvb_get_letoh64(tvb, offset);
5654         }
5655         proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5656         offset += 8;
5657
5658         /* File Attributes */
5659         attr_mask=tvb_get_letohl(tvb, offset);
5660         offset = dissect_file_ext_attr(tvb, tree, offset);
5661
5662         /* reserved */
5663         offset += 4;
5664
5665         /* fid */
5666         offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
5667
5668         /* We save this after dissect_smb2_fid just because it would be
5669         possible to have this response without having the mathing request.
5670         In that case the entry in the file info hash table has been created
5671         in dissect_smb2_fid */
5672         if (si->eo_file_info) {
5673                 si->eo_file_info->end_of_file = end_of_file;
5674                 si->eo_file_info->attr_mask = attr_mask;
5675         }
5676
5677         /* extrainfo offset */
5678         offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
5679
5680         /* If extrainfo_offset is non-null then this points to another
5681          * buffer. The offset is relative to the start of the smb packet
5682          */
5683         dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
5684
5685         offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
5686
5687         /* free si->saved->extra_info   we dont need it any more */
5688         if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
5689                 g_free(si->saved->extra_info);
5690                 si->saved->extra_info = NULL;
5691                 si->saved->extra_info_type = SMB2_EI_NONE;
5692         }
5693
5694         return offset;
5695 }
5696
5697
5698 static int
5699 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5700 {
5701         guint32 setinfo_size;
5702         guint16 setinfo_offset;
5703
5704         /* buffer code */
5705         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5706
5707         /* class and info level */
5708         offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5709
5710         /* size */
5711         setinfo_size = tvb_get_letohl(tvb, offset);
5712         proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5713         offset += 4;
5714
5715         /* offset */
5716         setinfo_offset = tvb_get_letohs(tvb, offset);
5717         proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5718         offset += 2;
5719
5720         /* some unknown bytes */
5721         proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
5722         offset += 6;
5723
5724         /* fid */
5725         dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5726
5727         /* data */
5728         if (si->saved)
5729           dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->smb2_class, si->saved->infolevel);
5730         offset = setinfo_offset + setinfo_size;
5731
5732         return offset;
5733 }
5734
5735 static int
5736 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5737 {
5738         /* class/infolevel */
5739         dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5740
5741         switch (si->status) {
5742         case 0x00000000: break;
5743         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
5744         }
5745
5746         /* buffer code */
5747         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5748
5749         return offset;
5750 }
5751
5752 static int
5753 dissect_smb2_break_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5754 {
5755         guint16 buffer_code;
5756
5757         /* buffer code */
5758         buffer_code = tvb_get_letohs(tvb, offset);
5759         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5760
5761         if (buffer_code == 24) {
5762                 /* OPLOCK Break */
5763
5764                 /* oplock */
5765                 offset = dissect_smb2_oplock(tree, tvb, offset);
5766
5767                 /* reserved */
5768                 offset += 1;
5769
5770                 /* reserved */
5771                 offset += 4;
5772
5773                 /* fid */
5774                 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5775
5776                 return offset;
5777         }
5778
5779         if (buffer_code == 36) {
5780                 /* Lease Break Acknowledgment */
5781
5782                 /* reserved */
5783                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5784                 offset +=2;
5785
5786                 /* lease flags */
5787                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
5788                                        ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5789                 offset += 4;
5790
5791                 /* lease key */
5792                 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5793                 offset += 16;
5794
5795                 /* lease state */
5796                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5797                                        ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5798                 offset += 4;
5799
5800                 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5801                 offset += 8;
5802
5803                 return offset;
5804         }
5805
5806         return offset;
5807 }
5808
5809 static int
5810 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5811 {
5812         guint16 buffer_code;
5813
5814         switch (si->status) {
5815         case 0x00000000: break;
5816         default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
5817         }
5818
5819         /* buffer code */
5820         buffer_code = tvb_get_letohs(tvb, offset);
5821         offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5822
5823         if (buffer_code == 24) {
5824                 /* OPLOCK Break Notification */
5825
5826                 /* oplock */
5827                 offset = dissect_smb2_oplock(tree, tvb, offset);
5828
5829                 /* reserved */
5830                 offset += 1;
5831
5832                 /* reserved */
5833                 offset += 4;
5834
5835                 /* fid */
5836                 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5837
5838                 /* in break requests from server to client here're 24 byte zero bytes
5839                  * which are likely a bug in windows (they may use 2* 24 bytes instead of just
5840                  * 1 *24 bytes
5841                  */
5842                 return offset;
5843         }
5844
5845         if (buffer_code == 44) {
5846                 proto_item *item;
5847
5848                 /* Lease Break Notification */
5849
5850                 /* new lease epoch */
5851                 proto_tree_add_item(tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5852                 offset += 2;
5853
5854                 /* lease flags */
5855                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
5856                                        ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5857                 offset += 4;
5858
5859                 /* lease key */
5860                 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5861                 offset += 16;
5862
5863                 /* current lease state */
5864                 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5865                                               ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5866                 if (item) {
5867                         proto_item_prepend_text(item, "Current ");
5868                 }
5869                 offset += 4;
5870
5871                 /* new lease state */
5872                 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5873                                               ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5874                 if (item) {
5875                         proto_item_prepend_text(item, "New ");
5876                 }
5877                 offset += 4;
5878
5879                 /* break reason - reserved */
5880                 proto_tree_add_item(tree, hf_smb2_lease_break_reason, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5881                 offset += 4;
5882
5883                 /* access mask hint - reserved */
5884                 proto_tree_add_item(tree, hf_smb2_lease_access_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5885                 offset += 4;
5886
5887                 /* share mask hint - reserved */
5888                 proto_tree_add_item(tree, hf_smb2_lease_share_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5889                 offset += 4;
5890
5891                 return offset;
5892         }
5893
5894         if (buffer_code == 36) {
5895                 /* Lease Break Response */
5896
5897                 /* reserved */
5898                 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5899                 offset +=2;
5900
5901                 /* lease flags */
5902                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
5903                                        ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5904                 offset += 4;
5905
5906                 /* lease key */
5907                 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5908                 offset += 16;
5909
5910                 /* lease state */
5911                 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5912                                        ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5913                 offset += 4;
5914
5915                 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5916                 offset += 8;
5917
5918                 return offset;
5919         }
5920
5921         return offset;
5922 }
5923
5924 /* names here are just until we find better names for these functions */
5925 static const value_string smb2_cmd_vals[] = {
5926         { 0x00, "Negotiate Protocol" },
5927         { 0x01, "Session Setup" },
5928         { 0x02, "Session Logoff" },
5929         { 0x03, "Tree Connect" },
5930         { 0x04, "Tree Disconnect" },
5931         { 0x05, "Create" },
5932         { 0x06, "Close" },
5933         { 0x07, "Flush" },
5934         { 0x08, "Read" },
5935         { 0x09, "Write" },
5936         { 0x0A, "Lock" },
5937         { 0x0B, "Ioctl" },
5938         { 0x0C, "Cancel" },
5939         { 0x0D, "KeepAlive" },
5940         { 0x0E, "Find" },
5941         { 0x0F, "Notify" },
5942         { 0x10, "GetInfo" },
5943         { 0x11, "SetInfo" },
5944         { 0x12, "Break" },
5945         { 0x13, "unknown-0x13" },
5946         { 0x14, "unknown-0x14" },
5947         { 0x15, "unknown-0x15" },
5948         { 0x16, "unknown-0x16" },
5949         { 0x17, "unknown-0x17" },
5950         { 0x18, "unknown-0x18" },
5951         { 0x19, "unknown-0x19" },
5952         { 0x1A, "unknown-0x1A" },
5953         { 0x1B, "unknown-0x1B" },
5954         { 0x1C, "unknown-0x1C" },
5955         { 0x1D, "unknown-0x1D" },
5956         { 0x1E, "unknown-0x1E" },
5957         { 0x1F, "unknown-0x1F" },
5958         { 0x20, "unknown-0x20" },
5959         { 0x21, "unknown-0x21" },
5960         { 0x22, "unknown-0x22" },
5961         { 0x23, "unknown-0x23" },
5962         { 0x24, "unknown-0x24" },
5963         { 0x25, "unknown-0x25" },
5964         { 0x26, "unknown-0x26" },
5965         { 0x27, "unknown-0x27" },
5966         { 0x28, "unknown-0x28" },
5967         { 0x29, "unknown-0x29" },
5968         { 0x2A, "unknown-0x2A" },
5969         { 0x2B, "unknown-0x2B" },
5970         { 0x2C, "unknown-0x2C" },
5971         { 0x2D, "unknown-0x2D" },
5972         { 0x2E, "unknown-0x2E" },
5973         { 0x2F, "unknown-0x2F" },
5974         { 0x30, "unknown-0x30" },
5975         { 0x31, "unknown-0x31" },
5976         { 0x32, "unknown-0x32" },
5977         { 0x33, "unknown-0x33" },
5978         { 0x34, "unknown-0x34" },
5979         { 0x35, "unknown-0x35" },
5980         { 0x36, "unknown-0x36" },
5981         { 0x37, "unknown-0x37" },
5982         { 0x38, "unknown-0x38" },
5983         { 0x39, "unknown-0x39" },
5984         { 0x3A, "unknown-0x3A" },
5985         { 0x3B, "unknown-0x3B" },
5986         { 0x3C, "unknown-0x3C" },
5987         { 0x3D, "unknown-0x3D" },
5988         { 0x3E, "unknown-0x3E" },
5989         { 0x3F, "unknown-0x3F" },
5990         { 0x40, "unknown-0x40" },
5991         { 0x41, "unknown-0x41" },
5992         { 0x42, "unknown-0x42" },
5993         { 0x43, "unknown-0x43" },
5994         { 0x44, "unknown-0x44" },
5995         { 0x45, "unknown-0x45" },
5996         { 0x46, "unknown-0x46" },
5997         { 0x47, "unknown-0x47" },
5998         { 0x48, "unknown-0x48" },
5999         { 0x49, "unknown-0x49" },
6000         { 0x4A, "unknown-0x4A" },
6001         { 0x4B, "unknown-0x4B" },
6002         { 0x4C, "unknown-0x4C" },
6003         { 0x4D, "unknown-0x4D" },
6004         { 0x4E, "unknown-0x4E" },
6005         { 0x4F, "unknown-0x4F" },
6006         { 0x50, "unknown-0x50" },
6007         { 0x51, "unknown-0x51" },
6008         { 0x52, "unknown-0x52" },
6009         { 0x53, "unknown-0x53" },
6010         { 0x54, "unknown-0x54" },
6011         { 0x55, "unknown-0x55" },
6012         { 0x56, "unknown-0x56" },
6013         { 0x57, "unknown-0x57" },
6014         { 0x58, "unknown-0x58" },
6015         { 0x59, "unknown-0x59" },
6016         { 0x5A, "unknown-0x5A" },
6017         { 0x5B, "unknown-0x5B" },
6018         { 0x5C, "unknown-0x5C" },
6019         { 0x5D, "unknown-0x5D" },
6020         { 0x5E, "unknown-0x5E" },
6021         { 0x5F, "unknown-0x5F" },
6022         { 0x60, "unknown-0x60" },
6023         { 0x61, "unknown-0x61" },
6024         { 0x62, "unknown-0x62" },
6025         { 0x63, "unknown-0x63" },
6026         { 0x64, "unknown-0x64" },
6027         { 0x65, "unknown-0x65" },
6028         { 0x66, "unknown-0x66" },
6029         { 0x67, "unknown-0x67" },
6030         { 0x68, "unknown-0x68" },
6031         { 0x69, "unknown-0x69" },
6032         { 0x6A, "unknown-0x6A" },
6033         { 0x6B, "unknown-0x6B" },
6034         { 0x6C, "unknown-0x6C" },
6035         { 0x6D, "unknown-0x6D" },
6036         { 0x6E, "unknown-0x6E" },
6037         { 0x6F, "unknown-0x6F" },
6038         { 0x70, "unknown-0x70" },
6039         { 0x71, "unknown-0x71" },
6040         { 0x72, "unknown-0x72" },
6041         { 0x73, "unknown-0x73" },
6042         { 0x74, "unknown-0x74" },
6043         { 0x75, "unknown-0x75" },
6044         { 0x76, "unknown-0x76" },
6045         { 0x77, "unknown-0x77" },
6046         { 0x78, "unknown-0x78" },
6047         { 0x79, "unknown-0x79" },
6048         { 0x7A, "unknown-0x7A" },
6049         { 0x7B, "unknown-0x7B" },
6050         { 0x7C, "unknown-0x7C" },
6051         { 0x7D, "unknown-0x7D" },
6052         { 0x7E, "unknown-0x7E" },
6053         { 0x7F, "unknown-0x7F" },
6054         { 0x80, "unknown-0x80" },
6055         { 0x81, "unknown-0x81" },
6056         { 0x82, "unknown-0x82" },
6057         { 0x83, "unknown-0x83" },
6058         { 0x84, "unknown-0x84" },
6059         { 0x85, "unknown-0x85" },
6060         { 0x86, "unknown-0x86" },
6061         { 0x87, "unknown-0x87" },
6062         { 0x88, "unknown-0x88" },
6063         { 0x89, "unknown-0x89" },
6064         { 0x8A, "unknown-0x8A" },
6065         { 0x8B, "unknown-0x8B" },
6066         { 0x8C, "unknown-0x8C" },
6067         { 0x8D, "unknown-0x8D" },
6068         { 0x8E, "unknown-0x8E" },
6069         { 0x8F, "unknown-0x8F" },
6070         { 0x90, "unknown-0x90" },
6071         { 0x91, "unknown-0x91" },
6072         { 0x92, "unknown-0x92" },
6073         { 0x93, "unknown-0x93" },
6074         { 0x94, "unknown-0x94" },
6075         { 0x95, "unknown-0x95" },
6076         { 0x96, "unknown-0x96" },
6077         { 0x97, "unknown-0x97" },
6078         { 0x98, "unknown-0x98" },
6079         { 0x99, "unknown-0x99" },
6080         { 0x9A, "unknown-0x9A" },
6081         { 0x9B, "unknown-0x9B" },
6082         { 0x9C, "unknown-0x9C" },
6083         { 0x9D, "unknown-0x9D" },
6084         { 0x9E, "unknown-0x9E" },
6085         { 0x9F, "unknown-0x9F" },
6086         { 0xA0, "unknown-0xA0" },
6087         { 0xA1, "unknown-0xA1" },
6088         { 0xA2, "unknown-0xA2" },
6089         { 0xA3, "unknown-0xA3" },
6090         { 0xA4, "unknown-0xA4" },
6091         { 0xA5, "unknown-0xA5" },
6092         { 0xA6, "unknown-0xA6" },
6093         { 0xA7, "unknown-0xA7" },
6094         { 0xA8, "unknown-0xA8" },
6095         { 0xA9, "unknown-0xA9" },
6096         { 0xAA, "unknown-0xAA" },
6097         { 0xAB, "unknown-0xAB" },
6098         { 0xAC, "unknown-0xAC" },
6099         { 0xAD, "unknown-0xAD" },
6100         { 0xAE, "unknown-0xAE" },
6101         { 0xAF, "unknown-0xAF" },
6102         { 0xB0, "unknown-0xB0" },
6103         { 0xB1, "unknown-0xB1" },
6104         { 0xB2, "unknown-0xB2" },
6105         { 0xB3, "unknown-0xB3" },
6106         { 0xB4, "unknown-0xB4" },
6107         { 0xB5, "unknown-0xB5" },
6108         { 0xB6, "unknown-0xB6" },
6109         { 0xB7, "unknown-0xB7" },
6110         { 0xB8, "unknown-0xB8" },
6111         { 0xB9, "unknown-0xB9" },
6112         { 0xBA, "unknown-0xBA" },
6113         { 0xBB, "unknown-0xBB" },
6114         { 0xBC, "unknown-0xBC" },
6115         { 0xBD, "unknown-0xBD" },
6116         { 0xBE, "unknown-0xBE" },
6117         { 0xBF, "unknown-0xBF" },
6118         { 0xC0, "unknown-0xC0" },
6119         { 0xC1, "unknown-0xC1" },
6120         { 0xC2, "unknown-0xC2" },
6121         { 0xC3, "unknown-0xC3" },
6122         { 0xC4, "unknown-0xC4" },
6123         { 0xC5, "unknown-0xC5" },
6124         { 0xC6, "unknown-0xC6" },
6125         { 0xC7, "unknown-0xC7" },
6126         { 0xC8, "unknown-0xC8" },
6127         { 0xC9, "unknown-0xC9" },
6128         { 0xCA, "unknown-0xCA" },
6129         { 0xCB, "unknown-0xCB" },
6130         { 0xCC, "unknown-0xCC" },
6131         { 0xCD, "unknown-0xCD" },
6132         { 0xCE, "unknown-0xCE" },
6133         { 0xCF, "unknown-0xCF" },
6134         { 0xD0, "unknown-0xD0" },
6135         { 0xD1, "unknown-0xD1" },
6136         { 0xD2, "unknown-0xD2" },
6137         { 0xD3, "unknown-0xD3" },
6138         { 0xD4, "unknown-0xD4" },
6139         { 0xD5, "unknown-0xD5" },
6140         { 0xD6, "unknown-0xD6" },
6141         { 0xD7, "unknown-0xD7" },
6142         { 0xD8, "unknown-0xD8" },
6143         { 0xD9, "unknown-0xD9" },
6144         { 0xDA, "unknown-0xDA" },
6145         { 0xDB, "unknown-0xDB" },
6146         { 0xDC, "unknown-0xDC" },
6147         { 0xDD, "unknown-0xDD" },
6148         { 0xDE, "unknown-0xDE" },
6149         { 0xDF, "unknown-0xDF" },
6150         { 0xE0, "unknown-0xE0" },
6151         { 0xE1, "unknown-0xE1" },
6152         { 0xE2, "unknown-0xE2" },
6153         { 0xE3, "unknown-0xE3" },
6154         { 0xE4, "unknown-0xE4" },
6155         { 0xE5, "unknown-0xE5" },
6156         { 0xE6, "unknown-0xE6" },
6157         { 0xE7, "unknown-0xE7" },
6158         { 0xE8, "unknown-0xE8" },
6159         { 0xE9, "unknown-0xE9" },
6160         { 0xEA, "unknown-0xEA" },
6161         { 0xEB, "unknown-0xEB" },
6162         { 0xEC, "unknown-0xEC" },
6163         { 0xED, "unknown-0xED" },
6164         { 0xEE, "unknown-0xEE" },
6165         { 0xEF, "unknown-0xEF" },
6166         { 0xF0, "unknown-0xF0" },
6167         { 0xF1, "unknown-0xF1" },
6168         { 0xF2, "unknown-0xF2" },
6169         { 0xF3, "unknown-0xF3" },
6170         { 0xF4, "unknown-0xF4" },
6171         { 0xF5, "unknown-0xF5" },
6172         { 0xF6, "unknown-0xF6" },
6173         { 0xF7, "unknown-0xF7" },
6174         { 0xF8, "unknown-0xF8" },
6175         { 0xF9, "unknown-0xF9" },
6176         { 0xFA, "unknown-0xFA" },
6177         { 0xFB, "unknown-0xFB" },
6178         { 0xFC, "unknown-0xFC" },
6179         { 0xFD, "unknown-0xFD" },
6180         { 0xFE, "unknown-0xFE" },
6181         { 0xFF, "unknown-0xFF" },
6182         { 0x00, NULL },
6183 };
6184 value_string_ext smb2_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb2_cmd_vals);
6185
6186 static const char *decode_smb2_name(guint16 cmd)
6187 {
6188         if (cmd > 0xFF) return "unknown";
6189         return(smb2_cmd_vals[cmd & 0xFF].strptr);
6190 }
6191
6192 static smb2_function smb2_dissector[256] = {
6193   /* 0x00 NegotiateProtocol*/
6194         {dissect_smb2_negotiate_protocol_request,
6195          dissect_smb2_negotiate_protocol_response},
6196   /* 0x01 SessionSetup*/
6197         {dissect_smb2_session_setup_request,
6198          dissect_smb2_session_setup_response},
6199   /* 0x02 SessionLogoff*/
6200         {dissect_smb2_sessionlogoff_request,
6201          dissect_smb2_sessionlogoff_response},
6202   /* 0x03 TreeConnect*/
6203         {dissect_smb2_tree_connect_request,
6204          dissect_smb2_tree_connect_response},
6205   /* 0x04 TreeDisconnect*/
6206         {dissect_smb2_tree_disconnect_request,
6207          dissect_smb2_tree_disconnect_response},
6208   /* 0x05 Create*/
6209         {dissect_smb2_create_request,
6210          dissect_smb2_create_response},
6211   /* 0x06 Close*/
6212         {dissect_smb2_close_request,
6213          dissect_smb2_close_response},
6214   /* 0x07 Flush*/
6215         {dissect_smb2_flush_request,
6216          dissect_smb2_flush_response},
6217   /* 0x08 Read*/
6218         {dissect_smb2_read_request,
6219          dissect_smb2_read_response},
6220   /* 0x09 Writew*/
6221         {dissect_smb2_write_request,
6222          dissect_smb2_write_response},
6223   /* 0x0a Lock */
6224         {dissect_smb2_lock_request,
6225          dissect_smb2_lock_response},
6226   /* 0x0b Ioctl*/
6227         {dissect_smb2_ioctl_request,
6228          dissect_smb2_ioctl_response},
6229   /* 0x0c Cancel*/
6230         {dissect_smb2_cancel_request,
6231          NULL},
6232   /* 0x0d KeepAlive*/
6233         {dissect_smb2_keepalive_request,
6234          dissect_smb2_keepalive_response},
6235   /* 0x0e Find*/
6236         {dissect_smb2_find_request,
6237          dissect_smb2_find_response},
6238   /* 0x0f Notify*/
6239         {dissect_smb2_notify_request,
6240          dissect_smb2_notify_response},
6241   /* 0x10 GetInfo*/
6242         {dissect_smb2_getinfo_request,
6243          dissect_smb2_getinfo_response},
6244   /* 0x11 SetInfo*/
6245         {dissect_smb2_setinfo_request,
6246          dissect_smb2_setinfo_response},
6247   /* 0x12 Break */
6248         {dissect_smb2_break_request,
6249          dissect_smb2_break_response},
6250   /* 0x13 */  {NULL, NULL},
6251   /* 0x14 */  {NULL, NULL},
6252   /* 0x15 */  {NULL, NULL},
6253   /* 0x16 */  {NULL, NULL},
6254   /* 0x17 */  {NULL, NULL},
6255   /* 0x18 */  {NULL, NULL},
6256   /* 0x19 */  {NULL, NULL},
6257   /* 0x1a */  {NULL, NULL},
6258   /* 0x1b */  {NULL, NULL},
6259   /* 0x1c */  {NULL, NULL},
6260   /* 0x1d */  {NULL, NULL},
6261   /* 0x1e */  {NULL, NULL},
6262   /* 0x1f */  {NULL, NULL},
6263   /* 0x20 */  {NULL, NULL},
6264   /* 0x21 */  {NULL, NULL},
6265   /* 0x22 */  {NULL, NULL},
6266   /* 0x23 */  {NULL, NULL},
6267   /* 0x24 */  {NULL, NULL},
6268   /* 0x25 */  {NULL, NULL},
6269   /* 0x26 */  {NULL, NULL},
6270   /* 0x27 */  {NULL, NULL},
6271   /* 0x28 */  {NULL, NULL},
6272   /* 0x29 */  {NULL, NULL},
6273   /* 0x2a */  {NULL, NULL},
6274   /* 0x2b */  {NULL, NULL},
6275   /* 0x2c */  {NULL, NULL},
6276   /* 0x2d */  {NULL, NULL},
6277   /* 0x2e */  {NULL, NULL},
6278   /* 0x2f */  {NULL, NULL},
6279   /* 0x30 */  {NULL, NULL},
6280   /* 0x31 */  {NULL, NULL},
6281   /* 0x32 */  {NULL, NULL},
6282   /* 0x33 */  {NULL, NULL},
6283   /* 0x34 */  {NULL, NULL},
6284   /* 0x35 */  {NULL, NULL},
6285   /* 0x36 */  {NULL, NULL},
6286   /* 0x37 */  {NULL, NULL},
6287   /* 0x38 */  {NULL, NULL},
6288   /* 0x39 */  {NULL, NULL},
6289   /* 0x3a */  {NULL, NULL},
6290   /* 0x3b */  {NULL, NULL},
6291   /* 0x3c */  {NULL, NULL},
6292   /* 0x3d */  {NULL, NULL},
6293   /* 0x3e */  {NULL, NULL},
6294   /* 0x3f */  {NULL, NULL},
6295   /* 0x40 */  {NULL, NULL},
6296   /* 0x41 */  {NULL, NULL},
6297   /* 0x42 */  {NULL, NULL},
6298   /* 0x43 */  {NULL, NULL},
6299   /* 0x44 */  {NULL, NULL},
6300   /* 0x45 */  {NULL, NULL},
6301   /* 0x46 */  {NULL, NULL},
6302   /* 0x47 */  {NULL, NULL},
6303   /* 0x48 */  {NULL, NULL},
6304   /* 0x49 */  {NULL, NULL},
6305   /* 0x4a */  {NULL, NULL},
6306   /* 0x4b */  {NULL, NULL},
6307   /* 0x4c */  {NULL, NULL},
6308   /* 0x4d */  {NULL, NULL},
6309   /* 0x4e */  {NULL, NULL},
6310   /* 0x4f */  {NULL, NULL},
6311   /* 0x50 */  {NULL, NULL},
6312   /* 0x51 */  {NULL, NULL},
6313   /* 0x52 */  {NULL, NULL},
6314   /* 0x53 */  {NULL, NULL},
6315   /* 0x54 */  {NULL, NULL},
6316   /* 0x55 */  {NULL, NULL},
6317   /* 0x56 */  {NULL, NULL},
6318   /* 0x57 */  {NULL, NULL},
6319   /* 0x58 */  {NULL, NULL},
6320   /* 0x59 */  {NULL, NULL},
6321   /* 0x5a */  {NULL, NULL},
6322   /* 0x5b */  {NULL, NULL},
6323   /* 0x5c */  {NULL, NULL},
6324   /* 0x5d */  {NULL, NULL},
6325   /* 0x5e */  {NULL, NULL},
6326   /* 0x5f */  {NULL, NULL},
6327   /* 0x60 */  {NULL, NULL},
6328   /* 0x61 */  {NULL, NULL},
6329   /* 0x62 */  {NULL, NULL},
6330   /* 0x63 */  {NULL, NULL},
6331   /* 0x64 */  {NULL, NULL},
6332   /* 0x65 */  {NULL, NULL},
6333   /* 0x66 */  {NULL, NULL},
6334   /* 0x67 */  {NULL, NULL},
6335   /* 0x68 */  {NULL, NULL},
6336   /* 0x69 */  {NULL, NULL},
6337   /* 0x6a */  {NULL, NULL},
6338   /* 0x6b */  {NULL, NULL},
6339   /* 0x6c */  {NULL, NULL},
6340   /* 0x6d */  {NULL, NULL},
6341   /* 0x6e */  {NULL, NULL},
6342   /* 0x6f */  {NULL, NULL},
6343   /* 0x70 */  {NULL, NULL},
6344   /* 0x71 */  {NULL, NULL},
6345   /* 0x72 */  {NULL, NULL},
6346   /* 0x73 */  {NULL, NULL},
6347   /* 0x74 */  {NULL, NULL},
6348   /* 0x75 */  {NULL, NULL},
6349   /* 0x76 */  {NULL, NULL},
6350   /* 0x77 */  {NULL, NULL},
6351   /* 0x78 */  {NULL, NULL},
6352   /* 0x79 */  {NULL, NULL},
6353   /* 0x7a */  {NULL, NULL},
6354   /* 0x7b */  {NULL, NULL},
6355   /* 0x7c */  {NULL, NULL},
6356   /* 0x7d */  {NULL, NULL},
6357   /* 0x7e */  {NULL, NULL},
6358   /* 0x7f */  {NULL, NULL},
6359   /* 0x80 */  {NULL, NULL},
6360   /* 0x81 */  {NULL, NULL},
6361   /* 0x82 */  {NULL, NULL},
6362   /* 0x83 */  {NULL, NULL},
6363   /* 0x84 */  {NULL, NULL},
6364   /* 0x85 */  {NULL, NULL},
6365   /* 0x86 */  {NULL, NULL},
6366   /* 0x87 */  {NULL, NULL},
6367   /* 0x88 */  {NULL, NULL},
6368   /* 0x89 */  {NULL, NULL},
6369   /* 0x8a */  {NULL, NULL},
6370   /* 0x8b */  {NULL, NULL},
6371   /* 0x8c */  {NULL, NULL},
6372   /* 0x8d */  {NULL, NULL},
6373   /* 0x8e */  {NULL, NULL},
6374   /* 0x8f */  {NULL, NULL},
6375   /* 0x90 */  {NULL, NULL},
6376   /* 0x91 */  {NULL, NULL},
6377   /* 0x92 */  {NULL, NULL},
6378   /* 0x93 */  {NULL, NULL},
6379   /* 0x94 */  {NULL, NULL},
6380   /* 0x95 */  {NULL, NULL},
6381   /* 0x96 */  {NULL, NULL},
6382   /* 0x97 */  {NULL, NULL},
6383   /* 0x98 */  {NULL, NULL},
6384   /* 0x99 */  {NULL, NULL},
6385   /* 0x9a */  {NULL, NULL},
6386   /* 0x9b */  {NULL, NULL},
6387   /* 0x9c */  {NULL, NULL},
6388   /* 0x9d */  {NULL, NULL},
6389   /* 0x9e */  {NULL, NULL},
6390   /* 0x9f */  {NULL, NULL},
6391   /* 0xa0 */  {NULL, NULL},
6392   /* 0xa1 */  {NULL, NULL},
6393   /* 0xa2 */  {NULL, NULL},
6394   /* 0xa3 */  {NULL, NULL},
6395   /* 0xa4 */  {NULL, NULL},
6396   /* 0xa5 */  {NULL, NULL},
6397   /* 0xa6 */  {NULL, NULL},
6398   /* 0xa7 */  {NULL, NULL},
6399   /* 0xa8 */  {NULL, NULL},
6400   /* 0xa9 */  {NULL, NULL},
6401   /* 0xaa */  {NULL, NULL},
6402   /* 0xab */  {NULL, NULL},
6403   /* 0xac */  {NULL, NULL},
6404   /* 0xad */  {NULL, NULL},
6405   /* 0xae */  {NULL, NULL},
6406   /* 0xaf */  {NULL, NULL},
6407   /* 0xb0 */  {NULL, NULL},
6408   /* 0xb1 */  {NULL, NULL},
6409   /* 0xb2 */  {NULL, NULL},
6410   /* 0xb3 */  {NULL, NULL},
6411   /* 0xb4 */  {NULL, NULL},
6412   /* 0xb5 */  {NULL, NULL},
6413   /* 0xb6 */  {NULL, NULL},
6414   /* 0xb7 */  {NULL, NULL},
6415   /* 0xb8 */  {NULL, NULL},
6416   /* 0xb9 */  {NULL, NULL},
6417   /* 0xba */  {NULL, NULL},
6418   /* 0xbb */  {NULL, NULL},
6419   /* 0xbc */  {NULL, NULL},
6420   /* 0xbd */  {NULL, NULL},
6421   /* 0xbe */  {NULL, NULL},
6422   /* 0xbf */  {NULL, NULL},
6423   /* 0xc0 */  {NULL, NULL},
6424   /* 0xc1 */  {NULL, NULL},
6425   /* 0xc2 */  {NULL, NULL},
6426   /* 0xc3 */  {NULL, NULL},
6427   /* 0xc4 */  {NULL, NULL},
6428   /* 0xc5 */  {NULL, NULL},
6429   /* 0xc6 */  {NULL, NULL},
6430   /* 0xc7 */  {NULL, NULL},
6431   /* 0xc8 */  {NULL, NULL},
6432   /* 0xc9 */  {NULL, NULL},
6433   /* 0xca */  {NULL, NULL},
6434   /* 0xcb */  {NULL, NULL},
6435   /* 0xcc */  {NULL, NULL},
6436   /* 0xcd */  {NULL, NULL},
6437   /* 0xce */  {NULL, NULL},
6438   /* 0xcf */  {NULL, NULL},
6439   /* 0xd0 */  {NULL, NULL},
6440   /* 0xd1 */  {NULL, NULL},
6441   /* 0xd2 */  {NULL, NULL},
6442   /* 0xd3 */  {NULL, NULL},
6443   /* 0xd4 */  {NULL, NULL},
6444   /* 0xd5 */  {NULL, NULL},
6445   /* 0xd6 */  {NULL, NULL},
6446   /* 0xd7 */  {NULL, NULL},
6447   /* 0xd8 */  {NULL, NULL},
6448   /* 0xd9 */  {NULL, NULL},
6449   /* 0xda */  {NULL, NULL},
6450   /* 0xdb */  {NULL, NULL},
6451   /* 0xdc */  {NULL, NULL},
6452   /* 0xdd */  {NULL, NULL},
6453   /* 0xde */  {NULL, NULL},
6454   /* 0xdf */  {NULL, NULL},
6455   /* 0xe0 */  {NULL, NULL},
6456   /* 0xe1 */  {NULL, NULL},
6457   /* 0xe2 */  {NULL, NULL},
6458   /* 0xe3 */  {NULL, NULL},
6459   /* 0xe4 */  {NULL, NULL},
6460   /* 0xe5 */  {NULL, NULL},
6461   /* 0xe6 */  {NULL, NULL},
6462   /* 0xe7 */  {NULL, NULL},
6463   /* 0xe8 */  {NULL, NULL},
6464   /* 0xe9 */  {NULL, NULL},
6465   /* 0xea */  {NULL, NULL},
6466   /* 0xeb */  {NULL, NULL},
6467   /* 0xec */  {NULL, NULL},
6468   /* 0xed */  {NULL, NULL},
6469   /* 0xee */  {NULL, NULL},
6470   /* 0xef */  {NULL, NULL},
6471   /* 0xf0 */  {NULL, NULL},
6472   /* 0xf1 */  {NULL, NULL},
6473   /* 0xf2 */  {NULL, NULL},
6474   /* 0xf3 */  {NULL, NULL},
6475   /* 0xf4 */  {NULL, NULL},
6476   /* 0xf5 */  {NULL, NULL},
6477   /* 0xf6 */  {NULL, NULL},
6478   /* 0xf7 */  {NULL, NULL},
6479   /* 0xf8 */  {NULL, NULL},
6480   /* 0xf9 */  {NULL, NULL},
6481   /* 0xfa */  {NULL, NULL},
6482   /* 0xfb */  {NULL, NULL},
6483   /* 0xfc */  {NULL, NULL},
6484   /* 0xfd */  {NULL, NULL},
6485   /* 0xfe */  {NULL, NULL},
6486   /* 0xff */  {NULL, NULL},
6487 };
6488
6489
6490 #define ENC_ALG_aes128_ccm      0x0001
6491
6492 static int
6493 dissect_smb2_transform_header(packet_info *pinfo _U_, proto_tree *tree,
6494                               tvbuff_t *tvb, int offset,
6495                               smb2_transform_info_t *sti,
6496                               tvbuff_t **enc_tvb, tvbuff_t **plain_tvb)
6497 {
6498         proto_item        *sesid_item     = NULL;
6499         proto_tree        *sesid_tree     = NULL;
6500         smb2_sesid_info_t  sesid_key;
6501         int                sesid_offset;
6502         guint8            *plain_data     = NULL;
6503 #ifdef HAVE_LIBGCRYPT
6504         guint8            *decryption_key = NULL;
6505 #endif
6506         proto_item        *item;
6507
6508         static const int *sf_fields[] = {
6509                 &hf_smb2_encryption_aes128_ccm,
6510                 NULL
6511         };
6512
6513         *enc_tvb = NULL;
6514         *plain_tvb = NULL;
6515
6516         /* signature */
6517         proto_tree_add_item(tree, hf_smb2_transform_signature, tvb, offset, 16, ENC_NA);
6518         offset += 16;
6519
6520         /* nonce */
6521         proto_tree_add_item(tree, hf_smb2_transform_nonce, tvb, offset, 16, ENC_NA);
6522         tvb_memcpy(tvb, sti->nonce, offset, 16);
6523         offset += 16;
6524
6525         /* size */
6526         proto_tree_add_item(tree, hf_smb2_transform_msg_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6527         sti->size = tvb_get_letohl(tvb, offset);
6528         offset += 4;
6529
6530         /* reserved */
6531         proto_tree_add_item(tree, hf_smb2_transform_reserved, tvb, offset, 2, ENC_NA);
6532         offset += 2;
6533
6534         /* enc algorithm */
6535         proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_transform_enc_alg, ett_smb2_transform_enc_alg, sf_fields, ENC_LITTLE_ENDIAN);
6536         sti->alg = tvb_get_letohs(tvb, offset);
6537         offset += 2;
6538
6539         /* session ID */
6540         sesid_offset = offset;
6541         sti->sesid = tvb_get_letoh64(tvb, offset);
6542         sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6543         if (tree) {
6544                 sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
6545         }
6546         offset += 8;
6547
6548         /* now we need to first lookup the uid session */
6549         sesid_key.sesid = sti->sesid;
6550         sti->session = (smb2_sesid_info_t *)g_hash_table_lookup(sti->conv->sesids, &sesid_key);
6551
6552         if (sti->session != NULL && sti->session->auth_frame != (guint32)-1) {
6553                 item = proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, sti->session->acct_name);
6554                 PROTO_ITEM_SET_GENERATED(item);
6555                 proto_item_append_text(sesid_item, " Acct:%s", sti->session->acct_name);
6556
6557                 item = proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, sti->session->domain_name);
6558                 PROTO_ITEM_SET_GENERATED(item);
6559                 proto_item_append_text(sesid_item, " Domain:%s", sti->session->domain_name);
6560
6561                 item = proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, sti->session->host_name);
6562                 PROTO_ITEM_SET_GENERATED(item);
6563                 proto_item_append_text(sesid_item, " Host:%s", sti->session->host_name);
6564
6565                 item = proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, sti->session->auth_frame);
6566                 PROTO_ITEM_SET_GENERATED(item);
6567         }
6568
6569 #ifdef HAVE_LIBGCRYPT
6570         if (sti->session != NULL && sti->alg == ENC_ALG_aes128_ccm) {
6571                 if (pinfo->destport == sti->session->server_port) {
6572                         decryption_key = sti->session->server_decryption_key;
6573                 } else {
6574                         decryption_key = sti->session->client_decryption_key;
6575                 }
6576
6577                 if (memcmp(decryption_key, zeros, 16) == 0) {
6578                         decryption_key = NULL;
6579                 }
6580         }
6581
6582         if (decryption_key != NULL) {
6583                 gcry_cipher_hd_t cipher_hd = NULL;
6584                 guint8 A_1[16] = {
6585                         3, 0, 0, 0, 0, 0, 0, 0,
6586                         0, 0, 0, 0, 0, 0, 0, 1
6587                 };
6588
6589                 memcpy(&A_1[1], sti->nonce, 15 - 4);
6590
6591                 plain_data = (guint8 *)tvb_memdup(NULL, tvb, offset, sti->size);
6592
6593                 /* Open the cipher. */
6594                 if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0)) {
6595                         g_free(plain_data);
6596                         plain_data = NULL;
6597                         goto done_decryption;
6598                 }
6599
6600                 /* Set the key and initial value. */
6601                 if (gcry_cipher_setkey(cipher_hd, decryption_key, 16)) {
6602                         gcry_cipher_close(cipher_hd);
6603                         g_free(plain_data);
6604                         plain_data = NULL;
6605                         goto done_decryption;
6606                 }
6607                 if (gcry_cipher_setctr(cipher_hd, A_1, 16)) {
6608                         gcry_cipher_close(cipher_hd);
6609                         g_free(plain_data);
6610                         plain_data = NULL;
6611                         goto done_decryption;
6612                 }
6613
6614                 if (gcry_cipher_encrypt(cipher_hd, plain_data, sti->size, NULL, 0)) {
6615                         gcry_cipher_close(cipher_hd);
6616                         g_free(plain_data);
6617                         plain_data = NULL;
6618                         goto done_decryption;
6619                 }
6620
6621                 /* Done with the cipher. */
6622                 gcry_cipher_close(cipher_hd);
6623         }
6624 done_decryption:
6625 #endif
6626         *enc_tvb = tvb_new_subset(tvb, offset, sti->size, sti->size);
6627
6628         if (plain_data != NULL) {
6629                 *plain_tvb = tvb_new_child_real_data(*enc_tvb, plain_data, sti->size, sti->size);
6630                 tvb_set_free_cb(*plain_tvb, g_free);
6631                 add_new_data_source(pinfo, *plain_tvb, "Decrypted SMB3");
6632         }
6633
6634         offset += sti->size;
6635         return offset;
6636 }
6637
6638 static int
6639 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
6640 {
6641         int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
6642         proto_item *cmd_item;
6643         proto_tree *cmd_tree;
6644         int         old_offset = offset;
6645
6646         cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
6647                         "%s %s (0x%02x)",
6648                         decode_smb2_name(si->opcode),
6649                         (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
6650                         si->opcode);
6651         cmd_tree = proto_item_add_subtree(cmd_item, ett_smb2_command);
6652
6653
6654         cmd_dissector = (si->flags & SMB2_FLAGS_RESPONSE)?
6655                 smb2_dissector[si->opcode&0xff].response:
6656                 smb2_dissector[si->opcode&0xff].request;
6657         if (cmd_dissector) {
6658                 offset = (*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
6659         } else {
6660                 proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, ENC_NA);
6661                 offset = tvb_length(tvb);
6662         }
6663
6664         proto_item_set_len(cmd_item, offset-old_offset);
6665
6666         return offset;
6667 }
6668
6669 static int
6670 dissect_smb2_tid_sesid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
6671 {
6672         proto_item        *tid_item   = NULL;
6673         proto_tree        *tid_tree   = NULL;
6674         smb2_tid_info_t    tid_key;
6675         int                tid_offset = 0;
6676         proto_item        *sesid_item = NULL;
6677         proto_tree        *sesid_tree = NULL;
6678         smb2_sesid_info_t  sesid_key;
6679         int                sesid_offset;
6680         proto_item        *item;
6681
6682
6683         if (si->flags&SMB2_FLAGS_ASYNC_CMD) {
6684                 proto_tree_add_item(tree, hf_smb2_aid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6685                 offset += 8;
6686         } else {
6687                 /* Process ID */
6688                 proto_tree_add_item(tree, hf_smb2_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6689                 offset += 4;
6690
6691                 /* Tree ID */
6692                 tid_offset = offset;
6693                 si->tid = tvb_get_letohl(tvb, offset);
6694                 tid_item = proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6695                 if (tree) {
6696                         tid_tree = proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
6697                 }
6698                 offset += 4;
6699         }
6700
6701         /* Session ID */
6702         sesid_offset = offset;
6703         si->sesid = tvb_get_letoh64(tvb, offset);
6704         sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6705         if (tree) {
6706                 sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
6707         }
6708         offset += 8;
6709
6710         /* now we need to first lookup the uid session */
6711         sesid_key.sesid = si->sesid;
6712         si->session = (smb2_sesid_info_t *)g_hash_table_lookup(si->conv->sesids, &sesid_key);
6713         if (!si->session) {
6714                 if (si->opcode != 0x03) return offset;
6715
6716                 /* if we come to a session that is unknown, and the operation is
6717                  * a tree connect, we create a dummy sessison, so we can hang the
6718                  * tree data on it
6719                  */
6720                 si->session              = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
6721                 si->session->sesid       = si->sesid;
6722                 si->session->acct_name   = NULL;
6723                 si->session->domain_name = NULL;
6724                 si->session->host_name   = NULL;
6725                 si->session->auth_frame  = (guint32)-1;
6726                 si->session->tids        = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
6727                 g_hash_table_insert(si->conv->sesids, si->session, si->session);
6728
6729                 return offset;
6730         }
6731
6732         if (si->session->auth_frame != (guint32)-1) {
6733                 item = proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, si->session->acct_name);
6734                 PROTO_ITEM_SET_GENERATED(item);
6735                 proto_item_append_text(sesid_item, " Acct:%s", si->session->acct_name);
6736
6737                 item = proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, si->session->domain_name);
6738                 PROTO_ITEM_SET_GENERATED(item);
6739                 proto_item_append_text(sesid_item, " Domain:%s", si->session->domain_name);
6740
6741                 item = proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, si->session->host_name);
6742                 PROTO_ITEM_SET_GENERATED(item);
6743                 proto_item_append_text(sesid_item, " Host:%s", si->session->host_name);
6744
6745                 item = proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, si->session->auth_frame);
6746                 PROTO_ITEM_SET_GENERATED(item);
6747         }
6748
6749         if (!(si->flags&SMB2_FLAGS_ASYNC_CMD)) {
6750                 /* see if we can find the name for this tid */
6751                 tid_key.tid = si->tid;
6752                 si->tree = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
6753                 if (!si->tree) return offset;
6754
6755                 item = proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
6756                 PROTO_ITEM_SET_GENERATED(item);
6757                 proto_item_append_text(tid_item, "  %s", si->tree->name);
6758
6759                 item = proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
6760                 PROTO_ITEM_SET_GENERATED(item);
6761
6762                 item = proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
6763                 PROTO_ITEM_SET_GENERATED(item);
6764         }
6765
6766         return offset;
6767 }
6768
6769 static int
6770 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
6771 {
6772         gboolean    smb2_transform_header = FALSE;
6773         proto_item *msg_id_item;
6774         proto_item *item                  = NULL;
6775         proto_tree *tree                  = NULL;
6776         proto_item *header_item           = NULL;
6777         proto_tree *header_tree           = NULL;
6778         proto_item *flags_item            = NULL;
6779         proto_tree *flags_tree            = NULL;
6780         int         offset                = 0;
6781         int         chain_offset          = 0;
6782         const char *label                 = smb_header_label;
6783         conversation_t    *conversation;
6784         smb2_saved_info_t *ssi          = NULL, ssi_key;
6785         smb2_info_t       *si;
6786         smb2_transform_info_t *sti;
6787         char                *fid_name;
6788         guint32              open_frame,close_frame;
6789         smb2_eo_file_info_t *eo_file_info;
6790         e_ctx_hnd           *policy_hnd_hashtablekey;
6791
6792         sti = wmem_new(wmem_packet_scope(), smb2_transform_info_t);
6793         si  = wmem_new(wmem_packet_scope(), smb2_info_t);
6794         si->eo_file_info = NULL;
6795         si->conv         = NULL;
6796         si->saved        = NULL;
6797         si->tree         = NULL;
6798         si->top_tree     = parent_tree;
6799
6800         if (tvb_get_guint8(tvb, 0) == 0xfd) {
6801                 smb2_transform_header = TRUE;
6802                 label = smb_transform_header_label;
6803         }
6804         /* find which conversation we are part of and get the data for that
6805          * conversation
6806          */
6807         conversation = find_or_create_conversation(pinfo);
6808         si->conv = (smb2_conv_info_t *)conversation_get_proto_data(conversation, proto_smb2);
6809         if (!si->conv) {
6810                 /* no smb2_into_t structure for this conversation yet,
6811                  * create it.
6812                  */
6813                 si->conv = wmem_new(wmem_file_scope(), smb2_conv_info_t);
6814                 /* qqq this leaks memory for now since we never free
6815                    the hashtables */
6816                 si->conv->matched = g_hash_table_new(smb2_saved_info_hash_matched,
6817                         smb2_saved_info_equal_matched);
6818                 si->conv->unmatched = g_hash_table_new(smb2_saved_info_hash_unmatched,
6819                         smb2_saved_info_equal_unmatched);
6820                 si->conv->sesids = g_hash_table_new(smb2_sesid_info_hash,
6821                         smb2_sesid_info_equal);
6822                 si->conv->files = g_hash_table_new(smb2_eo_files_hash,smb2_eo_files_equal);
6823
6824                 /* Bit of a hack to avoid leaking the hash tables - register a
6825                  * callback to free them. Ideally wmem would implement a simple
6826                  * hash table so we wouldn't have to do this. */
6827                 wmem_register_callback(wmem_file_scope(), smb2_conv_destroy,
6828                                 si->conv);
6829
6830                 conversation_add_proto_data(conversation, proto_smb2, si->conv);
6831         }
6832
6833         sti->conv = si->conv;
6834
6835         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
6836         if (first_in_chain) {
6837                 /* first packet */
6838                 col_clear(pinfo->cinfo, COL_INFO);
6839         } else {
6840                 col_append_str(pinfo->cinfo, COL_INFO, ";");
6841         }
6842
6843         if (parent_tree) {
6844                 item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset,
6845                         -1, ENC_NA);
6846                 tree = proto_item_add_subtree(item, ett_smb2);
6847         }
6848
6849
6850         if (tree) {
6851                 header_item = proto_tree_add_text(tree, tvb, offset, -1, "%s", label);
6852                 header_tree = proto_item_add_subtree(header_item, ett_smb2_header);
6853         }
6854
6855         /* Decode the header */
6856
6857         if (!smb2_transform_header) {
6858                 /* SMB2 marker */
6859                 proto_tree_add_text(header_tree, tvb, offset, 4, "Server Component: SMB2");
6860                 offset += 4;
6861
6862                 /* we need the flags before we know how to parse the credits field */
6863                 si->flags = tvb_get_letohl(tvb, offset+12);
6864
6865                 /* header length */
6866                 proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6867                 offset += 2;
6868
6869                 /* credit charge (previously "epoch" (unused) which has been deprecated as of "SMB 2.1") */
6870                 proto_tree_add_item(header_tree, hf_smb2_credit_charge, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6871                 offset += 2;
6872
6873                 /* Status Code */
6874                 if (si->flags & SMB2_FLAGS_RESPONSE) {
6875                         si->status = tvb_get_letohl(tvb, offset);
6876                         proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6877                         offset += 4;
6878                 } else {
6879                         si->status = 0;
6880                         proto_tree_add_item(header_tree, hf_smb2_channel_sequence, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6881                         offset += 2;
6882                         proto_tree_add_item(header_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6883                         offset += 2;
6884                 }
6885
6886                 /* opcode */
6887                 si->opcode = tvb_get_letohs(tvb, offset);
6888                 proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6889                 offset += 2;
6890
6891                 /* credits */
6892                 if (si->flags & SMB2_FLAGS_RESPONSE) {
6893                         proto_tree_add_item(header_tree, hf_smb2_credits_granted, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6894                 } else {
6895                         proto_tree_add_item(header_tree, hf_smb2_credits_requested, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6896                 }
6897                 offset += 2;
6898
6899                 /* flags */
6900                 if (header_tree) {
6901                         flags_item = proto_tree_add_uint_format(header_tree, hf_smb2_flags,  tvb, offset, 4, si->flags,
6902                                 "Flags: 0x%08x", si->flags);
6903                         flags_tree = proto_item_add_subtree(flags_item, ett_smb2_flags);
6904
6905                         proto_tree_add_boolean(flags_tree, hf_smb2_flags_response,                      tvb, offset, 4, si->flags);
6906                         proto_tree_add_boolean(flags_tree, hf_smb2_flags_async_cmd,                     tvb, offset, 4, si->flags);
6907                         proto_tree_add_boolean(flags_tree, hf_smb2_flags_chained,                       tvb, offset, 4, si->flags);
6908                         proto_tree_add_boolean(flags_tree, hf_smb2_flags_signature,                     tvb, offset, 4, si->flags);
6909                         proto_tree_add_boolean(flags_tree, hf_smb2_flags_dfs_op,                        tvb, offset, 4, si->flags);
6910                         proto_tree_add_boolean(flags_tree, hf_smb2_flags_replay_operation,      tvb, offset, 4, si->flags);
6911                 }
6912
6913                 offset += 4;
6914
6915                 /* Next Command */
6916                 chain_offset = tvb_get_letohl(tvb, offset);
6917                 proto_tree_add_item(header_tree, hf_smb2_chain_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
6918                 offset += 4;
6919
6920                 /* Message ID */
6921                 si->msg_id = tvb_get_letoh64(tvb, offset);
6922                 ssi_key.msg_id = si->msg_id;
6923                 msg_id_item = proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6924                 if (msg_id_item && (si->msg_id == -1)) {
6925                         proto_item_append_text(msg_id_item, " (unsolicited response)");
6926                 }
6927                 offset += 8;
6928
6929                 /* Tree ID and Session ID */
6930                 offset = dissect_smb2_tid_sesid(pinfo, header_tree, tvb, offset, si);
6931
6932                 /* Signature */
6933                 proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, ENC_NA);
6934                 offset += 16;
6935
6936                 proto_item_set_len(header_item, offset);
6937
6938
6939                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
6940                                 decode_smb2_name(si->opcode),
6941                                 (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
6942                 if (si->status) {
6943                         col_append_fstr(
6944                                         pinfo->cinfo, COL_INFO, ", Error: %s",
6945                                         val_to_str_ext(si->status, &NT_errors_ext,
6946                                                        "Unknown (0x%08X)"));
6947                 }
6948
6949
6950                 if (!pinfo->fd->flags.visited) {
6951                         /* see if we can find this msg_id in the unmatched table */
6952                         ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
6953
6954                         if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
6955                                 /* This is a request */
6956                                 if (ssi) {
6957                                         /* this is a request and we already found
6958                                         * an older ssi so just delete the previous
6959                                         * one
6960                                         */
6961                                         g_hash_table_remove(si->conv->unmatched, ssi);
6962                                         ssi = NULL;
6963                                 }
6964
6965                                 if (!ssi) {
6966                                         /* no we couldnt find it, so just add it then
6967                                         * if was a request we are decoding
6968                                         */
6969                                         ssi                  = wmem_new0(wmem_file_scope(), smb2_saved_info_t);
6970                                         ssi->msg_id          = ssi_key.msg_id;
6971                                         ssi->frame_req       = pinfo->fd->num;
6972                                         ssi->req_time        = pinfo->fd->abs_ts;
6973                                         ssi->extra_info_type = SMB2_EI_NONE;
6974                                         g_hash_table_insert(si->conv->unmatched, ssi, ssi);
6975                                 }
6976                         } else {
6977                                 /* This is a response */
6978                                 if (ssi) {
6979                                         /* just  set the response frame and move it to the matched table */
6980                                         ssi->frame_res = pinfo->fd->num;
6981                                         g_hash_table_remove(si->conv->unmatched, ssi);
6982                                         g_hash_table_insert(si->conv->matched, ssi, ssi);
6983                                 }
6984                         }
6985                 } else {
6986                         /* see if we can find this msg_id in the matched table */
6987                         ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->matched, &ssi_key);
6988                         /* if we couldnt find it in the matched table, it might still
6989                         * be in the unmatched table
6990                         */
6991                         if (!ssi) {
6992                                 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
6993                         }
6994                 }
6995
6996                 if (ssi) {
6997                         if (dcerpc_fetch_polhnd_data(&ssi->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num)) {
6998                                 /* If needed, create the file entry and save the policy hnd */
6999                                 if (!si->eo_file_info) {
7000                                         if (si->conv) {
7001                                                 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&ssi->policy_hnd);
7002                                                 if (!eo_file_info) { /* XXX This should never happen */
7003                                                         /* assert(1==0); */
7004                                                         eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
7005                                                         policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
7006                                                         memcpy(policy_hnd_hashtablekey, &ssi->policy_hnd, sizeof(e_ctx_hnd));
7007                                                         eo_file_info->end_of_file=0;
7008                                                         g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
7009                                                 }
7010                                                 si->eo_file_info=eo_file_info;
7011                                         }
7012                                 }
7013                         }
7014
7015                         if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
7016                                 if (ssi->frame_res) {
7017                                         proto_item *tmp_item;
7018                                         tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
7019                                         PROTO_ITEM_SET_GENERATED(tmp_item);
7020                                 }
7021                         } else {
7022                                 if (ssi->frame_req) {
7023                                         proto_item *tmp_item;
7024                                         nstime_t    t, deltat;
7025
7026                                         tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
7027                                         PROTO_ITEM_SET_GENERATED(tmp_item);
7028                                         t = pinfo->fd->abs_ts;
7029                                         nstime_delta(&deltat, &t, &ssi->req_time);
7030                                         tmp_item = proto_tree_add_time(header_tree, hf_smb2_time, tvb,
7031                                         0, 0, &deltat);
7032                                         PROTO_ITEM_SET_GENERATED(tmp_item);
7033                                 }
7034                         }
7035                 }
7036                 /* if we dont have ssi yet we must fake it */
7037                 /*qqq*/
7038                 si->saved = ssi;
7039
7040                 tap_queue_packet(smb2_tap, pinfo, si);
7041
7042                 /* Decode the payload */
7043                 offset                = dissect_smb2_command(pinfo, tree, tvb, offset, si);
7044         } else {
7045                 proto_item *enc_item;
7046                 proto_tree *enc_tree;
7047                 tvbuff_t   *enc_tvb   = NULL;
7048                 tvbuff_t   *plain_tvb = NULL;
7049
7050                 /* SMB2_TRANSFORM marker */
7051                 proto_tree_add_text(header_tree, tvb, offset, 4, "Server Component: SMB2_TRANSFORM");
7052                 offset += 4;
7053
7054                 offset = dissect_smb2_transform_header(pinfo, header_tree, tvb, offset, sti,
7055                                                        &enc_tvb, &plain_tvb);
7056
7057                 enc_item = proto_tree_add_text(tree, enc_tvb, 0, sti->size, "Encrypted SMB3 data");
7058                 enc_tree = proto_item_add_subtree(enc_item, ett_smb2_encrypted);
7059                 if (plain_tvb != NULL) {
7060                         col_append_str(pinfo->cinfo, COL_INFO, "Decrypted SMB3");
7061                         dissect_smb2(plain_tvb, pinfo, enc_tree, FALSE);
7062                 } else {
7063                         col_append_str(pinfo->cinfo, COL_INFO, "Encrypted SMB3");
7064                         proto_tree_add_item(enc_tree, hf_smb2_transform_encrypted_data,
7065                                             enc_tvb, 0, sti->size, ENC_NA);
7066                 }
7067
7068                 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7069                         chain_offset = offset;
7070                 }
7071         }
7072
7073         if (chain_offset > 0) {
7074                 tvbuff_t *next_tvb;
7075
7076                 proto_item_set_len(item, chain_offset);
7077
7078                 next_tvb = tvb_new_subset_remaining(tvb, chain_offset);
7079                 offset   = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
7080         }
7081
7082         return offset;
7083 }
7084
7085 static gboolean
7086 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
7087 {
7088
7089         /* must check that this really is a smb2 packet */
7090         if (tvb_length(tvb) < 4)
7091                 return FALSE;
7092
7093         if (((tvb_get_guint8(tvb, 0) != 0xfe) && (tvb_get_guint8(tvb, 0) != 0xfd))
7094             || (tvb_get_guint8(tvb, 1) != 'S')
7095             || (tvb_get_guint8(tvb, 2) != 'M')
7096             || (tvb_get_guint8(tvb, 3) != 'B') ) {
7097                 return FALSE;
7098         }
7099
7100         dissect_smb2(tvb, pinfo, parent_tree, TRUE);
7101
7102         return TRUE;
7103 }
7104
7105 void
7106 proto_register_smb2(void)
7107 {
7108         module_t *smb2_module;
7109         static hf_register_info hf[] = {
7110                 { &hf_smb2_cmd,
7111                   { "Command", "smb2.cmd", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
7112                     &smb2_cmd_vals_ext, 0, "SMB2 Command Opcode", HFILL }},
7113                 { &hf_smb2_response_to,
7114                   { "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
7115                     NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
7116                 { &hf_smb2_response_in,
7117                   { "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
7118                     NULL, 0, "The response to this packet is in this packet", HFILL }},
7119                 { &hf_smb2_time,
7120                   { "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
7121                     NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }},
7122                 { &hf_smb2_header_len,
7123                   { "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
7124                     NULL, 0, "SMB2 Size of Header", HFILL }},
7125                 { &hf_smb2_nt_status,
7126                   { "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
7127                     &NT_errors_ext, 0, "NT Status code", HFILL }},
7128                 { &hf_smb2_msg_id,
7129                   { "Message ID", "smb2.msg_id", FT_INT64, BASE_DEC,
7130                     NULL, 0, "SMB2 Messsage ID", HFILL }},
7131                 { &hf_smb2_tid,
7132                   { "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
7133                     NULL, 0, "SMB2 Tree Id", HFILL }},
7134                 { &hf_smb2_aid,
7135                   { "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
7136                     NULL, 0, "SMB2 Async Id", HFILL }},
7137                 { &hf_smb2_sesid,
7138                   { "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
7139                     NULL, 0, "SMB2 Session Id", HFILL }},
7140                 { &hf_smb2_previous_sesid,
7141                   { "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
7142                     NULL, 0, "SMB2 Previous Session Id", HFILL }},
7143                 { &hf_smb2_chain_offset,
7144                   { "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
7145                     NULL, 0, "SMB2 Chain Offset", HFILL }},
7146                 { &hf_smb2_end_of_file,
7147                   { "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
7148                     NULL, 0, "SMB2 End Of File/File size", HFILL }},
7149                 { &hf_smb2_nlinks,
7150                   { "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
7151                     NULL, 0, "Number of links to this object", HFILL }},
7152                 { &hf_smb2_file_id,
7153                   { "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
7154                     NULL, 0, "SMB2 File Id", HFILL }},
7155                 { &hf_smb2_allocation_size,
7156                   { "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
7157                     NULL, 0, "SMB2 Allocation Size for this object", HFILL }},
7158                 { &hf_smb2_max_response_size,
7159                   { "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
7160                     NULL, 0, "SMB2 Maximum response size", HFILL }},
7161                 { &hf_smb2_setinfo_size,
7162                   { "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
7163                     NULL, 0, "SMB2 setinfo size", HFILL }},
7164                 { &hf_smb2_setinfo_offset,
7165                   { "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
7166                     NULL, 0, "SMB2 setinfo offset", HFILL }},
7167                 { &hf_smb2_max_ioctl_out_size,
7168                   { "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
7169                     NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
7170                 { &hf_smb2_max_ioctl_in_size,
7171                   { "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
7172                     NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
7173                 { &hf_smb2_required_buffer_size,
7174                   { "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
7175                     NULL, 0, "SMB2 required buffer size", HFILL }},
7176                 { &hf_smb2_pid,
7177                   { "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
7178                     NULL, 0, "SMB2 Process Id", HFILL }},
7179
7180                 /* SMB2 header flags  */
7181                 { &hf_smb2_flags,
7182                   { "Flags", "smb2.flags", FT_UINT32, BASE_HEX,
7183                     NULL, 0, "SMB2 flags", HFILL }},
7184                 { &hf_smb2_flags_response,
7185                   { "Response", "smb2.flags.response", FT_BOOLEAN, 32,
7186                     TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }},
7187                 { &hf_smb2_flags_async_cmd,
7188                   { "Async command", "smb2.flags.async", FT_BOOLEAN, 32,
7189                     TFS(&tfs_flags_async_cmd), SMB2_FLAGS_ASYNC_CMD, NULL, HFILL }},
7190                 { &hf_smb2_flags_dfs_op,
7191                   { "DFS operation", "smb2.flags.dfs", FT_BOOLEAN, 32,
7192                     TFS(&tfs_flags_dfs_op), SMB2_FLAGS_DFS_OP, NULL, HFILL }},
7193                 { &hf_smb2_flags_chained,
7194                   { "Chained", "smb2.flags.chained", FT_BOOLEAN, 32,
7195                     TFS(&tfs_flags_chained), SMB2_FLAGS_CHAINED, "Whether the pdu continues a chain or not", HFILL }},
7196                 { &hf_smb2_flags_signature,
7197                   { "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
7198                     TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }},
7199                 { &hf_smb2_flags_replay_operation,
7200                   { "Replay operation", "smb2.flags.replay", FT_BOOLEAN, 32,
7201                     TFS(&tfs_flags_replay_operation), SMB2_FLAGS_REPLAY_OPERATION, "Whether this is a replay operation", HFILL }},
7202
7203                 { &hf_smb2_tree,
7204                   { "Tree", "smb2.tree", FT_STRING, BASE_NONE,
7205                     NULL, 0, "Name of the Tree/Share", HFILL }},
7206                 { &hf_smb2_filename,
7207                   { "Filename", "smb2.filename", FT_STRING, BASE_NONE,
7208                     NULL, 0, "Name of the file", HFILL }},
7209                 { &hf_smb2_filename_len,
7210                   { "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
7211                     NULL, 0, "Length of the file name", HFILL }},
7212
7213                 { &hf_smb2_data_offset,
7214                   { "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
7215                     NULL, 0, "Offset to data", HFILL }},
7216
7217                 { &hf_smb2_find_info_level,
7218                   { "Info Level", "smb2.find.infolevel", FT_UINT32, BASE_DEC,
7219                     VALS(smb2_find_info_levels), 0, "Find_Info Infolevel", HFILL }},
7220                 { &hf_smb2_find_flags,
7221                   { "Find Flags", "smb2.find.flags", FT_UINT8, BASE_HEX,
7222                     NULL, 0, NULL, HFILL }},
7223
7224                 { &hf_smb2_find_pattern,
7225                   { "Search Pattern", "smb2.find.pattern", FT_STRING, BASE_NONE,
7226                     NULL, 0, "Find pattern", HFILL }},
7227
7228                 { &hf_smb2_find_info_blob,
7229                   { "Info", "smb2.find.info_blob", FT_BYTES, BASE_NONE,
7230                     NULL, 0, "Find Info", HFILL }},
7231
7232                 { &hf_smb2_ea_size,
7233                   { "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
7234                     NULL, 0, "Size of EA data", HFILL }},
7235
7236                 { &hf_smb2_class,
7237                   { "Class", "smb2.class", FT_UINT8, BASE_HEX,
7238                     VALS(smb2_class_vals), 0, "Info class", HFILL }},
7239
7240                 { &hf_smb2_infolevel,
7241                   { "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
7242                     NULL, 0, NULL, HFILL }},
7243
7244                 { &hf_smb2_infolevel_file_info,
7245                   { "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
7246                     &smb2_file_info_levels_ext, 0, "File_Info Infolevel", HFILL }},
7247
7248                 { &hf_smb2_infolevel_fs_info,
7249                   { "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
7250                     &smb2_fs_info_levels_ext, 0, "Fs_Info Infolevel", HFILL }},
7251
7252                 { &hf_smb2_infolevel_sec_info,
7253                   { "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
7254                     &smb2_sec_info_levels_ext, 0, "Sec_Info Infolevel", HFILL }},
7255
7256                 { &hf_smb2_write_length,
7257                   { "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
7258                     NULL, 0, "Amount of data to write", HFILL }},
7259
7260                 { &hf_smb2_read_length,
7261                   { "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
7262                     NULL, 0, "Amount of data to read", HFILL }},
7263
7264                 { &hf_smb2_read_remaining,
7265                   { "Read Remaining", "smb2.read_remaining", FT_UINT32, BASE_DEC,
7266                     NULL, 0, NULL, HFILL }},
7267
7268                 { &hf_smb2_create_flags,
7269                   { "Create Flags", "smb2.create_flags", FT_UINT64, BASE_HEX,
7270                     NULL, 0, NULL, HFILL }},
7271
7272                 { &hf_smb2_file_offset,
7273                   { "File Offset", "smb2.file_offset", FT_UINT64, BASE_DEC,
7274                     NULL, 0, NULL, HFILL }},
7275
7276                 { &hf_smb2_security_blob,
7277                   { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_NONE,
7278                     NULL, 0, NULL, HFILL }},
7279
7280                 { &hf_smb2_ioctl_out_data,
7281                   { "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
7282                     NULL, 0, "Ioctl Out", HFILL }},
7283
7284                 { &hf_smb2_ioctl_in_data,
7285                   { "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
7286                     NULL, 0, "Ioctl In", HFILL }},
7287
7288                 { &hf_smb2_server_guid,
7289                   { "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
7290                     NULL, 0, NULL, HFILL }},
7291
7292                 { &hf_smb2_client_guid,
7293                   { "Client Guid", "smb2.client_guid", FT_GUID, BASE_NONE,
7294                     NULL, 0, NULL, HFILL }},
7295
7296                 { &hf_smb2_object_id,
7297                   { "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
7298                     NULL, 0, "ObjectID for this FID", HFILL }},
7299
7300                 { &hf_smb2_birth_volume_id,
7301                   { "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
7302                     NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }},
7303
7304                 { &hf_smb2_birth_object_id,
7305                   { "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
7306                     NULL, 0, "ObjectID for this FID when it was originally created", HFILL }},
7307
7308                 { &hf_smb2_domain_id,
7309                   { "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
7310                     NULL, 0, NULL, HFILL }},
7311
7312                 { &hf_smb2_create_timestamp,
7313                   { "Create", "smb2.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7314                     NULL, 0, "Time when this object was created", HFILL }},
7315
7316                 { &hf_smb2_fid,
7317                   { "File Id", "smb2.fid", FT_GUID, BASE_NONE,
7318                     NULL, 0, "SMB2 File Id", HFILL }},
7319
7320                 { &hf_smb2_write_data,
7321                   { "Write Data", "smb2.write_data", FT_BYTES, BASE_NONE,
7322                     NULL, 0, "SMB2 Data to be written", HFILL }},
7323
7324                 { &hf_smb2_write_flags,
7325                   { "Write Flags", "smb2.write.flags", FT_UINT32, BASE_HEX,
7326                     NULL, 0, NULL, HFILL }},
7327
7328                 { &hf_smb2_write_flags_write_through,
7329                   { "Write through", "smb2.write.flags.write_through", FT_BOOLEAN, 32,
7330                     NULL, SMB2_WRITE_FLAG_WRITE_THROUGH, NULL, HFILL }},
7331
7332                 { &hf_smb2_write_count,
7333                   { "Write Count", "smb2.write.count", FT_UINT32, BASE_DEC,
7334                     NULL, 0, NULL, HFILL }},
7335
7336                 { &hf_smb2_write_remaining,
7337                   { "Write Remaining", "smb2.write.remaining", FT_UINT32, BASE_DEC,
7338                     NULL, 0, NULL, HFILL }},
7339
7340                 { &hf_smb2_read_data,
7341                   { "Read Data", "smb2.read_data", FT_BYTES, BASE_NONE,
7342                     NULL, 0, "SMB2 Data that is read", HFILL }},
7343
7344                 { &hf_smb2_last_access_timestamp,
7345                   { "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7346                     NULL, 0, "Time when this object was last accessed", HFILL }},
7347
7348                 { &hf_smb2_last_write_timestamp,
7349                   { "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7350                     NULL, 0, "Time when this object was last written to", HFILL }},
7351
7352                 { &hf_smb2_last_change_timestamp,
7353                   { "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7354                     NULL, 0, "Time when this object was last changed", HFILL }},
7355
7356                 { &hf_smb2_file_all_info,
7357                   { "SMB2_FILE_ALL_INFO", "smb2.file_all_info", FT_NONE, BASE_NONE,
7358                     NULL, 0, "SMB2_FILE_ALL_INFO structure", HFILL }},
7359
7360                 { &hf_smb2_file_allocation_info,
7361                   { "SMB2_FILE_ALLOCATION_INFO", "smb2.file_allocation_info", FT_NONE, BASE_NONE,
7362                     NULL, 0, "SMB2_FILE_ALLOCATION_INFO structure", HFILL }},
7363
7364                 { &hf_smb2_file_endoffile_info,
7365                   { "SMB2_FILE_ENDOFFILE_INFO", "smb2.file_endoffile_info", FT_NONE, BASE_NONE,
7366                     NULL, 0, "SMB2_FILE_ENDOFFILE_INFO structure", HFILL }},
7367
7368                 { &hf_smb2_file_alternate_name_info,
7369                   { "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.file_alternate_name_info", FT_NONE, BASE_NONE,
7370                     NULL, 0, "SMB2_FILE_ALTERNATE_NAME_INFO structure", HFILL }},
7371
7372                 { &hf_smb2_file_stream_info,
7373                   { "SMB2_FILE_STREAM_INFO", "smb2.file_stream_info", FT_NONE, BASE_NONE,
7374                     NULL, 0, "SMB2_FILE_STREAM_INFO structure", HFILL }},
7375
7376                 { &hf_smb2_file_pipe_info,
7377                   { "SMB2_FILE_PIPE_INFO", "smb2.file_pipe_info", FT_NONE, BASE_NONE,
7378                     NULL, 0, "SMB2_FILE_PIPE_INFO structure", HFILL }},
7379
7380                 { &hf_smb2_file_compression_info,
7381                   { "SMB2_FILE_COMPRESSION_INFO", "smb2.file_compression_info", FT_NONE, BASE_NONE,
7382                     NULL, 0, "SMB2_FILE_COMPRESSION_INFO structure", HFILL }},
7383
7384                 { &hf_smb2_file_basic_info,
7385                   { "SMB2_FILE_BASIC_INFO", "smb2.file_basic_info", FT_NONE, BASE_NONE,
7386                     NULL, 0, "SMB2_FILE_BASIC_INFO structure", HFILL }},
7387
7388                 { &hf_smb2_file_standard_info,
7389                   { "SMB2_FILE_STANDARD_INFO", "smb2.file_standard_info", FT_NONE, BASE_NONE,
7390                     NULL, 0, "SMB2_FILE_STANDARD_INFO structure", HFILL }},
7391
7392                 { &hf_smb2_file_internal_info,
7393                   { "SMB2_FILE_INTERNAL_INFO", "smb2.file_internal_info", FT_NONE, BASE_NONE,
7394                     NULL, 0, "SMB2_FILE_INTERNAL_INFO structure", HFILL }},
7395
7396                 { &hf_smb2_file_mode_info,
7397                   { "SMB2_FILE_MODE_INFO", "smb2.file_mode_info", FT_NONE, BASE_NONE,
7398                     NULL, 0, "SMB2_FILE_MODE_INFO structure", HFILL }},
7399
7400                 { &hf_smb2_file_alignment_info,
7401                   { "SMB2_FILE_ALIGNMENT_INFO", "smb2.file_alignment_info", FT_NONE, BASE_NONE,
7402                     NULL, 0, "SMB2_FILE_ALIGNMENT_INFO structure", HFILL }},
7403
7404                 { &hf_smb2_file_position_info,
7405                   { "SMB2_FILE_POSITION_INFO", "smb2.file_position_info", FT_NONE, BASE_NONE,
7406                     NULL, 0, "SMB2_FILE_POSITION_INFO structure", HFILL }},
7407
7408                 { &hf_smb2_file_access_info,
7409                   { "SMB2_FILE_ACCESS_INFO", "smb2.file_access_info", FT_NONE, BASE_NONE,
7410                     NULL, 0, "SMB2_FILE_ACCESS_INFO structure", HFILL }},
7411
7412                 { &hf_smb2_file_ea_info,
7413                   { "SMB2_FILE_EA_INFO", "smb2.file_ea_info", FT_NONE, BASE_NONE,
7414                     NULL, 0, "SMB2_FILE_EA_INFO structure", HFILL }},
7415
7416                 { &hf_smb2_file_network_open_info,
7417                   { "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.file_network_open_info", FT_NONE, BASE_NONE,
7418                     NULL, 0, "SMB2_FILE_NETWORK_OPEN_INFO structure", HFILL }},
7419
7420                 { &hf_smb2_file_attribute_tag_info,
7421                   { "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.file_attribute_tag_info", FT_NONE, BASE_NONE,
7422                     NULL, 0, "SMB2_FILE_ATTRIBUTE_TAG_INFO structure", HFILL }},
7423
7424                 { &hf_smb2_file_disposition_info,
7425                   { "SMB2_FILE_DISPOSITION_INFO", "smb2.file_disposition_info", FT_NONE, BASE_NONE,
7426                     NULL, 0, "SMB2_FILE_DISPOSITION_INFO structure", HFILL }},
7427
7428                 { &hf_smb2_file_full_ea_info,
7429                   { "SMB2_FILE_FULL_EA_INFO", "smb2.file_full_ea_info", FT_NONE, BASE_NONE,
7430                     NULL, 0, "SMB2_FILE_FULL_EA_INFO structure", HFILL }},
7431
7432                 { &hf_smb2_file_rename_info,
7433                   { "SMB2_FILE_RENAME_INFO", "smb2.file_rename_info", FT_NONE, BASE_NONE,
7434                     NULL, 0, "SMB2_FILE_RENAME_INFO structure", HFILL }},
7435
7436                 { &hf_smb2_fs_info_01,
7437                   { "SMB2_FS_INFO_01", "smb2.fs_info_01", FT_NONE, BASE_NONE,
7438                     NULL, 0, "SMB2_FS_INFO_01 structure", HFILL }},
7439
7440                 { &hf_smb2_fs_info_03,
7441                   { "SMB2_FS_INFO_03", "smb2.fs_info_03", FT_NONE, BASE_NONE,
7442                     NULL, 0, "SMB2_FS_INFO_03 structure", HFILL }},
7443
7444                 { &hf_smb2_fs_info_04,
7445                   { "SMB2_FS_INFO_04", "smb2.fs_info_04", FT_NONE, BASE_NONE,
7446                     NULL, 0, "SMB2_FS_INFO_04 structure", HFILL }},
7447
7448                 { &hf_smb2_fs_info_05,
7449                   { "SMB2_FS_INFO_05", "smb2.fs_info_05", FT_NONE, BASE_NONE,
7450                     NULL, 0, "SMB2_FS_INFO_05 structure", HFILL }},
7451
7452                 { &hf_smb2_fs_info_06,
7453                   { "SMB2_FS_INFO_06", "smb2.fs_info_06", FT_NONE, BASE_NONE,
7454                     NULL, 0, "SMB2_FS_INFO_06 structure", HFILL }},
7455
7456                 { &hf_smb2_fs_info_07,
7457                   { "SMB2_FS_INFO_07", "smb2.fs_info_07", FT_NONE, BASE_NONE,
7458                     NULL, 0, "SMB2_FS_INFO_07 structure", HFILL }},
7459
7460                 { &hf_smb2_fs_objectid_info,
7461                   { "SMB2_FS_OBJECTID_INFO", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
7462                     NULL, 0, "SMB2_FS_OBJECTID_INFO structure", HFILL }},
7463
7464                 { &hf_smb2_sec_info_00,
7465                   { "SMB2_SEC_INFO_00", "smb2.sec_info_00", FT_NONE, BASE_NONE,
7466                     NULL, 0, "SMB2_SEC_INFO_00 structure", HFILL }},
7467
7468                 { &hf_smb2_disposition_delete_on_close,
7469                   { "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
7470                     TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
7471
7472
7473                 { &hf_smb2_create_disposition,
7474                   { "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
7475                     VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
7476
7477                 { &hf_smb2_create_action,
7478                   { "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
7479                     VALS(oa_open_vals), 0, NULL, HFILL }},
7480
7481                 { &hf_smb2_create_rep_flags,
7482                   { "Response Flags", "smb2.create.rep_flags", FT_UINT8, BASE_HEX,
7483                     NULL, 0, NULL, HFILL }},
7484
7485                 { &hf_smb2_create_rep_flags_reparse_point,
7486                   { "ReparsePoint", "smb2.create.rep_flags.reparse_point", FT_BOOLEAN, 8,
7487                     NULL, SMB2_CREATE_REP_FLAGS_REPARSE_POINT, NULL, HFILL }},
7488
7489                 { &hf_smb2_extrainfo,
7490                   { "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
7491                     NULL, 0, "Create ExtraInfo", HFILL }},
7492
7493                 { &hf_smb2_create_chain_offset,
7494                   { "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
7495                     NULL, 0, "Offset to next entry in chain or 0", HFILL }},
7496
7497                 { &hf_smb2_create_chain_data,
7498                   { "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
7499                     NULL, 0, "Chain Data", HFILL }},
7500
7501                 { &hf_smb2_FILE_OBJECTID_BUFFER,
7502                   { "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
7503                     NULL, 0, "A FILE_OBJECTID_BUFFER structure", HFILL }},
7504
7505                 { &hf_smb2_lease_key,
7506                   { "Lease Key", "smb2.lease.lease_key", FT_GUID, BASE_NONE,
7507                     NULL, 0, NULL, HFILL }},
7508
7509                 { &hf_smb2_lease_state,
7510                   { "Lease State", "smb2.lease.lease_state", FT_UINT32, BASE_HEX,
7511                     NULL, 0, NULL, HFILL }},
7512
7513                 { &hf_smb2_lease_state_read_caching,
7514                   { "Read Caching", "smb2.lease.lease_state.read_caching", FT_BOOLEAN, 32,
7515                     NULL, SMB2_LEASE_STATE_READ_CACHING, NULL, HFILL }},
7516
7517                 { &hf_smb2_lease_state_handle_caching,
7518                   { "Handle Caching", "smb2.lease.lease_state.handle_caching", FT_BOOLEAN, 32,
7519                     NULL, SMB2_LEASE_STATE_HANDLE_CACHING, NULL, HFILL }},
7520
7521                 { &hf_smb2_lease_state_write_caching,
7522                   { "Write Caching", "smb2.lease.lease_state.write_caching", FT_BOOLEAN, 32,
7523                     NULL, SMB2_LEASE_STATE_WRITE_CACHING, NULL, HFILL }},
7524
7525                 { &hf_smb2_lease_flags,
7526                   { "Lease Flags", "smb2.lease.lease_flags", FT_UINT32, BASE_HEX,
7527                     NULL, 0, NULL, HFILL }},
7528
7529                 { &hf_smb2_lease_flags_break_ack_required,
7530                   { "Break Ack Required", "smb2.lease.lease_state.break_ack_required", FT_BOOLEAN, 32,
7531                     NULL, SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED, NULL, HFILL }},
7532
7533                 { &hf_smb2_lease_flags_break_in_progress,
7534                   { "Break In Progress", "smb2.lease.lease_state.break_in_progress", FT_BOOLEAN, 32,
7535                     NULL, SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS, NULL, HFILL }},
7536
7537                 { &hf_smb2_lease_flags_parent_lease_key_set,
7538                   { "Parent Lease Key Set", "smb2.lease.lease_state.parent_lease_key_set", FT_BOOLEAN, 32,
7539                     NULL, SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET, NULL, HFILL }},
7540
7541                 { &hf_smb2_lease_duration,
7542                   { "Lease Duration", "smb2.lease.lease_duration", FT_UINT64, BASE_HEX,
7543                     NULL, 0, NULL, HFILL }},
7544
7545                 { &hf_smb2_parent_lease_key,
7546                   { "Parent Lease Key", "smb2.lease.parent_lease_key", FT_GUID, BASE_NONE,
7547                     NULL, 0, NULL, HFILL }},
7548
7549                 { &hf_smb2_lease_epoch,
7550                   { "Lease Epoch", "smb2.lease.lease_oplock", FT_UINT16, BASE_HEX,
7551                     NULL, 0, NULL, HFILL }},
7552
7553                 { &hf_smb2_lease_reserved,
7554                   { "Lease Reserved", "smb2.lease.lease_reserved", FT_UINT16, BASE_HEX,
7555                     NULL, 0, NULL, HFILL }},
7556
7557                 { &hf_smb2_lease_break_reason,
7558                   { "Lease Break Reason", "smb2.lease.lease_break_reason", FT_UINT32, BASE_HEX,
7559                     NULL, 0, NULL, HFILL }},
7560
7561                 { &hf_smb2_lease_access_mask_hint,
7562                   { "Access Mask Hint", "smb2.lease.access_mask_hint", FT_UINT32, BASE_HEX,
7563                     NULL, 0, NULL, HFILL }},
7564
7565                 { &hf_smb2_lease_share_mask_hint,
7566                   { "Share Mask Hint", "smb2.lease.share_mask_hint", FT_UINT32, BASE_HEX,
7567                     NULL, 0, NULL, HFILL }},
7568
7569                 { &hf_smb2_next_offset,
7570                   { "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
7571                     NULL, 0, "Offset to next buffer or 0", HFILL }},
7572
7573                 { &hf_smb2_current_time,
7574                   { "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7575                     NULL, 0, "Current Time at server", HFILL }},
7576
7577                 { &hf_smb2_boot_time,
7578                   { "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7579                     NULL, 0, "Boot Time at server", HFILL }},
7580
7581                 { &hf_smb2_ea_flags,
7582                   { "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
7583                     NULL, 0, NULL, HFILL }},
7584
7585                 { &hf_smb2_ea_name_len,
7586                   { "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
7587                     NULL, 0, NULL, HFILL }},
7588
7589                 { &hf_smb2_ea_data_len,
7590                   { "EA Data Length", "smb2.ea.data_len", FT_UINT8, BASE_DEC,
7591                     NULL, 0, NULL, HFILL }},
7592
7593                 { &hf_smb2_delete_pending,
7594                   { "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
7595                     NULL, 0, NULL, HFILL }},
7596
7597                 { &hf_smb2_is_directory,
7598                   { "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
7599                     NULL, 0, "Is this a directory?", HFILL }},
7600
7601                 { &hf_smb2_oplock,
7602                   { "Oplock", "smb2.create.oplock", FT_UINT8, BASE_HEX,
7603                     VALS(oplock_vals), 0, "Oplock type", HFILL }},
7604
7605                 { &hf_smb2_close_flags,
7606                   { "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
7607                     NULL, 0, NULL, HFILL }},
7608
7609                 { &hf_smb2_notify_flags,
7610                   { "Notify Flags", "smb2.notify.flags", FT_UINT16, BASE_HEX,
7611                     NULL, 0, NULL, HFILL }},
7612
7613                 { &hf_smb2_buffer_code,
7614                   { "StructureSize", "smb2.buffer_code", FT_UINT16, BASE_HEX,
7615                     NULL, 0, NULL, HFILL }},
7616
7617                 { &hf_smb2_buffer_code_len,
7618                   { "Fixed Part Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
7619                     NULL, 0, "Length of fixed portion of PDU", HFILL }},
7620
7621                 { &hf_smb2_olb_length,
7622                   { "Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
7623                     NULL, 0, "Length of the buffer", HFILL }},
7624
7625                 { &hf_smb2_olb_offset,
7626                   { "Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
7627                     NULL, 0, "Offset to the buffer", HFILL }},
7628
7629                 { &hf_smb2_buffer_code_flags_dyn,
7630                   { "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
7631                     NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }},
7632
7633                 { &hf_smb2_ea_data,
7634                   { "EA Data", "smb2.ea.data", FT_BYTES, BASE_NONE,
7635                     NULL, 0, NULL, HFILL }},
7636
7637                 { &hf_smb2_ea_name,
7638                   { "EA Name", "smb2.ea.name", FT_STRING, BASE_NONE,
7639                     NULL, 0, NULL, HFILL }},
7640
7641                 { &hf_smb2_impersonation_level,
7642                   { "Impersonation", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
7643                     VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
7644
7645                 { &hf_smb2_ioctl_function,
7646                   { "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
7647                     &smb2_ioctl_vals_ext, 0, "Ioctl function", HFILL }},
7648
7649                 { &hf_smb2_ioctl_function_device,
7650                   { "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
7651                     &smb2_ioctl_device_vals_ext, 0xffff0000, "Device for Ioctl", HFILL }},
7652
7653                 { &hf_smb2_ioctl_function_access,
7654                   { "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
7655                     VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }},
7656
7657                 { &hf_smb2_ioctl_function_function,
7658                   { "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
7659                     NULL, 0x00003ffc, "Function for Ioctl", HFILL }},
7660
7661                 { &hf_smb2_ioctl_function_method,
7662                   { "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
7663                     VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }},
7664
7665                 { &hf_smb2_ioctl_resiliency_timeout,
7666                   { "Timeout", "smb2.ioctl.resiliency.timeout", FT_UINT32, BASE_DEC,
7667                     NULL, 0, "Resiliency timeout", HFILL }},
7668
7669                 { &hf_smb2_ioctl_resiliency_reserved,
7670                   { "Reserved", "smb2.ioctl.resiliency.reserved", FT_UINT32, BASE_DEC,
7671                     NULL, 0, "Resiliency reserved", HFILL }},
7672
7673                 { &hf_windows_sockaddr_family,
7674                   { "Socket Family", "smb2.windows.sockaddr.family", FT_UINT16, BASE_DEC,
7675                     NULL, 0, "The socket address family (on windows)", HFILL }},
7676
7677                 { &hf_windows_sockaddr_port,
7678                   { "Socket Port", "smb2.windows.sockaddr.port", FT_UINT16, BASE_DEC,
7679                     NULL, 0, "The socket address port", HFILL }},
7680
7681                 { &hf_windows_sockaddr_in_addr,
7682                   { "Socket IPv4", "smb2.windows.sockaddr.in.addr", FT_IPv4, BASE_NONE,
7683                     NULL, 0, "The IPv4 address", HFILL }},
7684
7685                 { &hf_windows_sockaddr_in6_flowinfo,
7686                   { "IPv6 Flow Info", "smb2.windows.sockaddr.in6.flow_info", FT_UINT32, BASE_HEX,
7687                     NULL, 0, "The socket IPv6 flow info", HFILL }},
7688
7689                 { &hf_windows_sockaddr_in6_addr,
7690                   { "Socket IPv6", "smb2.windows.sockaddr.in6.addr", FT_IPv6, BASE_NONE,
7691                     NULL, 0, "The IPv6 address", HFILL }},
7692
7693                 { &hf_windows_sockaddr_in6_scope_id,
7694                   { "IPv6 Scope ID", "smb2.windows.sockaddr.in6.scope_id", FT_UINT32, BASE_DEC,
7695                     NULL, 0, "The socket IPv6 scope id", HFILL }},
7696
7697                 { &hf_smb2_ioctl_network_interface_next_offset,
7698                   { "Next Offset", "smb2.ioctl.network_interfaces.next_offset", FT_UINT32, BASE_HEX,
7699                     NULL, 0, "Offset to next entry in chain or 0", HFILL }},
7700
7701                 { &hf_smb2_ioctl_network_interface_index,
7702                   { "Interface Index", "smb2.ioctl.network_interfaces.index", FT_UINT32, BASE_DEC,
7703                     NULL, 0, "The index of the interface", HFILL }},
7704
7705                 { &hf_smb2_ioctl_network_interface_rss_queue_count,
7706                   { "RSS Queue Count", "smb2.ioctl.network_interfaces.rss_queue_count", FT_UINT32, BASE_DEC,
7707                     NULL, 0, "The RSS queue count", HFILL }},
7708
7709                 { &hf_smb2_ioctl_network_interface_capabilities,
7710                   { "Interface Cababilities", "smb2.ioctl.network_interfaces.capabilities", FT_UINT32, BASE_HEX,
7711                     NULL, 0, "The RSS queue count", HFILL }},
7712
7713                 { &hf_smb2_ioctl_network_interface_capability_rss,
7714                   { "RSS", "smb2.ioctl.network_interfaces.capabilities.rss", FT_BOOLEAN, 32,
7715                     TFS(&tfs_smb2_ioctl_network_interface_capability_rss),
7716                     NETWORK_INTERFACE_CAP_RSS, "If the host supports RSS", HFILL }},
7717
7718                 { &hf_smb2_ioctl_network_interface_capability_rdma,
7719                   { "RDMA", "smb2.ioctl.network_interfaces.capabilities.rdma", FT_BOOLEAN, 32,
7720                     TFS(&tfs_smb2_ioctl_network_interface_capability_rdma),
7721                     NETWORK_INTERFACE_CAP_RDMA, "If the host supports RDMA", HFILL }},
7722
7723                 { &hf_smb2_ioctl_network_interface_link_speed,
7724                   { "Link Speed", "smb2.ioctl.network_interfaces.link_speed", FT_UINT64, BASE_DEC,
7725                     NULL, 0, "The link speed of the interface", HFILL }},
7726
7727                 { &hf_smb2_ioctl_shadow_copy_num_volumes,
7728                   { "Num Volumes", "smb2.ioctl.shadow_copy.num_volumes", FT_UINT32, BASE_DEC,
7729                     NULL, 0, "Number of shadow copy volumes", HFILL }},
7730
7731                 { &hf_smb2_ioctl_shadow_copy_num_labels,
7732                   { "Num Labels", "smb2.ioctl.shadow_copy.num_labels", FT_UINT32, BASE_DEC,
7733                     NULL, 0, "Number of shadow copy labels", HFILL }},
7734
7735                 { &hf_smb2_ioctl_shadow_copy_label,
7736                   { "Label", "smb2.ioctl.shadow_copy.label", FT_STRING, BASE_NONE,
7737                     NULL, 0, "Shadow copy label", HFILL }},
7738
7739                 { &hf_smb2_compression_format,
7740                   { "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
7741                     VALS(compression_format_vals), 0, "Compression to use", HFILL }},
7742
7743                 { &hf_smb2_share_type,
7744                   { "Share Type", "smb2.share_type", FT_UINT8, BASE_HEX,
7745                     VALS(smb2_share_type_vals), 0, "Type of share", HFILL }},
7746
7747                 { &hf_smb2_credit_charge,
7748                   { "Credit Charge", "smb2.credit.charge", FT_UINT16, BASE_DEC,
7749                     NULL, 0, NULL, HFILL }},
7750
7751                 { &hf_smb2_credits_requested,
7752                   { "Credits requested", "smb2.credits.requested", FT_UINT16, BASE_DEC,
7753                     NULL, 0, NULL, HFILL }},
7754
7755                 { &hf_smb2_credits_granted,
7756                   { "Credits granted", "smb2.credits.granted", FT_UINT16, BASE_DEC,
7757                     NULL, 0, NULL, HFILL }},
7758
7759                 { &hf_smb2_channel_sequence,
7760                   { "Channel Sequence", "smb2.channel_sequence", FT_UINT16, BASE_DEC,
7761                     NULL, 0, NULL, HFILL }},
7762
7763                 { &hf_smb2_dialect_count,
7764                   { "Dialect count", "smb2.dialect_count", FT_UINT16, BASE_DEC,
7765                     NULL, 0, NULL, HFILL }},
7766
7767                 { &hf_smb2_dialect,
7768                   { "Dialect", "smb2.dialect", FT_UINT16, BASE_HEX,
7769                     NULL, 0, NULL, HFILL }},
7770
7771                 { &hf_smb2_security_mode,
7772                   { "Security mode", "smb2.sec_mode", FT_UINT8, BASE_HEX,
7773                     NULL, 0, NULL, HFILL }},
7774
7775                 { &hf_smb2_session_flags,
7776                   { "Session Flags", "smb2.session_flags", FT_UINT16, BASE_HEX,
7777                     NULL, 0, NULL, HFILL }},
7778
7779                 { &hf_smb2_lock_count,
7780                   { "Lock Count", "smb2.lock_count", FT_UINT16, BASE_DEC,
7781                     NULL, 0, NULL, HFILL }},
7782
7783                 { &hf_smb2_capabilities,
7784                   { "Capabilities", "smb2.capabilities", FT_UINT32, BASE_HEX,
7785                     NULL, 0, NULL, HFILL }},
7786
7787                 { &hf_smb2_ioctl_shadow_copy_count,
7788                   { "Count", "smb2.ioctl.shadow_copy.count", FT_UINT32, BASE_DEC,
7789                     NULL, 0, "Number of bytes for shadow copy label strings", HFILL }},
7790
7791                 { &hf_smb2_auth_frame,
7792                   { "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
7793                     NULL, 0, "Which frame this user was authenticated in", HFILL }},
7794
7795                 { &hf_smb2_tcon_frame,
7796                   { "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
7797                     NULL, 0, "Which frame this share was connected in", HFILL }},
7798
7799                 { &hf_smb2_tag,
7800                   { "Tag", "smb2.tag", FT_STRING, BASE_NONE,
7801                     NULL, 0, "Tag of chain entry", HFILL }},
7802
7803                 { &hf_smb2_acct_name,
7804                   { "Account", "smb2.acct", FT_STRING, BASE_NONE,
7805                     NULL, 0, "Account Name", HFILL }},
7806
7807                 { &hf_smb2_domain_name,
7808                   { "Domain", "smb2.domain", FT_STRING, BASE_NONE,
7809                     NULL, 0, "Domain Name", HFILL }},
7810
7811                 { &hf_smb2_host_name,
7812                   { "Host", "smb2.host", FT_STRING, BASE_NONE,
7813                     NULL, 0, "Host Name", HFILL }},
7814
7815                 { &hf_smb2_signature,
7816                   { "Signature", "smb2.signature", FT_BYTES, BASE_NONE,
7817                     NULL, 0, NULL, HFILL }},
7818
7819                 { &hf_smb2_unknown,
7820                   { "unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
7821                     NULL, 0, "Unknown bytes", HFILL }},
7822
7823                 { &hf_smb2_twrp_timestamp,
7824                   { "Timestamp", "smb2.twrp_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7825                     NULL, 0, "TWrp timestamp", HFILL }},
7826
7827                 { &hf_smb2_mxac_timestamp,
7828                   { "Timestamp", "smb2.mxac_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7829                     NULL, 0, "MxAc timestamp", HFILL }},
7830
7831                 { &hf_smb2_mxac_status,
7832                   { "Query Status", "smb2.mxac_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
7833                     &NT_errors_ext, 0, "NT Status code", HFILL }},
7834
7835                 { &hf_smb2_qfid_fid,
7836                   { "Opaque File ID", "smb2.qfid_fid", FT_BYTES, BASE_NONE,
7837                     NULL, 0, NULL, HFILL }},
7838
7839                 { &hf_smb2_ses_flags_guest,
7840                   { "Guest", "smb2.ses_flags.guest", FT_BOOLEAN, 16,
7841                     NULL, SES_FLAGS_GUEST, NULL, HFILL }},
7842
7843                 { &hf_smb2_ses_flags_null,
7844                   { "Null", "smb2.ses_flags.null", FT_BOOLEAN, 16,
7845                     NULL, SES_FLAGS_NULL, NULL, HFILL }},
7846
7847                 { &hf_smb2_secmode_flags_sign_required,
7848                   { "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
7849                     NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }},
7850
7851                 { &hf_smb2_secmode_flags_sign_enabled,
7852                   { "Signing enabled", "smb2.sec_mode.sign_enabled", FT_BOOLEAN, 8,
7853                     NULL, NEGPROT_SIGN_ENABLED, "Is signing enabled", HFILL }},
7854
7855                 { &hf_smb2_ses_req_flags,
7856                   { "Flags", "smb2.ses_req_flags", FT_UINT8, BASE_DEC,
7857                     NULL, 0, NULL, HFILL }},
7858
7859                 { &hf_smb2_ses_req_flags_session_binding,
7860                   { "Session Binding Request", "smb2.ses_req_flags.session_binding", FT_BOOLEAN, 8,
7861                     NULL, SES_REQ_FLAGS_SESSION_BINDING,
7862                     "The client wants to bind to an existing session", HFILL }},
7863
7864                 { &hf_smb2_cap_dfs,
7865                   { "DFS", "smb2.capabilities.dfs", FT_BOOLEAN, 32,
7866                     TFS(&tfs_cap_dfs), NEGPROT_CAP_DFS, "If the host supports dfs", HFILL }},
7867
7868                 { &hf_smb2_cap_leasing,
7869                   { "LEASING", "smb2.capabilities.leasing", FT_BOOLEAN, 32,
7870                     TFS(&tfs_cap_leasing), NEGPROT_CAP_LEASING,
7871                     "If the host supports leasing", HFILL }},
7872
7873                 { &hf_smb2_cap_large_mtu,
7874                   { "LARGE MTU", "smb2.capabilities.large_mtu", FT_BOOLEAN, 32,
7875                     TFS(&tfs_cap_large_mtu), NEGPROT_CAP_LARGE_MTU,
7876                     "If the host supports LARGE MTU", HFILL }},
7877
7878                 { &hf_smb2_cap_multi_channel,
7879                   { "MULTI CHANNEL", "smb2.capabilities.multi_channel", FT_BOOLEAN, 32,
7880                     TFS(&tfs_cap_multi_channel), NEGPROT_CAP_MULTI_CHANNEL,
7881                     "If the host supports MULTI CHANNEL", HFILL }},
7882
7883                 { &hf_smb2_cap_persistent_handles,
7884                   { "PERSISTENT HANDLES", "smb2.capabilities.persistent_handles", FT_BOOLEAN, 32,
7885                     TFS(&tfs_cap_persistent_handles), NEGPROT_CAP_PERSISTENT_HANDLES,
7886                     "If the host supports PERSISTENT HANDLES", HFILL }},
7887
7888                 { &hf_smb2_cap_directory_leasing,
7889                   { "DIRECTORY LEASING", "smb2.capabilities.directory_leasing", FT_BOOLEAN, 32,
7890                     TFS(&tfs_cap_directory_leasing), NEGPROT_CAP_DIRECTORY_LEASING,
7891                     "If the host supports DIRECTORY LEASING", HFILL }},
7892
7893                 { &hf_smb2_cap_encryption,
7894                   { "ENCRYPTION", "smb2.capabilities.encryption", FT_BOOLEAN, 32,
7895                     TFS(&tfs_cap_encryption), NEGPROT_CAP_ENCRYPTION,
7896                     "If the host supports ENCRYPTION", HFILL }},
7897
7898                 { &hf_smb2_max_trans_size,
7899                   { "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
7900                     NULL, 0, "Maximum size of a transaction", HFILL }},
7901
7902                 { &hf_smb2_max_read_size,
7903                   { "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
7904                     NULL, 0, "Maximum size of a read", HFILL }},
7905
7906                 { &hf_smb2_max_write_size,
7907                   { "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
7908                     NULL, 0, "Maximum size of a write", HFILL }},
7909
7910                 { &hf_smb2_channel,
7911                   { "Channel", "smb2.channel", FT_UINT32, BASE_DEC,
7912                     NULL, 0, NULL, HFILL }},
7913
7914                 { &hf_smb2_share_flags,
7915                   { "Share flags", "smb2.share_flags", FT_UINT32, BASE_HEX,
7916                     NULL, 0, NULL, HFILL }},
7917
7918                 { &hf_smb2_share_flags_dfs,
7919                   { "DFS", "smb2.share_flags.dfs", FT_BOOLEAN, 32,
7920                     NULL, SHARE_FLAGS_dfs, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }},
7921
7922                 { &hf_smb2_share_flags_dfs_root,
7923                   { "DFS root", "smb2.share_flags.dfs_root", FT_BOOLEAN, 32,
7924                     NULL, SHARE_FLAGS_dfs_root, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }},
7925
7926                 { &hf_smb2_share_flags_restrict_exclusive_opens,
7927                   { "Restrict exclusive opens", "smb2.share_flags.restrict_exclusive_opens", FT_BOOLEAN, 32,
7928                     NULL, SHARE_FLAGS_restrict_exclusive_opens, "The specified share disallows exclusive file opens that deny reads to an open file", HFILL }},
7929
7930                 { &hf_smb2_share_flags_force_shared_delete,
7931                   { "Force shared delete", "smb2.share_flags.force_shared_delete", FT_BOOLEAN, 32,
7932                     NULL, SHARE_FLAGS_force_shared_delete, "Shared files in the specified share can be forcibly deleted", HFILL }},
7933
7934                 { &hf_smb2_share_flags_allow_namespace_caching,
7935                   { "Allow namepsace caching", "smb2.share_flags.allow_namespace_caching", FT_BOOLEAN, 32,
7936                     NULL, SHARE_FLAGS_allow_namespace_caching, "Clients are allowed to cache the namespace of the specified share", HFILL }},
7937
7938                 { &hf_smb2_share_flags_access_based_dir_enum,
7939                   { "Access based directory enum", "smb2.share_flags.access_based_dir_enum", FT_BOOLEAN, 32,
7940                     NULL, SHARE_FLAGS_access_based_dir_enum, "The server will filter directory entries based on the access permissions of the client", HFILL }},
7941
7942                 { &hf_smb2_share_flags_force_levelii_oplock,
7943                   { "Force level II oplock", "smb2.share_flags.force_levelii_oplock", FT_BOOLEAN, 32,
7944                     NULL, SHARE_FLAGS_force_levelii_oplock, "The server will not issue exclusive caching rights on this share", HFILL }},
7945
7946                 { &hf_smb2_share_flags_enable_hash_v1,
7947                   { "Enable hash V1", "smb2.share_flags.enable_hash_v1", FT_BOOLEAN, 32,
7948                     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 }},
7949
7950                 { &hf_smb2_share_flags_enable_hash_v2,
7951                   { "Enable hash V2", "smb2.share_flags.enable_hash_v2", FT_BOOLEAN, 32,
7952                     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 }},
7953
7954                 { &hf_smb2_share_flags_encrypt_data,
7955                   { "Encrypted data required", "smb2.share_flags.encrypt_data", FT_BOOLEAN, 32,
7956                     NULL, SHARE_FLAGS_encryption_required, "The share require data encryption", HFILL }},
7957
7958                 { &hf_smb2_share_caching,
7959                   { "Caching policy", "smb2.share.caching", FT_UINT32, BASE_HEX,
7960                     VALS(share_cache_vals), 0, NULL, HFILL }},
7961
7962                 { &hf_smb2_share_caps,
7963                   { "Share Capabilities", "smb2.share_caps", FT_UINT32, BASE_HEX,
7964                     NULL, 0, NULL, HFILL }},
7965
7966                 { &hf_smb2_share_caps_dfs,
7967                   { "DFS", "smb2.share_caps.dfs", FT_BOOLEAN, 32,
7968                     NULL, SHARE_CAPS_DFS, "The specified share is present in a DFS tree structure", HFILL }},
7969
7970                 { &hf_smb2_share_caps_continuous_availability,
7971                   { "CONTINUOUS AVAILABILITY", "smb2.share_caps.continuous_availability", FT_BOOLEAN, 32,
7972                     NULL, SHARE_CAPS_CONTINUOUS_AVAILABILITY,
7973                     "The specified share is continuously available", HFILL }},
7974
7975                 { &hf_smb2_share_caps_scaleout,
7976                   { "SCALEOUT", "smb2.share_caps.scaleout", FT_BOOLEAN, 32,
7977                     NULL, SHARE_CAPS_SCALEOUT,
7978                     "The specified share is a scaleout share", HFILL }},
7979
7980                 { &hf_smb2_share_caps_cluster,
7981                   { "CLUSTER", "smb2.share_caps.cluster", FT_BOOLEAN, 32,
7982                     NULL, SHARE_CAPS_CLUSTER,
7983                     "The specified share is a cluster share", HFILL }},
7984
7985                 { &hf_smb2_ioctl_flags,
7986                   { "Flags", "smb2.ioctl.flags", FT_UINT32, BASE_HEX,
7987                     NULL, 0, NULL, HFILL }},
7988
7989                 { &hf_smb2_min_count,
7990                   { "Min Count", "smb2.min_count", FT_UINT32, BASE_DEC,
7991                     NULL, 0, NULL, HFILL }},
7992
7993                 { &hf_smb2_remaining_bytes,
7994                   { "Remaining Bytes", "smb2.remaining_bytes", FT_UINT32, BASE_DEC,             NULL, 0, NULL, HFILL }},
7995
7996                 { &hf_smb2_channel_info_offset,
7997                   { "Channel Info Offset", "smb2.channel_info_offset", FT_UINT16, BASE_DEC,
7998                     NULL, 0, NULL, HFILL }},
7999
8000                 { &hf_smb2_channel_info_length,
8001                   { "Channel Info Length", "smb2.channel_info_length", FT_UINT16, BASE_DEC,
8002                     NULL, 0, NULL, HFILL }},
8003
8004                 { &hf_smb2_ioctl_is_fsctl,
8005                   { "Is FSCTL", "smb2.ioctl.is_fsctl", FT_BOOLEAN, 32,
8006                     NULL, 0x00000001, NULL, HFILL }},
8007
8008                 { &hf_smb2_output_buffer_len,
8009                   { "Output Buffer Length", "smb2.output_buffer_len", FT_UINT16, BASE_DEC,
8010                     NULL, 0, NULL, HFILL }},
8011
8012                 { &hf_smb2_close_pq_attrib,
8013                   { "PostQuery Attrib", "smb2.close.pq_attrib", FT_BOOLEAN, 16,
8014                     NULL, 0x0001, NULL, HFILL }},
8015
8016                 { &hf_smb2_notify_watch_tree,
8017                   { "Watch Tree", "smb2.notify.watch_tree", FT_BOOLEAN, 16,
8018                     NULL, 0x0001, NULL, HFILL }},
8019
8020                 { &hf_smb2_notify_out_data,
8021                   { "Out Data", "smb2.notify.out", FT_NONE, BASE_NONE,
8022                     NULL, 0, NULL, HFILL }},
8023
8024                 { &hf_smb2_find_flags_restart_scans,
8025                   { "Restart Scans", "smb2.find.restart_scans", FT_BOOLEAN, 8,
8026                     NULL, SMB2_FIND_FLAG_RESTART_SCANS, NULL, HFILL }},
8027
8028                 { &hf_smb2_find_flags_single_entry,
8029                   { "Single Entry", "smb2.find.single_entry", FT_BOOLEAN, 8,
8030                     NULL, SMB2_FIND_FLAG_SINGLE_ENTRY, NULL, HFILL }},
8031
8032                 { &hf_smb2_find_flags_index_specified,
8033                   { "Index Specified", "smb2.find.index_specified", FT_BOOLEAN, 8,
8034                     NULL, SMB2_FIND_FLAG_INDEX_SPECIFIED, NULL, HFILL }},
8035
8036                 { &hf_smb2_find_flags_reopen,
8037                   { "Reopen", "smb2.find.reopen", FT_BOOLEAN, 8,
8038                     NULL, SMB2_FIND_FLAG_REOPEN, NULL, HFILL }},
8039
8040                 { &hf_smb2_file_index,
8041                   { "File Index", "smb2.file_index", FT_UINT32, BASE_HEX,
8042                     NULL, 0, NULL, HFILL }},
8043
8044                 { &hf_smb2_file_directory_info,
8045                   { "FileDirectoryInfo", "smb2.find.file_directory_info", FT_NONE, BASE_NONE,
8046                     NULL, 0, NULL, HFILL }},
8047
8048                 { &hf_smb2_full_directory_info,
8049                   { "FullDirectoryInfo", "smb2.find.full_directory_info", FT_NONE, BASE_NONE,
8050                     NULL, 0, NULL, HFILL }},
8051
8052                 { &hf_smb2_both_directory_info,
8053                   { "FileBothDirectoryInfo", "smb2.find.both_directory_info", FT_NONE, BASE_NONE,
8054                     NULL, 0, NULL, HFILL }},
8055
8056                 { &hf_smb2_id_both_directory_info,
8057                   { "FileIdBothDirectoryInfo", "smb2.find.id_both_directory_info", FT_NONE, BASE_NONE,
8058                     NULL, 0, NULL, HFILL }},
8059
8060                 { &hf_smb2_short_name_len,
8061                   { "Short Name Length", "smb2.short_name_len", FT_UINT8, BASE_DEC,
8062                     NULL, 0, NULL, HFILL }},
8063
8064                 { &hf_smb2_short_name,
8065                   { "Short Name", "smb2.shortname", FT_STRING, BASE_NONE,
8066                     NULL, 0, NULL, HFILL }},
8067
8068                 { &hf_smb2_lock_info,
8069                   { "Lock Info", "smb2.lock_info", FT_NONE, BASE_NONE,
8070                     NULL, 0, NULL, HFILL }},
8071
8072                 { &hf_smb2_lock_length,
8073                   { "Length", "smb2.lock_length", FT_UINT64, BASE_DEC,
8074                     NULL, 0, NULL, HFILL }},
8075
8076                 { &hf_smb2_lock_flags,
8077                   { "Flags", "smb2.lock_flags", FT_UINT32, BASE_HEX,
8078                     NULL, 0, NULL, HFILL }},
8079
8080                 { &hf_smb2_lock_flags_shared,
8081                   { "Shared", "smb2.lock_flags.shared", FT_BOOLEAN, 32,
8082                     NULL, 0x00000001, NULL, HFILL }},
8083
8084                 { &hf_smb2_lock_flags_exclusive,
8085                   { "Exclusive", "smb2.lock_flags.exclusive", FT_BOOLEAN, 32,
8086                     NULL, 0x00000002, NULL, HFILL }},
8087
8088                 { &hf_smb2_lock_flags_unlock,
8089                   { "Unlock", "smb2.lock_flags.unlock", FT_BOOLEAN, 32,
8090                     NULL, 0x00000004, NULL, HFILL }},
8091
8092                 { &hf_smb2_lock_flags_fail_immediately,
8093                   { "Fail Immediately", "smb2.lock_flags.fail_immediately", FT_BOOLEAN, 32,
8094                     NULL, 0x00000010, NULL, HFILL }},
8095
8096                 { &hf_smb2_error_reserved,
8097                   { "Reserved", "smb2.error.reserved", FT_UINT16, BASE_HEX,
8098                     NULL, 0, NULL, HFILL }},
8099
8100                 { &hf_smb2_error_byte_count,
8101                   { "Byte Count", "smb2.error.byte_count", FT_UINT32, BASE_DEC,
8102                     NULL, 0, NULL, HFILL }},
8103
8104                 { &hf_smb2_error_data,
8105                   { "Error Data", "smb2.error.data", FT_BYTES, BASE_NONE,
8106                     NULL, 0, NULL, HFILL }},
8107
8108                 { &hf_smb2_reserved,
8109                   { "Reserved", "smb2.reserved", FT_BYTES, BASE_NONE,
8110                     NULL, 0, "Reserved bytes", HFILL }},
8111
8112                 { &hf_smb2_dhnq_buffer_reserved,
8113                   { "Reserved", "smb2.dhnq_buffer_reserved", FT_UINT64, BASE_HEX,
8114                     NULL, 0, NULL, HFILL}},
8115
8116                 { &hf_smb2_dh2x_buffer_timeout,
8117                   { "Timeout", "smb2.dh2x.timeout", FT_UINT32, BASE_DEC,
8118                     NULL, 0, NULL, HFILL}},
8119
8120                 { &hf_smb2_dh2x_buffer_flags,
8121                   { "Flags", "smb2.dh2x.flags", FT_UINT32, BASE_HEX,
8122                     NULL, 0, NULL, HFILL}},
8123
8124                 { &hf_smb2_dh2x_buffer_flags_persistent_handle,
8125                   { "Persistent Handle", "smb2.dh2x.flags.persistent_handle", FT_BOOLEAN, 32,
8126                     NULL, SMB2_DH2X_FLAGS_PERSISTENT_HANDLE, NULL, HFILL}},
8127
8128                 { &hf_smb2_dh2x_buffer_reserved,
8129                   { "Reserved", "smb2.dh2x.reserved", FT_UINT64, BASE_HEX,
8130                     NULL, 0, NULL, HFILL}},
8131
8132                 { &hf_smb2_dh2x_buffer_create_guid,
8133                   { "Create Guid", "smb2.dh2x.create_guid", FT_GUID, BASE_NONE,
8134                     NULL, 0, NULL, HFILL}},
8135
8136                 { &hf_smb2_APP_INSTANCE_buffer_struct_size,
8137                   { "Struct Size", "smb2.app_instance.struct_size", FT_UINT16, BASE_DEC,
8138                     NULL, 0, NULL, HFILL}},
8139
8140                 { &hf_smb2_APP_INSTANCE_buffer_reserved,
8141                   { "Reserved", "smb2.app_instance.reserved", FT_UINT16, BASE_HEX,
8142                     NULL, 0, NULL, HFILL}},
8143
8144                 { &hf_smb2_APP_INSTANCE_buffer_app_guid,
8145                   { "Application Guid", "smb2.app_instance.app_guid", FT_GUID, BASE_NONE,
8146                     NULL, 0, NULL, HFILL}},
8147
8148                 { &hf_smb2_transform_signature,
8149                   { "Signature", "smb2.header.transform.signature", FT_BYTES, BASE_NONE,
8150                     NULL, 0, NULL, HFILL }},
8151
8152                 { &hf_smb2_transform_nonce,
8153                   { "Nonce", "smb2.header.transform.nonce", FT_BYTES, BASE_NONE,
8154                     NULL, 0, NULL, HFILL }},
8155
8156                 { &hf_smb2_transform_msg_size,
8157                   { "Message size", "smb2.header.transform.msg_size", FT_UINT32, BASE_DEC,
8158                     NULL, 0, NULL, HFILL }},
8159
8160                 { &hf_smb2_transform_reserved,
8161                   { "Reserved", "smb2.header.transform.reserved", FT_BYTES, BASE_NONE,
8162                     NULL, 0, NULL, HFILL }},
8163
8164                 { &hf_smb2_transform_enc_alg,
8165                   { "Encryption ALG", "smb2.header.transform.encryption_alg", FT_UINT16, BASE_HEX,
8166                     NULL, 0, NULL, HFILL }},
8167
8168                 { &hf_smb2_encryption_aes128_ccm,
8169                   { "SMB2_ENCRYPTION_AES128_CCM", "smb2.header.transform.enc_aes128_ccm", FT_BOOLEAN, 16,
8170                     NULL, ENC_ALG_aes128_ccm, NULL, HFILL }},
8171
8172                 { &hf_smb2_transform_encrypted_data,
8173                   { "Data", "smb2.header.transform.enc_data", FT_BYTES, BASE_NONE,
8174                     NULL, 0, NULL, HFILL }},
8175
8176         };
8177
8178         static gint *ett[] = {
8179                 &ett_smb2,
8180                 &ett_smb2_ea,
8181                 &ett_smb2_olb,
8182                 &ett_smb2_header,
8183                 &ett_smb2_encrypted,
8184                 &ett_smb2_command,
8185                 &ett_smb2_secblob,
8186                 &ett_smb2_file_basic_info,
8187                 &ett_smb2_file_standard_info,
8188                 &ett_smb2_file_internal_info,
8189                 &ett_smb2_file_ea_info,
8190                 &ett_smb2_file_access_info,
8191                 &ett_smb2_file_rename_info,
8192                 &ett_smb2_file_disposition_info,
8193                 &ett_smb2_file_position_info,
8194                 &ett_smb2_file_full_ea_info,
8195                 &ett_smb2_file_mode_info,
8196                 &ett_smb2_file_alignment_info,
8197                 &ett_smb2_file_all_info,
8198                 &ett_smb2_file_allocation_info,
8199                 &ett_smb2_file_endoffile_info,
8200                 &ett_smb2_file_alternate_name_info,
8201                 &ett_smb2_file_stream_info,
8202                 &ett_smb2_file_pipe_info,
8203                 &ett_smb2_file_compression_info,
8204                 &ett_smb2_file_network_open_info,
8205                 &ett_smb2_file_attribute_tag_info,
8206                 &ett_smb2_fs_info_01,
8207                 &ett_smb2_fs_info_03,
8208                 &ett_smb2_fs_info_04,
8209                 &ett_smb2_fs_info_05,
8210                 &ett_smb2_fs_info_06,
8211                 &ett_smb2_fs_info_07,
8212                 &ett_smb2_fs_objectid_info,
8213                 &ett_smb2_sec_info_00,
8214                 &ett_smb2_tid_tree,
8215                 &ett_smb2_sesid_tree,
8216                 &ett_smb2_create_chain_element,
8217                 &ett_smb2_MxAc_buffer,
8218                 &ett_smb2_QFid_buffer,
8219                 &ett_smb2_RqLs_buffer,
8220                 &ett_smb2_ioctl_function,
8221                 &ett_smb2_FILE_OBJECTID_BUFFER,
8222                 &ett_smb2_flags,
8223                 &ett_smb2_sec_mode,
8224                 &ett_smb2_capabilities,
8225                 &ett_smb2_ses_req_flags,
8226                 &ett_smb2_ses_flags,
8227                 &ett_smb2_create_rep_flags,
8228                 &ett_smb2_lease_state,
8229                 &ett_smb2_lease_flags,
8230                 &ett_smb2_share_flags,
8231                 &ett_smb2_share_caps,
8232                 &ett_smb2_ioctl_flags,
8233                 &ett_smb2_ioctl_network_interface,
8234                 &ett_windows_sockaddr,
8235                 &ett_smb2_close_flags,
8236                 &ett_smb2_notify_flags,
8237                 &ett_smb2_write_flags,
8238                 &ett_smb2_find_flags,
8239                 &ett_smb2_file_directory_info,
8240                 &ett_smb2_both_directory_info,
8241                 &ett_smb2_id_both_directory_info,
8242                 &ett_smb2_full_directory_info,
8243                 &ett_smb2_file_name_info,
8244                 &ett_smb2_lock_info,
8245                 &ett_smb2_lock_flags,
8246                 &ett_smb2_DH2Q_buffer,
8247                 &ett_smb2_DH2C_buffer,
8248                 &ett_smb2_dh2x_flags,
8249                 &ett_smb2_APP_INSTANCE_buffer,
8250                 &ett_smb2_transform_enc_alg,
8251                 &ett_smb2_buffercode,
8252         };
8253
8254         proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
8255                                              "SMB2", "smb2");
8256         proto_register_subtree_array(ett, array_length(ett));
8257         proto_register_field_array(proto_smb2, hf, array_length(hf));
8258
8259         smb2_module = prefs_register_protocol(proto_smb2, NULL);
8260         prefs_register_bool_preference(smb2_module, "eosmb2_take_name_as_fid",
8261                                        "Use the full file name as File ID when exporting an SMB2 object",
8262                                        "Whether the export object functionality will take the full path file name as file identifier",
8263                                        &eosmb2_take_name_as_fid);
8264
8265         register_heur_dissector_list("smb2_heur_subdissectors", &smb2_heur_subdissector_list);
8266         smb2_tap = register_tap("smb2");
8267         smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
8268
8269 }
8270
8271 void
8272 proto_reg_handoff_smb2(void)
8273 {
8274         gssapi_handle  = find_dissector("gssapi");
8275         ntlmssp_handle = find_dissector("ntlmssp");
8276         heur_dissector_add("netbios", dissect_smb2_heur, proto_smb2);
8277 }
8278
8279 /*
8280  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
8281  *
8282  * Local variables:
8283  * c-basic-offset: 8
8284  * tab-width: 8
8285  * indent-tabs-mode: t
8286  * End:
8287  *
8288  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
8289  * :indentSize=8:tabSize=8:noTabs=false:
8290  */