smb2: fix description from copy/paste typo
[wireshark-sm.git] / epan / dissectors / packet-smb2.c
blobe3f88d8cd4367a6cbc27b07ade9c1554791b2383
1 /* packet-smb2.c
2 * Routines for smb2 packet dissection
3 * Ronnie Sahlberg 2005
5 * For documentation of this protocol, see:
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://wiki.wireshark.org/SMB2
11 * If you edit this file, keep the wiki updated as well.
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include "config.h"
23 #include <epan/packet.h>
24 #include <epan/exceptions.h>
25 #include <epan/prefs.h>
26 #include <epan/expert.h>
27 #include <epan/tap.h>
28 #include <epan/srt_table.h>
29 #include <epan/aftypes.h>
30 #include <epan/to_str.h>
31 #include <epan/strutil.h>
32 #include <epan/asn1.h>
33 #include <epan/reassemble.h>
34 #include <epan/uat.h>
36 #include "packet-smb2.h"
37 #include "packet-ntlmssp.h"
38 #include "packet-kerberos.h"
39 #include "packet-windows-common.h"
40 #include "packet-dcerpc-nt.h"
42 #include "read_keytab_file.h"
44 #include <wsutil/wsgcrypt.h>
46 #define NT_STATUS_PENDING 0x00000103
47 #define NT_STATUS_BUFFER_TOO_SMALL 0xC0000023
48 #define NT_STATUS_STOPPED_ON_SYMLINK 0x8000002D
49 #define NT_STATUS_BAD_NETWORK_NAME 0xC00000CC
51 void proto_register_smb2(void);
52 void proto_reg_handoff_smb2(void);
54 static const char smb_header_label[] = "SMB2 Header";
55 static const char smb_transform_header_label[] = "SMB2 Transform Header";
57 static int proto_smb2 = -1;
58 static int hf_smb2_cmd = -1;
59 static int hf_smb2_nt_status = -1;
60 static int hf_smb2_response_to = -1;
61 static int hf_smb2_response_in = -1;
62 static int hf_smb2_time = -1;
63 static int hf_smb2_preauth_hash = -1;
64 static int hf_smb2_header_len = -1;
65 static int hf_smb2_msg_id = -1;
66 static int hf_smb2_pid = -1;
67 static int hf_smb2_tid = -1;
68 static int hf_smb2_aid = -1;
69 static int hf_smb2_sesid = -1;
70 static int hf_smb2_previous_sesid = -1;
71 static int hf_smb2_flags_response = -1;
72 static int hf_smb2_flags_async_cmd = -1;
73 static int hf_smb2_flags_dfs_op = -1;
74 static int hf_smb2_flags_chained = -1;
75 static int hf_smb2_flags_signature = -1;
76 static int hf_smb2_flags_replay_operation = -1;
77 static int hf_smb2_flags_priority_mask = -1;
78 static int hf_smb2_chain_offset = -1;
79 static int hf_smb2_security_blob = -1;
80 static int hf_smb2_ioctl_in_data = -1;
81 static int hf_smb2_ioctl_out_data = -1;
82 static int hf_smb2_unknown = -1;
83 static int hf_smb2_root_directory_mbz = -1;
84 static int hf_smb2_twrp_timestamp = -1;
85 static int hf_smb2_mxac_timestamp = -1;
86 static int hf_smb2_mxac_status = -1;
87 static int hf_smb2_qfid_fid = -1;
88 static int hf_smb2_create_timestamp = -1;
89 static int hf_smb2_oplock = -1;
90 static int hf_smb2_close_flags = -1;
91 static int hf_smb2_notify_flags = -1;
92 static int hf_smb2_last_access_timestamp = -1;
93 static int hf_smb2_last_write_timestamp = -1;
94 static int hf_smb2_last_change_timestamp = -1;
95 static int hf_smb2_current_time = -1;
96 static int hf_smb2_boot_time = -1;
97 static int hf_smb2_filename = -1;
98 static int hf_smb2_filename_len = -1;
99 static int hf_smb2_replace_if = -1;
100 static int hf_smb2_nlinks = -1;
101 static int hf_smb2_delete_pending = -1;
102 static int hf_smb2_is_directory = -1;
103 static int hf_smb2_file_id = -1;
104 static int hf_smb2_allocation_size = -1;
105 static int hf_smb2_end_of_file = -1;
106 static int hf_smb2_tree = -1;
107 static int hf_smb2_find_pattern = -1;
108 static int hf_smb2_find_info_level = -1;
109 static int hf_smb2_find_info_blob = -1;
110 static int hf_smb2_client_guid = -1;
111 static int hf_smb2_server_guid = -1;
112 static int hf_smb2_object_id = -1;
113 static int hf_smb2_birth_volume_id = -1;
114 static int hf_smb2_birth_object_id = -1;
115 static int hf_smb2_domain_id = -1;
116 static int hf_smb2_class = -1;
117 static int hf_smb2_infolevel = -1;
118 static int hf_smb2_infolevel_file_info = -1;
119 static int hf_smb2_infolevel_fs_info = -1;
120 static int hf_smb2_infolevel_sec_info = -1;
121 static int hf_smb2_infolevel_posix_info = -1;
122 static int hf_smb2_max_response_size = -1;
123 static int hf_smb2_max_ioctl_in_size = -1;
124 static int hf_smb2_max_ioctl_out_size = -1;
125 static int hf_smb2_flags = -1;
126 static int hf_smb2_required_buffer_size = -1;
127 static int hf_smb2_getinfo_input_size = -1;
128 static int hf_smb2_getinfo_input_offset = -1;
129 static int hf_smb2_getinfo_additional = -1;
130 static int hf_smb2_getinfo_flags = -1;
131 static int hf_smb2_setinfo_size = -1;
132 static int hf_smb2_setinfo_offset = -1;
133 static int hf_smb2_file_basic_info = -1;
134 static int hf_smb2_file_standard_info = -1;
135 static int hf_smb2_file_internal_info = -1;
136 static int hf_smb2_file_ea_info = -1;
137 static int hf_smb2_file_access_info = -1;
138 static int hf_smb2_file_rename_info = -1;
139 static int hf_smb2_file_disposition_info = -1;
140 static int hf_smb2_file_position_info = -1;
141 static int hf_smb2_file_full_ea_info = -1;
142 static int hf_smb2_file_mode_info = -1;
143 static int hf_smb2_file_alignment_info = -1;
144 static int hf_smb2_file_all_info = -1;
145 static int hf_smb2_file_allocation_info = -1;
146 static int hf_smb2_file_endoffile_info = -1;
147 static int hf_smb2_file_alternate_name_info = -1;
148 static int hf_smb2_file_stream_info = -1;
149 static int hf_smb2_file_pipe_info = -1;
150 static int hf_smb2_file_compression_info = -1;
151 static int hf_smb2_file_network_open_info = -1;
152 static int hf_smb2_file_attribute_tag_info = -1;
153 static int hf_smb2_fs_info_01 = -1;
154 static int hf_smb2_fs_info_03 = -1;
155 static int hf_smb2_fs_info_04 = -1;
156 static int hf_smb2_fs_info_05 = -1;
157 static int hf_smb2_fs_info_06 = -1;
158 static int hf_smb2_fs_info_07 = -1;
159 static int hf_smb2_fs_objectid_info = -1;
160 static int hf_smb2_sec_info_00 = -1;
161 static int hf_smb2_quota_info = -1;
162 static int hf_smb2_query_quota_info = -1;
163 static int hf_smb2_qq_single = -1;
164 static int hf_smb2_qq_restart = -1;
165 static int hf_smb2_qq_sidlist_len = -1;
166 static int hf_smb2_qq_start_sid_len = -1;
167 static int hf_smb2_qq_start_sid_offset = -1;
168 static int hf_smb2_fid = -1;
169 static int hf_smb2_write_length = -1;
170 static int hf_smb2_write_data = -1;
171 static int hf_smb2_write_flags = -1;
172 static int hf_smb2_write_flags_write_through = -1;
173 static int hf_smb2_write_count = -1;
174 static int hf_smb2_write_remaining = -1;
175 static int hf_smb2_read_length = -1;
176 static int hf_smb2_read_remaining = -1;
177 static int hf_smb2_file_offset = -1;
178 static int hf_smb2_qfr_length = -1;
179 static int hf_smb2_qfr_usage = -1;
180 static int hf_smb2_qfr_flags = -1;
181 static int hf_smb2_qfr_total_region_entry_count = -1;
182 static int hf_smb2_qfr_region_entry_count = -1;
183 static int hf_smb2_read_data = -1;
184 static int hf_smb2_disposition_delete_on_close = -1;
185 static int hf_smb2_create_disposition = -1;
186 static int hf_smb2_create_chain_offset = -1;
187 static int hf_smb2_create_chain_data = -1;
188 static int hf_smb2_data_offset = -1;
189 static int hf_smb2_extrainfo = -1;
190 static int hf_smb2_create_action = -1;
191 static int hf_smb2_create_rep_flags = -1;
192 static int hf_smb2_create_rep_flags_reparse_point = -1;
193 static int hf_smb2_next_offset = -1;
194 static int hf_smb2_negotiate_context_type = -1;
195 static int hf_smb2_negotiate_context_data_length = -1;
196 static int hf_smb2_negotiate_context_offset = -1;
197 static int hf_smb2_negotiate_context_count = -1;
198 static int hf_smb2_hash_alg_count = -1;
199 static int hf_smb2_hash_algorithm = -1;
200 static int hf_smb2_salt_length = -1;
201 static int hf_smb2_salt = -1;
202 static int hf_smb2_cipher_count = -1;
203 static int hf_smb2_cipher_id = -1;
204 static int hf_smb2_comp_alg_count = -1;
205 static int hf_smb2_comp_alg_id = -1;
206 static int hf_smb2_netname_neg_id = -1;
207 static int hf_smb2_ea_size = -1;
208 static int hf_smb2_ea_flags = -1;
209 static int hf_smb2_ea_name_len = -1;
210 static int hf_smb2_ea_data_len = -1;
211 static int hf_smb2_ea_name = -1;
212 static int hf_smb2_ea_data = -1;
213 static int hf_smb2_position_information = -1;
214 static int hf_smb2_mode_information = -1;
215 static int hf_smb2_mode_file_write_through = -1;
216 static int hf_smb2_mode_file_sequential_only = -1;
217 static int hf_smb2_mode_file_no_intermediate_buffering = -1;
218 static int hf_smb2_mode_file_synchronous_io_alert = -1;
219 static int hf_smb2_mode_file_synchronous_io_nonalert = -1;
220 static int hf_smb2_mode_file_delete_on_close = -1;
221 static int hf_smb2_alignment_information = -1;
222 static int hf_smb2_buffer_code = -1;
223 static int hf_smb2_buffer_code_len = -1;
224 static int hf_smb2_buffer_code_flags_dyn = -1;
225 static int hf_smb2_olb_offset = -1;
226 static int hf_smb2_olb_length = -1;
227 static int hf_smb2_tag = -1;
228 static int hf_smb2_impersonation_level = -1;
229 static int hf_smb2_ioctl_function = -1;
230 static int hf_smb2_ioctl_function_device = -1;
231 static int hf_smb2_ioctl_function_access = -1;
232 static int hf_smb2_ioctl_function_function = -1;
233 static int hf_smb2_fsctl_pipe_wait_timeout = -1;
234 static int hf_smb2_fsctl_pipe_wait_name = -1;
236 static int hf_smb2_fsctl_odx_token_type = -1;
237 static int hf_smb2_fsctl_odx_token_idlen = -1;
238 static int hf_smb2_fsctl_odx_token_idraw = -1;
239 static int hf_smb2_fsctl_odx_token_ttl = -1;
240 static int hf_smb2_fsctl_odx_size = -1;
241 static int hf_smb2_fsctl_odx_flags = -1;
242 static int hf_smb2_fsctl_odx_file_offset = -1;
243 static int hf_smb2_fsctl_odx_copy_length = -1;
244 static int hf_smb2_fsctl_odx_xfer_length = -1;
245 static int hf_smb2_fsctl_odx_token_offset = -1;
247 static int hf_smb2_fsctl_sparse_flag = -1;
248 static int hf_smb2_fsctl_range_offset = -1;
249 static int hf_smb2_fsctl_range_length = -1;
250 static int hf_smb2_ioctl_function_method = -1;
251 static int hf_smb2_ioctl_resiliency_timeout = -1;
252 static int hf_smb2_ioctl_resiliency_reserved = -1;
253 static int hf_smb2_ioctl_shared_virtual_disk_support = -1;
254 static int hf_smb2_ioctl_shared_virtual_disk_handle_state = -1;
255 static int hf_smb2_ioctl_sqos_protocol_version = -1;
256 static int hf_smb2_ioctl_sqos_reserved = -1;
257 static int hf_smb2_ioctl_sqos_options = -1;
258 static int hf_smb2_ioctl_sqos_op_set_logical_flow_id = -1;
259 static int hf_smb2_ioctl_sqos_op_set_policy = -1;
260 static int hf_smb2_ioctl_sqos_op_probe_policy = -1;
261 static int hf_smb2_ioctl_sqos_op_get_status = -1;
262 static int hf_smb2_ioctl_sqos_op_update_counters = -1;
263 static int hf_smb2_ioctl_sqos_logical_flow_id = -1;
264 static int hf_smb2_ioctl_sqos_policy_id = -1;
265 static int hf_smb2_ioctl_sqos_initiator_id = -1;
266 static int hf_smb2_ioctl_sqos_limit = -1;
267 static int hf_smb2_ioctl_sqos_reservation = -1;
268 static int hf_smb2_ioctl_sqos_initiator_name = -1;
269 static int hf_smb2_ioctl_sqos_initiator_node_name = -1;
270 static int hf_smb2_ioctl_sqos_io_count_increment = -1;
271 static int hf_smb2_ioctl_sqos_normalized_io_count_increment = -1;
272 static int hf_smb2_ioctl_sqos_latency_increment = -1;
273 static int hf_smb2_ioctl_sqos_lower_latency_increment = -1;
274 static int hf_smb2_ioctl_sqos_bandwidth_limit = -1;
275 static int hf_smb2_ioctl_sqos_kilobyte_count_increment = -1;
276 static int hf_smb2_ioctl_sqos_time_to_live = -1;
277 static int hf_smb2_ioctl_sqos_status = -1;
278 static int hf_smb2_ioctl_sqos_maximum_io_rate = -1;
279 static int hf_smb2_ioctl_sqos_minimum_io_rate = -1;
280 static int hf_smb2_ioctl_sqos_base_io_size = -1;
281 static int hf_smb2_ioctl_sqos_reserved2 = -1;
282 static int hf_smb2_ioctl_sqos_maximum_bandwidth = -1;
283 static int hf_windows_sockaddr_family = -1;
284 static int hf_windows_sockaddr_port = -1;
285 static int hf_windows_sockaddr_in_addr = -1;
286 static int hf_windows_sockaddr_in6_flowinfo = -1;
287 static int hf_windows_sockaddr_in6_addr = -1;
288 static int hf_windows_sockaddr_in6_scope_id = -1;
289 static int hf_smb2_ioctl_network_interface_next_offset = -1;
290 static int hf_smb2_ioctl_network_interface_index = -1;
291 static int hf_smb2_ioctl_network_interface_rss_queue_count = -1;
292 static int hf_smb2_ioctl_network_interface_capabilities = -1;
293 static int hf_smb2_ioctl_network_interface_capability_rss = -1;
294 static int hf_smb2_ioctl_network_interface_capability_rdma = -1;
295 static int hf_smb2_ioctl_network_interface_link_speed = -1;
296 static int hf_smb2_ioctl_enumerate_snapshots_num_snapshots = -1;
297 static int hf_smb2_ioctl_enumerate_snapshots_num_snapshots_returned = -1;
298 static int hf_smb2_ioctl_enumerate_snapshots_snapshot_array_size = -1;
299 static int hf_smb2_ioctl_enumerate_snapshots_snapshot = -1;
300 static int hf_smb2_compression_format = -1;
301 static int hf_smb2_checksum_algorithm = -1;
302 static int hf_smb2_integrity_reserved = -1;
303 static int hf_smb2_integrity_flags = -1;
304 static int hf_smb2_integrity_flags_enforcement_off = -1;
305 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
306 static int hf_smb2_lease_key = -1;
307 static int hf_smb2_lease_state = -1;
308 static int hf_smb2_lease_state_read_caching = -1;
309 static int hf_smb2_lease_state_handle_caching = -1;
310 static int hf_smb2_lease_state_write_caching = -1;
311 static int hf_smb2_lease_flags = -1;
312 static int hf_smb2_lease_flags_break_ack_required = -1;
313 static int hf_smb2_lease_flags_parent_lease_key_set = -1;
314 static int hf_smb2_lease_flags_break_in_progress = -1;
315 static int hf_smb2_lease_duration = -1;
316 static int hf_smb2_parent_lease_key = -1;
317 static int hf_smb2_lease_epoch = -1;
318 static int hf_smb2_lease_reserved = -1;
319 static int hf_smb2_lease_break_reason = -1;
320 static int hf_smb2_lease_access_mask_hint = -1;
321 static int hf_smb2_lease_share_mask_hint = -1;
322 static int hf_smb2_acct_name = -1;
323 static int hf_smb2_domain_name = -1;
324 static int hf_smb2_host_name = -1;
325 static int hf_smb2_auth_frame = -1;
326 static int hf_smb2_tcon_frame = -1;
327 static int hf_smb2_share_type = -1;
328 static int hf_smb2_signature = -1;
329 static int hf_smb2_credit_charge = -1;
330 static int hf_smb2_credits_requested = -1;
331 static int hf_smb2_credits_granted = -1;
332 static int hf_smb2_channel_sequence = -1;
333 static int hf_smb2_dialect_count = -1;
334 static int hf_smb2_security_mode = -1;
335 static int hf_smb2_secmode_flags_sign_required = -1;
336 static int hf_smb2_secmode_flags_sign_enabled = -1;
337 static int hf_smb2_ses_req_flags = -1;
338 static int hf_smb2_ses_req_flags_session_binding = -1;
339 static int hf_smb2_capabilities = -1;
340 static int hf_smb2_cap_dfs = -1;
341 static int hf_smb2_cap_leasing = -1;
342 static int hf_smb2_cap_large_mtu = -1;
343 static int hf_smb2_cap_multi_channel = -1;
344 static int hf_smb2_cap_persistent_handles = -1;
345 static int hf_smb2_cap_directory_leasing = -1;
346 static int hf_smb2_cap_encryption = -1;
347 static int hf_smb2_dialect = -1;
348 static int hf_smb2_max_trans_size = -1;
349 static int hf_smb2_max_read_size = -1;
350 static int hf_smb2_max_write_size = -1;
351 static int hf_smb2_channel = -1;
352 static int hf_smb2_rdma_v1_offset = -1;
353 static int hf_smb2_rdma_v1_token = -1;
354 static int hf_smb2_rdma_v1_length = -1;
355 static int hf_smb2_session_flags = -1;
356 static int hf_smb2_ses_flags_guest = -1;
357 static int hf_smb2_ses_flags_null = -1;
358 static int hf_smb2_ses_flags_encrypt = -1;
359 static int hf_smb2_share_flags = -1;
360 static int hf_smb2_share_flags_dfs = -1;
361 static int hf_smb2_share_flags_dfs_root = -1;
362 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
363 static int hf_smb2_share_flags_force_shared_delete = -1;
364 static int hf_smb2_share_flags_allow_namespace_caching = -1;
365 static int hf_smb2_share_flags_access_based_dir_enum = -1;
366 static int hf_smb2_share_flags_force_levelii_oplock = -1;
367 static int hf_smb2_share_flags_enable_hash_v1 = -1;
368 static int hf_smb2_share_flags_enable_hash_v2 = -1;
369 static int hf_smb2_share_flags_encrypt_data = -1;
370 static int hf_smb2_share_caching = -1;
371 static int hf_smb2_share_caps = -1;
372 static int hf_smb2_share_caps_dfs = -1;
373 static int hf_smb2_share_caps_continuous_availability = -1;
374 static int hf_smb2_share_caps_scaleout = -1;
375 static int hf_smb2_share_caps_cluster = -1;
376 static int hf_smb2_create_flags = -1;
377 static int hf_smb2_lock_count = -1;
378 static int hf_smb2_min_count = -1;
379 static int hf_smb2_remaining_bytes = -1;
380 static int hf_smb2_channel_info_offset = -1;
381 static int hf_smb2_channel_info_length = -1;
382 static int hf_smb2_channel_info_blob = -1;
383 static int hf_smb2_ioctl_flags = -1;
384 static int hf_smb2_ioctl_is_fsctl = -1;
385 static int hf_smb2_close_pq_attrib = -1;
386 static int hf_smb2_notify_watch_tree = -1;
387 static int hf_smb2_output_buffer_len = -1;
388 static int hf_smb2_notify_out_data = -1;
389 static int hf_smb2_notify_info = -1;
390 static int hf_smb2_notify_next_offset = -1;
391 static int hf_smb2_notify_action = -1;
392 static int hf_smb2_find_flags = -1;
393 static int hf_smb2_find_flags_restart_scans = -1;
394 static int hf_smb2_find_flags_single_entry = -1;
395 static int hf_smb2_find_flags_index_specified = -1;
396 static int hf_smb2_find_flags_reopen = -1;
397 static int hf_smb2_file_index = -1;
398 static int hf_smb2_file_directory_info = -1;
399 static int hf_smb2_both_directory_info = -1;
400 static int hf_smb2_short_name_len = -1;
401 static int hf_smb2_short_name = -1;
402 static int hf_smb2_id_both_directory_info = -1;
403 static int hf_smb2_full_directory_info = -1;
404 static int hf_smb2_lock_info = -1;
405 static int hf_smb2_lock_length = -1;
406 static int hf_smb2_lock_flags = -1;
407 static int hf_smb2_lock_flags_shared = -1;
408 static int hf_smb2_lock_flags_exclusive = -1;
409 static int hf_smb2_lock_flags_unlock = -1;
410 static int hf_smb2_lock_flags_fail_immediately = -1;
411 static int hf_smb2_dhnq_buffer_reserved = -1;
412 static int hf_smb2_dh2x_buffer_timeout = -1;
413 static int hf_smb2_dh2x_buffer_flags = -1;
414 static int hf_smb2_dh2x_buffer_flags_persistent_handle = -1;
415 static int hf_smb2_dh2x_buffer_reserved = -1;
416 static int hf_smb2_dh2x_buffer_create_guid = -1;
417 static int hf_smb2_APP_INSTANCE_buffer_struct_size = -1;
418 static int hf_smb2_APP_INSTANCE_buffer_reserved = -1;
419 static int hf_smb2_APP_INSTANCE_buffer_app_guid = -1;
420 static int hf_smb2_svhdx_open_device_context_version = -1;
421 static int hf_smb2_svhdx_open_device_context_has_initiator_id = -1;
422 static int hf_smb2_svhdx_open_device_context_reserved = -1;
423 static int hf_smb2_svhdx_open_device_context_initiator_id = -1;
424 static int hf_smb2_svhdx_open_device_context_flags = -1;
425 static int hf_smb2_svhdx_open_device_context_originator_flags = -1;
426 static int hf_smb2_svhdx_open_device_context_open_request_id = -1;
427 static int hf_smb2_svhdx_open_device_context_initiator_host_name_len = -1;
428 static int hf_smb2_svhdx_open_device_context_initiator_host_name = -1;
429 static int hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized = -1;
430 static int hf_smb2_svhdx_open_device_context_server_service_version = -1;
431 static int hf_smb2_svhdx_open_device_context_virtual_sector_size = -1;
432 static int hf_smb2_svhdx_open_device_context_physical_sector_size = -1;
433 static int hf_smb2_svhdx_open_device_context_virtual_size = -1;
434 static int hf_smb2_posix_v1_version = -1;
435 static int hf_smb2_posix_v1_request = -1;
436 static int hf_smb2_posix_v1_supported_features = -1;
437 static int hf_smb2_posix_v1_posix_lock = -1;
438 static int hf_smb2_posix_v1_posix_file_semantics = -1;
439 static int hf_smb2_posix_v1_posix_utf8_paths = -1;
440 static int hf_smb2_posix_v1_case_sensitive = -1;
441 static int hf_smb2_posix_v1_posix_will_convert_nt_acls = -1;
442 static int hf_smb2_posix_v1_posix_fileinfo = -1;
443 static int hf_smb2_posix_v1_posix_acls = -1;
444 static int hf_smb2_posix_v1_rich_acls = -1;
445 static int hf_smb2_aapl_command_code = -1;
446 static int hf_smb2_aapl_reserved = -1;
447 static int hf_smb2_aapl_server_query_bitmask = -1;
448 static int hf_smb2_aapl_server_query_bitmask_server_caps = -1;
449 static int hf_smb2_aapl_server_query_bitmask_volume_caps = -1;
450 static int hf_smb2_aapl_server_query_bitmask_model_info = -1;
451 static int hf_smb2_aapl_server_query_caps = -1;
452 static int hf_smb2_aapl_server_query_caps_supports_read_dir_attr = -1;
453 static int hf_smb2_aapl_server_query_caps_supports_osx_copyfile = -1;
454 static int hf_smb2_aapl_server_query_caps_unix_based = -1;
455 static int hf_smb2_aapl_server_query_caps_supports_nfs_ace = -1;
456 static int hf_smb2_aapl_server_query_volume_caps = -1;
457 static int hf_smb2_aapl_server_query_volume_caps_support_resolve_id = -1;
458 static int hf_smb2_aapl_server_query_volume_caps_case_sensitive = -1;
459 static int hf_smb2_aapl_server_query_volume_caps_supports_full_sync = -1;
460 static int hf_smb2_aapl_server_query_model_string = -1;
461 static int hf_smb2_aapl_server_query_server_path = -1;
462 static int hf_smb2_error_context_count = -1;
463 static int hf_smb2_error_reserved = -1;
464 static int hf_smb2_error_byte_count = -1;
465 static int hf_smb2_error_data = -1;
466 static int hf_smb2_error_context = -1;
467 static int hf_smb2_error_context_length = -1;
468 static int hf_smb2_error_context_id = -1;
469 static int hf_smb2_error_min_buf_length = -1;
470 static int hf_smb2_error_redir_context = -1;
471 static int hf_smb2_error_redir_struct_size = -1;
472 static int hf_smb2_error_redir_notif_type = -1;
473 static int hf_smb2_error_redir_flags = -1;
474 static int hf_smb2_error_redir_target_type = -1;
475 static int hf_smb2_error_redir_ip_count = -1;
476 static int hf_smb2_error_redir_ip_list = -1;
477 static int hf_smb2_error_redir_res_name = -1;
478 static int hf_smb2_reserved = -1;
479 static int hf_smb2_reserved_random = -1;
480 static int hf_smb2_transform_signature = -1;
481 static int hf_smb2_transform_nonce = -1;
482 static int hf_smb2_transform_msg_size = -1;
483 static int hf_smb2_transform_reserved = -1;
484 static int hf_smb2_transform_enc_alg = -1;
485 static int hf_smb2_transform_encrypted_data = -1;
486 static int hf_smb2_server_component_smb2 = -1;
487 static int hf_smb2_server_component_smb2_transform = -1;
488 static int hf_smb2_truncated = -1;
489 static int hf_smb2_pipe_fragments = -1;
490 static int hf_smb2_pipe_fragment = -1;
491 static int hf_smb2_pipe_fragment_overlap = -1;
492 static int hf_smb2_pipe_fragment_overlap_conflict = -1;
493 static int hf_smb2_pipe_fragment_multiple_tails = -1;
494 static int hf_smb2_pipe_fragment_too_long_fragment = -1;
495 static int hf_smb2_pipe_fragment_error = -1;
496 static int hf_smb2_pipe_fragment_count = -1;
497 static int hf_smb2_pipe_reassembled_in = -1;
498 static int hf_smb2_pipe_reassembled_length = -1;
499 static int hf_smb2_pipe_reassembled_data = -1;
500 static int hf_smb2_cchunk_resume_key = -1;
501 static int hf_smb2_cchunk_count = -1;
502 static int hf_smb2_cchunk_src_offset = -1;
503 static int hf_smb2_cchunk_dst_offset = -1;
504 static int hf_smb2_cchunk_xfer_len = -1;
505 static int hf_smb2_cchunk_chunks_written = -1;
506 static int hf_smb2_cchunk_bytes_written = -1;
507 static int hf_smb2_cchunk_total_written = -1;
508 static int hf_smb2_reparse_data_buffer = -1;
509 static int hf_smb2_reparse_tag = -1;
510 static int hf_smb2_reparse_guid = -1;
511 static int hf_smb2_reparse_data_length = -1;
512 static int hf_smb2_nfs_type = -1;
513 static int hf_smb2_nfs_symlink_target = -1;
514 static int hf_smb2_nfs_chr_major = -1;
515 static int hf_smb2_nfs_chr_minor = -1;
516 static int hf_smb2_nfs_blk_major = -1;
517 static int hf_smb2_nfs_blk_minor = -1;
518 static int hf_smb2_symlink_error_response = -1;
519 static int hf_smb2_symlink_length = -1;
520 static int hf_smb2_symlink_error_tag = -1;
521 static int hf_smb2_unparsed_path_length = -1;
522 static int hf_smb2_symlink_substitute_name = -1;
523 static int hf_smb2_symlink_print_name = -1;
524 static int hf_smb2_symlink_flags = -1;
526 static gint ett_smb2 = -1;
527 static gint ett_smb2_olb = -1;
528 static gint ett_smb2_ea = -1;
529 static gint ett_smb2_header = -1;
530 static gint ett_smb2_encrypted = -1;
531 static gint ett_smb2_command = -1;
532 static gint ett_smb2_secblob = -1;
533 static gint ett_smb2_negotiate_context_element = -1;
534 static gint ett_smb2_file_basic_info = -1;
535 static gint ett_smb2_file_standard_info = -1;
536 static gint ett_smb2_file_internal_info = -1;
537 static gint ett_smb2_file_ea_info = -1;
538 static gint ett_smb2_file_access_info = -1;
539 static gint ett_smb2_file_position_info = -1;
540 static gint ett_smb2_file_mode_info = -1;
541 static gint ett_smb2_file_alignment_info = -1;
542 static gint ett_smb2_file_all_info = -1;
543 static gint ett_smb2_file_allocation_info = -1;
544 static gint ett_smb2_file_endoffile_info = -1;
545 static gint ett_smb2_file_alternate_name_info = -1;
546 static gint ett_smb2_file_stream_info = -1;
547 static gint ett_smb2_file_pipe_info = -1;
548 static gint ett_smb2_file_compression_info = -1;
549 static gint ett_smb2_file_network_open_info = -1;
550 static gint ett_smb2_file_attribute_tag_info = -1;
551 static gint ett_smb2_file_rename_info = -1;
552 static gint ett_smb2_file_disposition_info = -1;
553 static gint ett_smb2_file_full_ea_info = -1;
554 static gint ett_smb2_fs_info_01 = -1;
555 static gint ett_smb2_fs_info_03 = -1;
556 static gint ett_smb2_fs_info_04 = -1;
557 static gint ett_smb2_fs_info_05 = -1;
558 static gint ett_smb2_fs_info_06 = -1;
559 static gint ett_smb2_fs_info_07 = -1;
560 static gint ett_smb2_fs_objectid_info = -1;
561 static gint ett_smb2_sec_info_00 = -1;
562 static gint ett_smb2_quota_info = -1;
563 static gint ett_smb2_query_quota_info = -1;
564 static gint ett_smb2_tid_tree = -1;
565 static gint ett_smb2_sesid_tree = -1;
566 static gint ett_smb2_create_chain_element = -1;
567 static gint ett_smb2_MxAc_buffer = -1;
568 static gint ett_smb2_QFid_buffer = -1;
569 static gint ett_smb2_RqLs_buffer = -1;
570 static gint ett_smb2_ioctl_function = -1;
571 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
572 static gint ett_smb2_flags = -1;
573 static gint ett_smb2_sec_mode = -1;
574 static gint ett_smb2_capabilities = -1;
575 static gint ett_smb2_ses_req_flags = -1;
576 static gint ett_smb2_ses_flags = -1;
577 static gint ett_smb2_lease_state = -1;
578 static gint ett_smb2_lease_flags = -1;
579 static gint ett_smb2_share_flags = -1;
580 static gint ett_smb2_create_rep_flags = -1;
581 static gint ett_smb2_share_caps = -1;
582 static gint ett_smb2_ioctl_flags = -1;
583 static gint ett_smb2_ioctl_network_interface = -1;
584 static gint ett_smb2_ioctl_sqos_opeations = -1;
585 static gint ett_smb2_fsctl_range_data = -1;
586 static gint ett_windows_sockaddr = -1;
587 static gint ett_smb2_close_flags = -1;
588 static gint ett_smb2_notify_info = -1;
589 static gint ett_smb2_notify_flags = -1;
590 static gint ett_smb2_write_flags = -1;
591 static gint ett_smb2_rdma_v1 = -1;
592 static gint ett_smb2_DH2Q_buffer = -1;
593 static gint ett_smb2_DH2C_buffer = -1;
594 static gint ett_smb2_dh2x_flags = -1;
595 static gint ett_smb2_APP_INSTANCE_buffer = -1;
596 static gint ett_smb2_svhdx_open_device_context = -1;
597 static gint ett_smb2_posix_v1_request = -1;
598 static gint ett_smb2_posix_v1_response = -1;
599 static gint ett_smb2_posix_v1_supported_features = -1;
600 static gint ett_smb2_aapl_create_context_request = -1;
601 static gint ett_smb2_aapl_server_query_bitmask = -1;
602 static gint ett_smb2_aapl_server_query_caps = -1;
603 static gint ett_smb2_aapl_create_context_response = -1;
604 static gint ett_smb2_aapl_server_query_volume_caps = -1;
605 static gint ett_smb2_integrity_flags = -1;
606 static gint ett_smb2_find_flags = -1;
607 static gint ett_smb2_file_directory_info = -1;
608 static gint ett_smb2_both_directory_info = -1;
609 static gint ett_smb2_id_both_directory_info = -1;
610 static gint ett_smb2_full_directory_info = -1;
611 static gint ett_smb2_file_name_info = -1;
612 static gint ett_smb2_lock_info = -1;
613 static gint ett_smb2_lock_flags = -1;
614 static gint ett_smb2_buffercode = -1;
615 static gint ett_smb2_ioctl_network_interface_capabilities = -1;
616 static gint ett_qfr_entry = -1;
617 static gint ett_smb2_pipe_fragment = -1;
618 static gint ett_smb2_pipe_fragments = -1;
619 static gint ett_smb2_cchunk_entry = -1;
620 static gint ett_smb2_fsctl_odx_token = -1;
621 static gint ett_smb2_symlink_error_response = -1;
622 static gint ett_smb2_reparse_data_buffer = -1;
623 static gint ett_smb2_error_data = -1;
624 static gint ett_smb2_error_context = -1;
625 static gint ett_smb2_error_redir_context = -1;
626 static gint ett_smb2_error_redir_ip_list = -1;
628 static expert_field ei_smb2_invalid_length = EI_INIT;
629 static expert_field ei_smb2_bad_response = EI_INIT;
630 static expert_field ei_smb2_invalid_getinfo_offset = EI_INIT;
631 static expert_field ei_smb2_invalid_getinfo_size = EI_INIT;
632 static expert_field ei_smb2_empty_getinfo_buffer = EI_INIT;
634 static int smb2_tap = -1;
635 static int smb2_eo_tap = -1;
637 static dissector_handle_t gssapi_handle = NULL;
638 static dissector_handle_t ntlmssp_handle = NULL;
639 static dissector_handle_t rsvd_handle = NULL;
641 static heur_dissector_list_t smb2_pipe_subdissector_list;
643 static const fragment_items smb2_pipe_frag_items = {
644 &ett_smb2_pipe_fragment,
645 &ett_smb2_pipe_fragments,
646 &hf_smb2_pipe_fragments,
647 &hf_smb2_pipe_fragment,
648 &hf_smb2_pipe_fragment_overlap,
649 &hf_smb2_pipe_fragment_overlap_conflict,
650 &hf_smb2_pipe_fragment_multiple_tails,
651 &hf_smb2_pipe_fragment_too_long_fragment,
652 &hf_smb2_pipe_fragment_error,
653 &hf_smb2_pipe_fragment_count,
654 &hf_smb2_pipe_reassembled_in,
655 &hf_smb2_pipe_reassembled_length,
656 &hf_smb2_pipe_reassembled_data,
657 "Fragments"
660 #define FILE_BYTE_ALIGNMENT 0x00
661 #define FILE_WORD_ALIGNMENT 0x01
662 #define FILE_LONG_ALIGNMENT 0x03
663 #define FILE_QUAD_ALIGNMENT 0x07
664 #define FILE_OCTA_ALIGNMENT 0x0f
665 #define FILE_32_BYTE_ALIGNMENT 0x1f
666 #define FILE_64_BYTE_ALIGNMENT 0x3f
667 #define FILE_128_BYTE_ALIGNMENT 0x7f
668 #define FILE_256_BYTE_ALIGNMENT 0xff
669 #define FILE_512_BYTE_ALIGNMENT 0x1ff
670 static const value_string smb2_alignment_vals[] = {
671 { FILE_BYTE_ALIGNMENT, "FILE_BYTE_ALIGNMENT" },
672 { FILE_WORD_ALIGNMENT, "FILE_WORD_ALIGNMENT" },
673 { FILE_LONG_ALIGNMENT, "FILE_LONG_ALIGNMENT" },
674 { FILE_OCTA_ALIGNMENT, "FILE_OCTA_ALIGNMENT" },
675 { FILE_32_BYTE_ALIGNMENT, "FILE_32_BYTE_ALIGNMENT" },
676 { FILE_64_BYTE_ALIGNMENT, "FILE_64_BYTE_ALIGNMENT" },
677 { FILE_128_BYTE_ALIGNMENT, "FILE_128_BYTE_ALIGNMENT" },
678 { FILE_256_BYTE_ALIGNMENT, "FILE_256_BYTE_ALIGNMENT" },
679 { FILE_512_BYTE_ALIGNMENT, "FILE_512_BYTE_ALIGNMENT" },
680 { 0, NULL }
684 #define SMB2_CLASS_FILE_INFO 0x01
685 #define SMB2_CLASS_FS_INFO 0x02
686 #define SMB2_CLASS_SEC_INFO 0x03
687 #define SMB2_CLASS_QUOTA_INFO 0x04
688 #define SMB2_CLASS_POSIX_INFO 0x80
689 static const value_string smb2_class_vals[] = {
690 { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
691 { SMB2_CLASS_FS_INFO, "FS_INFO"},
692 { SMB2_CLASS_SEC_INFO, "SEC_INFO"},
693 { SMB2_CLASS_QUOTA_INFO, "QUOTA_INFO"},
694 { SMB2_CLASS_POSIX_INFO, "POSIX_INFO"},
695 { 0, NULL }
698 #define SMB2_SHARE_TYPE_DISK 0x01
699 #define SMB2_SHARE_TYPE_PIPE 0x02
700 #define SMB2_SHARE_TYPE_PRINT 0x03
701 static const value_string smb2_share_type_vals[] = {
702 { SMB2_SHARE_TYPE_DISK, "Physical disk" },
703 { SMB2_SHARE_TYPE_PIPE, "Named pipe" },
704 { SMB2_SHARE_TYPE_PRINT, "Printer" },
705 { 0, NULL }
709 #define SMB2_FILE_BASIC_INFO 0x04
710 #define SMB2_FILE_STANDARD_INFO 0x05
711 #define SMB2_FILE_INTERNAL_INFO 0x06
712 #define SMB2_FILE_EA_INFO 0x07
713 #define SMB2_FILE_ACCESS_INFO 0x08
714 #define SMB2_FILE_RENAME_INFO 0x0a
715 #define SMB2_FILE_DISPOSITION_INFO 0x0d
716 #define SMB2_FILE_POSITION_INFO 0x0e
717 #define SMB2_FILE_FULL_EA_INFO 0x0f
718 #define SMB2_FILE_MODE_INFO 0x10
719 #define SMB2_FILE_ALIGNMENT_INFO 0x11
720 #define SMB2_FILE_ALL_INFO 0x12
721 #define SMB2_FILE_ALLOCATION_INFO 0x13
722 #define SMB2_FILE_ENDOFFILE_INFO 0x14
723 #define SMB2_FILE_ALTERNATE_NAME_INFO 0x15
724 #define SMB2_FILE_STREAM_INFO 0x16
725 #define SMB2_FILE_PIPE_INFO 0x17
726 #define SMB2_FILE_COMPRESSION_INFO 0x1c
727 #define SMB2_FILE_NETWORK_OPEN_INFO 0x22
728 #define SMB2_FILE_ATTRIBUTE_TAG_INFO 0x23
730 static const value_string smb2_file_info_levels[] = {
731 {SMB2_FILE_BASIC_INFO, "SMB2_FILE_BASIC_INFO" },
732 {SMB2_FILE_STANDARD_INFO, "SMB2_FILE_STANDARD_INFO" },
733 {SMB2_FILE_INTERNAL_INFO, "SMB2_FILE_INTERNAL_INFO" },
734 {SMB2_FILE_EA_INFO, "SMB2_FILE_EA_INFO" },
735 {SMB2_FILE_ACCESS_INFO, "SMB2_FILE_ACCESS_INFO" },
736 {SMB2_FILE_RENAME_INFO, "SMB2_FILE_RENAME_INFO" },
737 {SMB2_FILE_DISPOSITION_INFO, "SMB2_FILE_DISPOSITION_INFO" },
738 {SMB2_FILE_POSITION_INFO, "SMB2_FILE_POSITION_INFO" },
739 {SMB2_FILE_FULL_EA_INFO, "SMB2_FILE_FULL_EA_INFO" },
740 {SMB2_FILE_MODE_INFO, "SMB2_FILE_MODE_INFO" },
741 {SMB2_FILE_ALIGNMENT_INFO, "SMB2_FILE_ALIGNMENT_INFO" },
742 {SMB2_FILE_ALL_INFO, "SMB2_FILE_ALL_INFO" },
743 {SMB2_FILE_ALLOCATION_INFO, "SMB2_FILE_ALLOCATION_INFO" },
744 {SMB2_FILE_ENDOFFILE_INFO, "SMB2_FILE_ENDOFFILE_INFO" },
745 {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
746 {SMB2_FILE_STREAM_INFO, "SMB2_FILE_STREAM_INFO" },
747 {SMB2_FILE_PIPE_INFO, "SMB2_FILE_PIPE_INFO" },
748 {SMB2_FILE_COMPRESSION_INFO, "SMB2_FILE_COMPRESSION_INFO" },
749 {SMB2_FILE_NETWORK_OPEN_INFO, "SMB2_FILE_NETWORK_OPEN_INFO" },
750 {SMB2_FILE_ATTRIBUTE_TAG_INFO, "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
751 { 0, NULL }
753 static value_string_ext smb2_file_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_file_info_levels);
757 #define SMB2_FS_INFO_01 0x01
758 #define SMB2_FS_LABEL_INFO 0x02
759 #define SMB2_FS_INFO_03 0x03
760 #define SMB2_FS_INFO_04 0x04
761 #define SMB2_FS_INFO_05 0x05
762 #define SMB2_FS_INFO_06 0x06
763 #define SMB2_FS_INFO_07 0x07
764 #define SMB2_FS_OBJECTID_INFO 0x08
765 #define SMB2_FS_DRIVER_PATH_INFO 0x09
766 #define SMB2_FS_VOLUME_FLAGS_INFO 0x0a
767 #define SMB2_FS_SECTOR_SIZE_INFO 0x0b
769 static const value_string smb2_fs_info_levels[] = {
770 {SMB2_FS_INFO_01, "FileFsVolumeInformation" },
771 {SMB2_FS_LABEL_INFO, "FileFsLabelInformation" },
772 {SMB2_FS_INFO_03, "FileFsSizeInformation" },
773 {SMB2_FS_INFO_04, "FileFsDeviceInformation" },
774 {SMB2_FS_INFO_05, "FileFsAttributeInformation" },
775 {SMB2_FS_INFO_06, "FileFsControlInformation" },
776 {SMB2_FS_INFO_07, "FileFsFullSizeInformation" },
777 {SMB2_FS_OBJECTID_INFO, "FileFsObjectIdInformation" },
778 {SMB2_FS_DRIVER_PATH_INFO, "FileFsDriverPathInformation" },
779 {SMB2_FS_VOLUME_FLAGS_INFO, "FileFsVolumeFlagsInformation" },
780 {SMB2_FS_SECTOR_SIZE_INFO, "FileFsSectorSizeInformation" },
781 { 0, NULL }
783 static value_string_ext smb2_fs_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_fs_info_levels);
785 #define SMB2_SEC_INFO_00 0x00
786 static const value_string smb2_sec_info_levels[] = {
787 {SMB2_SEC_INFO_00, "SMB2_SEC_INFO_00" },
788 { 0, NULL }
790 static value_string_ext smb2_sec_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_sec_info_levels);
792 static const value_string smb2_posix_info_levels[] = {
793 { 0, "QueryFileUnixBasic" },
794 { 1, "QueryFileUnixLink" },
795 { 3, "QueryFileUnixHLink" },
796 { 5, "QueryFileUnixXAttr" },
797 { 0x0B, "QueryFileUnixInfo2" },
798 { 0, NULL }
801 static value_string_ext smb2_posix_info_levels_ext = VALUE_STRING_EXT_INIT(smb2_posix_info_levels);
803 #define SMB2_FIND_DIRECTORY_INFO 0x01
804 #define SMB2_FIND_FULL_DIRECTORY_INFO 0x02
805 #define SMB2_FIND_BOTH_DIRECTORY_INFO 0x03
806 #define SMB2_FIND_INDEX_SPECIFIED 0x04
807 #define SMB2_FIND_NAME_INFO 0x0C
808 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
809 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
810 static const value_string smb2_find_info_levels[] = {
811 { SMB2_FIND_DIRECTORY_INFO, "SMB2_FIND_DIRECTORY_INFO" },
812 { SMB2_FIND_FULL_DIRECTORY_INFO, "SMB2_FIND_FULL_DIRECTORY_INFO" },
813 { SMB2_FIND_BOTH_DIRECTORY_INFO, "SMB2_FIND_BOTH_DIRECTORY_INFO" },
814 { SMB2_FIND_INDEX_SPECIFIED, "SMB2_FIND_INDEX_SPECIFIED" },
815 { SMB2_FIND_NAME_INFO, "SMB2_FIND_NAME_INFO" },
816 { SMB2_FIND_ID_BOTH_DIRECTORY_INFO, "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
817 { SMB2_FIND_ID_FULL_DIRECTORY_INFO, "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
818 { 0, NULL }
821 #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001
822 #define SMB2_ENCRYPTION_CAPABILITIES 0x0002
823 #define SMB2_COMPRESSION_CAPABILITIES 0x0003
824 #define SMB2_NETNAME_NEGOTIATE_CONTEXT_ID 0x0005
825 static const value_string smb2_negotiate_context_types[] = {
826 { SMB2_PREAUTH_INTEGRITY_CAPABILITIES, "SMB2_PREAUTH_INTEGRITY_CAPABILITIES" },
827 { SMB2_ENCRYPTION_CAPABILITIES, "SMB2_ENCRYPTION_CAPABILITIES" },
828 { SMB2_COMPRESSION_CAPABILITIES, "SMB2_COMPRESSION_CAPABILITIES" },
829 { SMB2_NETNAME_NEGOTIATE_CONTEXT_ID, "SMB2_NETNAME_NEGOTIATE_CONTEXT_ID" },
830 { 0, NULL }
833 #define SMB2_HASH_ALGORITHM_SHA_512 0x0001
834 static const value_string smb2_hash_algorithm_types[] = {
835 { SMB2_HASH_ALGORITHM_SHA_512, "SHA-512" },
836 { 0, NULL }
839 #define SMB2_CIPHER_AES_128_CCM 0x0001
840 #define SMB2_CIPHER_AES_128_GCM 0x0002
841 static const value_string smb2_cipher_types[] = {
842 { SMB2_CIPHER_AES_128_CCM, "AES-128-CCM" },
843 { SMB2_CIPHER_AES_128_GCM, "AES-128-GCM" },
844 { 0, NULL }
847 #define SMB2_COMP_ALG_NONE 0x0000
848 #define SMB2_COMP_ALG_LZNT1 0x0001
849 #define SMB2_COMP_ALG_LZ77 0x0002
850 #define SMB2_COMP_ALG_LZ77HUFF 0x0003
851 static const value_string smb2_comp_alg_types[] = {
852 { SMB2_COMP_ALG_NONE, "None" },
853 { SMB2_COMP_ALG_LZNT1, "LZNT1" },
854 { SMB2_COMP_ALG_LZ77, "LZ77" },
855 { SMB2_COMP_ALG_LZ77HUFF, "LZ77+Huffman" },
856 { 0, NULL }
859 static const val64_string unique_unsolicited_response[] = {
860 { 0xffffffffffffffff, "unsolicited response" },
861 { 0, NULL }
864 #define SMB2_ERROR_ID_DEFAULT 0x00000000
865 #define SMB2_ERROR_ID_SHARE_REDIRECT 0x72645253
866 static const value_string smb2_error_id_vals[] = {
867 { SMB2_ERROR_ID_DEFAULT, "ERROR_ID_DEFAULT" },
868 { SMB2_ERROR_ID_SHARE_REDIRECT, "ERROR_ID_SHARE_REDIRECT" },
869 { 0, NULL }
872 #define REPARSE_TAG_RESERVED_ZERO 0x00000000 /* Reserved reparse tag value. */
873 #define REPARSE_TAG_RESERVED_ONE 0x00000001 /* Reserved reparse tag value. */
874 #define REPARSE_TAG_MOUNT_POINT 0xA0000003 /* Used for mount point */
875 #define REPARSE_TAG_HSM 0xC0000004 /* Obsolete. Used by legacy Hierarchical Storage Manager Product. */
876 #define REPARSE_TAG_DRIVER_EXTENDER 0x80000005 /* Home server drive extender. */
877 #define REPARSE_TAG_HSM2 0x80000006 /* Obsolete. Used by legacy Hierarchical Storage Manager Product. */
878 #define REPARSE_TAG_SIS 0x80000007 /* Used by single-instance storage (SIS) filter driver. */
879 #define REPARSE_TAG_DFS 0x8000000A /* Used by the DFS filter. */
880 #define REPARSE_TAG_FILTER_MANAGER 0x8000000B /* Used by filter manager test harness */
881 #define REPARSE_TAG_SYMLINK 0xA000000C /* Used for symbolic link support. */
882 #define REPARSE_TAG_DFSR 0x80000012 /* Used by the DFS filter. */
883 #define REPARSE_TAG_NFS 0x80000014 /* Used by the Network File System (NFS) component. */
884 static const value_string reparse_tag_vals[] = {
885 { REPARSE_TAG_RESERVED_ZERO, "REPARSE_TAG_RESERVED_ZERO"},
886 { REPARSE_TAG_RESERVED_ONE, "REPARSE_TAG_RESERVED_ONE"},
887 { REPARSE_TAG_MOUNT_POINT, "REPARSE_TAG_MOUNT_POINT"},
888 { REPARSE_TAG_HSM, "REPARSE_TAG_HSM"},
889 { REPARSE_TAG_DRIVER_EXTENDER, "REPARSE_TAG_DRIVER_EXTENDER"},
890 { REPARSE_TAG_HSM2, "REPARSE_TAG_HSM2"},
891 { REPARSE_TAG_SIS, "REPARSE_TAG_SIS"},
892 { REPARSE_TAG_DFS, "REPARSE_TAG_DFS"},
893 { REPARSE_TAG_FILTER_MANAGER, "REPARSE_TAG_FILTER_MANAGER"},
894 { REPARSE_TAG_SYMLINK, "REPARSE_TAG_SYMLINK"},
895 { REPARSE_TAG_DFSR, "REPARSE_TAG_DFSR"},
896 { REPARSE_TAG_NFS, "REPARSE_TAG_NFS"},
897 { 0, NULL }
900 #define NFS_SPECFILE_LNK 0x00000000014B4E4C
901 #define NFS_SPECFILE_CHR 0x0000000000524843
902 #define NFS_SPECFILE_BLK 0x00000000004B4C42
903 #define NFS_SPECFILE_FIFO 0x000000004F464946
904 #define NFS_SPECFILE_SOCK 0x000000004B434F53
905 static const val64_string nfs_type_vals[] = {
906 { NFS_SPECFILE_LNK, "Symbolic Link" },
907 { NFS_SPECFILE_CHR, "Character Device" },
908 { NFS_SPECFILE_BLK, "Block Device" },
909 { NFS_SPECFILE_FIFO, "FIFO" },
910 { NFS_SPECFILE_SOCK, "UNIX Socket" },
911 { 0, NULL }
914 #define SMB2_NUM_PROCEDURES 256
916 static int dissect_windows_sockaddr_storage(tvbuff_t *, packet_info *, proto_tree *, int, int);
917 static void dissect_smb2_error_data(tvbuff_t *, packet_info *, proto_tree *, int, int, smb2_info_t *);
919 static void update_preauth_hash(void *buf, tvbuff_t *tvb)
921 gcry_error_t err;
922 gcry_md_hd_t md;
923 void *pkt;
925 err = gcry_md_open(&md, GCRY_MD_SHA512, 0);
926 if (err)
927 return;
929 /* we dup in case of non-contiguous packet */
930 pkt = tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_captured_length(tvb));
931 gcry_md_write(md, buf, SMB2_PREAUTH_HASH_SIZE);
932 gcry_md_write(md, pkt, tvb_captured_length(tvb));
933 gcry_md_final(md);
934 memcpy(buf, gcry_md_read(md, 0), SMB2_PREAUTH_HASH_SIZE);
935 gcry_md_close(md);
938 static void
939 smb2stat_init(struct register_srt* srt _U_, GArray* srt_array)
941 srt_stat_table *smb2_srt_table;
942 guint32 i;
944 smb2_srt_table = init_srt_table("SMB2", NULL, srt_array, SMB2_NUM_PROCEDURES, "Commands", "smb2.cmd", NULL);
945 for (i = 0; i < SMB2_NUM_PROCEDURES; i++)
947 init_srt_table_row(smb2_srt_table, i, val_to_str_ext_const(i, &smb2_cmd_vals_ext, "<unknown>"));
951 static tap_packet_status
952 smb2stat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
954 guint i = 0;
955 srt_stat_table *smb2_srt_table;
956 srt_data_t *data = (srt_data_t *)pss;
957 const smb2_info_t *si=(const smb2_info_t *)prv;
959 /* we are only interested in response packets */
960 if(!(si->flags&SMB2_FLAGS_RESPONSE)){
961 return TAP_PACKET_DONT_REDRAW;
963 /* We should not include cancel and oplock break requests either */
964 if (si->opcode == SMB2_COM_CANCEL || si->opcode == SMB2_COM_BREAK) {
965 return TAP_PACKET_DONT_REDRAW;
968 /* if we haven't seen the request, just ignore it */
969 if(!si->saved){
970 return TAP_PACKET_DONT_REDRAW;
973 /* SMB2 SRT can be very inaccurate in the presence of retransmissions. Retransmitted responses
974 * not only add additional (bogus) transactions but also the latency associated with them.
975 * This can greatly inflate the maximum and average SRT stats especially in the case of
976 * retransmissions triggered by the expiry of the rexmit timer (RTOs). Only calculating SRT
977 * for the last received response accomplishes this goal without requiring the TCP pref
978 * "Do not call subdissectors for error packets" to be set. */
979 if ((si->saved->frame_req == 0) || (si->saved->frame_res != pinfo->num))
980 return TAP_PACKET_DONT_REDRAW;
982 smb2_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
983 add_srt_table_data(smb2_srt_table, si->opcode, &si->saved->req_time, pinfo);
984 return TAP_PACKET_REDRAW;
987 /* Structure for SessionID <=> SessionKey mapping for decryption. */
988 typedef struct _smb2_seskey_field_t {
989 guchar *id; /* *little-endian* - not necessarily host-endian! */
990 guint id_len;
991 guchar *key;
992 guint key_len;
993 } smb2_seskey_field_t;
995 static smb2_seskey_field_t *seskey_list = NULL;
996 static guint num_seskey_list = 0;
998 static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1000 /* Callbacks for SessionID <=> SessionKey mapping. */
1001 UAT_BUFFER_CB_DEF(seskey_list, id, smb2_seskey_field_t, id, id_len)
1002 UAT_BUFFER_CB_DEF(seskey_list, key, smb2_seskey_field_t, key, key_len)
1004 #define SMB_SESSION_ID_SIZE 8
1006 static gboolean seskey_list_update_cb(void *r, char **err)
1008 smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
1010 *err = NULL;
1012 if (rec->id_len != SMB_SESSION_ID_SIZE) {
1013 *err = g_strdup("Session ID must be " G_STRINGIFY(SMB_SESSION_ID_SIZE) " bytes long and in hexadecimal");
1014 return FALSE;
1017 if (rec->key_len == 0 || rec->key_len > NTLMSSP_KEY_LEN) {
1018 *err = g_strdup("Session Key must be a non-empty hexadecimal string representing at most " G_STRINGIFY(NTLMSSP_KEY_LEN) " bytes");
1019 return FALSE;
1022 return TRUE;
1025 static void* seskey_list_copy_cb(void *n, const void *o, size_t siz _U_)
1027 smb2_seskey_field_t *new_rec = (smb2_seskey_field_t *)n;
1028 const smb2_seskey_field_t *old_rec = (const smb2_seskey_field_t *)o;
1030 new_rec->id_len = old_rec->id_len;
1031 new_rec->id = old_rec->id ? (guchar *)g_memdup(old_rec->id, old_rec->id_len) : NULL;
1032 new_rec->key_len = old_rec->key_len;
1033 new_rec->key = old_rec->key ? (guchar *)g_memdup(old_rec->key, old_rec->key_len) : NULL;
1035 return new_rec;
1038 static void seskey_list_free_cb(void *r)
1040 smb2_seskey_field_t *rec = (smb2_seskey_field_t *)r;
1042 g_free(rec->id);
1043 g_free(rec->key);
1046 static gboolean seskey_find_sid_key(guint64 sesid, guint8 *out_key)
1048 guint i;
1049 guint64 sesid_le;
1052 * The session IDs in the UAT are octet arrays, in little-endian
1053 * byte order (as it appears on the wire); they have been
1054 * checked to make sure they're 8 bytes (SMB_SESSION_ID_SIZE)
1055 * long. They're *probably* aligned on an appropriate boundary,
1056 * but let's not assume that - let's just use memcmp().
1058 * The session ID passed to us, however, is in *host* byte order.
1059 * This is *NOT* necessarily little-endian; it's big-endian on,
1060 * for example, System/390 and z/Architecture ("s390" and "s390x"
1061 * in Linuxland), SPARC, and most PowerPC systems. We must,
1062 * therefore, put it into little-endian byte order before
1063 * comparing it with the IDs in the UAT values.
1065 sesid_le = GUINT64_TO_LE(sesid);
1067 for (i = 0; i < num_seskey_list; i++) {
1068 const smb2_seskey_field_t *p = &seskey_list[i];
1069 if (memcmp(&sesid_le, p->id, SMB_SESSION_ID_SIZE) == 0) {
1070 memset(out_key, 0, NTLMSSP_KEY_LEN);
1071 memcpy(out_key, p->key, p->key_len);
1072 return TRUE;
1076 return FALSE;
1079 /* ExportObject preferences variable */
1080 gboolean eosmb2_take_name_as_fid = FALSE ;
1082 /* unmatched smb_saved_info structures.
1083 For unmatched smb_saved_info structures we store the smb_saved_info
1084 structure using the msg_id field.
1086 static gint
1087 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
1089 const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
1090 const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
1091 return key1->msg_id == key2->msg_id;
1093 static guint
1094 smb2_saved_info_hash_unmatched(gconstpointer k)
1096 const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
1097 guint32 hash;
1099 hash = (guint32) (key->msg_id&0xffffffff);
1100 return hash;
1103 /* matched smb_saved_info structures.
1104 For matched smb_saved_info structures we store the smb_saved_info
1105 structure using the msg_id field.
1107 static gint
1108 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1110 const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
1111 const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
1112 return key1->msg_id == key2->msg_id;
1114 static guint
1115 smb2_saved_info_hash_matched(gconstpointer k)
1117 const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
1118 guint32 hash;
1120 hash = (guint32) (key->msg_id&0xffffffff);
1121 return hash;
1124 /* For Tids of a specific conversation.
1125 This keeps track of tid->sharename mappings and other information about the
1126 tid.
1128 We might need to refine this if it occurs that tids are reused on a single
1129 conversation. we don't worry about that yet for simplicity
1131 static gint
1132 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
1134 const smb2_tid_info_t *key1 = (const smb2_tid_info_t *)k1;
1135 const smb2_tid_info_t *key2 = (const smb2_tid_info_t *)k2;
1136 return key1->tid == key2->tid;
1138 static guint
1139 smb2_tid_info_hash(gconstpointer k)
1141 const smb2_tid_info_t *key = (const smb2_tid_info_t *)k;
1142 guint32 hash;
1144 hash = key->tid;
1145 return hash;
1148 /* For Uids of a specific conversation.
1149 This keeps track of uid->acct_name mappings and other information about the
1150 uid.
1152 We might need to refine this if it occurs that uids are reused on a single
1153 conversation. we don't worry about that yet for simplicity
1155 static gint
1156 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
1158 const smb2_sesid_info_t *key1 = (const smb2_sesid_info_t *)k1;
1159 const smb2_sesid_info_t *key2 = (const smb2_sesid_info_t *)k2;
1160 return key1->sesid == key2->sesid;
1162 static guint
1163 smb2_sesid_info_hash(gconstpointer k)
1165 const smb2_sesid_info_t *key = (const smb2_sesid_info_t *)k;
1166 guint32 hash;
1168 hash = (guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
1169 return hash;
1173 * For File IDs of a specific conversation.
1174 * This keeps track of fid to name mapping and application level conversations
1175 * over named pipes.
1177 * This handles implementation bugs, where the fid_persitent is 0 or
1178 * the fid_persitent/fid_volative is not unique per conversation.
1180 static gint
1181 smb2_fid_info_equal(gconstpointer k1, gconstpointer k2)
1183 const smb2_fid_info_t *key1 = (const smb2_fid_info_t *)k1;
1184 const smb2_fid_info_t *key2 = (const smb2_fid_info_t *)k2;
1186 if (key1->fid_persistent != key2->fid_persistent) {
1187 return 0;
1190 if (key1->fid_volatile != key2->fid_volatile) {
1191 return 0;
1194 if (key1->sesid != key2->sesid) {
1195 return 0;
1198 if (key1->tid != key2->tid) {
1199 return 0;
1202 return 1;
1205 static guint
1206 smb2_fid_info_hash(gconstpointer k)
1208 const smb2_fid_info_t *key = (const smb2_fid_info_t *)k;
1209 guint32 hash;
1211 if (key->fid_persistent != 0) {
1212 hash = (guint32)( ((key->fid_persistent>>32)&0xffffffff)+((key->fid_persistent)&0xffffffff) );
1213 } else {
1214 hash = (guint32)( ((key->fid_volatile>>32)&0xffffffff)+((key->fid_volatile)&0xffffffff) );
1217 return hash;
1220 /* Callback for destroying the glib hash tables associated with a conversation
1221 * struct. */
1222 static gboolean
1223 smb2_conv_destroy(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
1224 void *user_data)
1226 smb2_conv_info_t *conv = (smb2_conv_info_t *)user_data;
1228 g_hash_table_destroy(conv->matched);
1229 g_hash_table_destroy(conv->unmatched);
1230 g_hash_table_destroy(conv->fids);
1231 g_hash_table_destroy(conv->sesids);
1232 g_hash_table_destroy(conv->files);
1234 /* This conversation is gone, return FALSE to indicate we don't
1235 * want to be called again for this conversation. */
1236 return FALSE;
1239 static smb2_sesid_info_t *
1240 smb2_get_session(smb2_conv_info_t *conv, guint64 id, packet_info *pinfo, smb2_info_t *si)
1242 smb2_sesid_info_t key = {.sesid = id};
1243 smb2_sesid_info_t *ses = (smb2_sesid_info_t *)g_hash_table_lookup(conv->sesids, &key);
1245 if (!ses) {
1246 ses = wmem_new0(wmem_file_scope(), smb2_sesid_info_t);
1247 ses->sesid = id;
1248 ses->auth_frame = (guint32)-1;
1249 ses->tids = wmem_map_new(wmem_file_scope(), smb2_tid_info_hash, smb2_tid_info_equal);
1250 seskey_find_sid_key(id, ses->session_key);
1251 if (pinfo && si) {
1252 if (si->flags & SMB2_FLAGS_RESPONSE) {
1253 ses->server_port = pinfo->srcport;
1254 } else {
1255 ses->server_port = pinfo->destport;
1258 g_hash_table_insert(conv->sesids, ses, ses);
1261 return ses;
1264 static void
1265 smb2_add_session_info(proto_tree *tree, tvbuff_t *tvb, gint start, smb2_sesid_info_t *ses)
1267 proto_item *item;
1268 if (!ses)
1269 return;
1271 if (ses->acct_name) {
1272 item = proto_tree_add_string(tree, hf_smb2_acct_name, tvb, start, 0, ses->acct_name);
1273 proto_item_set_generated(item);
1274 proto_item_append_text(item, " Acct:%s", ses->acct_name);
1277 if (ses->domain_name) {
1278 item = proto_tree_add_string(tree, hf_smb2_domain_name, tvb, start, 0, ses->domain_name);
1279 proto_item_set_generated(item);
1280 proto_item_append_text(item, " Domain:%s", ses->domain_name);
1283 if (ses->host_name) {
1284 item = proto_tree_add_string(tree, hf_smb2_host_name, tvb, start, 0, ses->host_name);
1285 proto_item_set_generated(item);
1286 proto_item_append_text(item, " Host:%s", ses->host_name);
1289 if (ses->auth_frame != (guint32)-1) {
1290 item = proto_tree_add_uint(tree, hf_smb2_auth_frame, tvb, start, 0, ses->auth_frame);
1291 proto_item_set_generated(item);
1295 static void smb2_key_derivation(const guint8 *KI, guint32 KI_len,
1296 const guint8 *Label, guint32 Label_len,
1297 const guint8 *Context, guint32 Context_len,
1298 guint8 KO[16])
1300 gcry_md_hd_t hd = NULL;
1301 guint8 buf[4];
1302 guint8 *digest = NULL;
1305 * a simplified version of
1306 * "NIST Special Publication 800-108" section 5.1
1307 * using hmac-sha256.
1309 gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
1310 gcry_md_setkey(hd, KI, KI_len);
1312 memset(buf, 0, sizeof(buf));
1313 buf[3] = 1;
1314 gcry_md_write(hd, buf, sizeof(buf));
1315 gcry_md_write(hd, Label, Label_len);
1316 gcry_md_write(hd, buf, 1);
1317 gcry_md_write(hd, Context, Context_len);
1318 buf[3] = 128;
1319 gcry_md_write(hd, buf, sizeof(buf));
1321 digest = gcry_md_read(hd, GCRY_MD_SHA256);
1323 memcpy(KO, digest, 16);
1325 gcry_md_close(hd);
1328 /* for export-object-smb2 */
1329 static gchar *policy_hnd_to_file_id(const e_ctx_hnd *hnd) {
1330 gchar *file_id;
1331 file_id = wmem_strdup_printf(wmem_packet_scope(),
1332 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1333 hnd->uuid.data1,
1334 hnd->uuid.data2,
1335 hnd->uuid.data3,
1336 hnd->uuid.data4[0],
1337 hnd->uuid.data4[1],
1338 hnd->uuid.data4[2],
1339 hnd->uuid.data4[3],
1340 hnd->uuid.data4[4],
1341 hnd->uuid.data4[5],
1342 hnd->uuid.data4[6],
1343 hnd->uuid.data4[7]);
1344 return file_id;
1346 static guint smb2_eo_files_hash(gconstpointer k) {
1347 return g_str_hash(policy_hnd_to_file_id((const e_ctx_hnd *)k));
1349 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2) {
1350 int are_equal;
1351 const e_ctx_hnd *key1 = (const e_ctx_hnd *)k1;
1352 const e_ctx_hnd *key2 = (const e_ctx_hnd *)k2;
1354 are_equal = (key1->uuid.data1==key2->uuid.data1 &&
1355 key1->uuid.data2==key2->uuid.data2 &&
1356 key1->uuid.data3==key2->uuid.data3 &&
1357 key1->uuid.data4[0]==key2->uuid.data4[0] &&
1358 key1->uuid.data4[1]==key2->uuid.data4[1] &&
1359 key1->uuid.data4[2]==key2->uuid.data4[2] &&
1360 key1->uuid.data4[3]==key2->uuid.data4[3] &&
1361 key1->uuid.data4[4]==key2->uuid.data4[4] &&
1362 key1->uuid.data4[5]==key2->uuid.data4[5] &&
1363 key1->uuid.data4[6]==key2->uuid.data4[6] &&
1364 key1->uuid.data4[7]==key2->uuid.data4[7]);
1366 return are_equal;
1369 static void
1370 feed_eo_smb2(tvbuff_t * tvb,packet_info *pinfo,smb2_info_t * si, guint16 dataoffset,guint32 length, guint64 file_offset) {
1372 char *fid_name = NULL;
1373 guint32 open_frame = 0, close_frame = 0;
1374 tvbuff_t *data_tvb = NULL;
1375 smb_eo_t *eo_info;
1376 gchar *file_id;
1377 gchar *auxstring;
1378 gchar **aux_string_v;
1380 /* Create a new tvb to point to the payload data */
1381 data_tvb = tvb_new_subset_length(tvb, dataoffset, length);
1382 /* Create the eo_info to pass to the listener */
1383 eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
1384 /* Fill in eo_info */
1385 eo_info->smbversion=2;
1386 /* cmd == opcode */
1387 eo_info->cmd=si->opcode;
1388 /* We don't keep track of uid in SMB v2 */
1389 eo_info->uid=0;
1391 /* Try to get file id and filename */
1392 file_id=policy_hnd_to_file_id(&si->saved->policy_hnd);
1393 dcerpc_fetch_polhnd_data(&si->saved->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num);
1394 if (fid_name && g_strcmp0(fid_name,"File: ")!=0) {
1395 auxstring=fid_name;
1396 /* Remove "File: " from filename */
1397 if (g_str_has_prefix(auxstring, "File: ")) {
1398 aux_string_v = g_strsplit(auxstring, "File: ", -1);
1399 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",aux_string_v[g_strv_length(aux_string_v)-1]);
1400 g_strfreev(aux_string_v);
1401 } else {
1402 if (g_str_has_prefix(auxstring, "\\")) {
1403 eo_info->filename = wmem_strdup(wmem_packet_scope(), auxstring);
1404 } else {
1405 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",auxstring);
1408 } else {
1409 auxstring=wmem_strdup_printf(wmem_packet_scope(), "File_Id_%s", file_id);
1410 eo_info->filename=auxstring;
1415 if (eosmb2_take_name_as_fid) {
1416 eo_info->fid = g_str_hash(eo_info->filename);
1417 } else {
1418 eo_info->fid = g_str_hash(file_id);
1421 /* tid, hostname, tree_id */
1422 if (si->tree) {
1423 eo_info->tid=si->tree->tid;
1424 if (strlen(si->tree->name)>0 && strlen(si->tree->name)<=256) {
1425 eo_info->hostname = wmem_strdup(wmem_packet_scope(), si->tree->name);
1426 } else {
1427 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,si->opcode),si->tree->tid);
1429 } else {
1430 eo_info->tid=0;
1431 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,si->opcode));
1434 /* packet number */
1435 eo_info->pkt_num = pinfo->num;
1437 /* fid type */
1438 if (si->eo_file_info->attr_mask & SMB2_FLAGS_ATTR_DIRECTORY) {
1439 eo_info->fid_type=SMB2_FID_TYPE_DIR;
1440 } else {
1441 if (si->eo_file_info->attr_mask &
1442 (SMB2_FLAGS_ATTR_ARCHIVE | SMB2_FLAGS_ATTR_NORMAL |
1443 SMB2_FLAGS_ATTR_HIDDEN | SMB2_FLAGS_ATTR_READONLY |
1444 SMB2_FLAGS_ATTR_SYSTEM) ) {
1445 eo_info->fid_type=SMB2_FID_TYPE_FILE;
1446 } else {
1447 eo_info->fid_type=SMB2_FID_TYPE_OTHER;
1451 /* end_of_file */
1452 eo_info->end_of_file=si->eo_file_info->end_of_file;
1454 /* data offset and chunk length */
1455 eo_info->smb_file_offset=file_offset;
1456 eo_info->smb_chunk_len=length;
1457 /* XXX is this right? */
1458 if (length<si->saved->bytes_moved) {
1459 si->saved->file_offset=si->saved->file_offset+length;
1460 si->saved->bytes_moved=si->saved->bytes_moved-length;
1463 /* Payload */
1464 eo_info->payload_len = length;
1465 eo_info->payload_data = tvb_get_ptr(data_tvb, 0, length);
1467 tap_queue_packet(smb2_eo_tap, pinfo, eo_info);
1471 static int dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
1474 /* This is a helper to dissect the common string type
1475 * uint16 offset
1476 * uint16 length
1477 * ...
1478 * char *string
1480 * This function is called twice, first to decode the offset/length and
1481 * second time to dissect the actual string.
1482 * It is done this way since there is no guarantee that we have the full packet and we don't
1483 * want to abort dissection too early if the packet ends somewhere between the
1484 * length/offset and the actual buffer.
1487 enum offset_length_buffer_offset_size {
1488 OLB_O_UINT16_S_UINT16,
1489 OLB_O_UINT16_S_UINT32,
1490 OLB_O_UINT32_S_UINT32,
1491 OLB_S_UINT32_O_UINT32
1493 typedef struct _offset_length_buffer_t {
1494 guint32 off;
1495 guint32 len;
1496 int off_offset;
1497 int len_offset;
1498 enum offset_length_buffer_offset_size offset_size;
1499 int hfindex;
1500 } offset_length_buffer_t;
1501 static int
1502 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
1503 enum offset_length_buffer_offset_size offset_size, int hfindex)
1505 olb->hfindex = hfindex;
1506 olb->offset_size = offset_size;
1507 switch (offset_size) {
1508 case OLB_O_UINT16_S_UINT16:
1509 olb->off = tvb_get_letohs(tvb, offset);
1510 olb->off_offset = offset;
1511 offset += 2;
1512 olb->len = tvb_get_letohs(tvb, offset);
1513 olb->len_offset = offset;
1514 offset += 2;
1515 break;
1516 case OLB_O_UINT16_S_UINT32:
1517 olb->off = tvb_get_letohs(tvb, offset);
1518 olb->off_offset = offset;
1519 offset += 2;
1520 olb->len = tvb_get_letohl(tvb, offset);
1521 olb->len_offset = offset;
1522 offset += 4;
1523 break;
1524 case OLB_O_UINT32_S_UINT32:
1525 olb->off = tvb_get_letohl(tvb, offset);
1526 olb->off_offset = offset;
1527 offset += 4;
1528 olb->len = tvb_get_letohl(tvb, offset);
1529 olb->len_offset = offset;
1530 offset += 4;
1531 break;
1532 case OLB_S_UINT32_O_UINT32:
1533 olb->len = tvb_get_letohl(tvb, offset);
1534 olb->len_offset = offset;
1535 offset += 4;
1536 olb->off = tvb_get_letohl(tvb, offset);
1537 olb->off_offset = offset;
1538 offset += 4;
1539 break;
1542 return offset;
1545 #define OLB_TYPE_UNICODE_STRING 0x01
1546 #define OLB_TYPE_ASCII_STRING 0x02
1547 static const guint8 *
1548 dissect_smb2_olb_off_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int base, int type)
1550 int len, off;
1551 proto_item *item = NULL;
1552 proto_tree *tree = NULL;
1553 const guint8 *name = NULL;
1555 olb->off += base;
1557 len = olb->len;
1558 off = olb->off;
1561 /* sanity check */
1562 tvb_ensure_bytes_exist(tvb, off, len);
1563 if (((off+len)<off)
1564 || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1565 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, off, -1,
1566 "Invalid offset/length. Malformed packet");
1568 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1570 return NULL;
1574 switch (type) {
1575 case OLB_TYPE_UNICODE_STRING:
1576 item = proto_tree_add_item_ret_string(parent_tree,
1577 olb->hfindex, tvb, off, len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
1578 wmem_packet_scope(), &name);
1579 tree = proto_item_add_subtree(item, ett_smb2_olb);
1580 break;
1581 case OLB_TYPE_ASCII_STRING:
1582 item = proto_tree_add_item_ret_string(parent_tree,
1583 olb->hfindex, tvb, off, len, ENC_ASCII|ENC_NA,
1584 wmem_packet_scope(), &name);
1585 tree = proto_item_add_subtree(item, ett_smb2_olb);
1586 break;
1589 switch (olb->offset_size) {
1590 case OLB_O_UINT16_S_UINT16:
1591 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1592 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1593 break;
1594 case OLB_O_UINT16_S_UINT32:
1595 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1596 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1597 break;
1598 case OLB_O_UINT32_S_UINT32:
1599 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1600 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1601 break;
1602 case OLB_S_UINT32_O_UINT32:
1603 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1604 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1605 break;
1608 return name;
1611 static const guint8 *
1612 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
1614 return dissect_smb2_olb_off_string(pinfo, parent_tree, tvb, olb, 0, type);
1617 static void
1618 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
1619 offset_length_buffer_t *olb, smb2_info_t *si,
1620 void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
1622 int len, off;
1623 proto_item *sub_item = NULL;
1624 proto_tree *sub_tree = NULL;
1625 tvbuff_t *sub_tvb = NULL;
1626 int offset;
1628 offset = olb->off;
1629 len = olb->len;
1630 off = olb->off;
1632 /* sanity check */
1633 tvb_ensure_bytes_exist(tvb, off, len);
1634 if (((off+len)<off)
1635 || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
1636 proto_tree_add_expert_format(parent_tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
1637 "Invalid offset/length. Malformed packet");
1639 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
1641 return;
1644 switch (olb->offset_size) {
1645 case OLB_O_UINT16_S_UINT16:
1646 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1647 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1648 break;
1649 case OLB_O_UINT16_S_UINT32:
1650 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1651 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1652 break;
1653 case OLB_O_UINT32_S_UINT32:
1654 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1655 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1656 break;
1657 case OLB_S_UINT32_O_UINT32:
1658 proto_tree_add_item(parent_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1659 proto_tree_add_item(parent_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1660 break;
1663 /* if we don't want/need a subtree */
1664 if (olb->hfindex == -1) {
1665 sub_item = parent_tree;
1666 sub_tree = parent_tree;
1667 } else {
1668 if (parent_tree) {
1669 sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
1670 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
1674 if (off == 0 || len == 0) {
1675 proto_item_append_text(sub_item, ": NO DATA");
1676 return;
1679 if (!dissector) {
1680 return;
1683 sub_tvb = tvb_new_subset_length_caplen(tvb, off, MIN((int)len, tvb_captured_length_remaining(tvb, off)), len);
1685 dissector(sub_tvb, pinfo, sub_tree, si);
1688 static int
1689 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
1691 if (olb->off == 0) {
1692 return offset;
1694 return MAX(offset, (int)(olb->off + olb->len));
1697 typedef struct _smb2_function {
1698 int (*request) (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1699 int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1700 } smb2_function;
1702 static const true_false_string tfs_smb2_svhdx_has_initiator_id = {
1703 "Has an initiator id",
1704 "Does not have an initiator id"
1707 static const true_false_string tfs_flags_response = {
1708 "This is a RESPONSE",
1709 "This is a REQUEST"
1712 static const true_false_string tfs_flags_async_cmd = {
1713 "This is an ASYNC command",
1714 "This is a SYNC command"
1717 static const true_false_string tfs_flags_dfs_op = {
1718 "This is a DFS OPERATION",
1719 "This is a normal operation"
1722 static const true_false_string tfs_flags_chained = {
1723 "This pdu is a CHAINED command",
1724 "This pdu is NOT a chained command"
1727 static const true_false_string tfs_flags_signature = {
1728 "This pdu is SIGNED",
1729 "This pdu is NOT signed"
1732 static const true_false_string tfs_flags_replay_operation = {
1733 "This is a REPLAY OPEARATION",
1734 "This is NOT a replay operation"
1737 static const true_false_string tfs_flags_priority_mask = {
1738 "This pdu contains a PRIORITY",
1739 "This pdu does NOT contain a PRIORITY"
1742 static const true_false_string tfs_cap_dfs = {
1743 "This host supports DFS",
1744 "This host does NOT support DFS"
1747 static const true_false_string tfs_cap_leasing = {
1748 "This host supports LEASING",
1749 "This host does NOT support LEASING"
1752 static const true_false_string tfs_cap_large_mtu = {
1753 "This host supports LARGE_MTU",
1754 "This host does NOT support LARGE_MTU"
1757 static const true_false_string tfs_cap_multi_channel = {
1758 "This host supports MULTI CHANNEL",
1759 "This host does NOT support MULTI CHANNEL"
1762 static const true_false_string tfs_cap_persistent_handles = {
1763 "This host supports PERSISTENT HANDLES",
1764 "This host does NOT support PERSISTENT HANDLES"
1767 static const true_false_string tfs_cap_directory_leasing = {
1768 "This host supports DIRECTORY LEASING",
1769 "This host does NOT support DIRECTORY LEASING"
1772 static const true_false_string tfs_cap_encryption = {
1773 "This host supports ENCRYPTION",
1774 "This host does NOT support ENCRYPTION"
1777 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rss = {
1778 "This interface supports RSS",
1779 "This interface does not support RSS"
1782 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rdma = {
1783 "This interface supports RDMA",
1784 "This interface does not support RDMA"
1787 static const value_string file_region_usage_vals[] = {
1788 { 0x00000001, "FILE_REGION_USAGE_VALID_CACHED_DATA" },
1789 { 0, NULL }
1792 static const value_string originator_flags_vals[] = {
1793 { 1, "SVHDX_ORIGINATOR_PVHDPARSER" },
1794 { 4, "SVHDX_ORIGINATOR_VHDMP" },
1795 { 0, NULL }
1798 static const value_string posix_locks_vals[] = {
1799 { 1, "POSIX_V1_POSIX_LOCK" },
1800 { 0, NULL }
1803 static const value_string posix_utf8_paths_vals[] = {
1804 { 1, "POSIX_V1_UTF8_PATHS" },
1805 { 0, NULL }
1808 static const value_string posix_file_semantics_vals[] = {
1809 { 1, "POSIX_V1_POSIX_FILE_SEMANTICS" },
1810 { 0, NULL }
1813 static const value_string posix_case_sensitive_vals[] = {
1814 { 1, "POSIX_V1_CASE_SENSITIVE" },
1815 { 0, NULL }
1818 static const value_string posix_will_convert_ntacls_vals[] = {
1819 { 1, "POSIX_V1_WILL_CONVERT_NT_ACLS" },
1820 { 0, NULL }
1823 static const value_string posix_fileinfo_vals[] = {
1824 { 1, "POSIX_V1_POSIX_FILEINFO" },
1825 { 0, NULL }
1828 static const value_string posix_acls_vals[] = {
1829 { 1, "POSIX_V1_POSIX_ACLS" },
1830 { 0, NULL }
1833 static const value_string posix_rich_acls_vals[] = {
1834 { 1, "POSIX_V1_RICH_ACLS" },
1835 { 0, NULL }
1838 static const value_string compression_format_vals[] = {
1839 { 0, "COMPRESSION_FORMAT_NONE" },
1840 { 1, "COMPRESSION_FORMAT_DEFAULT" },
1841 { 2, "COMPRESSION_FORMAT_LZNT1" },
1842 { 0, NULL }
1845 static const value_string checksum_algorithm_vals[] = {
1846 { 0x0000, "CHECKSUM_TYPE_NONE" },
1847 { 0x0002, "CHECKSUM_TYPE_CRC64" },
1848 { 0xFFFF, "CHECKSUM_TYPE_UNCHANGED" },
1849 { 0, NULL }
1852 /* Note: All uncommented are "dissector not implemented" */
1853 static const value_string smb2_ioctl_vals[] = {
1854 {0x00060194, "FSCTL_DFS_GET_REFERRALS"}, /* dissector implemented */
1855 {0x000601B0, "FSCTL_DFS_GET_REFERRALS_EX"},
1856 {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
1857 {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
1858 {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
1859 {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
1860 {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
1861 {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
1862 {0x00090018, "FSCTL_LOCK_VOLUME"},
1863 {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
1864 {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
1865 {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
1866 {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
1867 {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
1868 {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
1869 {0x0009003C, "FSCTL_GET_COMPRESSION"}, /* dissector implemented */
1870 {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
1871 {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
1872 {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
1873 {0x00090058, "FSCTL_QUERY_FAT_BPB"},
1874 {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
1875 {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
1876 {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
1877 {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
1878 {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
1879 {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
1880 {0x00090074, "FSCTL_MOVE_FILE"},
1881 {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
1882 {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
1883 {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
1884 {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
1885 {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
1886 {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
1887 {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
1888 {0x0009009C, "FSCTL_GET_OBJECT_ID"}, /* dissector implemented */
1889 {0x000900A4, "FSCTL_SET_REPARSE_POINT"}, /* dissector implemented */
1890 {0x000900A8, "FSCTL_GET_REPARSE_POINT"}, /* dissector implemented */
1891 {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"}, /* dissector implemented */
1892 {0x000900C4, "FSCTL_SET_SPARSE"}, /* dissector implemented */
1893 {0x000900D4, "FSCTL_SET_ENCRYPTION"},
1894 {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
1895 {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
1896 {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
1897 {0x000900F0, "FSCTL_EXTEND_VOLUME"},
1898 {0x00090244, "FSCTL_CSV_TUNNEL_REQUEST"},
1899 {0x0009027C, "FSCTL_GET_INTEGRITY_INFORMATION"},
1900 {0x00090284, "FSCTL_QUERY_FILE_REGIONS"}, /* dissector implemented */
1901 {0x000902c8, "FSCTL_CSV_SYNC_TUNNEL_REQUEST"},
1902 {0x00090300, "FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT"}, /* dissector implemented */
1903 {0x00090304, "FSCTL_SVHDX_SYNC_TUNNEL_REQUEST"}, /* dissector implemented */
1904 {0x00090308, "FSCTL_SVHDX_SET_INITIATOR_INFORMATION"},
1905 {0x0009030C, "FSCTL_SET_EXTERNAL_BACKING"},
1906 {0x00090310, "FSCTL_GET_EXTERNAL_BACKING"},
1907 {0x00090314, "FSCTL_DELETE_EXTERNAL_BACKING"},
1908 {0x00090318, "FSCTL_ENUM_EXTERNAL_BACKING"},
1909 {0x0009031F, "FSCTL_ENUM_OVERLAY"},
1910 {0x00090350, "FSCTL_STORAGE_QOS_CONTROL"}, /* dissector implemented */
1911 {0x00090364, "FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST"}, /* dissector implemented */
1912 {0x000940B3, "FSCTL_ENUM_USN_DATA"},
1913 {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
1914 {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
1915 {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"}, /* dissector implemented */
1916 {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
1917 {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
1918 {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
1919 {0x00094264, "FSCTL_OFFLOAD_READ"}, /* dissector implemented */
1920 {0x00098098, "FSCTL_SET_OBJECT_ID"}, /* dissector implemented */
1921 {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
1922 {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
1923 {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
1924 {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"}, /* dissector implemented */
1925 {0x000980C8, "FSCTL_SET_ZERO_DATA"}, /* dissector implemented */
1926 {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
1927 {0x00098208, "FSCTL_FILE_LEVEL_TRIM"},
1928 {0x00098268, "FSCTL_OFFLOAD_WRITE"}, /* dissector implemented */
1929 {0x0009C040, "FSCTL_SET_COMPRESSION"}, /* dissector implemented */
1930 {0x0009C280, "FSCTL_SET_INTEGRITY_INFORMATION"}, /* dissector implemented */
1931 {0x00110018, "FSCTL_PIPE_WAIT"}, /* dissector implemented */
1932 {0x0011400C, "FSCTL_PIPE_PEEK"},
1933 {0x0011C017, "FSCTL_PIPE_TRANSCEIVE"}, /* dissector implemented */
1934 {0x00140078, "FSCTL_SRV_REQUEST_RESUME_KEY"},
1935 {0x001401D4, "FSCTL_LMR_REQUEST_RESILIENCY"}, /* dissector implemented */
1936 {0x001401FC, "FSCTL_QUERY_NETWORK_INTERFACE_INFO"}, /* dissector implemented */
1937 {0x00140200, "FSCTL_VALIDATE_NEGOTIATE_INFO_224"}, /* dissector implemented */
1938 {0x00140204, "FSCTL_VALIDATE_NEGOTIATE_INFO"}, /* dissector implemented */
1939 {0x00144064, "FSCTL_SRV_ENUMERATE_SNAPSHOTS"}, /* dissector implemented */
1940 {0x001440F2, "FSCTL_SRV_COPYCHUNK"},
1941 {0x001441bb, "FSCTL_SRV_READ_HASH"},
1942 {0x001480F2, "FSCTL_SRV_COPYCHUNK_WRITE"},
1943 { 0, NULL }
1945 static value_string_ext smb2_ioctl_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_vals);
1947 static const value_string smb2_ioctl_device_vals[] = {
1948 { 0x0001, "BEEP" },
1949 { 0x0002, "CD_ROM" },
1950 { 0x0003, "CD_ROM_FILE_SYSTEM" },
1951 { 0x0004, "CONTROLLER" },
1952 { 0x0005, "DATALINK" },
1953 { 0x0006, "DFS" },
1954 { 0x0007, "DISK" },
1955 { 0x0008, "DISK_FILE_SYSTEM" },
1956 { 0x0009, "FILE_SYSTEM" },
1957 { 0x000a, "INPORT_PORT" },
1958 { 0x000b, "KEYBOARD" },
1959 { 0x000c, "MAILSLOT" },
1960 { 0x000d, "MIDI_IN" },
1961 { 0x000e, "MIDI_OUT" },
1962 { 0x000f, "MOUSE" },
1963 { 0x0010, "MULTI_UNC_PROVIDER" },
1964 { 0x0011, "NAMED_PIPE" },
1965 { 0x0012, "NETWORK" },
1966 { 0x0013, "NETWORK_BROWSER" },
1967 { 0x0014, "NETWORK_FILE_SYSTEM" },
1968 { 0x0015, "NULL" },
1969 { 0x0016, "PARALLEL_PORT" },
1970 { 0x0017, "PHYSICAL_NETCARD" },
1971 { 0x0018, "PRINTER" },
1972 { 0x0019, "SCANNER" },
1973 { 0x001a, "SERIAL_MOUSE_PORT" },
1974 { 0x001b, "SERIAL_PORT" },
1975 { 0x001c, "SCREEN" },
1976 { 0x001d, "SOUND" },
1977 { 0x001e, "STREAMS" },
1978 { 0x001f, "TAPE" },
1979 { 0x0020, "TAPE_FILE_SYSTEM" },
1980 { 0x0021, "TRANSPORT" },
1981 { 0x0022, "UNKNOWN" },
1982 { 0x0023, "VIDEO" },
1983 { 0x0024, "VIRTUAL_DISK" },
1984 { 0x0025, "WAVE_IN" },
1985 { 0x0026, "WAVE_OUT" },
1986 { 0x0027, "8042_PORT" },
1987 { 0x0028, "NETWORK_REDIRECTOR" },
1988 { 0x0029, "BATTERY" },
1989 { 0x002a, "BUS_EXTENDER" },
1990 { 0x002b, "MODEM" },
1991 { 0x002c, "VDM" },
1992 { 0x002d, "MASS_STORAGE" },
1993 { 0x002e, "SMB" },
1994 { 0x002f, "KS" },
1995 { 0x0030, "CHANGER" },
1996 { 0x0031, "SMARTCARD" },
1997 { 0x0032, "ACPI" },
1998 { 0x0033, "DVD" },
1999 { 0x0034, "FULLSCREEN_VIDEO" },
2000 { 0x0035, "DFS_FILE_SYSTEM" },
2001 { 0x0036, "DFS_VOLUME" },
2002 { 0x0037, "SERENUM" },
2003 { 0x0038, "TERMSRV" },
2004 { 0x0039, "KSEC" },
2005 { 0, NULL }
2007 static value_string_ext smb2_ioctl_device_vals_ext = VALUE_STRING_EXT_INIT(smb2_ioctl_device_vals);
2009 static const value_string smb2_ioctl_access_vals[] = {
2010 { 0x00, "FILE_ANY_ACCESS" },
2011 { 0x01, "FILE_READ_ACCESS" },
2012 { 0x02, "FILE_WRITE_ACCESS" },
2013 { 0x03, "FILE_READ_WRITE_ACCESS" },
2014 { 0, NULL }
2017 static const value_string smb2_ioctl_method_vals[] = {
2018 { 0x00, "METHOD_BUFFERED" },
2019 { 0x01, "METHOD_IN_DIRECT" },
2020 { 0x02, "METHOD_OUT_DIRECT" },
2021 { 0x03, "METHOD_NEITHER" },
2022 { 0, NULL }
2025 static const value_string smb2_ioctl_shared_virtual_disk_vals[] = {
2026 { 0x01, "SharedVirtualDisksSupported" },
2027 { 0x07, "SharedVirtualDiskCDPSnapshotsSupported" },
2028 { 0, NULL }
2031 static const value_string smb2_ioctl_shared_virtual_disk_hstate_vals[] = {
2032 { 0x00, "HandleStateNone" },
2033 { 0x01, "HandleStateFileShared" },
2034 { 0x03, "HandleStateShared" },
2035 { 0, NULL }
2038 /* this is called from both smb and smb2. */
2040 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
2042 proto_item *item = NULL;
2043 proto_tree *tree = NULL;
2044 guint32 ioctl_function;
2046 if (parent_tree) {
2047 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2048 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
2051 ioctl_function = tvb_get_letohl(tvb, offset);
2052 if (ioctlfunc)
2053 *ioctlfunc = ioctl_function;
2054 if (ioctl_function) {
2055 const gchar *unknown = "unknown";
2056 const gchar *ioctl_name = val_to_str_ext_const(ioctl_function,
2057 &smb2_ioctl_vals_ext,
2058 unknown);
2061 * val_to_str_const() doesn't work with a unknown == NULL
2063 if (ioctl_name == unknown) {
2064 ioctl_name = NULL;
2067 if (ioctl_name != NULL) {
2068 col_append_fstr(
2069 pinfo->cinfo, COL_INFO, " %s", ioctl_name);
2072 /* device */
2073 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2074 if (ioctl_name == NULL) {
2075 col_append_fstr(
2076 pinfo->cinfo, COL_INFO, " %s",
2077 val_to_str_ext((ioctl_function>>16)&0xffff, &smb2_ioctl_device_vals_ext,
2078 "Unknown (0x%08X)"));
2081 /* access */
2082 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2084 /* function */
2085 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2086 if (ioctl_name == NULL) {
2087 col_append_fstr(
2088 pinfo->cinfo, COL_INFO, " Function:0x%04x",
2089 (ioctl_function>>2)&0x0fff);
2092 /* method */
2093 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2096 offset += 4;
2098 return offset;
2101 /* fake the dce/rpc support structures so we can piggy back on
2102 * dissect_nt_policy_hnd() since this will allow us
2103 * a cheap way to track where FIDs are opened, closed
2104 * and fid->filename mappings
2105 * if we want to do those things in the future.
2107 #define FID_MODE_OPEN 0
2108 #define FID_MODE_CLOSE 1
2109 #define FID_MODE_USE 2
2110 #define FID_MODE_DHNQ 3
2111 #define FID_MODE_DHNC 4
2112 static int
2113 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
2115 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2116 static dcerpc_info di; /* fake dcerpc_info struct */
2117 static dcerpc_call_value call_data;
2118 e_ctx_hnd policy_hnd;
2119 e_ctx_hnd *policy_hnd_hashtablekey;
2120 proto_item *hnd_item = NULL;
2121 char *fid_name;
2122 guint32 open_frame = 0, close_frame = 0;
2123 smb2_eo_file_info_t *eo_file_info;
2124 smb2_fid_info_t sfi_key;
2125 smb2_fid_info_t *sfi = NULL;
2127 sfi_key.fid_persistent = tvb_get_letoh64(tvb, offset);
2128 sfi_key.fid_volatile = tvb_get_letoh64(tvb, offset+8);
2129 sfi_key.sesid = si->sesid;
2130 sfi_key.tid = si->tid;
2131 sfi_key.name = NULL;
2133 di.conformant_run = 0;
2134 /* we need di->call_data->flags.NDR64 == 0 */
2135 di.call_data = &call_data;
2137 switch (mode) {
2138 case FID_MODE_OPEN:
2139 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
2140 if (!pinfo->fd->visited) {
2141 sfi = wmem_new(wmem_file_scope(), smb2_fid_info_t);
2142 *sfi = sfi_key;
2143 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
2144 sfi->name = wmem_strdup(wmem_file_scope(), (char *)si->saved->extra_info);
2145 } else {
2146 sfi->name = wmem_strdup_printf(wmem_file_scope(), "[unknown]");
2149 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
2150 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: %s", (char *)si->saved->extra_info);
2151 } else {
2152 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: ");
2154 dcerpc_store_polhnd_name(&policy_hnd, pinfo,
2155 fid_name);
2157 g_hash_table_insert(si->conv->fids, sfi, sfi);
2158 si->file = sfi;
2160 /* If needed, create the file entry and save the policy hnd */
2161 if (si->saved) {
2162 si->saved->file = sfi;
2163 si->saved->policy_hnd = policy_hnd;
2166 if (si->conv) {
2167 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
2168 if (!eo_file_info) {
2169 eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
2170 policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
2171 memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
2172 eo_file_info->end_of_file=0;
2173 g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
2175 si->eo_file_info=eo_file_info;
2178 break;
2179 case FID_MODE_CLOSE:
2180 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
2181 break;
2182 case FID_MODE_USE:
2183 case FID_MODE_DHNQ:
2184 case FID_MODE_DHNC:
2185 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
2186 break;
2189 si->file = (smb2_fid_info_t *)g_hash_table_lookup(si->conv->fids, &sfi_key);
2190 if (si->file) {
2191 if (si->saved) {
2192 si->saved->file = si->file;
2194 if (si->file->name) {
2195 if (hnd_item) {
2196 proto_item_append_text(hnd_item, " File: %s", si->file->name);
2198 col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", si->file->name);
2202 if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
2203 /* look for the eo_file_info */
2204 if (!si->eo_file_info) {
2205 if (si->saved) { si->saved->policy_hnd = policy_hnd; }
2206 if (si->conv) {
2207 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
2208 if (eo_file_info) {
2209 si->eo_file_info=eo_file_info;
2210 } else { /* XXX This should never happen */
2211 eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
2212 policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
2213 memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
2214 eo_file_info->end_of_file=0;
2215 g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
2222 return offset;
2226 /* this info level is unique to SMB2 and differst from the corresponding
2227 * SMB_FILE_ALL_INFO in SMB
2229 static int
2230 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2232 proto_item *item = NULL;
2233 proto_tree *tree = NULL;
2234 int length;
2235 static const int *mode_fields[] = {
2236 &hf_smb2_mode_file_write_through,
2237 &hf_smb2_mode_file_sequential_only,
2238 &hf_smb2_mode_file_no_intermediate_buffering,
2239 &hf_smb2_mode_file_synchronous_io_alert,
2240 &hf_smb2_mode_file_synchronous_io_nonalert,
2241 &hf_smb2_mode_file_delete_on_close,
2242 NULL,
2245 if (parent_tree) {
2246 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
2247 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
2250 /* create time */
2251 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2253 /* last access */
2254 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2256 /* last write */
2257 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2259 /* last change */
2260 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2262 /* File Attributes */
2263 offset = dissect_file_ext_attr(tvb, tree, offset);
2265 /* some unknown bytes */
2266 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2267 offset += 4;
2269 /* allocation size */
2270 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2271 offset += 8;
2273 /* end of file */
2274 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2275 offset += 8;
2277 /* number of links */
2278 proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2279 offset += 4;
2281 /* delete pending */
2282 proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2283 offset += 1;
2285 /* is directory */
2286 proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2287 offset += 1;
2289 /* padding */
2290 offset += 2;
2292 /* file id */
2293 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2294 offset += 8;
2296 /* ea size */
2297 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2298 offset += 4;
2300 /* access mask */
2301 offset = dissect_smb_access_mask(tvb, tree, offset);
2303 /* Position Information */
2304 proto_tree_add_item(tree, hf_smb2_position_information, tvb, offset, 8, ENC_NA);
2305 offset += 8;
2307 /* Mode Information */
2308 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_mode_information, ett_smb2_file_mode_info, mode_fields, ENC_LITTLE_ENDIAN);
2309 offset += 4;
2311 /* Alignment Information */
2312 proto_tree_add_item(tree, hf_smb2_alignment_information, tvb, offset, 4, ENC_NA);
2313 offset +=4;
2315 /* file name length */
2316 length = tvb_get_letohs(tvb, offset);
2317 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2318 offset += 4;
2320 /* file name */
2321 if (length) {
2322 proto_tree_add_item(tree, hf_smb2_filename,
2323 tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
2324 offset += length;
2327 return offset;
2331 static int
2332 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2334 proto_item *item = NULL;
2335 proto_tree *tree = NULL;
2336 guint16 bc;
2337 gboolean trunc;
2339 if (parent_tree) {
2340 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, ENC_NA);
2341 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
2344 bc = tvb_captured_length_remaining(tvb, offset);
2345 offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2347 return offset;
2350 static int
2351 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2353 proto_item *item = NULL;
2354 proto_tree *tree = NULL;
2355 guint16 bc;
2356 gboolean trunc;
2358 if (parent_tree) {
2359 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, ENC_NA);
2360 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
2363 bc = tvb_captured_length_remaining(tvb, offset);
2364 offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2366 return offset;
2369 static int
2370 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2372 proto_item *item = NULL;
2373 proto_tree *tree = NULL;
2374 guint16 bc;
2375 gboolean trunc;
2377 if (parent_tree) {
2378 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, ENC_NA);
2379 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
2382 bc = tvb_captured_length_remaining(tvb, offset);
2383 offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
2385 return offset;
2389 static int
2390 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2392 proto_item *item = NULL;
2393 proto_tree *tree = NULL;
2395 if (parent_tree) {
2396 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, ENC_NA);
2397 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
2400 /* create time */
2401 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2403 /* last access */
2404 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2406 /* last write */
2407 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2409 /* last change */
2410 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2412 /* File Attributes */
2413 offset = dissect_file_ext_attr(tvb, tree, offset);
2415 /* some unknown bytes */
2416 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2417 offset += 4;
2419 return offset;
2422 static int
2423 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2425 proto_item *item = NULL;
2426 proto_tree *tree = NULL;
2427 guint16 bc;
2428 gboolean trunc;
2430 if (parent_tree) {
2431 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, ENC_NA);
2432 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
2435 bc = tvb_captured_length_remaining(tvb, offset);
2436 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2438 return offset;
2440 static int
2441 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2443 proto_item *item = NULL;
2444 proto_tree *tree = NULL;
2445 guint16 bc;
2446 gboolean trunc;
2448 if (parent_tree) {
2449 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, ENC_NA);
2450 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
2453 bc = tvb_captured_length_remaining(tvb, offset);
2454 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2456 return offset;
2458 static int
2459 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2461 proto_item *item = NULL;
2462 proto_tree *tree = NULL;
2463 guint16 bc;
2464 gboolean trunc;
2466 if (parent_tree) {
2467 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, ENC_NA);
2468 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
2471 bc = tvb_captured_length_remaining(tvb, offset);
2472 offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2474 return offset;
2476 static int
2477 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2479 proto_item *item = NULL;
2480 proto_tree *tree = NULL;
2481 guint16 bc;
2482 gboolean trunc;
2484 if (parent_tree) {
2485 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, ENC_NA);
2486 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
2489 bc = tvb_captured_length_remaining(tvb, offset);
2490 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2492 return offset;
2494 static int
2495 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2497 proto_item *item = NULL;
2498 proto_tree *tree = NULL;
2499 guint16 bc;
2500 gboolean trunc;
2502 if (parent_tree) {
2503 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, ENC_NA);
2504 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
2507 bc = tvb_captured_length_remaining(tvb, offset);
2508 offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2510 return offset;
2513 static int
2514 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2516 proto_item *item = NULL;
2517 proto_tree *tree = NULL;
2519 if (parent_tree) {
2520 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, ENC_NA);
2521 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
2524 /* access mask */
2525 offset = dissect_smb_access_mask(tvb, tree, offset);
2527 return offset;
2530 static int
2531 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2533 proto_item *item = NULL;
2534 proto_tree *tree = NULL;
2535 guint16 bc;
2536 gboolean trunc;
2538 if (parent_tree) {
2539 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, ENC_NA);
2540 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
2543 bc = tvb_captured_length_remaining(tvb, offset);
2544 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2546 return offset;
2549 static int
2550 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2552 proto_item *item = NULL;
2553 proto_tree *tree = NULL;
2554 guint16 bc;
2555 gboolean trunc;
2557 if (parent_tree) {
2558 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, ENC_NA);
2559 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
2562 bc = tvb_captured_length_remaining(tvb, offset);
2563 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
2565 return offset;
2568 static int
2569 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2571 proto_item *item = NULL;
2572 proto_tree *tree = NULL;
2573 guint16 bc;
2574 gboolean trunc;
2576 if (parent_tree) {
2577 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, ENC_NA);
2578 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
2581 bc = tvb_captured_length_remaining(tvb, offset);
2582 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2584 return offset;
2587 static int
2588 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2590 proto_item *item = NULL;
2591 proto_tree *tree = NULL;
2592 guint16 bc;
2593 gboolean trunc;
2595 if (parent_tree) {
2596 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, ENC_NA);
2597 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
2600 bc = tvb_captured_length_remaining(tvb, offset);
2601 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2603 return offset;
2606 static int
2607 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2609 proto_item *item = NULL;
2610 proto_tree *tree = NULL;
2611 guint16 bc;
2612 gboolean trunc;
2614 if (parent_tree) {
2615 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, ENC_NA);
2616 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
2620 bc = tvb_captured_length_remaining(tvb, offset);
2621 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2623 return offset;
2626 static int
2627 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2629 proto_item *item = NULL;
2630 proto_tree *tree = NULL;
2631 guint16 bc;
2632 gboolean trunc;
2634 if (parent_tree) {
2635 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, ENC_NA);
2636 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
2640 bc = tvb_captured_length_remaining(tvb, offset);
2641 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
2643 return offset;
2646 static const true_false_string tfs_disposition_delete_on_close = {
2647 "DELETE this file when closed",
2648 "Normal access, do not delete on close"
2651 static int
2652 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2654 proto_item *item = NULL;
2655 proto_tree *tree = NULL;
2657 if (parent_tree) {
2658 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, ENC_NA);
2659 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
2662 /* file disposition */
2663 proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2665 return offset;
2668 static int
2669 dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2671 proto_item *item = NULL;
2672 proto_tree *tree = NULL;
2673 guint32 next_offset;
2674 guint8 ea_name_len;
2675 guint16 ea_data_len;
2677 if (parent_tree) {
2678 item = proto_tree_add_item(parent_tree, hf_smb2_file_full_ea_info, tvb, offset, -1, ENC_NA);
2679 tree = proto_item_add_subtree(item, ett_smb2_file_full_ea_info);
2682 while (1) {
2683 char *name = NULL;
2684 char *data = NULL;
2685 int start_offset = offset;
2686 proto_item *ea_item;
2687 proto_tree *ea_tree;
2689 ea_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_ea, &ea_item, "EA:");
2691 /* next offset */
2692 next_offset = tvb_get_letohl(tvb, offset);
2693 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2694 offset += 4;
2696 /* EA flags */
2697 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2698 offset += 1;
2700 /* EA Name Length */
2701 ea_name_len = tvb_get_guint8(tvb, offset);
2702 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2703 offset += 1;
2705 /* EA Data Length */
2706 ea_data_len = tvb_get_letohs(tvb, offset);
2707 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2708 offset += 2;
2710 /* ea name */
2711 if (ea_name_len) {
2712 proto_tree_add_item_ret_display_string(ea_tree, hf_smb2_ea_name,
2713 tvb, offset, ea_name_len, ENC_ASCII|ENC_NA,
2714 wmem_packet_scope(), &name);
2717 /* The name is terminated with a NULL */
2718 offset += ea_name_len + 1;
2720 /* ea data */
2721 if (ea_data_len) {
2722 proto_tree_add_item_ret_display_string(ea_tree, hf_smb2_ea_data,
2723 tvb, offset, ea_data_len, ENC_NA,
2724 wmem_packet_scope(), &data);
2726 offset += ea_data_len;
2729 if (ea_item) {
2730 proto_item_append_text(ea_item, " %s := %s",
2731 name ? name : "",
2732 data ? data : "");
2734 proto_item_set_len(ea_item, offset-start_offset);
2737 if (!next_offset) {
2738 break;
2741 offset = start_offset+next_offset;
2744 return offset;
2747 static const true_false_string tfs_replace_if_exists = {
2748 "Replace the target if it exists",
2749 "Fail if the target exists"
2752 static int
2753 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2755 proto_item *item = NULL;
2756 proto_tree *tree = NULL;
2757 int length;
2760 if (parent_tree) {
2761 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, ENC_NA);
2762 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
2765 /* ReplaceIfExists */
2766 proto_tree_add_item(tree, hf_smb2_replace_if, tvb, offset, 1, ENC_NA);
2767 offset += 1;
2769 /* reserved */
2770 proto_tree_add_item(tree, hf_smb2_reserved_random, tvb, offset, 7, ENC_NA);
2771 offset += 7;
2773 /* Root Directory Handle, MBZ */
2774 proto_tree_add_item(tree, hf_smb2_root_directory_mbz, tvb, offset, 8, ENC_NA);
2775 offset += 8;
2777 /* file name length */
2778 length = tvb_get_letohs(tvb, offset);
2779 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2780 offset += 4;
2782 /* file name */
2783 if (length) {
2784 char *display_string;
2786 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
2787 tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN,
2788 wmem_packet_scope(), &display_string);
2789 col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s",
2790 display_string);
2791 offset += length;
2794 return offset;
2797 static int
2798 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2800 proto_item *item = NULL;
2801 proto_tree *tree = NULL;
2803 if (parent_tree) {
2804 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, ENC_NA);
2805 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
2808 /* security descriptor */
2809 offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_captured_length_remaining(tvb, offset), NULL);
2811 return offset;
2814 static int
2815 dissect_smb2_quota_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2817 proto_item *item = NULL;
2818 proto_tree *tree = NULL;
2819 guint16 bcp;
2821 if (parent_tree) {
2822 item = proto_tree_add_item(parent_tree, hf_smb2_quota_info, tvb, offset, -1, ENC_NA);
2823 tree = proto_item_add_subtree(item, ett_smb2_quota_info);
2826 bcp = tvb_captured_length_remaining(tvb, offset);
2827 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
2829 return offset;
2832 static int
2833 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2835 proto_item *item = NULL;
2836 proto_tree *tree = NULL;
2837 guint16 bc;
2839 if (parent_tree) {
2840 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, ENC_NA);
2841 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
2844 bc = tvb_captured_length_remaining(tvb, offset);
2845 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2847 return offset;
2850 static int
2851 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2853 proto_item *item = NULL;
2854 proto_tree *tree = NULL;
2855 guint16 bc;
2857 if (parent_tree) {
2858 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, ENC_NA);
2859 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
2862 bc = tvb_captured_length_remaining(tvb, offset);
2863 offset = dissect_nt_quota(tvb, tree, offset, &bc);
2865 return offset;
2868 static int
2869 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2871 proto_item *item = NULL;
2872 proto_tree *tree = NULL;
2874 if (parent_tree) {
2875 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, ENC_NA);
2876 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
2879 /* FILE_OBJECTID_BUFFER */
2880 offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2882 return offset;
2885 static int
2886 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2888 proto_item *item = NULL;
2889 proto_tree *tree = NULL;
2890 guint16 bc;
2892 if (parent_tree) {
2893 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, ENC_NA);
2894 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
2897 bc = tvb_captured_length_remaining(tvb, offset);
2898 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2900 return offset;
2903 static int
2904 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2906 proto_item *item = NULL;
2907 proto_tree *tree = NULL;
2908 guint16 bc;
2910 if (parent_tree) {
2911 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, ENC_NA);
2912 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
2916 bc = tvb_captured_length_remaining(tvb, offset);
2917 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2919 return offset;
2922 static int
2923 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2925 proto_item *item = NULL;
2926 proto_tree *tree = NULL;
2927 guint16 bc;
2929 if (parent_tree) {
2930 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, ENC_NA);
2931 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
2935 bc = tvb_captured_length_remaining(tvb, offset);
2936 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2938 return offset;
2941 static int
2942 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2944 proto_item *item = NULL;
2945 proto_tree *tree = NULL;
2946 guint16 bc;
2948 if (parent_tree) {
2949 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, ENC_NA);
2950 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
2954 bc = tvb_captured_length_remaining(tvb, offset);
2955 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
2957 return offset;
2960 static const value_string oplock_vals[] = {
2961 { 0x00, "No oplock" },
2962 { 0x01, "Level2 oplock" },
2963 { 0x08, "Exclusive oplock" },
2964 { 0x09, "Batch oplock" },
2965 { 0xff, "Lease" },
2966 { 0, NULL }
2969 static int
2970 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2972 proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2974 offset += 1;
2975 return offset;
2978 static int
2979 dissect_smb2_buffercode(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 *length)
2981 proto_tree *tree;
2982 proto_item *item;
2983 guint16 buffer_code;
2985 /* dissect the first 2 bytes of the command PDU */
2986 buffer_code = tvb_get_letohs(tvb, offset);
2987 item = proto_tree_add_uint(parent_tree, hf_smb2_buffer_code, tvb, offset, 2, buffer_code);
2988 tree = proto_item_add_subtree(item, ett_smb2_buffercode);
2989 proto_tree_add_item(tree, hf_smb2_buffer_code_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2990 proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2991 offset += 2;
2993 if (length) {
2994 *length = buffer_code; /*&0xfffe don't mask it here, mask it on caller side */
2997 return offset;
3000 #define NEGPROT_CAP_DFS 0x00000001
3001 #define NEGPROT_CAP_LEASING 0x00000002
3002 #define NEGPROT_CAP_LARGE_MTU 0x00000004
3003 #define NEGPROT_CAP_MULTI_CHANNEL 0x00000008
3004 #define NEGPROT_CAP_PERSISTENT_HANDLES 0x00000010
3005 #define NEGPROT_CAP_DIRECTORY_LEASING 0x00000020
3006 #define NEGPROT_CAP_ENCRYPTION 0x00000040
3007 static int
3008 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3010 static const int * flags[] = {
3011 &hf_smb2_cap_dfs,
3012 &hf_smb2_cap_leasing,
3013 &hf_smb2_cap_large_mtu,
3014 &hf_smb2_cap_multi_channel,
3015 &hf_smb2_cap_persistent_handles,
3016 &hf_smb2_cap_directory_leasing,
3017 &hf_smb2_cap_encryption,
3018 NULL
3021 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_capabilities, ett_smb2_capabilities, flags, ENC_LITTLE_ENDIAN);
3022 offset += 4;
3024 return offset;
3029 #define NEGPROT_SIGN_REQ 0x0002
3030 #define NEGPROT_SIGN_ENABLED 0x0001
3032 static int
3033 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3035 static const int * flags[] = {
3036 &hf_smb2_secmode_flags_sign_enabled,
3037 &hf_smb2_secmode_flags_sign_required,
3038 NULL
3041 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_security_mode, ett_smb2_sec_mode, flags, ENC_LITTLE_ENDIAN);
3042 offset += 1;
3044 return offset;
3047 #define SES_REQ_FLAGS_SESSION_BINDING 0x01
3049 static int
3050 dissect_smb2_ses_req_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3052 static const int * flags[] = {
3053 &hf_smb2_ses_req_flags_session_binding,
3054 NULL
3057 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_ses_req_flags, ett_smb2_ses_req_flags, flags, ENC_LITTLE_ENDIAN);
3058 offset += 1;
3060 return offset;
3063 #define SES_FLAGS_GUEST 0x0001
3064 #define SES_FLAGS_NULL 0x0002
3065 #define SES_FLAGS_ENCRYPT 0x0004
3067 static int
3068 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3070 static const int * flags[] = {
3071 &hf_smb2_ses_flags_guest,
3072 &hf_smb2_ses_flags_null,
3073 &hf_smb2_ses_flags_encrypt,
3074 NULL
3077 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb2_session_flags, ett_smb2_ses_flags, flags, ENC_LITTLE_ENDIAN);
3078 offset += 2;
3080 return offset;
3083 #define SHARE_FLAGS_manual_caching 0x00000000
3084 #define SHARE_FLAGS_auto_caching 0x00000010
3085 #define SHARE_FLAGS_vdo_caching 0x00000020
3086 #define SHARE_FLAGS_no_caching 0x00000030
3088 static const value_string share_cache_vals[] = {
3089 { SHARE_FLAGS_manual_caching, "Manual caching" },
3090 { SHARE_FLAGS_auto_caching, "Auto caching" },
3091 { SHARE_FLAGS_vdo_caching, "VDO caching" },
3092 { SHARE_FLAGS_no_caching, "No caching" },
3093 { 0, NULL }
3096 #define SHARE_FLAGS_dfs 0x00000001
3097 #define SHARE_FLAGS_dfs_root 0x00000002
3098 #define SHARE_FLAGS_restrict_exclusive_opens 0x00000100
3099 #define SHARE_FLAGS_force_shared_delete 0x00000200
3100 #define SHARE_FLAGS_allow_namespace_caching 0x00000400
3101 #define SHARE_FLAGS_access_based_dir_enum 0x00000800
3102 #define SHARE_FLAGS_force_levelii_oplock 0x00001000
3103 #define SHARE_FLAGS_enable_hash_v1 0x00002000
3104 #define SHARE_FLAGS_enable_hash_v2 0x00004000
3105 #define SHARE_FLAGS_encryption_required 0x00008000
3107 static int
3108 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
3110 static const int *sf_fields[] = {
3111 &hf_smb2_share_flags_dfs,
3112 &hf_smb2_share_flags_dfs_root,
3113 &hf_smb2_share_flags_restrict_exclusive_opens,
3114 &hf_smb2_share_flags_force_shared_delete,
3115 &hf_smb2_share_flags_allow_namespace_caching,
3116 &hf_smb2_share_flags_access_based_dir_enum,
3117 &hf_smb2_share_flags_force_levelii_oplock,
3118 &hf_smb2_share_flags_enable_hash_v1,
3119 &hf_smb2_share_flags_enable_hash_v2,
3120 &hf_smb2_share_flags_encrypt_data,
3121 NULL
3123 proto_item *item;
3124 guint32 cp;
3126 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, ENC_LITTLE_ENDIAN);
3128 cp = tvb_get_letohl(tvb, offset);
3129 cp &= 0x00000030;
3130 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);
3133 offset += 4;
3135 return offset;
3138 #define SHARE_CAPS_DFS 0x00000008
3139 #define SHARE_CAPS_CONTINUOUS_AVAILABILITY 0x00000010
3140 #define SHARE_CAPS_SCALEOUT 0x00000020
3141 #define SHARE_CAPS_CLUSTER 0x00000040
3143 static int
3144 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
3146 static const int *sc_fields[] = {
3147 &hf_smb2_share_caps_dfs,
3148 &hf_smb2_share_caps_continuous_availability,
3149 &hf_smb2_share_caps_scaleout,
3150 &hf_smb2_share_caps_cluster,
3151 NULL
3154 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, ENC_LITTLE_ENDIAN);
3156 offset += 4;
3158 return offset;
3161 static void
3162 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
3164 if ((tvb_captured_length(tvb)>=7)
3165 && (!tvb_memeql(tvb, 0, "NTLMSSP", 7))) {
3166 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
3167 } else {
3168 call_dissector(gssapi_handle, tvb, pinfo, tree);
3173 * Derive client and server decryption keys from the secret session key
3174 * and set them in the session object.
3176 static void smb2_generate_decryption_keys(smb2_conv_info_t *conv, smb2_sesid_info_t *ses)
3178 if (memcmp(ses->session_key, zeros, NTLMSSP_KEY_LEN) == 0)
3179 return;
3181 if (conv->dialect == 0x300) {
3182 smb2_key_derivation(ses->session_key,
3183 NTLMSSP_KEY_LEN,
3184 "SMB2AESCCM", 11,
3185 "ServerIn ", 10,
3186 ses->server_decryption_key);
3187 smb2_key_derivation(ses->session_key,
3188 NTLMSSP_KEY_LEN,
3189 "SMB2AESCCM", 11,
3190 "ServerOut", 10,
3191 ses->client_decryption_key);
3192 } else if (conv->dialect >= 0x311) {
3193 smb2_key_derivation(ses->session_key,
3194 NTLMSSP_KEY_LEN,
3195 "SMBC2SCipherKey", 16,
3196 ses->preauth_hash, SMB2_PREAUTH_HASH_SIZE,
3197 ses->server_decryption_key);
3198 smb2_key_derivation(ses->session_key,
3199 NTLMSSP_KEY_LEN,
3200 "SMBS2CCipherKey", 16,
3201 ses->preauth_hash, SMB2_PREAUTH_HASH_SIZE,
3202 ses->client_decryption_key);
3206 static int
3207 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3209 offset_length_buffer_t s_olb;
3210 const ntlmssp_header_t *ntlmssph;
3211 static int ntlmssp_tap_id = 0;
3212 smb2_saved_info_t *ssi = si->saved;
3213 proto_item *hash_item;
3214 int idx;
3216 if (!ntlmssp_tap_id) {
3217 GString *error_string;
3218 /* We don't specify any callbacks at all.
3219 * Instead we manually fetch the tapped data after the
3220 * security blob has been fully dissected and before
3221 * we exit from this dissector.
3223 error_string = register_tap_listener("ntlmssp", NULL, NULL,
3224 TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL, NULL);
3225 if (!error_string) {
3226 ntlmssp_tap_id = find_tap_id("ntlmssp");
3227 } else {
3228 g_string_free(error_string, TRUE);
3232 if (!pinfo->fd->visited && ssi) {
3233 /* compute preauth hash on first pass */
3235 /* start from last preauth hash of the connection if 1st request */
3236 if (si->sesid == 0)
3237 memcpy(si->conv->preauth_hash_ses, si->conv->preauth_hash_con, SMB2_PREAUTH_HASH_SIZE);
3239 ssi->preauth_hash_req = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
3240 update_preauth_hash(si->conv->preauth_hash_current, tvb);
3241 memcpy(ssi->preauth_hash_req, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
3244 if (ssi && ssi->preauth_hash_req) {
3245 hash_item = proto_tree_add_bytes_with_length(tree, hf_smb2_preauth_hash, tvb,
3246 0, tvb_captured_length(tvb),
3247 ssi->preauth_hash_req, SMB2_PREAUTH_HASH_SIZE);
3248 proto_item_set_generated(hash_item);
3251 /* buffer code */
3252 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3253 /* some unknown bytes */
3255 /* flags */
3256 offset = dissect_smb2_ses_req_flags(tree, tvb, offset);
3258 /* security mode */
3259 offset = dissect_smb2_secmode(tree, tvb, offset);
3261 /* capabilities */
3262 offset = dissect_smb2_capabilities(tree, tvb, offset);
3264 /* channel */
3265 proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3266 offset += 4;
3268 /* security blob offset/length */
3269 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3271 /* previous session id */
3272 proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3273 offset += 8;
3276 /* the security blob itself */
3277 dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3279 offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3281 /* If we have found a uid->acct_name mapping, store it */
3282 if (!pinfo->fd->visited) {
3283 idx = 0;
3284 while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
3285 if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
3286 si->session = smb2_get_session(si->conv, si->sesid, pinfo, si);
3287 si->session->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
3288 si->session->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
3289 si->session->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
3290 /* don't overwrite session key from preferences */
3291 if (memcmp(si->session->session_key, zeros, SMB_SESSION_ID_SIZE) == 0) {
3292 memcpy(si->session->session_key, ntlmssph->session_key, NTLMSSP_KEY_LEN);
3294 si->session->auth_frame = pinfo->num;
3299 return offset;
3302 static void
3303 dissect_smb2_share_redirect_error(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3305 proto_tree *tree;
3306 proto_item *item;
3307 proto_tree *ips_tree;
3308 proto_item *ips_item;
3310 offset_length_buffer_t res_olb;
3311 guint32 i, ip_count;
3313 item = proto_tree_add_item(parent_tree, hf_smb2_error_redir_context, tvb, offset, 0, ENC_NA);
3314 tree = proto_item_add_subtree(item, ett_smb2_error_redir_context);
3316 /* structure size */
3317 proto_tree_add_item(tree, hf_smb2_error_redir_struct_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3318 offset += 4;
3320 /* notification type */
3321 proto_tree_add_item(tree, hf_smb2_error_redir_notif_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3322 offset += 4;
3324 /* resource name offset/length */
3325 offset = dissect_smb2_olb_length_offset(tvb, offset, &res_olb, OLB_O_UINT32_S_UINT32, hf_smb2_error_redir_res_name);
3327 /* flags */
3328 proto_tree_add_item(tree, hf_smb2_error_redir_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3329 offset += 2;
3331 /* target type */
3332 proto_tree_add_item(tree, hf_smb2_error_redir_target_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3333 offset += 2;
3335 /* ip addr count */
3336 proto_tree_add_item_ret_uint(tree, hf_smb2_error_redir_ip_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &ip_count);
3337 offset += 4;
3339 /* ip addr list */
3340 ips_item = proto_tree_add_item(tree, hf_smb2_error_redir_ip_list, tvb, offset, 0, ENC_NA);
3341 ips_tree = proto_item_add_subtree(ips_item, ett_smb2_error_redir_ip_list);
3342 for (i = 0; i < ip_count; i++)
3343 offset += dissect_windows_sockaddr_storage(tvb, pinfo, ips_tree, offset, -1);
3345 /* resource name */
3346 dissect_smb2_olb_off_string(pinfo, tree, tvb, &res_olb, offset, OLB_TYPE_UNICODE_STRING);
3349 static void
3350 dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3352 proto_tree *tree;
3353 proto_item *item;
3355 offset_length_buffer_t s_olb, p_olb;
3357 item = proto_tree_add_item(parent_tree, hf_smb2_symlink_error_response, tvb, offset, -1, ENC_NA);
3358 tree = proto_item_add_subtree(item, ett_smb2_symlink_error_response);
3360 /* symlink length */
3361 proto_tree_add_item(tree, hf_smb2_symlink_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3362 offset += 4;
3364 /* symlink error tag */
3365 proto_tree_add_item(tree, hf_smb2_symlink_error_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3366 offset += 4;
3368 /* reparse tag */
3369 proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3370 offset += 4;
3372 proto_tree_add_item(tree, hf_smb2_reparse_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3373 offset += 2;
3375 proto_tree_add_item(tree, hf_smb2_unparsed_path_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3376 offset += 2;
3378 /* substitute name offset/length */
3379 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_substitute_name);
3381 /* print name offset/length */
3382 offset = dissect_smb2_olb_length_offset(tvb, offset, &p_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_print_name);
3384 /* flags */
3385 proto_tree_add_item(tree, hf_smb2_symlink_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3386 offset += 4;
3388 /* substitute name string */
3389 dissect_smb2_olb_off_string(pinfo, tree, tvb, &s_olb, offset, OLB_TYPE_UNICODE_STRING);
3391 /* print name string */
3392 dissect_smb2_olb_off_string(pinfo, tree, tvb, &p_olb, offset, OLB_TYPE_UNICODE_STRING);
3395 static int
3396 dissect_smb2_error_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
3398 proto_tree *tree;
3399 proto_item *item;
3400 tvbuff_t *sub_tvb;
3401 guint32 length;
3402 guint32 id;
3404 item = proto_tree_add_item(parent_tree, hf_smb2_error_context, tvb, offset, -1, ENC_NA);
3405 tree = proto_item_add_subtree(item, ett_smb2_error_context);
3407 proto_tree_add_item_ret_uint(tree, hf_smb2_error_context_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
3408 offset += 4;
3410 proto_tree_add_item_ret_uint(tree, hf_smb2_error_context_id, tvb, offset, 4, ENC_LITTLE_ENDIAN, &id);
3411 offset += 4;
3413 sub_tvb = tvb_new_subset_length(tvb, offset, length);
3414 dissect_smb2_error_data(sub_tvb, pinfo, tree, 0, id, si);
3415 offset += length;
3417 return offset;
3421 * Assumes it is being called with a sub-tvb (dissects at offsets 0)
3423 static void
3424 dissect_smb2_error_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
3425 int error_context_count, int error_id,
3426 smb2_info_t *si _U_)
3428 proto_tree *tree;
3429 proto_item *item;
3431 int offset = 0;
3432 int i;
3434 item = proto_tree_add_item(parent_tree, hf_smb2_error_data, tvb, offset, -1, ENC_NA);
3435 tree = proto_item_add_subtree(item, ett_smb2_error_data);
3437 if (error_context_count == 0) {
3438 if (tvb_captured_length_remaining(tvb, offset) <= 1)
3439 return;
3440 switch (si->status) {
3441 case NT_STATUS_STOPPED_ON_SYMLINK:
3442 dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvb, pinfo, tree, offset, si);
3443 break;
3444 case NT_STATUS_BUFFER_TOO_SMALL:
3445 proto_tree_add_item(tree, hf_smb2_error_min_buf_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3446 break;
3447 case NT_STATUS_BAD_NETWORK_NAME:
3448 if (error_id == SMB2_ERROR_ID_SHARE_REDIRECT)
3449 dissect_smb2_share_redirect_error(tvb, pinfo, tree, offset, si);
3450 default:
3451 break;
3453 } else {
3454 for (i = 0; i < error_context_count; i++)
3455 offset += dissect_smb2_error_context(tvb, pinfo, tree, offset, si);
3460 * SMB2 Error responses are a bit convoluted. Error data can be a list
3461 * of error contexts which themselves can hold an error data field.
3462 * See [MS-SMB2] 2.2.2.1.
3464 * ERROR_RESP := ERROR_DATA
3466 * ERROR_DATA := ( ERROR_CONTEXT + )
3467 * | ERROR_STATUS_STOPPED_ON_SYMLINK
3468 * | ERROR_ID_SHARE_REDIRECT
3469 * | ERROR_BUFFER_TOO_SMALL
3471 * ERROR_CONTEXT := ... + ERROR_DATA
3472 * | ERROR_ID_SHARE_REDIRECT
3474 * This needs more fixes for cases when the original header had also the constant value of 9.
3475 * This should be fixed on caller side where it decides if it has to call this or not.
3478 static int
3479 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si,
3480 gboolean* continue_dissection)
3482 gint byte_count;
3483 guint8 error_context_count;
3484 guint16 length;
3485 tvbuff_t *sub_tvb;
3487 /* buffer code */
3488 offset = dissect_smb2_buffercode(tree, tvb, offset, &length);
3490 /* FIX: error response uses this constant, if not then it is not an error response */
3491 if(length != 9)
3493 if(continue_dissection)
3494 *continue_dissection = TRUE;
3495 } else {
3496 if(continue_dissection)
3497 *continue_dissection = FALSE;
3499 /* ErrorContextCount (1 bytes) */
3500 error_context_count = tvb_get_guint8(tvb, offset);
3501 proto_tree_add_item(tree, hf_smb2_error_context_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3502 offset += 1;
3504 /* Reserved (1 bytes) */
3505 proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3506 offset += 1;
3508 /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
3509 byte_count = tvb_get_letohl(tvb, offset);
3510 proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3511 offset += 4;
3513 /* If the ByteCount field is zero then the server MUST supply an ErrorData field
3514 that is one byte in length */
3515 if (byte_count == 0) byte_count = 1;
3517 /* ErrorData (variable): A variable-length data field that contains extended
3518 error information.*/
3519 sub_tvb = tvb_new_subset_length(tvb, offset, byte_count);
3520 offset += byte_count;
3522 dissect_smb2_error_data(sub_tvb, pinfo, tree, error_context_count, 0, si);
3525 return offset;
3528 static int
3529 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3531 offset_length_buffer_t s_olb;
3532 proto_item *hash_item;
3533 smb2_saved_info_t *ssi = si->saved;
3535 si->session = smb2_get_session(si->conv, si->sesid, pinfo, si);
3536 if (si->status == 0) {
3537 si->session->auth_frame = pinfo->num;
3540 /* compute preauth hash on first pass */
3541 if (!pinfo->fd->visited && ssi) {
3542 ssi->preauth_hash_res = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
3544 * Preauth hash can only be used if the session is
3545 * established i.e. last session setup response has a
3546 * success status. As per the specification, the last
3547 * response is NOT hashed.
3549 if (si->status != 0) {
3551 * Not sucessful means either more req/rsp
3552 * processing is required or we reached an
3553 * error, so update hash.
3555 update_preauth_hash(si->conv->preauth_hash_current, tvb);
3556 } else {
3558 * Session is established, we can generate the keys
3560 memcpy(si->session->preauth_hash, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
3561 smb2_generate_decryption_keys(si->conv, si->session);
3564 /* In all cases, stash the preauth hash */
3565 memcpy(ssi->preauth_hash_res, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
3568 if (ssi && ssi->preauth_hash_res) {
3569 hash_item = proto_tree_add_bytes_with_length(tree, hf_smb2_preauth_hash, tvb,
3570 0, tvb_captured_length(tvb),
3571 ssi->preauth_hash_res, SMB2_PREAUTH_HASH_SIZE);
3572 proto_item_set_generated(hash_item);
3575 /* session_setup is special and we don't use dissect_smb2_error_response() here! */
3577 /* buffer code */
3578 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3580 /* session flags */
3581 offset = dissect_smb2_ses_flags(tree, tvb, offset);
3583 /* security blob offset/length */
3584 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3586 /* the security blob itself */
3587 dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3589 offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3591 /* If we have found a uid->acct_name mapping, store it */
3592 #ifdef HAVE_KERBEROS
3593 if (!pinfo->fd->visited && si->status == 0) {
3594 enc_key_t *ek;
3596 if (krb_decrypt) {
3597 read_keytab_file_from_preferences();
3600 for (ek=enc_key_list;ek;ek=ek->next) {
3601 if (ek->fd_num == (int)pinfo->num) {
3602 break;
3606 if (ek != NULL) {
3607 /* TODO: fill in the correct user/dom/host information */
3610 #endif
3612 return offset;
3615 static int
3616 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3618 offset_length_buffer_t olb;
3619 const guint8 *buf;
3621 /* buffer code */
3622 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3624 /* reserved */
3625 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3626 offset += 2;
3628 /* tree offset/length */
3629 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
3631 /* tree string */
3632 buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
3634 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3636 /* treelen +1 is overkill here if the string is unicode,
3637 * but who ever has more than a handful of TCON in a trace anyways
3639 if (!pinfo->fd->visited && si->saved && buf && olb.len) {
3640 si->saved->extra_info_type = SMB2_EI_TREENAME;
3641 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
3642 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
3645 if (buf) {
3646 col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s",
3647 format_text(wmem_packet_scope(), buf, strlen(buf)));
3650 return offset;
3652 static int
3653 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3655 guint8 share_type;
3656 gboolean continue_dissection;
3658 switch (si->status) {
3659 /* buffer code */
3660 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3661 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3662 if (!continue_dissection) return offset;
3665 /* share type */
3666 share_type = tvb_get_guint8(tvb, offset);
3667 proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3668 offset += 1;
3670 /* byte is reserved and must be set to zero */
3671 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
3672 offset += 1;
3674 if (!pinfo->fd->visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
3675 smb2_tid_info_t *tid, tid_key;
3677 tid_key.tid = si->tid;
3678 tid = (smb2_tid_info_t *)wmem_map_lookup(si->session->tids, &tid_key);
3679 if (tid) {
3680 wmem_map_remove(si->session->tids, &tid_key);
3682 tid = wmem_new(wmem_file_scope(), smb2_tid_info_t);
3683 tid->tid = si->tid;
3684 tid->name = (char *)si->saved->extra_info;
3685 tid->connect_frame = pinfo->num;
3686 tid->share_type = share_type;
3688 wmem_map_insert(si->session->tids, tid, tid);
3690 si->saved->extra_info_type = SMB2_EI_NONE;
3691 si->saved->extra_info = NULL;
3694 /* share flags */
3695 offset = dissect_smb2_share_flags(tree, tvb, offset);
3697 /* share capabilities */
3698 offset = dissect_smb2_share_caps(tree, tvb, offset);
3700 /* this is some sort of access mask */
3701 offset = dissect_smb_access_mask(tvb, tree, offset);
3703 return offset;
3706 static int
3707 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3709 /* buffer code */
3710 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3712 /* reserved */
3713 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3714 offset += 2;
3716 return offset;
3719 static int
3720 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3722 gboolean continue_dissection;
3724 switch (si->status) {
3725 /* buffer code */
3726 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3727 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3728 if (!continue_dissection) return offset;
3731 /* reserved */
3732 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3733 offset += 2;
3735 return offset;
3738 static int
3739 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3741 /* buffer code */
3742 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3744 /* reserved bytes */
3745 offset += 2;
3747 return offset;
3750 static int
3751 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3753 gboolean continue_dissection;
3755 switch (si->status) {
3756 /* buffer code */
3757 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3758 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3759 if (!continue_dissection) return offset;
3762 /* reserved bytes */
3763 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
3764 offset += 2;
3766 return offset;
3769 static int
3770 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3772 /* buffer code */
3773 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3775 /* some unknown bytes */
3776 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3777 offset += 2;
3779 return offset;
3782 static int
3783 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3785 gboolean continue_dissection;
3787 switch (si->status) {
3788 /* buffer code */
3789 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3790 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3791 if (!continue_dissection) return offset;
3794 /* some unknown bytes */
3795 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3796 offset += 2;
3798 return offset;
3801 static int
3802 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3804 proto_tree *flags_tree = NULL;
3805 proto_item *flags_item = NULL;
3807 /* buffer code */
3808 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3810 /* notify flags */
3811 if (tree) {
3812 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3813 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
3815 proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3816 offset += 2;
3818 /* output buffer length */
3819 proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3820 offset += 4;
3822 /* fid */
3823 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3825 /* completion filter */
3826 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
3828 /* reserved */
3829 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
3830 offset += 4;
3832 return offset;
3835 static const value_string notify_action_vals[] = {
3836 {0x01, "FILE_ACTION_ADDED"},
3837 {0x02, "FILE_ACTION_REMOVED"},
3838 {0x03, "FILE_ACTION_MODIFIED"},
3839 {0x04, "FILE_ACTION_RENAMED_OLD_NAME"},
3840 {0x05, "FILE_ACTION_RENAMED_NEW_NAME"},
3841 {0x06, "FILE_ACTION_ADDED_STREAM"},
3842 {0x07, "FILE_ACTION_REMOVED_STREAM"},
3843 {0x08, "FILE_ACTION_MODIFIED_STREAM"},
3844 {0x09, "FILE_ACTION_REMOVED_BY_DELETE"},
3845 {0, NULL}
3848 static void
3849 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3851 proto_tree *tree = NULL;
3852 proto_item *item = NULL;
3853 int offset = 0;
3855 while (tvb_reported_length_remaining(tvb, offset) > 4) {
3856 guint32 start_offset = offset;
3857 guint32 next_offset;
3858 guint32 length;
3860 if (parent_tree) {
3861 item = proto_tree_add_item(parent_tree, hf_smb2_notify_info, tvb, offset, -1, ENC_NA);
3862 tree = proto_item_add_subtree(item, ett_smb2_notify_info);
3865 /* next offset */
3866 proto_tree_add_item_ret_uint(tree, hf_smb2_notify_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &next_offset);
3867 offset += 4;
3869 proto_tree_add_item(tree, hf_smb2_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3870 offset += 4;
3872 /* file name length */
3873 proto_tree_add_item_ret_uint(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
3874 offset += 4;
3876 /* file name */
3877 if (length) {
3878 proto_tree_add_item(tree, hf_smb2_filename,
3879 tvb, offset, length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
3882 if (!next_offset) {
3883 break;
3886 offset = start_offset+next_offset;
3890 static int
3891 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3893 offset_length_buffer_t olb;
3894 gboolean continue_dissection;
3896 switch (si->status) {
3897 /* MS-SMB2 3.3.4.4 says STATUS_NOTIFY_ENUM_DIR is not treated as an error */
3898 case 0x0000010c: /* STATUS_NOTIFY_ENUM_DIR */
3899 case 0x00000000: /* buffer code */
3900 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
3901 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
3902 if (!continue_dissection) return offset;
3905 /* out buffer offset/length */
3906 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
3908 /* out buffer */
3909 dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
3910 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3912 return offset;
3915 #define SMB2_FIND_FLAG_RESTART_SCANS 0x01
3916 #define SMB2_FIND_FLAG_SINGLE_ENTRY 0x02
3917 #define SMB2_FIND_FLAG_INDEX_SPECIFIED 0x04
3918 #define SMB2_FIND_FLAG_REOPEN 0x10
3920 static int
3921 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3923 offset_length_buffer_t olb;
3924 const guint8 *buf;
3925 guint8 il;
3926 static const int *f_fields[] = {
3927 &hf_smb2_find_flags_restart_scans,
3928 &hf_smb2_find_flags_single_entry,
3929 &hf_smb2_find_flags_index_specified,
3930 &hf_smb2_find_flags_reopen,
3931 NULL
3934 /* buffer code */
3935 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3937 il = tvb_get_guint8(tvb, offset);
3938 if (si->saved) {
3939 si->saved->infolevel = il;
3942 /* infolevel */
3943 proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
3944 offset += 1;
3946 /* find flags */
3947 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, ENC_LITTLE_ENDIAN);
3948 offset += 1;
3950 /* file index */
3951 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3952 offset += 4;
3954 /* fid */
3955 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3957 /* search pattern offset/length */
3958 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
3960 /* output buffer length */
3961 proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3962 offset += 4;
3964 /* search pattern */
3965 buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
3967 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3969 if (!pinfo->fd->visited && si->saved && olb.len) {
3970 si->saved->extra_info_type = SMB2_EI_FINDPATTERN;
3971 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
3972 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
3975 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
3976 val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
3977 buf);
3979 return offset;
3982 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3984 int offset = 0;
3985 proto_item *item = NULL;
3986 proto_tree *tree = NULL;
3988 while (tvb_reported_length_remaining(tvb, offset) > 4) {
3989 int old_offset = offset;
3990 int next_offset;
3991 int file_name_len;
3993 if (parent_tree) {
3994 item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, ENC_NA);
3995 tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
3998 /* next offset */
3999 next_offset = tvb_get_letohl(tvb, offset);
4000 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4001 offset += 4;
4003 /* file index */
4004 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4005 offset += 4;
4007 /* create time */
4008 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4010 /* last access */
4011 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4013 /* last write */
4014 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4016 /* last change */
4017 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4019 /* end of file */
4020 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4021 offset += 8;
4023 /* allocation size */
4024 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4025 offset += 8;
4027 /* File Attributes */
4028 offset = dissect_file_ext_attr(tvb, tree, offset);
4030 /* file name length */
4031 file_name_len = tvb_get_letohl(tvb, offset);
4032 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4033 offset += 4;
4035 /* file name */
4036 if (file_name_len) {
4037 char *display_string;
4039 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4040 tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4041 wmem_packet_scope(), &display_string);
4042 proto_item_append_text(item, ": %s", display_string);
4043 offset += file_name_len;
4046 proto_item_set_len(item, offset-old_offset);
4048 if (next_offset == 0) {
4049 return;
4052 offset = old_offset+next_offset;
4053 if (offset < old_offset) {
4054 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4055 "Invalid offset/length. Malformed packet");
4056 return;
4061 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4063 int offset = 0;
4064 proto_item *item = NULL;
4065 proto_tree *tree = NULL;
4067 while (tvb_reported_length_remaining(tvb, offset) > 4) {
4068 int old_offset = offset;
4069 int next_offset;
4070 int file_name_len;
4072 if (parent_tree) {
4073 item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, ENC_NA);
4074 tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
4077 /* next offset */
4078 next_offset = tvb_get_letohl(tvb, offset);
4079 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4080 offset += 4;
4082 /* file index */
4083 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4084 offset += 4;
4086 /* create time */
4087 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4089 /* last access */
4090 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4092 /* last write */
4093 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4095 /* last change */
4096 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4098 /* end of file */
4099 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4100 offset += 8;
4102 /* allocation size */
4103 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4104 offset += 8;
4106 /* File Attributes */
4107 offset = dissect_file_ext_attr(tvb, tree, offset);
4109 /* file name length */
4110 file_name_len = tvb_get_letohl(tvb, offset);
4111 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4112 offset += 4;
4114 /* ea size */
4115 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4116 offset += 4;
4118 /* file name */
4119 if (file_name_len) {
4120 char *display_string;
4122 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4123 tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4124 wmem_packet_scope(), &display_string);
4125 proto_item_append_text(item, ": %s", display_string);
4126 offset += file_name_len;
4129 proto_item_set_len(item, offset-old_offset);
4131 if (next_offset == 0) {
4132 return;
4135 offset = old_offset+next_offset;
4136 if (offset < old_offset) {
4137 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4138 "Invalid offset/length. Malformed packet");
4139 return;
4144 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4146 int offset = 0;
4147 proto_item *item = NULL;
4148 proto_tree *tree = NULL;
4150 while (tvb_reported_length_remaining(tvb, offset) > 4) {
4151 int old_offset = offset;
4152 int next_offset;
4153 int file_name_len;
4154 int short_name_len;
4156 if (parent_tree) {
4157 item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
4158 tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
4161 /* next offset */
4162 next_offset = tvb_get_letohl(tvb, offset);
4163 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4164 offset += 4;
4166 /* file index */
4167 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4168 offset += 4;
4170 /* create time */
4171 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4173 /* last access */
4174 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4176 /* last write */
4177 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4179 /* last change */
4180 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4182 /* end of file */
4183 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4184 offset += 8;
4186 /* allocation size */
4187 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4188 offset += 8;
4190 /* File Attributes */
4191 offset = dissect_file_ext_attr(tvb, tree, offset);
4193 /* file name length */
4194 file_name_len = tvb_get_letohl(tvb, offset);
4195 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4196 offset += 4;
4198 /* ea size */
4199 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4200 offset += 4;
4202 /* short name length */
4203 short_name_len = tvb_get_guint8(tvb, offset);
4204 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4205 offset += 1;
4207 /* reserved */
4208 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
4209 offset += 1;
4211 /* short name */
4212 if (short_name_len) {
4213 proto_tree_add_item(tree, hf_smb2_short_name,
4214 tvb, offset, short_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
4216 offset += 24;
4218 /* file name */
4219 if (file_name_len) {
4220 char *display_string;
4222 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4223 tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4224 wmem_packet_scope(), &display_string);
4225 proto_item_append_text(item, ": %s", display_string);
4226 offset += file_name_len;
4229 proto_item_set_len(item, offset-old_offset);
4231 if (next_offset == 0) {
4232 return;
4235 offset = old_offset+next_offset;
4236 if (offset < old_offset) {
4237 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4238 "Invalid offset/length. Malformed packet");
4239 return;
4244 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4246 int offset = 0;
4247 proto_item *item = NULL;
4248 proto_tree *tree = NULL;
4250 while (tvb_reported_length_remaining(tvb, offset) > 4) {
4251 int old_offset = offset;
4252 int next_offset;
4253 int file_name_len;
4255 if (parent_tree) {
4256 item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
4257 tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
4260 /* next offset */
4261 next_offset = tvb_get_letohl(tvb, offset);
4262 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4263 offset += 4;
4265 /* file index */
4266 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4267 offset += 4;
4269 /* file name length */
4270 file_name_len = tvb_get_letohl(tvb, offset);
4271 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4272 offset += 4;
4274 /* file name */
4275 if (file_name_len) {
4276 char *display_string;
4278 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4279 tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4280 wmem_packet_scope(), &display_string);
4281 proto_item_append_text(item, ": %s", display_string);
4282 offset += file_name_len;
4285 proto_item_set_len(item, offset-old_offset);
4287 if (next_offset == 0) {
4288 return;
4291 offset = old_offset+next_offset;
4292 if (offset < old_offset) {
4293 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4294 "Invalid offset/length. Malformed packet");
4295 return;
4300 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4302 int offset = 0;
4303 proto_item *item = NULL;
4304 proto_tree *tree = NULL;
4306 while (tvb_reported_length_remaining(tvb, offset) > 4) {
4307 int old_offset = offset;
4308 int next_offset;
4309 int file_name_len;
4310 int short_name_len;
4312 if (parent_tree) {
4313 item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
4314 tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
4317 /* next offset */
4318 next_offset = tvb_get_letohl(tvb, offset);
4319 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4320 offset += 4;
4322 /* file index */
4323 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4324 offset += 4;
4326 /* create time */
4327 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4329 /* last access */
4330 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4332 /* last write */
4333 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4335 /* last change */
4336 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4338 /* end of file */
4339 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4340 offset += 8;
4342 /* allocation size */
4343 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4344 offset += 8;
4346 /* File Attributes */
4347 offset = dissect_file_ext_attr(tvb, tree, offset);
4349 /* file name length */
4350 file_name_len = tvb_get_letohl(tvb, offset);
4351 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4352 offset += 4;
4354 /* ea size */
4355 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4356 offset += 4;
4358 /* short name length */
4359 short_name_len = tvb_get_guint8(tvb, offset);
4360 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4361 offset += 1;
4363 /* reserved */
4364 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
4365 offset += 1;
4367 /* short name */
4368 if (short_name_len) {
4369 proto_tree_add_item(tree, hf_smb2_short_name,
4370 tvb, offset, short_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
4372 offset += 24;
4374 /* reserved */
4375 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4376 offset += 2;
4378 /* file id */
4379 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4380 offset += 8;
4382 /* file name */
4383 if (file_name_len) {
4384 char *display_string;
4386 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4387 tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4388 wmem_packet_scope(), &display_string);
4389 proto_item_append_text(item, ": %s", display_string);
4390 offset += file_name_len;
4393 proto_item_set_len(item, offset-old_offset);
4395 if (next_offset == 0) {
4396 return;
4399 offset = old_offset+next_offset;
4400 if (offset < old_offset) {
4401 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4402 "Invalid offset/length. Malformed packet");
4403 return;
4409 static void dissect_smb2_id_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
4411 int offset = 0;
4412 proto_item *item = NULL;
4413 proto_tree *tree = NULL;
4415 while (tvb_reported_length_remaining(tvb, offset) > 4) {
4416 int old_offset = offset;
4417 int next_offset;
4418 int file_name_len;
4420 if (parent_tree) {
4421 item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
4422 tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
4425 /* next offset */
4426 next_offset = tvb_get_letohl(tvb, offset);
4427 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4428 offset += 4;
4430 /* file index */
4431 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4432 offset += 4;
4434 /* create time */
4435 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
4437 /* last access */
4438 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
4440 /* last write */
4441 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
4443 /* last change */
4444 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
4446 /* end of file */
4447 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4448 offset += 8;
4450 /* allocation size */
4451 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4452 offset += 8;
4454 /* File Attributes */
4455 offset = dissect_file_ext_attr(tvb, tree, offset);
4457 /* file name length */
4458 file_name_len = tvb_get_letohl(tvb, offset);
4459 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4460 offset += 4;
4462 /* ea size */
4463 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4464 offset += 4;
4466 /* reserved */
4467 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4468 offset += 4;
4470 /* file id */
4471 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4472 offset += 8;
4474 /* file name */
4475 if (file_name_len) {
4476 char *display_string;
4478 proto_tree_add_item_ret_display_string(tree, hf_smb2_filename,
4479 tvb, offset, file_name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
4480 wmem_packet_scope(), &display_string);
4481 proto_item_append_text(item, ": %s", display_string);
4482 offset += file_name_len;
4485 proto_item_set_len(item, offset-old_offset);
4487 if (next_offset == 0) {
4488 return;
4491 offset = old_offset+next_offset;
4492 if (offset < old_offset) {
4493 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_invalid_length, tvb, offset, -1,
4494 "Invalid offset/length. Malformed packet");
4495 return;
4501 typedef struct _smb2_find_dissector_t {
4502 guint32 level;
4503 void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
4504 } smb2_find_dissector_t;
4506 smb2_find_dissector_t smb2_find_dissectors[] = {
4507 {SMB2_FIND_DIRECTORY_INFO, dissect_smb2_file_directory_info},
4508 {SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
4509 {SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
4510 {SMB2_FIND_NAME_INFO, dissect_smb2_file_name_info},
4511 {SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
4512 {SMB2_FIND_ID_FULL_DIRECTORY_INFO,dissect_smb2_id_full_directory_info},
4513 {0, NULL}
4516 static void
4517 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4519 smb2_find_dissector_t *dis = smb2_find_dissectors;
4521 while (dis->dissector) {
4522 if (si && si->saved) {
4523 if (dis->level == si->saved->infolevel) {
4524 dis->dissector(tvb, pinfo, tree, si);
4525 return;
4528 dis++;
4531 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
4534 static int
4535 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4537 offset_length_buffer_t olb;
4538 proto_item *item = NULL;
4539 gboolean continue_dissection;
4541 if (si->saved) {
4542 /* infolevel */
4543 item = proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
4544 proto_item_set_generated(item);
4547 if (!pinfo->fd->visited && si->saved && si->saved->extra_info_type == SMB2_EI_FINDPATTERN) {
4548 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
4549 val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
4550 (const char *)si->saved->extra_info);
4552 wmem_free(wmem_file_scope(), si->saved->extra_info);
4553 si->saved->extra_info_type = SMB2_EI_NONE;
4554 si->saved->extra_info = NULL;
4557 switch (si->status) {
4558 /* buffer code */
4559 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4560 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4561 if (!continue_dissection) return offset;
4564 /* findinfo offset */
4565 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
4567 /* the buffer */
4568 dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
4570 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
4572 return offset;
4575 static int
4576 dissect_smb2_negotiate_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
4578 guint16 type;
4579 const gchar *type_str;
4580 guint32 i, data_length, salt_length, hash_count, cipher_count, comp_count;
4581 proto_item *sub_item;
4582 proto_tree *sub_tree;
4584 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_negotiate_context_element, &sub_item, "Negotiate Context");
4586 /* type */
4587 type = tvb_get_letohl(tvb, offset);
4588 type_str = val_to_str(type, smb2_negotiate_context_types, "Unknown Type: (0x%0x)");
4589 proto_item_append_text(sub_item, ": %s ", type_str);
4590 proto_tree_add_item(sub_tree, hf_smb2_negotiate_context_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4591 offset += 2;
4593 /* data length */
4594 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_negotiate_context_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &data_length);
4595 offset += 2;
4597 /* reserved */
4598 proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
4599 offset += 4;
4601 switch (type)
4603 case SMB2_PREAUTH_INTEGRITY_CAPABILITIES:
4604 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_hash_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &hash_count);
4605 offset += 2;
4606 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_salt_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &salt_length);
4607 offset += 2;
4609 for (i = 0; i < hash_count; i++)
4611 proto_tree_add_item(sub_tree, hf_smb2_hash_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4612 offset += 2;
4615 if (salt_length)
4617 proto_tree_add_item(sub_tree, hf_smb2_salt, tvb, offset, salt_length, ENC_NA);
4618 offset += salt_length;
4620 break;
4622 case SMB2_ENCRYPTION_CAPABILITIES:
4623 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_cipher_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &cipher_count);
4624 offset += 2;
4626 for (i = 0; i < cipher_count; i ++)
4628 /* in SMB3.1.1 the first cipher returned by the server session encryption algorithm */
4629 if (i == 0 && si && si->conv && (si->flags & SMB2_FLAGS_RESPONSE)) {
4630 guint16 first_cipher = tvb_get_letohs(tvb, offset);
4631 si->conv->enc_alg = first_cipher;
4633 proto_tree_add_item(sub_tree, hf_smb2_cipher_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4634 offset += 2;
4636 break;
4638 case SMB2_COMPRESSION_CAPABILITIES:
4639 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_comp_alg_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &comp_count);
4640 offset += 2;
4642 /* padding */
4643 offset += 2;
4645 /* reserved */
4646 offset += 4;
4648 for (i = 0; i < comp_count; i ++) {
4649 proto_tree_add_item(sub_tree, hf_smb2_comp_alg_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4650 offset += 2;
4652 break;
4654 case SMB2_NETNAME_NEGOTIATE_CONTEXT_ID:
4655 proto_tree_add_item(sub_tree, hf_smb2_netname_neg_id, tvb, offset,
4656 data_length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
4657 offset += data_length;
4658 break;
4660 default:
4661 proto_tree_add_item(sub_tree, hf_smb2_unknown, tvb, offset, data_length, ENC_NA);
4662 offset += data_length;
4663 break;
4666 return offset;
4669 static int
4670 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4672 guint16 dc;
4673 guint16 i;
4674 gboolean supports_smb_3_10 = FALSE;
4675 guint32 nco;
4676 guint16 ncc;
4677 proto_item *hash_item = NULL;
4678 smb2_saved_info_t *ssi = si->saved;
4680 /* compute preauth hash on first pass */
4681 if (!pinfo->fd->visited && ssi) {
4682 ssi->preauth_hash_req = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
4683 memset(si->conv->preauth_hash_ses, 0, SMB2_PREAUTH_HASH_SIZE);
4684 memset(si->conv->preauth_hash_con, 0, SMB2_PREAUTH_HASH_SIZE);
4685 si->conv->preauth_hash_current = si->conv->preauth_hash_con;
4686 update_preauth_hash(si->conv->preauth_hash_current, tvb);
4687 memcpy(ssi->preauth_hash_req, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
4690 if (ssi && ssi->preauth_hash_req) {
4691 hash_item = proto_tree_add_bytes_with_length(tree,
4692 hf_smb2_preauth_hash, tvb,
4693 0, tvb_captured_length(tvb),
4694 ssi->preauth_hash_req, SMB2_PREAUTH_HASH_SIZE);
4695 proto_item_set_generated(hash_item);
4698 /* buffer code */
4699 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4701 /* dialect count */
4702 dc = tvb_get_letohs(tvb, offset);
4703 proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4704 offset += 2;
4706 /* security mode, skip second byte */
4707 offset = dissect_smb2_secmode(tree, tvb, offset);
4708 offset++;
4711 /* reserved */
4712 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4713 offset += 2;
4715 /* capabilities */
4716 offset = dissect_smb2_capabilities(tree, tvb, offset);
4718 /* client guid */
4719 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4720 offset += 16;
4722 /* negotiate context offset */
4723 nco = tvb_get_letohl(tvb, offset);
4724 proto_tree_add_item(tree, hf_smb2_negotiate_context_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4725 offset += 4;
4727 /* negotiate context count */
4728 ncc = tvb_get_letohs(tvb, offset);
4729 proto_tree_add_item(tree, hf_smb2_negotiate_context_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4730 offset += 2;
4732 /* reserved */
4733 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4734 offset += 2;
4736 for (i = 0 ; i < dc; i++) {
4737 guint16 d = tvb_get_letohs(tvb, offset);
4738 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4739 offset += 2;
4741 if (d >= 0x310) {
4742 supports_smb_3_10 = TRUE;
4746 if (!supports_smb_3_10) {
4747 ncc = 0;
4750 if (nco != 0) {
4751 guint32 tmp = 0x40 + 36 + dc * 2;
4753 if (nco >= tmp) {
4754 offset += nco - tmp;
4755 } else {
4756 ncc = 0;
4760 for (i = 0; i < ncc; i++) {
4761 offset = (offset + 7) & ~7;
4762 offset = dissect_smb2_negotiate_context(tvb, pinfo, tree, offset, si);
4765 return offset;
4768 static int
4769 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4771 offset_length_buffer_t s_olb;
4772 guint16 i;
4773 guint32 nco;
4774 guint16 ncc;
4775 gboolean continue_dissection;
4776 proto_item *hash_item = NULL;
4777 smb2_saved_info_t *ssi = si->saved;
4779 /* compute preauth hash on first pass */
4780 if (!pinfo->fd->visited && ssi) {
4781 ssi->preauth_hash_res = (guint8*)wmem_alloc0(wmem_file_scope(), SMB2_PREAUTH_HASH_SIZE);
4782 update_preauth_hash(si->conv->preauth_hash_current, tvb);
4783 memcpy(ssi->preauth_hash_res, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
4786 * All new sessions on this conversation must reuse
4787 * the preauth hash value at the time of the negprot
4788 * response, so we stash it and switch buffers
4790 memcpy(si->conv->preauth_hash_ses, si->conv->preauth_hash_current, SMB2_PREAUTH_HASH_SIZE);
4791 si->conv->preauth_hash_current = si->conv->preauth_hash_ses;
4794 if (ssi && ssi->preauth_hash_res) {
4795 hash_item = proto_tree_add_bytes_with_length(tree,
4796 hf_smb2_preauth_hash, tvb,
4797 0, tvb_captured_length(tvb),
4798 ssi->preauth_hash_res, SMB2_PREAUTH_HASH_SIZE);
4799 proto_item_set_generated(hash_item);
4802 switch (si->status) {
4803 /* buffer code */
4804 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
4805 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
4806 if (!continue_dissection) return offset;
4809 /* security mode, skip second byte */
4810 offset = dissect_smb2_secmode(tree, tvb, offset);
4811 offset++;
4813 /* dialect picked */
4814 si->conv->dialect = tvb_get_letohs(tvb, offset);
4815 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4816 offset += 2;
4818 /* negotiate context count */
4819 ncc = tvb_get_letohs(tvb, offset);
4820 proto_tree_add_item(tree, hf_smb2_negotiate_context_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4821 offset += 2;
4823 /* server GUID */
4824 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4825 offset += 16;
4827 /* capabilities */
4828 offset = dissect_smb2_capabilities(tree, tvb, offset);
4830 /* max trans size */
4831 proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4832 offset += 4;
4834 /* max read size */
4835 proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4836 offset += 4;
4838 /* max write size */
4839 proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4840 offset += 4;
4842 /* current time */
4843 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
4844 offset += 8;
4846 /* boot time */
4847 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
4848 offset += 8;
4850 /* security blob offset/length */
4851 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
4853 /* the security blob itself */
4854 dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
4856 /* negotiate context offset */
4857 nco = tvb_get_letohl(tvb, offset);
4858 proto_tree_add_item(tree, hf_smb2_negotiate_context_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4859 offset += 4;
4861 offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
4863 if (si->conv->dialect < 0x310) {
4864 ncc = 0;
4867 if (nco != 0) {
4868 guint32 tmp = 0x40 + 64 + s_olb.len;
4870 if (nco >= tmp) {
4871 offset += nco - tmp;
4872 } else {
4873 ncc = 0;
4877 for (i = 0; i < ncc; i++) {
4878 offset = (offset + 7) & ~7;
4879 offset = dissect_smb2_negotiate_context(tvb, pinfo, tree, offset, si);
4882 return offset;
4885 static int
4886 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
4888 /* Additional Info */
4889 switch (si->saved->smb2_class) {
4890 case SMB2_CLASS_SEC_INFO:
4891 dissect_security_information_mask(tvb, tree, offset);
4892 break;
4893 default:
4894 proto_tree_add_item(tree, hf_smb2_getinfo_additional, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4896 offset += 4;
4898 /* Flags */
4899 proto_tree_add_item(tree, hf_smb2_getinfo_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4900 offset += 4;
4902 return offset;
4906 static int
4907 dissect_smb2_getinfo_buffer_quota(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
4909 guint32 sidlist_len = 0;
4910 guint32 startsid_len = 0;
4911 guint32 startsid_offset = 0;
4913 proto_item *item = NULL;
4914 proto_tree *tree = NULL;
4916 if (parent_tree) {
4917 item = proto_tree_add_item(parent_tree, hf_smb2_query_quota_info, tvb, offset, -1, ENC_NA);
4918 tree = proto_item_add_subtree(item, ett_smb2_query_quota_info);
4921 proto_tree_add_item(tree, hf_smb2_qq_single, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4922 offset += 1;
4924 proto_tree_add_item(tree, hf_smb2_qq_restart, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4925 offset += 1;
4927 /* reserved */
4928 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4929 offset += 2;
4931 proto_tree_add_item_ret_uint(tree, hf_smb2_qq_sidlist_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &sidlist_len);
4932 offset += 4;
4934 proto_tree_add_item_ret_uint(tree, hf_smb2_qq_start_sid_len, tvb, offset, 4, ENC_LITTLE_ENDIAN, &startsid_len);
4935 offset += 4;
4937 proto_tree_add_item_ret_uint(tree, hf_smb2_qq_start_sid_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &startsid_offset);
4938 offset += 4;
4940 if (sidlist_len != 0) {
4941 offset = dissect_nt_get_user_quota(tvb, tree, offset, &sidlist_len);
4942 } else if (startsid_len != 0) {
4943 offset = dissect_nt_sid(tvb, offset + startsid_offset, tree, "Start SID", NULL, -1);
4946 return offset;
4949 static int
4950 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
4952 guint8 cl, il;
4953 proto_item *item;
4954 int hfindex;
4955 value_string_ext *vsx;
4957 if (si->flags & SMB2_FLAGS_RESPONSE) {
4958 if (!si->saved) {
4959 return offset;
4961 cl = si->saved->smb2_class;
4962 il = si->saved->infolevel;
4963 } else {
4964 cl = tvb_get_guint8(tvb, offset);
4965 il = tvb_get_guint8(tvb, offset+1);
4966 if (si->saved) {
4967 si->saved->smb2_class = cl;
4968 si->saved->infolevel = il;
4973 switch (cl) {
4974 case SMB2_CLASS_FILE_INFO:
4975 hfindex = hf_smb2_infolevel_file_info;
4976 vsx = &smb2_file_info_levels_ext;
4977 break;
4978 case SMB2_CLASS_FS_INFO:
4979 hfindex = hf_smb2_infolevel_fs_info;
4980 vsx = &smb2_fs_info_levels_ext;
4981 break;
4982 case SMB2_CLASS_SEC_INFO:
4983 hfindex = hf_smb2_infolevel_sec_info;
4984 vsx = &smb2_sec_info_levels_ext;
4985 break;
4986 case SMB2_CLASS_QUOTA_INFO:
4987 /* infolevel is not being used for quota */
4988 hfindex = hf_smb2_infolevel;
4989 vsx = NULL;
4990 break;
4991 case SMB2_CLASS_POSIX_INFO:
4992 hfindex = hf_smb2_infolevel_posix_info;
4993 vsx = &smb2_posix_info_levels_ext;
4994 break;
4995 default:
4996 hfindex = hf_smb2_infolevel;
4997 vsx = NULL; /* allowed arg to val_to_str_ext() */
5001 /* class */
5002 item = proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
5003 if (si->flags & SMB2_FLAGS_RESPONSE) {
5004 proto_item_set_generated(item);
5006 /* infolevel */
5007 item = proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
5008 if (si->flags & SMB2_FLAGS_RESPONSE) {
5009 proto_item_set_generated(item);
5011 offset += 2;
5013 if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
5014 /* Only update COL_INFO for requests. It clutters the
5015 * display a bit too much if we do it for replies
5016 * as well.
5018 col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
5019 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
5020 val_to_str_ext(il, vsx, "(Level:0x%02x)"));
5023 return offset;
5026 static int
5027 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5029 guint32 getinfo_size = 0;
5030 guint32 getinfo_offset = 0;
5031 proto_item *offset_item;
5033 /* buffer code */
5034 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5036 /* class and info level */
5037 offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5039 /* max response size */
5040 proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5041 offset += 4;
5043 /* offset */
5044 offset_item = proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN, &getinfo_offset);
5045 offset += 2;
5047 /* reserved */
5048 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5049 offset += 2;
5051 /* size */
5052 proto_tree_add_item_ret_uint(tree, hf_smb2_getinfo_input_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &getinfo_size);
5053 offset += 4;
5055 /* parameters */
5056 if (si->saved) {
5057 offset = dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
5058 } else {
5059 /* some unknown bytes */
5060 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 8, ENC_NA);
5061 offset += 8;
5064 /* fid */
5065 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5067 /* buffer */
5068 if (si->saved) {
5069 if (getinfo_size != 0) {
5071 * 2.2.37 says "For quota requests, this MUST be
5072 * the length of the contained SMB2_QUERY_QUOTA_INFO
5073 * embedded in the request. For FileFullEaInformation
5074 * requests, this MUST be set to the length of the
5075 * user supplied EA list specified in [MS-FSCC]
5076 * section 2.4.15.1. For other information queries,
5077 * this field SHOULD be set to 0 and the server MUST
5078 * ignore it on receipt.
5080 * This seems to imply that, for requests other
5081 * than those to types, we should either completely
5082 * ignore a non-zero getinfo_size or should, at
5083 * most, add a warning-level expert info at the
5084 * protocol level saying that it should be zero,
5085 * but not try and interpret it or check its
5086 * validity.
5088 if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO ||
5089 (si->saved->smb2_class == SMB2_CLASS_FILE_INFO &&
5090 si->saved->infolevel == SMB2_FILE_FULL_EA_INFO)) {
5092 * According to 2.2.37 SMB2 QUERY_INFO
5093 * Request in the current MS-SMB2 spec,
5094 * these are the only info requests that
5095 * have an input buffer.
5099 * Make sure that the input buffer is after
5100 * the fixed-length part of the message.
5102 if (getinfo_offset < (guint)offset) {
5103 expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_offset);
5104 return offset;
5108 * Make sure the input buffer is within the
5109 * message, i.e. that it's within the tvbuff.
5111 * We check for offset+length overflowing and
5112 * for offset+length being beyond the reported
5113 * length of the tvbuff.
5115 if (getinfo_offset + getinfo_size < getinfo_offset ||
5116 getinfo_offset + getinfo_size > tvb_reported_length(tvb)) {
5117 expert_add_info(pinfo, offset_item, &ei_smb2_invalid_getinfo_size);
5118 return offset;
5121 if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO) {
5122 dissect_smb2_getinfo_buffer_quota(tvb, pinfo, tree, getinfo_offset, si);
5123 } else {
5125 * XXX - handle user supplied EA info.
5127 proto_tree_add_item(tree, hf_smb2_unknown, tvb, getinfo_offset, getinfo_size, ENC_NA);
5129 offset = getinfo_offset + getinfo_size;
5131 } else {
5133 * The buffer size is 0, meaning it's not present.
5135 * 2.2.37 says "For FileFullEaInformation requests,
5136 * the input buffer MUST contain the user supplied
5137 * EA list with zero or more FILE_GET_EA_INFORMATION
5138 * structures, specified in [MS-FSCC] section
5139 * 2.4.15.1.", so it seems that, for a "get full
5140 * EA information" request, the size can be zero -
5141 * there's no other obvious way for the list to
5142 * have zero structures.
5144 * 2.2.37 also says "For quota requests, the input
5145 * buffer MUST contain an SMB2_QUERY_QUOTA_INFO,
5146 * as specified in section 2.2.37.1."; that seems
5147 * to imply that the input buffer must not be empty
5148 * in that case.
5150 if (si->saved->smb2_class == SMB2_CLASS_QUOTA_INFO)
5151 expert_add_info(pinfo, offset_item, &ei_smb2_empty_getinfo_buffer);
5155 return offset;
5158 static int
5159 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 smb2_class, guint8 infolevel)
5161 int old_offset = offset;
5163 switch (smb2_class) {
5164 case SMB2_CLASS_FILE_INFO:
5165 switch (infolevel) {
5166 case SMB2_FILE_BASIC_INFO:
5167 offset = dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
5168 break;
5169 case SMB2_FILE_STANDARD_INFO:
5170 offset = dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
5171 break;
5172 case SMB2_FILE_INTERNAL_INFO:
5173 offset = dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
5174 break;
5175 case SMB2_FILE_EA_INFO:
5176 offset = dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
5177 break;
5178 case SMB2_FILE_ACCESS_INFO:
5179 offset = dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
5180 break;
5181 case SMB2_FILE_RENAME_INFO:
5182 offset = dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
5183 break;
5184 case SMB2_FILE_DISPOSITION_INFO:
5185 offset = dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
5186 break;
5187 case SMB2_FILE_POSITION_INFO:
5188 offset = dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
5189 break;
5190 case SMB2_FILE_FULL_EA_INFO:
5191 offset = dissect_smb2_file_full_ea_info(tvb, pinfo, tree, offset, si);
5192 break;
5193 case SMB2_FILE_MODE_INFO:
5194 offset = dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
5195 break;
5196 case SMB2_FILE_ALIGNMENT_INFO:
5197 offset = dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
5198 break;
5199 case SMB2_FILE_ALL_INFO:
5200 offset = dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
5201 break;
5202 case SMB2_FILE_ALLOCATION_INFO:
5203 offset = dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
5204 break;
5205 case SMB2_FILE_ENDOFFILE_INFO:
5206 dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
5207 break;
5208 case SMB2_FILE_ALTERNATE_NAME_INFO:
5209 offset = dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
5210 break;
5211 case SMB2_FILE_STREAM_INFO:
5212 offset = dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
5213 break;
5214 case SMB2_FILE_PIPE_INFO:
5215 offset = dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
5216 break;
5217 case SMB2_FILE_COMPRESSION_INFO:
5218 offset = dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
5219 break;
5220 case SMB2_FILE_NETWORK_OPEN_INFO:
5221 offset = dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
5222 break;
5223 case SMB2_FILE_ATTRIBUTE_TAG_INFO:
5224 offset = dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
5225 break;
5226 default:
5227 /* we don't handle this infolevel yet */
5228 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5229 offset += tvb_captured_length_remaining(tvb, offset);
5231 break;
5232 case SMB2_CLASS_FS_INFO:
5233 switch (infolevel) {
5234 case SMB2_FS_INFO_01:
5235 offset = dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
5236 break;
5237 case SMB2_FS_INFO_03:
5238 offset = dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
5239 break;
5240 case SMB2_FS_INFO_04:
5241 offset = dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
5242 break;
5243 case SMB2_FS_INFO_05:
5244 offset = dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
5245 break;
5246 case SMB2_FS_INFO_06:
5247 offset = dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
5248 break;
5249 case SMB2_FS_INFO_07:
5250 offset = dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
5251 break;
5252 case SMB2_FS_OBJECTID_INFO:
5253 offset = dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
5254 break;
5255 default:
5256 /* we don't handle this infolevel yet */
5257 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5258 offset += tvb_captured_length_remaining(tvb, offset);
5260 break;
5261 case SMB2_CLASS_SEC_INFO:
5262 switch (infolevel) {
5263 case SMB2_SEC_INFO_00:
5264 offset = dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
5265 break;
5266 default:
5267 /* we don't handle this infolevel yet */
5268 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5269 offset += tvb_captured_length_remaining(tvb, offset);
5271 break;
5272 case SMB2_CLASS_QUOTA_INFO:
5273 offset = dissect_smb2_quota_info(tvb, pinfo, tree, offset, si);
5274 break;
5275 default:
5276 /* we don't handle this class yet */
5277 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
5278 offset += tvb_captured_length_remaining(tvb, offset);
5281 /* if we get BUFFER_OVERFLOW there will be truncated data */
5282 if (si->status == 0x80000005) {
5283 proto_item *item;
5284 item = proto_tree_add_item(tree, hf_smb2_truncated, tvb, old_offset, 0, ENC_NA);
5285 proto_item_set_generated(item);
5287 return offset;
5290 static void
5291 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
5293 /* data */
5294 if (si->saved) {
5295 dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->smb2_class, si->saved->infolevel);
5296 } else {
5297 /* some unknown bytes */
5298 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
5304 static int
5305 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5307 offset_length_buffer_t olb;
5308 gboolean continue_dissection;
5310 /* class/infolevel */
5311 dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5313 switch (si->status) {
5314 case 0x00000000:
5315 /* if we get BUFFER_OVERFLOW there will be truncated data */
5316 case 0x80000005:
5317 /* if we get BUFFER_TOO_SMALL there will not be any data there, only
5318 * a guin32 specifying how big the buffer needs to be
5320 /* buffer code */
5321 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5322 break;
5323 case 0xc0000023:
5324 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5325 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
5326 proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5327 offset += 4;
5329 return offset;
5330 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5331 if (!continue_dissection) return offset;
5334 /* response buffer offset and size */
5335 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
5337 /* response data*/
5338 dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
5340 return offset;
5343 static int
5344 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5346 proto_tree *flags_tree = NULL;
5347 proto_item *flags_item = NULL;
5349 /* buffer code */
5350 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5352 /* close flags */
5353 if (tree) {
5354 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5355 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
5357 proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5358 offset += 2;
5360 /* padding */
5361 offset += 4;
5363 /* fid */
5364 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
5366 return offset;
5369 static int
5370 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5372 proto_tree *flags_tree = NULL;
5373 proto_item *flags_item = NULL;
5374 gboolean continue_dissection;
5376 switch (si->status) {
5377 /* buffer code */
5378 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5379 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5380 if (!continue_dissection) return offset;
5383 /* close flags */
5384 if (tree) {
5385 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5386 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
5388 proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5389 offset += 2;
5391 /* reserved */
5392 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5393 offset += 4;
5395 /* create time */
5396 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
5398 /* last access */
5399 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
5401 /* last write */
5402 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
5404 /* last change */
5405 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
5407 /* allocation size */
5408 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5409 offset += 8;
5411 /* end of file */
5412 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5413 offset += 8;
5415 /* File Attributes */
5416 offset = dissect_file_ext_attr(tvb, tree, offset);
5418 return offset;
5421 static int
5422 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5424 /* buffer code */
5425 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5427 /* some unknown bytes */
5428 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
5429 offset += 6;
5431 /* fid */
5432 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5434 return offset;
5437 static int
5438 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5440 gboolean continue_dissection;
5442 switch (si->status) {
5443 /* buffer code */
5444 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5445 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5446 if (!continue_dissection) return offset;
5449 /* some unknown bytes */
5450 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
5451 offset += 2;
5453 return offset;
5457 static int
5458 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5460 guint16 lock_count;
5462 /* buffer code */
5463 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5465 /* lock count */
5466 lock_count = tvb_get_letohs(tvb, offset);
5467 proto_tree_add_item(tree, hf_smb2_lock_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5468 offset += 2;
5470 /* reserved */
5471 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5472 offset += 4;
5474 /* fid */
5475 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5477 while (lock_count--) {
5478 proto_item *lock_item = NULL;
5479 proto_tree *lock_tree = NULL;
5480 static const int *lf_fields[] = {
5481 &hf_smb2_lock_flags_shared,
5482 &hf_smb2_lock_flags_exclusive,
5483 &hf_smb2_lock_flags_unlock,
5484 &hf_smb2_lock_flags_fail_immediately,
5485 NULL
5488 if (tree) {
5489 lock_item = proto_tree_add_item(tree, hf_smb2_lock_info, tvb, offset, 24, ENC_NA);
5490 lock_tree = proto_item_add_subtree(lock_item, ett_smb2_lock_info);
5493 /* offset */
5494 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5495 offset += 8;
5497 /* count */
5498 proto_tree_add_item(lock_tree, hf_smb2_lock_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5499 offset += 8;
5501 /* flags */
5502 proto_tree_add_bitmask(lock_tree, tvb, offset, hf_smb2_lock_flags, ett_smb2_lock_flags, lf_fields, ENC_LITTLE_ENDIAN);
5503 offset += 4;
5505 /* reserved */
5506 proto_tree_add_item(lock_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
5507 offset += 4;
5510 return offset;
5513 static int
5514 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5516 gboolean continue_dissection;
5518 switch (si->status) {
5519 /* buffer code */
5520 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5521 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5522 if (!continue_dissection) return offset;
5525 /* some unknown bytes */
5526 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
5527 offset += 2;
5529 return offset;
5531 static int
5532 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5534 /* buffer code */
5535 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5537 /* some unknown bytes */
5538 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
5539 offset += 2;
5541 return offset;
5544 static const smb2_fid_info_t *
5545 smb2_pipe_get_fid_info(const smb2_info_t *si)
5547 smb2_fid_info_t *file = NULL;
5549 if (si == NULL) {
5550 return NULL;
5552 if (si->file != NULL) {
5553 file = si->file;
5554 } else if (si->saved != NULL) {
5555 file = si->saved->file;
5557 if (file == NULL) {
5558 return NULL;
5561 return file;
5564 static void
5565 smb2_pipe_set_file_id(packet_info *pinfo, smb2_info_t *si)
5567 guint64 persistent;
5568 const smb2_fid_info_t *file = NULL;
5570 file = smb2_pipe_get_fid_info(si);
5571 if (file == NULL) {
5572 return;
5575 persistent = GPOINTER_TO_UINT(file);
5577 dcerpc_set_transport_salt(persistent, pinfo);
5580 static gboolean smb2_pipe_reassembly = TRUE;
5581 static reassembly_table smb2_pipe_reassembly_table;
5583 static int
5584 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)
5587 * Note: si is NULL for some callers from packet-smb.c
5589 const smb2_info_t *si = (const smb2_info_t *)data;
5590 gboolean result=0;
5591 gboolean save_fragmented;
5592 gint remaining;
5593 guint reported_len;
5594 const smb2_fid_info_t *file = NULL;
5595 guint32 id;
5596 fragment_head *fd_head;
5597 tvbuff_t *tvb;
5598 tvbuff_t *new_tvb;
5599 proto_item *frag_tree_item;
5600 heur_dtbl_entry_t *hdtbl_entry;
5602 file = smb2_pipe_get_fid_info(si);
5603 id = (guint32)(GPOINTER_TO_UINT(file) & G_MAXUINT32);
5605 remaining = tvb_captured_length_remaining(raw_tvb, offset);
5607 tvb = tvb_new_subset_length_caplen(raw_tvb, offset,
5608 MIN((int)datalen, remaining),
5609 datalen);
5612 * Offer desegmentation service to Named Pipe subdissectors (e.g. DCERPC)
5613 * if we have all the data. Otherwise, reassembly is (probably) impossible.
5615 pinfo->can_desegment = 0;
5616 pinfo->desegment_offset = 0;
5617 pinfo->desegment_len = 0;
5618 reported_len = tvb_reported_length(tvb);
5619 if (smb2_pipe_reassembly && tvb_captured_length(tvb) >= reported_len) {
5620 pinfo->can_desegment = 2;
5623 save_fragmented = pinfo->fragmented;
5626 * if we are not offering desegmentation, just try the heuristics
5627 *and bail out
5629 if (!pinfo->can_desegment) {
5630 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5631 tvb, pinfo, top_tree,
5632 &hdtbl_entry, data);
5633 goto clean_up_and_exit;
5636 /* below this line, we know we are doing reassembly */
5639 * this is a new packet, see if we are already reassembling this
5640 * pdu and if not, check if the dissector wants us
5641 * to reassemble it
5643 if (!pinfo->fd->visited) {
5645 * This is the first pass.
5647 * Check if we are already reassembling this PDU or not;
5648 * we check for an in-progress reassembly for this FID
5649 * in this direction, by searching for its reassembly
5650 * structure.
5652 fd_head = fragment_get(&smb2_pipe_reassembly_table,
5653 pinfo, id, NULL);
5654 if (!fd_head) {
5656 * No reassembly, so this is a new pdu. check if the
5657 * dissector wants us to reassemble it or if we
5658 * already got the full pdu in this tvb.
5662 * Try the heuristic dissectors and see if we
5663 * find someone that recognizes this payload.
5665 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5666 tvb, pinfo, top_tree,
5667 &hdtbl_entry, data);
5669 /* no this didn't look like something we know */
5670 if (!result) {
5671 goto clean_up_and_exit;
5674 /* did the subdissector want us to reassemble any
5675 more data ?
5677 if (pinfo->desegment_len) {
5678 fragment_add_check(&smb2_pipe_reassembly_table,
5679 tvb, 0, pinfo, id, NULL,
5680 0, reported_len, TRUE);
5681 fragment_set_tot_len(&smb2_pipe_reassembly_table,
5682 pinfo, id, NULL,
5683 pinfo->desegment_len+reported_len);
5685 goto clean_up_and_exit;
5688 /* OK, we're already doing a reassembly for this FID.
5689 skip to last segment in the existing reassembly structure
5690 and add this fragment there
5692 XXX we might add code here to use any offset values
5693 we might pick up from the Read/Write calls instead of
5694 assuming we always get them in the correct order
5696 while (fd_head->next) {
5697 fd_head = fd_head->next;
5699 fd_head = fragment_add_check(&smb2_pipe_reassembly_table,
5700 tvb, 0, pinfo, id, NULL,
5701 fd_head->offset+fd_head->len,
5702 reported_len, TRUE);
5704 /* if we completed reassembly */
5705 if (fd_head) {
5706 new_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
5707 add_new_data_source(pinfo, new_tvb,
5708 "Named Pipe over SMB2");
5709 pinfo->fragmented=FALSE;
5711 tvb = new_tvb;
5713 /* list what segments we have */
5714 show_fragment_tree(fd_head, &smb2_pipe_frag_items,
5715 tree, pinfo, tvb, &frag_tree_item);
5717 /* dissect the full PDU */
5718 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5719 tvb, pinfo, top_tree,
5720 &hdtbl_entry, data);
5722 goto clean_up_and_exit;
5726 * This is not the first pass; see if it's in the table of
5727 * reassembled packets.
5729 * XXX - we know that several of the arguments aren't going to
5730 * be used, so we pass bogus variables. Can we clean this
5731 * up so that we don't have to distinguish between the first
5732 * pass and subsequent passes?
5734 fd_head = fragment_add_check(&smb2_pipe_reassembly_table,
5735 tvb, 0, pinfo, id, NULL, 0, 0, TRUE);
5736 if (!fd_head) {
5737 /* we didn't find it, try any of the heuristic dissectors
5738 and bail out
5740 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5741 tvb, pinfo, top_tree,
5742 &hdtbl_entry, data);
5743 goto clean_up_and_exit;
5745 if (!(fd_head->flags&FD_DEFRAGMENTED)) {
5746 /* we don't have a fully reassembled frame */
5747 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5748 tvb, pinfo, top_tree,
5749 &hdtbl_entry, data);
5750 goto clean_up_and_exit;
5753 /* it is reassembled but it was reassembled in a different frame */
5754 if (pinfo->num != fd_head->reassembled_in) {
5755 proto_item *item;
5756 item = proto_tree_add_uint(top_tree, hf_smb2_pipe_reassembled_in,
5757 tvb, 0, 0, fd_head->reassembled_in);
5758 proto_item_set_generated(item);
5759 goto clean_up_and_exit;
5762 /* display the reassembled pdu */
5763 new_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
5764 add_new_data_source(pinfo, new_tvb,
5765 "Named Pipe over SMB2");
5766 pinfo->fragmented = FALSE;
5768 tvb = new_tvb;
5770 /* list what segments we have */
5771 show_fragment_tree(fd_head, &smb2_pipe_frag_items,
5772 top_tree, pinfo, tvb, &frag_tree_item);
5774 /* dissect the full PDU */
5775 result = dissector_try_heuristic(smb2_pipe_subdissector_list,
5776 tvb, pinfo, top_tree,
5777 &hdtbl_entry, data);
5779 clean_up_and_exit:
5780 /* clear out the variables */
5781 pinfo->can_desegment=0;
5782 pinfo->desegment_offset = 0;
5783 pinfo->desegment_len = 0;
5785 if (!result) {
5786 call_data_dissector(tvb, pinfo, top_tree);
5789 pinfo->fragmented = save_fragmented;
5791 offset += datalen;
5792 return offset;
5795 #define SMB2_CHANNEL_NONE 0x00000000
5796 #define SMB2_CHANNEL_RDMA_V1 0x00000001
5797 #define SMB2_CHANNEL_RDMA_V1_INVALIDATE 0x00000002
5799 static const value_string smb2_channel_vals[] = {
5800 { SMB2_CHANNEL_NONE, "None" },
5801 { SMB2_CHANNEL_RDMA_V1, "RDMA V1" },
5802 { SMB2_CHANNEL_RDMA_V1_INVALIDATE, "RDMA V1_INVALIDATE" },
5803 { 0, NULL }
5806 static void
5807 dissect_smb2_rdma_v1_blob(tvbuff_t *tvb, packet_info *pinfo _U_,
5808 proto_tree *parent_tree, smb2_info_t *si _U_)
5810 int offset = 0;
5811 int len;
5812 int i;
5813 int num;
5814 proto_tree *sub_tree;
5815 proto_item *parent_item;
5817 parent_item = proto_tree_get_parent(parent_tree);
5819 len = tvb_reported_length(tvb);
5821 num = len / 16;
5823 if (parent_item) {
5824 proto_item_append_text(parent_item, ": SMBDirect Buffer Descriptor V1: (%d elements)", num);
5827 for (i = 0; i < num; i++) {
5828 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, 8, ett_smb2_rdma_v1, NULL, "RDMA V1");
5830 proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5831 offset += 8;
5833 proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5834 offset += 4;
5836 proto_tree_add_item(sub_tree, hf_smb2_rdma_v1_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5837 offset += 4;
5841 #define SMB2_WRITE_FLAG_WRITE_THROUGH 0x00000001
5843 static int
5844 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5846 guint16 dataoffset = 0;
5847 guint32 data_tvb_len;
5848 offset_length_buffer_t c_olb;
5849 guint32 channel;
5850 guint32 length;
5851 guint64 off;
5852 static const int *f_fields[] = {
5853 &hf_smb2_write_flags_write_through,
5854 NULL
5857 /* buffer code */
5858 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5860 /* data offset */
5861 dataoffset=tvb_get_letohs(tvb,offset);
5862 proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5863 offset += 2;
5865 /* length */
5866 length = tvb_get_letohl(tvb, offset);
5867 proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5868 offset += 4;
5870 /* offset */
5871 off = tvb_get_letoh64(tvb, offset);
5872 if (si->saved) si->saved->file_offset=off;
5873 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5874 offset += 8;
5876 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", length, off);
5878 /* fid */
5879 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5881 /* channel */
5882 channel = tvb_get_letohl(tvb, offset);
5883 proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5884 offset += 4;
5886 /* remaining bytes */
5887 proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5888 offset += 4;
5890 /* write channel info blob offset/length */
5891 offset = dissect_smb2_olb_length_offset(tvb, offset, &c_olb, OLB_O_UINT16_S_UINT16, hf_smb2_channel_info_blob);
5893 /* flags */
5894 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_write_flags, ett_smb2_write_flags, f_fields, ENC_LITTLE_ENDIAN);
5895 offset += 4;
5897 /* the write channel info blob itself */
5898 switch (channel) {
5899 case SMB2_CHANNEL_RDMA_V1:
5900 case SMB2_CHANNEL_RDMA_V1_INVALIDATE:
5901 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, dissect_smb2_rdma_v1_blob);
5902 break;
5903 case SMB2_CHANNEL_NONE:
5904 default:
5905 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, NULL);
5906 break;
5909 data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
5911 /* data or namedpipe ?*/
5912 if (length) {
5913 int oldoffset = offset;
5914 smb2_pipe_set_file_id(pinfo, si);
5915 offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
5916 if (offset != oldoffset) {
5917 /* managed to dissect pipe data */
5918 goto out;
5922 /* just ordinary data */
5923 proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, ENC_NA);
5925 offset += MIN(length,(guint32)tvb_captured_length_remaining(tvb, offset));
5927 offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
5929 out:
5930 if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
5931 if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
5932 feed_eo_smb2(tvb,pinfo,si,dataoffset,length,off);
5936 return offset;
5940 static int
5941 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
5943 gboolean continue_dissection;
5945 switch (si->status) {
5946 /* buffer code */
5947 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
5948 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
5949 if (!continue_dissection) return offset;
5952 /* reserved */
5953 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5954 offset += 2;
5956 /* count */
5957 proto_tree_add_item(tree, hf_smb2_write_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5958 offset += 4;
5960 /* remaining, must be set to 0 */
5961 proto_tree_add_item(tree, hf_smb2_write_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5962 offset += 4;
5964 /* write channel info offset */
5965 proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5966 offset += 2;
5968 /* write channel info length */
5969 proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5970 offset += 2;
5972 return offset;
5975 /* The STORAGE_OFFLOAD_TOKEN is used for "Offload Data Transfer" (ODX) operations,
5976 including FSCTL_OFFLOAD_READ, FSCTL_OFFLOAD_WRITE. Ref: MS-FSCC 2.3.79
5977 Note: Unlike most of SMB2, the token fields are BIG-endian! */
5978 static int
5979 dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
5981 proto_tree *sub_tree;
5982 proto_item *sub_item;
5983 guint32 idlen = 0;
5984 guint32 idtype = 0;
5986 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 512, ett_smb2_fsctl_odx_token, &sub_item, "Token");
5988 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_fsctl_odx_token_type, tvb, offset, 4, ENC_BIG_ENDIAN, &idtype);
5989 offset += 4;
5991 proto_item_append_text(sub_item, " (IdType 0x%x)", idtype);
5993 /* reserved */
5994 proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5995 offset += 2;
5997 /* TokenIdLength */
5998 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_fsctl_odx_token_idlen, tvb, offset, 2, ENC_BIG_ENDIAN, &idlen);
5999 offset += 2;
6001 /* idlen is what the server says is the "meaningful" part of the token.
6002 However, token ID is always 504 bytes */
6003 proto_tree_add_bytes_format_value(sub_tree, hf_smb2_fsctl_odx_token_idraw, tvb,
6004 offset, idlen, NULL, "Opaque Data");
6005 offset += 504;
6007 return (offset);
6010 /* MS-FSCC 2.3.77, 2.3.78 */
6011 static void
6012 dissect_smb2_FSCTL_OFFLOAD_READ(tvbuff_t *tvb,
6013 packet_info *pinfo _U_,
6014 proto_tree *tree,
6015 int offset,
6016 gboolean in)
6018 proto_tree_add_item(tree, hf_smb2_fsctl_odx_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6019 offset += 4;
6021 proto_tree_add_item(tree, hf_smb2_fsctl_odx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6022 offset += 4;
6024 if (in) {
6025 proto_tree_add_item(tree, hf_smb2_fsctl_odx_token_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6026 offset += 4;
6028 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6029 offset += 4;
6031 proto_tree_add_item(tree, hf_smb2_fsctl_odx_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6032 offset += 8;
6034 proto_tree_add_item(tree, hf_smb2_fsctl_odx_copy_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6035 /* offset += 8; */
6036 } else {
6037 proto_tree_add_item(tree, hf_smb2_fsctl_odx_xfer_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6038 offset += 8;
6040 (void) dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvb, pinfo, tree, offset);
6044 /* MS-FSCC 2.3.80, 2.3.81 */
6045 static void
6046 dissect_smb2_FSCTL_OFFLOAD_WRITE(tvbuff_t *tvb,
6047 packet_info *pinfo _U_,
6048 proto_tree *tree,
6049 int offset,
6050 gboolean in)
6052 proto_tree_add_item(tree, hf_smb2_fsctl_odx_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6053 offset += 4;
6055 proto_tree_add_item(tree, hf_smb2_fsctl_odx_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6056 offset += 4;
6058 if (in) {
6059 proto_tree_add_item(tree, hf_smb2_fsctl_odx_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6060 offset += 8;
6062 proto_tree_add_item(tree, hf_smb2_fsctl_odx_copy_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6063 offset += 8;
6065 proto_tree_add_item(tree, hf_smb2_fsctl_odx_token_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6066 offset += 8;
6068 dissect_smb2_STORAGE_OFFLOAD_TOKEN(tvb, pinfo, tree, offset);
6070 } else {
6071 proto_tree_add_item(tree, hf_smb2_fsctl_odx_xfer_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6072 /* offset += 8; */
6076 static void
6077 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)
6079 dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, tvb_captured_length_remaining(tvb, offset), top_tree, data);
6082 static void
6083 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_)
6085 int timeout_offset;
6086 guint32 name_len;
6087 guint8 timeout_specified;
6088 char *display_string;
6090 /* Timeout */
6091 timeout_offset = offset;
6092 offset += 8;
6094 /* Name length */
6095 /* XXX - put the name length into the tree */
6096 name_len = tvb_get_letohl(tvb, offset);
6097 offset += 4;
6099 /* Timeout specified */
6100 timeout_specified = tvb_get_guint8(tvb, offset);
6101 if (timeout_specified) {
6102 proto_tree_add_item(top_tree, hf_smb2_fsctl_pipe_wait_timeout,
6103 tvb, timeout_offset, 8, ENC_LITTLE_ENDIAN);
6105 offset += 1;
6107 /* Padding */
6108 offset += 1;
6110 /* Name */
6111 proto_tree_add_item_ret_display_string(top_tree, hf_smb2_fsctl_pipe_wait_name,
6112 tvb, offset, name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
6113 wmem_packet_scope(), &display_string);
6115 col_append_fstr(pinfo->cinfo, COL_INFO, " Pipe: %s", display_string);
6118 static int
6119 dissect_smb2_FSCTL_SET_SPARSE(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6122 /* There is no out data */
6123 if (!data_in) {
6124 return offset;
6127 /* sparse flag (optional) */
6128 if (tvb_reported_length_remaining(tvb, offset) >= 1) {
6129 proto_tree_add_item(tree, hf_smb2_fsctl_sparse_flag, tvb, offset, 1, ENC_NA);
6130 offset += 1;
6133 return offset;
6136 static int
6137 dissect_smb2_FSCTL_SET_ZERO_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6139 proto_tree *sub_tree;
6140 proto_item *sub_item;
6142 /* There is no out data */
6143 if (!data_in) {
6144 return offset;
6147 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
6149 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6150 offset += 8;
6152 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6153 offset += 8;
6155 return offset;
6158 static void
6159 dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in)
6161 proto_tree *sub_tree;
6162 proto_item *sub_item;
6164 if (data_in) {
6165 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
6167 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6168 offset += 8;
6170 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6171 offset += 8;
6172 } else {
6173 /* Zero or more allocated ranges may be reported. */
6174 while (tvb_reported_length_remaining(tvb, offset) >= 16) {
6176 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_smb2_fsctl_range_data, &sub_item, "Range");
6178 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6179 offset += 8;
6181 proto_tree_add_item(sub_tree, hf_smb2_fsctl_range_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6182 offset += 8;
6188 static void
6189 dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_, gboolean data_in)
6192 if (data_in) {
6193 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6194 offset += 8;
6196 proto_tree_add_item(tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6197 offset += 8;
6199 proto_tree_add_item(tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6200 offset += 4;
6202 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6203 offset += 4;
6204 } else {
6205 guint32 entry_count = 0;
6207 proto_tree_add_item(tree, hf_smb2_qfr_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6208 offset += 4;
6210 proto_tree_add_item(tree, hf_smb2_qfr_total_region_entry_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6211 offset += 4;
6213 proto_tree_add_item_ret_uint(tree, hf_smb2_qfr_region_entry_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &entry_count);
6214 offset += 4;
6216 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6217 offset += 4;
6219 while (entry_count && tvb_reported_length_remaining(tvb, offset)) {
6220 proto_tree *sub_tree;
6221 proto_item *sub_item;
6223 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_qfr_entry, &sub_item, "Entry");
6225 proto_tree_add_item(sub_tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6226 offset += 8;
6228 proto_tree_add_item(sub_tree, hf_smb2_qfr_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6229 offset += 8;
6231 proto_tree_add_item(sub_tree, hf_smb2_qfr_usage, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6232 offset += 4;
6234 proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6235 offset += 4;
6237 entry_count--;
6242 static void
6243 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6245 /* There is no out data */
6246 if (!data_in) {
6247 return;
6250 /* timeout */
6251 proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6252 offset += 4;
6254 /* reserved */
6255 proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6258 static void
6259 dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6261 /* There is no in data */
6262 if (data_in) {
6263 return;
6266 proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_support, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6267 offset += 4;
6269 proto_tree_add_item(tree, hf_smb2_ioctl_shared_virtual_disk_handle_state, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6272 #define STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID 0x00000001
6273 #define STORAGE_QOS_CONTROL_FLAG_SET_POLICY 0x00000002
6274 #define STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY 0x00000004
6275 #define STORAGE_QOS_CONTROL_FLAG_GET_STATUS 0x00000008
6276 #define STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS 0x00000010
6278 static const value_string smb2_ioctl_sqos_protocol_version_vals[] = {
6279 { 0x0100, "Storage QoS Protocol Version 1.0" },
6280 { 0x0101, "Storage QoS Protocol Version 1.1" },
6281 { 0, NULL }
6284 static const value_string smb2_ioctl_sqos_status_vals[] = {
6285 { 0x00, "StorageQoSStatusOk" },
6286 { 0x01, "StorageQoSStatusInsufficientThroughput" },
6287 { 0x02, "StorageQoSUnknownPolicyId" },
6288 { 0x04, "StorageQoSStatusConfigurationMismatch" },
6289 { 0x05, "StorageQoSStatusNotAvailable" },
6290 { 0, NULL }
6293 static void
6294 dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, gboolean data_in)
6296 static const int * operations[] = {
6297 &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
6298 &hf_smb2_ioctl_sqos_op_set_policy,
6299 &hf_smb2_ioctl_sqos_op_probe_policy,
6300 &hf_smb2_ioctl_sqos_op_get_status,
6301 &hf_smb2_ioctl_sqos_op_update_counters,
6302 NULL
6305 gint proto_ver;
6307 /* Both request and reply have the same common header */
6309 proto_ver = tvb_get_letohs(tvb, offset);
6310 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_protocol_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6311 offset += 2;
6313 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6314 offset += 2;
6316 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_ioctl_sqos_options,
6317 ett_smb2_ioctl_sqos_opeations, operations, ENC_LITTLE_ENDIAN);
6318 offset += 4;
6320 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_logical_flow_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6321 offset += 16;
6323 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_policy_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6324 offset += 16;
6326 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_initiator_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6327 offset += 16;
6329 if (data_in) {
6330 offset_length_buffer_t host_olb, node_olb;
6332 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6333 offset += 8;
6335 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reservation, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6336 offset += 8;
6338 offset = dissect_smb2_olb_length_offset(tvb, offset, &host_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_name);
6340 offset = dissect_smb2_olb_length_offset(tvb, offset, &node_olb, OLB_O_UINT16_S_UINT16, hf_smb2_ioctl_sqos_initiator_node_name);
6342 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6343 offset += 8;
6345 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_normalized_io_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6346 offset += 8;
6348 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6349 offset += 8;
6351 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_lower_latency_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6352 offset += 8;
6354 if (proto_ver > 0x0100) {
6355 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_bandwidth_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6356 offset += 8;
6358 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_kilobyte_count_increment, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6359 /*offset += 8;*/
6362 dissect_smb2_olb_string(pinfo, tree, tvb, &host_olb, OLB_TYPE_UNICODE_STRING);
6364 dissect_smb2_olb_string(pinfo, tree, tvb, &node_olb, OLB_TYPE_UNICODE_STRING);
6365 } else {
6366 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_time_to_live, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6367 offset += 4;
6369 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6370 offset += 4;
6372 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6373 offset += 8;
6375 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_minimum_io_rate, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6376 offset += 8;
6378 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_base_io_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6379 offset += 4;
6381 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_reserved2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6383 if (proto_ver > 0x0100) {
6384 offset += 4;
6385 proto_tree_add_item(tree, hf_smb2_ioctl_sqos_maximum_bandwidth, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6390 static int
6391 dissect_windows_sockaddr_in(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
6393 proto_item *sub_item;
6394 proto_tree *sub_tree;
6395 proto_item *parent_item;
6397 if (len == -1) {
6398 len = 8;
6401 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
6402 parent_item = proto_tree_get_parent(parent_tree);
6404 /* family */
6405 proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6406 offset += 2;
6408 /* port */
6409 proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6410 offset += 2;
6412 /* IPv4 address */
6413 proto_tree_add_item(sub_tree, hf_windows_sockaddr_in_addr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6414 proto_item_append_text(sub_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset));
6415 proto_item_append_text(parent_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset));
6416 offset += 4;
6417 return offset;
6420 static int
6421 dissect_windows_sockaddr_in6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
6423 proto_item *sub_item;
6424 proto_tree *sub_tree;
6425 proto_item *parent_item;
6427 if (len == -1) {
6428 len = 26;
6431 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
6432 parent_item = proto_tree_get_parent(parent_tree);
6434 /* family */
6435 proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6436 offset += 2;
6438 /* port */
6439 proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6440 offset += 2;
6442 /* sin6_flowinfo */
6443 proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_flowinfo, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6444 offset += 4;
6446 /* IPv6 address */
6447 proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_addr, tvb, offset, 16, ENC_NA);
6448 proto_item_append_text(sub_item, ", IPv6: %s", tvb_ip6_to_str(tvb, offset));
6449 proto_item_append_text(parent_item, ", IPv6: %s", tvb_ip6_to_str(tvb, offset));
6450 offset += 16;
6452 /* sin6_scope_id */
6453 proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_scope_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6454 offset += 2;
6456 return offset;
6459 static int
6460 dissect_windows_sockaddr_storage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int len)
6462 proto_item *sub_item;
6463 proto_tree *sub_tree;
6464 proto_item *parent_item;
6465 guint16 family;
6467 family = tvb_get_letohs(tvb, offset);
6468 switch (family) {
6469 case WINSOCK_AF_INET:
6470 return dissect_windows_sockaddr_in(tvb, pinfo, parent_tree, offset, len);
6471 case WINSOCK_AF_INET6:
6472 return dissect_windows_sockaddr_in6(tvb, pinfo, parent_tree, offset, len);
6475 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_windows_sockaddr, &sub_item, "Socket Address");
6476 parent_item = proto_tree_get_parent(parent_tree);
6478 /* ss_family */
6479 proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6480 proto_item_append_text(sub_item, ", Family: %d (0x%04x)", family, family);
6481 proto_item_append_text(parent_item, ", Family: %d (0x%04x)", family, family);
6482 return offset + len;
6485 #define NETWORK_INTERFACE_CAP_RSS 0x00000001
6486 #define NETWORK_INTERFACE_CAP_RDMA 0x00000002
6488 static void
6489 dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
6491 guint32 next_offset;
6492 int offset = 0;
6493 int len = -1;
6494 proto_item *sub_item;
6495 proto_tree *sub_tree;
6496 proto_item *item;
6497 guint32 capabilities;
6498 guint64 link_speed;
6499 gfloat val = 0;
6500 const char *unit = NULL;
6501 static const int * capability_flags[] = {
6502 &hf_smb2_ioctl_network_interface_capability_rdma,
6503 &hf_smb2_ioctl_network_interface_capability_rss,
6504 NULL
6507 next_offset = tvb_get_letohl(tvb, offset);
6508 if (next_offset) {
6509 len = next_offset;
6512 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_smb2_ioctl_network_interface, &sub_item, "Network Interface");
6513 item = proto_tree_get_parent(parent_tree);
6515 /* next offset */
6516 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6517 offset += 4;
6519 /* interface index */
6520 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6521 offset += 4;
6523 /* capabilities */
6524 capabilities = tvb_get_letohl(tvb, offset);
6525 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);
6527 if (capabilities != 0) {
6528 proto_item_append_text(item, "%s%s",
6529 (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
6530 (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
6531 proto_item_append_text(sub_item, "%s%s",
6532 (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
6533 (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
6535 offset += 4;
6537 /* rss queue count */
6538 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_rss_queue_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6539 offset += 4;
6541 /* link speed */
6542 link_speed = tvb_get_letoh64(tvb, offset);
6543 item = proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_link_speed, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6544 if (link_speed >= (1000*1000*1000)) {
6545 val = (gfloat)(link_speed / (1000*1000*1000));
6546 unit = "G";
6547 } else if (link_speed >= (1000*1000)) {
6548 val = (gfloat)(link_speed / (1000*1000));
6549 unit = "M";
6550 } else if (link_speed >= (1000)) {
6551 val = (gfloat)(link_speed / (1000));
6552 unit = "K";
6553 } else {
6554 val = (gfloat)(link_speed);
6555 unit = "";
6557 proto_item_append_text(item, ", %.1f %sBits/s", val, unit);
6558 proto_item_append_text(sub_item, ", %.1f %sBits/s", val, unit);
6560 offset += 8;
6562 /* socket address */
6563 dissect_windows_sockaddr_storage(tvb, pinfo, sub_tree, offset, -1);
6565 if (next_offset) {
6566 tvbuff_t *next_tvb;
6567 next_tvb = tvb_new_subset_remaining(tvb, next_offset);
6569 /* next extra info */
6570 dissect_smb2_NETWORK_INTERFACE_INFO(next_tvb, pinfo, parent_tree);
6574 static void
6575 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
6577 /* There is no in data */
6578 if (data_in) {
6579 return;
6582 dissect_smb2_NETWORK_INTERFACE_INFO(tvb, pinfo, tree);
6585 static void
6586 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
6589 * This is only used by Windows 8 beta
6591 if (data_in) {
6592 /* capabilities */
6593 offset = dissect_smb2_capabilities(tree, tvb, offset);
6595 /* client guid */
6596 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6597 offset += 16;
6599 /* security mode, skip second byte */
6600 offset = dissect_smb2_secmode(tree, tvb, offset);
6601 offset++;
6603 /* dialect */
6604 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6605 offset += 2;
6606 } else {
6607 /* capabilities */
6608 offset = dissect_smb2_capabilities(tree, tvb, offset);
6610 /* server guid */
6611 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6612 offset += 16;
6614 /* security mode, skip second byte */
6615 offset = dissect_smb2_secmode(tree, tvb, offset);
6616 offset++;
6618 /* dialect */
6619 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6620 offset += 2;
6624 static void
6625 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
6627 if (data_in) {
6628 guint16 dc;
6630 /* capabilities */
6631 offset = dissect_smb2_capabilities(tree, tvb, offset);
6633 /* client guid */
6634 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6635 offset += 16;
6637 /* security mode, skip second byte */
6638 offset = dissect_smb2_secmode(tree, tvb, offset);
6639 offset++;
6641 /* dialect count */
6642 dc = tvb_get_letohs(tvb, offset);
6643 proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6644 offset += 2;
6646 for ( ; dc>0; dc--) {
6647 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6648 offset += 2;
6650 } else {
6651 /* capabilities */
6652 offset = dissect_smb2_capabilities(tree, tvb, offset);
6654 /* server guid */
6655 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6656 offset += 16;
6658 /* security mode, skip second byte */
6659 offset = dissect_smb2_secmode(tree, tvb, offset);
6660 offset++;
6662 /* dialect */
6663 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6664 offset += 2;
6668 static void
6669 dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6671 guint32 num_snapshots;
6673 /* There is no in data */
6674 if (data_in) {
6675 return;
6678 /* NumberOfSnapShots */
6679 proto_tree_add_item(tree, hf_smb2_ioctl_enumerate_snapshots_num_snapshots, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6680 offset += 4;
6682 /* NumberOfSnapshotsReturned */
6683 proto_tree_add_item_ret_uint(tree, hf_smb2_ioctl_enumerate_snapshots_num_snapshots_returned, tvb, offset, 4, ENC_LITTLE_ENDIAN, &num_snapshots);
6684 offset += 4;
6686 /* SnapShotArraySize */
6687 proto_tree_add_item(tree, hf_smb2_ioctl_enumerate_snapshots_snapshot_array_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6688 offset += 4;
6690 while (num_snapshots--) {
6691 gint len;
6692 int old_offset = offset;
6694 proto_tree_add_item_ret_length(tree, hf_smb2_ioctl_enumerate_snapshots_snapshot,
6695 tvb, offset, -1, ENC_UTF_16|ENC_LITTLE_ENDIAN, &len);
6697 offset = old_offset+len;
6702 dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
6704 proto_item *item = NULL;
6705 proto_tree *tree = NULL;
6707 /* FILE_OBJECTID_BUFFER */
6708 if (parent_tree) {
6709 item = proto_tree_add_item(parent_tree, hf_smb2_FILE_OBJECTID_BUFFER, tvb, offset, 64, ENC_NA);
6710 tree = proto_item_add_subtree(item, ett_smb2_FILE_OBJECTID_BUFFER);
6713 /* Object ID */
6714 proto_tree_add_item(tree, hf_smb2_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6715 offset += 16;
6717 /* Birth Volume ID */
6718 proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6719 offset += 16;
6721 /* Birth Object ID */
6722 proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6723 offset += 16;
6725 /* Domain ID */
6726 proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6727 offset += 16;
6729 return offset;
6732 static int
6733 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6736 /* There is no in data */
6737 if (data_in) {
6738 return offset;
6741 /* FILE_OBJECTID_BUFFER */
6742 offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
6744 return offset;
6747 static int
6748 dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6751 /* There is no in data */
6752 if (data_in) {
6753 return offset;
6756 /* compression format */
6757 proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6758 offset += 2;
6760 return offset;
6763 static int
6764 dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6767 /* There is no out data */
6768 if (!data_in) {
6769 return offset;
6772 /* compression format */
6773 proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6774 offset += 2;
6776 return offset;
6779 static int
6780 dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6782 const int *integrity_flags[] = {
6783 &hf_smb2_integrity_flags_enforcement_off,
6784 NULL
6787 /* There is no out data */
6788 if (!data_in) {
6789 return offset;
6792 proto_tree_add_item(tree, hf_smb2_checksum_algorithm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6793 offset += 2;
6795 proto_tree_add_item(tree, hf_smb2_integrity_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6796 offset += 2;
6798 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_integrity_flags, ett_smb2_integrity_flags, integrity_flags, ENC_LITTLE_ENDIAN);
6799 offset += 4;
6801 return offset;
6804 static int
6805 dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6808 /* There is no out data */
6809 if (!data_in) {
6810 return offset;
6813 /* FILE_OBJECTID_BUFFER */
6814 offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
6816 return offset;
6819 static int
6820 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6823 /* There is no out data */
6824 if (!data_in) {
6825 return offset;
6828 /* FILE_OBJECTID_BUFFER->ExtendedInfo */
6830 /* Birth Volume ID */
6831 proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6832 offset += 16;
6834 /* Birth Object ID */
6835 proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6836 offset += 16;
6838 /* Domain ID */
6839 proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
6840 offset += 16;
6842 return offset;
6845 static int
6846 dissect_smb2_cchunk_RESUME_KEY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
6849 proto_tree_add_bytes_format_value(tree, hf_smb2_cchunk_resume_key, tvb,
6850 offset, 24, NULL, "Opaque Data");
6851 offset += 24;
6853 return (offset);
6856 static void
6857 dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6860 /* There is no in data */
6861 if (data_in) {
6862 return;
6865 offset = dissect_smb2_cchunk_RESUME_KEY(tvb, pinfo, tree, offset);
6867 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6870 static void
6871 dissect_smb2_FSCTL_SRV_COPYCHUNK(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
6873 proto_tree *sub_tree;
6874 proto_item *sub_item;
6875 guint32 chunk_count = 0;
6877 /* Output is simpler - handle that first. */
6878 if (!data_in) {
6879 proto_tree_add_item(tree, hf_smb2_cchunk_chunks_written, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6880 proto_tree_add_item(tree, hf_smb2_cchunk_bytes_written, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
6881 proto_tree_add_item(tree, hf_smb2_cchunk_total_written, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
6882 return;
6885 /* Input data, fixed part */
6886 offset = dissect_smb2_cchunk_RESUME_KEY(tvb, pinfo, tree, offset);
6887 proto_tree_add_item_ret_uint(tree, hf_smb2_cchunk_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &chunk_count);
6888 offset += 4;
6890 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6891 offset += 4;
6893 /* Zero or more allocated ranges may be reported. */
6894 while (chunk_count && tvb_reported_length_remaining(tvb, offset) >= 24) {
6895 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_smb2_cchunk_entry, &sub_item, "Chunk");
6897 proto_tree_add_item(sub_tree, hf_smb2_cchunk_src_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6898 offset += 8;
6900 proto_tree_add_item(sub_tree, hf_smb2_cchunk_dst_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6901 offset += 8;
6903 proto_tree_add_item(sub_tree, hf_smb2_cchunk_xfer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6904 offset += 4;
6906 proto_tree_add_item(sub_tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
6907 offset += 4;
6909 chunk_count--;
6913 static void
6914 dissect_smb2_reparse_nfs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint32 length)
6916 guint64 type;
6917 int symlink_length;
6919 type = tvb_get_letoh64(tvb, offset);
6920 proto_tree_add_item(tree, hf_smb2_nfs_type, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6921 offset += 8;
6923 switch (type) {
6924 case NFS_SPECFILE_LNK:
6926 * According to [MS-FSCC] 2.1.2.6 "length" contains
6927 * the 8-byte type plus the symlink target in Unicode
6928 * non-NULL terminated.
6930 if (length < 8) {
6931 THROW(ReportedBoundsError);
6933 symlink_length = length - 8;
6934 proto_tree_add_item(tree, hf_smb2_nfs_symlink_target, tvb, offset,
6935 symlink_length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
6936 break;
6937 case NFS_SPECFILE_CHR:
6938 proto_tree_add_item(tree, hf_smb2_nfs_chr_major, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6939 offset += 4;
6940 proto_tree_add_item(tree, hf_smb2_nfs_chr_minor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6941 break;
6942 case NFS_SPECFILE_BLK:
6943 proto_tree_add_item(tree, hf_smb2_nfs_blk_major, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6944 offset += 4;
6945 proto_tree_add_item(tree, hf_smb2_nfs_blk_minor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6946 break;
6947 case NFS_SPECFILE_FIFO:
6948 case NFS_SPECFILE_SOCK:
6949 /* no data */
6950 break;
6954 static void
6955 dissect_smb2_FSCTL_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
6957 proto_item *item = NULL;
6958 proto_tree *tree = NULL;
6960 guint32 tag;
6961 guint32 length;
6962 offset_length_buffer_t s_olb, p_olb;
6964 /* REPARSE_DATA_BUFFER */
6965 if (parent_tree) {
6966 item = proto_tree_add_item(parent_tree, hf_smb2_reparse_data_buffer, tvb, offset, -1, ENC_NA);
6967 tree = proto_item_add_subtree(item, ett_smb2_reparse_data_buffer);
6970 /* reparse tag */
6971 tag = tvb_get_letohl(tvb, offset);
6972 proto_tree_add_item(tree, hf_smb2_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6973 offset += 4;
6975 /* reparse data length */
6976 length = tvb_get_letohs(tvb, offset);
6977 proto_tree_add_item(tree, hf_smb2_reparse_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6978 offset += 2;
6980 /* reserved */
6981 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6982 offset += 2;
6984 if (!(tag & 0x80000000)) {
6985 /* if high bit is not set, this buffer has a GUID field */
6986 /* reparse guid */
6987 proto_tree_add_item(tree, hf_smb2_reparse_guid, tvb, offset, 16, ENC_NA);
6988 offset += 16;
6991 switch (tag) {
6992 case REPARSE_TAG_SYMLINK:
6993 /* substitute name offset/length */
6994 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_substitute_name);
6996 /* print name offset/length */
6997 offset = dissect_smb2_olb_length_offset(tvb, offset, &p_olb, OLB_O_UINT16_S_UINT16, hf_smb2_symlink_print_name);
6999 /* flags */
7000 proto_tree_add_item(tree, hf_smb2_symlink_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7001 offset += 4;
7003 /* substitute name string */
7004 dissect_smb2_olb_off_string(pinfo, tree, tvb, &s_olb, offset, OLB_TYPE_UNICODE_STRING);
7006 /* print name string */
7007 dissect_smb2_olb_off_string(pinfo, tree, tvb, &p_olb, offset, OLB_TYPE_UNICODE_STRING);
7008 break;
7009 case REPARSE_TAG_NFS:
7010 dissect_smb2_reparse_nfs(tvb, pinfo, tree, offset, length);
7011 break;
7012 default:
7013 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, length, ENC_NA);
7017 static void
7018 dissect_smb2_FSCTL_SET_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, gboolean data_in)
7020 if (!data_in) {
7021 return;
7024 dissect_smb2_FSCTL_REPARSE_POINT(tvb, pinfo, parent_tree, offset);
7027 static void
7028 dissect_smb2_FSCTL_GET_REPARSE_POINT(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, gboolean data_in)
7030 if (data_in) {
7031 return;
7034 dissect_smb2_FSCTL_REPARSE_POINT(tvb, pinfo, parent_tree, offset);
7037 void
7038 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_)
7040 guint16 dc;
7042 dc = tvb_reported_length(tvb);
7044 switch (ioctl_function) {
7045 case 0x00060194: /* FSCTL_DFS_GET_REFERRALS */
7046 if (data_in) {
7047 dissect_get_dfs_request_data(tvb, pinfo, tree, 0, &dc, TRUE);
7048 } else {
7049 dissect_get_dfs_referral_data(tvb, pinfo, tree, 0, &dc, TRUE);
7051 break;
7052 case 0x000940CF: /* FSCTL_QUERY_ALLOCATED_RANGES */
7053 dissect_smb2_FSCTL_QUERY_ALLOCATED_RANGES(tvb, pinfo, tree, 0, data_in);
7054 break;
7055 case 0x00094264: /* FSCTL_OFFLOAD_READ */
7056 dissect_smb2_FSCTL_OFFLOAD_READ(tvb, pinfo, tree, 0, data_in);
7057 break;
7058 case 0x00098268: /* FSCTL_OFFLOAD_WRITE */
7059 dissect_smb2_FSCTL_OFFLOAD_WRITE(tvb, pinfo, tree, 0, data_in);
7060 break;
7061 case 0x0011c017: /* FSCTL_PIPE_TRANSCEIVE */
7062 dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvb, pinfo, tree, 0, top_tree, data_in, private_data);
7063 break;
7064 case 0x00110018: /* FSCTL_PIPE_WAIT */
7065 dissect_smb2_FSCTL_PIPE_WAIT(tvb, pinfo, tree, 0, top_tree, data_in);
7066 break;
7067 case 0x00140078: /* FSCTL_SRV_REQUEST_RESUME_KEY */
7068 dissect_smb2_FSCTL_SRV_REQUEST_RESUME_KEY(tvb, pinfo, tree, 0, data_in);
7069 break;
7070 case 0x001401D4: /* FSCTL_LMR_REQUEST_RESILIENCY */
7071 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvb, pinfo, tree, 0, data_in);
7072 break;
7073 case 0x001401FC: /* FSCTL_QUERY_NETWORK_INTERFACE_INFO */
7074 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvb, pinfo, tree, 0, data_in);
7075 break;
7076 case 0x00140200: /* FSCTL_VALIDATE_NEGOTIATE_INFO_224 */
7077 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvb, pinfo, tree, 0, data_in);
7078 break;
7079 case 0x00140204: /* FSCTL_VALIDATE_NEGOTIATE_INFO */
7080 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvb, pinfo, tree, 0, data_in);
7081 break;
7082 case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */
7083 dissect_smb2_FSCTL_SRV_ENUMERATE_SNAPSHOTS(tvb, pinfo, tree, 0, data_in);
7084 break;
7085 case 0x001440F2: /* FSCTL_SRV_COPYCHUNK */
7086 case 0x001480F2: /* FSCTL_SRV_COPYCHUNK_WRITE */
7087 dissect_smb2_FSCTL_SRV_COPYCHUNK(tvb, pinfo, tree, 0, data_in);
7088 break;
7089 case 0x000900A4: /* FSCTL_SET_REPARSE_POINT */
7090 dissect_smb2_FSCTL_SET_REPARSE_POINT(tvb, pinfo, tree, 0, data_in);
7091 break;
7092 case 0x000900A8: /* FSCTL_GET_REPARSE_POINT */
7093 dissect_smb2_FSCTL_GET_REPARSE_POINT(tvb, pinfo, tree, 0, data_in);
7094 break;
7095 case 0x0009009C: /* FSCTL_GET_OBJECT_ID */
7096 case 0x000900c0: /* FSCTL_CREATE_OR_GET_OBJECT_ID */
7097 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
7098 break;
7099 case 0x000900c4: /* FSCTL_SET_SPARSE */
7100 dissect_smb2_FSCTL_SET_SPARSE(tvb, pinfo, tree, 0, data_in);
7101 break;
7102 case 0x00098098: /* FSCTL_SET_OBJECT_ID */
7103 dissect_smb2_FSCTL_SET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
7104 break;
7105 case 0x000980BC: /* FSCTL_SET_OBJECT_ID_EXTENDED */
7106 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvb, pinfo, tree, 0, data_in);
7107 break;
7108 case 0x000980C8: /* FSCTL_SET_ZERO_DATA */
7109 dissect_smb2_FSCTL_SET_ZERO_DATA(tvb, pinfo, tree, 0, data_in);
7110 break;
7111 case 0x0009003C: /* FSCTL_GET_COMPRESSION */
7112 dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
7113 break;
7114 case 0x00090300: /* FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT */
7115 dissect_smb2_FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT(tvb, pinfo, tree, 0, data_in);
7116 break;
7117 case 0x00090304: /* FSCTL_SVHDX_SYNC_TUNNEL or response */
7118 case 0x00090364: /* FSCTL_SVHDX_ASYNC_TUNNEL or response */
7119 call_dissector_with_data(rsvd_handle, tvb, pinfo, top_tree, &data_in);
7120 break;
7121 case 0x00090350: /* FSCTL_STORAGE_QOS_CONTROL */
7122 dissect_smb2_FSCTL_STORAGE_QOS_CONTROL(tvb, pinfo, tree, 0, data_in);
7123 break;
7124 case 0x0009C040: /* FSCTL_SET_COMPRESSION */
7125 dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
7126 break;
7127 case 0x00090284: /* FSCTL_QUERY_FILE_REGIONS */
7128 dissect_smb2_FSCTL_QUERY_FILE_REGIONS(tvb, pinfo, tree, 0, data_in);
7129 break;
7130 case 0x0009C280: /* FSCTL_SET_INTEGRITY_INFORMATION request or response */
7131 dissect_smb2_FSCTL_SET_INTEGRITY_INFORMATION(tvb, pinfo, tree, 0, data_in);
7132 break;
7133 default:
7134 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_captured_length(tvb), ENC_NA);
7138 static void
7139 dissect_smb2_ioctl_data_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7141 smb2_pipe_set_file_id(pinfo, si);
7142 dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, TRUE, si);
7145 static void
7146 dissect_smb2_ioctl_data_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7148 smb2_pipe_set_file_id(pinfo, si);
7149 dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, FALSE, si);
7152 static int
7153 dissect_smb2_ioctl_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7155 offset_length_buffer_t o_olb;
7156 offset_length_buffer_t i_olb;
7157 proto_tree *flags_tree = NULL;
7158 proto_item *flags_item = NULL;
7160 /* buffer code */
7161 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
7163 /* reserved */
7164 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
7165 offset += 2;
7167 /* ioctl function */
7168 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
7170 /* fid */
7171 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
7173 /* in buffer offset/length */
7174 offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
7176 /* max ioctl in size */
7177 proto_tree_add_item(tree, hf_smb2_max_ioctl_in_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7178 offset += 4;
7180 /* out buffer offset/length */
7181 offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
7183 /* max ioctl out size */
7184 proto_tree_add_item(tree, hf_smb2_max_ioctl_out_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7185 offset += 4;
7187 /* flags */
7188 if (tree) {
7189 flags_item = proto_tree_add_item(tree, hf_smb2_ioctl_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7190 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_ioctl_flags);
7192 proto_tree_add_item(flags_tree, hf_smb2_ioctl_is_fsctl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7193 offset += 4;
7195 /* reserved */
7196 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7197 offset += 4;
7199 /* try to decode these blobs in the order they were encoded
7200 * so that for "short" packets we will dissect as much as possible
7201 * before aborting with "short packet"
7203 if (i_olb.off>o_olb.off) {
7204 /* out buffer */
7205 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7206 /* in buffer */
7207 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7208 } else {
7209 /* in buffer */
7210 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7211 /* out buffer */
7212 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7215 offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
7216 offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
7218 return offset;
7221 static int
7222 dissect_smb2_ioctl_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7224 offset_length_buffer_t o_olb;
7225 offset_length_buffer_t i_olb;
7226 gboolean continue_dissection;
7228 switch (si->status) {
7229 /* buffer code */
7230 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
7231 case 0x80000005: break;
7232 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
7233 if (!continue_dissection) return offset;
7236 /* some unknown bytes */
7237 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
7238 offset += 2;
7240 /* ioctl function */
7241 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
7243 /* fid */
7244 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
7246 /* in buffer offset/length */
7247 offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
7249 /* out buffer offset/length */
7250 offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
7253 /* flags: reserved: must be zero */
7254 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7255 offset += 4;
7257 /* reserved */
7258 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7259 offset += 4;
7261 /* try to decode these blobs in the order they were encoded
7262 * so that for "short" packets we will dissect as much as possible
7263 * before aborting with "short packet"
7265 if (i_olb.off>o_olb.off) {
7266 /* out buffer */
7267 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7268 /* in buffer */
7269 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7270 } else {
7271 /* in buffer */
7272 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
7273 /* out buffer */
7274 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
7277 offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
7278 offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
7280 return offset;
7284 static int
7285 dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
7287 offset_length_buffer_t c_olb;
7288 guint32 channel;
7289 guint32 len;
7290 guint64 off;
7292 /* buffer code */
7293 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
7295 /* padding and reserved */
7296 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
7297 offset += 2;
7299 /* length */
7300 len = tvb_get_letohl(tvb, offset);
7301 proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7302 offset += 4;
7304 /* offset */
7305 off = tvb_get_letoh64(tvb, offset);
7306 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7307 offset += 8;
7309 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", len, off);
7311 /* fid */
7312 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
7314 /* minimum count */
7315 proto_tree_add_item(tree, hf_smb2_min_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7316 offset += 4;
7318 /* channel */
7319 channel = tvb_get_letohl(tvb, offset);
7320 proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7321 offset += 4;
7323 /* remaining bytes */
7324 proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7325 offset += 4;
7327 /* read channel info blob offset/length */
7328 offset = dissect_smb2_olb_length_offset(tvb, offset, &c_olb, OLB_O_UINT16_S_UINT16, hf_smb2_channel_info_blob);
7330 /* the read channel info blob itself */
7331 switch (channel) {
7332 case SMB2_CHANNEL_RDMA_V1:
7333 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, dissect_smb2_rdma_v1_blob);
7334 break;
7335 case SMB2_CHANNEL_NONE:
7336 default:
7337 dissect_smb2_olb_buffer(pinfo, tree, tvb, &c_olb, si, NULL);
7338 break;
7341 offset = dissect_smb2_olb_tvb_max_offset(offset, &c_olb);
7343 /* Store len and offset */
7344 if (si->saved) {
7345 si->saved->file_offset=off;
7346 si->saved->bytes_moved=len;
7349 return offset;
7353 static int
7354 dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
7356 guint16 dataoffset = 0;
7357 guint32 data_tvb_len;
7358 guint32 length;
7359 gboolean continue_dissection;
7361 switch (si->status) {
7362 /* buffer code */
7363 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
7364 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
7365 if (!continue_dissection) return offset;
7368 /* data offset */
7369 dataoffset=tvb_get_letohl(tvb,offset);
7370 proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7371 offset += 2;
7373 /* length might even be 64bits if they are ambitious*/
7374 length = tvb_get_letohl(tvb, offset);
7375 proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7376 offset += 4;
7378 /* remaining */
7379 proto_tree_add_item(tree, hf_smb2_read_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7380 offset += 4;
7382 /* reserved */
7383 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
7384 offset += 4;
7386 data_tvb_len=(guint32)tvb_captured_length_remaining(tvb, offset);
7388 /* data or namedpipe ?*/
7389 if (length) {
7390 int oldoffset = offset;
7391 smb2_pipe_set_file_id(pinfo, si);
7392 offset = dissect_file_data_smb2_pipe(tvb, pinfo, tree, offset, length, si->top_tree, si);
7393 if (offset != oldoffset) {
7394 /* managed to dissect pipe data */
7395 goto out;
7399 /* data */
7400 proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, ENC_NA);
7402 offset += MIN(length,data_tvb_len);
7404 out:
7405 if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
7406 if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
7407 feed_eo_smb2(tvb,pinfo,si,dataoffset,length,si->saved->file_offset);
7411 return offset;
7414 static void
7415 report_create_context_malformed_buffer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const char *buffer_desc)
7417 proto_tree_add_expert_format(tree, pinfo, &ei_smb2_bad_response, tvb, 0, -1,
7418 "%s SHOULD NOT be generated", buffer_desc);
7420 static void
7421 dissect_smb2_ExtA_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7423 proto_item *item = NULL;
7424 if (tree) {
7425 item = proto_tree_get_parent(tree);
7426 proto_item_append_text(item, ": SMB2_FILE_FULL_EA_INFO");
7428 dissect_smb2_file_full_ea_info(tvb, pinfo, tree, 0, si);
7431 static void
7432 dissect_smb2_ExtA_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7434 report_create_context_malformed_buffer(tvb, pinfo, tree, "ExtA Response");
7437 static void
7438 dissect_smb2_SecD_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7440 proto_item *item = NULL;
7441 if (tree) {
7442 item = proto_tree_get_parent(tree);
7443 proto_item_append_text(item, ": SMB2_SEC_INFO_00");
7445 dissect_smb2_sec_info_00(tvb, pinfo, tree, 0, si);
7448 static void
7449 dissect_smb2_SecD_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7451 report_create_context_malformed_buffer(tvb, pinfo, tree, "SecD Response");
7454 static void
7455 dissect_smb2_TWrp_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7457 proto_item *item = NULL;
7458 if (tree) {
7459 item = proto_tree_get_parent(tree);
7460 proto_item_append_text(item, ": Timestamp");
7462 dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_twrp_timestamp);
7465 static void
7466 dissect_smb2_TWrp_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7468 report_create_context_malformed_buffer(tvb, pinfo, tree, "TWrp Response");
7471 static void
7472 dissect_smb2_QFid_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7474 proto_item *item = NULL;
7476 if (tree) {
7477 item = proto_tree_get_parent(tree);
7480 if (item) {
7481 if (tvb_reported_length(tvb) == 0) {
7482 proto_item_append_text(item, ": NO DATA");
7483 } else {
7484 proto_item_append_text(item, ": QFid request should have no data, malformed packet");
7489 static void
7490 dissect_smb2_QFid_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7492 int offset = 0;
7493 proto_item *item;
7494 proto_item *sub_tree;
7496 item = proto_tree_get_parent(tree);
7498 proto_item_append_text(item, ": QFid INFO");
7499 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_QFid_buffer, NULL, "QFid INFO");
7501 proto_tree_add_item(sub_tree, hf_smb2_qfid_fid, tvb, offset, 32, ENC_NA);
7504 static void
7505 dissect_smb2_AlSi_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7507 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, 0, 8, ENC_LITTLE_ENDIAN);
7510 static void
7511 dissect_smb2_AlSi_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7513 report_create_context_malformed_buffer(tvb, pinfo, tree, "AlSi Response");
7516 static void
7517 dissect_smb2_DHnQ_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7519 dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNQ);
7522 static void
7523 dissect_smb2_DHnQ_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7525 proto_tree_add_item(tree, hf_smb2_dhnq_buffer_reserved, tvb, 0, 8, ENC_LITTLE_ENDIAN);
7528 static void
7529 dissect_smb2_DHnC_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7531 dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNC);
7534 static void
7535 dissect_smb2_DHnC_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7537 report_create_context_malformed_buffer(tvb, pinfo, tree, "DHnC Response");
7541 * SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2
7542 * 4 - timeout
7543 * 4 - flags
7544 * 8 - reserved
7545 * 16 - create guid
7547 * SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2
7548 * 4 - timeout
7549 * 4 - flags
7551 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
7552 * 16 - file id
7553 * 16 - create guid
7554 * 4 - flags
7556 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
7557 * - nothing -
7559 #define SMB2_DH2X_FLAGS_PERSISTENT_HANDLE 0x00000002
7561 static void
7562 dissect_smb2_DH2Q_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7564 static const int *dh2x_flags_fields[] = {
7565 &hf_smb2_dh2x_buffer_flags_persistent_handle,
7566 NULL
7568 int offset = 0;
7569 proto_item *item;
7570 proto_item *sub_tree;
7572 item = proto_tree_get_parent(tree);
7574 proto_item_append_text(item, ": DH2Q Request");
7575 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2Q_buffer, NULL, "DH2Q Request");
7577 /* timeout */
7578 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7579 offset += 4;
7581 /* flags */
7582 proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_dh2x_buffer_flags,
7583 ett_smb2_dh2x_flags, dh2x_flags_fields, ENC_LITTLE_ENDIAN);
7584 offset += 4;
7586 /* reserved */
7587 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_reserved, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7588 offset += 8;
7590 /* create guid */
7591 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7594 static void
7595 dissect_smb2_DH2Q_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7597 int offset = 0;
7598 proto_item *item;
7599 proto_item *sub_tree;
7601 item = proto_tree_get_parent(tree);
7603 proto_item_append_text(item, ": DH2Q Response");
7604 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2Q_buffer, NULL, "DH2Q Response");
7606 /* timeout */
7607 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7608 offset += 4;
7610 /* flags */
7611 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7614 static void
7615 dissect_smb2_DH2C_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
7617 int offset = 0;
7618 proto_item *item;
7619 proto_item *sub_tree;
7621 item = proto_tree_get_parent(tree);
7623 proto_item_append_text(item, ": DH2C Request");
7624 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_DH2C_buffer, NULL, "DH2C Request");
7626 /* file id */
7627 dissect_smb2_fid(tvb, pinfo, sub_tree, offset, si, FID_MODE_DHNC);
7628 offset += 16;
7630 /* create guid */
7631 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7632 offset += 16;
7634 /* flags */
7635 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7638 static void
7639 dissect_smb2_DH2C_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
7641 report_create_context_malformed_buffer(tvb, pinfo, tree, "DH2C Response");
7644 static void
7645 dissect_smb2_MxAc_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7647 int offset = 0;
7648 proto_item *item = NULL;
7650 if (tree) {
7651 item = proto_tree_get_parent(tree);
7654 if (tvb_reported_length(tvb) == 0) {
7655 if (item) {
7656 proto_item_append_text(item, ": NO DATA");
7658 return;
7661 if (item) {
7662 proto_item_append_text(item, ": Timestamp");
7665 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_mxac_timestamp);
7668 static void
7669 dissect_smb2_MxAc_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7671 int offset = 0;
7672 proto_item *item;
7673 proto_tree *sub_tree;
7675 item = proto_tree_get_parent(tree);
7677 if (tvb_reported_length(tvb) == 0) {
7678 proto_item_append_text(item, ": NO DATA");
7679 return;
7682 proto_item_append_text(item, ": MxAc INFO");
7683 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_MxAc_buffer, NULL, "MxAc INFO");
7685 proto_tree_add_item(sub_tree, hf_smb2_mxac_status, tvb, offset, 4, ENC_BIG_ENDIAN);
7686 offset += 4;
7688 dissect_smb_access_mask(tvb, sub_tree, offset);
7692 * SMB2_CREATE_REQUEST_LEASE 32
7693 * 16 - lease key
7694 * 4 - lease state
7695 * 4 - lease flags
7696 * 8 - lease duration
7698 * SMB2_CREATE_REQUEST_LEASE_V2 52
7699 * 16 - lease key
7700 * 4 - lease state
7701 * 4 - lease flags
7702 * 8 - lease duration
7703 * 16 - parent lease key
7704 * 2 - epoch
7705 * 2 - reserved
7707 #define SMB2_LEASE_STATE_READ_CACHING 0x00000001
7708 #define SMB2_LEASE_STATE_HANDLE_CACHING 0x00000002
7709 #define SMB2_LEASE_STATE_WRITE_CACHING 0x00000004
7711 #define SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED 0x00000001
7712 #define SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS 0x00000002
7713 #define SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET 0x00000004
7715 static const int *lease_state_fields[] = {
7716 &hf_smb2_lease_state_read_caching,
7717 &hf_smb2_lease_state_handle_caching,
7718 &hf_smb2_lease_state_write_caching,
7719 NULL
7721 static const int *lease_flags_fields[] = {
7722 &hf_smb2_lease_flags_break_ack_required,
7723 &hf_smb2_lease_flags_break_in_progress,
7724 &hf_smb2_lease_flags_parent_lease_key_set,
7725 NULL
7728 static void
7729 dissect_SMB2_CREATE_LEASE_VX(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
7731 int offset = 0;
7732 int len;
7733 proto_tree *sub_tree = NULL;
7734 proto_item *parent_item;
7736 parent_item = proto_tree_get_parent(parent_tree);
7738 len = tvb_reported_length(tvb);
7740 switch (len) {
7741 case 32: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE */
7742 proto_item_append_text(parent_item, ": LEASE_V1");
7743 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_RqLs_buffer, NULL, "LEASE_V1");
7744 break;
7745 case 52: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE_V2 */
7746 proto_item_append_text(parent_item, ": LEASE_V2");
7747 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_smb2_RqLs_buffer, NULL, "LEASE_V2");
7748 break;
7749 default:
7750 report_create_context_malformed_buffer(tvb, pinfo, parent_tree, "RqLs");
7751 break;
7754 proto_tree_add_item(sub_tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7755 offset += 16;
7757 proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_state,
7758 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
7759 offset += 4;
7761 proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_flags,
7762 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
7763 offset += 4;
7765 proto_tree_add_item(sub_tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
7766 offset += 8;
7768 if (len < 52) {
7769 return;
7772 proto_tree_add_item(sub_tree, hf_smb2_parent_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7773 offset += 16;
7775 proto_tree_add_item(sub_tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7776 offset += 2;
7778 proto_tree_add_item(sub_tree, hf_smb2_lease_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7781 static void
7782 dissect_smb2_RqLs_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7784 dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
7787 static void
7788 dissect_smb2_RqLs_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7790 dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
7794 * SMB2_CREATE_APP_INSTANCE_ID
7795 * 2 - structure size - 20
7796 * 2 - reserved
7797 * 16 - application guid
7800 static void
7801 dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7803 int offset = 0;
7804 proto_item *item;
7805 proto_item *sub_tree;
7807 item = proto_tree_get_parent(tree);
7809 proto_item_append_text(item, ": CREATE APP INSTANCE ID");
7810 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_APP_INSTANCE_buffer, NULL, "APP INSTANCE ID");
7812 /* struct size */
7813 proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_struct_size,
7814 tvb, offset, 2, ENC_LITTLE_ENDIAN);
7815 offset += 2;
7817 /* reserved */
7818 proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_reserved,
7819 tvb, offset, 2, ENC_LITTLE_ENDIAN);
7820 offset += 2;
7822 /* create guid */
7823 proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_app_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
7826 static void
7827 dissect_smb2_APP_INSTANCE_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7829 report_create_context_malformed_buffer(tvb, pinfo, tree, "APP INSTANCE Response");
7833 * Dissect the MS-RSVD stuff that turns up when HyperV uses SMB3.x
7835 static void
7836 dissect_smb2_svhdx_open_device_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7838 int offset = 0;
7839 guint32 version;
7840 proto_item *item;
7841 proto_item *sub_tree;
7843 item = proto_tree_get_parent(tree);
7845 proto_item_append_text(item, ": SVHDX OPEN DEVICE CONTEXT");
7846 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_svhdx_open_device_context, NULL, "SVHDX OPEN DEVICE CONTEXT");
7848 /* Version */
7849 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_svhdx_open_device_context_version,
7850 tvb, offset, 4, ENC_LITTLE_ENDIAN, &version);
7851 offset += 4;
7853 /* HasInitiatorId */
7854 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_has_initiator_id,
7855 tvb, offset, 1, ENC_LITTLE_ENDIAN);
7856 offset += 1;
7858 /* Reserved */
7859 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_reserved,
7860 tvb, offset, 3, ENC_NA);
7861 offset += 3;
7863 /* InitiatorId */
7864 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_id,
7865 tvb, offset, 16, ENC_LITTLE_ENDIAN);
7866 offset += 16;
7868 /* Flags TODO: Dissect these*/
7869 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_flags,
7870 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7871 offset += 4;
7873 /* OriginatorFlags */
7874 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_originator_flags,
7875 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7876 offset += 4;
7878 /* OpenRequestId */
7879 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_open_request_id,
7880 tvb, offset, 8, ENC_LITTLE_ENDIAN);
7881 offset += 8;
7883 /* InitiatorHostNameLength */
7884 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name_len,
7885 tvb, offset, 2, ENC_LITTLE_ENDIAN);
7886 offset += 2;
7888 /* InitiatorHostName */
7889 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_initiator_host_name,
7890 tvb, offset, 126, ENC_ASCII | ENC_NA);
7891 offset += 126;
7893 if (version == 2) {
7894 /* VirtualDiskPropertiesInitialized */
7895 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
7896 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7897 offset += 4;
7899 /* ServerServiceVersion */
7900 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_server_service_version,
7901 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7902 offset += 4;
7904 /* VirtualSectorSize */
7905 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_sector_size,
7906 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7907 offset += 4;
7909 /* PhysicalSectorSize */
7910 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_physical_sector_size,
7911 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7912 offset += 4;
7914 /* VirtualSize */
7915 proto_tree_add_item(sub_tree, hf_smb2_svhdx_open_device_context_virtual_size,
7916 tvb, offset, 8, ENC_LITTLE_ENDIAN);
7920 static const int *posix_flags_fields[] = {
7921 &hf_smb2_posix_v1_case_sensitive,
7922 &hf_smb2_posix_v1_posix_lock,
7923 &hf_smb2_posix_v1_posix_file_semantics,
7924 &hf_smb2_posix_v1_posix_utf8_paths,
7925 &hf_smb2_posix_v1_posix_will_convert_nt_acls,
7926 &hf_smb2_posix_v1_posix_fileinfo,
7927 &hf_smb2_posix_v1_posix_acls,
7928 &hf_smb2_posix_v1_rich_acls,
7929 NULL
7932 static void
7933 dissect_smb2_posix_v1_caps_request(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7935 int offset = 0;
7936 proto_item *item;
7937 proto_item *sub_tree;
7939 item = proto_tree_get_parent(tree);
7941 proto_item_append_text(item, ": POSIX V1 CAPS request");
7942 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_posix_v1_request, NULL, "POSIX_V1_REQUEST");
7944 /* Version */
7945 proto_tree_add_item(sub_tree, hf_smb2_posix_v1_version,
7946 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7947 offset += 4;
7949 /* Request */
7950 proto_tree_add_item(sub_tree, hf_smb2_posix_v1_request,
7951 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7954 static void
7955 dissect_smb2_posix_v1_caps_response(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
7957 int offset = 0;
7958 proto_item *item;
7959 proto_item *sub_tree;
7961 item = proto_tree_get_parent(tree);
7963 proto_item_append_text(item, ": POSIX V1 CAPS response");
7964 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_posix_v1_response, NULL, "POSIX_V1_RESPONSE");
7966 /* Version */
7967 proto_tree_add_item(sub_tree, hf_smb2_posix_v1_version,
7968 tvb, offset, 4, ENC_LITTLE_ENDIAN);
7969 offset += 4;
7971 /* Supported Features */
7972 proto_tree_add_bitmask(sub_tree, tvb, offset,
7973 hf_smb2_posix_v1_supported_features,
7974 ett_smb2_posix_v1_supported_features,
7975 posix_flags_fields, ENC_LITTLE_ENDIAN);
7979 #define SMB2_AAPL_SERVER_QUERY 1
7980 #define SMB2_AAPL_RESOLVE_ID 2
7982 static const value_string aapl_command_code_vals[] = {
7983 { SMB2_AAPL_SERVER_QUERY, "Server query"},
7984 { SMB2_AAPL_RESOLVE_ID, "Resolve ID"},
7985 { 0, NULL }
7988 #define SMB2_AAPL_SERVER_CAPS 0x00000001
7989 #define SMB2_AAPL_VOLUME_CAPS 0x00000002
7990 #define SMB2_AAPL_MODEL_INFO 0x00000004
7992 static const int *aapl_server_query_bitmap_fields[] = {
7993 &hf_smb2_aapl_server_query_bitmask_server_caps,
7994 &hf_smb2_aapl_server_query_bitmask_volume_caps,
7995 &hf_smb2_aapl_server_query_bitmask_model_info,
7996 NULL
7999 #define SMB2_AAPL_SUPPORTS_READ_DIR_ATTR 0x00000001
8000 #define SMB2_AAPL_SUPPORTS_OSX_COPYFILE 0x00000002
8001 #define SMB2_AAPL_UNIX_BASED 0x00000004
8002 #define SMB2_AAPL_SUPPORTS_NFS_ACE 0x00000008
8004 static const int *aapl_server_query_caps_fields[] = {
8005 &hf_smb2_aapl_server_query_caps_supports_read_dir_attr,
8006 &hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
8007 &hf_smb2_aapl_server_query_caps_unix_based,
8008 &hf_smb2_aapl_server_query_caps_supports_nfs_ace,
8009 NULL
8012 static void
8013 dissect_smb2_AAPL_buffer_request(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
8015 int offset = 0;
8016 proto_item *item;
8017 proto_item *sub_tree;
8018 guint32 command_code;
8020 item = proto_tree_get_parent(tree);
8022 proto_item_append_text(item, ": AAPL Create Context request");
8023 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_aapl_create_context_request, NULL, "AAPL Create Context request");
8025 /* Command code */
8026 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_aapl_command_code,
8027 tvb, offset, 4, ENC_LITTLE_ENDIAN, &command_code);
8028 offset += 4;
8030 /* Reserved */
8031 proto_tree_add_item(sub_tree, hf_smb2_aapl_reserved,
8032 tvb, offset, 4, ENC_LITTLE_ENDIAN);
8033 offset += 4;
8035 switch (command_code) {
8037 case SMB2_AAPL_SERVER_QUERY:
8038 /* Request bitmap */
8039 proto_tree_add_bitmask(sub_tree, tvb, offset,
8040 hf_smb2_aapl_server_query_bitmask,
8041 ett_smb2_aapl_server_query_bitmask,
8042 aapl_server_query_bitmap_fields,
8043 ENC_LITTLE_ENDIAN);
8044 offset += 8;
8046 /* Client capabilities */
8047 proto_tree_add_bitmask(sub_tree, tvb, offset,
8048 hf_smb2_aapl_server_query_caps,
8049 ett_smb2_aapl_server_query_caps,
8050 aapl_server_query_caps_fields,
8051 ENC_LITTLE_ENDIAN);
8052 break;
8054 case SMB2_AAPL_RESOLVE_ID:
8055 /* file ID */
8056 proto_tree_add_item(sub_tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8057 break;
8059 default:
8060 break;
8064 #define SMB2_AAPL_SUPPORTS_RESOLVE_ID 0x00000001
8065 #define SMB2_AAPL_CASE_SENSITIVE 0x00000002
8066 #define SMB2_AAPL_SUPPORTS_FULL_SYNC 0x00000004
8068 static const int *aapl_server_query_volume_caps_fields[] = {
8069 &hf_smb2_aapl_server_query_volume_caps_support_resolve_id,
8070 &hf_smb2_aapl_server_query_volume_caps_case_sensitive,
8071 &hf_smb2_aapl_server_query_volume_caps_supports_full_sync,
8072 NULL
8075 static void
8076 dissect_smb2_AAPL_buffer_response(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, smb2_info_t *si _U_)
8078 int offset = 0;
8079 proto_item *item;
8080 proto_item *sub_tree;
8081 guint32 command_code;
8082 guint64 server_query_bitmask;
8084 item = proto_tree_get_parent(tree);
8086 proto_item_append_text(item, ": AAPL Create Context response");
8087 sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_aapl_create_context_response, NULL, "AAPL Create Context response");
8089 /* Command code */
8090 proto_tree_add_item_ret_uint(sub_tree, hf_smb2_aapl_command_code,
8091 tvb, offset, 4, ENC_LITTLE_ENDIAN, &command_code);
8092 offset += 4;
8094 /* Reserved */
8095 proto_tree_add_item(sub_tree, hf_smb2_aapl_reserved,
8096 tvb, offset, 4, ENC_LITTLE_ENDIAN);
8097 offset += 4;
8099 switch (command_code) {
8101 case SMB2_AAPL_SERVER_QUERY:
8102 /* Reply bitmap */
8103 proto_tree_add_bitmask_ret_uint64(sub_tree, tvb, offset,
8104 hf_smb2_aapl_server_query_bitmask,
8105 ett_smb2_aapl_server_query_bitmask,
8106 aapl_server_query_bitmap_fields,
8107 ENC_LITTLE_ENDIAN,
8108 &server_query_bitmask);
8109 offset += 8;
8111 if (server_query_bitmask & SMB2_AAPL_SERVER_CAPS) {
8112 /* Server capabilities */
8113 proto_tree_add_bitmask(sub_tree, tvb, offset,
8114 hf_smb2_aapl_server_query_caps,
8115 ett_smb2_aapl_server_query_caps,
8116 aapl_server_query_caps_fields,
8117 ENC_LITTLE_ENDIAN);
8118 offset += 8;
8120 if (server_query_bitmask & SMB2_AAPL_VOLUME_CAPS) {
8121 /* Volume capabilities */
8122 proto_tree_add_bitmask(sub_tree, tvb, offset,
8123 hf_smb2_aapl_server_query_volume_caps,
8124 ett_smb2_aapl_server_query_volume_caps,
8125 aapl_server_query_volume_caps_fields,
8126 ENC_LITTLE_ENDIAN);
8127 offset += 8;
8129 if (server_query_bitmask & SMB2_AAPL_MODEL_INFO) {
8130 /* Padding */
8131 offset += 4;
8133 /* Model string */
8134 proto_tree_add_item(sub_tree, hf_smb2_aapl_server_query_model_string,
8135 tvb, offset, 4,
8136 ENC_UTF_16|ENC_LITTLE_ENDIAN);
8138 break;
8140 case SMB2_AAPL_RESOLVE_ID:
8141 /* NT status */
8142 proto_tree_add_item(sub_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8143 offset += 4;
8145 /* Server path */
8146 proto_tree_add_item(sub_tree, hf_smb2_aapl_server_query_server_path,
8147 tvb, offset, 4,
8148 ENC_UTF_16|ENC_LITTLE_ENDIAN);
8149 break;
8151 default:
8152 break;
8156 typedef void (*create_context_data_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
8158 typedef struct create_context_data_dissectors {
8159 create_context_data_dissector_t request;
8160 create_context_data_dissector_t response;
8161 } create_context_data_dissectors_t;
8163 struct create_context_data_tag_dissectors {
8164 const char *tag;
8165 const char *val;
8166 create_context_data_dissectors_t dissectors;
8169 struct create_context_data_tag_dissectors create_context_dissectors_array[] = {
8170 { "ExtA", "SMB2_CREATE_EA_BUFFER",
8171 { dissect_smb2_ExtA_buffer_request, dissect_smb2_ExtA_buffer_response } },
8172 { "SecD", "SMB2_CREATE_SD_BUFFER",
8173 { dissect_smb2_SecD_buffer_request, dissect_smb2_SecD_buffer_response } },
8174 { "AlSi", "SMB2_CREATE_ALLOCATION_SIZE",
8175 { dissect_smb2_AlSi_buffer_request, dissect_smb2_AlSi_buffer_response } },
8176 { "MxAc", "SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST",
8177 { dissect_smb2_MxAc_buffer_request, dissect_smb2_MxAc_buffer_response } },
8178 { "DHnQ", "SMB2_CREATE_DURABLE_HANDLE_REQUEST",
8179 { dissect_smb2_DHnQ_buffer_request, dissect_smb2_DHnQ_buffer_response } },
8180 { "DHnC", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT",
8181 { dissect_smb2_DHnC_buffer_request, dissect_smb2_DHnC_buffer_response } },
8182 { "DH2Q", "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2",
8183 { dissect_smb2_DH2Q_buffer_request, dissect_smb2_DH2Q_buffer_response } },
8184 { "DH2C", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2",
8185 { dissect_smb2_DH2C_buffer_request, dissect_smb2_DH2C_buffer_response } },
8186 { "TWrp", "SMB2_CREATE_TIMEWARP_TOKEN",
8187 { dissect_smb2_TWrp_buffer_request, dissect_smb2_TWrp_buffer_response } },
8188 { "QFid", "SMB2_CREATE_QUERY_ON_DISK_ID",
8189 { dissect_smb2_QFid_buffer_request, dissect_smb2_QFid_buffer_response } },
8190 { "RqLs", "SMB2_CREATE_REQUEST_LEASE",
8191 { dissect_smb2_RqLs_buffer_request, dissect_smb2_RqLs_buffer_response } },
8192 { "744D142E-46FA-0890-4AF7-A7EF6AA6BC45", "SMB2_CREATE_APP_INSTANCE_ID",
8193 { dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
8194 { "6aa6bc45-a7ef-4af7-9008-fa462e144d74", "SMB2_CREATE_APP_INSTANCE_ID",
8195 { dissect_smb2_APP_INSTANCE_buffer_request, dissect_smb2_APP_INSTANCE_buffer_response } },
8196 { "9ecfcb9c-c104-43e6-980e-158da1f6ec83", "SVHDX_OPEN_DEVICE_CONTEXT",
8197 { dissect_smb2_svhdx_open_device_context, dissect_smb2_svhdx_open_device_context} },
8198 { "34263501-2921-4912-2586-447794114531", "SMB2_POSIX_V1_CAPS",
8199 { dissect_smb2_posix_v1_caps_request, dissect_smb2_posix_v1_caps_response } },
8200 { "AAPL", "SMB2_AAPL_CREATE_CONTEXT",
8201 { dissect_smb2_AAPL_buffer_request, dissect_smb2_AAPL_buffer_response } },
8204 static struct create_context_data_tag_dissectors*
8205 get_create_context_data_tag_dissectors(const char *tag)
8207 static struct create_context_data_tag_dissectors INVALID = {
8208 NULL, "<invalid>", { NULL, NULL }
8211 size_t i;
8213 for (i = 0; i<array_length(create_context_dissectors_array); i++) {
8214 if (!strcmp(tag, create_context_dissectors_array[i].tag))
8215 return &create_context_dissectors_array[i];
8217 return &INVALID;
8220 static void
8221 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
8223 offset_length_buffer_t tag_olb;
8224 offset_length_buffer_t data_olb;
8225 const guint8 *tag;
8226 guint16 chain_offset;
8227 int offset = 0;
8228 int len = -1;
8229 proto_item *sub_item;
8230 proto_tree *sub_tree;
8231 proto_item *parent_item = NULL;
8232 create_context_data_dissectors_t *dissectors = NULL;
8233 create_context_data_dissector_t dissector = NULL;
8234 struct create_context_data_tag_dissectors *tag_dissectors;
8236 chain_offset = tvb_get_letohl(tvb, offset);
8237 if (chain_offset) {
8238 len = chain_offset;
8241 sub_tree = proto_tree_add_subtree(parent_tree, tvb, offset, len, ett_smb2_create_chain_element, &sub_item, "Chain Element");
8242 parent_item = proto_tree_get_parent(parent_tree);
8244 /* chain offset */
8245 proto_tree_add_item(sub_tree, hf_smb2_create_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8246 offset += 4;
8248 /* tag offset/length */
8249 offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
8251 /* data offset/length */
8252 dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_create_chain_data);
8255 * These things are all either 4-char strings, like DH2C, or GUIDs,
8256 * however, at least one of them appears to be a GUID as a string and
8257 * one appears to be a binary guid. So, check if the the length is
8258 * 16, and if so, pull the GUID and convert it to a string. Otherwise
8259 * call dissect_smb2_olb_string.
8261 if (tag_olb.len == 16) {
8262 e_guid_t tag_guid;
8263 proto_item *tag_item;
8264 proto_tree *tag_tree;
8266 tvb_get_letohguid(tvb, tag_olb.off, &tag_guid);
8267 tag = guid_to_str(wmem_packet_scope(), &tag_guid);
8269 tag_item = proto_tree_add_string(sub_tree, tag_olb.hfindex, tvb, tag_olb.off, tag_olb.len, tag);
8270 tag_tree = proto_item_add_subtree(tag_item, ett_smb2_olb);
8271 proto_tree_add_item(tag_tree, hf_smb2_olb_offset, tvb, tag_olb.off_offset, 2, ENC_LITTLE_ENDIAN);
8272 proto_tree_add_item(tag_tree, hf_smb2_olb_length, tvb, tag_olb.len_offset, 2, ENC_LITTLE_ENDIAN);
8274 } else {
8275 /* tag string */
8276 tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
8279 tag_dissectors = get_create_context_data_tag_dissectors(tag);
8281 proto_item_append_text(parent_item, " %s", tag_dissectors->val);
8282 proto_item_append_text(sub_item, ": %s \"%s\"", tag_dissectors->val, tag);
8284 /* data */
8285 dissectors = &tag_dissectors->dissectors;
8286 if (dissectors)
8287 dissector = (si->flags & SMB2_FLAGS_RESPONSE) ? dissectors->response : dissectors->request;
8289 dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
8291 if (chain_offset) {
8292 tvbuff_t *chain_tvb;
8293 chain_tvb = tvb_new_subset_remaining(tvb, chain_offset);
8295 /* next extra info */
8296 dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
8300 static int
8301 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8303 offset_length_buffer_t f_olb, e_olb;
8304 const guint8 *fname;
8306 /* buffer code */
8307 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
8309 /* security flags */
8310 offset++;
8312 /* oplock */
8313 offset = dissect_smb2_oplock(tree, tvb, offset);
8315 /* impersonation level */
8316 proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8317 offset += 4;
8319 /* create flags */
8320 proto_tree_add_item(tree, hf_smb2_create_flags, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8321 offset += 8;
8323 /* reserved */
8324 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 8, ENC_NA);
8325 offset += 8;
8327 /* access mask */
8328 offset = dissect_smb_access_mask(tvb, tree, offset);
8330 /* File Attributes */
8331 offset = dissect_file_ext_attr(tvb, tree, offset);
8333 /* share access */
8334 offset = dissect_nt_share_access(tvb, tree, offset);
8336 /* create disposition */
8337 proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8338 offset += 4;
8340 /* create options */
8341 offset = dissect_nt_create_options(tvb, tree, offset);
8343 /* filename offset/length */
8344 offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
8346 /* extrainfo offset */
8347 offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
8349 /* filename string */
8350 fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
8351 col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s",
8352 format_text(wmem_packet_scope(), fname, strlen(fname)));
8354 /* save the name if it looks sane */
8355 if (!pinfo->fd->visited) {
8356 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
8357 wmem_free(wmem_file_scope(), si->saved->extra_info);
8358 si->saved->extra_info = NULL;
8359 si->saved->extra_info_type = SMB2_EI_NONE;
8361 if (si->saved && f_olb.len < 256) {
8362 si->saved->extra_info_type = SMB2_EI_FILENAME;
8363 si->saved->extra_info = (gchar *)wmem_alloc(wmem_file_scope(), f_olb.len+1);
8364 g_snprintf((gchar *)si->saved->extra_info, f_olb.len+1, "%s", fname);
8368 /* If extrainfo_offset is non-null then this points to another
8369 * buffer. The offset is relative to the start of the smb packet
8371 dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
8373 offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
8374 offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
8376 return offset;
8379 #define SMB2_CREATE_REP_FLAGS_REPARSE_POINT 0x01
8381 static int
8382 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8384 guint64 end_of_file;
8385 guint32 attr_mask;
8386 offset_length_buffer_t e_olb;
8387 static const int *create_rep_flags_fields[] = {
8388 &hf_smb2_create_rep_flags_reparse_point,
8389 NULL
8391 gboolean continue_dissection;
8393 switch (si->status) {
8394 /* buffer code */
8395 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8396 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8397 if (!continue_dissection) return offset;
8400 /* oplock */
8401 offset = dissect_smb2_oplock(tree, tvb, offset);
8403 /* reserved */
8404 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_create_rep_flags,
8405 ett_smb2_create_rep_flags, create_rep_flags_fields, ENC_LITTLE_ENDIAN);
8406 offset += 1;
8408 /* create action */
8409 proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8410 offset += 4;
8412 /* create time */
8413 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
8415 /* last access */
8416 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
8418 /* last write */
8419 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
8421 /* last change */
8422 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
8424 /* allocation size */
8425 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8426 offset += 8;
8428 /* end of file */
8429 end_of_file = tvb_get_letoh64(tvb, offset);
8430 if (si->eo_file_info) {
8431 si->eo_file_info->end_of_file = tvb_get_letoh64(tvb, offset);
8433 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8434 offset += 8;
8436 /* File Attributes */
8437 attr_mask=tvb_get_letohl(tvb, offset);
8438 offset = dissect_file_ext_attr(tvb, tree, offset);
8440 /* reserved */
8441 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8442 offset += 4;
8444 /* fid */
8445 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
8447 /* We save this after dissect_smb2_fid just because it would be
8448 possible to have this response without having the mathing request.
8449 In that case the entry in the file info hash table has been created
8450 in dissect_smb2_fid */
8451 if (si->eo_file_info) {
8452 si->eo_file_info->end_of_file = end_of_file;
8453 si->eo_file_info->attr_mask = attr_mask;
8456 /* extrainfo offset */
8457 offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
8459 /* If extrainfo_offset is non-null then this points to another
8460 * buffer. The offset is relative to the start of the smb packet
8462 dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
8464 offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
8466 /* free si->saved->extra_info we don't need it any more */
8467 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
8468 wmem_free(wmem_file_scope(), si->saved->extra_info);
8469 si->saved->extra_info = NULL;
8470 si->saved->extra_info_type = SMB2_EI_NONE;
8473 return offset;
8477 static int
8478 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8480 guint32 setinfo_size;
8481 guint16 setinfo_offset;
8483 /* buffer code */
8484 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
8486 /* class and info level */
8487 offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
8489 /* size */
8490 setinfo_size = tvb_get_letohl(tvb, offset);
8491 proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8492 offset += 4;
8494 /* offset */
8495 setinfo_offset = tvb_get_letohs(tvb, offset);
8496 proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
8497 offset += 2;
8499 /* some unknown bytes */
8500 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
8501 offset += 6;
8503 /* fid */
8504 dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
8506 /* data */
8507 if (si->saved)
8508 dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->smb2_class, si->saved->infolevel);
8509 offset = setinfo_offset + setinfo_size;
8511 return offset;
8514 static int
8515 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8517 gboolean continue_dissection;
8518 /* class/infolevel */
8519 dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
8521 switch (si->status) {
8522 /* buffer code */
8523 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8524 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8525 if (!continue_dissection) return offset;
8528 return offset;
8531 static int
8532 dissect_smb2_break_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8534 guint16 buffer_code;
8536 /* buffer code */
8537 buffer_code = tvb_get_letohs(tvb, offset);
8538 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
8540 if (buffer_code == 24) {
8541 /* OPLOCK Break */
8543 /* oplock */
8544 offset = dissect_smb2_oplock(tree, tvb, offset);
8546 /* reserved */
8547 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
8548 offset += 1;
8550 /* reserved */
8551 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8552 offset += 4;
8554 /* fid */
8555 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
8557 return offset;
8560 if (buffer_code == 36) {
8561 /* Lease Break Acknowledgment */
8563 /* reserved */
8564 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
8565 offset +=2;
8567 /* lease flags */
8568 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
8569 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8570 offset += 4;
8572 /* lease key */
8573 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8574 offset += 16;
8576 /* lease state */
8577 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8578 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8579 offset += 4;
8581 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8582 offset += 8;
8584 return offset;
8587 return offset;
8590 static int
8591 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
8593 guint16 buffer_code;
8594 gboolean continue_dissection;
8596 /* buffer code */
8597 buffer_code = tvb_get_letohs(tvb, offset);
8598 switch (si->status) {
8599 case 0x00000000: offset = dissect_smb2_buffercode(tree, tvb, offset, NULL); break;
8600 default: offset = dissect_smb2_error_response(tvb, pinfo, tree, offset, si, &continue_dissection);
8601 if (!continue_dissection) return offset;
8604 if (buffer_code == 24) {
8605 /* OPLOCK Break Notification */
8607 /* oplock */
8608 offset = dissect_smb2_oplock(tree, tvb, offset);
8610 /* reserved */
8611 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 1, ENC_NA);
8612 offset += 1;
8614 /* reserved */
8615 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 4, ENC_NA);
8616 offset += 4;
8618 /* fid */
8619 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
8621 /* in break requests from server to client here're 24 byte zero bytes
8622 * which are likely a bug in windows (they may use 2* 24 bytes instead of just
8623 * 1 *24 bytes
8625 return offset;
8628 if (buffer_code == 44) {
8629 proto_item *item;
8631 /* Lease Break Notification */
8633 /* new lease epoch */
8634 proto_tree_add_item(tree, hf_smb2_lease_epoch, tvb, offset, 2, ENC_LITTLE_ENDIAN);
8635 offset += 2;
8637 /* lease flags */
8638 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
8639 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8640 offset += 4;
8642 /* lease key */
8643 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8644 offset += 16;
8646 /* current lease state */
8647 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8648 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8649 if (item) {
8650 proto_item_prepend_text(item, "Current ");
8652 offset += 4;
8654 /* new lease state */
8655 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8656 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8657 if (item) {
8658 proto_item_prepend_text(item, "New ");
8660 offset += 4;
8662 /* break reason - reserved */
8663 proto_tree_add_item(tree, hf_smb2_lease_break_reason, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8664 offset += 4;
8666 /* access mask hint - reserved */
8667 proto_tree_add_item(tree, hf_smb2_lease_access_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8668 offset += 4;
8670 /* share mask hint - reserved */
8671 proto_tree_add_item(tree, hf_smb2_lease_share_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8672 offset += 4;
8674 return offset;
8677 if (buffer_code == 36) {
8678 /* Lease Break Response */
8680 /* reserved */
8681 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
8682 offset +=2;
8684 /* lease flags */
8685 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
8686 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
8687 offset += 4;
8689 /* lease key */
8690 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
8691 offset += 16;
8693 /* lease state */
8694 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
8695 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
8696 offset += 4;
8698 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8699 offset += 8;
8701 return offset;
8704 return offset;
8707 /* names here are just until we find better names for these functions */
8708 static const value_string smb2_cmd_vals[] = {
8709 { 0x00, "Negotiate Protocol" },
8710 { 0x01, "Session Setup" },
8711 { 0x02, "Session Logoff" },
8712 { 0x03, "Tree Connect" },
8713 { 0x04, "Tree Disconnect" },
8714 { 0x05, "Create" },
8715 { 0x06, "Close" },
8716 { 0x07, "Flush" },
8717 { 0x08, "Read" },
8718 { 0x09, "Write" },
8719 { 0x0A, "Lock" },
8720 { 0x0B, "Ioctl" },
8721 { 0x0C, "Cancel" },
8722 { 0x0D, "KeepAlive" },
8723 { 0x0E, "Find" },
8724 { 0x0F, "Notify" },
8725 { 0x10, "GetInfo" },
8726 { 0x11, "SetInfo" },
8727 { 0x12, "Break" },
8728 { 0x13, "unknown-0x13" },
8729 { 0x14, "unknown-0x14" },
8730 { 0x15, "unknown-0x15" },
8731 { 0x16, "unknown-0x16" },
8732 { 0x17, "unknown-0x17" },
8733 { 0x18, "unknown-0x18" },
8734 { 0x19, "unknown-0x19" },
8735 { 0x1A, "unknown-0x1A" },
8736 { 0x1B, "unknown-0x1B" },
8737 { 0x1C, "unknown-0x1C" },
8738 { 0x1D, "unknown-0x1D" },
8739 { 0x1E, "unknown-0x1E" },
8740 { 0x1F, "unknown-0x1F" },
8741 { 0x20, "unknown-0x20" },
8742 { 0x21, "unknown-0x21" },
8743 { 0x22, "unknown-0x22" },
8744 { 0x23, "unknown-0x23" },
8745 { 0x24, "unknown-0x24" },
8746 { 0x25, "unknown-0x25" },
8747 { 0x26, "unknown-0x26" },
8748 { 0x27, "unknown-0x27" },
8749 { 0x28, "unknown-0x28" },
8750 { 0x29, "unknown-0x29" },
8751 { 0x2A, "unknown-0x2A" },
8752 { 0x2B, "unknown-0x2B" },
8753 { 0x2C, "unknown-0x2C" },
8754 { 0x2D, "unknown-0x2D" },
8755 { 0x2E, "unknown-0x2E" },
8756 { 0x2F, "unknown-0x2F" },
8757 { 0x30, "unknown-0x30" },
8758 { 0x31, "unknown-0x31" },
8759 { 0x32, "unknown-0x32" },
8760 { 0x33, "unknown-0x33" },
8761 { 0x34, "unknown-0x34" },
8762 { 0x35, "unknown-0x35" },
8763 { 0x36, "unknown-0x36" },
8764 { 0x37, "unknown-0x37" },
8765 { 0x38, "unknown-0x38" },
8766 { 0x39, "unknown-0x39" },
8767 { 0x3A, "unknown-0x3A" },
8768 { 0x3B, "unknown-0x3B" },
8769 { 0x3C, "unknown-0x3C" },
8770 { 0x3D, "unknown-0x3D" },
8771 { 0x3E, "unknown-0x3E" },
8772 { 0x3F, "unknown-0x3F" },
8773 { 0x40, "unknown-0x40" },
8774 { 0x41, "unknown-0x41" },
8775 { 0x42, "unknown-0x42" },
8776 { 0x43, "unknown-0x43" },
8777 { 0x44, "unknown-0x44" },
8778 { 0x45, "unknown-0x45" },
8779 { 0x46, "unknown-0x46" },
8780 { 0x47, "unknown-0x47" },
8781 { 0x48, "unknown-0x48" },
8782 { 0x49, "unknown-0x49" },
8783 { 0x4A, "unknown-0x4A" },
8784 { 0x4B, "unknown-0x4B" },
8785 { 0x4C, "unknown-0x4C" },
8786 { 0x4D, "unknown-0x4D" },
8787 { 0x4E, "unknown-0x4E" },
8788 { 0x4F, "unknown-0x4F" },
8789 { 0x50, "unknown-0x50" },
8790 { 0x51, "unknown-0x51" },
8791 { 0x52, "unknown-0x52" },
8792 { 0x53, "unknown-0x53" },
8793 { 0x54, "unknown-0x54" },
8794 { 0x55, "unknown-0x55" },
8795 { 0x56, "unknown-0x56" },
8796 { 0x57, "unknown-0x57" },
8797 { 0x58, "unknown-0x58" },
8798 { 0x59, "unknown-0x59" },
8799 { 0x5A, "unknown-0x5A" },
8800 { 0x5B, "unknown-0x5B" },
8801 { 0x5C, "unknown-0x5C" },
8802 { 0x5D, "unknown-0x5D" },
8803 { 0x5E, "unknown-0x5E" },
8804 { 0x5F, "unknown-0x5F" },
8805 { 0x60, "unknown-0x60" },
8806 { 0x61, "unknown-0x61" },
8807 { 0x62, "unknown-0x62" },
8808 { 0x63, "unknown-0x63" },
8809 { 0x64, "unknown-0x64" },
8810 { 0x65, "unknown-0x65" },
8811 { 0x66, "unknown-0x66" },
8812 { 0x67, "unknown-0x67" },
8813 { 0x68, "unknown-0x68" },
8814 { 0x69, "unknown-0x69" },
8815 { 0x6A, "unknown-0x6A" },
8816 { 0x6B, "unknown-0x6B" },
8817 { 0x6C, "unknown-0x6C" },
8818 { 0x6D, "unknown-0x6D" },
8819 { 0x6E, "unknown-0x6E" },
8820 { 0x6F, "unknown-0x6F" },
8821 { 0x70, "unknown-0x70" },
8822 { 0x71, "unknown-0x71" },
8823 { 0x72, "unknown-0x72" },
8824 { 0x73, "unknown-0x73" },
8825 { 0x74, "unknown-0x74" },
8826 { 0x75, "unknown-0x75" },
8827 { 0x76, "unknown-0x76" },
8828 { 0x77, "unknown-0x77" },
8829 { 0x78, "unknown-0x78" },
8830 { 0x79, "unknown-0x79" },
8831 { 0x7A, "unknown-0x7A" },
8832 { 0x7B, "unknown-0x7B" },
8833 { 0x7C, "unknown-0x7C" },
8834 { 0x7D, "unknown-0x7D" },
8835 { 0x7E, "unknown-0x7E" },
8836 { 0x7F, "unknown-0x7F" },
8837 { 0x80, "unknown-0x80" },
8838 { 0x81, "unknown-0x81" },
8839 { 0x82, "unknown-0x82" },
8840 { 0x83, "unknown-0x83" },
8841 { 0x84, "unknown-0x84" },
8842 { 0x85, "unknown-0x85" },
8843 { 0x86, "unknown-0x86" },
8844 { 0x87, "unknown-0x87" },
8845 { 0x88, "unknown-0x88" },
8846 { 0x89, "unknown-0x89" },
8847 { 0x8A, "unknown-0x8A" },
8848 { 0x8B, "unknown-0x8B" },
8849 { 0x8C, "unknown-0x8C" },
8850 { 0x8D, "unknown-0x8D" },
8851 { 0x8E, "unknown-0x8E" },
8852 { 0x8F, "unknown-0x8F" },
8853 { 0x90, "unknown-0x90" },
8854 { 0x91, "unknown-0x91" },
8855 { 0x92, "unknown-0x92" },
8856 { 0x93, "unknown-0x93" },
8857 { 0x94, "unknown-0x94" },
8858 { 0x95, "unknown-0x95" },
8859 { 0x96, "unknown-0x96" },
8860 { 0x97, "unknown-0x97" },
8861 { 0x98, "unknown-0x98" },
8862 { 0x99, "unknown-0x99" },
8863 { 0x9A, "unknown-0x9A" },
8864 { 0x9B, "unknown-0x9B" },
8865 { 0x9C, "unknown-0x9C" },
8866 { 0x9D, "unknown-0x9D" },
8867 { 0x9E, "unknown-0x9E" },
8868 { 0x9F, "unknown-0x9F" },
8869 { 0xA0, "unknown-0xA0" },
8870 { 0xA1, "unknown-0xA1" },
8871 { 0xA2, "unknown-0xA2" },
8872 { 0xA3, "unknown-0xA3" },
8873 { 0xA4, "unknown-0xA4" },
8874 { 0xA5, "unknown-0xA5" },
8875 { 0xA6, "unknown-0xA6" },
8876 { 0xA7, "unknown-0xA7" },
8877 { 0xA8, "unknown-0xA8" },
8878 { 0xA9, "unknown-0xA9" },
8879 { 0xAA, "unknown-0xAA" },
8880 { 0xAB, "unknown-0xAB" },
8881 { 0xAC, "unknown-0xAC" },
8882 { 0xAD, "unknown-0xAD" },
8883 { 0xAE, "unknown-0xAE" },
8884 { 0xAF, "unknown-0xAF" },
8885 { 0xB0, "unknown-0xB0" },
8886 { 0xB1, "unknown-0xB1" },
8887 { 0xB2, "unknown-0xB2" },
8888 { 0xB3, "unknown-0xB3" },
8889 { 0xB4, "unknown-0xB4" },
8890 { 0xB5, "unknown-0xB5" },
8891 { 0xB6, "unknown-0xB6" },
8892 { 0xB7, "unknown-0xB7" },
8893 { 0xB8, "unknown-0xB8" },
8894 { 0xB9, "unknown-0xB9" },
8895 { 0xBA, "unknown-0xBA" },
8896 { 0xBB, "unknown-0xBB" },
8897 { 0xBC, "unknown-0xBC" },
8898 { 0xBD, "unknown-0xBD" },
8899 { 0xBE, "unknown-0xBE" },
8900 { 0xBF, "unknown-0xBF" },
8901 { 0xC0, "unknown-0xC0" },
8902 { 0xC1, "unknown-0xC1" },
8903 { 0xC2, "unknown-0xC2" },
8904 { 0xC3, "unknown-0xC3" },
8905 { 0xC4, "unknown-0xC4" },
8906 { 0xC5, "unknown-0xC5" },
8907 { 0xC6, "unknown-0xC6" },
8908 { 0xC7, "unknown-0xC7" },
8909 { 0xC8, "unknown-0xC8" },
8910 { 0xC9, "unknown-0xC9" },
8911 { 0xCA, "unknown-0xCA" },
8912 { 0xCB, "unknown-0xCB" },
8913 { 0xCC, "unknown-0xCC" },
8914 { 0xCD, "unknown-0xCD" },
8915 { 0xCE, "unknown-0xCE" },
8916 { 0xCF, "unknown-0xCF" },
8917 { 0xD0, "unknown-0xD0" },
8918 { 0xD1, "unknown-0xD1" },
8919 { 0xD2, "unknown-0xD2" },
8920 { 0xD3, "unknown-0xD3" },
8921 { 0xD4, "unknown-0xD4" },
8922 { 0xD5, "unknown-0xD5" },
8923 { 0xD6, "unknown-0xD6" },
8924 { 0xD7, "unknown-0xD7" },
8925 { 0xD8, "unknown-0xD8" },
8926 { 0xD9, "unknown-0xD9" },
8927 { 0xDA, "unknown-0xDA" },
8928 { 0xDB, "unknown-0xDB" },
8929 { 0xDC, "unknown-0xDC" },
8930 { 0xDD, "unknown-0xDD" },
8931 { 0xDE, "unknown-0xDE" },
8932 { 0xDF, "unknown-0xDF" },
8933 { 0xE0, "unknown-0xE0" },
8934 { 0xE1, "unknown-0xE1" },
8935 { 0xE2, "unknown-0xE2" },
8936 { 0xE3, "unknown-0xE3" },
8937 { 0xE4, "unknown-0xE4" },
8938 { 0xE5, "unknown-0xE5" },
8939 { 0xE6, "unknown-0xE6" },
8940 { 0xE7, "unknown-0xE7" },
8941 { 0xE8, "unknown-0xE8" },
8942 { 0xE9, "unknown-0xE9" },
8943 { 0xEA, "unknown-0xEA" },
8944 { 0xEB, "unknown-0xEB" },
8945 { 0xEC, "unknown-0xEC" },
8946 { 0xED, "unknown-0xED" },
8947 { 0xEE, "unknown-0xEE" },
8948 { 0xEF, "unknown-0xEF" },
8949 { 0xF0, "unknown-0xF0" },
8950 { 0xF1, "unknown-0xF1" },
8951 { 0xF2, "unknown-0xF2" },
8952 { 0xF3, "unknown-0xF3" },
8953 { 0xF4, "unknown-0xF4" },
8954 { 0xF5, "unknown-0xF5" },
8955 { 0xF6, "unknown-0xF6" },
8956 { 0xF7, "unknown-0xF7" },
8957 { 0xF8, "unknown-0xF8" },
8958 { 0xF9, "unknown-0xF9" },
8959 { 0xFA, "unknown-0xFA" },
8960 { 0xFB, "unknown-0xFB" },
8961 { 0xFC, "unknown-0xFC" },
8962 { 0xFD, "unknown-0xFD" },
8963 { 0xFE, "unknown-0xFE" },
8964 { 0xFF, "unknown-0xFF" },
8965 { 0x00, NULL },
8967 value_string_ext smb2_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb2_cmd_vals);
8969 static const char *decode_smb2_name(guint16 cmd)
8971 if (cmd > 0xFF) return "unknown";
8972 return(smb2_cmd_vals[cmd & 0xFF].strptr);
8975 static smb2_function smb2_dissector[256] = {
8976 /* 0x00 NegotiateProtocol*/
8977 {dissect_smb2_negotiate_protocol_request,
8978 dissect_smb2_negotiate_protocol_response},
8979 /* 0x01 SessionSetup*/
8980 {dissect_smb2_session_setup_request,
8981 dissect_smb2_session_setup_response},
8982 /* 0x02 SessionLogoff*/
8983 {dissect_smb2_sessionlogoff_request,
8984 dissect_smb2_sessionlogoff_response},
8985 /* 0x03 TreeConnect*/
8986 {dissect_smb2_tree_connect_request,
8987 dissect_smb2_tree_connect_response},
8988 /* 0x04 TreeDisconnect*/
8989 {dissect_smb2_tree_disconnect_request,
8990 dissect_smb2_tree_disconnect_response},
8991 /* 0x05 Create*/
8992 {dissect_smb2_create_request,
8993 dissect_smb2_create_response},
8994 /* 0x06 Close*/
8995 {dissect_smb2_close_request,
8996 dissect_smb2_close_response},
8997 /* 0x07 Flush*/
8998 {dissect_smb2_flush_request,
8999 dissect_smb2_flush_response},
9000 /* 0x08 Read*/
9001 {dissect_smb2_read_request,
9002 dissect_smb2_read_response},
9003 /* 0x09 Writew*/
9004 {dissect_smb2_write_request,
9005 dissect_smb2_write_response},
9006 /* 0x0a Lock */
9007 {dissect_smb2_lock_request,
9008 dissect_smb2_lock_response},
9009 /* 0x0b Ioctl*/
9010 {dissect_smb2_ioctl_request,
9011 dissect_smb2_ioctl_response},
9012 /* 0x0c Cancel*/
9013 {dissect_smb2_cancel_request,
9014 NULL},
9015 /* 0x0d KeepAlive*/
9016 {dissect_smb2_keepalive_request,
9017 dissect_smb2_keepalive_response},
9018 /* 0x0e Find*/
9019 {dissect_smb2_find_request,
9020 dissect_smb2_find_response},
9021 /* 0x0f Notify*/
9022 {dissect_smb2_notify_request,
9023 dissect_smb2_notify_response},
9024 /* 0x10 GetInfo*/
9025 {dissect_smb2_getinfo_request,
9026 dissect_smb2_getinfo_response},
9027 /* 0x11 SetInfo*/
9028 {dissect_smb2_setinfo_request,
9029 dissect_smb2_setinfo_response},
9030 /* 0x12 Break */
9031 {dissect_smb2_break_request,
9032 dissect_smb2_break_response},
9033 /* 0x13 */ {NULL, NULL},
9034 /* 0x14 */ {NULL, NULL},
9035 /* 0x15 */ {NULL, NULL},
9036 /* 0x16 */ {NULL, NULL},
9037 /* 0x17 */ {NULL, NULL},
9038 /* 0x18 */ {NULL, NULL},
9039 /* 0x19 */ {NULL, NULL},
9040 /* 0x1a */ {NULL, NULL},
9041 /* 0x1b */ {NULL, NULL},
9042 /* 0x1c */ {NULL, NULL},
9043 /* 0x1d */ {NULL, NULL},
9044 /* 0x1e */ {NULL, NULL},
9045 /* 0x1f */ {NULL, NULL},
9046 /* 0x20 */ {NULL, NULL},
9047 /* 0x21 */ {NULL, NULL},
9048 /* 0x22 */ {NULL, NULL},
9049 /* 0x23 */ {NULL, NULL},
9050 /* 0x24 */ {NULL, NULL},
9051 /* 0x25 */ {NULL, NULL},
9052 /* 0x26 */ {NULL, NULL},
9053 /* 0x27 */ {NULL, NULL},
9054 /* 0x28 */ {NULL, NULL},
9055 /* 0x29 */ {NULL, NULL},
9056 /* 0x2a */ {NULL, NULL},
9057 /* 0x2b */ {NULL, NULL},
9058 /* 0x2c */ {NULL, NULL},
9059 /* 0x2d */ {NULL, NULL},
9060 /* 0x2e */ {NULL, NULL},
9061 /* 0x2f */ {NULL, NULL},
9062 /* 0x30 */ {NULL, NULL},
9063 /* 0x31 */ {NULL, NULL},
9064 /* 0x32 */ {NULL, NULL},
9065 /* 0x33 */ {NULL, NULL},
9066 /* 0x34 */ {NULL, NULL},
9067 /* 0x35 */ {NULL, NULL},
9068 /* 0x36 */ {NULL, NULL},
9069 /* 0x37 */ {NULL, NULL},
9070 /* 0x38 */ {NULL, NULL},
9071 /* 0x39 */ {NULL, NULL},
9072 /* 0x3a */ {NULL, NULL},
9073 /* 0x3b */ {NULL, NULL},
9074 /* 0x3c */ {NULL, NULL},
9075 /* 0x3d */ {NULL, NULL},
9076 /* 0x3e */ {NULL, NULL},
9077 /* 0x3f */ {NULL, NULL},
9078 /* 0x40 */ {NULL, NULL},
9079 /* 0x41 */ {NULL, NULL},
9080 /* 0x42 */ {NULL, NULL},
9081 /* 0x43 */ {NULL, NULL},
9082 /* 0x44 */ {NULL, NULL},
9083 /* 0x45 */ {NULL, NULL},
9084 /* 0x46 */ {NULL, NULL},
9085 /* 0x47 */ {NULL, NULL},
9086 /* 0x48 */ {NULL, NULL},
9087 /* 0x49 */ {NULL, NULL},
9088 /* 0x4a */ {NULL, NULL},
9089 /* 0x4b */ {NULL, NULL},
9090 /* 0x4c */ {NULL, NULL},
9091 /* 0x4d */ {NULL, NULL},
9092 /* 0x4e */ {NULL, NULL},
9093 /* 0x4f */ {NULL, NULL},
9094 /* 0x50 */ {NULL, NULL},
9095 /* 0x51 */ {NULL, NULL},
9096 /* 0x52 */ {NULL, NULL},
9097 /* 0x53 */ {NULL, NULL},
9098 /* 0x54 */ {NULL, NULL},
9099 /* 0x55 */ {NULL, NULL},
9100 /* 0x56 */ {NULL, NULL},
9101 /* 0x57 */ {NULL, NULL},
9102 /* 0x58 */ {NULL, NULL},
9103 /* 0x59 */ {NULL, NULL},
9104 /* 0x5a */ {NULL, NULL},
9105 /* 0x5b */ {NULL, NULL},
9106 /* 0x5c */ {NULL, NULL},
9107 /* 0x5d */ {NULL, NULL},
9108 /* 0x5e */ {NULL, NULL},
9109 /* 0x5f */ {NULL, NULL},
9110 /* 0x60 */ {NULL, NULL},
9111 /* 0x61 */ {NULL, NULL},
9112 /* 0x62 */ {NULL, NULL},
9113 /* 0x63 */ {NULL, NULL},
9114 /* 0x64 */ {NULL, NULL},
9115 /* 0x65 */ {NULL, NULL},
9116 /* 0x66 */ {NULL, NULL},
9117 /* 0x67 */ {NULL, NULL},
9118 /* 0x68 */ {NULL, NULL},
9119 /* 0x69 */ {NULL, NULL},
9120 /* 0x6a */ {NULL, NULL},
9121 /* 0x6b */ {NULL, NULL},
9122 /* 0x6c */ {NULL, NULL},
9123 /* 0x6d */ {NULL, NULL},
9124 /* 0x6e */ {NULL, NULL},
9125 /* 0x6f */ {NULL, NULL},
9126 /* 0x70 */ {NULL, NULL},
9127 /* 0x71 */ {NULL, NULL},
9128 /* 0x72 */ {NULL, NULL},
9129 /* 0x73 */ {NULL, NULL},
9130 /* 0x74 */ {NULL, NULL},
9131 /* 0x75 */ {NULL, NULL},
9132 /* 0x76 */ {NULL, NULL},
9133 /* 0x77 */ {NULL, NULL},
9134 /* 0x78 */ {NULL, NULL},
9135 /* 0x79 */ {NULL, NULL},
9136 /* 0x7a */ {NULL, NULL},
9137 /* 0x7b */ {NULL, NULL},
9138 /* 0x7c */ {NULL, NULL},
9139 /* 0x7d */ {NULL, NULL},
9140 /* 0x7e */ {NULL, NULL},
9141 /* 0x7f */ {NULL, NULL},
9142 /* 0x80 */ {NULL, NULL},
9143 /* 0x81 */ {NULL, NULL},
9144 /* 0x82 */ {NULL, NULL},
9145 /* 0x83 */ {NULL, NULL},
9146 /* 0x84 */ {NULL, NULL},
9147 /* 0x85 */ {NULL, NULL},
9148 /* 0x86 */ {NULL, NULL},
9149 /* 0x87 */ {NULL, NULL},
9150 /* 0x88 */ {NULL, NULL},
9151 /* 0x89 */ {NULL, NULL},
9152 /* 0x8a */ {NULL, NULL},
9153 /* 0x8b */ {NULL, NULL},
9154 /* 0x8c */ {NULL, NULL},
9155 /* 0x8d */ {NULL, NULL},
9156 /* 0x8e */ {NULL, NULL},
9157 /* 0x8f */ {NULL, NULL},
9158 /* 0x90 */ {NULL, NULL},
9159 /* 0x91 */ {NULL, NULL},
9160 /* 0x92 */ {NULL, NULL},
9161 /* 0x93 */ {NULL, NULL},
9162 /* 0x94 */ {NULL, NULL},
9163 /* 0x95 */ {NULL, NULL},
9164 /* 0x96 */ {NULL, NULL},
9165 /* 0x97 */ {NULL, NULL},
9166 /* 0x98 */ {NULL, NULL},
9167 /* 0x99 */ {NULL, NULL},
9168 /* 0x9a */ {NULL, NULL},
9169 /* 0x9b */ {NULL, NULL},
9170 /* 0x9c */ {NULL, NULL},
9171 /* 0x9d */ {NULL, NULL},
9172 /* 0x9e */ {NULL, NULL},
9173 /* 0x9f */ {NULL, NULL},
9174 /* 0xa0 */ {NULL, NULL},
9175 /* 0xa1 */ {NULL, NULL},
9176 /* 0xa2 */ {NULL, NULL},
9177 /* 0xa3 */ {NULL, NULL},
9178 /* 0xa4 */ {NULL, NULL},
9179 /* 0xa5 */ {NULL, NULL},
9180 /* 0xa6 */ {NULL, NULL},
9181 /* 0xa7 */ {NULL, NULL},
9182 /* 0xa8 */ {NULL, NULL},
9183 /* 0xa9 */ {NULL, NULL},
9184 /* 0xaa */ {NULL, NULL},
9185 /* 0xab */ {NULL, NULL},
9186 /* 0xac */ {NULL, NULL},
9187 /* 0xad */ {NULL, NULL},
9188 /* 0xae */ {NULL, NULL},
9189 /* 0xaf */ {NULL, NULL},
9190 /* 0xb0 */ {NULL, NULL},
9191 /* 0xb1 */ {NULL, NULL},
9192 /* 0xb2 */ {NULL, NULL},
9193 /* 0xb3 */ {NULL, NULL},
9194 /* 0xb4 */ {NULL, NULL},
9195 /* 0xb5 */ {NULL, NULL},
9196 /* 0xb6 */ {NULL, NULL},
9197 /* 0xb7 */ {NULL, NULL},
9198 /* 0xb8 */ {NULL, NULL},
9199 /* 0xb9 */ {NULL, NULL},
9200 /* 0xba */ {NULL, NULL},
9201 /* 0xbb */ {NULL, NULL},
9202 /* 0xbc */ {NULL, NULL},
9203 /* 0xbd */ {NULL, NULL},
9204 /* 0xbe */ {NULL, NULL},
9205 /* 0xbf */ {NULL, NULL},
9206 /* 0xc0 */ {NULL, NULL},
9207 /* 0xc1 */ {NULL, NULL},
9208 /* 0xc2 */ {NULL, NULL},
9209 /* 0xc3 */ {NULL, NULL},
9210 /* 0xc4 */ {NULL, NULL},
9211 /* 0xc5 */ {NULL, NULL},
9212 /* 0xc6 */ {NULL, NULL},
9213 /* 0xc7 */ {NULL, NULL},
9214 /* 0xc8 */ {NULL, NULL},
9215 /* 0xc9 */ {NULL, NULL},
9216 /* 0xca */ {NULL, NULL},
9217 /* 0xcb */ {NULL, NULL},
9218 /* 0xcc */ {NULL, NULL},
9219 /* 0xcd */ {NULL, NULL},
9220 /* 0xce */ {NULL, NULL},
9221 /* 0xcf */ {NULL, NULL},
9222 /* 0xd0 */ {NULL, NULL},
9223 /* 0xd1 */ {NULL, NULL},
9224 /* 0xd2 */ {NULL, NULL},
9225 /* 0xd3 */ {NULL, NULL},
9226 /* 0xd4 */ {NULL, NULL},
9227 /* 0xd5 */ {NULL, NULL},
9228 /* 0xd6 */ {NULL, NULL},
9229 /* 0xd7 */ {NULL, NULL},
9230 /* 0xd8 */ {NULL, NULL},
9231 /* 0xd9 */ {NULL, NULL},
9232 /* 0xda */ {NULL, NULL},
9233 /* 0xdb */ {NULL, NULL},
9234 /* 0xdc */ {NULL, NULL},
9235 /* 0xdd */ {NULL, NULL},
9236 /* 0xde */ {NULL, NULL},
9237 /* 0xdf */ {NULL, NULL},
9238 /* 0xe0 */ {NULL, NULL},
9239 /* 0xe1 */ {NULL, NULL},
9240 /* 0xe2 */ {NULL, NULL},
9241 /* 0xe3 */ {NULL, NULL},
9242 /* 0xe4 */ {NULL, NULL},
9243 /* 0xe5 */ {NULL, NULL},
9244 /* 0xe6 */ {NULL, NULL},
9245 /* 0xe7 */ {NULL, NULL},
9246 /* 0xe8 */ {NULL, NULL},
9247 /* 0xe9 */ {NULL, NULL},
9248 /* 0xea */ {NULL, NULL},
9249 /* 0xeb */ {NULL, NULL},
9250 /* 0xec */ {NULL, NULL},
9251 /* 0xed */ {NULL, NULL},
9252 /* 0xee */ {NULL, NULL},
9253 /* 0xef */ {NULL, NULL},
9254 /* 0xf0 */ {NULL, NULL},
9255 /* 0xf1 */ {NULL, NULL},
9256 /* 0xf2 */ {NULL, NULL},
9257 /* 0xf3 */ {NULL, NULL},
9258 /* 0xf4 */ {NULL, NULL},
9259 /* 0xf5 */ {NULL, NULL},
9260 /* 0xf6 */ {NULL, NULL},
9261 /* 0xf7 */ {NULL, NULL},
9262 /* 0xf8 */ {NULL, NULL},
9263 /* 0xf9 */ {NULL, NULL},
9264 /* 0xfa */ {NULL, NULL},
9265 /* 0xfb */ {NULL, NULL},
9266 /* 0xfc */ {NULL, NULL},
9267 /* 0xfd */ {NULL, NULL},
9268 /* 0xfe */ {NULL, NULL},
9269 /* 0xff */ {NULL, NULL},
9273 #define SMB3_AES128CCM_NONCE 11
9274 #define SMB3_AES128GCM_NONCE 12
9276 #if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
9277 static guint8*
9278 decrypt_smb_payload(packet_info *pinfo,
9279 tvbuff_t *tvb, int offset,
9280 int offset_aad,
9281 smb2_transform_info_t *sti)
9283 gcry_error_t err;
9284 gcry_cipher_hd_t cipher_hd = NULL;
9285 const guint8 *aad = NULL;
9286 guint8 *data = NULL;
9287 guint8 *key = NULL;
9288 int mode;
9289 int iv_size;
9290 int aad_size;
9291 guint64 lengths[3];
9293 /* AAD is the rest of transform header after the ProtocolID and Signature */
9294 aad_size = 32;
9296 if ((unsigned)tvb_captured_length_remaining(tvb, offset) < sti->size)
9297 return NULL;
9299 if (tvb_captured_length_remaining(tvb, offset_aad) < aad_size)
9300 return NULL;
9302 if (pinfo->destport == sti->session->server_port)
9303 key = sti->session->server_decryption_key;
9304 else
9305 key = sti->session->client_decryption_key;
9307 if (memcmp(key, zeros, NTLMSSP_KEY_LEN) == 0)
9308 key = NULL;
9310 if (!key)
9311 return NULL;
9314 * In SMB3.0 the transform header had a Algorithm field to
9315 * know which type of encryption was used but only CCM was
9316 * supported.
9318 * SMB3.1.1 turned that field into a generic "Encrypted" flag
9319 * which cannot be used to determine the encryption
9320 * type. Instead the type is decided in the NegProt response,
9321 * within the Encryption Capability context which should only
9322 * have one element. That element is saved in the conversation
9323 * struct (si->conv) and checked here.
9326 /* g_warning("dialect 0x%x alg 0x%x conv alg 0x%x", sti->conv->dialect, sti->alg, sti->conv->enc_alg); */
9328 if (sti->conv->dialect == 0x300) {
9329 /* If we are decrypting in SMB3.0, it must be CCM */
9330 sti->conv->enc_alg = SMB2_CIPHER_AES_128_CCM;
9333 switch (sti->conv->enc_alg) {
9334 case SMB2_CIPHER_AES_128_CCM:
9335 mode = GCRY_CIPHER_MODE_CCM;
9336 iv_size = SMB3_AES128CCM_NONCE;
9337 break;
9338 case SMB2_CIPHER_AES_128_GCM:
9339 mode = GCRY_CIPHER_MODE_GCM;
9340 iv_size = SMB3_AES128GCM_NONCE;
9341 break;
9342 default:
9343 return NULL;
9346 /* Open the cipher */
9347 if ((err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, mode, 0))) {
9348 /* g_warning("GCRY: open %s/%s\n", gcry_strsource(err), gcry_strerror(err)); */
9349 return NULL;
9352 /* Set the key */
9353 if ((err = gcry_cipher_setkey(cipher_hd, key, NTLMSSP_KEY_LEN))) {
9354 /* g_warning("GCRY: setkey %s/%s\n", gcry_strsource(err), gcry_strerror(err)); */
9355 gcry_cipher_close(cipher_hd);
9356 return NULL;
9359 /* Set the initial value */
9360 if ((err = gcry_cipher_setiv(cipher_hd, sti->nonce, iv_size))) {
9361 /* g_warning("GCRY: setiv %s/%s\n", gcry_strsource(err), gcry_strerror(err)); */
9362 gcry_cipher_close(cipher_hd);
9363 return NULL;
9366 aad = tvb_get_ptr(tvb, offset_aad, aad_size);
9368 lengths[0] = sti->size; /* encrypted length */
9369 lengths[1] = aad_size; /* AAD length */
9370 lengths[2] = 16; /* tag length (signature size) */
9372 if (mode == GCRY_CIPHER_MODE_CCM) {
9373 if ((err = gcry_cipher_ctl(cipher_hd, GCRYCTL_SET_CCM_LENGTHS, lengths, sizeof(lengths)))) {
9374 /* g_warning("GCRY: ctl %s/%s\n", gcry_strsource(err), gcry_strerror(err)); */
9375 gcry_cipher_close(cipher_hd);
9376 return NULL;
9380 if ((err = gcry_cipher_authenticate(cipher_hd, aad, aad_size))) {
9381 /* g_warning("GCRY: auth %s/%s\n", gcry_strsource(err), gcry_strerror(err)); */
9382 gcry_cipher_close(cipher_hd);
9383 return NULL;
9386 data = (guint8 *)tvb_memdup(pinfo->pool, tvb, offset, sti->size);
9388 if ((err = gcry_cipher_decrypt(cipher_hd, data, sti->size, NULL, 0))) {
9389 /* g_warning("GCRY: decrypt %s/%s\n", gcry_strsource(err), gcry_strerror(err)); */
9390 gcry_cipher_close(cipher_hd);
9391 return NULL;
9394 /* Done with the cipher */
9395 gcry_cipher_close(cipher_hd);
9396 return data;
9398 #endif
9400 static int
9401 dissect_smb2_transform_header(packet_info *pinfo, proto_tree *tree,
9402 tvbuff_t *tvb, int offset,
9403 smb2_transform_info_t *sti,
9404 tvbuff_t **enc_tvb, tvbuff_t **plain_tvb)
9406 proto_item *sesid_item = NULL;
9407 proto_tree *sesid_tree = NULL;
9408 int sesid_offset;
9409 guint8 *plain_data = NULL;
9410 int offset_aad;
9412 *enc_tvb = NULL;
9413 *plain_tvb = NULL;
9415 /* signature */
9416 proto_tree_add_item(tree, hf_smb2_transform_signature, tvb, offset, 16, ENC_NA);
9417 offset += 16;
9419 offset_aad = offset;
9421 /* nonce */
9422 proto_tree_add_item(tree, hf_smb2_transform_nonce, tvb, offset, 16, ENC_NA);
9423 tvb_memcpy(tvb, sti->nonce, offset, 16);
9424 offset += 16;
9426 /* size */
9427 proto_tree_add_item(tree, hf_smb2_transform_msg_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9428 sti->size = tvb_get_letohl(tvb, offset);
9429 offset += 4;
9431 /* reserved */
9432 proto_tree_add_item(tree, hf_smb2_transform_reserved, tvb, offset, 2, ENC_NA);
9433 offset += 2;
9435 /* enc algorithm */
9436 proto_tree_add_item(tree, hf_smb2_transform_enc_alg, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9437 sti->alg = tvb_get_letohs(tvb, offset);
9438 offset += 2;
9440 /* session ID */
9441 sesid_offset = offset;
9442 sti->sesid = tvb_get_letoh64(tvb, offset);
9443 sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9444 sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
9445 offset += 8;
9447 /* now we need to first lookup the uid session */
9448 sti->session = smb2_get_session(sti->conv, sti->sesid, NULL, NULL);
9449 smb2_add_session_info(sesid_tree, tvb, sesid_offset, sti->session);
9451 #if GCRYPT_VERSION_NUMBER >= 0x010600 /* 1.6.0 */
9452 plain_data = decrypt_smb_payload(pinfo, tvb, offset, offset_aad, sti);
9453 #else
9454 (void) offset_aad;
9455 #endif
9456 *enc_tvb = tvb_new_subset_length(tvb, offset, sti->size);
9458 if (plain_data != NULL) {
9459 *plain_tvb = tvb_new_child_real_data(*enc_tvb, plain_data, sti->size, sti->size);
9460 add_new_data_source(pinfo, *plain_tvb, "Decrypted SMB3");
9463 offset += sti->size;
9464 return offset;
9467 static int
9468 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
9470 int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
9471 proto_item *cmd_item;
9472 proto_tree *cmd_tree;
9473 int old_offset = offset;
9475 cmd_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
9476 ett_smb2_command, &cmd_item, "%s %s (0x%02x)",
9477 decode_smb2_name(si->opcode),
9478 (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
9479 si->opcode);
9481 cmd_dissector = (si->flags & SMB2_FLAGS_RESPONSE)?
9482 smb2_dissector[si->opcode&0xff].response:
9483 smb2_dissector[si->opcode&0xff].request;
9484 if (cmd_dissector) {
9485 offset = (*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
9486 } else {
9487 proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, ENC_NA);
9488 offset = tvb_captured_length(tvb);
9491 proto_item_set_len(cmd_item, offset-old_offset);
9493 return offset;
9496 static int
9497 dissect_smb2_tid_sesid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
9499 proto_item *tid_item = NULL;
9500 proto_tree *tid_tree = NULL;
9501 smb2_tid_info_t tid_key;
9502 int tid_offset = 0;
9503 proto_item *sesid_item = NULL;
9504 proto_tree *sesid_tree = NULL;
9505 smb2_sesid_info_t sesid_key;
9506 int sesid_offset;
9507 proto_item *item;
9510 if (si->flags&SMB2_FLAGS_ASYNC_CMD) {
9511 proto_tree_add_item(tree, hf_smb2_aid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9512 offset += 8;
9513 } else {
9514 /* Process ID */
9515 proto_tree_add_item(tree, hf_smb2_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9516 offset += 4;
9518 /* Tree ID */
9519 tid_offset = offset;
9520 si->tid = tvb_get_letohl(tvb, offset);
9521 tid_item = proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9522 tid_tree = proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
9523 offset += 4;
9526 /* Session ID */
9527 sesid_offset = offset;
9528 si->sesid = tvb_get_letoh64(tvb, offset);
9529 sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9530 sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
9531 offset += 8;
9533 /* now we need to first lookup the uid session */
9534 sesid_key.sesid = si->sesid;
9535 si->session = (smb2_sesid_info_t *)g_hash_table_lookup(si->conv->sesids, &sesid_key);
9536 if (!si->session) {
9537 if (si->opcode != SMB2_COM_TREE_CONNECT)
9538 return offset;
9540 /* if we come to a session that is unknown, and the operation is
9541 * a tree connect, we create a dummy session, so we can hang the
9542 * tree data on it
9544 si->session = smb2_get_session(si->conv, si->sesid, pinfo, si);
9545 return offset;
9548 smb2_add_session_info(sesid_tree, tvb, sesid_offset, si->session);
9550 if (!(si->flags&SMB2_FLAGS_ASYNC_CMD)) {
9551 /* see if we can find the name for this tid */
9552 tid_key.tid = si->tid;
9553 si->tree = (smb2_tid_info_t *)wmem_map_lookup(si->session->tids, &tid_key);
9554 if (!si->tree) return offset;
9556 item = proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
9557 proto_item_set_generated(item);
9558 proto_item_append_text(tid_item, " %s", si->tree->name);
9560 item = proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
9561 proto_item_set_generated(item);
9563 item = proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
9564 proto_item_set_generated(item);
9567 return offset;
9570 static int
9571 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
9573 gboolean smb2_transform_header = FALSE;
9574 proto_item *item = NULL;
9575 proto_tree *tree = NULL;
9576 proto_item *header_item = NULL;
9577 proto_tree *header_tree = NULL;
9578 int offset = 0;
9579 int chain_offset = 0;
9580 const char *label = smb_header_label;
9581 conversation_t *conversation;
9582 smb2_saved_info_t *ssi = NULL, ssi_key;
9583 smb2_info_t *si;
9584 smb2_transform_info_t *sti;
9585 char *fid_name;
9586 guint32 open_frame,close_frame;
9587 smb2_eo_file_info_t *eo_file_info;
9588 e_ctx_hnd *policy_hnd_hashtablekey;
9590 sti = wmem_new(wmem_packet_scope(), smb2_transform_info_t);
9591 si = wmem_new0(wmem_packet_scope(), smb2_info_t);
9592 si->top_tree = parent_tree;
9594 if (tvb_get_guint8(tvb, 0) == 0xfd) {
9595 smb2_transform_header = TRUE;
9596 label = smb_transform_header_label;
9598 /* find which conversation we are part of and get the data for that
9599 * conversation
9601 conversation = find_or_create_conversation(pinfo);
9602 si->conv = (smb2_conv_info_t *)conversation_get_proto_data(conversation, proto_smb2);
9603 if (!si->conv) {
9604 /* no smb2_into_t structure for this conversation yet,
9605 * create it.
9607 si->conv = wmem_new0(wmem_file_scope(), smb2_conv_info_t);
9608 /* qqq this leaks memory for now since we never free
9609 the hashtables */
9610 si->conv->matched = g_hash_table_new(smb2_saved_info_hash_matched,
9611 smb2_saved_info_equal_matched);
9612 si->conv->unmatched = g_hash_table_new(smb2_saved_info_hash_unmatched,
9613 smb2_saved_info_equal_unmatched);
9614 si->conv->sesids = g_hash_table_new(smb2_sesid_info_hash,
9615 smb2_sesid_info_equal);
9616 si->conv->fids = g_hash_table_new(smb2_fid_info_hash,
9617 smb2_fid_info_equal);
9618 si->conv->files = g_hash_table_new(smb2_eo_files_hash,smb2_eo_files_equal);
9619 si->conv->preauth_hash_current = si->conv->preauth_hash_con;
9621 /* Bit of a hack to avoid leaking the hash tables - register a
9622 * callback to free them. Ideally wmem would implement a simple
9623 * hash table so we wouldn't have to do this. */
9624 wmem_register_callback(wmem_file_scope(), smb2_conv_destroy,
9625 si->conv);
9627 conversation_add_proto_data(conversation, proto_smb2, si->conv);
9630 sti->conv = si->conv;
9632 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
9633 if (first_in_chain) {
9634 /* first packet */
9635 col_clear(pinfo->cinfo, COL_INFO);
9636 } else {
9637 col_append_str(pinfo->cinfo, COL_INFO, ";");
9640 item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset, -1, ENC_NA);
9641 tree = proto_item_add_subtree(item, ett_smb2);
9643 header_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb2_header, &header_item, label);
9645 /* Decode the header */
9647 if (!smb2_transform_header) {
9648 /* SMB2 marker */
9649 proto_tree_add_item(header_tree, hf_smb2_server_component_smb2, tvb, offset, 4, ENC_NA);
9650 offset += 4;
9652 /* we need the flags before we know how to parse the credits field */
9653 si->flags = tvb_get_letohl(tvb, offset+12);
9655 /* header length */
9656 proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9657 offset += 2;
9659 /* credit charge (previously "epoch" (unused) which has been deprecated as of "SMB 2.1") */
9660 proto_tree_add_item(header_tree, hf_smb2_credit_charge, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9661 offset += 2;
9663 /* Status Code */
9664 if (si->flags & SMB2_FLAGS_RESPONSE) {
9665 si->status = tvb_get_letohl(tvb, offset);
9666 proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9667 offset += 4;
9668 } else {
9669 si->status = 0;
9670 proto_tree_add_item(header_tree, hf_smb2_channel_sequence, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9671 offset += 2;
9672 proto_tree_add_item(header_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
9673 offset += 2;
9676 /* opcode */
9677 si->opcode = tvb_get_letohs(tvb, offset);
9678 proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9679 offset += 2;
9681 /* credits */
9682 if (si->flags & SMB2_FLAGS_RESPONSE) {
9683 proto_tree_add_item(header_tree, hf_smb2_credits_granted, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9684 } else {
9685 proto_tree_add_item(header_tree, hf_smb2_credits_requested, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9687 offset += 2;
9689 /* flags */
9690 if (header_tree) {
9691 static const int * flags[] = {
9692 &hf_smb2_flags_response,
9693 &hf_smb2_flags_async_cmd,
9694 &hf_smb2_flags_chained,
9695 &hf_smb2_flags_signature,
9696 &hf_smb2_flags_priority_mask,
9697 &hf_smb2_flags_dfs_op,
9698 &hf_smb2_flags_replay_operation,
9699 NULL
9702 proto_tree_add_bitmask(header_tree, tvb, offset, hf_smb2_flags,
9703 ett_smb2_flags, flags, ENC_LITTLE_ENDIAN);
9706 offset += 4;
9708 /* Next Command */
9709 chain_offset = tvb_get_letohl(tvb, offset);
9710 proto_tree_add_item(header_tree, hf_smb2_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9711 offset += 4;
9713 /* Message ID */
9714 si->msg_id = tvb_get_letoh64(tvb, offset);
9715 ssi_key.msg_id = si->msg_id;
9716 proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9717 offset += 8;
9719 /* Tree ID and Session ID */
9720 offset = dissect_smb2_tid_sesid(pinfo, header_tree, tvb, offset, si);
9722 /* Signature */
9723 proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, ENC_NA);
9724 offset += 16;
9726 proto_item_set_len(header_item, offset);
9729 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
9730 decode_smb2_name(si->opcode),
9731 (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
9732 if (si->status) {
9733 col_append_fstr(
9734 pinfo->cinfo, COL_INFO, ", Error: %s",
9735 val_to_str_ext(si->status, &NT_errors_ext,
9736 "Unknown (0x%08X)"));
9740 if (!pinfo->fd->visited) {
9741 /* see if we can find this msg_id in the unmatched table */
9742 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
9744 if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
9745 /* This is a request */
9746 if (ssi) {
9747 /* this is a request and we already found
9748 * an older ssi so just delete the previous
9749 * one
9751 g_hash_table_remove(si->conv->unmatched, ssi);
9752 ssi = NULL;
9755 if (!ssi) {
9756 /* no we couldn't find it, so just add it then
9757 * if was a request we are decoding
9759 ssi = wmem_new0(wmem_file_scope(), smb2_saved_info_t);
9760 ssi->msg_id = ssi_key.msg_id;
9761 ssi->frame_req = pinfo->num;
9762 ssi->req_time = pinfo->abs_ts;
9763 ssi->extra_info_type = SMB2_EI_NONE;
9764 g_hash_table_insert(si->conv->unmatched, ssi, ssi);
9766 } else {
9767 /* This is a response */
9768 if (!((si->flags & SMB2_FLAGS_ASYNC_CMD)
9769 && si->status == NT_STATUS_PENDING)
9770 && ssi) {
9771 /* just set the response frame and move it to the matched table */
9772 ssi->frame_res = pinfo->num;
9773 g_hash_table_remove(si->conv->unmatched, ssi);
9774 g_hash_table_insert(si->conv->matched, ssi, ssi);
9777 } else {
9778 /* see if we can find this msg_id in the matched table */
9779 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->matched, &ssi_key);
9780 /* if we couldn't find it in the matched table, it might still
9781 * be in the unmatched table
9783 if (!ssi) {
9784 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
9788 if (ssi) {
9789 if (dcerpc_fetch_polhnd_data(&ssi->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->num)) {
9790 /* If needed, create the file entry and save the policy hnd */
9791 if (!si->eo_file_info) {
9792 if (si->conv) {
9793 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&ssi->policy_hnd);
9794 if (!eo_file_info) { /* XXX This should never happen */
9795 /* assert(1==0); */
9796 eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
9797 policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
9798 memcpy(policy_hnd_hashtablekey, &ssi->policy_hnd, sizeof(e_ctx_hnd));
9799 eo_file_info->end_of_file=0;
9800 g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
9802 si->eo_file_info=eo_file_info;
9807 if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
9808 if (ssi->frame_res) {
9809 proto_item *tmp_item;
9810 tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
9811 proto_item_set_generated(tmp_item);
9813 } else {
9814 if (ssi->frame_req) {
9815 proto_item *tmp_item;
9816 nstime_t t, deltat;
9818 tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
9819 proto_item_set_generated(tmp_item);
9820 t = pinfo->abs_ts;
9821 nstime_delta(&deltat, &t, &ssi->req_time);
9822 tmp_item = proto_tree_add_time(header_tree, hf_smb2_time, tvb,
9823 0, 0, &deltat);
9824 proto_item_set_generated(tmp_item);
9827 if (si->file != NULL) {
9828 ssi->file = si->file;
9829 } else {
9830 si->file = ssi->file;
9833 /* if we don't have ssi yet we must fake it */
9834 /*qqq*/
9835 si->saved = ssi;
9837 tap_queue_packet(smb2_tap, pinfo, si);
9839 /* Decode the payload */
9840 offset = dissect_smb2_command(pinfo, tree, tvb, offset, si);
9841 } else {
9842 proto_tree *enc_tree;
9843 tvbuff_t *enc_tvb = NULL;
9844 tvbuff_t *plain_tvb = NULL;
9846 /* SMB2_TRANSFORM marker */
9847 proto_tree_add_item(header_tree, hf_smb2_server_component_smb2_transform, tvb, offset, 4, ENC_NA);
9848 offset += 4;
9850 offset = dissect_smb2_transform_header(pinfo, header_tree, tvb, offset, sti,
9851 &enc_tvb, &plain_tvb);
9853 enc_tree = proto_tree_add_subtree(tree, enc_tvb, 0, sti->size, ett_smb2_encrypted, NULL, "Encrypted SMB3 data");
9854 if (plain_tvb != NULL) {
9855 col_append_str(pinfo->cinfo, COL_INFO, "Decrypted SMB3");
9856 dissect_smb2(plain_tvb, pinfo, enc_tree, FALSE);
9857 } else {
9858 col_append_str(pinfo->cinfo, COL_INFO, "Encrypted SMB3");
9859 proto_tree_add_item(enc_tree, hf_smb2_transform_encrypted_data,
9860 enc_tvb, 0, sti->size, ENC_NA);
9863 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9864 chain_offset = offset;
9868 if (chain_offset > 0) {
9869 tvbuff_t *next_tvb;
9871 proto_item_set_len(item, chain_offset);
9873 next_tvb = tvb_new_subset_remaining(tvb, chain_offset);
9874 offset = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
9877 return offset;
9880 static gboolean
9881 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
9884 /* must check that this really is a smb2 packet */
9885 if (tvb_captured_length(tvb) < 4)
9886 return FALSE;
9888 if (((tvb_get_guint8(tvb, 0) != 0xfe) && (tvb_get_guint8(tvb, 0) != 0xfd))
9889 || (tvb_get_guint8(tvb, 1) != 'S')
9890 || (tvb_get_guint8(tvb, 2) != 'M')
9891 || (tvb_get_guint8(tvb, 3) != 'B') ) {
9892 return FALSE;
9895 dissect_smb2(tvb, pinfo, parent_tree, TRUE);
9897 return TRUE;
9900 void
9901 proto_register_smb2(void)
9903 module_t *smb2_module;
9904 static hf_register_info hf[] = {
9905 { &hf_smb2_cmd,
9906 { "Command", "smb2.cmd", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
9907 &smb2_cmd_vals_ext, 0, "SMB2 Command Opcode", HFILL }
9910 { &hf_smb2_response_to,
9911 { "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
9912 FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0, "This packet is a response to the packet in this frame", HFILL }
9915 { &hf_smb2_response_in,
9916 { "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
9917 FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0, "The response to this packet is in this packet", HFILL }
9920 { &hf_smb2_time,
9921 { "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
9922 NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }
9925 { &hf_smb2_preauth_hash,
9926 { "Preauth Hash", "smb2.preauth_hash", FT_BYTES, BASE_NONE,
9927 NULL, 0, "SMB3.1.1 pre-authentication SHA512 hash after hashing the packet", HFILL }
9930 { &hf_smb2_header_len,
9931 { "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
9932 NULL, 0, "SMB2 Size of Header", HFILL }
9935 { &hf_smb2_nt_status,
9936 { "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
9937 &NT_errors_ext, 0, "NT Status code", HFILL }
9940 { &hf_smb2_msg_id,
9941 { "Message ID", "smb2.msg_id", FT_UINT64, BASE_DEC|BASE_VAL64_STRING|BASE_SPECIAL_VALS,
9942 VALS64(unique_unsolicited_response), 0, NULL, HFILL }
9945 { &hf_smb2_tid,
9946 { "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
9947 NULL, 0, NULL, HFILL }
9950 { &hf_smb2_aid,
9951 { "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
9952 NULL, 0, NULL, HFILL }
9955 { &hf_smb2_sesid,
9956 { "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
9957 NULL, 0, NULL, HFILL }
9960 { &hf_smb2_previous_sesid,
9961 { "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
9962 NULL, 0, NULL, HFILL }
9965 { &hf_smb2_chain_offset,
9966 { "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
9967 NULL, 0, NULL, HFILL }
9970 { &hf_smb2_end_of_file,
9971 { "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
9972 NULL, 0, "SMB2 End Of File/File size", HFILL }
9975 { &hf_smb2_nlinks,
9976 { "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
9977 NULL, 0, "Number of links to this object", HFILL }
9980 { &hf_smb2_file_id,
9981 { "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
9982 NULL, 0, NULL, HFILL }
9985 { &hf_smb2_allocation_size,
9986 { "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
9987 NULL, 0, NULL, HFILL }
9990 { &hf_smb2_max_response_size,
9991 { "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
9992 NULL, 0, NULL, HFILL }
9995 { &hf_smb2_getinfo_input_size,
9996 { "Getinfo Input Size", "smb2.getinfo_input_size", FT_UINT32, BASE_DEC,
9997 NULL, 0, NULL, HFILL }
10000 { &hf_smb2_getinfo_input_offset,
10001 { "Getinfo Input Offset", "smb2.getinfo_input_offset", FT_UINT16, BASE_HEX,
10002 NULL, 0, NULL, HFILL }
10005 { &hf_smb2_getinfo_additional,
10006 { "Additional Info", "smb2.getinfo_additional", FT_UINT32, BASE_HEX,
10007 NULL, 0, NULL, HFILL }
10010 { &hf_smb2_getinfo_flags,
10011 { "Flags", "smb2.getinfo_flags", FT_UINT32, BASE_HEX,
10012 NULL, 0, NULL, HFILL }
10015 { &hf_smb2_setinfo_size,
10016 { "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
10017 NULL, 0, NULL, HFILL }
10020 { &hf_smb2_setinfo_offset,
10021 { "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
10022 NULL, 0, NULL, HFILL }
10025 { &hf_smb2_max_ioctl_out_size,
10026 { "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
10027 NULL, 0, NULL, HFILL }
10030 { &hf_smb2_max_ioctl_in_size,
10031 { "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
10032 NULL, 0, NULL, HFILL }
10035 { &hf_smb2_required_buffer_size,
10036 { "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
10037 NULL, 0, NULL, HFILL }
10040 { &hf_smb2_pid,
10041 { "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
10042 NULL, 0, NULL, HFILL }
10046 /* SMB2 header flags */
10047 { &hf_smb2_flags,
10048 { "Flags", "smb2.flags", FT_UINT32, BASE_HEX,
10049 NULL, 0, "SMB2 flags", HFILL }
10052 { &hf_smb2_flags_response,
10053 { "Response", "smb2.flags.response", FT_BOOLEAN, 32,
10054 TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }
10057 { &hf_smb2_flags_async_cmd,
10058 { "Async command", "smb2.flags.async", FT_BOOLEAN, 32,
10059 TFS(&tfs_flags_async_cmd), SMB2_FLAGS_ASYNC_CMD, NULL, HFILL }
10062 { &hf_smb2_flags_dfs_op,
10063 { "DFS operation", "smb2.flags.dfs", FT_BOOLEAN, 32,
10064 TFS(&tfs_flags_dfs_op), SMB2_FLAGS_DFS_OP, NULL, HFILL }
10067 { &hf_smb2_flags_chained,
10068 { "Chained", "smb2.flags.chained", FT_BOOLEAN, 32,
10069 TFS(&tfs_flags_chained), SMB2_FLAGS_CHAINED, "Whether the pdu continues a chain or not", HFILL }
10071 { &hf_smb2_flags_signature,
10072 { "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
10073 TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }
10076 { &hf_smb2_flags_replay_operation,
10077 { "Replay operation", "smb2.flags.replay", FT_BOOLEAN, 32,
10078 TFS(&tfs_flags_replay_operation), SMB2_FLAGS_REPLAY_OPERATION, "Whether this is a replay operation", HFILL }
10081 { &hf_smb2_flags_priority_mask,
10082 { "Priority", "smb2.flags.priority_mask", FT_BOOLEAN, 32,
10083 TFS(&tfs_flags_priority_mask), SMB2_FLAGS_PRIORITY_MASK, "Priority Mask", HFILL }
10086 { &hf_smb2_tree,
10087 { "Tree", "smb2.tree", FT_STRING, STR_UNICODE,
10088 NULL, 0, "Name of the Tree/Share", HFILL }
10091 { &hf_smb2_filename,
10092 { "Filename", "smb2.filename", FT_STRING, STR_UNICODE,
10093 NULL, 0, NULL, HFILL }
10096 { &hf_smb2_filename_len,
10097 { "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
10098 NULL, 0, NULL, HFILL }
10101 { &hf_smb2_replace_if,
10102 { "Replace If", "smb2.rename.replace_if", FT_BOOLEAN, 8,
10103 TFS(&tfs_replace_if_exists), 0xFF, "Whether to replace if the target exists", HFILL }
10106 { &hf_smb2_data_offset,
10107 { "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
10108 NULL, 0, "Offset to data", HFILL }
10111 { &hf_smb2_find_info_level,
10112 { "Info Level", "smb2.find.infolevel", FT_UINT32, BASE_DEC,
10113 VALS(smb2_find_info_levels), 0, "Find_Info Infolevel", HFILL }
10115 { &hf_smb2_find_flags,
10116 { "Find Flags", "smb2.find.flags", FT_UINT8, BASE_HEX,
10117 NULL, 0, NULL, HFILL }
10120 { &hf_smb2_find_pattern,
10121 { "Search Pattern", "smb2.find.pattern", FT_STRING, STR_UNICODE,
10122 NULL, 0, "Find pattern", HFILL }
10125 { &hf_smb2_find_info_blob,
10126 { "Info", "smb2.find.info_blob", FT_BYTES, BASE_NONE,
10127 NULL, 0, "Find Info", HFILL }
10130 { &hf_smb2_ea_size,
10131 { "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
10132 NULL, 0, "Size of EA data", HFILL }
10135 { &hf_smb2_position_information,
10136 { "Position Information", "smb2.position_info", FT_UINT64, BASE_DEC,
10137 NULL, 0, "Current file position", HFILL }
10140 { &hf_smb2_mode_information,
10141 { "Mode Information", "smb2.mode_info", FT_UINT32, BASE_HEX,
10142 NULL, 0, "File mode informatino", HFILL }
10145 { &hf_smb2_mode_file_write_through,
10146 { "FILE_WRITE_THROUGH", "smb2.mode.file_write_through", FT_UINT32, BASE_HEX,
10147 NULL, 0x02, NULL, HFILL }
10150 { &hf_smb2_mode_file_sequential_only,
10151 { "FILE_SEQUENTIAL_ONLY", "smb2.mode.file_sequential_only", FT_UINT32, BASE_HEX,
10152 NULL, 0x04, NULL, HFILL }
10155 { &hf_smb2_mode_file_no_intermediate_buffering,
10156 { "FILE_NO_INTERMEDIATE_BUFFERING", "smb2.mode.file_no_intermediate_buffering", FT_UINT32, BASE_HEX,
10157 NULL, 0x08, NULL, HFILL }
10160 { &hf_smb2_mode_file_synchronous_io_alert,
10161 { "FILE_SYNCHRONOUS_IO_ALERT", "smb2.mode.file_synchronous_io_alert", FT_UINT32, BASE_HEX,
10162 NULL, 0x10, NULL, HFILL }
10165 { &hf_smb2_mode_file_synchronous_io_nonalert,
10166 { "FILE_SYNCHRONOUS_IO_NONALERT", "smb2.mode.file_synchronous_io_nonalert", FT_UINT32, BASE_HEX,
10167 NULL, 0x20, NULL, HFILL }
10170 { &hf_smb2_mode_file_delete_on_close,
10171 { "FILE_DELETE_ON_CLOSE", "smb2.mode.file_delete_on_close", FT_UINT32, BASE_HEX,
10172 NULL, 0x1000, NULL, HFILL }
10175 { &hf_smb2_alignment_information,
10176 { "Alignment Information", "smb2.alignment_info", FT_UINT32, BASE_HEX,
10177 VALS(smb2_alignment_vals), 0, "File alignment", HFILL}
10180 { &hf_smb2_class,
10181 { "Class", "smb2.class", FT_UINT8, BASE_HEX,
10182 VALS(smb2_class_vals), 0, "Info class", HFILL }
10185 { &hf_smb2_infolevel,
10186 { "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
10187 NULL, 0, NULL, HFILL }
10190 { &hf_smb2_infolevel_file_info,
10191 { "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
10192 &smb2_file_info_levels_ext, 0, "File_Info Infolevel", HFILL }
10195 { &hf_smb2_infolevel_fs_info,
10196 { "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
10197 &smb2_fs_info_levels_ext, 0, "Fs_Info Infolevel", HFILL }
10200 { &hf_smb2_infolevel_sec_info,
10201 { "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
10202 &smb2_sec_info_levels_ext, 0, "Sec_Info Infolevel", HFILL }
10205 { &hf_smb2_infolevel_posix_info,
10206 { "InfoLevel", "smb2.posix_info.infolevel", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
10207 &smb2_posix_info_levels_ext, 0, "Posix_Info Infolevel", HFILL }
10210 { &hf_smb2_write_length,
10211 { "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
10212 NULL, 0, "Amount of data to write", HFILL }
10215 { &hf_smb2_read_length,
10216 { "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
10217 NULL, 0, "Amount of data to read", HFILL }
10220 { &hf_smb2_read_remaining,
10221 { "Read Remaining", "smb2.read_remaining", FT_UINT32, BASE_DEC,
10222 NULL, 0, NULL, HFILL }
10225 { &hf_smb2_create_flags,
10226 { "Create Flags", "smb2.create_flags", FT_UINT64, BASE_HEX,
10227 NULL, 0, NULL, HFILL }
10230 { &hf_smb2_file_offset,
10231 { "File Offset", "smb2.file_offset", FT_UINT64, BASE_DEC,
10232 NULL, 0, NULL, HFILL }
10235 { &hf_smb2_fsctl_range_offset,
10236 { "File Offset", "smb2.fsctl.range_offset", FT_UINT64, BASE_DEC,
10237 NULL, 0, NULL, HFILL }
10240 { &hf_smb2_fsctl_range_length,
10241 { "Length", "smb2.fsctl.range_length", FT_UINT64, BASE_DEC,
10242 NULL, 0, NULL, HFILL }
10245 { &hf_smb2_qfr_length,
10246 { "Length", "smb2.qfr_length", FT_UINT64, BASE_DEC,
10247 NULL, 0, NULL, HFILL }
10250 { &hf_smb2_qfr_usage,
10251 { "Desired Usage", "smb2.qfr_usage", FT_UINT32, BASE_HEX,
10252 VALS(file_region_usage_vals), 0, NULL, HFILL }
10255 { &hf_smb2_qfr_flags,
10256 { "Flags", "smb2.qfr_flags", FT_UINT32, BASE_HEX,
10257 NULL, 0, NULL, HFILL }
10260 { &hf_smb2_qfr_total_region_entry_count,
10261 { "Total Region Entry Count", "smb2.qfr_tot_region_entry_count", FT_UINT32, BASE_HEX,
10262 NULL, 0, NULL, HFILL }
10265 { &hf_smb2_qfr_region_entry_count,
10266 { "Region Entry Count", "smb2.qfr_region_entry_count", FT_UINT32, BASE_HEX,
10267 NULL, 0, NULL, HFILL }
10270 { &hf_smb2_security_blob,
10271 { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_NONE,
10272 NULL, 0, NULL, HFILL }
10275 { &hf_smb2_ioctl_out_data,
10276 { "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
10277 NULL, 0, "Ioctl Out", HFILL }
10280 { &hf_smb2_ioctl_in_data,
10281 { "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
10282 NULL, 0, "Ioctl In", HFILL }
10285 { &hf_smb2_server_guid,
10286 { "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
10287 NULL, 0, NULL, HFILL }
10290 { &hf_smb2_client_guid,
10291 { "Client Guid", "smb2.client_guid", FT_GUID, BASE_NONE,
10292 NULL, 0, NULL, HFILL }
10295 { &hf_smb2_object_id,
10296 { "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
10297 NULL, 0, "ObjectID for this FID", HFILL }
10300 { &hf_smb2_birth_volume_id,
10301 { "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
10302 NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }
10305 { &hf_smb2_birth_object_id,
10306 { "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
10307 NULL, 0, "ObjectID for this FID when it was originally created", HFILL }
10310 { &hf_smb2_domain_id,
10311 { "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
10312 NULL, 0, NULL, HFILL }
10315 { &hf_smb2_create_timestamp,
10316 { "Create", "smb2.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10317 NULL, 0, "Time when this object was created", HFILL }
10320 { &hf_smb2_fid,
10321 { "File Id", "smb2.fid", FT_GUID, BASE_NONE,
10322 NULL, 0, "SMB2 File Id", HFILL }
10325 { &hf_smb2_write_data,
10326 { "Write Data", "smb2.write_data", FT_BYTES, BASE_NONE,
10327 NULL, 0, "SMB2 Data to be written", HFILL }
10330 { &hf_smb2_write_flags,
10331 { "Write Flags", "smb2.write.flags", FT_UINT32, BASE_HEX,
10332 NULL, 0, NULL, HFILL }
10335 { &hf_smb2_write_flags_write_through,
10336 { "Write through", "smb2.write.flags.write_through", FT_BOOLEAN, 32,
10337 NULL, SMB2_WRITE_FLAG_WRITE_THROUGH, NULL, HFILL }
10340 { &hf_smb2_write_count,
10341 { "Write Count", "smb2.write.count", FT_UINT32, BASE_DEC,
10342 NULL, 0, NULL, HFILL }
10345 { &hf_smb2_write_remaining,
10346 { "Write Remaining", "smb2.write.remaining", FT_UINT32, BASE_DEC,
10347 NULL, 0, NULL, HFILL }
10350 { &hf_smb2_read_data,
10351 { "Read Data", "smb2.read_data", FT_BYTES, BASE_NONE,
10352 NULL, 0, "SMB2 Data that is read", HFILL }
10355 { &hf_smb2_last_access_timestamp,
10356 { "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10357 NULL, 0, "Time when this object was last accessed", HFILL }
10360 { &hf_smb2_last_write_timestamp,
10361 { "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10362 NULL, 0, "Time when this object was last written to", HFILL }
10365 { &hf_smb2_last_change_timestamp,
10366 { "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10367 NULL, 0, "Time when this object was last changed", HFILL }
10370 { &hf_smb2_file_all_info,
10371 { "SMB2_FILE_ALL_INFO", "smb2.file_all_info", FT_NONE, BASE_NONE,
10372 NULL, 0, NULL, HFILL }
10375 { &hf_smb2_file_allocation_info,
10376 { "SMB2_FILE_ALLOCATION_INFO", "smb2.file_allocation_info", FT_NONE, BASE_NONE,
10377 NULL, 0, NULL, HFILL }
10380 { &hf_smb2_file_endoffile_info,
10381 { "SMB2_FILE_ENDOFFILE_INFO", "smb2.file_endoffile_info", FT_NONE, BASE_NONE,
10382 NULL, 0, NULL, HFILL }
10385 { &hf_smb2_file_alternate_name_info,
10386 { "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.file_alternate_name_info", FT_NONE, BASE_NONE,
10387 NULL, 0, NULL, HFILL }
10390 { &hf_smb2_file_stream_info,
10391 { "SMB2_FILE_STREAM_INFO", "smb2.file_stream_info", FT_NONE, BASE_NONE,
10392 NULL, 0, NULL, HFILL }
10395 { &hf_smb2_file_pipe_info,
10396 { "SMB2_FILE_PIPE_INFO", "smb2.file_pipe_info", FT_NONE, BASE_NONE,
10397 NULL, 0, NULL, HFILL }
10400 { &hf_smb2_file_compression_info,
10401 { "SMB2_FILE_COMPRESSION_INFO", "smb2.file_compression_info", FT_NONE, BASE_NONE,
10402 NULL, 0, NULL, HFILL }
10405 { &hf_smb2_file_basic_info,
10406 { "SMB2_FILE_BASIC_INFO", "smb2.file_basic_info", FT_NONE, BASE_NONE,
10407 NULL, 0, NULL, HFILL }
10410 { &hf_smb2_file_standard_info,
10411 { "SMB2_FILE_STANDARD_INFO", "smb2.file_standard_info", FT_NONE, BASE_NONE,
10412 NULL, 0, NULL, HFILL }
10415 { &hf_smb2_file_internal_info,
10416 { "SMB2_FILE_INTERNAL_INFO", "smb2.file_internal_info", FT_NONE, BASE_NONE,
10417 NULL, 0, NULL, HFILL }
10420 { &hf_smb2_file_mode_info,
10421 { "SMB2_FILE_MODE_INFO", "smb2.file_mode_info", FT_NONE, BASE_NONE,
10422 NULL, 0, NULL, HFILL }
10425 { &hf_smb2_file_alignment_info,
10426 { "SMB2_FILE_ALIGNMENT_INFO", "smb2.file_alignment_info", FT_NONE, BASE_NONE,
10427 NULL, 0, NULL, HFILL }
10430 { &hf_smb2_file_position_info,
10431 { "SMB2_FILE_POSITION_INFO", "smb2.file_position_info", FT_NONE, BASE_NONE,
10432 NULL, 0, NULL, HFILL }
10435 { &hf_smb2_file_access_info,
10436 { "SMB2_FILE_ACCESS_INFO", "smb2.file_access_info", FT_NONE, BASE_NONE,
10437 NULL, 0, NULL, HFILL }
10440 { &hf_smb2_file_ea_info,
10441 { "SMB2_FILE_EA_INFO", "smb2.file_ea_info", FT_NONE, BASE_NONE,
10442 NULL, 0, NULL, HFILL }
10445 { &hf_smb2_file_network_open_info,
10446 { "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.file_network_open_info", FT_NONE, BASE_NONE,
10447 NULL, 0, NULL, HFILL }
10450 { &hf_smb2_file_attribute_tag_info,
10451 { "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.file_attribute_tag_info", FT_NONE, BASE_NONE,
10452 NULL, 0, NULL, HFILL }
10455 { &hf_smb2_file_disposition_info,
10456 { "SMB2_FILE_DISPOSITION_INFO", "smb2.file_disposition_info", FT_NONE, BASE_NONE,
10457 NULL, 0, NULL, HFILL }
10460 { &hf_smb2_file_full_ea_info,
10461 { "SMB2_FILE_FULL_EA_INFO", "smb2.file_full_ea_info", FT_NONE, BASE_NONE,
10462 NULL, 0, NULL, HFILL }
10465 { &hf_smb2_file_rename_info,
10466 { "SMB2_FILE_RENAME_INFO", "smb2.file_rename_info", FT_NONE, BASE_NONE,
10467 NULL, 0, NULL, HFILL }
10470 { &hf_smb2_fs_info_01,
10471 { "FileFsVolumeInformation", "smb2.fs_volume_info", FT_NONE, BASE_NONE,
10472 NULL, 0, NULL, HFILL }
10475 { &hf_smb2_fs_info_03,
10476 { "FileFsSizeInformation", "smb2.fs_size_info", FT_NONE, BASE_NONE,
10477 NULL, 0, NULL, HFILL }
10480 { &hf_smb2_fs_info_04,
10481 { "FileFsDeviceInformation", "smb2.fs_device_info", FT_NONE, BASE_NONE,
10482 NULL, 0, NULL, HFILL }
10485 { &hf_smb2_fs_info_05,
10486 { "FileFsAttributeInformation", "smb2.fs_attribute_info", FT_NONE, BASE_NONE,
10487 NULL, 0, NULL, HFILL }
10490 { &hf_smb2_fs_info_06,
10491 { "FileFsControlInformation", "smb2.fs_control_info", FT_NONE, BASE_NONE,
10492 NULL, 0, NULL, HFILL }
10495 { &hf_smb2_fs_info_07,
10496 { "FileFsFullSizeInformation", "smb2.fs_full_size_info", FT_NONE, BASE_NONE,
10497 NULL, 0, NULL, HFILL }
10500 { &hf_smb2_fs_objectid_info,
10501 { "FileFsObjectIdInformation", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
10502 NULL, 0, NULL, HFILL }
10505 { &hf_smb2_sec_info_00,
10506 { "SMB2_SEC_INFO_00", "smb2.sec_info_00", FT_NONE, BASE_NONE,
10507 NULL, 0, NULL, HFILL }
10510 { &hf_smb2_quota_info,
10511 { "SMB2_QUOTA_INFO", "smb2.quota_info", FT_NONE, BASE_NONE,
10512 NULL, 0, NULL, HFILL }
10515 { &hf_smb2_query_quota_info,
10516 { "SMB2_QUERY_QUOTA_INFO", "smb2.query_quota_info", FT_NONE, BASE_NONE,
10517 NULL, 0, NULL, HFILL }
10520 { &hf_smb2_qq_single,
10521 { "ReturnSingle", "smb2.query_quota_info.single", FT_BOOLEAN, 8,
10522 NULL, 0xff, NULL, HFILL }
10525 { &hf_smb2_qq_restart,
10526 { "RestartScan", "smb2.query_quota_info.restart", FT_BOOLEAN, 8,
10527 NULL, 0xff, NULL, HFILL }
10530 { &hf_smb2_qq_sidlist_len,
10531 { "SidListLength", "smb2.query_quota_info.sidlistlen", FT_UINT32, BASE_DEC,
10532 NULL, 0, NULL, HFILL }
10535 { &hf_smb2_qq_start_sid_len,
10536 { "StartSidLength", "smb2.query_quota_info.startsidlen", FT_UINT32, BASE_DEC,
10537 NULL, 0, NULL, HFILL }
10540 { &hf_smb2_qq_start_sid_offset,
10541 { "StartSidOffset", "smb2.query_quota_info.startsidoffset", FT_UINT32, BASE_DEC,
10542 NULL, 0, NULL, HFILL }
10545 { &hf_smb2_disposition_delete_on_close,
10546 { "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
10547 TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }
10551 { &hf_smb2_create_disposition,
10552 { "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
10553 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }
10556 { &hf_smb2_create_action,
10557 { "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
10558 VALS(oa_open_vals), 0, NULL, HFILL }
10561 { &hf_smb2_create_rep_flags,
10562 { "Response Flags", "smb2.create.rep_flags", FT_UINT8, BASE_HEX,
10563 NULL, 0, NULL, HFILL }
10566 { &hf_smb2_create_rep_flags_reparse_point,
10567 { "ReparsePoint", "smb2.create.rep_flags.reparse_point", FT_BOOLEAN, 8,
10568 NULL, SMB2_CREATE_REP_FLAGS_REPARSE_POINT, NULL, HFILL }
10571 { &hf_smb2_extrainfo,
10572 { "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
10573 NULL, 0, "Create ExtraInfo", HFILL }
10576 { &hf_smb2_create_chain_offset,
10577 { "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
10578 NULL, 0, "Offset to next entry in chain or 0", HFILL }
10581 { &hf_smb2_create_chain_data,
10582 { "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
10583 NULL, 0, "Chain Data", HFILL }
10586 { &hf_smb2_FILE_OBJECTID_BUFFER,
10587 { "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
10588 NULL, 0, NULL, HFILL }
10591 { &hf_smb2_lease_key,
10592 { "Lease Key", "smb2.lease.lease_key", FT_GUID, BASE_NONE,
10593 NULL, 0, NULL, HFILL }
10596 { &hf_smb2_lease_state,
10597 { "Lease State", "smb2.lease.lease_state", FT_UINT32, BASE_HEX,
10598 NULL, 0, NULL, HFILL }
10601 { &hf_smb2_lease_state_read_caching,
10602 { "Read Caching", "smb2.lease.lease_state.read_caching", FT_BOOLEAN, 32,
10603 NULL, SMB2_LEASE_STATE_READ_CACHING, NULL, HFILL }
10606 { &hf_smb2_lease_state_handle_caching,
10607 { "Handle Caching", "smb2.lease.lease_state.handle_caching", FT_BOOLEAN, 32,
10608 NULL, SMB2_LEASE_STATE_HANDLE_CACHING, NULL, HFILL }
10611 { &hf_smb2_lease_state_write_caching,
10612 { "Write Caching", "smb2.lease.lease_state.write_caching", FT_BOOLEAN, 32,
10613 NULL, SMB2_LEASE_STATE_WRITE_CACHING, NULL, HFILL }
10616 { &hf_smb2_lease_flags,
10617 { "Lease Flags", "smb2.lease.lease_flags", FT_UINT32, BASE_HEX,
10618 NULL, 0, NULL, HFILL }
10621 { &hf_smb2_lease_flags_break_ack_required,
10622 { "Break Ack Required", "smb2.lease.lease_state.break_ack_required", FT_BOOLEAN, 32,
10623 NULL, SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED, NULL, HFILL }
10626 { &hf_smb2_lease_flags_break_in_progress,
10627 { "Break In Progress", "smb2.lease.lease_state.break_in_progress", FT_BOOLEAN, 32,
10628 NULL, SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS, NULL, HFILL }
10631 { &hf_smb2_lease_flags_parent_lease_key_set,
10632 { "Parent Lease Key Set", "smb2.lease.lease_state.parent_lease_key_set", FT_BOOLEAN, 32,
10633 NULL, SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET, NULL, HFILL }
10636 { &hf_smb2_lease_duration,
10637 { "Lease Duration", "smb2.lease.lease_duration", FT_UINT64, BASE_HEX,
10638 NULL, 0, NULL, HFILL }
10641 { &hf_smb2_parent_lease_key,
10642 { "Parent Lease Key", "smb2.lease.parent_lease_key", FT_GUID, BASE_NONE,
10643 NULL, 0, NULL, HFILL }
10646 { &hf_smb2_lease_epoch,
10647 { "Lease Epoch", "smb2.lease.lease_oplock", FT_UINT16, BASE_HEX,
10648 NULL, 0, NULL, HFILL }
10651 { &hf_smb2_lease_reserved,
10652 { "Lease Reserved", "smb2.lease.lease_reserved", FT_UINT16, BASE_HEX,
10653 NULL, 0, NULL, HFILL }
10656 { &hf_smb2_lease_break_reason,
10657 { "Lease Break Reason", "smb2.lease.lease_break_reason", FT_UINT32, BASE_HEX,
10658 NULL, 0, NULL, HFILL }
10661 { &hf_smb2_lease_access_mask_hint,
10662 { "Access Mask Hint", "smb2.lease.access_mask_hint", FT_UINT32, BASE_HEX,
10663 NULL, 0, NULL, HFILL }
10666 { &hf_smb2_lease_share_mask_hint,
10667 { "Share Mask Hint", "smb2.lease.share_mask_hint", FT_UINT32, BASE_HEX,
10668 NULL, 0, NULL, HFILL }
10671 { &hf_smb2_next_offset,
10672 { "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
10673 NULL, 0, "Offset to next buffer or 0", HFILL }
10676 { &hf_smb2_negotiate_context_type,
10677 { "Type", "smb2.negotiate_context.type", FT_UINT16, BASE_HEX,
10678 VALS(smb2_negotiate_context_types), 0, NULL, HFILL }
10681 { &hf_smb2_negotiate_context_data_length,
10682 { "DataLength", "smb2.negotiate_context.data_length", FT_UINT16, BASE_DEC,
10683 NULL, 0, NULL, HFILL }
10686 { &hf_smb2_negotiate_context_offset,
10687 { "NegotiateContextOffset", "smb2.negotiate_context.offset", FT_UINT16, BASE_HEX,
10688 NULL, 0, NULL, HFILL }
10691 { &hf_smb2_negotiate_context_count,
10692 { "NegotiateContextCount", "smb2.negotiate_context.count", FT_UINT16, BASE_DEC,
10693 NULL, 0, NULL, HFILL }
10696 { &hf_smb2_hash_alg_count,
10697 { "HashAlgorithmCount", "smb2.negotiate_context.hash_alg_count", FT_UINT16, BASE_DEC,
10698 NULL, 0, NULL, HFILL }},
10700 { &hf_smb2_hash_algorithm,
10701 { "HashAlgorithm", "smb2.negotiate_context.hash_algorithm", FT_UINT16, BASE_HEX,
10702 VALS(smb2_hash_algorithm_types), 0, NULL, HFILL }},
10704 { &hf_smb2_salt_length,
10705 { "SaltLength", "smb2.negotiate_context.salt_length", FT_UINT16, BASE_DEC,
10706 NULL, 0, NULL, HFILL }},
10708 { &hf_smb2_salt,
10709 { "Salt", "smb2.negotiate_context.salt", FT_BYTES, BASE_NONE,
10710 NULL, 0, NULL, HFILL }},
10712 { &hf_smb2_cipher_count,
10713 { "CipherCount", "smb2.negotiate_context.cipher_count", FT_UINT16, BASE_DEC,
10714 NULL, 0, NULL, HFILL }},
10716 { &hf_smb2_cipher_id,
10717 { "CipherId", "smb2.negotiate_context.cipher_id", FT_UINT16, BASE_HEX,
10718 VALS(smb2_cipher_types), 0, NULL, HFILL }},
10720 { &hf_smb2_comp_alg_count,
10721 { "CompressionAlgorithmCount", "smb2.negotiate_context.comp_alg_count", FT_UINT16, BASE_DEC,
10722 NULL, 0, NULL, HFILL }},
10724 { &hf_smb2_comp_alg_id,
10725 { "CompressionAlgorithmId", "smb2.negotiate_context.comp_alg_id", FT_UINT16, BASE_HEX,
10726 VALS(smb2_comp_alg_types), 0, NULL, HFILL }},
10728 { &hf_smb2_netname_neg_id,
10729 { "Netname", "smb2.negotiate_context.netname", FT_STRING,
10730 STR_UNICODE, NULL, 0x0, NULL, HFILL }
10733 { &hf_smb2_current_time,
10734 { "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10735 NULL, 0, "Current Time at server", HFILL }
10738 { &hf_smb2_boot_time,
10739 { "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
10740 NULL, 0, "Boot Time at server", HFILL }
10743 { &hf_smb2_ea_flags,
10744 { "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
10745 NULL, 0, NULL, HFILL }
10748 { &hf_smb2_ea_name_len,
10749 { "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
10750 NULL, 0, NULL, HFILL }
10753 { &hf_smb2_ea_data_len,
10754 { "EA Data Length", "smb2.ea.data_len", FT_UINT16, BASE_DEC,
10755 NULL, 0, NULL, HFILL }
10758 { &hf_smb2_delete_pending,
10759 { "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
10760 NULL, 0, NULL, HFILL }
10763 { &hf_smb2_is_directory,
10764 { "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
10765 NULL, 0, "Is this a directory?", HFILL }
10768 { &hf_smb2_oplock,
10769 { "Oplock", "smb2.create.oplock", FT_UINT8, BASE_HEX,
10770 VALS(oplock_vals), 0, "Oplock type", HFILL }
10773 { &hf_smb2_close_flags,
10774 { "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
10775 NULL, 0, NULL, HFILL }
10778 { &hf_smb2_notify_flags,
10779 { "Notify Flags", "smb2.notify.flags", FT_UINT16, BASE_HEX,
10780 NULL, 0, NULL, HFILL }
10783 { &hf_smb2_buffer_code,
10784 { "StructureSize", "smb2.buffer_code", FT_UINT16, BASE_HEX,
10785 NULL, 0, NULL, HFILL }
10788 { &hf_smb2_buffer_code_len,
10789 { "Fixed Part Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
10790 NULL, 0xFFFE, "Length of fixed portion of PDU", HFILL }
10793 { &hf_smb2_olb_length,
10794 { "Blob Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
10795 NULL, 0, "Length of the buffer", HFILL }
10798 { &hf_smb2_olb_offset,
10799 { "Blob Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
10800 NULL, 0, "Offset to the buffer", HFILL }
10803 { &hf_smb2_buffer_code_flags_dyn,
10804 { "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
10805 NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }
10808 { &hf_smb2_ea_data,
10809 { "EA Data", "smb2.ea.data", FT_BYTES, BASE_NONE|BASE_SHOW_ASCII_PRINTABLE,
10810 NULL, 0, NULL, HFILL }
10813 { &hf_smb2_ea_name,
10814 { "EA Name", "smb2.ea.name", FT_STRING, STR_UNICODE,
10815 NULL, 0, NULL, HFILL }
10818 { &hf_smb2_impersonation_level,
10819 { "Impersonation level", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
10820 VALS(impersonation_level_vals), 0, NULL, HFILL }
10823 { &hf_smb2_ioctl_function,
10824 { "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
10825 &smb2_ioctl_vals_ext, 0, "Ioctl function", HFILL }
10828 { &hf_smb2_ioctl_function_device,
10829 { "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
10830 &smb2_ioctl_device_vals_ext, 0xffff0000, "Device for Ioctl", HFILL }
10833 { &hf_smb2_ioctl_function_access,
10834 { "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
10835 VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }
10838 { &hf_smb2_ioctl_function_function,
10839 { "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
10840 NULL, 0x00003ffc, "Function for Ioctl", HFILL }
10843 { &hf_smb2_ioctl_function_method,
10844 { "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
10845 VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }
10848 { &hf_smb2_fsctl_pipe_wait_timeout,
10849 { "Timeout", "smb2.fsctl.wait.timeout", FT_INT64, BASE_DEC,
10850 NULL, 0, "Wait timeout", HFILL }
10853 { &hf_smb2_fsctl_pipe_wait_name,
10854 { "Name", "smb2.fsctl.wait.name", FT_STRING, STR_UNICODE,
10855 NULL, 0, "Pipe name", HFILL }
10858 { &hf_smb2_fsctl_odx_token_type,
10859 { "TokenType", "smb2.fsctl.odx.token.type", FT_UINT32, BASE_HEX,
10860 NULL, 0, NULL, HFILL }
10863 { &hf_smb2_fsctl_odx_token_idlen,
10864 { "TokenIdLength", "smb2.fsctl.odx.token.idlen", FT_UINT16, BASE_DEC,
10865 NULL, 0, NULL, HFILL }
10868 { &hf_smb2_fsctl_odx_token_idraw,
10869 { "TokenId", "smb2.fsctl.odx.token.id", FT_BYTES, BASE_NONE,
10870 NULL, 0, "Token ID (opaque)", HFILL }
10873 { &hf_smb2_fsctl_odx_token_ttl,
10874 { "TokenTimeToLive", "smb2.fsctl.odx.token_ttl", FT_UINT32, BASE_DEC,
10875 NULL, 0, "TTL requested for the token (in milliseconds)", HFILL }
10878 { &hf_smb2_fsctl_odx_size,
10879 { "Size", "smb2.fsctl.odx.size", FT_UINT32, BASE_DEC,
10880 NULL, 0, "Size of this data element", HFILL }
10883 { &hf_smb2_fsctl_odx_flags,
10884 { "Flags", "smb2.fsctl.odx.flags", FT_UINT32, BASE_HEX,
10885 NULL, 0, "Flags for this operation", HFILL }
10888 { &hf_smb2_fsctl_odx_file_offset,
10889 { "FileOffset", "smb2.fsctl.odx.file_offset", FT_UINT64, BASE_DEC,
10890 NULL, 0, NULL, HFILL }
10893 { &hf_smb2_fsctl_odx_copy_length,
10894 { "CopyLength", "smb2.fsctl.odx.copy_length", FT_UINT64, BASE_DEC,
10895 NULL, 0, NULL, HFILL }
10898 { &hf_smb2_fsctl_odx_xfer_length,
10899 { "TransferLength", "smb2.fsctl.odx.xfer_length", FT_UINT64, BASE_DEC,
10900 NULL, 0, NULL, HFILL }
10903 { &hf_smb2_fsctl_odx_token_offset,
10904 { "TokenOffset", "smb2.fsctl.odx.token_offset", FT_UINT64, BASE_DEC,
10905 NULL, 0, "Token Offset (relative to start of token)", HFILL }
10908 { &hf_smb2_fsctl_sparse_flag,
10909 { "SetSparse", "smb2.fsctl.set_sparse", FT_BOOLEAN, 8,
10910 NULL, 0xFF, NULL, HFILL }
10913 { &hf_smb2_ioctl_resiliency_timeout,
10914 { "Timeout", "smb2.ioctl.resiliency.timeout", FT_UINT32, BASE_DEC,
10915 NULL, 0, "Resiliency timeout", HFILL }
10918 { &hf_smb2_ioctl_resiliency_reserved,
10919 { "Reserved", "smb2.ioctl.resiliency.reserved", FT_UINT32, BASE_DEC,
10920 NULL, 0, "Resiliency reserved", HFILL }
10923 { &hf_smb2_ioctl_shared_virtual_disk_support,
10924 { "SharedVirtualDiskSupport", "smb2.ioctl.shared_virtual_disk.support", FT_UINT32, BASE_HEX,
10925 VALS(smb2_ioctl_shared_virtual_disk_vals), 0, "Supported shared capabilities", HFILL }
10928 { &hf_smb2_ioctl_shared_virtual_disk_handle_state,
10929 { "SharedVirtualDiskHandleState", "smb2.ioctl.shared_virtual_disk.handle_state", FT_UINT32, BASE_HEX,
10930 VALS(smb2_ioctl_shared_virtual_disk_hstate_vals), 0, NULL, HFILL }
10933 { &hf_smb2_ioctl_sqos_protocol_version,
10934 { "ProtocolVersion", "smb2.ioctl.sqos.protocol_version", FT_UINT16, BASE_HEX,
10935 VALS(smb2_ioctl_sqos_protocol_version_vals), 0, NULL, HFILL }
10938 { &hf_smb2_ioctl_sqos_reserved,
10939 { "Reserved", "smb2.ioctl.sqos.reserved", FT_UINT16, BASE_DEC,
10940 NULL, 0, NULL, HFILL }
10943 { &hf_smb2_ioctl_sqos_options,
10944 { "Operations", "smb2.ioctl.sqos.operations", FT_UINT32, BASE_HEX,
10945 NULL, 0, "SQOS operations", HFILL }
10948 { &hf_smb2_ioctl_sqos_op_set_logical_flow_id,
10949 { "Set Logical Flow ID", "smb2.ioctl.sqos.operations.set_logical_flow_id", FT_BOOLEAN, 32,
10950 NULL, STORAGE_QOS_CONTROL_FLAG_SET_LOGICAL_FLOW_ID, "Whether Set Logical Flow ID operation is performed", HFILL }
10953 { &hf_smb2_ioctl_sqos_op_set_policy,
10954 { "Set Policy", "smb2.ioctl.sqos.operations.set_policy", FT_BOOLEAN, 32,
10955 NULL, STORAGE_QOS_CONTROL_FLAG_SET_POLICY, "Whether Set Policy operation is performed", HFILL }
10958 { &hf_smb2_ioctl_sqos_op_probe_policy,
10959 { "Probe Policy", "smb2.ioctl.sqos.operations.probe_policy", FT_BOOLEAN, 32,
10960 NULL, STORAGE_QOS_CONTROL_FLAG_PROBE_POLICY, "Whether Probe Policy operation is performed", HFILL }
10963 { &hf_smb2_ioctl_sqos_op_get_status,
10964 { "Get Status", "smb2.ioctl.sqos.operations.get_status", FT_BOOLEAN, 32,
10965 NULL, STORAGE_QOS_CONTROL_FLAG_GET_STATUS, "Whether Get Status operation is performed", HFILL }
10968 { &hf_smb2_ioctl_sqos_op_update_counters,
10969 { "Update Counters", "smb2.ioctl.sqos.operations.update_counters", FT_BOOLEAN, 32,
10970 NULL, STORAGE_QOS_CONTROL_FLAG_UPDATE_COUNTERS, "Whether Update Counters operation is performed", HFILL }
10973 { &hf_smb2_ioctl_sqos_logical_flow_id,
10974 { "LogicalFlowID", "smb2.ioctl.sqos.logical_flow_id", FT_GUID, BASE_NONE,
10975 NULL, 0, NULL, HFILL }
10978 { &hf_smb2_ioctl_sqos_policy_id,
10979 { "PolicyID", "smb2.ioctl.sqos.policy_id", FT_GUID, BASE_NONE,
10980 NULL, 0, NULL, HFILL }
10983 { &hf_smb2_ioctl_sqos_initiator_id,
10984 { "InitiatorID", "smb2.ioctl.sqos.initiator_id", FT_GUID, BASE_NONE,
10985 NULL, 0, NULL, HFILL }
10988 { &hf_smb2_ioctl_sqos_limit,
10989 { "Limit", "smb2.ioctl.sqos.limit", FT_UINT64, BASE_DEC,
10990 NULL, 0, "Desired maximum throughput for the logical flow, in normalized IOPS", HFILL }
10993 { &hf_smb2_ioctl_sqos_reservation,
10994 { "Reservation", "smb2.ioctl.sqos.reservation", FT_UINT64, BASE_DEC,
10995 NULL, 0, "Desired minimum throughput for the logical flow, in normalized 8KB IOPS", HFILL }
10998 { &hf_smb2_ioctl_sqos_initiator_name,
10999 { "InitiatorName", "smb2.ioctl.sqos.initiator_name", FT_STRING, STR_UNICODE,
11000 NULL, 0x0, NULL, HFILL }
11003 { &hf_smb2_ioctl_sqos_initiator_node_name,
11004 { "InitiatorNodeName", "smb2.ioctl.sqos.initiator_node_name", FT_STRING, STR_UNICODE,
11005 NULL, 0x0, NULL, HFILL }
11008 { &hf_smb2_ioctl_sqos_io_count_increment,
11009 { "IoCountIncrement", "smb2.ioctl.sqos.io_count_increment", FT_UINT64, BASE_DEC,
11010 NULL, 0, "The total number of I/O requests issued by the initiator on the logical flow", HFILL }
11013 { &hf_smb2_ioctl_sqos_normalized_io_count_increment,
11014 { "NormalizedIoCountIncrement", "smb2.ioctl.sqos.normalized_io_count_increment", FT_UINT64, BASE_DEC,
11015 NULL, 0, "The total number of normalized 8-KB I/O requests issued by the initiator on the logical flow", HFILL }
11018 { &hf_smb2_ioctl_sqos_latency_increment,
11019 { "LatencyIncrement", "smb2.ioctl.sqos.latency_increment", FT_UINT64, BASE_DEC,
11020 NULL, 0, "The total latency (including initiator's queues delays) measured by the initiator", HFILL }
11023 { &hf_smb2_ioctl_sqos_lower_latency_increment,
11024 { "LowerLatencyIncrement", "smb2.ioctl.sqos.lower_latency_increment", FT_UINT64, BASE_DEC,
11025 NULL, 0, "The total latency (excluding initiator's queues delays) measured by the initiator", HFILL }
11028 { &hf_smb2_ioctl_sqos_bandwidth_limit,
11029 { "BandwidthLimit", "smb2.ioctl.sqos.bandwidth_limit", FT_UINT64, BASE_DEC,
11030 NULL, 0, "Desired maximum bandwidth for the logical flow, in kilobytes per second", HFILL }
11033 { &hf_smb2_ioctl_sqos_kilobyte_count_increment,
11034 { "KilobyteCountIncrement", "smb2.ioctl.sqos.kilobyte_count_increment", FT_UINT64, BASE_DEC,
11035 NULL, 0, "The total data transfer length of all I/O requests, in kilobyte units, issued by the initiator on the logical flow", HFILL }
11038 { &hf_smb2_ioctl_sqos_time_to_live,
11039 { "TimeToLive", "smb2.ioctl.sqos.time_to_live", FT_UINT32, BASE_DEC,
11040 NULL, 0, "The expected period of validity of the Status, MaximumIoRate and MinimumIoRate fields, expressed in milliseconds", HFILL }
11043 { &hf_smb2_ioctl_sqos_status,
11044 { "Status", "smb2.ioctl.sqos.status", FT_UINT32, BASE_HEX,
11045 VALS(smb2_ioctl_sqos_status_vals), 0, "The current status of the logical flow", HFILL }
11048 { &hf_smb2_ioctl_sqos_maximum_io_rate,
11049 { "MaximumIoRate", "smb2.ioctl.sqos.maximum_io_rate", FT_UINT64, BASE_DEC,
11050 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 }
11053 { &hf_smb2_ioctl_sqos_minimum_io_rate,
11054 { "MinimumIoRate", "smb2.ioctl.sqos.minimum_io_rate", FT_UINT64, BASE_DEC,
11055 NULL, 0, "The minimum I/O completion rate currently assigned to the logical flow, expressed in normalized IOPS", HFILL }
11058 { &hf_smb2_ioctl_sqos_base_io_size,
11059 { "BaseIoSize", "smb2.ioctl.sqos.base_io_size", FT_UINT32, BASE_DEC,
11060 NULL, 0, "The base I/O size used to compute the normalized size of an I/O request for the logical flow", HFILL }
11063 { &hf_smb2_ioctl_sqos_reserved2,
11064 { "Reserved", "smb2.ioctl.sqos.reserved2", FT_UINT32, BASE_DEC,
11065 NULL, 0, NULL, HFILL }
11068 { &hf_smb2_ioctl_sqos_maximum_bandwidth,
11069 { "MaximumBandwidth", "smb2.ioctl.sqos.maximum_bandwidth", FT_UINT64, BASE_DEC,
11070 NULL, 0, "The maximum bandwidth currently assigned to the logical flow, expressed in kilobytes per second", HFILL }
11074 { &hf_windows_sockaddr_family,
11075 { "Socket Family", "smb2.windows.sockaddr.family", FT_UINT16, BASE_DEC,
11076 NULL, 0, "The socket address family (on windows)", HFILL }
11079 { &hf_windows_sockaddr_port,
11080 { "Socket Port", "smb2.windows.sockaddr.port", FT_UINT16, BASE_DEC,
11081 NULL, 0, "The socket address port", HFILL }
11084 { &hf_windows_sockaddr_in_addr,
11085 { "Socket IPv4", "smb2.windows.sockaddr.in.addr", FT_IPv4, BASE_NONE,
11086 NULL, 0, "The IPv4 address", HFILL }
11089 { &hf_windows_sockaddr_in6_flowinfo,
11090 { "IPv6 Flow Info", "smb2.windows.sockaddr.in6.flow_info", FT_UINT32, BASE_HEX,
11091 NULL, 0, "The socket IPv6 flow info", HFILL }
11094 { &hf_windows_sockaddr_in6_addr,
11095 { "Socket IPv6", "smb2.windows.sockaddr.in6.addr", FT_IPv6, BASE_NONE,
11096 NULL, 0, "The IPv6 address", HFILL }
11099 { &hf_windows_sockaddr_in6_scope_id,
11100 { "IPv6 Scope ID", "smb2.windows.sockaddr.in6.scope_id", FT_UINT32, BASE_DEC,
11101 NULL, 0, "The socket IPv6 scope id", HFILL }
11104 { &hf_smb2_ioctl_network_interface_next_offset,
11105 { "Next Offset", "smb2.ioctl.network_interfaces.next_offset", FT_UINT32, BASE_HEX,
11106 NULL, 0, "Offset to next entry in chain or 0", HFILL }
11109 { &hf_smb2_ioctl_network_interface_index,
11110 { "Interface Index", "smb2.ioctl.network_interfaces.index", FT_UINT32, BASE_DEC,
11111 NULL, 0, "The index of the interface", HFILL }
11114 { &hf_smb2_ioctl_network_interface_rss_queue_count,
11115 { "RSS Queue Count", "smb2.ioctl.network_interfaces.rss_queue_count", FT_UINT32, BASE_DEC,
11116 NULL, 0, "The RSS queue count", HFILL }
11119 { &hf_smb2_ioctl_network_interface_capabilities,
11120 { "Interface Cababilities", "smb2.ioctl.network_interfaces.capabilities", FT_UINT32, BASE_HEX,
11121 NULL, 0, "The capabilities of the network interface", HFILL }
11124 { &hf_smb2_ioctl_network_interface_capability_rss,
11125 { "RSS", "smb2.ioctl.network_interfaces.capabilities.rss", FT_BOOLEAN, 32,
11126 TFS(&tfs_smb2_ioctl_network_interface_capability_rss), NETWORK_INTERFACE_CAP_RSS, "If the host supports RSS", HFILL }
11129 { &hf_smb2_ioctl_network_interface_capability_rdma,
11130 { "RDMA", "smb2.ioctl.network_interfaces.capabilities.rdma", FT_BOOLEAN, 32,
11131 TFS(&tfs_smb2_ioctl_network_interface_capability_rdma), NETWORK_INTERFACE_CAP_RDMA, "If the host supports RDMA", HFILL }
11134 { &hf_smb2_ioctl_network_interface_link_speed,
11135 { "Link Speed", "smb2.ioctl.network_interfaces.link_speed", FT_UINT64, BASE_DEC,
11136 NULL, 0, "The link speed of the interface", HFILL }
11139 { &hf_smb2_ioctl_enumerate_snapshots_num_snapshots,
11140 { "Number of snapshots", "smb2.ioctl.enumerate_snapshots.num_snapshots", FT_UINT32, BASE_DEC,
11141 NULL, 0, "Number of previous versions associated with the volume", HFILL }
11144 { &hf_smb2_ioctl_enumerate_snapshots_num_snapshots_returned,
11145 { "Number of snapshots returned", "smb2.ioctl.enumerate_snapshots.num_snapshots_returned", FT_UINT32, BASE_DEC,
11146 NULL, 0, "Number of previous version time stamps returned", HFILL }
11149 { &hf_smb2_ioctl_enumerate_snapshots_snapshot_array_size,
11150 { "Array size", "smb2.ioctl.enumerate_snapshots.array_size", FT_UINT32, BASE_DEC,
11151 NULL, 0, "Number of bytes for snapshot time stamp strings", HFILL }
11154 { &hf_smb2_ioctl_enumerate_snapshots_snapshot,
11155 { "Snapshot", "smb2.ioctl.enumerate_snapshots.snapshot", FT_STRINGZ, STR_UNICODE,
11156 NULL, 0, "Time stamp of previous version", HFILL }
11159 { &hf_smb2_compression_format,
11160 { "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
11161 VALS(compression_format_vals), 0, NULL, HFILL }
11164 { &hf_smb2_checksum_algorithm,
11165 { "Checksum Algorithm", "smb2.checksum_algorithm", FT_UINT16, BASE_HEX,
11166 VALS(checksum_algorithm_vals), 0, NULL, HFILL }
11169 { &hf_smb2_integrity_reserved,
11170 { "Reserved", "smb2.integrity_reserved", FT_UINT16, BASE_DEC,
11171 NULL, 0, NULL, HFILL }
11174 { &hf_smb2_integrity_flags,
11175 { "Flags", "smb2.integrity_flags", FT_UINT32, BASE_HEX,
11176 NULL, 0, NULL, HFILL }
11179 { &hf_smb2_integrity_flags_enforcement_off,
11180 { "FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF", "smb2.integrity_flags_enforcement", FT_BOOLEAN, 32,
11181 NULL, 0x1, "If checksum error enforcement is off", HFILL }
11184 { &hf_smb2_share_type,
11185 { "Share Type", "smb2.share_type", FT_UINT8, BASE_HEX,
11186 VALS(smb2_share_type_vals), 0, "Type of share", HFILL }
11189 { &hf_smb2_credit_charge,
11190 { "Credit Charge", "smb2.credit.charge", FT_UINT16, BASE_DEC,
11191 NULL, 0, NULL, HFILL }
11194 { &hf_smb2_credits_requested,
11195 { "Credits requested", "smb2.credits.requested", FT_UINT16, BASE_DEC,
11196 NULL, 0, NULL, HFILL }
11199 { &hf_smb2_credits_granted,
11200 { "Credits granted", "smb2.credits.granted", FT_UINT16, BASE_DEC,
11201 NULL, 0, NULL, HFILL }
11204 { &hf_smb2_channel_sequence,
11205 { "Channel Sequence", "smb2.channel_sequence", FT_UINT16, BASE_DEC,
11206 NULL, 0, NULL, HFILL }
11209 { &hf_smb2_dialect_count,
11210 { "Dialect count", "smb2.dialect_count", FT_UINT16, BASE_DEC,
11211 NULL, 0, NULL, HFILL }
11214 { &hf_smb2_dialect,
11215 { "Dialect", "smb2.dialect", FT_UINT16, BASE_HEX,
11216 NULL, 0, NULL, HFILL }
11219 { &hf_smb2_security_mode,
11220 { "Security mode", "smb2.sec_mode", FT_UINT8, BASE_HEX,
11221 NULL, 0, NULL, HFILL }
11224 { &hf_smb2_session_flags,
11225 { "Session Flags", "smb2.session_flags", FT_UINT16, BASE_HEX,
11226 NULL, 0, NULL, HFILL }
11229 { &hf_smb2_lock_count,
11230 { "Lock Count", "smb2.lock_count", FT_UINT16, BASE_DEC,
11231 NULL, 0, NULL, HFILL }
11234 { &hf_smb2_capabilities,
11235 { "Capabilities", "smb2.capabilities", FT_UINT32, BASE_HEX,
11236 NULL, 0, NULL, HFILL }
11239 { &hf_smb2_auth_frame,
11240 { "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
11241 NULL, 0, "Which frame this user was authenticated in", HFILL }
11244 { &hf_smb2_tcon_frame,
11245 { "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
11246 NULL, 0, "Which frame this share was connected in", HFILL }
11249 { &hf_smb2_tag,
11250 { "Tag", "smb2.tag", FT_STRING, STR_UNICODE,
11251 NULL, 0, "Tag of chain entry", HFILL }
11254 { &hf_smb2_acct_name,
11255 { "Account", "smb2.acct", FT_STRING, STR_UNICODE,
11256 NULL, 0, "Account Name", HFILL }
11259 { &hf_smb2_domain_name,
11260 { "Domain", "smb2.domain", FT_STRING, STR_UNICODE,
11261 NULL, 0, "Domain Name", HFILL }
11264 { &hf_smb2_host_name,
11265 { "Host", "smb2.host", FT_STRING, STR_UNICODE,
11266 NULL, 0, "Host Name", HFILL }
11269 { &hf_smb2_signature,
11270 { "Signature", "smb2.signature", FT_BYTES, BASE_NONE,
11271 NULL, 0, NULL, HFILL }
11274 { &hf_smb2_unknown,
11275 { "Unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
11276 NULL, 0, NULL, HFILL }
11279 { &hf_smb2_twrp_timestamp,
11280 { "Timestamp", "smb2.twrp_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
11281 NULL, 0, "TWrp timestamp", HFILL }
11284 { &hf_smb2_mxac_timestamp,
11285 { "Timestamp", "smb2.mxac_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
11286 NULL, 0, "MxAc timestamp", HFILL }
11289 { &hf_smb2_mxac_status,
11290 { "Query Status", "smb2.mxac_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
11291 &NT_errors_ext, 0, "NT Status code", HFILL }
11294 { &hf_smb2_qfid_fid,
11295 { "Opaque File ID", "smb2.qfid_fid", FT_BYTES, BASE_NONE,
11296 NULL, 0, NULL, HFILL }
11299 { &hf_smb2_ses_flags_guest,
11300 { "Guest", "smb2.ses_flags.guest", FT_BOOLEAN, 16,
11301 NULL, SES_FLAGS_GUEST, NULL, HFILL }
11304 { &hf_smb2_ses_flags_null,
11305 { "Null", "smb2.ses_flags.null", FT_BOOLEAN, 16,
11306 NULL, SES_FLAGS_NULL, NULL, HFILL }
11309 { &hf_smb2_ses_flags_encrypt,
11310 { "Encrypt", "smb2.ses_flags.encrypt", FT_BOOLEAN, 16,
11311 NULL, SES_FLAGS_ENCRYPT, NULL, HFILL }},
11313 { &hf_smb2_secmode_flags_sign_required,
11314 { "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
11315 NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }
11318 { &hf_smb2_secmode_flags_sign_enabled,
11319 { "Signing enabled", "smb2.sec_mode.sign_enabled", FT_BOOLEAN, 8,
11320 NULL, NEGPROT_SIGN_ENABLED, "Is signing enabled", HFILL }
11323 { &hf_smb2_ses_req_flags,
11324 { "Flags", "smb2.ses_req_flags", FT_UINT8, BASE_DEC,
11325 NULL, 0, NULL, HFILL }
11328 { &hf_smb2_ses_req_flags_session_binding,
11329 { "Session Binding Request", "smb2.ses_req_flags.session_binding", FT_BOOLEAN, 8,
11330 NULL, SES_REQ_FLAGS_SESSION_BINDING, "The client wants to bind to an existing session", HFILL }
11333 { &hf_smb2_cap_dfs,
11334 { "DFS", "smb2.capabilities.dfs", FT_BOOLEAN, 32,
11335 TFS(&tfs_cap_dfs), NEGPROT_CAP_DFS, "If the host supports dfs", HFILL }
11338 { &hf_smb2_cap_leasing,
11339 { "LEASING", "smb2.capabilities.leasing", FT_BOOLEAN, 32,
11340 TFS(&tfs_cap_leasing), NEGPROT_CAP_LEASING, "If the host supports leasing", HFILL }
11343 { &hf_smb2_cap_large_mtu,
11344 { "LARGE MTU", "smb2.capabilities.large_mtu", FT_BOOLEAN, 32,
11345 TFS(&tfs_cap_large_mtu), NEGPROT_CAP_LARGE_MTU, "If the host supports LARGE MTU", HFILL }
11348 { &hf_smb2_cap_multi_channel,
11349 { "MULTI CHANNEL", "smb2.capabilities.multi_channel", FT_BOOLEAN, 32,
11350 TFS(&tfs_cap_multi_channel), NEGPROT_CAP_MULTI_CHANNEL, "If the host supports MULTI CHANNEL", HFILL }
11353 { &hf_smb2_cap_persistent_handles,
11354 { "PERSISTENT HANDLES", "smb2.capabilities.persistent_handles", FT_BOOLEAN, 32,
11355 TFS(&tfs_cap_persistent_handles), NEGPROT_CAP_PERSISTENT_HANDLES, "If the host supports PERSISTENT HANDLES", HFILL }
11358 { &hf_smb2_cap_directory_leasing,
11359 { "DIRECTORY LEASING", "smb2.capabilities.directory_leasing", FT_BOOLEAN, 32,
11360 TFS(&tfs_cap_directory_leasing), NEGPROT_CAP_DIRECTORY_LEASING, "If the host supports DIRECTORY LEASING", HFILL }
11363 { &hf_smb2_cap_encryption,
11364 { "ENCRYPTION", "smb2.capabilities.encryption", FT_BOOLEAN, 32,
11365 TFS(&tfs_cap_encryption), NEGPROT_CAP_ENCRYPTION, "If the host supports ENCRYPTION", HFILL }
11368 { &hf_smb2_max_trans_size,
11369 { "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
11370 NULL, 0, NULL, HFILL }
11373 { &hf_smb2_max_read_size,
11374 { "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
11375 NULL, 0, NULL, HFILL }
11378 { &hf_smb2_max_write_size,
11379 { "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
11380 NULL, 0, NULL, HFILL }
11383 { &hf_smb2_channel,
11384 { "Channel", "smb2.channel", FT_UINT32, BASE_HEX,
11385 VALS(smb2_channel_vals), 0, NULL, HFILL }
11388 { &hf_smb2_rdma_v1_offset,
11389 { "Offset", "smb2.buffer_descriptor.offset", FT_UINT64, BASE_DEC,
11390 NULL, 0, NULL, HFILL }
11393 { &hf_smb2_rdma_v1_token,
11394 { "Token", "smb2.buffer_descriptor.token", FT_UINT32, BASE_HEX,
11395 NULL, 0, NULL, HFILL }
11398 { &hf_smb2_rdma_v1_length,
11399 { "Length", "smb2.buffer_descriptor.length", FT_UINT32, BASE_DEC,
11400 NULL, 0, NULL, HFILL }
11403 { &hf_smb2_share_flags,
11404 { "Share flags", "smb2.share_flags", FT_UINT32, BASE_HEX,
11405 NULL, 0, NULL, HFILL }
11408 { &hf_smb2_share_flags_dfs,
11409 { "DFS", "smb2.share_flags.dfs", FT_BOOLEAN, 32,
11410 NULL, SHARE_FLAGS_dfs, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }
11413 { &hf_smb2_share_flags_dfs_root,
11414 { "DFS root", "smb2.share_flags.dfs_root", FT_BOOLEAN, 32,
11415 NULL, SHARE_FLAGS_dfs_root, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }
11418 { &hf_smb2_share_flags_restrict_exclusive_opens,
11419 { "Restrict exclusive opens", "smb2.share_flags.restrict_exclusive_opens", FT_BOOLEAN, 32,
11420 NULL, SHARE_FLAGS_restrict_exclusive_opens, "The specified share disallows exclusive file opens that deny reads to an open file", HFILL }
11423 { &hf_smb2_share_flags_force_shared_delete,
11424 { "Force shared delete", "smb2.share_flags.force_shared_delete", FT_BOOLEAN, 32,
11425 NULL, SHARE_FLAGS_force_shared_delete, "Shared files in the specified share can be forcibly deleted", HFILL }
11428 { &hf_smb2_share_flags_allow_namespace_caching,
11429 { "Allow namepsace caching", "smb2.share_flags.allow_namespace_caching", FT_BOOLEAN, 32,
11430 NULL, SHARE_FLAGS_allow_namespace_caching, "Clients are allowed to cache the namespace of the specified share", HFILL }
11433 { &hf_smb2_share_flags_access_based_dir_enum,
11434 { "Access based directory enum", "smb2.share_flags.access_based_dir_enum", FT_BOOLEAN, 32,
11435 NULL, SHARE_FLAGS_access_based_dir_enum, "The server will filter directory entries based on the access permissions of the client", HFILL }
11438 { &hf_smb2_share_flags_force_levelii_oplock,
11439 { "Force level II oplock", "smb2.share_flags.force_levelii_oplock", FT_BOOLEAN, 32,
11440 NULL, SHARE_FLAGS_force_levelii_oplock, "The server will not issue exclusive caching rights on this share", HFILL }
11443 { &hf_smb2_share_flags_enable_hash_v1,
11444 { "Enable hash V1", "smb2.share_flags.enable_hash_v1", FT_BOOLEAN, 32,
11445 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 }
11448 { &hf_smb2_share_flags_enable_hash_v2,
11449 { "Enable hash V2", "smb2.share_flags.enable_hash_v2", FT_BOOLEAN, 32,
11450 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 }
11453 { &hf_smb2_share_flags_encrypt_data,
11454 { "Encrypted data required", "smb2.share_flags.encrypt_data", FT_BOOLEAN, 32,
11455 NULL, SHARE_FLAGS_encryption_required, "The share require data encryption", HFILL }
11458 { &hf_smb2_share_caching,
11459 { "Caching policy", "smb2.share.caching", FT_UINT32, BASE_HEX,
11460 VALS(share_cache_vals), 0, NULL, HFILL }
11463 { &hf_smb2_share_caps,
11464 { "Share Capabilities", "smb2.share_caps", FT_UINT32, BASE_HEX,
11465 NULL, 0, NULL, HFILL }
11468 { &hf_smb2_share_caps_dfs,
11469 { "DFS", "smb2.share_caps.dfs", FT_BOOLEAN, 32,
11470 NULL, SHARE_CAPS_DFS, "The specified share is present in a DFS tree structure", HFILL }
11473 { &hf_smb2_share_caps_continuous_availability,
11474 { "CONTINUOUS AVAILABILITY", "smb2.share_caps.continuous_availability", FT_BOOLEAN, 32,
11475 NULL, SHARE_CAPS_CONTINUOUS_AVAILABILITY, "The specified share is continuously available", HFILL }
11478 { &hf_smb2_share_caps_scaleout,
11479 { "SCALEOUT", "smb2.share_caps.scaleout", FT_BOOLEAN, 32,
11480 NULL, SHARE_CAPS_SCALEOUT, "The specified share is a scaleout share", HFILL }
11483 { &hf_smb2_share_caps_cluster,
11484 { "CLUSTER", "smb2.share_caps.cluster", FT_BOOLEAN, 32,
11485 NULL, SHARE_CAPS_CLUSTER, "The specified share is a cluster share", HFILL }
11488 { &hf_smb2_ioctl_flags,
11489 { "Flags", "smb2.ioctl.flags", FT_UINT32, BASE_HEX,
11490 NULL, 0, NULL, HFILL }
11493 { &hf_smb2_min_count,
11494 { "Min Count", "smb2.min_count", FT_UINT32, BASE_DEC,
11495 NULL, 0, NULL, HFILL }
11498 { &hf_smb2_remaining_bytes,
11499 { "Remaining Bytes", "smb2.remaining_bytes", FT_UINT32, BASE_DEC,
11500 NULL, 0, NULL, HFILL }
11503 { &hf_smb2_channel_info_offset,
11504 { "Channel Info Offset", "smb2.channel_info_offset", FT_UINT16, BASE_DEC,
11505 NULL, 0, NULL, HFILL }
11508 { &hf_smb2_channel_info_length,
11509 { "Channel Info Length", "smb2.channel_info_length", FT_UINT16, BASE_DEC,
11510 NULL, 0, NULL, HFILL }
11513 { &hf_smb2_channel_info_blob,
11514 { "Channel Info Blob", "smb2.channel_info_blob", FT_NONE, BASE_NONE,
11515 NULL, 0, NULL, HFILL }
11518 { &hf_smb2_ioctl_is_fsctl,
11519 { "Is FSCTL", "smb2.ioctl.is_fsctl", FT_BOOLEAN, 32,
11520 NULL, 0x00000001, NULL, HFILL }
11523 { &hf_smb2_output_buffer_len,
11524 { "Output Buffer Length", "smb2.output_buffer_len", FT_UINT16, BASE_DEC,
11525 NULL, 0, NULL, HFILL }
11528 { &hf_smb2_close_pq_attrib,
11529 { "PostQuery Attrib", "smb2.close.pq_attrib", FT_BOOLEAN, 16,
11530 NULL, 0x0001, NULL, HFILL }
11533 { &hf_smb2_notify_watch_tree,
11534 { "Watch Tree", "smb2.notify.watch_tree", FT_BOOLEAN, 16,
11535 NULL, 0x0001, NULL, HFILL }
11538 { &hf_smb2_notify_out_data,
11539 { "Out Data", "smb2.notify.out", FT_NONE, BASE_NONE,
11540 NULL, 0, NULL, HFILL }
11543 { &hf_smb2_notify_info,
11544 { "Notify Info", "smb2.notify.info", FT_NONE, BASE_NONE,
11545 NULL, 0, NULL, HFILL }
11548 { &hf_smb2_notify_next_offset,
11549 { "Next Offset", "smb2.notify.next_offset", FT_UINT32, BASE_HEX,
11550 NULL, 0, "Offset to next entry in chain or 0", HFILL }
11553 { &hf_smb2_notify_action,
11554 { "Action", "smb2.notify.action", FT_UINT32, BASE_HEX,
11555 VALS(notify_action_vals), 0, "Notify Action", HFILL }
11559 { &hf_smb2_find_flags_restart_scans,
11560 { "Restart Scans", "smb2.find.restart_scans", FT_BOOLEAN, 8,
11561 NULL, SMB2_FIND_FLAG_RESTART_SCANS, NULL, HFILL }
11564 { &hf_smb2_find_flags_single_entry,
11565 { "Single Entry", "smb2.find.single_entry", FT_BOOLEAN, 8,
11566 NULL, SMB2_FIND_FLAG_SINGLE_ENTRY, NULL, HFILL }
11569 { &hf_smb2_find_flags_index_specified,
11570 { "Index Specified", "smb2.find.index_specified", FT_BOOLEAN, 8,
11571 NULL, SMB2_FIND_FLAG_INDEX_SPECIFIED, NULL, HFILL }
11574 { &hf_smb2_find_flags_reopen,
11575 { "Reopen", "smb2.find.reopen", FT_BOOLEAN, 8,
11576 NULL, SMB2_FIND_FLAG_REOPEN, NULL, HFILL }
11579 { &hf_smb2_file_index,
11580 { "File Index", "smb2.file_index", FT_UINT32, BASE_HEX,
11581 NULL, 0, NULL, HFILL }
11584 { &hf_smb2_file_directory_info,
11585 { "FileDirectoryInfo", "smb2.find.file_directory_info", FT_NONE, BASE_NONE,
11586 NULL, 0, NULL, HFILL }
11589 { &hf_smb2_full_directory_info,
11590 { "FullDirectoryInfo", "smb2.find.full_directory_info", FT_NONE, BASE_NONE,
11591 NULL, 0, NULL, HFILL }
11594 { &hf_smb2_both_directory_info,
11595 { "FileBothDirectoryInfo", "smb2.find.both_directory_info", FT_NONE, BASE_NONE,
11596 NULL, 0, NULL, HFILL }
11599 { &hf_smb2_id_both_directory_info,
11600 { "FileIdBothDirectoryInfo", "smb2.find.id_both_directory_info", FT_NONE, BASE_NONE,
11601 NULL, 0, NULL, HFILL }
11604 { &hf_smb2_short_name_len,
11605 { "Short Name Length", "smb2.short_name_len", FT_UINT8, BASE_DEC,
11606 NULL, 0, NULL, HFILL }
11609 { &hf_smb2_short_name,
11610 { "Short Name", "smb2.shortname", FT_STRING, STR_UNICODE,
11611 NULL, 0, NULL, HFILL }
11614 { &hf_smb2_lock_info,
11615 { "Lock Info", "smb2.lock_info", FT_NONE, BASE_NONE,
11616 NULL, 0, NULL, HFILL }
11619 { &hf_smb2_lock_length,
11620 { "Length", "smb2.lock_length", FT_UINT64, BASE_DEC,
11621 NULL, 0, NULL, HFILL }
11624 { &hf_smb2_lock_flags,
11625 { "Flags", "smb2.lock_flags", FT_UINT32, BASE_HEX,
11626 NULL, 0, NULL, HFILL }
11629 { &hf_smb2_lock_flags_shared,
11630 { "Shared", "smb2.lock_flags.shared", FT_BOOLEAN, 32,
11631 NULL, 0x00000001, NULL, HFILL }
11634 { &hf_smb2_lock_flags_exclusive,
11635 { "Exclusive", "smb2.lock_flags.exclusive", FT_BOOLEAN, 32,
11636 NULL, 0x00000002, NULL, HFILL }
11639 { &hf_smb2_lock_flags_unlock,
11640 { "Unlock", "smb2.lock_flags.unlock", FT_BOOLEAN, 32,
11641 NULL, 0x00000004, NULL, HFILL }
11644 { &hf_smb2_lock_flags_fail_immediately,
11645 { "Fail Immediately", "smb2.lock_flags.fail_immediately", FT_BOOLEAN, 32,
11646 NULL, 0x00000010, NULL, HFILL }
11649 { &hf_smb2_error_context_count,
11650 { "Error Context Count", "smb2.error.context_count", FT_UINT8, BASE_DEC,
11651 NULL, 0, NULL, HFILL }
11654 { &hf_smb2_error_reserved,
11655 { "Reserved", "smb2.error.reserved", FT_UINT8, BASE_HEX,
11656 NULL, 0, NULL, HFILL }
11659 { &hf_smb2_error_byte_count,
11660 { "Byte Count", "smb2.error.byte_count", FT_UINT32, BASE_DEC,
11661 NULL, 0, NULL, HFILL }
11664 { &hf_smb2_error_data,
11665 { "Error Data", "smb2.error.data", FT_BYTES, BASE_NONE,
11666 NULL, 0, NULL, HFILL }
11669 { &hf_smb2_error_context,
11670 { "Error Context", "smb2.error.context", FT_BYTES, BASE_NONE,
11671 NULL, 0, NULL, HFILL }
11674 { &hf_smb2_error_context_id,
11675 { "Type", "smb2.error.context.id", FT_UINT32, BASE_HEX,
11676 VALS(smb2_error_id_vals), 0, NULL, HFILL }
11679 { &hf_smb2_error_context_length,
11680 { "Type", "smb2.error.context.length", FT_UINT32, BASE_DEC,
11681 NULL, 0, NULL, HFILL }
11684 { &hf_smb2_error_min_buf_length,
11685 { "Minimum required buffer length", "smb2.error.min_buf_length", FT_UINT32, BASE_DEC,
11686 NULL, 0, NULL, HFILL }
11689 { &hf_smb2_error_redir_context,
11690 { "Share Redirect", "smb2.error.share_redirect", FT_NONE, BASE_NONE,
11691 NULL, 0, NULL, HFILL }
11694 { &hf_smb2_error_redir_struct_size,
11695 { "Struct Size", "smb2.error.share_redirect.struct_size", FT_UINT32, BASE_DEC,
11696 NULL, 0, NULL, HFILL }
11699 { &hf_smb2_error_redir_notif_type,
11700 { "Notification Type", "smb2.error.share_redirect.notif_type", FT_UINT32, BASE_DEC,
11701 NULL, 0, NULL, HFILL }
11704 { &hf_smb2_error_redir_flags,
11705 { "Flags", "smb2.error.share_redirect.flags", FT_UINT16, BASE_HEX,
11706 NULL, 0, NULL, HFILL }
11709 { &hf_smb2_error_redir_target_type,
11710 { "Target Type", "smb2.error.share_redirect.target_type", FT_UINT16, BASE_HEX,
11711 NULL, 0, NULL, HFILL }
11714 { &hf_smb2_error_redir_ip_count,
11715 { "IP Addr Count", "smb2.error.share_redirect.ip_count", FT_UINT32, BASE_DEC,
11716 NULL, 0, NULL, HFILL }
11719 { &hf_smb2_error_redir_ip_list,
11720 { "IP Addr List", "smb2.error.share_redirect.ip_list", FT_NONE, BASE_NONE,
11721 NULL, 0, NULL, HFILL }
11724 { &hf_smb2_error_redir_res_name,
11725 { "Resourse Name", "smb2.error.share_redirect.res_name", FT_STRING, STR_UNICODE,
11726 NULL, 0, NULL, HFILL }
11729 { &hf_smb2_reserved,
11730 { "Reserved", "smb2.reserved", FT_BYTES, BASE_NONE,
11731 NULL, 0, NULL, HFILL }
11734 { &hf_smb2_reserved_random,
11735 { "Reserved (Random)", "smb2.reserved.random", FT_BYTES, BASE_NONE,
11736 NULL, 0, "Reserved bytes, random data", HFILL }
11739 { &hf_smb2_root_directory_mbz,
11740 { "Root Dir Handle (MBZ)", "smb2.root_directory", FT_BYTES, BASE_NONE,
11741 NULL, 0, NULL, HFILL }
11744 { &hf_smb2_dhnq_buffer_reserved,
11745 { "Reserved", "smb2.dhnq_buffer_reserved", FT_UINT64, BASE_HEX,
11746 NULL, 0, NULL, HFILL }
11749 { &hf_smb2_dh2x_buffer_timeout,
11750 { "Timeout", "smb2.dh2x.timeout", FT_UINT32, BASE_DEC,
11751 NULL, 0, NULL, HFILL }
11754 { &hf_smb2_dh2x_buffer_flags,
11755 { "Flags", "smb2.dh2x.flags", FT_UINT32, BASE_HEX,
11756 NULL, 0, NULL, HFILL }
11759 { &hf_smb2_dh2x_buffer_flags_persistent_handle,
11760 { "Persistent Handle", "smb2.dh2x.flags.persistent_handle", FT_BOOLEAN, 32,
11761 NULL, SMB2_DH2X_FLAGS_PERSISTENT_HANDLE, NULL, HFILL }
11764 { &hf_smb2_dh2x_buffer_reserved,
11765 { "Reserved", "smb2.dh2x.reserved", FT_UINT64, BASE_HEX,
11766 NULL, 0, NULL, HFILL }
11769 { &hf_smb2_dh2x_buffer_create_guid,
11770 { "Create Guid", "smb2.dh2x.create_guid", FT_GUID, BASE_NONE,
11771 NULL, 0, NULL, HFILL }
11774 { &hf_smb2_APP_INSTANCE_buffer_struct_size,
11775 { "Struct Size", "smb2.app_instance.struct_size", FT_UINT16, BASE_DEC,
11776 NULL, 0, NULL, HFILL }
11779 { &hf_smb2_APP_INSTANCE_buffer_reserved,
11780 { "Reserved", "smb2.app_instance.reserved", FT_UINT16, BASE_HEX,
11781 NULL, 0, NULL, HFILL }
11784 { &hf_smb2_APP_INSTANCE_buffer_app_guid,
11785 { "Application Guid", "smb2.app_instance.app_guid", FT_GUID, BASE_NONE,
11786 NULL, 0, NULL, HFILL }
11789 { &hf_smb2_svhdx_open_device_context_version,
11790 { "Version", "smb2.svhdx_open_device_context.version", FT_UINT32, BASE_DEC,
11791 NULL, 0, NULL, HFILL }
11794 { &hf_smb2_svhdx_open_device_context_has_initiator_id,
11795 { "HasInitiatorId", "smb2.svhdx_open_device_context.initiator_has_id", FT_BOOLEAN, 8,
11796 TFS(&tfs_smb2_svhdx_has_initiator_id), 0, "Whether the host has an intiator", HFILL }
11799 { &hf_smb2_svhdx_open_device_context_reserved,
11800 { "Reserved", "smb2.svhdx_open_device_context.reserved", FT_BYTES, BASE_NONE,
11801 NULL, 0, NULL, HFILL }
11804 { &hf_smb2_svhdx_open_device_context_initiator_id,
11805 { "InitiatorId", "smb2.svhdx_open_device_context.initiator_id", FT_GUID, BASE_NONE,
11806 NULL, 0, NULL, HFILL }
11809 { &hf_smb2_svhdx_open_device_context_flags,
11810 { "Flags", "smb2.svhdx_open_device_context.flags", FT_UINT32, BASE_HEX,
11811 NULL, 0, NULL, HFILL }
11814 { &hf_smb2_svhdx_open_device_context_originator_flags,
11815 { "OriginatorFlags", "smb2.svhdx_open_device_context.originator_flags", FT_UINT32, BASE_HEX,
11816 VALS(originator_flags_vals), 0, NULL, HFILL }
11819 { &hf_smb2_svhdx_open_device_context_open_request_id,
11820 { "OpenRequestId","smb2.svhxd_open_device_context.open_request_id", FT_UINT64, BASE_HEX,
11821 NULL, 0, NULL, HFILL }
11824 { &hf_smb2_svhdx_open_device_context_initiator_host_name_len,
11825 { "HostNameLength", "smb2.svhxd_open_device_context.initiator_host_name_len", FT_UINT16, BASE_DEC,
11826 NULL, 0, NULL, HFILL }
11829 { &hf_smb2_svhdx_open_device_context_initiator_host_name,
11830 { "HostName", "smb2.svhdx_open_device_context.host_name", FT_STRING, STR_UNICODE,
11831 NULL, 0, NULL, HFILL }
11834 { &hf_smb2_svhdx_open_device_context_virtual_disk_properties_initialized,
11835 { "VirtualDiskPropertiesInitialized", "smb2.svhdx_open_device_context.virtual_disk_properties_initialized", FT_BOOLEAN, 32,
11836 NULL, 0, "Whether VirtualSectorSize, PhysicalSectorSize, and VirtualSize fields are filled", HFILL }
11839 { &hf_smb2_svhdx_open_device_context_server_service_version,
11840 { "ServerServiceVersion", "smb2.svhdx_open_device_context.server_service_version", FT_UINT32, BASE_DEC,
11841 NULL, 0, "The current version of the protocol running on the server", HFILL }
11844 { &hf_smb2_svhdx_open_device_context_virtual_sector_size,
11845 { "VirtualSectorSize", "smb2.svhdx_open_device_context.virtual_sector_size", FT_UINT32, BASE_DEC,
11846 NULL, 0, "The virtual sector size of the virtual disk", HFILL }
11849 { &hf_smb2_svhdx_open_device_context_physical_sector_size,
11850 { "PhysicalSectorSize", "smb2.svhdx_open_device_context.physical_sector_size", FT_UINT32, BASE_DEC,
11851 NULL, 0, "The physical sector size of the virtual disk", HFILL }
11854 { &hf_smb2_svhdx_open_device_context_virtual_size,
11855 { "VirtualSize", "smb2.svhdx_open_device_context.virtual_size", FT_UINT64, BASE_DEC,
11856 NULL, 0, "The current length of the virtual disk, in bytes", HFILL }
11859 { &hf_smb2_posix_v1_version,
11860 { "Version", "smb2.posix_v1_version", FT_UINT32, BASE_DEC,
11861 NULL, 0, NULL, HFILL }
11864 { &hf_smb2_posix_v1_request,
11865 { "Request", "smb2.posix_request", FT_UINT32, BASE_HEX,
11866 NULL, 0, NULL, HFILL }
11869 { &hf_smb2_posix_v1_case_sensitive,
11870 { "Posix Case Sensitive File Names", "smb2.posix_case_sensitive", FT_UINT32, BASE_HEX,
11871 VALS(posix_case_sensitive_vals), 0x01, NULL, HFILL }
11874 { &hf_smb2_posix_v1_posix_lock,
11875 { "Posix Byte-Range Locks", "smb2.posix_locks", FT_UINT32, BASE_HEX,
11876 VALS(posix_locks_vals), 0x02, NULL, HFILL }
11879 { &hf_smb2_posix_v1_posix_file_semantics,
11880 { "Posix File Semantics", "smb2.posix_file_semantics", FT_UINT32, BASE_HEX,
11881 VALS(posix_file_semantics_vals), 0x04, NULL, HFILL }
11884 { &hf_smb2_posix_v1_posix_utf8_paths,
11885 { "Posix UTF8 Paths", "smb2.posix_utf8_paths", FT_UINT32, BASE_HEX,
11886 VALS(posix_utf8_paths_vals), 0x08, NULL, HFILL }
11889 { &hf_smb2_posix_v1_posix_will_convert_nt_acls,
11890 { "Posix Will Convert NT ACLs", "smb2.will_convert_NTACLs", FT_UINT32, BASE_HEX,
11891 VALS(posix_will_convert_ntacls_vals), 0x10, NULL, HFILL }
11894 { &hf_smb2_posix_v1_posix_fileinfo,
11895 { "Posix Fileinfo", "smb2.posix_fileinfo", FT_UINT32, BASE_HEX,
11896 VALS(posix_fileinfo_vals), 0x20, NULL, HFILL }
11899 { &hf_smb2_posix_v1_posix_acls,
11900 { "Posix ACLs", "smb2.posix_acls", FT_UINT32, BASE_HEX,
11901 VALS(posix_acls_vals), 0x40, NULL, HFILL }
11904 { &hf_smb2_posix_v1_rich_acls,
11905 { "Rich ACLs", "smb2.rich_acls", FT_UINT32, BASE_HEX,
11906 VALS(posix_rich_acls_vals), 0x80, NULL, HFILL }
11909 { &hf_smb2_posix_v1_supported_features,
11910 { "Supported Features", "smb2.posix_supported_features", FT_UINT32, BASE_HEX,
11911 NULL, 0, NULL, HFILL }
11914 { &hf_smb2_aapl_command_code,
11915 { "Command code", "smb2.aapl.command_code", FT_UINT32, BASE_DEC,
11916 VALS(aapl_command_code_vals), 0, NULL, HFILL }
11919 { &hf_smb2_aapl_reserved,
11920 { "Reserved", "smb2.aapl.reserved", FT_UINT32, BASE_HEX,
11921 NULL, 0, NULL, HFILL }
11924 { &hf_smb2_aapl_server_query_bitmask,
11925 { "Query bitmask", "smb2.aapl.query_bitmask", FT_UINT64, BASE_HEX,
11926 NULL, 0, NULL, HFILL }
11929 { &hf_smb2_aapl_server_query_bitmask_server_caps,
11930 { "Server capabilities", "smb2.aapl.bitmask.server_caps", FT_BOOLEAN, 64,
11931 NULL, SMB2_AAPL_SERVER_CAPS, NULL, HFILL }
11934 { &hf_smb2_aapl_server_query_bitmask_volume_caps,
11935 { "Volume capabilities", "smb2.aapl.bitmask.volume_caps", FT_BOOLEAN, 64,
11936 NULL, SMB2_AAPL_VOLUME_CAPS, NULL, HFILL }
11939 { &hf_smb2_aapl_server_query_bitmask_model_info,
11940 { "Model information", "smb2.aapl.bitmask.model_info", FT_BOOLEAN, 64,
11941 NULL, SMB2_AAPL_MODEL_INFO, NULL, HFILL }
11944 { &hf_smb2_aapl_server_query_caps,
11945 { "Client/Server capabilities", "smb2.aapl.caps", FT_UINT64, BASE_HEX,
11946 NULL, 0, NULL, HFILL }
11949 { &hf_smb2_aapl_server_query_caps_supports_read_dir_attr,
11950 { "Supports READDIRATTR", "smb2.aapl.caps.supports_read_dir_addr", FT_BOOLEAN, 64,
11951 NULL, SMB2_AAPL_SUPPORTS_READ_DIR_ATTR, NULL, HFILL }
11954 { &hf_smb2_aapl_server_query_caps_supports_osx_copyfile,
11955 { "Supports macOS copyfile", "smb2.aapl.caps.supports_osx_copyfile", FT_BOOLEAN, 64,
11956 NULL, SMB2_AAPL_SUPPORTS_OSX_COPYFILE, NULL, HFILL }
11959 { &hf_smb2_aapl_server_query_caps_unix_based,
11960 { "UNIX-based", "smb2.aapl.caps.unix_based", FT_BOOLEAN, 64,
11961 NULL, SMB2_AAPL_UNIX_BASED, NULL, HFILL }
11964 { &hf_smb2_aapl_server_query_caps_supports_nfs_ace,
11965 { "Supports NFS ACE", "smb2.aapl.supports_nfs_ace", FT_BOOLEAN, 64,
11966 NULL, SMB2_AAPL_SUPPORTS_NFS_ACE, NULL, HFILL }
11969 { &hf_smb2_aapl_server_query_volume_caps,
11970 { "Volume capabilities", "smb2.aapl.volume_caps", FT_UINT64, BASE_HEX,
11971 NULL, 0, NULL, HFILL }
11974 { &hf_smb2_aapl_server_query_volume_caps_support_resolve_id,
11975 { "Supports Resolve ID", "smb2.aapl.volume_caps.supports_resolve_id", FT_BOOLEAN, 64,
11976 NULL, SMB2_AAPL_SUPPORTS_RESOLVE_ID, NULL, HFILL }
11979 { &hf_smb2_aapl_server_query_volume_caps_case_sensitive,
11980 { "Case sensitive", "smb2.aapl.volume_caps.case_sensitive", FT_BOOLEAN, 64,
11981 NULL, SMB2_AAPL_CASE_SENSITIVE, NULL, HFILL }
11984 { &hf_smb2_aapl_server_query_volume_caps_supports_full_sync,
11985 { "Supports full sync", "smb2.aapl.volume_caps.supports_full_sync", FT_BOOLEAN, 64,
11986 NULL, SMB2_AAPL_SUPPORTS_FULL_SYNC, NULL, HFILL }
11989 { &hf_smb2_aapl_server_query_model_string,
11990 { "Model string", "smb2.aapl.model_string", FT_UINT_STRING, STR_UNICODE,
11991 NULL, 0, NULL, HFILL }
11994 { &hf_smb2_aapl_server_query_server_path,
11995 { "Server path", "smb2.aapl.server_path", FT_UINT_STRING, STR_UNICODE,
11996 NULL, 0, NULL, HFILL }
11999 { &hf_smb2_transform_signature,
12000 { "Signature", "smb2.header.transform.signature", FT_BYTES, BASE_NONE,
12001 NULL, 0, NULL, HFILL }
12004 { &hf_smb2_transform_nonce,
12005 { "Nonce", "smb2.header.transform.nonce", FT_BYTES, BASE_NONE,
12006 NULL, 0, NULL, HFILL }
12009 { &hf_smb2_transform_msg_size,
12010 { "Message size", "smb2.header.transform.msg_size", FT_UINT32, BASE_DEC,
12011 NULL, 0, NULL, HFILL }
12014 { &hf_smb2_transform_reserved,
12015 { "Reserved", "smb2.header.transform.reserved", FT_BYTES, BASE_NONE,
12016 NULL, 0, NULL, HFILL }
12019 { &hf_smb2_transform_enc_alg,
12020 { "Encryption ALG", "smb2.header.transform.encryption_alg", FT_UINT16, BASE_HEX,
12021 VALS(smb2_cipher_types), 0, NULL, HFILL }
12024 { &hf_smb2_transform_encrypted_data,
12025 { "Data", "smb2.header.transform.enc_data", FT_BYTES, BASE_NONE,
12026 NULL, 0, NULL, HFILL }
12029 { &hf_smb2_server_component_smb2,
12030 { "Server Component: SMB2", "smb2.server_component_smb2", FT_NONE, BASE_NONE,
12031 NULL, 0, NULL, HFILL }
12034 { &hf_smb2_server_component_smb2_transform,
12035 { "Server Component: SMB2_TRANSFORM", "smb2.server_component_smb2_transform", FT_NONE, BASE_NONE,
12036 NULL, 0, NULL, HFILL }
12039 { &hf_smb2_truncated,
12040 { "Truncated...", "smb2.truncated", FT_NONE, BASE_NONE,
12041 NULL, 0, NULL, HFILL }
12044 { &hf_smb2_pipe_fragment_overlap,
12045 { "Fragment overlap", "smb2.pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
12046 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }
12049 { &hf_smb2_pipe_fragment_overlap_conflict,
12050 { "Conflicting data in fragment overlap", "smb2.pipe.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE,
12051 NULL, 0x0, NULL, HFILL }
12054 { &hf_smb2_pipe_fragment_multiple_tails,
12055 { "Multiple tail fragments found", "smb2.pipe.fragment.multipletails", FT_BOOLEAN, BASE_NONE,
12056 NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }
12059 { &hf_smb2_pipe_fragment_too_long_fragment,
12060 { "Fragment too long", "smb2.pipe.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE,
12061 NULL, 0x0, "Fragment contained data past end of packet", HFILL }
12064 { &hf_smb2_pipe_fragment_error,
12065 { "Defragmentation error", "smb2.pipe.fragment.error", FT_FRAMENUM, BASE_NONE,
12066 NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }
12069 { &hf_smb2_pipe_fragment_count,
12070 { "Fragment count", "smb2.pipe.fragment.count", FT_UINT32, BASE_DEC,
12071 NULL, 0x0, NULL, HFILL }
12074 { &hf_smb2_pipe_fragment,
12075 { "Fragment SMB2 Named Pipe", "smb2.pipe.fragment", FT_FRAMENUM, BASE_NONE,
12076 NULL, 0x0, NULL, HFILL }
12079 { &hf_smb2_pipe_fragments,
12080 { "Reassembled SMB2 Named Pipe fragments", "smb2.pipe.fragments", FT_NONE, BASE_NONE,
12081 NULL, 0x0, NULL, HFILL }
12084 { &hf_smb2_pipe_reassembled_in,
12085 { "This SMB2 Named Pipe payload is reassembled in frame", "smb2.pipe.reassembled_in", FT_FRAMENUM, BASE_NONE,
12086 NULL, 0x0, "The Named Pipe PDU is completely reassembled in this frame", HFILL }
12089 { &hf_smb2_pipe_reassembled_length,
12090 { "Reassembled SMB2 Named Pipe length", "smb2.pipe.reassembled.length", FT_UINT32, BASE_DEC,
12091 NULL, 0x0, "The total length of the reassembled payload", HFILL }
12094 { &hf_smb2_pipe_reassembled_data,
12095 { "Reassembled SMB2 Named Pipe Data", "smb2.pipe.reassembled.data", FT_BYTES, BASE_NONE,
12096 NULL, 0x0, "The reassembled payload", HFILL }
12099 { &hf_smb2_cchunk_resume_key,
12100 { "ResumeKey", "smb2.fsctl.cchunk.resume_key", FT_BYTES, BASE_NONE,
12101 NULL, 0x0, "Opaque data representing source of copy", HFILL }
12104 { &hf_smb2_cchunk_count,
12105 { "Chunk Count", "smb2.fsctl.cchunk.count", FT_UINT32, BASE_DEC,
12106 NULL, 0x0, NULL, HFILL }
12109 { &hf_smb2_cchunk_src_offset,
12110 { "Source Offset", "smb2.fsctl.cchunk.src_offset", FT_UINT64, BASE_DEC,
12111 NULL, 0x0, NULL, HFILL }
12114 { &hf_smb2_cchunk_dst_offset,
12115 { "Target Offset", "smb2.fsctl.cchunk.dst_offset", FT_UINT64, BASE_DEC,
12116 NULL, 0x0, NULL, HFILL }
12119 { &hf_smb2_cchunk_xfer_len,
12120 { "Transfer Length", "smb2.fsctl.cchunk.xfer_len", FT_UINT32, BASE_DEC,
12121 NULL, 0x0, NULL, HFILL }
12124 { &hf_smb2_cchunk_chunks_written,
12125 { "Chunks Written", "smb2.fsctl.cchunk.chunks_written", FT_UINT32, BASE_DEC,
12126 NULL, 0x0, NULL, HFILL }
12129 { &hf_smb2_cchunk_bytes_written,
12130 { "Chunk Bytes Written", "smb2.fsctl.cchunk.bytes_written", FT_UINT32, BASE_DEC,
12131 NULL, 0x0, NULL, HFILL }
12134 { &hf_smb2_cchunk_total_written,
12135 { "Total Bytes Written", "smb2.fsctl.cchunk.total_written", FT_UINT32, BASE_DEC,
12136 NULL, 0x0, NULL, HFILL }
12138 { &hf_smb2_reparse_tag,
12139 { "Reparse Tag", "smb2.reparse_tag", FT_UINT32, BASE_HEX,
12140 VALS(reparse_tag_vals), 0x0, NULL, HFILL }
12142 { &hf_smb2_reparse_guid,
12143 { "Reparse GUID", "smb2.reparse_guid", FT_NONE, BASE_NONE,
12144 NULL, 0, NULL, HFILL }
12146 { &hf_smb2_reparse_data_length,
12147 { "Reparse Data Length", "smb2.reparse_data_length", FT_UINT16, BASE_DEC,
12148 NULL, 0x0, NULL, HFILL }
12150 { &hf_smb2_reparse_data_buffer,
12151 { "Reparse Data Buffer", "smb2.reparse_data_buffer", FT_NONE, BASE_NONE,
12152 NULL, 0, NULL, HFILL }
12154 { &hf_smb2_nfs_type,
12155 { "NFS file type", "smb2.nfs.type", FT_UINT64, BASE_HEX|BASE_VAL64_STRING,
12156 VALS64(nfs_type_vals), 0x0, NULL, HFILL }
12158 { &hf_smb2_nfs_symlink_target,
12159 { "Symlink Target", "smb2.nfs.symlink.target", FT_STRING,
12160 STR_UNICODE, NULL, 0x0, NULL, HFILL }
12162 { &hf_smb2_nfs_chr_major,
12163 { "Major", "smb2.nfs.char.major", FT_UINT32,
12164 BASE_HEX, NULL, 0x0, NULL, HFILL }
12166 { &hf_smb2_nfs_chr_minor,
12167 { "Minor", "smb2.nfs.char.minor", FT_UINT32,
12168 BASE_HEX, NULL, 0x0, NULL, HFILL }
12170 { &hf_smb2_nfs_blk_major,
12171 { "Major", "smb2.nfs.block.major", FT_UINT32,
12172 BASE_HEX, NULL, 0x0, NULL, HFILL }
12174 { &hf_smb2_nfs_blk_minor,
12175 { "Minor", "smb2.nfs.block.minor", FT_UINT32,
12176 BASE_HEX, NULL, 0x0, NULL, HFILL }
12178 { &hf_smb2_symlink_error_response,
12179 { "Symbolic Link Error Response", "smb2.symlink_error_response", FT_NONE, BASE_NONE,
12180 NULL, 0, NULL, HFILL }
12182 { &hf_smb2_symlink_length,
12183 { "SymLink Length", "smb2.symlink.length", FT_UINT32,
12184 BASE_DEC, NULL, 0x0, NULL, HFILL }
12186 { &hf_smb2_symlink_error_tag,
12187 { "SymLink Error Tag", "smb2.symlink.error_tag", FT_UINT32,
12188 BASE_HEX, NULL, 0x0, NULL, HFILL }
12190 { &hf_smb2_unparsed_path_length,
12191 { "Unparsed Path Length", "smb2.symlink.unparsed_path_length", FT_UINT16, BASE_DEC,
12192 NULL, 0x0, NULL, HFILL }
12194 { &hf_smb2_symlink_substitute_name,
12195 { "Substitute Name", "smb2.symlink.substitute_name", FT_STRING, STR_UNICODE,
12196 NULL, 0x0, NULL, HFILL }
12198 { &hf_smb2_symlink_print_name,
12199 { "Print Name", "smb2.symlink.print_name", FT_STRING, STR_UNICODE,
12200 NULL, 0x0, NULL, HFILL }
12202 { &hf_smb2_symlink_flags,
12203 { "Flags", "smb2.symlink.flags", FT_UINT32, BASE_DEC,
12204 NULL, 0x0, NULL, HFILL }
12208 static gint *ett[] = {
12209 &ett_smb2,
12210 &ett_smb2_ea,
12211 &ett_smb2_olb,
12212 &ett_smb2_header,
12213 &ett_smb2_encrypted,
12214 &ett_smb2_command,
12215 &ett_smb2_secblob,
12216 &ett_smb2_negotiate_context_element,
12217 &ett_smb2_file_basic_info,
12218 &ett_smb2_file_standard_info,
12219 &ett_smb2_file_internal_info,
12220 &ett_smb2_file_ea_info,
12221 &ett_smb2_file_access_info,
12222 &ett_smb2_file_rename_info,
12223 &ett_smb2_file_disposition_info,
12224 &ett_smb2_file_position_info,
12225 &ett_smb2_file_full_ea_info,
12226 &ett_smb2_file_mode_info,
12227 &ett_smb2_file_alignment_info,
12228 &ett_smb2_file_all_info,
12229 &ett_smb2_file_allocation_info,
12230 &ett_smb2_file_endoffile_info,
12231 &ett_smb2_file_alternate_name_info,
12232 &ett_smb2_file_stream_info,
12233 &ett_smb2_file_pipe_info,
12234 &ett_smb2_file_compression_info,
12235 &ett_smb2_file_network_open_info,
12236 &ett_smb2_file_attribute_tag_info,
12237 &ett_smb2_fs_info_01,
12238 &ett_smb2_fs_info_03,
12239 &ett_smb2_fs_info_04,
12240 &ett_smb2_fs_info_05,
12241 &ett_smb2_fs_info_06,
12242 &ett_smb2_fs_info_07,
12243 &ett_smb2_fs_objectid_info,
12244 &ett_smb2_sec_info_00,
12245 &ett_smb2_quota_info,
12246 &ett_smb2_query_quota_info,
12247 &ett_smb2_tid_tree,
12248 &ett_smb2_sesid_tree,
12249 &ett_smb2_create_chain_element,
12250 &ett_smb2_MxAc_buffer,
12251 &ett_smb2_QFid_buffer,
12252 &ett_smb2_RqLs_buffer,
12253 &ett_smb2_ioctl_function,
12254 &ett_smb2_FILE_OBJECTID_BUFFER,
12255 &ett_smb2_flags,
12256 &ett_smb2_sec_mode,
12257 &ett_smb2_capabilities,
12258 &ett_smb2_ses_req_flags,
12259 &ett_smb2_ses_flags,
12260 &ett_smb2_create_rep_flags,
12261 &ett_smb2_lease_state,
12262 &ett_smb2_lease_flags,
12263 &ett_smb2_share_flags,
12264 &ett_smb2_share_caps,
12265 &ett_smb2_ioctl_flags,
12266 &ett_smb2_ioctl_network_interface,
12267 &ett_smb2_ioctl_sqos_opeations,
12268 &ett_smb2_fsctl_range_data,
12269 &ett_windows_sockaddr,
12270 &ett_smb2_close_flags,
12271 &ett_smb2_notify_info,
12272 &ett_smb2_notify_flags,
12273 &ett_smb2_rdma_v1,
12274 &ett_smb2_write_flags,
12275 &ett_smb2_find_flags,
12276 &ett_smb2_file_directory_info,
12277 &ett_smb2_both_directory_info,
12278 &ett_smb2_id_both_directory_info,
12279 &ett_smb2_full_directory_info,
12280 &ett_smb2_file_name_info,
12281 &ett_smb2_lock_info,
12282 &ett_smb2_lock_flags,
12283 &ett_smb2_DH2Q_buffer,
12284 &ett_smb2_DH2C_buffer,
12285 &ett_smb2_dh2x_flags,
12286 &ett_smb2_APP_INSTANCE_buffer,
12287 &ett_smb2_svhdx_open_device_context,
12288 &ett_smb2_posix_v1_request,
12289 &ett_smb2_posix_v1_response,
12290 &ett_smb2_posix_v1_supported_features,
12291 &ett_smb2_aapl_create_context_request,
12292 &ett_smb2_aapl_server_query_bitmask,
12293 &ett_smb2_aapl_server_query_caps,
12294 &ett_smb2_aapl_create_context_response,
12295 &ett_smb2_aapl_server_query_volume_caps,
12296 &ett_smb2_integrity_flags,
12297 &ett_smb2_buffercode,
12298 &ett_smb2_ioctl_network_interface_capabilities,
12299 &ett_qfr_entry,
12300 &ett_smb2_pipe_fragment,
12301 &ett_smb2_pipe_fragments,
12302 &ett_smb2_cchunk_entry,
12303 &ett_smb2_fsctl_odx_token,
12304 &ett_smb2_symlink_error_response,
12305 &ett_smb2_reparse_data_buffer,
12306 &ett_smb2_error_data,
12307 &ett_smb2_error_context,
12308 &ett_smb2_error_redir_context,
12309 &ett_smb2_error_redir_ip_list,
12312 static ei_register_info ei[] = {
12313 { &ei_smb2_invalid_length, { "smb2.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
12314 { &ei_smb2_bad_response, { "smb2.bad_response", PI_MALFORMED, PI_ERROR, "Bad response", EXPFILL }},
12315 { &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 }},
12316 { &ei_smb2_invalid_getinfo_size, { "smb2.invalid_getinfo_size", PI_MALFORMED, PI_ERROR, "Input buffer length goes past the end of the message", EXPFILL }},
12317 { &ei_smb2_empty_getinfo_buffer, { "smb2.empty_getinfo_buffer", PI_PROTOCOL, PI_WARN, "Input buffer length is empty for a quota request", EXPFILL }},
12320 expert_module_t* expert_smb2;
12322 /* SessionID <=> SessionKey mappings for decryption */
12323 uat_t *seskey_uat;
12325 static uat_field_t seskey_uat_fields[] = {
12326 UAT_FLD_BUFFER(seskey_list, id, "Session ID", "The session ID buffer, coded as hex string, as it appears on the wire (LE)."),
12327 UAT_FLD_BUFFER(seskey_list, key, "Session Key", "The secret session key buffer, coded as 16-byte hex string as it appears on the wire (LE)."),
12328 UAT_END_FIELDS
12331 proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
12332 "SMB2", "smb2");
12333 proto_register_subtree_array(ett, array_length(ett));
12334 proto_register_field_array(proto_smb2, hf, array_length(hf));
12335 expert_smb2 = expert_register_protocol(proto_smb2);
12336 expert_register_field_array(expert_smb2, ei, array_length(ei));
12338 smb2_module = prefs_register_protocol(proto_smb2, NULL);
12339 prefs_register_bool_preference(smb2_module, "eosmb2_take_name_as_fid",
12340 "Use the full file name as File ID when exporting an SMB2 object",
12341 "Whether the export object functionality will take the full path file name as file identifier",
12342 &eosmb2_take_name_as_fid);
12344 prefs_register_bool_preference(smb2_module, "pipe_reassembly",
12345 "Reassemble Named Pipes over SMB2",
12346 "Whether the dissector should reassemble Named Pipes over SMB2 commands",
12347 &smb2_pipe_reassembly);
12349 seskey_uat = uat_new("Secret session key to use for decryption",
12350 sizeof(smb2_seskey_field_t),
12351 "smb2_seskey_list",
12352 TRUE,
12353 &seskey_list,
12354 &num_seskey_list,
12355 (UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS),
12356 NULL,
12357 seskey_list_copy_cb,
12358 seskey_list_update_cb,
12359 seskey_list_free_cb,
12360 NULL,
12361 NULL,
12362 seskey_uat_fields);
12364 prefs_register_uat_preference(smb2_module,
12365 "seskey_list",
12366 "Secret session keys for decryption",
12367 "A table of Session ID to Session key mappings used to derive decryption keys.",
12368 seskey_uat);
12370 smb2_pipe_subdissector_list = register_heur_dissector_list("smb2_pipe_subdissectors", proto_smb2);
12372 * XXX - addresses_ports_reassembly_table_functions?
12373 * Probably correct for SMB-over-NBT and SMB-over-TCP,
12374 * as stuff from two different connections should
12375 * probably not be combined, but what about other
12376 * transports for SMB, e.g. NBF or Netware?
12378 reassembly_table_register(&smb2_pipe_reassembly_table,
12379 &addresses_reassembly_table_functions);
12381 smb2_tap = register_tap("smb2");
12382 smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
12384 register_srt_table(proto_smb2, NULL, 1, smb2stat_packet, smb2stat_init, NULL);
12387 void
12388 proto_reg_handoff_smb2(void)
12390 gssapi_handle = find_dissector_add_dependency("gssapi", proto_smb2);
12391 ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_smb2);
12392 rsvd_handle = find_dissector_add_dependency("rsvd", proto_smb2);
12393 heur_dissector_add("netbios", dissect_smb2_heur, "SMB2 over Netbios", "smb2_netbios", proto_smb2, HEURISTIC_ENABLE);
12394 heur_dissector_add("smb_direct", dissect_smb2_heur, "SMB2 over SMB Direct", "smb2_smb_direct", proto_smb2, HEURISTIC_ENABLE);
12398 * Editor modelines - http://www.wireshark.org/tools/modelines.html
12400 * Local variables:
12401 * c-basic-offset: 8
12402 * tab-width: 8
12403 * indent-tabs-mode: t
12404 * End:
12406 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
12407 * :indentSize=8:tabSize=8:noTabs=false: