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, ×);
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