MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-smb2.c
blob52617c8cf3df5f82afd163ac71d610fef90b561e
1 /* packet-smb2.c
2 * Routines for smb2 packet dissection
3 * Ronnie Sahlberg 2005
5 * For documentation of this protocol, see:
7 * http://wiki.wireshark.org/SMB2
8 * http://msdn.microsoft.com/en-us/library/cc246482(PROT.10).aspx
10 * If you edit this file, keep the wiki updated as well.
12 * $Id$
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include "config.h"
35 #include <epan/packet.h>
36 #include <epan/conversation.h>
37 #include <epan/tap.h>
38 #include <epan/wmem/wmem.h>
39 #include <epan/aftypes.h>
41 #include "packet-smb2.h"
42 #include "packet-dcerpc.h"
43 #include "packet-ntlmssp.h"
44 #include "packet-windows-common.h"
45 #include "packet-smb-common.h"
46 #include "packet-smb.h"
47 #include "packet-dcerpc-nt.h"
48 #include <string.h>
49 #include <epan/prefs.h>
51 #include <glib.h>
52 /* Use libgcrypt for cipher libraries. */
53 #ifdef HAVE_LIBGCRYPT
54 #include <wsutil/wsgcrypt.h>
55 #endif /* HAVE_LIBGCRYPT */
57 static char smb_header_label[] = "SMB2 Header";
58 static char smb_transform_header_label[] = "SMB2 Transform Header";
60 static int proto_smb2 = -1;
61 static int hf_smb2_cmd = -1;
62 static int hf_smb2_nt_status = -1;
63 static int hf_smb2_response_to = -1;
64 static int hf_smb2_response_in = -1;
65 static int hf_smb2_time = -1;
66 static int hf_smb2_header_len = -1;
67 static int hf_smb2_msg_id = -1;
68 static int hf_smb2_pid = -1;
69 static int hf_smb2_tid = -1;
70 static int hf_smb2_aid = -1;
71 static int hf_smb2_sesid = -1;
72 static int hf_smb2_previous_sesid = -1;
73 static int hf_smb2_flags_response = -1;
74 static int hf_smb2_flags_async_cmd = -1;
75 static int hf_smb2_flags_dfs_op = -1;
76 static int hf_smb2_flags_chained = -1;
77 static int hf_smb2_flags_signature = -1;
78 static int hf_smb2_flags_replay_operation = -1;
79 static int hf_smb2_chain_offset = -1;
80 static int hf_smb2_security_blob = -1;
81 static int hf_smb2_ioctl_in_data = -1;
82 static int hf_smb2_ioctl_out_data = -1;
83 static int hf_smb2_unknown = -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_nlinks = -1;
100 static int hf_smb2_delete_pending = -1;
101 static int hf_smb2_is_directory = -1;
102 static int hf_smb2_file_id = -1;
103 static int hf_smb2_allocation_size = -1;
104 static int hf_smb2_end_of_file = -1;
105 static int hf_smb2_tree = -1;
106 static int hf_smb2_find_pattern = -1;
107 static int hf_smb2_find_info_level = -1;
108 static int hf_smb2_find_info_blob = -1;
109 static int hf_smb2_client_guid = -1;
110 static int hf_smb2_server_guid = -1;
111 static int hf_smb2_object_id = -1;
112 static int hf_smb2_birth_volume_id = -1;
113 static int hf_smb2_birth_object_id = -1;
114 static int hf_smb2_domain_id = -1;
115 static int hf_smb2_class = -1;
116 static int hf_smb2_infolevel = -1;
117 static int hf_smb2_infolevel_file_info = -1;
118 static int hf_smb2_infolevel_fs_info = -1;
119 static int hf_smb2_infolevel_sec_info = -1;
120 static int hf_smb2_max_response_size = -1;
121 static int hf_smb2_max_ioctl_in_size = -1;
122 static int hf_smb2_max_ioctl_out_size = -1;
123 static int hf_smb2_flags = -1;
124 static int hf_smb2_required_buffer_size = -1;
125 static int hf_smb2_setinfo_size = -1;
126 static int hf_smb2_setinfo_offset = -1;
127 static int hf_smb2_file_basic_info = -1;
128 static int hf_smb2_file_standard_info = -1;
129 static int hf_smb2_file_internal_info = -1;
130 static int hf_smb2_file_ea_info = -1;
131 static int hf_smb2_file_access_info = -1;
132 static int hf_smb2_file_rename_info = -1;
133 static int hf_smb2_file_disposition_info = -1;
134 static int hf_smb2_file_position_info = -1;
135 static int hf_smb2_file_full_ea_info = -1;
136 static int hf_smb2_file_mode_info = -1;
137 static int hf_smb2_file_alignment_info = -1;
138 static int hf_smb2_file_all_info = -1;
139 static int hf_smb2_file_allocation_info = -1;
140 static int hf_smb2_file_endoffile_info = -1;
141 static int hf_smb2_file_alternate_name_info = -1;
142 static int hf_smb2_file_stream_info = -1;
143 static int hf_smb2_file_pipe_info = -1;
144 static int hf_smb2_file_compression_info = -1;
145 static int hf_smb2_file_network_open_info = -1;
146 static int hf_smb2_file_attribute_tag_info = -1;
147 static int hf_smb2_fs_info_01 = -1;
148 static int hf_smb2_fs_info_03 = -1;
149 static int hf_smb2_fs_info_04 = -1;
150 static int hf_smb2_fs_info_05 = -1;
151 static int hf_smb2_fs_info_06 = -1;
152 static int hf_smb2_fs_info_07 = -1;
153 static int hf_smb2_fs_objectid_info = -1;
154 static int hf_smb2_sec_info_00 = -1;
155 static int hf_smb2_fid = -1;
156 static int hf_smb2_write_length = -1;
157 static int hf_smb2_write_data = -1;
158 static int hf_smb2_write_flags = -1;
159 static int hf_smb2_write_flags_write_through = -1;
160 static int hf_smb2_write_count = -1;
161 static int hf_smb2_write_remaining = -1;
162 static int hf_smb2_read_length = -1;
163 static int hf_smb2_read_remaining = -1;
164 static int hf_smb2_file_offset = -1;
165 static int hf_smb2_read_data = -1;
166 static int hf_smb2_disposition_delete_on_close = -1;
167 static int hf_smb2_create_disposition = -1;
168 static int hf_smb2_create_chain_offset = -1;
169 static int hf_smb2_create_chain_data = -1;
170 static int hf_smb2_data_offset = -1;
171 static int hf_smb2_extrainfo = -1;
172 static int hf_smb2_create_action = -1;
173 static int hf_smb2_create_rep_flags = -1;
174 static int hf_smb2_create_rep_flags_reparse_point = -1;
175 static int hf_smb2_next_offset = -1;
176 static int hf_smb2_ea_size = -1;
177 static int hf_smb2_ea_flags = -1;
178 static int hf_smb2_ea_name_len = -1;
179 static int hf_smb2_ea_data_len = -1;
180 static int hf_smb2_ea_name = -1;
181 static int hf_smb2_ea_data = -1;
182 static int hf_smb2_buffer_code = -1;
183 static int hf_smb2_buffer_code_len = -1;
184 static int hf_smb2_buffer_code_flags_dyn = -1;
185 static int hf_smb2_olb_offset = -1;
186 static int hf_smb2_olb_length = -1;
187 static int hf_smb2_tag = -1;
188 static int hf_smb2_impersonation_level = -1;
189 static int hf_smb2_ioctl_function = -1;
190 static int hf_smb2_ioctl_function_device = -1;
191 static int hf_smb2_ioctl_function_access = -1;
192 static int hf_smb2_ioctl_function_function = -1;
193 static int hf_smb2_fsctl_pipe_wait_timeout = -1;
194 static int hf_smb2_fsctl_pipe_wait_name = -1;
195 static int hf_smb2_ioctl_function_method = -1;
196 static int hf_smb2_ioctl_resiliency_timeout = -1;
197 static int hf_smb2_ioctl_resiliency_reserved = -1;
198 static int hf_windows_sockaddr_family = -1;
199 static int hf_windows_sockaddr_port = -1;
200 static int hf_windows_sockaddr_in_addr = -1;
201 static int hf_windows_sockaddr_in6_flowinfo = -1;
202 static int hf_windows_sockaddr_in6_addr = -1;
203 static int hf_windows_sockaddr_in6_scope_id = -1;
204 static int hf_smb2_ioctl_network_interface_next_offset = -1;
205 static int hf_smb2_ioctl_network_interface_index = -1;
206 static int hf_smb2_ioctl_network_interface_rss_queue_count = -1;
207 static int hf_smb2_ioctl_network_interface_capabilities = -1;
208 static int hf_smb2_ioctl_network_interface_capability_rss = -1;
209 static int hf_smb2_ioctl_network_interface_capability_rdma = -1;
210 static int hf_smb2_ioctl_network_interface_link_speed = -1;
211 static int hf_smb2_ioctl_shadow_copy_num_volumes = -1;
212 static int hf_smb2_ioctl_shadow_copy_num_labels = -1;
213 static int hf_smb2_ioctl_shadow_copy_count = -1;
214 static int hf_smb2_ioctl_shadow_copy_label = -1;
215 static int hf_smb2_compression_format = -1;
216 static int hf_smb2_FILE_OBJECTID_BUFFER = -1;
217 static int hf_smb2_lease_key = -1;
218 static int hf_smb2_lease_state = -1;
219 static int hf_smb2_lease_state_read_caching = -1;
220 static int hf_smb2_lease_state_handle_caching = -1;
221 static int hf_smb2_lease_state_write_caching = -1;
222 static int hf_smb2_lease_flags = -1;
223 static int hf_smb2_lease_flags_break_ack_required = -1;
224 static int hf_smb2_lease_flags_parent_lease_key_set = -1;
225 static int hf_smb2_lease_flags_break_in_progress = -1;
226 static int hf_smb2_lease_duration = -1;
227 static int hf_smb2_parent_lease_key = -1;
228 static int hf_smb2_lease_epoch = -1;
229 static int hf_smb2_lease_break_reason = -1;
230 static int hf_smb2_lease_access_mask_hint = -1;
231 static int hf_smb2_lease_share_mask_hint = -1;
232 static int hf_smb2_acct_name = -1;
233 static int hf_smb2_domain_name = -1;
234 static int hf_smb2_host_name = -1;
235 static int hf_smb2_auth_frame = -1;
236 static int hf_smb2_tcon_frame = -1;
237 static int hf_smb2_share_type = -1;
238 static int hf_smb2_signature = -1;
239 static int hf_smb2_credit_charge = -1;
240 static int hf_smb2_credits_requested = -1;
241 static int hf_smb2_credits_granted = -1;
242 static int hf_smb2_channel_sequence = -1;
243 static int hf_smb2_dialect_count = -1;
244 static int hf_smb2_security_mode = -1;
245 static int hf_smb2_secmode_flags_sign_required = -1;
246 static int hf_smb2_secmode_flags_sign_enabled = -1;
247 static int hf_smb2_ses_req_flags = -1;
248 static int hf_smb2_ses_req_flags_session_binding = -1;
249 static int hf_smb2_capabilities = -1;
250 static int hf_smb2_cap_dfs = -1;
251 static int hf_smb2_cap_leasing = -1;
252 static int hf_smb2_cap_large_mtu = -1;
253 static int hf_smb2_cap_multi_channel = -1;
254 static int hf_smb2_cap_persistent_handles = -1;
255 static int hf_smb2_cap_directory_leasing = -1;
256 static int hf_smb2_cap_encryption = -1;
257 static int hf_smb2_dialect = -1;
258 static int hf_smb2_max_trans_size = -1;
259 static int hf_smb2_max_read_size = -1;
260 static int hf_smb2_max_write_size = -1;
261 static int hf_smb2_channel = -1;
262 static int hf_smb2_session_flags = -1;
263 static int hf_smb2_ses_flags_guest = -1;
264 static int hf_smb2_ses_flags_null = -1;
265 static int hf_smb2_share_flags = -1;
266 static int hf_smb2_share_flags_dfs = -1;
267 static int hf_smb2_share_flags_dfs_root = -1;
268 static int hf_smb2_share_flags_restrict_exclusive_opens = -1;
269 static int hf_smb2_share_flags_force_shared_delete = -1;
270 static int hf_smb2_share_flags_allow_namespace_caching = -1;
271 static int hf_smb2_share_flags_access_based_dir_enum = -1;
272 static int hf_smb2_share_flags_force_levelii_oplock = -1;
273 static int hf_smb2_share_flags_enable_hash_v1 = -1;
274 static int hf_smb2_share_flags_enable_hash_v2 = -1;
275 static int hf_smb2_share_flags_encrypt_data = -1;
276 static int hf_smb2_share_caching = -1;
277 static int hf_smb2_share_caps = -1;
278 static int hf_smb2_share_caps_dfs = -1;
279 static int hf_smb2_share_caps_continuous_availability = -1;
280 static int hf_smb2_share_caps_scaleout = -1;
281 static int hf_smb2_share_caps_cluster = -1;
282 static int hf_smb2_create_flags = -1;
283 static int hf_smb2_lock_count = -1;
284 static int hf_smb2_min_count = -1;
285 static int hf_smb2_remaining_bytes = -1;
286 static int hf_smb2_channel_info_offset = -1;
287 static int hf_smb2_channel_info_length = -1;
288 static int hf_smb2_ioctl_flags = -1;
289 static int hf_smb2_ioctl_is_fsctl = -1;
290 static int hf_smb2_close_pq_attrib = -1;
291 static int hf_smb2_notify_watch_tree = -1;
292 static int hf_smb2_output_buffer_len = -1;
293 static int hf_smb2_notify_out_data = -1;
294 static int hf_smb2_find_flags = -1;
295 static int hf_smb2_find_flags_restart_scans = -1;
296 static int hf_smb2_find_flags_single_entry = -1;
297 static int hf_smb2_find_flags_index_specified = -1;
298 static int hf_smb2_find_flags_reopen = -1;
299 static int hf_smb2_file_index = -1;
300 static int hf_smb2_file_directory_info = -1;
301 static int hf_smb2_both_directory_info = -1;
302 static int hf_smb2_short_name_len = -1;
303 static int hf_smb2_short_name = -1;
304 static int hf_smb2_id_both_directory_info = -1;
305 static int hf_smb2_full_directory_info = -1;
306 static int hf_smb2_lock_info = -1;
307 static int hf_smb2_lock_length = -1;
308 static int hf_smb2_lock_flags = -1;
309 static int hf_smb2_lock_flags_shared = -1;
310 static int hf_smb2_lock_flags_exclusive = -1;
311 static int hf_smb2_lock_flags_unlock = -1;
312 static int hf_smb2_lock_flags_fail_immediately = -1;
313 static int hf_smb2_dhnq_buffer_reserved = -1;
314 static int hf_smb2_dh2x_buffer_timeout = -1;
315 static int hf_smb2_dh2x_buffer_flags = -1;
316 static int hf_smb2_dh2x_buffer_flags_persistent_handle = -1;
317 static int hf_smb2_dh2x_buffer_reserved = -1;
318 static int hf_smb2_dh2x_buffer_create_guid = -1;
319 static int hf_smb2_APP_INSTANCE_buffer_struct_size = -1;
320 static int hf_smb2_APP_INSTANCE_buffer_reserved = -1;
321 static int hf_smb2_APP_INSTANCE_buffer_app_guid = -1;
322 static int hf_smb2_error_byte_count = -1;
323 static int hf_smb2_error_data = -1;
324 static int hf_smb2_error_reserved = -1;
325 static int hf_smb2_reserved = -1;
326 static int hf_smb2_transform_signature = -1;
327 static int hf_smb2_transform_nonce = -1;
328 static int hf_smb2_transform_msg_size = -1;
329 static int hf_smb2_transform_reserved = -1;
330 static int hf_smb2_encryption_aes128_ccm = -1;
331 static int hf_smb2_transform_enc_alg = -1;
332 static int hf_smb2_transform_encrypted_data = -1;
334 static gint ett_smb2 = -1;
335 static gint ett_smb2_olb = -1;
336 static gint ett_smb2_ea = -1;
337 static gint ett_smb2_header = -1;
338 static gint ett_smb2_encrypted = -1;
339 static gint ett_smb2_command = -1;
340 static gint ett_smb2_secblob = -1;
341 static gint ett_smb2_file_basic_info = -1;
342 static gint ett_smb2_file_standard_info = -1;
343 static gint ett_smb2_file_internal_info = -1;
344 static gint ett_smb2_file_ea_info = -1;
345 static gint ett_smb2_file_access_info = -1;
346 static gint ett_smb2_file_position_info = -1;
347 static gint ett_smb2_file_mode_info = -1;
348 static gint ett_smb2_file_alignment_info = -1;
349 static gint ett_smb2_file_all_info = -1;
350 static gint ett_smb2_file_allocation_info = -1;
351 static gint ett_smb2_file_endoffile_info = -1;
352 static gint ett_smb2_file_alternate_name_info = -1;
353 static gint ett_smb2_file_stream_info = -1;
354 static gint ett_smb2_file_pipe_info = -1;
355 static gint ett_smb2_file_compression_info = -1;
356 static gint ett_smb2_file_network_open_info = -1;
357 static gint ett_smb2_file_attribute_tag_info = -1;
358 static gint ett_smb2_file_rename_info = -1;
359 static gint ett_smb2_file_disposition_info = -1;
360 static gint ett_smb2_file_full_ea_info = -1;
361 static gint ett_smb2_fs_info_01 = -1;
362 static gint ett_smb2_fs_info_03 = -1;
363 static gint ett_smb2_fs_info_04 = -1;
364 static gint ett_smb2_fs_info_05 = -1;
365 static gint ett_smb2_fs_info_06 = -1;
366 static gint ett_smb2_fs_info_07 = -1;
367 static gint ett_smb2_fs_objectid_info = -1;
368 static gint ett_smb2_sec_info_00 = -1;
369 static gint ett_smb2_tid_tree = -1;
370 static gint ett_smb2_sesid_tree = -1;
371 static gint ett_smb2_create_chain_element = -1;
372 static gint ett_smb2_MxAc_buffer = -1;
373 static gint ett_smb2_QFid_buffer = -1;
374 static gint ett_smb2_RqLs_buffer = -1;
375 static gint ett_smb2_ioctl_function = -1;
376 static gint ett_smb2_FILE_OBJECTID_BUFFER = -1;
377 static gint ett_smb2_flags = -1;
378 static gint ett_smb2_sec_mode = -1;
379 static gint ett_smb2_capabilities = -1;
380 static gint ett_smb2_ses_req_flags = -1;
381 static gint ett_smb2_ses_flags = -1;
382 static gint ett_smb2_lease_state = -1;
383 static gint ett_smb2_lease_flags = -1;
384 static gint ett_smb2_share_flags = -1;
385 static gint ett_smb2_create_rep_flags = -1;
386 static gint ett_smb2_share_caps = -1;
387 static gint ett_smb2_ioctl_flags = -1;
388 static gint ett_smb2_ioctl_network_interface = -1;
389 static gint ett_windows_sockaddr = -1;
390 static gint ett_smb2_close_flags = -1;
391 static gint ett_smb2_notify_flags = -1;
392 static gint ett_smb2_write_flags = -1;
393 static gint ett_smb2_DH2Q_buffer = -1;
394 static gint ett_smb2_DH2C_buffer = -1;
395 static gint ett_smb2_dh2x_flags = -1;
396 static gint ett_smb2_APP_INSTANCE_buffer = -1;
397 static gint ett_smb2_find_flags = -1;
398 static gint ett_smb2_file_directory_info = -1;
399 static gint ett_smb2_both_directory_info = -1;
400 static gint ett_smb2_id_both_directory_info = -1;
401 static gint ett_smb2_full_directory_info = -1;
402 static gint ett_smb2_file_name_info = -1;
403 static gint ett_smb2_lock_info = -1;
404 static gint ett_smb2_lock_flags = -1;
405 static gint ett_smb2_transform_enc_alg = -1;
406 static gint ett_smb2_buffercode = -1;
408 static int smb2_tap = -1;
409 static int smb2_eo_tap = -1;
411 static dissector_handle_t gssapi_handle = NULL;
412 static dissector_handle_t ntlmssp_handle = NULL;
414 static heur_dissector_list_t smb2_heur_subdissector_list;
416 #define SMB2_CLASS_FILE_INFO 0x01
417 #define SMB2_CLASS_FS_INFO 0x02
418 #define SMB2_CLASS_SEC_INFO 0x03
419 static const value_string smb2_class_vals[] = {
420 { SMB2_CLASS_FILE_INFO, "FILE_INFO"},
421 { SMB2_CLASS_FS_INFO, "FS_INFO"},
422 { SMB2_CLASS_SEC_INFO, "SEC_INFO"},
423 { 0, NULL }
426 #define SMB2_SHARE_TYPE_DISK 0x01
427 #define SMB2_SHARE_TYPE_PIPE 0x02
428 #define SMB2_SHARE_TYPE_PRINT 0x03
429 static const value_string smb2_share_type_vals[] = {
430 { SMB2_SHARE_TYPE_DISK, "Physical disk" },
431 { SMB2_SHARE_TYPE_PIPE, "Named pipe" },
432 { SMB2_SHARE_TYPE_PRINT, "Printer" },
433 { 0, NULL }
437 #define SMB2_FILE_BASIC_INFO 0x04
438 #define SMB2_FILE_STANDARD_INFO 0x05
439 #define SMB2_FILE_INTERNAL_INFO 0x06
440 #define SMB2_FILE_EA_INFO 0x07
441 #define SMB2_FILE_ACCESS_INFO 0x08
442 #define SMB2_FILE_RENAME_INFO 0x0a
443 #define SMB2_FILE_DISPOSITION_INFO 0x0d
444 #define SMB2_FILE_POSITION_INFO 0x0e
445 #define SMB2_FILE_FULL_EA_INFO 0x0f
446 #define SMB2_FILE_MODE_INFO 0x10
447 #define SMB2_FILE_ALIGNMENT_INFO 0x11
448 #define SMB2_FILE_ALL_INFO 0x12
449 #define SMB2_FILE_ALLOCATION_INFO 0x13
450 #define SMB2_FILE_ENDOFFILE_INFO 0x14
451 #define SMB2_FILE_ALTERNATE_NAME_INFO 0x15
452 #define SMB2_FILE_STREAM_INFO 0x16
453 #define SMB2_FILE_PIPE_INFO 0x17
454 #define SMB2_FILE_COMPRESSION_INFO 0x1c
455 #define SMB2_FILE_NETWORK_OPEN_INFO 0x22
456 #define SMB2_FILE_ATTRIBUTE_TAG_INFO 0x23
457 static const value_string smb2_file_info_levels[] = {
458 {SMB2_FILE_BASIC_INFO, "SMB2_FILE_BASIC_INFO" },
459 {SMB2_FILE_STANDARD_INFO, "SMB2_FILE_STANDARD_INFO" },
460 {SMB2_FILE_INTERNAL_INFO, "SMB2_FILE_INTERNAL_INFO" },
461 {SMB2_FILE_EA_INFO, "SMB2_FILE_EA_INFO" },
462 {SMB2_FILE_ACCESS_INFO, "SMB2_FILE_ACCESS_INFO" },
463 {SMB2_FILE_RENAME_INFO, "SMB2_FILE_RENAME_INFO" },
464 {SMB2_FILE_DISPOSITION_INFO, "SMB2_FILE_DISPOSITION_INFO" },
465 {SMB2_FILE_POSITION_INFO, "SMB2_FILE_POSITION_INFO" },
466 {SMB2_FILE_FULL_EA_INFO, "SMB2_FILE_FULL_EA_INFO" },
467 {SMB2_FILE_MODE_INFO, "SMB2_FILE_MODE_INFO" },
468 {SMB2_FILE_ALIGNMENT_INFO, "SMB2_FILE_ALIGNMENT_INFO" },
469 {SMB2_FILE_ALL_INFO, "SMB2_FILE_ALL_INFO" },
470 {SMB2_FILE_ALLOCATION_INFO, "SMB2_FILE_ALLOCATION_INFO" },
471 {SMB2_FILE_ENDOFFILE_INFO, "SMB2_FILE_ENDOFFILE_INFO" },
472 {SMB2_FILE_ALTERNATE_NAME_INFO, "SMB2_FILE_ALTERNATE_NAME_INFO" },
473 {SMB2_FILE_STREAM_INFO, "SMB2_FILE_STREAM_INFO" },
474 {SMB2_FILE_PIPE_INFO, "SMB2_FILE_PIPE_INFO" },
475 {SMB2_FILE_COMPRESSION_INFO, "SMB2_FILE_COMPRESSION_INFO" },
476 {SMB2_FILE_NETWORK_OPEN_INFO, "SMB2_FILE_NETWORK_OPEN_INFO" },
477 {SMB2_FILE_ATTRIBUTE_TAG_INFO, "SMB2_FILE_ATTRIBUTE_TAG_INFO" },
478 { 0, NULL }
483 #define SMB2_FS_INFO_01 0x01
484 #define SMB2_FS_INFO_03 0x03
485 #define SMB2_FS_INFO_04 0x04
486 #define SMB2_FS_INFO_05 0x05
487 #define SMB2_FS_INFO_06 0x06
488 #define SMB2_FS_INFO_07 0x07
489 #define SMB2_FS_OBJECTID_INFO 0x08
490 static const value_string smb2_fs_info_levels[] = {
491 {SMB2_FS_INFO_01, "SMB2_FS_INFO_01" },
492 {SMB2_FS_INFO_03, "SMB2_FS_INFO_03" },
493 {SMB2_FS_INFO_04, "SMB2_FS_INFO_04" },
494 {SMB2_FS_INFO_05, "SMB2_FS_INFO_05" },
495 {SMB2_FS_INFO_06, "SMB2_FS_INFO_06" },
496 {SMB2_FS_INFO_07, "SMB2_FS_INFO_07" },
497 {SMB2_FS_OBJECTID_INFO, "SMB2_FS_OBJECTID_INFO" },
498 { 0, NULL }
501 #define SMB2_SEC_INFO_00 0x00
502 static const value_string smb2_sec_info_levels[] = {
503 {SMB2_SEC_INFO_00, "SMB2_SEC_INFO_00" },
504 { 0, NULL }
507 #define SMB2_FIND_DIRECTORY_INFO 0x01
508 #define SMB2_FIND_FULL_DIRECTORY_INFO 0x02
509 #define SMB2_FIND_BOTH_DIRECTORY_INFO 0x03
510 #define SMB2_FIND_INDEX_SPECIFIED 0x04
511 #define SMB2_FIND_NAME_INFO 0x0C
512 #define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
513 #define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
514 static const value_string smb2_find_info_levels[] = {
515 { SMB2_FIND_DIRECTORY_INFO, "SMB2_FIND_DIRECTORY_INFO" },
516 { SMB2_FIND_FULL_DIRECTORY_INFO, "SMB2_FIND_FULL_DIRECTORY_INFO" },
517 { SMB2_FIND_BOTH_DIRECTORY_INFO, "SMB2_FIND_BOTH_DIRECTORY_INFO" },
518 { SMB2_FIND_INDEX_SPECIFIED, "SMB2_FIND_INDEX_SPECIFIED" },
519 { SMB2_FIND_NAME_INFO, "SMB2_FIND_NAME_INFO" },
520 { SMB2_FIND_ID_BOTH_DIRECTORY_INFO, "SMB2_FIND_ID_BOTH_DIRECTORY_INFO" },
521 { SMB2_FIND_ID_FULL_DIRECTORY_INFO, "SMB2_FIND_ID_FULL_DIRECTORY_INFO" },
522 { 0, NULL }
525 static const gint8 zeros[NTLMSSP_KEY_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
527 /* ExportObject preferences variable */
528 gboolean eosmb2_take_name_as_fid = FALSE ;
530 /* unmatched smb_saved_info structures.
531 For unmatched smb_saved_info structures we store the smb_saved_info
532 structure using the msg_id field.
534 static gint
535 smb2_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
537 const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
538 const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
539 return key1->msg_id == key2->msg_id;
541 static guint
542 smb2_saved_info_hash_unmatched(gconstpointer k)
544 const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
545 guint32 hash;
547 hash = (guint32) (key->msg_id&0xffffffff);
548 return hash;
551 /* matched smb_saved_info structures.
552 For matched smb_saved_info structures we store the smb_saved_info
553 structure using the msg_id field.
555 static gint
556 smb2_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
558 const smb2_saved_info_t *key1 = (const smb2_saved_info_t *)k1;
559 const smb2_saved_info_t *key2 = (const smb2_saved_info_t *)k2;
560 return key1->msg_id == key2->msg_id;
562 static guint
563 smb2_saved_info_hash_matched(gconstpointer k)
565 const smb2_saved_info_t *key = (const smb2_saved_info_t *)k;
566 guint32 hash;
568 hash = (guint32) (key->msg_id&0xffffffff);
569 return hash;
572 /* For Tids of a specific conversation.
573 This keeps track of tid->sharename mappings and other information about the
574 tid.
576 We might need to refine this if it occurs that tids are reused on a single
577 conversation. we dont worry about that yet for simplicity
579 static gint
580 smb2_tid_info_equal(gconstpointer k1, gconstpointer k2)
582 const smb2_tid_info_t *key1 = (const smb2_tid_info_t *)k1;
583 const smb2_tid_info_t *key2 = (const smb2_tid_info_t *)k2;
584 return key1->tid == key2->tid;
586 static guint
587 smb2_tid_info_hash(gconstpointer k)
589 const smb2_tid_info_t *key = (const smb2_tid_info_t *)k;
590 guint32 hash;
592 hash = key->tid;
593 return hash;
596 /* For Uids of a specific conversation.
597 This keeps track of uid->acct_name mappings and other information about the
598 uid.
600 We might need to refine this if it occurs that uids are reused on a single
601 conversation. we dont worry about that yet for simplicity
603 static gint
604 smb2_sesid_info_equal(gconstpointer k1, gconstpointer k2)
606 const smb2_sesid_info_t *key1 = (const smb2_sesid_info_t *)k1;
607 const smb2_sesid_info_t *key2 = (const smb2_sesid_info_t *)k2;
608 return key1->sesid == key2->sesid;
610 static guint
611 smb2_sesid_info_hash(gconstpointer k)
613 const smb2_sesid_info_t *key = (const smb2_sesid_info_t *)k;
614 guint32 hash;
616 hash = (guint32)( ((key->sesid>>32)&0xffffffff)+((key->sesid)&0xffffffff) );
617 return hash;
620 /* Callback for destroying the glib hash tables associated with a conversation
621 * struct. */
622 static gboolean
623 smb2_conv_destroy(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_,
624 void *user_data)
626 smb2_conv_info_t *conv = (smb2_conv_info_t *)user_data;
628 g_hash_table_destroy(conv->matched);
629 g_hash_table_destroy(conv->unmatched);
630 g_hash_table_destroy(conv->sesids);
631 g_hash_table_destroy(conv->files);
633 /* This conversation is gone, return FALSE to indicate we don't
634 * want to be called again for this conversation. */
635 return FALSE;
638 static void smb2_key_derivation(const guint8 *KI _U_, guint32 KI_len _U_,
639 const guint8 *Label _U_, guint32 Label_len _U_,
640 const guint8 *Context _U_, guint32 Context_len _U_,
641 guint8 KO[16])
643 #ifdef HAVE_LIBGCRYPT
644 gcry_md_hd_t hd = NULL;
645 guint8 buf[4];
646 guint8 *digest = NULL;
649 * a simplified version of
650 * "NIST Special Publication 800-108" section 5.1
651 * using hmac-sha256.
653 gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
654 gcry_md_setkey(hd, KI, KI_len);
656 memset(buf, 0, sizeof(buf));
657 buf[3] = 1;
658 gcry_md_write(hd, buf, sizeof(buf));
659 gcry_md_write(hd, Label, Label_len);
660 gcry_md_write(hd, buf, 1);
661 gcry_md_write(hd, Context, Context_len);
662 buf[3] = 128;
663 gcry_md_write(hd, buf, sizeof(buf));
665 digest = gcry_md_read(hd, GCRY_MD_SHA256);
667 memcpy(KO, digest, 16);
669 gcry_md_close(hd);
670 #else
671 memset(KO, 0, 16);
672 #endif
675 /* for export-object-smb2 */
676 static gchar *policy_hnd_to_file_id(const e_ctx_hnd *hnd) {
677 gchar *file_id;
678 file_id = wmem_strdup_printf(wmem_packet_scope(),
679 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
680 hnd->uuid.Data1,
681 hnd->uuid.Data2,
682 hnd->uuid.Data3,
683 hnd->uuid.Data4[0],
684 hnd->uuid.Data4[1],
685 hnd->uuid.Data4[2],
686 hnd->uuid.Data4[3],
687 hnd->uuid.Data4[4],
688 hnd->uuid.Data4[5],
689 hnd->uuid.Data4[6],
690 hnd->uuid.Data4[7]);
691 return file_id;
693 static guint smb2_eo_files_hash(gconstpointer k) {
694 return g_str_hash(policy_hnd_to_file_id((const e_ctx_hnd *)k));
696 static gint smb2_eo_files_equal(gconstpointer k1, gconstpointer k2) {
697 int are_equal;
698 const e_ctx_hnd *key1 = (const e_ctx_hnd *)k1;
699 const e_ctx_hnd *key2 = (const e_ctx_hnd *)k2;
701 are_equal = (key1->uuid.Data1==key2->uuid.Data1 &&
702 key1->uuid.Data2==key2->uuid.Data2 &&
703 key1->uuid.Data3==key2->uuid.Data3 &&
704 key1->uuid.Data4[0]==key2->uuid.Data4[0] &&
705 key1->uuid.Data4[1]==key2->uuid.Data4[1] &&
706 key1->uuid.Data4[2]==key2->uuid.Data4[2] &&
707 key1->uuid.Data4[3]==key2->uuid.Data4[3] &&
708 key1->uuid.Data4[4]==key2->uuid.Data4[4] &&
709 key1->uuid.Data4[5]==key2->uuid.Data4[5] &&
710 key1->uuid.Data4[6]==key2->uuid.Data4[6] &&
711 key1->uuid.Data4[7]==key2->uuid.Data4[7]);
713 return are_equal;
716 static void
717 feed_eo_smb2(tvbuff_t * tvb,packet_info *pinfo,smb2_info_t * si, guint16 dataoffset,guint32 length, guint64 file_offset) {
719 char *fid_name = NULL;
720 guint32 open_frame = 0, close_frame = 0;
721 tvbuff_t *data_tvb = NULL;
722 smb_eo_t *eo_info;
723 gchar *file_id;
724 gchar *auxstring;
725 gchar **aux_string_v;
727 /* Create a new tvb to point to the payload data */
728 data_tvb = tvb_new_subset(tvb, dataoffset, length, length);
729 /* Create the eo_info to pass to the listener */
730 eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
731 /* Fill in eo_info */
732 eo_info->smbversion=2;
733 /* cmd == opcode */
734 eo_info->cmd=si->opcode;
735 /* We don't keep track of uid in SMB v2 */
736 eo_info->uid=0;
738 /* Try to get file id and filename */
739 file_id=policy_hnd_to_file_id(&si->saved->policy_hnd);
740 dcerpc_fetch_polhnd_data(&si->saved->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num);
741 if (fid_name && g_strcmp0(fid_name,"File: ")!=0) {
742 auxstring=fid_name;
743 /* Remove "File: " from filename */
744 if (g_str_has_prefix(auxstring, "File: ")) {
745 aux_string_v = g_strsplit(auxstring, "File: ", -1);
746 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",aux_string_v[g_strv_length(aux_string_v)-1]);
747 g_strfreev(aux_string_v);
748 } else {
749 if (g_str_has_prefix(auxstring, "\\")) {
750 eo_info->filename = wmem_strdup(wmem_packet_scope(), auxstring);
751 } else {
752 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\%s",auxstring);
755 } else {
756 auxstring=wmem_strdup_printf(wmem_packet_scope(), "File_Id_%s", file_id);
757 eo_info->filename=auxstring;
762 if (eosmb2_take_name_as_fid) {
763 eo_info->fid = g_str_hash(eo_info->filename);
764 } else {
765 eo_info->fid = g_str_hash(file_id);
768 /* tid, hostname, tree_id */
769 if (si->tree) {
770 eo_info->tid=si->tree->tid;
771 if (strlen(si->tree->name)>0 && strlen(si->tree->name)<=256) {
772 eo_info->hostname = wmem_strdup(wmem_packet_scope(), si->tree->name);
773 } else {
774 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,si->opcode),si->tree->tid);
776 } else {
777 eo_info->tid=0;
778 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,si->opcode));
781 /* packet number */
782 eo_info->pkt_num = pinfo->fd->num;
784 /* fid type */
785 if (si->eo_file_info->attr_mask & SMB2_FLAGS_ATTR_DIRECTORY) {
786 eo_info->fid_type=SMB2_FID_TYPE_DIR;
787 } else {
788 if (si->eo_file_info->attr_mask &
789 (SMB2_FLAGS_ATTR_ARCHIVE | SMB2_FLAGS_ATTR_NORMAL |
790 SMB2_FLAGS_ATTR_HIDDEN | SMB2_FLAGS_ATTR_READONLY |
791 SMB2_FLAGS_ATTR_SYSTEM) ) {
792 eo_info->fid_type=SMB2_FID_TYPE_FILE;
793 } else {
794 eo_info->fid_type=SMB2_FID_TYPE_OTHER;
798 /* end_of_file */
799 eo_info->end_of_file=si->eo_file_info->end_of_file;
801 /* data offset and chunk length */
802 eo_info->smb_file_offset=file_offset;
803 eo_info->smb_chunk_len=length;
804 /* XXX is this right? */
805 if (length<si->saved->bytes_moved) {
806 si->saved->file_offset=si->saved->file_offset+length;
807 si->saved->bytes_moved=si->saved->bytes_moved-length;
810 /* Payload */
811 eo_info->payload_len = length;
812 eo_info->payload_data = tvb_get_ptr(data_tvb, 0, length);
814 tap_queue_packet(smb2_eo_tap, pinfo, eo_info);
818 static int dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb2_info_t *si);
821 /* This is a helper to dissect the common string type
822 * uint16 offset
823 * uint16 length
824 * ...
825 * char *string
827 * This function is called twice, first to decode the offset/length and
828 * second time to dissect the actual string.
829 * It is done this way since there is no guarantee that we have the full packet and we dont
830 * want to abort dissection too early if the packet ends somewhere between the
831 * length/offset and the actual buffer.
834 enum offset_length_buffer_offset_size {
835 OLB_O_UINT16_S_UINT16,
836 OLB_O_UINT16_S_UINT32,
837 OLB_O_UINT32_S_UINT32,
838 OLB_S_UINT32_O_UINT32
840 typedef struct _offset_length_buffer_t {
841 guint32 off;
842 guint32 len;
843 int off_offset;
844 int len_offset;
845 enum offset_length_buffer_offset_size offset_size;
846 int hfindex;
847 } offset_length_buffer_t;
848 static int
849 dissect_smb2_olb_length_offset(tvbuff_t *tvb, int offset, offset_length_buffer_t *olb,
850 enum offset_length_buffer_offset_size offset_size, int hfindex)
852 olb->hfindex = hfindex;
853 olb->offset_size = offset_size;
854 switch (offset_size) {
855 case OLB_O_UINT16_S_UINT16:
856 olb->off = tvb_get_letohs(tvb, offset);
857 olb->off_offset = offset;
858 offset += 2;
859 olb->len = tvb_get_letohs(tvb, offset);
860 olb->len_offset = offset;
861 offset += 2;
862 break;
863 case OLB_O_UINT16_S_UINT32:
864 olb->off = tvb_get_letohs(tvb, offset);
865 olb->off_offset = offset;
866 offset += 2;
867 olb->len = tvb_get_letohl(tvb, offset);
868 olb->len_offset = offset;
869 offset += 4;
870 break;
871 case OLB_O_UINT32_S_UINT32:
872 olb->off = tvb_get_letohl(tvb, offset);
873 olb->off_offset = offset;
874 offset += 4;
875 olb->len = tvb_get_letohl(tvb, offset);
876 olb->len_offset = offset;
877 offset += 4;
878 break;
879 case OLB_S_UINT32_O_UINT32:
880 olb->len = tvb_get_letohl(tvb, offset);
881 olb->len_offset = offset;
882 offset += 4;
883 olb->off = tvb_get_letohl(tvb, offset);
884 olb->off_offset = offset;
885 offset += 4;
886 break;
889 return offset;
892 #define OLB_TYPE_UNICODE_STRING 0x01
893 #define OLB_TYPE_ASCII_STRING 0x02
894 static const char *
895 dissect_smb2_olb_string(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, offset_length_buffer_t *olb, int type)
897 int len, off;
898 proto_item *item = NULL;
899 proto_tree *tree = NULL;
900 const char *name = NULL;
901 guint16 bc;
902 int offset;
904 offset = olb->off;
905 len = olb->len;
906 off = olb->off;
907 bc = tvb_length_remaining(tvb, offset);
910 /* sanity check */
911 tvb_ensure_bytes_exist(tvb, off, len);
912 if (((off+len)<off)
913 || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
914 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
915 "Invalid offset/length. Malformed packet");
917 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
919 return NULL;
923 switch (type) {
924 case OLB_TYPE_UNICODE_STRING:
925 name = get_unicode_or_ascii_string(tvb, &off,
926 TRUE, &len, TRUE, TRUE, &bc);
927 if (!name) {
928 name = "";
930 if (parent_tree) {
931 item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
932 tree = proto_item_add_subtree(item, ett_smb2_olb);
934 break;
935 case OLB_TYPE_ASCII_STRING:
936 name = get_unicode_or_ascii_string(tvb, &off,
937 FALSE, &len, TRUE, TRUE, &bc);
938 if (!name) {
939 name = "";
941 if (parent_tree) {
942 item = proto_tree_add_string(parent_tree, olb->hfindex, tvb, offset, len, name);
943 tree = proto_item_add_subtree(item, ett_smb2_olb);
945 break;
948 switch (olb->offset_size) {
949 case OLB_O_UINT16_S_UINT16:
950 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
951 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
952 break;
953 case OLB_O_UINT16_S_UINT32:
954 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
955 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
956 break;
957 case OLB_O_UINT32_S_UINT32:
958 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
959 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
960 break;
961 case OLB_S_UINT32_O_UINT32:
962 proto_tree_add_item(tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
963 proto_tree_add_item(tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
964 break;
967 return name;
970 static void
971 dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb,
972 offset_length_buffer_t *olb, smb2_info_t *si,
973 void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si))
975 int len, off;
976 proto_item *sub_item = NULL;
977 proto_tree *sub_tree = NULL;
978 tvbuff_t *sub_tvb = NULL;
979 int offset;
981 offset = olb->off;
982 len = olb->len;
983 off = olb->off;
985 /* sanity check */
986 tvb_ensure_bytes_exist(tvb, off, len);
987 if (((off+len)<off)
988 || ((off+len)>(off+tvb_reported_length_remaining(tvb, off)))) {
989 proto_tree_add_text(parent_tree, tvb, offset, tvb_length_remaining(tvb, offset),
990 "Invalid offset/length. Malformed packet");
992 col_append_str(pinfo->cinfo, COL_INFO, " [Malformed packet]");
994 return;
997 /* if we dont want/need a subtree */
998 if (olb->hfindex == -1) {
999 sub_item = parent_tree;
1000 sub_tree = parent_tree;
1001 } else {
1002 if (parent_tree) {
1003 sub_item = proto_tree_add_item(parent_tree, olb->hfindex, tvb, offset, len, ENC_NA);
1004 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_olb);
1008 switch (olb->offset_size) {
1009 case OLB_O_UINT16_S_UINT16:
1010 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1011 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 2, ENC_LITTLE_ENDIAN);
1012 break;
1013 case OLB_O_UINT16_S_UINT32:
1014 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 2, ENC_LITTLE_ENDIAN);
1015 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1016 break;
1017 case OLB_O_UINT32_S_UINT32:
1018 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1019 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1020 break;
1021 case OLB_S_UINT32_O_UINT32:
1022 proto_tree_add_item(sub_tree, hf_smb2_olb_length, tvb, olb->len_offset, 4, ENC_LITTLE_ENDIAN);
1023 proto_tree_add_item(sub_tree, hf_smb2_olb_offset, tvb, olb->off_offset, 4, ENC_LITTLE_ENDIAN);
1024 break;
1027 if (off == 0 || len == 0) {
1028 proto_item_append_text(sub_item, ": NO DATA");
1029 return;
1032 if (!dissector) {
1033 return;
1036 sub_tvb = tvb_new_subset(tvb, off, MIN((int)len, tvb_length_remaining(tvb, off)), len);
1038 dissector(sub_tvb, pinfo, sub_tree, si);
1041 static int
1042 dissect_smb2_olb_tvb_max_offset(int offset, offset_length_buffer_t *olb)
1044 if (olb->off == 0) {
1045 return offset;
1047 return MAX(offset, (int)(olb->off + olb->len));
1050 typedef struct _smb2_function {
1051 int (*request) (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1052 int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
1053 } smb2_function;
1055 static const true_false_string tfs_flags_response = {
1056 "This is a RESPONSE",
1057 "This is a REQUEST"
1060 static const true_false_string tfs_flags_async_cmd = {
1061 "This is an ASYNC command",
1062 "This is a SYNC command"
1065 static const true_false_string tfs_flags_dfs_op = {
1066 "This is a DFS OPERATION",
1067 "This is a normal operation"
1070 static const true_false_string tfs_flags_chained = {
1071 "This pdu a CHAINED command",
1072 "This pdu is NOT a chained command"
1075 static const true_false_string tfs_flags_signature = {
1076 "This pdu is SIGNED",
1077 "This pdu is NOT signed"
1080 static const true_false_string tfs_flags_replay_operation = {
1081 "This is a REPLAY OPEARATION",
1082 "This is NOT a replay operation"
1085 static const true_false_string tfs_cap_dfs = {
1086 "This host supports DFS",
1087 "This host does NOT support DFS"
1090 static const true_false_string tfs_cap_leasing = {
1091 "This host supports LEASING",
1092 "This host does NOT support LEASING"
1095 static const true_false_string tfs_cap_large_mtu = {
1096 "This host supports LARGE_MTU",
1097 "This host does NOT support LARGE_MTU"
1100 static const true_false_string tfs_cap_multi_channel = {
1101 "This host supports MULTI CHANNEL",
1102 "This host does NOT support MULTI CHANNEL"
1105 static const true_false_string tfs_cap_persistent_handles = {
1106 "This host supports PERSISTENT HANDLES",
1107 "This host does NOT support PERSISTENT HANDLES"
1110 static const true_false_string tfs_cap_directory_leasing = {
1111 "This host supports DIRECTORY LEASING",
1112 "This host does NOT support DIRECTORY LEASING"
1115 static const true_false_string tfs_cap_encryption = {
1116 "This host supports ENCRYPTION",
1117 "This host does NOT support ENCRYPTION"
1120 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rss = {
1121 "This interface supports RSS",
1122 "This interface does not support RSS"
1125 static const true_false_string tfs_smb2_ioctl_network_interface_capability_rdma = {
1126 "This interface supports RDMA",
1127 "This interface does not support RDMA"
1130 static const value_string compression_format_vals[] = {
1131 { 0, "COMPRESSION_FORMAT_NONE" },
1132 { 1, "COMPRESSION_FORMAT_DEFAULT" },
1133 { 2, "COMPRESSION_FORMAT_LZNT1" },
1134 { 0, NULL }
1138 static const value_string smb2_ioctl_vals[] = {
1139 /* dissector implemented */
1140 {0x00060194, "FSCTL_DFS_GET_REFERRALS"},
1141 {0x0011C017, "FSCTL_PIPE_TRANSCEIVE"},
1142 {0x00110018, "FSCTL_PIPE_WAIT"},
1143 {0x001401D4, "FSCTL_LMR_REQUEST_RESILIENCY"},
1144 {0x001401FC, "FSCTL_QUERY_NETWORK_INTERFACE_INFO"},
1145 {0x00140200, "FSCTL_VALIDATE_NEGOTIATE_INFO_224"},
1146 {0x00140204, "FSCTL_VALIDATE_NEGOTIATE_INFO"},
1147 {0x00144064, "FSCTL_GET_SHADOW_COPY_DATA"},
1148 {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},
1149 {0x0009009C, "FSCTL_GET_OBJECT_ID"},
1150 {0x000980A0, "FSCTL_DELETE_OBJECT_ID"}, /* no data in/out */
1151 {0x00098098, "FSCTL_SET_OBJECT_ID"},
1152 {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},
1153 {0x0009003C, "FSCTL_GET_COMPRESSION"},
1154 {0x0009C040, "FSCTL_SET_COMPRESSION"},
1156 /* dissector not yet implemented */
1157 {0x001440F2, "FSCTL_SRV_COPYCHUNK"},
1158 {0x00140078, "FSCTL_SRV_REQUEST_RESUME_KEY"},
1159 {0x001441bb, "FSCTL_SRV_READ_HASH"},
1160 {0x001480F2, "FSCTL_SRV_COPYCHUNK_WRITE"},
1161 {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
1162 {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
1163 {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
1164 {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
1165 {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
1166 {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
1167 {0x00090018, "FSCTL_LOCK_VOLUME"},
1168 {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
1169 {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
1170 {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
1171 {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
1172 {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
1173 {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
1174 {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
1175 {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
1176 {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
1177 {0x00090058, "FSCTL_QUERY_FAT_BPB"},
1178 {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
1179 {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
1180 {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
1181 {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
1182 {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
1183 {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
1184 {0x00090074, "FSCTL_MOVE_FILE"},
1185 {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
1186 {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
1187 {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
1188 {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
1189 {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
1190 {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
1191 {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
1192 {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
1193 {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
1194 {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
1195 {0x000940B3, "FSCTL_ENUM_USN_DATA"},
1196 {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
1197 {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
1198 {0x000980C4, "FSCTL_SET_SPARSE"},
1199 {0x000980C8, "FSCTL_SET_ZERO_DATA"},
1200 {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},
1201 {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
1202 {0x000900D4, "FSCTL_SET_ENCRYPTION"},
1203 {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
1204 {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
1205 {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
1206 {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
1207 {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
1208 {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
1209 {0x000900F0, "FSCTL_EXTEND_VOLUME"},
1210 { 0, NULL }
1214 static const value_string smb2_ioctl_device_vals[] = {
1215 { 0x0001, "BEEP" },
1216 { 0x0002, "CD_ROM" },
1217 { 0x0003, "CD_ROM_FILE_SYSTEM" },
1218 { 0x0004, "CONTROLLER" },
1219 { 0x0005, "DATALINK" },
1220 { 0x0006, "DFS" },
1221 { 0x0007, "DISK" },
1222 { 0x0008, "DISK_FILE_SYSTEM" },
1223 { 0x0009, "FILE_SYSTEM" },
1224 { 0x000a, "INPORT_PORT" },
1225 { 0x000b, "KEYBOARD" },
1226 { 0x000c, "MAILSLOT" },
1227 { 0x000d, "MIDI_IN" },
1228 { 0x000e, "MIDI_OUT" },
1229 { 0x000f, "MOUSE" },
1230 { 0x0010, "MULTI_UNC_PROVIDER" },
1231 { 0x0011, "NAMED_PIPE" },
1232 { 0x0012, "NETWORK" },
1233 { 0x0013, "NETWORK_BROWSER" },
1234 { 0x0014, "NETWORK_FILE_SYSTEM" },
1235 { 0x0015, "NULL" },
1236 { 0x0016, "PARALLEL_PORT" },
1237 { 0x0017, "PHYSICAL_NETCARD" },
1238 { 0x0018, "PRINTER" },
1239 { 0x0019, "SCANNER" },
1240 { 0x001a, "SERIAL_MOUSE_PORT" },
1241 { 0x001b, "SERIAL_PORT" },
1242 { 0x001c, "SCREEN" },
1243 { 0x001d, "SOUND" },
1244 { 0x001e, "STREAMS" },
1245 { 0x001f, "TAPE" },
1246 { 0x0020, "TAPE_FILE_SYSTEM" },
1247 { 0x0021, "TRANSPORT" },
1248 { 0x0022, "UNKNOWN" },
1249 { 0x0023, "VIDEO" },
1250 { 0x0024, "VIRTUAL_DISK" },
1251 { 0x0025, "WAVE_IN" },
1252 { 0x0026, "WAVE_OUT" },
1253 { 0x0027, "8042_PORT" },
1254 { 0x0028, "NETWORK_REDIRECTOR" },
1255 { 0x0029, "BATTERY" },
1256 { 0x002a, "BUS_EXTENDER" },
1257 { 0x002b, "MODEM" },
1258 { 0x002c, "VDM" },
1259 { 0x002d, "MASS_STORAGE" },
1260 { 0x002e, "SMB" },
1261 { 0x002f, "KS" },
1262 { 0x0030, "CHANGER" },
1263 { 0x0031, "SMARTCARD" },
1264 { 0x0032, "ACPI" },
1265 { 0x0033, "DVD" },
1266 { 0x0034, "FULLSCREEN_VIDEO" },
1267 { 0x0035, "DFS_FILE_SYSTEM" },
1268 { 0x0036, "DFS_VOLUME" },
1269 { 0x0037, "SERENUM" },
1270 { 0x0038, "TERMSRV" },
1271 { 0x0039, "KSEC" },
1272 { 0, NULL }
1275 static const value_string smb2_ioctl_access_vals[] = {
1276 { 0x00, "FILE_ANY_ACCESS" },
1277 { 0x01, "FILE_READ_ACCESS" },
1278 { 0x02, "FILE_WRITE_ACCESS" },
1279 { 0x03, "FILE_READ_WRITE_ACCESS" },
1280 { 0, NULL }
1283 static const value_string smb2_ioctl_method_vals[] = {
1284 { 0x00, "METHOD_BUFFERED" },
1285 { 0x01, "METHOD_IN_DIRECT" },
1286 { 0x02, "METHOD_OUT_DIRECT" },
1287 { 0x03, "METHOD_NEITHER" },
1288 { 0, NULL }
1291 /* this is called from both smb and smb2. */
1293 dissect_smb2_ioctl_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 *ioctlfunc)
1295 proto_item *item = NULL;
1296 proto_tree *tree = NULL;
1297 guint32 ioctl_function;
1299 if (parent_tree) {
1300 item = proto_tree_add_item(parent_tree, hf_smb2_ioctl_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1301 tree = proto_item_add_subtree(item, ett_smb2_ioctl_function);
1304 ioctl_function = tvb_get_letohl(tvb, offset);
1305 if (ioctlfunc)
1306 *ioctlfunc = ioctl_function;
1307 if (ioctl_function) {
1308 const gchar *unknown = "unknown";
1309 const gchar *ioctl_name = val_to_str_const(ioctl_function,
1310 smb2_ioctl_vals,
1311 unknown);
1314 * val_to_str_const() doesn't work with a unknown == NULL
1316 if (ioctl_name == unknown) {
1317 ioctl_name = NULL;
1320 if (ioctl_name != NULL) {
1321 col_append_fstr(
1322 pinfo->cinfo, COL_INFO, " %s", ioctl_name);
1325 /* device */
1326 proto_tree_add_item(tree, hf_smb2_ioctl_function_device, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1327 if (ioctl_name == NULL) {
1328 col_append_fstr(
1329 pinfo->cinfo, COL_INFO, " %s",
1330 val_to_str((ioctl_function>>16)&0xffff, smb2_ioctl_device_vals,
1331 "Unknown (0x%08X)"));
1334 /* access */
1335 proto_tree_add_item(tree, hf_smb2_ioctl_function_access, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1337 /* function */
1338 proto_tree_add_item(tree, hf_smb2_ioctl_function_function, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1339 if (ioctl_name == NULL) {
1340 col_append_fstr(
1341 pinfo->cinfo, COL_INFO, " Function:0x%04x",
1342 (ioctl_function>>2)&0x0fff);
1345 /* method */
1346 proto_tree_add_item(tree, hf_smb2_ioctl_function_method, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1349 offset += 4;
1351 return offset;
1354 /* fake the dce/rpc support structures so we can piggy back on
1355 * dissect_nt_policy_hnd() since this will allow us
1356 * a cheap way to track where FIDs are opened, closed
1357 * and fid->filename mappings
1358 * if we want to do those things in the future.
1360 #define FID_MODE_OPEN 0
1361 #define FID_MODE_CLOSE 1
1362 #define FID_MODE_USE 2
1363 #define FID_MODE_DHNQ 3
1364 #define FID_MODE_DHNC 4
1365 static int
1366 dissect_smb2_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si, int mode)
1368 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1369 static dcerpc_info di; /* fake dcerpc_info struct */
1370 static dcerpc_call_value call_data;
1371 e_ctx_hnd policy_hnd;
1372 e_ctx_hnd *policy_hnd_hashtablekey;
1373 proto_item *hnd_item = NULL;
1374 char *fid_name;
1375 guint32 open_frame = 0, close_frame = 0;
1376 smb2_eo_file_info_t *eo_file_info;
1378 di.conformant_run = 0;
1379 /* we need di->call_data->flags.NDR64 == 0 */
1380 di.call_data = &call_data;
1382 switch (mode) {
1383 case FID_MODE_OPEN:
1384 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, TRUE, FALSE);
1385 if (!pinfo->fd->flags.visited) {
1386 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
1387 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: %s", (char *)si->saved->extra_info);
1388 } else {
1389 fid_name = wmem_strdup_printf(wmem_file_scope(), "File: ");
1391 dcerpc_store_polhnd_name(&policy_hnd, pinfo,
1392 fid_name);
1394 /* If needed, create the file entry and save the policy hnd */
1395 if (si->saved) { si->saved->policy_hnd = policy_hnd; }
1397 if (si->conv) {
1398 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1399 if (!eo_file_info) {
1400 eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1401 policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1402 memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1403 eo_file_info->end_of_file=0;
1404 g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1406 si->eo_file_info=eo_file_info;
1409 break;
1410 case FID_MODE_CLOSE:
1411 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, TRUE);
1412 break;
1413 case FID_MODE_USE:
1414 case FID_MODE_DHNQ:
1415 case FID_MODE_DHNC:
1416 offset = dissect_nt_guid_hnd(tvb, offset, pinfo, tree, &di, drep, hf_smb2_fid, &policy_hnd, &hnd_item, FALSE, FALSE);
1417 break;
1420 if (dcerpc_fetch_polhnd_data(&policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num)) {
1421 /* put the filename in col_info */
1422 if (fid_name) {
1423 if (hnd_item) {
1424 proto_item_append_text(hnd_item, " %s", fid_name);
1426 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", fid_name);
1427 pinfo->dcerpc_procedure_name = fid_name;
1430 /* look for the eo_file_info */
1431 if (!si->eo_file_info) {
1432 if (si->saved) { si->saved->policy_hnd = policy_hnd; }
1433 if (si->conv) {
1434 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&policy_hnd);
1435 if (eo_file_info) {
1436 si->eo_file_info=eo_file_info;
1437 } else { /* XXX This should never happen */
1438 eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
1439 policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
1440 memcpy(policy_hnd_hashtablekey, &policy_hnd, sizeof(e_ctx_hnd));
1441 eo_file_info->end_of_file=0;
1442 g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
1449 return offset;
1453 /* this info level is unique to SMB2 and differst from the corresponding
1454 * SMB_FILE_ALL_INFO in SMB
1456 static int
1457 dissect_smb2_file_all_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1459 proto_item *item = NULL;
1460 proto_tree *tree = NULL;
1461 int length;
1462 const char *name = "";
1463 guint16 bc;
1465 if (parent_tree) {
1466 item = proto_tree_add_item(parent_tree, hf_smb2_file_all_info, tvb, offset, -1, ENC_NA);
1467 tree = proto_item_add_subtree(item, ett_smb2_file_all_info);
1470 /* create time */
1471 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1473 /* last access */
1474 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1476 /* last write */
1477 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1479 /* last change */
1480 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1482 /* File Attributes */
1483 offset = dissect_file_ext_attr(tvb, tree, offset);
1485 /* some unknown bytes */
1486 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
1487 offset += 4;
1489 /* allocation size */
1490 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1491 offset += 8;
1493 /* end of file */
1494 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1495 offset += 8;
1497 /* number of links */
1498 proto_tree_add_item(tree, hf_smb2_nlinks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1499 offset += 4;
1501 /* delete pending */
1502 proto_tree_add_item(tree, hf_smb2_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1503 offset += 1;
1505 /* is directory */
1506 proto_tree_add_item(tree, hf_smb2_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1507 offset += 1;
1509 /* padding */
1510 offset += 2;
1512 /* file id */
1513 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1514 offset += 8;
1516 /* ea size */
1517 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1518 offset += 4;
1520 /* access mask */
1521 offset = dissect_smb_access_mask(tvb, tree, offset);
1523 /* some unknown bytes */
1524 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
1525 offset += 16;
1527 /* file name length */
1528 length = tvb_get_letohs(tvb, offset);
1529 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1530 offset += 2;
1532 /* some unknown bytes */
1533 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
1534 offset += 2;
1536 /* file name */
1537 if (length) {
1538 bc = tvb_length_remaining(tvb, offset);
1539 name = get_unicode_or_ascii_string(tvb, &offset,
1540 TRUE, &length, TRUE, TRUE, &bc);
1541 if (name) {
1542 proto_tree_add_string(tree, hf_smb2_filename, tvb,
1543 offset, length, name);
1547 offset += length;
1550 return offset;
1554 static int
1555 dissect_smb2_file_allocation_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1557 proto_item *item = NULL;
1558 proto_tree *tree = NULL;
1559 guint16 bc;
1560 gboolean trunc;
1562 if (parent_tree) {
1563 item = proto_tree_add_item(parent_tree, hf_smb2_file_allocation_info, tvb, offset, -1, ENC_NA);
1564 tree = proto_item_add_subtree(item, ett_smb2_file_allocation_info);
1567 bc = tvb_length_remaining(tvb, offset);
1568 offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1570 return offset;
1573 static int
1574 dissect_smb2_file_endoffile_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1576 proto_item *item = NULL;
1577 proto_tree *tree = NULL;
1578 guint16 bc;
1579 gboolean trunc;
1581 if (parent_tree) {
1582 item = proto_tree_add_item(parent_tree, hf_smb2_file_endoffile_info, tvb, offset, -1, ENC_NA);
1583 tree = proto_item_add_subtree(item, ett_smb2_file_endoffile_info);
1586 bc = tvb_length_remaining(tvb, offset);
1587 offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1589 return offset;
1592 static int
1593 dissect_smb2_file_alternate_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1595 proto_item *item = NULL;
1596 proto_tree *tree = NULL;
1597 guint16 bc;
1598 gboolean trunc;
1600 if (parent_tree) {
1601 item = proto_tree_add_item(parent_tree, hf_smb2_file_alternate_name_info, tvb, offset, -1, ENC_NA);
1602 tree = proto_item_add_subtree(item, ett_smb2_file_alternate_name_info);
1605 bc = tvb_length_remaining(tvb, offset);
1606 offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, &bc, &trunc, /* XXX assumption hack */ TRUE);
1608 return offset;
1612 static int
1613 dissect_smb2_file_basic_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1615 proto_item *item = NULL;
1616 proto_tree *tree = NULL;
1618 if (parent_tree) {
1619 item = proto_tree_add_item(parent_tree, hf_smb2_file_basic_info, tvb, offset, -1, ENC_NA);
1620 tree = proto_item_add_subtree(item, ett_smb2_file_basic_info);
1623 /* create time */
1624 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
1626 /* last access */
1627 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
1629 /* last write */
1630 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
1632 /* last change */
1633 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
1635 /* File Attributes */
1636 offset = dissect_file_ext_attr(tvb, tree, offset);
1638 /* some unknown bytes */
1639 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
1640 offset += 4;
1642 return offset;
1645 static int
1646 dissect_smb2_file_standard_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1648 proto_item *item = NULL;
1649 proto_tree *tree = NULL;
1650 guint16 bc;
1651 gboolean trunc;
1653 if (parent_tree) {
1654 item = proto_tree_add_item(parent_tree, hf_smb2_file_standard_info, tvb, offset, -1, ENC_NA);
1655 tree = proto_item_add_subtree(item, ett_smb2_file_standard_info);
1658 bc = tvb_length_remaining(tvb, offset);
1659 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1661 return offset;
1663 static int
1664 dissect_smb2_file_internal_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1666 proto_item *item = NULL;
1667 proto_tree *tree = NULL;
1668 guint16 bc;
1669 gboolean trunc;
1671 if (parent_tree) {
1672 item = proto_tree_add_item(parent_tree, hf_smb2_file_internal_info, tvb, offset, -1, ENC_NA);
1673 tree = proto_item_add_subtree(item, ett_smb2_file_internal_info);
1676 bc = tvb_length_remaining(tvb, offset);
1677 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1679 return offset;
1681 static int
1682 dissect_smb2_file_mode_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1684 proto_item *item = NULL;
1685 proto_tree *tree = NULL;
1686 guint16 bc;
1687 gboolean trunc;
1689 if (parent_tree) {
1690 item = proto_tree_add_item(parent_tree, hf_smb2_file_mode_info, tvb, offset, -1, ENC_NA);
1691 tree = proto_item_add_subtree(item, ett_smb2_file_mode_info);
1694 bc = tvb_length_remaining(tvb, offset);
1695 offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1697 return offset;
1699 static int
1700 dissect_smb2_file_alignment_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1702 proto_item *item = NULL;
1703 proto_tree *tree = NULL;
1704 guint16 bc;
1705 gboolean trunc;
1707 if (parent_tree) {
1708 item = proto_tree_add_item(parent_tree, hf_smb2_file_alignment_info, tvb, offset, -1, ENC_NA);
1709 tree = proto_item_add_subtree(item, ett_smb2_file_alignment_info);
1712 bc = tvb_length_remaining(tvb, offset);
1713 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1715 return offset;
1717 static int
1718 dissect_smb2_file_position_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1720 proto_item *item = NULL;
1721 proto_tree *tree = NULL;
1722 guint16 bc;
1723 gboolean trunc;
1725 if (parent_tree) {
1726 item = proto_tree_add_item(parent_tree, hf_smb2_file_position_info, tvb, offset, -1, ENC_NA);
1727 tree = proto_item_add_subtree(item, ett_smb2_file_position_info);
1730 bc = tvb_length_remaining(tvb, offset);
1731 offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1733 return offset;
1736 static int
1737 dissect_smb2_file_access_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1739 proto_item *item = NULL;
1740 proto_tree *tree = NULL;
1742 if (parent_tree) {
1743 item = proto_tree_add_item(parent_tree, hf_smb2_file_access_info, tvb, offset, -1, ENC_NA);
1744 tree = proto_item_add_subtree(item, ett_smb2_file_access_info);
1747 /* access mask */
1748 offset = dissect_smb_access_mask(tvb, tree, offset);
1750 return offset;
1753 static int
1754 dissect_smb2_file_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1756 proto_item *item = NULL;
1757 proto_tree *tree = NULL;
1758 guint16 bc;
1759 gboolean trunc;
1761 if (parent_tree) {
1762 item = proto_tree_add_item(parent_tree, hf_smb2_file_ea_info, tvb, offset, -1, ENC_NA);
1763 tree = proto_item_add_subtree(item, ett_smb2_file_ea_info);
1766 bc = tvb_length_remaining(tvb, offset);
1767 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1769 return offset;
1772 static int
1773 dissect_smb2_file_stream_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1775 proto_item *item = NULL;
1776 proto_tree *tree = NULL;
1777 guint16 bc;
1778 gboolean trunc;
1780 if (parent_tree) {
1781 item = proto_tree_add_item(parent_tree, hf_smb2_file_stream_info, tvb, offset, -1, ENC_NA);
1782 tree = proto_item_add_subtree(item, ett_smb2_file_stream_info);
1785 bc = tvb_length_remaining(tvb, offset);
1786 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, &bc, &trunc, TRUE);
1788 return offset;
1791 static int
1792 dissect_smb2_file_pipe_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1794 proto_item *item = NULL;
1795 proto_tree *tree = NULL;
1796 guint16 bc;
1797 gboolean trunc;
1799 if (parent_tree) {
1800 item = proto_tree_add_item(parent_tree, hf_smb2_file_pipe_info, tvb, offset, -1, ENC_NA);
1801 tree = proto_item_add_subtree(item, ett_smb2_file_pipe_info);
1804 bc = tvb_length_remaining(tvb, offset);
1805 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1807 return offset;
1810 static int
1811 dissect_smb2_file_compression_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1813 proto_item *item = NULL;
1814 proto_tree *tree = NULL;
1815 guint16 bc;
1816 gboolean trunc;
1818 if (parent_tree) {
1819 item = proto_tree_add_item(parent_tree, hf_smb2_file_compression_info, tvb, offset, -1, ENC_NA);
1820 tree = proto_item_add_subtree(item, ett_smb2_file_compression_info);
1823 bc = tvb_length_remaining(tvb, offset);
1824 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1826 return offset;
1829 static int
1830 dissect_smb2_file_network_open_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1832 proto_item *item = NULL;
1833 proto_tree *tree = NULL;
1834 guint16 bc;
1835 gboolean trunc;
1837 if (parent_tree) {
1838 item = proto_tree_add_item(parent_tree, hf_smb2_file_network_open_info, tvb, offset, -1, ENC_NA);
1839 tree = proto_item_add_subtree(item, ett_smb2_file_network_open_info);
1843 bc = tvb_length_remaining(tvb, offset);
1844 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1846 return offset;
1849 static int
1850 dissect_smb2_file_attribute_tag_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1852 proto_item *item = NULL;
1853 proto_tree *tree = NULL;
1854 guint16 bc;
1855 gboolean trunc;
1857 if (parent_tree) {
1858 item = proto_tree_add_item(parent_tree, hf_smb2_file_attribute_tag_info, tvb, offset, -1, ENC_NA);
1859 tree = proto_item_add_subtree(item, ett_smb2_file_attribute_tag_info);
1863 bc = tvb_length_remaining(tvb, offset);
1864 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, &bc, &trunc);
1866 return offset;
1869 static const true_false_string tfs_disposition_delete_on_close = {
1870 "DELETE this file when closed",
1871 "Normal access, do not delete on close"
1874 static int
1875 dissect_smb2_file_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1877 proto_item *item = NULL;
1878 proto_tree *tree = NULL;
1880 if (parent_tree) {
1881 item = proto_tree_add_item(parent_tree, hf_smb2_file_disposition_info, tvb, offset, -1, ENC_NA);
1882 tree = proto_item_add_subtree(item, ett_smb2_file_disposition_info);
1885 /* file disposition */
1886 proto_tree_add_item(tree, hf_smb2_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1888 return offset;
1891 static int
1892 dissect_smb2_file_full_ea_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1894 proto_item *item = NULL;
1895 proto_tree *tree = NULL;
1896 guint32 next_offset;
1897 guint8 ea_name_len;
1898 guint16 ea_data_len;
1900 if (parent_tree) {
1901 item = proto_tree_add_item(parent_tree, hf_smb2_file_full_ea_info, tvb, offset, -1, ENC_NA);
1902 tree = proto_item_add_subtree(item, ett_smb2_file_full_ea_info);
1905 while (1) {
1906 int length;
1907 const char *name = "";
1908 const char *data = "";
1909 guint16 bc;
1910 int start_offset = offset;
1911 proto_item *ea_item = NULL;
1912 proto_tree *ea_tree = NULL;
1914 if (tree) {
1915 ea_item = proto_tree_add_text(tree, tvb, offset, -1, "EA:");
1916 ea_tree = proto_item_add_subtree(ea_item, ett_smb2_ea);
1919 /* next offset */
1920 next_offset = tvb_get_letohl(tvb, offset);
1921 proto_tree_add_item(ea_tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1922 offset += 4;
1924 /* EA flags */
1925 proto_tree_add_item(ea_tree, hf_smb2_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1926 offset += 1;
1928 /* EA Name Length */
1929 ea_name_len = tvb_get_guint8(tvb, offset);
1930 proto_tree_add_item(ea_tree, hf_smb2_ea_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1931 offset += 1;
1933 /* EA Data Length */
1934 ea_data_len = tvb_get_letohs(tvb, offset);
1935 proto_tree_add_item(ea_tree, hf_smb2_ea_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1936 offset += 2;
1938 /* ea name */
1939 length = ea_name_len;
1940 if (length) {
1941 bc = tvb_length_remaining(tvb, offset);
1942 name = get_unicode_or_ascii_string(tvb, &offset,
1943 FALSE, &length, TRUE, TRUE, &bc);
1944 if (name) {
1945 proto_tree_add_string(ea_tree, hf_smb2_ea_name, tvb,
1946 offset, length + 1, name);
1950 /* The name is terminated with a NULL */
1951 offset += ea_name_len + 1;
1953 /* ea data */
1954 length = ea_data_len;
1955 if (length) {
1956 bc = tvb_length_remaining(tvb, offset);
1957 data = get_unicode_or_ascii_string(tvb, &offset,
1958 FALSE, &length, TRUE, TRUE, &bc);
1960 * We put the data here ...
1962 proto_tree_add_item(ea_tree, hf_smb2_ea_data, tvb,
1963 offset, length, ENC_NA);
1965 offset += ea_data_len;
1968 if (ea_item) {
1969 proto_item_append_text(ea_item, " %s := %s", name, data);
1971 proto_item_set_len(ea_item, offset-start_offset);
1974 if (!next_offset) {
1975 break;
1978 offset = start_offset+next_offset;
1981 return offset;
1984 static int
1985 dissect_smb2_file_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
1987 proto_item *item = NULL;
1988 proto_tree *tree = NULL;
1989 int length;
1990 const char *name = "";
1991 guint16 bc;
1994 if (parent_tree) {
1995 item = proto_tree_add_item(parent_tree, hf_smb2_file_rename_info, tvb, offset, -1, ENC_NA);
1996 tree = proto_item_add_subtree(item, ett_smb2_file_rename_info);
1999 /* some unknown bytes */
2000 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
2001 offset += 16;
2003 /* file name length */
2004 length = tvb_get_letohs(tvb, offset);
2005 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2006 offset += 2;
2008 /* some unknown bytes */
2009 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
2010 offset += 2;
2012 /* file name */
2013 if (length) {
2014 bc = tvb_length_remaining(tvb, offset);
2015 name = get_unicode_or_ascii_string(tvb, &offset,
2016 TRUE, &length, TRUE, TRUE, &bc);
2017 if (name) {
2018 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2019 offset, length, name);
2022 col_append_fstr(pinfo->cinfo, COL_INFO, " NewName:%s", name);
2024 offset += length;
2026 /* some unknown bytes */
2027 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 4, ENC_NA);
2028 offset += 4;
2030 return offset;
2033 static int
2034 dissect_smb2_sec_info_00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2036 proto_item *item = NULL;
2037 proto_tree *tree = NULL;
2039 if (parent_tree) {
2040 item = proto_tree_add_item(parent_tree, hf_smb2_sec_info_00, tvb, offset, -1, ENC_NA);
2041 tree = proto_item_add_subtree(item, ett_smb2_sec_info_00);
2044 /* security descriptor */
2045 offset = dissect_nt_sec_desc(tvb, offset, pinfo, tree, NULL, TRUE, tvb_length_remaining(tvb, offset), NULL);
2047 return offset;
2050 static int
2051 dissect_smb2_fs_info_05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2053 proto_item *item = NULL;
2054 proto_tree *tree = NULL;
2055 guint16 bc;
2057 if (parent_tree) {
2058 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_05, tvb, offset, -1, ENC_NA);
2059 tree = proto_item_add_subtree(item, ett_smb2_fs_info_05);
2062 bc = tvb_length_remaining(tvb, offset);
2063 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2065 return offset;
2068 static int
2069 dissect_smb2_fs_info_06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2071 proto_item *item = NULL;
2072 proto_tree *tree = NULL;
2073 guint16 bc;
2075 if (parent_tree) {
2076 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_06, tvb, offset, -1, ENC_NA);
2077 tree = proto_item_add_subtree(item, ett_smb2_fs_info_06);
2080 bc = tvb_length_remaining(tvb, offset);
2081 offset = dissect_nt_quota(tvb, tree, offset, &bc);
2083 return offset;
2086 static int
2087 dissect_smb2_FS_OBJECTID_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2089 proto_item *item = NULL;
2090 proto_tree *tree = NULL;
2092 if (parent_tree) {
2093 item = proto_tree_add_item(parent_tree, hf_smb2_fs_objectid_info, tvb, offset, -1, ENC_NA);
2094 tree = proto_item_add_subtree(item, ett_smb2_fs_objectid_info);
2097 /* FILE_OBJECTID_BUFFER */
2098 offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
2100 return offset;
2103 static int
2104 dissect_smb2_fs_info_07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2106 proto_item *item = NULL;
2107 proto_tree *tree = NULL;
2108 guint16 bc;
2110 if (parent_tree) {
2111 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_07, tvb, offset, -1, ENC_NA);
2112 tree = proto_item_add_subtree(item, ett_smb2_fs_info_07);
2115 bc = tvb_length_remaining(tvb, offset);
2116 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2118 return offset;
2121 static int
2122 dissect_smb2_fs_info_01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2124 proto_item *item = NULL;
2125 proto_tree *tree = NULL;
2126 guint16 bc;
2128 if (parent_tree) {
2129 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_01, tvb, offset, -1, ENC_NA);
2130 tree = proto_item_add_subtree(item, ett_smb2_fs_info_01);
2134 bc = tvb_length_remaining(tvb, offset);
2135 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, &bc, TRUE);
2137 return offset;
2140 static int
2141 dissect_smb2_fs_info_03(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2143 proto_item *item = NULL;
2144 proto_tree *tree = NULL;
2145 guint16 bc;
2147 if (parent_tree) {
2148 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_03, tvb, offset, -1, ENC_NA);
2149 tree = proto_item_add_subtree(item, ett_smb2_fs_info_03);
2153 bc = tvb_length_remaining(tvb, offset);
2154 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, &bc);
2156 return offset;
2159 static int
2160 dissect_smb2_fs_info_04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
2162 proto_item *item = NULL;
2163 proto_tree *tree = NULL;
2164 guint16 bc;
2166 if (parent_tree) {
2167 item = proto_tree_add_item(parent_tree, hf_smb2_fs_info_04, tvb, offset, -1, ENC_NA);
2168 tree = proto_item_add_subtree(item, ett_smb2_fs_info_04);
2172 bc = tvb_length_remaining(tvb, offset);
2173 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, &bc);
2175 return offset;
2178 static const value_string oplock_vals[] = {
2179 { 0x00, "No oplock" },
2180 { 0x01, "Level2 oplock" },
2181 { 0x08, "Exclusive oplock" },
2182 { 0x09, "Batch oplock" },
2183 { 0xff, "Lease" },
2184 { 0, NULL }
2187 static int
2188 dissect_smb2_oplock(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2190 proto_tree_add_item(parent_tree, hf_smb2_oplock, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2192 offset += 1;
2193 return offset;
2196 static int
2197 dissect_smb2_buffercode(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint16 *length)
2199 proto_tree *tree;
2200 proto_item *item;
2201 guint16 buffer_code;
2203 /* dissect the first 2 bytes of the command PDU */
2204 buffer_code = tvb_get_letohs(tvb, offset);
2205 item = proto_tree_add_uint(parent_tree, hf_smb2_buffer_code, tvb, offset, 2, buffer_code);
2206 tree = proto_item_add_subtree(item, ett_smb2_buffercode);
2207 proto_tree_add_uint_format(tree, hf_smb2_buffer_code_len, tvb, offset, 2,
2208 buffer_code&0xfffe, "%s: %u",
2209 decode_numeric_bitfield(buffer_code, 0xfffe, 16, "Fixed Part Length"),
2210 buffer_code&0xfffe);
2211 proto_tree_add_item(tree, hf_smb2_buffer_code_flags_dyn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2212 offset += 2;
2214 if (length) {
2215 *length = buffer_code&0xfffe;
2218 return offset;
2221 #define NEGPROT_CAP_DFS 0x00000001
2222 #define NEGPROT_CAP_LEASING 0x00000002
2223 #define NEGPROT_CAP_LARGE_MTU 0x00000004
2224 #define NEGPROT_CAP_MULTI_CHANNEL 0x00000008
2225 #define NEGPROT_CAP_PERSISTENT_HANDLES 0x00000010
2226 #define NEGPROT_CAP_DIRECTORY_LEASING 0x00000020
2227 #define NEGPROT_CAP_ENCRYPTION 0x00000040
2228 static int
2229 dissect_smb2_capabilities(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2231 guint32 cap;
2232 proto_item *item = NULL;
2233 proto_tree *tree = NULL;
2235 cap = tvb_get_letohl(tvb, offset);
2237 item = proto_tree_add_item(parent_tree, hf_smb2_capabilities, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2238 tree = proto_item_add_subtree(item, ett_smb2_capabilities);
2241 proto_tree_add_boolean(tree, hf_smb2_cap_dfs, tvb, offset, 4, cap);
2242 proto_tree_add_boolean(tree, hf_smb2_cap_leasing, tvb, offset, 4, cap);
2243 proto_tree_add_boolean(tree, hf_smb2_cap_large_mtu, tvb, offset, 4, cap);
2244 proto_tree_add_boolean(tree, hf_smb2_cap_multi_channel, tvb, offset, 4, cap);
2245 proto_tree_add_boolean(tree, hf_smb2_cap_persistent_handles, tvb, offset, 4, cap);
2246 proto_tree_add_boolean(tree, hf_smb2_cap_directory_leasing, tvb, offset, 4, cap);
2247 proto_tree_add_boolean(tree, hf_smb2_cap_encryption, tvb, offset, 4, cap);
2249 offset += 4;
2251 return offset;
2256 #define NEGPROT_SIGN_REQ 0x0002
2257 #define NEGPROT_SIGN_ENABLED 0x0001
2259 static int
2260 dissect_smb2_secmode(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2262 guint8 sm;
2263 proto_item *item = NULL;
2264 proto_tree *tree = NULL;
2266 sm = tvb_get_guint8(tvb, offset);
2268 item = proto_tree_add_item(parent_tree, hf_smb2_security_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2269 tree = proto_item_add_subtree(item, ett_smb2_sec_mode);
2271 proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_enabled, tvb, offset, 1, sm);
2272 proto_tree_add_boolean(tree, hf_smb2_secmode_flags_sign_required, tvb, offset, 1, sm);
2274 offset += 1;
2276 return offset;
2279 #define SES_REQ_FLAGS_SESSION_BINDING 0x01
2281 static int
2282 dissect_smb2_ses_req_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2284 guint8 sf;
2285 proto_item *item = NULL;
2286 proto_tree *tree = NULL;
2288 sf = tvb_get_guint8(tvb, offset);
2290 item = proto_tree_add_item(parent_tree, hf_smb2_ses_req_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2291 tree = proto_item_add_subtree(item, ett_smb2_ses_req_flags);
2293 proto_tree_add_boolean(tree, hf_smb2_ses_req_flags_session_binding, tvb, offset, 1, sf);
2295 offset += 1;
2297 return offset;
2300 #define SES_FLAGS_GUEST 0x0001
2301 #define SES_FLAGS_NULL 0x0002
2303 static int
2304 dissect_smb2_ses_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
2306 guint16 sf;
2307 proto_item *item = NULL;
2308 proto_tree *tree = NULL;
2310 sf = tvb_get_letohs(tvb, offset);
2312 item = proto_tree_add_item(parent_tree, hf_smb2_session_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2313 tree = proto_item_add_subtree(item, ett_smb2_ses_flags);
2315 proto_tree_add_boolean(tree, hf_smb2_ses_flags_guest, tvb, offset, 2, sf);
2316 proto_tree_add_boolean(tree, hf_smb2_ses_flags_null, tvb, offset, 2, sf);
2318 offset += 2;
2320 return offset;
2323 #define SHARE_FLAGS_manual_caching 0x00000000
2324 #define SHARE_FLAGS_auto_caching 0x00000010
2325 #define SHARE_FLAGS_vdo_caching 0x00000020
2326 #define SHARE_FLAGS_no_caching 0x00000030
2328 static const value_string share_cache_vals[] = {
2329 { SHARE_FLAGS_manual_caching, "Manual caching" },
2330 { SHARE_FLAGS_auto_caching, "Auto caching" },
2331 { SHARE_FLAGS_vdo_caching, "VDO caching" },
2332 { SHARE_FLAGS_no_caching, "No caching" },
2333 { 0, NULL }
2336 #define SHARE_FLAGS_dfs 0x00000001
2337 #define SHARE_FLAGS_dfs_root 0x00000002
2338 #define SHARE_FLAGS_restrict_exclusive_opens 0x00000100
2339 #define SHARE_FLAGS_force_shared_delete 0x00000200
2340 #define SHARE_FLAGS_allow_namespace_caching 0x00000400
2341 #define SHARE_FLAGS_access_based_dir_enum 0x00000800
2342 #define SHARE_FLAGS_force_levelii_oplock 0x00001000
2343 #define SHARE_FLAGS_enable_hash_v1 0x00002000
2344 #define SHARE_FLAGS_enable_hash_v2 0x00004000
2345 #define SHARE_FLAGS_encryption_required 0x00008000
2347 static int
2348 dissect_smb2_share_flags(proto_tree *tree, tvbuff_t *tvb, int offset)
2350 static const int *sf_fields[] = {
2351 &hf_smb2_share_flags_dfs,
2352 &hf_smb2_share_flags_dfs_root,
2353 &hf_smb2_share_flags_restrict_exclusive_opens,
2354 &hf_smb2_share_flags_force_shared_delete,
2355 &hf_smb2_share_flags_allow_namespace_caching,
2356 &hf_smb2_share_flags_access_based_dir_enum,
2357 &hf_smb2_share_flags_force_levelii_oplock,
2358 &hf_smb2_share_flags_enable_hash_v1,
2359 &hf_smb2_share_flags_enable_hash_v2,
2360 &hf_smb2_share_flags_encrypt_data,
2361 NULL
2363 proto_item *item;
2364 guint32 cp;
2366 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_flags, ett_smb2_share_flags, sf_fields, ENC_LITTLE_ENDIAN);
2368 cp = tvb_get_letohl(tvb, offset);
2369 cp &= 0x00000030;
2370 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);
2373 offset += 4;
2375 return offset;
2378 #define SHARE_CAPS_DFS 0x00000008
2379 #define SHARE_CAPS_CONTINUOUS_AVAILABILITY 0x00000010
2380 #define SHARE_CAPS_SCALEOUT 0x00000020
2381 #define SHARE_CAPS_CLUSTER 0x00000040
2383 static int
2384 dissect_smb2_share_caps(proto_tree *tree, tvbuff_t *tvb, int offset)
2386 static const int *sc_fields[] = {
2387 &hf_smb2_share_caps_dfs,
2388 &hf_smb2_share_caps_continuous_availability,
2389 &hf_smb2_share_caps_scaleout,
2390 &hf_smb2_share_caps_cluster,
2391 NULL
2394 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_share_caps, ett_smb2_share_caps, sc_fields, ENC_LITTLE_ENDIAN);
2396 offset += 4;
2398 return offset;
2401 static void
2402 dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
2404 if ((tvb_length(tvb)>=7)
2405 && (!tvb_memeql(tvb, 0, "NTLMSSP", 7))) {
2406 call_dissector(ntlmssp_handle, tvb, pinfo, tree);
2407 } else {
2408 call_dissector(gssapi_handle, tvb, pinfo, tree);
2412 static int
2413 dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2415 offset_length_buffer_t s_olb;
2416 const ntlmssp_header_t *ntlmssph;
2417 static int ntlmssp_tap_id = 0;
2418 int idx;
2420 if (!ntlmssp_tap_id) {
2421 GString *error_string;
2422 /* We dont specify any callbacks at all.
2423 * Instead we manually fetch the tapped data after the
2424 * security blob has been fully dissected and before
2425 * we exit from this dissector.
2427 error_string = register_tap_listener("ntlmssp", NULL, NULL,
2428 TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
2429 if (!error_string) {
2430 ntlmssp_tap_id = find_tap_id("ntlmssp");
2431 } else {
2432 g_string_free(error_string, TRUE);
2437 /* buffer code */
2438 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2439 /* some unknown bytes */
2441 /* flags */
2442 offset = dissect_smb2_ses_req_flags(tree, tvb, offset);
2444 /* security mode */
2445 offset = dissect_smb2_secmode(tree, tvb, offset);
2447 /* capabilities */
2448 offset = dissect_smb2_capabilities(tree, tvb, offset);
2450 /* channel */
2451 proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2452 offset += 4;
2454 /* security blob offset/length */
2455 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2457 /* previous session id */
2458 proto_tree_add_item(tree, hf_smb2_previous_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2459 offset += 8;
2462 /* the security blob itself */
2463 dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2465 offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2467 /* If we have found a uid->acct_name mapping, store it */
2468 if (!pinfo->fd->flags.visited) {
2469 idx = 0;
2470 while ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL) {
2471 if (ntlmssph && ntlmssph->type == NTLMSSP_AUTH) {
2472 smb2_sesid_info_t *sesid;
2473 sesid = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
2474 sesid->sesid = si->sesid;
2475 sesid->acct_name = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
2476 sesid->domain_name = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
2477 sesid->host_name = wmem_strdup(wmem_file_scope(), ntlmssph->host_name);
2478 if (memcmp(ntlmssph->session_key, zeros, NTLMSSP_KEY_LEN) != 0) {
2479 smb2_key_derivation(ntlmssph->session_key,
2480 NTLMSSP_KEY_LEN,
2481 "SMB2AESCCM", 11,
2482 "ServerIn ", 10,
2483 sesid->server_decryption_key);
2484 smb2_key_derivation(ntlmssph->session_key,
2485 NTLMSSP_KEY_LEN,
2486 "SMB2AESCCM", 11,
2487 "ServerOut", 10,
2488 sesid->client_decryption_key);
2489 } else {
2490 memset(sesid->server_decryption_key, 0,
2491 sizeof(sesid->server_decryption_key));
2492 memset(sesid->client_decryption_key, 0,
2493 sizeof(sesid->client_decryption_key));
2495 sesid->server_port = pinfo->destport;
2496 sesid->auth_frame = pinfo->fd->num;
2497 sesid->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
2498 g_hash_table_insert(si->conv->sesids, sesid, sesid);
2503 return offset;
2506 static int
2507 dissect_smb2_error_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2509 gint byte_count;
2511 /* buffer code */
2512 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2515 /* Reserved (2 bytes) */
2516 proto_tree_add_item(tree, hf_smb2_error_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2517 offset += 2;
2519 /* ByteCount (4 bytes): The number of bytes of data contained in ErrorData[]. */
2520 byte_count = tvb_get_ntohl(tvb, offset);
2521 proto_tree_add_item(tree, hf_smb2_error_byte_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2522 offset += 4;
2524 /* If the ByteCount field is zero then the server MUST supply an ErrorData field
2525 that is one byte in length */
2526 if (byte_count == 0) byte_count = 1;
2528 /* ErrorData (variable): A variable-length data field that contains extended
2529 error information.*/
2530 proto_tree_add_item(tree, hf_smb2_error_data, tvb, offset, byte_count, ENC_NA);
2531 offset += byte_count;
2533 return offset;
2536 static int
2537 dissect_smb2_session_setup_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2539 offset_length_buffer_t s_olb;
2541 /* session_setup is special and we don't use dissect_smb2_error_response() here! */
2543 /* buffer code */
2544 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2546 /* session flags */
2547 offset = dissect_smb2_ses_flags(tree, tvb, offset);
2549 /* security blob offset/length */
2550 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
2552 /* the security blob itself */
2553 dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
2555 offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
2557 return offset;
2560 static int
2561 dissect_smb2_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2563 offset_length_buffer_t olb;
2564 const char *buf;
2566 /* buffer code */
2567 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2569 /* reserved */
2570 offset += 2;
2572 /* tree offset/length */
2573 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_tree);
2575 /* tree string */
2576 buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2578 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2580 /* treelen +1 is overkill here if the string is unicode,
2581 * but who ever has more than a handful of TCON in a trace anyways
2583 if (!pinfo->fd->flags.visited && si->saved && buf && olb.len) {
2584 si->saved->extra_info_type = SMB2_EI_TREENAME;
2585 si->saved->extra_info = wmem_alloc(wmem_file_scope(), olb.len+1);
2586 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2589 col_append_fstr(pinfo->cinfo, COL_INFO, " Tree: %s", buf);
2591 return offset;
2593 static int
2594 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
2596 guint16 share_type;
2598 switch (si->status) {
2599 case 0x00000000: break;
2600 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2603 /* buffer code */
2604 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2606 /* share type */
2607 share_type = tvb_get_letohs(tvb, offset);
2608 proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2609 /* Next byte is reserved and must be set to zero */
2610 offset += 2;
2612 if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_TREENAME && si->session) {
2613 smb2_tid_info_t *tid, tid_key;
2615 tid_key.tid = si->tid;
2616 tid = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
2617 if (tid) {
2618 g_hash_table_remove(si->session->tids, &tid_key);
2620 tid = wmem_new(wmem_file_scope(), smb2_tid_info_t);
2621 tid->tid = si->tid;
2622 tid->name = (char *)si->saved->extra_info;
2623 tid->connect_frame = pinfo->fd->num;
2624 tid->share_type = share_type;
2626 g_hash_table_insert(si->session->tids, tid, tid);
2628 si->saved->extra_info_type = SMB2_EI_NONE;
2629 si->saved->extra_info = NULL;
2632 /* share flags */
2633 offset = dissect_smb2_share_flags(tree, tvb, offset);
2635 /* share capabilities */
2636 offset = dissect_smb2_share_caps(tree, tvb, offset);
2638 /* this is some sort of access mask */
2639 offset = dissect_smb_access_mask(tvb, tree, offset);
2641 return offset;
2644 static int
2645 dissect_smb2_tree_disconnect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2647 /* buffer code */
2648 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2650 /* reserved */
2651 offset += 2;
2653 return offset;
2656 static int
2657 dissect_smb2_tree_disconnect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2659 switch (si->status) {
2660 case 0x00000000: break;
2661 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2664 /* buffer code */
2665 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2667 /* reserved */
2668 offset += 2;
2670 return offset;
2673 static int
2674 dissect_smb2_sessionlogoff_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2676 /* buffer code */
2677 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2679 /* reserved bytes */
2680 offset += 2;
2682 return offset;
2685 static int
2686 dissect_smb2_sessionlogoff_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2688 switch (si->status) {
2689 case 0x00000000: break;
2690 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2693 /* buffer code */
2694 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2696 /* reserved bytes */
2697 offset += 2;
2699 return offset;
2702 static int
2703 dissect_smb2_keepalive_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2705 /* buffer code */
2706 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2708 /* some unknown bytes */
2709 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
2710 offset += 2;
2712 return offset;
2715 static int
2716 dissect_smb2_keepalive_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
2718 switch (si->status) {
2719 case 0x00000000: break;
2720 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2723 /* buffer code */
2724 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2726 /* some unknown bytes */
2727 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
2728 offset += 2;
2730 return offset;
2733 static int
2734 dissect_smb2_notify_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2736 proto_tree *flags_tree = NULL;
2737 proto_item *flags_item = NULL;
2739 /* buffer code */
2740 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2742 /* notify flags */
2743 if (tree) {
2744 flags_item = proto_tree_add_item(tree, hf_smb2_notify_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2745 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_notify_flags);
2747 proto_tree_add_item(flags_tree, hf_smb2_notify_watch_tree, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2748 offset += 2;
2750 /* output buffer length */
2751 proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2752 offset += 4;
2754 /* fid */
2755 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2757 /* completion filter */
2758 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
2760 /* reserved */
2761 offset += 4;
2763 return offset;
2766 static void
2767 dissect_smb2_notify_data_out(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
2769 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA);
2772 static int
2773 dissect_smb2_notify_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
2775 offset_length_buffer_t olb;
2777 switch (si->status) {
2778 case 0x00000000: break;
2779 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
2782 /* buffer code */
2783 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2785 /* out buffer offset/length */
2786 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_notify_out_data);
2788 /* out buffer */
2789 dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_notify_data_out);
2790 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2792 return offset;
2795 #define SMB2_FIND_FLAG_RESTART_SCANS 0x01
2796 #define SMB2_FIND_FLAG_SINGLE_ENTRY 0x02
2797 #define SMB2_FIND_FLAG_INDEX_SPECIFIED 0x04
2798 #define SMB2_FIND_FLAG_REOPEN 0x10
2800 static int
2801 dissect_smb2_find_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
2803 offset_length_buffer_t olb;
2804 const char *buf;
2805 guint8 il;
2806 static const int *f_fields[] = {
2807 &hf_smb2_find_flags_restart_scans,
2808 &hf_smb2_find_flags_single_entry,
2809 &hf_smb2_find_flags_index_specified,
2810 &hf_smb2_find_flags_reopen,
2811 NULL
2814 /* buffer code */
2815 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
2817 il = tvb_get_guint8(tvb, offset);
2818 if (si->saved) {
2819 si->saved->infolevel = il;
2822 /* infolevel */
2823 proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 1, il);
2824 offset += 1;
2826 /* find flags */
2827 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_find_flags, ett_smb2_find_flags, f_fields, ENC_LITTLE_ENDIAN);
2828 offset += 1;
2830 /* file index */
2831 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2832 offset += 4;
2834 /* fid */
2835 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
2837 /* search pattern offset/length */
2838 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT16, hf_smb2_find_pattern);
2840 /* output buffer length */
2841 proto_tree_add_item(tree, hf_smb2_output_buffer_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2842 offset += 4;
2844 /* search pattern */
2845 buf = dissect_smb2_olb_string(pinfo, tree, tvb, &olb, OLB_TYPE_UNICODE_STRING);
2847 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
2849 if (!pinfo->fd->flags.visited && si->saved && olb.len) {
2850 si->saved->extra_info_type = SMB2_EI_FINDPATTERN;
2851 si->saved->extra_info = g_malloc(olb.len+1);
2852 g_snprintf((char *)si->saved->extra_info,olb.len+1,"%s",buf);
2855 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
2856 val_to_str(il, smb2_find_info_levels, "(Level:0x%02x)"),
2857 buf);
2859 return offset;
2862 static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2864 int offset = 0;
2865 proto_item *item = NULL;
2866 proto_tree *tree = NULL;
2867 const char *name = NULL;
2868 guint16 bc;
2870 while (tvb_length_remaining(tvb, offset) > 4) {
2871 int old_offset = offset;
2872 int next_offset;
2873 int file_name_len;
2875 if (parent_tree) {
2876 item = proto_tree_add_item(parent_tree, hf_smb2_file_directory_info, tvb, offset, -1, ENC_NA);
2877 tree = proto_item_add_subtree(item, ett_smb2_file_directory_info);
2880 /* next offset */
2881 next_offset = tvb_get_letohl(tvb, offset);
2882 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2883 offset += 4;
2885 /* file index */
2886 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2887 offset += 4;
2889 /* create time */
2890 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2892 /* last access */
2893 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2895 /* last write */
2896 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2898 /* last change */
2899 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2901 /* end of file */
2902 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2903 offset += 8;
2905 /* allocation size */
2906 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2907 offset += 8;
2909 /* File Attributes */
2910 offset = dissect_file_ext_attr(tvb, tree, offset);
2912 /* file name length */
2913 file_name_len = tvb_get_letohl(tvb, offset);
2914 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2915 offset += 4;
2917 /* file name */
2918 if (file_name_len) {
2919 bc = file_name_len;
2920 name = get_unicode_or_ascii_string(tvb, &offset,
2921 TRUE, &file_name_len, TRUE, TRUE, &bc);
2922 if (name) {
2923 proto_tree_add_string(tree, hf_smb2_filename, tvb,
2924 offset, file_name_len, name);
2925 proto_item_append_text(item, ": %s", name);
2930 proto_item_set_len(item, offset-old_offset);
2932 if (next_offset == 0) {
2933 return;
2936 offset = old_offset+next_offset;
2937 if (offset < old_offset) {
2938 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
2939 "Invalid offset/length. Malformed packet");
2940 return;
2945 static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
2947 int offset = 0;
2948 proto_item *item = NULL;
2949 proto_tree *tree = NULL;
2950 const char *name = NULL;
2951 guint16 bc;
2953 while (tvb_length_remaining(tvb, offset) > 4) {
2954 int old_offset = offset;
2955 int next_offset;
2956 int file_name_len;
2958 if (parent_tree) {
2959 item = proto_tree_add_item(parent_tree, hf_smb2_full_directory_info, tvb, offset, -1, ENC_NA);
2960 tree = proto_item_add_subtree(item, ett_smb2_full_directory_info);
2963 /* next offset */
2964 next_offset = tvb_get_letohl(tvb, offset);
2965 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2966 offset += 4;
2968 /* file index */
2969 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2970 offset += 4;
2972 /* create time */
2973 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
2975 /* last access */
2976 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
2978 /* last write */
2979 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
2981 /* last change */
2982 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
2984 /* end of file */
2985 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2986 offset += 8;
2988 /* allocation size */
2989 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2990 offset += 8;
2992 /* File Attributes */
2993 offset = dissect_file_ext_attr(tvb, tree, offset);
2995 /* file name length */
2996 file_name_len = tvb_get_letohl(tvb, offset);
2997 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2998 offset += 4;
3000 /* ea size */
3001 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3002 offset += 4;
3004 /* file name */
3005 if (file_name_len) {
3006 bc = file_name_len;
3007 name = get_unicode_or_ascii_string(tvb, &offset,
3008 TRUE, &file_name_len, TRUE, TRUE, &bc);
3009 if (name) {
3010 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3011 offset, file_name_len, name);
3012 proto_item_append_text(item, ": %s", name);
3017 proto_item_set_len(item, offset-old_offset);
3019 if (next_offset == 0) {
3020 return;
3023 offset = old_offset+next_offset;
3024 if (offset < old_offset) {
3025 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
3026 "Invalid offset/length. Malformed packet");
3027 return;
3032 static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3034 int offset = 0;
3035 proto_item *item = NULL;
3036 proto_tree *tree = NULL;
3037 const char *name = NULL;
3038 guint16 bc;
3040 while (tvb_length_remaining(tvb, offset) > 4) {
3041 int old_offset = offset;
3042 int next_offset;
3043 int file_name_len;
3044 int short_name_len;
3046 if (parent_tree) {
3047 item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
3048 tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
3051 /* next offset */
3052 next_offset = tvb_get_letohl(tvb, offset);
3053 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3054 offset += 4;
3056 /* file index */
3057 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3058 offset += 4;
3060 /* create time */
3061 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3063 /* last access */
3064 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3066 /* last write */
3067 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3069 /* last change */
3070 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3072 /* end of file */
3073 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3074 offset += 8;
3076 /* allocation size */
3077 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3078 offset += 8;
3080 /* File Attributes */
3081 offset = dissect_file_ext_attr(tvb, tree, offset);
3083 /* file name length */
3084 file_name_len = tvb_get_letohl(tvb, offset);
3085 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3086 offset += 4;
3088 /* ea size */
3089 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3090 offset += 4;
3092 /* short name length */
3093 short_name_len = tvb_get_guint8(tvb, offset);
3094 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3095 offset += 1;
3097 /* reserved */
3098 offset += 1;
3100 /* short name */
3101 if (short_name_len) {
3102 bc = short_name_len;
3103 name = get_unicode_or_ascii_string(tvb, &offset,
3104 TRUE, &short_name_len, TRUE, TRUE, &bc);
3105 if (name) {
3106 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
3107 offset, short_name_len, name);
3110 offset += 24;
3112 /* file name */
3113 if (file_name_len) {
3114 bc = file_name_len;
3115 name = get_unicode_or_ascii_string(tvb, &offset,
3116 TRUE, &file_name_len, TRUE, TRUE, &bc);
3117 if (name) {
3118 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3119 offset, file_name_len, name);
3120 proto_item_append_text(item, ": %s", name);
3125 proto_item_set_len(item, offset-old_offset);
3127 if (next_offset == 0) {
3128 return;
3131 offset = old_offset+next_offset;
3132 if (offset < old_offset) {
3133 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
3134 "Invalid offset/length. Malformed packet");
3135 return;
3140 static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3142 int offset = 0;
3143 proto_item *item = NULL;
3144 proto_tree *tree = NULL;
3145 const char *name = NULL;
3146 guint16 bc;
3148 while (tvb_length_remaining(tvb, offset) > 4) {
3149 int old_offset = offset;
3150 int next_offset;
3151 int file_name_len;
3153 if (parent_tree) {
3154 item = proto_tree_add_item(parent_tree, hf_smb2_both_directory_info, tvb, offset, -1, ENC_NA);
3155 tree = proto_item_add_subtree(item, ett_smb2_both_directory_info);
3158 /* next offset */
3159 next_offset = tvb_get_letohl(tvb, offset);
3160 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3161 offset += 4;
3163 /* file index */
3164 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3165 offset += 4;
3167 /* file name length */
3168 file_name_len = tvb_get_letohl(tvb, offset);
3169 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3170 offset += 4;
3172 /* file name */
3173 if (file_name_len) {
3174 bc = file_name_len;
3175 name = get_unicode_or_ascii_string(tvb, &offset,
3176 TRUE, &file_name_len, TRUE, TRUE, &bc);
3177 if (name) {
3178 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3179 offset, file_name_len, name);
3180 proto_item_append_text(item, ": %s", name);
3185 proto_item_set_len(item, offset-old_offset);
3187 if (next_offset == 0) {
3188 return;
3191 offset = old_offset+next_offset;
3192 if (offset < old_offset) {
3193 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
3194 "Invalid offset/length. Malformed packet");
3195 return;
3200 static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
3202 int offset = 0;
3203 proto_item *item = NULL;
3204 proto_tree *tree = NULL;
3205 const char *name = NULL;
3206 guint16 bc;
3208 while (tvb_length_remaining(tvb, offset) > 4) {
3209 int old_offset = offset;
3210 int next_offset;
3211 int file_name_len;
3212 int short_name_len;
3214 if (parent_tree) {
3215 item = proto_tree_add_item(parent_tree, hf_smb2_id_both_directory_info, tvb, offset, -1, ENC_NA);
3216 tree = proto_item_add_subtree(item, ett_smb2_id_both_directory_info);
3219 /* next offset */
3220 next_offset = tvb_get_letohl(tvb, offset);
3221 proto_tree_add_item(tree, hf_smb2_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3222 offset += 4;
3224 /* file index */
3225 proto_tree_add_item(tree, hf_smb2_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3226 offset += 4;
3228 /* create time */
3229 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3231 /* last access */
3232 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3234 /* last write */
3235 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3237 /* last change */
3238 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3240 /* end of file */
3241 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3242 offset += 8;
3244 /* allocation size */
3245 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3246 offset += 8;
3248 /* File Attributes */
3249 offset = dissect_file_ext_attr(tvb, tree, offset);
3251 /* file name length */
3252 file_name_len = tvb_get_letohl(tvb, offset);
3253 proto_tree_add_item(tree, hf_smb2_filename_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3254 offset += 4;
3256 /* ea size */
3257 proto_tree_add_item(tree, hf_smb2_ea_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3258 offset += 4;
3260 /* short name length */
3261 short_name_len = tvb_get_guint8(tvb, offset);
3262 proto_tree_add_item(tree, hf_smb2_short_name_len, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3263 offset += 1;
3265 /* reserved */
3266 offset += 1;
3268 /* short name */
3269 if (short_name_len) {
3270 bc = short_name_len;
3271 name = get_unicode_or_ascii_string(tvb, &offset,
3272 TRUE, &short_name_len, TRUE, TRUE, &bc);
3273 if (name) {
3274 proto_tree_add_string(tree, hf_smb2_short_name, tvb,
3275 offset, short_name_len, name);
3278 offset += 24;
3280 /* reserved */
3281 offset += 2;
3283 /* file id */
3284 proto_tree_add_item(tree, hf_smb2_file_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3285 offset += 8;
3287 /* file name */
3288 if (file_name_len) {
3289 bc = file_name_len;
3290 name = get_unicode_or_ascii_string(tvb, &offset,
3291 TRUE, &file_name_len, TRUE, TRUE, &bc);
3292 if (name) {
3293 proto_tree_add_string(tree, hf_smb2_filename, tvb,
3294 offset, file_name_len, name);
3295 proto_item_append_text(item, ": %s", name);
3300 proto_item_set_len(item, offset-old_offset);
3302 if (next_offset == 0) {
3303 return;
3306 offset = old_offset+next_offset;
3307 if (offset < old_offset) {
3308 proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset),
3309 "Invalid offset/length. Malformed packet");
3310 return;
3316 typedef struct _smb2_find_dissector_t {
3317 guint32 level;
3318 void (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
3319 } smb2_find_dissector_t;
3321 smb2_find_dissector_t smb2_find_dissectors[] = {
3322 {SMB2_FIND_DIRECTORY_INFO, dissect_smb2_file_directory_info},
3323 {SMB2_FIND_FULL_DIRECTORY_INFO, dissect_smb2_full_directory_info},
3324 {SMB2_FIND_BOTH_DIRECTORY_INFO, dissect_smb2_both_directory_info},
3325 {SMB2_FIND_NAME_INFO, dissect_smb2_file_name_info},
3326 {SMB2_FIND_ID_BOTH_DIRECTORY_INFO,dissect_smb2_id_both_directory_info},
3327 {0, NULL}
3330 static void
3331 dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3333 smb2_find_dissector_t *dis = smb2_find_dissectors;
3335 while (dis->dissector) {
3336 if (si && si->saved && si->saved) {
3337 if (dis->level ==si->saved->infolevel) {
3338 dis->dissector(tvb, pinfo, tree, si);
3339 return;
3342 dis++;
3345 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA);
3348 static int
3349 dissect_smb2_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3351 offset_length_buffer_t olb;
3352 proto_item *item = NULL;
3354 if (si->saved) {
3355 /* infolevel */
3356 item = proto_tree_add_uint(tree, hf_smb2_find_info_level, tvb, offset, 0, si->saved->infolevel);
3357 PROTO_ITEM_SET_GENERATED(item);
3360 if (!pinfo->fd->flags.visited && si->saved && si->saved->extra_info_type == SMB2_EI_FINDPATTERN) {
3361 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Pattern: %s",
3362 val_to_str(si->saved->infolevel, smb2_find_info_levels, "(Level:0x%02x)"),
3363 (const char *)si->saved->extra_info);
3365 g_free(si->saved->extra_info);
3366 si->saved->extra_info_type = SMB2_EI_NONE;
3367 si->saved->extra_info = NULL;
3370 switch (si->status) {
3371 case 0x00000000: break;
3372 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3375 /* buffer code */
3376 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3378 /* findinfo offset */
3379 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, hf_smb2_find_info_blob);
3381 /* the buffer */
3382 dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_find_data);
3384 offset = dissect_smb2_olb_tvb_max_offset(offset, &olb);
3386 return offset;
3389 static int
3390 dissect_smb2_negotiate_protocol_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3392 guint16 dc;
3394 /* buffer code */
3395 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3397 /* dialect count */
3398 dc = tvb_get_letohs(tvb, offset);
3399 proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3400 offset += 2;
3402 /* security mode, skip second byte */
3403 offset = dissect_smb2_secmode(tree, tvb, offset);
3404 offset++;
3407 /* reserved */
3408 offset += 2;
3410 /* capabilities */
3411 offset = dissect_smb2_capabilities(tree, tvb, offset);
3413 /* client guid */
3414 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
3415 offset += 16;
3417 /* client boot time */
3418 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3419 offset += 8;
3421 for ( ; dc>0; dc--) {
3422 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3423 offset += 2;
3426 return offset;
3429 static int
3430 dissect_smb2_negotiate_protocol_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
3432 offset_length_buffer_t s_olb;
3434 switch (si->status) {
3435 case 0x00000000: break;
3436 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3439 /* buffer code */
3440 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3442 /* security mode, skip second byte */
3443 offset = dissect_smb2_secmode(tree, tvb, offset);
3444 offset++;
3446 /* dialect picked */
3447 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3448 offset += 2;
3450 /* reserved */
3451 offset += 2;
3453 /* server GUID */
3454 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
3455 offset += 16;
3457 /* capabilities */
3458 offset = dissect_smb2_capabilities(tree, tvb, offset);
3460 /* max trans size */
3461 proto_tree_add_item(tree, hf_smb2_max_trans_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3462 offset += 4;
3464 /* max read size */
3465 proto_tree_add_item(tree, hf_smb2_max_read_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3466 offset += 4;
3468 /* max write size */
3469 proto_tree_add_item(tree, hf_smb2_max_write_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3470 offset += 4;
3472 /* current time */
3473 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_current_time);
3474 offset += 8;
3476 /* boot time */
3477 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_boot_time);
3478 offset += 8;
3480 /* security blob offset/length */
3481 offset = dissect_smb2_olb_length_offset(tvb, offset, &s_olb, OLB_O_UINT16_S_UINT16, hf_smb2_security_blob);
3483 /* the security blob itself */
3484 dissect_smb2_olb_buffer(pinfo, tree, tvb, &s_olb, si, dissect_smb2_secblob);
3486 /* reserved */
3487 offset += 4;
3489 offset = dissect_smb2_olb_tvb_max_offset(offset, &s_olb);
3491 return offset;
3494 static int
3495 dissect_smb2_getinfo_parameters(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si)
3497 switch (si->saved->smb2_class) {
3498 case SMB2_CLASS_FILE_INFO:
3499 switch (si->saved->infolevel) {
3500 default:
3501 /* we dont handle this infolevel yet */
3502 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
3503 offset += tvb_length_remaining(tvb, offset);
3505 break;
3506 case SMB2_CLASS_FS_INFO:
3507 switch (si->saved->infolevel) {
3508 default:
3509 /* we dont handle this infolevel yet */
3510 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
3511 offset += tvb_length_remaining(tvb, offset);
3513 break;
3514 case SMB2_CLASS_SEC_INFO:
3515 switch (si->saved->infolevel) {
3516 case SMB2_SEC_INFO_00:
3517 dissect_security_information_mask(tvb, tree, offset+8);
3518 break;
3519 default:
3520 /* we dont handle this infolevel yet */
3521 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
3522 offset += tvb_length_remaining(tvb, offset);
3524 break;
3525 default:
3526 /* we dont handle this class yet */
3527 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
3528 offset += tvb_length_remaining(tvb, offset);
3530 return offset;
3534 static int
3535 dissect_smb2_class_infolevel(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, smb2_info_t *si)
3537 char cl, il;
3538 proto_item *item;
3539 int hfindex;
3540 static const value_string dummy_value_string[] = {
3541 { 0, NULL }
3543 const value_string *vs;
3545 if (si->flags & SMB2_FLAGS_RESPONSE) {
3546 if (!si->saved) {
3547 return offset;
3549 cl = si->saved->smb2_class;
3550 il = si->saved->infolevel;
3551 } else {
3552 cl = tvb_get_guint8(tvb, offset);
3553 il = tvb_get_guint8(tvb, offset+1);
3554 if (si->saved) {
3555 si->saved->smb2_class = cl;
3556 si->saved->infolevel = il;
3561 switch (cl) {
3562 case SMB2_CLASS_FILE_INFO:
3563 hfindex = hf_smb2_infolevel_file_info;
3564 vs = smb2_file_info_levels;
3565 break;
3566 case SMB2_CLASS_FS_INFO:
3567 hfindex = hf_smb2_infolevel_fs_info;
3568 vs = smb2_fs_info_levels;
3569 break;
3570 case SMB2_CLASS_SEC_INFO:
3571 hfindex = hf_smb2_infolevel_sec_info;
3572 vs = smb2_sec_info_levels;
3573 break;
3574 default:
3575 hfindex = hf_smb2_infolevel;
3576 vs = dummy_value_string;
3580 /* class */
3581 item = proto_tree_add_uint(tree, hf_smb2_class, tvb, offset, 1, cl);
3582 if (si->flags & SMB2_FLAGS_RESPONSE) {
3583 PROTO_ITEM_SET_GENERATED(item);
3585 /* infolevel */
3586 item = proto_tree_add_uint(tree, hfindex, tvb, offset+1, 1, il);
3587 if (si->flags & SMB2_FLAGS_RESPONSE) {
3588 PROTO_ITEM_SET_GENERATED(item);
3590 offset += 2;
3592 if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
3593 /* Only update COL_INFO for requests. It clutters the
3594 * display ab bit too much if we do it for replies
3595 * as well.
3597 col_append_fstr(pinfo->cinfo, COL_INFO, " %s/%s",
3598 val_to_str(cl, smb2_class_vals, "(Class:0x%02x)"),
3599 val_to_str(il, vs, "(Level:0x%02x)"));
3602 return offset;
3605 static int
3606 dissect_smb2_getinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3608 /* buffer code */
3609 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3611 /* class and info level */
3612 offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3614 /* max response size */
3615 proto_tree_add_item(tree, hf_smb2_max_response_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3616 offset += 4;
3618 /* parameters */
3619 if (si->saved) {
3620 dissect_smb2_getinfo_parameters(tvb, pinfo, tree, offset, si);
3621 } else {
3622 /* some unknown bytes */
3623 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 16, ENC_NA);
3625 offset += 16;
3627 /* fid */
3628 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3630 return offset;
3633 static int
3634 dissect_smb2_infolevel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si, guint8 smb2_class, guint8 infolevel)
3636 int old_offset = offset;
3638 switch (smb2_class) {
3639 case SMB2_CLASS_FILE_INFO:
3640 switch (infolevel) {
3641 case SMB2_FILE_BASIC_INFO:
3642 offset = dissect_smb2_file_basic_info(tvb, pinfo, tree, offset, si);
3643 break;
3644 case SMB2_FILE_STANDARD_INFO:
3645 offset = dissect_smb2_file_standard_info(tvb, pinfo, tree, offset, si);
3646 break;
3647 case SMB2_FILE_INTERNAL_INFO:
3648 offset = dissect_smb2_file_internal_info(tvb, pinfo, tree, offset, si);
3649 break;
3650 case SMB2_FILE_EA_INFO:
3651 offset = dissect_smb2_file_ea_info(tvb, pinfo, tree, offset, si);
3652 break;
3653 case SMB2_FILE_ACCESS_INFO:
3654 offset = dissect_smb2_file_access_info(tvb, pinfo, tree, offset, si);
3655 break;
3656 case SMB2_FILE_RENAME_INFO:
3657 offset = dissect_smb2_file_rename_info(tvb, pinfo, tree, offset, si);
3658 break;
3659 case SMB2_FILE_DISPOSITION_INFO:
3660 offset = dissect_smb2_file_disposition_info(tvb, pinfo, tree, offset, si);
3661 break;
3662 case SMB2_FILE_POSITION_INFO:
3663 offset = dissect_smb2_file_position_info(tvb, pinfo, tree, offset, si);
3664 break;
3665 case SMB2_FILE_FULL_EA_INFO:
3666 offset = dissect_smb2_file_full_ea_info(tvb, pinfo, tree, offset, si);
3667 break;
3668 case SMB2_FILE_MODE_INFO:
3669 offset = dissect_smb2_file_mode_info(tvb, pinfo, tree, offset, si);
3670 break;
3671 case SMB2_FILE_ALIGNMENT_INFO:
3672 offset = dissect_smb2_file_alignment_info(tvb, pinfo, tree, offset, si);
3673 break;
3674 case SMB2_FILE_ALL_INFO:
3675 offset = dissect_smb2_file_all_info(tvb, pinfo, tree, offset, si);
3676 break;
3677 case SMB2_FILE_ALLOCATION_INFO:
3678 offset = dissect_smb2_file_allocation_info(tvb, pinfo, tree, offset, si);
3679 break;
3680 case SMB2_FILE_ENDOFFILE_INFO:
3681 dissect_smb2_file_endoffile_info(tvb, pinfo, tree, offset, si);
3682 break;
3683 case SMB2_FILE_ALTERNATE_NAME_INFO:
3684 offset = dissect_smb2_file_alternate_name_info(tvb, pinfo, tree, offset, si);
3685 break;
3686 case SMB2_FILE_STREAM_INFO:
3687 offset = dissect_smb2_file_stream_info(tvb, pinfo, tree, offset, si);
3688 break;
3689 case SMB2_FILE_PIPE_INFO:
3690 offset = dissect_smb2_file_pipe_info(tvb, pinfo, tree, offset, si);
3691 break;
3692 case SMB2_FILE_COMPRESSION_INFO:
3693 offset = dissect_smb2_file_compression_info(tvb, pinfo, tree, offset, si);
3694 break;
3695 case SMB2_FILE_NETWORK_OPEN_INFO:
3696 offset = dissect_smb2_file_network_open_info(tvb, pinfo, tree, offset, si);
3697 break;
3698 case SMB2_FILE_ATTRIBUTE_TAG_INFO:
3699 offset = dissect_smb2_file_attribute_tag_info(tvb, pinfo, tree, offset, si);
3700 break;
3701 default:
3702 /* we dont handle this infolevel yet */
3703 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
3704 offset += tvb_length_remaining(tvb, offset);
3706 break;
3707 case SMB2_CLASS_FS_INFO:
3708 switch (infolevel) {
3709 case SMB2_FS_INFO_01:
3710 offset = dissect_smb2_fs_info_01(tvb, pinfo, tree, offset, si);
3711 break;
3712 case SMB2_FS_INFO_03:
3713 offset = dissect_smb2_fs_info_03(tvb, pinfo, tree, offset, si);
3714 break;
3715 case SMB2_FS_INFO_04:
3716 offset = dissect_smb2_fs_info_04(tvb, pinfo, tree, offset, si);
3717 break;
3718 case SMB2_FS_INFO_05:
3719 offset = dissect_smb2_fs_info_05(tvb, pinfo, tree, offset, si);
3720 break;
3721 case SMB2_FS_INFO_06:
3722 offset = dissect_smb2_fs_info_06(tvb, pinfo, tree, offset, si);
3723 break;
3724 case SMB2_FS_INFO_07:
3725 offset = dissect_smb2_fs_info_07(tvb, pinfo, tree, offset, si);
3726 break;
3727 case SMB2_FS_OBJECTID_INFO:
3728 offset = dissect_smb2_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, si);
3729 break;
3730 default:
3731 /* we dont handle this infolevel yet */
3732 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
3733 offset += tvb_length_remaining(tvb, offset);
3735 break;
3736 case SMB2_CLASS_SEC_INFO:
3737 switch (infolevel) {
3738 case SMB2_SEC_INFO_00:
3739 offset = dissect_smb2_sec_info_00(tvb, pinfo, tree, offset, si);
3740 break;
3741 default:
3742 /* we dont handle this infolevel yet */
3743 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
3744 offset += tvb_length_remaining(tvb, offset);
3746 break;
3747 default:
3748 /* we dont handle this class yet */
3749 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, tvb_length_remaining(tvb, offset), ENC_NA);
3750 offset += tvb_length_remaining(tvb, offset);
3753 /* if we get BUFFER_OVERFLOW there will be truncated data */
3754 if (si->status == 0x80000005) {
3755 proto_item *item;
3756 item = proto_tree_add_text(tree, tvb, old_offset, 0, "Truncated...");
3757 PROTO_ITEM_SET_GENERATED(item);
3759 return offset;
3762 static void
3763 dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
3765 /* data */
3766 if (si->saved) {
3767 dissect_smb2_infolevel(tvb, pinfo, tree, 0, si, si->saved->smb2_class, si->saved->infolevel);
3768 } else {
3769 /* some unknown bytes */
3770 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA);
3776 static int
3777 dissect_smb2_getinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3779 offset_length_buffer_t olb;
3781 /* class/infolevel */
3782 dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
3784 switch (si->status) {
3785 case 0x00000000: break;
3786 /* if we get BUFFER_OVERFLOW there will be truncated data */
3787 case 0x80000005: break;
3788 /* if we get BUFFER_TOO_SMALL there will not be any data there, only
3789 * a guin32 specifying how big the buffer needs to be
3791 case 0xc0000023:
3792 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3793 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
3794 proto_tree_add_item(tree, hf_smb2_required_buffer_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3795 offset += 4;
3797 return offset;
3798 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3802 /* buffer code */
3803 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3804 /* response buffer offset and size */
3805 offset = dissect_smb2_olb_length_offset(tvb, offset, &olb, OLB_O_UINT16_S_UINT32, -1);
3807 /* response data*/
3808 dissect_smb2_olb_buffer(pinfo, tree, tvb, &olb, si, dissect_smb2_getinfo_response_data);
3810 return offset;
3813 static int
3814 dissect_smb2_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3816 proto_tree *flags_tree = NULL;
3817 proto_item *flags_item = NULL;
3819 /* buffer code */
3820 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3822 /* close flags */
3823 if (tree) {
3824 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3825 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
3827 proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3828 offset += 2;
3830 /* padding */
3831 offset += 4;
3833 /* fid */
3834 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_CLOSE);
3836 return offset;
3839 static int
3840 dissect_smb2_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3842 proto_tree *flags_tree = NULL;
3843 proto_item *flags_item = NULL;
3845 switch (si->status) {
3846 case 0x00000000: break;
3847 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3850 /* buffer code */
3851 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3853 /* close flags */
3854 if (tree) {
3855 flags_item = proto_tree_add_item(tree, hf_smb2_close_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3856 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_close_flags);
3858 proto_tree_add_item(flags_tree, hf_smb2_close_pq_attrib, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3859 offset += 2;
3861 /* reserved */
3862 offset += 4;
3864 /* create time */
3865 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
3867 /* last access */
3868 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
3870 /* last write */
3871 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
3873 /* last change */
3874 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
3876 /* allocation size */
3877 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3878 offset += 8;
3880 /* end of file */
3881 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3882 offset += 8;
3884 /* File Attributes */
3885 offset = dissect_file_ext_attr(tvb, tree, offset);
3887 return offset;
3890 static int
3891 dissect_smb2_flush_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3893 /* buffer code */
3894 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3896 /* some unknown bytes */
3897 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
3898 offset += 6;
3900 /* fid */
3901 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3903 return offset;
3906 static int
3907 dissect_smb2_flush_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3909 switch (si->status) {
3910 case 0x00000000: break;
3911 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3914 /* buffer code */
3915 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3917 /* some unknown bytes */
3918 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3919 offset += 2;
3921 return offset;
3925 static int
3926 dissect_smb2_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
3928 guint16 lock_count;
3930 /* buffer code */
3931 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3933 /* lock count */
3934 lock_count = tvb_get_letohs(tvb, offset);
3935 proto_tree_add_item(tree, hf_smb2_lock_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3936 offset += 2;
3938 /* reserved */
3939 offset += 4;
3941 /* fid */
3942 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
3944 while (lock_count--) {
3945 proto_item *lock_item = NULL;
3946 proto_tree *lock_tree = NULL;
3947 static const int *lf_fields[] = {
3948 &hf_smb2_lock_flags_shared,
3949 &hf_smb2_lock_flags_exclusive,
3950 &hf_smb2_lock_flags_unlock,
3951 &hf_smb2_lock_flags_fail_immediately,
3952 NULL
3955 if (tree) {
3956 lock_item = proto_tree_add_item(tree, hf_smb2_lock_info, tvb, offset, 24, ENC_NA);
3957 lock_tree = proto_item_add_subtree(lock_item, ett_smb2_lock_info);
3960 /* offset */
3961 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3962 offset += 8;
3964 /* count */
3965 proto_tree_add_item(lock_tree, hf_smb2_lock_length, tvb, offset, 8, ENC_LITTLE_ENDIAN);
3966 offset += 8;
3968 /* flags */
3969 proto_tree_add_bitmask(lock_tree, tvb, offset, hf_smb2_lock_flags, ett_smb2_lock_flags, lf_fields, ENC_LITTLE_ENDIAN);
3970 offset += 4;
3972 /* reserved */
3973 offset += 4;
3976 return offset;
3979 static int
3980 dissect_smb2_lock_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3982 switch (si->status) {
3983 case 0x00000000: break;
3984 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
3987 /* buffer code */
3988 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
3990 /* some unknown bytes */
3991 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
3992 offset += 2;
3994 return offset;
3996 static int
3997 dissect_smb2_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
3999 /* buffer code */
4000 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4002 /* some unknown bytes */
4003 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
4004 offset += 2;
4006 return offset;
4010 static int
4011 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, guint32 datalen, proto_tree *top_tree)
4013 tvbuff_t *dcerpc_tvb;
4014 dcerpc_tvb = tvb_new_subset(tvb, offset, MIN((int)datalen, tvb_length_remaining(tvb, offset)), datalen);
4016 /* dissect the full PDU */
4017 dissector_try_heuristic(smb2_heur_subdissector_list, dcerpc_tvb, pinfo, top_tree, NULL);
4020 offset += datalen;
4022 return offset;
4025 #define SMB2_WRITE_FLAG_WRITE_THROUGH 0x00000001
4027 static int
4028 dissect_smb2_write_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4030 guint16 dataoffset = 0;
4031 guint32 data_tvb_len;
4032 guint32 length;
4033 guint64 off;
4034 static const int *f_fields[] = {
4035 &hf_smb2_write_flags_write_through,
4036 NULL
4039 /* buffer code */
4040 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4042 /* data offset */
4043 dataoffset=tvb_get_letohl(tvb,offset);
4044 proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4045 offset += 2;
4047 /* length */
4048 length = tvb_get_letohl(tvb, offset);
4049 proto_tree_add_item(tree, hf_smb2_write_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4050 offset += 4;
4052 /* offset */
4053 off = tvb_get_letoh64(tvb, offset);
4054 if (si->saved) si->saved->file_offset=off;
4055 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4056 offset += 8;
4058 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", length, off);
4060 /* fid */
4061 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4063 /* channel */
4064 proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4065 offset += 4;
4067 /* remaining bytes */
4068 proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4069 offset += 4;
4071 /* write channel info offset */
4072 proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4073 offset += 2;
4075 /* write channel info length */
4076 proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4077 offset += 2;
4079 /* flags */
4080 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_write_flags, ett_smb2_write_flags, f_fields, ENC_LITTLE_ENDIAN);
4081 offset += 4;
4083 /* data or dcerpc ?*/
4084 if (length && si->tree && si->tree->share_type == SMB2_SHARE_TYPE_PIPE) {
4085 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si->top_tree);
4086 return offset;
4089 /* just ordinary data */
4090 proto_tree_add_item(tree, hf_smb2_write_data, tvb, offset, length, ENC_NA);
4092 data_tvb_len=(guint32)tvb_length_remaining(tvb, offset);
4094 offset += MIN(length,(guint32)tvb_length_remaining(tvb, offset));
4096 if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
4097 if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
4098 feed_eo_smb2(tvb,pinfo,si,dataoffset,length,off);
4102 return offset;
4106 static int
4107 dissect_smb2_write_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, smb2_info_t *si _U_)
4109 switch (si->status) {
4110 case 0x00000000: break;
4111 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4114 /* buffer code */
4115 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4117 /* reserved */
4118 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
4119 offset += 2;
4121 /* count */
4122 proto_tree_add_item(tree, hf_smb2_write_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4123 offset += 4;
4125 /* remaining, must be set to 0 */
4126 proto_tree_add_item(tree, hf_smb2_write_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4127 offset += 4;
4129 /* write channel info offset */
4130 proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4131 offset += 2;
4133 /* write channel info length */
4134 proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4135 offset += 2;
4137 return offset;
4140 static void
4141 dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *top_tree, gboolean data_in _U_)
4143 dissect_file_data_dcerpc(tvb, pinfo, tree, offset, tvb_length_remaining(tvb, offset), top_tree);
4146 static void
4147 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_)
4149 guint8 timeout_specified = tvb_get_guint8(tvb, offset + 12);
4150 guint32 name_len = tvb_get_letohs(tvb, offset + 8);
4151 const gchar *name;
4152 int off = offset + 14;
4153 guint16 bc = tvb_length_remaining(tvb, off);
4154 int len = name_len;
4156 /* sanity check */
4157 tvb_ensure_bytes_exist(tvb, off, name_len);
4159 name = get_unicode_or_ascii_string(tvb, &off, TRUE, &len, TRUE, TRUE, &bc);
4160 if (name == NULL) {
4161 name = "";
4164 if (check_col(pinfo->cinfo, COL_INFO)) {
4165 col_append_fstr(pinfo->cinfo, COL_INFO, " Pipe: %s", name);
4168 if (top_tree) {
4169 proto_tree_add_string(top_tree, hf_smb2_fsctl_pipe_wait_name, tvb, offset + 14, name_len, name);
4170 if (timeout_specified) {
4171 proto_tree_add_item(top_tree, hf_smb2_fsctl_pipe_wait_timeout, tvb, 0, 8, ENC_LITTLE_ENDIAN);
4176 static void
4177 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4179 /* There is no out data */
4180 if (!data_in) {
4181 return;
4184 /* timeout */
4185 proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4186 offset += 4;
4188 /* reserved */
4189 proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4192 static void
4193 dissect_windows_sockaddr_in(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
4195 proto_item *sub_item = NULL;
4196 proto_tree *sub_tree = NULL;
4197 proto_item *parent_item = NULL;
4198 guint32 addr;
4200 if (len == -1) {
4201 len = 16;
4204 if (parent_tree) {
4205 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Socket Address");
4206 sub_tree = proto_item_add_subtree(sub_item, ett_windows_sockaddr);
4207 parent_item = proto_tree_get_parent(parent_tree);
4210 /* family */
4211 proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4212 offset += 2;
4214 /* port */
4215 proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4216 offset += 2;
4218 /* IPv4 address */
4219 addr = tvb_get_ipv4(tvb, offset);
4220 proto_tree_add_ipv4(sub_tree, hf_windows_sockaddr_in_addr, tvb, offset, 4, addr);
4221 if (sub_item) {
4222 proto_item_append_text(sub_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset));
4224 if (parent_item) {
4225 proto_item_append_text(parent_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset));
4229 static void
4230 dissect_windows_sockaddr_in6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, int len)
4232 struct e_in6_addr addr;
4233 proto_item *sub_item = NULL;
4234 proto_tree *sub_tree = NULL;
4235 proto_item *parent_item = NULL;
4237 if (len == -1) {
4238 len = 16;
4241 if (parent_tree) {
4242 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Socket Address");
4243 sub_tree = proto_item_add_subtree(sub_item, ett_windows_sockaddr);
4244 parent_item = proto_tree_get_parent(parent_tree);
4247 /* family */
4248 proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4249 offset += 2;
4251 /* port */
4252 proto_tree_add_item(sub_tree, hf_windows_sockaddr_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4253 offset += 2;
4255 /* sin6_flowinfo */
4256 proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_flowinfo, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4257 offset += 4;
4259 /* IPv4 address */
4260 tvb_get_ipv6(tvb, offset, &addr);
4261 proto_tree_add_ipv6(sub_tree, hf_windows_sockaddr_in6_addr, tvb, offset, 16, (guint8 *)&addr);
4262 if (sub_item) {
4263 proto_item_append_text(sub_item, ", IPv6: %s", tvb_ip6_to_str(tvb, offset));
4265 if (parent_item) {
4266 proto_item_append_text(parent_item, ", IPv6: %s", tvb_ip6_to_str(tvb, offset));
4268 offset += 16;
4270 /* sin6_scope_id */
4271 proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_scope_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4274 static void
4275 dissect_windows_sockaddr_storage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4277 int len = 128;
4278 proto_item *sub_item = NULL;
4279 proto_tree *sub_tree = NULL;
4280 proto_item *parent_item = NULL;
4281 guint16 family;
4283 family = tvb_get_letohs(tvb, offset);
4284 switch (family) {
4285 case WINSOCK_AF_INET:
4286 dissect_windows_sockaddr_in(tvb, pinfo, parent_tree, offset, len);
4287 return;
4288 case WINSOCK_AF_INET6:
4289 dissect_windows_sockaddr_in6(tvb, pinfo, parent_tree, offset, len);
4290 return;
4293 if (parent_tree) {
4294 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Socket Address");
4295 sub_tree = proto_item_add_subtree(sub_item, ett_windows_sockaddr);
4296 parent_item = proto_tree_get_parent(parent_tree);
4299 /* ss_family */
4300 proto_tree_add_item(sub_tree, hf_windows_sockaddr_family, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4301 if (sub_item) {
4302 proto_item_append_text(sub_item, ", Family: %d (0x%04x)", family, family);
4304 if (parent_item) {
4305 proto_item_append_text(sub_item, ", Family: %d (0x%04x)", family, family);
4307 /*offset += 2;*/
4309 /* unknown */
4310 /*offset += 126;*/
4313 #define NETWORK_INTERFACE_CAP_RSS 0x00000001
4314 #define NETWORK_INTERFACE_CAP_RDMA 0x00000002
4316 static void
4317 dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
4319 guint32 next_offset;
4320 int offset = 0;
4321 int len = -1;
4322 proto_item *sub_item = NULL;
4323 proto_tree *sub_tree = NULL;
4324 proto_item *item = NULL;
4325 guint32 capabilities;
4326 guint64 link_speed;
4327 gfloat val = 0;
4328 const char *unit = NULL;
4330 next_offset = tvb_get_letohl(tvb, offset);
4331 if (next_offset) {
4332 len = next_offset;
4335 if (parent_tree) {
4336 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Network Interface");
4337 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_ioctl_network_interface);
4340 /* next offset */
4341 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_next_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4342 offset += 4;
4344 /* interface index */
4345 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4346 offset += 4;
4348 /* capabilities */
4349 capabilities = tvb_get_letohl(tvb, offset);
4350 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_capabilities, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4351 proto_tree_add_boolean(sub_tree, hf_smb2_ioctl_network_interface_capability_rdma, tvb, offset, 4, capabilities);
4352 proto_tree_add_boolean(sub_tree, hf_smb2_ioctl_network_interface_capability_rss, tvb, offset, 4, capabilities);
4353 if (capabilities != 0) {
4354 proto_item_append_text(item, "%s%s",
4355 (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
4356 (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
4357 if (sub_item) {
4358 proto_item_append_text(sub_item, "%s%s",
4359 (capabilities & NETWORK_INTERFACE_CAP_RDMA)?", RDMA":"",
4360 (capabilities & NETWORK_INTERFACE_CAP_RSS)?", RSS":"");
4363 offset += 4;
4365 /* rss queue count */
4366 proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_rss_queue_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4367 offset += 4;
4369 /* link speed */
4370 link_speed = tvb_get_letoh64(tvb, offset);
4371 item = proto_tree_add_item(sub_tree, hf_smb2_ioctl_network_interface_link_speed, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4372 if (link_speed >= (1000*1000*1000)) {
4373 val = (gfloat)(link_speed / (1000*1000*1000));
4374 unit = "G";
4375 } else if (link_speed >= (1000*1000)) {
4376 val = (gfloat)(link_speed / (1000*1000));
4377 unit = "M";
4378 } else if (link_speed >= (1000)) {
4379 val = (gfloat)(link_speed / (1000));
4380 unit = "K";
4381 } else {
4382 val = (gfloat)(link_speed);
4383 unit = "";
4385 proto_item_append_text(item, ", %.1f %sBits/s", val, unit);
4386 if (sub_item) {
4387 proto_item_append_text(sub_item, ", %.1f %sBits/s", val, unit);
4390 offset += 8;
4392 /* socket address */
4393 dissect_windows_sockaddr_storage(tvb, pinfo, sub_tree, offset);
4395 if (next_offset) {
4396 tvbuff_t *next_tvb;
4397 next_tvb = tvb_new_subset_remaining(tvb, next_offset);
4399 /* next extra info */
4400 dissect_smb2_NETWORK_INTERFACE_INFO(next_tvb, pinfo, parent_tree);
4404 static void
4405 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
4407 /* There is no in data */
4408 if (data_in) {
4409 return;
4412 dissect_smb2_NETWORK_INTERFACE_INFO(tvb, pinfo, tree);
4415 static void
4416 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
4419 * This is only used by Windows 8 beta
4421 if (data_in) {
4422 /* capabilities */
4423 offset = dissect_smb2_capabilities(tree, tvb, offset);
4425 /* client guid */
4426 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4427 offset += 16;
4429 /* security mode, skip second byte */
4430 offset = dissect_smb2_secmode(tree, tvb, offset);
4431 offset++;
4433 /* dialect */
4434 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4435 offset += 2;
4436 } else {
4437 /* capabilities */
4438 offset = dissect_smb2_capabilities(tree, tvb, offset);
4440 /* server guid */
4441 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4442 offset += 16;
4444 /* security mode, skip second byte */
4445 offset = dissect_smb2_secmode(tree, tvb, offset);
4446 offset++;
4448 /* dialect */
4449 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4450 offset += 2;
4454 static void
4455 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset _U_, gboolean data_in)
4457 if (data_in) {
4458 guint16 dc;
4460 /* capabilities */
4461 offset = dissect_smb2_capabilities(tree, tvb, offset);
4463 /* client guid */
4464 proto_tree_add_item(tree, hf_smb2_client_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4465 offset += 16;
4467 /* security mode, skip second byte */
4468 offset = dissect_smb2_secmode(tree, tvb, offset);
4469 offset++;
4471 /* dialect count */
4472 dc = tvb_get_letohs(tvb, offset);
4473 proto_tree_add_item(tree, hf_smb2_dialect_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4474 offset += 2;
4476 for ( ; dc>0; dc--) {
4477 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4478 offset += 2;
4480 } else {
4481 /* capabilities */
4482 offset = dissect_smb2_capabilities(tree, tvb, offset);
4484 /* server guid */
4485 proto_tree_add_item(tree, hf_smb2_server_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4486 offset += 16;
4488 /* security mode, skip second byte */
4489 offset = dissect_smb2_secmode(tree, tvb, offset);
4490 offset++;
4492 /* dialect */
4493 proto_tree_add_item(tree, hf_smb2_dialect, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4494 offset += 2;
4498 static void
4499 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4501 guint32 num_volumes;
4503 /* There is no in data */
4504 if (data_in) {
4505 return;
4508 /* num volumes */
4509 num_volumes = tvb_get_letohl(tvb, offset);
4510 proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_volumes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4511 offset += 4;
4513 /* num labels */
4514 proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_num_labels, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4515 offset += 4;
4517 /* count */
4518 proto_tree_add_item(tree, hf_smb2_ioctl_shadow_copy_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4519 offset += 4;
4521 while (num_volumes--) {
4522 const char *name;
4523 guint16 bc;
4524 int len = 0;
4525 int old_offset = offset;
4527 bc = tvb_length_remaining(tvb, offset);
4528 name = get_unicode_or_ascii_string(tvb, &offset,
4529 TRUE, &len, TRUE, FALSE, &bc);
4530 proto_tree_add_string(tree, hf_smb2_ioctl_shadow_copy_label, tvb, old_offset, len, name);
4532 offset = old_offset+len;
4534 if (!len) {
4535 break;
4541 dissect_smb2_FILE_OBJECTID_BUFFER(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset)
4543 proto_item *item = NULL;
4544 proto_tree *tree = NULL;
4546 /* FILE_OBJECTID_BUFFER */
4547 if (parent_tree) {
4548 item = proto_tree_add_item(parent_tree, hf_smb2_FILE_OBJECTID_BUFFER, tvb, offset, 64, ENC_NA);
4549 tree = proto_item_add_subtree(item, ett_smb2_FILE_OBJECTID_BUFFER);
4552 /* Object ID */
4553 proto_tree_add_item(tree, hf_smb2_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4554 offset += 16;
4556 /* Birth Volume ID */
4557 proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4558 offset += 16;
4560 /* Birth Object ID */
4561 proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4562 offset += 16;
4564 /* Domain ID */
4565 proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4566 offset += 16;
4568 return offset;
4571 static int
4572 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4575 /* There is no in data */
4576 if (data_in) {
4577 return offset;
4580 /* FILE_OBJECTID_BUFFER */
4581 offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
4583 return offset;
4586 static int
4587 dissect_smb2_FSCTL_GET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4590 /* There is no in data */
4591 if (data_in) {
4592 return offset;
4595 /* compression format */
4596 proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4597 offset += 2;
4599 return offset;
4601 static int
4602 dissect_smb2_FSCTL_SET_COMPRESSION(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4605 /* There is no out data */
4606 if (!data_in) {
4607 return offset;
4610 /* compression format */
4611 proto_tree_add_item(tree, hf_smb2_compression_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4612 offset += 2;
4614 return offset;
4617 static int
4618 dissect_smb2_FSCTL_SET_OBJECT_ID(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4621 /* There is no out data */
4622 if (!data_in) {
4623 return offset;
4626 /* FILE_OBJECTID_BUFFER */
4627 offset = dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
4629 return offset;
4632 static int
4633 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean data_in)
4636 /* There is no out data */
4637 if (!data_in) {
4638 return offset;
4641 /* FILE_OBJECTID_BUFFER->ExtendedInfo */
4643 /* Birth Volume ID */
4644 proto_tree_add_item(tree, hf_smb2_birth_volume_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4645 offset += 16;
4647 /* Birth Object ID */
4648 proto_tree_add_item(tree, hf_smb2_birth_object_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4649 offset += 16;
4651 /* Domain ID */
4652 proto_tree_add_item(tree, hf_smb2_domain_id, tvb, offset, 16, ENC_LITTLE_ENDIAN);
4653 offset += 16;
4655 return offset;
4658 void
4659 dissect_smb2_ioctl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *top_tree, guint32 ioctl_function, gboolean data_in)
4661 guint16 dc;
4663 dc = tvb_reported_length(tvb);
4665 switch (ioctl_function) {
4666 case 0x00060194: /* FSCTL_DFS_GET_REFERRALS */
4667 if (data_in) {
4668 dissect_get_dfs_request_data(tvb, pinfo, tree, 0, &dc, TRUE);
4669 } else {
4670 dissect_get_dfs_referral_data(tvb, pinfo, tree, 0, &dc, TRUE);
4672 break;
4673 case 0x0011c017:
4674 dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvb, pinfo, tree, 0, top_tree, data_in);
4675 break;
4676 case 0x00110018:
4677 dissect_smb2_FSCTL_PIPE_WAIT(tvb, pinfo, tree, 0, top_tree, data_in);
4678 break;
4679 case 0x001401D4: /* FSCTL_LMR_REQUEST_RESILIENCY */
4680 dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvb, pinfo, tree, 0, data_in);
4681 break;
4682 case 0x001401FC: /* FSCTL_QUERY_NETWORK_INTERFACE_INFO */
4683 dissect_smb2_FSCTL_QUERY_NETWORK_INTERFACE_INFO(tvb, pinfo, tree, 0, data_in);
4684 break;
4685 case 0x00140200: /* FSCTL_VALIDATE_NEGOTIATE_INFO_224 */
4686 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO_224(tvb, pinfo, tree, 0, data_in);
4687 break;
4688 case 0x00140204: /* FSCTL_VALIDATE_NEGOTIATE_INFO */
4689 dissect_smb2_FSCTL_VALIDATE_NEGOTIATE_INFO(tvb, pinfo, tree, 0, data_in);
4690 break;
4691 case 0x00144064: /* FSCTL_GET_SHADOW_COPY_DATA */
4692 dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvb, pinfo, tree, 0, data_in);
4693 break;
4694 case 0x0009009C: /* FSCTL_GET_OBJECT_ID */
4695 case 0x000900c0: /* FSCTL_CREATE_OR_GET_OBJECT_ID */
4696 dissect_smb2_FSCTL_CREATE_OR_GET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
4697 break;
4698 case 0x00098098: /* FSCTL_SET_OBJECT_ID */
4699 dissect_smb2_FSCTL_SET_OBJECT_ID(tvb, pinfo, tree, 0, data_in);
4700 break;
4701 case 0x000980BC: /* FSCTL_SET_OBJECT_ID_EXTENDED */
4702 dissect_smb2_FSCTL_SET_OBJECT_ID_EXTENDED(tvb, pinfo, tree, 0, data_in);
4703 break;
4704 case 0x0009003C: /* FSCTL_GET_COMPRESSION */
4705 dissect_smb2_FSCTL_GET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
4706 break;
4707 case 0x0009C040: /* FSCTL_SET_COMPRESSION */
4708 dissect_smb2_FSCTL_SET_COMPRESSION(tvb, pinfo, tree, 0, data_in);
4709 break;
4710 default:
4711 proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA);
4715 static void
4716 dissect_smb2_ioctl_data_in(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4718 dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, TRUE);
4721 static void
4722 dissect_smb2_ioctl_data_out(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4724 dissect_smb2_ioctl_data(tvb, pinfo, tree, si->top_tree, si->ioctl_function, FALSE);
4727 static int
4728 dissect_smb2_ioctl_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4730 offset_length_buffer_t o_olb;
4731 offset_length_buffer_t i_olb;
4732 proto_tree *flags_tree = NULL;
4733 proto_item *flags_item = NULL;
4735 /* buffer code */
4736 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4738 /* reserved */
4739 offset += 2;
4741 /* ioctl function */
4742 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
4744 /* fid */
4745 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4747 /* in buffer offset/length */
4748 offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
4750 /* max ioctl in size */
4751 proto_tree_add_item(tree, hf_smb2_max_ioctl_in_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4752 offset += 4;
4754 /* out buffer offset/length */
4755 offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
4757 /* max ioctl out size */
4758 proto_tree_add_item(tree, hf_smb2_max_ioctl_out_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4759 offset += 4;
4761 /* flags */
4762 if (tree) {
4763 flags_item = proto_tree_add_item(tree, hf_smb2_ioctl_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4764 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_ioctl_flags);
4766 proto_tree_add_item(flags_tree, hf_smb2_ioctl_is_fsctl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4767 offset += 4;
4769 /* reserved */
4770 offset += 4;
4772 /* try to decode these blobs in the order they were encoded
4773 * so that for "short" packets we will dissect as much as possible
4774 * before aborting with "short packet"
4776 if (i_olb.off>o_olb.off) {
4777 /* out buffer */
4778 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
4779 /* in buffer */
4780 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
4781 } else {
4782 /* in buffer */
4783 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
4784 /* out buffer */
4785 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
4788 offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
4789 offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
4791 return offset;
4794 static int
4795 dissect_smb2_ioctl_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4797 offset_length_buffer_t o_olb;
4798 offset_length_buffer_t i_olb;
4800 switch (si->status) {
4801 case 0x00000000: break;
4802 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4805 /* buffer code */
4806 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4808 /* some unknown bytes */
4809 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 2, ENC_NA);
4810 offset += 2;
4812 /* ioctl function */
4813 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &si->ioctl_function);
4815 /* fid */
4816 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4818 /* in buffer offset/length */
4819 offset = dissect_smb2_olb_length_offset(tvb, offset, &i_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_in_data);
4821 /* out buffer offset/length */
4822 offset = dissect_smb2_olb_length_offset(tvb, offset, &o_olb, OLB_O_UINT32_S_UINT32, hf_smb2_ioctl_out_data);
4825 /* flags: reserved: must be zero */
4826 offset += 4;
4828 /* reserved */
4829 offset += 4;
4831 /* try to decode these blobs in the order they were encoded
4832 * so that for "short" packets we will dissect as much as possible
4833 * before aborting with "short packet"
4835 if (i_olb.off>o_olb.off) {
4836 /* out buffer */
4837 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
4838 /* in buffer */
4839 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
4840 } else {
4841 /* in buffer */
4842 dissect_smb2_olb_buffer(pinfo, tree, tvb, &i_olb, si, dissect_smb2_ioctl_data_in);
4843 /* out buffer */
4844 dissect_smb2_olb_buffer(pinfo, tree, tvb, &o_olb, si, dissect_smb2_ioctl_data_out);
4847 offset = dissect_smb2_olb_tvb_max_offset(offset, &i_olb);
4848 offset = dissect_smb2_olb_tvb_max_offset(offset, &o_olb);
4850 return offset;
4854 static int
4855 dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
4857 guint32 len;
4858 guint64 off;
4860 /* buffer code */
4861 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4863 /* padding and reserved */
4864 offset += 2;
4866 /* length */
4867 len = tvb_get_letohl(tvb, offset);
4868 proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4869 offset += 4;
4871 /* offset */
4872 off = tvb_get_letoh64(tvb, offset);
4873 proto_tree_add_item(tree, hf_smb2_file_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
4874 offset += 8;
4876 col_append_fstr(pinfo->cinfo, COL_INFO, " Len:%d Off:%" G_GINT64_MODIFIER "u", len, off);
4878 /* fid */
4879 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
4881 /* minimum count */
4882 proto_tree_add_item(tree, hf_smb2_min_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4883 offset += 4;
4885 /* channel */
4886 proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4887 offset += 4;
4889 /* remaining bytes */
4890 proto_tree_add_item(tree, hf_smb2_remaining_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4891 offset += 4;
4893 /* channel info offset */
4894 proto_tree_add_item(tree, hf_smb2_channel_info_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4895 offset += 2;
4897 /* channel info length */
4898 proto_tree_add_item(tree, hf_smb2_channel_info_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4899 offset += 2;
4901 /* there is a buffer here but it is never used (yet) */
4903 /* Store len and offset */
4904 if (si->saved) {
4905 si->saved->file_offset=off;
4906 si->saved->bytes_moved=len;
4909 return offset;
4913 static int
4914 dissect_smb2_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
4916 guint16 dataoffset = 0;
4917 guint32 data_tvb_len;
4918 guint32 length;
4919 switch (si->status) {
4920 case 0x00000000: break;
4921 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
4924 /* buffer code */
4925 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
4927 /* data offset */
4928 dataoffset=tvb_get_letohl(tvb,offset);
4929 proto_tree_add_item(tree, hf_smb2_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4930 offset += 2;
4932 /* length might even be 64bits if they are ambitious*/
4933 length = tvb_get_letohl(tvb, offset);
4934 proto_tree_add_item(tree, hf_smb2_read_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4935 offset += 4;
4937 /* remaining */
4938 proto_tree_add_item(tree, hf_smb2_read_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4939 offset += 4;
4941 /* reserved */
4942 offset += 4;
4944 /* data or dcerpc ?
4945 * If the pidvalid flag is set we assume it is a deferred
4946 * STATUS_PENDING read and thus a named pipe (==dcerpc)
4948 if (length && ( (si->tree && si->tree->share_type == SMB2_SHARE_TYPE_PIPE)||(si->flags & SMB2_FLAGS_ASYNC_CMD))) {
4949 offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si->top_tree);
4950 return offset;
4953 /* data */
4954 proto_tree_add_item(tree, hf_smb2_read_data, tvb, offset, length, ENC_NA);
4956 data_tvb_len=(guint32)tvb_length_remaining(tvb, offset);
4958 offset += MIN(length,data_tvb_len);
4960 if (have_tap_listener(smb2_eo_tap) && (data_tvb_len == length)) {
4961 if (si->saved && si->eo_file_info) { /* without this data we don't know wich file this belongs to */
4962 feed_eo_smb2(tvb,pinfo,si,dataoffset,length,si->saved->file_offset);
4966 return offset;
4969 static void
4970 report_create_context_malformed_buffer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, const char *buffer_desc)
4972 proto_tree_add_text(tree, tvb, 0, tvb_length_remaining(tvb, 0),
4973 "%s SHOULD NOT be generated. Malformed packet", buffer_desc);
4975 static void
4976 dissect_smb2_ExtA_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4978 proto_item *item = NULL;
4979 if (tree) {
4980 item = proto_tree_get_parent(tree);
4981 proto_item_append_text(item, ": SMB2_FILE_FULL_EA_INFO");
4983 dissect_smb2_file_full_ea_info(tvb, pinfo, tree, 0, si);
4986 static void
4987 dissect_smb2_ExtA_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
4989 report_create_context_malformed_buffer(tvb, pinfo, tree, "ExtA Response");
4992 static void
4993 dissect_smb2_SecD_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
4995 proto_item *item = NULL;
4996 if (tree) {
4997 item = proto_tree_get_parent(tree);
4998 proto_item_append_text(item, ": SMB2_SEC_INFO_00");
5000 dissect_smb2_sec_info_00(tvb, pinfo, tree, 0, si);
5003 static void
5004 dissect_smb2_SecD_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
5006 report_create_context_malformed_buffer(tvb, pinfo, tree, "SecD Response");
5009 static void
5010 dissect_smb2_TWrp_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5012 proto_item *item = NULL;
5013 if (tree) {
5014 item = proto_tree_get_parent(tree);
5015 proto_item_append_text(item, ": Timestamp");
5017 dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_twrp_timestamp);
5020 static void
5021 dissect_smb2_TWrp_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5023 report_create_context_malformed_buffer(tvb, pinfo, tree, "TWrp Response");
5026 static void
5027 dissect_smb2_QFid_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5029 proto_item *item = NULL;
5031 if (tree) {
5032 item = proto_tree_get_parent(tree);
5035 if (item) {
5036 if (tvb_length(tvb) == 0) {
5037 proto_item_append_text(item, ": NO DATA");
5038 } else {
5039 proto_item_append_text(item, ": QFid request should have no data, malformed packet");
5044 static void
5045 dissect_smb2_QFid_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5047 int offset = 0;
5048 proto_item *item = NULL;
5049 proto_item *sub_item = NULL;
5050 proto_item *sub_tree = NULL;
5052 if (tree) {
5053 item = proto_tree_get_parent(tree);
5056 if (item) {
5057 proto_item_append_text(item, ": QFid INFO");
5058 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "QFid INFO");
5059 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_QFid_buffer);
5062 proto_tree_add_item(sub_tree, hf_smb2_qfid_fid, tvb, offset, 32, ENC_NA);
5065 static void
5066 dissect_smb2_AlSi_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5068 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, 0, 8, ENC_LITTLE_ENDIAN);
5071 static void
5072 dissect_smb2_AlSi_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5074 report_create_context_malformed_buffer(tvb, pinfo, tree, "AlSi Response");
5077 static void
5078 dissect_smb2_DHnQ_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
5080 dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNQ);
5083 static void
5084 dissect_smb2_DHnQ_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5086 proto_tree_add_item(tree, hf_smb2_dhnq_buffer_reserved, tvb, 0, 8, ENC_LITTLE_ENDIAN);
5089 static void
5090 dissect_smb2_DHnC_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
5092 dissect_smb2_fid(tvb, pinfo, tree, 0, si, FID_MODE_DHNC);
5095 static void
5096 dissect_smb2_DHnC_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
5098 report_create_context_malformed_buffer(tvb, pinfo, tree, "DHnC Response");
5102 * SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2
5103 * 4 - timeout
5104 * 4 - flags
5105 * 8 - reserved
5106 * 16 - create guid
5108 * SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2
5109 * 4 - timeout
5110 * 4 - flags
5112 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
5113 * 16 - file id
5114 * 16 - create guid
5115 * 4 - flags
5117 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2
5118 * - nothing -
5120 #define SMB2_DH2X_FLAGS_PERSISTENT_HANDLE 0x00000002
5122 static void
5123 dissect_smb2_DH2Q_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5125 static const int *dh2x_flags_fields[] = {
5126 &hf_smb2_dh2x_buffer_flags_persistent_handle,
5127 NULL
5129 int offset = 0;
5130 proto_item *item = NULL;
5131 proto_item *sub_item = NULL;
5132 proto_item *sub_tree = NULL;
5134 if (tree) {
5135 item = proto_tree_get_parent(tree);
5138 if (item) {
5139 proto_item_append_text(item, ": DH2Q Request");
5140 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "DH2Q Request");
5141 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_DH2Q_buffer);
5144 /* timeout */
5145 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5146 offset += 4;
5148 /* flags */
5149 proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_dh2x_buffer_flags,
5150 ett_smb2_dh2x_flags, dh2x_flags_fields, ENC_LITTLE_ENDIAN);
5151 offset += 4;
5153 /* reserved */
5154 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_reserved, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5155 offset += 8;
5157 /* create guid */
5158 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5161 static void
5162 dissect_smb2_DH2Q_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5164 int offset = 0;
5165 proto_item *item = NULL;
5166 proto_item *sub_item = NULL;
5167 proto_item *sub_tree = NULL;
5169 if (tree) {
5170 item = proto_tree_get_parent(tree);
5173 if (item) {
5174 proto_item_append_text(item, ": DH2Q Response");
5175 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "DH2Q Response");
5176 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_DH2Q_buffer);
5179 /* timeout */
5180 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_timeout, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5181 offset += 4;
5183 /* flags */
5184 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5187 static void
5188 dissect_smb2_DH2C_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si)
5190 int offset = 0;
5191 proto_item *item = NULL;
5192 proto_item *sub_item = NULL;
5193 proto_item *sub_tree = NULL;
5195 if (tree) {
5196 item = proto_tree_get_parent(tree);
5199 if (item) {
5200 proto_item_append_text(item, ": DH2C Request");
5201 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "DH2C Request");
5202 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_DH2C_buffer);
5205 /* file id */
5206 dissect_smb2_fid(tvb, pinfo, sub_tree, offset, si, FID_MODE_DHNC);
5207 offset += 16;
5209 /* create guid */
5210 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5211 offset += 16;
5213 /* flags */
5214 proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5217 static void
5218 dissect_smb2_DH2C_buffer_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si _U_)
5220 report_create_context_malformed_buffer(tvb, pinfo, tree, "DH2C Response");
5223 static void
5224 dissect_smb2_MxAc_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5226 int offset = 0;
5227 proto_item *item = NULL;
5229 if (tree) {
5230 item = proto_tree_get_parent(tree);
5233 if (tvb_length(tvb) == 0) {
5234 if (item) {
5235 proto_item_append_text(item, ": NO DATA");
5237 return;
5240 if (item) {
5241 proto_item_append_text(item, ": Timestamp");
5244 dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_mxac_timestamp);
5247 static void
5248 dissect_smb2_MxAc_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5250 int offset = 0;
5251 proto_item *item = NULL;
5252 proto_item *sub_item = NULL;
5253 proto_tree *sub_tree = NULL;
5255 if (tree) {
5256 item = proto_tree_get_parent(tree);
5259 if (tvb_length(tvb) == 0) {
5260 if (item) {
5261 proto_item_append_text(item, ": NO DATA");
5263 return;
5266 if (item) {
5267 proto_item_append_text(item, ": MxAc INFO");
5268 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "MxAc INFO");
5269 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_MxAc_buffer);
5272 proto_tree_add_item(sub_tree, hf_smb2_mxac_status, tvb, offset, 4, ENC_BIG_ENDIAN);
5273 offset += 4;
5275 dissect_smb_access_mask(tvb, sub_tree, offset);
5279 * SMB2_CREATE_REQUEST_LEASE 32
5280 * 16 - lease key
5281 * 4 - lease state
5282 * 4 - lease flags
5283 * 8 - lease duration
5285 * SMB2_CREATE_REQUEST_LEASE_V2 52
5286 * 16 - lease key
5287 * 4 - lease state
5288 * 4 - lease flags
5289 * 8 - lease duration
5290 * 16 - pareant lease key
5291 * 4 - epoch
5293 #define SMB2_LEASE_STATE_READ_CACHING 0x00000001
5294 #define SMB2_LEASE_STATE_HANDLE_CACHING 0x00000002
5295 #define SMB2_LEASE_STATE_WRITE_CACHING 0x00000004
5297 #define SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED 0x00000001
5298 #define SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS 0x00000002
5299 #define SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET 0x00000004
5301 static const int *lease_state_fields[] = {
5302 &hf_smb2_lease_state_read_caching,
5303 &hf_smb2_lease_state_handle_caching,
5304 &hf_smb2_lease_state_write_caching,
5305 NULL
5307 static const int *lease_flags_fields[] = {
5308 &hf_smb2_lease_flags_break_ack_required,
5309 &hf_smb2_lease_flags_break_in_progress,
5310 &hf_smb2_lease_flags_parent_lease_key_set,
5311 NULL
5314 static void
5315 dissect_SMB2_CREATE_LEASE_VX(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_)
5317 int offset = 0;
5318 int len;
5319 proto_item *sub_item = NULL;
5320 proto_tree *sub_tree = NULL;
5321 proto_item *parent_item = NULL;
5323 if (parent_tree) {
5324 parent_item = proto_tree_get_parent(parent_tree);
5327 len = tvb_length(tvb);
5329 switch (len) {
5330 case 32: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE */
5331 if (parent_item) {
5332 proto_item_append_text(parent_item, ": LEASE_V1");
5333 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "LEASE_V1");
5334 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_RqLs_buffer);
5337 break;
5338 case 52: /* SMB2_CREATE_REQUEST/RESPONSE_LEASE_V2 */
5339 if (parent_item) {
5340 proto_item_append_text(parent_item, ": LEASE_V2");
5341 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "LEASE_V2");
5342 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_RqLs_buffer);
5345 break;
5346 default:
5347 report_create_context_malformed_buffer(tvb, pinfo, parent_tree, "RqLs");
5348 break;
5351 proto_tree_add_item(sub_tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5352 offset += 16;
5354 proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_state,
5355 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5356 offset += 4;
5358 proto_tree_add_bitmask(sub_tree, tvb, offset, hf_smb2_lease_flags,
5359 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5360 offset += 4;
5362 proto_tree_add_item(sub_tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5363 offset += 8;
5365 if (len < 52) {
5366 return;
5369 proto_tree_add_item(sub_tree, hf_smb2_parent_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5370 offset += 16;
5372 proto_tree_add_item(sub_tree, hf_smb2_lease_epoch, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5375 static void
5376 dissect_smb2_RqLs_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5378 dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
5381 static void
5382 dissect_smb2_RqLs_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5384 dissect_SMB2_CREATE_LEASE_VX(tvb, pinfo, tree, si);
5388 * SMB2_CREATE_APP_INSTANCE_ID
5389 * 2 - structure size - 20
5390 * 2 - reserved
5391 * 16 - application guid
5394 static void
5395 dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5397 int offset = 0;
5398 proto_item *item = NULL;
5399 proto_item *sub_item = NULL;
5400 proto_item *sub_tree = NULL;
5402 if (tree) {
5403 item = proto_tree_get_parent(tree);
5406 if (item) {
5407 proto_item_append_text(item, ": APP INSTANCE ID");
5408 sub_item = proto_tree_add_text(tree, tvb, offset, -1, "APP INSTANCE ID");
5409 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_APP_INSTANCE_buffer);
5412 /* struct size */
5413 proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_struct_size,
5414 tvb, offset, 2, ENC_LITTLE_ENDIAN);
5415 offset += 2;
5417 /* reserved */
5418 proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_reserved,
5419 tvb, offset, 2, ENC_LITTLE_ENDIAN);
5420 offset += 2;
5422 /* create guid */
5423 proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_app_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5426 static void
5427 dissect_smb2_APP_INSTANCE_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, smb2_info_t *si _U_)
5429 report_create_context_malformed_buffer(tvb, pinfo, tree, "APP INSTANCE Response");
5432 typedef void (*create_context_data_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_info_t *si);
5434 typedef struct create_context_data_dissectors {
5435 create_context_data_dissector_t request;
5436 create_context_data_dissector_t response;
5437 } create_context_data_dissectors_t;
5439 struct create_context_data_tag_dissectors {
5440 const char *tag;
5441 const char *val;
5442 create_context_data_dissectors_t dissectors;
5445 struct create_context_data_tag_dissectors create_context_dissectors_array[] = {
5446 { "ExtA", "SMB2_CREATE_EA_BUFFER",
5447 { dissect_smb2_ExtA_buffer_request, dissect_smb2_ExtA_buffer_response } },
5448 { "SecD", "SMB2_CREATE_SD_BUFFER",
5449 { dissect_smb2_SecD_buffer_request, dissect_smb2_SecD_buffer_response } },
5450 { "AlSi", "SMB2_CREATE_ALLOCATION_SIZE",
5451 { dissect_smb2_AlSi_buffer_request, dissect_smb2_AlSi_buffer_response } },
5452 { "MxAc", "SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST",
5453 { dissect_smb2_MxAc_buffer_request, dissect_smb2_MxAc_buffer_response } },
5454 { "DHnQ", "SMB2_CREATE_DURABLE_HANDLE_REQUEST",
5455 { dissect_smb2_DHnQ_buffer_request, dissect_smb2_DHnQ_buffer_response } },
5456 { "DHnC", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT",
5457 { dissect_smb2_DHnC_buffer_request, dissect_smb2_DHnC_buffer_response } },
5458 { "DH2Q", "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2",
5459 { dissect_smb2_DH2Q_buffer_request, dissect_smb2_DH2Q_buffer_response } },
5460 { "DH2C", "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2",
5461 { dissect_smb2_DH2C_buffer_request, dissect_smb2_DH2C_buffer_response } },
5462 { "TWrp", "SMB2_CREATE_TIMEWARP_TOKEN",
5463 { dissect_smb2_TWrp_buffer_request, dissect_smb2_TWrp_buffer_response } },
5464 { "QFid", "SMB2_CREATE_QUERY_ON_DISK_ID",
5465 { dissect_smb2_QFid_buffer_request, dissect_smb2_QFid_buffer_response } },
5466 { "RqLs", "SMB2_CREATE_REQUEST_LEASE",
5467 { dissect_smb2_RqLs_buffer_request, dissect_smb2_RqLs_buffer_response } },
5468 { "744D142E-46FA-0890-4AF7-A7EF6AA6BC45", "SMB2_CREATE_APP_INSTANCE_ID",
5469 { dissect_smb2_APP_INSTANCE_buffer_request,
5470 dissect_smb2_APP_INSTANCE_buffer_response } }
5473 static struct create_context_data_tag_dissectors*
5474 get_create_context_data_tag_dissectors(const char *tag)
5476 static struct create_context_data_tag_dissectors INVALID = {
5477 NULL, "<invalid>", { NULL, NULL }
5480 size_t i;
5481 for (i = 0; i<array_length(create_context_dissectors_array); i++) {
5482 if (!strcmp(tag, create_context_dissectors_array[i].tag))
5483 return &create_context_dissectors_array[i];
5485 return &INVALID;
5488 static void
5489 dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
5491 offset_length_buffer_t tag_olb;
5492 offset_length_buffer_t data_olb;
5493 const char *tag;
5494 guint16 chain_offset;
5495 int offset = 0;
5496 int len = -1;
5497 proto_item *sub_item = NULL;
5498 proto_tree *sub_tree = NULL;
5499 proto_item *parent_item = NULL;
5500 create_context_data_dissectors_t *dissectors = NULL;
5501 create_context_data_dissector_t dissector = NULL;
5502 struct create_context_data_tag_dissectors *tag_dissectors;
5504 chain_offset = tvb_get_letohl(tvb, offset);
5505 if (chain_offset) {
5506 len = chain_offset;
5509 if (parent_tree) {
5510 sub_item = proto_tree_add_text(parent_tree, tvb, offset, len, "Chain Element");
5511 sub_tree = proto_item_add_subtree(sub_item, ett_smb2_create_chain_element);
5512 parent_item = proto_tree_get_parent(parent_tree);
5515 /* chain offset */
5516 proto_tree_add_item(sub_tree, hf_smb2_create_chain_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5517 offset += 4;
5519 /* tag offset/length */
5520 offset = dissect_smb2_olb_length_offset(tvb, offset, &tag_olb, OLB_O_UINT16_S_UINT32, hf_smb2_tag);
5522 /* data offset/length */
5523 dissect_smb2_olb_length_offset(tvb, offset, &data_olb, OLB_O_UINT16_S_UINT32, hf_smb2_create_chain_data);
5525 /* tag string */
5526 tag = dissect_smb2_olb_string(pinfo, sub_tree, tvb, &tag_olb, OLB_TYPE_ASCII_STRING);
5528 tag_dissectors = get_create_context_data_tag_dissectors(tag);
5530 proto_item_append_text(parent_item, " %s", tag);
5531 proto_item_append_text(sub_item, ": %s \"%s\"", tag_dissectors->val, tag);
5533 /* data */
5534 dissectors = &tag_dissectors->dissectors;
5535 if (dissectors)
5536 dissector = (si->flags & SMB2_FLAGS_RESPONSE) ? dissectors->response : dissectors->request;
5538 dissect_smb2_olb_buffer(pinfo, sub_tree, tvb, &data_olb, si, dissector);
5540 if (chain_offset) {
5541 tvbuff_t *chain_tvb;
5542 chain_tvb = tvb_new_subset_remaining(tvb, chain_offset);
5544 /* next extra info */
5545 dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
5549 static int
5550 dissect_smb2_create_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5552 offset_length_buffer_t f_olb, e_olb;
5553 const char *fname;
5555 /* buffer code */
5556 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5558 /* security flags */
5559 offset++;
5561 /* oplock */
5562 offset = dissect_smb2_oplock(tree, tvb, offset);
5564 /* impersonation level */
5565 proto_tree_add_item(tree, hf_smb2_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5566 offset += 4;
5568 /* create flags */
5569 proto_tree_add_item(tree, hf_smb2_create_flags, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5570 offset += 8;
5572 /* reserved */
5573 offset += 8;
5575 /* access mask */
5576 offset = dissect_smb_access_mask(tvb, tree, offset);
5578 /* File Attributes */
5579 offset = dissect_file_ext_attr(tvb, tree, offset);
5581 /* share access */
5582 offset = dissect_nt_share_access(tvb, tree, offset);
5584 /* create disposition */
5585 proto_tree_add_item(tree, hf_smb2_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5586 offset += 4;
5588 /* create options */
5589 offset = dissect_nt_create_options(tvb, tree, offset);
5591 /* filename offset/length */
5592 offset = dissect_smb2_olb_length_offset(tvb, offset, &f_olb, OLB_O_UINT16_S_UINT16, hf_smb2_filename);
5594 /* extrainfo offset */
5595 offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
5597 /* filename string */
5598 fname = dissect_smb2_olb_string(pinfo, tree, tvb, &f_olb, OLB_TYPE_UNICODE_STRING);
5599 col_append_fstr(pinfo->cinfo, COL_INFO, " File: %s", fname);
5601 /* save the name if it looks sane */
5602 if (!pinfo->fd->flags.visited) {
5603 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
5604 g_free(si->saved->extra_info);
5605 si->saved->extra_info = NULL;
5606 si->saved->extra_info_type = SMB2_EI_NONE;
5608 if (si->saved && f_olb.len && f_olb.len<256) {
5609 si->saved->extra_info_type = SMB2_EI_FILENAME;
5610 si->saved->extra_info = (gchar *)g_malloc(f_olb.len+1);
5611 g_snprintf((gchar *)si->saved->extra_info, f_olb.len+1, "%s", fname);
5615 /* If extrainfo_offset is non-null then this points to another
5616 * buffer. The offset is relative to the start of the smb packet
5618 dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
5620 offset = dissect_smb2_olb_tvb_max_offset(offset, &f_olb);
5621 offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
5623 return offset;
5626 #define SMB2_CREATE_REP_FLAGS_REPARSE_POINT 0x01
5628 static int
5629 dissect_smb2_create_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5631 guint64 end_of_file;
5632 guint32 attr_mask;
5633 offset_length_buffer_t e_olb;
5634 static const int *create_rep_flags_fields[] = {
5635 &hf_smb2_create_rep_flags_reparse_point,
5636 NULL
5639 switch (si->status) {
5640 case 0x00000000: break;
5641 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
5644 /* buffer code */
5645 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5647 /* oplock */
5648 offset = dissect_smb2_oplock(tree, tvb, offset);
5650 /* reserved */
5651 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_create_rep_flags,
5652 ett_smb2_create_rep_flags, create_rep_flags_fields, ENC_LITTLE_ENDIAN);
5653 offset += 1;
5655 /* create action */
5656 proto_tree_add_item(tree, hf_smb2_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5657 offset += 4;
5659 /* create time */
5660 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_create_timestamp);
5662 /* last access */
5663 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_access_timestamp);
5665 /* last write */
5666 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_write_timestamp);
5668 /* last change */
5669 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_last_change_timestamp);
5671 /* allocation size */
5672 proto_tree_add_item(tree, hf_smb2_allocation_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5673 offset += 8;
5675 /* end of file */
5676 end_of_file = tvb_get_letoh64(tvb, offset);
5677 if (si->eo_file_info) {
5678 si->eo_file_info->end_of_file = tvb_get_letoh64(tvb, offset);
5680 proto_tree_add_item(tree, hf_smb2_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5681 offset += 8;
5683 /* File Attributes */
5684 attr_mask=tvb_get_letohl(tvb, offset);
5685 offset = dissect_file_ext_attr(tvb, tree, offset);
5687 /* reserved */
5688 offset += 4;
5690 /* fid */
5691 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_OPEN);
5693 /* We save this after dissect_smb2_fid just because it would be
5694 possible to have this response without having the mathing request.
5695 In that case the entry in the file info hash table has been created
5696 in dissect_smb2_fid */
5697 if (si->eo_file_info) {
5698 si->eo_file_info->end_of_file = end_of_file;
5699 si->eo_file_info->attr_mask = attr_mask;
5702 /* extrainfo offset */
5703 offset = dissect_smb2_olb_length_offset(tvb, offset, &e_olb, OLB_O_UINT32_S_UINT32, hf_smb2_extrainfo);
5705 /* If extrainfo_offset is non-null then this points to another
5706 * buffer. The offset is relative to the start of the smb packet
5708 dissect_smb2_olb_buffer(pinfo, tree, tvb, &e_olb, si, dissect_smb2_create_extra_info);
5710 offset = dissect_smb2_olb_tvb_max_offset(offset, &e_olb);
5712 /* free si->saved->extra_info we dont need it any more */
5713 if (si->saved && si->saved->extra_info_type == SMB2_EI_FILENAME) {
5714 g_free(si->saved->extra_info);
5715 si->saved->extra_info = NULL;
5716 si->saved->extra_info_type = SMB2_EI_NONE;
5719 return offset;
5723 static int
5724 dissect_smb2_setinfo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5726 guint32 setinfo_size;
5727 guint16 setinfo_offset;
5729 /* buffer code */
5730 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5732 /* class and info level */
5733 offset = dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5735 /* size */
5736 setinfo_size = tvb_get_letohl(tvb, offset);
5737 proto_tree_add_item(tree, hf_smb2_setinfo_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5738 offset += 4;
5740 /* offset */
5741 setinfo_offset = tvb_get_letohs(tvb, offset);
5742 proto_tree_add_item(tree, hf_smb2_setinfo_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5743 offset += 2;
5745 /* some unknown bytes */
5746 proto_tree_add_item(tree, hf_smb2_unknown, tvb, offset, 6, ENC_NA);
5747 offset += 6;
5749 /* fid */
5750 dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5752 /* data */
5753 if (si->saved)
5754 dissect_smb2_infolevel(tvb, pinfo, tree, setinfo_offset, si, si->saved->smb2_class, si->saved->infolevel);
5755 offset = setinfo_offset + setinfo_size;
5757 return offset;
5760 static int
5761 dissect_smb2_setinfo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5763 /* class/infolevel */
5764 dissect_smb2_class_infolevel(pinfo, tvb, offset, tree, si);
5766 switch (si->status) {
5767 case 0x00000000: break;
5768 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
5771 /* buffer code */
5772 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5774 return offset;
5777 static int
5778 dissect_smb2_break_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5780 guint16 buffer_code;
5782 /* buffer code */
5783 buffer_code = tvb_get_letohs(tvb, offset);
5784 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5786 if (buffer_code == 24) {
5787 /* OPLOCK Break */
5789 /* oplock */
5790 offset = dissect_smb2_oplock(tree, tvb, offset);
5792 /* reserved */
5793 offset += 1;
5795 /* reserved */
5796 offset += 4;
5798 /* fid */
5799 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5801 return offset;
5804 if (buffer_code == 36) {
5805 /* Lease Break Acknowledgment */
5807 /* reserved */
5808 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5809 offset +=2;
5811 /* lease flags */
5812 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
5813 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5814 offset += 4;
5816 /* lease key */
5817 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5818 offset += 16;
5820 /* lease state */
5821 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5822 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5823 offset += 4;
5825 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5826 offset += 8;
5828 return offset;
5831 return offset;
5834 static int
5835 dissect_smb2_break_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si)
5837 guint16 buffer_code;
5839 switch (si->status) {
5840 case 0x00000000: break;
5841 default: return dissect_smb2_error_response(tvb, pinfo, tree, offset, si);
5844 /* buffer code */
5845 buffer_code = tvb_get_letohs(tvb, offset);
5846 offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
5848 if (buffer_code == 24) {
5849 /* OPLOCK Break Notification */
5851 /* oplock */
5852 offset = dissect_smb2_oplock(tree, tvb, offset);
5854 /* reserved */
5855 offset += 1;
5857 /* reserved */
5858 offset += 4;
5860 /* fid */
5861 offset = dissect_smb2_fid(tvb, pinfo, tree, offset, si, FID_MODE_USE);
5863 /* in break requests from server to client here're 24 byte zero bytes
5864 * which are likely a bug in windows (they may use 2* 24 bytes instead of just
5865 * 1 *24 bytes
5867 return offset;
5870 if (buffer_code == 44) {
5871 proto_item *item;
5873 /* Lease Break Notification */
5875 /* reserved */
5876 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5877 offset +=2;
5879 /* lease flags */
5880 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
5881 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5882 offset += 4;
5884 /* lease key */
5885 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5886 offset += 16;
5888 /* current lease state */
5889 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5890 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5891 if (item) {
5892 proto_item_prepend_text(item, "Current ");
5894 offset += 4;
5896 /* new lease state */
5897 item = proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5898 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5899 if (item) {
5900 proto_item_prepend_text(item, "New ");
5902 offset += 4;
5904 /* break reason - reserved */
5905 proto_tree_add_item(tree, hf_smb2_lease_break_reason, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5906 offset += 4;
5908 /* access mask hint - reserved */
5909 proto_tree_add_item(tree, hf_smb2_lease_access_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5910 offset += 4;
5912 /* share mask hint - reserved */
5913 proto_tree_add_item(tree, hf_smb2_lease_share_mask_hint, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5914 offset += 4;
5916 return offset;
5919 if (buffer_code == 36) {
5920 /* Lease Break Response */
5922 /* reserved */
5923 proto_tree_add_item(tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
5924 offset +=2;
5926 /* lease flags */
5927 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_flags,
5928 ett_smb2_lease_flags, lease_flags_fields, ENC_LITTLE_ENDIAN);
5929 offset += 4;
5931 /* lease key */
5932 proto_tree_add_item(tree, hf_smb2_lease_key, tvb, offset, 16, ENC_LITTLE_ENDIAN);
5933 offset += 16;
5935 /* lease state */
5936 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_lease_state,
5937 ett_smb2_lease_state, lease_state_fields, ENC_LITTLE_ENDIAN);
5938 offset += 4;
5940 proto_tree_add_item(tree, hf_smb2_lease_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
5941 offset += 8;
5943 return offset;
5946 return offset;
5949 /* names here are just until we find better names for these functions */
5950 static const value_string smb2_cmd_vals[] = {
5951 { 0x00, "Negotiate Protocol" },
5952 { 0x01, "Session Setup" },
5953 { 0x02, "Session Logoff" },
5954 { 0x03, "Tree Connect" },
5955 { 0x04, "Tree Disconnect" },
5956 { 0x05, "Create" },
5957 { 0x06, "Close" },
5958 { 0x07, "Flush" },
5959 { 0x08, "Read" },
5960 { 0x09, "Write" },
5961 { 0x0A, "Lock" },
5962 { 0x0B, "Ioctl" },
5963 { 0x0C, "Cancel" },
5964 { 0x0D, "KeepAlive" },
5965 { 0x0E, "Find" },
5966 { 0x0F, "Notify" },
5967 { 0x10, "GetInfo" },
5968 { 0x11, "SetInfo" },
5969 { 0x12, "Break" },
5970 { 0x13, "unknown-0x13" },
5971 { 0x14, "unknown-0x14" },
5972 { 0x15, "unknown-0x15" },
5973 { 0x16, "unknown-0x16" },
5974 { 0x17, "unknown-0x17" },
5975 { 0x18, "unknown-0x18" },
5976 { 0x19, "unknown-0x19" },
5977 { 0x1A, "unknown-0x1A" },
5978 { 0x1B, "unknown-0x1B" },
5979 { 0x1C, "unknown-0x1C" },
5980 { 0x1D, "unknown-0x1D" },
5981 { 0x1E, "unknown-0x1E" },
5982 { 0x1F, "unknown-0x1F" },
5983 { 0x20, "unknown-0x20" },
5984 { 0x21, "unknown-0x21" },
5985 { 0x22, "unknown-0x22" },
5986 { 0x23, "unknown-0x23" },
5987 { 0x24, "unknown-0x24" },
5988 { 0x25, "unknown-0x25" },
5989 { 0x26, "unknown-0x26" },
5990 { 0x27, "unknown-0x27" },
5991 { 0x28, "unknown-0x28" },
5992 { 0x29, "unknown-0x29" },
5993 { 0x2A, "unknown-0x2A" },
5994 { 0x2B, "unknown-0x2B" },
5995 { 0x2C, "unknown-0x2C" },
5996 { 0x2D, "unknown-0x2D" },
5997 { 0x2E, "unknown-0x2E" },
5998 { 0x2F, "unknown-0x2F" },
5999 { 0x30, "unknown-0x30" },
6000 { 0x31, "unknown-0x31" },
6001 { 0x32, "unknown-0x32" },
6002 { 0x33, "unknown-0x33" },
6003 { 0x34, "unknown-0x34" },
6004 { 0x35, "unknown-0x35" },
6005 { 0x36, "unknown-0x36" },
6006 { 0x37, "unknown-0x37" },
6007 { 0x38, "unknown-0x38" },
6008 { 0x39, "unknown-0x39" },
6009 { 0x3A, "unknown-0x3A" },
6010 { 0x3B, "unknown-0x3B" },
6011 { 0x3C, "unknown-0x3C" },
6012 { 0x3D, "unknown-0x3D" },
6013 { 0x3E, "unknown-0x3E" },
6014 { 0x3F, "unknown-0x3F" },
6015 { 0x40, "unknown-0x40" },
6016 { 0x41, "unknown-0x41" },
6017 { 0x42, "unknown-0x42" },
6018 { 0x43, "unknown-0x43" },
6019 { 0x44, "unknown-0x44" },
6020 { 0x45, "unknown-0x45" },
6021 { 0x46, "unknown-0x46" },
6022 { 0x47, "unknown-0x47" },
6023 { 0x48, "unknown-0x48" },
6024 { 0x49, "unknown-0x49" },
6025 { 0x4A, "unknown-0x4A" },
6026 { 0x4B, "unknown-0x4B" },
6027 { 0x4C, "unknown-0x4C" },
6028 { 0x4D, "unknown-0x4D" },
6029 { 0x4E, "unknown-0x4E" },
6030 { 0x4F, "unknown-0x4F" },
6031 { 0x50, "unknown-0x50" },
6032 { 0x51, "unknown-0x51" },
6033 { 0x52, "unknown-0x52" },
6034 { 0x53, "unknown-0x53" },
6035 { 0x54, "unknown-0x54" },
6036 { 0x55, "unknown-0x55" },
6037 { 0x56, "unknown-0x56" },
6038 { 0x57, "unknown-0x57" },
6039 { 0x58, "unknown-0x58" },
6040 { 0x59, "unknown-0x59" },
6041 { 0x5A, "unknown-0x5A" },
6042 { 0x5B, "unknown-0x5B" },
6043 { 0x5C, "unknown-0x5C" },
6044 { 0x5D, "unknown-0x5D" },
6045 { 0x5E, "unknown-0x5E" },
6046 { 0x5F, "unknown-0x5F" },
6047 { 0x60, "unknown-0x60" },
6048 { 0x61, "unknown-0x61" },
6049 { 0x62, "unknown-0x62" },
6050 { 0x63, "unknown-0x63" },
6051 { 0x64, "unknown-0x64" },
6052 { 0x65, "unknown-0x65" },
6053 { 0x66, "unknown-0x66" },
6054 { 0x67, "unknown-0x67" },
6055 { 0x68, "unknown-0x68" },
6056 { 0x69, "unknown-0x69" },
6057 { 0x6A, "unknown-0x6A" },
6058 { 0x6B, "unknown-0x6B" },
6059 { 0x6C, "unknown-0x6C" },
6060 { 0x6D, "unknown-0x6D" },
6061 { 0x6E, "unknown-0x6E" },
6062 { 0x6F, "unknown-0x6F" },
6063 { 0x70, "unknown-0x70" },
6064 { 0x71, "unknown-0x71" },
6065 { 0x72, "unknown-0x72" },
6066 { 0x73, "unknown-0x73" },
6067 { 0x74, "unknown-0x74" },
6068 { 0x75, "unknown-0x75" },
6069 { 0x76, "unknown-0x76" },
6070 { 0x77, "unknown-0x77" },
6071 { 0x78, "unknown-0x78" },
6072 { 0x79, "unknown-0x79" },
6073 { 0x7A, "unknown-0x7A" },
6074 { 0x7B, "unknown-0x7B" },
6075 { 0x7C, "unknown-0x7C" },
6076 { 0x7D, "unknown-0x7D" },
6077 { 0x7E, "unknown-0x7E" },
6078 { 0x7F, "unknown-0x7F" },
6079 { 0x80, "unknown-0x80" },
6080 { 0x81, "unknown-0x81" },
6081 { 0x82, "unknown-0x82" },
6082 { 0x83, "unknown-0x83" },
6083 { 0x84, "unknown-0x84" },
6084 { 0x85, "unknown-0x85" },
6085 { 0x86, "unknown-0x86" },
6086 { 0x87, "unknown-0x87" },
6087 { 0x88, "unknown-0x88" },
6088 { 0x89, "unknown-0x89" },
6089 { 0x8A, "unknown-0x8A" },
6090 { 0x8B, "unknown-0x8B" },
6091 { 0x8C, "unknown-0x8C" },
6092 { 0x8D, "unknown-0x8D" },
6093 { 0x8E, "unknown-0x8E" },
6094 { 0x8F, "unknown-0x8F" },
6095 { 0x90, "unknown-0x90" },
6096 { 0x91, "unknown-0x91" },
6097 { 0x92, "unknown-0x92" },
6098 { 0x93, "unknown-0x93" },
6099 { 0x94, "unknown-0x94" },
6100 { 0x95, "unknown-0x95" },
6101 { 0x96, "unknown-0x96" },
6102 { 0x97, "unknown-0x97" },
6103 { 0x98, "unknown-0x98" },
6104 { 0x99, "unknown-0x99" },
6105 { 0x9A, "unknown-0x9A" },
6106 { 0x9B, "unknown-0x9B" },
6107 { 0x9C, "unknown-0x9C" },
6108 { 0x9D, "unknown-0x9D" },
6109 { 0x9E, "unknown-0x9E" },
6110 { 0x9F, "unknown-0x9F" },
6111 { 0xA0, "unknown-0xA0" },
6112 { 0xA1, "unknown-0xA1" },
6113 { 0xA2, "unknown-0xA2" },
6114 { 0xA3, "unknown-0xA3" },
6115 { 0xA4, "unknown-0xA4" },
6116 { 0xA5, "unknown-0xA5" },
6117 { 0xA6, "unknown-0xA6" },
6118 { 0xA7, "unknown-0xA7" },
6119 { 0xA8, "unknown-0xA8" },
6120 { 0xA9, "unknown-0xA9" },
6121 { 0xAA, "unknown-0xAA" },
6122 { 0xAB, "unknown-0xAB" },
6123 { 0xAC, "unknown-0xAC" },
6124 { 0xAD, "unknown-0xAD" },
6125 { 0xAE, "unknown-0xAE" },
6126 { 0xAF, "unknown-0xAF" },
6127 { 0xB0, "unknown-0xB0" },
6128 { 0xB1, "unknown-0xB1" },
6129 { 0xB2, "unknown-0xB2" },
6130 { 0xB3, "unknown-0xB3" },
6131 { 0xB4, "unknown-0xB4" },
6132 { 0xB5, "unknown-0xB5" },
6133 { 0xB6, "unknown-0xB6" },
6134 { 0xB7, "unknown-0xB7" },
6135 { 0xB8, "unknown-0xB8" },
6136 { 0xB9, "unknown-0xB9" },
6137 { 0xBA, "unknown-0xBA" },
6138 { 0xBB, "unknown-0xBB" },
6139 { 0xBC, "unknown-0xBC" },
6140 { 0xBD, "unknown-0xBD" },
6141 { 0xBE, "unknown-0xBE" },
6142 { 0xBF, "unknown-0xBF" },
6143 { 0xC0, "unknown-0xC0" },
6144 { 0xC1, "unknown-0xC1" },
6145 { 0xC2, "unknown-0xC2" },
6146 { 0xC3, "unknown-0xC3" },
6147 { 0xC4, "unknown-0xC4" },
6148 { 0xC5, "unknown-0xC5" },
6149 { 0xC6, "unknown-0xC6" },
6150 { 0xC7, "unknown-0xC7" },
6151 { 0xC8, "unknown-0xC8" },
6152 { 0xC9, "unknown-0xC9" },
6153 { 0xCA, "unknown-0xCA" },
6154 { 0xCB, "unknown-0xCB" },
6155 { 0xCC, "unknown-0xCC" },
6156 { 0xCD, "unknown-0xCD" },
6157 { 0xCE, "unknown-0xCE" },
6158 { 0xCF, "unknown-0xCF" },
6159 { 0xD0, "unknown-0xD0" },
6160 { 0xD1, "unknown-0xD1" },
6161 { 0xD2, "unknown-0xD2" },
6162 { 0xD3, "unknown-0xD3" },
6163 { 0xD4, "unknown-0xD4" },
6164 { 0xD5, "unknown-0xD5" },
6165 { 0xD6, "unknown-0xD6" },
6166 { 0xD7, "unknown-0xD7" },
6167 { 0xD8, "unknown-0xD8" },
6168 { 0xD9, "unknown-0xD9" },
6169 { 0xDA, "unknown-0xDA" },
6170 { 0xDB, "unknown-0xDB" },
6171 { 0xDC, "unknown-0xDC" },
6172 { 0xDD, "unknown-0xDD" },
6173 { 0xDE, "unknown-0xDE" },
6174 { 0xDF, "unknown-0xDF" },
6175 { 0xE0, "unknown-0xE0" },
6176 { 0xE1, "unknown-0xE1" },
6177 { 0xE2, "unknown-0xE2" },
6178 { 0xE3, "unknown-0xE3" },
6179 { 0xE4, "unknown-0xE4" },
6180 { 0xE5, "unknown-0xE5" },
6181 { 0xE6, "unknown-0xE6" },
6182 { 0xE7, "unknown-0xE7" },
6183 { 0xE8, "unknown-0xE8" },
6184 { 0xE9, "unknown-0xE9" },
6185 { 0xEA, "unknown-0xEA" },
6186 { 0xEB, "unknown-0xEB" },
6187 { 0xEC, "unknown-0xEC" },
6188 { 0xED, "unknown-0xED" },
6189 { 0xEE, "unknown-0xEE" },
6190 { 0xEF, "unknown-0xEF" },
6191 { 0xF0, "unknown-0xF0" },
6192 { 0xF1, "unknown-0xF1" },
6193 { 0xF2, "unknown-0xF2" },
6194 { 0xF3, "unknown-0xF3" },
6195 { 0xF4, "unknown-0xF4" },
6196 { 0xF5, "unknown-0xF5" },
6197 { 0xF6, "unknown-0xF6" },
6198 { 0xF7, "unknown-0xF7" },
6199 { 0xF8, "unknown-0xF8" },
6200 { 0xF9, "unknown-0xF9" },
6201 { 0xFA, "unknown-0xFA" },
6202 { 0xFB, "unknown-0xFB" },
6203 { 0xFC, "unknown-0xFC" },
6204 { 0xFD, "unknown-0xFD" },
6205 { 0xFE, "unknown-0xFE" },
6206 { 0xFF, "unknown-0xFF" },
6207 { 0x00, NULL },
6209 value_string_ext smb2_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb2_cmd_vals);
6211 static const char *decode_smb2_name(guint16 cmd)
6213 if (cmd > 0xFF) return "unknown";
6214 return(smb2_cmd_vals[cmd & 0xFF].strptr);
6217 static smb2_function smb2_dissector[256] = {
6218 /* 0x00 NegotiateProtocol*/
6219 {dissect_smb2_negotiate_protocol_request,
6220 dissect_smb2_negotiate_protocol_response},
6221 /* 0x01 SessionSetup*/
6222 {dissect_smb2_session_setup_request,
6223 dissect_smb2_session_setup_response},
6224 /* 0x02 SessionLogoff*/
6225 {dissect_smb2_sessionlogoff_request,
6226 dissect_smb2_sessionlogoff_response},
6227 /* 0x03 TreeConnect*/
6228 {dissect_smb2_tree_connect_request,
6229 dissect_smb2_tree_connect_response},
6230 /* 0x04 TreeDisconnect*/
6231 {dissect_smb2_tree_disconnect_request,
6232 dissect_smb2_tree_disconnect_response},
6233 /* 0x05 Create*/
6234 {dissect_smb2_create_request,
6235 dissect_smb2_create_response},
6236 /* 0x06 Close*/
6237 {dissect_smb2_close_request,
6238 dissect_smb2_close_response},
6239 /* 0x07 Flush*/
6240 {dissect_smb2_flush_request,
6241 dissect_smb2_flush_response},
6242 /* 0x08 Read*/
6243 {dissect_smb2_read_request,
6244 dissect_smb2_read_response},
6245 /* 0x09 Writew*/
6246 {dissect_smb2_write_request,
6247 dissect_smb2_write_response},
6248 /* 0x0a Lock */
6249 {dissect_smb2_lock_request,
6250 dissect_smb2_lock_response},
6251 /* 0x0b Ioctl*/
6252 {dissect_smb2_ioctl_request,
6253 dissect_smb2_ioctl_response},
6254 /* 0x0c Cancel*/
6255 {dissect_smb2_cancel_request,
6256 NULL},
6257 /* 0x0d KeepAlive*/
6258 {dissect_smb2_keepalive_request,
6259 dissect_smb2_keepalive_response},
6260 /* 0x0e Find*/
6261 {dissect_smb2_find_request,
6262 dissect_smb2_find_response},
6263 /* 0x0f Notify*/
6264 {dissect_smb2_notify_request,
6265 dissect_smb2_notify_response},
6266 /* 0x10 GetInfo*/
6267 {dissect_smb2_getinfo_request,
6268 dissect_smb2_getinfo_response},
6269 /* 0x11 SetInfo*/
6270 {dissect_smb2_setinfo_request,
6271 dissect_smb2_setinfo_response},
6272 /* 0x12 Break */
6273 {dissect_smb2_break_request,
6274 dissect_smb2_break_response},
6275 /* 0x13 */ {NULL, NULL},
6276 /* 0x14 */ {NULL, NULL},
6277 /* 0x15 */ {NULL, NULL},
6278 /* 0x16 */ {NULL, NULL},
6279 /* 0x17 */ {NULL, NULL},
6280 /* 0x18 */ {NULL, NULL},
6281 /* 0x19 */ {NULL, NULL},
6282 /* 0x1a */ {NULL, NULL},
6283 /* 0x1b */ {NULL, NULL},
6284 /* 0x1c */ {NULL, NULL},
6285 /* 0x1d */ {NULL, NULL},
6286 /* 0x1e */ {NULL, NULL},
6287 /* 0x1f */ {NULL, NULL},
6288 /* 0x20 */ {NULL, NULL},
6289 /* 0x21 */ {NULL, NULL},
6290 /* 0x22 */ {NULL, NULL},
6291 /* 0x23 */ {NULL, NULL},
6292 /* 0x24 */ {NULL, NULL},
6293 /* 0x25 */ {NULL, NULL},
6294 /* 0x26 */ {NULL, NULL},
6295 /* 0x27 */ {NULL, NULL},
6296 /* 0x28 */ {NULL, NULL},
6297 /* 0x29 */ {NULL, NULL},
6298 /* 0x2a */ {NULL, NULL},
6299 /* 0x2b */ {NULL, NULL},
6300 /* 0x2c */ {NULL, NULL},
6301 /* 0x2d */ {NULL, NULL},
6302 /* 0x2e */ {NULL, NULL},
6303 /* 0x2f */ {NULL, NULL},
6304 /* 0x30 */ {NULL, NULL},
6305 /* 0x31 */ {NULL, NULL},
6306 /* 0x32 */ {NULL, NULL},
6307 /* 0x33 */ {NULL, NULL},
6308 /* 0x34 */ {NULL, NULL},
6309 /* 0x35 */ {NULL, NULL},
6310 /* 0x36 */ {NULL, NULL},
6311 /* 0x37 */ {NULL, NULL},
6312 /* 0x38 */ {NULL, NULL},
6313 /* 0x39 */ {NULL, NULL},
6314 /* 0x3a */ {NULL, NULL},
6315 /* 0x3b */ {NULL, NULL},
6316 /* 0x3c */ {NULL, NULL},
6317 /* 0x3d */ {NULL, NULL},
6318 /* 0x3e */ {NULL, NULL},
6319 /* 0x3f */ {NULL, NULL},
6320 /* 0x40 */ {NULL, NULL},
6321 /* 0x41 */ {NULL, NULL},
6322 /* 0x42 */ {NULL, NULL},
6323 /* 0x43 */ {NULL, NULL},
6324 /* 0x44 */ {NULL, NULL},
6325 /* 0x45 */ {NULL, NULL},
6326 /* 0x46 */ {NULL, NULL},
6327 /* 0x47 */ {NULL, NULL},
6328 /* 0x48 */ {NULL, NULL},
6329 /* 0x49 */ {NULL, NULL},
6330 /* 0x4a */ {NULL, NULL},
6331 /* 0x4b */ {NULL, NULL},
6332 /* 0x4c */ {NULL, NULL},
6333 /* 0x4d */ {NULL, NULL},
6334 /* 0x4e */ {NULL, NULL},
6335 /* 0x4f */ {NULL, NULL},
6336 /* 0x50 */ {NULL, NULL},
6337 /* 0x51 */ {NULL, NULL},
6338 /* 0x52 */ {NULL, NULL},
6339 /* 0x53 */ {NULL, NULL},
6340 /* 0x54 */ {NULL, NULL},
6341 /* 0x55 */ {NULL, NULL},
6342 /* 0x56 */ {NULL, NULL},
6343 /* 0x57 */ {NULL, NULL},
6344 /* 0x58 */ {NULL, NULL},
6345 /* 0x59 */ {NULL, NULL},
6346 /* 0x5a */ {NULL, NULL},
6347 /* 0x5b */ {NULL, NULL},
6348 /* 0x5c */ {NULL, NULL},
6349 /* 0x5d */ {NULL, NULL},
6350 /* 0x5e */ {NULL, NULL},
6351 /* 0x5f */ {NULL, NULL},
6352 /* 0x60 */ {NULL, NULL},
6353 /* 0x61 */ {NULL, NULL},
6354 /* 0x62 */ {NULL, NULL},
6355 /* 0x63 */ {NULL, NULL},
6356 /* 0x64 */ {NULL, NULL},
6357 /* 0x65 */ {NULL, NULL},
6358 /* 0x66 */ {NULL, NULL},
6359 /* 0x67 */ {NULL, NULL},
6360 /* 0x68 */ {NULL, NULL},
6361 /* 0x69 */ {NULL, NULL},
6362 /* 0x6a */ {NULL, NULL},
6363 /* 0x6b */ {NULL, NULL},
6364 /* 0x6c */ {NULL, NULL},
6365 /* 0x6d */ {NULL, NULL},
6366 /* 0x6e */ {NULL, NULL},
6367 /* 0x6f */ {NULL, NULL},
6368 /* 0x70 */ {NULL, NULL},
6369 /* 0x71 */ {NULL, NULL},
6370 /* 0x72 */ {NULL, NULL},
6371 /* 0x73 */ {NULL, NULL},
6372 /* 0x74 */ {NULL, NULL},
6373 /* 0x75 */ {NULL, NULL},
6374 /* 0x76 */ {NULL, NULL},
6375 /* 0x77 */ {NULL, NULL},
6376 /* 0x78 */ {NULL, NULL},
6377 /* 0x79 */ {NULL, NULL},
6378 /* 0x7a */ {NULL, NULL},
6379 /* 0x7b */ {NULL, NULL},
6380 /* 0x7c */ {NULL, NULL},
6381 /* 0x7d */ {NULL, NULL},
6382 /* 0x7e */ {NULL, NULL},
6383 /* 0x7f */ {NULL, NULL},
6384 /* 0x80 */ {NULL, NULL},
6385 /* 0x81 */ {NULL, NULL},
6386 /* 0x82 */ {NULL, NULL},
6387 /* 0x83 */ {NULL, NULL},
6388 /* 0x84 */ {NULL, NULL},
6389 /* 0x85 */ {NULL, NULL},
6390 /* 0x86 */ {NULL, NULL},
6391 /* 0x87 */ {NULL, NULL},
6392 /* 0x88 */ {NULL, NULL},
6393 /* 0x89 */ {NULL, NULL},
6394 /* 0x8a */ {NULL, NULL},
6395 /* 0x8b */ {NULL, NULL},
6396 /* 0x8c */ {NULL, NULL},
6397 /* 0x8d */ {NULL, NULL},
6398 /* 0x8e */ {NULL, NULL},
6399 /* 0x8f */ {NULL, NULL},
6400 /* 0x90 */ {NULL, NULL},
6401 /* 0x91 */ {NULL, NULL},
6402 /* 0x92 */ {NULL, NULL},
6403 /* 0x93 */ {NULL, NULL},
6404 /* 0x94 */ {NULL, NULL},
6405 /* 0x95 */ {NULL, NULL},
6406 /* 0x96 */ {NULL, NULL},
6407 /* 0x97 */ {NULL, NULL},
6408 /* 0x98 */ {NULL, NULL},
6409 /* 0x99 */ {NULL, NULL},
6410 /* 0x9a */ {NULL, NULL},
6411 /* 0x9b */ {NULL, NULL},
6412 /* 0x9c */ {NULL, NULL},
6413 /* 0x9d */ {NULL, NULL},
6414 /* 0x9e */ {NULL, NULL},
6415 /* 0x9f */ {NULL, NULL},
6416 /* 0xa0 */ {NULL, NULL},
6417 /* 0xa1 */ {NULL, NULL},
6418 /* 0xa2 */ {NULL, NULL},
6419 /* 0xa3 */ {NULL, NULL},
6420 /* 0xa4 */ {NULL, NULL},
6421 /* 0xa5 */ {NULL, NULL},
6422 /* 0xa6 */ {NULL, NULL},
6423 /* 0xa7 */ {NULL, NULL},
6424 /* 0xa8 */ {NULL, NULL},
6425 /* 0xa9 */ {NULL, NULL},
6426 /* 0xaa */ {NULL, NULL},
6427 /* 0xab */ {NULL, NULL},
6428 /* 0xac */ {NULL, NULL},
6429 /* 0xad */ {NULL, NULL},
6430 /* 0xae */ {NULL, NULL},
6431 /* 0xaf */ {NULL, NULL},
6432 /* 0xb0 */ {NULL, NULL},
6433 /* 0xb1 */ {NULL, NULL},
6434 /* 0xb2 */ {NULL, NULL},
6435 /* 0xb3 */ {NULL, NULL},
6436 /* 0xb4 */ {NULL, NULL},
6437 /* 0xb5 */ {NULL, NULL},
6438 /* 0xb6 */ {NULL, NULL},
6439 /* 0xb7 */ {NULL, NULL},
6440 /* 0xb8 */ {NULL, NULL},
6441 /* 0xb9 */ {NULL, NULL},
6442 /* 0xba */ {NULL, NULL},
6443 /* 0xbb */ {NULL, NULL},
6444 /* 0xbc */ {NULL, NULL},
6445 /* 0xbd */ {NULL, NULL},
6446 /* 0xbe */ {NULL, NULL},
6447 /* 0xbf */ {NULL, NULL},
6448 /* 0xc0 */ {NULL, NULL},
6449 /* 0xc1 */ {NULL, NULL},
6450 /* 0xc2 */ {NULL, NULL},
6451 /* 0xc3 */ {NULL, NULL},
6452 /* 0xc4 */ {NULL, NULL},
6453 /* 0xc5 */ {NULL, NULL},
6454 /* 0xc6 */ {NULL, NULL},
6455 /* 0xc7 */ {NULL, NULL},
6456 /* 0xc8 */ {NULL, NULL},
6457 /* 0xc9 */ {NULL, NULL},
6458 /* 0xca */ {NULL, NULL},
6459 /* 0xcb */ {NULL, NULL},
6460 /* 0xcc */ {NULL, NULL},
6461 /* 0xcd */ {NULL, NULL},
6462 /* 0xce */ {NULL, NULL},
6463 /* 0xcf */ {NULL, NULL},
6464 /* 0xd0 */ {NULL, NULL},
6465 /* 0xd1 */ {NULL, NULL},
6466 /* 0xd2 */ {NULL, NULL},
6467 /* 0xd3 */ {NULL, NULL},
6468 /* 0xd4 */ {NULL, NULL},
6469 /* 0xd5 */ {NULL, NULL},
6470 /* 0xd6 */ {NULL, NULL},
6471 /* 0xd7 */ {NULL, NULL},
6472 /* 0xd8 */ {NULL, NULL},
6473 /* 0xd9 */ {NULL, NULL},
6474 /* 0xda */ {NULL, NULL},
6475 /* 0xdb */ {NULL, NULL},
6476 /* 0xdc */ {NULL, NULL},
6477 /* 0xdd */ {NULL, NULL},
6478 /* 0xde */ {NULL, NULL},
6479 /* 0xdf */ {NULL, NULL},
6480 /* 0xe0 */ {NULL, NULL},
6481 /* 0xe1 */ {NULL, NULL},
6482 /* 0xe2 */ {NULL, NULL},
6483 /* 0xe3 */ {NULL, NULL},
6484 /* 0xe4 */ {NULL, NULL},
6485 /* 0xe5 */ {NULL, NULL},
6486 /* 0xe6 */ {NULL, NULL},
6487 /* 0xe7 */ {NULL, NULL},
6488 /* 0xe8 */ {NULL, NULL},
6489 /* 0xe9 */ {NULL, NULL},
6490 /* 0xea */ {NULL, NULL},
6491 /* 0xeb */ {NULL, NULL},
6492 /* 0xec */ {NULL, NULL},
6493 /* 0xed */ {NULL, NULL},
6494 /* 0xee */ {NULL, NULL},
6495 /* 0xef */ {NULL, NULL},
6496 /* 0xf0 */ {NULL, NULL},
6497 /* 0xf1 */ {NULL, NULL},
6498 /* 0xf2 */ {NULL, NULL},
6499 /* 0xf3 */ {NULL, NULL},
6500 /* 0xf4 */ {NULL, NULL},
6501 /* 0xf5 */ {NULL, NULL},
6502 /* 0xf6 */ {NULL, NULL},
6503 /* 0xf7 */ {NULL, NULL},
6504 /* 0xf8 */ {NULL, NULL},
6505 /* 0xf9 */ {NULL, NULL},
6506 /* 0xfa */ {NULL, NULL},
6507 /* 0xfb */ {NULL, NULL},
6508 /* 0xfc */ {NULL, NULL},
6509 /* 0xfd */ {NULL, NULL},
6510 /* 0xfe */ {NULL, NULL},
6511 /* 0xff */ {NULL, NULL},
6515 #define ENC_ALG_aes128_ccm 0x0001
6517 static int
6518 dissect_smb2_transform_header(packet_info *pinfo _U_, proto_tree *tree,
6519 tvbuff_t *tvb, int offset,
6520 smb2_transform_info_t *sti,
6521 tvbuff_t **enc_tvb, tvbuff_t **plain_tvb)
6523 proto_item *sesid_item = NULL;
6524 proto_tree *sesid_tree = NULL;
6525 smb2_sesid_info_t sesid_key;
6526 int sesid_offset;
6527 guint8 *plain_data = NULL;
6528 #ifdef HAVE_LIBGCRYPT
6529 guint8 *decryption_key = NULL;
6530 #endif
6531 proto_item *item;
6533 static const int *sf_fields[] = {
6534 &hf_smb2_encryption_aes128_ccm,
6535 NULL
6538 *enc_tvb = NULL;
6539 *plain_tvb = NULL;
6541 /* signature */
6542 proto_tree_add_item(tree, hf_smb2_transform_signature, tvb, offset, 16, ENC_NA);
6543 offset += 16;
6545 /* nonce */
6546 proto_tree_add_item(tree, hf_smb2_transform_nonce, tvb, offset, 16, ENC_NA);
6547 tvb_memcpy(tvb, sti->nonce, offset, 16);
6548 offset += 16;
6550 /* size */
6551 proto_tree_add_item(tree, hf_smb2_transform_msg_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6552 sti->size = tvb_get_letohl(tvb, offset);
6553 offset += 4;
6555 /* reserved */
6556 proto_tree_add_item(tree, hf_smb2_transform_reserved, tvb, offset, 2, ENC_NA);
6557 offset += 2;
6559 /* enc algorithm */
6560 proto_tree_add_bitmask(tree, tvb, offset, hf_smb2_transform_enc_alg, ett_smb2_transform_enc_alg, sf_fields, ENC_LITTLE_ENDIAN);
6561 sti->alg = tvb_get_letohs(tvb, offset);
6562 offset += 2;
6564 /* session ID */
6565 sesid_offset = offset;
6566 sti->sesid = tvb_get_letoh64(tvb, offset);
6567 sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6568 if (tree) {
6569 sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
6571 offset += 8;
6573 /* now we need to first lookup the uid session */
6574 sesid_key.sesid = sti->sesid;
6575 sti->session = (smb2_sesid_info_t *)g_hash_table_lookup(sti->conv->sesids, &sesid_key);
6577 if (sti->session != NULL && sti->session->auth_frame != (guint32)-1) {
6578 item = proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, sti->session->acct_name);
6579 PROTO_ITEM_SET_GENERATED(item);
6580 proto_item_append_text(sesid_item, " Acct:%s", sti->session->acct_name);
6582 item = proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, sti->session->domain_name);
6583 PROTO_ITEM_SET_GENERATED(item);
6584 proto_item_append_text(sesid_item, " Domain:%s", sti->session->domain_name);
6586 item = proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, sti->session->host_name);
6587 PROTO_ITEM_SET_GENERATED(item);
6588 proto_item_append_text(sesid_item, " Host:%s", sti->session->host_name);
6590 item = proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, sti->session->auth_frame);
6591 PROTO_ITEM_SET_GENERATED(item);
6594 #ifdef HAVE_LIBGCRYPT
6595 if (sti->session != NULL && sti->alg == ENC_ALG_aes128_ccm) {
6596 if (pinfo->destport == sti->session->server_port) {
6597 decryption_key = sti->session->server_decryption_key;
6598 } else {
6599 decryption_key = sti->session->client_decryption_key;
6602 if (memcmp(decryption_key, zeros, 16) == 0) {
6603 decryption_key = NULL;
6607 if (decryption_key != NULL) {
6608 gcry_cipher_hd_t cipher_hd = NULL;
6609 guint8 A_1[16] = {
6610 3, 0, 0, 0, 0, 0, 0, 0,
6611 0, 0, 0, 0, 0, 0, 0, 1
6614 memcpy(&A_1[1], sti->nonce, 15 - 4);
6616 plain_data = (guint8 *)tvb_memdup(NULL, tvb, offset, sti->size);
6618 /* Open the cipher. */
6619 if (gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0)) {
6620 g_free(plain_data);
6621 plain_data = NULL;
6622 goto done_decryption;
6625 /* Set the key and initial value. */
6626 if (gcry_cipher_setkey(cipher_hd, decryption_key, 16)) {
6627 gcry_cipher_close(cipher_hd);
6628 g_free(plain_data);
6629 plain_data = NULL;
6630 goto done_decryption;
6632 if (gcry_cipher_setctr(cipher_hd, A_1, 16)) {
6633 gcry_cipher_close(cipher_hd);
6634 g_free(plain_data);
6635 plain_data = NULL;
6636 goto done_decryption;
6639 if (gcry_cipher_encrypt(cipher_hd, plain_data, sti->size, NULL, 0)) {
6640 gcry_cipher_close(cipher_hd);
6641 g_free(plain_data);
6642 plain_data = NULL;
6643 goto done_decryption;
6646 /* Done with the cipher. */
6647 gcry_cipher_close(cipher_hd);
6649 done_decryption:
6650 #endif
6651 *enc_tvb = tvb_new_subset(tvb, offset, sti->size, sti->size);
6653 if (plain_data != NULL) {
6654 *plain_tvb = tvb_new_child_real_data(*enc_tvb, plain_data, sti->size, sti->size);
6655 tvb_set_free_cb(*plain_tvb, g_free);
6656 add_new_data_source(pinfo, *plain_tvb, "Decrypted SMB3");
6659 offset += sti->size;
6660 return offset;
6663 static int
6664 dissect_smb2_command(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
6666 int (*cmd_dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si);
6667 proto_item *cmd_item;
6668 proto_tree *cmd_tree;
6669 int old_offset = offset;
6671 cmd_item = proto_tree_add_text(tree, tvb, offset, -1,
6672 "%s %s (0x%02x)",
6673 decode_smb2_name(si->opcode),
6674 (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request",
6675 si->opcode);
6676 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb2_command);
6679 cmd_dissector = (si->flags & SMB2_FLAGS_RESPONSE)?
6680 smb2_dissector[si->opcode&0xff].response:
6681 smb2_dissector[si->opcode&0xff].request;
6682 if (cmd_dissector) {
6683 offset = (*cmd_dissector)(tvb, pinfo, cmd_tree, offset, si);
6684 } else {
6685 proto_tree_add_item(cmd_tree, hf_smb2_unknown, tvb, offset, -1, ENC_NA);
6686 offset = tvb_length(tvb);
6689 proto_item_set_len(cmd_item, offset-old_offset);
6691 return offset;
6694 static int
6695 dissect_smb2_tid_sesid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
6697 proto_item *tid_item = NULL;
6698 proto_tree *tid_tree = NULL;
6699 smb2_tid_info_t tid_key;
6700 int tid_offset = 0;
6701 proto_item *sesid_item = NULL;
6702 proto_tree *sesid_tree = NULL;
6703 smb2_sesid_info_t sesid_key;
6704 int sesid_offset;
6705 proto_item *item;
6708 if (si->flags&SMB2_FLAGS_ASYNC_CMD) {
6709 proto_tree_add_item(tree, hf_smb2_aid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6710 offset += 8;
6711 } else {
6712 /* Process ID */
6713 proto_tree_add_item(tree, hf_smb2_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6714 offset += 4;
6716 /* Tree ID */
6717 tid_offset = offset;
6718 si->tid = tvb_get_letohl(tvb, offset);
6719 tid_item = proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6720 if (tree) {
6721 tid_tree = proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
6723 offset += 4;
6726 /* Session ID */
6727 sesid_offset = offset;
6728 si->sesid = tvb_get_letoh64(tvb, offset);
6729 sesid_item = proto_tree_add_item(tree, hf_smb2_sesid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6730 if (tree) {
6731 sesid_tree = proto_item_add_subtree(sesid_item, ett_smb2_sesid_tree);
6733 offset += 8;
6735 /* now we need to first lookup the uid session */
6736 sesid_key.sesid = si->sesid;
6737 si->session = (smb2_sesid_info_t *)g_hash_table_lookup(si->conv->sesids, &sesid_key);
6738 if (!si->session) {
6739 if (si->opcode != 0x03) return offset;
6741 /* if we come to a session that is unknown, and the operation is
6742 * a tree connect, we create a dummy sessison, so we can hang the
6743 * tree data on it
6745 si->session = wmem_new(wmem_file_scope(), smb2_sesid_info_t);
6746 si->session->sesid = si->sesid;
6747 si->session->acct_name = NULL;
6748 si->session->domain_name = NULL;
6749 si->session->host_name = NULL;
6750 si->session->auth_frame = (guint32)-1;
6751 si->session->tids = g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
6752 g_hash_table_insert(si->conv->sesids, si->session, si->session);
6754 return offset;
6757 if (si->session->auth_frame != (guint32)-1) {
6758 item = proto_tree_add_string(sesid_tree, hf_smb2_acct_name, tvb, sesid_offset, 0, si->session->acct_name);
6759 PROTO_ITEM_SET_GENERATED(item);
6760 proto_item_append_text(sesid_item, " Acct:%s", si->session->acct_name);
6762 item = proto_tree_add_string(sesid_tree, hf_smb2_domain_name, tvb, sesid_offset, 0, si->session->domain_name);
6763 PROTO_ITEM_SET_GENERATED(item);
6764 proto_item_append_text(sesid_item, " Domain:%s", si->session->domain_name);
6766 item = proto_tree_add_string(sesid_tree, hf_smb2_host_name, tvb, sesid_offset, 0, si->session->host_name);
6767 PROTO_ITEM_SET_GENERATED(item);
6768 proto_item_append_text(sesid_item, " Host:%s", si->session->host_name);
6770 item = proto_tree_add_uint(sesid_tree, hf_smb2_auth_frame, tvb, sesid_offset, 0, si->session->auth_frame);
6771 PROTO_ITEM_SET_GENERATED(item);
6774 if (!(si->flags&SMB2_FLAGS_ASYNC_CMD)) {
6775 /* see if we can find the name for this tid */
6776 tid_key.tid = si->tid;
6777 si->tree = (smb2_tid_info_t *)g_hash_table_lookup(si->session->tids, &tid_key);
6778 if (!si->tree) return offset;
6780 item = proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
6781 PROTO_ITEM_SET_GENERATED(item);
6782 proto_item_append_text(tid_item, " %s", si->tree->name);
6784 item = proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
6785 PROTO_ITEM_SET_GENERATED(item);
6787 item = proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
6788 PROTO_ITEM_SET_GENERATED(item);
6791 return offset;
6794 static int
6795 dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
6797 gboolean smb2_transform_header = FALSE;
6798 proto_item *msg_id_item;
6799 proto_item *item = NULL;
6800 proto_tree *tree = NULL;
6801 proto_item *header_item = NULL;
6802 proto_tree *header_tree = NULL;
6803 proto_item *flags_item = NULL;
6804 proto_tree *flags_tree = NULL;
6805 int offset = 0;
6806 int chain_offset = 0;
6807 char* label = smb_header_label;
6808 conversation_t *conversation;
6809 smb2_saved_info_t *ssi = NULL, ssi_key;
6810 smb2_info_t *si;
6811 smb2_transform_info_t *sti;
6812 char *fid_name;
6813 guint32 open_frame,close_frame;
6814 smb2_eo_file_info_t *eo_file_info;
6815 e_ctx_hnd *policy_hnd_hashtablekey;
6816 void *private_data_bak;
6818 sti = wmem_new(wmem_packet_scope(), smb2_transform_info_t);
6819 si = wmem_new(wmem_packet_scope(), smb2_info_t);
6820 si->eo_file_info = NULL;
6821 si->conv = NULL;
6822 si->saved = NULL;
6823 si->tree = NULL;
6824 si->top_tree = parent_tree;
6826 private_data_bak = pinfo->private_data;
6827 pinfo->private_data = si;
6829 if (tvb_get_guint8(tvb, 0) == 0xfd) {
6830 smb2_transform_header = TRUE;
6831 label = smb_transform_header_label;
6833 /* find which conversation we are part of and get the data for that
6834 * conversation
6836 conversation = find_or_create_conversation(pinfo);
6837 si->conv = (smb2_conv_info_t *)conversation_get_proto_data(conversation, proto_smb2);
6838 if (!si->conv) {
6839 /* no smb2_into_t structure for this conversation yet,
6840 * create it.
6842 si->conv = wmem_new(wmem_file_scope(), smb2_conv_info_t);
6843 /* qqq this leaks memory for now since we never free
6844 the hashtables */
6845 si->conv->matched = g_hash_table_new(smb2_saved_info_hash_matched,
6846 smb2_saved_info_equal_matched);
6847 si->conv->unmatched = g_hash_table_new(smb2_saved_info_hash_unmatched,
6848 smb2_saved_info_equal_unmatched);
6849 si->conv->sesids = g_hash_table_new(smb2_sesid_info_hash,
6850 smb2_sesid_info_equal);
6851 si->conv->files = g_hash_table_new(smb2_eo_files_hash,smb2_eo_files_equal);
6853 /* Bit of a hack to avoid leaking the hash tables - register a
6854 * callback to free them. Ideally wmem would implement a simple
6855 * hash table so we wouldn't have to do this. */
6856 wmem_register_callback(wmem_file_scope(), smb2_conv_destroy,
6857 si->conv);
6859 conversation_add_proto_data(conversation, proto_smb2, si->conv);
6862 sti->conv = si->conv;
6864 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB2");
6865 if (first_in_chain) {
6866 /* first packet */
6867 col_clear(pinfo->cinfo, COL_INFO);
6868 } else {
6869 col_append_str(pinfo->cinfo, COL_INFO, ";");
6872 if (parent_tree) {
6873 item = proto_tree_add_item(parent_tree, proto_smb2, tvb, offset,
6874 -1, ENC_NA);
6875 tree = proto_item_add_subtree(item, ett_smb2);
6879 if (tree) {
6880 header_item = proto_tree_add_text(tree, tvb, offset, -1, "%s", label);
6881 header_tree = proto_item_add_subtree(header_item, ett_smb2_header);
6884 /* Decode the header */
6886 if (!smb2_transform_header) {
6887 /* SMB2 marker */
6888 proto_tree_add_text(header_tree, tvb, offset, 4, "Server Component: SMB2");
6889 offset += 4;
6891 /* we need the flags before we know how to parse the credits field */
6892 si->flags = tvb_get_letohl(tvb, offset+12);
6894 /* header length */
6895 proto_tree_add_item(header_tree, hf_smb2_header_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6896 offset += 2;
6898 /* credit charge (previously "epoch" (unused) which has been deprecated as of "SMB 2.1") */
6899 proto_tree_add_item(header_tree, hf_smb2_credit_charge, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6900 offset += 2;
6902 /* Status Code */
6903 if (si->flags & SMB2_FLAGS_RESPONSE) {
6904 si->status = tvb_get_letohl(tvb, offset);
6905 proto_tree_add_item(header_tree, hf_smb2_nt_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6906 offset += 4;
6907 } else {
6908 si->status = 0;
6909 proto_tree_add_item(header_tree, hf_smb2_channel_sequence, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6910 offset += 2;
6911 proto_tree_add_item(header_tree, hf_smb2_reserved, tvb, offset, 2, ENC_NA);
6912 offset += 2;
6915 /* opcode */
6916 si->opcode = tvb_get_letohs(tvb, offset);
6917 proto_tree_add_item(header_tree, hf_smb2_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6918 offset += 2;
6920 /* credits */
6921 if (si->flags & SMB2_FLAGS_RESPONSE) {
6922 proto_tree_add_item(header_tree, hf_smb2_credits_granted, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6923 } else {
6924 proto_tree_add_item(header_tree, hf_smb2_credits_requested, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6926 offset += 2;
6928 /* flags */
6929 if (header_tree) {
6930 flags_item = proto_tree_add_uint_format(header_tree, hf_smb2_flags, tvb, offset, 4, si->flags,
6931 "Flags: 0x%08x", si->flags);
6932 flags_tree = proto_item_add_subtree(flags_item, ett_smb2_flags);
6934 proto_tree_add_boolean(flags_tree, hf_smb2_flags_response, tvb, offset, 4, si->flags);
6935 proto_tree_add_boolean(flags_tree, hf_smb2_flags_async_cmd, tvb, offset, 4, si->flags);
6936 proto_tree_add_boolean(flags_tree, hf_smb2_flags_chained, tvb, offset, 4, si->flags);
6937 proto_tree_add_boolean(flags_tree, hf_smb2_flags_signature, tvb, offset, 4, si->flags);
6938 proto_tree_add_boolean(flags_tree, hf_smb2_flags_dfs_op, tvb, offset, 4, si->flags);
6939 proto_tree_add_boolean(flags_tree, hf_smb2_flags_replay_operation, tvb, offset, 4, si->flags);
6942 offset += 4;
6944 /* Next Command */
6945 chain_offset = tvb_get_letohl(tvb, offset);
6946 proto_tree_add_item(header_tree, hf_smb2_chain_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
6947 offset += 4;
6949 /* Message ID */
6950 si->msg_id = tvb_get_letoh64(tvb, offset);
6951 ssi_key.msg_id = si->msg_id;
6952 msg_id_item = proto_tree_add_item(header_tree, hf_smb2_msg_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
6953 if (msg_id_item && (si->msg_id == -1)) {
6954 proto_item_append_text(msg_id_item, " (unsolicited response)");
6956 offset += 8;
6958 /* Tree ID and Session ID */
6959 offset = dissect_smb2_tid_sesid(pinfo, header_tree, tvb, offset, si);
6961 /* Signature */
6962 proto_tree_add_item(header_tree, hf_smb2_signature, tvb, offset, 16, ENC_NA);
6963 offset += 16;
6965 proto_item_set_len(header_item, offset);
6968 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
6969 decode_smb2_name(si->opcode),
6970 (si->flags & SMB2_FLAGS_RESPONSE)?"Response":"Request");
6971 if (si->status) {
6972 col_append_fstr(
6973 pinfo->cinfo, COL_INFO, ", Error: %s",
6974 val_to_str(si->status, NT_errors,
6975 "Unknown (0x%08X)"));
6979 if (!pinfo->fd->flags.visited) {
6980 /* see if we can find this msg_id in the unmatched table */
6981 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
6983 if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
6984 /* This is a request */
6985 if (ssi) {
6986 /* this is a request and we already found
6987 * an older ssi so just delete the previous
6988 * one
6990 g_hash_table_remove(si->conv->unmatched, ssi);
6991 ssi = NULL;
6994 if (!ssi) {
6995 /* no we couldnt find it, so just add it then
6996 * if was a request we are decoding
6998 ssi = wmem_new0(wmem_file_scope(), smb2_saved_info_t);
6999 ssi->msg_id = ssi_key.msg_id;
7000 ssi->frame_req = pinfo->fd->num;
7001 ssi->req_time = pinfo->fd->abs_ts;
7002 ssi->extra_info_type = SMB2_EI_NONE;
7003 g_hash_table_insert(si->conv->unmatched, ssi, ssi);
7005 } else {
7006 /* This is a response */
7007 if (ssi) {
7008 /* just set the response frame and move it to the matched table */
7009 ssi->frame_res = pinfo->fd->num;
7010 g_hash_table_remove(si->conv->unmatched, ssi);
7011 g_hash_table_insert(si->conv->matched, ssi, ssi);
7014 } else {
7015 /* see if we can find this msg_id in the matched table */
7016 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->matched, &ssi_key);
7017 /* if we couldnt find it in the matched table, it might still
7018 * be in the unmatched table
7020 if (!ssi) {
7021 ssi = (smb2_saved_info_t *)g_hash_table_lookup(si->conv->unmatched, &ssi_key);
7025 if (ssi) {
7026 if (dcerpc_fetch_polhnd_data(&ssi->policy_hnd, &fid_name, NULL, &open_frame, &close_frame, pinfo->fd->num)) {
7027 /* If needed, create the file entry and save the policy hnd */
7028 if (!si->eo_file_info) {
7029 if (si->conv) {
7030 eo_file_info = (smb2_eo_file_info_t *)g_hash_table_lookup(si->conv->files,&ssi->policy_hnd);
7031 if (!eo_file_info) { /* XXX This should never happen */
7032 /* assert(1==0); */
7033 eo_file_info = wmem_new(wmem_file_scope(), smb2_eo_file_info_t);
7034 policy_hnd_hashtablekey = wmem_new(wmem_file_scope(), e_ctx_hnd);
7035 memcpy(policy_hnd_hashtablekey, &ssi->policy_hnd, sizeof(e_ctx_hnd));
7036 eo_file_info->end_of_file=0;
7037 g_hash_table_insert(si->conv->files,policy_hnd_hashtablekey,eo_file_info);
7039 si->eo_file_info=eo_file_info;
7044 if (!(si->flags & SMB2_FLAGS_RESPONSE)) {
7045 if (ssi->frame_res) {
7046 proto_item *tmp_item;
7047 tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_in, tvb, 0, 0, ssi->frame_res);
7048 PROTO_ITEM_SET_GENERATED(tmp_item);
7050 } else {
7051 if (ssi->frame_req) {
7052 proto_item *tmp_item;
7053 nstime_t t, deltat;
7055 tmp_item = proto_tree_add_uint(header_tree, hf_smb2_response_to, tvb, 0, 0, ssi->frame_req);
7056 PROTO_ITEM_SET_GENERATED(tmp_item);
7057 t = pinfo->fd->abs_ts;
7058 nstime_delta(&deltat, &t, &ssi->req_time);
7059 tmp_item = proto_tree_add_time(header_tree, hf_smb2_time, tvb,
7060 0, 0, &deltat);
7061 PROTO_ITEM_SET_GENERATED(tmp_item);
7065 /* if we dont have ssi yet we must fake it */
7066 /*qqq*/
7067 si->saved = ssi;
7069 tap_queue_packet(smb2_tap, pinfo, si);
7071 /* Decode the payload */
7072 offset = dissect_smb2_command(pinfo, tree, tvb, offset, si);
7073 } else {
7074 proto_item *enc_item;
7075 proto_tree *enc_tree;
7076 tvbuff_t *enc_tvb = NULL;
7077 tvbuff_t *plain_tvb = NULL;
7079 /* SMB2_TRANSFORM marker */
7080 proto_tree_add_text(header_tree, tvb, offset, 4, "Server Component: SMB2_TRANSFORM");
7081 offset += 4;
7083 offset = dissect_smb2_transform_header(pinfo, header_tree, tvb, offset, sti,
7084 &enc_tvb, &plain_tvb);
7086 enc_item = proto_tree_add_text(tree, enc_tvb, 0, sti->size, "Encrypted SMB3 data");
7087 enc_tree = proto_item_add_subtree(enc_item, ett_smb2_encrypted);
7088 if (plain_tvb != NULL) {
7089 col_append_str(pinfo->cinfo, COL_INFO, "Decrypted SMB3");
7090 dissect_smb2(plain_tvb, pinfo, enc_tree, FALSE);
7091 } else {
7092 col_append_str(pinfo->cinfo, COL_INFO, "Encrypted SMB3");
7093 proto_tree_add_item(enc_tree, hf_smb2_transform_encrypted_data,
7094 enc_tvb, 0, sti->size, ENC_NA);
7097 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7098 chain_offset = offset;
7102 if (chain_offset > 0) {
7103 tvbuff_t *next_tvb;
7105 proto_item_set_len(item, chain_offset);
7107 next_tvb = tvb_new_subset_remaining(tvb, chain_offset);
7108 offset = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
7111 pinfo->private_data = private_data_bak;
7112 return offset;
7115 static gboolean
7116 dissect_smb2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
7119 /* must check that this really is a smb2 packet */
7120 if (tvb_length(tvb) < 4)
7121 return FALSE;
7123 if (((tvb_get_guint8(tvb, 0) != 0xfe) && (tvb_get_guint8(tvb, 0) != 0xfd))
7124 || (tvb_get_guint8(tvb, 1) != 'S')
7125 || (tvb_get_guint8(tvb, 2) != 'M')
7126 || (tvb_get_guint8(tvb, 3) != 'B') ) {
7127 return FALSE;
7130 dissect_smb2(tvb, pinfo, parent_tree, TRUE);
7132 return TRUE;
7135 void
7136 proto_register_smb2(void)
7138 module_t *smb2_module;
7139 static hf_register_info hf[] = {
7140 { &hf_smb2_cmd,
7141 { "Command", "smb2.cmd", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
7142 &smb2_cmd_vals_ext, 0, "SMB2 Command Opcode", HFILL }},
7143 { &hf_smb2_response_to,
7144 { "Response to", "smb2.response_to", FT_FRAMENUM, BASE_NONE,
7145 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
7146 { &hf_smb2_response_in,
7147 { "Response in", "smb2.response_in", FT_FRAMENUM, BASE_NONE,
7148 NULL, 0, "The response to this packet is in this packet", HFILL }},
7149 { &hf_smb2_time,
7150 { "Time from request", "smb2.time", FT_RELATIVE_TIME, BASE_NONE,
7151 NULL, 0, "Time between Request and Response for SMB2 cmds", HFILL }},
7152 { &hf_smb2_header_len,
7153 { "Header Length", "smb2.header_len", FT_UINT16, BASE_DEC,
7154 NULL, 0, "SMB2 Size of Header", HFILL }},
7155 { &hf_smb2_nt_status,
7156 { "NT Status", "smb2.nt_status", FT_UINT32, BASE_HEX,
7157 VALS(NT_errors), 0, "NT Status code", HFILL }},
7158 { &hf_smb2_msg_id,
7159 { "Message ID", "smb2.msg_id", FT_INT64, BASE_DEC,
7160 NULL, 0, "SMB2 Messsage ID", HFILL }},
7161 { &hf_smb2_tid,
7162 { "Tree Id", "smb2.tid", FT_UINT32, BASE_HEX,
7163 NULL, 0, "SMB2 Tree Id", HFILL }},
7164 { &hf_smb2_aid,
7165 { "Async Id", "smb2.aid", FT_UINT64, BASE_HEX,
7166 NULL, 0, "SMB2 Async Id", HFILL }},
7167 { &hf_smb2_sesid,
7168 { "Session Id", "smb2.sesid", FT_UINT64, BASE_HEX,
7169 NULL, 0, "SMB2 Session Id", HFILL }},
7170 { &hf_smb2_previous_sesid,
7171 { "Previous Session Id", "smb2.previous_sesid", FT_UINT64, BASE_HEX,
7172 NULL, 0, "SMB2 Previous Session Id", HFILL }},
7173 { &hf_smb2_chain_offset,
7174 { "Chain Offset", "smb2.chain_offset", FT_UINT32, BASE_HEX,
7175 NULL, 0, "SMB2 Chain Offset", HFILL }},
7176 { &hf_smb2_end_of_file,
7177 { "End Of File", "smb2.eof", FT_UINT64, BASE_DEC,
7178 NULL, 0, "SMB2 End Of File/File size", HFILL }},
7179 { &hf_smb2_nlinks,
7180 { "Number of Links", "smb2.nlinks", FT_UINT32, BASE_DEC,
7181 NULL, 0, "Number of links to this object", HFILL }},
7182 { &hf_smb2_file_id,
7183 { "File Id", "smb2.file_id", FT_UINT64, BASE_HEX,
7184 NULL, 0, "SMB2 File Id", HFILL }},
7185 { &hf_smb2_allocation_size,
7186 { "Allocation Size", "smb2.allocation_size", FT_UINT64, BASE_DEC,
7187 NULL, 0, "SMB2 Allocation Size for this object", HFILL }},
7188 { &hf_smb2_max_response_size,
7189 { "Max Response Size", "smb2.max_response_size", FT_UINT32, BASE_DEC,
7190 NULL, 0, "SMB2 Maximum response size", HFILL }},
7191 { &hf_smb2_setinfo_size,
7192 { "Setinfo Size", "smb2.setinfo_size", FT_UINT32, BASE_DEC,
7193 NULL, 0, "SMB2 setinfo size", HFILL }},
7194 { &hf_smb2_setinfo_offset,
7195 { "Setinfo Offset", "smb2.setinfo_offset", FT_UINT16, BASE_HEX,
7196 NULL, 0, "SMB2 setinfo offset", HFILL }},
7197 { &hf_smb2_max_ioctl_out_size,
7198 { "Max Ioctl Out Size", "smb2.max_ioctl_out_size", FT_UINT32, BASE_DEC,
7199 NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
7200 { &hf_smb2_max_ioctl_in_size,
7201 { "Max Ioctl In Size", "smb2.max_ioctl_in_size", FT_UINT32, BASE_DEC,
7202 NULL, 0, "SMB2 Maximum ioctl out size", HFILL }},
7203 { &hf_smb2_required_buffer_size,
7204 { "Required Buffer Size", "smb2.required_size", FT_UINT32, BASE_DEC,
7205 NULL, 0, "SMB2 required buffer size", HFILL }},
7206 { &hf_smb2_pid,
7207 { "Process Id", "smb2.pid", FT_UINT32, BASE_HEX,
7208 NULL, 0, "SMB2 Process Id", HFILL }},
7210 /* SMB2 header flags */
7211 { &hf_smb2_flags,
7212 { "Flags", "smb2.flags", FT_UINT32, BASE_HEX,
7213 NULL, 0, "SMB2 flags", HFILL }},
7214 { &hf_smb2_flags_response,
7215 { "Response", "smb2.flags.response", FT_BOOLEAN, 32,
7216 TFS(&tfs_flags_response), SMB2_FLAGS_RESPONSE, "Whether this is an SMB2 Request or Response", HFILL }},
7217 { &hf_smb2_flags_async_cmd,
7218 { "Async command", "smb2.flags.async", FT_BOOLEAN, 32,
7219 TFS(&tfs_flags_async_cmd), SMB2_FLAGS_ASYNC_CMD, NULL, HFILL }},
7220 { &hf_smb2_flags_dfs_op,
7221 { "DFS operation", "smb2.flags.dfs", FT_BOOLEAN, 32,
7222 TFS(&tfs_flags_dfs_op), SMB2_FLAGS_DFS_OP, NULL, HFILL }},
7223 { &hf_smb2_flags_chained,
7224 { "Chained", "smb2.flags.chained", FT_BOOLEAN, 32,
7225 TFS(&tfs_flags_chained), SMB2_FLAGS_CHAINED, "Whether the pdu continues a chain or not", HFILL }},
7226 { &hf_smb2_flags_signature,
7227 { "Signing", "smb2.flags.signature", FT_BOOLEAN, 32,
7228 TFS(&tfs_flags_signature), SMB2_FLAGS_SIGNATURE, "Whether the pdu is signed or not", HFILL }},
7229 { &hf_smb2_flags_replay_operation,
7230 { "Replay operation", "smb2.flags.replay", FT_BOOLEAN, 32,
7231 TFS(&tfs_flags_replay_operation), SMB2_FLAGS_REPLAY_OPERATION, "Whether this is a replay operation", HFILL }},
7233 { &hf_smb2_tree,
7234 { "Tree", "smb2.tree", FT_STRING, BASE_NONE,
7235 NULL, 0, "Name of the Tree/Share", HFILL }},
7236 { &hf_smb2_filename,
7237 { "Filename", "smb2.filename", FT_STRING, BASE_NONE,
7238 NULL, 0, "Name of the file", HFILL }},
7239 { &hf_smb2_filename_len,
7240 { "Filename Length", "smb2.filename.len", FT_UINT32, BASE_DEC,
7241 NULL, 0, "Length of the file name", HFILL }},
7243 { &hf_smb2_data_offset,
7244 { "Data Offset", "smb2.data_offset", FT_UINT16, BASE_HEX,
7245 NULL, 0, "Offset to data", HFILL }},
7247 { &hf_smb2_find_info_level,
7248 { "Info Level", "smb2.find.infolevel", FT_UINT32, BASE_DEC,
7249 VALS(smb2_find_info_levels), 0, "Find_Info Infolevel", HFILL }},
7250 { &hf_smb2_find_flags,
7251 { "Find Flags", "smb2.find.flags", FT_UINT8, BASE_HEX,
7252 NULL, 0, NULL, HFILL }},
7254 { &hf_smb2_find_pattern,
7255 { "Search Pattern", "smb2.find.pattern", FT_STRING, BASE_NONE,
7256 NULL, 0, "Find pattern", HFILL }},
7258 { &hf_smb2_find_info_blob,
7259 { "Info", "smb2.find.info_blob", FT_BYTES, BASE_NONE,
7260 NULL, 0, "Find Info", HFILL }},
7262 { &hf_smb2_ea_size,
7263 { "EA Size", "smb2.ea_size", FT_UINT32, BASE_DEC,
7264 NULL, 0, "Size of EA data", HFILL }},
7266 { &hf_smb2_class,
7267 { "Class", "smb2.class", FT_UINT8, BASE_HEX,
7268 VALS(smb2_class_vals), 0, "Info class", HFILL }},
7270 { &hf_smb2_infolevel,
7271 { "InfoLevel", "smb2.infolevel", FT_UINT8, BASE_HEX,
7272 NULL, 0, NULL, HFILL }},
7274 { &hf_smb2_infolevel_file_info,
7275 { "InfoLevel", "smb2.file_info.infolevel", FT_UINT8, BASE_HEX,
7276 VALS(smb2_file_info_levels), 0, "File_Info Infolevel", HFILL }},
7278 { &hf_smb2_infolevel_fs_info,
7279 { "InfoLevel", "smb2.fs_info.infolevel", FT_UINT8, BASE_HEX,
7280 VALS(smb2_fs_info_levels), 0, "Fs_Info Infolevel", HFILL }},
7282 { &hf_smb2_infolevel_sec_info,
7283 { "InfoLevel", "smb2.sec_info.infolevel", FT_UINT8, BASE_HEX,
7284 VALS(smb2_sec_info_levels), 0, "Sec_Info Infolevel", HFILL }},
7286 { &hf_smb2_write_length,
7287 { "Write Length", "smb2.write_length", FT_UINT32, BASE_DEC,
7288 NULL, 0, "Amount of data to write", HFILL }},
7290 { &hf_smb2_read_length,
7291 { "Read Length", "smb2.read_length", FT_UINT32, BASE_DEC,
7292 NULL, 0, "Amount of data to read", HFILL }},
7294 { &hf_smb2_read_remaining,
7295 { "Read Remaining", "smb2.read_remaining", FT_UINT32, BASE_DEC,
7296 NULL, 0, NULL, HFILL }},
7298 { &hf_smb2_create_flags,
7299 { "Create Flags", "smb2.create_flags", FT_UINT64, BASE_HEX,
7300 NULL, 0, NULL, HFILL }},
7302 { &hf_smb2_file_offset,
7303 { "File Offset", "smb2.file_offset", FT_UINT64, BASE_DEC,
7304 NULL, 0, NULL, HFILL }},
7306 { &hf_smb2_security_blob,
7307 { "Security Blob", "smb2.security_blob", FT_BYTES, BASE_NONE,
7308 NULL, 0, NULL, HFILL }},
7310 { &hf_smb2_ioctl_out_data,
7311 { "Out Data", "smb2.ioctl.out", FT_NONE, BASE_NONE,
7312 NULL, 0, "Ioctl Out", HFILL }},
7314 { &hf_smb2_ioctl_in_data,
7315 { "In Data", "smb2.ioctl.in", FT_NONE, BASE_NONE,
7316 NULL, 0, "Ioctl In", HFILL }},
7318 { &hf_smb2_server_guid,
7319 { "Server Guid", "smb2.server_guid", FT_GUID, BASE_NONE,
7320 NULL, 0, NULL, HFILL }},
7322 { &hf_smb2_client_guid,
7323 { "Client Guid", "smb2.client_guid", FT_GUID, BASE_NONE,
7324 NULL, 0, NULL, HFILL }},
7326 { &hf_smb2_object_id,
7327 { "ObjectId", "smb2.object_id", FT_GUID, BASE_NONE,
7328 NULL, 0, "ObjectID for this FID", HFILL }},
7330 { &hf_smb2_birth_volume_id,
7331 { "BirthVolumeId", "smb2.birth_volume_id", FT_GUID, BASE_NONE,
7332 NULL, 0, "ObjectID for the volume where this FID was originally created", HFILL }},
7334 { &hf_smb2_birth_object_id,
7335 { "BirthObjectId", "smb2.birth_object_id", FT_GUID, BASE_NONE,
7336 NULL, 0, "ObjectID for this FID when it was originally created", HFILL }},
7338 { &hf_smb2_domain_id,
7339 { "DomainId", "smb2.domain_id", FT_GUID, BASE_NONE,
7340 NULL, 0, NULL, HFILL }},
7342 { &hf_smb2_create_timestamp,
7343 { "Create", "smb2.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7344 NULL, 0, "Time when this object was created", HFILL }},
7346 { &hf_smb2_fid,
7347 { "File Id", "smb2.fid", FT_GUID, BASE_NONE,
7348 NULL, 0, "SMB2 File Id", HFILL }},
7350 { &hf_smb2_write_data,
7351 { "Write Data", "smb2.write_data", FT_BYTES, BASE_NONE,
7352 NULL, 0, "SMB2 Data to be written", HFILL }},
7354 { &hf_smb2_write_flags,
7355 { "Write Flags", "smb2.write.flags", FT_UINT32, BASE_HEX,
7356 NULL, 0, NULL, HFILL }},
7358 { &hf_smb2_write_flags_write_through,
7359 { "Write through", "smb2.write.flags.write_through", FT_BOOLEAN, 32,
7360 NULL, SMB2_WRITE_FLAG_WRITE_THROUGH, NULL, HFILL }},
7362 { &hf_smb2_write_count,
7363 { "Write Count", "smb2.write.count", FT_UINT32, BASE_DEC,
7364 NULL, 0, NULL, HFILL }},
7366 { &hf_smb2_write_remaining,
7367 { "Write Remaining", "smb2.write.remaining", FT_UINT32, BASE_DEC,
7368 NULL, 0, NULL, HFILL }},
7370 { &hf_smb2_read_data,
7371 { "Read Data", "smb2.read_data", FT_BYTES, BASE_NONE,
7372 NULL, 0, "SMB2 Data that is read", HFILL }},
7374 { &hf_smb2_last_access_timestamp,
7375 { "Last Access", "smb2.last_access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7376 NULL, 0, "Time when this object was last accessed", HFILL }},
7378 { &hf_smb2_last_write_timestamp,
7379 { "Last Write", "smb2.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7380 NULL, 0, "Time when this object was last written to", HFILL }},
7382 { &hf_smb2_last_change_timestamp,
7383 { "Last Change", "smb2.last_change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7384 NULL, 0, "Time when this object was last changed", HFILL }},
7386 { &hf_smb2_file_all_info,
7387 { "SMB2_FILE_ALL_INFO", "smb2.file_all_info", FT_NONE, BASE_NONE,
7388 NULL, 0, "SMB2_FILE_ALL_INFO structure", HFILL }},
7390 { &hf_smb2_file_allocation_info,
7391 { "SMB2_FILE_ALLOCATION_INFO", "smb2.file_allocation_info", FT_NONE, BASE_NONE,
7392 NULL, 0, "SMB2_FILE_ALLOCATION_INFO structure", HFILL }},
7394 { &hf_smb2_file_endoffile_info,
7395 { "SMB2_FILE_ENDOFFILE_INFO", "smb2.file_endoffile_info", FT_NONE, BASE_NONE,
7396 NULL, 0, "SMB2_FILE_ENDOFFILE_INFO structure", HFILL }},
7398 { &hf_smb2_file_alternate_name_info,
7399 { "SMB2_FILE_ALTERNATE_NAME_INFO", "smb2.file_alternate_name_info", FT_NONE, BASE_NONE,
7400 NULL, 0, "SMB2_FILE_ALTERNATE_NAME_INFO structure", HFILL }},
7402 { &hf_smb2_file_stream_info,
7403 { "SMB2_FILE_STREAM_INFO", "smb2.file_stream_info", FT_NONE, BASE_NONE,
7404 NULL, 0, "SMB2_FILE_STREAM_INFO structure", HFILL }},
7406 { &hf_smb2_file_pipe_info,
7407 { "SMB2_FILE_PIPE_INFO", "smb2.file_pipe_info", FT_NONE, BASE_NONE,
7408 NULL, 0, "SMB2_FILE_PIPE_INFO structure", HFILL }},
7410 { &hf_smb2_file_compression_info,
7411 { "SMB2_FILE_COMPRESSION_INFO", "smb2.file_compression_info", FT_NONE, BASE_NONE,
7412 NULL, 0, "SMB2_FILE_COMPRESSION_INFO structure", HFILL }},
7414 { &hf_smb2_file_basic_info,
7415 { "SMB2_FILE_BASIC_INFO", "smb2.file_basic_info", FT_NONE, BASE_NONE,
7416 NULL, 0, "SMB2_FILE_BASIC_INFO structure", HFILL }},
7418 { &hf_smb2_file_standard_info,
7419 { "SMB2_FILE_STANDARD_INFO", "smb2.file_standard_info", FT_NONE, BASE_NONE,
7420 NULL, 0, "SMB2_FILE_STANDARD_INFO structure", HFILL }},
7422 { &hf_smb2_file_internal_info,
7423 { "SMB2_FILE_INTERNAL_INFO", "smb2.file_internal_info", FT_NONE, BASE_NONE,
7424 NULL, 0, "SMB2_FILE_INTERNAL_INFO structure", HFILL }},
7426 { &hf_smb2_file_mode_info,
7427 { "SMB2_FILE_MODE_INFO", "smb2.file_mode_info", FT_NONE, BASE_NONE,
7428 NULL, 0, "SMB2_FILE_MODE_INFO structure", HFILL }},
7430 { &hf_smb2_file_alignment_info,
7431 { "SMB2_FILE_ALIGNMENT_INFO", "smb2.file_alignment_info", FT_NONE, BASE_NONE,
7432 NULL, 0, "SMB2_FILE_ALIGNMENT_INFO structure", HFILL }},
7434 { &hf_smb2_file_position_info,
7435 { "SMB2_FILE_POSITION_INFO", "smb2.file_position_info", FT_NONE, BASE_NONE,
7436 NULL, 0, "SMB2_FILE_POSITION_INFO structure", HFILL }},
7438 { &hf_smb2_file_access_info,
7439 { "SMB2_FILE_ACCESS_INFO", "smb2.file_access_info", FT_NONE, BASE_NONE,
7440 NULL, 0, "SMB2_FILE_ACCESS_INFO structure", HFILL }},
7442 { &hf_smb2_file_ea_info,
7443 { "SMB2_FILE_EA_INFO", "smb2.file_ea_info", FT_NONE, BASE_NONE,
7444 NULL, 0, "SMB2_FILE_EA_INFO structure", HFILL }},
7446 { &hf_smb2_file_network_open_info,
7447 { "SMB2_FILE_NETWORK_OPEN_INFO", "smb2.file_network_open_info", FT_NONE, BASE_NONE,
7448 NULL, 0, "SMB2_FILE_NETWORK_OPEN_INFO structure", HFILL }},
7450 { &hf_smb2_file_attribute_tag_info,
7451 { "SMB2_FILE_ATTRIBUTE_TAG_INFO", "smb2.file_attribute_tag_info", FT_NONE, BASE_NONE,
7452 NULL, 0, "SMB2_FILE_ATTRIBUTE_TAG_INFO structure", HFILL }},
7454 { &hf_smb2_file_disposition_info,
7455 { "SMB2_FILE_DISPOSITION_INFO", "smb2.file_disposition_info", FT_NONE, BASE_NONE,
7456 NULL, 0, "SMB2_FILE_DISPOSITION_INFO structure", HFILL }},
7458 { &hf_smb2_file_full_ea_info,
7459 { "SMB2_FILE_FULL_EA_INFO", "smb2.file_full_ea_info", FT_NONE, BASE_NONE,
7460 NULL, 0, "SMB2_FILE_FULL_EA_INFO structure", HFILL }},
7462 { &hf_smb2_file_rename_info,
7463 { "SMB2_FILE_RENAME_INFO", "smb2.file_rename_info", FT_NONE, BASE_NONE,
7464 NULL, 0, "SMB2_FILE_RENAME_INFO structure", HFILL }},
7466 { &hf_smb2_fs_info_01,
7467 { "SMB2_FS_INFO_01", "smb2.fs_info_01", FT_NONE, BASE_NONE,
7468 NULL, 0, "SMB2_FS_INFO_01 structure", HFILL }},
7470 { &hf_smb2_fs_info_03,
7471 { "SMB2_FS_INFO_03", "smb2.fs_info_03", FT_NONE, BASE_NONE,
7472 NULL, 0, "SMB2_FS_INFO_03 structure", HFILL }},
7474 { &hf_smb2_fs_info_04,
7475 { "SMB2_FS_INFO_04", "smb2.fs_info_04", FT_NONE, BASE_NONE,
7476 NULL, 0, "SMB2_FS_INFO_04 structure", HFILL }},
7478 { &hf_smb2_fs_info_05,
7479 { "SMB2_FS_INFO_05", "smb2.fs_info_05", FT_NONE, BASE_NONE,
7480 NULL, 0, "SMB2_FS_INFO_05 structure", HFILL }},
7482 { &hf_smb2_fs_info_06,
7483 { "SMB2_FS_INFO_06", "smb2.fs_info_06", FT_NONE, BASE_NONE,
7484 NULL, 0, "SMB2_FS_INFO_06 structure", HFILL }},
7486 { &hf_smb2_fs_info_07,
7487 { "SMB2_FS_INFO_07", "smb2.fs_info_07", FT_NONE, BASE_NONE,
7488 NULL, 0, "SMB2_FS_INFO_07 structure", HFILL }},
7490 { &hf_smb2_fs_objectid_info,
7491 { "SMB2_FS_OBJECTID_INFO", "smb2.fs_objectid_info", FT_NONE, BASE_NONE,
7492 NULL, 0, "SMB2_FS_OBJECTID_INFO structure", HFILL }},
7494 { &hf_smb2_sec_info_00,
7495 { "SMB2_SEC_INFO_00", "smb2.sec_info_00", FT_NONE, BASE_NONE,
7496 NULL, 0, "SMB2_SEC_INFO_00 structure", HFILL }},
7498 { &hf_smb2_disposition_delete_on_close,
7499 { "Delete on close", "smb2.disposition.delete_on_close", FT_BOOLEAN, 8,
7500 TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
7503 { &hf_smb2_create_disposition,
7504 { "Disposition", "smb2.create.disposition", FT_UINT32, BASE_DEC,
7505 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
7507 { &hf_smb2_create_action,
7508 { "Create Action", "smb2.create.action", FT_UINT32, BASE_DEC,
7509 VALS(oa_open_vals), 0, NULL, HFILL }},
7511 { &hf_smb2_create_rep_flags,
7512 { "Response Flags", "smb2.create.rep_flags", FT_UINT8, BASE_HEX,
7513 NULL, 0, NULL, HFILL }},
7515 { &hf_smb2_create_rep_flags_reparse_point,
7516 { "ReparsePoint", "smb2.create.rep_flags.reparse_point", FT_BOOLEAN, 8,
7517 NULL, SMB2_CREATE_REP_FLAGS_REPARSE_POINT, NULL, HFILL }},
7519 { &hf_smb2_extrainfo,
7520 { "ExtraInfo", "smb2.create.extrainfo", FT_NONE, BASE_NONE,
7521 NULL, 0, "Create ExtraInfo", HFILL }},
7523 { &hf_smb2_create_chain_offset,
7524 { "Chain Offset", "smb2.create.chain_offset", FT_UINT32, BASE_HEX,
7525 NULL, 0, "Offset to next entry in chain or 0", HFILL }},
7527 { &hf_smb2_create_chain_data,
7528 { "Data", "smb2.create.chain_data", FT_NONE, BASE_NONE,
7529 NULL, 0, "Chain Data", HFILL }},
7531 { &hf_smb2_FILE_OBJECTID_BUFFER,
7532 { "FILE_OBJECTID_BUFFER", "smb2.FILE_OBJECTID_BUFFER", FT_NONE, BASE_NONE,
7533 NULL, 0, "A FILE_OBJECTID_BUFFER structure", HFILL }},
7535 { &hf_smb2_lease_key,
7536 { "Lease Key", "smb2.lease.lease_key", FT_GUID, BASE_NONE,
7537 NULL, 0, NULL, HFILL }},
7539 { &hf_smb2_lease_state,
7540 { "Lease State", "smb2.lease.lease_state", FT_UINT32, BASE_HEX,
7541 NULL, 0, NULL, HFILL }},
7543 { &hf_smb2_lease_state_read_caching,
7544 { "Read Caching", "smb2.lease.lease_state.read_caching", FT_BOOLEAN, 32,
7545 NULL, SMB2_LEASE_STATE_READ_CACHING, NULL, HFILL }},
7547 { &hf_smb2_lease_state_handle_caching,
7548 { "Handle Caching", "smb2.lease.lease_state.handle_caching", FT_BOOLEAN, 32,
7549 NULL, SMB2_LEASE_STATE_HANDLE_CACHING, NULL, HFILL }},
7551 { &hf_smb2_lease_state_write_caching,
7552 { "Write Caching", "smb2.lease.lease_state.write_caching", FT_BOOLEAN, 32,
7553 NULL, SMB2_LEASE_STATE_WRITE_CACHING, NULL, HFILL }},
7555 { &hf_smb2_lease_flags,
7556 { "Lease Flags", "smb2.lease.lease_flags", FT_UINT32, BASE_HEX,
7557 NULL, 0, NULL, HFILL }},
7559 { &hf_smb2_lease_flags_break_ack_required,
7560 { "Break Ack Required", "smb2.lease.lease_state.break_ack_required", FT_BOOLEAN, 32,
7561 NULL, SMB2_LEASE_FLAGS_BREAK_ACK_REQUIRED, NULL, HFILL }},
7563 { &hf_smb2_lease_flags_break_in_progress,
7564 { "Break In Progress", "smb2.lease.lease_state.break_in_progress", FT_BOOLEAN, 32,
7565 NULL, SMB2_LEASE_FLAGS_BREAK_IN_PROGRESS, NULL, HFILL }},
7567 { &hf_smb2_lease_flags_parent_lease_key_set,
7568 { "Parent Lease Key Set", "smb2.lease.lease_state.parent_lease_key_set", FT_BOOLEAN, 32,
7569 NULL, SMB2_LEASE_FLAGS_PARENT_LEASE_KEY_SET, NULL, HFILL }},
7571 { &hf_smb2_lease_duration,
7572 { "Lease Duration", "smb2.lease.lease_duration", FT_UINT64, BASE_HEX,
7573 NULL, 0, NULL, HFILL }},
7575 { &hf_smb2_parent_lease_key,
7576 { "Parent Lease Key", "smb2.lease.parent_lease_key", FT_GUID, BASE_NONE,
7577 NULL, 0, NULL, HFILL }},
7579 { &hf_smb2_lease_epoch,
7580 { "Lease Epoch", "smb2.lease.lease_oplock", FT_UINT32, BASE_HEX,
7581 NULL, 0, NULL, HFILL }},
7583 { &hf_smb2_lease_break_reason,
7584 { "Lease Break Reason", "smb2.lease.lease_break_reason", FT_UINT32, BASE_HEX,
7585 NULL, 0, NULL, HFILL }},
7587 { &hf_smb2_lease_access_mask_hint,
7588 { "Access Mask Hint", "smb2.lease.access_mask_hint", FT_UINT32, BASE_HEX,
7589 NULL, 0, NULL, HFILL }},
7591 { &hf_smb2_lease_share_mask_hint,
7592 { "Share Mask Hint", "smb2.lease.share_mask_hint", FT_UINT32, BASE_HEX,
7593 NULL, 0, NULL, HFILL }},
7595 { &hf_smb2_next_offset,
7596 { "Next Offset", "smb2.next_offset", FT_UINT32, BASE_DEC,
7597 NULL, 0, "Offset to next buffer or 0", HFILL }},
7599 { &hf_smb2_current_time,
7600 { "Current Time", "smb2.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7601 NULL, 0, "Current Time at server", HFILL }},
7603 { &hf_smb2_boot_time,
7604 { "Boot Time", "smb2.boot_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7605 NULL, 0, "Boot Time at server", HFILL }},
7607 { &hf_smb2_ea_flags,
7608 { "EA Flags", "smb2.ea.flags", FT_UINT8, BASE_HEX,
7609 NULL, 0, NULL, HFILL }},
7611 { &hf_smb2_ea_name_len,
7612 { "EA Name Length", "smb2.ea.name_len", FT_UINT8, BASE_DEC,
7613 NULL, 0, NULL, HFILL }},
7615 { &hf_smb2_ea_data_len,
7616 { "EA Data Length", "smb2.ea.data_len", FT_UINT8, BASE_DEC,
7617 NULL, 0, NULL, HFILL }},
7619 { &hf_smb2_delete_pending,
7620 { "Delete Pending", "smb2.delete_pending", FT_UINT8, BASE_DEC,
7621 NULL, 0, NULL, HFILL }},
7623 { &hf_smb2_is_directory,
7624 { "Is Directory", "smb2.is_directory", FT_UINT8, BASE_DEC,
7625 NULL, 0, "Is this a directory?", HFILL }},
7627 { &hf_smb2_oplock,
7628 { "Oplock", "smb2.create.oplock", FT_UINT8, BASE_HEX,
7629 VALS(oplock_vals), 0, "Oplock type", HFILL }},
7631 { &hf_smb2_close_flags,
7632 { "Close Flags", "smb2.close.flags", FT_UINT16, BASE_HEX,
7633 NULL, 0, NULL, HFILL }},
7635 { &hf_smb2_notify_flags,
7636 { "Notify Flags", "smb2.notify.flags", FT_UINT16, BASE_HEX,
7637 NULL, 0, NULL, HFILL }},
7639 { &hf_smb2_buffer_code,
7640 { "StructureSize", "smb2.buffer_code", FT_UINT16, BASE_HEX,
7641 NULL, 0, NULL, HFILL }},
7643 { &hf_smb2_buffer_code_len,
7644 { "Fixed Part Length", "smb2.buffer_code.length", FT_UINT16, BASE_DEC,
7645 NULL, 0, "Length of fixed portion of PDU", HFILL }},
7647 { &hf_smb2_olb_length,
7648 { "Length", "smb2.olb.length", FT_UINT32, BASE_DEC,
7649 NULL, 0, "Length of the buffer", HFILL }},
7651 { &hf_smb2_olb_offset,
7652 { "Offset", "smb2.olb.offset", FT_UINT32, BASE_HEX,
7653 NULL, 0, "Offset to the buffer", HFILL }},
7655 { &hf_smb2_buffer_code_flags_dyn,
7656 { "Dynamic Part", "smb2.buffer_code.dynamic", FT_BOOLEAN, 16,
7657 NULL, 0x0001, "Whether a dynamic length blob follows", HFILL }},
7659 { &hf_smb2_ea_data,
7660 { "EA Data", "smb2.ea.data", FT_BYTES, BASE_NONE,
7661 NULL, 0, NULL, HFILL }},
7663 { &hf_smb2_ea_name,
7664 { "EA Name", "smb2.ea.name", FT_STRING, BASE_NONE,
7665 NULL, 0, NULL, HFILL }},
7667 { &hf_smb2_impersonation_level,
7668 { "Impersonation", "smb2.impersonation.level", FT_UINT32, BASE_DEC,
7669 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
7671 { &hf_smb2_ioctl_function,
7672 { "Function", "smb2.ioctl.function", FT_UINT32, BASE_HEX,
7673 VALS(smb2_ioctl_vals), 0, "Ioctl function", HFILL }},
7675 { &hf_smb2_ioctl_function_device,
7676 { "Device", "smb2.ioctl.function.device", FT_UINT32, BASE_HEX,
7677 VALS(smb2_ioctl_device_vals), 0xffff0000, "Device for Ioctl", HFILL }},
7679 { &hf_smb2_ioctl_function_access,
7680 { "Access", "smb2.ioctl.function.access", FT_UINT32, BASE_HEX,
7681 VALS(smb2_ioctl_access_vals), 0x0000c000, "Access for Ioctl", HFILL }},
7683 { &hf_smb2_ioctl_function_function,
7684 { "Function", "smb2.ioctl.function.function", FT_UINT32, BASE_HEX,
7685 NULL, 0x00003ffc, "Function for Ioctl", HFILL }},
7687 { &hf_smb2_ioctl_function_method,
7688 { "Method", "smb2.ioctl.function.method", FT_UINT32, BASE_HEX,
7689 VALS(smb2_ioctl_method_vals), 0x00000003, "Method for Ioctl", HFILL }},
7691 { &hf_smb2_fsctl_pipe_wait_timeout,
7692 { "Timeout", "smb2.fsctl.wait.timeout", FT_INT64, BASE_DEC,
7693 NULL, 0, "Wait timeout", HFILL }},
7695 { &hf_smb2_fsctl_pipe_wait_name,
7696 { "Name", "smb2.fsctl.wait.name", FT_STRING, BASE_NONE,
7697 NULL, 0, "Pipe name", HFILL }},
7699 { &hf_smb2_ioctl_resiliency_timeout,
7700 { "Timeout", "smb2.ioctl.resiliency.timeout", FT_UINT32, BASE_DEC,
7701 NULL, 0, "Resiliency timeout", HFILL }},
7703 { &hf_smb2_ioctl_resiliency_reserved,
7704 { "Reserved", "smb2.ioctl.resiliency.reserved", FT_UINT32, BASE_DEC,
7705 NULL, 0, "Resiliency reserved", HFILL }},
7707 { &hf_windows_sockaddr_family,
7708 { "Socket Family", "smb2.windows.sockaddr.family", FT_UINT16, BASE_DEC,
7709 NULL, 0, "The socket address family (on windows)", HFILL }},
7711 { &hf_windows_sockaddr_port,
7712 { "Socket Port", "smb2.windows.sockaddr.port", FT_UINT16, BASE_DEC,
7713 NULL, 0, "The socket address port", HFILL }},
7715 { &hf_windows_sockaddr_in_addr,
7716 { "Socket IPv4", "smb2.windows.sockaddr.in.addr", FT_IPv4, BASE_NONE,
7717 NULL, 0, "The IPv4 address", HFILL }},
7719 { &hf_windows_sockaddr_in6_flowinfo,
7720 { "IPv6 Flow Info", "smb2.windows.sockaddr.in6.flow_info", FT_UINT32, BASE_HEX,
7721 NULL, 0, "The socket IPv6 flow info", HFILL }},
7723 { &hf_windows_sockaddr_in6_addr,
7724 { "Socket IPv6", "smb2.windows.sockaddr.in6.addr", FT_IPv6, BASE_NONE,
7725 NULL, 0, "The IPv6 address", HFILL }},
7727 { &hf_windows_sockaddr_in6_scope_id,
7728 { "IPv6 Scope ID", "smb2.windows.sockaddr.in6.scope_id", FT_UINT32, BASE_DEC,
7729 NULL, 0, "The socket IPv6 scope id", HFILL }},
7731 { &hf_smb2_ioctl_network_interface_next_offset,
7732 { "Next Offset", "smb2.ioctl.network_interfaces.next_offset", FT_UINT32, BASE_HEX,
7733 NULL, 0, "Offset to next entry in chain or 0", HFILL }},
7735 { &hf_smb2_ioctl_network_interface_index,
7736 { "Interface Index", "smb2.ioctl.network_interfaces.index", FT_UINT32, BASE_DEC,
7737 NULL, 0, "The index of the interface", HFILL }},
7739 { &hf_smb2_ioctl_network_interface_rss_queue_count,
7740 { "RSS Queue Count", "smb2.ioctl.network_interfaces.rss_queue_count", FT_UINT32, BASE_DEC,
7741 NULL, 0, "The RSS queue count", HFILL }},
7743 { &hf_smb2_ioctl_network_interface_capabilities,
7744 { "Interface Cababilities", "smb2.ioctl.network_interfaces.capabilities", FT_UINT32, BASE_HEX,
7745 NULL, 0, "The RSS queue count", HFILL }},
7747 { &hf_smb2_ioctl_network_interface_capability_rss,
7748 { "RSS", "smb2.ioctl.network_interfaces.capabilities.rss", FT_BOOLEAN, 32,
7749 TFS(&tfs_smb2_ioctl_network_interface_capability_rss),
7750 NETWORK_INTERFACE_CAP_RSS, "If the host supports RSS", HFILL }},
7752 { &hf_smb2_ioctl_network_interface_capability_rdma,
7753 { "RDMA", "smb2.ioctl.network_interfaces.capabilities.rdma", FT_BOOLEAN, 32,
7754 TFS(&tfs_smb2_ioctl_network_interface_capability_rdma),
7755 NETWORK_INTERFACE_CAP_RDMA, "If the host supports RDMA", HFILL }},
7757 { &hf_smb2_ioctl_network_interface_link_speed,
7758 { "Link Speed", "smb2.ioctl.network_interfaces.link_speed", FT_UINT64, BASE_DEC,
7759 NULL, 0, "The link speed of the interface", HFILL }},
7761 { &hf_smb2_ioctl_shadow_copy_num_volumes,
7762 { "Num Volumes", "smb2.ioctl.shadow_copy.num_volumes", FT_UINT32, BASE_DEC,
7763 NULL, 0, "Number of shadow copy volumes", HFILL }},
7765 { &hf_smb2_ioctl_shadow_copy_num_labels,
7766 { "Num Labels", "smb2.ioctl.shadow_copy.num_labels", FT_UINT32, BASE_DEC,
7767 NULL, 0, "Number of shadow copy labels", HFILL }},
7769 { &hf_smb2_ioctl_shadow_copy_label,
7770 { "Label", "smb2.ioctl.shadow_copy.label", FT_STRING, BASE_NONE,
7771 NULL, 0, "Shadow copy label", HFILL }},
7773 { &hf_smb2_compression_format,
7774 { "Compression Format", "smb2.compression_format", FT_UINT16, BASE_DEC,
7775 VALS(compression_format_vals), 0, "Compression to use", HFILL }},
7777 { &hf_smb2_share_type,
7778 { "Share Type", "smb2.share_type", FT_UINT8, BASE_HEX,
7779 VALS(smb2_share_type_vals), 0, "Type of share", HFILL }},
7781 { &hf_smb2_credit_charge,
7782 { "Credit Charge", "smb2.credit.charge", FT_UINT16, BASE_DEC,
7783 NULL, 0, NULL, HFILL }},
7785 { &hf_smb2_credits_requested,
7786 { "Credits requested", "smb2.credits.requested", FT_UINT16, BASE_DEC,
7787 NULL, 0, NULL, HFILL }},
7789 { &hf_smb2_credits_granted,
7790 { "Credits granted", "smb2.credits.granted", FT_UINT16, BASE_DEC,
7791 NULL, 0, NULL, HFILL }},
7793 { &hf_smb2_channel_sequence,
7794 { "Channel Sequence", "smb2.channel_sequence", FT_UINT16, BASE_DEC,
7795 NULL, 0, NULL, HFILL }},
7797 { &hf_smb2_dialect_count,
7798 { "Dialect count", "smb2.dialect_count", FT_UINT16, BASE_DEC,
7799 NULL, 0, NULL, HFILL }},
7801 { &hf_smb2_dialect,
7802 { "Dialect", "smb2.dialect", FT_UINT16, BASE_HEX,
7803 NULL, 0, NULL, HFILL }},
7805 { &hf_smb2_security_mode,
7806 { "Security mode", "smb2.sec_mode", FT_UINT8, BASE_HEX,
7807 NULL, 0, NULL, HFILL }},
7809 { &hf_smb2_session_flags,
7810 { "Session Flags", "smb2.session_flags", FT_UINT16, BASE_HEX,
7811 NULL, 0, NULL, HFILL }},
7813 { &hf_smb2_lock_count,
7814 { "Lock Count", "smb2.lock_count", FT_UINT16, BASE_DEC,
7815 NULL, 0, NULL, HFILL }},
7817 { &hf_smb2_capabilities,
7818 { "Capabilities", "smb2.capabilities", FT_UINT32, BASE_HEX,
7819 NULL, 0, NULL, HFILL }},
7821 { &hf_smb2_ioctl_shadow_copy_count,
7822 { "Count", "smb2.ioctl.shadow_copy.count", FT_UINT32, BASE_DEC,
7823 NULL, 0, "Number of bytes for shadow copy label strings", HFILL }},
7825 { &hf_smb2_auth_frame,
7826 { "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
7827 NULL, 0, "Which frame this user was authenticated in", HFILL }},
7829 { &hf_smb2_tcon_frame,
7830 { "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
7831 NULL, 0, "Which frame this share was connected in", HFILL }},
7833 { &hf_smb2_tag,
7834 { "Tag", "smb2.tag", FT_STRING, BASE_NONE,
7835 NULL, 0, "Tag of chain entry", HFILL }},
7837 { &hf_smb2_acct_name,
7838 { "Account", "smb2.acct", FT_STRING, BASE_NONE,
7839 NULL, 0, "Account Name", HFILL }},
7841 { &hf_smb2_domain_name,
7842 { "Domain", "smb2.domain", FT_STRING, BASE_NONE,
7843 NULL, 0, "Domain Name", HFILL }},
7845 { &hf_smb2_host_name,
7846 { "Host", "smb2.host", FT_STRING, BASE_NONE,
7847 NULL, 0, "Host Name", HFILL }},
7849 { &hf_smb2_signature,
7850 { "Signature", "smb2.signature", FT_BYTES, BASE_NONE,
7851 NULL, 0, NULL, HFILL }},
7853 { &hf_smb2_unknown,
7854 { "unknown", "smb2.unknown", FT_BYTES, BASE_NONE,
7855 NULL, 0, "Unknown bytes", HFILL }},
7857 { &hf_smb2_twrp_timestamp,
7858 { "Timestamp", "smb2.twrp_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7859 NULL, 0, "TWrp timestamp", HFILL }},
7861 { &hf_smb2_mxac_timestamp,
7862 { "Timestamp", "smb2.mxac_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7863 NULL, 0, "MxAc timestamp", HFILL }},
7865 { &hf_smb2_mxac_status,
7866 { "Query Status", "smb2.mxac_status", FT_UINT32, BASE_HEX,
7867 VALS(NT_errors), 0, "NT Status code", HFILL }},
7869 { &hf_smb2_qfid_fid,
7870 { "Opaque File ID", "smb2.qfid_fid", FT_BYTES, BASE_NONE,
7871 NULL, 0, NULL, HFILL }},
7873 { &hf_smb2_ses_flags_guest,
7874 { "Guest", "smb2.ses_flags.guest", FT_BOOLEAN, 16,
7875 NULL, SES_FLAGS_GUEST, NULL, HFILL }},
7877 { &hf_smb2_ses_flags_null,
7878 { "Null", "smb2.ses_flags.null", FT_BOOLEAN, 16,
7879 NULL, SES_FLAGS_NULL, NULL, HFILL }},
7881 { &hf_smb2_secmode_flags_sign_required,
7882 { "Signing required", "smb2.sec_mode.sign_required", FT_BOOLEAN, 8,
7883 NULL, NEGPROT_SIGN_REQ, "Is signing required", HFILL }},
7885 { &hf_smb2_secmode_flags_sign_enabled,
7886 { "Signing enabled", "smb2.sec_mode.sign_enabled", FT_BOOLEAN, 8,
7887 NULL, NEGPROT_SIGN_ENABLED, "Is signing enabled", HFILL }},
7889 { &hf_smb2_ses_req_flags,
7890 { "Flags", "smb2.ses_req_flags", FT_UINT8, BASE_DEC,
7891 NULL, 0, NULL, HFILL }},
7893 { &hf_smb2_ses_req_flags_session_binding,
7894 { "Session Binding Request", "smb2.ses_req_flags.session_binding", FT_BOOLEAN, 8,
7895 NULL, SES_REQ_FLAGS_SESSION_BINDING,
7896 "The client wants to bind to an existing session", HFILL }},
7898 { &hf_smb2_cap_dfs,
7899 { "DFS", "smb2.capabilities.dfs", FT_BOOLEAN, 32,
7900 TFS(&tfs_cap_dfs), NEGPROT_CAP_DFS, "If the host supports dfs", HFILL }},
7902 { &hf_smb2_cap_leasing,
7903 { "LEASING", "smb2.capabilities.leasing", FT_BOOLEAN, 32,
7904 TFS(&tfs_cap_leasing), NEGPROT_CAP_LEASING,
7905 "If the host supports leasing", HFILL }},
7907 { &hf_smb2_cap_large_mtu,
7908 { "LARGE MTU", "smb2.capabilities.large_mtu", FT_BOOLEAN, 32,
7909 TFS(&tfs_cap_large_mtu), NEGPROT_CAP_LARGE_MTU,
7910 "If the host supports LARGE MTU", HFILL }},
7912 { &hf_smb2_cap_multi_channel,
7913 { "MULTI CHANNEL", "smb2.capabilities.multi_channel", FT_BOOLEAN, 32,
7914 TFS(&tfs_cap_multi_channel), NEGPROT_CAP_MULTI_CHANNEL,
7915 "If the host supports MULTI CHANNEL", HFILL }},
7917 { &hf_smb2_cap_persistent_handles,
7918 { "PERSISTENT HANDLES", "smb2.capabilities.persistent_handles", FT_BOOLEAN, 32,
7919 TFS(&tfs_cap_persistent_handles), NEGPROT_CAP_PERSISTENT_HANDLES,
7920 "If the host supports PERSISTENT HANDLES", HFILL }},
7922 { &hf_smb2_cap_directory_leasing,
7923 { "DIRECTORY LEASING", "smb2.capabilities.directory_leasing", FT_BOOLEAN, 32,
7924 TFS(&tfs_cap_directory_leasing), NEGPROT_CAP_DIRECTORY_LEASING,
7925 "If the host supports DIRECTORY LEASING", HFILL }},
7927 { &hf_smb2_cap_encryption,
7928 { "ENCRYPTION", "smb2.capabilities.encryption", FT_BOOLEAN, 32,
7929 TFS(&tfs_cap_encryption), NEGPROT_CAP_ENCRYPTION,
7930 "If the host supports ENCRYPTION", HFILL }},
7932 { &hf_smb2_max_trans_size,
7933 { "Max Transaction Size", "smb2.max_trans_size", FT_UINT32, BASE_DEC,
7934 NULL, 0, "Maximum size of a transaction", HFILL }},
7936 { &hf_smb2_max_read_size,
7937 { "Max Read Size", "smb2.max_read_size", FT_UINT32, BASE_DEC,
7938 NULL, 0, "Maximum size of a read", HFILL }},
7940 { &hf_smb2_max_write_size,
7941 { "Max Write Size", "smb2.max_write_size", FT_UINT32, BASE_DEC,
7942 NULL, 0, "Maximum size of a write", HFILL }},
7944 { &hf_smb2_channel,
7945 { "Channel", "smb2.channel", FT_UINT32, BASE_DEC,
7946 NULL, 0, NULL, HFILL }},
7948 { &hf_smb2_share_flags,
7949 { "Share flags", "smb2.share_flags", FT_UINT32, BASE_HEX,
7950 NULL, 0, NULL, HFILL }},
7952 { &hf_smb2_share_flags_dfs,
7953 { "DFS", "smb2.share_flags.dfs", FT_BOOLEAN, 32,
7954 NULL, SHARE_FLAGS_dfs, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }},
7956 { &hf_smb2_share_flags_dfs_root,
7957 { "DFS root", "smb2.share_flags.dfs_root", FT_BOOLEAN, 32,
7958 NULL, SHARE_FLAGS_dfs_root, "The specified share is present in a Distributed File System (DFS) tree structure", HFILL }},
7960 { &hf_smb2_share_flags_restrict_exclusive_opens,
7961 { "Restrict exclusive opens", "smb2.share_flags.restrict_exclusive_opens", FT_BOOLEAN, 32,
7962 NULL, SHARE_FLAGS_restrict_exclusive_opens, "The specified share disallows exclusive file opens that deny reads to an open file", HFILL }},
7964 { &hf_smb2_share_flags_force_shared_delete,
7965 { "Force shared delete", "smb2.share_flags.force_shared_delete", FT_BOOLEAN, 32,
7966 NULL, SHARE_FLAGS_force_shared_delete, "Shared files in the specified share can be forcibly deleted", HFILL }},
7968 { &hf_smb2_share_flags_allow_namespace_caching,
7969 { "Allow namepsace caching", "smb2.share_flags.allow_namespace_caching", FT_BOOLEAN, 32,
7970 NULL, SHARE_FLAGS_allow_namespace_caching, "Clients are allowed to cache the namespace of the specified share", HFILL }},
7972 { &hf_smb2_share_flags_access_based_dir_enum,
7973 { "Access based directory enum", "smb2.share_flags.access_based_dir_enum", FT_BOOLEAN, 32,
7974 NULL, SHARE_FLAGS_access_based_dir_enum, "The server will filter directory entries based on the access permissions of the client", HFILL }},
7976 { &hf_smb2_share_flags_force_levelii_oplock,
7977 { "Force level II oplock", "smb2.share_flags.force_levelii_oplock", FT_BOOLEAN, 32,
7978 NULL, SHARE_FLAGS_force_levelii_oplock, "The server will not issue exclusive caching rights on this share", HFILL }},
7980 { &hf_smb2_share_flags_enable_hash_v1,
7981 { "Enable hash V1", "smb2.share_flags.enable_hash_v1", FT_BOOLEAN, 32,
7982 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 }},
7984 { &hf_smb2_share_flags_enable_hash_v2,
7985 { "Enable hash V2", "smb2.share_flags.enable_hash_v2", FT_BOOLEAN, 32,
7986 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 }},
7988 { &hf_smb2_share_flags_encrypt_data,
7989 { "Encrypted data required", "smb2.share_flags.encrypt_data", FT_BOOLEAN, 32,
7990 NULL, SHARE_FLAGS_encryption_required, "The share require data encryption", HFILL }},
7992 { &hf_smb2_share_caching,
7993 { "Caching policy", "smb2.share.caching", FT_UINT32, BASE_HEX,
7994 VALS(share_cache_vals), 0, NULL, HFILL }},
7996 { &hf_smb2_share_caps,
7997 { "Share Capabilities", "smb2.share_caps", FT_UINT32, BASE_HEX,
7998 NULL, 0, NULL, HFILL }},
8000 { &hf_smb2_share_caps_dfs,
8001 { "DFS", "smb2.share_caps.dfs", FT_BOOLEAN, 32,
8002 NULL, SHARE_CAPS_DFS, "The specified share is present in a DFS tree structure", HFILL }},
8004 { &hf_smb2_share_caps_continuous_availability,
8005 { "CONTINUOUS AVAILABILITY", "smb2.share_caps.continuous_availability", FT_BOOLEAN, 32,
8006 NULL, SHARE_CAPS_CONTINUOUS_AVAILABILITY,
8007 "The specified share is continuously available", HFILL }},
8009 { &hf_smb2_share_caps_scaleout,
8010 { "SCALEOUT", "smb2.share_caps.scaleout", FT_BOOLEAN, 32,
8011 NULL, SHARE_CAPS_SCALEOUT,
8012 "The specified share is a scaleout share", HFILL }},
8014 { &hf_smb2_share_caps_cluster,
8015 { "CLUSTER", "smb2.share_caps.cluster", FT_BOOLEAN, 32,
8016 NULL, SHARE_CAPS_CLUSTER,
8017 "The specified share is a cluster share", HFILL }},
8019 { &hf_smb2_ioctl_flags,
8020 { "Flags", "smb2.ioctl.flags", FT_UINT32, BASE_HEX,
8021 NULL, 0, NULL, HFILL }},
8023 { &hf_smb2_min_count,
8024 { "Min Count", "smb2.min_count", FT_UINT32, BASE_DEC,
8025 NULL, 0, NULL, HFILL }},
8027 { &hf_smb2_remaining_bytes,
8028 { "Remaining Bytes", "smb2.remaining_bytes", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8030 { &hf_smb2_channel_info_offset,
8031 { "Channel Info Offset", "smb2.channel_info_offset", FT_UINT16, BASE_DEC,
8032 NULL, 0, NULL, HFILL }},
8034 { &hf_smb2_channel_info_length,
8035 { "Channel Info Length", "smb2.channel_info_length", FT_UINT16, BASE_DEC,
8036 NULL, 0, NULL, HFILL }},
8038 { &hf_smb2_ioctl_is_fsctl,
8039 { "Is FSCTL", "smb2.ioctl.is_fsctl", FT_BOOLEAN, 32,
8040 NULL, 0x00000001, NULL, HFILL }},
8042 { &hf_smb2_output_buffer_len,
8043 { "Output Buffer Length", "smb2.output_buffer_len", FT_UINT16, BASE_DEC,
8044 NULL, 0, NULL, HFILL }},
8046 { &hf_smb2_close_pq_attrib,
8047 { "PostQuery Attrib", "smb2.close.pq_attrib", FT_BOOLEAN, 16,
8048 NULL, 0x0001, NULL, HFILL }},
8050 { &hf_smb2_notify_watch_tree,
8051 { "Watch Tree", "smb2.notify.watch_tree", FT_BOOLEAN, 16,
8052 NULL, 0x0001, NULL, HFILL }},
8054 { &hf_smb2_notify_out_data,
8055 { "Out Data", "smb2.notify.out", FT_NONE, BASE_NONE,
8056 NULL, 0, NULL, HFILL }},
8058 { &hf_smb2_find_flags_restart_scans,
8059 { "Restart Scans", "smb2.find.restart_scans", FT_BOOLEAN, 8,
8060 NULL, SMB2_FIND_FLAG_RESTART_SCANS, NULL, HFILL }},
8062 { &hf_smb2_find_flags_single_entry,
8063 { "Single Entry", "smb2.find.single_entry", FT_BOOLEAN, 8,
8064 NULL, SMB2_FIND_FLAG_SINGLE_ENTRY, NULL, HFILL }},
8066 { &hf_smb2_find_flags_index_specified,
8067 { "Index Specified", "smb2.find.index_specified", FT_BOOLEAN, 8,
8068 NULL, SMB2_FIND_FLAG_INDEX_SPECIFIED, NULL, HFILL }},
8070 { &hf_smb2_find_flags_reopen,
8071 { "Reopen", "smb2.find.reopen", FT_BOOLEAN, 8,
8072 NULL, SMB2_FIND_FLAG_REOPEN, NULL, HFILL }},
8074 { &hf_smb2_file_index,
8075 { "File Index", "smb2.file_index", FT_UINT32, BASE_HEX,
8076 NULL, 0, NULL, HFILL }},
8078 { &hf_smb2_file_directory_info,
8079 { "FileDirectoryInfo", "smb2.find.file_directory_info", FT_NONE, BASE_NONE,
8080 NULL, 0, NULL, HFILL }},
8082 { &hf_smb2_full_directory_info,
8083 { "FullDirectoryInfo", "smb2.find.full_directory_info", FT_NONE, BASE_NONE,
8084 NULL, 0, NULL, HFILL }},
8086 { &hf_smb2_both_directory_info,
8087 { "FileBothDirectoryInfo", "smb2.find.both_directory_info", FT_NONE, BASE_NONE,
8088 NULL, 0, NULL, HFILL }},
8090 { &hf_smb2_id_both_directory_info,
8091 { "FileIdBothDirectoryInfo", "smb2.find.id_both_directory_info", FT_NONE, BASE_NONE,
8092 NULL, 0, NULL, HFILL }},
8094 { &hf_smb2_short_name_len,
8095 { "Short Name Length", "smb2.short_name_len", FT_UINT8, BASE_DEC,
8096 NULL, 0, NULL, HFILL }},
8098 { &hf_smb2_short_name,
8099 { "Short Name", "smb2.shortname", FT_STRING, BASE_NONE,
8100 NULL, 0, NULL, HFILL }},
8102 { &hf_smb2_lock_info,
8103 { "Lock Info", "smb2.lock_info", FT_NONE, BASE_NONE,
8104 NULL, 0, NULL, HFILL }},
8106 { &hf_smb2_lock_length,
8107 { "Length", "smb2.lock_length", FT_UINT64, BASE_DEC,
8108 NULL, 0, NULL, HFILL }},
8110 { &hf_smb2_lock_flags,
8111 { "Flags", "smb2.lock_flags", FT_UINT32, BASE_HEX,
8112 NULL, 0, NULL, HFILL }},
8114 { &hf_smb2_lock_flags_shared,
8115 { "Shared", "smb2.lock_flags.shared", FT_BOOLEAN, 32,
8116 NULL, 0x00000001, NULL, HFILL }},
8118 { &hf_smb2_lock_flags_exclusive,
8119 { "Exclusive", "smb2.lock_flags.exclusive", FT_BOOLEAN, 32,
8120 NULL, 0x00000002, NULL, HFILL }},
8122 { &hf_smb2_lock_flags_unlock,
8123 { "Unlock", "smb2.lock_flags.unlock", FT_BOOLEAN, 32,
8124 NULL, 0x00000004, NULL, HFILL }},
8126 { &hf_smb2_lock_flags_fail_immediately,
8127 { "Fail Immediately", "smb2.lock_flags.fail_immediately", FT_BOOLEAN, 32,
8128 NULL, 0x00000010, NULL, HFILL }},
8130 { &hf_smb2_error_reserved,
8131 { "Reserved", "smb2.error.reserved", FT_UINT16, BASE_HEX,
8132 NULL, 0, NULL, HFILL }},
8134 { &hf_smb2_error_byte_count,
8135 { "Byte Count", "smb2.error.byte_count", FT_UINT32, BASE_DEC,
8136 NULL, 0, NULL, HFILL }},
8138 { &hf_smb2_error_data,
8139 { "Error Data", "smb2.error.data", FT_BYTES, BASE_NONE,
8140 NULL, 0, NULL, HFILL }},
8142 { &hf_smb2_reserved,
8143 { "Reserved", "smb2.reserved", FT_BYTES, BASE_NONE,
8144 NULL, 0, "Reserved bytes", HFILL }},
8146 { &hf_smb2_dhnq_buffer_reserved,
8147 { "Reserved", "smb2.dhnq_buffer_reserved", FT_UINT64, BASE_HEX,
8148 NULL, 0, NULL, HFILL}},
8150 { &hf_smb2_dh2x_buffer_timeout,
8151 { "Timeout", "smb2.dh2x.timeout", FT_UINT32, BASE_DEC,
8152 NULL, 0, NULL, HFILL}},
8154 { &hf_smb2_dh2x_buffer_flags,
8155 { "Flags", "smb2.dh2x.flags", FT_UINT32, BASE_HEX,
8156 NULL, 0, NULL, HFILL}},
8158 { &hf_smb2_dh2x_buffer_flags_persistent_handle,
8159 { "Persistent Handle", "smb2.dh2x.flags.persistent_handle", FT_BOOLEAN, 32,
8160 NULL, SMB2_DH2X_FLAGS_PERSISTENT_HANDLE, NULL, HFILL}},
8162 { &hf_smb2_dh2x_buffer_reserved,
8163 { "Reserved", "smb2.dh2x.reserved", FT_UINT64, BASE_HEX,
8164 NULL, 0, NULL, HFILL}},
8166 { &hf_smb2_dh2x_buffer_create_guid,
8167 { "Create Guid", "smb2.dh2x.create_guid", FT_GUID, BASE_NONE,
8168 NULL, 0, NULL, HFILL}},
8170 { &hf_smb2_APP_INSTANCE_buffer_struct_size,
8171 { "Struct Size", "smb2.app_instance.struct_size", FT_UINT16, BASE_DEC,
8172 NULL, 0, NULL, HFILL}},
8174 { &hf_smb2_APP_INSTANCE_buffer_reserved,
8175 { "Reserved", "smb2.app_instance.reserved", FT_UINT16, BASE_HEX,
8176 NULL, 0, NULL, HFILL}},
8178 { &hf_smb2_APP_INSTANCE_buffer_app_guid,
8179 { "Application Guid", "smb2.app_instance.app_guid", FT_GUID, BASE_NONE,
8180 NULL, 0, NULL, HFILL}},
8182 { &hf_smb2_transform_signature,
8183 { "Signature", "smb2.header.transform.signature", FT_BYTES, BASE_NONE,
8184 NULL, 0, NULL, HFILL }},
8186 { &hf_smb2_transform_nonce,
8187 { "Nonce", "smb2.header.transform.nonce", FT_BYTES, BASE_NONE,
8188 NULL, 0, NULL, HFILL }},
8190 { &hf_smb2_transform_msg_size,
8191 { "Message size", "smb2.header.transform.msg_size", FT_UINT32, BASE_DEC,
8192 NULL, 0, NULL, HFILL }},
8194 { &hf_smb2_transform_reserved,
8195 { "Reserved", "smb2.header.transform.reserved", FT_BYTES, BASE_NONE,
8196 NULL, 0, NULL, HFILL }},
8198 { &hf_smb2_transform_enc_alg,
8199 { "Encryption ALG", "smb2.header.transform.encryption_alg", FT_UINT16, BASE_HEX,
8200 NULL, 0, NULL, HFILL }},
8202 { &hf_smb2_encryption_aes128_ccm,
8203 { "SMB2_ENCRYPTION_AES128_CCM", "smb2.header.transform.enc_aes128_ccm", FT_BOOLEAN, 16,
8204 NULL, ENC_ALG_aes128_ccm, NULL, HFILL }},
8206 { &hf_smb2_transform_encrypted_data,
8207 { "Data", "smb2.header.transform.enc_data", FT_BYTES, BASE_NONE,
8208 NULL, 0, NULL, HFILL }},
8212 static gint *ett[] = {
8213 &ett_smb2,
8214 &ett_smb2_ea,
8215 &ett_smb2_olb,
8216 &ett_smb2_header,
8217 &ett_smb2_encrypted,
8218 &ett_smb2_command,
8219 &ett_smb2_secblob,
8220 &ett_smb2_file_basic_info,
8221 &ett_smb2_file_standard_info,
8222 &ett_smb2_file_internal_info,
8223 &ett_smb2_file_ea_info,
8224 &ett_smb2_file_access_info,
8225 &ett_smb2_file_rename_info,
8226 &ett_smb2_file_disposition_info,
8227 &ett_smb2_file_position_info,
8228 &ett_smb2_file_full_ea_info,
8229 &ett_smb2_file_mode_info,
8230 &ett_smb2_file_alignment_info,
8231 &ett_smb2_file_all_info,
8232 &ett_smb2_file_allocation_info,
8233 &ett_smb2_file_endoffile_info,
8234 &ett_smb2_file_alternate_name_info,
8235 &ett_smb2_file_stream_info,
8236 &ett_smb2_file_pipe_info,
8237 &ett_smb2_file_compression_info,
8238 &ett_smb2_file_network_open_info,
8239 &ett_smb2_file_attribute_tag_info,
8240 &ett_smb2_fs_info_01,
8241 &ett_smb2_fs_info_03,
8242 &ett_smb2_fs_info_04,
8243 &ett_smb2_fs_info_05,
8244 &ett_smb2_fs_info_06,
8245 &ett_smb2_fs_info_07,
8246 &ett_smb2_fs_objectid_info,
8247 &ett_smb2_sec_info_00,
8248 &ett_smb2_tid_tree,
8249 &ett_smb2_sesid_tree,
8250 &ett_smb2_create_chain_element,
8251 &ett_smb2_MxAc_buffer,
8252 &ett_smb2_QFid_buffer,
8253 &ett_smb2_RqLs_buffer,
8254 &ett_smb2_ioctl_function,
8255 &ett_smb2_FILE_OBJECTID_BUFFER,
8256 &ett_smb2_flags,
8257 &ett_smb2_sec_mode,
8258 &ett_smb2_capabilities,
8259 &ett_smb2_ses_req_flags,
8260 &ett_smb2_ses_flags,
8261 &ett_smb2_create_rep_flags,
8262 &ett_smb2_lease_state,
8263 &ett_smb2_lease_flags,
8264 &ett_smb2_share_flags,
8265 &ett_smb2_share_caps,
8266 &ett_smb2_ioctl_flags,
8267 &ett_smb2_ioctl_network_interface,
8268 &ett_windows_sockaddr,
8269 &ett_smb2_close_flags,
8270 &ett_smb2_notify_flags,
8271 &ett_smb2_write_flags,
8272 &ett_smb2_find_flags,
8273 &ett_smb2_file_directory_info,
8274 &ett_smb2_both_directory_info,
8275 &ett_smb2_id_both_directory_info,
8276 &ett_smb2_full_directory_info,
8277 &ett_smb2_file_name_info,
8278 &ett_smb2_lock_info,
8279 &ett_smb2_lock_flags,
8280 &ett_smb2_DH2Q_buffer,
8281 &ett_smb2_DH2C_buffer,
8282 &ett_smb2_dh2x_flags,
8283 &ett_smb2_APP_INSTANCE_buffer,
8284 &ett_smb2_transform_enc_alg,
8285 &ett_smb2_buffercode,
8288 proto_smb2 = proto_register_protocol("SMB2 (Server Message Block Protocol version 2)",
8289 "SMB2", "smb2");
8290 proto_register_subtree_array(ett, array_length(ett));
8291 proto_register_field_array(proto_smb2, hf, array_length(hf));
8293 smb2_module = prefs_register_protocol(proto_smb2, NULL);
8294 prefs_register_bool_preference(smb2_module, "eosmb2_take_name_as_fid",
8295 "Use the full file name as File ID when exporting an SMB2 object",
8296 "Whether the export object functionality will take the full path file name as file identifier",
8297 &eosmb2_take_name_as_fid);
8299 register_heur_dissector_list("smb2_heur_subdissectors", &smb2_heur_subdissector_list);
8300 smb2_tap = register_tap("smb2");
8301 smb2_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
8305 void
8306 proto_reg_handoff_smb2(void)
8308 gssapi_handle = find_dissector("gssapi");
8309 ntlmssp_handle = find_dissector("ntlmssp");
8310 heur_dissector_add("netbios", dissect_smb2_heur, proto_smb2);
8314 * Editor modelines - http://www.wireshark.org/tools/modelines.html
8316 * Local variables:
8317 * c-basic-offset: 8
8318 * tab-width: 8
8319 * indent-tabs-mode: t
8320 * End:
8322 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
8323 * :indentSize=8:tabSize=8:noTabs=false: