1 /* packet-smb2.c
2  * Routines for smb2 packet dissection
3  * Ronnie Sahlberg 2005
4  *
5  * For documentation of this protocol, see:
6  *
7  * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/
8  * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/
9  * https://gitlab.com/wireshark/wireshark/-/wikis/SMB2
10  *
11  * If you edit this file, keep the wiki updated as well.
12  *
13  * Wireshark - Network traffic analyzer
14  * By Gerald Combs <gerald@wireshark.org>
15  * Copyright 1998 Gerald Combs
16  *
17  * SPDX-License-Identifier: GPL-2.0-or-later
18  */
19 
20 #include "config.h"
21 
22 #include <epan/packet.h>
23 #include <epan/exceptions.h>
24 #include <epan/prefs.h>
25 #include <epan/expert.h>
26 #include <epan/tap.h>
27 #include <epan/srt_table.h>
28 #include <epan/aftypes.h>
29 #include <epan/to_str.h>
30 #include <epan/strutil.h>
31 #include <epan/asn1.h>
32 #include <epan/reassemble.h>
33 #include <epan/uat.h>
34 
35 #include "packet-smb2.h"
36 #include "packet-ntlmssp.h"
37 #include "packet-kerberos.h"
38 #include "packet-windows-common.h"
39 #include "packet-dcerpc-nt.h"
40 
41 #include "read_keytab_file.h"
42 
43 #include <wsutil/wsgcrypt.h>
44 #include <wsutil/ws_roundup.h>
45 
46 //#define DEBUG_SMB2
47 #ifdef DEBUG_SMB2
48 #define DEBUG(...) g_ ## warning(__VA_ARGS__)
49 #define HEXDUMP(p, sz) do_hexdump((const guint8 *)(p), sz)
50 static void
do_hexdump(const guint8 * data,gsize len)51 do_hexdump (const guint8 *data, gsize len)
52 {
53 	guint n, m;
54 
55 	for (n = 0; n < len; n += 16) {
56 		g_printerr ("%04x: ", n);
57 
58 		for (m = n; m < n + 16; m++) {
59 			if (m > n && (m%4) == 0)
60 				g_printerr (" ");
61 			if (m < len)
62 				g_printerr ("%02x ", data[m]);
63 			else
64 				g_printerr ("   ");
65 		}
66 
67 		g_printerr ("   ");
68 
69 		for (m = n; m < len && m < n + 16; m++)
70 			g_printerr ("%c", g_ascii_isprint (data[m]) ? data[m] : '.');
71 
72 		g_printerr ("\n");
73 	}
74 }
75 #else
76 #define DEBUG(...)
77 #define HEXDUMP(...)
78 #endif
79 
80 #define NT_STATUS_PENDING		0x00000103
81 #define NT_STATUS_BUFFER_TOO_SMALL	0xC0000023
82 #define NT_STATUS_STOPPED_ON_SYMLINK	0x8000002D
83 #define NT_STATUS_BAD_NETWORK_NAME	0xC00000CC
84 
85 void proto_register_smb2(void);
86 void proto_reg_handoff_smb2(void);
87 
88 #define SMB2_NORM_HEADER 0xFE
89 #define SMB2_ENCR_HEADER 0xFD
90 #define SMB2_COMP_HEADER 0xFC
91 
92 static wmem_map_t *smb2_sessions = NULL;
93 
94 static const char smb_header_label[] = "SMB2 Header";
95 static const char smb_transform_header_label[] = "SMB2 Transform Header";
96 static const char smb_comp_transform_header_label[] = "SMB2 Compression Transform Header";
97 static const char smb_bad_header_label[] = "Bad SMB2 Header";
98 
99 static int proto_smb2 = -1;
100 static int hf_smb2_cmd = -1;
101 static int hf_smb2_nt_status = -1;
102 static int hf_smb2_response_to = -1;
103 static int hf_smb2_response_in = -1;
104 static int hf_smb2_time = -1;
105 static int hf_smb2_preauth_hash = -1;
106 static int hf_smb2_header_len = -1;
107 static int hf_smb2_msg_id = -1;
108 static int hf_smb2_pid = -1;
109 static int hf_smb2_tid = -1;
110 static int hf_smb2_aid = -1;
111 static int hf_smb2_sesid = -1;
112 static int hf_smb2_previous_sesid = -1;
113 static int hf_smb2_flags_response = -1;
114 static int hf_smb2_flags_async_cmd = -1;
115 static int hf_smb2_flags_dfs_op = -1;
116 static int hf_smb2_flags_chained = -1;
117 static int hf_smb2_flags_signature = -1;
118 static int hf_smb2_flags_replay_operation = -1;
119 static int hf_smb2_flags_priority_mask = -1;
120 static int hf_smb2_chain_offset = -1;
121 static int hf_smb2_security_blob = -1;
122 static int hf_smb2_ioctl_in_data = -1;
123 static int hf_smb2_ioctl_out_data = -1;
124 static int hf_smb2_unknown = -1;
125 static int hf_smb2_root_directory_mbz = -1;
126 static int hf_smb2_twrp_timestamp = -1;
127 static int hf_smb2_mxac_timestamp = -1;
128 static int hf_smb2_mxac_status = -1;
129 static int hf_smb2_qfid_fid = -1;
130 static int hf_smb2_create_timestamp = -1;
131 static int hf_smb2_oplock = -1;
132 static int hf_smb2_close_flags = -1;
133 static int hf_smb2_notify_flags = -1;
134 static int hf_smb2_last_access_timestamp = -1;
135 static int hf_smb2_last_write_timestamp = -1;
136 static int hf_smb2_last_change_timestamp = -1;
137 static int hf_smb2_current_time = -1;
138 static int hf_smb2_boot_time = -1;
139 static int hf_smb2_filename = -1;
140 static int hf_smb2_filename_len = -1;
141 static int hf_smb2_replace_if = -1;
142 static int hf_smb2_nlinks = -1;
143 static int hf_smb2_delete_pending = -1;
144 static int hf_smb2_is_directory = -1;
145 static int hf_smb2_file_id = -1;
146 static int hf_smb2_allocation_size = -1;
147 static int hf_smb2_end_of_file = -1;
148 static int hf_smb2_tree = -1;
149 static int hf_smb2_find_pattern = -1;
150 static int hf_smb2_find_info_level = -1;
151 static int hf_smb2_find_info_blob = -1;
152 static int hf_smb2_client_guid = -1;
153 static int hf_smb2_server_guid = -1;
154 static int hf_smb2_object_id = -1;
155 static int hf_smb2_birth_volume_id = -1;
156 static int hf_smb2_birth_object_id = -1;
157 static int hf_smb2_domain_id = -1;
158 static int hf_smb2_class = -1;
159 static int hf_smb2_infolevel = -1;
160 static int hf_smb2_infolevel_file_info = -1;
161 static int hf_smb2_infolevel_fs_info = -1;
162 static int hf_smb2_infolevel_sec_info = -1;
163 static int hf_smb2_max_response_size = -1;
164 static int hf_smb2_max_ioctl_in_size = -1;
165 static int hf_smb2_max_ioctl_out_size = -1;
166 static int hf_smb2_flags = -1;
167 static int hf_smb2_required_buffer_size = -1;
168 static int hf_smb2_getinfo_input_size = -1;
169 static int hf_smb2_getinfo_input_offset = -1;
170 static int hf_smb2_getsetinfo_additional = -1;
171 static int hf_smb2_getsetinfo_additionals = -1;
172 static int hf_smb2_getsetinfo_additional_owner = -1;
173 static int hf_smb2_getsetinfo_additional_group = -1;
174 static int hf_smb2_getsetinfo_additional_dacl = -1;
175 static int hf_smb2_getsetinfo_additional_sacl = -1;
176 static int hf_smb2_getsetinfo_additional_label = -1;
177 static int hf_smb2_getsetinfo_additional_attribute = -1;
178 static int hf_smb2_getsetinfo_additional_scope = -1;
179 static int hf_smb2_getsetinfo_additional_backup = -1;
180 static int hf_smb2_getinfo_flags = -1;
181 static int hf_smb2_setinfo_size = -1;
182 static int hf_smb2_setinfo_offset = -1;
183 static int hf_smb2_setinfo_reserved = -1;
184 static int hf_smb2_file_basic_info = -1;
185 static int hf_smb2_file_standard_info = -1;
186 static int hf_smb2_file_internal_info = -1;
187 static int hf_smb2_file_ea_info = -1;
188 static int hf_smb2_file_access_info = -1;
189 static int hf_smb2_file_rename_info = -1;
190 static int hf_smb2_file_disposition_info = -1;
191 static int hf_smb2_file_position_info = -1;
192 static int hf_smb2_file_full_ea_info = -1;
193 static int hf_smb2_file_mode_info = -1;
194 static int hf_smb2_file_alignment_info = -1;
195 static int hf_smb2_file_all_info = -1;
196 static int hf_smb2_file_allocation_info = -1;
197 static int hf_smb2_file_endoffile_info = -1;
198 static int hf_smb2_file_alternate_name_info = -1;
199 static int hf_smb2_file_stream_info = -1;
200 static int hf_smb2_file_pipe_info = -1;
201 static int hf_smb2_file_compression_info = -1;
202 static int hf_smb2_file_network_open_info = -1;
203 static int hf_smb2_file_attribute_tag_info = -1;
204 static int hf_smb2_file_normalized_name_info = -1;
205 static int hf_smb2_fs_info_01 = -1;
206 static int hf_smb2_fs_info_03 = -1;
207 static int hf_smb2_fs_info_04 = -1;
208 static int hf_smb2_fs_info_05 = -1;
209 static int hf_smb2_fs_info_06 = -1;
210 static int hf_smb2_fs_info_07 = -1;
211 static int hf_smb2_fs_objectid_info = -1;
212 static int hf_smb2_sec_info_00 = -1;
213 static int hf_smb2_quota_info = -1;
214 static int hf_smb2_query_quota_info = -1;
215 static int hf_smb2_qq_single = -1;
216 static int hf_smb2_qq_restart = -1;
217 static int hf_smb2_qq_sidlist_len = -1;
218 static int hf_smb2_qq_start_sid_len = -1;
219 static int hf_smb2_qq_start_sid_offset = -1;
220 static int hf_smb2_fid = -1;
221 static int hf_smb2_write_length = -1;
222 static int hf_smb2_write_data = -1;
223 static int hf_smb2_write_flags = -1;
224 static int hf_smb2_write_flags_write_through = -1;
225 static int hf_smb2_write_flags_write_unbuffered = -1;
226 static int hf_smb2_write_count = -1;
227 static int hf_smb2_write_remaining = -1;
228 static int hf_smb2_read_blob = -1;
229 static int hf_smb2_read_length = -1;
230 static int hf_smb2_read_remaining = -1;
231 static int hf_smb2_read_padding = -1;
232 static int hf_smb2_read_flags = -1;
233 static int hf_smb2_read_flags_unbuffered = -1;
234 static int hf_smb2_read_flags_compressed = -1;
235 static int hf_smb2_file_offset = -1;
236 static int hf_smb2_qfr_length = -1;
237 static int hf_smb2_qfr_usage = -1;
238 static int hf_smb2_qfr_flags = -1;
239 static int hf_smb2_qfr_total_region_entry_count = -1;
240 static int hf_smb2_qfr_region_entry_count = -1;
241 static int hf_smb2_read_data = -1;
242 static int hf_smb2_disposition_delete_on_close = -1;
243 static int hf_smb2_create_disposition = -1;
244 static int hf_smb2_create_chain_offset = -1;
245 static int hf_smb2_create_chain_data = -1;
246 static int hf_smb2_data_offset = -1;
247 static int hf_smb2_extrainfo = -1;
248 static int hf_smb2_create_action = -1;
249 static int hf_smb2_create_rep_flags = -1;
250 static int hf_smb2_create_rep_flags_reparse_point = -1;
251 static int hf_smb2_next_offset = -1;
252 static int hf_smb2_negotiate_context_type = -1;
253 static int hf_smb2_negotiate_context_data_length = -1;
254 static int hf_smb2_negotiate_context_offset = -1;
255 static int hf_smb2_negotiate_context_count = -1;
256 static int hf_smb2_hash_alg_count = -1;
257 static int hf_smb2_hash_algorithm = -1;
258 static int hf_smb2_salt_length = -1;
259 static int hf_smb2_salt = -1;
260 static int hf_smb2_cipher_count = -1;
261 static int hf_smb2_cipher_id = -1;
262 static int hf_smb2_signing_alg_count = -1;
263 static int hf_smb2_signing_alg_id = -1;
264 static int hf_smb2_comp_alg_count = -1;
265 static int hf_smb2_comp_alg_id = -1;
266 static int hf_smb2_comp_alg_flags = -1;
267 static int hf_smb2_comp_alg_flags_chained = -1;
268 static int hf_smb2_comp_alg_flags_reserved = -1;
269 static int hf_smb2_netname_neg_id = -1;
270 static int hf_smb2_transport_ctx_flags = -1;
271 static int hf_smb2_rdma_transform_count = -1;
272 static int hf_smb2_rdma_transform_reserved1 = -1;
273 static int hf_smb2_rdma_transform_reserved2 = -1;
274 static int hf_smb2_rdma_transform_id = -1;
275 static int hf_smb2_posix_reserved = -1;
276 static int hf_smb2_inode = -1;
277 static int hf_smb2_ea_size = -1;
278 static int hf_smb2_ea_flags = -1;
279 static int hf_smb2_ea_name_len = -1;
280 static int hf_smb2_ea_data_len = -1;
281 static int hf_smb2_ea_name = -1;
282 static int hf_smb2_ea_data = -1;
283 static int hf_smb2_position_information = -1;
284 static int hf_smb2_mode_information = -1;
285 static int hf_smb2_mode_file_write_through = -1;
286 static int hf_smb2_mode_file_sequential_only = -1;
287 static int hf_smb2_mode_file_no_intermediate_buffering = -1;
288 static int hf_smb2_mode_file_synchronous_io_alert = -1;
289 static int hf_smb2_mode_file_synchronous_io_nonalert = -1;
290 static int hf_smb2_mode_file_delete_on_close = -1;
291 static int hf_smb2_alignment_information = -1;
292 static int hf_smb2_buffer_code = -1;
293 static int hf_smb2_buffer_code_len = -1;
294 static int hf_smb2_buffer_code_flags_dyn = -1;
295 static int hf_smb2_olb_offset = -1;
296 static int hf_smb2_olb_length = -1;
297 static int hf_smb2_tag = -1;
298 static int hf_smb2_impersonation_level = -1;
299 static int hf_smb2_ioctl_function = -1;
300 static int hf_smb2_ioctl_function_device = -1;
301 static int hf_smb2_ioctl_function_access = -1;
302 static int hf_smb2_ioctl_function_function = -1;
303 static int hf_smb2_fsctl_pipe_wait_timeout = -1;
304 static int hf_smb2_fsctl_pipe_wait_name = -1;
305 
306 static int hf_smb2_fsctl_odx_token_type = -1;
307 static int hf_smb2_fsctl_odx_token_idlen = -1;
308 static int hf_smb2_fsctl_odx_token_idraw = -1;
309 static int hf_smb2_fsctl_odx_token_ttl = -1;
310 static int hf_smb2_fsctl_odx_size = -1;
311 static int hf_smb2_fsctl_odx_flags = -1;
312 static int hf_smb2_fsctl_odx_file_offset = -1;
313 static int hf_smb2_fsctl_odx_copy_length = -1;
314 static int hf_smb2_fsctl_odx_xfer_length = -1;
315 static int hf_smb2_fsctl_odx_token_offset = -1;
316 
317 static int hf_smb2_fsctl_sparse_flag = -1;
318 static int hf_smb2_fsctl_range_offset = -1;
319 static int hf_smb2_fsctl_range_length = -1;
320 static int hf_smb2_ioctl_function_method = -1;
321 static int hf_smb2_ioctl_resiliency_timeout = -1;
322 static int hf_smb2_ioctl_resiliency_reserved = -1;
323 static int hf_smb2_ioctl_shared_virtual_disk_support = -1;
324 static int hf_smb2_ioctl_shared_virtual_disk_handle_state = -1;
325 static int hf_smb2_ioctl_sqos_protocol_version = -1;
326 static int hf_smb2_ioctl_sqos_reserved = -1;
327 static int hf_smb2_ioctl_sqos_options = -1;
328 static int hf_smb2_ioctl_sqos_op_set_logical_flow_id = -1;
329 static int hf_smb2_ioctl_sqos_op_set_policy = -1;
330 static int hf_smb2_ioctl_sqos_op_probe_policy = -1;
331 static int hf_smb2_ioctl_sqos_op_get_status = -1;
332 static int hf_smb2_ioctl_sqos_op_update_counters = -1;
333 static int hf_smb2_ioctl_sqos_logical_flow_id = -1;
334 static int hf_smb2_ioctl_sqos_policy_id = -1;
335 static int hf_smb2_ioctl_sqos_initiator_id = -1;
336 static int hf_smb2_ioctl_sqos_limit = -1;
337 static int hf_smb2_ioctl_sqos_reservation = -1;
338 static int hf_smb2_ioctl_sqos_initiator_name = -1;
339 static int hf_smb2_ioctl_sqos_initiator_node_name = -1;
340 static int hf_smb2_ioctl_sqos_io_count_increment = -1;
341 static int hf_smb2_ioctl_sqos_normalized_io_count_increment = -1;
342 static int hf_smb2_ioctl_sqos_latency_increment = -1;
343 static int hf_smb2_ioctl_sqos_lower_latency_increment = -1;
344 static int hf_smb2_ioctl_sqos_bandwidth_limit = -1;
345 static int hf_smb2_ioctl_sqos_kilobyte_count_increment = -1;
346 static int hf_smb2_ioctl_sqos_time_to_live = -1;
347 static int hf_smb2_ioctl_sqos_status = -1;
348 static int hf_smb2_ioctl_sqos_maximum_io_rate = -1;
349 static int hf_smb2_ioctl_sqos_minimum_io_rate = -1;
350 static int hf_smb2_ioctl_sqos_base_io_size = -1;
351 static int hf_smb2_ioctl_sqos_reserved2 = -1;
352 static int hf_smb2_ioctl_sqos_maximum_bandwidth = -1;
353 static int hf_windows_sockaddr_family = -1;
354 static int hf_windows_sockaddr_port = -1;
355 static int hf_windows_sockaddr_in_addr = -1;
356 static int hf_windows_sockaddr_in6_flowinfo = -1;
357 static int hf_windows_sockaddr_in6_addr = -1;
358 static int hf_windows_sockaddr_in6_scope_id = -1;
359 static int hf_smb2_ioctl_network_interface_next_offset = -1;
360 static int hf_smb2_ioctl_network_interface_index = -1;
361 static int hf_smb2_ioctl_network_interface_rss_queue_count = -1;
362 static int hf_smb2_ioctl_network_interface_capabilities = -1;
363 static int hf_smb2_ioctl_network_interface_capability_rss = -1;
364 static int hf_smb2_ioctl_network_interface_capability_rdma = -1;
365 static int hf_smb2_ioctl_network_interface_link_speed = -1;
366 static int hf_smb2_ioctl_enumerate_snapshots_num_snapshots = -1;
367 static int hf_smb2_ioctl_enumerate_snapshots_num_snapshots_returned = -1;
368 static int hf_smb2_ioctl_enumerate_snapshots_snapshot_array_size = -1;
369 static int hf_smb2_ioctl_enumerate_snapshots_snapshot = -1;
370 static int hf_smb2_compression_format = -1;
371 static int hf_smb2_checksum_algorithm = -1;
372 static int hf_smb2_integrity_reserved = -1;
373 static int hf_smb2_integrity_flags = -1;
374 static int hf_smb2_integrity_flags_enforcement_off = -1;
375 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
376 static int hf_smb2_lease_key = -1;
377 static int hf_smb2_lease_state = -1;
378 static int hf_smb2_lease_state_read_caching = -1;
379 static int hf_smb2_lease_state_handle_caching = -1;
380 static int hf_smb2_lease_state_write_caching = -1;
381 static int hf_smb2_lease_flags = -1;
382 static int hf_smb2_lease_flags_break_ack_required = -1;
383 static int hf_smb2_lease_flags_parent_lease_key_set = -1;
384 static int hf_smb2_lease_flags_break_in_progress = -1;
385 static int hf_smb2_lease_duration = -1;
386 static int hf_smb2_parent_lease_key = -1;
387 static int hf_smb2_lease_epoch = -1;
388 static int hf_smb2_lease_reserved = -1;
389 static int hf_smb2_lease_break_reason = -1;
390 static int hf_smb2_lease_access_mask_hint = -1;
391 static int hf_smb2_lease_share_mask_hint = -1;
392 static int hf_smb2_acct_name = -1;
393 static int hf_smb2_domain_name = -1;
394 static int hf_smb2_host_name = -1;
395 static int hf_smb2_auth_frame = -1;
396 static int hf_smb2_tcon_frame = -1;
397 static int hf_smb2_share_type = -1;
398 static int hf_smb2_signature = -1;
399 static int hf_smb2_credit_charge = -1;
400 static int hf_smb2_credits_requested = -1;
401 static int hf_smb2_credits_granted = -1;
402 static int hf_smb2_channel_sequence = -1;
403 static int hf_smb2_dialect_count = -1;
404 static int hf_smb2_security_mode = -1;
405 static int hf_smb2_secmode_flags_sign_required = -1;
406 static int hf_smb2_secmode_flags_sign_enabled = -1;
407 static int hf_smb2_ses_req_flags = -1;
408 static int hf_smb2_ses_req_flags_session_binding = -1;
409 static int hf_smb2_capabilities = -1;
410 static int hf_smb2_cap_dfs = -1;
411 static int hf_smb2_cap_leasing = -1;
412 static int hf_smb2_cap_large_mtu = -1;
413 static int hf_smb2_cap_multi_channel = -1;
414 static int hf_smb2_cap_persistent_handles = -1;
415 static int hf_smb2_cap_directory_leasing = -1;
416 static int hf_smb2_cap_encryption = -1;
417 static int hf_smb2_dialect = -1;
418 static int hf_smb2_max_trans_size = -1;
419 static int hf_smb2_max_read_size = -1;
420 static int hf_smb2_max_write_size = -1;
421 static int hf_smb2_channel = -1;
422 static int hf_smb2_rdma_v1_offset = -1;
423 static int hf_smb2_rdma_v1_token = -1;
424 static int hf_smb2_rdma_v1_length = -1;
425 static int hf_smb2_session_flags = -1;
426 static int hf_smb2_ses_flags_guest = -1;
427 static int hf_smb2_ses_flags_null = -1;
428 static int hf_smb2_ses_flags_encrypt = -1;
429 static int hf_smb2_share_flags = -1;
430 static int hf_smb2_share_flags_dfs = -1;
431 static int hf_smb2_share_flags_dfs_root = -1;
432 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
433 static int hf_smb2_share_flags_force_shared_delete = -1;
434 static int hf_smb2_share_flags_allow_namespace_caching = -1;
435 static int hf_smb2_share_flags_access_based_dir_enum = -1;
436 static int hf_smb2_share_flags_force_levelii_oplock = -1;
437 static int hf_smb2_share_flags_enable_hash_v1 = -1;
438 static int hf_smb2_share_flags_enable_hash_v2 = -1;
439 static int hf_smb2_share_flags_encrypt_data = -1;
440 static int hf_smb2_share_flags_identity_remoting = -1;
441 static int hf_smb2_share_flags_compress_data = -1;
442 static int hf_smb2_share_caching = -1;
443 static int hf_smb2_share_caps = -1;
444 static int hf_smb2_share_caps_dfs = -1;
445 static int hf_smb2_share_caps_continuous_availability = -1;
446 static int hf_smb2_share_caps_scaleout = -1;
447 static int hf_smb2_share_caps_cluster = -1;
448 static int hf_smb2_share_caps_assymetric = -1;
449 static int hf_smb2_share_caps_redirect_to_owner = -1;
450 static int hf_smb2_create_flags = -1;
451 static int hf_smb2_lock_count = -1;
452 static int hf_smb2_min_count = -1;
453 static int hf_smb2_remaining_bytes = -1;
454 static int hf_smb2_channel_info_offset = -1;
455 static int hf_smb2_channel_info_length = -1;
456 static int hf_smb2_channel_info_blob = -1;
457 static int hf_smb2_ioctl_flags = -1;
458 static int hf_smb2_ioctl_is_fsctl = -1;
459 static int hf_smb2_close_pq_attrib = -1;
460 static int hf_smb2_notify_watch_tree = -1;
461 static int hf_smb2_output_buffer_len = -1;
462 static int hf_smb2_notify_out_data = -1;
463 static int hf_smb2_notify_info = -1;
464 static int hf_smb2_notify_next_offset = -1;
465 static int hf_smb2_notify_action = -1;
466 static int hf_smb2_find_flags = -1;
467 static int hf_smb2_find_flags_restart_scans = -1;
468 static int hf_smb2_find_flags_single_entry = -1;
469 static int hf_smb2_find_flags_index_specified = -1;
470 static int hf_smb2_find_flags_reopen = -1;
471 static int hf_smb2_file_index = -1;
472 static int hf_smb2_file_directory_info = -1;
473 static int hf_smb2_both_directory_info = -1;
474 static int hf_smb2_posix_info = -1;
475 static int hf_smb2_short_name_len = -1;
476 static int hf_smb2_short_name = -1;
477 static int hf_smb2_id_both_directory_info = -1;
478 static int hf_smb2_full_directory_info = -1;
479 static int hf_smb2_lock_info = -1;
480 static int hf_smb2_lock_length = -1;
481 static int hf_smb2_lock_flags = -1;
482 static int hf_smb2_lock_flags_shared = -1;
483 static int hf_smb2_lock_flags_exclusive = -1;
484 static int hf_smb2_lock_flags_unlock = -1;
485 static int hf_smb2_lock_flags_fail_immediately = -1;
486 static int hf_smb2_dhnq_buffer_reserved = -1;
487 static int hf_smb2_dh2x_buffer_timeout = -1;
488 static int hf_smb2_dh2x_buffer_flags = -1;
489 static int hf_smb2_dh2x_buffer_flags_persistent_handle = -1;
490 static int hf_smb2_dh2x_buffer_reserved = -1;
491 static int hf_smb2_dh2x_buffer_create_guid = -1;
492 static int hf_smb2_APP_INSTANCE_buffer_struct_size = -1;
493 static int hf_smb2_APP_INSTANCE_buffer_reserved = -1;
494 static int hf_smb2_APP_INSTANCE_buffer_app_guid = -1;
495 static int hf_smb2_svhdx_open_device_context_version = -1;
496 static int hf_smb2_svhdx_open_device_context_has_initiator_id = -1;
497 static int hf_smb2_svhdx_open_device_context_reserved = -1;
498 static int hf_smb2_svhdx_open_device_context_initiator_id = -1;
499 static int hf_smb2_svhdx_open_device_context_flags = -1;
500 static int hf_smb2_svhdx_open_device_context_originator_flags = -1;
501 static int hf_smb2_svhdx_open_device_context_open_request_id = -1;
502 static int hf_smb2_svhdx_open_device_context_initiator_host_name_len = -1;
503 static int hf_smb2_svhdx_open_device_context_initiator_host_name = -1;
504 static int hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized = -1;
505 static int hf_smb2_svhdx_open_device_context_server_service_version = -1;
506 static int hf_smb2_svhdx_open_device_context_virtual_sector_size = -1;
507 static int hf_smb2_svhdx_open_device_context_physical_sector_size = -1;
508 static int hf_smb2_svhdx_open_device_context_virtual_size = -1;
509 static int hf_smb2_app_instance_version_struct_size = -1;
510 static int hf_smb2_app_instance_version_reserved = -1;
511 static int hf_smb2_app_instance_version_padding = -1;
512 static int hf_smb2_app_instance_version_high = -1;
513 static int hf_smb2_app_instance_version_low = -1;
514 static int hf_smb2_posix_perms = -1;
515 static int hf_smb2_aapl_command_code = -1;
516 static int hf_smb2_aapl_reserved = -1;
517 static int hf_smb2_aapl_server_query_bitmask = -1;
518 static int hf_smb2_aapl_server_query_bitmask_server_caps = -1;
519 static int hf_smb2_aapl_server_query_bitmask_volume_caps = -1;
520 static int hf_smb2_aapl_server_query_bitmask_model_info = -1;
521 static int hf_smb2_aapl_server_query_caps = -1;
522 static int hf_smb2_aapl_server_query_caps_supports_read_dir_attr = -1;
523 static int hf_smb2_aapl_server_query_caps_supports_osx_copyfile = -1;
524 static int hf_smb2_aapl_server_query_caps_unix_based = -1;
525 static int hf_smb2_aapl_server_query_caps_supports_nfs_ace = -1;
526 static int hf_smb2_aapl_server_query_volume_caps = -1;
527 static int hf_smb2_aapl_server_query_volume_caps_support_resolve_id = -1;
528 static int hf_smb2_aapl_server_query_volume_caps_case_sensitive = -1;
529 static int hf_smb2_aapl_server_query_volume_caps_supports_full_sync = -1;
530 static int hf_smb2_aapl_server_query_model_string = -1;
531 static int hf_smb2_aapl_server_query_server_path = -1;
532 static int hf_smb2_error_context_count = -1;
533 static int hf_smb2_error_reserved = -1;
534 static int hf_smb2_error_byte_count = -1;
535 static int hf_smb2_error_data = -1;
536 static int hf_smb2_error_context = -1;
537 static int hf_smb2_error_context_length = -1;
538 static int hf_smb2_error_context_id = -1;
539 static int hf_smb2_error_min_buf_length = -1;
540 static int hf_smb2_error_redir_context = -1;
541 static int hf_smb2_error_redir_struct_size = -1;
542 static int hf_smb2_error_redir_notif_type = -1;
543 static int hf_smb2_error_redir_flags = -1;
544 static int hf_smb2_error_redir_target_type = -1;
545 static int hf_smb2_error_redir_ip_count = -1;
546 static int hf_smb2_error_redir_ip_list = -1;
547 static int hf_smb2_error_redir_res_name = -1;
548 static int hf_smb2_reserved = -1;
549 static int hf_smb2_reserved_random = -1;
550 static int hf_smb2_transform_signature = -1;
551 static int hf_smb2_transform_nonce = -1;
552 static int hf_smb2_transform_msg_size = -1;
553 static int hf_smb2_transform_reserved = -1;
554 static int hf_smb2_transform_flags = -1;
555 static int hf_smb2_transform_flags_encrypted = -1;
556 static int hf_smb2_transform_encrypted_data = -1;
557 static int hf_smb2_protocol_id = -1;
558 static int hf_smb2_comp_transform_orig_size = -1;
559 static int hf_smb2_comp_transform_comp_alg = -1;
560 static int hf_smb2_comp_transform_flags = -1;
561 static int hf_smb2_comp_transform_offset = -1;
562 static int hf_smb2_comp_transform_length = -1;
563 static int hf_smb2_comp_transform_data = -1;
564 static int hf_smb2_comp_transform_orig_payload_size = -1;
565 static int hf_smb2_comp_pattern_v1_pattern = -1;
566 static int hf_smb2_comp_pattern_v1_reserved1 = -1;
567 static int hf_smb2_comp_pattern_v1_reserved2 = -1;
568 static int hf_smb2_comp_pattern_v1_repetitions = -1;
569 static int hf_smb2_truncated = -1;
570 static int hf_smb2_pipe_fragments = -1;
571 static int hf_smb2_pipe_fragment = -1;
572 static int hf_smb2_pipe_fragment_overlap = -1;
573 static int hf_smb2_pipe_fragment_overlap_conflict = -1;
574 static int hf_smb2_pipe_fragment_multiple_tails = -1;
575 static int hf_smb2_pipe_fragment_too_long_fragment = -1;
576 static int hf_smb2_pipe_fragment_error = -1;
577 static int hf_smb2_pipe_fragment_count = -1;
578 static int hf_smb2_pipe_reassembled_in = -1;
579 static int hf_smb2_pipe_reassembled_length = -1;
580 static int hf_smb2_pipe_reassembled_data = -1;
581 static int hf_smb2_cchunk_resume_key = -1;
582 static int hf_smb2_cchunk_count = -1;
583 static int hf_smb2_cchunk_src_offset = -1;
584 static int hf_smb2_cchunk_dst_offset = -1;
585 static int hf_smb2_cchunk_xfer_len = -1;
586 static int hf_smb2_cchunk_chunks_written = -1;
587 static int hf_smb2_cchunk_bytes_written = -1;
588 static int hf_smb2_cchunk_total_written = -1;
589 static int hf_smb2_reparse_data_buffer = -1;
590 static int hf_smb2_reparse_tag = -1;
591 static int hf_smb2_reparse_guid = -1;
592 static int hf_smb2_reparse_data_length = -1;
593 static int hf_smb2_nfs_type = -1;
594 static int hf_smb2_nfs_symlink_target = -1;
595 static int hf_smb2_nfs_chr_major = -1;
596 static int hf_smb2_nfs_chr_minor = -1;
597 static int hf_smb2_nfs_blk_major = -1;
598 static int hf_smb2_nfs_blk_minor = -1;
599 static int hf_smb2_symlink_error_response = -1;
600 static int hf_smb2_symlink_length = -1;
601 static int hf_smb2_symlink_error_tag = -1;
602 static int hf_smb2_unparsed_path_length = -1;
603 static int hf_smb2_symlink_substitute_name = -1;
604 static int hf_smb2_symlink_print_name = -1;
605 static int hf_smb2_symlink_flags = -1;
606 static int hf_smb2_bad_signature = -1;
607 static int hf_smb2_good_signature = -1;
608 static int hf_smb2_fscc_file_attr = -1;
609 static int hf_smb2_fscc_file_attr_archive = -1;
610 static int hf_smb2_fscc_file_attr_compressed = -1;
611 static int hf_smb2_fscc_file_attr_directory = -1;
612 static int hf_smb2_fscc_file_attr_encrypted = -1;
613 static int hf_smb2_fscc_file_attr_hidden = -1;
614 static int hf_smb2_fscc_file_attr_normal = -1;
615 static int hf_smb2_fscc_file_attr_not_content_indexed = -1;
616 static int hf_smb2_fscc_file_attr_offline = -1;
617 static int hf_smb2_fscc_file_attr_read_only = -1;
618 static int hf_smb2_fscc_file_attr_reparse_point = -1;
619 static int hf_smb2_fscc_file_attr_sparse_file = -1;
620 static int hf_smb2_fscc_file_attr_system = -1;
621 static int hf_smb2_fscc_file_attr_temporary = -1;
622 static int hf_smb2_fscc_file_attr_integrity_stream = -1;
623 static int hf_smb2_fscc_file_attr_no_scrub_data = -1;
624 static int hf_smb2_tree_connect_flags = -1;
625 static int hf_smb2_tc_cluster_reconnect = -1;
626 static int hf_smb2_tc_redirect_to_owner = -1;
627 static int hf_smb2_tc_extension_present = -1;
628 static int hf_smb2_tc_reserved = -1;
629 
630 static gint ett_smb2 = -1;
631 static gint ett_smb2_olb = -1;
632 static gint ett_smb2_ea = -1;
633 static gint ett_smb2_header = -1;
634 static gint ett_smb2_encrypted = -1;
635 static gint ett_smb2_compressed = -1;
636 static gint ett_smb2_decompressed = -1;
637 static gint ett_smb2_command = -1;
638 static gint ett_smb2_secblob = -1;
639 static gint ett_smb2_negotiate_context_element = -1;
640 static gint ett_smb2_file_basic_info = -1;
641 static gint ett_smb2_file_standard_info = -1;
642 static gint ett_smb2_file_internal_info = -1;
643 static gint ett_smb2_file_ea_info = -1;
644 static gint ett_smb2_file_access_info = -1;
645 static gint ett_smb2_file_position_info = -1;
646 static gint ett_smb2_file_mode_info = -1;
647 static gint ett_smb2_file_alignment_info = -1;
648 static gint ett_smb2_file_all_info = -1;
649 static gint ett_smb2_file_allocation_info = -1;
650 static gint ett_smb2_file_endoffile_info = -1;
651 static gint ett_smb2_file_alternate_name_info = -1;
652 static gint ett_smb2_file_stream_info = -1;
653 static gint ett_smb2_file_pipe_info = -1;
654 static gint ett_smb2_file_compression_info = -1;
655 static gint ett_smb2_file_network_open_info = -1;
656 static gint ett_smb2_file_attribute_tag_info = -1;
657 static gint ett_smb2_file_rename_info = -1;
658 static gint ett_smb2_file_disposition_info = -1;
659 static gint ett_smb2_file_full_ea_info = -1;
660 static gint ett_smb2_file_normalized_name_info = -1;
661 static gint ett_smb2_fs_info_01 = -1;
662 static gint ett_smb2_fs_info_03 = -1;
663 static gint ett_smb2_fs_info_04 = -1;
664 static gint ett_smb2_fs_info_05 = -1;
665 static gint ett_smb2_fs_info_06 = -1;
666 static gint ett_smb2_fs_info_07 = -1;
667 static gint ett_smb2_fs_objectid_info = -1;
668 static gint ett_smb2_sec_info_00 = -1;
669 static gint ett_smb2_additional_information_sec_mask = -1;
670 static gint ett_smb2_quota_info = -1;
671 static gint ett_smb2_query_quota_info = -1;
672 static gint ett_smb2_tid_tree = -1;
673 static gint ett_smb2_sesid_tree = -1;
674 static gint ett_smb2_create_chain_element = -1;
675 static gint ett_smb2_MxAc_buffer = -1;
676 static gint ett_smb2_QFid_buffer = -1;
677 static gint ett_smb2_RqLs_buffer = -1;
678 static gint ett_smb2_ioctl_function = -1;
679 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
680 static gint ett_smb2_flags = -1;
681 static gint ett_smb2_sec_mode = -1;
682 static gint ett_smb2_capabilities = -1;
683 static gint ett_smb2_ses_req_flags = -1;
684 static gint ett_smb2_ses_flags = -1;
685 static gint ett_smb2_lease_state = -1;
686 static gint ett_smb2_lease_flags = -1;
687 static gint ett_smb2_share_flags = -1;
688 static gint ett_smb2_create_rep_flags = -1;
689 static gint ett_smb2_share_caps = -1;
690 static gint ett_smb2_comp_alg_flags = -1;
691 static gint ett_smb2_ioctl_flags = -1;
692 static gint ett_smb2_ioctl_network_interface = -1;
693 static gint ett_smb2_ioctl_sqos_opeations = -1;
694 static gint ett_smb2_fsctl_range_data = -1;
695 static gint ett_windows_sockaddr = -1;
696 static gint ett_smb2_close_flags = -1;
697 static gint ett_smb2_notify_info = -1;
698 static gint ett_smb2_notify_flags = -1;
699 static gint ett_smb2_write_flags = -1;
700 static gint ett_smb2_rdma_v1 = -1;
701 static gint ett_smb2_DH2Q_buffer = -1;
702 static gint ett_smb2_DH2C_buffer = -1;
703 static gint ett_smb2_dh2x_flags = -1;
704 static gint ett_smb2_APP_INSTANCE_buffer = -1;
705 static gint ett_smb2_svhdx_open_device_context = -1;
706 static gint ett_smb2_app_instance_version_buffer = -1;
707 static gint ett_smb2_app_instance_version_buffer_version = -1;
708 static gint ett_smb2_aapl_create_context_request = -1;
709 static gint ett_smb2_aapl_server_query_bitmask = -1;
710 static gint ett_smb2_aapl_server_query_caps = -1;
711 static gint ett_smb2_aapl_create_context_response = -1;
712 static gint ett_smb2_aapl_server_query_volume_caps = -1;
713 static gint ett_smb2_integrity_flags = -1;
714 static gint ett_smb2_find_flags = -1;
715 static gint ett_smb2_file_directory_info = -1;
716 static gint ett_smb2_both_directory_info = -1;
717 static gint ett_smb2_id_both_directory_info = -1;
718 static gint ett_smb2_full_directory_info = -1;
719 static gint ett_smb2_posix_info = -1;
720 static gint ett_smb2_file_name_info = -1;
721 static gint ett_smb2_lock_info = -1;
722 static gint ett_smb2_lock_flags = -1;
723 static gint ett_smb2_buffercode = -1;
724 static gint ett_smb2_ioctl_network_interface_capabilities = -1;
725 static gint ett_smb2_tree_connect_flags = -1;
726 static gint ett_qfr_entry = -1;
727 static gint ett_smb2_pipe_fragment = -1;
728 static gint ett_smb2_pipe_fragments = -1;
729 static gint ett_smb2_cchunk_entry = -1;
730 static gint ett_smb2_fsctl_odx_token = -1;
731 static gint ett_smb2_symlink_error_response = -1;
732 static gint ett_smb2_reparse_data_buffer = -1;
733 static gint ett_smb2_error_data = -1;
734 static gint ett_smb2_error_context = -1;
735 static gint ett_smb2_error_redir_context = -1;
736 static gint ett_smb2_error_redir_ip_list = -1;
737 static gint ett_smb2_read_flags = -1;
738 static gint ett_smb2_signature = -1;
739 static gint ett_smb2_transform_flags = -1;
740 static gint ett_smb2_fscc_file_attributes = -1;
741 static gint ett_smb2_comp_payload = -1;
742 static gint ett_smb2_comp_pattern_v1 = -1;
743 
744 static expert_field ei_smb2_invalid_length = EI_INIT;
745 static expert_field ei_smb2_bad_response = EI_INIT;
746 static expert_field ei_smb2_invalid_getinfo_offset = EI_INIT;
747 static expert_field ei_smb2_invalid_getinfo_size = EI_INIT;
748 static expert_field ei_smb2_empty_getinfo_buffer = EI_INIT;
749 static expert_field ei_smb2_invalid_signature = EI_INIT;
750 
751 static int smb2_tap = -1;
752 static int smb2_eo_tap = -1;
753 
754 static dissector_handle_t gssapi_handle  = NULL;
755 static dissector_handle_t ntlmssp_handle = NULL;
756 static dissector_handle_t rsvd_handle = NULL;
757 
758 static heur_dissector_list_t smb2_pipe_subdissector_list;
759 
760 static const fragment_items smb2_pipe_frag_items = {
761 	&ett_smb2_pipe_fragment,
762 	&ett_smb2_pipe_fragments,
763 	&hf_smb2_pipe_fragments,
764 	&hf_smb2_pipe_fragment,
765 	&hf_smb2_pipe_fragment_overlap,
766 	&hf_smb2_pipe_fragment_overlap_conflict,
767 	&hf_smb2_pipe_fragment_multiple_tails,
768 	&hf_smb2_pipe_fragment_too_long_fragment,
769 	&hf_smb2_pipe_fragment_error,
770 	&hf_smb2_pipe_fragment_count,
771 	&hf_smb2_pipe_reassembled_in,
772 	&hf_smb2_pipe_reassembled_length,
773 	&hf_smb2_pipe_reassembled_data,
774 	"Fragments"
775 };
776 
777 #define FILE_BYTE_ALIGNMENT 0x00
778 #define FILE_WORD_ALIGNMENT 0x01
779 #define FILE_LONG_ALIGNMENT 0x03
780 #define FILE_QUAD_ALIGNMENT 0x07
781 #define FILE_OCTA_ALIGNMENT 0x0f
782 #define FILE_32_BYTE_ALIGNMENT 0x1f
783 #define FILE_64_BYTE_ALIGNMENT 0x3f
784 #define FILE_128_BYTE_ALIGNMENT 0x7f
785 #define FILE_256_BYTE_ALIGNMENT 0xff
786 #define FILE_512_BYTE_ALIGNMENT 0x1ff
787 static const value_string smb2_alignment_vals[] = {
788 	{ FILE_BYTE_ALIGNMENT,     "FILE_BYTE_ALIGNMENT" },
789 	{ FILE_WORD_ALIGNMENT,     "FILE_WORD_ALIGNMENT" },
790 	{ FILE_LONG_ALIGNMENT,     "FILE_LONG_ALIGNMENT" },
791 	{ FILE_OCTA_ALIGNMENT,     "FILE_OCTA_ALIGNMENT" },
792 	{ FILE_32_BYTE_ALIGNMENT,  "FILE_32_BYTE_ALIGNMENT" },
793 	{ FILE_64_BYTE_ALIGNMENT,  "FILE_64_BYTE_ALIGNMENT" },
794 	{ FILE_128_BYTE_ALIGNMENT, "FILE_128_BYTE_ALIGNMENT" },
795 	{ FILE_256_BYTE_ALIGNMENT, "FILE_256_BYTE_ALIGNMENT" },
796 	{ FILE_512_BYTE_ALIGNMENT, "FILE_512_BYTE_ALIGNMENT" },
797 	{ 0, NULL }
798 };
799 
800 
801 #define SMB2_CLASS_FILE_INFO	0x01
802 #define SMB2_CLASS_FS_INFO	0x02
803 #define SMB2_CLASS_SEC_INFO	0x03
804 #define SMB2_CLASS_QUOTA_INFO	0x04
805 static const value_string smb2_class_vals[] = {
806 	{ SMB2_CLASS_FILE_INFO,	"FILE_INFO"},
807 	{ SMB2_CLASS_FS_INFO,	"FS_INFO"},
808 	{ SMB2_CLASS_SEC_INFO,	"SEC_INFO"},
809 	{ SMB2_CLASS_QUOTA_INFO, "QUOTA_INFO"},
810 	{ 0, NULL }
811 };
812 
813 #define SMB2_SHARE_TYPE_DISK	0x01
814 #define SMB2_SHARE_TYPE_PIPE	0x02
815 #define SMB2_SHARE_TYPE_PRINT	0x03
816 static const value_string smb2_share_type_vals[] = {
817 	{ SMB2_SHARE_TYPE_DISK,		"Physical disk" },
818 	{ SMB2_SHARE_TYPE_PIPE,		"Named pipe" },
819 	{ SMB2_SHARE_TYPE_PRINT,	"Printer" },
820 	{ 0, NULL }
821 };
822 
823 
824 #define SMB2_FILE_BASIC_INFO          0x04
825 #define SMB2_FILE_STANDARD_INFO       0x05
826 #define SMB2_FILE_INTERNAL_INFO       0x06
827 #define SMB2_FILE_EA_INFO             0x07
828 #define SMB2_FILE_ACCESS_INFO         0x08
829 #define SMB2_FILE_RENAME_INFO         0x0a
830 #define SMB2_FILE_DISPOSITION_INFO    0x0d
831 #define SMB2_FILE_POSITION_INFO       0x0e
832 #define SMB2_FILE_FULL_EA_INFO        0x0f
833 #define SMB2_FILE_MODE_INFO           0x10
834 #define SMB2_FILE_ALIGNMENT_INFO      0x11
835 #define SMB2_FILE_ALL_INFO            0x12
836 #define SMB2_FILE_ALLOCATION_INFO     0x13
837 #define SMB2_FILE_ENDOFFILE_INFO      0x14
838 #define SMB2_FILE_ALTERNATE_NAME_INFO 0x15
839 #define SMB2_FILE_STREAM_INFO	      0x16
840 #define SMB2_FILE_PIPE_INFO	      0x17
841 #define SMB2_FILE_COMPRESSION_INFO    0x1c
842 #define SMB2_FILE_NETWORK_OPEN_INFO   0x22
843 #define SMB2_FILE_ATTRIBUTE_TAG_INFO  0x23
844 #define SMB2_FILE_NORMALIZED_NAME_INFO 0x30
845 #define SMB2_FILE_POSIX_INFO          0x64
846 
847 static const value_string smb2_file_info_levels[] = {
848 	{SMB2_FILE_BASIC_INFO,		"SMB2_FILE_BASIC_INFO" },
849 	{SMB2_FILE_STANDARD_INFO,	"SMB2_FILE_STANDARD_INFO" },
850 	{SMB2_FILE_INTERNAL_INFO,	"SMB2_FILE_INTERNAL_INFO" },
851 	{SMB2_FILE_EA_INFO,		"SMB2_FILE_EA_INFO" },
852 	{SMB2_FILE_ACCESS_INFO,		"SMB2_FILE_ACCESS_INFO" },
853 	{SMB2_FILE_RENAME_INFO,		"SMB2_FILE_RENAME_INFO" },
854 	{SMB2_FILE_DISPOSITION_INFO,	"SMB2_FILE_DISPOSITION_INFO" },
855 	{SMB2_FILE_POSITION_INFO,	"SMB2_FILE_POSITION_INFO" },
856 	{SMB2_FILE_FULL_EA_INFO,	"SMB2_FILE_FULL_EA_INFO" },
857 	{SMB2_FILE_MODE_INFO,		"SMB2_FILE_MODE_INFO" },
858 	{SMB2_FILE_ALIGNMENT_INFO,	"SMB2_FILE_ALIGNMENT_INFO" },
859 	{SMB2_FILE_ALL_INFO,		"SMB2_FILE_ALL_INFO" },
860 	{SMB2_FILE_ALLOCATION_INFO,	"SMB2_FILE_ALLOCATION_INFO" },
861 	{SMB2_FILE_ENDOFFILE_INFO,	"SMB2_FILE_ENDOFFILE_INFO" },
862 	{SMB2_FILE_ALTERNATE_NAME_INFO,	"SMB2_FILE_ALTERNATE_NAME_INFO" },
863 	{SMB2_FILE_STREAM_INFO,		"SMB2_FILE_STREAM_INFO" },
864 	{SMB2_FILE_PIPE_INFO,		"SMB2_FILE_PIPE_INFO" },
865 	{SMB2_FILE_COMPRESSION_INFO,	"SMB2_FILE_COMPRESSION_INFO" },
866 	{SMB2_FILE_NETWORK_OPEN_INFO,	"SMB2_FILE_NETWORK_OPEN_INFO" },
867 	{SMB2_FILE_ATTRIBUTE_TAG_INFO,	"SMB2_FILE_ATTRIBUTE_TAG_INFO" },
868 	{SMB2_FILE_NORMALIZED_NAME_INFO,"SMB2_FILE_NORMALIZED_NAME_INFO" },
869 	{SMB2_FILE_POSIX_INFO,		"SMB2_FILE_POSIX_INFO" },
870 	{ 0, NULL }
871 };
872 static value_string_ext smb2_file_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_file_info_levels);
873 
874 
875 
876 #define SMB2_FS_INFO_01			0x01
877 #define SMB2_FS_LABEL_INFO		0x02
878 #define SMB2_FS_INFO_03			0x03
879 #define SMB2_FS_INFO_04			0x04
880 #define SMB2_FS_INFO_05			0x05
881 #define SMB2_FS_INFO_06			0x06
882 #define SMB2_FS_INFO_07			0x07
883 #define SMB2_FS_OBJECTID_INFO		0x08
884 #define SMB2_FS_DRIVER_PATH_INFO	0x09
885 #define SMB2_FS_VOLUME_FLAGS_INFO	0x0a
886 #define SMB2_FS_SECTOR_SIZE_INFO	0x0b
887 
888 static const value_string smb2_fs_info_levels[] = {
889 	{SMB2_FS_INFO_01,		"FileFsVolumeInformation" },
890 	{SMB2_FS_LABEL_INFO,		"FileFsLabelInformation" },
891 	{SMB2_FS_INFO_03,		"FileFsSizeInformation" },
892 	{SMB2_FS_INFO_04,		"FileFsDeviceInformation" },
893 	{SMB2_FS_INFO_05,		"FileFsAttributeInformation" },
894 	{SMB2_FS_INFO_06,		"FileFsControlInformation" },
895 	{SMB2_FS_INFO_07,		"FileFsFullSizeInformation" },
896 	{SMB2_FS_OBJECTID_INFO,		"FileFsObjectIdInformation" },
897 	{SMB2_FS_DRIVER_PATH_INFO,	"FileFsDriverPathInformation" },
898 	{SMB2_FS_VOLUME_FLAGS_INFO,	"FileFsVolumeFlagsInformation" },
899 	{SMB2_FS_SECTOR_SIZE_INFO,	"FileFsSectorSizeInformation" },
900 	{ 0, NULL }
901 };
902 static value_string_ext smb2_fs_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_fs_info_levels);
903 
904 #define SMB2_SEC_INFO_00	0x00
905 static const value_string smb2_sec_info_levels[] = {
906 	{SMB2_SEC_INFO_00,	"SMB2_SEC_INFO_00" },
907 	{ 0, NULL }
908 };
909 static value_string_ext smb2_sec_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_sec_info_levels);
910 
911 #define SMB2_FIND_DIRECTORY_INFO         0x01
912 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
913 #define SMB2_FIND_BOTH_DIRECTORY_INFO    0x03
914 #define SMB2_FIND_INDEX_SPECIFIED        0x04
915 #define SMB2_FIND_NAME_INFO              0x0C
916 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
917 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
918 #define SMB2_FIND_POSIX_INFO             0x64
919 static const value_string smb2_find_info_levels[] = {
920 	{ SMB2_FIND_DIRECTORY_INFO,		"SMB2_FIND_DIRECTORY_INFO" },
921 	{ SMB2_FIND_FULL_DIRECTORY_INFO,	"SMB2_FIND_FULL_DIRECTORY_INFO" },
922 	{ SMB2_FIND_BOTH_DIRECTORY_INFO,	"SMB2_FIND_BOTH_DIRECTORY_INFO" },
923 	{ SMB2_FIND_INDEX_SPECIFIED,		"SMB2_FIND_INDEX_SPECIFIED" },
924 	{ SMB2_FIND_NAME_INFO,			"SMB2_FIND_NAME_INFO" },
925 	{ SMB2_FIND_ID_BOTH_DIRECTORY_INFO,	"SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
926 	{ SMB2_FIND_ID_FULL_DIRECTORY_INFO,	"SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
927 	{ SMB2_FIND_POSIX_INFO,			"SMB2_FIND_POSIX_INFO" },
928 	{ 0, NULL }
929 };
930 
931 #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001
932 #define SMB2_ENCRYPTION_CAPABILITIES        0x0002
933 #define SMB2_COMPRESSION_CAPABILITIES       0x0003
934 #define SMB2_NETNAME_NEGOTIATE_CONTEXT_ID   0x0005
935 #define SMB2_TRANSPORT_CAPABILITIES         0x0006
936 #define SMB2_RDMA_TRANSFORM_CAPABILITIES    0x0007
937 #define SMB2_SIGNING_CAPABILITIES           0x0008
938 #define SMB2_POSIX_EXTENSIONS_CAPABILITIES  0x0100
939 static const value_string smb2_negotiate_context_types[] = {
940 	{ SMB2_PREAUTH_INTEGRITY_CAPABILITIES,  "SMB2_PREAUTH_INTEGRITY_CAPABILITIES" },
941 	{ SMB2_ENCRYPTION_CAPABILITIES,	"SMB2_ENCRYPTION_CAPABILITIES" },
942 	{ SMB2_COMPRESSION_CAPABILITIES, "SMB2_COMPRESSION_CAPABILITIES" },
943 	{ SMB2_NETNAME_NEGOTIATE_CONTEXT_ID, "SMB2_NETNAME_NEGOTIATE_CONTEXT_ID" },
944 	{ SMB2_TRANSPORT_CAPABILITIES, "SMB2_TRANSPORT_CAPABILITIES" },
945 	{ SMB2_RDMA_TRANSFORM_CAPABILITIES, "SMB2_RDMA_TRANSFORM_CAPABILITIES" },
946 	{ SMB2_SIGNING_CAPABILITIES, "SMB2_SIGNING_CAPABILITIES" },
947 	{ SMB2_POSIX_EXTENSIONS_CAPABILITIES, "SMB2_POSIX_EXTENSIONS_CAPABILITIES" },
948 	{ 0, NULL }
949 };
950 
951 #define SMB2_HASH_ALGORITHM_SHA_512    0x0001
952 static const value_string smb2_hash_algorithm_types[] = {
953 	{ SMB2_HASH_ALGORITHM_SHA_512, "SHA-512" },
954 	{ 0, NULL }
955 };
956 
957 #define SMB2_SIGNING_ALG_HMAC_SHA256 0x0000
958 #define SMB2_SIGNING_ALG_AES_CMAC    0x0001
959 #define SMB2_SIGNING_ALG_AES_GMAC    0x0002
960 static const value_string smb2_signing_alg_types[] = {
961 	{ SMB2_SIGNING_ALG_HMAC_SHA256, "HMAC-SHA256" },
962 	{ SMB2_SIGNING_ALG_AES_CMAC,    "AES-CMAC" },
963 	{ SMB2_SIGNING_ALG_AES_GMAC,    "AES-GMAC" },
964 	{ 0, NULL },
965 };
966 
967 #define SMB2_CIPHER_AES_128_CCM        0x0001
968 #define SMB2_CIPHER_AES_128_GCM        0x0002
969 #define SMB2_CIPHER_AES_256_CCM        0x0003
970 #define SMB2_CIPHER_AES_256_GCM        0x0004
971 static const value_string smb2_cipher_types[] = {
972 	{ SMB2_CIPHER_AES_128_CCM, "AES-128-CCM" },
973 	{ SMB2_CIPHER_AES_128_GCM, "AES-128-GCM" },
974 	{ SMB2_CIPHER_AES_256_CCM, "AES-256-CCM" },
975 	{ SMB2_CIPHER_AES_256_GCM, "AES-256-GCM" },
976 	{ 0, NULL }
977 };
978 
979 #define SMB2_TRANSFORM_FLAGS_ENCRYPTED        0x0001
980 static int * const smb2_transform_flags[] = {
981 	&hf_smb2_transform_flags_encrypted,
982 	NULL,
983 };
984 
985 #define SMB2_COMP_ALG_FLAGS_CHAINED  0x00000001
986 
987 #define SMB2_COMP_ALG_NONE        0x0000
988 #define SMB2_COMP_ALG_LZNT1       0x0001
989 #define SMB2_COMP_ALG_LZ77        0x0002
990 #define SMB2_COMP_ALG_LZ77HUFF    0x0003
991 #define SMB2_COMP_ALG_PATTERN_V1  0x0004
992 static const value_string smb2_comp_alg_types[] = {
993 	{ SMB2_COMP_ALG_NONE, "None" },
994 	{ SMB2_COMP_ALG_LZNT1, "LZNT1" },
995 	{ SMB2_COMP_ALG_LZ77, "LZ77" },
996 	{ SMB2_COMP_ALG_LZ77HUFF, "LZ77+Huffman" },
997 	{ SMB2_COMP_ALG_PATTERN_V1, "Pattern_V1" },
998 	{ 0, NULL }
999 };
1000 
1001 #define SMB2_COMP_FLAG_NONE    0x0000
1002 #define SMB2_COMP_FLAG_CHAINED 0x0001
1003 static const value_string smb2_comp_transform_flags_vals[] = {
1004 	{ SMB2_COMP_FLAG_NONE, "None" },
1005 	{ SMB2_COMP_FLAG_CHAINED, "Chained" },
1006 	{ 0, NULL }
1007 };
1008 
1009 #define SMB2_RDMA_TRANSFORM_NONE       0x0000
1010 #define SMB2_RDMA_TRANSFORM_ENCRYPTION 0x0001
1011 #define SMB2_RDMA_TRANSFORM_SIGNING    0x0002
1012 static const value_string smb2_rdma_transform_types[] = {
1013 	{ SMB2_RDMA_TRANSFORM_NONE, "None" },
1014 	{ SMB2_RDMA_TRANSFORM_ENCRYPTION, "Encryption" },
1015 	{ SMB2_RDMA_TRANSFORM_SIGNING, "Signing" },
1016 	{ 0, NULL }
1017 };
1018 
1019 #define OPLOCK_BREAK_OPLOCK_STRUCTURE_SIZE 24               /* [MS-SMB2] 2.2.23.1, 2.2.24.1 and 2.2.25.1 */
1020 #define OPLOCK_BREAK_LEASE_NOTIFICATION_STRUCTURE_SIZE 44   /* [MS-SMB2] 2.2.23.2 Lease Break Notification */
1021 #define OPLOCK_BREAK_LEASE_ACKNOWLEDGMENT_STRUCTURE_SIZE 36 /* [MS-SMB2] 2.2.24.2 Lease Break Acknowledgment */
1022 #define OPLOCK_BREAK_LEASE_RESPONSE_STRUCTURE_SIZE 36       /* [MS-SMB2] 2.2.25.2 Lease Break Response */
1023 
1024 static const val64_string unique_unsolicited_response[] = {
1025 	{ 0xffffffffffffffff, "unsolicited response" },
1026 	{ 0, NULL }
1027 };
1028 
1029 #define SMB2_ERROR_ID_DEFAULT 0x00000000
1030 #define SMB2_ERROR_ID_SHARE_REDIRECT 0x72645253
1031 static const value_string smb2_error_id_vals[] = {
1032 	{ SMB2_ERROR_ID_DEFAULT, "ERROR_ID_DEFAULT" },
1033 	{ SMB2_ERROR_ID_SHARE_REDIRECT, "ERROR_ID_SHARE_REDIRECT" },
1034 	{ 0, NULL }
1035 };
1036 
1037 #define SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY 0x00000001
1038 static const value_string smb2_transport_ctx_flags_vals[] = {
1039 	{ SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY, "SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY" },
1040 	{ 0, NULL }
1041 };
1042 
1043 #define REPARSE_TAG_RESERVED_ZERO      0x00000000 /* Reserved reparse tag value. */
1044 #define REPARSE_TAG_RESERVED_ONE       0x00000001 /* Reserved reparse tag value. */
1045 #define REPARSE_TAG_MOUNT_POINT        0xA0000003 /* Used for mount point */
1046 #define REPARSE_TAG_HSM                0xC0000004 /* Obsolete. Used by legacy Hierarchical Storage Manager Product. */
1047 #define REPARSE_TAG_DRIVER_EXTENDER    0x80000005 /* Home server drive extender. */
1048 #define REPARSE_TAG_HSM2               0x80000006 /* Obsolete. Used by legacy Hierarchical Storage Manager Product. */
1049 #define REPARSE_TAG_SIS                0x80000007 /* Used by single-instance storage (SIS) filter driver. */
1050 #define REPARSE_TAG_DFS                0x8000000A /* Used by the DFS filter. */
1051 #define REPARSE_TAG_FILTER_MANAGER     0x8000000B /* Used by filter manager test harness */
1052 #define REPARSE_TAG_SYMLINK            0xA000000C /* Used for symbolic link support. */
1053 #define REPARSE_TAG_DFSR               0x80000012 /* Used by the DFS filter. */
1054 #define REPARSE_TAG_NFS                0x80000014 /* Used by the Network File System (NFS) component. */
1055 #define REPARSE_TAG_LX_SYMLINK         0xA000001D /* WSL symbolic link */
1056 #define REPARSE_TAG_AF_UNIX            0x80000023 /* WSL unix socket */
1057 #define REPARSE_TAG_LX_FIFO            0x80000024 /* WSL fifo pipe */
1058 #define REPARSE_TAG_LX_CHR             0x80000025 /* WSL char device */
1059 #define REPARSE_TAG_LX_BLK             0x80000026 /* WSL block device */
1060 static const value_string reparse_tag_vals[] = {
1061 	{ REPARSE_TAG_RESERVED_ZERO,   "REPARSE_TAG_RESERVED_ZERO"},
1062 	{ REPARSE_TAG_RESERVED_ONE,    "REPARSE_TAG_RESERVED_ONE"},
1063 	{ REPARSE_TAG_MOUNT_POINT,     "REPARSE_TAG_MOUNT_POINT"},
1064 	{ REPARSE_TAG_HSM,             "REPARSE_TAG_HSM"},
1065 	{ REPARSE_TAG_DRIVER_EXTENDER, "REPARSE_TAG_DRIVER_EXTENDER"},
1066 	{ REPARSE_TAG_HSM2,            "REPARSE_TAG_HSM2"},
1067 	{ REPARSE_TAG_SIS,             "REPARSE_TAG_SIS"},
1068 	{ REPARSE_TAG_DFS,             "REPARSE_TAG_DFS"},
1069 	{ REPARSE_TAG_FILTER_MANAGER,  "REPARSE_TAG_FILTER_MANAGER"},
1070 	{ REPARSE_TAG_SYMLINK,         "REPARSE_TAG_SYMLINK"},
1071 	{ REPARSE_TAG_DFSR,            "REPARSE_TAG_DFSR"},
1072 	{ REPARSE_TAG_NFS,             "REPARSE_TAG_NFS"},
1073 	{ REPARSE_TAG_LX_SYMLINK,      "REPARSE_TAG_LX_SYMLINK"},
1074 	{ REPARSE_TAG_AF_UNIX,         "REPARSE_TAG_AF_UNIX"},
1075 	{ REPARSE_TAG_LX_FIFO,         "REPARSE_TAG_LX_FIFO"},
1076 	{ REPARSE_TAG_LX_CHR,          "REPARSE_TAG_LX_CHR"},
1077 	{ REPARSE_TAG_LX_BLK,          "REPARSE_TAG_LX_BLK"},
1078 	{ 0, NULL }
1079 };
1080 
1081 #define NFS_SPECFILE_LNK 0x00000000014B4E4C
1082 #define NFS_SPECFILE_CHR 0x0000000000524843
1083 #define NFS_SPECFILE_BLK 0x00000000004B4C42
1084 #define NFS_SPECFILE_FIFO 0x000000004F464946
1085 #define NFS_SPECFILE_SOCK 0x000000004B434F53
1086 static const val64_string nfs_type_vals[] = {
1087 	{ NFS_SPECFILE_LNK,  "Symbolic Link" },
1088 	{ NFS_SPECFILE_CHR,  "Character Device" },
1089 	{ NFS_SPECFILE_BLK,  "Block Device" },
1090 	{ NFS_SPECFILE_FIFO, "FIFO" },
1091 	{ NFS_SPECFILE_SOCK, "UNIX Socket" },
1092 	{ 0, NULL }
1093 };
1094 
1095 #define SMB2_NUM_PROCEDURES     256
1096 #define MAX_UNCOMPRESSED_SIZE (1<<24) /* 16MB */
1097 
1098 #define SMB2_DIALECT_202  0x0202
1099 #define SMB2_DIALECT_210  0x0210
1100 #define SMB2_DIALECT_2FF  0x02FF
1101 #define SMB2_DIALECT_222  0x0222
1102 #define SMB2_DIALECT_224  0x0224
1103 #define SMB2_DIALECT_300  0x0300
1104 #define SMB2_DIALECT_302  0x0302
1105 #define SMB2_DIALECT_310  0x0310
1106 #define SMB2_DIALECT_311  0x0311
1107 
1108 static const value_string smb2_dialect_vals[] = {
1109 	{ SMB2_DIALECT_202, "SMB 2.0.2" },
1110 	{ SMB2_DIALECT_210, "SMB 2.1" },
1111 	{ SMB2_DIALECT_2FF, "SMB2 wildcard" },
1112 	{ SMB2_DIALECT_222, "SMB 2.2.2 (deprecated; should be 3.0)" },
1113 	{ SMB2_DIALECT_224, "SMB 2.2.4 (deprecated; should be 3.0)" },
1114 	{ SMB2_DIALECT_300, "SMB 3.0" },
1115 	{ SMB2_DIALECT_302, "SMB 3.0.2" },
1116 	{ SMB2_DIALECT_310, "SMB 3.1.0 (deprecated; should be 3.1.1)" },
1117 	{ SMB2_DIALECT_311, "SMB 3.1.1" },
1118 	{ 0, NULL }
1119 };
1120 
1121 static int dissect_windows_sockaddr_storage(tvbuff_t *, packet_info *, proto_tree *, int, int);
1122 static void dissect_smb2_error_data(tvbuff_t *, packet_info *, proto_tree *, int, int, smb2_info_t *);
1123 static guint smb2_eo_files_hash(gconstpointer k);
1124 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2);
1125 
update_preauth_hash(void * buf,packet_info * pinfo,tvbuff_t * tvb)1126 static void update_preauth_hash(void *buf, packet_info *pinfo, tvbuff_t *tvb)
1127 {
1128 	gcry_error_t err;
1129 	gcry_md_hd_t md;
1130 	void *pkt;
1131 
1132 	err = gcry_md_open(&md, GCRY_MD_SHA512, 0);
1133 	if (err)
1134 		return;
1135 
1136 	/* we dup in case of non-contiguous packet */
1137 	pkt = tvb_memdup(pinfo->pool, tvb, 0, tvb_captured_length(tvb));
1138 	gcry_md_write(md, buf, SMB2_PREAUTH_HASH_SIZE);
1139 	gcry_md_write(md, pkt, tvb_captured_length(tvb));
1140 	gcry_md_final(md);
1141 	memcpy(buf, gcry_md_read(md, 0), SMB2_PREAUTH_HASH_SIZE);
1142 	gcry_md_close(md);
1143 }
1144 
1145 static void
smb2stat_init(struct register_srt * srt _U_,GArray * srt_array)1146 smb2stat_init(struct register_srt* srt _U_, GArray* srt_array)
1147 {
1148 	srt_stat_table *smb2_srt_table;
1149 	guint32 i;
1150 
1151 	smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", NULL);
1152 	for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
1153 	{
1154 		init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
1155 	}
1156 }
1157 
1158 static tap_packet_status
smb2stat_packet(void * pss,packet_info * pinfo,epan_dissect_t * edt _U_,const void * prv)1159 smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
1160 {
1161 	guint i = 0;
1162 	srt_stat_table *smb2_srt_table;
1163 	srt_data_t *data = (srt_data_t *)pss;
1164 	const smb2_info_t *si=(const smb2_info_t *)prv;
1165 
1166 	/* we are only interested in response packets */
1167 	if(!(si->flags&SMB2_FLAGS_RESPONSE)){
1168 		return TAP_PACKET_DONT_REDRAW;
1169 	}
1170 	/* We should not include cancel and oplock break requests either */
1171 	if (si->opcode == SMB2_COM_CANCEL || si->opcode == SMB2_COM_BREAK) {
1172 		return TAP_PACKET_DONT_REDRAW;
1173 	}
1174 
1175 	/* if we haven't seen the request, just ignore it */
1176 	if(!si->saved){
1177 		return TAP_PACKET_DONT_REDRAW;
1178 	}
1179 
1180 	/* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
1181 	 * not only add additional (bogus) transactions but also the latency associated with them.
1182 	 * This can greatly inflate the maximum and average SRT stats especially in the case of
1183 	 * retransmissions triggered by the expiry of the rexmit timer (RTOs). Only calculating SRT
1184 	 * for the last received response accomplishes this goal without requiring the TCP pref
1185 	 * "Do not call subdissectors for error packets" to be set. */
1186 	if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->num))
1187 		return TAP_PACKET_DONT_REDRAW;
1188 
1189 	smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
1190 	add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
1191 	return TAP_PACKET_REDRAW;
1192 }
1193 
1194 /* Structure for SessionID <=> SessionKey mapping for decryption. */
1195 typedef struct _smb2_seskey_field_t {
1196 	/* session id */
1197 	guchar *id;		/* *little-endian* - not necessarily host-endian! */
1198 	guint id_len;
1199 	/* session key */
1200 	guchar *seskey;
1201 	guint seskey_len;
1202 	/* server to client key */
1203 	guchar *s2ckey;
1204 	guint s2ckey_len;
1205 	/* client to server key */
1206 	guchar *c2skey;
1207 	guint c2skey_len;
1208 } smb2_seskey_field_t;
1209 
1210 static smb2_seskey_field_t *seskey_list = NULL;
1211 static guint num_seskey_list = 0;
1212 
1213 static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1214 
1215 /* Callbacks for SessionID <=> SessionKey mapping. */
UAT_BUFFER_CB_DEF(seskey_list,id,smb2_seskey_field_t,id,id_len)1216 UAT_BUFFER_CB_DEF(seskey_list, id, smb2_seskey_field_t, id, id_len)
1217 UAT_BUFFER_CB_DEF(seskey_list, seskey, smb2_seskey_field_t, seskey, seskey_len)
1218 UAT_BUFFER_CB_DEF(seskey_list, s2ckey, smb2_seskey_field_t, s2ckey, s2ckey_len)
1219 UAT_BUFFER_CB_DEF(seskey_list, c2skey, smb2_seskey_field_t, c2skey, c2skey_len)
1220 
1221 #define SMB_SESSION_ID_SIZE 8
1222 
1223 static gboolean seskey_list_update_cb(void *r, char **err)
1224 {
1225 	smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
1226 	gboolean has_seskey = rec->seskey_len != 0;
1227 	gboolean has_s2ckey = rec->s2ckey_len != 0;
1228 	gboolean has_c2skey = rec->c2skey_len != 0;
1229 
1230 	*err = NULL;
1231 
1232 	if (rec->id_len != SMB_SESSION_ID_SIZE) {
1233 		*err = g_strdup("Session ID must be " G_STRINGIFY(SMB_SESSION_ID_SIZE) " bytes long and in hexadecimal");
1234 		return FALSE;
1235 	}
1236 
1237 	if (!has_seskey && !(has_c2skey || has_s2ckey)) {
1238 		*err = g_strdup("Decryption requires either the Session Key or at least one of the client-server AES keys");
1239 		return FALSE;
1240 	}
1241 
1242 
1243 	if (rec->seskey_len > NTLMSSP_KEY_LEN) {
1244 		*err = g_strdup("Session Key must be a hexadecimal string representing at most " G_STRINGIFY(NTLMSSP_KEY_LEN) " bytes");
1245 		return FALSE;
1246 	}
1247 
1248 	if (has_s2ckey && rec->s2ckey_len != AES_KEY_SIZE) {
1249 		*err = g_strdup("Server-to-Client key must be a hexadecimal string representing " G_STRINGIFY(AES_KEY_SIZE));
1250 		return FALSE;
1251 	}
1252 
1253 	if (has_c2skey && rec->c2skey_len != AES_KEY_SIZE) {
1254 		*err = g_strdup("Client-to-Server key must be a hexadecimal string representing " G_STRINGIFY(AES_KEY_SIZE));
1255 		return FALSE;
1256 	}
1257 
1258 	return TRUE;
1259 }
1260 
seskey_list_copy_cb(void * n,const void * o,size_t siz _U_)1261 static void* seskey_list_copy_cb(void *n, const void *o, size_t siz _U_)
1262 {
1263 	smb2_seskey_field_t *new_rec = (smb2_seskey_field_t *)n;
1264 	const smb2_seskey_field_t *old_rec = (const smb2_seskey_field_t *)o;
1265 
1266 	new_rec->id_len = old_rec->id_len;
1267 	new_rec->id = old_rec->id ? (guchar *)g_memdup2(old_rec->id, old_rec->id_len) : NULL;
1268 	new_rec->seskey_len = old_rec->seskey_len;
1269 	new_rec->seskey = old_rec->seskey ? (guchar *)g_memdup2(old_rec->seskey, old_rec->seskey_len) : NULL;
1270 	new_rec->s2ckey_len = old_rec->s2ckey_len;
1271 	new_rec->s2ckey = old_rec->s2ckey ? (guchar *)g_memdup2(old_rec->s2ckey, old_rec->s2ckey_len) : NULL;
1272 	new_rec->c2skey_len = old_rec->c2skey_len;
1273 	new_rec->c2skey = old_rec->c2skey ? (guchar *)g_memdup2(old_rec->c2skey, old_rec->c2skey_len) : NULL;
1274 
1275 	return new_rec;
1276 }
1277 
seskey_list_free_cb(void * r)1278 static void seskey_list_free_cb(void *r)
1279 {
1280 	smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
1281 
1282 	g_free(rec->id);
1283 	g_free(rec->seskey);
1284 	g_free(rec->s2ckey);
1285 	g_free(rec->c2skey);
1286 }
1287 
seskey_find_sid_key(guint64 sesid,guint8 * out_seskey,guint8 * out_s2ckey,guint8 * out_c2skey)1288 static gboolean seskey_find_sid_key(guint64 sesid, guint8 *out_seskey, guint8 *out_s2ckey, guint8 *out_c2skey)
1289 {
1290 	guint i;
1291 	guint64 sesid_le;
1292 
1293 	/*
1294 	 * The session IDs in the UAT are octet arrays, in little-endian
1295 	 * byte order (as it appears on the wire); they have been
1296 	 * checked to make sure they're 8 bytes (SMB_SESSION_ID_SIZE)
1297 	 * long.  They're *probably* aligned on an appropriate boundary,
1298 	 * but let's not assume that - let's just use memcmp().
1299 	 *
1300 	 * The session ID passed to us, however, is in *host* byte order.
1301 	 * This is *NOT* necessarily little-endian; it's big-endian on,
1302 	 * for example, System/390 and z/Architecture ("s390" and "s390x"
1303 	 * in Linuxland), SPARC, and most PowerPC systems.  We must,
1304 	 * therefore, put it into little-endian byte order before
1305 	 * comparing it with the IDs in the UAT values.
1306 	 */
1307 	sesid_le = GUINT64_TO_LE(sesid);
1308 
1309 	for (i = 0; i < num_seskey_list; i++) {
1310 		const smb2_seskey_field_t *p = &seskey_list[i];
1311 		if (memcmp(&sesid_le, p->id, SMB_SESSION_ID_SIZE) == 0) {
1312 			memset(out_seskey, 0, NTLMSSP_KEY_LEN);
1313 			memset(out_s2ckey, 0, AES_KEY_SIZE);
1314 			memset(out_c2skey, 0, AES_KEY_SIZE);
1315 
1316 			if (p->seskey_len != 0)
1317 				memcpy(out_seskey, p->seskey, p->seskey_len);
1318 			if (p->s2ckey_len != 0)
1319 				memcpy(out_s2ckey, p->s2ckey, p->s2ckey_len);
1320 			if (p->c2skey_len != 0)
1321 				memcpy(out_c2skey, p->c2skey, p->c2skey_len);
1322 
1323 			return TRUE;
1324 		}
1325 	}
1326 
1327 	return FALSE;
1328 }
1329 
1330 /* ExportObject preferences variable */
1331 gboolean eosmb2_take_name_as_fid = FALSE ;
1332 
1333 /* unmatched smb_saved_info structures.
1334    For unmatched smb_saved_info structures we store the smb_saved_info
1335    structure using the msg_id field.
1336 */
1337 static gint
smb2_saved_info_equal_unmatched(gconstpointer k1,gconstpointer k2)1338 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
1339 {
1340 	const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
1341 	const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
1342 	return key1->msg_id == key2->msg_id;
1343 }
1344 static guint
smb2_saved_info_hash_unmatched(gconstpointer k)1345 smb2_saved_info_hash_unmatched(gconstpointer k)
1346 {
1347 	const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
1348 	guint32 hash;
1349 
1350 	hash = (guint32) (key->msg_id&0xffffffff);
1351 	return hash;
1352 }
1353 
1354 /* matched smb_saved_info structures.
1355    For matched smb_saved_info structures we store the smb_saved_info
1356    structure using the msg_id field.
1357 */
1358 static gint
smb2_saved_info_equal_matched(gconstpointer k1,gconstpointer k2)1359 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1360 {
1361 	const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
1362 	const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
1363 	return key1->msg_id == key2->msg_id;
1364 }
1365 static guint
smb2_saved_info_hash_matched(gconstpointer k)1366 smb2_saved_info_hash_matched(gconstpointer k)
1367 {
1368 	const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
1369 	guint32 hash;
1370 
1371 	hash = (guint32) (key->msg_id&0xffffffff);
1372 	return hash;
1373 }
1374 
1375 /* For Tids of a specific conversation.
1376    This keeps track of tid->sharename mappings and other information about the
1377    tid.
1378    qqq
1379    We might need to refine this if it occurs that tids are reused on a single
1380    conversation.   we don't worry about that yet for simplicity
1381 */
1382 static gint
smb2_tid_info_equal(gconstpointer k1,gconstpointer k2)1383 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
1384 {
1385 	const smb2_tid_info_t *key1 = (const smb2_tid_info_t *)k1;
1386 	const smb2_tid_info_t *key2 = (const smb2_tid_info_t *)k2;
1387 	return key1->tid == key2->tid;
1388 }
1389 static guint
smb2_tid_info_hash(gconstpointer k)1390 smb2_tid_info_hash(gconstpointer k)
1391 {
1392 	const smb2_tid_info_t *key = (const smb2_tid_info_t *)k;
1393 	guint32 hash;
1394 
1395 	hash = key->tid;
1396 	return hash;
1397 }
1398 
1399 /* For Uids of a specific conversation.
1400    This keeps track of uid->acct_name mappings and other information about the
1401    uid.
1402    qqq
1403    We might need to refine this if it occurs that uids are reused on a single
1404    conversation.   we don't worry about that yet for simplicity
1405 */
1406 static gint
smb2_sesid_info_equal(gconstpointer k1,gconstpointer k2)1407 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
1408 {
1409 	const smb2_sesid_info_t *key1 = (const smb2_sesid_info_t *)k1;
1410 	const smb2_sesid_info_t *key2 = (const smb2_sesid_info_t *)k2;
1411 	return key1->sesid == key2->sesid;
1412 }
1413 static guint
smb2_sesid_info_hash(gconstpointer k)1414 smb2_sesid_info_hash(gconstpointer k)
1415 {
1416 	const smb2_sesid_info_t *key = (const smb2_sesid_info_t *)k;
1417 	guint32 hash;
1418 
1419 	hash = (guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
1420 	return hash;
1421 }
1422 
1423 /*
1424  * For File IDs of a specific conversation.
1425  * This keeps track of fid to name mapping and application level conversations
1426  * over named pipes.
1427  *
1428  * This handles implementation bugs, where the fid_persitent is 0 or
1429  * the fid_persitent/fid_volative is not unique per conversation.
1430  */
1431 static gint
smb2_fid_info_equal(gconstpointer k1,gconstpointer k2)1432 smb2_fid_info_equal(gconstpointer k1, gconstpointer k2)
1433 {
1434 	const smb2_fid_info_t *key = (const smb2_fid_info_t *)k1;
1435 	const smb2_fid_info_t *val = (const smb2_fid_info_t *)k2;
1436 
1437 	if (!key->frame_key) {
1438 		key = (const smb2_fid_info_t *)k2;
1439 		val = (const smb2_fid_info_t *)k1;
1440 	}
1441 
1442 	if (key->fid_persistent != val->fid_persistent) {
1443 		return 0;
1444 	}
1445 
1446 	if (key->fid_volatile != val->fid_volatile) {
1447 		return 0;
1448 	}
1449 
1450 	if (key->sesid != val->sesid) {
1451 		return 0;
1452 	}
1453 
1454 	if (key->tid != val->tid) {
1455 		return 0;
1456 	}
1457 
1458 	if (!(val->frame_beg <= key->frame_key && key->frame_key <= val->frame_end)) {
1459 		return 0;
1460 	}
1461 
1462 	return 1;
1463 }
1464 
1465 static guint
smb2_fid_info_hash(gconstpointer k)1466 smb2_fid_info_hash(gconstpointer k)
1467 {
1468 	const smb2_fid_info_t *key = (const smb2_fid_info_t *)k;
1469 	guint32 hash;
1470 
1471 	if (key->fid_persistent != 0) {
1472 		hash = (guint32)( ((key->fid_persistent>>32)&0xffffffff)+((key->fid_persistent)&0xffffffff) );
1473 	} else {
1474 		hash = (guint32)( ((key->fid_volatile>>32)&0xffffffff)+((key->fid_volatile)&0xffffffff) );
1475 	}
1476 
1477 	return hash;
1478 }
1479 
1480 /* Callback for destroying the glib hash tables associated with a conversation
1481  * struct. */
1482 static gboolean
smb2_conv_destroy(wmem_allocator_t * allocator _U_,wmem_cb_event_t event _U_,void * user_data)1483 smb2_conv_destroy(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
1484 	          void *user_data)
1485 {
1486 	smb2_conv_info_t *conv = (smb2_conv_info_t *)user_data;
1487 
1488 	g_hash_table_destroy(conv->matched);
1489 	g_hash_table_destroy(conv->unmatched);
1490 
1491 	/* This conversation is gone, return FALSE to indicate we don't
1492 	 * want to be called again for this conversation. */
1493 	return FALSE;
1494 }
1495 
1496 static smb2_sesid_info_t *
smb2_get_session(smb2_conv_info_t * conv _U_,guint64 id,packet_info * pinfo,smb2_info_t * si)1497 smb2_get_session(smb2_conv_info_t *conv _U_, guint64 id, packet_info *pinfo, smb2_info_t *si)
1498 {
1499 	smb2_sesid_info_t key = {.sesid = id};
1500 	smb2_sesid_info_t *ses = (smb2_sesid_info_t *)wmem_map_lookup(smb2_sessions, &key);
1501 
1502 	if (!ses) {
1503 		ses = wmem_new0(wmem_file_scope(), smb2_sesid_info_t);
1504 		ses->sesid = id;
1505 		ses->auth_frame = (guint32)-1;
1506 		ses->tids = wmem_map_new(wmem_file_scope(), smb2_tid_info_hash, smb2_tid_info_equal);
1507 		ses->fids = wmem_map_new(wmem_file_scope(), smb2_fid_info_hash, smb2_fid_info_equal);
1508 		ses->files = wmem_map_new(wmem_file_scope(), smb2_eo_files_hash, smb2_eo_files_equal);
1509 
1510 		seskey_find_sid_key(id, ses->session_key, ses->client_decryption_key, ses->server_decryption_key);
1511 		if (pinfo && si) {
1512 			if (si->flags & SMB2_FLAGS_RESPONSE) {
1513 				ses->server_port = pinfo->srcport;
1514 			} else {
1515 				ses->server_port = pinfo->destport;
1516 			}
1517 		}
1518 		wmem_map_insert(smb2_sessions, ses, ses);
1519 	}
1520 
1521 	return ses;
1522 }
1523 
1524 static void
smb2_add_session_info(proto_tree * ses_tree,proto_item * ses_item,tvbuff_t * tvb,gint start,smb2_sesid_info_t * ses)1525 smb2_add_session_info(proto_tree *ses_tree, proto_item *ses_item, tvbuff_t *tvb, gint start, smb2_sesid_info_t *ses)
1526 {
1527 	proto_item  *new_item;
1528 	if (!ses)
1529 		return;
1530 
1531 	if (ses->acct_name) {
1532 		new_item = proto_tree_add_string(ses_tree, hf_smb2_acct_name, tvb, start, 0, ses->acct_name);
1533 		proto_item_set_generated(new_item);
1534 		proto_item_append_text(ses_item, " Acct:%s", ses->acct_name);
1535 	}
1536 
1537 	if (ses->domain_name) {
1538 		new_item = proto_tree_add_string(ses_tree, hf_smb2_domain_name, tvb, start, 0, ses->domain_name);
1539 		proto_item_set_generated(new_item);
1540 		proto_item_append_text(ses_item, " Domain:%s", ses->domain_name);
1541 	}
1542 
1543 	if (ses->host_name) {
1544 		new_item = proto_tree_add_string(ses_tree, hf_smb2_host_name, tvb, start, 0, ses->host_name);
1545 		proto_item_set_generated(new_item);
1546 		proto_item_append_text(ses_item, " Host:%s", ses->host_name);
1547 	}
1548 
1549 	if (ses->auth_frame != (guint32)-1) {
1550 		new_item = proto_tree_add_uint(ses_tree, hf_smb2_auth_frame, tvb, start, 0, ses->auth_frame);
1551 		proto_item_set_generated(new_item);
1552 	}
1553 }
1554 
smb2_key_derivation(const guint8 * KI,guint32 KI_len,const guint8 * Label,guint32 Label_len,const guint8 * Context,guint32 Context_len,guint8 KO[16])1555 static void smb2_key_derivation(const guint8 *KI, guint32 KI_len,
1556 			 const guint8 *Label, guint32 Label_len,
1557 			 const guint8 *Context, guint32 Context_len,
1558 			 guint8 KO[16])
1559 {
1560 	gcry_md_hd_t  hd     = NULL;
1561 	guint8        buf[4];
1562 	guint8       *digest = NULL;
1563 
1564 	/*
1565 	 * a simplified version of
1566 	 * "NIST Special Publication 800-108" section 5.1
1567 	 * using hmac-sha256.
1568 	 */
1569 	gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
1570 	gcry_md_setkey(hd, KI, KI_len);
1571 
1572 	memset(buf, 0, sizeof(buf));
1573 	buf[3] = 1;
1574 	gcry_md_write(hd, buf, sizeof(buf));
1575 	gcry_md_write(hd, Label, Label_len);
1576 	gcry_md_write(hd, buf, 1);
1577 	gcry_md_write(hd, Context, Context_len);
1578 	buf[3] = 128;
1579 	gcry_md_write(hd, buf, sizeof(buf));
1580 
1581 	digest = gcry_md_read(hd, GCRY_MD_SHA256);
1582 
1583 	memcpy(KO, digest, 16);
1584 
1585 	gcry_md_close(hd);
1586 }
1587 
1588 /* for export-object-smb2 */
policy_hnd_to_file_id(wmem_allocator_t * pool,const e_ctx_hnd * hnd)1589 static gchar *policy_hnd_to_file_id(wmem_allocator_t *pool, const e_ctx_hnd *hnd) {
1590 	return guid_to_str(pool, &hnd->uuid);
1591 }
smb2_eo_files_hash(gconstpointer k)1592 static guint smb2_eo_files_hash(gconstpointer k) {
1593 	return g_str_hash(policy_hnd_to_file_id(wmem_packet_scope(), (const e_ctx_hnd *)k));
1594 }
smb2_eo_files_equal(gconstpointer k1,gconstpointer k2)1595 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2) {
1596 int	are_equal;
1597 	const e_ctx_hnd *key1 = (const e_ctx_hnd *)k1;
1598 	const e_ctx_hnd *key2 = (const e_ctx_hnd *)k2;
1599 
1600 	are_equal = (key1->uuid.data1==key2->uuid.data1 &&
1601 		key1->uuid.data2==key2->uuid.data2 &&
1602 		key1->uuid.data3==key2->uuid.data3 &&
1603 		key1->uuid.data4[0]==key2->uuid.data4[0] &&
1604 		key1->uuid.data4[1]==key2->uuid.data4[1] &&
1605 		key1->uuid.data4[2]==key2->uuid.data4[2] &&
1606 		key1->uuid.data4[3]==key2->uuid.data4[3] &&
1607 		key1->uuid.data4[4]==key2->uuid.data4[4] &&
1608 		key1->uuid.data4[5]==key2->uuid.data4[5] &&
1609 		key1->uuid.data4[6]==key2->uuid.data4[6] &&
1610 		key1->uuid.data4[7]==key2->uuid.data4[7]);
1611 
1612 	return are_equal;
1613 }
1614 
1615 static void
feed_eo_smb2(tvbuff_t * tvb,packet_info * pinfo,smb2_info_t * si,guint16 dataoffset,guint32 length,guint64 file_offset)1616 feed_eo_smb2(tvbuff_t * tvb,packet_info *pinfo,smb2_info_t * si, guint16 dataoffset,guint32 length, guint64 file_offset) {
1617 
1618 	char       *fid_name = NULL;
1619 	guint32     open_frame = 0, close_frame = 0;
1620 	tvbuff_t        *data_tvb = NULL;
1621 	smb_eo_t        *eo_info;
1622 	gchar           *file_id;
1623 	gchar		*auxstring;
1624 	gchar		**aux_string_v;
1625 
1626 	/* Create a new tvb to point to the payload data */
1627 	data_tvb = tvb_new_subset_length(tvb, dataoffset, length);
1628 	/* Create the eo_info to pass to the listener */
1629 	eo_info = wmem_new(pinfo->pool, smb_eo_t);
1630 	/* Fill in eo_info */
1631 	eo_info->smbversion=2;
1632 	/* cmd == opcode */
1633 	eo_info->cmd=si->opcode;
1634 	/* We don't keep track of uid in SMB v2 */
1635 	eo_info->uid=0;
1636 
1637 	/* Try to get file id and filename */
1638 	file_id=policy_hnd_to_file_id(pinfo->pool, &si->saved->policy_hnd);
1639 	dcerpc_fetch_polhnd_data(&si->saved->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num);
1640 	if (fid_name && g_strcmp0(fid_name,"File: ")!=0) {
1641 		auxstring=fid_name;
1642 		/* Remove "File: " from filename */
1643 		if (g_str_has_prefix(auxstring, "File: ")) {
1644 			aux_string_v = g_strsplit(auxstring, "File: ", -1);
1645 			eo_info->filename = wmem_strdup_printf(pinfo->pool, "\\%s",aux_string_v[g_strv_length(aux_string_v)-1]);
1646 			g_strfreev(aux_string_v);
1647 		} else {
1648 			if (g_str_has_prefix(auxstring, "\\")) {
1649 				eo_info->filename = wmem_strdup(pinfo->pool, auxstring);
1650 			} else {
1651 				eo_info->filename = wmem_strdup_printf(pinfo->pool, "\\%s",auxstring);
1652 			}
1653 		}
1654 	} else {
1655 		auxstring=wmem_strdup_printf(pinfo->pool, "File_Id_%s", file_id);
1656 		eo_info->filename=auxstring;
1657 	}
1658 
1659 
1660 
1661 	if (eosmb2_take_name_as_fid) {
1662 		eo_info->fid = g_str_hash(eo_info->filename);
1663 	} else {
1664 		eo_info->fid = g_str_hash(file_id);
1665 	}
1666 
1667 	/* tid, hostname, tree_id */
1668 	if (si->tree) {
1669 		eo_info->tid=si->tree->tid;
1670 		if (strlen(si->tree->name)>0 && strlen(si->tree->name)<=256) {
1671 			eo_info->hostname = wmem_strdup(pinfo->pool, si->tree->name);
1672 		} else {
1673 			eo_info->hostname = wmem_strdup_printf(pinfo->pool, "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,si->opcode),si->tree->tid);
1674 		}
1675 	} else {
1676 		eo_info->tid=0;
1677 		eo_info->hostname = wmem_strdup_printf(pinfo->pool, "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,si->opcode));
1678 	}
1679 
1680 	/* packet number */
1681 	eo_info->pkt_num = pinfo->num;
1682 
1683 	/* fid type */
1684 	if (si->eo_file_info->attr_mask & SMB2_FLAGS_ATTR_DIRECTORY) {
1685 		eo_info->fid_type=SMB2_FID_TYPE_DIR;
1686 	} else {
1687 		if (si->eo_file_info->attr_mask &
1688 			(SMB2_FLAGS_ATTR_ARCHIVE | SMB2_FLAGS_ATTR_NORMAL |
1689 			 SMB2_FLAGS_ATTR_HIDDEN | SMB2_FLAGS_ATTR_READONLY |
1690 			 SMB2_FLAGS_ATTR_SYSTEM) ) {
1691 			eo_info->fid_type=SMB2_FID_TYPE_FILE;
1692 		} else {
1693 			eo_info->fid_type=SMB2_FID_TYPE_OTHER;
1694 		}
1695 	}
1696 
1697 	/* end_of_file */
1698 	eo_info->end_of_file=si->eo_file_info->end_of_file;
1699 
1700 	/* data offset and chunk length */
1701 	eo_info->smb_file_offset=file_offset;
1702 	eo_info->smb_chunk_len=length;
1703 	/* XXX is this right? */
1704 	if (length<si->saved->bytes_moved) {
1705 		si->saved->file_offset=si->saved->file_offset+length;
1706 		si->saved->bytes_moved=si->saved->bytes_moved-length;
1707 	}
1708 
1709 	/* Payload */
1710 	eo_info->payload_len = length;
1711 	eo_info->payload_data = tvb_get_ptr(data_tvb, 0, length);
1712 
1713 	tap_queue_packet(smb2_eo_tap, pinfo, eo_info);
1714 
1715 }
1716 
1717 static int dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
1718 
1719 
1720 /* This is a helper to dissect the common string type
1721  * uint16 offset
1722  * uint16 length
1723  * ...
1724  * char *string
1725  *
1726  * This function is called twice, first to decode the offset/length and
1727  * second time to dissect the actual string.
1728  * It is done this way since there is no guarantee that we have the full packet and we don't
1729  * want to abort dissection too early if the packet ends somewhere between the
1730  * length/offset and the actual buffer.
1731  *
1732  */
1733 enum offset_length_buffer_offset_size {
1734 	OLB_O_UINT16_S_UINT16,
1735 	OLB_O_UINT16_S_UINT32,
1736 	OLB_O_UINT8_P_UINT8_S_UINT32,
1737 	OLB_O_UINT32_S_UINT32,
1738 	OLB_S_UINT32_O_UINT32
1739 };
1740 typedef struct _offset_length_buffer_t {
1741 	guint32 off;
1742 	guint32 len;
1743 	int off_offset;
1744 	int len_offset;
1745 	enum offset_length_buffer_offset_size offset_size;
1746 	int hfindex;
1747 } offset_length_buffer_t;
1748 static int
dissect_smb2_olb_length_offset(tvbuff_t * tvb,int offset,offset_length_buffer_t * olb,enum offset_length_buffer_offset_size offset_size,int hfindex)1749 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
1750 			       enum offset_length_buffer_offset_size offset_size, int hfindex)
1751 {
1752 	olb->hfindex = hfindex;
1753 	olb->offset_size = offset_size;
1754 	switch (offset_size) {
1755 	case OLB_O_UINT16_S_UINT16:
1756 		olb->off = tvb_get_letohs(tvb, offset);
1757 		olb->off_offset = offset;
1758 		offset += 2;
1759 		olb->len = tvb_get_letohs(tvb, offset);
1760 		olb->len_offset = offset;
1761 		offset += 2;
1762 		break;
1763 	case OLB_O_UINT16_S_UINT32:
1764 		olb->off = tvb_get_letohs(tvb, offset);
1765 		olb->off_offset = offset;
1766 		offset += 2;
1767 		olb->len = tvb_get_letohl(tvb, offset);
1768 		olb->len_offset = offset;
1769 		offset += 4;
1770 		break;
1771 	case OLB_O_UINT8_P_UINT8_S_UINT32:
1772 		olb->off = tvb_get_guint8(tvb, offset);
1773 		olb->off_offset = offset;
1774 		offset += 1;
1775 		/* 1 byte reserved */
1776 		offset += 1;
1777 		olb->len = tvb_get_letohl(tvb, offset);
1778 		olb->len_offset = offset;
1779 		offset += 4;
1780 		break;
1781 	case OLB_O_UINT32_S_UINT32:
1782 		olb->off = tvb_get_letohl(tvb, offset);
1783 		olb->off_offset = offset;
1784 		offset += 4;
1785 		olb->len = tvb_get_letohl(tvb, offset);
1786 		olb->len_offset = offset;
1787 		offset += 4;
1788 		break;
1789 	case OLB_S_UINT32_O_UINT32:
1790 		olb->len = tvb_get_letohl(tvb, offset);
1791 		olb->len_offset = offset;
1792 		offset += 4;
1793 		olb->off = tvb_get_letohl(tvb, offset);
1794 		olb->off_offset = offset;
1795 		offset += 4;
1796 		break;
1797 	}
1798 
1799 	return offset;
1800 }
1801 
1802 #define OLB_TYPE_UNICODE_STRING		0x01
1803 #define OLB_TYPE_ASCII_STRING		0x02
1804 static const guint8 *
dissect_smb2_olb_off_string(packet_info * pinfo,proto_tree * parent_tree,tvbuff_t * tvb,offset_length_buffer_t * olb,int base,int type)1805 dissect_smb2_olb_off_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int base, int type)
1806 {
1807 	int           len, off;
1808 	proto_item   *item = NULL;
1809 	proto_tree   *tree = NULL;
1810 	const guint8 *name = NULL;
1811 
1812 	olb->off += base;
1813 
1814 	len = olb->len;
1815 	off = olb->off;
1816 
1817 
1818 	/* sanity check */
1819 	tvb_ensure_bytes_exist(tvb, off, len);
1820 	if (((off+len)<off)
1821 	|| ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1822 		proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, off, -1,
1823 				    "Invalid offset/length. Malformed packet");
1824 
1825 		col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1826 
1827 		return NULL;
1828 	}
1829 
1830 
1831 	switch (type) {
1832 	case OLB_TYPE_UNICODE_STRING:
1833 		item = proto_tree_add_item_ret_string(parent_tree,
1834 		    olb->hfindex, tvb, off, len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
1835 		    pinfo->pool, &name);
1836 		tree = proto_item_add_subtree(item, ett_smb2_olb);
1837 		break;
1838 	case OLB_TYPE_ASCII_STRING:
1839 		item = proto_tree_add_item_ret_string(parent_tree,
1840 		    olb->hfindex, tvb, off, len, ENC_ASCII|ENC_NA,
1841 		    pinfo->pool, &name);
1842 		tree = proto_item_add_subtree(item, ett_smb2_olb);
1843 		break;
1844 	}
1845 
1846 	switch (olb->offset_size) {
1847 	case OLB_O_UINT16_S_UINT16:
1848 		proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1849 		proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1850 		break;
1851 	case OLB_O_UINT16_S_UINT32:
1852 		proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1853 		proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1854 		break;
1855 	case OLB_O_UINT8_P_UINT8_S_UINT32:
1856 		proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 1, ENC_NA);
1857 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, olb->off_offset+1, 1, ENC_NA);
1858 		proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1859 		break;
1860 	case OLB_O_UINT32_S_UINT32:
1861 		proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1862 		proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1863 		break;
1864 	case OLB_S_UINT32_O_UINT32:
1865 		proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1866 		proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1867 		break;
1868 	}
1869 
1870 	return name;
1871 }
1872 
1873 static const guint8 *
dissect_smb2_olb_string(packet_info * pinfo,proto_tree * parent_tree,tvbuff_t * tvb,offset_length_buffer_t * olb,int type)1874 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
1875 {
1876 	return dissect_smb2_olb_off_string(pinfo, parent_tree, tvb, olb, 0, type);
1877 }
1878 
1879 static void
dissect_smb2_olb_buffer(packet_info * pinfo,proto_tree * parent_tree,tvbuff_t * tvb,offset_length_buffer_t * olb,smb2_info_t * si,void (* dissector)(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si))1880 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
1881 			offset_length_buffer_t *olb, smb2_info_t *si,
1882 			void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
1883 {
1884 	int         len, off;
1885 	proto_item *sub_item = NULL;
1886 	proto_tree *sub_tree = NULL;
1887 	tvbuff_t   *sub_tvb  = NULL;
1888 	int         offset;
1889 
1890 	offset = olb->off;
1891 	len    = olb->len;
1892 	off    = olb->off;
1893 
1894 	/* sanity check */
1895 	tvb_ensure_bytes_exist(tvb, off, len);
1896 	if (((off+len)<off)
1897 	    || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1898 		proto_tree_add_expert_format(parent_tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1899 				    "Invalid offset/length. Malformed packet");
1900 
1901 		col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1902 
1903 		return;
1904 	}
1905 
1906 	switch (olb->offset_size) {
1907 	case OLB_O_UINT16_S_UINT16:
1908 		proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1909 		proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1910 		break;
1911 	case OLB_O_UINT16_S_UINT32:
1912 		proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1913 		proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1914 		break;
1915 	case OLB_O_UINT8_P_UINT8_S_UINT32:
1916 		proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 1, ENC_NA);
1917 		proto_tree_add_item(parent_tree, hf_smb2_reserved, tvb, olb->off_offset+1, 1, ENC_NA);
1918 		proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1919 		break;
1920 	case OLB_O_UINT32_S_UINT32:
1921 		proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1922 		proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1923 		break;
1924 	case OLB_S_UINT32_O_UINT32:
1925 		proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1926 		proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1927 		break;
1928 	}
1929 
1930 	/* if we don't want/need a subtree */
1931 	if (olb->hfindex == -1) {
1932 		sub_item = parent_tree;
1933 		sub_tree = parent_tree;
1934 	} else {
1935 		if (parent_tree) {
1936 			sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
1937 			sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
1938 		}
1939 	}
1940 
1941 	if (off == 0 || len == 0) {
1942 		proto_item_append_text(sub_item, ": NO DATA");
1943 		return;
1944 	}
1945 
1946 	if (!dissector) {
1947 		return;
1948 	}
1949 
1950 	sub_tvb = tvb_new_subset_length_caplen(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
1951 
1952 	dissector(sub_tvb, pinfo, sub_tree, si);
1953 }
1954 
1955 static int
dissect_smb2_olb_tvb_max_offset(int offset,offset_length_buffer_t * olb)1956 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
1957 {
1958 	if (olb->off == 0) {
1959 		return offset;
1960 	}
1961 	return MAX(offset, (int)(olb->off + olb->len));
1962 }
1963 
1964 typedef struct _smb2_function {
1965 	int (*request) (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1966 	int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1967 } smb2_function;
1968 
1969 static const true_false_string tfs_smb2_svhdx_has_initiator_id = {
1970 	"Has an initiator id",
1971 	"Does not have an initiator id"
1972 };
1973 
1974 static const true_false_string tfs_flags_response = {
1975 	"This is a RESPONSE",
1976 	"This is a REQUEST"
1977 };
1978 
1979 static const true_false_string tfs_flags_async_cmd = {
1980 	"This is an ASYNC command",
1981 	"This is a SYNC command"
1982 };
1983 
1984 static const true_false_string tfs_flags_dfs_op = {
1985 	"This is a DFS OPERATION",
1986 	"This is a normal operation"
1987 };
1988 
1989 static const true_false_string tfs_flags_chained = {
1990 	"This pdu is a CHAINED command",
1991 	"This pdu is NOT a chained command"
1992 };
1993 
1994 static const true_false_string tfs_flags_signature = {
1995 	"This pdu is SIGNED",
1996 	"This pdu is NOT signed"
1997 };
1998 
1999 static const true_false_string tfs_flags_replay_operation = {
2000 	"This is a REPLAY OPERATION",
2001 	"This is NOT a replay operation"
2002 };
2003 
2004 static const true_false_string tfs_flags_priority_mask = {
2005 	"This pdu contains a PRIORITY",
2006 	"This pdu does NOT contain a PRIORITY"
2007 };
2008 
2009 static const true_false_string tfs_cap_dfs = {
2010 	"This host supports DFS",
2011 	"This host does NOT support DFS"
2012 };
2013 
2014 static const true_false_string tfs_cap_leasing = {
2015 	"This host supports LEASING",
2016 	"This host does NOT support LEASING"
2017 };
2018 
2019 static const true_false_string tfs_cap_large_mtu = {
2020 	"This host supports LARGE_MTU",
2021 	"This host does NOT support LARGE_MTU"
2022 };
2023 
2024 static const true_false_string tfs_cap_multi_channel = {
2025 	"This host supports MULTI CHANNEL",
2026 	"This host does NOT support MULTI CHANNEL"
2027 };
2028 
2029 static const true_false_string tfs_cap_persistent_handles = {
2030 	"This host supports PERSISTENT HANDLES",
2031 	"This host does NOT support PERSISTENT HANDLES"
2032 };
2033 
2034 static const true_false_string tfs_cap_directory_leasing = {
2035 	"This host supports DIRECTORY LEASING",
2036 	"This host does NOT support DIRECTORY LEASING"
2037 };
2038 
2039 static const true_false_string tfs_cap_encryption = {
2040 	"This host supports ENCRYPTION",
2041 	"This host does NOT support ENCRYPTION"
2042 };
2043 
2044 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rss = {
2045 	"This interface supports RSS",
2046 	"This interface does not support RSS"
2047 };
2048 
2049 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rdma = {
2050 	"This interface supports RDMA",
2051 	"This interface does not support RDMA"
2052 };
2053 
2054 static const value_string file_region_usage_vals[] = {
2055 	{ 0x00000001, "FILE_REGION_USAGE_VALID_CACHED_DATA" },
2056 	{ 0, NULL }
2057 };
2058 
2059 static const value_string originator_flags_vals[] = {
2060 	{ 1, "SVHDX_ORIGINATOR_PVHDPARSER" },
2061 	{ 4, "SVHDX_ORIGINATOR_VHDMP" },
2062 	{ 0, NULL }
2063 };
2064 
2065 static const value_string compression_format_vals[] = {
2066 	{ 0, "COMPRESSION_FORMAT_NONE" },
2067 	{ 1, "COMPRESSION_FORMAT_DEFAULT" },
2068 	{ 2, "COMPRESSION_FORMAT_LZNT1" },
2069 	{ 0, NULL }
2070 };
2071 
2072 static const value_string checksum_algorithm_vals[] = {
2073 	{ 0x0000, "CHECKSUM_TYPE_NONE" },
2074 	{ 0x0002, "CHECKSUM_TYPE_CRC64" },
2075 	{ 0xFFFF, "CHECKSUM_TYPE_UNCHANGED" },
2076 	{ 0, NULL }
2077 };
2078 
2079 /* Note: All uncommented are "dissector not implemented" */
2080 static const value_string smb2_ioctl_vals[] = {
2081 	{0x00060194, "FSCTL_DFS_GET_REFERRALS"},		      /* dissector implemented */
2082 	{0x000601B0, "FSCTL_DFS_GET_REFERRALS_EX"},
2083 	{0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
2084 	{0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
2085 	{0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
2086 	{0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
2087 	{0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
2088 	{0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
2089 	{0x00090018, "FSCTL_LOCK_VOLUME"},
2090 	{0x0009001C, "FSCTL_UNLOCK_VOLUME"},
2091 	{0x00090020, "FSCTL_DISMOUNT_VOLUME"},
2092 	{0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
2093 	{0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
2094 	{0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
2095 	{0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
2096 	{0x0009003C, "FSCTL_GET_COMPRESSION"},			      /* dissector implemented */
2097 	{0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
2098 	{0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
2099 	{0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
2100 	{0x00090058, "FSCTL_QUERY_FAT_BPB"},
2101 	{0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
2102 	{0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
2103 	{0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
2104 	{0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
2105 	{0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
2106 	{0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
2107 	{0x00090074, "FSCTL_MOVE_FILE"},
2108 	{0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
2109 	{0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
2110 	{0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
2111 	{0x00090087, "FSCTL_READ_PROPERTY_DATA"},
2112 	{0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
2113 	{0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
2114 	{0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
2115 	{0x0009009C, "FSCTL_GET_OBJECT_ID"},			      /* dissector implemented */
2116 	{0x000900A4, "FSCTL_SET_REPARSE_POINT"}, 		      /* dissector implemented */
2117 	{0x000900A8, "FSCTL_GET_REPARSE_POINT"}, 		      /* dissector implemented */
2118 	{0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},		      /* dissector implemented */
2119 	{0x000900C4, "FSCTL_SET_SPARSE"},			      /* dissector implemented */
2120 	{0x000900D4, "FSCTL_SET_ENCRYPTION"},
2121 	{0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
2122 	{0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
2123 	{0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
2124 	{0x000900F0, "FSCTL_EXTEND_VOLUME"},
2125 	{0x00090244, "FSCTL_CSV_TUNNEL_REQUEST"},
2126 	{0x0009027C, "FSCTL_GET_INTEGRITY_INFORMATION"},
2127 	{0x00090284, "FSCTL_QUERY_FILE_REGIONS"},                     /* dissector implemented */
2128 	{0x000902c8, "FSCTL_CSV_SYNC_TUNNEL_REQUEST"},
2129 	{0x00090300, "FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT"},      /* dissector implemented */
2130 	{0x00090304, "FSCTL_SVHDX_SYNC_TUNNEL_REQUEST"},              /* dissector implemented */
2131 	{0x00090308, "FSCTL_SVHDX_SET_INITIATOR_INFORMATION"},
2132 	{0x0009030C, "FSCTL_SET_EXTERNAL_BACKING"},
2133 	{0x00090310, "FSCTL_GET_EXTERNAL_BACKING"},
2134 	{0x00090314, "FSCTL_DELETE_EXTERNAL_BACKING"},
2135 	{0x00090318, "FSCTL_ENUM_EXTERNAL_BACKING"},
2136 	{0x0009031F, "FSCTL_ENUM_OVERLAY"},
2137 	{0x00090350, "FSCTL_STORAGE_QOS_CONTROL"},                    /* dissector implemented */
2138 	{0x00090364, "FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST"},             /* dissector implemented */
2139 	{0x000940B3, "FSCTL_ENUM_USN_DATA"},
2140 	{0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
2141 	{0x000940BB, "FSCTL_READ_USN_JOURNAL"},
2142 	{0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},		      /* dissector implemented */
2143 	{0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
2144 	{0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
2145 	{0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
2146 	{0x00094264, "FSCTL_OFFLOAD_READ"},			      /* dissector implemented */
2147 	{0x00098098, "FSCTL_SET_OBJECT_ID"},			      /* dissector implemented */
2148 	{0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
2149 	{0x000980A4, "FSCTL_SET_REPARSE_POINT"},
2150 	{0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
2151 	{0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},		      /* dissector implemented */
2152 	{0x000980C8, "FSCTL_SET_ZERO_DATA"},			      /* dissector implemented */
2153 	{0x000980D0, "FSCTL_ENABLE_UPGRADE"},
2154 	{0x00098208, "FSCTL_FILE_LEVEL_TRIM"},
2155 	{0x00098268, "FSCTL_OFFLOAD_WRITE"},			      /* dissector implemented */
2156 	{0x0009C040, "FSCTL_SET_COMPRESSION"},			      /* dissector implemented */
2157 	{0x0009C280, "FSCTL_SET_INTEGRITY_INFORMATION"},	      /* dissector implemented */
2158 	{0x00110018, "FSCTL_PIPE_WAIT"},			      /* dissector implemented */
2159 	{0x0011400C, "FSCTL_PIPE_PEEK"},
2160 	{0x0011C017, "FSCTL_PIPE_TRANSCEIVE"},			      /* dissector implemented */
2161 	{0x00140078, "FSCTL_SRV_REQUEST_RESUME_KEY"},
2162 	{0x001401D4, "FSCTL_LMR_REQUEST_RESILIENCY"},		      /* dissector implemented */
2163 	{0x001401FC, "FSCTL_QUERY_NETWORK_INTERFACE_INFO"},	      /* dissector implemented */
2164 	{0x00140200, "FSCTL_VALIDATE_NEGOTIATE_INFO_224"},	      /* dissector implemented */
2165 	{0x00140204, "FSCTL_VALIDATE_NEGOTIATE_INFO"},		      /* dissector implemented */
2166 	{0x00144064, "FSCTL_SRV_ENUMERATE_SNAPSHOTS"},		      /* dissector implemented */
2167 	{0x001440F2, "FSCTL_SRV_COPYCHUNK"},
2168 	{0x001441bb, "FSCTL_SRV_READ_HASH"},
2169 	{0x001480F2, "FSCTL_SRV_COPYCHUNK_WRITE"},
2170 	{ 0, NULL }
2171 };
2172 static value_string_ext smb2_ioctl_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_vals);
2173 
2174 static const value_string smb2_ioctl_device_vals[] = {
2175 	{ 0x0001, "BEEP" },
2176 	{ 0x0002, "CD_ROM" },
2177 	{ 0x0003, "CD_ROM_FILE_SYSTEM" },
2178 	{ 0x0004, "CONTROLLER" },
2179 	{ 0x0005, "DATALINK" },
2180 	{ 0x0006, "DFS" },
2181 	{ 0x0007, "DISK" },
2182 	{ 0x0008, "DISK_FILE_SYSTEM" },
2183 	{ 0x0009, "FILE_SYSTEM" },
2184 	{ 0x000a, "INPORT_PORT" },
2185 	{ 0x000b, "KEYBOARD" },
2186 	{ 0x000c, "MAILSLOT" },
2187 	{ 0x000d, "MIDI_IN" },
2188 	{ 0x000e, "MIDI_OUT" },
2189 	{ 0x000f, "MOUSE" },
2190 	{ 0x0010, "MULTI_UNC_PROVIDER" },
2191 	{ 0x0011, "NAMED_PIPE" },
2192 	{ 0x0012, "NETWORK" },
2193 	{ 0x0013, "NETWORK_BROWSER" },
2194 	{ 0x0014, "NETWORK_FILE_SYSTEM" },
2195 	{ 0x0015, "NULL" },
2196 	{ 0x0016, "PARALLEL_PORT" },
2197 	{ 0x0017, "PHYSICAL_NETCARD" },
2198 	{ 0x0018, "PRINTER" },
2199 	{ 0x0019, "SCANNER" },
2200 	{ 0x001a, "SERIAL_MOUSE_PORT" },
2201 	{ 0x001b, "SERIAL_PORT" },
2202 	{ 0x001c, "SCREEN" },
2203 	{ 0x001d, "SOUND" },
2204 	{ 0x001e, "STREAMS" },
2205 	{ 0x001f, "TAPE" },
2206 	{ 0x0020, "TAPE_FILE_SYSTEM" },
2207 	{ 0x0021, "TRANSPORT" },
2208 	{ 0x0022, "UNKNOWN" },
2209 	{ 0x0023, "VIDEO" },
2210 	{ 0x0024, "VIRTUAL_DISK" },
2211 	{ 0x0025, "WAVE_IN" },
2212 	{ 0x0026, "WAVE_OUT" },
2213 	{ 0x0027, "8042_PORT" },
2214 	{ 0x0028, "NETWORK_REDIRECTOR" },
2215 	{ 0x0029, "BATTERY" },
2216 	{ 0x002a, "BUS_EXTENDER" },
2217 	{ 0x002b, "MODEM" },
2218 	{ 0x002c, "VDM" },
2219 	{ 0x002d, "MASS_STORAGE" },
2220 	{ 0x002e, "SMB" },
2221 	{ 0x002f, "KS" },
2222 	{ 0x0030, "CHANGER" },
2223 	{ 0x0031, "SMARTCARD" },
2224 	{ 0x0032, "ACPI" },
2225 	{ 0x0033, "DVD" },
2226 	{ 0x0034, "FULLSCREEN_VIDEO" },
2227 	{ 0x0035, "DFS_FILE_SYSTEM" },
2228 	{ 0x0036, "DFS_VOLUME" },
2229 	{ 0x0037, "SERENUM" },
2230 	{ 0x0038, "TERMSRV" },
2231 	{ 0x0039, "KSEC" },
2232 	{ 0, NULL }
2233 };
2234 static value_string_ext smb2_ioctl_device_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_device_vals);
2235 
2236 static const value_string smb2_ioctl_access_vals[] = {
2237 	{ 0x00, "FILE_ANY_ACCESS" },
2238 	{ 0x01, "FILE_READ_ACCESS" },
2239 	{ 0x02, "FILE_WRITE_ACCESS" },
2240 	{ 0x03, "FILE_READ_WRITE_ACCESS" },
2241 	{ 0, NULL }
2242 };
2243 
2244 static const value_string smb2_ioctl_method_vals[] = {
2245 	{ 0x00, "METHOD_BUFFERED" },
2246 	{ 0x01, "METHOD_IN_DIRECT" },
2247 	{ 0x02, "METHOD_OUT_DIRECT" },
2248 	{ 0x03, "METHOD_NEITHER" },
2249 	{ 0, NULL }
2250 };
2251 
2252 static const value_string smb2_ioctl_shared_virtual_disk_vals[] = {
2253 	{ 0x01, "SharedVirtualDisksSupported" },
2254 	{ 0x07, "SharedVirtualDiskCDPSnapshotsSupported" },
2255 	{ 0, NULL }
2256 };
2257 
2258 static const value_string smb2_ioctl_shared_virtual_disk_hstate_vals[] = {
2259 	{ 0x00, "HandleStateNone" },
2260 	{ 0x01, "HandleStateFileShared" },
2261 	{ 0x03, "HandleStateShared" },
2262 	{ 0, NULL }
2263 };
2264 
2265 /* this is called from both smb and smb2. */
2266 int
dissect_smb2_ioctl_function(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint32 * ioctlfunc)2267 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
2268 {
2269 	proto_item *item = NULL;
2270 	proto_tree *tree = NULL;
2271 	guint32     ioctl_function;
2272 
2273 	if (parent_tree) {
2274 		item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2275 		tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
2276 	}
2277 
2278 	ioctl_function = tvb_get_letohl(tvb, offset);
2279 	if (ioctlfunc)
2280 		*ioctlfunc = ioctl_function;
2281 	if (ioctl_function) {
2282 		const gchar *unknown = "unknown";
2283 		const gchar *ioctl_name = val_to_str_ext_const(ioctl_function,
2284 							       &smb2_ioctl_vals_ext,
2285 							       unknown);
2286 
2287 		/*
2288 		 * val_to_str_const() doesn't work with a unknown == NULL
2289 		 */
2290 		if (ioctl_name == unknown) {
2291 			ioctl_name = NULL;
2292 		}
2293 
2294 		if (ioctl_name != NULL) {
2295 			col_append_fstr(
2296 				pinfo->cinfo, COL_INFO, " %s", ioctl_name);
2297 		}
2298 
2299 		/* device */
2300 		proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2301 		if (ioctl_name == NULL) {
2302 			col_append_fstr(
2303 				pinfo->cinfo, COL_INFO, " %s",
2304 				val_to_str_ext((ioctl_function>>16)&0xffff, &smb2_ioctl_device_vals_ext,
2305 				"Unknown (0x%08X)"));
2306 		}
2307 
2308 		/* access */
2309 		proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2310 
2311 		/* function */
2312 		proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2313 		if (ioctl_name == NULL) {
2314 			col_append_fstr(
2315 				pinfo->cinfo, COL_INFO, " Function:0x%04x",
2316 				(ioctl_function>>2)&0x0fff);
2317 		}
2318 
2319 		/* method */
2320 		proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2321 	}
2322 
2323 	offset += 4;
2324 
2325 	return offset;
2326 }
2327 
2328 /* fake the dce/rpc support structures so we can piggy back on
2329  * dissect_nt_policy_hnd()   since this will allow us
2330  * a cheap way to track where FIDs are opened, closed
2331  * and fid->filename mappings
2332  * if we want to do those things in the future.
2333  */
2334 #define FID_MODE_OPEN		0
2335 #define FID_MODE_CLOSE		1
2336 #define FID_MODE_USE		2
2337 #define FID_MODE_DHNQ		3
2338 #define FID_MODE_DHNC		4
2339 static int
dissect_smb2_fid(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si,int mode)2340 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
2341 {
2342 	guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2343 	static dcerpc_info        di; /* fake dcerpc_info struct */
2344 	static dcerpc_call_value  call_data;
2345 	e_ctx_hnd   policy_hnd;
2346 	e_ctx_hnd   *policy_hnd_hashtablekey;
2347 	proto_item *hnd_item   = NULL;
2348 	char       *fid_name;
2349 	guint32     open_frame = 0, close_frame = 0;
2350 	smb2_eo_file_info_t	*eo_file_info;
2351 	smb2_fid_info_t sfi_key;
2352 	smb2_fid_info_t *sfi = NULL;
2353 
2354 	memset(&sfi_key, 0, sizeof(sfi_key));
2355 	sfi_key.fid_persistent = tvb_get_letoh64(tvb, offset);
2356 	sfi_key.fid_volatile = tvb_get_letoh64(tvb, offset+8);
2357 	sfi_key.sesid = si->sesid;
2358 	sfi_key.tid = si->tid;
2359 	sfi_key.frame_key = pinfo->num;
2360 	sfi_key.name = NULL;
2361 
2362 	di.conformant_run = 0;
2363 	/* we need di->call_data->flags.NDR64 == 0 */
2364 	di.call_data = &call_data;
2365 
2366 	switch (mode) {
2367 	case FID_MODE_OPEN:
2368 		offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
2369 		if (!pinfo->fd->visited) {
2370 			sfi = wmem_new(wmem_file_scope(), smb2_fid_info_t);
2371 			*sfi = sfi_key;
2372 			sfi->frame_key = 0;
2373 			sfi->frame_beg = si->saved ? si->saved->frame_req : pinfo->num;
2374 			sfi->frame_end = G_MAXUINT32;
2375 
2376 			if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
2377 				sfi->name = wmem_strdup(wmem_file_scope(), (char *)si->saved->extra_info);
2378 			} else {
2379 				sfi->name = wmem_strdup_printf(wmem_file_scope(), "[unknown]");
2380 			}
2381 
2382 			if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
2383 				fid_name = wmem_strdup_printf(wmem_file_scope(), "File: %s", (char *)si->saved->extra_info);
2384 			} else {
2385 				fid_name = wmem_strdup_printf(wmem_file_scope(), "File: ");
2386 			}
2387 			dcerpc_store_polhnd_name(&policy_hnd, pinfo,
2388 						  fid_name);
2389 
2390 			wmem_map_insert(si->session->fids, sfi, sfi);
2391 			si->file = sfi;
2392 
2393 			/* If needed, create the file entry and save the policy hnd */
2394 			if (si->saved) {
2395 				si->saved->file = sfi;
2396 				si->saved->policy_hnd = policy_hnd;
2397 			}
2398 
2399 			if (si->conv) {
2400 				eo_file_info = (smb2_eo_file_info_t *)wmem_map_lookup(si->session->files,&policy_hnd);
2401 				if (!eo_file_info) {
2402 					eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
2403 					policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
2404 					memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
2405 					eo_file_info->end_of_file=0;
2406 					wmem_map_insert(si->session->files,policy_hnd_hashtablekey,eo_file_info);
2407 				}
2408 				si->eo_file_info=eo_file_info;
2409 			}
2410 		}
2411 		break;
2412 	case FID_MODE_CLOSE:
2413 		if (!pinfo->fd->visited) {
2414 			smb2_fid_info_t *fid = (smb2_fid_info_t *)wmem_map_lookup(si->session->fids, &sfi_key);
2415 			if (fid) {
2416 				/* set last frame */
2417 				fid->frame_end = pinfo->num;
2418 			}
2419 		}
2420 		offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
2421 		break;
2422 	case FID_MODE_USE:
2423 	case FID_MODE_DHNQ:
2424 	case FID_MODE_DHNC:
2425 		offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
2426 		break;
2427 	}
2428 
2429 	si->file = (smb2_fid_info_t *)wmem_map_lookup(si->session->fids, &sfi_key);
2430 	if (si->file) {
2431 		if (si->saved) {
2432 			si->saved->file = si->file;
2433 		}
2434 		if (si->file->name) {
2435 			if (hnd_item) {
2436 				proto_item_append_text(hnd_item, " File: %s", si->file->name);
2437 			}
2438 			col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", si->file->name);
2439 		}
2440 	}
2441 
2442 	if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
2443 		/* look for the eo_file_info */
2444 		if (!si->eo_file_info) {
2445 			if (si->saved) { si->saved->policy_hnd = policy_hnd; }
2446 			if (si->conv) {
2447 				eo_file_info = (smb2_eo_file_info_t *)wmem_map_lookup(si->session->files,&policy_hnd);
2448 				if (eo_file_info) {
2449 					si->eo_file_info=eo_file_info;
2450 				} else { /* XXX This should never happen */
2451 					eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
2452 					policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
2453 					memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
2454 					eo_file_info->end_of_file=0;
2455 					wmem_map_insert(si->session->files,policy_hnd_hashtablekey,eo_file_info);
2456 				}
2457 			}
2458 
2459 		}
2460 	}
2461 
2462 	return offset;
2463 }
2464 
2465 #define SMB2_FSCC_FILE_ATTRIBUTE_READ_ONLY			0x00000001
2466 #define SMB2_FSCC_FILE_ATTRIBUTE_HIDDEN				0x00000002
2467 #define SMB2_FSCC_FILE_ATTRIBUTE_SYSTEM				0x00000004
2468 #define SMB2_FSCC_FILE_ATTRIBUTE_DIRECTORY			0x00000010
2469 #define SMB2_FSCC_FILE_ATTRIBUTE_ARCHIVE			0x00000020
2470 #define SMB2_FSCC_FILE_ATTRIBUTE_NORMAL				0x00000080
2471 #define SMB2_FSCC_FILE_ATTRIBUTE_TEMPORARY			0x00000100
2472 #define SMB2_FSCC_FILE_ATTRIBUTE_SPARSE_FILE			0x00000200
2473 #define SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT			0x00000400
2474 #define SMB2_FSCC_FILE_ATTRIBUTE_COMPRESSED			0x00000800
2475 #define SMB2_FSCC_FILE_ATTRIBUTE_OFFLINE			0x00001000
2476 #define SMB2_FSCC_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED		0x00002000
2477 #define SMB2_FSCC_FILE_ATTRIBUTE_ENCRYPTED			0x00004000
2478 #define SMB2_FSCC_FILE_ATTRIBUTE_INTEGRITY_STREAM		0x00008000
2479 #define SMB2_FSCC_FILE_ATTRIBUTE_NO_SCRUB_DATA			0x00020000
2480 
2481 
2482 static const true_false_string tfs_fscc_file_attribute_reparse = {
2483 	"Has an associated REPARSE POINT",
2484 	"Does NOT have an associated reparse point"
2485 };
2486 static const true_false_string tfs_fscc_file_attribute_compressed = {
2487 	"COMPRESSED",
2488 	"Uncompressed"
2489 };
2490 static const true_false_string tfs_fscc_file_attribute_offline = {
2491 	"OFFLINE",
2492 	"Online"
2493 };
2494 static const true_false_string tfs_fscc_file_attribute_not_content_indexed = {
2495 	"Is not indexed by the content indexing service",
2496 	"Is indexed by the content indexing service"
2497 };
2498 static const true_false_string tfs_fscc_file_attribute_integrity_stream = {
2499 	"Has Integrity Support",
2500 	"Does NOT have Integrity Support"
2501 };
2502 static const true_false_string tfs_fscc_file_attribute_no_scrub_data = {
2503 	"Is excluded from the data integrity scan",
2504 	"Is not excluded from the data integrity scan"
2505 };
2506 
2507 /*
2508  * File Attributes, section 2.6 in the [MS-FSCC] spec
2509  */
2510 static int
dissect_fscc_file_attr(tvbuff_t * tvb,proto_tree * parent_tree,int offset,guint32 * attr)2511 dissect_fscc_file_attr(tvbuff_t* tvb, proto_tree* parent_tree, int offset, guint32* attr)
2512 {
2513 	guint32 mask = tvb_get_letohl(tvb, offset);
2514 	static int* const mask_fields[] = {
2515 		&hf_smb2_fscc_file_attr_read_only,
2516 		&hf_smb2_fscc_file_attr_hidden,
2517 		&hf_smb2_fscc_file_attr_system,
2518 		&hf_smb2_fscc_file_attr_directory,
2519 		&hf_smb2_fscc_file_attr_archive,
2520 		&hf_smb2_fscc_file_attr_normal,
2521 		&hf_smb2_fscc_file_attr_temporary,
2522 		&hf_smb2_fscc_file_attr_sparse_file,
2523 		&hf_smb2_fscc_file_attr_reparse_point,
2524 		&hf_smb2_fscc_file_attr_compressed,
2525 		&hf_smb2_fscc_file_attr_offline,
2526 		&hf_smb2_fscc_file_attr_not_content_indexed,
2527 		&hf_smb2_fscc_file_attr_encrypted,
2528 		&hf_smb2_fscc_file_attr_integrity_stream,
2529 		&hf_smb2_fscc_file_attr_no_scrub_data,
2530 		NULL
2531 	};
2532 
2533 	proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset, hf_smb2_fscc_file_attr, ett_smb2_fscc_file_attributes, mask_fields, mask, BMT_NO_APPEND);
2534 
2535 	offset += 4;
2536 
2537 	if (attr)
2538 		*attr = mask;
2539 
2540 	return offset;
2541 }
2542 
2543 /* this info level is unique to SMB2 and differst from the corresponding
2544  * SMB_FILE_ALL_INFO in SMB
2545  */
2546 static int
dissect_smb2_file_all_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2547 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2548 {
2549 	proto_item *item = NULL;
2550 	proto_tree *tree = NULL;
2551 	int         length;
2552 	static int * const mode_fields[] = {
2553 		&hf_smb2_mode_file_write_through,
2554 		&hf_smb2_mode_file_sequential_only,
2555 		&hf_smb2_mode_file_no_intermediate_buffering,
2556 		&hf_smb2_mode_file_synchronous_io_alert,
2557 		&hf_smb2_mode_file_synchronous_io_nonalert,
2558 		&hf_smb2_mode_file_delete_on_close,
2559 		NULL,
2560 	};
2561 
2562 	if (parent_tree) {
2563 		item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
2564 		tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
2565 	}
2566 
2567 	/* create time */
2568 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2569 
2570 	/* last access */
2571 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2572 
2573 	/* last write */
2574 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2575 
2576 	/* last change */
2577 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2578 
2579 	/* File Attributes */
2580 	offset = dissect_fscc_file_attr(tvb, tree, offset, NULL);
2581 
2582 	/* some unknown bytes */
2583 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2584 	offset += 4;
2585 
2586 	/* allocation size */
2587 	proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2588 	offset += 8;
2589 
2590 	/* end of file */
2591 	proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2592 	offset += 8;
2593 
2594 	/* number of links */
2595 	proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2596 	offset += 4;
2597 
2598 	/* delete pending */
2599 	proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2600 	offset += 1;
2601 
2602 	/* is directory */
2603 	proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2604 	offset += 1;
2605 
2606 	/* padding */
2607 	offset += 2;
2608 
2609 	/* file id */
2610 	proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2611 	offset += 8;
2612 
2613 	/* ea size */
2614 	proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2615 	offset += 4;
2616 
2617 	/* access mask */
2618 	offset = dissect_smb_access_mask(tvb, tree, offset);
2619 
2620 	/* Position Information */
2621 	proto_tree_add_item(tree, hf_smb2_position_information, tvb, offset, 8, ENC_NA);
2622 	offset += 8;
2623 
2624 	/* Mode Information */
2625 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_mode_information, ett_smb2_file_mode_info, mode_fields, ENC_LITTLE_ENDIAN);
2626 	offset += 4;
2627 
2628 	/* Alignment Information */
2629 	proto_tree_add_item(tree, hf_smb2_alignment_information, tvb, offset, 4, ENC_NA);
2630 	offset +=4;
2631 
2632 	/* file name length */
2633 	length = tvb_get_letohs(tvb, offset);
2634 	proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2635 	offset += 4;
2636 
2637 	/* file name */
2638 	if (length) {
2639 		proto_tree_add_item(tree, hf_smb2_filename,
2640 		    tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
2641 		offset += length;
2642 	}
2643 
2644 	return offset;
2645 }
2646 
2647 
2648 static int
dissect_smb2_file_allocation_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2649 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2650 {
2651 	proto_item *item = NULL;
2652 	proto_tree *tree = NULL;
2653 	guint16     bc;
2654 	gboolean    trunc;
2655 
2656 	if (parent_tree) {
2657 		item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, ENC_NA);
2658 		tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
2659 	}
2660 
2661 	bc = tvb_captured_length_remaining(tvb, offset);
2662 	offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2663 
2664 	return offset;
2665 }
2666 
2667 static int
dissect_smb2_file_endoffile_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2668 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2669 {
2670 	proto_item *item = NULL;
2671 	proto_tree *tree = NULL;
2672 	guint16     bc;
2673 	gboolean    trunc;
2674 
2675 	if (parent_tree) {
2676 		item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, ENC_NA);
2677 		tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
2678 	}
2679 
2680 	bc = tvb_captured_length_remaining(tvb, offset);
2681 	offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2682 
2683 	return offset;
2684 }
2685 
2686 static int
dissect_smb2_file_alternate_name_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2687 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2688 {
2689 	proto_item *item = NULL;
2690 	proto_tree *tree = NULL;
2691 	guint16     bc;
2692 	gboolean    trunc;
2693 
2694 	if (parent_tree) {
2695 		item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, ENC_NA);
2696 		tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
2697 	}
2698 
2699 	bc = tvb_captured_length_remaining(tvb, offset);
2700 	offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
2701 
2702 	return offset;
2703 }
2704 
2705 static int
dissect_smb2_file_normalized_name_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2706 dissect_smb2_file_normalized_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2707 {
2708 	proto_item *item = NULL;
2709 	proto_tree *tree = NULL;
2710 	guint16     bc;
2711 	gboolean    trunc;
2712 
2713 	if (parent_tree) {
2714 		item = proto_tree_add_item(parent_tree, hf_smb2_file_normalized_name_info, tvb, offset, -1, ENC_NA);
2715 		tree = proto_item_add_subtree(item, ett_smb2_file_normalized_name_info);
2716 	}
2717 
2718 	bc = tvb_captured_length_remaining(tvb, offset);
2719 	offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
2720 
2721 	return offset;
2722 }
2723 
2724 static int
dissect_smb2_file_basic_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2725 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2726 {
2727 	proto_item *item = NULL;
2728 	proto_tree *tree = NULL;
2729 
2730 	if (parent_tree) {
2731 		item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, ENC_NA);
2732 		tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
2733 	}
2734 
2735 	/* create time */
2736 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2737 
2738 	/* last access */
2739 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2740 
2741 	/* last write */
2742 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2743 
2744 	/* last change */
2745 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2746 
2747 	/* File Attributes */
2748 	offset = dissect_fscc_file_attr(tvb, tree, offset, NULL);
2749 
2750 	/* some unknown bytes */
2751 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2752 	offset += 4;
2753 
2754 	return offset;
2755 }
2756 
2757 static int
dissect_smb2_file_standard_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2758 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2759 {
2760 	proto_item *item = NULL;
2761 	proto_tree *tree = NULL;
2762 	guint16     bc;
2763 	gboolean    trunc;
2764 
2765 	if (parent_tree) {
2766 		item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, ENC_NA);
2767 		tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
2768 	}
2769 
2770 	bc = tvb_captured_length_remaining(tvb, offset);
2771 	offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2772 
2773 	return offset;
2774 }
2775 static int
dissect_smb2_file_internal_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2776 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2777 {
2778 	proto_item *item = NULL;
2779 	proto_tree *tree = NULL;
2780 	guint16     bc;
2781 	gboolean    trunc;
2782 
2783 	if (parent_tree) {
2784 		item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, ENC_NA);
2785 		tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
2786 	}
2787 
2788 	bc = tvb_captured_length_remaining(tvb, offset);
2789 	offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2790 
2791 	return offset;
2792 }
2793 static int
dissect_smb2_file_mode_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2794 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2795 {
2796 	proto_item *item = NULL;
2797 	proto_tree *tree = NULL;
2798 	guint16     bc;
2799 	gboolean    trunc;
2800 
2801 	if (parent_tree) {
2802 		item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, ENC_NA);
2803 		tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
2804 	}
2805 
2806 	bc = tvb_captured_length_remaining(tvb, offset);
2807 	offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2808 
2809 	return offset;
2810 }
2811 static int
dissect_smb2_file_alignment_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2812 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2813 {
2814 	proto_item *item = NULL;
2815 	proto_tree *tree = NULL;
2816 	guint16     bc;
2817 	gboolean    trunc;
2818 
2819 	if (parent_tree) {
2820 		item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, ENC_NA);
2821 		tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
2822 	}
2823 
2824 	bc = tvb_captured_length_remaining(tvb, offset);
2825 	offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2826 
2827 	return offset;
2828 }
2829 static int
dissect_smb2_file_position_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2830 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2831 {
2832 	proto_item *item = NULL;
2833 	proto_tree *tree = NULL;
2834 	guint16     bc;
2835 	gboolean    trunc;
2836 
2837 	if (parent_tree) {
2838 		item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, ENC_NA);
2839 		tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
2840 	}
2841 
2842 	bc = tvb_captured_length_remaining(tvb, offset);
2843 	offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2844 
2845 	return offset;
2846 }
2847 
2848 static int
dissect_smb2_file_access_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2849 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2850 {
2851 	proto_item *item = NULL;
2852 	proto_tree *tree = NULL;
2853 
2854 	if (parent_tree) {
2855 		item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, ENC_NA);
2856 		tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
2857 	}
2858 
2859 	/* access mask */
2860 	offset = dissect_smb_access_mask(tvb, tree, offset);
2861 
2862 	return offset;
2863 }
2864 
2865 static int
dissect_smb2_file_ea_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2866 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2867 {
2868 	proto_item *item = NULL;
2869 	proto_tree *tree = NULL;
2870 	guint16     bc;
2871 	gboolean    trunc;
2872 
2873 	if (parent_tree) {
2874 		item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, ENC_NA);
2875 		tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
2876 	}
2877 
2878 	bc = tvb_captured_length_remaining(tvb, offset);
2879 	offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2880 
2881 	return offset;
2882 }
2883 
2884 static int
dissect_smb2_file_stream_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2885 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2886 {
2887 	proto_item *item = NULL;
2888 	proto_tree *tree = NULL;
2889 	guint16     bc;
2890 	gboolean    trunc;
2891 
2892 	if (parent_tree) {
2893 		item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, ENC_NA);
2894 		tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
2895 	}
2896 
2897 	bc = tvb_captured_length_remaining(tvb, offset);
2898 	offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
2899 
2900 	return offset;
2901 }
2902 
2903 static int
dissect_smb2_file_pipe_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2904 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2905 {
2906 	proto_item *item = NULL;
2907 	proto_tree *tree = NULL;
2908 	guint16     bc;
2909 	gboolean    trunc;
2910 
2911 	if (parent_tree) {
2912 		item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, ENC_NA);
2913 		tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
2914 	}
2915 
2916 	bc = tvb_captured_length_remaining(tvb, offset);
2917 	offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2918 
2919 	return offset;
2920 }
2921 
2922 static int
dissect_smb2_file_compression_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2923 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2924 {
2925 	proto_item *item = NULL;
2926 	proto_tree *tree = NULL;
2927 	guint16     bc;
2928 	gboolean    trunc;
2929 
2930 	if (parent_tree) {
2931 		item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, ENC_NA);
2932 		tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
2933 	}
2934 
2935 	bc = tvb_captured_length_remaining(tvb, offset);
2936 	offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2937 
2938 	return offset;
2939 }
2940 
2941 static int
dissect_smb2_file_network_open_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2942 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2943 {
2944 	proto_item *item = NULL;
2945 	proto_tree *tree = NULL;
2946 	guint16     bc;
2947 	gboolean    trunc;
2948 
2949 	if (parent_tree) {
2950 		item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, ENC_NA);
2951 		tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
2952 	}
2953 
2954 
2955 	bc = tvb_captured_length_remaining(tvb, offset);
2956 	offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2957 
2958 	return offset;
2959 }
2960 
2961 static int
dissect_smb2_file_attribute_tag_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2962 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2963 {
2964 	proto_item *item = NULL;
2965 	proto_tree *tree = NULL;
2966 	guint16     bc;
2967 	gboolean    trunc;
2968 
2969 	if (parent_tree) {
2970 		item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, ENC_NA);
2971 		tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
2972 	}
2973 
2974 
2975 	bc = tvb_captured_length_remaining(tvb, offset);
2976 	offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2977 
2978 	return offset;
2979 }
2980 
2981 static const true_false_string tfs_disposition_delete_on_close = {
2982 	"DELETE this file when closed",
2983 	"Normal access, do not delete on close"
2984 };
2985 
2986 static int
dissect_smb2_file_disposition_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)2987 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2988 {
2989 	proto_item *item = NULL;
2990 	proto_tree *tree = NULL;
2991 
2992 	if (parent_tree) {
2993 		item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, ENC_NA);
2994 		tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
2995 	}
2996 
2997 	/* file disposition */
2998 	proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2999 
3000 	return offset;
3001 }
3002 
3003 static int
dissect_smb2_file_full_ea_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3004 dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3005 {
3006 	proto_item *item = NULL;
3007 	proto_tree *tree = NULL;
3008 	guint32     next_offset;
3009 	guint8      ea_name_len;
3010 	guint16     ea_data_len;
3011 
3012 	if (parent_tree) {
3013 		item = proto_tree_add_item(parent_tree, hf_smb2_file_full_ea_info, tvb, offset, -1, ENC_NA);
3014 		tree = proto_item_add_subtree(item, ett_smb2_file_full_ea_info);
3015 	}
3016 
3017 	while (1) {
3018 		char *name = NULL;
3019 		char *data = NULL;
3020 		int start_offset = offset;
3021 		proto_item *ea_item;
3022 		proto_tree *ea_tree;
3023 
3024 		ea_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_ea, &ea_item, "EA:");
3025 
3026 		/* next offset */
3027 		next_offset = tvb_get_letohl(tvb, offset);
3028 		proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3029 		offset += 4;
3030 
3031 		/* EA flags */
3032 		proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3033 		offset += 1;
3034 
3035 		/* EA Name Length */
3036 		ea_name_len = tvb_get_guint8(tvb, offset);
3037 		proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3038 		offset += 1;
3039 
3040 		/* EA Data Length */
3041 		ea_data_len = tvb_get_letohs(tvb, offset);
3042 		proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3043 		offset += 2;
3044 
3045 		/* ea name */
3046 		if (ea_name_len) {
3047 			proto_tree_add_item_ret_display_string(ea_tree, hf_smb2_ea_name,
3048 				tvb, offset, ea_name_len, ENC_ASCII|ENC_NA,
3049 				pinfo->pool, &name);
3050 		}
3051 
3052 		/* The name is terminated with a NULL */
3053 		offset += ea_name_len + 1;
3054 
3055 		/* ea data */
3056 		if (ea_data_len) {
3057 			proto_tree_add_item_ret_display_string(ea_tree, hf_smb2_ea_data,
3058 				tvb, offset, ea_data_len, ENC_NA,
3059 				pinfo->pool, &data);
3060 		}
3061 		offset += ea_data_len;
3062 
3063 
3064 		if (ea_item) {
3065 			proto_item_append_text(ea_item, " %s := %s",
3066 			    name ? name : "",
3067 			    data ? data : "");
3068 		}
3069 		proto_item_set_len(ea_item, offset-start_offset);
3070 
3071 
3072 		if (!next_offset) {
3073 			break;
3074 		}
3075 
3076 		offset = start_offset+next_offset;
3077 	}
3078 
3079 	return offset;
3080 }
3081 
3082 static const true_false_string tfs_replace_if_exists = {
3083 	"Replace the target if it exists",
3084 	"Fail if the target exists"
3085 };
3086 
3087 static int
dissect_smb2_file_rename_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3088 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3089 {
3090 	proto_item *item = NULL;
3091 	proto_tree *tree = NULL;
3092 	int         length;
3093 
3094 
3095 	if (parent_tree) {
3096 		item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, ENC_NA);
3097 		tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
3098 	}
3099 
3100 	/* ReplaceIfExists */
3101 	proto_tree_add_item(tree, hf_smb2_replace_if, tvb, offset, 1, ENC_NA);
3102 	offset += 1;
3103 
3104 	/* reserved */
3105 	proto_tree_add_item(tree, hf_smb2_reserved_random, tvb, offset, 7, ENC_NA);
3106 	offset += 7;
3107 
3108 	/* Root Directory Handle, MBZ */
3109 	proto_tree_add_item(tree, hf_smb2_root_directory_mbz, tvb, offset, 8, ENC_NA);
3110 	offset += 8;
3111 
3112 	/* file name length */
3113 	length = tvb_get_letohs(tvb, offset);
3114 	proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3115 	offset += 4;
3116 
3117 	/* file name */
3118 	if (length) {
3119 		char *display_string;
3120 
3121 		proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
3122 		    tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN,
3123 		    pinfo->pool, &display_string);
3124 		col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s",
3125 		    display_string);
3126 		offset += length;
3127 	}
3128 
3129 	return offset;
3130 }
3131 
3132 static int
dissect_smb2_sec_info_00(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3133 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3134 {
3135 	proto_item *item = NULL;
3136 	proto_tree *tree = NULL;
3137 
3138 	if (parent_tree) {
3139 		item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, ENC_NA);
3140 		tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
3141 	}
3142 
3143 	/* security descriptor */
3144 	offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_captured_length_remaining(tvb, offset), NULL);
3145 
3146 	return offset;
3147 }
3148 
3149 static int
dissect_smb2_quota_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3150 dissect_smb2_quota_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3151 {
3152 	proto_item *item = NULL;
3153 	proto_tree *tree = NULL;
3154 	guint16 bcp;
3155 
3156 	if (parent_tree) {
3157 		item = proto_tree_add_item(parent_tree, hf_smb2_quota_info, tvb, offset, -1, ENC_NA);
3158 		tree = proto_item_add_subtree(item, ett_smb2_quota_info);
3159 	}
3160 
3161 	bcp = tvb_captured_length_remaining(tvb, offset);
3162 	offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
3163 
3164 	return offset;
3165 }
3166 
3167 static int
dissect_smb2_fs_info_05(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3168 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3169 {
3170 	proto_item *item = NULL;
3171 	proto_tree *tree = NULL;
3172 	guint16     bc;
3173 
3174 	if (parent_tree) {
3175 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, ENC_NA);
3176 		tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
3177 	}
3178 
3179 	bc = tvb_captured_length_remaining(tvb, offset);
3180 	offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc);
3181 
3182 	return offset;
3183 }
3184 
3185 static int
dissect_smb2_fs_info_06(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3186 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3187 {
3188 	proto_item *item = NULL;
3189 	proto_tree *tree = NULL;
3190 	guint16     bc;
3191 
3192 	if (parent_tree) {
3193 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, ENC_NA);
3194 		tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
3195 	}
3196 
3197 	bc = tvb_captured_length_remaining(tvb, offset);
3198 	offset = dissect_nt_quota(tvb, tree, offset, &bc);
3199 
3200 	return offset;
3201 }
3202 
3203 static int
dissect_smb2_FS_OBJECTID_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3204 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3205 {
3206 	proto_item *item = NULL;
3207 	proto_tree *tree = NULL;
3208 
3209 	if (parent_tree) {
3210 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, ENC_NA);
3211 		tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
3212 	}
3213 
3214 	/* FILE_OBJECTID_BUFFER */
3215 	offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
3216 
3217 	return offset;
3218 }
3219 
3220 static int
dissect_smb2_fs_info_07(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3221 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3222 {
3223 	proto_item *item = NULL;
3224 	proto_tree *tree = NULL;
3225 	guint16     bc;
3226 
3227 	if (parent_tree) {
3228 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, ENC_NA);
3229 		tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
3230 	}
3231 
3232 	bc = tvb_captured_length_remaining(tvb, offset);
3233 	offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
3234 
3235 	return offset;
3236 }
3237 
3238 static int
dissect_smb2_fs_info_01(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3239 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3240 {
3241 	proto_item *item = NULL;
3242 	proto_tree *tree = NULL;
3243 	guint16     bc;
3244 
3245 	if (parent_tree) {
3246 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, ENC_NA);
3247 		tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
3248 	}
3249 
3250 
3251 	bc = tvb_captured_length_remaining(tvb, offset);
3252 	offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
3253 
3254 	return offset;
3255 }
3256 
3257 static int
dissect_smb2_fs_info_03(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3258 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3259 {
3260 	proto_item *item = NULL;
3261 	proto_tree *tree = NULL;
3262 	guint16     bc;
3263 
3264 	if (parent_tree) {
3265 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, ENC_NA);
3266 		tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
3267 	}
3268 
3269 
3270 	bc = tvb_captured_length_remaining(tvb, offset);
3271 	offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
3272 
3273 	return offset;
3274 }
3275 
3276 static int
dissect_smb2_fs_info_04(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3277 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3278 {
3279 	proto_item *item = NULL;
3280 	proto_tree *tree = NULL;
3281 	guint16     bc;
3282 
3283 	if (parent_tree) {
3284 		item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, ENC_NA);
3285 		tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
3286 	}
3287 
3288 
3289 	bc = tvb_captured_length_remaining(tvb, offset);
3290 	offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
3291 
3292 	return offset;
3293 }
3294 
3295 static const value_string oplock_vals[] = {
3296 	{ 0x00, "No oplock" },
3297 	{ 0x01, "Level2 oplock" },
3298 	{ 0x08, "Exclusive oplock" },
3299 	{ 0x09, "Batch oplock" },
3300 	{ 0xff, "Lease" },
3301 	{ 0, NULL }
3302 };
3303 
3304 static int
dissect_smb2_oplock(proto_tree * parent_tree,tvbuff_t * tvb,int offset)3305 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3306 {
3307 	proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3308 
3309 	offset += 1;
3310 	return offset;
3311 }
3312 
3313 static int
dissect_smb2_buffercode(proto_tree * parent_tree,tvbuff_t * tvb,int offset,guint16 * length)3314 dissect_smb2_buffercode(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 *length)
3315 {
3316 	proto_tree *tree;
3317 	proto_item *item;
3318 	guint16 buffer_code;
3319 
3320 	/* dissect the first 2 bytes of the command PDU */
3321 	buffer_code = tvb_get_letohs(tvb, offset);
3322 	item = proto_tree_add_uint(parent_tree, hf_smb2_buffer_code, tvb, offset, 2, buffer_code);
3323 	tree = proto_item_add_subtree(item, ett_smb2_buffercode);
3324 	proto_tree_add_item(tree, hf_smb2_buffer_code_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3325 	proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3326 	offset += 2;
3327 
3328 	if (length) {
3329 		*length = buffer_code; /*&0xfffe don't mask it here, mask it on caller side */
3330 	}
3331 
3332 	return offset;
3333 }
3334 
3335 #define NEGPROT_CAP_DFS		0x00000001
3336 #define NEGPROT_CAP_LEASING	0x00000002
3337 #define NEGPROT_CAP_LARGE_MTU	0x00000004
3338 #define NEGPROT_CAP_MULTI_CHANNEL	0x00000008
3339 #define NEGPROT_CAP_PERSISTENT_HANDLES	0x00000010
3340 #define NEGPROT_CAP_DIRECTORY_LEASING	0x00000020
3341 #define NEGPROT_CAP_ENCRYPTION		0x00000040
3342 static int
dissect_smb2_capabilities(proto_tree * parent_tree,tvbuff_t * tvb,int offset)3343 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3344 {
3345 	static int * const flags[] = {
3346 		&hf_smb2_cap_dfs,
3347 		&hf_smb2_cap_leasing,
3348 		&hf_smb2_cap_large_mtu,
3349 		&hf_smb2_cap_multi_channel,
3350 		&hf_smb2_cap_persistent_handles,
3351 		&hf_smb2_cap_directory_leasing,
3352 		&hf_smb2_cap_encryption,
3353 		NULL
3354 	};
3355 
3356 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_capabilities, ett_smb2_capabilities, flags, ENC_LITTLE_ENDIAN);
3357 	offset += 4;
3358 
3359 	return offset;
3360 }
3361 
3362 
3363 
3364 #define NEGPROT_SIGN_REQ	0x0002
3365 #define NEGPROT_SIGN_ENABLED	0x0001
3366 
3367 static int
dissect_smb2_secmode(proto_tree * parent_tree,tvbuff_t * tvb,int offset)3368 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3369 {
3370 	static int * const flags[] = {
3371 		&hf_smb2_secmode_flags_sign_enabled,
3372 		&hf_smb2_secmode_flags_sign_required,
3373 		NULL
3374 	};
3375 
3376 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_security_mode, ett_smb2_sec_mode, flags, ENC_LITTLE_ENDIAN);
3377 	offset += 1;
3378 
3379 	return offset;
3380 }
3381 
3382 #define SES_REQ_FLAGS_SESSION_BINDING		0x01
3383 
3384 static int
dissect_smb2_ses_req_flags(proto_tree * parent_tree,tvbuff_t * tvb,int offset)3385 dissect_smb2_ses_req_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3386 {
3387 	static int * const flags[] = {
3388 		&hf_smb2_ses_req_flags_session_binding,
3389 		NULL
3390 	};
3391 
3392 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_ses_req_flags, ett_smb2_ses_req_flags, flags, ENC_LITTLE_ENDIAN);
3393 	offset += 1;
3394 
3395 	return offset;
3396 }
3397 
3398 #define SES_FLAGS_GUEST		0x0001
3399 #define SES_FLAGS_NULL		0x0002
3400 #define SES_FLAGS_ENCRYPT	0x0004
3401 
3402 static int
dissect_smb2_ses_flags(proto_tree * parent_tree,tvbuff_t * tvb,int offset)3403 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3404 {
3405 	static int * const flags[] = {
3406 		&hf_smb2_ses_flags_guest,
3407 		&hf_smb2_ses_flags_null,
3408 		&hf_smb2_ses_flags_encrypt,
3409 		NULL
3410 	};
3411 
3412 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_session_flags, ett_smb2_ses_flags, flags, ENC_LITTLE_ENDIAN);
3413 	offset += 2;
3414 
3415 	return offset;
3416 }
3417 
3418 #define SHARE_FLAGS_manual_caching		0x00000000
3419 #define SHARE_FLAGS_auto_caching		0x00000010
3420 #define SHARE_FLAGS_vdo_caching			0x00000020
3421 #define SHARE_FLAGS_no_caching			0x00000030
3422 
3423 static const value_string share_cache_vals[] = {
3424 	{ SHARE_FLAGS_manual_caching,	"Manual caching" },
3425 	{ SHARE_FLAGS_auto_caching,	"Auto caching" },
3426 	{ SHARE_FLAGS_vdo_caching,	"VDO caching" },
3427 	{ SHARE_FLAGS_no_caching,	"No caching" },
3428 	{ 0, NULL }
3429 };
3430 
3431 #define SHARE_FLAGS_dfs				0x00000001
3432 #define SHARE_FLAGS_dfs_root			0x00000002
3433 #define SHARE_FLAGS_restrict_exclusive_opens	0x00000100
3434 #define SHARE_FLAGS_force_shared_delete		0x00000200
3435 #define SHARE_FLAGS_allow_namespace_caching	0x00000400
3436 #define SHARE_FLAGS_access_based_dir_enum	0x00000800
3437 #define SHARE_FLAGS_force_levelii_oplock	0x00001000
3438 #define SHARE_FLAGS_enable_hash_v1		0x00002000
3439 #define SHARE_FLAGS_enable_hash_v2		0x00004000
3440 #define SHARE_FLAGS_encryption_required		0x00008000
3441 #define SHARE_FLAGS_identity_remoting		0x00040000
3442 #define SHARE_FLAGS_compress_data		0x00100000
3443 
3444 static int
dissect_smb2_share_flags(proto_tree * tree,tvbuff_t * tvb,int offset)3445 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
3446 {
3447 	static int * const sf_fields[] = {
3448 		&hf_smb2_share_flags_dfs,
3449 		&hf_smb2_share_flags_dfs_root,
3450 		&hf_smb2_share_flags_restrict_exclusive_opens,
3451 		&hf_smb2_share_flags_force_shared_delete,
3452 		&hf_smb2_share_flags_allow_namespace_caching,
3453 		&hf_smb2_share_flags_access_based_dir_enum,
3454 		&hf_smb2_share_flags_force_levelii_oplock,
3455 		&hf_smb2_share_flags_enable_hash_v1,
3456 		&hf_smb2_share_flags_enable_hash_v2,
3457 		&hf_smb2_share_flags_encrypt_data,
3458 		&hf_smb2_share_flags_identity_remoting,
3459 		&hf_smb2_share_flags_compress_data,
3460 		NULL
3461 	};
3462 	proto_item *item;
3463 	guint32 cp;
3464 
3465 	item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, ENC_LITTLE_ENDIAN);
3466 
3467 	cp = tvb_get_letohl(tvb, offset);
3468 	cp &= 0x00000030;
3469 	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);
3470 
3471 
3472 	offset += 4;
3473 
3474 	return offset;
3475 }
3476 
3477 #define SHARE_CAPS_DFS				0x00000008
3478 #define SHARE_CAPS_CONTINUOUS_AVAILABILITY	0x00000010
3479 #define SHARE_CAPS_SCALEOUT			0x00000020
3480 #define SHARE_CAPS_CLUSTER			0x00000040
3481 #define SHARE_CAPS_ASSYMETRIC			0x00000080
3482 #define SHARE_CAPS_REDIRECT_TO_OWNER		0x00000100
3483 
3484 static int
dissect_smb2_share_caps(proto_tree * tree,tvbuff_t * tvb,int offset)3485 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
3486 {
3487 	static int * const sc_fields[] = {
3488 		&hf_smb2_share_caps_dfs,
3489 		&hf_smb2_share_caps_continuous_availability,
3490 		&hf_smb2_share_caps_scaleout,
3491 		&hf_smb2_share_caps_cluster,
3492 		&hf_smb2_share_caps_assymetric,
3493 		&hf_smb2_share_caps_redirect_to_owner,
3494 		NULL
3495 	};
3496 
3497 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, ENC_LITTLE_ENDIAN);
3498 
3499 	offset += 4;
3500 
3501 	return offset;
3502 }
3503 
3504 static void
dissect_smb2_secblob(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si _U_)3505 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
3506 {
3507 	if ((tvb_captured_length(tvb)>=7)
3508 	&&  (!tvb_memeql(tvb, 0, "NTLMSSP", 7))) {
3509 		call_dissector(ntlmssp_handle, tvb, pinfo, tree);
3510 	} else {
3511 		call_dissector(gssapi_handle, tvb, pinfo, tree);
3512 	}
3513 }
3514 
3515 /*
3516  * Derive client and server decryption keys from the secret session key
3517  * and set them in the session object.
3518  */
smb2_generate_decryption_keys(smb2_conv_info_t * conv,smb2_sesid_info_t * ses)3519 static void smb2_generate_decryption_keys(smb2_conv_info_t *conv, smb2_sesid_info_t *ses)
3520 {
3521 	gboolean has_seskey = memcmp(ses->session_key, zeros, NTLMSSP_KEY_LEN) != 0;
3522 	gboolean has_signkey = memcmp(ses->signing_key, zeros, NTLMSSP_KEY_LEN) != 0;
3523 	gboolean has_client_key = memcmp(ses->client_decryption_key, zeros, AES_KEY_SIZE) != 0;
3524 	gboolean has_server_key = memcmp(ses->server_decryption_key, zeros, AES_KEY_SIZE) != 0;
3525 
3526 	/* if all decryption keys are provided, nothing to do */
3527 	if (has_client_key && has_server_key && has_signkey)
3528 		return;
3529 
3530 	/* otherwise, generate them from session key, if it's there */
3531 	if (!has_seskey)
3532 		return;
3533 
3534 	/* generate decryption keys */
3535 	if (conv->dialect <= SMB2_DIALECT_210) {
3536 		if (!has_signkey)
3537 			memcpy(ses->signing_key, ses->session_key,
3538 			       NTLMSSP_KEY_LEN);
3539 	} else if (conv->dialect < SMB2_DIALECT_311) {
3540 		if (!has_server_key)
3541 			smb2_key_derivation(ses->session_key,
3542 					    NTLMSSP_KEY_LEN,
3543 					    "SMB2AESCCM", 11,
3544 					    "ServerIn ", 10,
3545 					    ses->server_decryption_key);
3546 		if (!has_client_key)
3547 			smb2_key_derivation(ses->session_key,
3548 					    NTLMSSP_KEY_LEN,
3549 					    "SMB2AESCCM", 11,
3550 					    "ServerOut", 10,
3551 					    ses->client_decryption_key);
3552 		if (!has_signkey)
3553 			smb2_key_derivation(ses->session_key,
3554 					    NTLMSSP_KEY_LEN,
3555 					    "SMB2AESCMAC", 12,
3556 					    "SmbSign", 8,
3557 					    ses->signing_key);
3558 	} else if (conv->dialect >= SMB2_DIALECT_311) {
3559 		if (!has_server_key)
3560 			smb2_key_derivation(ses->session_key,
3561 					    NTLMSSP_KEY_LEN,
3562 					    "SMBC2SCipherKey", 16,
3563 					    ses->preauth_hash, SMB2_PREAUTH_HASH_SIZE,
3564 					    ses->server_decryption_key);
3565 		if (!has_client_key)
3566 			smb2_key_derivation(ses->session_key,
3567 					    NTLMSSP_KEY_LEN,
3568 					    "SMBS2CCipherKey", 16,
3569 					    ses->preauth_hash, SMB2_PREAUTH_HASH_SIZE,
3570 					    ses->client_decryption_key);
3571 		if (!has_signkey)
3572 			smb2_key_derivation(ses->session_key,
3573 					    NTLMSSP_KEY_LEN,
3574 					    "SMBSigningKey", 14,
3575 					    ses->preauth_hash, SMB2_PREAUTH_HASH_SIZE,
3576 					    ses->signing_key);
3577 	}
3578 
3579 	DEBUG("Generated Sign key");
3580 	HEXDUMP(ses->signing_key, NTLMSSP_KEY_LEN)
3581 	DEBUG("Generated S2C key");
3582 	HEXDUMP(ses->client_decryption_key, AES_KEY_SIZE);
3583 	DEBUG("Generated C2S key");
3584 	HEXDUMP(ses->server_decryption_key, AES_KEY_SIZE);
3585 }
3586 
3587 static int
dissect_smb2_session_setup_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)3588 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3589 {
3590 	offset_length_buffer_t  s_olb;
3591 	const ntlmssp_header_t *ntlmssph;
3592 	static int ntlmssp_tap_id = 0;
3593 	smb2_saved_info_t *ssi = si->saved;
3594 	proto_item *hash_item;
3595 	int        idx;
3596 
3597 	if (!ntlmssp_tap_id) {
3598 		GString *error_string;
3599 		/* We don't specify any callbacks at all.
3600 		 * Instead we manually fetch the tapped data after the
3601 		 * security blob has been fully dissected and before
3602 		 * we exit from this dissector.
3603 		 */
3604 		error_string = register_tap_listener("ntlmssp", NULL, NULL,
3605 		    TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL, NULL);
3606 		if (!error_string) {
3607 			ntlmssp_tap_id = find_tap_id("ntlmssp");
3608 		} else {
3609 			g_string_free(error_string, TRUE);
3610 		}
3611 	}
3612 
3613 	if (!pinfo->fd->visited && ssi) {
3614 		/* compute preauth hash on first pass */
3615 
3616 		/* start from last preauth hash of the connection if 1st request */
3617 		if (si->sesid == 0)
3618 			memcpy(si->conv->preauth_hash_ses, si->conv->preauth_hash_con, SMB2_PREAUTH_HASH_SIZE);
3619 
3620 		ssi->preauth_hash_req = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
3621 		update_preauth_hash(si->conv->preauth_hash_current, pinfo, tvb);
3622 		memcpy(ssi->preauth_hash_req, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
3623 	}
3624 
3625 	if (ssi && ssi->preauth_hash_req) {
3626 		hash_item = proto_tree_add_bytes_with_length(tree, hf_smb2_preauth_hash, tvb,
3627 							     0, tvb_captured_length(tvb),
3628 							     ssi->preauth_hash_req, SMB2_PREAUTH_HASH_SIZE);
3629 		proto_item_set_generated(hash_item);
3630 	}
3631 
3632 	/* buffer code */
3633 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3634 	/* some unknown bytes */
3635 
3636 	/* flags */
3637 	offset = dissect_smb2_ses_req_flags(tree, tvb, offset);
3638 
3639 	/* security mode */
3640 	offset = dissect_smb2_secmode(tree, tvb, offset);
3641 
3642 	/* capabilities */
3643 	offset = dissect_smb2_capabilities(tree, tvb, offset);
3644 
3645 	/* channel */
3646 	proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3647 	offset += 4;
3648 
3649 	/* security blob offset/length */
3650 	offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3651 
3652 	/* previous session id */
3653 	proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3654 	offset += 8;
3655 
3656 
3657 	/* the security blob itself */
3658 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3659 
3660 	offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3661 
3662 	/* If we have found a uid->acct_name mapping, store it */
3663 	if (!pinfo->fd->visited) {
3664 		idx = 0;
3665 		while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
3666 			if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
3667 				si->session = smb2_get_session(si->conv, si->sesid, pinfo, si);
3668 				si->session->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
3669 				si->session->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
3670 				si->session->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
3671 				/* don't overwrite session key from preferences */
3672 				if (memcmp(si->session->session_key, zeros, SMB_SESSION_ID_SIZE) == 0) {
3673 					memcpy(si->session->session_key, ntlmssph->session_key, NTLMSSP_KEY_LEN);
3674 				}
3675 				si->session->auth_frame = pinfo->num;
3676 			}
3677 		}
3678 	}
3679 
3680 	return offset;
3681 }
3682 
3683 static void
dissect_smb2_share_redirect_error(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3684 dissect_smb2_share_redirect_error(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3685 {
3686 	proto_tree *tree;
3687 	proto_item *item;
3688 	proto_tree *ips_tree;
3689 	proto_item *ips_item;
3690 
3691 	offset_length_buffer_t res_olb;
3692 	guint32 i, ip_count;
3693 
3694 	item = proto_tree_add_item(parent_tree, hf_smb2_error_redir_context, tvb, offset, 0, ENC_NA);
3695 	tree = proto_item_add_subtree(item, ett_smb2_error_redir_context);
3696 
3697 	/* structure size */
3698 	proto_tree_add_item(tree, hf_smb2_error_redir_struct_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3699 	offset += 4;
3700 
3701 	/* notification type */
3702 	proto_tree_add_item(tree, hf_smb2_error_redir_notif_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3703 	offset += 4;
3704 
3705 	/* resource name offset/length */
3706 	offset = dissect_smb2_olb_length_offset(tvb, offset, &res_olb, OLB_O_UINT32_S_UINT32, hf_smb2_error_redir_res_name);
3707 
3708 	/* flags */
3709 	proto_tree_add_item(tree, hf_smb2_error_redir_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3710 	offset += 2;
3711 
3712 	/* target type */
3713 	proto_tree_add_item(tree, hf_smb2_error_redir_target_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3714 	offset += 2;
3715 
3716 	/* ip addr count */
3717 	proto_tree_add_item_ret_uint(tree, hf_smb2_error_redir_ip_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &ip_count);
3718 	offset += 4;
3719 
3720 	/* ip addr list */
3721 	ips_item = proto_tree_add_item(tree, hf_smb2_error_redir_ip_list, tvb, offset, 0, ENC_NA);
3722 	ips_tree = proto_item_add_subtree(ips_item, ett_smb2_error_redir_ip_list);
3723 	for (i = 0; i < ip_count; i++)
3724 		offset += dissect_windows_sockaddr_storage(tvb, pinfo, ips_tree, offset, -1);
3725 
3726 	/* resource name */
3727 	dissect_smb2_olb_off_string(pinfo, tree, tvb, &res_olb, offset, OLB_TYPE_UNICODE_STRING);
3728 }
3729 
3730 static void
dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3731 dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3732 {
3733 	proto_tree *tree;
3734 	proto_item *item;
3735 
3736 	offset_length_buffer_t  s_olb, p_olb;
3737 
3738 	item = proto_tree_add_item(parent_tree, hf_smb2_symlink_error_response, tvb, offset, -1, ENC_NA);
3739 	tree = proto_item_add_subtree(item, ett_smb2_symlink_error_response);
3740 
3741 	/* symlink length */
3742 	proto_tree_add_item(tree, hf_smb2_symlink_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3743 	offset += 4;
3744 
3745 	/* symlink error tag */
3746 	proto_tree_add_item(tree, hf_smb2_symlink_error_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3747 	offset += 4;
3748 
3749 	/* reparse tag */
3750 	proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3751 	offset += 4;
3752 
3753 	proto_tree_add_item(tree, hf_smb2_reparse_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3754 	offset += 2;
3755 
3756 	proto_tree_add_item(tree, hf_smb2_unparsed_path_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3757 	offset += 2;
3758 
3759 	/* substitute name  offset/length */
3760 	offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_substitute_name);
3761 
3762 	/* print name offset/length */
3763 	offset = dissect_smb2_olb_length_offset(tvb, offset, &p_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_print_name);
3764 
3765 	/* flags */
3766 	proto_tree_add_item(tree, hf_smb2_symlink_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3767 	offset += 4;
3768 
3769 	/* substitute name string */
3770 	dissect_smb2_olb_off_string(pinfo, tree, tvb, &s_olb, offset, OLB_TYPE_UNICODE_STRING);
3771 
3772 	/* print name string */
3773 	dissect_smb2_olb_off_string(pinfo, tree, tvb, &p_olb, offset, OLB_TYPE_UNICODE_STRING);
3774 }
3775 
3776 static int
dissect_smb2_error_context(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)3777 dissect_smb2_error_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3778 {
3779 	proto_tree *tree;
3780 	proto_item *item;
3781 	tvbuff_t *sub_tvb;
3782 	guint32 length;
3783 	guint32 id;
3784 
3785 	item = proto_tree_add_item(parent_tree, hf_smb2_error_context, tvb, offset, -1, ENC_NA);
3786 	tree = proto_item_add_subtree(item, ett_smb2_error_context);
3787 
3788 	proto_tree_add_item_ret_uint(tree, hf_smb2_error_context_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
3789 	offset += 4;
3790 
3791 	proto_tree_add_item_ret_uint(tree, hf_smb2_error_context_id, tvb, offset, 4, ENC_LITTLE_ENDIAN, &id);
3792 	offset += 4;
3793 
3794 	sub_tvb = tvb_new_subset_length(tvb, offset, length);
3795 	dissect_smb2_error_data(sub_tvb, pinfo, tree, 0, id, si);
3796 	offset += length;
3797 
3798 	return offset;
3799 }
3800 
3801 /*
3802  * Assumes it is being called with a sub-tvb (dissects at offsets 0)
3803  */
3804 static void
dissect_smb2_error_data(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int error_context_count,int error_id,smb2_info_t * si _U_)3805 dissect_smb2_error_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
3806 			int error_context_count, int error_id,
3807 			smb2_info_t *si _U_)
3808 {
3809 	proto_tree *tree;
3810 	proto_item *item;
3811 
3812 	int offset = 0;
3813 	int i;
3814 
3815 	item = proto_tree_add_item(parent_tree, hf_smb2_error_data, tvb, offset, -1, ENC_NA);
3816 	tree = proto_item_add_subtree(item, ett_smb2_error_data);
3817 
3818 	if (error_context_count == 0) {
3819 		if (tvb_captured_length_remaining(tvb, offset) <= 1)
3820 			return;
3821 		switch (si->status) {
3822 		case NT_STATUS_STOPPED_ON_SYMLINK:
3823 			dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvb, pinfo, tree, offset, si);
3824 			break;
3825 		case NT_STATUS_BUFFER_TOO_SMALL:
3826 			proto_tree_add_item(tree, hf_smb2_error_min_buf_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3827 			break;
3828 		case NT_STATUS_BAD_NETWORK_NAME:
3829 			if (error_id == SMB2_ERROR_ID_SHARE_REDIRECT)
3830 				dissect_smb2_share_redirect_error(tvb, pinfo, tree, offset, si);
3831 		default:
3832 			break;
3833 		}
3834 	} else {
3835 		for (i = 0; i < error_context_count; i++)
3836 			offset += dissect_smb2_error_context(tvb, pinfo, tree, offset, si);
3837 	}
3838 }
3839 
3840 /*
3841  * SMB2 Error responses are a bit convoluted. Error data can be a list
3842  * of error contexts which themselves can hold an error data field.
3843  * See [MS-SMB2] 2.2.2.1.
3844  *
3845  * ERROR_RESP := ERROR_DATA
3846  *
3847  * ERROR_DATA := ( ERROR_CONTEXT + )
3848  *             | ERROR_STATUS_STOPPED_ON_SYMLINK
3849  *             | ERROR_ID_SHARE_REDIRECT
3850  *             | ERROR_BUFFER_TOO_SMALL
3851  *
3852  * ERROR_CONTEXT := ... + ERROR_DATA
3853  *                | ERROR_ID_SHARE_REDIRECT
3854  *
3855  * This needs more fixes for cases when the original header had also the constant value of 9.
3856  * This should be fixed on caller side where it decides if it has to call this or not.
3857  *
3858  */
3859 static int
dissect_smb2_error_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si,gboolean * continue_dissection)3860 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si,
3861 							gboolean* continue_dissection)
3862 {
3863 	gint byte_count;
3864 	guint8 error_context_count;
3865 	guint16 length;
3866 	tvbuff_t *sub_tvb;
3867 
3868 	/* buffer code */
3869 	offset = dissect_smb2_buffercode(tree, tvb, offset, &length);
3870 
3871 	/* FIX: error response uses this constant, if not then it is not an error response */
3872 	if(length != 9)
3873 	{
3874 		if(continue_dissection)
3875 			*continue_dissection = TRUE;
3876 	} else {
3877 		if(continue_dissection)
3878 			*continue_dissection = FALSE;
3879 
3880 		/* ErrorContextCount (1 bytes) */
3881 		error_context_count = tvb_get_guint8(tvb, offset);
3882 		proto_tree_add_item(tree, hf_smb2_error_context_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3883 		offset += 1;
3884 
3885 		/* Reserved (1 bytes) */
3886 		proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3887 		offset += 1;
3888 
3889 		/* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
3890 		byte_count = tvb_get_letohl(tvb, offset);
3891 		proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3892 		offset += 4;
3893 
3894 		/* If the ByteCount field is zero then the server MUST supply an ErrorData field
3895 		   that is one byte in length */
3896 		if (byte_count == 0) byte_count = 1;
3897 
3898 		/* ErrorData (variable): A variable-length data field that contains extended
3899 		   error information.*/
3900 		sub_tvb = tvb_new_subset_length(tvb, offset, byte_count);
3901 		offset += byte_count;
3902 
3903 		dissect_smb2_error_data(sub_tvb, pinfo, tree, error_context_count, 0, si);
3904 	}
3905 
3906 	return offset;
3907 }
3908 
3909 static int
dissect_smb2_session_setup_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)3910 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3911 {
3912 	offset_length_buffer_t s_olb;
3913 	proto_item *hash_item;
3914 	smb2_saved_info_t *ssi = si->saved;
3915 
3916 	si->session = smb2_get_session(si->conv, si->sesid, pinfo, si);
3917 	if (si->status == 0) {
3918 		si->session->auth_frame = pinfo->num;
3919 	}
3920 
3921 	/* compute preauth hash on first pass */
3922 	if (!pinfo->fd->visited && ssi) {
3923 		ssi->preauth_hash_res = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
3924 		/*
3925 		 * Preauth hash can only be used if the session is
3926 		 * established i.e. last session setup response has a
3927 		 * success status. As per the specification, the last
3928 		 * response is NOT hashed.
3929 		 */
3930 		if (si->status != 0) {
3931 			/*
3932 			 * Not sucessful means either more req/rsp
3933 			 * processing is required or we reached an
3934 			 * error, so update hash.
3935 			 */
3936 			update_preauth_hash(si->conv->preauth_hash_current, pinfo, tvb);
3937 		} else {
3938 			/*
3939 			 * Session is established, we can generate the keys
3940 			 */
3941 			memcpy(si->session->preauth_hash, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
3942 			smb2_generate_decryption_keys(si->conv, si->session);
3943 		}
3944 
3945 		/* In all cases, stash the preauth hash */
3946 		memcpy(ssi->preauth_hash_res, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
3947 	}
3948 
3949 	if (ssi && ssi->preauth_hash_res) {
3950 		hash_item = proto_tree_add_bytes_with_length(tree, hf_smb2_preauth_hash, tvb,
3951 							     0, tvb_captured_length(tvb),
3952 							     ssi->preauth_hash_res, SMB2_PREAUTH_HASH_SIZE);
3953 		proto_item_set_generated(hash_item);
3954 	}
3955 
3956 	/* session_setup is special and we don't use dissect_smb2_error_response() here! */
3957 
3958 	/* buffer code */
3959 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3960 
3961 	/* session flags */
3962 	offset = dissect_smb2_ses_flags(tree, tvb, offset);
3963 
3964 	/* security blob offset/length */
3965 	offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3966 
3967 	/* the security blob itself */
3968 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3969 
3970 	offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3971 
3972 	/* If we have found a uid->acct_name mapping, store it */
3973 #ifdef HAVE_KERBEROS
3974 	if (!pinfo->fd->visited && si->status == 0) {
3975 		enc_key_t *ek;
3976 
3977 		if (krb_decrypt) {
3978 			read_keytab_file_from_preferences();
3979 		}
3980 
3981 		for (ek=enc_key_list;ek;ek=ek->next) {
3982 			if (ek->fd_num == (int)pinfo->num) {
3983 				break;
3984 			}
3985 		}
3986 
3987 		if (ek != NULL) {
3988 			/* TODO: fill in the correct user/dom/host information */
3989 		}
3990 	}
3991 #endif
3992 
3993 	return offset;
3994 }
3995 
3996 static int
dissect_smb2_tree_connect_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si _U_)3997 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3998 {
3999 	offset_length_buffer_t olb;
4000 	const guint8 *buf;
4001 	guint16       flags;
4002 	proto_item *item;
4003 	static int * const connect_flags[] = {
4004 		&hf_smb2_tc_cluster_reconnect,
4005 		&hf_smb2_tc_redirect_to_owner,
4006 		&hf_smb2_tc_extension_present,
4007 		&hf_smb2_tc_reserved,
4008 		NULL
4009 	};
4010 
4011 	/* buffer code */
4012 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4013 
4014 	/* flags */
4015 	item = proto_tree_get_parent(tree);
4016 	flags = tvb_get_letohs(tvb, offset);
4017 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_tree_connect_flags, ett_smb2_tree_connect_flags, connect_flags, ENC_LITTLE_ENDIAN);
4018 
4019 	if (flags != 0) {
4020 		proto_item_append_text(item, "%s%s%s",
4021 			       (flags & 0x0001)?", CLUSTER_RECONNECT":"",
4022 			       (flags & 0x0002)?", REDIRECT_TO_OWNER":"",
4023 			       (flags & 0x0004)?", EXTENSION_PRESENT":"");
4024 	}
4025 	offset += 2;
4026 
4027 	/* tree  offset/length */
4028 	offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
4029 
4030 	/* tree string */
4031 	buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
4032 
4033 	offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
4034 
4035 	/* treelen  +1 is overkill here if the string is unicode,
4036 	 * but who ever has more than a handful of TCON in a trace anyways
4037 	 */
4038 	if (!pinfo->fd->visited && si->saved && buf && olb.len) {
4039 		si->saved->extra_info_type = SMB2_EI_TREENAME;
4040 		si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
4041 		g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
4042 	}
4043 
4044 	if (buf) {
4045 		col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s",
4046 		    format_text(pinfo->pool, buf, strlen(buf)));
4047 	}
4048 
4049 	return offset;
4050 }
4051 static int
dissect_smb2_tree_connect_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si _U_)4052 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
4053 {
4054 	guint8 share_type;
4055 	gboolean continue_dissection;
4056 
4057 	switch (si->status) {
4058 	/* buffer code */
4059 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4060 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4061 		if (!continue_dissection) return offset;
4062 	}
4063 
4064 	/* share type */
4065 	share_type = tvb_get_guint8(tvb, offset);
4066 	proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4067 	offset += 1;
4068 
4069 	/* byte is reserved and must be set to zero */
4070 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
4071 	offset += 1;
4072 
4073 	if (!pinfo->fd->visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
4074 		smb2_tid_info_t *tid, tid_key;
4075 
4076 		tid_key.tid = si->tid;
4077 		tid = (smb2_tid_info_t *)wmem_map_lookup(si->session->tids, &tid_key);
4078 		if (tid) {
4079 			wmem_map_remove(si->session->tids, &tid_key);
4080 		}
4081 		tid = wmem_new(wmem_file_scope(), smb2_tid_info_t);
4082 		tid->tid = si->tid;
4083 		tid->name = (char *)si->saved->extra_info;
4084 		tid->connect_frame = pinfo->num;
4085 		tid->share_type = share_type;
4086 
4087 		wmem_map_insert(si->session->tids, tid, tid);
4088 
4089 		si->saved->extra_info_type = SMB2_EI_NONE;
4090 		si->saved->extra_info = NULL;
4091 	}
4092 
4093 	/* share flags */
4094 	offset = dissect_smb2_share_flags(tree, tvb, offset);
4095 
4096 	/* share capabilities */
4097 	offset = dissect_smb2_share_caps(tree, tvb, offset);
4098 
4099 	/* this is some sort of access mask */
4100 	offset = dissect_smb_access_mask(tvb, tree, offset);
4101 
4102 	return offset;
4103 }
4104 
4105 static int
dissect_smb2_tree_disconnect_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4106 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4107 {
4108 	/* buffer code */
4109 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4110 
4111 	/* reserved */
4112 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4113 	offset += 2;
4114 
4115 	return offset;
4116 }
4117 
4118 static int
dissect_smb2_tree_disconnect_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4119 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4120 {
4121 	gboolean continue_dissection;
4122 
4123 	switch (si->status) {
4124 	/* buffer code */
4125 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4126 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4127 		if (!continue_dissection) return offset;
4128 	}
4129 
4130 	/* reserved */
4131 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4132 	offset += 2;
4133 
4134 	return offset;
4135 }
4136 
4137 static int
dissect_smb2_sessionlogoff_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4138 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4139 {
4140 	/* buffer code */
4141 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4142 
4143 	/* reserved bytes */
4144 	offset += 2;
4145 
4146 	return offset;
4147 }
4148 
4149 static int
dissect_smb2_sessionlogoff_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4150 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4151 {
4152 	gboolean continue_dissection;
4153 
4154 	switch (si->status) {
4155 	/* buffer code */
4156 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4157 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4158 		if (!continue_dissection) return offset;
4159 	}
4160 
4161 	/* reserved bytes */
4162 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4163 	offset += 2;
4164 
4165 	return offset;
4166 }
4167 
4168 static int
dissect_smb2_keepalive_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4169 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4170 {
4171 	/* buffer code */
4172 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4173 
4174 	/* some unknown bytes */
4175 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
4176 	offset += 2;
4177 
4178 	return offset;
4179 }
4180 
4181 static int
dissect_smb2_keepalive_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4182 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4183 {
4184 	gboolean continue_dissection;
4185 
4186 	switch (si->status) {
4187 	/* buffer code */
4188 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4189 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4190 		if (!continue_dissection) return offset;
4191 	}
4192 
4193 	/* some unknown bytes */
4194 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
4195 	offset += 2;
4196 
4197 	return offset;
4198 }
4199 
4200 static int
dissect_smb2_notify_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)4201 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4202 {
4203 	proto_tree *flags_tree = NULL;
4204 	proto_item *flags_item = NULL;
4205 
4206 	/* buffer code */
4207 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4208 
4209 	/* notify flags */
4210 	if (tree) {
4211 		flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4212 		flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
4213 	}
4214 	proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4215 	offset += 2;
4216 
4217 	/* output buffer length */
4218 	proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4219 	offset += 4;
4220 
4221 	/* fid */
4222 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4223 
4224 	/* completion filter */
4225 	offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
4226 
4227 	/* reserved */
4228 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4229 	offset += 4;
4230 
4231 	return offset;
4232 }
4233 
4234 static const value_string notify_action_vals[] = {
4235 	{0x01, "FILE_ACTION_ADDED"},
4236 	{0x02, "FILE_ACTION_REMOVED"},
4237 	{0x03, "FILE_ACTION_MODIFIED"},
4238 	{0x04, "FILE_ACTION_RENAMED_OLD_NAME"},
4239 	{0x05, "FILE_ACTION_RENAMED_NEW_NAME"},
4240 	{0x06, "FILE_ACTION_ADDED_STREAM"},
4241 	{0x07, "FILE_ACTION_REMOVED_STREAM"},
4242 	{0x08, "FILE_ACTION_MODIFIED_STREAM"},
4243 	{0x09, "FILE_ACTION_REMOVED_BY_DELETE"},
4244 	{0, NULL}
4245 };
4246 
4247 static void
dissect_smb2_notify_data_out(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,smb2_info_t * si _U_)4248 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4249 {
4250 	proto_tree *tree = NULL;
4251 	proto_item *item = NULL;
4252 	int offset = 0;
4253 
4254 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4255 		guint32 start_offset = offset;
4256 		guint32 next_offset;
4257 		guint32 length;
4258 
4259 		if (parent_tree) {
4260 			item = proto_tree_add_item(parent_tree, hf_smb2_notify_info, tvb, offset, -1, ENC_NA);
4261 			tree = proto_item_add_subtree(item, ett_smb2_notify_info);
4262 		}
4263 
4264 		/* next offset */
4265 		proto_tree_add_item_ret_uint(tree, hf_smb2_notify_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &next_offset);
4266 		offset += 4;
4267 
4268 		proto_tree_add_item(tree, hf_smb2_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4269 		offset += 4;
4270 
4271 		/* file name length */
4272 		proto_tree_add_item_ret_uint(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
4273 		offset += 4;
4274 
4275 		/* file name */
4276 		if (length) {
4277 			proto_tree_add_item(tree, hf_smb2_filename,
4278 			    tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
4279 		}
4280 
4281 		if (!next_offset) {
4282 			break;
4283 		}
4284 
4285 		offset = start_offset+next_offset;
4286 	}
4287 }
4288 
4289 static int
dissect_smb2_notify_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si)4290 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
4291 {
4292 	offset_length_buffer_t olb;
4293 	gboolean continue_dissection;
4294 
4295 	switch (si->status) {
4296 	/* MS-SMB2 3.3.4.4 says STATUS_NOTIFY_ENUM_DIR is not treated as an error */
4297 	case 0x0000010c: /* STATUS_NOTIFY_ENUM_DIR */
4298 	case 0x00000000: /* buffer code */
4299 	 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4300 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4301 		if (!continue_dissection) return offset;
4302 	}
4303 
4304 	/* out buffer offset/length */
4305 	offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
4306 
4307 	/* out buffer */
4308 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
4309 	offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
4310 
4311 	return offset;
4312 }
4313 
4314 #define SMB2_FIND_FLAG_RESTART_SCANS		0x01
4315 #define SMB2_FIND_FLAG_SINGLE_ENTRY		0x02
4316 #define SMB2_FIND_FLAG_INDEX_SPECIFIED		0x04
4317 #define SMB2_FIND_FLAG_REOPEN			0x10
4318 
4319 static int
dissect_smb2_find_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)4320 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4321 {
4322 	offset_length_buffer_t olb;
4323 	const guint8 *buf;
4324 	guint8      il;
4325 	static int * const f_fields[] = {
4326 		&hf_smb2_find_flags_restart_scans,
4327 		&hf_smb2_find_flags_single_entry,
4328 		&hf_smb2_find_flags_index_specified,
4329 		&hf_smb2_find_flags_reopen,
4330 		NULL
4331 	};
4332 
4333 	/* buffer code */
4334 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4335 
4336 	il = tvb_get_guint8(tvb, offset);
4337 	if (si->saved) {
4338 		si->saved->infolevel = il;
4339 	}
4340 
4341 	/* infolevel */
4342 	proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
4343 	offset += 1;
4344 
4345 	/* find flags */
4346 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, ENC_LITTLE_ENDIAN);
4347 	offset += 1;
4348 
4349 	/* file index */
4350 	proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4351 	offset += 4;
4352 
4353 	/* fid */
4354 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4355 
4356 	/* search pattern  offset/length */
4357 	offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
4358 
4359 	/* output buffer length */
4360 	proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4361 	offset += 4;
4362 
4363 	/* search pattern */
4364 	buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
4365 
4366 	offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
4367 
4368 	if (!pinfo->fd->visited && si->saved && olb.len) {
4369 		si->saved->extra_info_type = SMB2_EI_FINDPATTERN;
4370 		si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
4371 		g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
4372 	}
4373 
4374 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
4375 			val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
4376 			buf);
4377 
4378 	return offset;
4379 }
4380 
dissect_smb2_file_directory_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si _U_)4381 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si _U_)
4382 {
4383 	int         offset = 0;
4384 	proto_item *item   = NULL;
4385 	proto_tree *tree   = NULL;
4386 
4387 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4388 		int old_offset = offset;
4389 		int next_offset;
4390 		int file_name_len;
4391 
4392 		if (parent_tree) {
4393 			item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, ENC_NA);
4394 			tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
4395 		}
4396 
4397 		/* next offset */
4398 		next_offset = tvb_get_letohl(tvb, offset);
4399 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4400 		offset += 4;
4401 
4402 		/* file index */
4403 		proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4404 		offset += 4;
4405 
4406 		/* create time */
4407 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4408 
4409 		/* last access */
4410 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4411 
4412 		/* last write */
4413 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4414 
4415 		/* last change */
4416 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4417 
4418 		/* end of file */
4419 		proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4420 		offset += 8;
4421 
4422 		/* allocation size */
4423 		proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4424 		offset += 8;
4425 
4426 		/* File Attributes */
4427 		offset = dissect_fscc_file_attr(tvb, tree, offset, NULL);
4428 
4429 		/* file name length */
4430 		file_name_len = tvb_get_letohl(tvb, offset);
4431 		proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4432 		offset += 4;
4433 
4434 		/* file name */
4435 		if (file_name_len) {
4436 			char *display_string;
4437 
4438 			proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4439 			    tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4440 			    pinfo->pool, &display_string);
4441 			proto_item_append_text(item, ": %s", display_string);
4442 			offset += file_name_len;
4443 		}
4444 
4445 		proto_item_set_len(item, offset-old_offset);
4446 
4447 		if (next_offset == 0) {
4448 			return;
4449 		}
4450 
4451 		offset = old_offset+next_offset;
4452 		if (offset < old_offset) {
4453 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4454 				    "Invalid offset/length. Malformed packet");
4455 			return;
4456 		}
4457 	}
4458 }
4459 
dissect_smb2_full_directory_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si _U_)4460 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si _U_)
4461 {
4462 	int         offset = 0;
4463 	proto_item *item   = NULL;
4464 	proto_tree *tree   = NULL;
4465 
4466 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4467 		int old_offset = offset;
4468 		int next_offset;
4469 		int file_name_len;
4470 		guint32 attr;
4471 
4472 		if (parent_tree) {
4473 			item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, ENC_NA);
4474 			tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
4475 		}
4476 
4477 		/* next offset */
4478 		next_offset = tvb_get_letohl(tvb, offset);
4479 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4480 		offset += 4;
4481 
4482 		/* file index */
4483 		proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4484 		offset += 4;
4485 
4486 		/* create time */
4487 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4488 
4489 		/* last access */
4490 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4491 
4492 		/* last write */
4493 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4494 
4495 		/* last change */
4496 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4497 
4498 		/* end of file */
4499 		proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4500 		offset += 8;
4501 
4502 		/* allocation size */
4503 		proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4504 		offset += 8;
4505 
4506 		/* File Attributes */
4507 		offset = dissect_fscc_file_attr(tvb, tree, offset, &attr);
4508 
4509 		/* file name length */
4510 		file_name_len = tvb_get_letohl(tvb, offset);
4511 		proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4512 		offset += 4;
4513 
4514 		/* ea size or reparse tag */
4515 		if (attr & SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT)
4516 			proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4517 		else
4518 			proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4519 		offset += 4;
4520 
4521 		/* file name */
4522 		if (file_name_len) {
4523 			char *display_string;
4524 
4525 			proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4526 			    tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4527 			    pinfo->pool, &display_string);
4528 			proto_item_append_text(item, ": %s", display_string);
4529 			offset += file_name_len;
4530 		}
4531 
4532 		proto_item_set_len(item, offset-old_offset);
4533 
4534 		if (next_offset == 0) {
4535 			return;
4536 		}
4537 
4538 		offset = old_offset+next_offset;
4539 		if (offset < old_offset) {
4540 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4541 				    "Invalid offset/length. Malformed packet");
4542 			return;
4543 		}
4544 	}
4545 }
4546 
dissect_smb2_both_directory_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si _U_)4547 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si _U_)
4548 {
4549 	int         offset = 0;
4550 	proto_item *item   = NULL;
4551 	proto_tree *tree   = NULL;
4552 
4553 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4554 		int old_offset = offset;
4555 		int next_offset;
4556 		int file_name_len;
4557 		int short_name_len;
4558 		guint32 attr;
4559 
4560 		if (parent_tree) {
4561 			item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
4562 			tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
4563 		}
4564 
4565 		/* next offset */
4566 		next_offset = tvb_get_letohl(tvb, offset);
4567 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4568 		offset += 4;
4569 
4570 		/* file index */
4571 		proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4572 		offset += 4;
4573 
4574 		/* create time */
4575 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4576 
4577 		/* last access */
4578 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4579 
4580 		/* last write */
4581 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4582 
4583 		/* last change */
4584 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4585 
4586 		/* end of file */
4587 		proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4588 		offset += 8;
4589 
4590 		/* allocation size */
4591 		proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4592 		offset += 8;
4593 
4594 		/* File Attributes */
4595 		offset = dissect_fscc_file_attr(tvb, tree, offset, &attr);
4596 
4597 		/* file name length */
4598 		file_name_len = tvb_get_letohl(tvb, offset);
4599 		proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4600 		offset += 4;
4601 
4602 		/* ea size or reparse tag */
4603 		if (attr & SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT)
4604 			proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4605 		else
4606 			proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4607 		offset += 4;
4608 
4609 		/* short name length */
4610 		short_name_len = tvb_get_guint8(tvb, offset);
4611 		proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4612 		offset += 1;
4613 
4614 		/* reserved */
4615 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
4616 		offset += 1;
4617 
4618 		/* short name */
4619 		if (short_name_len) {
4620 			proto_tree_add_item(tree, hf_smb2_short_name,
4621 			    tvb, offset, short_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
4622 		}
4623 		offset += 24;
4624 
4625 		/* file name */
4626 		if (file_name_len) {
4627 			char *display_string;
4628 
4629 			proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4630 			    tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4631 			    pinfo->pool, &display_string);
4632 			proto_item_append_text(item, ": %s", display_string);
4633 			offset += file_name_len;
4634 		}
4635 
4636 		proto_item_set_len(item, offset-old_offset);
4637 
4638 		if (next_offset == 0) {
4639 			return;
4640 		}
4641 
4642 		offset = old_offset+next_offset;
4643 		if (offset < old_offset) {
4644 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4645 				    "Invalid offset/length. Malformed packet");
4646 			return;
4647 		}
4648 	}
4649 }
4650 
dissect_smb2_file_name_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si _U_)4651 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si _U_)
4652 {
4653 	int         offset = 0;
4654 	proto_item *item   = NULL;
4655 	proto_tree *tree   = NULL;
4656 
4657 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4658 		int old_offset = offset;
4659 		int next_offset;
4660 		int file_name_len;
4661 
4662 		if (parent_tree) {
4663 			item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
4664 			tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
4665 		}
4666 
4667 		/* next offset */
4668 		next_offset = tvb_get_letohl(tvb, offset);
4669 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4670 		offset += 4;
4671 
4672 		/* file index */
4673 		proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4674 		offset += 4;
4675 
4676 		/* file name length */
4677 		file_name_len = tvb_get_letohl(tvb, offset);
4678 		proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4679 		offset += 4;
4680 
4681 		/* file name */
4682 		if (file_name_len) {
4683 			char *display_string;
4684 
4685 			proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4686 			    tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4687 			    pinfo->pool, &display_string);
4688 			proto_item_append_text(item, ": %s", display_string);
4689 			offset += file_name_len;
4690 		}
4691 
4692 		proto_item_set_len(item, offset-old_offset);
4693 
4694 		if (next_offset == 0) {
4695 			return;
4696 		}
4697 
4698 		offset = old_offset+next_offset;
4699 		if (offset < old_offset) {
4700 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4701 				    "Invalid offset/length. Malformed packet");
4702 			return;
4703 		}
4704 	}
4705 }
4706 
dissect_smb2_id_both_directory_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si _U_)4707 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si _U_)
4708 {
4709 	int         offset = 0;
4710 	proto_item *item   = NULL;
4711 	proto_tree *tree   = NULL;
4712 
4713 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4714 		int old_offset = offset;
4715 		int next_offset;
4716 		int file_name_len;
4717 		int short_name_len;
4718 		guint32 attr;
4719 
4720 		if (parent_tree) {
4721 			item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
4722 			tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
4723 		}
4724 
4725 		/* next offset */
4726 		next_offset = tvb_get_letohl(tvb, offset);
4727 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4728 		offset += 4;
4729 
4730 		/* file index */
4731 		proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4732 		offset += 4;
4733 
4734 		/* create time */
4735 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4736 
4737 		/* last access */
4738 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4739 
4740 		/* last write */
4741 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4742 
4743 		/* last change */
4744 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4745 
4746 		/* end of file */
4747 		proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4748 		offset += 8;
4749 
4750 		/* allocation size */
4751 		proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4752 		offset += 8;
4753 
4754 		/* File Attributes */
4755 		offset = dissect_fscc_file_attr(tvb, tree, offset, &attr);
4756 
4757 		/* file name length */
4758 		file_name_len = tvb_get_letohl(tvb, offset);
4759 		proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4760 		offset += 4;
4761 
4762 		/* ea size or reparse tag */
4763 		if (attr & SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT)
4764 			proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4765 		else
4766 			proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4767 		offset += 4;
4768 
4769 		/* short name length */
4770 		short_name_len = tvb_get_guint8(tvb, offset);
4771 		proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4772 		offset += 1;
4773 
4774 		/* reserved */
4775 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
4776 		offset += 1;
4777 
4778 		/* short name */
4779 		if (short_name_len) {
4780 			proto_tree_add_item(tree, hf_smb2_short_name,
4781 			    tvb, offset, short_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
4782 		}
4783 		offset += 24;
4784 
4785 		/* reserved */
4786 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4787 		offset += 2;
4788 
4789 		/* file id */
4790 		proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4791 		offset += 8;
4792 
4793 		/* file name */
4794 		if (file_name_len) {
4795 			char *display_string;
4796 
4797 			proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4798 			    tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4799 			    pinfo->pool, &display_string);
4800 			proto_item_append_text(item, ": %s", display_string);
4801 			offset += file_name_len;
4802 		}
4803 
4804 		proto_item_set_len(item, offset-old_offset);
4805 
4806 		if (next_offset == 0) {
4807 			return;
4808 		}
4809 
4810 		offset = old_offset+next_offset;
4811 		if (offset < old_offset) {
4812 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4813 				    "Invalid offset/length. Malformed packet");
4814 			return;
4815 		}
4816 	}
4817 }
4818 
4819 
dissect_smb2_id_full_directory_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si _U_)4820 static void dissect_smb2_id_full_directory_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si _U_)
4821 {
4822 	int         offset = 0;
4823 	proto_item *item   = NULL;
4824 	proto_tree *tree   = NULL;
4825 
4826 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4827 		int old_offset = offset;
4828 		int next_offset;
4829 		int file_name_len;
4830 		guint32 attr;
4831 
4832 		if (parent_tree) {
4833 			item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
4834 			tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
4835 		}
4836 
4837 		/* next offset */
4838 		next_offset = tvb_get_letohl(tvb, offset);
4839 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4840 		offset += 4;
4841 
4842 		/* file index */
4843 		proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4844 		offset += 4;
4845 
4846 		/* create time */
4847 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4848 
4849 		/* last access */
4850 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4851 
4852 		/* last write */
4853 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4854 
4855 		/* last change */
4856 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4857 
4858 		/* end of file */
4859 		proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4860 		offset += 8;
4861 
4862 		/* allocation size */
4863 		proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4864 		offset += 8;
4865 
4866 		/* File Attributes */
4867 		offset = dissect_fscc_file_attr(tvb, tree, offset, &attr);
4868 
4869 		/* file name length */
4870 		file_name_len = tvb_get_letohl(tvb, offset);
4871 		proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4872 		offset += 4;
4873 
4874 		/* ea size or reparse tag */
4875 		if (attr & SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT)
4876 			proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4877 		else
4878 			proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4879 		offset += 4;
4880 
4881 		/* reserved */
4882 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4883 		offset += 4;
4884 
4885 		/* file id */
4886 		proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4887 		offset += 8;
4888 
4889 		/* file name */
4890 		if (file_name_len) {
4891 			char *display_string;
4892 
4893 			proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4894 			    tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4895 			    pinfo->pool, &display_string);
4896 			proto_item_append_text(item, ": %s", display_string);
4897 			offset += file_name_len;
4898 		}
4899 
4900 		proto_item_set_len(item, offset-old_offset);
4901 
4902 		if (next_offset == 0) {
4903 			return;
4904 		}
4905 
4906 		offset = old_offset+next_offset;
4907 		if (offset < old_offset) {
4908 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4909 				    "Invalid offset/length. Malformed packet");
4910 			return;
4911 		}
4912 	}
4913 }
4914 
dissect_smb2_posix_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)4915 static int dissect_smb2_posix_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4916 {
4917 	/* create time */
4918 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4919 
4920 	/* last access */
4921 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4922 
4923 	/* last write */
4924 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4925 
4926 	/* last change */
4927 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4928 
4929 	/* allocation size */
4930 	proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4931 	offset += 8;
4932 
4933 	/* end of file */
4934 	proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4935 	offset += 8;
4936 
4937 	/* File Attributes */
4938 	offset = dissect_fscc_file_attr(tvb, tree, offset, NULL);
4939 
4940 	/* file index */
4941 	proto_tree_add_item(tree, hf_smb2_inode, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4942 	offset += 8;
4943 
4944 	/* dev id */
4945 	proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4946 	offset += 4;
4947 
4948 	/* zero */
4949 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4950 	offset += 4;
4951 
4952 	/* Hardlinks */
4953 	proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4954 	offset += 4;
4955 
4956 	/* Reparse tag */
4957 	proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4958 	offset += 4;
4959 
4960 	/* POSIX mode bits */
4961 	proto_tree_add_item(tree, hf_smb2_posix_perms, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4962 	offset += 4;
4963 
4964 	/* Owner and Group SID */
4965 	offset = dissect_nt_sid(tvb, offset, tree, "Owner SID", NULL, -1);
4966 	offset = dissect_nt_sid(tvb, offset, tree, "Group SID", NULL, -1);
4967 
4968 	return offset;
4969 }
4970 
dissect_smb2_posix_directory_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,smb2_info_t * si _U_)4971 static void dissect_smb2_posix_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4972 {
4973 	int offset = 0;
4974 	proto_item *item = NULL;
4975 	proto_tree *tree = NULL;
4976 
4977 	while (tvb_reported_length_remaining(tvb, offset) > 4) {
4978 		int old_offset = offset;
4979 		int next_offset;
4980 		int file_name_len;
4981 
4982 		if (parent_tree) {
4983 			item = proto_tree_add_item(parent_tree, hf_smb2_posix_info, tvb, offset, -1, ENC_NA);
4984 			tree = proto_item_add_subtree(item, ett_smb2_posix_info);
4985 		}
4986 
4987 		/* next offset */
4988 		next_offset = tvb_get_letohl(tvb, offset);
4989 		proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4990 		offset += 4;
4991 		offset += 4;
4992 
4993 		offset = dissect_smb2_posix_info(tvb, pinfo, tree, offset, si);
4994 
4995 		/* file name length */
4996 		proto_tree_add_item_ret_uint(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &file_name_len);
4997 		offset += 4;
4998 
4999 		/* file name */
5000 		if (file_name_len) {
5001 			proto_tree_add_item(tree, hf_smb2_filename, tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
5002 			offset += file_name_len;
5003 		}
5004 
5005 		proto_item_set_len(item, offset-old_offset);
5006 
5007 		if (next_offset == 0) {
5008 			return;
5009 		}
5010 
5011 		offset = old_offset+next_offset;
5012 		if (offset < old_offset) {
5013 			proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
5014 				    "Invalid offset/length. Malformed packet");
5015 			return;
5016 		}
5017 	}
5018 }
5019 
5020 
5021 typedef struct _smb2_find_dissector_t {
5022 	guint32	level;
5023 	void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
5024 } smb2_find_dissector_t;
5025 
5026 static smb2_find_dissector_t smb2_find_dissectors[] = {
5027 	{SMB2_FIND_DIRECTORY_INFO,	dissect_smb2_file_directory_info},
5028 	{SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
5029 	{SMB2_FIND_BOTH_DIRECTORY_INFO,	dissect_smb2_both_directory_info},
5030 	{SMB2_FIND_NAME_INFO,		dissect_smb2_file_name_info},
5031 	{SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
5032 	{SMB2_FIND_ID_FULL_DIRECTORY_INFO,dissect_smb2_id_full_directory_info},
5033 	{SMB2_FIND_POSIX_INFO,		dissect_smb2_posix_directory_info},
5034 	{0, NULL}
5035 };
5036 
5037 static void
dissect_smb2_find_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)5038 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
5039 {
5040 	smb2_find_dissector_t *dis = smb2_find_dissectors;
5041 
5042 	while (dis->dissector) {
5043 		if (si && si->saved) {
5044 			if (dis->level == si->saved->infolevel) {
5045 				dis->dissector(tvb, pinfo, tree, si);
5046 				return;
5047 			}
5048 		}
5049 		dis++;
5050 	}
5051 
5052 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
5053 }
5054 
5055 static int
dissect_smb2_find_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)5056 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5057 {
5058 	offset_length_buffer_t olb;
5059 	proto_item *item = NULL;
5060 	gboolean continue_dissection;
5061 
5062 	if (si->saved) {
5063 		/* infolevel */
5064 		item = proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
5065 		proto_item_set_generated(item);
5066 	}
5067 
5068 	if (!pinfo->fd->visited && si->saved && si->saved->extra_info_type == SMB2_EI_FINDPATTERN) {
5069 		col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
5070 				val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
5071 				(const char *)si->saved->extra_info);
5072 
5073 		wmem_free(wmem_file_scope(), si->saved->extra_info);
5074 		si->saved->extra_info_type = SMB2_EI_NONE;
5075 		si->saved->extra_info = NULL;
5076 	}
5077 
5078 	switch (si->status) {
5079 	/* buffer code */
5080 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5081 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5082 		if (!continue_dissection) return offset;
5083 	}
5084 
5085 	/* findinfo offset */
5086 	offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
5087 
5088 	/* the buffer */
5089 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
5090 
5091 	offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
5092 
5093 	return offset;
5094 }
5095 
5096 static int
dissect_smb2_negotiate_context(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)5097 dissect_smb2_negotiate_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
5098 {
5099 	guint16 type;
5100 	const gchar *type_str;
5101 	guint32 i, data_length, salt_length, hash_count, cipher_count, comp_count, transform_count;
5102 	guint32 signing_count;
5103 	proto_item *sub_item;
5104 	proto_tree *sub_tree;
5105 	static int * const comp_alg_flags_fields[] = {
5106 		&hf_smb2_comp_alg_flags_chained,
5107 		&hf_smb2_comp_alg_flags_reserved,
5108 		NULL
5109 	};
5110 
5111 	sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_negotiate_context_element, &sub_item, "Negotiate Context");
5112 
5113 	/* type */
5114 	type = tvb_get_letohl(tvb, offset);
5115 	type_str = val_to_str(type, smb2_negotiate_context_types, "Unknown Type: (0x%0x)");
5116 	proto_item_append_text(sub_item, ": %s ", type_str);
5117 	proto_tree_add_item(sub_tree, hf_smb2_negotiate_context_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5118 	offset += 2;
5119 
5120 	/* data length */
5121 	proto_tree_add_item_ret_uint(sub_tree, hf_smb2_negotiate_context_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &data_length);
5122 	proto_item_set_len(sub_item, data_length + 8);
5123 	offset += 2;
5124 
5125 	/* reserved */
5126 	proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5127 	offset += 4;
5128 
5129 	switch (type)
5130 	{
5131 		case SMB2_PREAUTH_INTEGRITY_CAPABILITIES:
5132 			proto_tree_add_item_ret_uint(sub_tree, hf_smb2_hash_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &hash_count);
5133 			offset += 2;
5134 			proto_tree_add_item_ret_uint(sub_tree, hf_smb2_salt_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &salt_length);
5135 			offset += 2;
5136 
5137 			for (i = 0; i < hash_count; i++)
5138 			{
5139 				proto_tree_add_item(sub_tree, hf_smb2_hash_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5140 				offset += 2;
5141 			}
5142 
5143 			if (salt_length)
5144 			{
5145 				proto_tree_add_item(sub_tree, hf_smb2_salt, tvb, offset, salt_length, ENC_NA);
5146 				offset += salt_length;
5147 			}
5148 			break;
5149 
5150 		case SMB2_ENCRYPTION_CAPABILITIES:
5151 			proto_tree_add_item_ret_uint(sub_tree, hf_smb2_cipher_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cipher_count);
5152 			offset += 2;
5153 
5154 			for (i = 0; i < cipher_count; i ++)
5155 			{
5156 				/* in SMB3.1.1 the first cipher returned by the server session encryption algorithm */
5157 				if (i == 0 && si && si->conv && (si->flags & SMB2_FLAGS_RESPONSE)) {
5158 					guint16 first_cipher = tvb_get_letohs(tvb, offset);
5159 					si->conv->enc_alg = first_cipher;
5160 				}
5161 				proto_tree_add_item(sub_tree, hf_smb2_cipher_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5162 				offset += 2;
5163 			}
5164 			break;
5165 
5166 		case SMB2_COMPRESSION_CAPABILITIES:
5167 			proto_tree_add_item_ret_uint(sub_tree, hf_smb2_comp_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &comp_count);
5168 			offset += 2;
5169 
5170 			/* padding */
5171 			offset += 2;
5172 
5173 			/* flags */
5174 			proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_comp_alg_flags, ett_smb2_comp_alg_flags, comp_alg_flags_fields, ENC_LITTLE_ENDIAN);
5175 			offset += 4;
5176 
5177 			for (i = 0; i < comp_count; i ++) {
5178 				proto_tree_add_item(sub_tree, hf_smb2_comp_alg_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5179 				offset += 2;
5180 			}
5181 			break;
5182 
5183 		case SMB2_NETNAME_NEGOTIATE_CONTEXT_ID:
5184 			proto_tree_add_item(sub_tree, hf_smb2_netname_neg_id, tvb, offset,
5185 					    data_length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
5186 			offset += data_length;
5187 			break;
5188 
5189 		case SMB2_TRANSPORT_CAPABILITIES:
5190 			proto_tree_add_item(sub_tree, hf_smb2_transport_ctx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5191 			offset += 4;
5192 			break;
5193 
5194 		case SMB2_RDMA_TRANSFORM_CAPABILITIES:
5195 			proto_tree_add_item_ret_uint(sub_tree, hf_smb2_rdma_transform_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &transform_count);
5196 			offset += 2;
5197 
5198 			proto_tree_add_item(sub_tree, hf_smb2_rdma_transform_reserved1, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5199 			offset += 2;
5200 			proto_tree_add_item(sub_tree, hf_smb2_rdma_transform_reserved2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5201 			offset += 4;
5202 
5203 			for (i = 0; i < transform_count; i++) {
5204 				proto_tree_add_item(sub_tree, hf_smb2_rdma_transform_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5205 				offset += 2;
5206 			}
5207 			break;
5208 
5209 		case SMB2_SIGNING_CAPABILITIES:
5210 			proto_tree_add_item_ret_uint(sub_tree, hf_smb2_signing_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &signing_count);
5211 			offset += 2;
5212 
5213 			for (i = 0; i < signing_count; i++) {
5214 				proto_tree_add_item(sub_tree, hf_smb2_signing_alg_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5215 				offset += 2;
5216 			}
5217 			break;
5218 
5219 		case SMB2_POSIX_EXTENSIONS_CAPABILITIES:
5220 			proto_tree_add_item(sub_tree, hf_smb2_posix_reserved, tvb, offset, data_length, ENC_NA);
5221 			offset += data_length;
5222 			break;
5223 
5224 		default:
5225 			proto_tree_add_item(sub_tree, hf_smb2_unknown, tvb, offset, data_length, ENC_NA);
5226 			offset += data_length;
5227 			break;
5228 	}
5229 
5230 	return offset;
5231 }
5232 
5233 static int
dissect_smb2_negotiate_protocol_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)5234 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5235 {
5236 	guint16 dc;
5237 	guint16 i;
5238 	gboolean supports_smb_3_10 = FALSE;
5239 	guint32 nco;
5240 	guint16 ncc;
5241 	proto_item *hash_item = NULL;
5242 	smb2_saved_info_t *ssi = si->saved;
5243 
5244 	/* compute preauth hash on first pass */
5245 	if (!pinfo->fd->visited && ssi) {
5246 		ssi->preauth_hash_req = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
5247 		memset(si->conv->preauth_hash_ses, 0, SMB2_PREAUTH_HASH_SIZE);
5248 		memset(si->conv->preauth_hash_con, 0, SMB2_PREAUTH_HASH_SIZE);
5249 		si->conv->preauth_hash_current = si->conv->preauth_hash_con;
5250 		update_preauth_hash(si->conv->preauth_hash_current, pinfo, tvb);
5251 		memcpy(ssi->preauth_hash_req, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
5252 	}
5253 
5254 	if (ssi && ssi->preauth_hash_req) {
5255 		hash_item = proto_tree_add_bytes_with_length(tree,
5256 							     hf_smb2_preauth_hash, tvb,
5257 							     0, tvb_captured_length(tvb),
5258 							     ssi->preauth_hash_req, SMB2_PREAUTH_HASH_SIZE);
5259 		proto_item_set_generated(hash_item);
5260 	}
5261 
5262 	/* buffer code */
5263 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5264 
5265 	/* dialect count */
5266 	dc = tvb_get_letohs(tvb, offset);
5267 	proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5268 	offset += 2;
5269 
5270 	/* security mode, skip second byte */
5271 	offset = dissect_smb2_secmode(tree, tvb, offset);
5272 	offset++;
5273 
5274 
5275 	/* reserved */
5276 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5277 	offset += 2;
5278 
5279 	/* capabilities */
5280 	offset = dissect_smb2_capabilities(tree, tvb, offset);
5281 
5282 	/* client guid */
5283 	proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5284 	offset += 16;
5285 
5286 	/* negotiate context offset */
5287 	nco = tvb_get_letohl(tvb, offset);
5288 	proto_tree_add_item(tree, hf_smb2_negotiate_context_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5289 	offset += 4;
5290 
5291 	/* negotiate context count */
5292 	ncc = tvb_get_letohs(tvb, offset);
5293 	proto_tree_add_item(tree, hf_smb2_negotiate_context_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5294 	offset += 2;
5295 
5296 	/* reserved */
5297 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5298 	offset += 2;
5299 
5300 	for (i = 0 ; i < dc; i++) {
5301 		guint16 d = tvb_get_letohs(tvb, offset);
5302 		proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5303 		offset += 2;
5304 
5305 		if (d >= SMB2_DIALECT_310) {
5306 			supports_smb_3_10 = TRUE;
5307 		}
5308 	}
5309 
5310 	if (!supports_smb_3_10) {
5311 		ncc = 0;
5312 	}
5313 
5314 	if (nco != 0) {
5315 		guint32 tmp = 0x40 + 36 + dc * 2;
5316 
5317 		if (nco >= tmp) {
5318 			offset += nco - tmp;
5319 		} else {
5320 			ncc = 0;
5321 		}
5322 	}
5323 
5324 	for (i = 0; i < ncc; i++) {
5325 		offset = WS_ROUNDUP_8(offset);
5326 		offset = dissect_smb2_negotiate_context(tvb, pinfo, tree, offset, si);
5327 	}
5328 
5329 	return offset;
5330 }
5331 
5332 static int
dissect_smb2_negotiate_protocol_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)5333 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5334 {
5335 	offset_length_buffer_t s_olb;
5336 	guint16 i;
5337 	guint32 nco;
5338 	guint16 ncc;
5339 	gboolean continue_dissection;
5340 	proto_item *hash_item = NULL;
5341 	smb2_saved_info_t *ssi = si->saved;
5342 
5343 	/* compute preauth hash on first pass */
5344 	if (!pinfo->fd->visited && ssi) {
5345 		ssi->preauth_hash_res = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
5346 		update_preauth_hash(si->conv->preauth_hash_current, pinfo, tvb);
5347 		memcpy(ssi->preauth_hash_res, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
5348 
5349 		/*
5350 		 * All new sessions on this conversation must reuse
5351 		 * the preauth hash value at the time of the negprot
5352 		 * response, so we stash it and switch buffers
5353 		 */
5354 		memcpy(si->conv->preauth_hash_ses, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
5355 		si->conv->preauth_hash_current = si->conv->preauth_hash_ses;
5356 	}
5357 
5358 	if (ssi && ssi->preauth_hash_res) {
5359 		hash_item = proto_tree_add_bytes_with_length(tree,
5360 							     hf_smb2_preauth_hash, tvb,
5361 							     0, tvb_captured_length(tvb),
5362 							     ssi->preauth_hash_res, SMB2_PREAUTH_HASH_SIZE);
5363 		proto_item_set_generated(hash_item);
5364 	}
5365 
5366 	switch (si->status) {
5367 	/* buffer code */
5368 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5369 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5370 		if (!continue_dissection) return offset;
5371 	}
5372 
5373 	/* security mode, skip second byte */
5374 	offset = dissect_smb2_secmode(tree, tvb, offset);
5375 	offset++;
5376 
5377 	/* dialect picked */
5378 	si->conv->dialect = tvb_get_letohs(tvb, offset);
5379 	proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5380 	offset += 2;
5381 
5382 	/* negotiate context count */
5383 	ncc = tvb_get_letohs(tvb, offset);
5384 	proto_tree_add_item(tree, hf_smb2_negotiate_context_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5385 	offset += 2;
5386 
5387 	/* server GUID */
5388 	proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5389 	offset += 16;
5390 
5391 	/* capabilities */
5392 	offset = dissect_smb2_capabilities(tree, tvb, offset);
5393 
5394 	/* max trans size */
5395 	proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5396 	offset += 4;
5397 
5398 	/* max read size */
5399 	proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5400 	offset += 4;
5401 
5402 	/* max write size */
5403 	proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5404 	offset += 4;
5405 
5406 	/* current time */
5407 	dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
5408 	offset += 8;
5409 
5410 	/* boot time */
5411 	dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
5412 	offset += 8;
5413 
5414 	/* security blob offset/length */
5415 	offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
5416 
5417 	/* the security blob itself */
5418 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
5419 
5420 	/* negotiate context offset */
5421 	nco = tvb_get_letohl(tvb, offset);
5422 	proto_tree_add_item(tree, hf_smb2_negotiate_context_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5423 	offset += 4;
5424 
5425 	offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
5426 
5427 	if (si->conv->dialect < SMB2_DIALECT_310) {
5428 		ncc = 0;
5429 	}
5430 
5431 	if (nco != 0) {
5432 		guint32 tmp = 0x40 + 64 + s_olb.len;
5433 
5434 		if (nco >= tmp) {
5435 			offset += nco - tmp;
5436 		} else {
5437 			ncc = 0;
5438 		}
5439 	}
5440 
5441 	for (i = 0; i < ncc; i++) {
5442 		offset = WS_ROUNDUP_8(offset);
5443 		offset = dissect_smb2_negotiate_context(tvb, pinfo, tree, offset, si);
5444 	}
5445 
5446 	return offset;
5447 }
5448 
5449 static const true_false_string tfs_additional_owner = {
5450 	"Requesting OWNER security information",
5451 	"NOT requesting owner security information",
5452 };
5453 
5454 static const true_false_string tfs_additional_group = {
5455 	"Requesting GROUP security information",
5456 	"NOT requesting group security information",
5457 };
5458 
5459 static const true_false_string tfs_additional_dacl = {
5460 	"Requesting DACL security information",
5461 	"NOT requesting DACL security information",
5462 };
5463 
5464 static const true_false_string tfs_additional_sacl = {
5465 	"Requesting SACL security information",
5466 	"NOT requesting SACL security information",
5467 };
5468 
5469 static const true_false_string tfs_additional_label = {
5470 	"Requesting integrity label security information",
5471 	"NOT requesting integrity label security information",
5472 };
5473 
5474 static const true_false_string tfs_additional_attribute = {
5475 	"Requesting resource attribute security information",
5476 	"NOT requesting resource attribute security information",
5477 };
5478 
5479 static const true_false_string tfs_additional_scope = {
5480 	"Requesting central access policy security information",
5481 	"NOT requesting central access policy security information",
5482 };
5483 
5484 static const true_false_string tfs_additional_backup = {
5485 	"Requesting backup operation security information",
5486 	"NOT requesting backup operation security information",
5487 };
5488 
5489 #ifndef _MSC_VER
5490 /*  Those macros are already defined by winnt.h for Windows build */
5491 #define OWNER_SECURITY_INFORMATION 0x00000001
5492 #define GROUP_SECURITY_INFORMATION 0x00000002
5493 #define DACL_SECURITY_INFORMATION 0x00000004
5494 #define SACL_SECURITY_INFORMATION 0x00000008
5495 #define LABEL_SECURITY_INFORMATION 0x00000010
5496 #define ATTRIBUTE_SECURITY_INFORMATION 0x00000020
5497 #define SCOPE_SECURITY_INFORMATION 0x00000040
5498 #define BACKUP_SECURITY_INFORMATION 0x00010000
5499 #endif
5500 
5501 static int
dissect_additional_information_sec_mask(tvbuff_t * tvb,proto_tree * parent_tree,int offset)5502 dissect_additional_information_sec_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5503 {
5504 	/*	Note that in SMB1 protocol some security flags were not defined yet - see dissect_security_information_mask()
5505 		So for SMB2 we have to use own dissector */
5506 	static int * const flags[] = {
5507 		&hf_smb2_getsetinfo_additional_owner,
5508 		&hf_smb2_getsetinfo_additional_group,
5509 		&hf_smb2_getsetinfo_additional_dacl,
5510 		&hf_smb2_getsetinfo_additional_sacl,
5511 		&hf_smb2_getsetinfo_additional_label,
5512 		&hf_smb2_getsetinfo_additional_attribute,
5513 		&hf_smb2_getsetinfo_additional_scope,
5514 		&hf_smb2_getsetinfo_additional_backup,
5515 		NULL
5516 	};
5517 
5518 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_getsetinfo_additionals,
5519 		ett_smb2_additional_information_sec_mask, flags, ENC_LITTLE_ENDIAN);
5520 	offset += 4;
5521 
5522 	return offset;
5523 }
5524 
5525 static int
dissect_smb2_getinfo_parameters(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si)5526 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
5527 {
5528 	/* Additional Info */
5529 	switch (si->saved->smb2_class) {
5530 	case SMB2_CLASS_SEC_INFO:
5531 		dissect_additional_information_sec_mask(tvb, tree, offset);
5532 		break;
5533 	default:
5534 		proto_tree_add_item(tree, hf_smb2_getsetinfo_additional, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5535 	}
5536 	offset += 4;
5537 
5538 	/* Flags */
5539 	proto_tree_add_item(tree, hf_smb2_getinfo_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5540 	offset += 4;
5541 
5542 	return offset;
5543 }
5544 
5545 
5546 static int
dissect_smb2_getinfo_buffer_quota(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,smb2_info_t * si _U_)5547 dissect_smb2_getinfo_buffer_quota(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
5548 {
5549 	guint32 sidlist_len = 0;
5550 	guint32 startsid_len = 0;
5551 	guint32 startsid_offset = 0;
5552 
5553 	proto_item *item = NULL;
5554 	proto_tree *tree = NULL;
5555 
5556 	if (parent_tree) {
5557 		item = proto_tree_add_item(parent_tree, hf_smb2_query_quota_info, tvb, offset, -1, ENC_NA);
5558 		tree = proto_item_add_subtree(item, ett_smb2_query_quota_info);
5559 	}
5560 
5561 	proto_tree_add_item(tree, hf_smb2_qq_single, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5562 	offset += 1;
5563 
5564 	proto_tree_add_item(tree, hf_smb2_qq_restart, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5565 	offset += 1;
5566 
5567 	/* reserved */
5568 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5569 	offset += 2;
5570 
5571 	proto_tree_add_item_ret_uint(tree, hf_smb2_qq_sidlist_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &sidlist_len);
5572 	offset += 4;
5573 
5574 	proto_tree_add_item_ret_uint(tree, hf_smb2_qq_start_sid_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &startsid_len);
5575 	offset += 4;
5576 
5577 	proto_tree_add_item_ret_uint(tree, hf_smb2_qq_start_sid_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &startsid_offset);
5578 	offset += 4;
5579 
5580 	if (sidlist_len != 0) {
5581 		offset = dissect_nt_get_user_quota(tvb, tree, offset, &sidlist_len);
5582 	} else if (startsid_len != 0) {
5583 		offset = dissect_nt_sid(tvb, offset + startsid_offset, tree, "Start SID", NULL, -1);
5584 	}
5585 
5586 	return offset;
5587 }
5588 
5589 static int
dissect_smb2_class_infolevel(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * tree,smb2_info_t * si)5590 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
5591 {
5592 	guint8		  cl, il;
5593 	proto_item	 *item;
5594 	int		  hfindex;
5595 	value_string_ext *vsx;
5596 
5597 	if (si->flags & SMB2_FLAGS_RESPONSE) {
5598 		if (!si->saved) {
5599 			return offset;
5600 		}
5601 		cl = si->saved->smb2_class;
5602 		il = si->saved->infolevel;
5603 	} else {
5604 		cl = tvb_get_guint8(tvb, offset);
5605 		il = tvb_get_guint8(tvb, offset+1);
5606 		if (si->saved) {
5607 			si->saved->smb2_class = cl;
5608 			si->saved->infolevel = il;
5609 		}
5610 	}
5611 
5612 
5613 	switch (cl) {
5614 	case SMB2_CLASS_FILE_INFO:
5615 		hfindex = hf_smb2_infolevel_file_info;
5616 		vsx = &smb2_file_info_levels_ext;
5617 		break;
5618 	case SMB2_CLASS_FS_INFO:
5619 		hfindex = hf_smb2_infolevel_fs_info;
5620 		vsx = &smb2_fs_info_levels_ext;
5621 		break;
5622 	case SMB2_CLASS_SEC_INFO:
5623 		hfindex = hf_smb2_infolevel_sec_info;
5624 		vsx = &smb2_sec_info_levels_ext;
5625 		break;
5626 	case SMB2_CLASS_QUOTA_INFO:
5627 		/* infolevel is not being used for quota */
5628 		hfindex = hf_smb2_infolevel;
5629 		vsx = NULL;
5630 		break;
5631 	default:
5632 		hfindex = hf_smb2_infolevel;
5633 		vsx = NULL;  /* allowed arg to val_to_str_ext() */
5634 	}
5635 
5636 
5637 	/* class */
5638 	item = proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
5639 	if (si->flags & SMB2_FLAGS_RESPONSE) {
5640 		proto_item_set_generated(item);
5641 	}
5642 	/* infolevel */
5643 	item = proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
5644 	if (si->flags & SMB2_FLAGS_RESPONSE) {
5645 		proto_item_set_generated(item);
5646 	}
5647 	offset += 2;
5648 
5649 	if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
5650 		/* Only update COL_INFO for requests. It clutters the
5651 		 * display a bit too much if we do it for replies
5652 		 * as well.
5653 		 */
5654 		col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
5655 				val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
5656 				val_to_str_ext(il, vsx, "(Level:0x%02x)"));
5657 	}
5658 
5659 	return offset;
5660 }
5661 
5662 static int
dissect_smb2_getinfo_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)5663 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5664 {
5665 	guint32 getinfo_size = 0;
5666 	guint32 getinfo_offset = 0;
5667 	proto_item *offset_item;
5668 
5669 	/* buffer code */
5670 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5671 
5672 	/* class and info level */
5673 	offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5674 
5675 	/* max response size */
5676 	proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5677 	offset += 4;
5678 
5679 	/* offset */
5680 	offset_item = proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN, &getinfo_offset);
5681 	offset += 2;
5682 
5683 	/* reserved */
5684 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5685 	offset += 2;
5686 
5687 	/* size */
5688 	proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &getinfo_size);
5689 	offset += 4;
5690 
5691 	/* parameters */
5692 	if (si->saved) {
5693 		offset = dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
5694 	} else {
5695 		/* some unknown bytes */
5696 		proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, ENC_NA);
5697 		offset += 8;
5698 	}
5699 
5700 	/* fid */
5701 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5702 
5703 	/* buffer */
5704 	if (si->saved) {
5705 		if (getinfo_size != 0) {
5706 			/*
5707 			 * 2.2.37 says "For quota requests, this MUST be
5708 			 * the length of the contained SMB2_QUERY_QUOTA_INFO
5709 			 * embedded in the request. For FileFullEaInformation
5710 			 * requests, this MUST be set to the length of the
5711 			 * user supplied EA list specified in [MS-FSCC]
5712 			 * section 2.4.15.1. For other information queries,
5713 			 * this field SHOULD be set to 0 and the server MUST
5714 			 * ignore it on receipt.
5715 			 *
5716 			 * This seems to imply that, for requests other
5717 			 * than those to types, we should either completely
5718 			 * ignore a non-zero getinfo_size or should, at
5719 			 * most, add a warning-level expert info at the
5720 			 * protocol level saying that it should be zero,
5721 			 * but not try and interpret it or check its
5722 			 * validity.
5723 			 */
5724 			if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO ||
5725 			    (si->saved->smb2_class == SMB2_CLASS_FILE_INFO &&
5726 			     si->saved->infolevel == SMB2_FILE_FULL_EA_INFO)) {
5727 				/*
5728 				 * According to 2.2.37 SMB2 QUERY_INFO
5729 				 * Request in the current MS-SMB2 spec,
5730 				 * these are the only info requests that
5731 				 * have an input buffer.
5732 				 */
5733 
5734 				/*
5735 				 * Make sure that the input buffer is after
5736 				 * the fixed-length part of the message.
5737 				 */
5738 				if (getinfo_offset < (guint)offset) {
5739 					expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_offset);
5740 					return offset;
5741 				}
5742 
5743 				/*
5744 				 * Make sure the input buffer is within the
5745 				 * message, i.e. that it's within the tvbuff.
5746 				 *
5747 				 * We check for offset+length overflowing and
5748 				 * for offset+length being beyond the reported
5749 				 * length of the tvbuff.
5750 				 */
5751 				if (getinfo_offset + getinfo_size < getinfo_offset ||
5752 				    getinfo_offset + getinfo_size > tvb_reported_length(tvb)) {
5753 					expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_size);
5754 					return offset;
5755 				}
5756 
5757 				if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO) {
5758 					dissect_smb2_getinfo_buffer_quota(tvb, pinfo, tree, getinfo_offset, si);
5759 				} else {
5760 					/*
5761 					 * XXX - handle user supplied EA info.
5762 					 */
5763 					proto_tree_add_item(tree, hf_smb2_unknown, tvb, getinfo_offset, getinfo_size, ENC_NA);
5764 				}
5765 				offset = getinfo_offset + getinfo_size;
5766 			}
5767 		} else {
5768 			/*
5769 			 * The buffer size is 0, meaning it's not present.
5770 			 *
5771 			 * 2.2.37 says "For FileFullEaInformation requests,
5772 			 * the input buffer MUST contain the user supplied
5773 			 * EA list with zero or more FILE_GET_EA_INFORMATION
5774 			 * structures, specified in [MS-FSCC] section
5775 			 * 2.4.15.1.", so it seems that, for a "get full
5776 			 * EA information" request, the size can be zero -
5777 			 * there's no other obvious way for the list to
5778 			 * have zero structures.
5779 			 *
5780 			 * 2.2.37 also says "For quota requests, the input
5781 			 * buffer MUST contain an SMB2_QUERY_QUOTA_INFO,
5782 			 * as specified in section 2.2.37.1."; that seems
5783 			 * to imply that the input buffer must not be empty
5784 			 * in that case.
5785 			 */
5786 			if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO)
5787 				expert_add_info(pinfo, offset_item, &ei_smb2_empty_getinfo_buffer);
5788 		}
5789 	}
5790 
5791 	return offset;
5792 }
5793 
5794 static int
dissect_smb2_infolevel(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si,guint8 smb2_class,guint8 infolevel)5795 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 smb2_class, guint8 infolevel)
5796 {
5797 	int old_offset = offset;
5798 
5799 	switch (smb2_class) {
5800 	case SMB2_CLASS_FILE_INFO:
5801 		switch (infolevel) {
5802 		case SMB2_FILE_BASIC_INFO:
5803 			offset = dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
5804 			break;
5805 		case SMB2_FILE_STANDARD_INFO:
5806 			offset = dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
5807 			break;
5808 		case SMB2_FILE_INTERNAL_INFO:
5809 			offset = dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
5810 			break;
5811 		case SMB2_FILE_EA_INFO:
5812 			offset = dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
5813 			break;
5814 		case SMB2_FILE_ACCESS_INFO:
5815 			offset = dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
5816 			break;
5817 		case SMB2_FILE_RENAME_INFO:
5818 			offset = dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
5819 			break;
5820 		case SMB2_FILE_DISPOSITION_INFO:
5821 			offset = dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
5822 			break;
5823 		case SMB2_FILE_POSITION_INFO:
5824 			offset = dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
5825 			break;
5826 		case SMB2_FILE_FULL_EA_INFO:
5827 			offset = dissect_smb2_file_full_ea_info(tvb, pinfo, tree, offset, si);
5828 			break;
5829 		case SMB2_FILE_MODE_INFO:
5830 			offset = dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
5831 			break;
5832 		case SMB2_FILE_ALIGNMENT_INFO:
5833 			offset = dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
5834 			break;
5835 		case SMB2_FILE_ALL_INFO:
5836 			offset = dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
5837 			break;
5838 		case SMB2_FILE_ALLOCATION_INFO:
5839 			offset = dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
5840 			break;
5841 		case SMB2_FILE_ENDOFFILE_INFO:
5842 			dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
5843 			break;
5844 		case SMB2_FILE_ALTERNATE_NAME_INFO:
5845 			offset = dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
5846 			break;
5847 		case SMB2_FILE_STREAM_INFO:
5848 			offset = dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
5849 			break;
5850 		case SMB2_FILE_PIPE_INFO:
5851 			offset = dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
5852 			break;
5853 		case SMB2_FILE_COMPRESSION_INFO:
5854 			offset = dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
5855 			break;
5856 		case SMB2_FILE_NETWORK_OPEN_INFO:
5857 			offset = dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
5858 			break;
5859 		case SMB2_FILE_ATTRIBUTE_TAG_INFO:
5860 			offset = dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
5861 			break;
5862 		case SMB2_FILE_NORMALIZED_NAME_INFO:
5863 			offset = dissect_smb2_file_normalized_name_info(tvb, pinfo, tree, offset, si);
5864 			break;
5865 		case SMB2_FILE_POSIX_INFO:
5866 			offset = dissect_smb2_posix_info(tvb, pinfo, tree, offset, si);
5867 			break;
5868 		default:
5869 			/* we don't handle this infolevel yet */
5870 			proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5871 			offset += tvb_captured_length_remaining(tvb, offset);
5872 		}
5873 		break;
5874 	case SMB2_CLASS_FS_INFO:
5875 		switch (infolevel) {
5876 		case SMB2_FS_INFO_01:
5877 			offset = dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
5878 			break;
5879 		case SMB2_FS_INFO_03:
5880 			offset = dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
5881 			break;
5882 		case SMB2_FS_INFO_04:
5883 			offset = dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
5884 			break;
5885 		case SMB2_FS_INFO_05:
5886 			offset = dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
5887 			break;
5888 		case SMB2_FS_INFO_06:
5889 			offset = dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
5890 			break;
5891 		case SMB2_FS_INFO_07:
5892 			offset = dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
5893 			break;
5894 		case SMB2_FS_OBJECTID_INFO:
5895 			offset = dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
5896 			break;
5897 		default:
5898 			/* we don't handle this infolevel yet */
5899 			proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5900 			offset += tvb_captured_length_remaining(tvb, offset);
5901 		}
5902 		break;
5903 	case SMB2_CLASS_SEC_INFO:
5904 		switch (infolevel) {
5905 		case SMB2_SEC_INFO_00:
5906 			offset = dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
5907 			break;
5908 		default:
5909 			/* we don't handle this infolevel yet */
5910 			proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5911 			offset += tvb_captured_length_remaining(tvb, offset);
5912 		}
5913 		break;
5914 	case SMB2_CLASS_QUOTA_INFO:
5915 		offset = dissect_smb2_quota_info(tvb, pinfo, tree, offset, si);
5916 		break;
5917 	default:
5918 		/* we don't handle this class yet */
5919 		proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5920 		offset += tvb_captured_length_remaining(tvb, offset);
5921 	}
5922 
5923 	/* if we get BUFFER_OVERFLOW there will be truncated data */
5924 	if (si->status == 0x80000005) {
5925 		proto_item *item;
5926 		item = proto_tree_add_item(tree, hf_smb2_truncated, tvb, old_offset, 0, ENC_NA);
5927 		proto_item_set_generated(item);
5928 	}
5929 	return offset;
5930 }
5931 
5932 static void
dissect_smb2_getinfo_response_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)5933 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
5934 {
5935 	/* data */
5936 	if (si->saved) {
5937 		dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->smb2_class, si->saved->infolevel);
5938 	} else {
5939 		/* some unknown bytes */
5940 		proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
5941 	}
5942 
5943 }
5944 
5945 
5946 static int
dissect_smb2_getinfo_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)5947 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5948 {
5949 	offset_length_buffer_t olb;
5950 	gboolean continue_dissection;
5951 
5952 	/* class/infolevel */
5953 	dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5954 
5955 	switch (si->status) {
5956 	case 0x00000000:
5957 	/* if we get BUFFER_OVERFLOW there will be truncated data */
5958 	case 0x80000005:
5959 	/* if we get BUFFER_TOO_SMALL there will not be any data there, only
5960 	 * a guin32 specifying how big the buffer needs to be
5961 	 */
5962 		/* buffer code */
5963 		offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5964 		break;
5965 	case 0xc0000023:
5966 		offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5967 		offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
5968 		proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5969 		offset += 4;
5970 
5971 		return offset;
5972 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5973 		if (!continue_dissection) return offset;
5974 	}
5975 
5976 	 /* response buffer offset  and size */
5977 	offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
5978 
5979 	/* response data*/
5980 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
5981 
5982 	return offset;
5983 }
5984 
5985 static int
dissect_smb2_close_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)5986 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5987 {
5988 	proto_tree *flags_tree = NULL;
5989 	proto_item *flags_item = NULL;
5990 
5991 	/* buffer code */
5992 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5993 
5994 	/* close flags */
5995 	if (tree) {
5996 		flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5997 		flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
5998 	}
5999 	proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6000 	offset += 2;
6001 
6002 	/* padding */
6003 	offset += 4;
6004 
6005 	/* fid */
6006 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
6007 
6008 	return offset;
6009 }
6010 
6011 static int
dissect_smb2_close_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)6012 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
6013 {
6014 	proto_tree *flags_tree = NULL;
6015 	proto_item *flags_item = NULL;
6016 	gboolean continue_dissection;
6017 
6018 	switch (si->status) {
6019 	/* buffer code */
6020 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
6021 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
6022 		if (!continue_dissection) return offset;
6023 	}
6024 
6025 	/* close flags */
6026 	if (tree) {
6027 		flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6028 		flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
6029 	}
6030 	proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6031 	offset += 2;
6032 
6033 	/* reserved */
6034 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6035 	offset += 4;
6036 
6037 	/* create time */
6038 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
6039 
6040 	/* last access */
6041 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
6042 
6043 	/* last write */
6044 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
6045 
6046 	/* last change */
6047 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
6048 
6049 	/* allocation size */
6050 	proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6051 	offset += 8;
6052 
6053 	/* end of file */
6054 	proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6055 	offset += 8;
6056 
6057 	/* File Attributes */
6058 	offset = dissect_fscc_file_attr(tvb, tree, offset, NULL);
6059 
6060 	return offset;
6061 }
6062 
6063 static int
dissect_smb2_flush_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)6064 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
6065 {
6066 	/* buffer code */
6067 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
6068 
6069 	/* some unknown bytes */
6070 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
6071 	offset += 6;
6072 
6073 	/* fid */
6074 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
6075 
6076 	return offset;
6077 }
6078 
6079 static int
dissect_smb2_flush_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)6080 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
6081 {
6082 	gboolean continue_dissection;
6083 
6084 	switch (si->status) {
6085 	/* buffer code */
6086 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
6087 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
6088 		if (!continue_dissection) return offset;
6089 	}
6090 
6091 	/* some unknown bytes */
6092 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
6093 	offset += 2;
6094 
6095 	return offset;
6096 }
6097 
6098 
6099 static int
dissect_smb2_lock_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)6100 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
6101 {
6102 	guint16 lock_count;
6103 
6104 	/* buffer code */
6105 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
6106 
6107 	/* lock count */
6108 	lock_count = tvb_get_letohs(tvb, offset);
6109 	proto_tree_add_item(tree, hf_smb2_lock_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6110 	offset += 2;
6111 
6112 	/* reserved */
6113 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6114 	offset += 4;
6115 
6116 	/* fid */
6117 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
6118 
6119 	while (lock_count--) {
6120 		proto_item *lock_item = NULL;
6121 		proto_tree *lock_tree = NULL;
6122 		static int * const lf_fields[] = {
6123 			&hf_smb2_lock_flags_shared,
6124 			&hf_smb2_lock_flags_exclusive,
6125 			&hf_smb2_lock_flags_unlock,
6126 			&hf_smb2_lock_flags_fail_immediately,
6127 			NULL
6128 		};
6129 
6130 		if (tree) {
6131 			lock_item = proto_tree_add_item(tree, hf_smb2_lock_info, tvb, offset, 24, ENC_NA);
6132 			lock_tree = proto_item_add_subtree(lock_item, ett_smb2_lock_info);
6133 		}
6134 
6135 		/* offset */
6136 		proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6137 		offset += 8;
6138 
6139 		/* count */
6140 		proto_tree_add_item(lock_tree, hf_smb2_lock_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6141 		offset += 8;
6142 
6143 		/* flags */
6144 		proto_tree_add_bitmask(lock_tree, tvb, offset, hf_smb2_lock_flags, ett_smb2_lock_flags, lf_fields, ENC_LITTLE_ENDIAN);
6145 		offset += 4;
6146 
6147 		/* reserved */
6148 		proto_tree_add_item(lock_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6149 		offset += 4;
6150 	}
6151 
6152 	return offset;
6153 }
6154 
6155 static int
dissect_smb2_lock_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)6156 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
6157 {
6158 	gboolean continue_dissection;
6159 
6160 	switch (si->status) {
6161 	/* buffer code */
6162 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
6163 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
6164 		if (!continue_dissection) return offset;
6165 	}
6166 
6167 	/* some unknown bytes */
6168 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
6169 	offset += 2;
6170 
6171 	return offset;
6172 }
6173 static int
dissect_smb2_cancel_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)6174 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
6175 {
6176 	/* buffer code */
6177 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
6178 
6179 	/* some unknown bytes */
6180 	proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
6181 	offset += 2;
6182 
6183 	return offset;
6184 }
6185 
6186 static const smb2_fid_info_t *
smb2_pipe_get_fid_info(const smb2_info_t * si)6187 smb2_pipe_get_fid_info(const smb2_info_t *si)
6188 {
6189 	smb2_fid_info_t *file = NULL;
6190 
6191 	if (si == NULL) {
6192 		return NULL;
6193 	}
6194 	if (si->file != NULL) {
6195 		file = si->file;
6196 	} else if (si->saved != NULL) {
6197 		file = si->saved->file;
6198 	}
6199 	if (file == NULL) {
6200 		return NULL;
6201 	}
6202 
6203 	return file;
6204 }
6205 
6206 static void
smb2_pipe_set_file_id(packet_info * pinfo,smb2_info_t * si)6207 smb2_pipe_set_file_id(packet_info *pinfo, smb2_info_t *si)
6208 {
6209 	guint64 persistent;
6210 	const smb2_fid_info_t *file = NULL;
6211 
6212 	file = smb2_pipe_get_fid_info(si);
6213 	if (file == NULL) {
6214 		return;
6215 	}
6216 
6217 	persistent = GPOINTER_TO_UINT(file);
6218 
6219 	dcerpc_set_transport_salt(persistent, pinfo);
6220 }
6221 
6222 static gboolean smb2_pipe_reassembly = TRUE;
6223 static gboolean smb2_verify_signatures = FALSE;
6224 static reassembly_table smb2_pipe_reassembly_table;
6225 
6226 static int
dissect_file_data_smb2_pipe(tvbuff_t * raw_tvb,packet_info * pinfo,proto_tree * tree _U_,int offset,guint32 datalen,proto_tree * top_tree,void * data)6227 dissect_file_data_smb2_pipe(tvbuff_t *raw_tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, proto_tree *top_tree, void *data)
6228 {
6229 	/*
6230 	 * Note: si is NULL for some callers from packet-smb.c
6231 	 */
6232 	const smb2_info_t *si = (const smb2_info_t *)data;
6233 	gboolean result=0;
6234 	gboolean save_fragmented;
6235 	gint remaining;
6236 	guint reported_len;
6237 	const smb2_fid_info_t *file = NULL;
6238 	guint32 id;
6239 	fragment_head *fd_head;
6240 	tvbuff_t *tvb;
6241 	tvbuff_t *new_tvb;
6242 	proto_item *frag_tree_item;
6243 	heur_dtbl_entry_t *hdtbl_entry;
6244 
6245 	file = smb2_pipe_get_fid_info(si);
6246 	id = (guint32)(GPOINTER_TO_UINT(file) & G_MAXUINT32);
6247 
6248 	remaining = tvb_captured_length_remaining(raw_tvb, offset);
6249 
6250 	tvb = tvb_new_subset_length_caplen(raw_tvb, offset,
6251 			     MIN((int)datalen, remaining),
6252 			     datalen);
6253 
6254 	/*
6255 	 * Offer desegmentation service to Named Pipe subdissectors (e.g. DCERPC)
6256 	 * if we have all the data.  Otherwise, reassembly is (probably) impossible.
6257 	 */
6258 	pinfo->can_desegment = 0;
6259 	pinfo->desegment_offset = 0;
6260 	pinfo->desegment_len = 0;
6261 	reported_len = tvb_reported_length(tvb);
6262 	if (smb2_pipe_reassembly && tvb_captured_length(tvb) >= reported_len) {
6263 		pinfo->can_desegment = 2;
6264 	}
6265 
6266 	save_fragmented = pinfo->fragmented;
6267 
6268 	/*
6269 	 * if we are not offering desegmentation, just try the heuristics
6270 	 *and bail out
6271 	 */
6272 	if (!pinfo->can_desegment) {
6273 		result = dissector_try_heuristic(smb2_pipe_subdissector_list,
6274 						 tvb, pinfo, top_tree,
6275 						 &hdtbl_entry, data);
6276 		goto clean_up_and_exit;
6277 	}
6278 
6279 	/* below this line, we know we are doing reassembly */
6280 
6281 	/*
6282 	 * this is a new packet, see if we are already reassembling this
6283 	 * pdu and if not, check if the dissector wants us
6284 	 * to reassemble it
6285 	 */
6286 	if (!pinfo->fd->visited) {
6287 		/*
6288 		 * This is the first pass.
6289 		 *
6290 		 * Check if we are already reassembling this PDU or not;
6291 		 * we check for an in-progress reassembly for this FID
6292 		 * in this direction, by searching for its reassembly
6293 		 * structure.
6294 		 */
6295 		fd_head = fragment_get(&smb2_pipe_reassembly_table,
6296 				       pinfo, id, NULL);
6297 		if (!fd_head) {
6298 			/*
6299 			 * No reassembly, so this is a new pdu. check if the
6300 			 * dissector wants us to reassemble it or if we
6301 			 * already got the full pdu in this tvb.
6302 			 */
6303 
6304 			/*
6305 			 * Try the heuristic dissectors and see if we
6306 			 * find someone that recognizes this payload.
6307 			 */
6308 			result = dissector_try_heuristic(smb2_pipe_subdissector_list,
6309 							 tvb, pinfo, top_tree,
6310 							 &hdtbl_entry, data);
6311 
6312 			/* no this didn't look like something we know */
6313 			if (!result) {
6314 				goto clean_up_and_exit;
6315 			}
6316 
6317 			/* did the subdissector want us to reassemble any
6318 			   more data ?
6319 			*/
6320 			if (pinfo->desegment_len) {
6321 				fragment_add_check(&smb2_pipe_reassembly_table,
6322 					tvb, 0, pinfo, id, NULL,
6323 					0, reported_len, TRUE);
6324 				fragment_set_tot_len(&smb2_pipe_reassembly_table,
6325 					pinfo, id, NULL,
6326 					pinfo->desegment_len+reported_len);
6327 			}
6328 			goto clean_up_and_exit;
6329 		}
6330 
6331 		/* OK, we're already doing a reassembly for this FID.
6332 		   skip to last segment in the existing reassembly structure
6333 		   and add this fragment there
6334 
6335 		   XXX we might add code here to use any offset values
6336 		   we might pick up from the Read/Write calls instead of
6337 		   assuming we always get them in the correct order
6338 		*/
6339 		while (fd_head->next) {
6340 			fd_head = fd_head->next;
6341 		}
6342 		fd_head = fragment_add_check(&smb2_pipe_reassembly_table,
6343 			tvb, 0, pinfo, id, NULL,
6344 			fd_head->offset+fd_head->len,
6345 			reported_len, TRUE);
6346 
6347 		/* if we completed reassembly */
6348 		if (fd_head) {
6349 			new_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
6350 			add_new_data_source(pinfo, new_tvb,
6351 				  "Named Pipe over SMB2");
6352 			pinfo->fragmented=FALSE;
6353 
6354 			tvb = new_tvb;
6355 
6356 			/* list what segments we have */
6357 			show_fragment_tree(fd_head, &smb2_pipe_frag_items,
6358 					   tree, pinfo, tvb, &frag_tree_item);
6359 
6360 			/* dissect the full PDU */
6361 			result = dissector_try_heuristic(smb2_pipe_subdissector_list,
6362 							 tvb, pinfo, top_tree,
6363 							 &hdtbl_entry, data);
6364 		}
6365 		goto clean_up_and_exit;
6366 	}
6367 
6368 	/*
6369 	 * This is not the first pass; see if it's in the table of
6370 	 * reassembled packets.
6371 	 *
6372 	 * XXX - we know that several of the arguments aren't going to
6373 	 * be used, so we pass bogus variables.  Can we clean this
6374 	 * up so that we don't have to distinguish between the first
6375 	 * pass and subsequent passes?
6376 	 */
6377 	fd_head = fragment_add_check(&smb2_pipe_reassembly_table,
6378 				     tvb, 0, pinfo, id, NULL, 0, 0, TRUE);
6379 	if (!fd_head) {
6380 		/* we didn't find it, try any of the heuristic dissectors
6381 		   and bail out
6382 		*/
6383 		result = dissector_try_heuristic(smb2_pipe_subdissector_list,
6384 						 tvb, pinfo, top_tree,
6385 						 &hdtbl_entry, data);
6386 		goto clean_up_and_exit;
6387 	}
6388 	if (!(fd_head->flags&FD_DEFRAGMENTED)) {
6389 		/* we don't have a fully reassembled frame */
6390 		result = dissector_try_heuristic(smb2_pipe_subdissector_list,
6391 						 tvb, pinfo, top_tree,
6392 						 &hdtbl_entry, data);
6393 		goto clean_up_and_exit;
6394 	}
6395 
6396 	/* it is reassembled but it was reassembled in a different frame */
6397 	if (pinfo->num != fd_head->reassembled_in) {
6398 		proto_item *item;
6399 		item = proto_tree_add_uint(top_tree, hf_smb2_pipe_reassembled_in,
6400 					   tvb, 0, 0, fd_head->reassembled_in);
6401 		proto_item_set_generated(item);
6402 		goto clean_up_and_exit;
6403 	}
6404 
6405 	/* display the reassembled pdu */
6406 	new_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
6407 	add_new_data_source(pinfo, new_tvb,
6408 		  "Named Pipe over SMB2");
6409 	pinfo->fragmented = FALSE;
6410 
6411 	tvb = new_tvb;
6412 
6413 	/* list what segments we have */
6414 	show_fragment_tree(fd_head, &smb2_pipe_frag_items,
6415 			   top_tree, pinfo, tvb, &frag_tree_item);
6416 
6417 	/* dissect the full PDU */
6418 	result = dissector_try_heuristic(smb2_pipe_subdissector_list,
6419 					 tvb, pinfo, top_tree,
6420 					 &hdtbl_entry, data);
6421 
6422 clean_up_and_exit:
6423 	/* clear out the variables */
6424 	pinfo->can_desegment=0;
6425 	pinfo->desegment_offset = 0;
6426 	pinfo->desegment_len = 0;
6427 
6428 	if (!result) {
6429 		call_data_dissector(tvb, pinfo, top_tree);
6430 	}
6431 
6432 	pinfo->fragmented = save_fragmented;
6433 
6434 	offset += datalen;
6435 	return offset;
6436 }
6437 
6438 #define SMB2_CHANNEL_NONE		0x00000000
6439 #define SMB2_CHANNEL_RDMA_V1		0x00000001
6440 #define SMB2_CHANNEL_RDMA_V1_INVALIDATE	0x00000002
6441 #define SMB2_CHANNEL_RDMA_TRANSFORM	0x00000003
6442 
6443 static const value_string smb2_channel_vals[] = {
6444 	{ SMB2_CHANNEL_NONE,	"None" },
6445 	{ SMB2_CHANNEL_RDMA_V1,	"RDMA V1" },
6446 	{ SMB2_CHANNEL_RDMA_V1_INVALIDATE,	"RDMA V1_INVALIDATE" },
6447 	{ SMB2_CHANNEL_RDMA_TRANSFORM,	"RDMA TRANSFORM" },
6448 	{ 0, NULL }
6449 };
6450 
6451 static void
dissect_smb2_rdma_v1_blob(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,smb2_info_t * si _U_)6452 dissect_smb2_rdma_v1_blob(tvbuff_t *tvb, packet_info *pinfo _U_,
6453 			  proto_tree *parent_tree, smb2_info_t *si _U_)
6454 {
6455 	int         offset      = 0;
6456 	int         len;
6457 	int         i;
6458 	int         num;
6459 	proto_tree *sub_tree;
6460 	proto_item *parent_item;
6461 
6462 	parent_item = proto_tree_get_parent(parent_tree);
6463 
6464 	len = tvb_reported_length(tvb);
6465 
6466 	num = len / 16;
6467 
6468 	if (parent_item) {
6469 		proto_item_append_text(parent_item, ": SMBDirect Buffer Descriptor V1: (%d elements)", num);
6470 	}
6471 
6472 	for (i = 0; i < num; i++) {
6473 		sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, 8, ett_smb2_rdma_v1, NULL, "RDMA V1");
6474 
6475 		proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6476 		offset += 8;
6477 
6478 		proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6479 		offset += 4;
6480 
6481 		proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6482 		offset += 4;
6483 	}
6484 }
6485 
6486 #define SMB2_WRITE_FLAG_WRITE_THROUGH		0x00000001
6487 #define SMB2_WRITE_FLAG_WRITE_UNBUFFERED	0x00000002
6488 
6489 static const true_false_string tfs_write_through = {
6490 	"Client is asking for WRITE_THROUGH",
6491 	"Client is NOT asking for WRITE_THROUGH"
6492 };
6493 
6494 static const true_false_string tfs_write_unbuffered = {
6495 	"Client is asking for UNBUFFERED write",
6496 	"Client is NOT asking for UNBUFFERED write"
6497 };
6498 
6499 static int
dissect_smb2_write_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)6500 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
6501 {
6502 	guint16 dataoffset = 0;
6503 	guint32 data_tvb_len;
6504 	offset_length_buffer_t c_olb;
6505 	guint32 channel;
6506 	guint32 length;
6507 	guint64 off;
6508 	static int * const f_fields[] = {
6509 		&hf_smb2_write_flags_write_through,
6510 		&hf_smb2_write_flags_write_unbuffered,
6511 		NULL
6512 	};
6513 
6514 	/* buffer code */
6515 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
6516 
6517 	/* data offset */
6518 	dataoffset=tvb_get_letohs(tvb,offset);
6519 	proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6520 	offset += 2;
6521 
6522 	/* length */
6523 	length = tvb_get_letohl(tvb, offset);
6524 	proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6525 	offset += 4;
6526 
6527 	/* offset */
6528 	off = tvb_get_letoh64(tvb, offset);
6529 	if (si->saved) si->saved->file_offset=off;
6530 	proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6531 	offset += 8;
6532 
6533 	col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", length, off);
6534 
6535 	/* fid */
6536 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
6537 
6538 	/* channel */
6539 	channel = tvb_get_letohl(tvb, offset);
6540 	proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6541 	offset += 4;
6542 
6543 	/* remaining bytes */
6544 	proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6545 	offset += 4;
6546 
6547 	/* write channel info blob offset/length */
6548 	offset = dissect_smb2_olb_length_offset(tvb, offset, &c_olb, OLB_O_UINT16_S_UINT16, hf_smb2_channel_info_blob);
6549 
6550 	/* flags */
6551 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_write_flags, ett_smb2_write_flags, f_fields, ENC_LITTLE_ENDIAN);
6552 	offset += 4;
6553 
6554 	/* the write channel info blob itself */
6555 	switch (channel) {
6556 	case SMB2_CHANNEL_RDMA_V1:
6557 	case SMB2_CHANNEL_RDMA_V1_INVALIDATE:
6558 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, dissect_smb2_rdma_v1_blob);
6559 		break;
6560 	case SMB2_CHANNEL_NONE:
6561 	default:
6562 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, NULL);
6563 		break;
6564 	}
6565 
6566 	data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
6567 
6568 	/* data or namedpipe ?*/
6569 	if (length) {
6570 		int oldoffset = offset;
6571 		smb2_pipe_set_file_id(pinfo, si);
6572 		offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
6573 		if (offset != oldoffset) {
6574 			/* managed to dissect pipe data */
6575 			goto out;
6576 		}
6577 	}
6578 
6579 	/* just ordinary data */
6580 	proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, ENC_NA);
6581 
6582 	offset += MIN(length,(guint32)tvb_captured_length_remaining(tvb, offset));
6583 
6584 	offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
6585 
6586 out:
6587 	if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
6588 		if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
6589 			feed_eo_smb2(tvb,pinfo,si,dataoffset,length,off);
6590 		}
6591 	}
6592 
6593 	return offset;
6594 }
6595 
6596 
6597 static int
dissect_smb2_write_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,smb2_info_t * si _U_)6598 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
6599 {
6600 	gboolean continue_dissection;
6601 
6602 	switch (si->status) {
6603 	/* buffer code */
6604 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
6605 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
6606 		if (!continue_dissection) return offset;
6607 	}
6608 
6609 	/* reserved */
6610 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6611 	offset += 2;
6612 
6613 	/* count */
6614 	proto_tree_add_item(tree, hf_smb2_write_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6615 	offset += 4;
6616 
6617 	/* remaining, must be set to 0 */
6618 	proto_tree_add_item(tree, hf_smb2_write_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6619 	offset += 4;
6620 
6621 	/* write channel info offset */
6622 	proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6623 	offset += 2;
6624 
6625 	/* write channel info length */
6626 	proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6627 	offset += 2;
6628 
6629 	return offset;
6630 }
6631 
6632 /* The STORAGE_OFFLOAD_TOKEN is used for "Offload Data Transfer" (ODX) operations,
6633    including FSCTL_OFFLOAD_READ, FSCTL_OFFLOAD_WRITE.  Ref: MS-FSCC 2.3.79
6634    Note: Unlike most of SMB2, the token fields are BIG-endian! */
6635 static int
dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)6636 dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
6637 {
6638 	proto_tree *sub_tree;
6639 	proto_item *sub_item;
6640 	guint32 idlen = 0;
6641 	guint32 idtype = 0;
6642 
6643 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, 512, ett_smb2_fsctl_odx_token, &sub_item, "Token");
6644 
6645 	proto_tree_add_item_ret_uint(sub_tree, hf_smb2_fsctl_odx_token_type, tvb, offset, 4, ENC_BIG_ENDIAN, &idtype);
6646 	offset += 4;
6647 
6648 	proto_item_append_text(sub_item, " (IdType 0x%x)", idtype);
6649 
6650 	/* reserved */
6651 	proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6652 	offset += 2;
6653 
6654 	/* TokenIdLength */
6655 	proto_tree_add_item_ret_uint(sub_tree, hf_smb2_fsctl_odx_token_idlen, tvb, offset, 2, ENC_BIG_ENDIAN, &idlen);
6656 	offset += 2;
6657 
6658 	/* idlen is what the server says is the "meaningful" part of the token.
6659 		However, token ID is always 504 bytes */
6660 	proto_tree_add_bytes_format_value(sub_tree, hf_smb2_fsctl_odx_token_idraw, tvb,
6661 					  offset, idlen, NULL, "Opaque Data");
6662 	offset += 504;
6663 
6664 	return (offset);
6665 }
6666 
6667 /* MS-FSCC 2.3.77, 2.3.78 */
6668 static void
dissect_smb2_FSCTL_OFFLOAD_READ(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean in)6669 dissect_smb2_FSCTL_OFFLOAD_READ(tvbuff_t *tvb,
6670 				packet_info *pinfo _U_,
6671 				proto_tree *tree,
6672 				int offset,
6673 				gboolean in)
6674 {
6675 	proto_tree_add_item(tree, hf_smb2_fsctl_odx_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6676 	offset += 4;
6677 
6678 	proto_tree_add_item(tree, hf_smb2_fsctl_odx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6679 	offset += 4;
6680 
6681 	if (in) {
6682 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_token_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6683 		offset += 4;
6684 
6685 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6686 		offset += 4;
6687 
6688 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6689 		offset += 8;
6690 
6691 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_copy_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6692 		/* offset += 8; */
6693 	} else {
6694 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_xfer_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6695 		offset += 8;
6696 
6697 		(void) dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvb, pinfo, tree, offset);
6698 	}
6699 }
6700 
6701 /* MS-FSCC 2.3.80, 2.3.81 */
6702 static void
dissect_smb2_FSCTL_OFFLOAD_WRITE(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean in)6703 dissect_smb2_FSCTL_OFFLOAD_WRITE(tvbuff_t *tvb,
6704 				packet_info *pinfo _U_,
6705 				proto_tree *tree,
6706 				int offset,
6707 				gboolean in)
6708 {
6709 	proto_tree_add_item(tree, hf_smb2_fsctl_odx_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6710 	offset += 4;
6711 
6712 	proto_tree_add_item(tree, hf_smb2_fsctl_odx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6713 	offset += 4;
6714 
6715 	if (in) {
6716 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6717 		offset += 8;
6718 
6719 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_copy_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6720 		offset += 8;
6721 
6722 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_token_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6723 		offset += 8;
6724 
6725 		dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvb, pinfo, tree, offset);
6726 
6727 	} else {
6728 		proto_tree_add_item(tree, hf_smb2_fsctl_odx_xfer_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6729 		/* offset += 8; */
6730 	}
6731 }
6732 
6733 static void
dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * top_tree,gboolean data_in _U_,void * data)6734 dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *top_tree, gboolean data_in _U_, void *data)
6735 {
6736 	dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, tvb_captured_length_remaining(tvb, offset), top_tree, data);
6737 }
6738 
6739 static void
dissect_smb2_FSCTL_PIPE_WAIT(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree _U_,int offset,proto_tree * top_tree,gboolean data_in _U_)6740 dissect_smb2_FSCTL_PIPE_WAIT(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, proto_tree *top_tree, gboolean data_in _U_)
6741 {
6742 	int timeout_offset;
6743 	guint32 name_len;
6744 	guint8 timeout_specified;
6745 	char *display_string;
6746 
6747 	/* Timeout */
6748 	timeout_offset = offset;
6749 	offset += 8;
6750 
6751 	/* Name length */
6752 	/* XXX - put the name length into the tree */
6753 	name_len = tvb_get_letohl(tvb, offset);
6754 	offset += 4;
6755 
6756 	/* Timeout specified */
6757 	timeout_specified = tvb_get_guint8(tvb, offset);
6758 	if (timeout_specified) {
6759 		proto_tree_add_item(top_tree, hf_smb2_fsctl_pipe_wait_timeout,
6760 		    tvb, timeout_offset, 8, ENC_LITTLE_ENDIAN);
6761 	}
6762 	offset += 1;
6763 
6764 	/* Padding */
6765 	offset += 1;
6766 
6767 	/* Name */
6768 	proto_tree_add_item_ret_display_string(top_tree, hf_smb2_fsctl_pipe_wait_name,
6769 	    tvb, offset, name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
6770 	    pinfo->pool, &display_string);
6771 
6772 	col_append_fstr(pinfo->cinfo, COL_INFO, " Pipe: %s", display_string);
6773 }
6774 
6775 static int
dissect_smb2_FSCTL_SET_SPARSE(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)6776 dissect_smb2_FSCTL_SET_SPARSE(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6777 {
6778 
6779 	/* There is no out data */
6780 	if (!data_in) {
6781 		return offset;
6782 	}
6783 
6784 	/* sparse flag (optional) */
6785 	if (tvb_reported_length_remaining(tvb, offset) >= 1) {
6786 		proto_tree_add_item(tree, hf_smb2_fsctl_sparse_flag, tvb, offset, 1, ENC_NA);
6787 		offset += 1;
6788 	}
6789 
6790 	return offset;
6791 }
6792 
6793 static int
dissect_smb2_FSCTL_SET_ZERO_DATA(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)6794 dissect_smb2_FSCTL_SET_ZERO_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6795 {
6796 	proto_tree *sub_tree;
6797 	proto_item *sub_item;
6798 
6799 	/* There is no out data */
6800 	if (!data_in) {
6801 		return offset;
6802 	}
6803 
6804 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
6805 
6806 	proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6807 	offset += 8;
6808 
6809 	proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6810 	offset += 8;
6811 
6812 	return offset;
6813 }
6814 
6815 static void
dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,int offset _U_,gboolean data_in)6816 dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in)
6817 {
6818 	proto_tree *sub_tree;
6819 	proto_item *sub_item;
6820 
6821 	if (data_in) {
6822 		sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
6823 
6824 		proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6825 		offset += 8;
6826 
6827 		proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6828 		offset += 8;
6829 	} else {
6830 		/* Zero or more allocated ranges may be reported. */
6831 		while (tvb_reported_length_remaining(tvb, offset) >= 16) {
6832 
6833 			sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
6834 
6835 			proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6836 			offset += 8;
6837 
6838 			proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6839 			offset += 8;
6840 		}
6841 	}
6842 }
6843 
6844 
6845 static void
dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,int offset _U_,gboolean data_in)6846 dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in)
6847 {
6848 
6849 	if (data_in) {
6850 		proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6851 		offset += 8;
6852 
6853 		proto_tree_add_item(tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6854 		offset += 8;
6855 
6856 		proto_tree_add_item(tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6857 		offset += 4;
6858 
6859 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6860 		offset += 4;
6861 	} else {
6862 		guint32 entry_count = 0;
6863 
6864 		proto_tree_add_item(tree, hf_smb2_qfr_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6865 		offset += 4;
6866 
6867 		proto_tree_add_item(tree, hf_smb2_qfr_total_region_entry_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6868 		offset += 4;
6869 
6870 		proto_tree_add_item_ret_uint(tree, hf_smb2_qfr_region_entry_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &entry_count);
6871 		offset += 4;
6872 
6873 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6874 		offset += 4;
6875 
6876 		while (entry_count && tvb_reported_length_remaining(tvb, offset)) {
6877 			proto_tree *sub_tree;
6878 			proto_item *sub_item;
6879 
6880 			sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_qfr_entry, &sub_item, "Entry");
6881 
6882 			proto_tree_add_item(sub_tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6883 			offset += 8;
6884 
6885 			proto_tree_add_item(sub_tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6886 			offset += 8;
6887 
6888 			proto_tree_add_item(sub_tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6889 			offset += 4;
6890 
6891 			proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6892 			offset += 4;
6893 
6894 			entry_count--;
6895 		}
6896 	}
6897 }
6898 
6899 static void
dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)6900 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6901 {
6902 	/* There is no out data */
6903 	if (!data_in) {
6904 		return;
6905 	}
6906 
6907 	/* timeout */
6908 	proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6909 	offset += 4;
6910 
6911 	/* reserved */
6912 	proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6913 }
6914 
6915 static void
dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)6916 dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6917 {
6918 	/* There is no in data */
6919 	if (data_in) {
6920 		return;
6921 	}
6922 
6923 	proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_support, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6924 	offset += 4;
6925 
6926 	proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_handle_state, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6927 }
6928 
6929 #define STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID 0x00000001
6930 #define STORAGE_QOS_CONTROL_FLAG_SET_POLICY 0x00000002
6931 #define STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY 0x00000004
6932 #define STORAGE_QOS_CONTROL_FLAG_GET_STATUS 0x00000008
6933 #define STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS 0x00000010
6934 
6935 static const value_string smb2_ioctl_sqos_protocol_version_vals[] = {
6936 	{ 0x0100, "Storage QoS Protocol Version 1.0" },
6937 	{ 0x0101, "Storage QoS Protocol Version 1.1" },
6938 	{ 0, NULL }
6939 };
6940 
6941 static const value_string smb2_ioctl_sqos_status_vals[] = {
6942 	{ 0x00, "StorageQoSStatusOk" },
6943 	{ 0x01, "StorageQoSStatusInsufficientThroughput" },
6944 	{ 0x02, "StorageQoSUnknownPolicyId" },
6945 	{ 0x04, "StorageQoSStatusConfigurationMismatch" },
6946 	{ 0x05, "StorageQoSStatusNotAvailable" },
6947 	{ 0, NULL }
6948 };
6949 
6950 static void
dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,gboolean data_in)6951 dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, gboolean data_in)
6952 {
6953 	static int * const operations[] = {
6954 		&hf_smb2_ioctl_sqos_op_set_logical_flow_id,
6955 		&hf_smb2_ioctl_sqos_op_set_policy,
6956 		&hf_smb2_ioctl_sqos_op_probe_policy,
6957 		&hf_smb2_ioctl_sqos_op_get_status,
6958 		&hf_smb2_ioctl_sqos_op_update_counters,
6959 		NULL
6960 	};
6961 
6962 	gint proto_ver;
6963 
6964 	/* Both request and reply have the same common header */
6965 
6966 	proto_ver = tvb_get_letohs(tvb, offset);
6967 	proto_tree_add_item(tree, hf_smb2_ioctl_sqos_protocol_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6968 	offset += 2;
6969 
6970 	proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6971 	offset += 2;
6972 
6973 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_ioctl_sqos_options,
6974 							ett_smb2_ioctl_sqos_opeations, operations, ENC_LITTLE_ENDIAN);
6975 	offset += 4;
6976 
6977 	proto_tree_add_item(tree, hf_smb2_ioctl_sqos_logical_flow_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6978 	offset += 16;
6979 
6980 	proto_tree_add_item(tree, hf_smb2_ioctl_sqos_policy_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6981 	offset += 16;
6982 
6983 	proto_tree_add_item(tree, hf_smb2_ioctl_sqos_initiator_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6984 	offset += 16;
6985 
6986 	if (data_in) {
6987 		offset_length_buffer_t host_olb, node_olb;
6988 
6989 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6990 		offset += 8;
6991 
6992 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reservation, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6993 		offset += 8;
6994 
6995 		offset = dissect_smb2_olb_length_offset(tvb, offset, &host_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_name);
6996 
6997 		offset = dissect_smb2_olb_length_offset(tvb, offset, &node_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_node_name);
6998 
6999 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7000 		offset += 8;
7001 
7002 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_normalized_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7003 		offset += 8;
7004 
7005 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7006 		offset += 8;
7007 
7008 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_lower_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7009 		offset += 8;
7010 
7011 		if (proto_ver > 0x0100) {
7012 			proto_tree_add_item(tree, hf_smb2_ioctl_sqos_bandwidth_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7013 			offset += 8;
7014 
7015 			proto_tree_add_item(tree, hf_smb2_ioctl_sqos_kilobyte_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7016 			/*offset += 8;*/
7017 		}
7018 
7019 		dissect_smb2_olb_string(pinfo, tree, tvb, &host_olb, OLB_TYPE_UNICODE_STRING);
7020 
7021 		dissect_smb2_olb_string(pinfo, tree, tvb, &node_olb, OLB_TYPE_UNICODE_STRING);
7022 	} else {
7023 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_time_to_live, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7024 		offset += 4;
7025 
7026 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7027 		offset += 4;
7028 
7029 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7030 		offset += 8;
7031 
7032 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_minimum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7033 		offset += 8;
7034 
7035 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_base_io_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7036 		offset += 4;
7037 
7038 		proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7039 
7040 		if (proto_ver > 0x0100) {
7041 			offset += 4;
7042 			proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_bandwidth, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7043 		}
7044 	}
7045 }
7046 
7047 static int
dissect_windows_sockaddr_in(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,int len)7048 dissect_windows_sockaddr_in(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
7049 {
7050 	proto_item *sub_item;
7051 	proto_tree *sub_tree;
7052 	proto_item *parent_item;
7053 
7054 	if (len == -1) {
7055 		len = 8;
7056 	}
7057 
7058 	sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
7059 	parent_item = proto_tree_get_parent(parent_tree);
7060 
7061 	/* family */
7062 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7063 	offset += 2;
7064 
7065 	/* port */
7066 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7067 	offset += 2;
7068 
7069 	/* IPv4 address */
7070 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_in_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
7071 	proto_item_append_text(sub_item, ", IPv4: %s", tvb_ip_to_str(pinfo->pool, tvb, offset));
7072 	proto_item_append_text(parent_item, ", IPv4: %s", tvb_ip_to_str(pinfo->pool, tvb, offset));
7073 	offset += 4;
7074 	return offset;
7075 }
7076 
7077 static int
dissect_windows_sockaddr_in6(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,int len)7078 dissect_windows_sockaddr_in6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
7079 {
7080 	proto_item        *sub_item;
7081 	proto_tree        *sub_tree;
7082 	proto_item        *parent_item;
7083 
7084 	if (len == -1) {
7085 		len = 26;
7086 	}
7087 
7088 	sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
7089 	parent_item = proto_tree_get_parent(parent_tree);
7090 
7091 	/* family */
7092 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7093 	offset += 2;
7094 
7095 	/* port */
7096 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7097 	offset += 2;
7098 
7099 	/* sin6_flowinfo */
7100 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_flowinfo, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7101 	offset += 4;
7102 
7103 	/* IPv6 address */
7104 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_addr, tvb, offset, 16, ENC_NA);
7105 	proto_item_append_text(sub_item, ", IPv6: %s", tvb_ip6_to_str(pinfo->pool, tvb, offset));
7106 	proto_item_append_text(parent_item, ", IPv6: %s", tvb_ip6_to_str(pinfo->pool, tvb, offset));
7107 	offset += 16;
7108 
7109 	/* sin6_scope_id */
7110 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_scope_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7111 	offset += 2;
7112 
7113 	return offset;
7114 }
7115 
7116 static int
dissect_windows_sockaddr_storage(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,int len)7117 dissect_windows_sockaddr_storage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int len)
7118 {
7119 	proto_item *sub_item;
7120 	proto_tree *sub_tree;
7121 	proto_item *parent_item;
7122 	guint16     family;
7123 
7124 	family = tvb_get_letohs(tvb, offset);
7125 	switch (family) {
7126 	case WINSOCK_AF_INET:
7127 		return dissect_windows_sockaddr_in(tvb, pinfo, parent_tree, offset, len);
7128 	case WINSOCK_AF_INET6:
7129 		return dissect_windows_sockaddr_in6(tvb, pinfo, parent_tree, offset, len);
7130 	}
7131 
7132 	sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
7133 	parent_item = proto_tree_get_parent(parent_tree);
7134 
7135 	/* ss_family */
7136 	proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7137 	proto_item_append_text(sub_item, ", Family: %d (0x%04x)", family, family);
7138 	proto_item_append_text(parent_item, ", Family: %d (0x%04x)", family, family);
7139 	return offset + len;
7140 }
7141 
7142 #define NETWORK_INTERFACE_CAP_RSS 0x00000001
7143 #define NETWORK_INTERFACE_CAP_RDMA 0x00000002
7144 
7145 static void
dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree)7146 dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
7147 {
7148 	guint32     next_offset;
7149 	int         offset   = 0;
7150 	int         len      = -1;
7151 	proto_item *sub_item;
7152 	proto_tree *sub_tree;
7153 	proto_item *item;
7154 	guint32     capabilities;
7155 	guint64     link_speed;
7156 	gfloat      val      = 0;
7157 	const char *unit     = NULL;
7158 	static int * const capability_flags[] = {
7159 		&hf_smb2_ioctl_network_interface_capability_rdma,
7160 		&hf_smb2_ioctl_network_interface_capability_rss,
7161 		NULL
7162 	};
7163 
7164 	next_offset = tvb_get_letohl(tvb, offset);
7165 	if (next_offset) {
7166 		len = next_offset;
7167 	}
7168 
7169 	sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_smb2_ioctl_network_interface, &sub_item, "Network Interface");
7170 	item = proto_tree_get_parent(parent_tree);
7171 
7172 	/* next offset */
7173 	proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7174 	offset += 4;
7175 
7176 	/* interface index */
7177 	proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7178 	offset += 4;
7179 
7180 	/* capabilities */
7181 	capabilities = tvb_get_letohl(tvb, offset);
7182 	proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_ioctl_network_interface_capabilities, ett_smb2_ioctl_network_interface_capabilities, capability_flags, ENC_LITTLE_ENDIAN);
7183 
7184 	if (capabilities != 0) {
7185 		proto_item_append_text(item, "%s%s",
7186 				       (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
7187 				       (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
7188 		proto_item_append_text(sub_item, "%s%s",
7189 				       (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
7190 				       (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
7191 	}
7192 	offset += 4;
7193 
7194 	/* rss queue count */
7195 	proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_rss_queue_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7196 	offset += 4;
7197 
7198 	/* link speed */
7199 	link_speed = tvb_get_letoh64(tvb, offset);
7200 	item = proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_link_speed, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7201 	if (link_speed >= (1000*1000*1000)) {
7202 		val = (gfloat)(link_speed / (1000*1000*1000));
7203 		unit = "G";
7204 	} else if (link_speed >= (1000*1000)) {
7205 		val = (gfloat)(link_speed / (1000*1000));
7206 		unit = "M";
7207 	} else if (link_speed >= (1000)) {
7208 		val = (gfloat)(link_speed / (1000));
7209 		unit = "K";
7210 	} else {
7211 		val = (gfloat)(link_speed);
7212 		unit = "";
7213 	}
7214 	proto_item_append_text(item, ", %.1f %sBits/s", val, unit);
7215 	proto_item_append_text(sub_item, ", %.1f %sBits/s", val, unit);
7216 
7217 	offset += 8;
7218 
7219 	/* socket address */
7220 	dissect_windows_sockaddr_storage(tvb, pinfo, sub_tree, offset, -1);
7221 
7222 	if (next_offset) {
7223 		tvbuff_t *next_tvb;
7224 		next_tvb = tvb_new_subset_remaining(tvb, next_offset);
7225 
7226 		/* next extra info */
7227 		dissect_smb2_NETWORK_INTERFACE_INFO(next_tvb, pinfo, parent_tree);
7228 	}
7229 }
7230 
7231 static void
dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset _U_,gboolean data_in)7232 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
7233 {
7234 	/* There is no in data */
7235 	if (data_in) {
7236 		return;
7237 	}
7238 
7239 	dissect_smb2_NETWORK_INTERFACE_INFO(tvb, pinfo, tree);
7240 }
7241 
7242 static void
dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset _U_,gboolean data_in)7243 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
7244 {
7245 	/*
7246 	 * This is only used by Windows 8 beta
7247 	 */
7248 	if (data_in) {
7249 		/* capabilities */
7250 		offset = dissect_smb2_capabilities(tree, tvb, offset);
7251 
7252 		/* client guid */
7253 		proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7254 		offset += 16;
7255 
7256 		/* security mode, skip second byte */
7257 		offset = dissect_smb2_secmode(tree, tvb, offset);
7258 		offset++;
7259 
7260 		/* dialect */
7261 		proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7262 		offset += 2;
7263 	} else {
7264 		/* capabilities */
7265 		offset = dissect_smb2_capabilities(tree, tvb, offset);
7266 
7267 		/* server guid */
7268 		proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7269 		offset += 16;
7270 
7271 		/* security mode, skip second byte */
7272 		offset = dissect_smb2_secmode(tree, tvb, offset);
7273 		offset++;
7274 
7275 		/* dialect */
7276 		proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7277 		offset += 2;
7278 	}
7279 }
7280 
7281 static void
dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset _U_,gboolean data_in)7282 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
7283 {
7284 	if (data_in) {
7285 		guint16 dc;
7286 
7287 		/* capabilities */
7288 		offset = dissect_smb2_capabilities(tree, tvb, offset);
7289 
7290 		/* client guid */
7291 		proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7292 		offset += 16;
7293 
7294 		/* security mode, skip second byte */
7295 		offset = dissect_smb2_secmode(tree, tvb, offset);
7296 		offset++;
7297 
7298 		/* dialect count */
7299 		dc = tvb_get_letohs(tvb, offset);
7300 		proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7301 		offset += 2;
7302 
7303 		for ( ; dc>0; dc--) {
7304 			proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7305 			offset += 2;
7306 		}
7307 	} else {
7308 		/* capabilities */
7309 		offset = dissect_smb2_capabilities(tree, tvb, offset);
7310 
7311 		/* server guid */
7312 		proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7313 		offset += 16;
7314 
7315 		/* security mode, skip second byte */
7316 		offset = dissect_smb2_secmode(tree, tvb, offset);
7317 		offset++;
7318 
7319 		/* dialect */
7320 		proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7321 		offset += 2;
7322 	}
7323 }
7324 
7325 static void
dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7326 dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7327 {
7328 	guint32 num_snapshots;
7329 
7330 	/* There is no in data */
7331 	if (data_in) {
7332 		return;
7333 	}
7334 
7335 	/* NumberOfSnapShots */
7336 	proto_tree_add_item(tree, hf_smb2_ioctl_enumerate_snapshots_num_snapshots, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7337 	offset += 4;
7338 
7339 	/* NumberOfSnapshotsReturned */
7340 	proto_tree_add_item_ret_uint(tree, hf_smb2_ioctl_enumerate_snapshots_num_snapshots_returned, tvb, offset, 4, ENC_LITTLE_ENDIAN, &num_snapshots);
7341 	offset += 4;
7342 
7343 	/* SnapShotArraySize */
7344 	proto_tree_add_item(tree, hf_smb2_ioctl_enumerate_snapshots_snapshot_array_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7345 	offset += 4;
7346 
7347 	while (num_snapshots--) {
7348 		gint len;
7349 		int old_offset = offset;
7350 
7351 		proto_tree_add_item_ret_length(tree, hf_smb2_ioctl_enumerate_snapshots_snapshot,
7352 			tvb, offset, -1, ENC_UTF_16|ENC_LITTLE_ENDIAN, &len);
7353 
7354 		offset = old_offset+len;
7355 	}
7356 }
7357 
7358 int
dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset)7359 dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
7360 {
7361 	proto_item *item = NULL;
7362 	proto_tree *tree = NULL;
7363 
7364 	/* FILE_OBJECTID_BUFFER */
7365 	if (parent_tree) {
7366 		item = proto_tree_add_item(parent_tree, hf_smb2_FILE_OBJECTID_BUFFER, tvb, offset, 64, ENC_NA);
7367 		tree = proto_item_add_subtree(item, ett_smb2_FILE_OBJECTID_BUFFER);
7368 	}
7369 
7370 	/* Object ID */
7371 	proto_tree_add_item(tree, hf_smb2_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7372 	offset += 16;
7373 
7374 	/* Birth Volume ID */
7375 	proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7376 	offset += 16;
7377 
7378 	/* Birth Object ID */
7379 	proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7380 	offset += 16;
7381 
7382 	/* Domain ID */
7383 	proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7384 	offset += 16;
7385 
7386 	return offset;
7387 }
7388 
7389 static int
dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7390 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7391 {
7392 
7393 	/* There is no in data */
7394 	if (data_in) {
7395 		return offset;
7396 	}
7397 
7398 	/* FILE_OBJECTID_BUFFER */
7399 	offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
7400 
7401 	return offset;
7402 }
7403 
7404 static int
dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7405 dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7406 {
7407 
7408 	/* There is no in data */
7409 	if (data_in) {
7410 		return offset;
7411 	}
7412 
7413 	/* compression format */
7414 	proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7415 	offset += 2;
7416 
7417 	return offset;
7418 }
7419 
7420 static int
dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7421 dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7422 {
7423 
7424 	/* There is no out data */
7425 	if (!data_in) {
7426 		return offset;
7427 	}
7428 
7429 	/* compression format */
7430 	proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7431 	offset += 2;
7432 
7433 	return offset;
7434 }
7435 
7436 static int
dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7437 dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7438 {
7439 	static int * const integrity_flags[] = {
7440 		&hf_smb2_integrity_flags_enforcement_off,
7441 		NULL
7442 	};
7443 
7444 	/* There is no out data */
7445 	if (!data_in) {
7446 		return offset;
7447 	}
7448 
7449 	proto_tree_add_item(tree, hf_smb2_checksum_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7450 	offset += 2;
7451 
7452 	proto_tree_add_item(tree, hf_smb2_integrity_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7453 	offset += 2;
7454 
7455 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_integrity_flags, ett_smb2_integrity_flags, integrity_flags, ENC_LITTLE_ENDIAN);
7456 	offset += 4;
7457 
7458 	return offset;
7459 }
7460 
7461 static int
dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7462 dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7463 {
7464 
7465 	/* There is no out data */
7466 	if (!data_in) {
7467 		return offset;
7468 	}
7469 
7470 	/* FILE_OBJECTID_BUFFER */
7471 	offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
7472 
7473 	return offset;
7474 }
7475 
7476 static int
dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7477 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7478 {
7479 
7480 	/* There is no out data */
7481 	if (!data_in) {
7482 		return offset;
7483 	}
7484 
7485 	/* FILE_OBJECTID_BUFFER->ExtendedInfo */
7486 
7487 	/* Birth Volume ID */
7488 	proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7489 	offset += 16;
7490 
7491 	/* Birth Object ID */
7492 	proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7493 	offset += 16;
7494 
7495 	/* Domain ID */
7496 	proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7497 	offset += 16;
7498 
7499 	return offset;
7500 }
7501 
7502 static int
dissect_smb2_cchunk_RESUME_KEY(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)7503 dissect_smb2_cchunk_RESUME_KEY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
7504 {
7505 
7506 	proto_tree_add_bytes_format_value(tree, hf_smb2_cchunk_resume_key, tvb,
7507 					  offset, 24, NULL, "Opaque Data");
7508 	offset += 24;
7509 
7510 	return (offset);
7511 }
7512 
7513 static void
dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7514 dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7515 {
7516 
7517 	/* There is no in data */
7518 	if (data_in) {
7519 		return;
7520 	}
7521 
7522 	offset = dissect_smb2_cchunk_RESUME_KEY(tvb, pinfo, tree, offset);
7523 
7524 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7525 }
7526 
7527 static void
dissect_smb2_FSCTL_SRV_COPYCHUNK(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,gboolean data_in)7528 dissect_smb2_FSCTL_SRV_COPYCHUNK(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
7529 {
7530 	proto_tree *sub_tree;
7531 	proto_item *sub_item;
7532 	guint32 chunk_count = 0;
7533 
7534 	/* Output is simpler - handle that first. */
7535 	if (!data_in) {
7536 		proto_tree_add_item(tree, hf_smb2_cchunk_chunks_written, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7537 		proto_tree_add_item(tree, hf_smb2_cchunk_bytes_written, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
7538 		proto_tree_add_item(tree, hf_smb2_cchunk_total_written, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
7539 		return;
7540 	}
7541 
7542 	/* Input data, fixed part */
7543 	offset = dissect_smb2_cchunk_RESUME_KEY(tvb, pinfo, tree, offset);
7544 	proto_tree_add_item_ret_uint(tree, hf_smb2_cchunk_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &chunk_count);
7545 	offset += 4;
7546 
7547 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7548 	offset += 4;
7549 
7550 	/* Zero or more allocated ranges may be reported. */
7551 	while (chunk_count && tvb_reported_length_remaining(tvb, offset) >= 24) {
7552 		sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_smb2_cchunk_entry, &sub_item, "Chunk");
7553 
7554 		proto_tree_add_item(sub_tree, hf_smb2_cchunk_src_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7555 		offset += 8;
7556 
7557 		proto_tree_add_item(sub_tree, hf_smb2_cchunk_dst_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7558 		offset += 8;
7559 
7560 		proto_tree_add_item(sub_tree, hf_smb2_cchunk_xfer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7561 		offset += 4;
7562 
7563 		proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7564 		offset += 4;
7565 
7566 		chunk_count--;
7567 	}
7568 }
7569 
7570 static void
dissect_smb2_reparse_nfs(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint32 length)7571 dissect_smb2_reparse_nfs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint32 length)
7572 {
7573 	guint64 type;
7574 	int symlink_length;
7575 
7576 	type = tvb_get_letoh64(tvb, offset);
7577 	proto_tree_add_item(tree, hf_smb2_nfs_type, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7578 	offset += 8;
7579 
7580 	switch (type) {
7581 	case NFS_SPECFILE_LNK:
7582 		/*
7583 		 * According to [MS-FSCC] 2.1.2.6 "length" contains
7584 		 * the 8-byte type plus the symlink target in Unicode
7585 		 * non-NULL terminated.
7586 		 */
7587 		if (length < 8) {
7588 			THROW(ReportedBoundsError);
7589 		}
7590 		symlink_length = length - 8;
7591 		proto_tree_add_item(tree, hf_smb2_nfs_symlink_target, tvb, offset,
7592 				      symlink_length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
7593 		break;
7594 	case NFS_SPECFILE_CHR:
7595 		proto_tree_add_item(tree, hf_smb2_nfs_chr_major, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7596 		offset += 4;
7597 		proto_tree_add_item(tree, hf_smb2_nfs_chr_minor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7598 		break;
7599 	case NFS_SPECFILE_BLK:
7600 		proto_tree_add_item(tree, hf_smb2_nfs_blk_major, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7601 		offset += 4;
7602 		proto_tree_add_item(tree, hf_smb2_nfs_blk_minor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7603 		break;
7604 	case NFS_SPECFILE_FIFO:
7605 	case NFS_SPECFILE_SOCK:
7606 		/* no data */
7607 		break;
7608 	}
7609 }
7610 
7611 static void
dissect_smb2_FSCTL_REPARSE_POINT(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset)7612 dissect_smb2_FSCTL_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
7613 {
7614 	proto_item *item = NULL;
7615 	proto_tree *tree = NULL;
7616 
7617 	guint32 tag;
7618 	guint32 length;
7619 	offset_length_buffer_t  s_olb, p_olb;
7620 
7621 	/* REPARSE_DATA_BUFFER */
7622 	if (parent_tree) {
7623 		item = proto_tree_add_item(parent_tree, hf_smb2_reparse_data_buffer, tvb, offset, -1, ENC_NA);
7624 		tree = proto_item_add_subtree(item, ett_smb2_reparse_data_buffer);
7625 	}
7626 
7627 	/* reparse tag */
7628 	tag = tvb_get_letohl(tvb, offset);
7629 	proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7630 	offset += 4;
7631 
7632 	/* reparse data length */
7633 	length = tvb_get_letohs(tvb, offset);
7634 	proto_tree_add_item(tree, hf_smb2_reparse_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7635 	offset += 2;
7636 
7637 	/* reserved */
7638 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
7639 	offset += 2;
7640 
7641 	if (!(tag & 0x80000000)) {
7642 		/* if high bit is not set, this buffer has a GUID field */
7643 		/* reparse guid */
7644 		proto_tree_add_item(tree, hf_smb2_reparse_guid, tvb, offset, 16, ENC_NA);
7645 		offset += 16;
7646 	}
7647 
7648 	switch (tag) {
7649 	case REPARSE_TAG_SYMLINK:
7650 		/* substitute name  offset/length */
7651 		offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_substitute_name);
7652 
7653 		/* print name offset/length */
7654 		offset = dissect_smb2_olb_length_offset(tvb, offset, &p_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_print_name);
7655 
7656 		/* flags */
7657 		proto_tree_add_item(tree, hf_smb2_symlink_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7658 		offset += 4;
7659 
7660 		/* substitute name string */
7661 		dissect_smb2_olb_off_string(pinfo, tree, tvb, &s_olb, offset, OLB_TYPE_UNICODE_STRING);
7662 
7663 		/* print name string */
7664 		dissect_smb2_olb_off_string(pinfo, tree, tvb, &p_olb, offset, OLB_TYPE_UNICODE_STRING);
7665 		break;
7666 	case REPARSE_TAG_NFS:
7667 		dissect_smb2_reparse_nfs(tvb, pinfo, tree, offset, length);
7668 		break;
7669 	default:
7670 		proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, length, ENC_NA);
7671 	}
7672 }
7673 
7674 static void
dissect_smb2_FSCTL_SET_REPARSE_POINT(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,gboolean data_in)7675 dissect_smb2_FSCTL_SET_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, gboolean data_in)
7676 {
7677 	if (!data_in) {
7678 		return;
7679 	}
7680 
7681 	dissect_smb2_FSCTL_REPARSE_POINT(tvb, pinfo, parent_tree, offset);
7682 }
7683 
7684 static void
dissect_smb2_FSCTL_GET_REPARSE_POINT(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,gboolean data_in)7685 dissect_smb2_FSCTL_GET_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, gboolean data_in)
7686 {
7687 	if (data_in) {
7688 		return;
7689 	}
7690 
7691 	dissect_smb2_FSCTL_REPARSE_POINT(tvb, pinfo, parent_tree, offset);
7692 }
7693 
7694 void
dissect_smb2_ioctl_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * top_tree,guint32 ioctl_function,gboolean data_in,void * private_data _U_)7695 dissect_smb2_ioctl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *top_tree, guint32 ioctl_function, gboolean data_in, void *private_data _U_)
7696 {
7697 	guint16 dc;
7698 
7699 	dc = tvb_reported_length(tvb);
7700 
7701 	switch (ioctl_function) {
7702 	case 0x00060194: /* FSCTL_DFS_GET_REFERRALS */
7703 		if (data_in) {
7704 			dissect_get_dfs_request_data(tvb, pinfo, tree, 0, &dc, TRUE);
7705 		} else {
7706 			dissect_get_dfs_referral_data(tvb, pinfo, tree, 0, &dc, TRUE);
7707 		}
7708 		break;
7709 	case 0x000940CF: /* FSCTL_QUERY_ALLOCATED_RANGES */
7710 		dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvb, pinfo, tree, 0, data_in);
7711 		break;
7712 	case 0x00094264: /* FSCTL_OFFLOAD_READ */
7713 		dissect_smb2_FSCTL_OFFLOAD_READ(tvb, pinfo, tree, 0, data_in);
7714 		break;
7715 	case 0x00098268: /* FSCTL_OFFLOAD_WRITE */
7716 		dissect_smb2_FSCTL_OFFLOAD_WRITE(tvb, pinfo, tree, 0, data_in);
7717 		break;
7718 	case 0x0011c017: /* FSCTL_PIPE_TRANSCEIVE */
7719 		dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvb, pinfo, tree, 0, top_tree, data_in, private_data);
7720 		break;
7721 	case 0x00110018: /* FSCTL_PIPE_WAIT */
7722 		dissect_smb2_FSCTL_PIPE_WAIT(tvb, pinfo, tree, 0, top_tree, data_in);
7723 		break;
7724 	case 0x00140078: /* FSCTL_SRV_REQUEST_RESUME_KEY */
7725 		dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvb, pinfo, tree, 0, data_in);
7726 		break;
7727 	case 0x001401D4: /* FSCTL_LMR_REQUEST_RESILIENCY */
7728 		dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvb, pinfo, tree, 0, data_in);
7729 		break;
7730 	case 0x001401FC: /* FSCTL_QUERY_NETWORK_INTERFACE_INFO */
7731 		dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvb, pinfo, tree, 0, data_in);
7732 		break;
7733 	case 0x00140200: /* FSCTL_VALIDATE_NEGOTIATE_INFO_224 */
7734 		dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvb, pinfo, tree, 0, data_in);
7735 		break;
7736 	case 0x00140204: /* FSCTL_VALIDATE_NEGOTIATE_INFO */
7737 		dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvb, pinfo, tree, 0, data_in);
7738 		break;
7739 	case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */
7740 		dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvb, pinfo, tree, 0, data_in);
7741 		break;
7742 	case 0x001440F2: /* FSCTL_SRV_COPYCHUNK */
7743 	case 0x001480F2: /* FSCTL_SRV_COPYCHUNK_WRITE */
7744 		dissect_smb2_FSCTL_SRV_COPYCHUNK(tvb, pinfo, tree, 0, data_in);
7745 		break;
7746 	case 0x000900A4: /* FSCTL_SET_REPARSE_POINT */
7747 		dissect_smb2_FSCTL_SET_REPARSE_POINT(tvb, pinfo, tree, 0, data_in);
7748 		break;
7749 	case 0x000900A8: /* FSCTL_GET_REPARSE_POINT */
7750 		dissect_smb2_FSCTL_GET_REPARSE_POINT(tvb, pinfo, tree, 0, data_in);
7751 		break;
7752 	case 0x0009009C: /* FSCTL_GET_OBJECT_ID */
7753 	case 0x000900c0: /* FSCTL_CREATE_OR_GET_OBJECT_ID */
7754 		dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
7755 		break;
7756 	case 0x000900c4: /* FSCTL_SET_SPARSE */
7757 		dissect_smb2_FSCTL_SET_SPARSE(tvb, pinfo, tree, 0, data_in);
7758 		break;
7759 	case 0x00098098: /* FSCTL_SET_OBJECT_ID */
7760 		dissect_smb2_FSCTL_SET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
7761 		break;
7762 	case 0x000980BC: /* FSCTL_SET_OBJECT_ID_EXTENDED */
7763 		dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvb, pinfo, tree, 0, data_in);
7764 		break;
7765 	case 0x000980C8: /* FSCTL_SET_ZERO_DATA */
7766 		dissect_smb2_FSCTL_SET_ZERO_DATA(tvb, pinfo, tree, 0, data_in);
7767 		break;
7768 	case 0x0009003C: /* FSCTL_GET_COMPRESSION */
7769 		dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
7770 		break;
7771 	case 0x00090300: /* FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT */
7772 		dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvb, pinfo, tree, 0, data_in);
7773 		break;
7774 	case 0x00090304: /* FSCTL_SVHDX_SYNC_TUNNEL or response */
7775 	case 0x00090364: /* FSCTL_SVHDX_ASYNC_TUNNEL or response */
7776 		call_dissector_with_data(rsvd_handle, tvb, pinfo, top_tree, &data_in);
7777 		break;
7778 	case 0x00090350: /* FSCTL_STORAGE_QOS_CONTROL */
7779 		dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvb, pinfo, tree, 0, data_in);
7780 		break;
7781 	case 0x0009C040: /* FSCTL_SET_COMPRESSION */
7782 		dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
7783 		break;
7784 	case 0x00090284: /* FSCTL_QUERY_FILE_REGIONS */
7785 		dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvb, pinfo, tree, 0, data_in);
7786 		break;
7787 	case 0x0009C280: /* FSCTL_SET_INTEGRITY_INFORMATION request or response */
7788 		dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvb, pinfo, tree, 0, data_in);
7789 		break;
7790 	default:
7791 		proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
7792 	}
7793 }
7794 
7795 static void
dissect_smb2_ioctl_data_in(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)7796 dissect_smb2_ioctl_data_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7797 {
7798 	smb2_pipe_set_file_id(pinfo, si);
7799 	dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, TRUE, si);
7800 }
7801 
7802 static void
dissect_smb2_ioctl_data_out(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)7803 dissect_smb2_ioctl_data_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7804 {
7805 	smb2_pipe_set_file_id(pinfo, si);
7806 	dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, FALSE, si);
7807 }
7808 
7809 static int
dissect_smb2_ioctl_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)7810 dissect_smb2_ioctl_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7811 {
7812 	offset_length_buffer_t o_olb;
7813 	offset_length_buffer_t i_olb;
7814 	proto_tree *flags_tree = NULL;
7815 	proto_item *flags_item = NULL;
7816 
7817 	/* buffer code */
7818 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
7819 
7820 	/* reserved */
7821 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
7822 	offset += 2;
7823 
7824 	/* ioctl function */
7825 	offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
7826 
7827 	/* fid */
7828 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
7829 
7830 	/* in buffer offset/length */
7831 	offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
7832 
7833 	/* max ioctl in size */
7834 	proto_tree_add_item(tree, hf_smb2_max_ioctl_in_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7835 	offset += 4;
7836 
7837 	/* out buffer offset/length */
7838 	offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
7839 
7840 	/* max ioctl out size */
7841 	proto_tree_add_item(tree, hf_smb2_max_ioctl_out_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7842 	offset += 4;
7843 
7844 	/* flags */
7845 	if (tree) {
7846 		flags_item = proto_tree_add_item(tree, hf_smb2_ioctl_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7847 		flags_tree = proto_item_add_subtree(flags_item, ett_smb2_ioctl_flags);
7848 	}
7849 	proto_tree_add_item(flags_tree, hf_smb2_ioctl_is_fsctl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7850 	offset += 4;
7851 
7852 	/* reserved */
7853 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7854 	offset += 4;
7855 
7856 	/* try to decode these blobs in the order they were encoded
7857 	 * so that for "short" packets we will dissect as much as possible
7858 	 * before aborting with "short packet"
7859 	 */
7860 	if (i_olb.off>o_olb.off) {
7861 		/* out buffer */
7862 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7863 		/* in buffer */
7864 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7865 	} else {
7866 		/* in buffer */
7867 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7868 		/* out buffer */
7869 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7870 	}
7871 
7872 	offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
7873 	offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
7874 
7875 	return offset;
7876 }
7877 
7878 static int
dissect_smb2_ioctl_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)7879 dissect_smb2_ioctl_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7880 {
7881 	offset_length_buffer_t o_olb;
7882 	offset_length_buffer_t i_olb;
7883 	gboolean continue_dissection;
7884 
7885 	switch (si->status) {
7886 	/* buffer code */
7887 	/* if we get BUFFER_OVERFLOW there will be truncated data */
7888 	case 0x80000005:
7889 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
7890 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
7891 		if (!continue_dissection) return offset;
7892 	}
7893 
7894 	/* reserved */
7895 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
7896 	offset += 2;
7897 
7898 	/* ioctl function */
7899 	offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
7900 
7901 	/* fid */
7902 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
7903 
7904 	/* in buffer offset/length */
7905 	offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
7906 
7907 	/* out buffer offset/length */
7908 	offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
7909 
7910 
7911 	/* flags: reserved: must be zero */
7912 	proto_tree_add_item(tree, hf_smb2_flags, tvb, offset, 4, ENC_NA);
7913 	offset += 4;
7914 
7915 	/* reserved */
7916 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7917 	offset += 4;
7918 
7919 	/* try to decode these blobs in the order they were encoded
7920 	 * so that for "short" packets we will dissect as much as possible
7921 	 * before aborting with "short packet"
7922 	 */
7923 	if (i_olb.off>o_olb.off) {
7924 		/* out buffer */
7925 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7926 		/* in buffer */
7927 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7928 	} else {
7929 		/* in buffer */
7930 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7931 		/* out buffer */
7932 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7933 	}
7934 
7935 	offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
7936 	offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
7937 
7938 	return offset;
7939 }
7940 
7941 
7942 #define SMB2_READFLAG_READ_UNBUFFERED 0x01
7943 #define SMB2_READFLAG_READ_COMPRESSED 0x02
7944 
7945 static const true_false_string tfs_read_unbuffered = {
7946 	"Client is asking for UNBUFFERED read",
7947 	"Client is NOT asking for UNBUFFERED read"
7948 };
7949 
7950 static const true_false_string tfs_read_compressed = {
7951 	"Client is asking for COMPRESSED data",
7952 	"Client is NOT asking for COMPRESSED data"
7953 };
7954 
7955 static int
dissect_smb2_read_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)7956 dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7957 {
7958 	offset_length_buffer_t c_olb;
7959 	guint32 channel;
7960 	guint32 len;
7961 	guint64 off;
7962 
7963 	static int * const flags[] = {
7964 	     &hf_smb2_read_flags_unbuffered,
7965 	     &hf_smb2_read_flags_compressed,
7966 	     NULL
7967 	};
7968 
7969 	/* buffer code */
7970 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
7971 
7972 	/* padding */
7973 	proto_tree_add_item(tree, hf_smb2_read_padding, tvb, offset, 1, ENC_LITTLE_ENDIAN);
7974 	offset += 1;
7975 
7976 	/* flags */
7977 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_read_flags,
7978 			       ett_smb2_read_flags, flags, ENC_LITTLE_ENDIAN);
7979 	offset += 1;
7980 
7981 	/* length */
7982 	len = tvb_get_letohl(tvb, offset);
7983 	proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7984 	offset += 4;
7985 
7986 	/* offset */
7987 	off = tvb_get_letoh64(tvb, offset);
7988 	proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7989 	offset += 8;
7990 
7991 	col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", len, off);
7992 
7993 	/* fid */
7994 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
7995 
7996 	/* minimum count */
7997 	proto_tree_add_item(tree, hf_smb2_min_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7998 	offset += 4;
7999 
8000 	/* channel */
8001 	channel = tvb_get_letohl(tvb, offset);
8002 	proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8003 	offset += 4;
8004 
8005 	/* remaining bytes */
8006 	proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8007 	offset += 4;
8008 
8009 	/* read channel info blob offset/length */
8010 	offset = dissect_smb2_olb_length_offset(tvb, offset, &c_olb, OLB_O_UINT16_S_UINT16, hf_smb2_channel_info_blob);
8011 
8012 	/* the read channel info blob itself */
8013 	switch (channel) {
8014 	case SMB2_CHANNEL_RDMA_V1:
8015 	case SMB2_CHANNEL_RDMA_V1_INVALIDATE:
8016 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, dissect_smb2_rdma_v1_blob);
8017 		break;
8018 	case SMB2_CHANNEL_NONE:
8019 	default:
8020 		dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, NULL);
8021 		break;
8022 	}
8023 
8024 	offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
8025 
8026 	/* Store len and offset */
8027 	if (si->saved) {
8028 		si->saved->file_offset=off;
8029 		si->saved->bytes_moved=len;
8030 	}
8031 
8032 	return offset;
8033 }
8034 
8035 static void
dissect_smb2_read_blob(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)8036 dissect_smb2_read_blob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
8037 {
8038 	gint offset = 0;
8039 	gint length = tvb_captured_length_remaining(tvb, offset);
8040 
8041 	smb2_pipe_set_file_id(pinfo, si);
8042 
8043 	offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
8044 	if (offset != 0) {
8045 		/* managed to dissect pipe data */
8046 		return;
8047 	}
8048 
8049 	/* data */
8050 	proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, ENC_NA);
8051 }
8052 
8053 static int
dissect_smb2_read_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si _U_)8054 dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
8055 {
8056 	offset_length_buffer_t olb;
8057 	guint32 data_tvb_len;
8058 	gboolean continue_dissection;
8059 
8060 	switch (si->status) {
8061 	/* buffer code */
8062 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8063 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8064 		if (!continue_dissection) return offset;
8065 	}
8066 
8067 	/* data offset 8 bit, 8 bit reserved, length 32bit */
8068 	offset = dissect_smb2_olb_length_offset(tvb, offset, &olb,
8069 						OLB_O_UINT8_P_UINT8_S_UINT32,
8070 						hf_smb2_read_blob);
8071 
8072 	/* remaining */
8073 	proto_tree_add_item(tree, hf_smb2_read_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8074 	offset += 4;
8075 
8076 	/* reserved */
8077 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8078 	offset += 4;
8079 
8080 	data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
8081 
8082 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_read_blob);
8083 
8084 	offset += MIN(olb.len, data_tvb_len);
8085 
8086 	if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == olb.len)) {
8087 		if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
8088 			feed_eo_smb2(tvb,pinfo,si,olb.off,olb.len,si->saved->file_offset);
8089 		}
8090 	}
8091 
8092 	return offset;
8093 }
8094 
8095 static void
report_create_context_malformed_buffer(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const char * buffer_desc)8096 report_create_context_malformed_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const char *buffer_desc)
8097 {
8098 	proto_tree_add_expert_format(tree, pinfo, &ei_smb2_bad_response, tvb, 0, -1,
8099 			    "%s SHOULD NOT be generated", buffer_desc);
8100 }
8101 static void
dissect_smb2_ExtA_buffer_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)8102 dissect_smb2_ExtA_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
8103 {
8104 	proto_item *item = NULL;
8105 	if (tree) {
8106 		item = proto_tree_get_parent(tree);
8107 		proto_item_append_text(item, ": SMB2_FILE_FULL_EA_INFO");
8108 	}
8109 	dissect_smb2_file_full_ea_info(tvb, pinfo, tree, 0, si);
8110 }
8111 
8112 static void
dissect_smb2_ExtA_buffer_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si _U_)8113 dissect_smb2_ExtA_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
8114 {
8115 	report_create_context_malformed_buffer(tvb, pinfo, tree, "ExtA Response");
8116 }
8117 
8118 static void
dissect_smb2_SecD_buffer_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)8119 dissect_smb2_SecD_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
8120 {
8121 	proto_item *item = NULL;
8122 	if (tree) {
8123 		item = proto_tree_get_parent(tree);
8124 		proto_item_append_text(item, ": SMB2_SEC_INFO_00");
8125 	}
8126 	dissect_smb2_sec_info_00(tvb, pinfo, tree, 0, si);
8127 }
8128 
8129 static void
dissect_smb2_SecD_buffer_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si _U_)8130 dissect_smb2_SecD_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
8131 {
8132 	report_create_context_malformed_buffer(tvb, pinfo, tree, "SecD Response");
8133 }
8134 
8135 /*
8136  * Add the timestamp to the info column and to the name of the file if
8137  * we have not visited this packet before.
8138  */
8139 static void
add_timestamp_to_info_col(tvbuff_t * tvb,packet_info * pinfo,smb2_info_t * si,int offset)8140 add_timestamp_to_info_col(tvbuff_t *tvb, packet_info *pinfo, smb2_info_t *si,
8141 			  int offset)
8142 {
8143 	guint32 filetime_high, filetime_low;
8144 	guint64 ft;
8145 	nstime_t ts;
8146 
8147 	filetime_low = tvb_get_letohl(tvb, offset);
8148 	filetime_high = tvb_get_letohl(tvb, offset + 4);
8149 
8150 	ft = ((guint64)filetime_high << 32) | filetime_low;
8151 	if (!filetime_to_nstime(&ts, ft)) {
8152 		return;
8153 	}
8154 
8155 	col_append_fstr(pinfo->cinfo, COL_INFO, "@%s",
8156             abs_time_to_str(pinfo->pool, &ts, ABSOLUTE_TIME_UTC,
8157 		            FALSE));
8158 
8159 	/* Append the timestamp */
8160 	if (!pinfo->fd->visited) {
8161 		if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
8162 			gchar *saved_name = (gchar *)si->saved->extra_info;
8163 			gulong len = (gulong)strlen(saved_name);
8164 
8165 			si->saved->extra_info = (gchar *)wmem_alloc(wmem_file_scope(), len + 32 + 1);
8166 			g_snprintf((gchar *)si->saved->extra_info,
8167 				   len + 32 + 1 , "%s@%s", (char *)saved_name,
8168 				   abs_time_to_str(pinfo->pool, &ts,
8169 					           ABSOLUTE_TIME_UTC, FALSE));
8170 			wmem_free(wmem_file_scope(), saved_name);
8171 		}
8172 	}
8173 }
8174 
8175 static void
dissect_smb2_TWrp_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8176 dissect_smb2_TWrp_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8177 {
8178 	proto_item *item = NULL;
8179 	if (tree) {
8180 		item = proto_tree_get_parent(tree);
8181 		proto_item_append_text(item, ": Timestamp");
8182 	}
8183 	add_timestamp_to_info_col(tvb, pinfo, si, 0);
8184 	dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_twrp_timestamp);
8185 }
8186 
8187 static void
dissect_smb2_TWrp_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8188 dissect_smb2_TWrp_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8189 {
8190 	report_create_context_malformed_buffer(tvb, pinfo, tree, "TWrp Response");
8191 }
8192 
8193 static void
dissect_smb2_QFid_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8194 dissect_smb2_QFid_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8195 {
8196 	proto_item *item = NULL;
8197 
8198 	if (tree) {
8199 		item = proto_tree_get_parent(tree);
8200 	}
8201 
8202 	if (item) {
8203 		if (tvb_reported_length(tvb) == 0) {
8204 			proto_item_append_text(item, ": NO DATA");
8205 		} else {
8206 			proto_item_append_text(item, ": QFid request should have no data, malformed packet");
8207 		}
8208 	}
8209 }
8210 
8211 static void
dissect_smb2_QFid_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8212 dissect_smb2_QFid_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8213 {
8214 	int         offset   = 0;
8215 	proto_item *item;
8216 	proto_item *sub_tree;
8217 
8218 	item = proto_tree_get_parent(tree);
8219 
8220 	proto_item_append_text(item, ": QFid INFO");
8221 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_QFid_buffer, NULL, "QFid INFO");
8222 
8223 	proto_tree_add_item(sub_tree, hf_smb2_qfid_fid, tvb, offset, 32, ENC_NA);
8224 }
8225 
8226 static void
dissect_smb2_AlSi_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8227 dissect_smb2_AlSi_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8228 {
8229 	proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, 0, 8, ENC_LITTLE_ENDIAN);
8230 }
8231 
8232 static void
dissect_smb2_AlSi_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8233 dissect_smb2_AlSi_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8234 {
8235 	report_create_context_malformed_buffer(tvb, pinfo, tree, "AlSi Response");
8236 }
8237 
8238 static void
dissect_smb2_DHnQ_buffer_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)8239 dissect_smb2_DHnQ_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
8240 {
8241 	dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNQ);
8242 }
8243 
8244 static void
dissect_smb2_DHnQ_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8245 dissect_smb2_DHnQ_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8246 {
8247 	proto_tree_add_item(tree, hf_smb2_dhnq_buffer_reserved, tvb, 0, 8, ENC_LITTLE_ENDIAN);
8248 }
8249 
8250 static void
dissect_smb2_DHnC_buffer_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)8251 dissect_smb2_DHnC_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
8252 {
8253 	dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNC);
8254 }
8255 
8256 static void
dissect_smb2_DHnC_buffer_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si _U_)8257 dissect_smb2_DHnC_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
8258 {
8259 	report_create_context_malformed_buffer(tvb, pinfo, tree, "DHnC Response");
8260 }
8261 
8262 /*
8263  * SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2
8264  *  4 - timeout
8265  *  4 - flags
8266  *  8 - reserved
8267  * 16 - create guid
8268  *
8269  * SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2
8270  *  4 - timeout
8271  *  4 - flags
8272  *
8273  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
8274  * 16 - file id
8275  * 16 - create guid
8276  *  4 - flags
8277  *
8278  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
8279  * - nothing -
8280  */
8281 #define SMB2_DH2X_FLAGS_PERSISTENT_HANDLE 0x00000002
8282 
8283 static void
dissect_smb2_DH2Q_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8284 dissect_smb2_DH2Q_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8285 {
8286 	static int * const dh2x_flags_fields[] = {
8287 		&hf_smb2_dh2x_buffer_flags_persistent_handle,
8288 		NULL
8289 	};
8290 	int         offset   = 0;
8291 	proto_item *item;
8292 	proto_item *sub_tree;
8293 
8294 	item = proto_tree_get_parent(tree);
8295 
8296 	proto_item_append_text(item, ": DH2Q Request");
8297 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2Q_buffer, NULL, "DH2Q Request");
8298 
8299 	/* timeout */
8300 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8301 	offset += 4;
8302 
8303 	/* flags */
8304 	proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_dh2x_buffer_flags,
8305 				ett_smb2_dh2x_flags, dh2x_flags_fields, ENC_LITTLE_ENDIAN);
8306 	offset += 4;
8307 
8308 	/* reserved */
8309 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_reserved, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8310 	offset += 8;
8311 
8312 	/* create guid */
8313 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8314 }
8315 
8316 static void
dissect_smb2_DH2Q_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8317 dissect_smb2_DH2Q_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8318 {
8319 	int         offset   = 0;
8320 	proto_item *item;
8321 	proto_item *sub_tree;
8322 
8323 	item = proto_tree_get_parent(tree);
8324 
8325 	proto_item_append_text(item, ": DH2Q Response");
8326 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2Q_buffer, NULL, "DH2Q Response");
8327 
8328 	/* timeout */
8329 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8330 	offset += 4;
8331 
8332 	/* flags */
8333 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8334 }
8335 
8336 static void
dissect_smb2_DH2C_buffer_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si)8337 dissect_smb2_DH2C_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
8338 {
8339 	int         offset   = 0;
8340 	proto_item *item;
8341 	proto_item *sub_tree;
8342 
8343 	item = proto_tree_get_parent(tree);
8344 
8345 	proto_item_append_text(item, ": DH2C Request");
8346 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2C_buffer, NULL, "DH2C Request");
8347 
8348 	/* file id */
8349 	dissect_smb2_fid(tvb, pinfo, sub_tree, offset, si, FID_MODE_DHNC);
8350 	offset += 16;
8351 
8352 	/* create guid */
8353 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8354 	offset += 16;
8355 
8356 	/* flags */
8357 	proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8358 }
8359 
8360 static void
dissect_smb2_DH2C_buffer_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,smb2_info_t * si _U_)8361 dissect_smb2_DH2C_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
8362 {
8363 	report_create_context_malformed_buffer(tvb, pinfo, tree, "DH2C Response");
8364 }
8365 
8366 static void
dissect_smb2_MxAc_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8367 dissect_smb2_MxAc_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8368 {
8369 	int	    offset = 0;
8370 	proto_item *item   = NULL;
8371 
8372 	if (tree) {
8373 		item = proto_tree_get_parent(tree);
8374 	}
8375 
8376 	if (tvb_reported_length(tvb) == 0) {
8377 		if (item) {
8378 			proto_item_append_text(item, ": NO DATA");
8379 		}
8380 		return;
8381 	}
8382 
8383 	if (item) {
8384 		proto_item_append_text(item, ": Timestamp");
8385 	}
8386 
8387 	dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_mxac_timestamp);
8388 }
8389 
8390 static void
dissect_smb2_MxAc_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8391 dissect_smb2_MxAc_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8392 {
8393 	int         offset   = 0;
8394 	proto_item *item;
8395 	proto_tree *sub_tree;
8396 
8397 	item = proto_tree_get_parent(tree);
8398 
8399 	if (tvb_reported_length(tvb) == 0) {
8400 		proto_item_append_text(item, ": NO DATA");
8401 		return;
8402 	}
8403 
8404 	proto_item_append_text(item, ": MxAc INFO");
8405 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_MxAc_buffer, NULL, "MxAc INFO");
8406 
8407 	proto_tree_add_item(sub_tree, hf_smb2_mxac_status, tvb, offset, 4, ENC_BIG_ENDIAN);
8408 	offset += 4;
8409 
8410 	dissect_smb_access_mask(tvb, sub_tree, offset);
8411 }
8412 
8413 /*
8414  * SMB2_CREATE_REQUEST_LEASE 32
8415  * 16 - lease key
8416  *  4 - lease state
8417  *  4 - lease flags
8418  *  8 - lease duration
8419  *
8420  * SMB2_CREATE_REQUEST_LEASE_V2 52
8421  * 16 - lease key
8422  *  4 - lease state
8423  *  4 - lease flags
8424  *  8 - lease duration
8425  * 16 - parent lease key
8426  *  2 - epoch
8427  *  2 - reserved
8428  */
8429 #define SMB2_LEASE_STATE_READ_CACHING   0x00000001
8430 #define SMB2_LEASE_STATE_HANDLE_CACHING 0x00000002
8431 #define SMB2_LEASE_STATE_WRITE_CACHING  0x00000004
8432 
8433 #define SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED    0x00000001
8434 #define SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS     0x00000002
8435 #define SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET  0x00000004
8436 
8437 static int * const lease_state_fields[] = {
8438 	&hf_smb2_lease_state_read_caching,
8439 	&hf_smb2_lease_state_handle_caching,
8440 	&hf_smb2_lease_state_write_caching,
8441 	NULL
8442 };
8443 static int * const lease_flags_fields[] = {
8444 	&hf_smb2_lease_flags_break_ack_required,
8445 	&hf_smb2_lease_flags_break_in_progress,
8446 	&hf_smb2_lease_flags_parent_lease_key_set,
8447 	NULL
8448 };
8449 
8450 static void
dissect_SMB2_CREATE_LEASE_VX(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,smb2_info_t * si _U_)8451 dissect_SMB2_CREATE_LEASE_VX(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
8452 {
8453 	int         offset      = 0;
8454 	int         len;
8455 	proto_tree *sub_tree    = NULL;
8456 	proto_item *parent_item;
8457 
8458 	parent_item = proto_tree_get_parent(parent_tree);
8459 
8460 	len = tvb_reported_length(tvb);
8461 
8462 	switch (len) {
8463 	case 32: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE */
8464 		proto_item_append_text(parent_item, ": LEASE_V1");
8465 		sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_RqLs_buffer, NULL, "LEASE_V1");
8466 		break;
8467 	case 52: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE_V2 */
8468 		proto_item_append_text(parent_item, ": LEASE_V2");
8469 		sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_RqLs_buffer, NULL, "LEASE_V2");
8470 		break;
8471 	default:
8472 		report_create_context_malformed_buffer(tvb, pinfo, parent_tree, "RqLs");
8473 		break;
8474 	}
8475 
8476 	proto_tree_add_item(sub_tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8477 	offset += 16;
8478 
8479 	proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_state,
8480 			       ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8481 	offset += 4;
8482 
8483 	proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_flags,
8484 			       ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8485 	offset += 4;
8486 
8487 	proto_tree_add_item(sub_tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8488 	offset += 8;
8489 
8490 	if (len < 52) {
8491 		return;
8492 	}
8493 
8494 	proto_tree_add_item(sub_tree, hf_smb2_parent_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8495 	offset += 16;
8496 
8497 	proto_tree_add_item(sub_tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
8498 	offset += 2;
8499 
8500 	proto_tree_add_item(sub_tree, hf_smb2_lease_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
8501 }
8502 
8503 static void
dissect_smb2_RqLs_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8504 dissect_smb2_RqLs_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8505 {
8506 	dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
8507 }
8508 
8509 static void
dissect_smb2_RqLs_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8510 dissect_smb2_RqLs_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8511 {
8512 	dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
8513 }
8514 
8515 /*
8516  * SMB2_CREATE_APP_INSTANCE_ID
8517  *  2 - structure size - 20
8518  *  2 - reserved
8519  * 16 - application guid
8520  */
8521 
8522 static void
dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8523 dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8524 {
8525 	int         offset   = 0;
8526 	proto_item *item;
8527 	proto_item *sub_tree;
8528 
8529 	item = proto_tree_get_parent(tree);
8530 
8531 	proto_item_append_text(item, ": CREATE APP INSTANCE ID");
8532 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_APP_INSTANCE_buffer, NULL, "APP INSTANCE ID");
8533 
8534 	/* struct size */
8535 	proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_struct_size,
8536 			    tvb, offset, 2, ENC_LITTLE_ENDIAN);
8537 	offset += 2;
8538 
8539 	/* reserved */
8540 	proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_reserved,
8541 			    tvb, offset, 2, ENC_LITTLE_ENDIAN);
8542 	offset += 2;
8543 
8544 	/* create guid */
8545 	proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_app_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8546 }
8547 
8548 static void
dissect_smb2_APP_INSTANCE_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8549 dissect_smb2_APP_INSTANCE_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8550 {
8551 	report_create_context_malformed_buffer(tvb, pinfo, tree, "APP INSTANCE Response");
8552 }
8553 
8554 /*
8555  * Dissect the MS-RSVD stuff that turns up when HyperV uses SMB3.x
8556  */
8557 static void
dissect_smb2_svhdx_open_device_context(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8558 dissect_smb2_svhdx_open_device_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8559 {
8560 	int offset = 0;
8561 	guint32 version;
8562 	proto_item *item;
8563 	proto_item *sub_tree;
8564 
8565 	item = proto_tree_get_parent(tree);
8566 
8567 	proto_item_append_text(item, ": SVHDX OPEN DEVICE CONTEXT");
8568 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_svhdx_open_device_context, NULL, "SVHDX OPEN DEVICE CONTEXT");
8569 
8570 	/* Version */
8571 	proto_tree_add_item_ret_uint(sub_tree, hf_smb2_svhdx_open_device_context_version,
8572 			    tvb, offset, 4, ENC_LITTLE_ENDIAN, &version);
8573 	offset += 4;
8574 
8575 	/* HasInitiatorId */
8576 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_has_initiator_id,
8577 			    tvb, offset, 1, ENC_LITTLE_ENDIAN);
8578 	offset += 1;
8579 
8580 	/* Reserved */
8581 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_reserved,
8582 			    tvb, offset, 3, ENC_NA);
8583 	offset += 3;
8584 
8585 	/* InitiatorId */
8586 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_id,
8587 			    tvb, offset, 16, ENC_LITTLE_ENDIAN);
8588 	offset += 16;
8589 
8590 	/* Flags TODO: Dissect these*/
8591 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_flags,
8592 			    tvb, offset, 4, ENC_LITTLE_ENDIAN);
8593 	offset += 4;
8594 
8595 	/* OriginatorFlags */
8596 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_originator_flags,
8597 			    tvb, offset, 4, ENC_LITTLE_ENDIAN);
8598 	offset += 4;
8599 
8600 	/* OpenRequestId */
8601 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_open_request_id,
8602 			    tvb, offset, 8, ENC_LITTLE_ENDIAN);
8603 	offset += 8;
8604 
8605 	/* InitiatorHostNameLength */
8606 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name_len,
8607 			    tvb, offset, 2, ENC_LITTLE_ENDIAN);
8608 	offset += 2;
8609 
8610 	/* InitiatorHostName */
8611 	proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name,
8612 			    tvb, offset, 126, ENC_ASCII | ENC_NA);
8613 	offset += 126;
8614 
8615 	if (version == 2) {
8616 		/* VirtualDiskPropertiesInitialized */
8617 		proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
8618 					tvb, offset, 4, ENC_LITTLE_ENDIAN);
8619 		offset += 4;
8620 
8621 		/* ServerServiceVersion */
8622 		proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_server_service_version,
8623 					tvb, offset, 4, ENC_LITTLE_ENDIAN);
8624 		offset += 4;
8625 
8626 		/* VirtualSectorSize */
8627 		proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_sector_size,
8628 					tvb, offset, 4, ENC_LITTLE_ENDIAN);
8629 		offset += 4;
8630 
8631 		/* PhysicalSectorSize */
8632 		proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_physical_sector_size,
8633 					tvb, offset, 4, ENC_LITTLE_ENDIAN);
8634 		offset += 4;
8635 
8636 		/* VirtualSize */
8637 		proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_size,
8638 					tvb, offset, 8, ENC_LITTLE_ENDIAN);
8639 	}
8640 }
8641 
8642 /*
8643  * SMB2_CREATE_APP_INSTANCE_VERSION
8644  *  2 - structure size - 24
8645  *  2 - reserved
8646  *  4 - padding
8647  *  8 - AppInstanceVersionHigh
8648  *  8 - AppInstanceVersionHigh
8649  */
8650 
8651 static void
dissect_smb2_app_instance_version_buffer_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8652 dissect_smb2_app_instance_version_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8653 {
8654 	int         offset   = 0;
8655 	proto_item *item;
8656 	proto_item *sub_tree;
8657 	proto_item *version_sub_tree;
8658 	guint64 	version_high;
8659 	guint64 	version_low;
8660 
8661 	item = proto_tree_get_parent(tree);
8662 
8663 	proto_item_append_text(item, ": CREATE APP INSTANCE VERSION");
8664 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_app_instance_version_buffer, NULL, "APP INSTANCE VERSION");
8665 
8666 	/* struct size */
8667 	proto_tree_add_item(sub_tree, hf_smb2_app_instance_version_struct_size,
8668 			    tvb, offset, 2, ENC_LITTLE_ENDIAN);
8669 	offset += 2;
8670 
8671 	/* reserved */
8672 	proto_tree_add_item(sub_tree, hf_smb2_app_instance_version_reserved,
8673 			    tvb, offset, 2, ENC_LITTLE_ENDIAN);
8674 	offset += 2;
8675 
8676 	/* padding */
8677 	proto_tree_add_item(sub_tree, hf_smb2_app_instance_version_padding,
8678 			    tvb, offset, 4, ENC_LITTLE_ENDIAN);
8679 	offset += 4;
8680 
8681 	version_sub_tree = proto_tree_add_subtree(sub_tree, tvb, offset, -1, ett_smb2_app_instance_version_buffer_version, NULL, "version");
8682 
8683 	/* version high */
8684 	proto_tree_add_item_ret_uint64(version_sub_tree, hf_smb2_app_instance_version_high,
8685 			    tvb, offset, 8, ENC_LITTLE_ENDIAN, &version_high);
8686 	offset += 8;
8687 
8688 	/* version low */
8689 	proto_tree_add_item_ret_uint64(version_sub_tree, hf_smb2_app_instance_version_low,
8690 			    tvb, offset, 8, ENC_LITTLE_ENDIAN, &version_low);
8691 
8692 	proto_item_append_text(version_sub_tree, " : %" G_GUINT64_FORMAT ".%" G_GUINT64_FORMAT "", version_high, version_low);
8693 	proto_item_append_text(sub_tree, ", version: %" G_GUINT64_FORMAT ".%" G_GUINT64_FORMAT "", version_high, version_low);
8694 }
8695 
8696 static void
dissect_smb2_app_instance_version_buffer_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,smb2_info_t * si _U_)8697 dissect_smb2_app_instance_version_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
8698 {
8699 	report_create_context_malformed_buffer(tvb, pinfo, tree, "APP INSTANCE Version Response");
8700 }
8701 
8702 static void
dissect_smb2_posix_buffer_request(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,smb2_info_t * si _U_)8703 dissect_smb2_posix_buffer_request(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
8704 {
8705 	int offset = 0;
8706 	proto_item *item;
8707 
8708 	item = proto_tree_get_parent(tree);
8709 	proto_item_append_text(item, ": POSIX Create Context request");
8710 
8711 	/* POSIX mode bits */
8712 	proto_tree_add_item(tree, hf_smb2_posix_perms, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8713 }
8714 
8715 static void
dissect_smb2_posix_buffer_response(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,smb2_info_t * si _U_)8716 dissect_smb2_posix_buffer_response(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
8717 {
8718 	int offset = 0;
8719 	proto_item *item;
8720 
8721 	item = proto_tree_get_parent(tree);
8722 	proto_item_append_text(item, ": POSIX Create Context response");
8723 
8724 	/* Hardlinks */
8725 	proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8726 	offset += 4;
8727 
8728 	/* Reparse tag */
8729 	proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8730 	offset += 4;
8731 
8732 	/* POSIX mode bits */
8733 	proto_tree_add_item(tree, hf_smb2_posix_perms, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8734 	offset += 4;
8735 
8736 	/* Owner and Group SID */
8737 	offset = dissect_nt_sid(tvb, offset, tree, "Owner SID", NULL, -1);
8738 	dissect_nt_sid(tvb, offset, tree, "Group SID", NULL, -1);
8739 }
8740 
8741 #define SMB2_AAPL_SERVER_QUERY	1
8742 #define SMB2_AAPL_RESOLVE_ID	2
8743 
8744 static const value_string aapl_command_code_vals[] = {
8745 	{ SMB2_AAPL_SERVER_QUERY,	"Server query"},
8746 	{ SMB2_AAPL_RESOLVE_ID,		"Resolve ID"},
8747 	{ 0, NULL }
8748 };
8749 
8750 #define SMB2_AAPL_SERVER_CAPS		0x00000001
8751 #define SMB2_AAPL_VOLUME_CAPS		0x00000002
8752 #define SMB2_AAPL_MODEL_INFO		0x00000004
8753 
8754 static int * const aapl_server_query_bitmap_fields[] = {
8755 	&hf_smb2_aapl_server_query_bitmask_server_caps,
8756 	&hf_smb2_aapl_server_query_bitmask_volume_caps,
8757 	&hf_smb2_aapl_server_query_bitmask_model_info,
8758 	NULL
8759 };
8760 
8761 #define SMB2_AAPL_SUPPORTS_READ_DIR_ATTR	0x00000001
8762 #define SMB2_AAPL_SUPPORTS_OSX_COPYFILE		0x00000002
8763 #define SMB2_AAPL_UNIX_BASED			0x00000004
8764 #define SMB2_AAPL_SUPPORTS_NFS_ACE		0x00000008
8765 
8766 static int * const aapl_server_query_caps_fields[] = {
8767 	&hf_smb2_aapl_server_query_caps_supports_read_dir_attr,
8768 	&hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
8769 	&hf_smb2_aapl_server_query_caps_unix_based,
8770 	&hf_smb2_aapl_server_query_caps_supports_nfs_ace,
8771 	NULL
8772 };
8773 
8774 static void
dissect_smb2_AAPL_buffer_request(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,smb2_info_t * si _U_)8775 dissect_smb2_AAPL_buffer_request(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
8776 {
8777 	int         offset   = 0;
8778 	proto_item *item;
8779 	proto_item *sub_tree;
8780 	guint32     command_code;
8781 
8782 	item = proto_tree_get_parent(tree);
8783 
8784 	proto_item_append_text(item, ": AAPL Create Context request");
8785 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_aapl_create_context_request, NULL, "AAPL Create Context request");
8786 
8787 	/* Command code */
8788 	proto_tree_add_item_ret_uint(sub_tree, hf_smb2_aapl_command_code,
8789 	    tvb, offset, 4, ENC_LITTLE_ENDIAN, &command_code);
8790 	offset += 4;
8791 
8792 	/* Reserved */
8793 	proto_tree_add_item(sub_tree, hf_smb2_aapl_reserved,
8794 	    tvb, offset, 4, ENC_LITTLE_ENDIAN);
8795 	offset += 4;
8796 
8797 	switch (command_code) {
8798 
8799 	case SMB2_AAPL_SERVER_QUERY:
8800 		/* Request bitmap */
8801 		proto_tree_add_bitmask(sub_tree, tvb, offset,
8802 				       hf_smb2_aapl_server_query_bitmask,
8803 				       ett_smb2_aapl_server_query_bitmask,
8804 				       aapl_server_query_bitmap_fields,
8805 				       ENC_LITTLE_ENDIAN);
8806 		offset += 8;
8807 
8808 		/* Client capabilities */
8809 		proto_tree_add_bitmask(sub_tree, tvb, offset,
8810 				       hf_smb2_aapl_server_query_caps,
8811 				       ett_smb2_aapl_server_query_caps,
8812 				       aapl_server_query_caps_fields,
8813 				       ENC_LITTLE_ENDIAN);
8814 		break;
8815 
8816 	case SMB2_AAPL_RESOLVE_ID:
8817 		/* file ID */
8818 		proto_tree_add_item(sub_tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8819 		break;
8820 
8821 	default:
8822 		break;
8823 	}
8824 }
8825 
8826 #define SMB2_AAPL_SUPPORTS_RESOLVE_ID	0x00000001
8827 #define SMB2_AAPL_CASE_SENSITIVE		0x00000002
8828 #define SMB2_AAPL_SUPPORTS_FULL_SYNC	0x00000004
8829 
8830 static int * const aapl_server_query_volume_caps_fields[] = {
8831 	&hf_smb2_aapl_server_query_volume_caps_support_resolve_id,
8832 	&hf_smb2_aapl_server_query_volume_caps_case_sensitive,
8833 	&hf_smb2_aapl_server_query_volume_caps_supports_full_sync,
8834 	NULL
8835 };
8836 
8837 static void
dissect_smb2_AAPL_buffer_response(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,smb2_info_t * si _U_)8838 dissect_smb2_AAPL_buffer_response(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
8839 {
8840 	int         offset   = 0;
8841 	proto_item *item;
8842 	proto_item *sub_tree;
8843 	guint32     command_code;
8844 	guint64     server_query_bitmask;
8845 
8846 	item = proto_tree_get_parent(tree);
8847 
8848 	proto_item_append_text(item, ": AAPL Create Context response");
8849 	sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_aapl_create_context_response, NULL, "AAPL Create Context response");
8850 
8851 	/* Command code */
8852 	proto_tree_add_item_ret_uint(sub_tree, hf_smb2_aapl_command_code,
8853 	    tvb, offset, 4, ENC_LITTLE_ENDIAN, &command_code);
8854 	offset += 4;
8855 
8856 	/* Reserved */
8857 	proto_tree_add_item(sub_tree, hf_smb2_aapl_reserved,
8858 	    tvb, offset, 4, ENC_LITTLE_ENDIAN);
8859 	offset += 4;
8860 
8861 	switch (command_code) {
8862 
8863 	case SMB2_AAPL_SERVER_QUERY:
8864 		/* Reply bitmap */
8865 		proto_tree_add_bitmask_ret_uint64(sub_tree, tvb, offset,
8866 						  hf_smb2_aapl_server_query_bitmask,
8867 						  ett_smb2_aapl_server_query_bitmask,
8868 						  aapl_server_query_bitmap_fields,
8869 						  ENC_LITTLE_ENDIAN,
8870 						  &server_query_bitmask);
8871 		offset += 8;
8872 
8873 		if (server_query_bitmask & SMB2_AAPL_SERVER_CAPS) {
8874 			/* Server capabilities */
8875 			proto_tree_add_bitmask(sub_tree, tvb, offset,
8876 					       hf_smb2_aapl_server_query_caps,
8877 					       ett_smb2_aapl_server_query_caps,
8878 					       aapl_server_query_caps_fields,
8879 					       ENC_LITTLE_ENDIAN);
8880 			offset += 8;
8881 		}
8882 		if (server_query_bitmask & SMB2_AAPL_VOLUME_CAPS) {
8883 			/* Volume capabilities */
8884 			proto_tree_add_bitmask(sub_tree, tvb, offset,
8885 					       hf_smb2_aapl_server_query_volume_caps,
8886 					       ett_smb2_aapl_server_query_volume_caps,
8887 					       aapl_server_query_volume_caps_fields,
8888 					       ENC_LITTLE_ENDIAN);
8889 			offset += 8;
8890 		}
8891 		if (server_query_bitmask & SMB2_AAPL_MODEL_INFO) {
8892 			/* Padding */
8893 			offset += 4;
8894 
8895 			/* Model string */
8896 			proto_tree_add_item(sub_tree, hf_smb2_aapl_server_query_model_string,
8897 					    tvb, offset, 4,
8898 					    ENC_UTF_16|ENC_LITTLE_ENDIAN);
8899 		}
8900 		break;
8901 
8902 	case SMB2_AAPL_RESOLVE_ID:
8903 		/* NT status */
8904 		proto_tree_add_item(sub_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8905 		offset += 4;
8906 
8907 		/* Server path */
8908 		proto_tree_add_item(sub_tree, hf_smb2_aapl_server_query_server_path,
8909 				    tvb, offset, 4,
8910 				    ENC_UTF_16|ENC_LITTLE_ENDIAN);
8911 		break;
8912 
8913 	default:
8914 		break;
8915 	}
8916 }
8917 
8918 typedef void (*create_context_data_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
8919 
8920 typedef struct create_context_data_dissectors {
8921 	create_context_data_dissector_t request;
8922 	create_context_data_dissector_t response;
8923 } create_context_data_dissectors_t;
8924 
8925 struct create_context_data_tag_dissectors {
8926 	const char *tag;
8927 	const char *val;
8928 	create_context_data_dissectors_t dissectors;
8929 };
8930 
8931 static struct create_context_data_tag_dissectors create_context_dissectors_array[] = {
8932 	{ "ExtA", "SMB2_CREATE_EA_BUFFER",
8933 	  { dissect_smb2_ExtA_buffer_request, dissect_smb2_ExtA_buffer_response } },
8934 	{ "SecD", "SMB2_CREATE_SD_BUFFER",
8935 	  { dissect_smb2_SecD_buffer_request, dissect_smb2_SecD_buffer_response } },
8936 	{ "AlSi", "SMB2_CREATE_ALLOCATION_SIZE",
8937 	  { dissect_smb2_AlSi_buffer_request, dissect_smb2_AlSi_buffer_response } },
8938 	{ "MxAc", "SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST",
8939 	  { dissect_smb2_MxAc_buffer_request, dissect_smb2_MxAc_buffer_response } },
8940 	{ "DHnQ", "SMB2_CREATE_DURABLE_HANDLE_REQUEST",
8941 	  { dissect_smb2_DHnQ_buffer_request, dissect_smb2_DHnQ_buffer_response } },
8942 	{ "DHnC", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT",
8943 	  { dissect_smb2_DHnC_buffer_request, dissect_smb2_DHnC_buffer_response } },
8944 	{ "DH2Q", "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2",
8945 	  { dissect_smb2_DH2Q_buffer_request, dissect_smb2_DH2Q_buffer_response } },
8946 	{ "DH2C", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2",
8947 	  { dissect_smb2_DH2C_buffer_request, dissect_smb2_DH2C_buffer_response } },
8948 	{ "TWrp", "SMB2_CREATE_TIMEWARP_TOKEN",
8949 	  { dissect_smb2_TWrp_buffer_request, dissect_smb2_TWrp_buffer_response } },
8950 	{ "QFid", "SMB2_CREATE_QUERY_ON_DISK_ID",
8951 	  { dissect_smb2_QFid_buffer_request, dissect_smb2_QFid_buffer_response } },
8952 	{ "RqLs", "SMB2_CREATE_REQUEST_LEASE",
8953 	  { dissect_smb2_RqLs_buffer_request, dissect_smb2_RqLs_buffer_response } },
8954 	{ "744D142E-46FA-0890-4AF7-A7EF6AA6BC45", "SMB2_CREATE_APP_INSTANCE_ID",
8955 	  { dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
8956 	{ "6aa6bc45-a7ef-4af7-9008-fa462e144d74", "SMB2_CREATE_APP_INSTANCE_ID",
8957 	  { dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
8958 	{ "9ecfcb9c-c104-43e6-980e-158da1f6ec83", "SVHDX_OPEN_DEVICE_CONTEXT",
8959 	  { dissect_smb2_svhdx_open_device_context, dissect_smb2_svhdx_open_device_context} },
8960 	{ "b7d082b9-563b-4f07-a07b-524a8116a010", "SMB2_CREATE_APP_INSTANCE_VERSION",
8961 	   { dissect_smb2_app_instance_version_buffer_request, dissect_smb2_app_instance_version_buffer_response } },
8962 	{ "5025ad93-b49c-e711-b423-83de968bcd7c", "SMB2_POSIX_CREATE_CONTEXT",
8963 	  { dissect_smb2_posix_buffer_request, dissect_smb2_posix_buffer_response } },
8964 	{ "AAPL", "SMB2_AAPL_CREATE_CONTEXT",
8965 	  { dissect_smb2_AAPL_buffer_request, dissect_smb2_AAPL_buffer_response } },
8966 };
8967 
8968 static struct create_context_data_tag_dissectors*
get_create_context_data_tag_dissectors(const char * tag)8969 get_create_context_data_tag_dissectors(const char *tag)
8970 {
8971 	static struct create_context_data_tag_dissectors INVALID = {
8972 		NULL, "<invalid>", { NULL, NULL }
8973 	};
8974 
8975 	size_t i;
8976 
8977 	for (i = 0; i<array_length(create_context_dissectors_array); i++) {
8978 		if (!strcmp(tag, create_context_dissectors_array[i].tag))
8979 			return &create_context_dissectors_array[i];
8980 	}
8981 	return &INVALID;
8982 }
8983 
8984 static void
dissect_smb2_create_extra_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb2_info_t * si)8985 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
8986 {
8987 	offset_length_buffer_t  tag_olb;
8988 	offset_length_buffer_t  data_olb;
8989 	const guint8 *tag;
8990 	guint16     chain_offset;
8991 	int         offset      = 0;
8992 	int         len         = -1;
8993 	proto_item *sub_item;
8994 	proto_tree *sub_tree;
8995 	proto_item *parent_item = NULL;
8996 	create_context_data_dissectors_t *dissectors = NULL;
8997 	create_context_data_dissector_t   dissector  = NULL;
8998 	struct create_context_data_tag_dissectors *tag_dissectors;
8999 
9000 	chain_offset = tvb_get_letohl(tvb, offset);
9001 	if (chain_offset) {
9002 		len = chain_offset;
9003 	}
9004 
9005 	sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_smb2_create_chain_element, &sub_item, "Chain Element");
9006 	parent_item = proto_tree_get_parent(parent_tree);
9007 
9008 	/* chain offset */
9009 	proto_tree_add_item(sub_tree, hf_smb2_create_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9010 	offset += 4;
9011 
9012 	/* tag  offset/length */
9013 	offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
9014 
9015 	/* data  offset/length */
9016 	dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_create_chain_data);
9017 
9018 	/*
9019 	 * These things are all either 4-char strings, like DH2C, or GUIDs,
9020 	 * however, at least one of them appears to be a GUID as a string and
9021 	 * one appears to be a binary guid. So, check if the the length is
9022 	 * 16, and if so, pull the GUID and convert it to a string. Otherwise
9023 	 * call dissect_smb2_olb_string.
9024 	 */
9025 	if (tag_olb.len == 16) {
9026 		e_guid_t tag_guid;
9027 		proto_item *tag_item;
9028 		proto_tree *tag_tree;
9029 
9030 		tvb_get_letohguid(tvb, tag_olb.off, &tag_guid);
9031 		tag = guid_to_str(pinfo->pool, &tag_guid);
9032 
9033 		tag_item = proto_tree_add_string(sub_tree, tag_olb.hfindex, tvb, tag_olb.off, tag_olb.len, tag);
9034 		tag_tree = proto_item_add_subtree(tag_item, ett_smb2_olb);
9035 		proto_tree_add_item(tag_tree, hf_smb2_olb_offset, tvb, tag_olb.off_offset, 2, ENC_LITTLE_ENDIAN);
9036 		proto_tree_add_item(tag_tree, hf_smb2_olb_length, tvb, tag_olb.len_offset, 2, ENC_LITTLE_ENDIAN);
9037 
9038 	} else {
9039 		/* tag string */
9040 		tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
9041 	}
9042 
9043 	tag_dissectors = get_create_context_data_tag_dissectors(tag);
9044 
9045 	proto_item_append_text(parent_item, " %s", tag_dissectors->val);
9046 	proto_item_append_text(sub_item, ": %s \"%s\"", tag_dissectors->val, tag);
9047 
9048 	/* data */
9049 	dissectors = &tag_dissectors->dissectors;
9050 	if (dissectors)
9051 		dissector = (si->flags & SMB2_FLAGS_RESPONSE) ? dissectors->response : dissectors->request;
9052 
9053 	dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
9054 
9055 	if (chain_offset) {
9056 		tvbuff_t *chain_tvb;
9057 		chain_tvb = tvb_new_subset_remaining(tvb, chain_offset);
9058 
9059 		/* next extra info */
9060 		dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
9061 	}
9062 }
9063 
9064 static int
dissect_smb2_create_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)9065 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
9066 {
9067 	offset_length_buffer_t  f_olb, e_olb;
9068 	const guint8           *fname;
9069 
9070 	/* buffer code */
9071 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
9072 
9073 	/* security flags */
9074 	offset++;
9075 
9076 	/* oplock */
9077 	offset = dissect_smb2_oplock(tree, tvb, offset);
9078 
9079 	/* impersonation level */
9080 	proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9081 	offset += 4;
9082 
9083 	/* create flags */
9084 	proto_tree_add_item(tree, hf_smb2_create_flags, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9085 	offset += 8;
9086 
9087 	/* reserved */
9088 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 8, ENC_NA);
9089 	offset += 8;
9090 
9091 	/* access mask */
9092 	offset = dissect_smb_access_mask(tvb, tree, offset);
9093 
9094 	/* File Attributes */
9095 	offset = dissect_fscc_file_attr(tvb, tree, offset, NULL);
9096 
9097 	/* share access */
9098 	offset = dissect_nt_share_access(tvb, tree, offset);
9099 
9100 	/* create disposition */
9101 	proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9102 	offset += 4;
9103 
9104 	/* create options */
9105 	offset = dissect_nt_create_options(tvb, tree, offset);
9106 
9107 	/* filename  offset/length */
9108 	offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
9109 
9110 	/* extrainfo offset */
9111 	offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
9112 
9113 	/* filename string */
9114 	fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
9115 	col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s",
9116 	    format_text(pinfo->pool, fname, strlen(fname)));
9117 
9118 	/* save the name if it looks sane */
9119 	if (!pinfo->fd->visited) {
9120 		if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
9121 			wmem_free(wmem_file_scope(), si->saved->extra_info);
9122 			si->saved->extra_info = NULL;
9123 			si->saved->extra_info_type = SMB2_EI_NONE;
9124 		}
9125 		if (si->saved && f_olb.len < 1024) {
9126 			si->saved->extra_info_type = SMB2_EI_FILENAME;
9127 			si->saved->extra_info = (gchar *)wmem_alloc(wmem_file_scope(), f_olb.len+1);
9128 			g_snprintf((gchar *)si->saved->extra_info, f_olb.len+1, "%s", fname);
9129 		}
9130 	}
9131 
9132 	/* If extrainfo_offset is non-null then this points to another
9133 	 * buffer. The offset is relative to the start of the smb packet
9134 	 */
9135 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
9136 
9137 	offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
9138 	offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
9139 
9140 	return offset;
9141 }
9142 
9143 #define SMB2_CREATE_REP_FLAGS_REPARSE_POINT 0x01
9144 
9145 static int
dissect_smb2_create_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)9146 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
9147 {
9148 	guint64 end_of_file;
9149 	guint32	attr_mask;
9150 	offset_length_buffer_t e_olb;
9151 	static int * const create_rep_flags_fields[] = {
9152 		&hf_smb2_create_rep_flags_reparse_point,
9153 		NULL
9154 	};
9155 	gboolean continue_dissection;
9156 
9157 	switch (si->status) {
9158 	/* buffer code */
9159 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
9160 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
9161 		if (!continue_dissection) return offset;
9162 	}
9163 
9164 	/* oplock */
9165 	offset = dissect_smb2_oplock(tree, tvb, offset);
9166 
9167 	/* reserved */
9168 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_create_rep_flags,
9169 			       ett_smb2_create_rep_flags, create_rep_flags_fields, ENC_LITTLE_ENDIAN);
9170 	offset += 1;
9171 
9172 	/* create action */
9173 	proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9174 	offset += 4;
9175 
9176 	/* create time */
9177 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
9178 
9179 	/* last access */
9180 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
9181 
9182 	/* last write */
9183 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
9184 
9185 	/* last change */
9186 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
9187 
9188 	/* allocation size */
9189 	proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9190 	offset += 8;
9191 
9192 	/* end of file */
9193 	end_of_file = tvb_get_letoh64(tvb, offset);
9194 	if (si->eo_file_info) {
9195 		si->eo_file_info->end_of_file = tvb_get_letoh64(tvb, offset);
9196 	}
9197 	proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9198 	offset += 8;
9199 
9200 	/* File Attributes */
9201 	offset = dissect_fscc_file_attr(tvb, tree, offset, &attr_mask);
9202 
9203 	/* reserved */
9204 	proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
9205 	offset += 4;
9206 
9207 	/* fid */
9208 	offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
9209 
9210 	/* We save this after dissect_smb2_fid just because it would be
9211 	possible to have this response without having the mathing request.
9212 	In that case the entry in the file info hash table has been created
9213 	in dissect_smb2_fid */
9214 	if (si->eo_file_info) {
9215 		si->eo_file_info->end_of_file = end_of_file;
9216 		si->eo_file_info->attr_mask = attr_mask;
9217 	}
9218 
9219 	/* extrainfo offset */
9220 	offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
9221 
9222 	/* If extrainfo_offset is non-null then this points to another
9223 	 * buffer. The offset is relative to the start of the smb packet
9224 	 */
9225 	dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
9226 
9227 	offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
9228 
9229 	/* free si->saved->extra_info   we don't need it any more */
9230 	if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
9231 		wmem_free(wmem_file_scope(), si->saved->extra_info);
9232 		si->saved->extra_info = NULL;
9233 		si->saved->extra_info_type = SMB2_EI_NONE;
9234 	}
9235 
9236 	return offset;
9237 }
9238 
9239 
9240 static int
dissect_smb2_setinfo_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)9241 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
9242 {
9243 	guint32 setinfo_size;
9244 	guint16 setinfo_offset;
9245 
9246 	/* buffer code */
9247 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
9248 
9249 	/* class and info level */
9250 	offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
9251 
9252 	/* size */
9253 	setinfo_size = tvb_get_letohl(tvb, offset);
9254 	proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9255 	offset += 4;
9256 
9257 	/* offset */
9258 	setinfo_offset = tvb_get_letohs(tvb, offset);
9259 	proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9260 	offset += 2;
9261 
9262 	/* reserved */
9263 	proto_tree_add_item(tree, hf_smb2_setinfo_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9264 	offset += 2;
9265 
9266 	if (si->saved && si->saved->smb2_class == SMB2_CLASS_SEC_INFO) {
9267 		/* AdditionalInformation (4 bytes): Provides additional information to the server.
9268 			If security information is being set, this value MUST contain a 4-byte bit field
9269 			of flags indicating what security attributes MUST be applied.  */
9270 		offset = dissect_additional_information_sec_mask(tvb, tree, offset);
9271 	} else {
9272 		/* For all other set requests, this field MUST be 0. */
9273 		proto_tree_add_item(tree, hf_smb2_getsetinfo_additional, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9274 		offset += 4;
9275 	}
9276 
9277 	/* fid */
9278 	dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
9279 
9280 	/* data */
9281 	if (si->saved)
9282 		dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->smb2_class, si->saved->infolevel);
9283 	offset = setinfo_offset + setinfo_size;
9284 
9285 	return offset;
9286 }
9287 
9288 static int
dissect_smb2_setinfo_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)9289 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
9290 {
9291 	gboolean continue_dissection;
9292 	/* class/infolevel */
9293 	dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
9294 
9295 	switch (si->status) {
9296 	/* buffer code */
9297 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
9298 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
9299 		if (!continue_dissection) return offset;
9300 	}
9301 
9302 	return offset;
9303 }
9304 
9305 static int
dissect_smb2_break_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)9306 dissect_smb2_break_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
9307 {
9308 	guint16 buffer_code;
9309 
9310 	/* buffer code */
9311 	buffer_code = tvb_get_letohs(tvb, offset);
9312 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
9313 
9314 	if (buffer_code == OPLOCK_BREAK_OPLOCK_STRUCTURE_SIZE) {
9315 		/* OPLOCK Break */
9316 
9317 		/* oplock */
9318 		offset = dissect_smb2_oplock(tree, tvb, offset);
9319 
9320 		/* reserved */
9321 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
9322 		offset += 1;
9323 
9324 		/* reserved */
9325 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
9326 		offset += 4;
9327 
9328 		/* fid */
9329 		offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
9330 
9331 		return offset;
9332 	}
9333 
9334 	if (buffer_code == OPLOCK_BREAK_LEASE_ACKNOWLEDGMENT_STRUCTURE_SIZE) {
9335 		/* Lease Break Acknowledgment */
9336 
9337 		/* reserved */
9338 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
9339 		offset +=2;
9340 
9341 		/* lease flags */
9342 		proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
9343 				       ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
9344 		offset += 4;
9345 
9346 		/* lease key */
9347 		proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
9348 		offset += 16;
9349 
9350 		/* lease state */
9351 		proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
9352 				       ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
9353 		offset += 4;
9354 
9355 		proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9356 		offset += 8;
9357 
9358 		return offset;
9359 	}
9360 
9361 	return offset;
9362 }
9363 
9364 static int
dissect_smb2_break_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,smb2_info_t * si)9365 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
9366 {
9367 	guint16 buffer_code;
9368 	gboolean continue_dissection;
9369 
9370 	/* buffer code */
9371 	buffer_code = tvb_get_letohs(tvb, offset);
9372 	switch (si->status) {
9373 	case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
9374 	default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
9375 		if (!continue_dissection) return offset;
9376 	}
9377 
9378 	if (buffer_code == OPLOCK_BREAK_OPLOCK_STRUCTURE_SIZE) {
9379 		/* OPLOCK Break Notification */
9380 
9381 		/* oplock */
9382 		offset = dissect_smb2_oplock(tree, tvb, offset);
9383 
9384 		/* reserved */
9385 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
9386 		offset += 1;
9387 
9388 		/* reserved */
9389 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
9390 		offset += 4;
9391 
9392 		/* fid */
9393 		offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
9394 
9395 		/* in break requests from server to client here're 24 byte zero bytes
9396 		 * which are likely a bug in windows (they may use 2* 24 bytes instead of just
9397 		 * 1 *24 bytes
9398 		 */
9399 		return offset;
9400 	}
9401 
9402 	if (buffer_code == OPLOCK_BREAK_LEASE_NOTIFICATION_STRUCTURE_SIZE) {
9403 		proto_item *item;
9404 
9405 		/* Lease Break Notification */
9406 
9407 		/* new lease epoch */
9408 		proto_tree_add_item(tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9409 		offset += 2;
9410 
9411 		/* lease flags */
9412 		proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
9413 				       ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
9414 		offset += 4;
9415 
9416 		/* lease key */
9417 		proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
9418 		offset += 16;
9419 
9420 		/* current lease state */
9421 		item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
9422 					      ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
9423 		if (item) {
9424 			proto_item_prepend_text(item, "Current ");
9425 		}
9426 		offset += 4;
9427 
9428 		/* new lease state */
9429 		item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
9430 					      ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
9431 		if (item) {
9432 			proto_item_prepend_text(item, "New ");
9433 		}
9434 		offset += 4;
9435 
9436 		/* break reason - reserved */
9437 		proto_tree_add_item(tree, hf_smb2_lease_break_reason, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9438 		offset += 4;
9439 
9440 		/* access mask hint - reserved */
9441 		proto_tree_add_item(tree, hf_smb2_lease_access_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9442 		offset += 4;
9443 
9444 		/* share mask hint - reserved */
9445 		proto_tree_add_item(tree, hf_smb2_lease_share_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9446 		offset += 4;
9447 
9448 		return offset;
9449 	}
9450 
9451 	if (buffer_code == OPLOCK_BREAK_LEASE_RESPONSE_STRUCTURE_SIZE) {
9452 		/* Lease Break Response */
9453 
9454 		/* reserved */
9455 		proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
9456 		offset +=2;
9457 
9458 		/* lease flags */
9459 		proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
9460 				       ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
9461 		offset += 4;
9462 
9463 		/* lease key */
9464 		proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
9465 		offset += 16;
9466 
9467 		/* lease state */
9468 		proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
9469 				       ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
9470 		offset += 4;
9471 
9472 		proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9473 		offset += 8;
9474 
9475 		return offset;
9476 	}
9477 
9478 	return offset;
9479 }
9480 
9481 /* names here are just until we find better names for these functions */
9482 static const value_string smb2_cmd_vals[] = {
9483 	{ 0x00, "Negotiate Protocol" },
9484 	{ 0x01, "Session Setup" },
9485 	{ 0x02, "Session Logoff" },
9486 	{ 0x03, "Tree Connect" },
9487 	{ 0x04, "Tree Disconnect" },
9488 	{ 0x05, "Create" },
9489 	{ 0x06, "Close" },
9490 	{ 0x07, "Flush" },
9491 	{ 0x08, "Read" },
9492 	{ 0x09, "Write" },
9493 	{ 0x0A, "Lock" },
9494 	{ 0x0B, "Ioctl" },
9495 	{ 0x0C, "Cancel" },
9496 	{ 0x0D, "KeepAlive" },
9497 	{ 0x0E, "Find" },
9498 	{ 0x0F, "Notify" },
9499 	{ 0x10, "GetInfo" },
9500 	{ 0x11, "SetInfo" },
9501 	{ 0x12, "Break" },
9502 	{ 0x13, "unknown-0x13" },
9503 	{ 0x14, "unknown-0x14" },
9504 	{ 0x15, "unknown-0x15" },
9505 	{ 0x16, "unknown-0x16" },
9506 	{ 0x17, "unknown-0x17" },
9507 	{ 0x18, "unknown-0x18" },
9508 	{ 0x19, "unknown-0x19" },
9509 	{ 0x1A, "unknown-0x1A" },
9510 	{ 0x1B, "unknown-0x1B" },
9511 	{ 0x1C, "unknown-0x1C" },
9512 	{ 0x1D, "unknown-0x1D" },
9513 	{ 0x1E, "unknown-0x1E" },
9514 	{ 0x1F, "unknown-0x1F" },
9515 	{ 0x20, "unknown-0x20" },
9516 	{ 0x21, "unknown-0x21" },
9517 	{ 0x22, "unknown-0x22" },
9518 	{ 0x23, "unknown-0x23" },
9519 	{ 0x24, "unknown-0x24" },
9520 	{ 0x25, "unknown-0x25" },
9521 	{ 0x26, "unknown-0x26" },
9522 	{ 0x27, "unknown-0x27" },
9523 	{ 0x28, "unknown-0x28" },
9524 	{ 0x29, "unknown-0x29" },
9525 	{ 0x2A, "unknown-0x2A" },
9526 	{ 0x2B, "unknown-0x2B" },
9527 	{ 0x2C, "unknown-0x2C" },
9528 	{ 0x2D, "unknown-0x2D" },
9529 	{ 0x2E, "unknown-0x2E" },
9530 	{ 0x2F, "unknown-0x2F" },
9531 	{ 0x30, "unknown-0x30" },
9532 	{ 0x31, "unknown-0x31" },
9533 	{ 0x32, "unknown-0x32" },
9534 	{ 0x33, "unknown-0x33" },
9535 	{ 0x34, "unknown-0x34" },
9536 	{ 0x35, "unknown-0x35" },
9537 	{ 0x36, "unknown-0x36" },
9538 	{ 0x37, "unknown-0x37" },
9539 	{ 0x38, "unknown-0x38" },
9540 	{ 0x39, "unknown-0x39" },
9541 	{ 0x3A, "unknown-0x3A" },
9542 	{ 0x3B, "unknown-0x3B" },
9543 	{ 0x3C, "unknown-0x3C" },
9544 	{ 0x3D, "unknown-0x3D" },
9545 	{ 0x3E, "unknown-0x3E" },
9546 	{ 0x3F, "unknown-0x3F" },
9547 	{ 0x40, "unknown-0x40" },
9548 	{ 0x41, "unknown-0x41" },
9549 	{ 0x42, "unknown-0x42" },
9550 	{ 0x43, "unknown-0x43" },
9551 	{ 0x44, "unknown-0x44" },
9552 	{ 0x45, "unknown-0x45" },
9553 	{ 0x46, "unknown-0x46" },
9554 	{ 0x47, "unknown-0x47" },
9555 	{ 0x48, "unknown-0x48" },
9556 	{ 0x49, "unknown-0x49" },
9557 	{ 0x4A, "unknown-0x4A" },
9558 	{ 0x4B, "unknown-0x4B" },
9559 	{ 0x4C, "unknown-0x4C" },
9560 	{ 0x4D, "unknown-0x4D" },
9561 	{ 0x4E, "unknown-0x4E" },
9562 	{ 0x4F, "unknown-0x4F" },
9563 	{ 0x50, "unknown-0x50" },
9564 	{ 0x51, "unknown-0x51" },
9565 	{ 0x52, "unknown-0x52" },
9566 	{ 0x53, "unknown-0x53" },
9567 	{ 0x54, "unknown-0x54" },
9568 	{ 0x55, "unknown-0x55" },
9569 	{ 0x56, "unknown-0x56" },
9570 	{ 0x57, "unknown-0x57" },
9571 	{ 0x58, "unknown-0x58" },
9572 	{ 0x59, "unknown-0x59" },
9573 	{ 0x5A, "unknown-0x5A" },
9574 	{ 0x5B, "unknown-0x5B" },
9575 	{ 0x5C, "unknown-0x5C" },
9576 	{ 0x5D, "unknown-0x5D" },
9577 	{ 0x5E, "unknown-0x5E" },
9578 	{ 0x5F, "unknown-0x5F" },
9579 	{ 0x60, "unknown-0x60" },
9580 	{ 0x61, "unknown-0x61" },
9581 	{ 0x62, "unknown-0x62" },
9582 	{ 0x63, "unknown-0x63" },
9583 	{ 0x64, "unknown-0x64" },
9584 	{ 0x65, "unknown-0x65" },
9585 	{ 0x66, "unknown-0x66" },
9586 	{ 0x67, "unknown-0x67" },
9587 	{ 0x68, "unknown-0x68" },
9588 	{ 0x69, "unknown-0x69" },
9589 	{ 0x6A, "unknown-0x6A" },
9590 	{ 0x6B, "unknown-0x6B" },
9591 	{ 0x6C, "unknown-0x6C" },
9592 	{ 0x6D, "unknown-0x6D" },
9593 	{ 0x6E, "unknown-0x6E" },
9594 	{ 0x6F, "unknown-0x6F" },
9595 	{ 0x70, "unknown-0x70" },
9596 	{ 0x71, "unknown-0x71" },
9597 	{ 0x72, "unknown-0x72" },
9598 	{ 0x73, "unknown-0x73" },
9599 	{ 0x74, "unknown-0x74" },
9600 	{ 0x75, "unknown-0x75" },
9601 	{ 0x76, "unknown-0x76" },
9602 	{ 0x77, "unknown-0x77" },
9603 	{ 0x78, "unknown-0x78" },
9604 	{ 0x79, "unknown-0x79" },
9605 	{ 0x7A, "unknown-0x7A" },
9606 	{ 0x7B, "unknown-0x7B" },
9607 	{ 0x7C, "unknown-0x7C" },
9608 	{ 0x7D, "unknown-0x7D" },
9609 	{ 0x7E, "unknown-0x7E" },
9610 	{ 0x7F, "unknown-0x7F" },
9611 	{ 0x80, "unknown-0x80" },
9612 	{ 0x81, "unknown-0x81" },
9613 	{ 0x82, "unknown-0x82" },
9614 	{ 0x83, "unknown-0x83" },
9615 	{ 0x84, "unknown-0x84" },
9616 	{ 0x85, "unknown-0x85" },
9617 	{ 0x86, "unknown-0x86" },
9618 	{ 0x87, "unknown-0x87" },
9619 	{ 0x88, "unknown-0x88" },
9620 	{ 0x89, "unknown-0x89" },
9621 	{ 0x8A, "unknown-0x8A" },
9622 	{ 0x8B, "unknown-0x8B" },
9623 	{ 0x8C, "unknown-0x8C" },
9624 	{ 0x8D, "unknown-0x8D" },
9625 	{ 0x8E, "unknown-0x8E" },
9626 	{ 0x8F, "unknown-0x8F" },
9627 	{ 0x90, "unknown-0x90" },
9628 	{ 0x91, "unknown-0x91" },
9629 	{ 0x92, "unknown-0x92" },
9630 	{ 0x93, "unknown-0x93" },
9631 	{ 0x94, "unknown-0x94" },
9632 	{ 0x95, "unknown-0x95" },
9633 	{ 0x96, "unknown-0x96" },
9634 	{ 0x97, "unknown-0x97" },
9635 	{ 0x98, "unknown-0x98" },
9636 	{ 0x99, "unknown-0x99" },
9637 	{ 0x9A, "unknown-0x9A" },
9638 	{ 0x9B, "unknown-0x9B" },
9639 	{ 0x9C, "unknown-0x9C" },
9640 	{ 0x9D, "unknown-0x9D" },
9641 	{ 0x9E, "unknown-0x9E" },
9642 	{ 0x9F, "unknown-0x9F" },
9643 	{ 0xA0, "unknown-0xA0" },
9644 	{ 0xA1, "unknown-0xA1" },
9645 	{ 0xA2, "unknown-0xA2" },
9646 	{ 0xA3, "unknown-0xA3" },
9647 	{ 0xA4, "unknown-0xA4" },
9648 	{ 0xA5, "unknown-0xA5" },
9649 	{ 0xA6, "unknown-0xA6" },
9650 	{ 0xA7, "unknown-0xA7" },
9651 	{ 0xA8, "unknown-0xA8" },
9652 	{ 0xA9, "unknown-0xA9" },
9653 	{ 0xAA, "unknown-0xAA" },
9654 	{ 0xAB, "unknown-0xAB" },
9655 	{ 0xAC, "unknown-0xAC" },
9656 	{ 0xAD, "unknown-0xAD" },
9657 	{ 0xAE, "unknown-0xAE" },
9658 	{ 0xAF, "unknown-0xAF" },
9659 	{ 0xB0, "unknown-0xB0" },
9660 	{ 0xB1, "unknown-0xB1" },
9661 	{ 0xB2, "unknown-0xB2" },
9662 	{ 0xB3, "unknown-0xB3" },
9663 	{ 0xB4, "unknown-0xB4" },
9664 	{ 0xB5, "unknown-0xB5" },
9665 	{ 0xB6, "unknown-0xB6" },
9666 	{ 0xB7, "unknown-0xB7" },
9667 	{ 0xB8, "unknown-0xB8" },
9668 	{ 0xB9, "unknown-0xB9" },
9669 	{ 0xBA, "unknown-0xBA" },
9670 	{ 0xBB, "unknown-0xBB" },
9671 	{ 0xBC, "unknown-0xBC" },
9672 	{ 0xBD, "unknown-0xBD" },
9673 	{ 0xBE, "unknown-0xBE" },
9674 	{ 0xBF, "unknown-0xBF" },
9675 	{ 0xC0, "unknown-0xC0" },
9676 	{ 0xC1, "unknown-0xC1" },
9677 	{ 0xC2, "unknown-0xC2" },
9678 	{ 0xC3, "unknown-0xC3" },
9679 	{ 0xC4, "unknown-0xC4" },
9680 	{ 0xC5, "unknown-0xC5" },
9681 	{ 0xC6, "unknown-0xC6" },
9682 	{ 0xC7, "unknown-0xC7" },
9683 	{ 0xC8, "unknown-0xC8" },
9684 	{ 0xC9, "unknown-0xC9" },
9685 	{ 0xCA, "unknown-0xCA" },
9686 	{ 0xCB, "unknown-0xCB" },
9687 	{ 0xCC, "unknown-0xCC" },
9688 	{ 0xCD, "unknown-0xCD" },
9689 	{ 0xCE, "unknown-0xCE" },
9690 	{ 0xCF, "unknown-0xCF" },
9691 	{ 0xD0, "unknown-0xD0" },
9692 	{ 0xD1, "unknown-0xD1" },
9693 	{ 0xD2, "unknown-0xD2" },
9694 	{ 0xD3, "unknown-0xD3" },
9695 	{ 0xD4, "unknown-0xD4" },
9696 	{ 0xD5, "unknown-0xD5" },
9697 	{ 0xD6, "unknown-0xD6" },
9698 	{ 0xD7, "unknown-0xD7" },
9699 	{ 0xD8, "unknown-0xD8" },
9700 	{ 0xD9, "unknown-0xD9" },
9701 	{ 0xDA, "unknown-0xDA" },
9702 	{ 0xDB, "unknown-0xDB" },
9703 	{ 0xDC, "unknown-0xDC" },
9704 	{ 0xDD, "unknown-0xDD" },
9705 	{ 0xDE, "unknown-0xDE" },
9706 	{ 0xDF, "unknown-0xDF" },
9707 	{ 0xE0, "unknown-0xE0" },
9708 	{ 0xE1, "unknown-0xE1" },
9709 	{ 0xE2, "unknown-0xE2" },
9710 	{ 0xE3, "unknown-0xE3" },
9711 	{ 0xE4, "unknown-0xE4" },
9712 	{ 0xE5, "unknown-0xE5" },
9713 	{ 0xE6, "unknown-0xE6" },
9714 	{ 0xE7, "unknown-0xE7" },
9715 	{ 0xE8, "unknown-0xE8" },
9716 	{ 0xE9, "unknown-0xE9" },
9717 	{ 0xEA, "unknown-0xEA" },
9718 	{ 0xEB, "unknown-0xEB" },
9719 	{ 0xEC, "unknown-0xEC" },
9720 	{ 0xED, "unknown-0xED" },
9721 	{ 0xEE, "unknown-0xEE" },
9722 	{ 0xEF, "unknown-0xEF" },
9723 	{ 0xF0, "unknown-0xF0" },
9724 	{ 0xF1, "unknown-0xF1" },
9725 	{ 0xF2, "unknown-0xF2" },
9726 	{ 0xF3, "unknown-0xF3" },
9727 	{ 0xF4, "unknown-0xF4" },
9728 	{ 0xF5, "unknown-0xF5" },
9729 	{ 0xF6, "unknown-0xF6" },
9730 	{ 0xF7, "unknown-0xF7" },
9731 	{ 0xF8, "unknown-0xF8" },
9732 	{ 0xF9, "unknown-0xF9" },
9733 	{ 0xFA, "unknown-0xFA" },
9734 	{ 0xFB, "unknown-0xFB" },
9735 	{ 0xFC, "unknown-0xFC" },
9736 	{ 0xFD, "unknown-0xFD" },
9737 	{ 0xFE, "unknown-0xFE" },
9738 	{ 0xFF, "unknown-0xFF" },
9739 	{ 0x00, NULL },
9740 };
9741 value_string_ext smb2_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb2_cmd_vals);
9742 
decode_smb2_name(guint16 cmd)9743 static const char *decode_smb2_name(guint16 cmd)
9744 {
9745 	if (cmd > 0xFF) return "unknown";
9746 	return(smb2_cmd_vals[cmd & 0xFF].strptr);
9747 }
9748 
9749 static smb2_function smb2_dissector[256] = {
9750   /* 0x00 NegotiateProtocol*/
9751 	{dissect_smb2_negotiate_protocol_request,
9752 	 dissect_smb2_negotiate_protocol_response},
9753   /* 0x01 SessionSetup*/
9754 	{dissect_smb2_session_setup_request,
9755 	 dissect_smb2_session_setup_response},
9756   /* 0x02 SessionLogoff*/
9757 	{dissect_smb2_sessionlogoff_request,
9758 	 dissect_smb2_sessionlogoff_response},
9759   /* 0x03 TreeConnect*/
9760 	{dissect_smb2_tree_connect_request,
9761 	 dissect_smb2_tree_connect_response},
9762   /* 0x04 TreeDisconnect*/
9763 	{dissect_smb2_tree_disconnect_request,
9764 	 dissect_smb2_tree_disconnect_response},
9765   /* 0x05 Create*/
9766 	{dissect_smb2_create_request,
9767 	 dissect_smb2_create_response},
9768   /* 0x06 Close*/
9769 	{dissect_smb2_close_request,
9770 	 dissect_smb2_close_response},
9771   /* 0x07 Flush*/
9772 	{dissect_smb2_flush_request,
9773 	 dissect_smb2_flush_response},
9774   /* 0x08 Read*/
9775 	{dissect_smb2_read_request,
9776 	 dissect_smb2_read_response},
9777   /* 0x09 Writew*/
9778 	{dissect_smb2_write_request,
9779 	 dissect_smb2_write_response},
9780   /* 0x0a Lock */
9781 	{dissect_smb2_lock_request,
9782 	 dissect_smb2_lock_response},
9783   /* 0x0b Ioctl*/
9784 	{dissect_smb2_ioctl_request,
9785 	 dissect_smb2_ioctl_response},
9786   /* 0x0c Cancel*/
9787 	{dissect_smb2_cancel_request,
9788 	 NULL},
9789   /* 0x0d KeepAlive*/
9790 	{dissect_smb2_keepalive_request,
9791 	 dissect_smb2_keepalive_response},
9792   /* 0x0e Find*/
9793 	{dissect_smb2_find_request,
9794 	 dissect_smb2_find_response},
9795   /* 0x0f Notify*/
9796 	{dissect_smb2_notify_request,
9797 	 dissect_smb2_notify_response},
9798   /* 0x10 GetInfo*/
9799 	{dissect_smb2_getinfo_request,
9800 	 dissect_smb2_getinfo_response},
9801   /* 0x11 SetInfo*/
9802 	{dissect_smb2_setinfo_request,
9803 	 dissect_smb2_setinfo_response},
9804   /* 0x12 Break */
9805   	{dissect_smb2_break_request,
9806 	 dissect_smb2_break_response},
9807   /* 0x13 */  {NULL, NULL},
9808   /* 0x14 */  {NULL, NULL},
9809   /* 0x15 */  {NULL, NULL},
9810   /* 0x16 */  {NULL, NULL},
9811   /* 0x17 */  {NULL, NULL},
9812   /* 0x18 */  {NULL, NULL},
9813   /* 0x19 */  {NULL, NULL},
9814   /* 0x1a */  {NULL, NULL},
9815   /* 0x1b */  {NULL, NULL},
9816   /* 0x1c */  {NULL, NULL},
9817   /* 0x1d */  {NULL, NULL},
9818   /* 0x1e */  {NULL, NULL},
9819   /* 0x1f */  {NULL, NULL},
9820   /* 0x20 */  {NULL, NULL},
9821   /* 0x21 */  {NULL, NULL},
9822   /* 0x22 */  {NULL, NULL},
9823   /* 0x23 */  {NULL, NULL},
9824   /* 0x24 */  {NULL, NULL},
9825   /* 0x25 */  {NULL, NULL},
9826   /* 0x26 */  {NULL, NULL},
9827   /* 0x27 */  {NULL, NULL},
9828   /* 0x28 */  {NULL, NULL},
9829   /* 0x29 */  {NULL, NULL},
9830   /* 0x2a */  {NULL, NULL},
9831   /* 0x2b */  {NULL, NULL},
9832   /* 0x2c */  {NULL, NULL},
9833   /* 0x2d */  {NULL, NULL},
9834   /* 0x2e */  {NULL, NULL},
9835   /* 0x2f */  {NULL, NULL},
9836   /* 0x30 */  {NULL, NULL},
9837   /* 0x31 */  {NULL, NULL},
9838   /* 0x32 */  {NULL, NULL},
9839   /* 0x33 */  {NULL, NULL},
9840   /* 0x34 */  {NULL, NULL},
9841   /* 0x35 */  {NULL, NULL},
9842   /* 0x36 */  {NULL, NULL},
9843   /* 0x37 */  {NULL, NULL},
9844   /* 0x38 */  {NULL, NULL},
9845   /* 0x39 */  {NULL, NULL},
9846   /* 0x3a */  {NULL, NULL},
9847   /* 0x3b */  {NULL, NULL},
9848   /* 0x3c */  {NULL, NULL},
9849   /* 0x3d */  {NULL, NULL},
9850   /* 0x3e */  {NULL, NULL},
9851   /* 0x3f */  {NULL, NULL},
9852   /* 0x40 */  {NULL, NULL},
9853   /* 0x41 */  {NULL, NULL},
9854   /* 0x42 */  {NULL, NULL},
9855   /* 0x43 */  {NULL, NULL},
9856   /* 0x44 */  {NULL, NULL},
9857   /* 0x45 */  {NULL, NULL},
9858   /* 0x46 */  {NULL, NULL},
9859   /* 0x47 */  {NULL, NULL},
9860   /* 0x48 */  {NULL, NULL},
9861   /* 0x49 */  {NULL, NULL},
9862   /* 0x4a */  {NULL, NULL},
9863   /* 0x4b */  {NULL, NULL},
9864   /* 0x4c */  {NULL, NULL},
9865   /* 0x4d */  {NULL, NULL},
9866   /* 0x4e */  {NULL, NULL},
9867   /* 0x4f */  {NULL, NULL},
9868   /* 0x50 */  {NULL, NULL},
9869   /* 0x51 */  {NULL, NULL},
9870   /* 0x52 */  {NULL, NULL},
9871   /* 0x53 */  {NULL, NULL},
9872   /* 0x54 */  {NULL, NULL},
9873   /* 0x55 */  {NULL, NULL},
9874   /* 0x56 */  {NULL, NULL},
9875   /* 0x57 */  {NULL, NULL},
9876   /* 0x58 */  {NULL, NULL},
9877   /* 0x59 */  {NULL, NULL},
9878   /* 0x5a */  {NULL, NULL},
9879   /* 0x5b */  {NULL, NULL},
9880   /* 0x5c */  {NULL, NULL},
9881   /* 0x5d */  {NULL, NULL},
9882   /* 0x5e */  {NULL, NULL},
9883   /* 0x5f */  {NULL, NULL},
9884   /* 0x60 */  {NULL, NULL},
9885   /* 0x61 */  {NULL, NULL},
9886   /* 0x62 */  {NULL, NULL},
9887   /* 0x63 */  {NULL, NULL},
9888   /* 0x64 */  {NULL, NULL},
9889   /* 0x65 */  {NULL, NULL},
9890   /* 0x66 */  {NULL, NULL},
9891   /* 0x67 */  {NULL, NULL},
9892   /* 0x68 */  {NULL, NULL},
9893   /* 0x69 */  {NULL, NULL},
9894   /* 0x6a */  {NULL, NULL},
9895   /* 0x6b */  {NULL, NULL},
9896   /* 0x6c */  {NULL, NULL},
9897   /* 0x6d */  {NULL, NULL},
9898   /* 0x6e */  {NULL, NULL},
9899   /* 0x6f */  {NULL, NULL},
9900   /* 0x70 */  {NULL, NULL},
9901   /* 0x71 */  {NULL, NULL},
9902   /* 0x72 */  {NULL, NULL},
9903   /* 0x73 */  {NULL, NULL},
9904   /* 0x74 */  {NULL, NULL},
9905   /* 0x75 */  {NULL, NULL},
9906   /* 0x76 */  {NULL, NULL},
9907   /* 0x77 */  {NULL, NULL},
9908   /* 0x78 */  {NULL, NULL},
9909   /* 0x79 */  {NULL, NULL},
9910   /* 0x7a */  {NULL, NULL},
9911   /* 0x7b */  {NULL, NULL},
9912   /* 0x7c */  {NULL, NULL},
9913   /* 0x7d */  {NULL, NULL},
9914   /* 0x7e */  {NULL, NULL},
9915   /* 0x7f */  {NULL, NULL},
9916   /* 0x80 */  {NULL, NULL},
9917   /* 0x81 */  {NULL, NULL},
9918   /* 0x82 */  {NULL, NULL},
9919   /* 0x83 */  {NULL, NULL},
9920   /* 0x84 */  {NULL, NULL},
9921   /* 0x85 */  {NULL, NULL},
9922   /* 0x86 */  {NULL, NULL},
9923   /* 0x87 */  {NULL, NULL},
9924   /* 0x88 */  {NULL, NULL},
9925   /* 0x89 */  {NULL, NULL},
9926   /* 0x8a */  {NULL, NULL},
9927   /* 0x8b */  {NULL, NULL},
9928   /* 0x8c */  {NULL, NULL},
9929   /* 0x8d */  {NULL, NULL},
9930   /* 0x8e */  {NULL, NULL},
9931   /* 0x8f */  {NULL, NULL},
9932   /* 0x90 */  {NULL, NULL},
9933   /* 0x91 */  {NULL, NULL},
9934   /* 0x92 */  {NULL, NULL},
9935   /* 0x93 */  {NULL, NULL},
9936   /* 0x94 */  {NULL, NULL},
9937   /* 0x95 */  {NULL, NULL},
9938   /* 0x96 */  {NULL, NULL},
9939   /* 0x97 */  {NULL, NULL},
9940   /* 0x98 */  {NULL, NULL},
9941   /* 0x99 */  {NULL, NULL},
9942   /* 0x9a */  {NULL, NULL},
9943   /* 0x9b */  {NULL, NULL},
9944   /* 0x9c */  {NULL, NULL},
9945   /* 0x9d */  {NULL, NULL},
9946   /* 0x9e */  {NULL, NULL},
9947   /* 0x9f */  {NULL, NULL},
9948   /* 0xa0 */  {NULL, NULL},
9949   /* 0xa1 */  {NULL, NULL},
9950   /* 0xa2 */  {NULL, NULL},
9951   /* 0xa3 */  {NULL, NULL},
9952   /* 0xa4 */  {NULL, NULL},
9953   /* 0xa5 */  {NULL, NULL},
9954   /* 0xa6 */  {NULL, NULL},
9955   /* 0xa7 */  {NULL, NULL},
9956   /* 0xa8 */  {NULL, NULL},
9957   /* 0xa9 */  {NULL, NULL},
9958   /* 0xaa */  {NULL, NULL},
9959   /* 0xab */  {NULL, NULL},
9960   /* 0xac */  {NULL, NULL},
9961   /* 0xad */  {NULL, NULL},
9962   /* 0xae */  {NULL, NULL},
9963   /* 0xaf */  {NULL, NULL},
9964   /* 0xb0 */  {NULL, NULL},
9965   /* 0xb1 */  {NULL, NULL},
9966   /* 0xb2 */  {NULL, NULL},
9967   /* 0xb3 */  {NULL, NULL},
9968   /* 0xb4 */  {NULL, NULL},
9969   /* 0xb5 */  {NULL, NULL},
9970   /* 0xb6 */  {NULL, NULL},
9971   /* 0xb7 */  {NULL, NULL},
9972   /* 0xb8 */  {NULL, NULL},
9973   /* 0xb9 */  {NULL, NULL},
9974   /* 0xba */  {NULL, NULL},
9975   /* 0xbb */  {NULL, NULL},
9976   /* 0xbc */  {NULL, NULL},
9977   /* 0xbd */  {NULL, NULL},
9978   /* 0xbe */  {NULL, NULL},
9979   /* 0xbf */  {NULL, NULL},
9980   /* 0xc0 */  {NULL, NULL},
9981   /* 0xc1 */  {NULL, NULL},
9982   /* 0xc2 */  {NULL, NULL},
9983   /* 0xc3 */  {NULL, NULL},
9984   /* 0xc4 */  {NULL, NULL},
9985   /* 0xc5 */  {NULL, NULL},
9986   /* 0xc6 */  {NULL, NULL},
9987   /* 0xc7 */  {NULL, NULL},
9988   /* 0xc8 */  {NULL, NULL},
9989   /* 0xc9 */  {NULL, NULL},
9990   /* 0xca */  {NULL, NULL},
9991   /* 0xcb */  {NULL, NULL},
9992   /* 0xcc */  {NULL, NULL},
9993   /* 0xcd */  {NULL, NULL},
9994   /* 0xce */  {NULL, NULL},
9995   /* 0xcf */  {NULL, NULL},
9996   /* 0xd0 */  {NULL, NULL},
9997   /* 0xd1 */  {NULL, NULL},
9998   /* 0xd2 */  {NULL, NULL},
9999   /* 0xd3 */  {NULL, NULL},
10000   /* 0xd4 */  {NULL, NULL},
10001   /* 0xd5 */  {NULL, NULL},
10002   /* 0xd6 */  {NULL, NULL},
10003   /* 0xd7 */  {NULL, NULL},
10004   /* 0xd8 */  {NULL, NULL},
10005   /* 0xd9 */  {NULL, NULL},
10006   /* 0xda */  {NULL, NULL},
10007   /* 0xdb */  {NULL, NULL},
10008   /* 0xdc */  {NULL, NULL},
10009   /* 0xdd */  {NULL, NULL},
10010   /* 0xde */  {NULL, NULL},
10011   /* 0xdf */  {NULL, NULL},
10012   /* 0xe0 */  {NULL, NULL},
10013   /* 0xe1 */  {NULL, NULL},
10014   /* 0xe2 */  {NULL, NULL},
10015   /* 0xe3 */  {NULL, NULL},
10016   /* 0xe4 */  {NULL, NULL},
10017   /* 0xe5 */  {NULL, NULL},
10018   /* 0xe6 */  {NULL, NULL},
10019   /* 0xe7 */  {NULL, NULL},
10020   /* 0xe8 */  {NULL, NULL},
10021   /* 0xe9 */  {NULL, NULL},
10022   /* 0xea */  {NULL, NULL},
10023   /* 0xeb */  {NULL, NULL},
10024   /* 0xec */  {NULL, NULL},
10025   /* 0xed */  {NULL, NULL},
10026   /* 0xee */  {NULL, NULL},
10027   /* 0xef */  {NULL, NULL},
10028   /* 0xf0 */  {NULL, NULL},
10029   /* 0xf1 */  {NULL, NULL},
10030   /* 0xf2 */  {NULL, NULL},
10031   /* 0xf3 */  {NULL, NULL},
10032   /* 0xf4 */  {NULL, NULL},
10033   /* 0xf5 */  {NULL, NULL},
10034   /* 0xf6 */  {NULL, NULL},
10035   /* 0xf7 */  {NULL, NULL},
10036   /* 0xf8 */  {NULL, NULL},
10037   /* 0xf9 */  {NULL, NULL},
10038   /* 0xfa */  {NULL, NULL},
10039   /* 0xfb */  {NULL, NULL},
10040   /* 0xfc */  {NULL, NULL},
10041   /* 0xfd */  {NULL, NULL},
10042   /* 0xfe */  {NULL, NULL},
10043   /* 0xff */  {NULL, NULL},
10044 };
10045 
10046 
10047 #define SMB3_AES128CCM_NONCE	11
10048 #define SMB3_AES128GCM_NONCE	12
10049 
10050 #if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
is_decrypted_header_ok(guint8 * p,size_t size)10051 static gboolean is_decrypted_header_ok(guint8 *p, size_t size)
10052 {
10053 	if (size < 4)
10054 		return FALSE;
10055 
10056 	if ((p[0] == SMB2_COMP_HEADER || p[0] == SMB2_NORM_HEADER)
10057 	    && (p[1] == 'S' || p[2] == 'M' || p[3] == 'B')) {
10058 		return TRUE;
10059 	}
10060 
10061 	DEBUG("decrypt: bad SMB header");
10062 	return FALSE;
10063 }
10064 
10065 static gboolean
do_decrypt(guint8 * data,size_t data_size,const guint8 * key,const guint8 * aad,int aad_size,const guint8 * nonce,int alg)10066 do_decrypt(guint8 *data,
10067 	   size_t data_size,
10068 	   const guint8 *key,
10069 	   const guint8 *aad,
10070 	   int aad_size,
10071 	   const guint8 *nonce,
10072 	   int alg)
10073 {
10074 	gcry_error_t err;
10075 	gcry_cipher_hd_t cipher_hd = NULL;
10076 	int mode;
10077 	int iv_size;
10078 	guint64 lengths[3];
10079 
10080 	switch (alg) {
10081 	case SMB2_CIPHER_AES_128_CCM:
10082 		mode = GCRY_CIPHER_MODE_CCM;
10083 		iv_size = SMB3_AES128CCM_NONCE;
10084 		break;
10085 	case SMB2_CIPHER_AES_128_GCM:
10086 		mode = GCRY_CIPHER_MODE_GCM;
10087 		iv_size = SMB3_AES128GCM_NONCE;
10088 		break;
10089 	default:
10090 		return FALSE;
10091 	}
10092 
10093 	/* Open the cipher */
10094 	if ((err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, mode, 0))) {
10095 		DEBUG("GCRY: open %s/%s", gcry_strsource(err), gcry_strerror(err));
10096 		return FALSE;
10097 	}
10098 
10099 	/* Set the key */
10100 	if ((err = gcry_cipher_setkey(cipher_hd, key, AES_KEY_SIZE))) {
10101 		DEBUG("GCRY: setkey %s/%s", gcry_strsource(err), gcry_strerror(err));
10102 		gcry_cipher_close(cipher_hd);
10103 		return FALSE;
10104 	}
10105 
10106 	/* Set the initial value */
10107 	if ((err = gcry_cipher_setiv(cipher_hd, nonce, iv_size))) {
10108 		DEBUG("GCRY: setiv %s/%s", gcry_strsource(err), gcry_strerror(err));
10109 		gcry_cipher_close(cipher_hd);
10110 		return FALSE;
10111 	}
10112 
10113 	lengths[0] = data_size; /* encrypted length */
10114 	lengths[1] = aad_size; /* AAD length */
10115 	lengths[2] = 16; /* tag length (signature size) */
10116 
10117 	if (mode == GCRY_CIPHER_MODE_CCM) {
10118 		if ((err = gcry_cipher_ctl(cipher_hd, GCRYCTL_SET_CCM_LENGTHS, lengths, sizeof(lengths)))) {
10119 			DEBUG("GCRY: ctl %s/%s", gcry_strsource(err), gcry_strerror(err));
10120 			gcry_cipher_close(cipher_hd);
10121 			return FALSE;
10122 		}
10123 	}
10124 
10125 	if ((err = gcry_cipher_authenticate(cipher_hd, aad, aad_size))) {
10126 		DEBUG("GCRY: auth %s/%s", gcry_strsource(err), gcry_strerror(err));
10127 		gcry_cipher_close(cipher_hd);
10128 		return FALSE;
10129 	}
10130 
10131 	if ((err = gcry_cipher_decrypt(cipher_hd, data, data_size, NULL, 0))) {
10132 		DEBUG("GCRY: decrypt %s/%s", gcry_strsource(err), gcry_strerror(err));
10133 		gcry_cipher_close(cipher_hd);
10134 		return FALSE;
10135 	}
10136 
10137 	/* Done with the cipher */
10138 	gcry_cipher_close(cipher_hd);
10139 	return is_decrypted_header_ok(data, data_size);
10140 }
10141 
10142 static guint8*
decrypt_smb_payload(packet_info * pinfo,tvbuff_t * tvb,int offset,int offset_aad,smb2_transform_info_t * sti)10143 decrypt_smb_payload(packet_info *pinfo,
10144 		    tvbuff_t *tvb, int offset,
10145 		    int offset_aad,
10146 		    smb2_transform_info_t *sti)
10147 {
10148 	const guint8 *aad = NULL;
10149 	guint8 *data = NULL;
10150 	guint8 *keys[2], *key;
10151 	gboolean ok;
10152 	int aad_size;
10153 	int alg;
10154 
10155 	/* AAD is the rest of transform header after the ProtocolID and Signature */
10156 	aad_size = 32;
10157 
10158 	if ((unsigned)tvb_captured_length_remaining(tvb, offset) < sti->size)
10159 		return NULL;
10160 
10161 	if (tvb_captured_length_remaining(tvb, offset_aad) < aad_size)
10162 		return NULL;
10163 
10164 	if (pinfo->destport == sti->session->server_port) {
10165 		keys[0] = sti->session->server_decryption_key;
10166 		keys[1] = sti->session->client_decryption_key;
10167 	} else {
10168 		keys[1] = sti->session->server_decryption_key;
10169 		keys[0] = sti->session->client_decryption_key;
10170 	}
10171 
10172 	aad = tvb_get_ptr(tvb, offset_aad, aad_size);
10173 	data = (guint8 *)tvb_memdup(pinfo->pool, tvb, offset, sti->size);
10174 
10175 	/*
10176 	 * In SMB3.0 the transform header had a Algorithm field to
10177 	 * know which type of encryption was used but only CCM was
10178 	 * supported.
10179 	 *
10180 	 * SMB3.1.1 turned that field into a generic "Encrypted" flag
10181 	 * which cannot be used to determine the encryption
10182 	 * type. Instead the type is decided in the NegProt response,
10183 	 * within the Encryption Capability context which should only
10184 	 * have one element. That element is saved in the conversation
10185 	 * struct (si->conv) and checked here.
10186 	 *
10187 	 * If the trace didn't contain NegProt packets, we have to
10188 	 * guess the encryption type by trying them all.
10189 	 *
10190 	 * Similarly, if we don't have unencrypted packets telling us
10191 	 * which host is the server and which host is the client, we
10192 	 * have to guess by trying both keys.
10193 	 */
10194 
10195 	DEBUG("dialect 0x%x alg 0x%x conv alg 0x%x", sti->conv->dialect, sti->alg, sti->conv->enc_alg);
10196 
10197 	if (sti->conv->dialect == SMB2_DIALECT_300) {
10198 		/* If we know we are decrypting SMB3.0, it must be CCM */
10199 		sti->conv->enc_alg = SMB2_CIPHER_AES_128_CCM;
10200 	}
10201 
10202 	for (guint i = 0; i < G_N_ELEMENTS(keys); i++) {
10203 		gboolean try_ccm, try_gcm;
10204 		key = keys[i];
10205 		ok = try_ccm = try_gcm = FALSE;
10206 
10207 		switch (sti->conv->enc_alg) {
10208 		case SMB2_CIPHER_AES_128_CCM:
10209 			try_ccm = TRUE;
10210 			break;
10211 		case SMB2_CIPHER_AES_128_GCM:
10212 			try_gcm = TRUE;
10213 			break;
10214 		default:
10215 			/* we don't know, try both */
10216 			try_ccm = TRUE;
10217 			try_gcm = TRUE;
10218 		}
10219 
10220 		if (try_ccm) {
10221 			DEBUG("trying CCM decryption");
10222 			alg = SMB2_CIPHER_AES_128_CCM;
10223 			ok = do_decrypt(data, sti->size, key, aad, aad_size, sti->nonce, alg);
10224 			if (ok)
10225 				break;
10226 			DEBUG("bad decrypted buffer with CCM");
10227 		}
10228 		if (try_gcm) {
10229 			DEBUG("trying GCM decryption");
10230 			alg = SMB2_CIPHER_AES_128_GCM;
10231 			tvb_memcpy(tvb, data, offset, sti->size);
10232 			ok = do_decrypt(data, sti->size, key, aad, aad_size, sti->nonce, alg);
10233 			if (ok)
10234 				break;
10235 			DEBUG("bad decrypted buffer with GCM");
10236 		}
10237 		DEBUG("trying to decrypt with swapped client/server keys");
10238 		tvb_memcpy(tvb, data, offset, sti->size);
10239 	}
10240 
10241 	if (!ok)
10242 		return NULL;
10243 
10244 	/* Remember what worked */
10245 	sti->conv->enc_alg = alg;
10246 	if (key == sti->session->server_decryption_key)
10247 		sti->session->server_port = pinfo->destport;
10248 	else
10249 		sti->session->server_port = pinfo->srcport;
10250 	return data;
10251 }
10252 #endif
10253 
10254 /*
10255   Append tvb[offset:offset+length] to out
10256 */
10257 static void
append_uncompress_data(wmem_array_t * out,tvbuff_t * tvb,int offset,guint length)10258 append_uncompress_data(wmem_array_t *out, tvbuff_t *tvb, int offset, guint length)
10259 {
10260 	wmem_array_append(out, tvb_get_ptr(tvb, offset, length), length);
10261 }
10262 
10263 static int
dissect_smb2_compression_pattern_v1(proto_tree * tree,tvbuff_t * tvb,int offset,int length,wmem_array_t * out)10264 dissect_smb2_compression_pattern_v1(proto_tree *tree,
10265 				    tvbuff_t *tvb, int offset, int length,
10266 				    wmem_array_t *out)
10267 {
10268 	proto_item *pat_item;
10269 	proto_tree *pat_tree;
10270 	guint pattern, times;
10271 
10272 	pat_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
10273 						 ett_smb2_comp_pattern_v1, &pat_item,
10274 						 "Pattern");
10275 
10276 	proto_tree_add_item_ret_uint(pat_tree, hf_smb2_comp_pattern_v1_pattern, tvb, offset, 1, ENC_LITTLE_ENDIAN, &pattern);
10277 	offset += 1;
10278 
10279 	proto_tree_add_item(pat_tree, hf_smb2_comp_pattern_v1_reserved1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10280 	offset += 1;
10281 
10282 	proto_tree_add_item(pat_tree, hf_smb2_comp_pattern_v1_reserved2, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10283 	offset += 2;
10284 
10285 	proto_tree_add_item_ret_uint(pat_tree, hf_smb2_comp_pattern_v1_repetitions, tvb, offset, 4, ENC_LITTLE_ENDIAN, &times);
10286 	offset += 4;
10287 
10288 	proto_item_append_text(pat_item, " 0x%02x repeated %u times", pattern, times);
10289 
10290 	if (out && times < MAX_UNCOMPRESSED_SIZE) {
10291 		guint8 v = (guint8)pattern;
10292 
10293 		for (guint i = 0; i < times; i++)
10294 			wmem_array_append(out, &v, 1);
10295 	}
10296 
10297 	return offset;
10298 }
10299 
10300 static int
dissect_smb2_chained_comp_payload(packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,int offset,wmem_array_t * out,gboolean * ok)10301 dissect_smb2_chained_comp_payload(packet_info *pinfo, proto_tree *tree,
10302 				  tvbuff_t *tvb, int offset,
10303 				  wmem_array_t *out,
10304 				  gboolean *ok)
10305 {
10306 	proto_tree *subtree;
10307 	proto_item *subitem;
10308 	guint alg, length, flags, orig_size = 0;
10309 	tvbuff_t *uncomp_tvb = NULL;
10310 	gboolean lz_based = FALSE;
10311 
10312 	*ok = TRUE;
10313 
10314 	subtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_smb2_comp_payload, &subitem, "COMPRESSION_PAYLOAD_HEADER");
10315 	proto_tree_add_item_ret_uint(subtree, hf_smb2_comp_transform_comp_alg, tvb, offset, 2, ENC_LITTLE_ENDIAN, &alg);
10316 	offset += 2;
10317 
10318 	proto_tree_add_item_ret_uint(subtree, hf_smb2_comp_transform_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN, &flags);
10319 	offset += 2;
10320 
10321 	proto_tree_add_item_ret_uint(subtree, hf_smb2_comp_transform_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
10322 	offset += 4;
10323 
10324 	proto_item_set_len(subitem, length);
10325 
10326 	lz_based = (SMB2_COMP_ALG_LZNT1 <= alg && alg <= SMB2_COMP_ALG_LZ77HUFF);
10327 	if (lz_based) {
10328 		proto_tree_add_item_ret_uint(subtree, hf_smb2_comp_transform_orig_payload_size,
10329 					     tvb, offset, 4, ENC_LITTLE_ENDIAN, &orig_size);
10330 		offset += 4;
10331 		length -= 4;
10332 	}
10333 
10334 	if (length > MAX_UNCOMPRESSED_SIZE) {
10335 		/* decompression error */
10336 		col_append_str(pinfo->cinfo, COL_INFO, "Comp. SMB3 (invalid)");
10337 		*ok = FALSE;
10338 		goto out;
10339 	}
10340 
10341 	switch (alg) {
10342 	case SMB2_COMP_ALG_NONE:
10343 		append_uncompress_data(out, tvb, offset, length);
10344 		break;
10345 	case SMB2_COMP_ALG_LZ77:
10346 		uncomp_tvb = tvb_uncompress_lz77(tvb, offset, length);
10347 		break;
10348 	case SMB2_COMP_ALG_LZ77HUFF:
10349 		uncomp_tvb = tvb_uncompress_lz77huff(tvb, offset, length);
10350 		break;
10351 	case SMB2_COMP_ALG_LZNT1:
10352 		uncomp_tvb = tvb_uncompress_lznt1(tvb, offset, length);
10353 		break;
10354 	case SMB2_COMP_ALG_PATTERN_V1:
10355 		dissect_smb2_compression_pattern_v1(subtree, tvb, offset, length, out);
10356 		break;
10357 	default:
10358 		col_append_str(pinfo->cinfo, COL_INFO, "Comp. SMB3 (unknown)");
10359 		uncomp_tvb = NULL;
10360 		break;
10361 	}
10362 
10363 	if (lz_based) {
10364 		if (!uncomp_tvb || tvb_reported_length(uncomp_tvb) != orig_size) {
10365 			/* decompression error */
10366 			col_append_str(pinfo->cinfo, COL_INFO, "Comp. SMB3 (invalid)");
10367 			*ok = FALSE;
10368 			goto out;
10369 		}
10370 		append_uncompress_data(out, uncomp_tvb, 0, tvb_reported_length(uncomp_tvb));
10371 	}
10372 
10373  out:
10374 	if (uncomp_tvb)
10375 		tvb_free(uncomp_tvb);
10376 	proto_tree_add_item(subtree, hf_smb2_comp_transform_data, tvb, offset, length, ENC_NA);
10377 	offset += length;
10378 
10379 	return offset;
10380 }
10381 
10382 static int
dissect_smb2_comp_transform_header(packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,int offset,smb2_comp_transform_info_t * scti,tvbuff_t ** comp_tvb,tvbuff_t ** plain_tvb)10383 dissect_smb2_comp_transform_header(packet_info *pinfo, proto_tree *tree,
10384 				   tvbuff_t *tvb, int offset,
10385 				   smb2_comp_transform_info_t *scti,
10386 				   tvbuff_t **comp_tvb,
10387 				   tvbuff_t **plain_tvb)
10388 {
10389 	gint in_size;
10390 	tvbuff_t *uncomp_tvb = NULL;
10391 	guint flags;
10392 	wmem_array_t *uncomp_data;
10393 
10394 	*comp_tvb = NULL;
10395 	*plain_tvb = NULL;
10396 
10397 	/*
10398 	  "old" compressed method:
10399 
10400 	  [COMPRESS_TRANSFORM_HEADER with Flags=0]
10401 	    [OPTIONAL UNCOMPRESSED DATA]
10402 	    [COMPRESSED DATA]
10403 
10404 	  new "chained" compressed method:
10405 
10406 	  [fist 8 bytes of COMPRESS_TRANSFORM_HEADER with Flags=CHAINED]
10407 	    [ sequence of
10408                [ COMPRESSION_PAYLOAD_HEADER ]
10409                [ COMPRESSED PAYLOAD ]
10410 	    ]
10411 	 */
10412 
10413 	/* SMB2_COMPRESSION_TRANSFORM marker */
10414 	proto_tree_add_item(tree, hf_smb2_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
10415 	offset += 4;
10416 
10417 	proto_tree_add_item_ret_uint(tree, hf_smb2_comp_transform_orig_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &scti->orig_size);
10418 	offset += 4;
10419 
10420 	uncomp_data = wmem_array_sized_new(pinfo->pool, 1, 1024);
10421 
10422 	flags = tvb_get_letohs(tvb, offset+2);
10423 	if (flags & SMB2_COMP_FLAG_CHAINED) {
10424 		gboolean all_ok = TRUE;
10425 
10426 		*comp_tvb = tvb_new_subset_length(tvb, offset, tvb_reported_length_remaining(tvb, offset));
10427 		do {
10428 			gboolean ok = FALSE;
10429 
10430 			offset = dissect_smb2_chained_comp_payload(pinfo, tree, tvb, offset, uncomp_data, &ok);
10431 			if (!ok)
10432 				all_ok = FALSE;
10433 		} while (tvb_reported_length_remaining(tvb, offset) > 8);
10434 		if (all_ok)
10435 			goto decompression_ok;
10436 		else
10437 			goto out;
10438 
10439 	}
10440 
10441 	proto_tree_add_item_ret_uint(tree, hf_smb2_comp_transform_comp_alg, tvb, offset, 2, ENC_LITTLE_ENDIAN, &scti->alg);
10442 	offset += 2;
10443 
10444 	proto_tree_add_item_ret_uint(tree, hf_smb2_comp_transform_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN, &flags);
10445 	offset += 2;
10446 
10447 	proto_tree_add_item_ret_uint(tree, hf_smb2_comp_transform_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &scti->comp_offset);
10448 	offset += 4;
10449 
10450 	*comp_tvb = tvb_new_subset_length(tvb, offset, tvb_reported_length_remaining(tvb, offset));
10451 
10452 	if (scti->orig_size > MAX_UNCOMPRESSED_SIZE || scti->comp_offset > MAX_UNCOMPRESSED_SIZE) {
10453 		col_append_str(pinfo->cinfo, COL_INFO, "Comp. SMB3 (too big)");
10454 		goto out;
10455 	}
10456 
10457 	/*
10458 	 *  final uncompressed size is the partial normal packet + uncompressed segment
10459          *  final_size = scti->orig_size + scti->comp_offset
10460 	 */
10461 
10462 	append_uncompress_data(uncomp_data, tvb, offset, scti->comp_offset);
10463 	in_size = tvb_reported_length_remaining(tvb, offset + scti->comp_offset);
10464 
10465 	/* decompress compressed segment */
10466 	switch (scti->alg) {
10467 	case SMB2_COMP_ALG_LZ77:
10468 		uncomp_tvb = tvb_uncompress_lz77(tvb, offset + scti->comp_offset, in_size);
10469 		break;
10470 	case SMB2_COMP_ALG_LZ77HUFF:
10471 		uncomp_tvb = tvb_uncompress_lz77huff(tvb, offset + scti->comp_offset, in_size);
10472 		break;
10473 	case SMB2_COMP_ALG_LZNT1:
10474 		uncomp_tvb = tvb_uncompress_lznt1(tvb, offset + scti->comp_offset, in_size);
10475 		break;
10476 	default:
10477 		col_append_str(pinfo->cinfo, COL_INFO, "Comp. SMB3 (unknown)");
10478 		uncomp_tvb = NULL;
10479 		goto out;
10480 	}
10481 
10482 	if (!uncomp_tvb || tvb_reported_length(uncomp_tvb) != scti->orig_size) {
10483 		/* decompression error */
10484 		col_append_str(pinfo->cinfo, COL_INFO, "Comp. SMB3 (invalid)");
10485 		goto out;
10486 	}
10487 
10488 	/* write decompressed segment at the end of partial packet */
10489 	append_uncompress_data(uncomp_data, uncomp_tvb, 0, scti->orig_size);
10490 
10491  decompression_ok:
10492 	col_append_str(pinfo->cinfo, COL_INFO, "Decomp. SMB3");
10493 	*plain_tvb = tvb_new_child_real_data(tvb,
10494 					     (guint8 *)wmem_array_get_raw(uncomp_data),
10495 					     wmem_array_get_count(uncomp_data),
10496 					     wmem_array_get_count(uncomp_data));
10497 	add_new_data_source(pinfo, *plain_tvb, "Decomp. SMB3");
10498 
10499  out:
10500 	if (uncomp_tvb)
10501 		tvb_free(uncomp_tvb);
10502 	return offset;
10503 }
10504 
10505 static int
dissect_smb2_transform_header(packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,int offset,smb2_transform_info_t * sti,tvbuff_t ** enc_tvb,tvbuff_t ** plain_tvb)10506 dissect_smb2_transform_header(packet_info *pinfo, proto_tree *tree,
10507 			      tvbuff_t *tvb, int offset,
10508 			      smb2_transform_info_t *sti,
10509 			      tvbuff_t **enc_tvb, tvbuff_t **plain_tvb)
10510 {
10511 	proto_item        *sesid_item     = NULL;
10512 	proto_tree        *sesid_tree     = NULL;
10513 	int                sesid_offset;
10514 	guint8            *plain_data     = NULL;
10515 	int                offset_aad;
10516 
10517 	*enc_tvb = NULL;
10518 	*plain_tvb = NULL;
10519 
10520 	/* signature */
10521 	proto_tree_add_item(tree, hf_smb2_transform_signature, tvb, offset, 16, ENC_NA);
10522 	offset += 16;
10523 
10524 	offset_aad = offset;
10525 
10526 	/* nonce */
10527 	proto_tree_add_item(tree, hf_smb2_transform_nonce, tvb, offset, 16, ENC_NA);
10528 	tvb_memcpy(tvb, sti->nonce, offset, 16);
10529 	offset += 16;
10530 
10531 	/* size */
10532 	proto_tree_add_item(tree, hf_smb2_transform_msg_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10533 	sti->size = tvb_get_letohl(tvb, offset);
10534 	offset += 4;
10535 
10536 	/* reserved */
10537 	proto_tree_add_item(tree, hf_smb2_transform_reserved, tvb, offset, 2, ENC_NA);
10538 	offset += 2;
10539 
10540 	/* flags */
10541 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_transform_flags,
10542 			       ett_smb2_transform_flags,
10543 			       smb2_transform_flags, ENC_LITTLE_ENDIAN);
10544 	sti->flags = tvb_get_letohs(tvb, offset);
10545 	offset += 2;
10546 
10547 	/* session ID */
10548 	sesid_offset = offset;
10549 	sti->sesid = tvb_get_letoh64(tvb, offset);
10550 	sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10551 	sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
10552 	offset += 8;
10553 
10554 	/* now we need to first lookup the uid session */
10555 	sti->session = smb2_get_session(sti->conv, sti->sesid, NULL, NULL);
10556 	smb2_add_session_info(sesid_tree, sesid_item, tvb, sesid_offset, sti->session);
10557 
10558 #if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
10559 	if (sti->flags & SMB2_TRANSFORM_FLAGS_ENCRYPTED) {
10560 		plain_data = decrypt_smb_payload(pinfo, tvb, offset, offset_aad, sti);
10561 	}
10562 #else
10563 	(void) offset_aad;
10564 #endif
10565 	*enc_tvb = tvb_new_subset_length(tvb, offset, sti->size);
10566 
10567 	if (plain_data != NULL) {
10568 		*plain_tvb = tvb_new_child_real_data(*enc_tvb, plain_data, sti->size, sti->size);
10569 		add_new_data_source(pinfo, *plain_tvb, "Decrypted SMB3");
10570 	}
10571 
10572 	offset += sti->size;
10573 	return offset;
10574 }
10575 
10576 static const char *
get_special_packet_title(guint16 cmd,guint32 flags,guint64 msg_id,tvbuff_t * tvb,int offset)10577 get_special_packet_title(guint16 cmd, guint32 flags, guint64 msg_id, tvbuff_t *tvb, int offset)
10578 {
10579 	/*  for some types of packets we don't have request/response packets but something else
10580 	 *  to show more correct names while displaying them we use this logic to override standard naming convention
10581 	 */
10582 
10583 	guint16 buffer_code;
10584 	/* detect oplock/lease break packets */
10585 	if (cmd != SMB2_COM_BREAK) {
10586 		return NULL;
10587 	}
10588 
10589 	buffer_code = tvb_get_letohs(tvb, offset);
10590 	if (flags & SMB2_FLAGS_RESPONSE) {
10591 		switch (buffer_code) {
10592 		case OPLOCK_BREAK_OPLOCK_STRUCTURE_SIZE:
10593 			/* note - Notification and Response packets for Oplock Break are equivalent,
10594 			 * we can distinguish them only via msg_id value */
10595 			if (msg_id == 0xFFFFFFFFFFFFFFFF)	/* see [MS-SMB2] 3.3.4.6 Object Store Indicates an Oplock Break */
10596 				return "Oplock Break Notification";
10597 			else
10598 				return "Oplock Break Response";
10599 		case OPLOCK_BREAK_LEASE_NOTIFICATION_STRUCTURE_SIZE:
10600 			return "Lease Break Notification";
10601 		case OPLOCK_BREAK_LEASE_RESPONSE_STRUCTURE_SIZE:
10602 			return "Lease Break Response";
10603 		}
10604 	} else {
10605 		switch (buffer_code) {
10606 		case OPLOCK_BREAK_OPLOCK_STRUCTURE_SIZE:
10607 			return "Oplock Break Acknowledgment";
10608 		case OPLOCK_BREAK_LEASE_ACKNOWLEDGMENT_STRUCTURE_SIZE:
10609 			return "Lease Break Acknowledgment";
10610 		}
10611 	}
10612 	/* return back to standard notation if we can't detect packet type of break packet */
10613 	return NULL;
10614 }
10615 
10616 static int
dissect_smb2_command(packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,int offset,smb2_info_t * si)10617 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
10618 {
10619 	int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
10620 	proto_item *cmd_item;
10621 	proto_tree *cmd_tree;
10622 	int         old_offset = offset;
10623 	const char *packet_title = get_special_packet_title(si->opcode, si->flags, si->msg_id, tvb, offset);
10624 
10625 	if (packet_title) {
10626 		cmd_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
10627 				ett_smb2_command, &cmd_item, "%s (0x%02x)",
10628 				packet_title,
10629 				si->opcode);
10630 	} else {
10631 		cmd_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
10632 				ett_smb2_command, &cmd_item, "%s %s (0x%02x)",
10633 				decode_smb2_name(si->opcode),
10634 				(si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
10635 				si->opcode);
10636 	}
10637 
10638 	cmd_dissector = (si->flags & SMB2_FLAGS_RESPONSE)?
10639 		smb2_dissector[si->opcode&0xff].response:
10640 		smb2_dissector[si->opcode&0xff].request;
10641 	if (cmd_dissector) {
10642 		offset = (*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
10643 	} else {
10644 		proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, ENC_NA);
10645 		offset = tvb_captured_length(tvb);
10646 	}
10647 
10648 	proto_item_set_len(cmd_item, offset-old_offset);
10649 
10650 	return offset;
10651 }
10652 
10653 static int
dissect_smb2_tid_sesid(packet_info * pinfo _U_,proto_tree * tree,tvbuff_t * tvb,int offset,smb2_info_t * si)10654 dissect_smb2_tid_sesid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
10655 {
10656 	proto_item        *tid_item   = NULL;
10657 	proto_tree        *tid_tree   = NULL;
10658 	smb2_tid_info_t    tid_key;
10659 	int                tid_offset = 0;
10660 	proto_item        *sesid_item = NULL;
10661 	proto_tree        *sesid_tree = NULL;
10662 	smb2_sesid_info_t  sesid_key;
10663 	int                sesid_offset;
10664 	proto_item        *item;
10665 
10666 
10667 	if (si->flags&SMB2_FLAGS_ASYNC_CMD) {
10668 		proto_tree_add_item(tree, hf_smb2_aid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10669 		offset += 8;
10670 	} else {
10671 		/* Process ID */
10672 		proto_tree_add_item(tree, hf_smb2_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10673 		offset += 4;
10674 
10675 		/* Tree ID */
10676 		tid_offset = offset;
10677 		si->tid = tvb_get_letohl(tvb, offset);
10678 		tid_item = proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10679 		tid_tree = proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
10680 		offset += 4;
10681 	}
10682 
10683 	/* Session ID */
10684 	sesid_offset = offset;
10685 	si->sesid = tvb_get_letoh64(tvb, offset);
10686 	sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10687 	sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
10688 	offset += 8;
10689 
10690 	/* now we need to first lookup the uid session */
10691 	sesid_key.sesid = si->sesid;
10692 	si->session = (smb2_sesid_info_t *)wmem_map_lookup(smb2_sessions, &sesid_key);
10693 	if (!si->session) {
10694 		si->session = smb2_get_session(si->conv, si->sesid, pinfo, si);
10695 		return offset;
10696 	}
10697 
10698 	smb2_add_session_info(sesid_tree, sesid_item, tvb, sesid_offset, si->session);
10699 
10700 	if (!(si->flags&SMB2_FLAGS_ASYNC_CMD)) {
10701 		/* see if we can find the name for this tid */
10702 		tid_key.tid = si->tid;
10703 		si->tree = (smb2_tid_info_t *)wmem_map_lookup(si->session->tids, &tid_key);
10704 		if (!si->tree) return offset;
10705 
10706 		item = proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
10707 		proto_item_set_generated(item);
10708 		proto_item_append_text(tid_item, "  %s", si->tree->name);
10709 
10710 		item = proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
10711 		proto_item_set_generated(item);
10712 
10713 		item = proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
10714 		proto_item_set_generated(item);
10715 	}
10716 
10717 	return offset;
10718 }
10719 #if GCRYPT_VERSION_NUMBER >= 0x010600
10720 static void
dissect_smb2_signature(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * tree,smb2_info_t * si)10721 dissect_smb2_signature(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
10722 {
10723 	proto_item   *item = NULL;
10724 	proto_tree   *stree = NULL;
10725 	gcry_error_t err;
10726 	gcry_mac_hd_t md;
10727 	guint8 mac[NTLMSSP_KEY_LEN];
10728 	size_t len = NTLMSSP_KEY_LEN;
10729 	int i, remaining;
10730 
10731 	item = proto_tree_add_item(tree, hf_smb2_signature, tvb, offset, 16, ENC_NA);
10732 
10733 	if (!si || !si->session ||!si->conv)
10734 		return;
10735 
10736 	if (!smb2_verify_signatures || !(si->flags & SMB2_FLAGS_SIGNATURE))
10737 		return;
10738 
10739 	if (memcmp(si->session->signing_key, zeros, NTLMSSP_KEY_LEN) == 0) {
10740 		return;
10741 	}
10742 
10743 	if (tvb_reported_length(tvb) > tvb_captured_length(tvb))
10744 		return;
10745 
10746 	remaining = tvb_reported_length_remaining(tvb, offset + NTLMSSP_KEY_LEN);
10747 
10748 	if (si->conv->dialect < SMB2_DIALECT_300) {
10749 		err = gcry_mac_open(&md, GCRY_MAC_HMAC_SHA256, 0, NULL);
10750 		if (err)
10751 			return;
10752 	} else {
10753 		err = gcry_mac_open(&md, GCRY_MAC_CMAC_AES, 0, NULL);
10754 		if (err)
10755 			return;
10756 
10757 	}
10758 
10759 	gcry_mac_setkey(md, si->session->signing_key, len);
10760 	gcry_mac_write(md, tvb_get_ptr(tvb, 0, 48), 48);
10761 	gcry_mac_write(md, zeros, NTLMSSP_KEY_LEN);
10762 	gcry_mac_write(md, tvb_get_ptr(tvb, offset + NTLMSSP_KEY_LEN, remaining), remaining);
10763 	gcry_mac_read(md, &mac[0], &len);
10764 	gcry_mac_close(md);
10765 
10766 	stree = proto_item_add_subtree(item, ett_smb2_signature);
10767 
10768 	if (memcmp(&mac[0], tvb_get_ptr(tvb, offset, NTLMSSP_KEY_LEN), NTLMSSP_KEY_LEN) == 0) {
10769 		proto_tree_add_item(stree, hf_smb2_good_signature, tvb, offset, 16, ENC_NA);
10770 		return; /* signature matched */
10771 	}
10772 
10773 	item = proto_tree_add_item(stree, hf_smb2_bad_signature, tvb, offset, 16, ENC_NA);
10774 	proto_item_append_text(item, " ");
10775 	for (i = 0; i < NTLMSSP_KEY_LEN; i++)
10776 		proto_item_append_text(item, "%02x", mac[i]);
10777 	proto_item_set_generated(item);
10778 	expert_add_info(pinfo, item, &ei_smb2_invalid_signature);
10779 
10780 	return;
10781 }
10782 #endif
10783 
10784 static int
dissect_smb2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,gboolean first_in_chain)10785 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
10786 {
10787 	int msg_type;
10788 	proto_item *item		  = NULL;
10789 	proto_tree *tree		  = NULL;
10790 	proto_item *header_item		  = NULL;
10791 	proto_tree *header_tree		  = NULL;
10792 	int         offset		  = 0;
10793 	int         chain_offset	  = 0;
10794 	const char *label		  = smb_header_label;
10795 	conversation_t    *conversation;
10796 	smb2_saved_info_t *ssi          = NULL, ssi_key;
10797 	smb2_info_t       *si;
10798 	smb2_transform_info_t *sti;
10799 	smb2_comp_transform_info_t *scti;
10800 	char		    *fid_name;
10801 	guint32		     open_frame,close_frame;
10802 	smb2_eo_file_info_t *eo_file_info;
10803 	e_ctx_hnd	    *policy_hnd_hashtablekey;
10804 	const char	    *packet_title;
10805 
10806 	sti = wmem_new(pinfo->pool, smb2_transform_info_t);
10807 	scti = wmem_new(pinfo->pool, smb2_comp_transform_info_t);
10808 	si  = wmem_new0(pinfo->pool, smb2_info_t);
10809 	si->top_tree = parent_tree;
10810 
10811 	msg_type = tvb_get_guint8(tvb, 0);
10812 
10813 	switch (msg_type) {
10814 	case SMB2_COMP_HEADER:
10815 		label = smb_comp_transform_header_label;
10816 		break;
10817 	case SMB2_ENCR_HEADER:
10818 		label = smb_transform_header_label;
10819 		break;
10820 	case SMB2_NORM_HEADER:
10821 		label = smb_header_label;
10822 		break;
10823 	default:
10824 		label = smb_bad_header_label;
10825 		break;
10826 	}
10827 
10828 	/* find which conversation we are part of and get the data for that
10829 	 * conversation
10830 	 */
10831 	conversation = find_or_create_conversation(pinfo);
10832 	si->conv = (smb2_conv_info_t *)conversation_get_proto_data(conversation, proto_smb2);
10833 	if (!si->conv) {
10834 		/* no smb2_into_t structure for this conversation yet,
10835 		 * create it.
10836 		 */
10837 		si->conv = wmem_new0(wmem_file_scope(), smb2_conv_info_t);
10838 		/* qqq this leaks memory for now since we never free
10839 		   the hashtables */
10840 		si->conv->matched = g_hash_table_new(smb2_saved_info_hash_matched,
10841 			smb2_saved_info_equal_matched);
10842 		si->conv->unmatched = g_hash_table_new(smb2_saved_info_hash_unmatched,
10843 			smb2_saved_info_equal_unmatched);
10844 		si->conv->preauth_hash_current = si->conv->preauth_hash_con;
10845 
10846 		/* Bit of a hack to avoid leaking the hash tables - register a
10847 		 * callback to free them. Ideally wmem would implement a simple
10848 		 * hash table so we wouldn't have to do this. */
10849 		wmem_register_callback(wmem_file_scope(), smb2_conv_destroy,
10850 				si->conv);
10851 
10852 		conversation_add_proto_data(conversation, proto_smb2, si->conv);
10853 	}
10854 
10855 	sti->conv = si->conv;
10856 	scti->conv = si->conv;
10857 
10858 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
10859 	if (first_in_chain) {
10860 		/* first packet */
10861 		col_clear(pinfo->cinfo, COL_INFO);
10862 	} else {
10863 		col_append_str(pinfo->cinfo, COL_INFO, ";");
10864 	}
10865 
10866 	item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset, -1, ENC_NA);
10867 	tree = proto_item_add_subtree(item, ett_smb2);
10868 
10869 	header_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_header, &header_item, label);
10870 
10871 	/* Decode the header */
10872 
10873 	if (msg_type == SMB2_NORM_HEADER) {
10874 		/* SMB2 marker */
10875 		proto_tree_add_item(header_tree, hf_smb2_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
10876 		offset += 4;
10877 
10878 		/* we need the flags before we know how to parse the credits field */
10879 		si->flags = tvb_get_letohl(tvb, offset+12);
10880 
10881 		/* header length */
10882 		proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10883 		offset += 2;
10884 
10885 		/* credit charge (previously "epoch" (unused) which has been deprecated as of "SMB 2.1") */
10886 		proto_tree_add_item(header_tree, hf_smb2_credit_charge, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10887 		offset += 2;
10888 
10889 		/* Status Code */
10890 		if (si->flags & SMB2_FLAGS_RESPONSE) {
10891 			si->status = tvb_get_letohl(tvb, offset);
10892 			proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10893 			offset += 4;
10894 		} else {
10895 			si->status = 0;
10896 			proto_tree_add_item(header_tree, hf_smb2_channel_sequence, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10897 			offset += 2;
10898 			proto_tree_add_item(header_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
10899 			offset += 2;
10900 		}
10901 
10902 		/* opcode */
10903 		si->opcode = tvb_get_letohs(tvb, offset);
10904 		proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10905 		offset += 2;
10906 
10907 		/* credits */
10908 		if (si->flags & SMB2_FLAGS_RESPONSE) {
10909 			proto_tree_add_item(header_tree, hf_smb2_credits_granted, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10910 		} else {
10911 			proto_tree_add_item(header_tree, hf_smb2_credits_requested, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10912 		}
10913 		offset += 2;
10914 
10915 		/* flags */
10916 		if (header_tree) {
10917 			static int * const  flags[] = {
10918 				&hf_smb2_flags_response,
10919 				&hf_smb2_flags_async_cmd,
10920 				&hf_smb2_flags_chained,
10921 				&hf_smb2_flags_signature,
10922 				&hf_smb2_flags_priority_mask,
10923 				&hf_smb2_flags_dfs_op,
10924 				&hf_smb2_flags_replay_operation,
10925 				NULL
10926 			};
10927 
10928 			proto_tree_add_bitmask(header_tree, tvb, offset, hf_smb2_flags,
10929 									ett_smb2_flags, flags, ENC_LITTLE_ENDIAN);
10930 		}
10931 
10932 		offset += 4;
10933 
10934 		/* Next Command */
10935 		chain_offset = tvb_get_letohl(tvb, offset);
10936 		proto_tree_add_item(header_tree, hf_smb2_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10937 		offset += 4;
10938 
10939 		/* Message ID */
10940 		si->msg_id = tvb_get_letoh64(tvb, offset);
10941 		ssi_key.msg_id = si->msg_id;
10942 		proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10943 		offset += 8;
10944 
10945 		/* Tree ID and Session ID */
10946 		offset = dissect_smb2_tid_sesid(pinfo, header_tree, tvb, offset, si);
10947 
10948 		/* Signature */
10949 #if GCRYPT_VERSION_NUMBER >= 0x010600
10950 		dissect_smb2_signature(pinfo, tvb, offset, header_tree, si);
10951 #else
10952 		proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, ENC_NA);
10953 #endif
10954 		offset += 16;
10955 		proto_item_set_len(header_item, offset);
10956 
10957 		/* Check if this is a special packet type and it has non-regular title */
10958 		packet_title = get_special_packet_title(si->opcode, si->flags, si->msg_id, tvb, offset);
10959 		if (packet_title) {
10960 			col_append_fstr(pinfo->cinfo, COL_INFO, "%s", packet_title);
10961 		} else {
10962 			/* Regular packets have standard title */
10963 			col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
10964 					decode_smb2_name(si->opcode),
10965 					(si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
10966 		}
10967 		if (si->status) {
10968 			col_append_fstr(
10969 					pinfo->cinfo, COL_INFO, ", Error: %s",
10970 					val_to_str_ext(si->status, &NT_errors_ext,
10971 						       "Unknown (0x%08X)"));
10972 		}
10973 
10974 
10975 		if (!pinfo->fd->visited) {
10976 			/* see if we can find this msg_id in the unmatched table */
10977 			ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
10978 
10979 			if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
10980 				/* This is a request */
10981 				if (ssi) {
10982 					/* this is a request and we already found
10983 					* an older ssi so just delete the previous
10984 					* one
10985 					*/
10986 					g_hash_table_remove(si->conv->unmatched, ssi);
10987 					ssi = NULL;
10988 				}
10989 
10990 				if (!ssi) {
10991 					/* no we couldn't find it, so just add it then
10992 					* if was a request we are decoding
10993 					*/
10994 					ssi                  = wmem_new0(wmem_file_scope(), smb2_saved_info_t);
10995 					ssi->msg_id          = ssi_key.msg_id;
10996 					ssi->frame_req       = pinfo->num;
10997 					ssi->req_time        = pinfo->abs_ts;
10998 					ssi->extra_info_type = SMB2_EI_NONE;
10999 					g_hash_table_insert(si->conv->unmatched, ssi, ssi);
11000 				}
11001 			} else {
11002 				/* This is a response */
11003 				if (!((si->flags & SMB2_FLAGS_ASYNC_CMD)
11004 					&& si->status == NT_STATUS_PENDING)
11005 					&& ssi) {
11006 					/* just  set the response frame and move it to the matched table */
11007 					ssi->frame_res = pinfo->num;
11008 					g_hash_table_remove(si->conv->unmatched, ssi);
11009 					g_hash_table_insert(si->conv->matched, ssi, ssi);
11010 				}
11011 			}
11012 		} else {
11013 			/* see if we can find this msg_id in the matched table */
11014 			ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->matched, &ssi_key);
11015 			/* if we couldn't find it in the matched table, it might still
11016 			* be in the unmatched table
11017 			*/
11018 			if (!ssi) {
11019 				ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
11020 			}
11021 		}
11022 
11023 		if (ssi) {
11024 			if (dcerpc_fetch_polhnd_data(&ssi->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
11025 				/* If needed, create the file entry and save the policy hnd */
11026 				if (!si->eo_file_info) {
11027 					if (si->conv) {
11028 						eo_file_info = (smb2_eo_file_info_t *)wmem_map_lookup(si->session->files,&ssi->policy_hnd);
11029 						if (!eo_file_info) { /* XXX This should never happen */
11030 							/* assert(1==0); */
11031 							eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
11032 							policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
11033 							memcpy(policy_hnd_hashtablekey, &ssi->policy_hnd, sizeof(e_ctx_hnd));
11034 							eo_file_info->end_of_file=0;
11035 							wmem_map_insert(si->session->files,policy_hnd_hashtablekey,eo_file_info);
11036 						}
11037 						si->eo_file_info=eo_file_info;
11038 					}
11039 				}
11040 			}
11041 
11042 			if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
11043 				if (ssi->frame_res) {
11044 					proto_item *tmp_item;
11045 					tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
11046 					proto_item_set_generated(tmp_item);
11047 				}
11048 			} else {
11049 				if (ssi->frame_req) {
11050 					proto_item *tmp_item;
11051 					nstime_t    t, deltat;
11052 
11053 					tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
11054 					proto_item_set_generated(tmp_item);
11055 					t = pinfo->abs_ts;
11056 					nstime_delta(&deltat, &t, &ssi->req_time);
11057 					tmp_item = proto_tree_add_time(header_tree, hf_smb2_time, tvb,
11058 					0, 0, &deltat);
11059 					proto_item_set_generated(tmp_item);
11060 				}
11061 			}
11062 			if (si->file != NULL) {
11063 				ssi->file = si->file;
11064 			} else {
11065 				si->file = ssi->file;
11066 			}
11067 		}
11068 		/* if we don't have ssi yet we must fake it */
11069 		/*qqq*/
11070 		si->saved = ssi;
11071 
11072 		tap_queue_packet(smb2_tap, pinfo, si);
11073 
11074 		/* Decode the payload */
11075 		offset                = dissect_smb2_command(pinfo, tree, tvb, offset, si);
11076 	} else if (msg_type == SMB2_ENCR_HEADER) {
11077 		proto_tree *enc_tree;
11078 		tvbuff_t   *enc_tvb   = NULL;
11079 		tvbuff_t   *plain_tvb = NULL;
11080 
11081 		/* SMB2_TRANSFORM marker */
11082 		proto_tree_add_item(header_tree, hf_smb2_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
11083 		offset += 4;
11084 
11085 		offset = dissect_smb2_transform_header(pinfo, header_tree, tvb, offset, sti,
11086 						       &enc_tvb, &plain_tvb);
11087 
11088 		enc_tree = proto_tree_add_subtree(tree, enc_tvb, 0, sti->size, ett_smb2_encrypted, NULL, "Encrypted SMB3 data");
11089 		if (plain_tvb != NULL) {
11090 			col_append_str(pinfo->cinfo, COL_INFO, "Decrypted SMB3");
11091 			dissect_smb2(plain_tvb, pinfo, enc_tree, FALSE);
11092 		} else {
11093 			col_append_str(pinfo->cinfo, COL_INFO, "Encrypted SMB3");
11094 			proto_tree_add_item(enc_tree, hf_smb2_transform_encrypted_data,
11095 					    enc_tvb, 0, sti->size, ENC_NA);
11096 		}
11097 
11098 		if (tvb_reported_length_remaining(tvb, offset) > 0) {
11099 			chain_offset = offset;
11100 		}
11101 	} else if (msg_type == SMB2_COMP_HEADER) {
11102 		proto_tree *comp_tree;
11103 		proto_item *decomp_item;
11104 		tvbuff_t   *plain_tvb = NULL;
11105 		tvbuff_t   *comp_tvb = NULL;
11106 
11107 		offset = dissect_smb2_comp_transform_header(pinfo, header_tree, tvb, offset,
11108 							    scti, &comp_tvb, &plain_tvb);
11109 
11110 		if (plain_tvb) {
11111 			comp_tree = proto_tree_add_subtree(header_tree, plain_tvb, 0,
11112 							   tvb_reported_length_remaining(plain_tvb, 0),
11113 							   ett_smb2_decompressed, &decomp_item,
11114 							   "Decompressed SMB3 data");
11115 			proto_item_set_generated(decomp_item);
11116 			dissect_smb2(plain_tvb, pinfo, comp_tree, FALSE);
11117 		} else {
11118 			comp_tree = proto_tree_add_subtree(header_tree, tvb, offset,
11119 							   tvb_reported_length_remaining(tvb, offset),
11120 							   ett_smb2_compressed, NULL,
11121 							   "Compressed SMB3 data");
11122 			/* show the compressed payload only if we cant uncompress it */
11123 			proto_tree_add_item(comp_tree, hf_smb2_comp_transform_data,
11124 					    tvb, offset,
11125 					    tvb_reported_length_remaining(tvb, offset),
11126 					    ENC_NA);
11127 		}
11128 
11129 		offset += tvb_reported_length_remaining(tvb, offset);
11130 	} else {
11131 		col_append_str(pinfo->cinfo, COL_INFO, "Invalid header");
11132 
11133 		/* bad packet after decompressing/decrypting */
11134 		offset += tvb_reported_length_remaining(tvb, offset);
11135 	}
11136 
11137 	if (chain_offset > 0) {
11138 		tvbuff_t *next_tvb;
11139 
11140 		proto_item_set_len(item, chain_offset);
11141 
11142 		next_tvb = tvb_new_subset_remaining(tvb, chain_offset);
11143 		offset   = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
11144 	}
11145 
11146 	return offset;
11147 }
11148 
11149 static gboolean
dissect_smb2_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)11150 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
11151 {
11152 	guint8 b;
11153 
11154 	/* must check that this really is a smb2 packet */
11155 	if (tvb_captured_length(tvb) < 4)
11156 		return FALSE;
11157 
11158 	b = tvb_get_guint8(tvb, 0);
11159 	if (((b != SMB2_COMP_HEADER) && (b != SMB2_ENCR_HEADER) && (b != SMB2_NORM_HEADER))
11160 	    || (tvb_get_guint8(tvb, 1) != 'S')
11161 	    || (tvb_get_guint8(tvb, 2) != 'M')
11162 	    || (tvb_get_guint8(tvb, 3) != 'B') ) {
11163 		return FALSE;
11164 	}
11165 
11166 	dissect_smb2(tvb, pinfo, parent_tree, TRUE);
11167 
11168 	return TRUE;
11169 }
11170 
11171 void
proto_register_smb2(void)11172 proto_register_smb2(void)
11173 {
11174 	module_t *smb2_module;
11175 	static hf_register_info hf[] = {
11176 		{ &hf_smb2_cmd,
11177 			{ "Command", "smb2.cmd", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
11178 			&smb2_cmd_vals_ext, 0, "SMB2 Command Opcode", HFILL }
11179 		},
11180 
11181 		{ &hf_smb2_response_to,
11182 			{ "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
11183 			FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0, "This packet is a response to the packet in this frame", HFILL }
11184 		},
11185 
11186 		{ &hf_smb2_response_in,
11187 			{ "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
11188 			FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0, "The response to this packet is in this packet", HFILL }
11189 		},
11190 
11191 		{ &hf_smb2_time,
11192 			{ "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
11193 			NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }
11194 		},
11195 
11196 		{ &hf_smb2_preauth_hash,
11197 			{ "Preauth Hash", "smb2.preauth_hash", FT_BYTES, BASE_NONE,
11198 			NULL, 0, "SMB3.1.1 pre-authentication SHA512 hash after hashing the packet", HFILL }
11199 		},
11200 
11201 		{ &hf_smb2_header_len,
11202 			{ "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
11203 			NULL, 0, "SMB2 Size of Header", HFILL }
11204 		},
11205 
11206 		{ &hf_smb2_nt_status,
11207 			{ "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
11208 			&NT_errors_ext, 0, "NT Status code", HFILL }
11209 		},
11210 
11211 		{ &hf_smb2_msg_id,
11212 			{ "Message ID", "smb2.msg_id", FT_UINT64, BASE_DEC|BASE_VAL64_STRING|BASE_SPECIAL_VALS,
11213 			VALS64(unique_unsolicited_response), 0, NULL, HFILL }
11214 		},
11215 
11216 		{ &hf_smb2_tid,
11217 			{ "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
11218 			NULL, 0, NULL, HFILL }
11219 		},
11220 
11221 		{ &hf_smb2_aid,
11222 			{ "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
11223 			NULL, 0, NULL, HFILL }
11224 		},
11225 
11226 		{ &hf_smb2_sesid,
11227 			{ "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
11228 			NULL, 0, NULL, HFILL }
11229 		},
11230 
11231 		{ &hf_smb2_previous_sesid,
11232 			{ "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
11233 			NULL, 0, NULL, HFILL }
11234 		},
11235 
11236 		{ &hf_smb2_chain_offset,
11237 			{ "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
11238 			NULL, 0, NULL, HFILL }
11239 		},
11240 
11241 		{ &hf_smb2_end_of_file,
11242 			{ "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
11243 			NULL, 0, "SMB2 End Of File/File size", HFILL }
11244 		},
11245 
11246 		{ &hf_smb2_nlinks,
11247 			{ "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
11248 			NULL, 0, "Number of links to this object", HFILL }
11249 		},
11250 
11251 		{ &hf_smb2_file_id,
11252 			{ "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
11253 			NULL, 0, NULL, HFILL }
11254 		},
11255 
11256 		{ &hf_smb2_allocation_size,
11257 			{ "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
11258 			NULL, 0, NULL, HFILL }
11259 		},
11260 
11261 		{ &hf_smb2_max_response_size,
11262 			{ "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
11263 			NULL, 0, NULL, HFILL }
11264 		},
11265 
11266 		{ &hf_smb2_getinfo_input_size,
11267 			{ "Getinfo Input Size", "smb2.getinfo_input_size", FT_UINT32, BASE_DEC,
11268 			NULL, 0, NULL, HFILL }
11269 		},
11270 
11271 		{ &hf_smb2_getinfo_input_offset,
11272 			{ "Getinfo Input Offset", "smb2.getinfo_input_offset", FT_UINT16, BASE_HEX,
11273 			NULL, 0, NULL, HFILL }
11274 		},
11275 
11276 		{ &hf_smb2_getsetinfo_additional,
11277 			{ "Additional Info", "smb2.getsetinfo_additional", FT_UINT32, BASE_HEX,
11278 			NULL, 0, NULL, HFILL }
11279 		},
11280 
11281 		{ &hf_smb2_getsetinfo_additionals,
11282 			{ "Additional Info", "smb2.getsetinfo_additionals", FT_UINT32, BASE_HEX,
11283 			NULL, 0, NULL, HFILL }
11284 		},
11285 
11286 		{ &hf_smb2_getsetinfo_additional_owner,
11287 			{ "Owner", "smb2.getsetinfo_additional_secinfo.owner", FT_BOOLEAN, 32,
11288 			TFS(&tfs_additional_owner), OWNER_SECURITY_INFORMATION, "Is owner security information being queried?", HFILL }},
11289 
11290 		{ &hf_smb2_getsetinfo_additional_group,
11291 			{ "Group", "smb2.getsetinfo_additional_secinfo.group", FT_BOOLEAN, 32,
11292 			TFS(&tfs_additional_group), GROUP_SECURITY_INFORMATION, "Is group security information being queried?", HFILL }},
11293 
11294 		{ &hf_smb2_getsetinfo_additional_dacl,
11295 			{ "DACL", "smb2.getsetinfo_additional_secinfo.dacl", FT_BOOLEAN, 32,
11296 			TFS(&tfs_additional_dacl), DACL_SECURITY_INFORMATION, "Is DACL security information being queried?", HFILL }},
11297 
11298 		{ &hf_smb2_getsetinfo_additional_sacl,
11299 			{ "SACL", "smb2.getsetinfo_additional_secinfo.sacl", FT_BOOLEAN, 32,
11300 			TFS(&tfs_additional_sacl), SACL_SECURITY_INFORMATION, "Is SACL security information being queried?", HFILL }},
11301 
11302 		{ &hf_smb2_getsetinfo_additional_label,
11303 			{ "Integrity label", "smb2.getsetinfo_additional_secinfo.label", FT_BOOLEAN, 32,
11304 			TFS(&tfs_additional_label), LABEL_SECURITY_INFORMATION, "Is integrity label security information being queried?", HFILL }},
11305 
11306 		{ &hf_smb2_getsetinfo_additional_attribute,
11307 			{ "Resource attribute", "smb2.getsetinfo_additional_secinfo.attribute", FT_BOOLEAN, 32,
11308 			TFS(&tfs_additional_attribute), ATTRIBUTE_SECURITY_INFORMATION, "Is resource attribute security information being queried?", HFILL }},
11309 
11310 		{ &hf_smb2_getsetinfo_additional_scope,
11311 			{ "Central access policy", "smb2.getsetinfo_additional_secinfo.scope", FT_BOOLEAN, 32,
11312 			TFS(&tfs_additional_scope), SCOPE_SECURITY_INFORMATION, "Is central access policy security information being queried?", HFILL }},
11313 
11314 		{ &hf_smb2_getsetinfo_additional_backup,
11315 			{ "Backup operation", "smb2.getsetinfo_additional_secinfo.backup", FT_BOOLEAN, 32,
11316 			TFS(&tfs_additional_backup), BACKUP_SECURITY_INFORMATION, "Is backup operation security information being queried?", HFILL }},
11317 
11318 		{ &hf_smb2_getinfo_flags,
11319 			{ "Flags", "smb2.getinfo_flags", FT_UINT32, BASE_HEX,
11320 			NULL, 0, NULL, HFILL }
11321 		},
11322 
11323 		{ &hf_smb2_setinfo_size,
11324 			{ "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
11325 			NULL, 0, NULL, HFILL }
11326 		},
11327 
11328 		{ &hf_smb2_setinfo_offset,
11329 			{ "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
11330 			NULL, 0, NULL, HFILL }
11331 		},
11332 
11333 		{ &hf_smb2_setinfo_reserved,
11334 			{ "Reserved", "smb2.setinfo_reserved", FT_UINT16, BASE_DEC,
11335 			NULL, 0, NULL, HFILL }
11336 		},
11337 
11338 		{ &hf_smb2_max_ioctl_out_size,
11339 			{ "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
11340 			NULL, 0, NULL, HFILL }
11341 		},
11342 
11343 		{ &hf_smb2_max_ioctl_in_size,
11344 			{ "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
11345 			NULL, 0, NULL, HFILL }
11346 		},
11347 
11348 		{ &hf_smb2_required_buffer_size,
11349 			{ "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
11350 			NULL, 0, NULL, HFILL }
11351 		},
11352 
11353 		{ &hf_smb2_pid,
11354 			{ "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
11355 			NULL, 0, NULL, HFILL }
11356 		},
11357 
11358 
11359 		/* SMB2 header flags  */
11360 		{ &hf_smb2_flags,
11361 			{ "Flags", "smb2.flags", FT_UINT32, BASE_HEX,
11362 			NULL, 0, "SMB2 flags", HFILL }
11363 		},
11364 
11365 		{ &hf_smb2_flags_response,
11366 			{ "Response", "smb2.flags.response", FT_BOOLEAN, 32,
11367 			TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }
11368 		},
11369 
11370 		{ &hf_smb2_flags_async_cmd,
11371 			{ "Async command", "smb2.flags.async", FT_BOOLEAN, 32,
11372 			TFS(&tfs_flags_async_cmd), SMB2_FLAGS_ASYNC_CMD, NULL, HFILL }
11373 		},
11374 
11375 		{ &hf_smb2_flags_dfs_op,
11376 			{ "DFS operation", "smb2.flags.dfs", FT_BOOLEAN, 32,
11377 			TFS(&tfs_flags_dfs_op), SMB2_FLAGS_DFS_OP, NULL, HFILL }
11378 		},
11379 
11380 		{ &hf_smb2_flags_chained,
11381 			{ "Chained", "smb2.flags.chained", FT_BOOLEAN, 32,
11382 			TFS(&tfs_flags_chained), SMB2_FLAGS_CHAINED, "Whether the pdu continues a chain or not", HFILL }
11383 		},
11384 		{ &hf_smb2_flags_signature,
11385 			{ "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
11386 			TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }
11387 		},
11388 
11389 		{ &hf_smb2_flags_replay_operation,
11390 			{ "Replay operation", "smb2.flags.replay", FT_BOOLEAN, 32,
11391 			TFS(&tfs_flags_replay_operation), SMB2_FLAGS_REPLAY_OPERATION, "Whether this is a replay operation", HFILL }
11392 		},
11393 
11394 		{ &hf_smb2_flags_priority_mask,
11395 			{ "Priority", "smb2.flags.priority_mask", FT_BOOLEAN, 32,
11396 			TFS(&tfs_flags_priority_mask), SMB2_FLAGS_PRIORITY_MASK, "Priority Mask", HFILL }
11397 		},
11398 
11399 		{ &hf_smb2_tree,
11400 			{ "Tree", "smb2.tree", FT_STRING, STR_UNICODE,
11401 			NULL, 0, "Name of the Tree/Share", HFILL }
11402 		},
11403 
11404 		{ &hf_smb2_filename,
11405 			{ "Filename", "smb2.filename", FT_STRING, STR_UNICODE,
11406 			NULL, 0, NULL, HFILL }
11407 		},
11408 
11409 		{ &hf_smb2_filename_len,
11410 			{ "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
11411 			NULL, 0, NULL, HFILL }
11412 		},
11413 
11414 		{ &hf_smb2_replace_if,
11415 			{ "Replace If", "smb2.rename.replace_if", FT_BOOLEAN, 8,
11416 			TFS(&tfs_replace_if_exists), 0xFF, "Whether to replace if the target exists", HFILL }
11417 		},
11418 
11419 		{ &hf_smb2_data_offset,
11420 			{ "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
11421 			NULL, 0, "Offset to data", HFILL }
11422 		},
11423 
11424 		{ &hf_smb2_find_info_level,
11425 			{ "Info Level", "smb2.find.infolevel", FT_UINT32, BASE_DEC,
11426 			VALS(smb2_find_info_levels), 0, "Find_Info Infolevel", HFILL }
11427 		},
11428 		{ &hf_smb2_find_flags,
11429 			{ "Find Flags", "smb2.find.flags", FT_UINT8, BASE_HEX,
11430 			NULL, 0, NULL, HFILL }
11431 		},
11432 
11433 		{ &hf_smb2_find_pattern,
11434 			{ "Search Pattern", "smb2.find.pattern", FT_STRING, STR_UNICODE,
11435 			NULL, 0, "Find pattern", HFILL }
11436 		},
11437 
11438 		{ &hf_smb2_find_info_blob,
11439 			{ "Info", "smb2.find.info_blob", FT_BYTES, BASE_NONE,
11440 			NULL, 0, "Find Info", HFILL }
11441 		},
11442 
11443 		{ &hf_smb2_ea_size,
11444 			{ "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
11445 			NULL, 0, "Size of EA data", HFILL }
11446 		},
11447 
11448 		{ &hf_smb2_position_information,
11449 			{ "Position Information", "smb2.position_info", FT_UINT64, BASE_DEC,
11450 			NULL, 0, "Current file position", HFILL }
11451 		},
11452 
11453 		{ &hf_smb2_mode_information,
11454 			{ "Mode Information", "smb2.mode_info", FT_UINT32, BASE_HEX,
11455 			NULL, 0, "File mode information", HFILL }
11456 		},
11457 
11458 		{ &hf_smb2_mode_file_write_through,
11459 			{ "FILE_WRITE_THROUGH", "smb2.mode.file_write_through", FT_UINT32, BASE_HEX,
11460 			NULL, 0x02, NULL, HFILL }
11461 		},
11462 
11463 		{ &hf_smb2_mode_file_sequential_only,
11464 			{ "FILE_SEQUENTIAL_ONLY", "smb2.mode.file_sequential_only", FT_UINT32, BASE_HEX,
11465 			NULL, 0x04, NULL, HFILL }
11466 		},
11467 
11468 		{ &hf_smb2_mode_file_no_intermediate_buffering,
11469 			{ "FILE_NO_INTERMEDIATE_BUFFERING", "smb2.mode.file_no_intermediate_buffering", FT_UINT32, BASE_HEX,
11470 			NULL, 0x08, NULL, HFILL }
11471 		},
11472 
11473 		{ &hf_smb2_mode_file_synchronous_io_alert,
11474 			{ "FILE_SYNCHRONOUS_IO_ALERT", "smb2.mode.file_synchronous_io_alert", FT_UINT32, BASE_HEX,
11475 			NULL, 0x10, NULL, HFILL }
11476 		},
11477 
11478 		{ &hf_smb2_mode_file_synchronous_io_nonalert,
11479 			{ "FILE_SYNCHRONOUS_IO_NONALERT", "smb2.mode.file_synchronous_io_nonalert", FT_UINT32, BASE_HEX,
11480 			NULL, 0x20, NULL, HFILL }
11481 		},
11482 
11483 		{ &hf_smb2_mode_file_delete_on_close,
11484 			{ "FILE_DELETE_ON_CLOSE", "smb2.mode.file_delete_on_close", FT_UINT32, BASE_HEX,
11485 			NULL, 0x1000, NULL, HFILL }
11486 		},
11487 
11488 		{ &hf_smb2_alignment_information,
11489 			{ "Alignment Information", "smb2.alignment_info", FT_UINT32, BASE_HEX,
11490 			VALS(smb2_alignment_vals), 0, "File alignment", HFILL}
11491 		},
11492 
11493 		{ &hf_smb2_class,
11494 			{ "Class", "smb2.class", FT_UINT8, BASE_HEX,
11495 			VALS(smb2_class_vals), 0, "Info class", HFILL }
11496 		},
11497 
11498 		{ &hf_smb2_infolevel,
11499 			{ "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
11500 			NULL, 0, NULL, HFILL }
11501 		},
11502 
11503 		{ &hf_smb2_infolevel_file_info,
11504 			{ "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
11505 			&smb2_file_info_levels_ext, 0, "File_Info Infolevel", HFILL }
11506 		},
11507 
11508 		{ &hf_smb2_infolevel_fs_info,
11509 			{ "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
11510 			&smb2_fs_info_levels_ext, 0, "Fs_Info Infolevel", HFILL }
11511 		},
11512 
11513 		{ &hf_smb2_infolevel_sec_info,
11514 			{ "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
11515 			&smb2_sec_info_levels_ext, 0, "Sec_Info Infolevel", HFILL }
11516 		},
11517 
11518 		{ &hf_smb2_write_length,
11519 			{ "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
11520 			NULL, 0, "Amount of data to write", HFILL }
11521 		},
11522 
11523 		{ &hf_smb2_read_blob,
11524 			{ "Info", "smb2.read.blob", FT_BYTES, BASE_NONE,
11525 			NULL, 0, "Read Blob", HFILL }
11526 		},
11527 
11528 		{ &hf_smb2_read_length,
11529 			{ "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
11530 			NULL, 0, "Amount of data to read", HFILL }
11531 		},
11532 
11533 		{ &hf_smb2_read_remaining,
11534 			{ "Read Remaining", "smb2.read_remaining", FT_UINT32, BASE_DEC,
11535 			NULL, 0, NULL, HFILL }
11536 		},
11537 
11538 		{ &hf_smb2_read_padding,
11539 			{ "Padding", "smb2.read_padding", FT_UINT8, BASE_HEX,
11540 			NULL, 0, NULL, HFILL }
11541 		},
11542 
11543 		{ &hf_smb2_read_flags,
11544 			{ "Flags", "smb2.read_flags", FT_UINT8, BASE_HEX,
11545 			NULL, 0, NULL, HFILL }
11546 		},
11547 
11548 		{ &hf_smb2_read_flags_unbuffered,
11549 			{ "Unbuffered", "smb2.read_flags.unbuffered", FT_BOOLEAN, 8,
11550 			TFS(&tfs_read_unbuffered), SMB2_READFLAG_READ_UNBUFFERED, "If client requests unbuffered read", HFILL }
11551 		},
11552 
11553 		{ &hf_smb2_read_flags_compressed,
11554 			{ "Compressed", "smb2.read_flags.compressed", FT_BOOLEAN, 8,
11555 			TFS(&tfs_read_compressed), SMB2_READFLAG_READ_COMPRESSED, "If client requests compressed response", HFILL }
11556 		},
11557 
11558 		{ &hf_smb2_create_flags,
11559 			{ "Create Flags", "smb2.create_flags", FT_UINT64, BASE_HEX,
11560 			NULL, 0, NULL, HFILL }
11561 		},
11562 
11563 		{ &hf_smb2_file_offset,
11564 			{ "File Offset", "smb2.file_offset", FT_UINT64, BASE_DEC,
11565 			NULL, 0, NULL, HFILL }
11566 		},
11567 
11568 		{ &hf_smb2_fsctl_range_offset,
11569 			{ "File Offset", "smb2.fsctl.range_offset", FT_UINT64, BASE_DEC,
11570 			NULL, 0, NULL, HFILL }
11571 		},
11572 
11573 		{ &hf_smb2_fsctl_range_length,
11574 			{ "Length", "smb2.fsctl.range_length", FT_UINT64, BASE_DEC,
11575 			NULL, 0, NULL, HFILL }
11576 		},
11577 
11578 		{ &hf_smb2_qfr_length,
11579 			{ "Length", "smb2.qfr_length", FT_UINT64, BASE_DEC,
11580 			NULL, 0, NULL, HFILL }
11581 		},
11582 
11583 		{ &hf_smb2_qfr_usage,
11584 			{ "Desired Usage", "smb2.qfr_usage", FT_UINT32, BASE_HEX,
11585 			VALS(file_region_usage_vals), 0, NULL, HFILL }
11586 		},
11587 
11588 		{ &hf_smb2_qfr_flags,
11589 			{ "Flags", "smb2.qfr_flags", FT_UINT32, BASE_HEX,
11590 			NULL, 0, NULL, HFILL }
11591 		},
11592 
11593 		{ &hf_smb2_qfr_total_region_entry_count,
11594 			{ "Total Region Entry Count", "smb2.qfr_tot_region_entry_count", FT_UINT32, BASE_HEX,
11595 			NULL, 0, NULL, HFILL }
11596 		},
11597 
11598 		{ &hf_smb2_qfr_region_entry_count,
11599 			{ "Region Entry Count", "smb2.qfr_region_entry_count", FT_UINT32, BASE_HEX,
11600 			NULL, 0, NULL, HFILL }
11601 		},
11602 
11603 		{ &hf_smb2_security_blob,
11604 			{ "Security Blob", "smb2.security_blob", FT_BYTES, BASE_NONE,
11605 			NULL, 0, NULL, HFILL }
11606 		},
11607 
11608 		{ &hf_smb2_ioctl_out_data,
11609 			{ "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
11610 			NULL, 0, "Ioctl Out", HFILL }
11611 		},
11612 
11613 		{ &hf_smb2_ioctl_in_data,
11614 			{ "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
11615 			NULL, 0, "Ioctl In", HFILL }
11616 		},
11617 
11618 		{ &hf_smb2_server_guid,
11619 			{ "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
11620 			NULL, 0, NULL, HFILL }
11621 		},
11622 
11623 		{ &hf_smb2_client_guid,
11624 			{ "Client Guid", "smb2.client_guid", FT_GUID, BASE_NONE,
11625 			NULL, 0, NULL, HFILL }
11626 		},
11627 
11628 		{ &hf_smb2_object_id,
11629 			{ "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
11630 			NULL, 0, "ObjectID for this FID", HFILL }
11631 		},
11632 
11633 		{ &hf_smb2_birth_volume_id,
11634 			{ "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
11635 			NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }
11636 		},
11637 
11638 		{ &hf_smb2_birth_object_id,
11639 			{ "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
11640 			NULL, 0, "ObjectID for this FID when it was originally created", HFILL }
11641 		},
11642 
11643 		{ &hf_smb2_domain_id,
11644 			{ "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
11645 			NULL, 0, NULL, HFILL }
11646 		},
11647 
11648 		{ &hf_smb2_create_timestamp,
11649 			{ "Create", "smb2.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
11650 			NULL, 0, "Time when this object was created", HFILL }
11651 		},
11652 
11653 		{ &hf_smb2_fid,
11654 			{ "File Id", "smb2.fid", FT_GUID, BASE_NONE,
11655 			NULL, 0, "SMB2 File Id", HFILL }
11656 		},
11657 
11658 		{ &hf_smb2_write_data,
11659 			{ "Write Data", "smb2.write_data", FT_BYTES, BASE_NONE,
11660 			NULL, 0, "SMB2 Data to be written", HFILL }
11661 		},
11662 
11663 		{ &hf_smb2_write_flags,
11664 			{ "Write Flags", "smb2.write.flags", FT_UINT32, BASE_HEX,
11665 			NULL, 0, NULL, HFILL }
11666 		},
11667 
11668 		{ &hf_smb2_write_flags_write_through,
11669 			{ "Write through", "smb2.write.flags.write_through", FT_BOOLEAN, 32,
11670 			TFS(&tfs_write_through), SMB2_WRITE_FLAG_WRITE_THROUGH, "If the client requests WRITE_THROUGH", HFILL }
11671 		},
11672 
11673 		{ &hf_smb2_write_flags_write_unbuffered,
11674 			{ "Unbuffered", "smb2.write.flags.unbuffered", FT_BOOLEAN, 32,
11675 			TFS(&tfs_write_unbuffered), SMB2_WRITE_FLAG_WRITE_UNBUFFERED, "If client requests UNBUFFERED read", HFILL }
11676 		},
11677 
11678 		{ &hf_smb2_write_count,
11679 			{ "Write Count", "smb2.write.count", FT_UINT32, BASE_DEC,
11680 			NULL, 0, NULL, HFILL }
11681 		},
11682 
11683 		{ &hf_smb2_write_remaining,
11684 			{ "Write Remaining", "smb2.write.remaining", FT_UINT32, BASE_DEC,
11685 			NULL, 0, NULL, HFILL }
11686 		},
11687 
11688 		{ &hf_smb2_read_data,
11689 			{ "Read Data", "smb2.read_data", FT_BYTES, BASE_NONE,
11690 			NULL, 0, "SMB2 Data that is read", HFILL }
11691 		},
11692 
11693 		{ &hf_smb2_last_access_timestamp,
11694 			{ "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
11695 			NULL, 0, "Time when this object was last accessed", HFILL }
11696 		},
11697 
11698 		{ &hf_smb2_last_write_timestamp,
11699 			{ "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
11700 			NULL, 0, "Time when this object was last written to", HFILL }
11701 		},
11702 
11703 		{ &hf_smb2_last_change_timestamp,
11704 			{ "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
11705 			NULL, 0, "Time when this object was last changed", HFILL }
11706 		},
11707 
11708 		{ &hf_smb2_file_all_info,
11709 			{ "SMB2_FILE_ALL_INFO", "smb2.file_all_info", FT_NONE, BASE_NONE,
11710 			NULL, 0, NULL, HFILL }
11711 		},
11712 
11713 		{ &hf_smb2_file_allocation_info,
11714 			{ "SMB2_FILE_ALLOCATION_INFO", "smb2.file_allocation_info", FT_NONE, BASE_NONE,
11715 			NULL, 0, NULL, HFILL }
11716 		},
11717 
11718 		{ &hf_smb2_file_endoffile_info,
11719 			{ "SMB2_FILE_ENDOFFILE_INFO", "smb2.file_endoffile_info", FT_NONE, BASE_NONE,
11720 			NULL, 0, NULL, HFILL }
11721 		},
11722 
11723 		{ &hf_smb2_good_signature,
11724 			{ "Good signature", "smb2.good_signature", FT_NONE, BASE_NONE,
11725 			NULL, 0, NULL, HFILL }
11726 		},
11727 
11728 		{ &hf_smb2_bad_signature,
11729 			{ "Bad signature. Should be", "smb2.bad_signature", FT_NONE, BASE_NONE,
11730 			NULL, 0, NULL, HFILL }
11731 		},
11732 
11733 		{ &hf_smb2_file_alternate_name_info,
11734 			{ "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.file_alternate_name_info", FT_NONE, BASE_NONE,
11735 			NULL, 0, NULL, HFILL }
11736 		},
11737 
11738 		{ &hf_smb2_file_normalized_name_info,
11739 			{ "SMB2_FILE_NORMALIZED_NAME_INFO", "smb2.file_normalized_name_info", FT_NONE, BASE_NONE,
11740 			NULL, 0, NULL, HFILL }
11741 		},
11742 
11743 		{ &hf_smb2_file_stream_info,
11744 			{ "SMB2_FILE_STREAM_INFO", "smb2.file_stream_info", FT_NONE, BASE_NONE,
11745 			NULL, 0, NULL, HFILL }
11746 		},
11747 
11748 		{ &hf_smb2_file_pipe_info,
11749 			{ "SMB2_FILE_PIPE_INFO", "smb2.file_pipe_info", FT_NONE, BASE_NONE,
11750 			NULL, 0, NULL, HFILL }
11751 		},
11752 
11753 		{ &hf_smb2_file_compression_info,
11754 			{ "SMB2_FILE_COMPRESSION_INFO", "smb2.file_compression_info", FT_NONE, BASE_NONE,
11755 			NULL, 0, NULL, HFILL }
11756 		},
11757 
11758 		{ &hf_smb2_file_basic_info,
11759 			{ "SMB2_FILE_BASIC_INFO", "smb2.file_basic_info", FT_NONE, BASE_NONE,
11760 			NULL, 0, NULL, HFILL }
11761 		},
11762 
11763 		{ &hf_smb2_file_standard_info,
11764 			{ "SMB2_FILE_STANDARD_INFO", "smb2.file_standard_info", FT_NONE, BASE_NONE,
11765 			NULL, 0, NULL, HFILL }
11766 		},
11767 
11768 		{ &hf_smb2_file_internal_info,
11769 			{ "SMB2_FILE_INTERNAL_INFO", "smb2.file_internal_info", FT_NONE, BASE_NONE,
11770 			NULL, 0, NULL, HFILL }
11771 		},
11772 
11773 		{ &hf_smb2_file_mode_info,
11774 			{ "SMB2_FILE_MODE_INFO", "smb2.file_mode_info", FT_NONE, BASE_NONE,
11775 			NULL, 0, NULL, HFILL }
11776 		},
11777 
11778 		{ &hf_smb2_file_alignment_info,
11779 			{ "SMB2_FILE_ALIGNMENT_INFO", "smb2.file_alignment_info", FT_NONE, BASE_NONE,
11780 			NULL, 0, NULL, HFILL }
11781 		},
11782 
11783 		{ &hf_smb2_file_position_info,
11784 			{ "SMB2_FILE_POSITION_INFO", "smb2.file_position_info", FT_NONE, BASE_NONE,
11785 			NULL, 0, NULL, HFILL }
11786 		},
11787 
11788 		{ &hf_smb2_file_access_info,
11789 			{ "SMB2_FILE_ACCESS_INFO", "smb2.file_access_info", FT_NONE, BASE_NONE,
11790 			NULL, 0, NULL, HFILL }
11791 		},
11792 
11793 		{ &hf_smb2_file_ea_info,
11794 			{ "SMB2_FILE_EA_INFO", "smb2.file_ea_info", FT_NONE, BASE_NONE,
11795 			NULL, 0, NULL, HFILL }
11796 		},
11797 
11798 		{ &hf_smb2_file_network_open_info,
11799 			{ "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.file_network_open_info", FT_NONE, BASE_NONE,
11800 			NULL, 0, NULL, HFILL }
11801 		},
11802 
11803 		{ &hf_smb2_file_attribute_tag_info,
11804 			{ "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.file_attribute_tag_info", FT_NONE, BASE_NONE,
11805 			NULL, 0, NULL, HFILL }
11806 		},
11807 
11808 		{ &hf_smb2_file_disposition_info,
11809 			{ "SMB2_FILE_DISPOSITION_INFO", "smb2.file_disposition_info", FT_NONE, BASE_NONE,
11810 			NULL, 0, NULL, HFILL }
11811 		},
11812 
11813 		{ &hf_smb2_file_full_ea_info,
11814 			{ "SMB2_FILE_FULL_EA_INFO", "smb2.file_full_ea_info", FT_NONE, BASE_NONE,
11815 			NULL, 0, NULL, HFILL }
11816 		},
11817 
11818 		{ &hf_smb2_file_rename_info,
11819 			{ "SMB2_FILE_RENAME_INFO", "smb2.file_rename_info", FT_NONE, BASE_NONE,
11820 			NULL, 0, NULL, HFILL }
11821 		},
11822 
11823 		{ &hf_smb2_fs_info_01,
11824 			{ "FileFsVolumeInformation", "smb2.fs_volume_info", FT_NONE, BASE_NONE,
11825 			NULL, 0, NULL, HFILL }
11826 		},
11827 
11828 		{ &hf_smb2_fs_info_03,
11829 			{ "FileFsSizeInformation", "smb2.fs_size_info", FT_NONE, BASE_NONE,
11830 			NULL, 0, NULL, HFILL }
11831 		},
11832 
11833 		{ &hf_smb2_fs_info_04,
11834 			{ "FileFsDeviceInformation", "smb2.fs_device_info", FT_NONE, BASE_NONE,
11835 			NULL, 0, NULL, HFILL }
11836 		},
11837 
11838 		{ &hf_smb2_fs_info_05,
11839 			{ "FileFsAttributeInformation", "smb2.fs_attribute_info", FT_NONE, BASE_NONE,
11840 			NULL, 0, NULL, HFILL }
11841 		},
11842 
11843 		{ &hf_smb2_fs_info_06,
11844 			{ "FileFsControlInformation", "smb2.fs_control_info", FT_NONE, BASE_NONE,
11845 			NULL, 0, NULL, HFILL }
11846 		},
11847 
11848 		{ &hf_smb2_fs_info_07,
11849 			{ "FileFsFullSizeInformation", "smb2.fs_full_size_info", FT_NONE, BASE_NONE,
11850 			NULL, 0, NULL, HFILL }
11851 		},
11852 
11853 		{ &hf_smb2_fs_objectid_info,
11854 			{ "FileFsObjectIdInformation", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
11855 			NULL, 0, NULL, HFILL }
11856 		},
11857 
11858 		{ &hf_smb2_sec_info_00,
11859 			{ "SMB2_SEC_INFO_00", "smb2.sec_info_00", FT_NONE, BASE_NONE,
11860 			NULL, 0, NULL, HFILL }
11861 		},
11862 
11863 		{ &hf_smb2_quota_info,
11864 			{ "SMB2_QUOTA_INFO", "smb2.quota_info", FT_NONE, BASE_NONE,
11865 			NULL, 0, NULL, HFILL }
11866 		},
11867 
11868 		{ &hf_smb2_query_quota_info,
11869 			{ "SMB2_QUERY_QUOTA_INFO", "smb2.query_quota_info", FT_NONE, BASE_NONE,
11870 			NULL, 0, NULL, HFILL }
11871 		},
11872 
11873 		{ &hf_smb2_qq_single,
11874 			{ "ReturnSingle", "smb2.query_quota_info.single", FT_BOOLEAN, 8,
11875 			NULL, 0xff, NULL, HFILL }
11876 		},
11877 
11878 		{ &hf_smb2_qq_restart,
11879 			{ "RestartScan", "smb2.query_quota_info.restart", FT_BOOLEAN, 8,
11880 			NULL, 0xff, NULL, HFILL }
11881 		},
11882 
11883 		{ &hf_smb2_qq_sidlist_len,
11884 			{ "SidListLength", "smb2.query_quota_info.sidlistlen", FT_UINT32, BASE_DEC,
11885 			NULL, 0, NULL, HFILL }
11886 		},
11887 
11888 		{ &hf_smb2_qq_start_sid_len,
11889 			{ "StartSidLength", "smb2.query_quota_info.startsidlen", FT_UINT32, BASE_DEC,
11890 			NULL, 0, NULL, HFILL }
11891 		},
11892 
11893 		{ &hf_smb2_qq_start_sid_offset,
11894 			{ "StartSidOffset", "smb2.query_quota_info.startsidoffset", FT_UINT32, BASE_DEC,
11895 			NULL, 0, NULL, HFILL }
11896 		},
11897 
11898 		{ &hf_smb2_disposition_delete_on_close,
11899 			{ "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
11900 			TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }
11901 		},
11902 
11903 
11904 		{ &hf_smb2_create_disposition,
11905 			{ "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
11906 			VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }
11907 		},
11908 
11909 		{ &hf_smb2_create_action,
11910 			{ "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
11911 			VALS(oa_open_vals), 0, NULL, HFILL }
11912 		},
11913 
11914 		{ &hf_smb2_create_rep_flags,
11915 			{ "Response Flags", "smb2.create.rep_flags", FT_UINT8, BASE_HEX,
11916 			NULL, 0, NULL, HFILL }
11917 		},
11918 
11919 		{ &hf_smb2_create_rep_flags_reparse_point,
11920 			{ "ReparsePoint", "smb2.create.rep_flags.reparse_point", FT_BOOLEAN, 8,
11921 			NULL, SMB2_CREATE_REP_FLAGS_REPARSE_POINT, NULL, HFILL }
11922 		},
11923 
11924 		{ &hf_smb2_extrainfo,
11925 			{ "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
11926 			NULL, 0, "Create ExtraInfo", HFILL }
11927 		},
11928 
11929 		{ &hf_smb2_create_chain_offset,
11930 			{ "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
11931 			NULL, 0, "Offset to next entry in chain or 0", HFILL }
11932 		},
11933 
11934 		{ &hf_smb2_create_chain_data,
11935 			{ "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
11936 			NULL, 0, "Chain Data", HFILL }
11937 		},
11938 
11939 		{ &hf_smb2_FILE_OBJECTID_BUFFER,
11940 			{ "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
11941 			NULL, 0, NULL, HFILL }
11942 		},
11943 
11944 		{ &hf_smb2_lease_key,
11945 			{ "Lease Key", "smb2.lease.lease_key", FT_GUID, BASE_NONE,
11946 			NULL, 0, NULL, HFILL }
11947 		},
11948 
11949 		{ &hf_smb2_lease_state,
11950 			{ "Lease State", "smb2.lease.lease_state", FT_UINT32, BASE_HEX,
11951 			NULL, 0, NULL, HFILL }
11952 		},
11953 
11954 		{ &hf_smb2_lease_state_read_caching,
11955 			{ "Read Caching", "smb2.lease.lease_state.read_caching", FT_BOOLEAN, 32,
11956 			NULL, SMB2_LEASE_STATE_READ_CACHING, NULL, HFILL }
11957 		},
11958 
11959 		{ &hf_smb2_lease_state_handle_caching,
11960 			{ "Handle Caching", "smb2.lease.lease_state.handle_caching", FT_BOOLEAN, 32,
11961 			NULL, SMB2_LEASE_STATE_HANDLE_CACHING, NULL, HFILL }
11962 		},
11963 
11964 		{ &hf_smb2_lease_state_write_caching,
11965 			{ "Write Caching", "smb2.lease.lease_state.write_caching", FT_BOOLEAN, 32,
11966 			NULL, SMB2_LEASE_STATE_WRITE_CACHING, NULL, HFILL }
11967 		},
11968 
11969 		{ &hf_smb2_lease_flags,
11970 			{ "Lease Flags", "smb2.lease.lease_flags", FT_UINT32, BASE_HEX,
11971 			NULL, 0, NULL, HFILL }
11972 		},
11973 
11974 		{ &hf_smb2_lease_flags_break_ack_required,
11975 			{ "Break Ack Required", "smb2.lease.lease_state.break_ack_required", FT_BOOLEAN, 32,
11976 			NULL, SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED, NULL, HFILL }
11977 		},
11978 
11979 		{ &hf_smb2_lease_flags_break_in_progress,
11980 			{ "Break In Progress", "smb2.lease.lease_state.break_in_progress", FT_BOOLEAN, 32,
11981 			NULL, SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS, NULL, HFILL }
11982 		},
11983 
11984 		{ &hf_smb2_lease_flags_parent_lease_key_set,
11985 			{ "Parent Lease Key Set", "smb2.lease.lease_state.parent_lease_key_set", FT_BOOLEAN, 32,
11986 			NULL, SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET, NULL, HFILL }
11987 		},
11988 
11989 		{ &hf_smb2_lease_duration,
11990 			{ "Lease Duration", "smb2.lease.lease_duration", FT_UINT64, BASE_HEX,
11991 			NULL, 0, NULL, HFILL }
11992 		},
11993 
11994 		{ &hf_smb2_parent_lease_key,
11995 			{ "Parent Lease Key", "smb2.lease.parent_lease_key", FT_GUID, BASE_NONE,
11996 			NULL, 0, NULL, HFILL }
11997 		},
11998 
11999 		{ &hf_smb2_lease_epoch,
12000 			{ "Lease Epoch", "smb2.lease.lease_oplock", FT_UINT16, BASE_HEX,
12001 			NULL, 0, NULL, HFILL }
12002 		},
12003 
12004 		{ &hf_smb2_lease_reserved,
12005 			{ "Lease Reserved", "smb2.lease.lease_reserved", FT_UINT16, BASE_HEX,
12006 			NULL, 0, NULL, HFILL }
12007 		},
12008 
12009 		{ &hf_smb2_lease_break_reason,
12010 			{ "Lease Break Reason", "smb2.lease.lease_break_reason", FT_UINT32, BASE_HEX,
12011 			NULL, 0, NULL, HFILL }
12012 		},
12013 
12014 		{ &hf_smb2_lease_access_mask_hint,
12015 			{ "Access Mask Hint", "smb2.lease.access_mask_hint", FT_UINT32, BASE_HEX,
12016 			NULL, 0, NULL, HFILL }
12017 		},
12018 
12019 		{ &hf_smb2_lease_share_mask_hint,
12020 			{ "Share Mask Hint", "smb2.lease.share_mask_hint", FT_UINT32, BASE_HEX,
12021 			NULL, 0, NULL, HFILL }
12022 		},
12023 
12024 		{ &hf_smb2_next_offset,
12025 			{ "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
12026 			NULL, 0, "Offset to next buffer or 0", HFILL }
12027 		},
12028 
12029 		{ &hf_smb2_negotiate_context_type,
12030 			{ "Type", "smb2.negotiate_context.type", FT_UINT16, BASE_HEX,
12031 			VALS(smb2_negotiate_context_types), 0, NULL, HFILL }
12032 		},
12033 
12034 		{ &hf_smb2_negotiate_context_data_length,
12035 			{ "DataLength", "smb2.negotiate_context.data_length", FT_UINT16, BASE_DEC,
12036 			NULL, 0, NULL, HFILL }
12037 		},
12038 
12039 		{ &hf_smb2_negotiate_context_offset,
12040 			{ "NegotiateContextOffset", "smb2.negotiate_context.offset", FT_UINT32, BASE_HEX,
12041 			NULL, 0, NULL, HFILL }
12042 		},
12043 
12044 		{ &hf_smb2_negotiate_context_count,
12045 			{ "NegotiateContextCount", "smb2.negotiate_context.count", FT_UINT16, BASE_DEC,
12046 			NULL, 0, NULL, HFILL }
12047 		},
12048 
12049 		{ &hf_smb2_hash_alg_count,
12050 			{ "HashAlgorithmCount", "smb2.negotiate_context.hash_alg_count", FT_UINT16, BASE_DEC,
12051 			NULL, 0, NULL, HFILL }},
12052 
12053 		{ &hf_smb2_hash_algorithm,
12054 			{ "HashAlgorithm", "smb2.negotiate_context.hash_algorithm", FT_UINT16, BASE_HEX,
12055 			VALS(smb2_hash_algorithm_types), 0, NULL, HFILL }},
12056 
12057 		{ &hf_smb2_salt_length,
12058 			{ "SaltLength", "smb2.negotiate_context.salt_length", FT_UINT16, BASE_DEC,
12059 			NULL, 0, NULL, HFILL }},
12060 
12061 		{ &hf_smb2_salt,
12062 			{ "Salt", "smb2.negotiate_context.salt", FT_BYTES, BASE_NONE,
12063 			NULL, 0, NULL, HFILL }},
12064 
12065 		{ &hf_smb2_signing_alg_count,
12066 			{ "SigningAlgorithmCount", "smb2.negotiate_context.signing_alg_count", FT_UINT16, BASE_DEC,
12067 			NULL, 0, NULL, HFILL }},
12068 
12069 		{ &hf_smb2_signing_alg_id,
12070 			{ "SigningAlgorithmId", "smb2.negotiate_context.signing_id", FT_UINT16, BASE_HEX,
12071 			VALS(smb2_signing_alg_types), 0, NULL, HFILL }},
12072 
12073 		{ &hf_smb2_cipher_count,
12074 			{ "CipherCount", "smb2.negotiate_context.cipher_count", FT_UINT16, BASE_DEC,
12075 			NULL, 0, NULL, HFILL }},
12076 
12077 		{ &hf_smb2_cipher_id,
12078 			{ "CipherId", "smb2.negotiate_context.cipher_id", FT_UINT16, BASE_HEX,
12079 			VALS(smb2_cipher_types), 0, NULL, HFILL }},
12080 
12081 		{ &hf_smb2_posix_reserved,
12082 			{ "POSIX Reserved", "smb2.negotiate_context.posix_reserved", FT_BYTES, BASE_NONE,
12083 			NULL, 0, NULL, HFILL }
12084 		},
12085 
12086 		{ &hf_smb2_inode,
12087 			{ "Inode", "smb2.inode", FT_UINT64, BASE_HEX,
12088 			NULL, 0, NULL, HFILL }
12089 		},
12090 
12091 		{ &hf_smb2_comp_alg_count,
12092 			{ "CompressionAlgorithmCount", "smb2.negotiate_context.comp_alg_count", FT_UINT16, BASE_DEC,
12093 			NULL, 0, NULL, HFILL }},
12094 
12095 		{ &hf_smb2_comp_alg_id,
12096 			{ "CompressionAlgorithmId", "smb2.negotiate_context.comp_alg_id", FT_UINT16, BASE_HEX,
12097 			VALS(smb2_comp_alg_types), 0, NULL, HFILL }},
12098 
12099 		{ &hf_smb2_comp_alg_flags,
12100 			{ "Flags", "smb2.negotiate_context.comp_alg_flags", FT_UINT32, BASE_HEX,
12101 			NULL, 0, NULL, HFILL }
12102 		},
12103 
12104 		{ &hf_smb2_comp_alg_flags_chained,
12105 			{ "Chained", "smb2.negotiate_context.comp_alg_flags.chained", FT_BOOLEAN, 32,
12106 			NULL, SMB2_COMP_ALG_FLAGS_CHAINED, "Chained compression is supported on this connection", HFILL }
12107 		},
12108 
12109 		{ &hf_smb2_comp_alg_flags_reserved,
12110 			{ "Reserved", "smb2.negotiate_context.comp_alg_flags.reserved", FT_UINT32, BASE_HEX,
12111 			NULL, 0xFFFFFFFE, "Must be zero", HFILL }
12112 		},
12113 
12114 		{ &hf_smb2_netname_neg_id,
12115 			{ "Netname", "smb2.negotiate_context.netname", FT_STRING,
12116 			STR_UNICODE, NULL, 0x0, NULL, HFILL }
12117 		},
12118 
12119 		{ &hf_smb2_transport_ctx_flags,
12120 			{ "Flags", "smb2.negotiate_context.transport_flags", FT_UINT32, BASE_HEX,
12121 			  VALS(smb2_transport_ctx_flags_vals), 0, NULL, HFILL }
12122 		},
12123 
12124 		{ &hf_smb2_rdma_transform_count,
12125 			{ "TransformCount", "smb2.negotiate_context.rdma_transform_count", FT_UINT16, BASE_DEC,
12126 			NULL, 0, NULL, HFILL }
12127 		},
12128 
12129 		{ &hf_smb2_rdma_transform_reserved1,
12130 			{ "Reserved1", "smb2.negotiate_context.rdma_transform_reserved1", FT_UINT16, BASE_HEX,
12131 			NULL, 0, NULL, HFILL }
12132 		},
12133 
12134 		{ &hf_smb2_rdma_transform_reserved2,
12135 			{ "Reserved2", "smb2.negotiate_context.rdma_transform_reserved2", FT_UINT32, BASE_HEX,
12136 			NULL, 0, NULL, HFILL }
12137 		},
12138 
12139 		{ &hf_smb2_rdma_transform_id,
12140 			{ "RDMATransformId", "smb2.negotiate_context.rdma_transform_id", FT_UINT16, BASE_HEX,
12141 			VALS(smb2_rdma_transform_types), 0, NULL, HFILL }
12142 		},
12143 
12144 		{ &hf_smb2_current_time,
12145 			{ "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
12146 			NULL, 0, "Current Time at server", HFILL }
12147 		},
12148 
12149 		{ &hf_smb2_boot_time,
12150 			{ "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
12151 			NULL, 0, "Boot Time at server", HFILL }
12152 		},
12153 
12154 		{ &hf_smb2_ea_flags,
12155 			{ "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
12156 			NULL, 0, NULL, HFILL }
12157 		},
12158 
12159 		{ &hf_smb2_ea_name_len,
12160 			{ "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
12161 			NULL, 0, NULL, HFILL }
12162 		},
12163 
12164 		{ &hf_smb2_ea_data_len,
12165 			{ "EA Data Length", "smb2.ea.data_len", FT_UINT16, BASE_DEC,
12166 			NULL, 0, NULL, HFILL }
12167 		},
12168 
12169 		{ &hf_smb2_delete_pending,
12170 			{ "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
12171 			NULL, 0, NULL, HFILL }
12172 		},
12173 
12174 		{ &hf_smb2_is_directory,
12175 			{ "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
12176 			NULL, 0, "Is this a directory?", HFILL }
12177 		},
12178 
12179 		{ &hf_smb2_oplock,
12180 			{ "Oplock", "smb2.create.oplock", FT_UINT8, BASE_HEX,
12181 			VALS(oplock_vals), 0, "Oplock type", HFILL }
12182 		},
12183 
12184 		{ &hf_smb2_close_flags,
12185 			{ "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
12186 			NULL, 0, NULL, HFILL }
12187 		},
12188 
12189 		{ &hf_smb2_notify_flags,
12190 			{ "Notify Flags", "smb2.notify.flags", FT_UINT16, BASE_HEX,
12191 			NULL, 0, NULL, HFILL }
12192 		},
12193 
12194 		{ &hf_smb2_buffer_code,
12195 			{ "StructureSize", "smb2.buffer_code", FT_UINT16, BASE_HEX,
12196 			NULL, 0, NULL, HFILL }
12197 		},
12198 
12199 		{ &hf_smb2_buffer_code_len,
12200 			{ "Fixed Part Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
12201 			NULL, 0xFFFE, "Length of fixed portion of PDU", HFILL }
12202 		},
12203 
12204 		{ &hf_smb2_olb_length,
12205 			{ "Blob Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
12206 			NULL, 0, "Length of the buffer", HFILL }
12207 		},
12208 
12209 		{ &hf_smb2_olb_offset,
12210 			{ "Blob Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
12211 			NULL, 0, "Offset to the buffer", HFILL }
12212 		},
12213 
12214 		{ &hf_smb2_buffer_code_flags_dyn,
12215 			{ "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
12216 			NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }
12217 		},
12218 
12219 		{ &hf_smb2_ea_data,
12220 			{ "EA Data", "smb2.ea.data", FT_BYTES, BASE_NONE|BASE_SHOW_ASCII_PRINTABLE,
12221 			NULL, 0, NULL, HFILL }
12222 		},
12223 
12224 		{ &hf_smb2_ea_name,
12225 			{ "EA Name", "smb2.ea.name", FT_STRING, STR_UNICODE,
12226 			NULL, 0, NULL, HFILL }
12227 		},
12228 
12229 		{ &hf_smb2_impersonation_level,
12230 			{ "Impersonation level", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
12231 			VALS(impersonation_level_vals), 0, NULL, HFILL }
12232 		},
12233 
12234 		{ &hf_smb2_ioctl_function,
12235 			{ "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
12236 			&smb2_ioctl_vals_ext, 0, "Ioctl function", HFILL }
12237 		},
12238 
12239 		{ &hf_smb2_ioctl_function_device,
12240 			{ "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
12241 			&smb2_ioctl_device_vals_ext, 0xffff0000, "Device for Ioctl", HFILL }
12242 		},
12243 
12244 		{ &hf_smb2_ioctl_function_access,
12245 			{ "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
12246 			VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }
12247 		},
12248 
12249 		{ &hf_smb2_ioctl_function_function,
12250 			{ "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
12251 			NULL, 0x00003ffc, "Function for Ioctl", HFILL }
12252 		},
12253 
12254 		{ &hf_smb2_ioctl_function_method,
12255 			{ "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
12256 			VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }
12257 		},
12258 
12259 		{ &hf_smb2_fsctl_pipe_wait_timeout,
12260 			{ "Timeout", "smb2.fsctl.wait.timeout", FT_INT64, BASE_DEC,
12261 			NULL, 0, "Wait timeout", HFILL }
12262 		},
12263 
12264 		{ &hf_smb2_fsctl_pipe_wait_name,
12265 			{ "Name", "smb2.fsctl.wait.name", FT_STRING, STR_UNICODE,
12266 			NULL, 0, "Pipe name", HFILL }
12267 		},
12268 
12269 		{ &hf_smb2_fsctl_odx_token_type,
12270 			{ "TokenType", "smb2.fsctl.odx.token.type", FT_UINT32, BASE_HEX,
12271 			NULL, 0, NULL, HFILL }
12272 		},
12273 
12274 		{ &hf_smb2_fsctl_odx_token_idlen,
12275 			{ "TokenIdLength", "smb2.fsctl.odx.token.idlen", FT_UINT16, BASE_DEC,
12276 			NULL, 0, NULL, HFILL }
12277 		},
12278 
12279 		{ &hf_smb2_fsctl_odx_token_idraw,
12280 			{ "TokenId", "smb2.fsctl.odx.token.id", FT_BYTES, BASE_NONE,
12281 			NULL, 0, "Token ID (opaque)", HFILL }
12282 		},
12283 
12284 		{ &hf_smb2_fsctl_odx_token_ttl,
12285 			{ "TokenTimeToLive", "smb2.fsctl.odx.token_ttl", FT_UINT32, BASE_DEC,
12286 			NULL, 0, "TTL requested for the token (in milliseconds)", HFILL }
12287 		},
12288 
12289 		{ &hf_smb2_fsctl_odx_size,
12290 			{ "Size", "smb2.fsctl.odx.size", FT_UINT32, BASE_DEC,
12291 			NULL, 0, "Size of this data element", HFILL }
12292 		},
12293 
12294 		{ &hf_smb2_fsctl_odx_flags,
12295 			{ "Flags", "smb2.fsctl.odx.flags", FT_UINT32, BASE_HEX,
12296 			NULL, 0, "Flags for this operation", HFILL }
12297 		},
12298 
12299 		{ &hf_smb2_fsctl_odx_file_offset,
12300 			{ "FileOffset", "smb2.fsctl.odx.file_offset", FT_UINT64, BASE_DEC,
12301 			NULL, 0, NULL, HFILL }
12302 		},
12303 
12304 		{ &hf_smb2_fsctl_odx_copy_length,
12305 			{ "CopyLength", "smb2.fsctl.odx.copy_length", FT_UINT64, BASE_DEC,
12306 			NULL, 0, NULL, HFILL }
12307 		},
12308 
12309 		{ &hf_smb2_fsctl_odx_xfer_length,
12310 			{ "TransferLength", "smb2.fsctl.odx.xfer_length", FT_UINT64, BASE_DEC,
12311 			NULL, 0, NULL, HFILL }
12312 		},
12313 
12314 		{ &hf_smb2_fsctl_odx_token_offset,
12315 			{ "TokenOffset", "smb2.fsctl.odx.token_offset", FT_UINT64, BASE_DEC,
12316 			NULL, 0, "Token Offset (relative to start of token)", HFILL }
12317 		},
12318 
12319 		{ &hf_smb2_fsctl_sparse_flag,
12320 			{ "SetSparse", "smb2.fsctl.set_sparse", FT_BOOLEAN, 8,
12321 			NULL, 0xFF, NULL, HFILL }
12322 		},
12323 
12324 		{ &hf_smb2_ioctl_resiliency_timeout,
12325 			{ "Timeout", "smb2.ioctl.resiliency.timeout", FT_UINT32, BASE_DEC,
12326 			NULL, 0, "Resiliency timeout", HFILL }
12327 		},
12328 
12329 		{ &hf_smb2_ioctl_resiliency_reserved,
12330 			{ "Reserved", "smb2.ioctl.resiliency.reserved", FT_UINT32, BASE_DEC,
12331 			NULL, 0, "Resiliency reserved", HFILL }
12332 		},
12333 
12334 		{ &hf_smb2_ioctl_shared_virtual_disk_support,
12335 			{ "SharedVirtualDiskSupport", "smb2.ioctl.shared_virtual_disk.support", FT_UINT32, BASE_HEX,
12336 			VALS(smb2_ioctl_shared_virtual_disk_vals), 0, "Supported shared capabilities", HFILL }
12337 		},
12338 
12339 		{ &hf_smb2_ioctl_shared_virtual_disk_handle_state,
12340 			{ "SharedVirtualDiskHandleState", "smb2.ioctl.shared_virtual_disk.handle_state", FT_UINT32, BASE_HEX,
12341 			VALS(smb2_ioctl_shared_virtual_disk_hstate_vals), 0, NULL, HFILL }
12342 		},
12343 
12344 		{ &hf_smb2_ioctl_sqos_protocol_version,
12345 			{ "ProtocolVersion", "smb2.ioctl.sqos.protocol_version", FT_UINT16, BASE_HEX,
12346 			VALS(smb2_ioctl_sqos_protocol_version_vals), 0, NULL, HFILL }
12347 		},
12348 
12349 		{ &hf_smb2_ioctl_sqos_reserved,
12350 			{ "Reserved", "smb2.ioctl.sqos.reserved", FT_UINT16, BASE_DEC,
12351 			NULL, 0, NULL, HFILL }
12352 		},
12353 
12354 		{ &hf_smb2_ioctl_sqos_options,
12355 			{ "Operations", "smb2.ioctl.sqos.operations", FT_UINT32, BASE_HEX,
12356 			NULL, 0, "SQOS operations", HFILL }
12357 		},
12358 
12359 		{ &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
12360 			{ "Set Logical Flow ID", "smb2.ioctl.sqos.operations.set_logical_flow_id", FT_BOOLEAN, 32,
12361 			NULL, STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID, "Whether Set Logical Flow ID operation is performed", HFILL }
12362 		},
12363 
12364 		{ &hf_smb2_ioctl_sqos_op_set_policy,
12365 			{ "Set Policy", "smb2.ioctl.sqos.operations.set_policy", FT_BOOLEAN, 32,
12366 			NULL, STORAGE_QOS_CONTROL_FLAG_SET_POLICY, "Whether Set Policy operation is performed", HFILL }
12367 		},
12368 
12369 		{ &hf_smb2_ioctl_sqos_op_probe_policy,
12370 			{ "Probe Policy", "smb2.ioctl.sqos.operations.probe_policy", FT_BOOLEAN, 32,
12371 			NULL, STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY, "Whether Probe Policy operation is performed", HFILL }
12372 		},
12373 
12374 		{ &hf_smb2_ioctl_sqos_op_get_status,
12375 			{ "Get Status", "smb2.ioctl.sqos.operations.get_status", FT_BOOLEAN, 32,
12376 			NULL, STORAGE_QOS_CONTROL_FLAG_GET_STATUS, "Whether Get Status operation is performed", HFILL }
12377 		},
12378 
12379 		{ &hf_smb2_ioctl_sqos_op_update_counters,
12380 			{ "Update Counters", "smb2.ioctl.sqos.operations.update_counters", FT_BOOLEAN, 32,
12381 			NULL, STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS, "Whether Update Counters operation is performed", HFILL }
12382 		},
12383 
12384 		{ &hf_smb2_ioctl_sqos_logical_flow_id,
12385 			{ "LogicalFlowID", "smb2.ioctl.sqos.logical_flow_id", FT_GUID, BASE_NONE,
12386 			NULL, 0, NULL, HFILL }
12387 		},
12388 
12389 		{ &hf_smb2_ioctl_sqos_policy_id,
12390 			{ "PolicyID", "smb2.ioctl.sqos.policy_id", FT_GUID, BASE_NONE,
12391 			NULL, 0, NULL, HFILL }
12392 		},
12393 
12394 		{ &hf_smb2_ioctl_sqos_initiator_id,
12395 			{ "InitiatorID", "smb2.ioctl.sqos.initiator_id", FT_GUID, BASE_NONE,
12396 			NULL, 0, NULL, HFILL }
12397 		},
12398 
12399 		{ &hf_smb2_ioctl_sqos_limit,
12400 			{ "Limit", "smb2.ioctl.sqos.limit", FT_UINT64, BASE_DEC,
12401 			NULL, 0, "Desired maximum throughput for the logical flow, in normalized IOPS", HFILL }
12402 		},
12403 
12404 		{ &hf_smb2_ioctl_sqos_reservation,
12405 			{ "Reservation", "smb2.ioctl.sqos.reservation", FT_UINT64, BASE_DEC,
12406 			NULL, 0, "Desired minimum throughput for the logical flow, in normalized 8KB IOPS", HFILL }
12407 		},
12408 
12409 		{ &hf_smb2_ioctl_sqos_initiator_name,
12410 			{ "InitiatorName", "smb2.ioctl.sqos.initiator_name", FT_STRING, STR_UNICODE,
12411 			NULL, 0x0, NULL, HFILL }
12412 		},
12413 
12414 		{ &hf_smb2_ioctl_sqos_initiator_node_name,
12415 			{ "InitiatorNodeName", "smb2.ioctl.sqos.initiator_node_name", FT_STRING, STR_UNICODE,
12416 			NULL, 0x0, NULL, HFILL }
12417 		},
12418 
12419 		{ &hf_smb2_ioctl_sqos_io_count_increment,
12420 			{ "IoCountIncrement", "smb2.ioctl.sqos.io_count_increment", FT_UINT64, BASE_DEC,
12421 			NULL, 0, "The total number of I/O requests issued by the initiator on the logical flow", HFILL }
12422 		},
12423 
12424 		{ &hf_smb2_ioctl_sqos_normalized_io_count_increment,
12425 			{ "NormalizedIoCountIncrement", "smb2.ioctl.sqos.normalized_io_count_increment", FT_UINT64, BASE_DEC,
12426 			NULL, 0, "The total number of normalized 8-KB I/O requests issued by the initiator on the logical flow", HFILL }
12427 		},
12428 
12429 		{ &hf_smb2_ioctl_sqos_latency_increment,
12430 			{ "LatencyIncrement", "smb2.ioctl.sqos.latency_increment", FT_UINT64, BASE_DEC,
12431 			NULL, 0, "The total latency (including initiator's queues delays) measured by the initiator", HFILL }
12432 		},
12433 
12434 		{ &hf_smb2_ioctl_sqos_lower_latency_increment,
12435 			{ "LowerLatencyIncrement", "smb2.ioctl.sqos.lower_latency_increment", FT_UINT64, BASE_DEC,
12436 			NULL, 0, "The total latency (excluding initiator's queues delays) measured by the initiator", HFILL }
12437 		},
12438 
12439 		{ &hf_smb2_ioctl_sqos_bandwidth_limit,
12440 			{ "BandwidthLimit", "smb2.ioctl.sqos.bandwidth_limit", FT_UINT64, BASE_DEC,
12441 			NULL, 0, "Desired maximum bandwidth for the logical flow, in kilobytes per second", HFILL }
12442 		},
12443 
12444 		{ &hf_smb2_ioctl_sqos_kilobyte_count_increment,
12445 			{ "KilobyteCountIncrement", "smb2.ioctl.sqos.kilobyte_count_increment", FT_UINT64, BASE_DEC,
12446 			NULL, 0, "The total data transfer length of all I/O requests, in kilobyte units, issued by the initiator on the logical flow", HFILL }
12447 		},
12448 
12449 		{ &hf_smb2_ioctl_sqos_time_to_live,
12450 			{ "TimeToLive", "smb2.ioctl.sqos.time_to_live", FT_UINT32, BASE_DEC,
12451 			NULL, 0, "The expected period of validity of the Status, MaximumIoRate and MinimumIoRate fields, expressed in milliseconds", HFILL }
12452 		},
12453 
12454 		{ &hf_smb2_ioctl_sqos_status,
12455 			{ "Status", "smb2.ioctl.sqos.status", FT_UINT32, BASE_HEX,
12456 			VALS(smb2_ioctl_sqos_status_vals), 0, "The current status of the logical flow", HFILL }
12457 		},
12458 
12459 		{ &hf_smb2_ioctl_sqos_maximum_io_rate,
12460 			{ "MaximumIoRate", "smb2.ioctl.sqos.maximum_io_rate", FT_UINT64, BASE_DEC,
12461 			NULL, 0, "The maximum I/O initiation rate currently assigned to the logical flow, expressed in normalized input/output operations per second (normalized IOPS)", HFILL }
12462 		},
12463 
12464 		{ &hf_smb2_ioctl_sqos_minimum_io_rate,
12465 			{ "MinimumIoRate", "smb2.ioctl.sqos.minimum_io_rate", FT_UINT64, BASE_DEC,
12466 			NULL, 0, "The minimum I/O completion rate currently assigned to the logical flow, expressed in normalized IOPS", HFILL }
12467 		},
12468 
12469 		{ &hf_smb2_ioctl_sqos_base_io_size,
12470 			{ "BaseIoSize", "smb2.ioctl.sqos.base_io_size", FT_UINT32, BASE_DEC,
12471 			NULL, 0, "The base I/O size used to compute the normalized size of an I/O request for the logical flow", HFILL }
12472 		},
12473 
12474 		{ &hf_smb2_ioctl_sqos_reserved2,
12475 			{ "Reserved", "smb2.ioctl.sqos.reserved2", FT_UINT32, BASE_DEC,
12476 			NULL, 0, NULL, HFILL }
12477 		},
12478 
12479 		{ &hf_smb2_ioctl_sqos_maximum_bandwidth,
12480 			{ "MaximumBandwidth", "smb2.ioctl.sqos.maximum_bandwidth", FT_UINT64, BASE_DEC,
12481 			NULL, 0, "The maximum bandwidth currently assigned to the logical flow, expressed in kilobytes per second", HFILL }
12482 		},
12483 
12484 
12485 		{ &hf_windows_sockaddr_family,
12486 			{ "Socket Family", "smb2.windows.sockaddr.family", FT_UINT16, BASE_DEC,
12487 			NULL, 0, "The socket address family (on windows)", HFILL }
12488 		},
12489 
12490 		{ &hf_windows_sockaddr_port,
12491 			{ "Socket Port", "smb2.windows.sockaddr.port", FT_UINT16, BASE_DEC,
12492 			NULL, 0, "The socket address port", HFILL }
12493 		},
12494 
12495 		{ &hf_windows_sockaddr_in_addr,
12496 			{ "Socket IPv4", "smb2.windows.sockaddr.in.addr", FT_IPv4, BASE_NONE,
12497 			NULL, 0, "The IPv4 address", HFILL }
12498 		},
12499 
12500 		{ &hf_windows_sockaddr_in6_flowinfo,
12501 			{ "IPv6 Flow Info", "smb2.windows.sockaddr.in6.flow_info", FT_UINT32, BASE_HEX,
12502 			NULL, 0, "The socket IPv6 flow info", HFILL }
12503 		},
12504 
12505 		{ &hf_windows_sockaddr_in6_addr,
12506 			{ "Socket IPv6", "smb2.windows.sockaddr.in6.addr", FT_IPv6, BASE_NONE,
12507 			NULL, 0, "The IPv6 address", HFILL }
12508 		},
12509 
12510 		{ &hf_windows_sockaddr_in6_scope_id,
12511 			{ "IPv6 Scope ID", "smb2.windows.sockaddr.in6.scope_id", FT_UINT32, BASE_DEC,
12512 			NULL, 0, "The socket IPv6 scope id", HFILL }
12513 		},
12514 
12515 		{ &hf_smb2_ioctl_network_interface_next_offset,
12516 			{ "Next Offset", "smb2.ioctl.network_interfaces.next_offset", FT_UINT32, BASE_HEX,
12517 			NULL, 0, "Offset to next entry in chain or 0", HFILL }
12518 		},
12519 
12520 		{ &hf_smb2_ioctl_network_interface_index,
12521 			{ "Interface Index", "smb2.ioctl.network_interfaces.index", FT_UINT32, BASE_DEC,
12522 			NULL, 0, "The index of the interface", HFILL }
12523 		},
12524 
12525 		{ &hf_smb2_ioctl_network_interface_rss_queue_count,
12526 			{ "RSS Queue Count", "smb2.ioctl.network_interfaces.rss_queue_count", FT_UINT32, BASE_DEC,
12527 			NULL, 0, "The RSS queue count", HFILL }
12528 		},
12529 
12530 		{ &hf_smb2_ioctl_network_interface_capabilities,
12531 			{ "Interface Cababilities", "smb2.ioctl.network_interfaces.capabilities", FT_UINT32, BASE_HEX,
12532 			NULL, 0, "The capabilities of the network interface", HFILL }
12533 		},
12534 
12535 		{ &hf_smb2_ioctl_network_interface_capability_rss,
12536 			{ "RSS", "smb2.ioctl.network_interfaces.capabilities.rss", FT_BOOLEAN, 32,
12537 			TFS(&tfs_smb2_ioctl_network_interface_capability_rss), NETWORK_INTERFACE_CAP_RSS, "If the host supports RSS", HFILL }
12538 		},
12539 
12540 		{ &hf_smb2_ioctl_network_interface_capability_rdma,
12541 			{ "RDMA", "smb2.ioctl.network_interfaces.capabilities.rdma", FT_BOOLEAN, 32,
12542 			TFS(&tfs_smb2_ioctl_network_interface_capability_rdma), NETWORK_INTERFACE_CAP_RDMA, "If the host supports RDMA", HFILL }
12543 		},
12544 
12545 		{ &hf_smb2_ioctl_network_interface_link_speed,
12546 			{ "Link Speed", "smb2.ioctl.network_interfaces.link_speed", FT_UINT64, BASE_DEC,
12547 			NULL, 0, "The link speed of the interface", HFILL }
12548 		},
12549 
12550 		{ &hf_smb2_ioctl_enumerate_snapshots_num_snapshots,
12551 			{ "Number of snapshots", "smb2.ioctl.enumerate_snapshots.num_snapshots", FT_UINT32, BASE_DEC,
12552 			NULL, 0, "Number of previous versions associated with the volume", HFILL }
12553 		},
12554 
12555 		{ &hf_smb2_ioctl_enumerate_snapshots_num_snapshots_returned,
12556 			{ "Number of snapshots returned", "smb2.ioctl.enumerate_snapshots.num_snapshots_returned", FT_UINT32, BASE_DEC,
12557 			NULL, 0, "Number of previous version time stamps returned", HFILL }
12558 		},
12559 
12560 		{ &hf_smb2_ioctl_enumerate_snapshots_snapshot_array_size,
12561 			{ "Array size", "smb2.ioctl.enumerate_snapshots.array_size", FT_UINT32, BASE_DEC,
12562 			NULL, 0, "Number of bytes for snapshot time stamp strings", HFILL }
12563 		},
12564 
12565 		{ &hf_smb2_ioctl_enumerate_snapshots_snapshot,
12566 			{ "Snapshot", "smb2.ioctl.enumerate_snapshots.snapshot", FT_STRINGZ, STR_UNICODE,
12567 			NULL, 0, "Time stamp of previous version", HFILL }
12568 		},
12569 
12570 		{ &hf_smb2_tree_connect_flags,
12571 			{ "Flags", "smb2.tc.flags", FT_UINT16, BASE_HEX,
12572 			NULL, 0, "Tree Connect flags", HFILL }
12573 		},
12574 
12575 		{ &hf_smb2_tc_cluster_reconnect,
12576 			{ "Cluster Reconnect", "smb2.tc.cluster_reconnect", FT_BOOLEAN, 16,
12577 			TFS(&tfs_set_notset), 0x0001, "If this is a Cluster Reconnect", HFILL }
12578 		},
12579 
12580 		{ &hf_smb2_tc_redirect_to_owner,
12581 			{ "Redirect To Owner", "smb2.tc.redirect_to_owner", FT_BOOLEAN, 16,
12582 			TFS(&tfs_set_notset), 0x0002, "Set if the client can handle Share Redirects", HFILL }
12583 		},
12584 
12585 		{ &hf_smb2_tc_extension_present,
12586 			{ "Extension Present", "smb2.tc.extension_present", FT_BOOLEAN, 16,
12587 			TFS(&tfs_set_notset), 0x0004, "Set if an extension structure is present", HFILL }
12588 		},
12589 
12590 		{ &hf_smb2_tc_reserved,
12591 			{ "Reserved", "smb2.tc.reserved", FT_UINT16, BASE_HEX,
12592 			NULL, 0xFFF8, "Must be zero", HFILL }
12593 		},
12594 
12595 		{ &hf_smb2_compression_format,
12596 			{ "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
12597 			VALS(compression_format_vals), 0, NULL, HFILL }
12598 		},
12599 
12600 		{ &hf_smb2_checksum_algorithm,
12601 			{ "Checksum Algorithm", "smb2.checksum_algorithm", FT_UINT16, BASE_HEX,
12602 			VALS(checksum_algorithm_vals), 0, NULL, HFILL }
12603 		},
12604 
12605 		{ &hf_smb2_integrity_reserved,
12606 			{ "Reserved", "smb2.integrity_reserved", FT_UINT16, BASE_DEC,
12607 			NULL, 0, NULL, HFILL }
12608 		},
12609 
12610 		{ &hf_smb2_integrity_flags,
12611 			{ "Flags", "smb2.integrity_flags", FT_UINT32, BASE_HEX,
12612 			NULL, 0, NULL, HFILL }
12613 		},
12614 
12615 		{ &hf_smb2_integrity_flags_enforcement_off,
12616 			{ "FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF", "smb2.integrity_flags_enforcement", FT_BOOLEAN, 32,
12617 			NULL, 0x1, "If checksum error enforcement is off", HFILL }
12618 		},
12619 
12620 		{ &hf_smb2_share_type,
12621 			{ "Share Type", "smb2.share_type", FT_UINT8, BASE_HEX,
12622 			VALS(smb2_share_type_vals), 0, "Type of share", HFILL }
12623 		},
12624 
12625 		{ &hf_smb2_credit_charge,
12626 			{ "Credit Charge", "smb2.credit.charge", FT_UINT16, BASE_DEC,
12627 			NULL, 0, NULL, HFILL }
12628 		},
12629 
12630 		{ &hf_smb2_credits_requested,
12631 			{ "Credits requested", "smb2.credits.requested", FT_UINT16, BASE_DEC,
12632 			NULL, 0, NULL, HFILL }
12633 		},
12634 
12635 		{ &hf_smb2_credits_granted,
12636 			{ "Credits granted", "smb2.credits.granted", FT_UINT16, BASE_DEC,
12637 			NULL, 0, NULL, HFILL }
12638 		},
12639 
12640 		{ &hf_smb2_channel_sequence,
12641 			{ "Channel Sequence", "smb2.channel_sequence", FT_UINT16, BASE_DEC,
12642 			NULL, 0, NULL, HFILL }
12643 		},
12644 
12645 		{ &hf_smb2_dialect_count,
12646 			{ "Dialect count", "smb2.dialect_count", FT_UINT16, BASE_DEC,
12647 			NULL, 0, NULL, HFILL }
12648 		},
12649 
12650 		{ &hf_smb2_dialect,
12651 			{ "Dialect", "smb2.dialect", FT_UINT16, BASE_HEX,
12652 			VALS(smb2_dialect_vals), 0, NULL, HFILL }
12653 		},
12654 
12655 		{ &hf_smb2_security_mode,
12656 			{ "Security mode", "smb2.sec_mode", FT_UINT8, BASE_HEX,
12657 			NULL, 0, NULL, HFILL }
12658 		},
12659 
12660 		{ &hf_smb2_session_flags,
12661 			{ "Session Flags", "smb2.session_flags", FT_UINT16, BASE_HEX,
12662 			NULL, 0, NULL, HFILL }
12663 		},
12664 
12665 		{ &hf_smb2_lock_count,
12666 			{ "Lock Count", "smb2.lock_count", FT_UINT16, BASE_DEC,
12667 			NULL, 0, NULL, HFILL }
12668 		},
12669 
12670 		{ &hf_smb2_capabilities,
12671 			{ "Capabilities", "smb2.capabilities", FT_UINT32, BASE_HEX,
12672 			NULL, 0, NULL, HFILL }
12673 		},
12674 
12675 		{ &hf_smb2_auth_frame,
12676 			{ "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
12677 			NULL, 0, "Which frame this user was authenticated in", HFILL }
12678 		},
12679 
12680 		{ &hf_smb2_tcon_frame,
12681 			{ "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
12682 			NULL, 0, "Which frame this share was connected in", HFILL }
12683 		},
12684 
12685 		{ &hf_smb2_tag,
12686 			{ "Tag", "smb2.tag", FT_STRING, STR_UNICODE,
12687 			NULL, 0, "Tag of chain entry", HFILL }
12688 		},
12689 
12690 		{ &hf_smb2_acct_name,
12691 			{ "Account", "smb2.acct", FT_STRING, STR_UNICODE,
12692 			NULL, 0, "Account Name", HFILL }
12693 		},
12694 
12695 		{ &hf_smb2_domain_name,
12696 			{ "Domain", "smb2.domain", FT_STRING, STR_UNICODE,
12697 			NULL, 0, "Domain Name", HFILL }
12698 		},
12699 
12700 		{ &hf_smb2_host_name,
12701 			{ "Host", "smb2.host", FT_STRING, STR_UNICODE,
12702 			NULL, 0, "Host Name", HFILL }
12703 		},
12704 
12705 		{ &hf_smb2_signature,
12706 			{ "Signature", "smb2.signature", FT_BYTES, BASE_NONE,
12707 			NULL, 0, NULL, HFILL }
12708 		},
12709 
12710 		{ &hf_smb2_unknown,
12711 			{ "Unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
12712 			NULL, 0, NULL, HFILL }
12713 		},
12714 
12715 		{ &hf_smb2_twrp_timestamp,
12716 			{ "Timestamp", "smb2.twrp_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
12717 			NULL, 0, "TWrp timestamp", HFILL }
12718 		},
12719 
12720 		{ &hf_smb2_mxac_timestamp,
12721 			{ "Timestamp", "smb2.mxac_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
12722 			NULL, 0, "MxAc timestamp", HFILL }
12723 		},
12724 
12725 		{ &hf_smb2_mxac_status,
12726 			{ "Query Status", "smb2.mxac_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
12727 			&NT_errors_ext, 0, "NT Status code", HFILL }
12728 		},
12729 
12730 		{ &hf_smb2_qfid_fid,
12731 			{ "Opaque File ID", "smb2.qfid_fid", FT_BYTES, BASE_NONE,
12732 			NULL, 0, NULL, HFILL }
12733 		},
12734 
12735 		{ &hf_smb2_ses_flags_guest,
12736 			{ "Guest", "smb2.ses_flags.guest", FT_BOOLEAN, 16,
12737 			NULL, SES_FLAGS_GUEST, NULL, HFILL }
12738 		},
12739 
12740 		{ &hf_smb2_ses_flags_null,
12741 			{ "Null", "smb2.ses_flags.null", FT_BOOLEAN, 16,
12742 			NULL, SES_FLAGS_NULL, NULL, HFILL }
12743 		},
12744 
12745 		{ &hf_smb2_ses_flags_encrypt,
12746 			{ "Encrypt", "smb2.ses_flags.encrypt", FT_BOOLEAN, 16,
12747 			NULL, SES_FLAGS_ENCRYPT, NULL, HFILL }},
12748 
12749 		{ &hf_smb2_secmode_flags_sign_required,
12750 			{ "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
12751 			NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }
12752 		},
12753 
12754 		{ &hf_smb2_secmode_flags_sign_enabled,
12755 			{ "Signing enabled", "smb2.sec_mode.sign_enabled", FT_BOOLEAN, 8,
12756 			NULL, NEGPROT_SIGN_ENABLED, "Is signing enabled", HFILL }
12757 		},
12758 
12759 		{ &hf_smb2_ses_req_flags,
12760 			{ "Flags", "smb2.ses_req_flags", FT_UINT8, BASE_DEC,
12761 			NULL, 0, NULL, HFILL }
12762 		},
12763 
12764 		{ &hf_smb2_ses_req_flags_session_binding,
12765 			{ "Session Binding Request", "smb2.ses_req_flags.session_binding", FT_BOOLEAN, 8,
12766 			NULL, SES_REQ_FLAGS_SESSION_BINDING, "The client wants to bind to an existing session", HFILL }
12767 		},
12768 
12769 		{ &hf_smb2_cap_dfs,
12770 			{ "DFS", "smb2.capabilities.dfs", FT_BOOLEAN, 32,
12771 			TFS(&tfs_cap_dfs), NEGPROT_CAP_DFS, "If the host supports dfs", HFILL }
12772 		},
12773 
12774 		{ &hf_smb2_cap_leasing,
12775 			{ "LEASING", "smb2.capabilities.leasing", FT_BOOLEAN, 32,
12776 			TFS(&tfs_cap_leasing), NEGPROT_CAP_LEASING, "If the host supports leasing", HFILL }
12777 		},
12778 
12779 		{ &hf_smb2_cap_large_mtu,
12780 			{ "LARGE MTU", "smb2.capabilities.large_mtu", FT_BOOLEAN, 32,
12781 			TFS(&tfs_cap_large_mtu), NEGPROT_CAP_LARGE_MTU, "If the host supports LARGE MTU", HFILL }
12782 		},
12783 
12784 		{ &hf_smb2_cap_multi_channel,
12785 			{ "MULTI CHANNEL", "smb2.capabilities.multi_channel", FT_BOOLEAN, 32,
12786 			TFS(&tfs_cap_multi_channel), NEGPROT_CAP_MULTI_CHANNEL, "If the host supports MULTI CHANNEL", HFILL }
12787 		},
12788 
12789 		{ &hf_smb2_cap_persistent_handles,
12790 			{ "PERSISTENT HANDLES", "smb2.capabilities.persistent_handles", FT_BOOLEAN, 32,
12791 			TFS(&tfs_cap_persistent_handles), NEGPROT_CAP_PERSISTENT_HANDLES, "If the host supports PERSISTENT HANDLES", HFILL }
12792 		},
12793 
12794 		{ &hf_smb2_cap_directory_leasing,
12795 			{ "DIRECTORY LEASING", "smb2.capabilities.directory_leasing", FT_BOOLEAN, 32,
12796 			TFS(&tfs_cap_directory_leasing), NEGPROT_CAP_DIRECTORY_LEASING, "If the host supports DIRECTORY LEASING", HFILL }
12797 		},
12798 
12799 		{ &hf_smb2_cap_encryption,
12800 			{ "ENCRYPTION", "smb2.capabilities.encryption", FT_BOOLEAN, 32,
12801 			TFS(&tfs_cap_encryption), NEGPROT_CAP_ENCRYPTION, "If the host supports ENCRYPTION", HFILL }
12802 		},
12803 
12804 		{ &hf_smb2_max_trans_size,
12805 			{ "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
12806 			NULL, 0, NULL, HFILL }
12807 		},
12808 
12809 		{ &hf_smb2_max_read_size,
12810 			{ "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
12811 			NULL, 0, NULL, HFILL }
12812 		},
12813 
12814 		{ &hf_smb2_max_write_size,
12815 			{ "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
12816 			NULL, 0, NULL, HFILL }
12817 		},
12818 
12819 		{ &hf_smb2_channel,
12820 			{ "Channel", "smb2.channel", FT_UINT32, BASE_HEX,
12821 			VALS(smb2_channel_vals), 0, NULL, HFILL }
12822 		},
12823 
12824 		{ &hf_smb2_rdma_v1_offset,
12825 			{ "Offset", "smb2.buffer_descriptor.offset", FT_UINT64, BASE_DEC,
12826 			NULL, 0, NULL, HFILL }
12827 		},
12828 
12829 		{ &hf_smb2_rdma_v1_token,
12830 			{ "Token", "smb2.buffer_descriptor.token", FT_UINT32, BASE_HEX,
12831 			NULL, 0, NULL, HFILL }
12832 		},
12833 
12834 		{ &hf_smb2_rdma_v1_length,
12835 			{ "Length", "smb2.buffer_descriptor.length", FT_UINT32, BASE_DEC,
12836 			NULL, 0, NULL, HFILL }
12837 		},
12838 
12839 		{ &hf_smb2_share_flags,
12840 			{ "Share flags", "smb2.share_flags", FT_UINT32, BASE_HEX,
12841 			NULL, 0, NULL, HFILL }
12842 		},
12843 
12844 		{ &hf_smb2_share_flags_dfs,
12845 			{ "DFS", "smb2.share_flags.dfs", FT_BOOLEAN, 32,
12846 			NULL, SHARE_FLAGS_dfs, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }
12847 		},
12848 
12849 		{ &hf_smb2_share_flags_dfs_root,
12850 			{ "DFS root", "smb2.share_flags.dfs_root", FT_BOOLEAN, 32,
12851 			NULL, SHARE_FLAGS_dfs_root, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }
12852 		},
12853 
12854 		{ &hf_smb2_share_flags_restrict_exclusive_opens,
12855 			{ "Restrict exclusive opens", "smb2.share_flags.restrict_exclusive_opens", FT_BOOLEAN, 32,
12856 			NULL, SHARE_FLAGS_restrict_exclusive_opens, "The specified share disallows exclusive file opens that deny reads to an open file", HFILL }
12857 		},
12858 
12859 		{ &hf_smb2_share_flags_force_shared_delete,
12860 			{ "Force shared delete", "smb2.share_flags.force_shared_delete", FT_BOOLEAN, 32,
12861 			NULL, SHARE_FLAGS_force_shared_delete, "Shared files in the specified share can be forcibly deleted", HFILL }
12862 		},
12863 
12864 		{ &hf_smb2_share_flags_allow_namespace_caching,
12865 			{ "Allow namespace caching", "smb2.share_flags.allow_namespace_caching", FT_BOOLEAN, 32,
12866 			NULL, SHARE_FLAGS_allow_namespace_caching, "Clients are allowed to cache the namespace of the specified share", HFILL }
12867 		},
12868 
12869 		{ &hf_smb2_share_flags_access_based_dir_enum,
12870 			{ "Access based directory enum", "smb2.share_flags.access_based_dir_enum", FT_BOOLEAN, 32,
12871 			NULL, SHARE_FLAGS_access_based_dir_enum, "The server will filter directory entries based on the access permissions of the client", HFILL }
12872 		},
12873 
12874 		{ &hf_smb2_share_flags_force_levelii_oplock,
12875 			{ "Force level II oplock", "smb2.share_flags.force_levelii_oplock", FT_BOOLEAN, 32,
12876 			NULL, SHARE_FLAGS_force_levelii_oplock, "The server will not issue exclusive caching rights on this share", HFILL }
12877 		},
12878 
12879 		{ &hf_smb2_share_flags_enable_hash_v1,
12880 			{ "Enable hash V1", "smb2.share_flags.enable_hash_v1", FT_BOOLEAN, 32,
12881 			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 }
12882 		},
12883 
12884 		{ &hf_smb2_share_flags_enable_hash_v2,
12885 			{ "Enable hash V2", "smb2.share_flags.enable_hash_v2", FT_BOOLEAN, 32,
12886 			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 }
12887 		},
12888 
12889 		{ &hf_smb2_share_flags_encrypt_data,
12890 			{ "Encrypted data required", "smb2.share_flags.encrypt_data", FT_BOOLEAN, 32,
12891 			NULL, SHARE_FLAGS_encryption_required, "The share require data encryption", HFILL }
12892 		},
12893 
12894 		{ &hf_smb2_share_flags_identity_remoting,
12895 			{ "Identity Remoting", "smb2.share_flags.identity_remoting", FT_BOOLEAN, 32,
12896 			NULL, SHARE_FLAGS_identity_remoting, "The specified share supports Identity Remoting", HFILL }
12897 		},
12898 
12899 		{ &hf_smb2_share_flags_compress_data,
12900 			{ "Compressed IO", "smb2.share_flags.compress_data", FT_BOOLEAN, 32,
12901 			NULL, SHARE_FLAGS_compress_data, "The share supports compression of read/write messages", HFILL }
12902 		},
12903 
12904 		{ &hf_smb2_share_caching,
12905 			{ "Caching policy", "smb2.share.caching", FT_UINT32, BASE_HEX,
12906 			VALS(share_cache_vals), 0, NULL, HFILL }
12907 		},
12908 
12909 		{ &hf_smb2_share_caps,
12910 			{ "Share Capabilities", "smb2.share_caps", FT_UINT32, BASE_HEX,
12911 			NULL, 0, NULL, HFILL }
12912 		},
12913 
12914 		{ &hf_smb2_share_caps_dfs,
12915 			{ "DFS", "smb2.share_caps.dfs", FT_BOOLEAN, 32,
12916 			NULL, SHARE_CAPS_DFS, "The specified share is present in a DFS tree structure", HFILL }
12917 		},
12918 
12919 		{ &hf_smb2_share_caps_continuous_availability,
12920 			{ "CONTINUOUS AVAILABILITY", "smb2.share_caps.continuous_availability", FT_BOOLEAN, 32,
12921 			NULL, SHARE_CAPS_CONTINUOUS_AVAILABILITY, "The specified share is continuously available", HFILL }
12922 		},
12923 
12924 		{ &hf_smb2_share_caps_scaleout,
12925 			{ "SCALEOUT", "smb2.share_caps.scaleout", FT_BOOLEAN, 32,
12926 			NULL, SHARE_CAPS_SCALEOUT, "The specified share is a scaleout share", HFILL }
12927 		},
12928 
12929 		{ &hf_smb2_share_caps_cluster,
12930 			{ "CLUSTER", "smb2.share_caps.cluster", FT_BOOLEAN, 32,
12931 			NULL, SHARE_CAPS_CLUSTER, "The specified share is a cluster share", HFILL }
12932 		},
12933 
12934 		{ &hf_smb2_share_caps_assymetric,
12935 			{ "ASSYMETRIC", "smb2.share_caps.assymetric", FT_BOOLEAN, 32,
12936 			NULL, SHARE_CAPS_ASSYMETRIC, "The specified share allows dynamic changes in ownership of the share", HFILL }
12937 		},
12938 
12939 		{ &hf_smb2_share_caps_redirect_to_owner,
12940 			{ "REDIRECT_TO_OWNER", "smb2.share_caps.redirect_to_owner", FT_BOOLEAN, 32,
12941 			NULL, SHARE_CAPS_REDIRECT_TO_OWNER, "The specified share supports synchronous share level redirection", HFILL }
12942 		},
12943 
12944 		{ &hf_smb2_ioctl_flags,
12945 			{ "Flags", "smb2.ioctl.flags", FT_UINT32, BASE_HEX,
12946 			NULL, 0, NULL, HFILL }
12947 		},
12948 
12949 		{ &hf_smb2_min_count,
12950 			{ "Min Count", "smb2.min_count", FT_UINT32, BASE_DEC,
12951 			NULL, 0, NULL, HFILL }
12952 		},
12953 
12954 		{ &hf_smb2_remaining_bytes,
12955 			{ "Remaining Bytes", "smb2.remaining_bytes", FT_UINT32, BASE_DEC,
12956 			NULL, 0, NULL, HFILL }
12957 		},
12958 
12959 		{ &hf_smb2_channel_info_offset,
12960 			{ "Channel Info Offset", "smb2.channel_info_offset", FT_UINT16, BASE_DEC,
12961 			NULL, 0, NULL, HFILL }
12962 		},
12963 
12964 		{ &hf_smb2_channel_info_length,
12965 			{ "Channel Info Length", "smb2.channel_info_length", FT_UINT16, BASE_DEC,
12966 			NULL, 0, NULL, HFILL }
12967 		},
12968 
12969 		{ &hf_smb2_channel_info_blob,
12970 			{ "Channel Info Blob", "smb2.channel_info_blob", FT_NONE, BASE_NONE,
12971 			NULL, 0, NULL, HFILL }
12972 		},
12973 
12974 		{ &hf_smb2_ioctl_is_fsctl,
12975 			{ "Is FSCTL", "smb2.ioctl.is_fsctl", FT_BOOLEAN, 32,
12976 			NULL, 0x00000001, NULL, HFILL }
12977 		},
12978 
12979 		{ &hf_smb2_output_buffer_len,
12980 			{ "Output Buffer Length", "smb2.output_buffer_len", FT_UINT32, BASE_DEC,
12981 			NULL, 0, NULL, HFILL }
12982 		},
12983 
12984 		{ &hf_smb2_close_pq_attrib,
12985 			{ "PostQuery Attrib", "smb2.close.pq_attrib", FT_BOOLEAN, 16,
12986 			NULL, 0x0001, NULL, HFILL }
12987 		},
12988 
12989 		{ &hf_smb2_notify_watch_tree,
12990 			{ "Watch Tree", "smb2.notify.watch_tree", FT_BOOLEAN, 16,
12991 			NULL, 0x0001, NULL, HFILL }
12992 		},
12993 
12994 		{ &hf_smb2_notify_out_data,
12995 			{ "Out Data", "smb2.notify.out", FT_NONE, BASE_NONE,
12996 			NULL, 0, NULL, HFILL }
12997 		},
12998 
12999 		{ &hf_smb2_notify_info,
13000 			{ "Notify Info", "smb2.notify.info", FT_NONE, BASE_NONE,
13001 			NULL, 0, NULL, HFILL }
13002 		},
13003 
13004 		{ &hf_smb2_notify_next_offset,
13005 			{ "Next Offset", "smb2.notify.next_offset", FT_UINT32, BASE_HEX,
13006 			NULL, 0, "Offset to next entry in chain or 0", HFILL }
13007 		},
13008 
13009 		{ &hf_smb2_notify_action,
13010 			{ "Action", "smb2.notify.action", FT_UINT32, BASE_HEX,
13011 			VALS(notify_action_vals), 0, "Notify Action", HFILL }
13012 		},
13013 
13014 
13015 		{ &hf_smb2_find_flags_restart_scans,
13016 			{ "Restart Scans", "smb2.find.restart_scans", FT_BOOLEAN, 8,
13017 			NULL, SMB2_FIND_FLAG_RESTART_SCANS, NULL, HFILL }
13018 		},
13019 
13020 		{ &hf_smb2_find_flags_single_entry,
13021 			{ "Single Entry", "smb2.find.single_entry", FT_BOOLEAN, 8,
13022 			NULL, SMB2_FIND_FLAG_SINGLE_ENTRY, NULL, HFILL }
13023 		},
13024 
13025 		{ &hf_smb2_find_flags_index_specified,
13026 			{ "Index Specified", "smb2.find.index_specified", FT_BOOLEAN, 8,
13027 			NULL, SMB2_FIND_FLAG_INDEX_SPECIFIED, NULL, HFILL }
13028 		},
13029 
13030 		{ &hf_smb2_find_flags_reopen,
13031 			{ "Reopen", "smb2.find.reopen", FT_BOOLEAN, 8,
13032 			NULL, SMB2_FIND_FLAG_REOPEN, NULL, HFILL }
13033 		},
13034 
13035 		{ &hf_smb2_file_index,
13036 			{ "File Index", "smb2.file_index", FT_UINT32, BASE_HEX,
13037 			NULL, 0, NULL, HFILL }
13038 		},
13039 
13040 		{ &hf_smb2_file_directory_info,
13041 			{ "FileDirectoryInfo", "smb2.find.file_directory_info", FT_NONE, BASE_NONE,
13042 			NULL, 0, NULL, HFILL }
13043 		},
13044 
13045 		{ &hf_smb2_full_directory_info,
13046 			{ "FullDirectoryInfo", "smb2.find.full_directory_info", FT_NONE, BASE_NONE,
13047 			NULL, 0, NULL, HFILL }
13048 		},
13049 
13050 		{ &hf_smb2_both_directory_info,
13051 			{ "FileBothDirectoryInfo", "smb2.find.both_directory_info", FT_NONE, BASE_NONE,
13052 			NULL, 0, NULL, HFILL }
13053 		},
13054 
13055 		{ &hf_smb2_id_both_directory_info,
13056 			{ "FileIdBothDirectoryInfo", "smb2.find.id_both_directory_info", FT_NONE, BASE_NONE,
13057 			NULL, 0, NULL, HFILL }
13058 		},
13059 
13060 		{ &hf_smb2_posix_info,
13061 			{ "FilePosixInfo", "smb2.find.posix_info", FT_NONE, BASE_NONE,
13062 			NULL, 0, NULL, HFILL }
13063 		},
13064 
13065 		{ &hf_smb2_short_name_len,
13066 			{ "Short Name Length", "smb2.short_name_len", FT_UINT8, BASE_DEC,
13067 			NULL, 0, NULL, HFILL }
13068 		},
13069 
13070 		{ &hf_smb2_short_name,
13071 			{ "Short Name", "smb2.shortname", FT_STRING, STR_UNICODE,
13072 			NULL, 0, NULL, HFILL }
13073 		},
13074 
13075 		{ &hf_smb2_lock_info,
13076 			{ "Lock Info", "smb2.lock_info", FT_NONE, BASE_NONE,
13077 			NULL, 0, NULL, HFILL }
13078 		},
13079 
13080 		{ &hf_smb2_lock_length,
13081 			{ "Length", "smb2.lock_length", FT_UINT64, BASE_DEC,
13082 			NULL, 0, NULL, HFILL }
13083 		},
13084 
13085 		{ &hf_smb2_lock_flags,
13086 			{ "Flags", "smb2.lock_flags", FT_UINT32, BASE_HEX,
13087 			NULL, 0, NULL, HFILL }
13088 		},
13089 
13090 		{ &hf_smb2_lock_flags_shared,
13091 			{ "Shared", "smb2.lock_flags.shared", FT_BOOLEAN, 32,
13092 			NULL, 0x00000001, NULL, HFILL }
13093 		},
13094 
13095 		{ &hf_smb2_lock_flags_exclusive,
13096 			{ "Exclusive", "smb2.lock_flags.exclusive", FT_BOOLEAN, 32,
13097 			NULL, 0x00000002, NULL, HFILL }
13098 		},
13099 
13100 		{ &hf_smb2_lock_flags_unlock,
13101 			{ "Unlock", "smb2.lock_flags.unlock", FT_BOOLEAN, 32,
13102 			NULL, 0x00000004, NULL, HFILL }
13103 		},
13104 
13105 		{ &hf_smb2_lock_flags_fail_immediately,
13106 			{ "Fail Immediately", "smb2.lock_flags.fail_immediately", FT_BOOLEAN, 32,
13107 			NULL, 0x00000010, NULL, HFILL }
13108 		},
13109 
13110 		{ &hf_smb2_error_context_count,
13111 			{ "Error Context Count", "smb2.error.context_count", FT_UINT8, BASE_DEC,
13112 			NULL, 0, NULL, HFILL }
13113 		},
13114 
13115 		{ &hf_smb2_error_reserved,
13116 			{ "Reserved", "smb2.error.reserved", FT_UINT8, BASE_HEX,
13117 			NULL, 0, NULL, HFILL }
13118 		},
13119 
13120 		{ &hf_smb2_error_byte_count,
13121 			{ "Byte Count", "smb2.error.byte_count", FT_UINT32, BASE_DEC,
13122 			NULL, 0, NULL, HFILL }
13123 		},
13124 
13125 		{ &hf_smb2_error_data,
13126 			{ "Error Data", "smb2.error.data", FT_BYTES, BASE_NONE,
13127 			NULL, 0, NULL, HFILL }
13128 		},
13129 
13130 		{ &hf_smb2_error_context,
13131 			{ "Error Context", "smb2.error.context", FT_BYTES, BASE_NONE,
13132 			NULL, 0, NULL, HFILL }
13133 		},
13134 
13135 		{ &hf_smb2_error_context_id,
13136 			{ "Type", "smb2.error.context.id", FT_UINT32, BASE_HEX,
13137 			VALS(smb2_error_id_vals), 0, NULL, HFILL }
13138 		},
13139 
13140 		{ &hf_smb2_error_context_length,
13141 			{ "Type", "smb2.error.context.length", FT_UINT32, BASE_DEC,
13142 			NULL, 0, NULL, HFILL }
13143 		},
13144 
13145 		{ &hf_smb2_error_min_buf_length,
13146 			{ "Minimum required buffer length", "smb2.error.min_buf_length", FT_UINT32, BASE_DEC,
13147 			NULL, 0, NULL, HFILL }
13148 		},
13149 
13150 		{ &hf_smb2_error_redir_context,
13151 			{ "Share Redirect", "smb2.error.share_redirect", FT_NONE, BASE_NONE,
13152 			NULL, 0, NULL, HFILL }
13153 		},
13154 
13155 		{ &hf_smb2_error_redir_struct_size,
13156 			{ "Struct Size", "smb2.error.share_redirect.struct_size", FT_UINT32, BASE_DEC,
13157 			NULL, 0, NULL, HFILL }
13158 		},
13159 
13160 		{ &hf_smb2_error_redir_notif_type,
13161 			{ "Notification Type", "smb2.error.share_redirect.notif_type", FT_UINT32, BASE_DEC,
13162 			NULL, 0, NULL, HFILL }
13163 		},
13164 
13165 		{ &hf_smb2_error_redir_flags,
13166 			{ "Flags", "smb2.error.share_redirect.flags", FT_UINT16, BASE_HEX,
13167 			NULL, 0, NULL, HFILL }
13168 		},
13169 
13170 		{ &hf_smb2_error_redir_target_type,
13171 			{ "Target Type", "smb2.error.share_redirect.target_type", FT_UINT16, BASE_HEX,
13172 			NULL, 0, NULL, HFILL }
13173 		},
13174 
13175 		{ &hf_smb2_error_redir_ip_count,
13176 			{ "IP Addr Count", "smb2.error.share_redirect.ip_count", FT_UINT32, BASE_DEC,
13177 			NULL, 0, NULL, HFILL }
13178 		},
13179 
13180 		{ &hf_smb2_error_redir_ip_list,
13181 			{ "IP Addr List", "smb2.error.share_redirect.ip_list", FT_NONE, BASE_NONE,
13182 			NULL, 0, NULL, HFILL }
13183 		},
13184 
13185 		{ &hf_smb2_error_redir_res_name,
13186 			{ "Resource Name", "smb2.error.share_redirect.res_name", FT_STRING, STR_UNICODE,
13187 			NULL, 0, NULL, HFILL }
13188 		},
13189 
13190 		{ &hf_smb2_reserved,
13191 			{ "Reserved", "smb2.reserved", FT_BYTES, BASE_NONE,
13192 			NULL, 0, NULL, HFILL }
13193 		},
13194 
13195 		{ &hf_smb2_reserved_random,
13196 			{ "Reserved (Random)", "smb2.reserved.random", FT_BYTES, BASE_NONE,
13197 			NULL, 0, "Reserved bytes, random data", HFILL }
13198 		},
13199 
13200 		{ &hf_smb2_root_directory_mbz,
13201 			{ "Root Dir Handle (MBZ)", "smb2.root_directory", FT_BYTES, BASE_NONE,
13202 			NULL, 0, NULL, HFILL }
13203 		},
13204 
13205 		{ &hf_smb2_dhnq_buffer_reserved,
13206 			{ "Reserved", "smb2.dhnq_buffer_reserved", FT_UINT64, BASE_HEX,
13207 			NULL, 0, NULL, HFILL }
13208 		},
13209 
13210 		{ &hf_smb2_dh2x_buffer_timeout,
13211 			{ "Timeout", "smb2.dh2x.timeout", FT_UINT32, BASE_DEC,
13212 			NULL, 0, NULL, HFILL }
13213 		},
13214 
13215 		{ &hf_smb2_dh2x_buffer_flags,
13216 			{ "Flags", "smb2.dh2x.flags", FT_UINT32, BASE_HEX,
13217 			NULL, 0, NULL, HFILL }
13218 		},
13219 
13220 		{ &hf_smb2_dh2x_buffer_flags_persistent_handle,
13221 			{ "Persistent Handle", "smb2.dh2x.flags.persistent_handle", FT_BOOLEAN, 32,
13222 			NULL, SMB2_DH2X_FLAGS_PERSISTENT_HANDLE, NULL, HFILL }
13223 		},
13224 
13225 		{ &hf_smb2_dh2x_buffer_reserved,
13226 			{ "Reserved", "smb2.dh2x.reserved", FT_UINT64, BASE_HEX,
13227 			NULL, 0, NULL, HFILL }
13228 		},
13229 
13230 		{ &hf_smb2_dh2x_buffer_create_guid,
13231 			{ "Create Guid", "smb2.dh2x.create_guid", FT_GUID, BASE_NONE,
13232 			NULL, 0, NULL, HFILL }
13233 		},
13234 
13235 		{ &hf_smb2_APP_INSTANCE_buffer_struct_size,
13236 			{ "Struct Size", "smb2.app_instance.struct_size", FT_UINT16, BASE_DEC,
13237 			NULL, 0, NULL, HFILL }
13238 		},
13239 
13240 		{ &hf_smb2_APP_INSTANCE_buffer_reserved,
13241 			{ "Reserved", "smb2.app_instance.reserved", FT_UINT16, BASE_HEX,
13242 			NULL, 0, NULL, HFILL }
13243 		},
13244 
13245 		{ &hf_smb2_APP_INSTANCE_buffer_app_guid,
13246 			{ "Application Guid", "smb2.app_instance.app_guid", FT_GUID, BASE_NONE,
13247 			NULL, 0, NULL, HFILL }
13248 		},
13249 
13250 		{ &hf_smb2_svhdx_open_device_context_version,
13251 			{ "Version", "smb2.svhdx_open_device_context.version", FT_UINT32, BASE_DEC,
13252 			NULL, 0, NULL, HFILL }
13253 		},
13254 
13255 		{ &hf_smb2_svhdx_open_device_context_has_initiator_id,
13256 			{ "HasInitiatorId", "smb2.svhdx_open_device_context.initiator_has_id", FT_BOOLEAN, 8,
13257 			TFS(&tfs_smb2_svhdx_has_initiator_id), 0, "Whether the host has an initiator", HFILL }
13258 		},
13259 
13260 		{ &hf_smb2_svhdx_open_device_context_reserved,
13261 			{ "Reserved", "smb2.svhdx_open_device_context.reserved", FT_BYTES, BASE_NONE,
13262 			NULL, 0, NULL, HFILL }
13263 		},
13264 
13265 		{ &hf_smb2_svhdx_open_device_context_initiator_id,
13266 			{ "InitiatorId", "smb2.svhdx_open_device_context.initiator_id", FT_GUID, BASE_NONE,
13267 			NULL, 0, NULL, HFILL }
13268 		},
13269 
13270 		{ &hf_smb2_svhdx_open_device_context_flags,
13271 			{ "Flags", "smb2.svhdx_open_device_context.flags", FT_UINT32, BASE_HEX,
13272 			NULL, 0, NULL, HFILL }
13273 		},
13274 
13275 		{ &hf_smb2_svhdx_open_device_context_originator_flags,
13276 			{ "OriginatorFlags", "smb2.svhdx_open_device_context.originator_flags", FT_UINT32, BASE_HEX,
13277 			VALS(originator_flags_vals), 0, NULL, HFILL }
13278 		},
13279 
13280 		{ &hf_smb2_svhdx_open_device_context_open_request_id,
13281 			{ "OpenRequestId","smb2.svhxd_open_device_context.open_request_id", FT_UINT64, BASE_HEX,
13282 			 NULL, 0, NULL, HFILL }
13283 		},
13284 
13285 		{ &hf_smb2_svhdx_open_device_context_initiator_host_name_len,
13286 			{ "HostNameLength", "smb2.svhxd_open_device_context.initiator_host_name_len", FT_UINT16, BASE_DEC,
13287 			 NULL, 0, NULL, HFILL }
13288 		},
13289 
13290 		{ &hf_smb2_svhdx_open_device_context_initiator_host_name,
13291 			{ "HostName", "smb2.svhdx_open_device_context.host_name", FT_STRING, STR_UNICODE,
13292 			 NULL, 0, NULL, HFILL }
13293 		},
13294 
13295 		{ &hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
13296 			{ "VirtualDiskPropertiesInitialized", "smb2.svhdx_open_device_context.virtual_disk_properties_initialized", FT_BOOLEAN, 32,
13297 			NULL, 0, "Whether VirtualSectorSize, PhysicalSectorSize, and VirtualSize fields are filled", HFILL }
13298 		},
13299 
13300 		{ &hf_smb2_svhdx_open_device_context_server_service_version,
13301 			{ "ServerServiceVersion", "smb2.svhdx_open_device_context.server_service_version", FT_UINT32, BASE_DEC,
13302 			NULL, 0, "The current version of the protocol running on the server", HFILL }
13303 		},
13304 
13305 		{ &hf_smb2_svhdx_open_device_context_virtual_sector_size,
13306 			{ "VirtualSectorSize", "smb2.svhdx_open_device_context.virtual_sector_size", FT_UINT32, BASE_DEC,
13307 			NULL, 0, "The virtual sector size of the virtual disk", HFILL }
13308 		},
13309 
13310 		{ &hf_smb2_svhdx_open_device_context_physical_sector_size,
13311 			{ "PhysicalSectorSize", "smb2.svhdx_open_device_context.physical_sector_size", FT_UINT32, BASE_DEC,
13312 			NULL, 0, "The physical sector size of the virtual disk", HFILL }
13313 		},
13314 
13315 		{ &hf_smb2_svhdx_open_device_context_virtual_size,
13316 			{ "VirtualSize", "smb2.svhdx_open_device_context.virtual_size", FT_UINT64, BASE_DEC,
13317 			NULL, 0, "The current length of the virtual disk, in bytes", HFILL }
13318 		},
13319 
13320 		{ &hf_smb2_app_instance_version_struct_size,
13321 			{ "Struct Size", "smb2.app_instance_version.struct_size", FT_UINT16, BASE_DEC,
13322 			NULL, 0, NULL, HFILL }
13323 		},
13324 
13325 		{ &hf_smb2_app_instance_version_reserved,
13326 			{ "Reserved", "smb2.app_instance_version.reserved", FT_UINT16, BASE_DEC,
13327 			NULL, 0, NULL, HFILL }
13328 		},
13329 
13330 		{ &hf_smb2_app_instance_version_padding,
13331 			{ "Padding", "smb2.app_instance_version.padding", FT_UINT32, BASE_HEX,
13332 			NULL, 0, NULL, HFILL }
13333 		},
13334 
13335 		{ &hf_smb2_app_instance_version_high,
13336 			{ "AppInstanceVersionHigh", "smb2.app_instance_version.version.high", FT_UINT64, BASE_DEC,
13337 			NULL, 0, NULL, HFILL }
13338 		},
13339 
13340 		{ &hf_smb2_app_instance_version_low,
13341 			{ "AppInstanceVersionLow", "smb2.app_instance_version.version.low", FT_UINT64, BASE_DEC,
13342 			NULL, 0, NULL, HFILL }
13343 		},
13344 
13345 		{ &hf_smb2_posix_perms,
13346 			{ "POSIX perms", "smb2.posix_perms", FT_UINT32, BASE_OCT,
13347 			NULL, 0, NULL, HFILL }
13348 		},
13349 
13350 		{ &hf_smb2_aapl_command_code,
13351 			{ "Command code", "smb2.aapl.command_code", FT_UINT32, BASE_DEC,
13352 			VALS(aapl_command_code_vals), 0, NULL, HFILL }
13353 		},
13354 
13355 		{ &hf_smb2_aapl_reserved,
13356 			{ "Reserved", "smb2.aapl.reserved", FT_UINT32, BASE_HEX,
13357 			NULL, 0, NULL, HFILL }
13358 		},
13359 
13360 		{ &hf_smb2_aapl_server_query_bitmask,
13361 			{ "Query bitmask", "smb2.aapl.query_bitmask", FT_UINT64, BASE_HEX,
13362 			NULL, 0, NULL, HFILL }
13363 		},
13364 
13365 		{ &hf_smb2_aapl_server_query_bitmask_server_caps,
13366 			{ "Server capabilities", "smb2.aapl.bitmask.server_caps", FT_BOOLEAN, 64,
13367 			NULL, SMB2_AAPL_SERVER_CAPS, NULL, HFILL }
13368 		},
13369 
13370 		{ &hf_smb2_aapl_server_query_bitmask_volume_caps,
13371 			{ "Volume capabilities", "smb2.aapl.bitmask.volume_caps", FT_BOOLEAN, 64,
13372 			NULL, SMB2_AAPL_VOLUME_CAPS, NULL, HFILL }
13373 		},
13374 
13375 		{ &hf_smb2_aapl_server_query_bitmask_model_info,
13376 			{ "Model information", "smb2.aapl.bitmask.model_info", FT_BOOLEAN, 64,
13377 			NULL, SMB2_AAPL_MODEL_INFO, NULL, HFILL }
13378 		},
13379 
13380 		{ &hf_smb2_aapl_server_query_caps,
13381 			{ "Client/Server capabilities", "smb2.aapl.caps", FT_UINT64, BASE_HEX,
13382 			NULL, 0, NULL, HFILL }
13383 		},
13384 
13385 		{ &hf_smb2_aapl_server_query_caps_supports_read_dir_attr,
13386 			{ "Supports READDIRATTR", "smb2.aapl.caps.supports_read_dir_addr", FT_BOOLEAN, 64,
13387 			NULL, SMB2_AAPL_SUPPORTS_READ_DIR_ATTR, NULL, HFILL }
13388 		},
13389 
13390 		{ &hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
13391 			{ "Supports macOS copyfile", "smb2.aapl.caps.supports_osx_copyfile", FT_BOOLEAN, 64,
13392 			NULL, SMB2_AAPL_SUPPORTS_OSX_COPYFILE, NULL, HFILL }
13393 		},
13394 
13395 		{ &hf_smb2_aapl_server_query_caps_unix_based,
13396 			{ "UNIX-based", "smb2.aapl.caps.unix_based", FT_BOOLEAN, 64,
13397 			NULL, SMB2_AAPL_UNIX_BASED, NULL, HFILL }
13398 		},
13399 
13400 		{ &hf_smb2_aapl_server_query_caps_supports_nfs_ace,
13401 			{ "Supports NFS ACE", "smb2.aapl.supports_nfs_ace", FT_BOOLEAN, 64,
13402 			NULL, SMB2_AAPL_SUPPORTS_NFS_ACE, NULL, HFILL }
13403 		},
13404 
13405 		{ &hf_smb2_aapl_server_query_volume_caps,
13406 			{ "Volume capabilities", "smb2.aapl.volume_caps", FT_UINT64, BASE_HEX,
13407 			NULL, 0, NULL, HFILL }
13408 		},
13409 
13410 		{ &hf_smb2_aapl_server_query_volume_caps_support_resolve_id,
13411 			{ "Supports Resolve ID", "smb2.aapl.volume_caps.supports_resolve_id", FT_BOOLEAN, 64,
13412 			NULL, SMB2_AAPL_SUPPORTS_RESOLVE_ID, NULL, HFILL }
13413 		},
13414 
13415 		{ &hf_smb2_aapl_server_query_volume_caps_case_sensitive,
13416 			{ "Case sensitive", "smb2.aapl.volume_caps.case_sensitive", FT_BOOLEAN, 64,
13417 			NULL, SMB2_AAPL_CASE_SENSITIVE, NULL, HFILL }
13418 		},
13419 
13420 		{ &hf_smb2_aapl_server_query_volume_caps_supports_full_sync,
13421 			{ "Supports full sync", "smb2.aapl.volume_caps.supports_full_sync", FT_BOOLEAN, 64,
13422 			NULL, SMB2_AAPL_SUPPORTS_FULL_SYNC, NULL, HFILL }
13423 		},
13424 
13425 		{ &hf_smb2_aapl_server_query_model_string,
13426 			{ "Model string", "smb2.aapl.model_string", FT_UINT_STRING, STR_UNICODE,
13427 			NULL, 0, NULL, HFILL }
13428 		},
13429 
13430 		{ &hf_smb2_aapl_server_query_server_path,
13431 			{ "Server path", "smb2.aapl.server_path", FT_UINT_STRING, STR_UNICODE,
13432 			NULL, 0, NULL, HFILL }
13433 		},
13434 
13435 		{ &hf_smb2_transform_signature,
13436 			{ "Signature", "smb2.header.transform.signature", FT_BYTES, BASE_NONE,
13437 			NULL, 0, NULL, HFILL }
13438 		},
13439 
13440 		{ &hf_smb2_transform_nonce,
13441 			{ "Nonce", "smb2.header.transform.nonce", FT_BYTES, BASE_NONE,
13442 			NULL, 0, NULL, HFILL }
13443 		},
13444 
13445 		{ &hf_smb2_transform_msg_size,
13446 			{ "Message size", "smb2.header.transform.msg_size", FT_UINT32, BASE_DEC,
13447 			NULL, 0, NULL, HFILL }
13448 		},
13449 
13450 		{ &hf_smb2_transform_reserved,
13451 			{ "Reserved", "smb2.header.transform.reserved", FT_BYTES, BASE_NONE,
13452 			NULL, 0, NULL, HFILL }
13453 		},
13454 
13455 		/* SMB2 header flags  */
13456 		{ &hf_smb2_transform_flags,
13457 			{ "Flags", "smb2.header.transform.flags", FT_UINT16, BASE_HEX,
13458 			NULL, 0, "SMB2 transform flags", HFILL }
13459 		},
13460 
13461 		{ &hf_smb2_transform_flags_encrypted,
13462 			{ "Encrypted", "smb2.header.transform.flags.encrypted", FT_BOOLEAN, 16,
13463 			NULL, SMB2_TRANSFORM_FLAGS_ENCRYPTED,
13464 			"Whether the payload is encrypted", HFILL }
13465 		},
13466 
13467 		{ &hf_smb2_transform_encrypted_data,
13468 			{ "Data", "smb2.header.transform.enc_data", FT_BYTES, BASE_NONE,
13469 			NULL, 0, NULL, HFILL }
13470 		},
13471 
13472 		{ &hf_smb2_comp_transform_orig_size,
13473 			{ "OriginalSize", "smb2.header.comp_transform.original_size", FT_UINT32, BASE_DEC,
13474 			NULL, 0, NULL, HFILL }
13475 		},
13476 
13477 		{ &hf_smb2_comp_transform_comp_alg,
13478 			{ "CompressionAlgorithm", "smb2.header.comp_transform.comp_alg", FT_UINT16, BASE_HEX,
13479 			VALS(smb2_comp_alg_types), 0, NULL, HFILL }
13480 		},
13481 
13482 		{ &hf_smb2_comp_transform_flags,
13483 			{ "Flags", "smb2.header.comp_transform.flags", FT_UINT16, BASE_HEX,
13484 			  VALS(smb2_comp_transform_flags_vals), 0, NULL, HFILL }
13485 		},
13486 
13487 		{ &hf_smb2_comp_transform_offset,
13488 			{ "Offset", "smb2.header.comp_transform.offset", FT_UINT32, BASE_HEX,
13489 			NULL, 0, NULL, HFILL }
13490 		},
13491 
13492 		{ &hf_smb2_comp_transform_length,
13493 			{ "Length", "smb2.header.comp_transform.length", FT_UINT32, BASE_HEX,
13494 			NULL, 0, NULL, HFILL }
13495 		},
13496 
13497 		{ &hf_smb2_comp_transform_data,
13498 		  { "CompressedData", "smb2.header.comp_transform.data", FT_BYTES, BASE_NONE,
13499 		    NULL, 0, NULL, HFILL }
13500 		},
13501 
13502 		{ &hf_smb2_comp_transform_orig_payload_size,
13503 		  { "OriginalPayloadSize", "smb2.header.comp_transform.orig_payload_size", FT_UINT32, BASE_DEC,
13504 		    NULL, 0, NULL, HFILL }
13505 		},
13506 
13507 		{ &hf_smb2_comp_pattern_v1_pattern,
13508 		  { "Pattern", "smb2.pattern_v1.pattern", FT_UINT8, BASE_HEX,
13509 		    NULL, 0, NULL, HFILL }
13510 		},
13511 
13512 		{ &hf_smb2_comp_pattern_v1_reserved1,
13513 		  { "Reserved1", "smb2.pattern_v1.reserved1", FT_UINT8, BASE_HEX,
13514 		    NULL, 0, NULL, HFILL }
13515 		},
13516 
13517 		{ &hf_smb2_comp_pattern_v1_reserved2,
13518 		  { "Reserved2", "smb2.pattern_v1.reserved2", FT_UINT16, BASE_HEX,
13519 		    NULL, 0, NULL, HFILL }
13520 		},
13521 
13522 		{ &hf_smb2_comp_pattern_v1_repetitions,
13523 		  { "Repetitions", "smb2.pattern_v1.repetitions", FT_UINT32, BASE_DEC,
13524 		    NULL, 0, NULL, HFILL }
13525 		},
13526 
13527 		{ &hf_smb2_protocol_id,
13528 			{ "ProtocolId", "smb2.protocol_id", FT_UINT32, BASE_HEX,
13529 			NULL, 0, NULL, HFILL }
13530 		},
13531 
13532 		{ &hf_smb2_truncated,
13533 			{ "Truncated...", "smb2.truncated", FT_NONE, BASE_NONE,
13534 			NULL, 0, NULL, HFILL }
13535 		},
13536 
13537 		{ &hf_smb2_pipe_fragment_overlap,
13538 			{ "Fragment overlap", "smb2.pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
13539 			NULL, 0x0, "Fragment overlaps with other fragments", HFILL }
13540 		},
13541 
13542 		{ &hf_smb2_pipe_fragment_overlap_conflict,
13543 			{ "Conflicting data in fragment overlap", "smb2.pipe.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE,
13544 			NULL, 0x0, NULL, HFILL }
13545 		},
13546 
13547 		{ &hf_smb2_pipe_fragment_multiple_tails,
13548 			{ "Multiple tail fragments found", "smb2.pipe.fragment.multipletails", FT_BOOLEAN, BASE_NONE,
13549 			NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }
13550 		},
13551 
13552 		{ &hf_smb2_pipe_fragment_too_long_fragment,
13553 			{ "Fragment too long", "smb2.pipe.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE,
13554 			NULL, 0x0, "Fragment contained data past end of packet", HFILL }
13555 		},
13556 
13557 		{ &hf_smb2_pipe_fragment_error,
13558 			{ "Defragmentation error", "smb2.pipe.fragment.error", FT_FRAMENUM, BASE_NONE,
13559 			NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }
13560 		},
13561 
13562 		{ &hf_smb2_pipe_fragment_count,
13563 			{ "Fragment count", "smb2.pipe.fragment.count", FT_UINT32, BASE_DEC,
13564 			NULL, 0x0, NULL, HFILL }
13565 		},
13566 
13567 		{ &hf_smb2_pipe_fragment,
13568 			{ "Fragment SMB2 Named Pipe", "smb2.pipe.fragment", FT_FRAMENUM, BASE_NONE,
13569 			NULL, 0x0, NULL, HFILL }
13570 		},
13571 
13572 		{ &hf_smb2_pipe_fragments,
13573 			{ "Reassembled SMB2 Named Pipe fragments", "smb2.pipe.fragments", FT_NONE, BASE_NONE,
13574 			NULL, 0x0, NULL, HFILL }
13575 		},
13576 
13577 		{ &hf_smb2_pipe_reassembled_in,
13578 			{ "This SMB2 Named Pipe payload is reassembled in frame", "smb2.pipe.reassembled_in", FT_FRAMENUM, BASE_NONE,
13579 			NULL, 0x0, "The Named Pipe PDU is completely reassembled in this frame", HFILL }
13580 		},
13581 
13582 		{ &hf_smb2_pipe_reassembled_length,
13583 			{ "Reassembled SMB2 Named Pipe length", "smb2.pipe.reassembled.length", FT_UINT32, BASE_DEC,
13584 			NULL, 0x0, "The total length of the reassembled payload", HFILL }
13585 		},
13586 
13587 		{ &hf_smb2_pipe_reassembled_data,
13588 			{ "Reassembled SMB2 Named Pipe Data", "smb2.pipe.reassembled.data", FT_BYTES, BASE_NONE,
13589 			NULL, 0x0, "The reassembled payload", HFILL }
13590 		},
13591 
13592 		{ &hf_smb2_cchunk_resume_key,
13593 			{ "ResumeKey", "smb2.fsctl.cchunk.resume_key", FT_BYTES, BASE_NONE,
13594 			NULL, 0x0, "Opaque data representing source of copy", HFILL }
13595 		},
13596 
13597 		{ &hf_smb2_cchunk_count,
13598 			{ "Chunk Count", "smb2.fsctl.cchunk.count", FT_UINT32, BASE_DEC,
13599 			NULL, 0x0, NULL, HFILL }
13600 		},
13601 
13602 		{ &hf_smb2_cchunk_src_offset,
13603 			{ "Source Offset", "smb2.fsctl.cchunk.src_offset", FT_UINT64, BASE_DEC,
13604 			NULL, 0x0, NULL, HFILL }
13605 		},
13606 
13607 		{ &hf_smb2_cchunk_dst_offset,
13608 			{ "Target Offset", "smb2.fsctl.cchunk.dst_offset", FT_UINT64, BASE_DEC,
13609 			NULL, 0x0, NULL, HFILL }
13610 		},
13611 
13612 		{ &hf_smb2_cchunk_xfer_len,
13613 			{ "Transfer Length", "smb2.fsctl.cchunk.xfer_len", FT_UINT32, BASE_DEC,
13614 			NULL, 0x0, NULL, HFILL }
13615 		},
13616 
13617 		{ &hf_smb2_cchunk_chunks_written,
13618 			{ "Chunks Written", "smb2.fsctl.cchunk.chunks_written", FT_UINT32, BASE_DEC,
13619 			NULL, 0x0, NULL, HFILL }
13620 		},
13621 
13622 		{ &hf_smb2_cchunk_bytes_written,
13623 			{ "Chunk Bytes Written", "smb2.fsctl.cchunk.bytes_written", FT_UINT32, BASE_DEC,
13624 			NULL, 0x0, NULL, HFILL }
13625 		},
13626 
13627 		{ &hf_smb2_cchunk_total_written,
13628 			{ "Total Bytes Written", "smb2.fsctl.cchunk.total_written", FT_UINT32, BASE_DEC,
13629 			NULL, 0x0, NULL, HFILL }
13630 		},
13631 		{ &hf_smb2_reparse_tag,
13632 			{ "Reparse Tag", "smb2.reparse_tag", FT_UINT32, BASE_HEX,
13633 			VALS(reparse_tag_vals), 0x0, NULL, HFILL }
13634 		},
13635 		{ &hf_smb2_reparse_guid,
13636 			{ "Reparse GUID", "smb2.reparse_guid", FT_NONE, BASE_NONE,
13637 			NULL, 0, NULL, HFILL }
13638 		},
13639 		{ &hf_smb2_reparse_data_length,
13640 			{ "Reparse Data Length", "smb2.reparse_data_length", FT_UINT16, BASE_DEC,
13641 			NULL, 0x0, NULL, HFILL }
13642 		},
13643 		{ &hf_smb2_reparse_data_buffer,
13644 			{ "Reparse Data Buffer", "smb2.reparse_data_buffer", FT_NONE, BASE_NONE,
13645 			NULL, 0, NULL, HFILL }
13646 		},
13647 		{ &hf_smb2_nfs_type,
13648 			{ "NFS file type", "smb2.nfs.type", FT_UINT64, BASE_HEX|BASE_VAL64_STRING,
13649 			VALS64(nfs_type_vals), 0x0, NULL, HFILL }
13650 		},
13651 		{ &hf_smb2_nfs_symlink_target,
13652 			{ "Symlink Target", "smb2.nfs.symlink.target", FT_STRING,
13653 			STR_UNICODE, NULL, 0x0, NULL, HFILL }
13654 		},
13655 		{ &hf_smb2_nfs_chr_major,
13656 			{ "Major", "smb2.nfs.char.major", FT_UINT32,
13657 			BASE_HEX, NULL, 0x0, NULL, HFILL }
13658 		},
13659 		{ &hf_smb2_nfs_chr_minor,
13660 			{ "Minor", "smb2.nfs.char.minor", FT_UINT32,
13661 			BASE_HEX, NULL, 0x0, NULL, HFILL }
13662 		},
13663 		{ &hf_smb2_nfs_blk_major,
13664 			{ "Major", "smb2.nfs.block.major", FT_UINT32,
13665 			BASE_HEX, NULL, 0x0, NULL, HFILL }
13666 		},
13667 		{ &hf_smb2_nfs_blk_minor,
13668 			{ "Minor", "smb2.nfs.block.minor", FT_UINT32,
13669 			BASE_HEX, NULL, 0x0, NULL, HFILL }
13670 		},
13671 		{ &hf_smb2_symlink_error_response,
13672 			{ "Symbolic Link Error Response", "smb2.symlink_error_response", FT_NONE, BASE_NONE,
13673 			NULL, 0, NULL, HFILL }
13674 		},
13675 		{ &hf_smb2_symlink_length,
13676 			{ "SymLink Length", "smb2.symlink.length", FT_UINT32,
13677 			BASE_DEC, NULL, 0x0, NULL, HFILL }
13678 		},
13679 		{ &hf_smb2_symlink_error_tag,
13680 			{ "SymLink Error Tag", "smb2.symlink.error_tag", FT_UINT32,
13681 			BASE_HEX, NULL, 0x0, NULL, HFILL }
13682 		},
13683 		{ &hf_smb2_unparsed_path_length,
13684 			{ "Unparsed Path Length", "smb2.symlink.unparsed_path_length", FT_UINT16, BASE_DEC,
13685 			NULL, 0x0, NULL, HFILL }
13686 		},
13687 		{ &hf_smb2_symlink_substitute_name,
13688 			{ "Substitute Name", "smb2.symlink.substitute_name", FT_STRING, STR_UNICODE,
13689 			NULL, 0x0, NULL, HFILL }
13690 		},
13691 		{ &hf_smb2_symlink_print_name,
13692 			{ "Print Name", "smb2.symlink.print_name", FT_STRING, STR_UNICODE,
13693 			NULL, 0x0, NULL, HFILL }
13694 		},
13695 		{ &hf_smb2_symlink_flags,
13696 			{ "Flags", "smb2.symlink.flags", FT_UINT32, BASE_DEC,
13697 			NULL, 0x0, NULL, HFILL }
13698 		},
13699 		{ &hf_smb2_fscc_file_attr,
13700 			{ "File Attributes", "smb2.file_attribute", FT_UINT32, BASE_HEX,
13701 			NULL, 0x0, NULL, HFILL }
13702 		},
13703 		{ &hf_smb2_fscc_file_attr_read_only,
13704 			{ "Read Only", "smb2.file_attribute.read_only", FT_BOOLEAN, 32,
13705 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL } },
13706 
13707 		{ &hf_smb2_fscc_file_attr_hidden,
13708 			{ "Hidden", "smb2.file_attribute.hidden", FT_BOOLEAN, 32,
13709 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL } },
13710 
13711 		{ &hf_smb2_fscc_file_attr_system,
13712 			{ "System", "smb2.file_attribute.system", FT_BOOLEAN, 32,
13713 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL } },
13714 
13715 		{ &hf_smb2_fscc_file_attr_directory,
13716 			{ "Directory", "smb2.file_attribute.directory", FT_BOOLEAN, 32,
13717 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL } },
13718 
13719 		{ &hf_smb2_fscc_file_attr_archive,
13720 			{ "Requires archived", "smb2.file_attribute.archive", FT_BOOLEAN, 32,
13721 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL } },
13722 
13723 		{ &hf_smb2_fscc_file_attr_normal,
13724 			{ "Normal", "smb2.file_attribute.normal", FT_BOOLEAN, 32,
13725 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL } },
13726 
13727 		{ &hf_smb2_fscc_file_attr_temporary,
13728 			{ "Temporary", "smb2.file_attribute.temporary", FT_BOOLEAN, 32,
13729 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL } },
13730 
13731 		{ &hf_smb2_fscc_file_attr_sparse_file,
13732 			{ "Sparse", "smb2.file_attribute.sparse", FT_BOOLEAN, 32,
13733 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_SPARSE_FILE, "Is this a sparse file?", HFILL } },
13734 
13735 		{ &hf_smb2_fscc_file_attr_reparse_point,
13736 			{ "Reparse Point", "smb2.file_attribute.reparse", FT_BOOLEAN, 32,
13737 			TFS(&tfs_fscc_file_attribute_reparse), SMB2_FSCC_FILE_ATTRIBUTE_REPARSE_POINT, "Does this file have an associated reparse point?", HFILL } },
13738 
13739 		{ &hf_smb2_fscc_file_attr_compressed,
13740 			{ "Compressed", "smb2.file_attribute.compressed", FT_BOOLEAN, 32,
13741 			TFS(&tfs_fscc_file_attribute_compressed), SMB2_FSCC_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL } },
13742 
13743 		{ &hf_smb2_fscc_file_attr_offline,
13744 			{ "Offline", "smb2.file_attribute.offline", FT_BOOLEAN, 32,
13745 			TFS(&tfs_fscc_file_attribute_offline), SMB2_FSCC_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL } },
13746 
13747 		{ &hf_smb2_fscc_file_attr_not_content_indexed,
13748 			{ "Not Content Indexed", "smb2.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
13749 			TFS(&tfs_fscc_file_attribute_not_content_indexed), SMB2_FSCC_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL } },
13750 
13751 		{ &hf_smb2_fscc_file_attr_encrypted,
13752 			{ "Encrypted", "smb2.file_attribute.encrypted", FT_BOOLEAN, 32,
13753 			TFS(&tfs_yes_no), SMB2_FSCC_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL } },
13754 
13755 		{ &hf_smb2_fscc_file_attr_integrity_stream,
13756 			{ "Integrity Stream", "smb2.file_attribute.integrity_stream", FT_BOOLEAN, 32,
13757 			TFS(&tfs_fscc_file_attribute_integrity_stream), SMB2_FSCC_FILE_ATTRIBUTE_INTEGRITY_STREAM, "Is this file configured with integrity support?", HFILL } },
13758 
13759 		{ &hf_smb2_fscc_file_attr_no_scrub_data,
13760 			{ "No Scrub Data", "smb2.file_attribute.no_scrub_data", FT_BOOLEAN, 32,
13761 			TFS(&tfs_fscc_file_attribute_no_scrub_data), SMB2_FSCC_FILE_ATTRIBUTE_NO_SCRUB_DATA, "Is this file configured to be excluded from the data integrity scan?", HFILL } },
13762 	};
13763 
13764 	static gint *ett[] = {
13765 		&ett_smb2,
13766 		&ett_smb2_ea,
13767 		&ett_smb2_olb,
13768 		&ett_smb2_header,
13769 		&ett_smb2_encrypted,
13770 		&ett_smb2_compressed,
13771 		&ett_smb2_decompressed,
13772 		&ett_smb2_command,
13773 		&ett_smb2_secblob,
13774 		&ett_smb2_negotiate_context_element,
13775 		&ett_smb2_file_basic_info,
13776 		&ett_smb2_file_standard_info,
13777 		&ett_smb2_file_internal_info,
13778 		&ett_smb2_file_ea_info,
13779 		&ett_smb2_file_access_info,
13780 		&ett_smb2_file_rename_info,
13781 		&ett_smb2_file_disposition_info,
13782 		&ett_smb2_file_position_info,
13783 		&ett_smb2_file_full_ea_info,
13784 		&ett_smb2_file_mode_info,
13785 		&ett_smb2_file_alignment_info,
13786 		&ett_smb2_file_all_info,
13787 		&ett_smb2_file_allocation_info,
13788 		&ett_smb2_file_endoffile_info,
13789 		&ett_smb2_file_alternate_name_info,
13790 		&ett_smb2_file_stream_info,
13791 		&ett_smb2_file_pipe_info,
13792 		&ett_smb2_file_compression_info,
13793 		&ett_smb2_file_network_open_info,
13794 		&ett_smb2_file_attribute_tag_info,
13795 		&ett_smb2_file_normalized_name_info,
13796 		&ett_smb2_fs_info_01,
13797 		&ett_smb2_fs_info_03,
13798 		&ett_smb2_fs_info_04,
13799 		&ett_smb2_fs_info_05,
13800 		&ett_smb2_fs_info_06,
13801 		&ett_smb2_fs_info_07,
13802 		&ett_smb2_fs_objectid_info,
13803 		&ett_smb2_sec_info_00,
13804 		&ett_smb2_additional_information_sec_mask,
13805 		&ett_smb2_quota_info,
13806 		&ett_smb2_query_quota_info,
13807 		&ett_smb2_tid_tree,
13808 		&ett_smb2_sesid_tree,
13809 		&ett_smb2_create_chain_element,
13810 		&ett_smb2_MxAc_buffer,
13811 		&ett_smb2_QFid_buffer,
13812 		&ett_smb2_RqLs_buffer,
13813 		&ett_smb2_ioctl_function,
13814 		&ett_smb2_FILE_OBJECTID_BUFFER,
13815 		&ett_smb2_flags,
13816 		&ett_smb2_sec_mode,
13817 		&ett_smb2_capabilities,
13818 		&ett_smb2_ses_req_flags,
13819 		&ett_smb2_ses_flags,
13820 		&ett_smb2_create_rep_flags,
13821 		&ett_smb2_lease_state,
13822 		&ett_smb2_lease_flags,
13823 		&ett_smb2_share_flags,
13824 		&ett_smb2_share_caps,
13825 		&ett_smb2_comp_alg_flags,
13826 		&ett_smb2_ioctl_flags,
13827 		&ett_smb2_ioctl_network_interface,
13828 		&ett_smb2_ioctl_sqos_opeations,
13829 		&ett_smb2_fsctl_range_data,
13830 		&ett_windows_sockaddr,
13831 		&ett_smb2_close_flags,
13832 		&ett_smb2_notify_info,
13833 		&ett_smb2_notify_flags,
13834 		&ett_smb2_rdma_v1,
13835 		&ett_smb2_write_flags,
13836 		&ett_smb2_find_flags,
13837 		&ett_smb2_file_directory_info,
13838 		&ett_smb2_both_directory_info,
13839 		&ett_smb2_id_both_directory_info,
13840 		&ett_smb2_full_directory_info,
13841 		&ett_smb2_posix_info,
13842 		&ett_smb2_file_name_info,
13843 		&ett_smb2_lock_info,
13844 		&ett_smb2_lock_flags,
13845 		&ett_smb2_DH2Q_buffer,
13846 		&ett_smb2_DH2C_buffer,
13847 		&ett_smb2_dh2x_flags,
13848 		&ett_smb2_APP_INSTANCE_buffer,
13849 		&ett_smb2_svhdx_open_device_context,
13850 		&ett_smb2_app_instance_version_buffer,
13851 		&ett_smb2_app_instance_version_buffer_version,
13852 		&ett_smb2_aapl_create_context_request,
13853 		&ett_smb2_aapl_server_query_bitmask,
13854 		&ett_smb2_aapl_server_query_caps,
13855 		&ett_smb2_aapl_create_context_response,
13856 		&ett_smb2_aapl_server_query_volume_caps,
13857 		&ett_smb2_integrity_flags,
13858 		&ett_smb2_buffercode,
13859 		&ett_smb2_ioctl_network_interface_capabilities,
13860 		&ett_smb2_tree_connect_flags,
13861 		&ett_qfr_entry,
13862 		&ett_smb2_pipe_fragment,
13863 		&ett_smb2_pipe_fragments,
13864 		&ett_smb2_cchunk_entry,
13865 		&ett_smb2_fsctl_odx_token,
13866 		&ett_smb2_symlink_error_response,
13867 		&ett_smb2_reparse_data_buffer,
13868 		&ett_smb2_error_data,
13869 		&ett_smb2_error_context,
13870 		&ett_smb2_error_redir_context,
13871 		&ett_smb2_error_redir_ip_list,
13872 		&ett_smb2_read_flags,
13873 		&ett_smb2_signature,
13874 		&ett_smb2_transform_flags,
13875 		&ett_smb2_fscc_file_attributes,
13876 		&ett_smb2_comp_pattern_v1,
13877 		&ett_smb2_comp_payload,
13878 	};
13879 
13880 	static ei_register_info ei[] = {
13881 		{ &ei_smb2_invalid_length, { "smb2.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
13882 		{ &ei_smb2_bad_response, { "smb2.bad_response", PI_MALFORMED, PI_ERROR, "Bad response", EXPFILL }},
13883 		{ &ei_smb2_invalid_getinfo_offset, { "smb2.invalid_getinfo_offset", PI_MALFORMED, PI_ERROR, "Input buffer offset isn't past the fixed data in the message", EXPFILL }},
13884 		{ &ei_smb2_invalid_getinfo_size, { "smb2.invalid_getinfo_size", PI_MALFORMED, PI_ERROR, "Input buffer length goes past the end of the message", EXPFILL }},
13885 		{ &ei_smb2_empty_getinfo_buffer, { "smb2.empty_getinfo_buffer", PI_PROTOCOL, PI_WARN, "Input buffer length is empty for a quota request", EXPFILL }},
13886 		{ &ei_smb2_invalid_signature, { "smb2.invalid_signature", PI_MALFORMED, PI_ERROR, "Invalid Signature", EXPFILL }},
13887 	};
13888 
13889 	expert_module_t* expert_smb2;
13890 
13891 	/* SessionID <=> SessionKey mappings for decryption */
13892 	uat_t *seskey_uat;
13893 
13894 	static uat_field_t seskey_uat_fields[] = {
13895 		UAT_FLD_BUFFER(seskey_list, id, "Session ID", "The session ID buffer, coded as hex string, as it appears on the wire (LE)."),
13896 		UAT_FLD_BUFFER(seskey_list, seskey, "Session Key", "The secret session key buffer, coded as 16-byte hex string."),
13897 		UAT_FLD_BUFFER(seskey_list, s2ckey, "Server-to-Client", "The AES-128 key used by the client to decrypt server messages, coded as 16-byte hex string."),
13898 		UAT_FLD_BUFFER(seskey_list, c2skey, "Client-to-Server", "The AES-128 key used by the server to decrypt client messages, coded as 16-byte hex string."),
13899 		UAT_END_FIELDS
13900 	};
13901 
13902 	proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
13903 					     "SMB2", "smb2");
13904 	proto_register_subtree_array(ett, array_length(ett));
13905 	proto_register_field_array(proto_smb2, hf, array_length(hf));
13906 	expert_smb2 = expert_register_protocol(proto_smb2);
13907 	expert_register_field_array(expert_smb2, ei, array_length(ei));
13908 
13909 	smb2_module = prefs_register_protocol(proto_smb2, NULL);
13910 	prefs_register_bool_preference(smb2_module, "eosmb2_take_name_as_fid",
13911 				       "Use the full file name as File ID when exporting an SMB2 object",
13912 				       "Whether the export object functionality will take the full path file name as file identifier",
13913 				       &eosmb2_take_name_as_fid);
13914 
13915 	prefs_register_bool_preference(smb2_module, "pipe_reassembly",
13916 		"Reassemble Named Pipes over SMB2",
13917 		"Whether the dissector should reassemble Named Pipes over SMB2 commands",
13918 		&smb2_pipe_reassembly);
13919 
13920 	prefs_register_bool_preference(smb2_module, "verify_signatures",
13921 		"Verify SMB2 Signatures",
13922 		"Whether the dissector should try to verify SMB2 signatures",
13923 		&smb2_verify_signatures);
13924 
13925 	seskey_uat = uat_new("Secret session key to use for decryption",
13926 			     sizeof(smb2_seskey_field_t),
13927 			     "smb2_seskey_list",
13928 			     TRUE,
13929 			     &seskey_list,
13930 			     &num_seskey_list,
13931 			     (UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS),
13932 			     NULL,
13933 			     seskey_list_copy_cb,
13934 			     seskey_list_update_cb,
13935 			     seskey_list_free_cb,
13936 			     NULL,
13937 			     NULL,
13938 			     seskey_uat_fields);
13939 
13940 	prefs_register_uat_preference(smb2_module,
13941 				      "seskey_list",
13942 				      "Secret session keys for decryption",
13943 				      "A table of Session ID to Session keys mappings used to decrypt traffic.",
13944 				      seskey_uat);
13945 
13946 	smb2_pipe_subdissector_list = register_heur_dissector_list("smb2_pipe_subdissectors", proto_smb2);
13947 	/*
13948 	 * XXX - addresses_ports_reassembly_table_functions?
13949 	 * Probably correct for SMB-over-NBT and SMB-over-TCP,
13950 	 * as stuff from two different connections should
13951 	 * probably not be combined, but what about other
13952 	 * transports for SMB, e.g. NBF or Netware?
13953 	 */
13954 	reassembly_table_register(&smb2_pipe_reassembly_table,
13955 	    &addresses_reassembly_table_functions);
13956 
13957 	smb2_tap = register_tap("smb2");
13958 	smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
13959 
13960 	register_srt_table(proto_smb2, NULL, 1, smb2stat_packet, smb2stat_init, NULL);
13961 	smb2_sessions = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), smb2_sesid_info_hash, smb2_sesid_info_equal);
13962 }
13963 
13964 void
proto_reg_handoff_smb2(void)13965 proto_reg_handoff_smb2(void)
13966 {
13967 	gssapi_handle  = find_dissector_add_dependency("gssapi", proto_smb2);
13968 	ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_smb2);
13969 	rsvd_handle    = find_dissector_add_dependency("rsvd", proto_smb2);
13970 	heur_dissector_add("netbios", dissect_smb2_heur, "SMB2 over Netbios", "smb2_netbios", proto_smb2, HEURISTIC_ENABLE);
13971 	heur_dissector_add("smb_direct", dissect_smb2_heur, "SMB2 over SMB Direct", "smb2_smb_direct", proto_smb2, HEURISTIC_ENABLE);
13972 }
13973 
13974 /*
13975  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
13976  *
13977  * Local variables:
13978  * c-basic-offset: 8
13979  * tab-width: 8
13980  * indent-tabs-mode: t
13981  * End:
13982  *
13983  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
13984  * :indentSize=8:tabSize=8:noTabs=false:
13985  */
13986