HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-smb.c
blob4514bf48b7c5e980411c3c96ce126d2e0e28b207
1 /* packet-smb.c
2 * Routines for smb packet dissection
3 * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4 * 2001 Rewrite by Ronnie Sahlberg and Guy Harris
6 * $Id$
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-pop.c
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "config.h"
31 #include <glib.h>
33 #include <epan/packet.h>
34 #include <epan/exceptions.h>
35 #include <epan/conversation.h>
36 #include <epan/wmem/wmem.h>
37 #include <epan/dissectors/packet-smb.h>
38 #include <epan/strutil.h>
39 #include <epan/prefs.h>
40 #include <epan/reassemble.h>
41 #include <epan/tap.h>
42 #include <epan/expert.h>
44 #include "packet-ipx.h"
45 #include "packet-idp.h"
47 #include "packet-windows-common.h"
48 #include "packet-smb.h"
49 #include "packet-smb-common.h"
50 #include "packet-smb-mailslot.h"
51 #include "packet-smb-pipe.h"
52 #include "packet-dcerpc.h"
53 #include "packet-ntlmssp.h"
54 #include "packet-smb2.h"
57 * Various specifications and documents about SMB can be found in
59 * ftp://ftp.microsoft.com/developr/drg/CIFS/
61 * and a CIFS specification from the Storage Networking Industry Association
62 * can be found on a link from the page at
64 * http://www.snia.org/tech_activities/CIFS
66 * (it supercedes the document at
68 * ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
70 * ).
72 * There are also some Open Group publications documenting CIFS available
73 * for download; catalog entries for them are at:
75 * http://www.opengroup.org/products/publications/catalog/c209.htm
77 * http://www.opengroup.org/products/publications/catalog/c195.htm
79 * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
80 * can be found at
82 * http://www.samba.org/samba/ftp/specs/smb-nt01.doc
84 * (or, presumably a similar path under the Samba mirrors). As the
85 * ".doc" indicates, it's a Word document. Some of the specs from the
86 * Microsoft FTP site can be found in the
88 * http://www.samba.org/samba/ftp/specs/
90 * directory as well.
92 * Beware - these specs may have errors.
94 * Microsoft's public protocol specifications, including MS-CIFS and
95 * other SMB-related specifications, can be found at
97 * http://msdn.microsoft.com/en-us/library/cc216513.aspx
99 * See also
101 * https://wiki.samba.org/index.php/UNIX_Extensions
104 /* DFS referral entry flags */
105 #define REFENT_FLAGS_NAME_LIST_REFERRAL 0x0002
106 #define REFENT_FLAGS_TARGET_SET_BOUNDARY 0x0004
109 static int proto_smb = -1;
110 static int hf_smb_cmd = -1;
111 static int hf_smb_andxcmd = -1;
112 static int hf_smb_mapped_in = -1;
113 static int hf_smb_unmapped_in = -1;
114 static int hf_smb_opened_in = -1;
115 static int hf_smb_closed_in = -1;
116 static int hf_smb_key = -1;
117 static int hf_smb_session_id = -1;
118 static int hf_smb_sequence_num = -1;
119 static int hf_smb_group_id = -1;
120 static int hf_smb_pid = -1;
121 static int hf_smb_tid = -1;
122 static int hf_smb_uid = -1;
123 static int hf_smb_mid = -1;
124 static int hf_smb_pid_high = -1;
125 static int hf_smb_sig = -1;
126 static int hf_smb_response_to = -1;
127 static int hf_smb_time = -1;
128 static int hf_smb_response_in = -1;
129 static int hf_smb_continuation_to = -1;
130 static int hf_smb_nt_status = -1;
131 static int hf_smb_error_class = -1;
132 static int hf_smb_error_code = -1;
133 static int hf_smb_reserved = -1;
134 static int hf_smb_create_flags = -1;
135 static int hf_smb_create_options = -1;
136 static int hf_smb_share_access = -1;
137 static int hf_smb_access_mask = -1;
138 static int hf_smb_flags = -1;
139 static int hf_smb_flags_lock = -1;
140 static int hf_smb_flags_receive_buffer = -1;
141 static int hf_smb_flags_caseless = -1;
142 static int hf_smb_flags_canon = -1;
143 static int hf_smb_flags_oplock = -1;
144 static int hf_smb_flags_notify = -1;
145 static int hf_smb_flags_response = -1;
146 static int hf_smb_flags2 = -1;
147 static int hf_smb_flags2_long_names_allowed = -1;
148 static int hf_smb_flags2_ea = -1;
149 static int hf_smb_flags2_sec_sig = -1;
150 static int hf_smb_flags2_compressed = -1;
151 static int hf_smb_flags2_sec_sig_required = -1;
152 static int hf_smb_flags2_long_names_used = -1;
153 static int hf_smb_flags2_reparse_path = -1;
154 static int hf_smb_flags2_esn = -1;
155 static int hf_smb_flags2_dfs = -1;
156 static int hf_smb_flags2_roe = -1;
157 static int hf_smb_flags2_nt_error = -1;
158 static int hf_smb_flags2_string = -1;
159 static int hf_smb_word_count = -1;
160 static int hf_smb_byte_count = -1;
161 static int hf_smb_buffer_format = -1;
162 static int hf_smb_dialect = -1;
163 static int hf_smb_dialect_name = -1;
164 static int hf_smb_dialect_index = -1;
165 static int hf_smb_max_trans_buf_size = -1;
166 static int hf_smb_max_mpx_count = -1;
167 static int hf_smb_max_vcs_num = -1;
168 static int hf_smb_session_key = -1;
169 static int hf_smb_server_timezone = -1;
170 static int hf_smb_encryption_key_length = -1;
171 static int hf_smb_encryption_key = -1;
172 static int hf_smb_primary_domain = -1;
173 static int hf_smb_server = -1;
174 static int hf_smb_max_raw_buf_size = -1;
175 static int hf_smb_server_guid = -1;
176 static int hf_smb_volume_guid = -1;
177 static int hf_smb_security_blob_len = -1;
178 static int hf_smb_security_blob = -1;
179 static int hf_smb_sm16 = -1;
180 static int hf_smb_sm_mode16 = -1;
181 static int hf_smb_sm_password16 = -1;
182 static int hf_smb_sm = -1;
183 static int hf_smb_sm_mode = -1;
184 static int hf_smb_sm_password = -1;
185 static int hf_smb_sm_signatures = -1;
186 static int hf_smb_sm_sig_required = -1;
187 static int hf_smb_rm = -1;
188 static int hf_smb_rm_read = -1;
189 static int hf_smb_rm_write = -1;
190 static int hf_smb_server_date_time = -1;
191 static int hf_smb_server_smb_date = -1;
192 static int hf_smb_server_smb_time = -1;
193 static int hf_smb_server_cap = -1;
194 static int hf_smb_server_cap_raw_mode = -1;
195 static int hf_smb_server_cap_mpx_mode = -1;
196 static int hf_smb_server_cap_unicode = -1;
197 static int hf_smb_server_cap_large_files = -1;
198 static int hf_smb_server_cap_nt_smbs = -1;
199 static int hf_smb_server_cap_rpc_remote_apis = -1;
200 static int hf_smb_server_cap_nt_status = -1;
201 static int hf_smb_server_cap_level_ii_oplocks = -1;
202 static int hf_smb_server_cap_lock_and_read = -1;
203 static int hf_smb_server_cap_nt_find = -1;
204 static int hf_smb_server_cap_dfs = -1;
205 static int hf_smb_server_cap_infolevel_passthru = -1;
206 static int hf_smb_server_cap_large_readx = -1;
207 static int hf_smb_server_cap_large_writex = -1;
208 static int hf_smb_server_cap_lwio = -1;
209 static int hf_smb_server_cap_unix = -1;
210 static int hf_smb_server_cap_compressed_data = -1;
211 static int hf_smb_server_cap_dynamic_reauth = -1;
212 static int hf_smb_server_cap_extended_security = -1;
213 static int hf_smb_system_time = -1;
214 static int hf_smb_unknown = -1;
215 static int hf_smb_dir_name = -1;
216 static int hf_smb_echo_count = -1;
217 static int hf_smb_echo_data = -1;
218 static int hf_smb_echo_seq_num = -1;
219 static int hf_smb_max_buf_size = -1;
220 static int hf_smb_password = -1;
221 static int hf_smb_password_len = -1;
222 static int hf_smb_ansi_password = -1;
223 static int hf_smb_ansi_password_len = -1;
224 static int hf_smb_unicode_password = -1;
225 static int hf_smb_unicode_password_len = -1;
226 static int hf_smb_path = -1;
227 static int hf_smb_service = -1;
228 static int hf_smb_move_flags = -1;
229 static int hf_smb_move_flags_file = -1;
230 static int hf_smb_move_flags_dir = -1;
231 static int hf_smb_move_flags_verify = -1;
232 static int hf_smb_files_moved = -1;
233 static int hf_smb_file_access_mask_read_data = -1;
234 static int hf_smb_file_access_mask_write_data = -1;
235 static int hf_smb_file_access_mask_append_data = -1;
236 static int hf_smb_file_access_mask_read_ea = -1;
237 static int hf_smb_file_access_mask_write_ea = -1;
238 static int hf_smb_file_access_mask_execute = -1;
239 static int hf_smb_file_access_mask_read_attribute = -1;
240 static int hf_smb_file_access_mask_write_attribute = -1;
241 static int hf_smb_dir_access_mask_list = -1;
242 static int hf_smb_dir_access_mask_add_file = -1;
243 static int hf_smb_dir_access_mask_add_subdir = -1;
244 static int hf_smb_dir_access_mask_read_ea = -1;
245 static int hf_smb_dir_access_mask_write_ea = -1;
246 static int hf_smb_dir_access_mask_traverse = -1;
247 static int hf_smb_dir_access_mask_delete_child = -1;
248 static int hf_smb_dir_access_mask_read_attribute = -1;
249 static int hf_smb_dir_access_mask_write_attribute = -1;
250 static int hf_smb_copy_flags = -1;
251 static int hf_smb_copy_flags_file = -1;
252 static int hf_smb_copy_flags_dir = -1;
253 static int hf_smb_copy_flags_dest_mode = -1;
254 static int hf_smb_copy_flags_source_mode = -1;
255 static int hf_smb_copy_flags_verify = -1;
256 static int hf_smb_copy_flags_tree_copy = -1;
257 static int hf_smb_copy_flags_ea_action = -1;
258 static int hf_smb_count = -1;
259 static int hf_smb_count_low = -1;
260 static int hf_smb_count_high = -1;
261 static int hf_smb_file_name = -1;
262 static int hf_smb_open_function = -1;
263 static int hf_smb_open_function_open = -1;
264 static int hf_smb_open_function_create = -1;
265 static int hf_smb_fid = -1;
266 static int hf_smb_file_attr_16bit = -1;
267 static int hf_smb_file_attr_8bit = -1;
268 static int hf_smb_file_attr_read_only_16bit = -1;
269 static int hf_smb_file_attr_read_only_8bit = -1;
270 static int hf_smb_file_attr_hidden_16bit = -1;
271 static int hf_smb_file_attr_hidden_8bit = -1;
272 static int hf_smb_file_attr_system_16bit = -1;
273 static int hf_smb_file_attr_system_8bit = -1;
274 static int hf_smb_file_attr_volume_16bit = -1;
275 static int hf_smb_file_attr_volume_8bit = -1;
276 static int hf_smb_file_attr_directory_16bit = -1;
277 static int hf_smb_file_attr_directory_8bit = -1;
278 static int hf_smb_file_attr_archive_16bit = -1;
279 static int hf_smb_file_attr_archive_8bit = -1;
280 #if 0
281 static int hf_smb_file_attr_device = -1;
282 static int hf_smb_file_attr_normal = -1;
283 static int hf_smb_file_attr_temporary = -1;
284 static int hf_smb_file_attr_sparse = -1;
285 static int hf_smb_file_attr_reparse = -1;
286 static int hf_smb_file_attr_compressed = -1;
287 static int hf_smb_file_attr_offline = -1;
288 static int hf_smb_file_attr_not_content_indexed = -1;
289 static int hf_smb_file_attr_encrypted = -1;
290 #endif
291 static int hf_smb_file_size = -1;
292 static int hf_smb_search_attribute = -1;
293 static int hf_smb_search_attribute_read_only = -1;
294 static int hf_smb_search_attribute_hidden = -1;
295 static int hf_smb_search_attribute_system = -1;
296 static int hf_smb_search_attribute_volume = -1;
297 static int hf_smb_search_attribute_directory = -1;
298 static int hf_smb_search_attribute_archive = -1;
299 static int hf_smb_access_mode = -1;
300 static int hf_smb_access_sharing = -1;
301 static int hf_smb_access_locality = -1;
302 static int hf_smb_access_caching = -1;
303 static int hf_smb_access_writetru = -1;
304 static int hf_smb_create_time = -1;
305 static int hf_smb_modify_time = -1;
306 static int hf_smb_backup_time = -1;
307 static int hf_smb_mac_alloc_block_count = -1;
308 static int hf_smb_mac_alloc_block_size = -1;
309 static int hf_smb_mac_free_block_count = -1;
310 static int hf_smb_mac_fndrinfo = -1;
311 static int hf_smb_mac_root_file_count = -1;
312 static int hf_smb_mac_root_dir_count = -1;
313 static int hf_smb_mac_file_count = -1;
314 static int hf_smb_mac_dir_count = -1;
315 static int hf_smb_mac_sup = -1;
316 static int hf_smb_mac_sup_access_ctrl = -1;
317 static int hf_smb_mac_sup_getset_comments = -1;
318 static int hf_smb_mac_sup_desktopdb_calls = -1;
319 static int hf_smb_mac_sup_unique_ids = -1;
320 static int hf_smb_mac_sup_streams = -1;
321 static int hf_smb_create_dos_date = -1;
322 static int hf_smb_create_dos_time = -1;
323 static int hf_smb_last_write_time = -1;
324 static int hf_smb_last_write_dos_date = -1;
325 static int hf_smb_last_write_dos_time = -1;
326 static int hf_smb_access_time = -1;
327 static int hf_smb_access_dos_date = -1;
328 static int hf_smb_access_dos_time = -1;
329 static int hf_smb_old_file_name = -1;
330 static int hf_smb_offset = -1;
331 static int hf_smb_remaining = -1;
332 static int hf_smb_padding = -1;
333 static int hf_smb_file_data = -1;
334 /* static int hf_smb_raw_ea_data = -1; */
335 static int hf_smb_total_data_len = -1;
336 static int hf_smb_data_len = -1;
337 static int hf_smb_data_len_low = -1;
338 static int hf_smb_data_len_high = -1;
339 static int hf_smb_seek_mode = -1;
340 static int hf_smb_data_size = -1;
341 static int hf_smb_alloc_size = -1;
342 static int hf_smb_alloc_size64 = -1;
343 static int hf_smb_max_count = -1;
344 static int hf_smb_max_count_low = -1;
345 static int hf_smb_max_count_high = -1;
346 static int hf_smb_min_count = -1;
347 static int hf_smb_timeout = -1;
348 static int hf_smb_high_offset = -1;
349 static int hf_smb_units = -1;
350 static int hf_smb_bpu = -1;
351 static int hf_smb_blocksize = -1;
352 static int hf_smb_freeunits = -1;
353 static int hf_smb_data_offset = -1;
354 static int hf_smb_dcm = -1;
355 static int hf_smb_request_mask = -1;
356 static int hf_smb_response_mask = -1;
357 static int hf_smb_search_id = -1;
358 static int hf_smb_write_mode = -1;
359 static int hf_smb_write_mode_write_through = -1;
360 static int hf_smb_write_mode_return_remaining = -1;
361 static int hf_smb_write_mode_raw = -1;
362 static int hf_smb_write_mode_message_start = -1;
363 static int hf_smb_write_mode_connectionless = -1;
364 static int hf_smb_resume_key_len = -1;
365 static int hf_smb_resume_find_id = -1;
366 static int hf_smb_resume_server_cookie = -1;
367 static int hf_smb_resume_client_cookie = -1;
368 static int hf_smb_andxoffset = -1;
369 static int hf_smb_lock_type = -1;
370 static int hf_smb_lock_type_large = -1;
371 static int hf_smb_lock_type_cancel = -1;
372 static int hf_smb_lock_type_change = -1;
373 static int hf_smb_lock_type_oplock = -1;
374 static int hf_smb_lock_type_shared = -1;
375 static int hf_smb_locking_ol = -1;
376 static int hf_smb_number_of_locks = -1;
377 static int hf_smb_number_of_unlocks = -1;
378 static int hf_smb_lock_long_offset = -1;
379 static int hf_smb_lock_long_length = -1;
380 static int hf_smb_file_type = -1;
381 static int hf_smb_ipc_state = -1;
382 static int hf_smb_ipc_state_nonblocking = -1;
383 static int hf_smb_ipc_state_endpoint = -1;
384 static int hf_smb_ipc_state_pipe_type = -1;
385 static int hf_smb_ipc_state_read_mode = -1;
386 static int hf_smb_ipc_state_icount = -1;
387 static int hf_smb_server_fid = -1;
388 static int hf_smb_open_flags = -1;
389 static int hf_smb_open_flags_add_info = -1;
390 static int hf_smb_open_flags_ex_oplock = -1;
391 static int hf_smb_open_flags_batch_oplock = -1;
392 static int hf_smb_open_flags_ealen = -1;
393 static int hf_smb_open_action = -1;
394 static int hf_smb_open_action_open = -1;
395 static int hf_smb_open_action_lock = -1;
396 static int hf_smb_vc_num = -1;
397 static int hf_smb_account = -1;
398 static int hf_smb_os = -1;
399 static int hf_smb_lanman = -1;
400 static int hf_smb_setup_action = -1;
401 static int hf_smb_setup_action_guest = -1;
402 static int hf_smb_fs = -1;
403 static int hf_smb_connect_flags = -1;
404 static int hf_smb_connect_flags_dtid = -1;
405 static int hf_smb_connect_flags_ext_sig = -1;
406 static int hf_smb_connect_flags_ext_resp = -1;
407 static int hf_smb_connect_support = -1;
408 static int hf_smb_connect_support_search = -1;
409 static int hf_smb_connect_support_in_dfs = -1;
410 static int hf_smb_connect_support_csc_mask_vals = -1;
411 static int hf_smb_connect_support_uniquefilename = -1;
412 static int hf_smb_connect_support_extended_signature = -1;
413 static int hf_smb_max_setup_count = -1;
414 static int hf_smb_total_param_count = -1;
415 static int hf_smb_total_data_count = -1;
416 static int hf_smb_max_param_count = -1;
417 static int hf_smb_max_data_count = -1;
418 static int hf_smb_param_disp16 = -1;
419 static int hf_smb_param_count16 = -1;
420 static int hf_smb_param_offset16 = -1;
421 static int hf_smb_param_disp32 = -1;
422 static int hf_smb_param_count32 = -1;
423 static int hf_smb_param_offset32 = -1;
424 static int hf_smb_data_disp16 = -1;
425 static int hf_smb_data_count16 = -1;
426 static int hf_smb_data_offset16 = -1;
427 static int hf_smb_data_disp32 = -1;
428 static int hf_smb_data_count32 = -1;
429 static int hf_smb_data_offset32 = -1;
430 static int hf_smb_setup_count = -1;
431 static int hf_smb_nt_trans_subcmd = -1;
432 static int hf_smb_nt_ioctl_isfsctl = -1;
433 static int hf_smb_nt_ioctl_flags_completion_filter = -1;
434 static int hf_smb_nt_ioctl_flags_root_handle = -1;
435 static int hf_smb_nt_notify_action = -1;
436 static int hf_smb_nt_notify_watch_tree = -1;
437 static int hf_smb_nt_notify_completion_filter = -1;
438 static int hf_smb_nt_notify_stream_write = -1;
439 static int hf_smb_nt_notify_stream_size = -1;
440 static int hf_smb_nt_notify_stream_name = -1;
441 static int hf_smb_nt_notify_security = -1;
442 static int hf_smb_nt_notify_ea = -1;
443 static int hf_smb_nt_notify_creation = -1;
444 static int hf_smb_nt_notify_last_access = -1;
445 static int hf_smb_nt_notify_last_write = -1;
446 static int hf_smb_nt_notify_size = -1;
447 static int hf_smb_nt_notify_attributes = -1;
448 static int hf_smb_nt_notify_dir_name = -1;
449 static int hf_smb_nt_notify_file_name = -1;
450 static int hf_smb_root_dir_fid = -1;
451 static int hf_smb_nt_create_disposition = -1;
452 static int hf_smb_sd_length = -1;
453 static int hf_smb_ea_list_length = -1;
454 static int hf_smb_ea_flags = -1;
455 static int hf_smb_ea_name_length = -1;
456 static int hf_smb_ea_data_length = -1;
457 static int hf_smb_ea_name = -1;
458 static int hf_smb_ea_data = -1;
459 static int hf_smb_file_name_len = -1;
460 static int hf_smb_nt_impersonation_level = -1;
461 static int hf_smb_nt_security_flags = -1;
462 static int hf_smb_nt_security_flags_context_tracking = -1;
463 static int hf_smb_nt_security_flags_effective_only = -1;
464 static int hf_smb_nt_access_mask_generic_read = -1;
465 static int hf_smb_nt_access_mask_generic_write = -1;
466 static int hf_smb_nt_access_mask_generic_execute = -1;
467 static int hf_smb_nt_access_mask_generic_all = -1;
468 static int hf_smb_nt_access_mask_maximum_allowed = -1;
469 static int hf_smb_nt_access_mask_system_security = -1;
470 static int hf_smb_nt_access_mask_synchronize = -1;
471 static int hf_smb_nt_access_mask_write_owner = -1;
472 static int hf_smb_nt_access_mask_write_dac = -1;
473 static int hf_smb_nt_access_mask_read_control = -1;
474 static int hf_smb_nt_access_mask_delete = -1;
475 static int hf_smb_nt_access_mask_write_attributes = -1;
476 static int hf_smb_nt_access_mask_read_attributes = -1;
477 static int hf_smb_nt_access_mask_delete_child = -1;
478 static int hf_smb_nt_access_mask_execute = -1;
479 static int hf_smb_nt_access_mask_write_ea = -1;
480 static int hf_smb_nt_access_mask_read_ea = -1;
481 static int hf_smb_nt_access_mask_append = -1;
482 static int hf_smb_nt_access_mask_write = -1;
483 static int hf_smb_nt_access_mask_read = -1;
484 static int hf_smb_nt_create_bits_oplock = -1;
485 static int hf_smb_nt_create_bits_boplock = -1;
486 static int hf_smb_nt_create_bits_dir = -1;
487 static int hf_smb_nt_create_bits_ext_resp = -1;
488 static int hf_smb_nt_create_options_directory_file = -1;
489 static int hf_smb_nt_create_options_write_through = -1;
490 static int hf_smb_nt_create_options_sequential_only = -1;
491 static int hf_smb_nt_create_options_no_intermediate_buffering = -1;
492 static int hf_smb_nt_create_options_sync_io_alert = -1;
493 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
494 static int hf_smb_nt_create_options_non_directory_file = -1;
495 static int hf_smb_nt_create_options_create_tree_connection = -1;
496 static int hf_smb_nt_create_options_complete_if_oplocked = -1;
497 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
498 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
499 static int hf_smb_nt_create_options_random_access = -1;
500 static int hf_smb_nt_create_options_delete_on_close = -1;
501 static int hf_smb_nt_create_options_open_by_fileid = -1;
502 static int hf_smb_nt_create_options_backup_intent = -1;
503 static int hf_smb_nt_create_options_no_compression = -1;
504 static int hf_smb_nt_create_options_reserve_opfilter = -1;
505 static int hf_smb_nt_create_options_open_reparse_point = -1;
506 static int hf_smb_nt_create_options_open_no_recall = -1;
507 static int hf_smb_nt_create_options_open_for_free_space_query = -1;
508 static int hf_smb_nt_share_access_read = -1;
509 static int hf_smb_nt_share_access_write = -1;
510 static int hf_smb_nt_share_access_delete = -1;
511 static int hf_smb_file_eattr = -1;
512 static int hf_smb_file_eattr_read_only = -1;
513 static int hf_smb_file_eattr_hidden = -1;
514 static int hf_smb_file_eattr_system = -1;
515 static int hf_smb_file_eattr_volume = -1;
516 static int hf_smb_file_eattr_directory = -1;
517 static int hf_smb_file_eattr_archive = -1;
518 static int hf_smb_file_eattr_device = -1;
519 static int hf_smb_file_eattr_normal = -1;
520 static int hf_smb_file_eattr_temporary = -1;
521 static int hf_smb_file_eattr_sparse = -1;
522 static int hf_smb_file_eattr_reparse = -1;
523 static int hf_smb_file_eattr_compressed = -1;
524 static int hf_smb_file_eattr_offline = -1;
525 static int hf_smb_file_eattr_not_content_indexed = -1;
526 static int hf_smb_file_eattr_encrypted = -1;
527 static int hf_smb_size_returned_quota_data = -1;
528 static int hf_smb_sec_desc_len = -1;
529 static int hf_smb_nt_qsd = -1;
530 static int hf_smb_nt_qsd_owner = -1;
531 static int hf_smb_nt_qsd_group = -1;
532 static int hf_smb_nt_qsd_dacl = -1;
533 static int hf_smb_nt_qsd_sacl = -1;
534 static int hf_smb_extended_attributes = -1;
535 static int hf_smb_oplock_level = -1;
536 static int hf_smb_create_action = -1;
537 static int hf_smb_file_id = -1;
538 static int hf_smb_file_id_64bit = -1;
539 static int hf_smb_ea_error_offset = -1;
540 static int hf_smb_end_of_file = -1;
541 static int hf_smb_replace = -1;
542 static int hf_smb_root_dir_handle = -1;
543 static int hf_smb_target_name_len = -1;
544 static int hf_smb_target_name = -1;
545 static int hf_smb_device_type = -1;
546 static int hf_smb_is_directory = -1;
547 static int hf_smb_next_entry_offset = -1;
548 static int hf_smb_change_time = -1;
549 static int hf_smb_setup_len = -1;
550 static int hf_smb_print_mode = -1;
551 static int hf_smb_print_identifier = -1;
552 static int hf_smb_restart_index = -1;
553 static int hf_smb_print_queue_date = -1;
554 static int hf_smb_print_queue_dos_date = -1;
555 static int hf_smb_print_queue_dos_time = -1;
556 static int hf_smb_print_status = -1;
557 static int hf_smb_print_spool_file_number = -1;
558 static int hf_smb_print_spool_file_size = -1;
559 static int hf_smb_print_spool_file_name = -1;
560 static int hf_smb_start_index = -1;
561 static int hf_smb_originator_name = -1;
562 static int hf_smb_destination_name = -1;
563 static int hf_smb_message_len = -1;
564 static int hf_smb_message = -1;
565 static int hf_smb_mgid = -1;
566 static int hf_smb_forwarded_name = -1;
567 static int hf_smb_machine_name = -1;
568 static int hf_smb_cancel_to = -1;
569 static int hf_smb_trans2_subcmd = -1;
570 static int hf_smb_trans_name = -1;
571 static int hf_smb_transaction_flags = -1;
572 static int hf_smb_transaction_flags_dtid = -1;
573 static int hf_smb_transaction_flags_owt = -1;
574 static int hf_smb_search_count = -1;
575 static int hf_smb_search_pattern = -1;
576 static int hf_smb_ff2 = -1;
577 static int hf_smb_ff2_backup = -1;
578 static int hf_smb_ff2_continue = -1;
579 static int hf_smb_ff2_resume = -1;
580 static int hf_smb_ff2_close_eos = -1;
581 static int hf_smb_ff2_close = -1;
582 static int hf_smb_ff2_information_level = -1;
583 static int hf_smb_qpi_loi = -1;
584 static int hf_smb_spi_loi = -1;
585 #if 0
586 static int hf_smb_sfi_writetru = -1;
587 static int hf_smb_sfi_caching = -1;
588 #endif
589 static int hf_smb_storage_type = -1;
590 static int hf_smb_resume = -1;
591 static int hf_smb_max_referral_level = -1;
592 static int hf_smb_qfsi_information_level = -1;
593 static int hf_smb_sfsi_information_level = -1;
594 static int hf_smb_number_of_links = -1;
595 static int hf_smb_delete_pending = -1;
596 static int hf_smb_index_number = -1;
597 static int hf_smb_position = -1;
598 /* static int hf_smb_current_offset = -1; */
599 static int hf_smb_t2_alignment = -1;
600 static int hf_smb_t2_stream_name_length = -1;
601 static int hf_smb_t2_stream_size = -1;
602 static int hf_smb_t2_stream_name = -1;
603 static int hf_smb_t2_compressed_file_size = -1;
604 static int hf_smb_t2_compressed_format = -1;
605 static int hf_smb_t2_compressed_unit_shift = -1;
606 static int hf_smb_t2_compressed_chunk_shift = -1;
607 static int hf_smb_t2_compressed_cluster_shift = -1;
608 static int hf_smb_t2_marked_for_deletion = -1;
609 static int hf_smb_dfs_path_consumed = -1;
610 static int hf_smb_dfs_num_referrals = -1;
611 static int hf_smb_get_dfs_flags = -1;
612 static int hf_smb_get_dfs_server_hold_storage = -1;
613 static int hf_smb_get_dfs_fielding = -1;
614 static int hf_smb_dfs_referral_version = -1;
615 static int hf_smb_dfs_referral_size = -1;
616 static int hf_smb_dfs_referral_server_type = -1;
617 static int hf_smb_dfs_referral_flags = -1;
618 static int hf_smb_dfs_referral_flags_name_list_referral = -1;
619 static int hf_smb_dfs_referral_flags_target_set_boundary = -1;
620 static int hf_smb_dfs_referral_node_offset = -1;
621 static int hf_smb_dfs_referral_node = -1;
622 static int hf_smb_dfs_referral_proximity = -1;
623 static int hf_smb_dfs_referral_ttl = -1;
624 static int hf_smb_dfs_referral_path_offset = -1;
625 static int hf_smb_dfs_referral_path = -1;
626 static int hf_smb_dfs_referral_alt_path_offset = -1;
627 static int hf_smb_dfs_referral_alt_path = -1;
628 static int hf_smb_dfs_referral_domain_offset = -1;
629 static int hf_smb_dfs_referral_number_of_expnames = -1;
630 static int hf_smb_dfs_referral_expnames_offset = -1;
631 static int hf_smb_dfs_referral_domain_name = -1;
632 static int hf_smb_dfs_referral_expname = -1;
633 static int hf_smb_dfs_referral_server_guid = -1;
634 static int hf_smb_end_of_search = -1;
635 static int hf_smb_last_name_offset = -1;
636 static int hf_smb_fn_information_level = -1;
637 static int hf_smb_monitor_handle = -1;
638 static int hf_smb_change_count = -1;
639 static int hf_smb_file_index = -1;
640 static int hf_smb_short_file_name = -1;
641 static int hf_smb_short_file_name_len = -1;
642 static int hf_smb_fs_id = -1;
643 static int hf_smb_sector_unit = -1;
644 static int hf_smb_fs_units = -1;
645 static int hf_smb_fs_sector = -1;
646 static int hf_smb_avail_units = -1;
647 static int hf_smb_volume_serial_num = -1;
648 static int hf_smb_volume_label_len = -1;
649 static int hf_smb_volume_label = -1;
650 static int hf_smb_free_alloc_units64 = -1;
651 static int hf_smb_caller_free_alloc_units64 = -1;
652 static int hf_smb_actual_free_alloc_units64 = -1;
653 static int hf_smb_max_name_len = -1;
654 static int hf_smb_fs_name_len = -1;
655 static int hf_smb_fs_name = -1;
656 static int hf_smb_device_char = -1;
657 static int hf_smb_device_char_removable = -1;
658 static int hf_smb_device_char_read_only = -1;
659 static int hf_smb_device_char_floppy = -1;
660 static int hf_smb_device_char_write_once = -1;
661 static int hf_smb_device_char_remote = -1;
662 static int hf_smb_device_char_mounted = -1;
663 static int hf_smb_device_char_virtual = -1;
664 static int hf_smb_fs_attr = -1;
665 static int hf_smb_fs_attr_css = -1;
666 static int hf_smb_fs_attr_cpn = -1;
667 static int hf_smb_fs_attr_uod = -1;
668 static int hf_smb_fs_attr_pacls = -1;
669 static int hf_smb_fs_attr_fc = -1;
670 static int hf_smb_fs_attr_vq = -1;
671 static int hf_smb_fs_attr_ssf = -1;
672 static int hf_smb_fs_attr_srp = -1;
673 static int hf_smb_fs_attr_srs = -1;
674 static int hf_smb_fs_attr_sla = -1;
675 static int hf_smb_fs_attr_vic = -1;
676 static int hf_smb_fs_attr_soids = -1;
677 static int hf_smb_fs_attr_se = -1;
678 static int hf_smb_fs_attr_ns = -1;
679 static int hf_smb_fs_attr_rov = -1;
680 static int hf_smb_quota_flags_enabled = -1;
681 static int hf_smb_quota_flags_deny_disk = -1;
682 static int hf_smb_quota_flags_log_limit = -1;
683 static int hf_smb_quota_flags_log_warning = -1;
684 static int hf_smb_soft_quota_limit = -1;
685 static int hf_smb_hard_quota_limit = -1;
686 static int hf_smb_user_quota_used = -1;
687 static int hf_smb_length_of_sid = -1;
688 static int hf_smb_user_quota_offset = -1;
689 static int hf_smb_nt_rename_level = -1;
690 static int hf_smb_cluster_count = -1;
691 static int hf_smb_segments = -1;
692 static int hf_smb_segment = -1;
693 static int hf_smb_segment_overlap = -1;
694 static int hf_smb_segment_overlap_conflict = -1;
695 static int hf_smb_segment_multiple_tails = -1;
696 static int hf_smb_segment_too_long_fragment = -1;
697 static int hf_smb_segment_error = -1;
698 static int hf_smb_segment_count = -1;
699 static int hf_smb_reassembled_length = -1;
700 static int hf_smb_pipe_write_len = -1;
701 static int hf_smb_unix_major_version = -1;
702 static int hf_smb_unix_minor_version = -1;
703 static int hf_smb_unix_capability = -1;
704 static int hf_smb_unix_capability_fcntl = -1;
705 static int hf_smb_unix_capability_posix_acl = -1;
706 static int hf_smb_unix_file_link_dest = -1;
707 static int hf_smb_unix_file_size = -1;
708 static int hf_smb_unix_file_num_bytes = -1;
709 static int hf_smb_unix_file_last_status = -1;
710 static int hf_smb_unix_file_last_access = -1;
711 static int hf_smb_unix_file_last_change = -1;
712 static int hf_smb_unix_file_creation_time = -1;
713 static int hf_smb_unix_file_uid = -1;
714 static int hf_smb_unix_file_gid = -1;
715 static int hf_smb_unix_file_type = -1;
716 static int hf_smb_unix_file_dev_major = -1;
717 static int hf_smb_unix_file_dev_minor = -1;
718 static int hf_smb_unix_file_unique_id = -1;
719 static int hf_smb_unix_file_permissions = -1;
720 static int hf_smb_unix_file_nlinks = -1;
721 static int hf_smb_unix_info2_file_flags = -1;
722 static int hf_smb_unix_info2_file_flags_mask = -1;
723 static int hf_smb_unix_info2_file_flags_secure_delete = -1;
724 static int hf_smb_unix_info2_file_flags_enable_undelete = -1;
725 static int hf_smb_unix_info2_file_flags_synchronous = -1;
726 static int hf_smb_unix_info2_file_flags_immutable = -1;
727 static int hf_smb_unix_info2_file_flags_append_only = -1;
728 static int hf_smb_unix_info2_file_flags_do_not_backup = -1;
729 static int hf_smb_unix_info2_file_flags_no_update_atime = -1;
730 static int hf_smb_unix_info2_file_flags_hidden = -1;
731 static int hf_smb_unix_file_name_length = -1;
732 static int hf_smb_unix_file_name = -1;
733 static int hf_smb_unix_find_file_nextoffset = -1;
734 static int hf_smb_unix_find_file_resumekey = -1;
735 static int hf_smb_disposition_delete_on_close = -1;
736 static int hf_smb_pipe_info_flag = -1;
737 static int hf_smb_mode = -1;
738 static int hf_smb_attribute = -1;
739 static int hf_smb_reparse_tag = -1;
740 static int hf_smb_logged_in = -1;
741 static int hf_smb_logged_out = -1;
742 static int hf_smb_file_rw_offset = -1;
743 static int hf_smb_file_rw_length = -1;
744 static int hf_smb_posix_acl_version = -1;
745 static int hf_smb_posix_num_file_aces = -1;
746 static int hf_smb_posix_num_def_aces = -1;
747 static int hf_smb_posix_ace_type = -1;
748 static int hf_smb_posix_ace_flags = -1;
749 static int hf_smb_posix_ace_perm_read = -1;
750 static int hf_smb_posix_ace_perm_write = -1;
751 static int hf_smb_posix_ace_perm_execute = -1;
752 static int hf_smb_posix_ace_perm_owner_uid = -1;
753 static int hf_smb_posix_ace_perm_owner_gid = -1;
754 static int hf_smb_posix_ace_perm_uid = -1;
755 static int hf_smb_posix_ace_perm_gid = -1;
756 static int hf_smb_trans_data_setup_word = -1;
757 static int hf_smb_trans_data_parameters = -1;
758 static int hf_smb_trans_data = -1;
760 static gint ett_smb = -1;
761 static gint ett_smb_fid = -1;
762 static gint ett_smb_tid = -1;
763 static gint ett_smb_uid = -1;
764 static gint ett_smb_hdr = -1;
765 static gint ett_smb_command = -1;
766 static gint ett_smb_fileattributes = -1;
767 static gint ett_smb_capabilities = -1;
768 static gint ett_smb_aflags = -1;
769 static gint ett_smb_dialect = -1;
770 static gint ett_smb_dialects = -1;
771 static gint ett_smb_mode = -1;
772 static gint ett_smb_rawmode = -1;
773 static gint ett_smb_flags = -1;
774 static gint ett_smb_flags2 = -1;
775 static gint ett_smb_desiredaccess = -1;
776 static gint ett_smb_search = -1;
777 static gint ett_smb_file = -1;
778 static gint ett_smb_openfunction = -1;
779 static gint ett_smb_filetype = -1;
780 static gint ett_smb_openaction = -1;
781 static gint ett_smb_writemode = -1;
782 static gint ett_smb_lock_type = -1;
783 static gint ett_smb_ssetupandxaction = -1;
784 static gint ett_smb_optionsup = -1;
785 static gint ett_smb_time_date = -1;
786 static gint ett_smb_move_copy_flags = -1;
787 static gint ett_smb_file_attributes = -1;
788 static gint ett_smb_search_resume_key = -1;
789 static gint ett_smb_search_dir_info = -1;
790 static gint ett_smb_unlocks = -1;
791 static gint ett_smb_unlock = -1;
792 static gint ett_smb_locks = -1;
793 static gint ett_smb_lock = -1;
794 static gint ett_smb_open_flags = -1;
795 static gint ett_smb_ipc_state = -1;
796 static gint ett_smb_open_action = -1;
797 static gint ett_smb_setup_action = -1;
798 static gint ett_smb_connect_flags = -1;
799 static gint ett_smb_connect_support_bits = -1;
800 static gint ett_smb_nt_access_mask = -1;
801 static gint ett_smb_nt_create_bits = -1;
802 static gint ett_smb_nt_create_options = -1;
803 static gint ett_smb_nt_share_access = -1;
804 static gint ett_smb_nt_security_flags = -1;
805 static gint ett_smb_nt_trans_setup = -1;
806 static gint ett_smb_nt_trans_data = -1;
807 static gint ett_smb_nt_trans_param = -1;
808 static gint ett_smb_nt_notify_completion_filter = -1;
809 static gint ett_smb_nt_ioctl_flags = -1;
810 static gint ett_smb_security_information_mask = -1;
811 static gint ett_smb_print_queue_entry = -1;
812 static gint ett_smb_transaction_flags = -1;
813 static gint ett_smb_transaction_params = -1;
814 static gint ett_smb_find_first2_flags = -1;
815 static gint ett_smb_mac_support_flags = -1;
816 #if 0
817 static gint ett_smb_ioflag = -1;
818 #endif
819 static gint ett_smb_transaction_data = -1;
820 static gint ett_smb_stream_info = -1;
821 static gint ett_smb_dfs_referrals = -1;
822 static gint ett_smb_dfs_referral = -1;
823 static gint ett_smb_dfs_referral_flags = -1;
824 static gint ett_smb_dfs_referral_expnames = -1;
825 static gint ett_smb_get_dfs_flags = -1;
826 static gint ett_smb_ff2_data = -1;
827 static gint ett_smb_device_characteristics = -1;
828 static gint ett_smb_fs_attributes = -1;
829 static gint ett_smb_segments = -1;
830 static gint ett_smb_segment = -1;
831 static gint ett_smb_quotaflags = -1;
832 static gint ett_smb_secblob = -1;
833 static gint ett_smb_unicode_password = -1;
834 static gint ett_smb_ea = -1;
835 static gint ett_smb_unix_capabilities = -1;
836 static gint ett_smb_posix_ace = -1;
837 static gint ett_smb_posix_ace_perms = -1;
838 static gint ett_smb_info2_file_flags = -1;
840 static expert_field ei_smb_mal_information_level = EI_INIT;
841 static expert_field ei_smb_not_implemented = EI_INIT;
843 static int smb_tap = -1;
844 static int smb_eo_tap = -1;
846 static dissector_handle_t gssapi_handle;
847 static dissector_handle_t ntlmssp_handle;
849 static const fragment_items smb_frag_items = {
850 &ett_smb_segment,
851 &ett_smb_segments,
853 &hf_smb_segments,
854 &hf_smb_segment,
855 &hf_smb_segment_overlap,
856 &hf_smb_segment_overlap_conflict,
857 &hf_smb_segment_multiple_tails,
858 &hf_smb_segment_too_long_fragment,
859 &hf_smb_segment_error,
860 &hf_smb_segment_count,
861 NULL,
862 &hf_smb_reassembled_length,
863 /* Reassembled data field */
864 NULL,
865 "segments"
868 static proto_tree *top_tree_global = NULL; /* ugly */
870 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu, smb_info_t *si);
873 * Macros for use in the main dissector routines for an SMB.
876 #define WORD_COUNT \
877 /* Word Count */ \
878 wc = tvb_get_guint8(tvb, offset); \
879 proto_tree_add_uint(tree, hf_smb_word_count, \
880 tvb, offset, 1, wc); \
881 offset += 1; \
882 if (wc == 0) goto bytecount;
884 #define BYTE_COUNT \
885 bytecount: \
886 bc = tvb_get_letohs(tvb, offset); \
887 proto_tree_add_uint(tree, hf_smb_byte_count, \
888 tvb, offset, 2, bc); \
889 offset += 2; \
890 if (bc == 0) goto endofcommand;
892 #define CHECK_BYTE_COUNT(len) \
893 if (bc < len) goto endofcommand;
895 #define COUNT_BYTES(len) {\
896 int tmp; \
897 tmp = len; \
898 offset += tmp; \
899 bc -= tmp; \
902 #define END_OF_SMB \
903 if (bc != 0) { \
904 gint bc_remaining; \
905 bc_remaining = tvb_length_remaining(tvb, offset); \
906 if ( ((gint)bc) > bc_remaining) { \
907 bc = bc_remaining; \
909 if (bc) { \
910 tvb_ensure_bytes_exist(tvb, offset, bc); \
911 proto_tree_add_text(tree, tvb, offset, bc, \
912 "Extra byte parameters"); \
914 offset += bc; \
916 endofcommand:
919 * Macros for use in routines called by them.
921 #define CHECK_BYTE_COUNT_SUBR(len) \
922 if (*bcp < len) { \
923 *trunc = TRUE; \
924 return offset; \
927 #define CHECK_STRING_SUBR(fn) \
928 if (fn == NULL) { \
929 *trunc = TRUE; \
930 return offset; \
933 #define COUNT_BYTES_SUBR(len) \
934 offset += len; \
935 *bcp -= len;
938 * Macros for use when dissecting transaction parameters and data
940 #define CHECK_BYTE_COUNT_TRANS(len) \
941 if (bc < len) return offset;
943 #define CHECK_STRING_TRANS(fn) \
944 if (fn == NULL) return offset;
946 #define COUNT_BYTES_TRANS(len) \
947 offset += len; \
948 bc -= len;
951 * Macros for use in subrroutines dissecting transaction parameters or data
953 #define CHECK_BYTE_COUNT_TRANS_SUBR(len) \
954 if (*bcp < len) return offset;
956 #define CHECK_STRING_TRANS_SUBR(fn) \
957 if (fn == NULL) return offset;
959 #define COUNT_BYTES_TRANS_SUBR(len) \
960 offset += len; \
961 *bcp -= len;
963 gboolean sid_display_hex = FALSE;
964 gboolean sid_name_snooping = FALSE;
966 /* ExportObject preferences variable */
967 gboolean eosmb_take_name_as_fid = FALSE ;
968 /* Utility to get an str reprensenting ipv4 or ipv6 address */
969 const gchar *tree_ip_str(packet_info *pinfo, guint16 cmd) {
970 const gchar *buf;
972 if (pinfo->src.type==AT_IPv4) {
973 if ( cmd==SMB_COM_READ_ANDX ||
974 cmd==SMB_COM_READ ||
975 cmd==SMB2_COM_READ) {
976 buf=(gchar *)ip_to_str((const guint8 *)pinfo->src.data);
977 } else {
978 buf=(gchar *)ip_to_str((const guint8 *)pinfo->dst.data);
980 } else {
981 if ( cmd==SMB_COM_READ_ANDX ||
982 cmd==SMB_COM_READ ||
983 cmd==SMB2_COM_READ) {
984 buf=(gchar *)ip6_to_str((const struct e_in6_addr *)pinfo->src.data);
985 } else {
986 buf=(gchar *)ip6_to_str((const struct e_in6_addr *)pinfo->dst.data);
990 return buf;
994 /* ExportObject feed function*/
995 static void
996 feed_eo_smb(guint16 cmd, guint16 fid, tvbuff_t * tvb,packet_info *pinfo,guint16 dataoffset,guint32 datalen, guint32 chunk_len,
997 guint64 file_offset, smb_info_t *si) {
998 smb_eo_t *eo_info; /* eo_info variable to pass info. to
999 export object and aux */
1000 smb_tid_info_t *tid_info = NULL;
1001 smb_fid_info_t *fid_info = NULL;
1002 smb_fid_info_t *suspect_fid_info = NULL;
1003 tvbuff_t *data_tvb;
1004 GSList *GSL_iterator;
1006 /* Create a new tvb to point to the payload data */
1007 data_tvb = tvb_new_subset(tvb, dataoffset, datalen, datalen);
1008 /* Create the eo_info to pass to the listener */
1009 eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
1011 /* Try to get fid_info and tid_info */
1012 if (fid_info == NULL) {
1013 GSL_iterator = si->ct->GSL_fid_info;
1014 while (GSL_iterator) {
1015 suspect_fid_info = (smb_fid_info_t *)GSL_iterator->data;
1016 if (suspect_fid_info->opened_in > pinfo->fd->num) break;
1017 if ((suspect_fid_info->tid == si->tid) && (suspect_fid_info->fid == fid))
1018 fid_info = suspect_fid_info;
1019 GSL_iterator = g_slist_next(GSL_iterator);
1024 tid_info = (smb_tid_info_t *)wmem_tree_lookup32(si->ct->tid_tree, si->tid);
1026 /* Construct the eo_info structure */
1027 eo_info->smbversion=1;
1028 if (tid_info) {
1029 if (tid_info->filename) {
1030 eo_info->hostname = tid_info->filename;
1031 } else {
1032 eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN",tree_ip_str(pinfo,cmd));
1035 else eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i",tree_ip_str(pinfo,cmd),si->tid);
1036 if (fid_info) {
1037 eo_info->filename = NULL;
1038 if (fid_info->fsi)
1039 if (fid_info->fsi->filename)
1040 eo_info->filename = (gchar *) fid_info->fsi->filename;
1041 if (!eo_info->filename) eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\FILEID_%i",fid);
1042 eo_info->fid_type = fid_info->type;
1043 eo_info->end_of_file = fid_info->end_of_file;
1044 } else {
1045 eo_info->fid_type = SMB_FID_TYPE_UNKNOWN;
1046 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\FILEID_%i",fid);
1047 eo_info->end_of_file = 0;
1049 if (eosmb_take_name_as_fid) {
1050 eo_info->fid = g_str_hash(eo_info->filename);
1051 } else {
1052 eo_info->fid = fid;
1054 eo_info->tid = si->tid;
1055 eo_info->uid = si->uid;
1056 eo_info->payload_len = datalen;
1057 eo_info->payload_data = tvb_get_ptr(data_tvb, 0, datalen);
1058 eo_info->smb_file_offset = file_offset;
1059 eo_info->smb_chunk_len = chunk_len;
1060 eo_info->cmd = cmd;
1061 /* Queue data to the listener */
1063 tap_queue_packet(smb_eo_tap, pinfo, eo_info);
1064 } /* feed_eo_smb */
1066 /* Compare funtion to maintain the GSL_fid_info ordered
1067 Order criteria: packet where the fid was opened */
1068 static gint
1069 fid_cmp(smb_fid_info_t *fida, smb_fid_info_t *fidb)
1071 return (fida->opened_in - fidb->opened_in);
1074 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1075 These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
1076 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1077 static gboolean smb_trans_reassembly = TRUE;
1078 gboolean smb_dcerpc_reassembly = TRUE;
1080 static reassembly_table smb_trans_reassembly_table;
1082 static void
1083 smb_trans_reassembly_init(void)
1086 * XXX - addresses_ports_reassembly_table_functions?
1087 * Probably correct for SMB-over-NBT and SMB-over-TCP,
1088 * as stuff from two different connections should
1089 * probably not be combined, but what about other
1090 * transports for SMB, e.g. NBF or Netware?
1092 reassembly_table_init(&smb_trans_reassembly_table,
1093 &addresses_reassembly_table_functions);
1096 static fragment_head *
1097 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
1098 int offset, guint count, guint pos, guint totlen, smb_info_t *si)
1100 fragment_head *fd_head = NULL;
1101 int more_frags;
1103 /* Don't pass the reassembly code data that doesn't exist */
1104 /* Fail if some or all of the fragment is located beyond the total length */
1105 if ( !tvb_bytes_exist(tvb, offset, count) || (pos > totlen) || (count > totlen) || ((pos + count) > totlen)) {
1106 THROW(ReportedBoundsError);
1109 more_frags = totlen > (pos + count);
1111 DISSECTOR_ASSERT(si);
1113 if (si->sip == NULL) {
1115 * We don't have the frame number of the request.
1117 return NULL;
1120 if (!pinfo->fd->flags.visited) {
1121 fd_head = fragment_add(&smb_trans_reassembly_table, tvb, offset,
1122 pinfo, si->sip->frame_req, NULL,
1123 pos, count, more_frags);
1124 } else {
1125 fd_head = fragment_get(&smb_trans_reassembly_table,
1126 pinfo, si->sip->frame_req, NULL);
1129 if (!fd_head || !(fd_head->flags & FD_DEFRAGMENTED)) {
1130 /* This is continued - mark it as such, so we recognize
1131 continuation responses.
1133 si->sip->flags |= SMB_SIF_IS_CONTINUED;
1134 } else {
1135 /* We've finished reassembling, so there are no more
1136 continuation responses.
1138 si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
1141 /* we only show the defragmented packet for the first fragment,
1142 or else we might end up with dissecting one HUGE transaction PDU
1143 a LOT of times. (first fragment is the only one containing the setup
1144 bytes)
1145 I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
1146 SMBs. Takes a LOT of time dissecting and is not fun.
1148 if ( (pos == 0) && fd_head && (fd_head->flags & FD_DEFRAGMENTED)) {
1149 return fd_head;
1150 } else {
1151 return NULL;
1159 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1160 These variables and functions are used to match
1161 responses with calls
1162 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1164 * The information we need to save about a request in order to show the
1165 * frame number of the request in the dissection of the reply.
1167 typedef struct {
1168 guint32 frame;
1169 guint32 pid_mid;
1170 } smb_saved_info_key_t;
1172 /* unmatched smb_saved_info structures.
1173 For unmatched smb_saved_info structures we store the smb_saved_info
1174 structure using the MID and the PID as the key.
1176 Oh, yes, the key is really a pointer, but we use it as if it was an integer.
1177 Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
1178 The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
1180 static gint
1181 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
1183 register guint32 key1 = GPOINTER_TO_UINT(k1);
1184 register guint32 key2 = GPOINTER_TO_UINT(k2);
1185 return key1 == key2;
1187 static guint
1188 smb_saved_info_hash_unmatched(gconstpointer k)
1190 register guint32 key = GPOINTER_TO_UINT(k);
1191 return key;
1194 /* matched smb_saved_info structures.
1195 For matched smb_saved_info structures we store the smb_saved_info
1196 structure twice in the table using the frame number, and a combination
1197 of the MID and the PID, as the key.
1198 The frame number is guaranteed to be unique but if ever someone makes
1199 some change that will renumber the frames in a capture we are in BIG trouble.
1200 This is not likely though since that would break (among other things) all the
1201 reassembly routines as well.
1203 We also need the MID as there may be more than one SMB request or reply
1204 in a single frame, and we also need the PID as there may be more than
1205 one outstanding request with the same MID and different PIDs.
1207 static gint
1208 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1210 const smb_saved_info_key_t *key1 = (const smb_saved_info_key_t *)k1;
1211 const smb_saved_info_key_t *key2 = (const smb_saved_info_key_t *)k2;
1212 return (key1->frame == key2->frame) && (key1->pid_mid == key2->pid_mid);
1214 static guint
1215 smb_saved_info_hash_matched(gconstpointer k)
1217 const smb_saved_info_key_t *key = (const smb_saved_info_key_t *)k;
1218 return key->frame + key->pid_mid;
1221 static GSList *conv_tables = NULL;
1224 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1225 End of request/response matching functions
1226 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1230 typedef struct _smb_uid_t {
1231 char *domain;
1232 char *account;
1233 int logged_in;
1234 int logged_out;
1235 } smb_uid_t;
1237 static void
1238 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1240 mask &= 0x0000ffff;
1241 if (mask == 0x000001ff) {
1242 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1246 proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_attribute, tvb, offset, 4, mask);
1247 proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_attribute, tvb, offset, 4, mask);
1248 proto_tree_add_boolean(tree, hf_smb_file_access_mask_execute, tvb, offset, 4, mask);
1249 proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_ea, tvb, offset, 4, mask);
1250 proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_ea, tvb, offset, 4, mask);
1251 proto_tree_add_boolean(tree, hf_smb_file_access_mask_append_data, tvb, offset, 4, mask);
1252 proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_data, tvb, offset, 4, mask);
1253 proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_data, tvb, offset, 4, mask);
1255 struct access_mask_info smb_file_access_mask_info = {
1256 "FILE", /* Name of specific rights */
1257 smb_file_specific_rights, /* Dissection function */
1258 NULL, /* Generic mapping table */
1259 NULL /* Standard mapping table */
1263 static void
1264 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1266 mask &= 0x0000ffff;
1267 if (mask == 0x000001ff) {
1268 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1272 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_attribute, tvb, offset, 4, mask);
1273 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_attribute, tvb, offset, 4, mask);
1274 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_delete_child, tvb, offset, 4, mask);
1275 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_traverse, tvb, offset, 4, mask);
1276 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_ea, tvb, offset, 4, mask);
1277 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_ea, tvb, offset, 4, mask);
1278 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_subdir, tvb, offset, 4, mask);
1279 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_file, tvb, offset, 4, mask);
1280 proto_tree_add_boolean(tree, hf_smb_dir_access_mask_list, tvb, offset, 4, mask);
1282 struct access_mask_info smb_dir_access_mask_info = {
1283 "DIR", /* Name of specific rights */
1284 smb_dir_specific_rights, /* Dissection function */
1285 NULL, /* Generic mapping table */
1286 NULL /* Standard mapping table */
1291 static const value_string buffer_format_vals[] = {
1292 {1, "Data Block"},
1293 {2, "Dialect"},
1294 {3, "Pathname"},
1295 {4, "ASCII"},
1296 {5, "Variable Block"},
1297 {0, NULL}
1300 #define POSIX_ACE_TYPE_USER_OBJ 0x01
1301 #define POSIX_ACE_TYPE_USER 0x02
1302 #define POSIX_ACE_TYPE_GROUP_OBJ 0x04
1303 #define POSIX_ACE_TYPE_GROUP 0x08
1304 #define POSIX_ACE_TYPE_MASK 0x10
1305 #define POSIX_ACE_TYPE_OTHER 0x20
1306 static const value_string ace_type_vals[] = {
1307 {POSIX_ACE_TYPE_USER_OBJ, "User Obj"},
1308 {POSIX_ACE_TYPE_USER, "User"},
1309 {POSIX_ACE_TYPE_GROUP_OBJ, "Group Obj"},
1310 {POSIX_ACE_TYPE_GROUP, "Group"},
1311 {POSIX_ACE_TYPE_MASK, "Mask"},
1312 {POSIX_ACE_TYPE_OTHER, "Other"},
1313 {0, NULL}
1317 * UTIME - this is *almost* like a UNIX time stamp, except that it's
1318 * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1319 * January 1, 1970, 00:00:00 GMT.
1321 * This means we have to do some extra work to convert it. This code is
1322 * based on the Samba code:
1324 * Unix SMB/Netbios implementation.
1325 * Version 1.9.
1326 * time handling functions
1327 * Copyright (C) Andrew Tridgell 1992-1998
1331 * Yield the difference between *A and *B, in seconds, ignoring leap
1332 * seconds.
1334 #define TM_YEAR_BASE 1900
1336 static int
1337 tm_diff(struct tm *a, struct tm *b)
1339 int ay = a->tm_year + (TM_YEAR_BASE - 1);
1340 int by = b->tm_year + (TM_YEAR_BASE - 1);
1341 int intervening_leap_days =
1342 (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1343 int years = ay - by;
1344 int days =
1345 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1346 int hours = 24*days + (a->tm_hour - b->tm_hour);
1347 int minutes = 60*hours + (a->tm_min - b->tm_min);
1348 int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1350 return seconds;
1354 * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1355 * determined.
1357 static int
1358 TimeZone(time_t t)
1360 struct tm *tm = gmtime(&t);
1361 struct tm tm_utc;
1363 if (tm == NULL)
1364 return 0;
1365 tm_utc = *tm;
1366 tm = localtime(&t);
1367 if (tm == NULL)
1368 return 0;
1369 return tm_diff(&tm_utc,tm);
1373 * Return the same value as TimeZone, but it should be more efficient.
1375 * We keep a table of DST offsets to prevent calling localtime() on each
1376 * call of this function. This saves a LOT of time on many unixes.
1378 * Updated by Paul Eggert <eggert@twinsun.com>
1380 #ifndef CHAR_BIT
1381 #define CHAR_BIT 8
1382 #endif
1384 #ifndef TIME_T_MIN
1385 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1386 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1387 #endif
1388 #ifndef TIME_T_MAX
1389 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1390 #endif
1392 static int
1393 TimeZoneFaster(time_t t)
1395 static struct dst_table {time_t start,end; int zone;} *tdt;
1396 static struct dst_table *dst_table = NULL;
1397 static int table_size = 0;
1398 int i;
1399 int zone = 0;
1401 if (t == 0)
1402 t = time(NULL);
1404 /* Tunis has a 8 day DST region, we need to be careful ... */
1405 #define MAX_DST_WIDTH (365*24*60*60)
1406 #define MAX_DST_SKIP (7*24*60*60)
1408 for (i = 0; i < table_size; i++) {
1409 if ((t >= dst_table[i].start) && (t <= dst_table[i].end))
1410 break;
1413 if (i < table_size) {
1414 zone = dst_table[i].zone;
1415 } else {
1416 time_t low,high;
1418 zone = TimeZone(t);
1419 if (dst_table == NULL)
1420 tdt = (struct dst_table *)g_malloc(sizeof(dst_table[0])*(i+1));
1421 else
1422 tdt = (struct dst_table *)g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1423 if (tdt == NULL) {
1424 g_free(dst_table);
1425 table_size = 0;
1426 } else {
1427 dst_table = tdt;
1428 table_size++;
1430 dst_table[i].zone = zone;
1431 dst_table[i].start = dst_table[i].end = t;
1433 /* no entry will cover more than 6 months */
1434 low = t - MAX_DST_WIDTH/2;
1435 /* XXX - what if t < MAX_DST_WIDTH/2? */
1437 high = t + MAX_DST_WIDTH/2;
1438 /* XXX - what if this overflows? */
1441 * Widen the new entry using two bisection searches.
1443 while (low+60*60 < dst_table[i].start) {
1444 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1445 t = dst_table[i].start - MAX_DST_SKIP;
1446 else
1447 t = low + (dst_table[i].start-low)/2;
1448 if (TimeZone(t) == zone)
1449 dst_table[i].start = t;
1450 else
1451 low = t;
1454 while (high-60*60 > dst_table[i].end) {
1455 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1456 t = dst_table[i].end + MAX_DST_SKIP;
1457 else
1458 t = high - (high-dst_table[i].end)/2;
1459 if (TimeZone(t) == zone)
1460 dst_table[i].end = t;
1461 else
1462 high = t;
1466 return zone;
1470 * Return the UTC offset in seconds west of UTC, adjusted for extra time
1471 * offset, for a local time value. If ut = lt + LocTimeDiff(lt), then
1472 * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1473 * daylight savings transitions because some local times are ambiguous.
1474 * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1476 static int
1477 LocTimeDiff(time_t lt)
1479 int d = TimeZoneFaster(lt);
1480 time_t t = lt + d;
1482 /* if overflow occurred, ignore all the adjustments so far */
1483 if (((t < lt) ^ (d < 0)))
1484 t = lt;
1487 * Now t should be close enough to the true UTC to yield the
1488 * right answer.
1490 return TimeZoneFaster(t);
1493 static int
1494 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1496 guint32 timeval;
1497 nstime_t ts;
1499 ts.secs = timeval = tvb_get_letohl(tvb, offset);
1500 ts.nsecs = 0;
1501 if (timeval == 0xffffffff) {
1502 proto_tree_add_time_format_value(tree, hf_date, tvb, offset, 4, &ts,
1503 "No time specified (0xffffffff)");
1504 offset += 4;
1505 return offset;
1509 * We add the local time offset.
1511 ts.secs = timeval + LocTimeDiff(timeval);
1513 proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1514 offset += 4;
1516 return offset;
1519 static int
1520 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1521 int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1523 guint16 dos_time, dos_date;
1524 proto_item *item = NULL;
1525 proto_tree *tree = NULL;
1526 struct tm tm;
1527 time_t t;
1528 nstime_t tv;
1530 static const int mday_noleap[12] = {
1531 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1533 static const int mday_leap[12] = {
1534 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1537 #define ISLEAP(y) ((((y) % 4) == 0) && ((((y) % 100) != 0) || (((y) % 400) == 0)))
1539 if (time_first) {
1540 dos_time = tvb_get_letohs(tvb, offset);
1541 dos_date = tvb_get_letohs(tvb, offset+2);
1542 } else {
1543 dos_date = tvb_get_letohs(tvb, offset);
1544 dos_time = tvb_get_letohs(tvb, offset+2);
1547 if (((dos_date == 0xffff) && (dos_time == 0xffff)) ||
1548 ((dos_date == 0) && (dos_time == 0))) {
1550 * No date/time specified.
1552 if (parent_tree) {
1553 tv.secs = 0;
1554 tv.nsecs = 0;
1555 proto_tree_add_time_format_value(parent_tree, hf_date, tvb, offset, 4,
1556 &tv, "No time specified (0x%08x)",
1557 ((dos_date << 16) | dos_time));
1559 offset += 4;
1560 return offset;
1563 tm.tm_sec = (dos_time & 0x1f) * 2;
1564 tm.tm_min = (dos_time>>5) & 0x3f;
1565 tm.tm_hour = (dos_time>>11) & 0x1f;
1566 tm.tm_mday = dos_date & 0x1f;
1567 tm.tm_mon = ((dos_date>>5) & 0x0f) - 1;
1568 tm.tm_year = ((dos_date>>9) & 0x7f) + 1980 - 1900;
1569 tm.tm_isdst = -1;
1572 * Do some sanity checks before calling "mktime()";
1573 * "mktime()" doesn't do them, it "normalizes" out-of-range
1574 * values.
1576 if ((tm.tm_sec > 59) || (tm.tm_min > 59) || (tm.tm_hour > 23) ||
1577 (tm.tm_mon < 0) || (tm.tm_mon > 11) ||
1578 (ISLEAP(tm.tm_year + 1900) ?
1579 (tm.tm_mday > mday_leap[tm.tm_mon]) :
1580 (tm.tm_mday > mday_noleap[tm.tm_mon])) ||
1581 ((t = mktime(&tm)) == -1)) {
1583 * Invalid date/time.
1585 if (parent_tree) {
1586 tv.secs = 0;
1587 tv.nsecs = 0;
1588 item = proto_tree_add_time_format_value(parent_tree, hf_date, tvb, offset, 4,
1589 &tv, "Invalid time (0x%08x)", ((dos_date << 16) | dos_time));
1590 tree = proto_item_add_subtree(item, ett_smb_time_date);
1591 if (time_first) {
1592 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1593 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1594 } else {
1595 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1596 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1599 offset += 4;
1600 return offset;
1603 tv.secs = t;
1604 tv.nsecs = 0;
1606 if (parent_tree) {
1607 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1608 tree = proto_item_add_subtree(item, ett_smb_time_date);
1609 if (time_first) {
1610 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1611 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1612 } else {
1613 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1614 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1618 offset += 4;
1620 return offset;
1623 static const true_false_string tfs_disposition_delete_on_close = {
1624 "DELETE this file when closed",
1625 "Normal access, do not delete on close"
1628 static const true_false_string tfs_pipe_info_flag = {
1629 "SET NAMED PIPE mode",
1630 "Clear NAMED PIPE mode"
1634 static const value_string da_access_vals[] = {
1635 { 0, "Open for reading"},
1636 { 1, "Open for writing"},
1637 { 2, "Open for reading and writing"},
1638 { 3, "Open for execute"},
1639 {0, NULL}
1641 static const value_string da_sharing_vals[] = {
1642 { 0, "Compatibility mode"},
1643 { 1, "Deny read/write/execute (exclusive)"},
1644 { 2, "Deny write"},
1645 { 3, "Deny read/execute"},
1646 { 4, "Deny none"},
1647 {0, NULL}
1649 static const value_string da_locality_vals[] = {
1650 { 0, "Locality of reference unknown"},
1651 { 1, "Mainly sequential access"},
1652 { 2, "Mainly random access"},
1653 { 3, "Random access with some locality"},
1654 {0, NULL}
1656 static const true_false_string tfs_da_caching = {
1657 "Do not cache this file",
1658 "Caching permitted on this file"
1660 static const true_false_string tfs_da_writetru = {
1661 "Write through enabled",
1662 "Write through disabled"
1664 static int
1665 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1667 guint16 mask;
1668 proto_item *item;
1669 proto_tree *tree;
1671 mask = tvb_get_letohs(tvb, offset);
1673 if (parent_tree) {
1674 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1675 "%s Access: 0x%04x", type, mask);
1676 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1678 proto_tree_add_boolean(tree, hf_smb_access_writetru,
1679 tvb, offset, 2, mask);
1680 proto_tree_add_boolean(tree, hf_smb_access_caching,
1681 tvb, offset, 2, mask);
1682 proto_tree_add_uint(tree, hf_smb_access_locality,
1683 tvb, offset, 2, mask);
1684 proto_tree_add_uint(tree, hf_smb_access_sharing,
1685 tvb, offset, 2, mask);
1686 proto_tree_add_uint(tree, hf_smb_access_mode,
1687 tvb, offset, 2, mask);
1690 offset += 2;
1692 return offset;
1695 #define SMB_FILE_ATTRIBUTE_READ_ONLY 0x00000001
1696 #define SMB_FILE_ATTRIBUTE_HIDDEN 0x00000002
1697 #define SMB_FILE_ATTRIBUTE_SYSTEM 0x00000004
1698 #define SMB_FILE_ATTRIBUTE_VOLUME 0x00000008
1699 #define SMB_FILE_ATTRIBUTE_DIRECTORY 0x00000010
1700 #define SMB_FILE_ATTRIBUTE_ARCHIVE 0x00000020
1701 #define SMB_FILE_ATTRIBUTE_DEVICE 0x00000040
1702 #define SMB_FILE_ATTRIBUTE_NORMAL 0x00000080
1703 #define SMB_FILE_ATTRIBUTE_TEMPORARY 0x00000100
1704 #define SMB_FILE_ATTRIBUTE_SPARSE 0x00000200
1705 #define SMB_FILE_ATTRIBUTE_REPARSE 0x00000400
1706 #define SMB_FILE_ATTRIBUTE_COMPRESSED 0x00000800
1707 #define SMB_FILE_ATTRIBUTE_OFFLINE 0x00001000
1708 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
1709 #define SMB_FILE_ATTRIBUTE_ENCRYPTED 0x00004000
1711 static const true_false_string tfs_file_attribute_read_only = {
1712 "READ ONLY",
1713 "NOT read only",
1715 static const true_false_string tfs_file_attribute_hidden = {
1716 "HIDDEN",
1717 "NOT hidden"
1719 static const true_false_string tfs_file_attribute_system = {
1720 "SYSTEM file/dir",
1721 "NOT a system file/dir"
1723 static const true_false_string tfs_file_attribute_volume = {
1724 "VOLUME ID",
1725 "NOT a volume ID"
1727 static const true_false_string tfs_file_attribute_directory = {
1728 "DIRECTORY",
1729 "NOT a directory"
1731 static const true_false_string tfs_file_attribute_archive = {
1732 "Modified since last ARCHIVE",
1733 "Has NOT been modified since last archive"
1735 static const true_false_string tfs_file_attribute_device = {
1736 "A DEVICE",
1737 "NOT a device"
1739 static const true_false_string tfs_file_attribute_normal = {
1740 "An ordinary file/dir",
1741 "Has some attribute set"
1743 static const true_false_string tfs_file_attribute_temporary = {
1744 "A TEMPORARY file",
1745 "NOT a temporary file"
1747 static const true_false_string tfs_file_attribute_sparse = {
1748 "A SPARSE file",
1749 "NOT a sparse file"
1751 static const true_false_string tfs_file_attribute_reparse = {
1752 "Has an associated REPARSE POINT",
1753 "Does NOT have an associated reparse point"
1755 static const true_false_string tfs_file_attribute_compressed = {
1756 "COMPRESSED",
1757 "Uncompressed"
1759 static const true_false_string tfs_file_attribute_offline = {
1760 "OFFLINE",
1761 "Online"
1763 static const true_false_string tfs_file_attribute_not_content_indexed = {
1764 "CONTENT INDEXED",
1765 "NOT content indexed"
1767 static const true_false_string tfs_file_attribute_encrypted = {
1768 "This is an ENCRYPTED file",
1769 "This is NOT an encrypted file"
1773 * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
1774 * section 2.2.1.2.4 of [MS-CIFS], in cases where it's just file attributes,
1775 * not search attributes.
1777 static int
1778 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1780 guint16 mask;
1781 proto_item *item;
1782 proto_tree *tree;
1784 mask = tvb_get_letohs(tvb, offset);
1786 if (parent_tree) {
1787 item = proto_tree_add_item(parent_tree, hf_smb_file_attr_16bit, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1788 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1790 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1791 tvb, offset, 2, mask);
1792 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1793 tvb, offset, 2, mask);
1794 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1795 tvb, offset, 2, mask);
1796 proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1797 tvb, offset, 2, mask);
1798 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1799 tvb, offset, 2, mask);
1800 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1801 tvb, offset, 2, mask);
1804 offset += 2;
1806 return offset;
1810 * 3.11 in the SNIA CIFS spec
1811 * SMB_EXT_FILE_ATTR, section 2.2.1.2.3 in the [MS-CIFS] spec
1813 static int
1814 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1815 int len, guint32 mask)
1817 proto_item *item;
1818 proto_tree *tree;
1820 if (parent_tree) {
1821 item = proto_tree_add_uint(parent_tree, hf_smb_file_eattr, tvb, offset, len, mask);
1822 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1823 if (len==0)
1824 PROTO_ITEM_SET_GENERATED(item);
1826 * XXX - Network Monitor disagrees on some of the
1827 * bits, e.g. the bits above temporary are "atomic write"
1828 * and "transaction write", and it says nothing about the
1829 * bits above that.
1831 * Does the Win32 API documentation, or the NT Native API book,
1832 * suggest anything?
1834 proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1835 tvb, offset, len, mask);
1836 proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1837 tvb, offset, len, mask);
1838 proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1839 tvb, offset, len, mask);
1840 proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1841 tvb, offset, len, mask);
1842 proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1843 tvb, offset, len, mask);
1844 proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1845 tvb, offset, len, mask);
1846 proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1847 tvb, offset, len, mask);
1848 proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1849 tvb, offset, len, mask);
1850 proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1851 tvb, offset, len, mask);
1852 proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1853 tvb, offset, len, mask);
1854 proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1855 tvb, offset, len, mask);
1856 proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1857 tvb, offset, len, mask);
1858 proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1859 tvb, offset, len, mask);
1860 proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1861 tvb, offset, len, mask);
1862 proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1863 tvb, offset, len, mask);
1866 offset += len;
1868 return offset;
1871 /* 3.11 */
1873 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1875 guint32 mask;
1877 mask = tvb_get_letohl(tvb, offset);
1879 offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
1881 return offset;
1884 static int
1885 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1887 guint8 mask;
1888 proto_item *item;
1889 proto_tree *tree;
1891 mask = tvb_get_guint8(tvb, offset);
1893 if (parent_tree) {
1894 item = proto_tree_add_item(parent_tree, hf_smb_file_attr_8bit, tvb, offset, 1, ENC_NA);
1895 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1897 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1898 tvb, offset, 1, mask);
1899 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1900 tvb, offset, 1, mask);
1901 proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1902 tvb, offset, 1, mask);
1903 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1904 tvb, offset, 1, mask);
1905 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1906 tvb, offset, 1, mask);
1907 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1908 tvb, offset, 1, mask);
1911 offset += 1;
1913 return offset;
1916 static const true_false_string tfs_search_attribute_read_only = {
1917 "Include READ ONLY files in search results",
1918 "Do NOT include read only files in search results",
1920 static const true_false_string tfs_search_attribute_hidden = {
1921 "Include HIDDEN files in search results",
1922 "Do NOT include hidden files in search results"
1924 static const true_false_string tfs_search_attribute_system = {
1925 "Include SYSTEM files in search results",
1926 "Do NOT include system files in search results"
1928 static const true_false_string tfs_search_attribute_volume = {
1929 "Include VOLUME IDs in search results",
1930 "Do NOT include volume IDs in search results"
1932 static const true_false_string tfs_search_attribute_directory = {
1933 "Include DIRECTORIES in search results",
1934 "Do NOT include directories in search results"
1936 static const true_false_string tfs_search_attribute_archive = {
1937 "Include ARCHIVE files in search results",
1938 "Do NOT include archive files in search results"
1942 * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
1943 * section 2.2.1.2.4 of [MS-CIFS], in cases where it's search attributes.
1945 static int
1946 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1948 guint16 mask;
1949 proto_item *item;
1950 proto_tree *tree;
1952 mask = tvb_get_letohs(tvb, offset);
1954 if (parent_tree) {
1955 item = proto_tree_add_item(parent_tree, hf_smb_search_attribute, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1956 tree = proto_item_add_subtree(item, ett_smb_search);
1958 proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1959 tvb, offset, 2, mask);
1960 proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1961 tvb, offset, 2, mask);
1962 proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1963 tvb, offset, 2, mask);
1964 proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1965 tvb, offset, 2, mask);
1966 proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1967 tvb, offset, 2, mask);
1968 proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1969 tvb, offset, 2, mask);
1972 offset += 2;
1973 return offset;
1976 #if 0
1978 * XXX - this isn't used.
1979 * Is this used for anything? NT Create AndX doesn't use it.
1980 * Is there some 16-bit attribute field with more bits than Read Only,
1981 * Hidden, System, Volume ID, Directory, and Archive?
1983 static int
1984 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1986 guint32 mask;
1987 proto_item *item;
1988 proto_tree *tree;
1990 mask = tvb_get_letohl(tvb, offset);
1992 if (parent_tree) {
1993 item = proto_tree_add_item(parent_tree, hf_smb_file_eattr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1994 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1996 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1997 tvb, offset, 2, mask);
1998 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1999 tvb, offset, 2, mask);
2000 proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
2001 tvb, offset, 2, mask);
2002 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
2003 tvb, offset, 2, mask);
2004 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
2005 tvb, offset, 2, mask);
2006 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
2007 tvb, offset, 2, mask);
2008 proto_tree_add_boolean(tree, hf_smb_file_attr_device,
2009 tvb, offset, 2, mask);
2010 proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
2011 tvb, offset, 2, mask);
2012 proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
2013 tvb, offset, 2, mask);
2014 proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
2015 tvb, offset, 2, mask);
2016 proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
2017 tvb, offset, 2, mask);
2018 proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
2019 tvb, offset, 2, mask);
2020 proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
2021 tvb, offset, 2, mask);
2022 proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
2023 tvb, offset, 2, mask);
2024 proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
2025 tvb, offset, 2, mask);
2027 offset += 2;
2029 return offset;
2031 #endif
2034 #define SERVER_CAP_RAW_MODE 0x00000001
2035 #define SERVER_CAP_MPX_MODE 0x00000002
2036 #define SERVER_CAP_UNICODE 0x00000004
2037 #define SERVER_CAP_LARGE_FILES 0x00000008
2038 #define SERVER_CAP_NT_SMBS 0x00000010
2039 #define SERVER_CAP_RPC_REMOTE_APIS 0x00000020
2040 #define SERVER_CAP_STATUS32 0x00000040
2041 #define SERVER_CAP_LEVEL_II_OPLOCKS 0x00000080
2042 #define SERVER_CAP_LOCK_AND_READ 0x00000100
2043 #define SERVER_CAP_NT_FIND 0x00000200
2044 #define SERVER_CAP_DFS 0x00001000
2045 #define SERVER_CAP_INFOLEVEL_PASSTHRU 0x00002000
2046 #define SERVER_CAP_LARGE_READX 0x00004000
2047 #define SERVER_CAP_LARGE_WRITEX 0x00008000
2048 #define SERVER_CAP_LWIO 0x00010000
2049 #define SERVER_CAP_UNIX 0x00800000
2050 #define SERVER_CAP_COMPRESSED_DATA 0x02000000
2051 #define SERVER_CAP_DYNAMIC_REAUTH 0x20000000
2052 #define SERVER_CAP_EXTENDED_SECURITY 0x80000000
2054 static const true_false_string tfs_server_cap_raw_mode = {
2055 "Read Raw and Write Raw are supported",
2056 "Read Raw and Write Raw are not supported"
2058 static const true_false_string tfs_server_cap_mpx_mode = {
2059 "Read Mpx and Write Mpx are supported",
2060 "Read Mpx and Write Mpx are not supported"
2062 static const true_false_string tfs_server_cap_unicode = {
2063 "Unicode strings are supported",
2064 "Unicode strings are not supported"
2066 static const true_false_string tfs_server_cap_large_files = {
2067 "Large files are supported",
2068 "Large files are not supported",
2070 static const true_false_string tfs_server_cap_nt_smbs = {
2071 "NT SMBs are supported",
2072 "NT SMBs are not supported"
2074 static const true_false_string tfs_server_cap_rpc_remote_apis = {
2075 "RPC remote APIs are supported",
2076 "RPC remote APIs are not supported"
2078 static const true_false_string tfs_server_cap_nt_status = {
2079 "NT status codes are supported",
2080 "NT status codes are not supported"
2082 static const true_false_string tfs_server_cap_level_ii_oplocks = {
2083 "Level 2 oplocks are supported",
2084 "Level 2 oplocks are not supported"
2086 static const true_false_string tfs_server_cap_lock_and_read = {
2087 "Lock and Read is supported",
2088 "Lock and Read is not supported"
2090 static const true_false_string tfs_server_cap_nt_find = {
2091 "NT Find is supported",
2092 "NT Find is not supported"
2094 static const true_false_string tfs_server_cap_dfs = {
2095 "Dfs is supported",
2096 "Dfs is not supported"
2098 static const true_false_string tfs_server_cap_infolevel_passthru = {
2099 "NT information level request passthrough is supported",
2100 "NT information level request passthrough is not supported"
2102 static const true_false_string tfs_server_cap_large_readx = {
2103 "Large Read andX is supported",
2104 "Large Read andX is not supported"
2106 static const true_false_string tfs_server_cap_large_writex = {
2107 "Large Write andX is supported",
2108 "Large Write andX is not supported"
2110 static const true_false_string tfs_server_cap_lwio = {
2111 "LWIO ioctl/fsctl is supported",
2112 "LWIO ioctl/fsctl is not supported"
2114 static const true_false_string tfs_server_cap_unix = {
2115 "UNIX extensions are supported",
2116 "UNIX extensions are not supported"
2118 static const true_false_string tfs_server_cap_compressed_data = {
2119 "Compressed data transfer is supported",
2120 "Compressed data transfer is not supported"
2122 static const true_false_string tfs_server_cap_dynamic_reauth = {
2123 "Dynamic Reauth is supported",
2124 "Dynamic Reauth is not supported"
2126 static const true_false_string tfs_server_cap_extended_security = {
2127 "Extended security exchanges are supported",
2128 "Extended security exchanges are not supported"
2130 static int
2131 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2133 guint32 mask;
2134 proto_item *item;
2135 proto_tree *tree;
2137 mask = tvb_get_letohl(tvb, offset);
2139 if (parent_tree) {
2140 item = proto_tree_add_item(parent_tree, hf_smb_server_cap, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2141 tree = proto_item_add_subtree(item, ett_smb_capabilities);
2143 proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
2144 tvb, offset, 4, mask);
2145 proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
2146 tvb, offset, 4, mask);
2147 proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
2148 tvb, offset, 4, mask);
2149 proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
2150 tvb, offset, 4, mask);
2151 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
2152 tvb, offset, 4, mask);
2153 proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
2154 tvb, offset, 4, mask);
2155 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
2156 tvb, offset, 4, mask);
2157 proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
2158 tvb, offset, 4, mask);
2159 proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
2160 tvb, offset, 4, mask);
2161 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
2162 tvb, offset, 4, mask);
2163 proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
2164 tvb, offset, 4, mask);
2165 proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
2166 tvb, offset, 4, mask);
2167 proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
2168 tvb, offset, 4, mask);
2169 proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
2170 tvb, offset, 4, mask);
2171 proto_tree_add_boolean(tree, hf_smb_server_cap_lwio,
2172 tvb, offset, 4, mask);
2173 proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
2174 tvb, offset, 4, mask);
2175 proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
2176 tvb, offset, 4, mask);
2177 proto_tree_add_boolean(tree, hf_smb_server_cap_dynamic_reauth,
2178 tvb, offset, 4, mask);
2179 proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
2180 tvb, offset, 4, mask);
2183 return mask;
2186 #define RAWMODE_READ 0x01
2187 #define RAWMODE_WRITE 0x02
2188 static const true_false_string tfs_rm_read = {
2189 "Read Raw is supported",
2190 "Read Raw is not supported"
2192 static const true_false_string tfs_rm_write = {
2193 "Write Raw is supported",
2194 "Write Raw is not supported"
2197 static int
2198 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2200 guint16 mask;
2201 proto_item *item;
2202 proto_tree *tree;
2204 mask = tvb_get_letohs(tvb, offset);
2206 if (parent_tree) {
2207 item = proto_tree_add_item(parent_tree, hf_smb_rm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2208 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2210 proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2211 proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2214 offset += 2;
2216 return offset;
2219 #define SECURITY_MODE_MODE 0x01
2220 #define SECURITY_MODE_PASSWORD 0x02
2221 #define SECURITY_MODE_SIGNATURES 0x04
2222 #define SECURITY_MODE_SIG_REQUIRED 0x08
2223 static const true_false_string tfs_sm_mode = {
2224 "USER security mode",
2225 "SHARE security mode"
2227 static const true_false_string tfs_sm_password = {
2228 "ENCRYPTED password. Use challenge/response",
2229 "PLAINTEXT password"
2231 static const true_false_string tfs_sm_signatures = {
2232 "Security signatures ENABLED",
2233 "Security signatures NOT enabled"
2235 static const true_false_string tfs_sm_sig_required = {
2236 "Security signatures REQUIRED",
2237 "Security signatures NOT required"
2240 static int
2241 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2243 guint16 mask = 0;
2244 proto_item *item = NULL;
2245 proto_tree *tree = NULL;
2247 switch(wc) {
2248 case 13:
2249 mask = tvb_get_letohs(tvb, offset);
2250 item = proto_tree_add_item(parent_tree, hf_smb_sm16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2251 tree = proto_item_add_subtree(item, ett_smb_mode);
2252 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2253 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2254 offset += 2;
2255 break;
2257 case 17:
2258 mask = tvb_get_guint8(tvb, offset);
2259 item = proto_tree_add_item(parent_tree, hf_smb_sm, tvb, offset, 1, ENC_NA);
2260 tree = proto_item_add_subtree(item, ett_smb_mode);
2261 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2262 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2263 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2264 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2265 offset += 1;
2266 break;
2269 return offset;
2272 #define MAX_DIALECTS 20
2273 struct negprot_dialects {
2274 int num;
2275 char *name[MAX_DIALECTS+1];
2278 static int
2279 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2281 proto_item *it = NULL;
2282 proto_tree *tr = NULL;
2283 guint16 bc;
2284 guint8 wc;
2285 struct negprot_dialects *dialects = NULL;
2287 DISSECTOR_ASSERT(si);
2289 WORD_COUNT;
2291 BYTE_COUNT;
2293 if (tree) {
2294 tvb_ensure_bytes_exist(tvb, offset, bc);
2295 it = proto_tree_add_text(tree, tvb, offset, bc, "Requested Dialects");
2296 tr = proto_item_add_subtree(it, ett_smb_dialects);
2299 if (!pinfo->fd->flags.visited && si->sip) {
2300 dialects = wmem_new(wmem_file_scope(), struct negprot_dialects);
2301 dialects->num = 0;
2302 si->sip->extra_info_type = SMB_EI_DIALECTS;
2303 si->sip->extra_info = dialects;
2306 while(bc) {
2307 int len;
2308 const guint8 *str;
2309 proto_item *dit = NULL;
2310 proto_tree *dtr = NULL;
2312 /* XXX - what if this runs past bc? */
2313 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2314 str = tvb_get_const_stringz(tvb, offset+1, &len);
2316 if (tr) {
2317 dit = proto_tree_add_string(tr, hf_smb_dialect, tvb, offset, len+1, str);
2318 dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2321 /* Buffer Format */
2322 CHECK_BYTE_COUNT(1);
2323 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2324 ENC_LITTLE_ENDIAN);
2325 COUNT_BYTES(1);
2327 /*Dialect Name */
2328 CHECK_BYTE_COUNT(len);
2329 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2330 len, str);
2331 COUNT_BYTES(len);
2333 if (!pinfo->fd->flags.visited && dialects && (dialects->num < MAX_DIALECTS)) {
2334 dialects->name[dialects->num++] = wmem_strdup(wmem_file_scope(), str);
2339 END_OF_SMB
2341 return offset;
2344 static int
2345 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2347 guint8 wc;
2348 guint16 dialect;
2349 const char *dn;
2350 int dn_len;
2351 guint16 bc;
2352 guint16 ekl = 0;
2353 guint32 caps = 0;
2354 gint16 tz;
2355 const char *dialect_name = NULL;
2356 struct negprot_dialects *dialects = NULL;
2358 DISSECTOR_ASSERT(si);
2360 WORD_COUNT;
2362 /* Dialect Index */
2363 dialect = tvb_get_letohs(tvb, offset);
2365 if (si->sip && (si->sip->extra_info_type == SMB_EI_DIALECTS)) {
2366 dialects = (struct negprot_dialects *)si->sip->extra_info;
2367 if (dialect < dialects->num) {
2368 dialect_name = dialects->name[dialect];
2371 if (!dialect_name) {
2372 dialect_name = "unknown";
2375 switch(wc) {
2376 case 1:
2377 if (dialect == 0xffff) {
2378 proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2379 tvb, offset, 2, dialect,
2380 "-1, PC NETWORK PROGRAM 1.0 chosen");
2381 } else {
2382 proto_tree_add_uint(tree, hf_smb_dialect_index,
2383 tvb, offset, 2, dialect);
2385 break;
2386 case 13:
2387 proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2388 tvb, offset, 2, dialect,
2389 "%u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2390 break;
2391 case 17:
2392 proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2393 tvb, offset, 2, dialect,
2394 "%u: %s", dialect, dialect_name);
2395 break;
2396 default:
2397 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2398 proto_tree_add_text(tree, tvb, offset, wc*2,
2399 "Words for unknown response format");
2400 offset += wc*2;
2401 goto bytecount;
2403 offset += 2;
2405 switch(wc) {
2406 case 13:
2407 /* Security Mode */
2408 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2410 /* Maximum Transmit Buffer Size */
2411 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2412 tvb, offset, 2, ENC_LITTLE_ENDIAN);
2413 offset += 2;
2415 /* Maximum Multiplex Count */
2416 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2417 tvb, offset, 2, ENC_LITTLE_ENDIAN);
2418 offset += 2;
2420 /* Maximum Vcs Number */
2421 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2422 tvb, offset, 2, ENC_LITTLE_ENDIAN);
2423 offset += 2;
2425 /* raw mode */
2426 offset = dissect_negprot_rawmode(tvb, tree, offset);
2428 /* session key */
2429 proto_tree_add_item(tree, hf_smb_session_key,
2430 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2431 offset += 4;
2433 /* current time and date at server */
2434 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2435 TRUE);
2437 /* time zone */
2438 tz = tvb_get_letohs(tvb, offset);
2439 proto_tree_add_int_format_value(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "%d min from UTC", tz);
2440 offset += 2;
2442 /* encryption key length */
2443 ekl = tvb_get_letohs(tvb, offset);
2444 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2445 offset += 2;
2447 /* 2 reserved bytes */
2448 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
2449 offset += 2;
2451 break;
2453 case 17:
2454 /* Security Mode */
2455 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2457 /* Maximum Multiplex Count */
2458 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2459 tvb, offset, 2, ENC_LITTLE_ENDIAN);
2460 offset += 2;
2462 /* Maximum Vcs Number */
2463 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2464 tvb, offset, 2, ENC_LITTLE_ENDIAN);
2465 offset += 2;
2467 /* Maximum Transmit Buffer Size */
2468 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2469 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2470 offset += 4;
2472 /* maximum raw buffer size */
2473 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2474 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2475 offset += 4;
2477 /* session key */
2478 proto_tree_add_item(tree, hf_smb_session_key,
2479 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2480 offset += 4;
2482 /* server capabilities */
2483 caps = dissect_negprot_capabilities(tvb, tree, offset);
2484 offset += 4;
2486 /* system time */
2487 offset = dissect_nt_64bit_time(tvb, tree, offset,
2488 hf_smb_system_time);
2490 /* time zone */
2491 tz = tvb_get_letohs(tvb, offset);
2492 proto_tree_add_int_format_value(tree, hf_smb_server_timezone,
2493 tvb, offset, 2, tz,
2494 "%d min from UTC", tz);
2495 offset += 2;
2497 /* encryption key length */
2498 ekl = tvb_get_guint8(tvb, offset);
2499 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2500 tvb, offset, 1, ekl);
2501 offset += 1;
2503 break;
2506 BYTE_COUNT;
2508 switch(wc) {
2509 case 13:
2510 /* challenge/response encryption key */
2511 if (ekl) {
2512 CHECK_BYTE_COUNT(ekl);
2513 proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, ENC_NA);
2514 COUNT_BYTES(ekl);
2518 * Primary domain.
2520 * XXX - not present if negotiated dialect isn't
2521 * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2522 * have to see the request, or assume what dialect strings
2523 * were sent, to determine that.
2525 * Is this something other than a primary domain if the
2526 * negotiated dialect is Windows for Workgroups 3.1a?
2527 * It appears to be 8 bytes of binary data in at least
2528 * one capture - is that an encryption key or something
2529 * such as that?
2531 dn = get_unicode_or_ascii_string(tvb, &offset,
2532 si->unicode, &dn_len, FALSE, FALSE, &bc);
2533 if (dn == NULL)
2534 goto endofcommand;
2535 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2536 offset, dn_len,dn);
2537 COUNT_BYTES(dn_len);
2538 break;
2540 case 17:
2541 if (!(caps & SERVER_CAP_EXTENDED_SECURITY)) {
2542 /* challenge/response encryption key */
2543 /* XXX - is this aligned on an even boundary? */
2544 if (ekl) {
2545 CHECK_BYTE_COUNT(ekl);
2546 proto_tree_add_item(tree, hf_smb_encryption_key,
2547 tvb, offset, ekl, ENC_NA);
2548 COUNT_BYTES(ekl);
2551 /* domain */
2552 /* this string is special, unicode is flagged in caps */
2553 /* This string is NOT padded to be 16bit aligned.
2554 (seen in actual capture)
2555 XXX - I've seen a capture where it appears to be
2556 so aligned, but I've also seen captures where
2557 it is. The captures where it appeared to be
2558 aligned may have been from buggy servers. */
2559 /* However, don't get rid of existing setting */
2560 si->unicode = (caps & SERVER_CAP_UNICODE) || si->unicode;
2562 dn = get_unicode_or_ascii_string(tvb,
2563 &offset, si->unicode, &dn_len, TRUE, FALSE,
2564 &bc);
2565 if (dn == NULL)
2566 goto endofcommand;
2567 proto_tree_add_string(tree, hf_smb_primary_domain,
2568 tvb, offset, dn_len, dn);
2569 COUNT_BYTES(dn_len);
2571 /* server name, seen in w2k pro capture */
2572 dn = get_unicode_or_ascii_string(tvb,
2573 &offset, si->unicode, &dn_len, TRUE, FALSE,
2574 &bc);
2575 if (dn == NULL)
2576 goto endofcommand;
2577 proto_tree_add_string(tree, hf_smb_server,
2578 tvb, offset, dn_len, dn);
2579 COUNT_BYTES(dn_len);
2581 } else {
2582 proto_item *blob_item;
2583 guint16 sbloblen;
2585 /* guid */
2586 /* XXX - show it in the standard Microsoft format
2587 for GUIDs? */
2588 CHECK_BYTE_COUNT(16);
2589 proto_tree_add_item(tree, hf_smb_server_guid,
2590 tvb, offset, 16, ENC_NA);
2591 COUNT_BYTES(16);
2593 /* security blob */
2594 /* If it runs past the end of the captured data, don't
2595 * try to put all of it into the protocol tree as the
2596 * raw security blob; we might get an exception on
2597 * short frames and then we will not see anything at all
2598 * of the security blob.
2600 sbloblen = bc;
2601 if (sbloblen > tvb_length_remaining(tvb, offset)) {
2602 sbloblen = tvb_length_remaining(tvb,offset);
2604 blob_item = proto_tree_add_item(
2605 tree, hf_smb_security_blob,
2606 tvb, offset, sbloblen, ENC_NA);
2609 * If Extended security and BCC == 16, then raw
2610 * NTLMSSP is in use. We need to save this info
2613 if (bc) {
2614 tvbuff_t *gssapi_tvb;
2615 proto_tree *gssapi_tree;
2617 gssapi_tree = proto_item_add_subtree(
2618 blob_item, ett_smb_secblob);
2621 * Set the reported length of this to
2622 * the reported length of the blob,
2623 * rather than the amount of data
2624 * available from the blob, so that
2625 * we'll throw the right exception if
2626 * it's too short.
2628 gssapi_tvb = tvb_new_subset(
2629 tvb, offset, sbloblen, bc);
2631 call_dissector(
2632 gssapi_handle, gssapi_tvb, pinfo,
2633 gssapi_tree);
2635 if (si->ct)
2636 si->ct->raw_ntlmssp = 0;
2638 COUNT_BYTES(bc);
2640 else {
2643 * There is no blob. We just have to make sure
2644 * that subsequent routines know to call the
2645 * right things ...
2648 if (si->ct)
2649 si->ct->raw_ntlmssp = 1;
2653 break;
2656 END_OF_SMB
2658 return offset;
2662 static int
2663 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2665 int dn_len;
2666 const char *dn;
2667 guint8 wc;
2668 guint16 bc;
2670 DISSECTOR_ASSERT(si);
2672 WORD_COUNT;
2674 BYTE_COUNT;
2676 /* buffer format */
2677 CHECK_BYTE_COUNT(1);
2678 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2679 COUNT_BYTES(1);
2681 /* dir name */
2682 dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2683 FALSE, FALSE, &bc);
2685 if ((!pinfo->fd->flags.visited) && si->sip) {
2686 si->sip->extra_info_type = SMB_EI_FILENAME;
2687 si->sip->extra_info = wmem_strdup(wmem_file_scope(), dn);
2690 if (dn == NULL)
2691 goto endofcommand;
2692 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2693 dn);
2694 COUNT_BYTES(dn_len);
2696 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2697 format_text(dn, strlen(dn)));
2699 END_OF_SMB
2701 return offset;
2704 static int
2705 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2707 guint8 wc;
2708 guint16 bc;
2709 proto_item *item = NULL;
2711 DISSECTOR_ASSERT(si);
2713 if (si->sip && (si->sip->extra_info_type == SMB_EI_FILENAME)) {
2714 item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, (const char *)si->sip->extra_info);
2715 PROTO_ITEM_SET_GENERATED(item);
2719 WORD_COUNT;
2721 BYTE_COUNT;
2723 END_OF_SMB
2725 return offset;
2728 static int
2729 dissect_rename_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2731 guint8 wc;
2732 guint16 bc;
2733 proto_item *item = NULL;
2735 DISSECTOR_ASSERT(si);
2737 if (si->sip && (si->sip->extra_info_type == SMB_EI_RENAMEDATA)) {
2738 smb_rename_saved_info_t *rni = (smb_rename_saved_info_t *)si->sip->extra_info;
2740 item = proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
2741 PROTO_ITEM_SET_GENERATED(item);
2742 item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
2743 PROTO_ITEM_SET_GENERATED(item);
2747 WORD_COUNT;
2749 BYTE_COUNT;
2751 END_OF_SMB
2753 return offset;
2756 static int
2757 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
2759 guint16 ec, bc;
2760 guint8 wc;
2762 WORD_COUNT;
2764 /* echo count */
2765 ec = tvb_get_letohs(tvb, offset);
2766 proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2767 offset += 2;
2769 BYTE_COUNT;
2771 if (bc != 0) {
2772 /* echo data */
2773 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, ENC_NA);
2774 COUNT_BYTES(bc);
2777 END_OF_SMB
2779 return offset;
2782 static int
2783 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
2785 guint16 bc;
2786 guint8 wc;
2788 WORD_COUNT;
2790 /* echo sequence number */
2791 proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2792 offset += 2;
2794 BYTE_COUNT;
2796 if (bc != 0) {
2797 /* echo data */
2798 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, ENC_NA);
2799 COUNT_BYTES(bc);
2802 END_OF_SMB
2804 return offset;
2807 static int
2808 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2810 int an_len, pwlen;
2811 const char *an;
2812 guint8 wc;
2813 guint16 bc;
2815 DISSECTOR_ASSERT(si);
2817 WORD_COUNT;
2819 BYTE_COUNT;
2821 /* buffer format */
2822 CHECK_BYTE_COUNT(1);
2823 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2824 COUNT_BYTES(1);
2826 /* Path */
2827 an = get_unicode_or_ascii_string(tvb, &offset,
2828 si->unicode, &an_len, FALSE, FALSE, &bc);
2829 if (an == NULL)
2830 goto endofcommand;
2831 proto_tree_add_string(tree, hf_smb_path, tvb,
2832 offset, an_len, an);
2833 COUNT_BYTES(an_len);
2835 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2836 format_text(an, strlen(an)));
2838 /* buffer format */
2839 CHECK_BYTE_COUNT(1);
2840 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2841 COUNT_BYTES(1);
2843 /* password, ANSI */
2844 /* XXX - what if this runs past bc? */
2845 pwlen = tvb_strsize(tvb, offset);
2846 CHECK_BYTE_COUNT(pwlen);
2847 proto_tree_add_item(tree, hf_smb_password,
2848 tvb, offset, pwlen, ENC_NA);
2849 COUNT_BYTES(pwlen);
2851 /* buffer format */
2852 CHECK_BYTE_COUNT(1);
2853 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2854 COUNT_BYTES(1);
2856 /* Service */
2858 * XXX - the SNIA CIFS spec "Strings that are never passed in
2859 * Unicode are: ... The service name string in the
2860 * Tree_Connect_AndX SMB". Is that claim false?
2862 an = get_unicode_or_ascii_string(tvb, &offset,
2863 si->unicode, &an_len, FALSE, FALSE, &bc);
2864 if (an == NULL)
2865 goto endofcommand;
2866 proto_tree_add_string(tree, hf_smb_service, tvb,
2867 offset, an_len, an);
2868 COUNT_BYTES(an_len);
2870 END_OF_SMB
2872 return offset;
2875 static int
2876 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2878 proto_item *item, *subitem;
2879 proto_tree *tree;
2880 smb_uid_t *smb_uid = NULL;
2882 item = proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2883 tree = proto_item_add_subtree(item, ett_smb_uid);
2885 smb_uid = (smb_uid_t *)wmem_tree_lookup32(si->ct->uid_tree, si->uid);
2886 if (smb_uid) {
2887 if (smb_uid->domain && smb_uid->account)
2888 proto_item_append_text(item, " (");
2889 if (smb_uid->domain) {
2890 proto_item_append_text(item, "%s", smb_uid->domain);
2891 subitem = proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2892 PROTO_ITEM_SET_GENERATED(subitem);
2894 if (smb_uid->account) {
2895 proto_item_append_text(item, "\\%s", smb_uid->account);
2896 subitem = proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2897 PROTO_ITEM_SET_GENERATED(subitem);
2899 if (smb_uid->domain && smb_uid->account)
2900 proto_item_append_text(item, ")");
2901 if (smb_uid->logged_in > 0) {
2902 subitem = proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2903 PROTO_ITEM_SET_GENERATED(subitem);
2905 if (smb_uid->logged_out > 0) {
2906 subitem = proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2907 PROTO_ITEM_SET_GENERATED(subitem);
2910 offset += 2;
2912 return offset;
2915 static int
2916 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed, smb_info_t *si)
2918 proto_item *it;
2919 proto_tree *tr;
2920 smb_tid_info_t *tid_info = NULL;
2922 DISSECTOR_ASSERT(si);
2924 /* tid */
2925 it = proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2926 tr = proto_item_add_subtree(it, ett_smb_tid);
2927 offset += 2;
2929 if ((!pinfo->fd->flags.visited) && is_created) {
2930 tid_info = wmem_new(wmem_file_scope(), smb_tid_info_t);
2931 tid_info->opened_in = pinfo->fd->num;
2932 tid_info->closed_in = 0;
2933 tid_info->type = SMB_FID_TYPE_UNKNOWN;
2934 if (si->sip && (si->sip->extra_info_type == SMB_EI_TIDNAME)) {
2935 tid_info->filename = (char *)si->sip->extra_info;
2936 } else {
2937 tid_info->filename = NULL;
2939 wmem_tree_insert32(si->ct->tid_tree, tid, tid_info);
2942 if (!tid_info) {
2943 tid_info = (smb_tid_info_t *)wmem_tree_lookup32_le(si->ct->tid_tree, tid);
2945 if (!tid_info) {
2946 return offset;
2949 if ((!pinfo->fd->flags.visited) && is_closed) {
2950 tid_info->closed_in = pinfo->fd->num;
2953 if (tid_info->opened_in) {
2954 if (tid_info->filename) {
2955 proto_item_append_text(it, " (%s)", tid_info->filename);
2957 it = proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2958 PROTO_ITEM_SET_GENERATED(it);
2961 it = proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2962 PROTO_ITEM_SET_GENERATED(it);
2964 if (tid_info->closed_in) {
2965 it = proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2966 PROTO_ITEM_SET_GENERATED(it);
2970 return offset;
2973 static int
2974 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2976 guint8 wc;
2977 guint16 bc;
2979 WORD_COUNT;
2981 /* Maximum Buffer Size */
2982 proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2983 offset += 2;
2985 /* tid */
2986 offset = dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE, si);
2988 BYTE_COUNT;
2990 END_OF_SMB
2992 return offset;
2996 static const true_false_string tfs_of_create = {
2997 "Create file if it does not exist",
2998 "Fail if file does not exist"
3000 static const value_string of_open[] = {
3001 { 0, "Fail if file exists"},
3002 { 1, "Open file if it exists"},
3003 { 2, "Truncate file if it exists"},
3004 {0, NULL}
3006 static int
3007 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3009 guint16 mask;
3010 proto_item *item = NULL;
3011 proto_tree *tree = NULL;
3013 mask = tvb_get_letohs(tvb, offset);
3015 if (parent_tree) {
3016 item = proto_tree_add_item(parent_tree, hf_smb_open_function, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3017 tree = proto_item_add_subtree(item, ett_smb_openfunction);
3020 proto_tree_add_boolean(tree, hf_smb_open_function_create,
3021 tvb, offset, 2, mask);
3022 proto_tree_add_uint(tree, hf_smb_open_function_open,
3023 tvb, offset, 2, mask);
3025 offset += 2;
3027 return offset;
3031 static const true_false_string tfs_mf_file = {
3032 "Target must be a file",
3033 "Target needn't be a file"
3035 static const true_false_string tfs_mf_dir = {
3036 "Target must be a directory",
3037 "Target needn't be a directory"
3039 static const true_false_string tfs_mf_verify = {
3040 "MUST verify all writes",
3041 "Don't have to verify writes"
3043 static int
3044 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3046 guint16 mask;
3047 proto_item *item = NULL;
3048 proto_tree *tree = NULL;
3050 mask = tvb_get_letohs(tvb, offset);
3052 if (parent_tree) {
3053 item = proto_tree_add_item(parent_tree, hf_smb_move_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3054 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
3057 proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
3058 tvb, offset, 2, mask);
3059 proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
3060 tvb, offset, 2, mask);
3061 proto_tree_add_boolean(tree, hf_smb_move_flags_file,
3062 tvb, offset, 2, mask);
3064 offset += 2;
3066 return offset;
3069 static const true_false_string tfs_cf_mode = {
3070 "ASCII",
3071 "Binary"
3073 static const true_false_string tfs_cf_tree_copy = {
3074 "Copy is a tree copy",
3075 "Copy is a file copy"
3077 static const true_false_string tfs_cf_ea_action = {
3078 "Fail copy",
3079 "Discard EAs"
3081 static int
3082 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3084 guint16 mask;
3085 proto_item *item = NULL;
3086 proto_tree *tree = NULL;
3088 mask = tvb_get_letohs(tvb, offset);
3090 if (parent_tree) {
3091 item = proto_tree_add_item(parent_tree, hf_smb_copy_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3092 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
3095 proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
3096 tvb, offset, 2, mask);
3097 proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
3098 tvb, offset, 2, mask);
3099 proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
3100 tvb, offset, 2, mask);
3101 proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
3102 tvb, offset, 2, mask);
3103 proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
3104 tvb, offset, 2, mask);
3105 proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
3106 tvb, offset, 2, mask);
3107 proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
3108 tvb, offset, 2, mask);
3110 offset += 2;
3112 return offset;
3115 static int
3116 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3118 int fn_len;
3119 guint16 tid;
3120 guint16 bc;
3121 guint8 wc;
3122 const char *fn;
3124 DISSECTOR_ASSERT(si);
3126 WORD_COUNT;
3128 /* tid */
3129 tid = tvb_get_letohs(tvb, offset);
3130 offset = dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE, si);
3132 /* open function */
3133 offset = dissect_open_function(tvb, tree, offset);
3135 /* move flags */
3136 offset = dissect_move_flags(tvb, tree, offset);
3138 BYTE_COUNT;
3140 /* buffer format */
3141 CHECK_BYTE_COUNT(1);
3142 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3143 COUNT_BYTES(1);
3145 /* file name */
3146 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3147 FALSE, FALSE, &bc);
3148 if (fn == NULL)
3149 goto endofcommand;
3150 proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3151 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
3152 COUNT_BYTES(fn_len);
3154 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3155 format_text(fn, strlen(fn)));
3157 /* buffer format */
3158 CHECK_BYTE_COUNT(1);
3159 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3160 COUNT_BYTES(1);
3162 /* file name */
3163 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3164 FALSE, FALSE, &bc);
3165 if (fn == NULL)
3166 goto endofcommand;
3167 proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3168 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
3169 COUNT_BYTES(fn_len);
3171 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3172 format_text(fn, strlen(fn)));
3174 END_OF_SMB
3176 return offset;
3179 static int
3180 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3182 int fn_len;
3183 guint16 tid;
3184 guint16 bc;
3185 guint8 wc;
3186 const char *fn;
3188 DISSECTOR_ASSERT(si);
3190 WORD_COUNT;
3192 /* tid */
3193 tid = tvb_get_letohs(tvb, offset);
3194 offset = dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE, si);
3196 /* open function */
3197 offset = dissect_open_function(tvb, tree, offset);
3199 /* copy flags */
3200 offset = dissect_copy_flags(tvb, tree, offset);
3202 BYTE_COUNT;
3204 /* buffer format */
3205 CHECK_BYTE_COUNT(1);
3206 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3207 COUNT_BYTES(1);
3209 /* file name */
3210 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3211 FALSE, FALSE, &bc);
3212 if (fn == NULL)
3213 goto endofcommand;
3214 proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3215 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
3216 COUNT_BYTES(fn_len);
3218 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3219 format_text(fn, strlen(fn)));
3221 /* buffer format */
3222 CHECK_BYTE_COUNT(1);
3223 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3224 COUNT_BYTES(1);
3226 /* file name */
3227 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3228 FALSE, FALSE, &bc);
3229 if (fn == NULL)
3230 goto endofcommand;
3231 proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3232 fn_len, fn, "Destination File Name: %s",
3233 format_text(fn, strlen(fn)));
3234 COUNT_BYTES(fn_len);
3236 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
3238 END_OF_SMB
3240 return offset;
3243 static int
3244 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3246 int fn_len;
3247 const char *fn;
3248 guint8 wc;
3249 guint16 bc;
3251 DISSECTOR_ASSERT(si);
3253 WORD_COUNT;
3255 /* # of files moved */
3256 proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3257 offset += 2;
3259 BYTE_COUNT;
3261 /* buffer format */
3262 CHECK_BYTE_COUNT(1);
3263 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3264 COUNT_BYTES(1);
3266 /* file name */
3267 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3268 FALSE, FALSE, &bc);
3269 if (fn == NULL)
3270 goto endofcommand;
3271 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3272 fn);
3273 COUNT_BYTES(fn_len);
3275 END_OF_SMB
3277 return offset;
3280 static int
3281 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3283 int fn_len;
3284 const char *fn;
3285 guint8 wc;
3286 guint16 bc;
3287 smb_fid_saved_info_t *fsi; /* eo_smb needs to track this info */
3289 DISSECTOR_ASSERT(si);
3291 WORD_COUNT;
3293 /* desired access */
3294 offset = dissect_access(tvb, tree, offset, "Desired");
3296 /* Search Attributes */
3297 offset = dissect_search_attributes(tvb, tree, offset);
3299 BYTE_COUNT;
3301 /* buffer format */
3302 CHECK_BYTE_COUNT(1);
3303 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3304 COUNT_BYTES(1);
3306 /* file name */
3307 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3308 FALSE, FALSE, &bc);
3309 if (fn == NULL)
3310 goto endofcommand;
3311 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3312 fn);
3313 COUNT_BYTES(fn_len);
3315 /* store it for the fid->name/openframe/closeframe matching in
3316 * dissect_smb_fid() called from the response.
3318 if ((!pinfo->fd->flags.visited) && si->sip && fn) {
3319 fsi = wmem_new(wmem_file_scope(), smb_fid_saved_info_t);
3320 fsi->filename = wmem_strdup(wmem_file_scope(), fn);
3321 fsi->create_flags = 0;
3322 fsi->access_mask = 0;
3323 fsi->file_attributes = 0;
3324 fsi->share_access = 0;
3325 fsi->create_options = 0;
3326 fsi->create_disposition = 0;
3328 si->sip->extra_info_type = SMB_EI_FILEDATA;
3329 si->sip->extra_info = fsi;
3332 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3333 format_text(fn, strlen(fn)));
3335 END_OF_SMB
3337 return offset;
3342 static int
3343 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3344 int len, guint32 mask)
3346 proto_item *item = NULL;
3347 proto_tree *tree = NULL;
3349 if (parent_tree) {
3350 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
3352 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3353 if (len==0)
3354 PROTO_ITEM_SET_GENERATED(item);
3358 * XXX - it's 0x00000016 in at least one capture, but
3359 * Network Monitor doesn't say what the 0x00000010 bit is.
3360 * Does the Win32 API documentation, or NT Native API book,
3361 * suggest anything?
3363 * That is the extended response desired bit ... RJS, from Samba
3364 * Well, maybe. Samba thinks it is, and uses it to encode
3365 * OpLock granted as the high order bit of the Action field
3366 * in the response. However, Windows does not do that. Or at least
3367 * Win2K doesn't.
3369 proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3370 tvb, offset, len, mask);
3371 proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3372 tvb, offset, len, mask);
3373 proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3374 tvb, offset, len, mask);
3375 proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3376 tvb, offset, len, mask);
3377 offset += len;
3379 return offset;
3382 /* FIXME: need to call dissect_nt_access_mask() instead */
3383 static int
3384 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3385 int offset, int len, guint32 mask)
3387 proto_item *item;
3388 proto_tree *tree;
3390 if (parent_tree) {
3391 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
3392 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3393 if (len==0)
3394 PROTO_ITEM_SET_GENERATED(item);
3396 * Some of these bits come from
3398 * http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3400 * and others come from the section on ZwOpenFile in "Windows(R)
3401 * NT(R)/2000 Native API Reference".
3403 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3404 tvb, offset, len, mask);
3405 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3406 tvb, offset, len, mask);
3407 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3408 tvb, offset, len, mask);
3409 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3410 tvb, offset, len, mask);
3411 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3412 tvb, offset, len, mask);
3413 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3414 tvb, offset, len, mask);
3415 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3416 tvb, offset, len, mask);
3417 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3418 tvb, offset, len, mask);
3419 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3420 tvb, offset, len, mask);
3421 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3422 tvb, offset, len, mask);
3423 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3424 tvb, offset, len, mask);
3425 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3426 tvb, offset, len, mask);
3427 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3428 tvb, offset, len, mask);
3429 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3430 tvb, offset, len, mask);
3431 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3432 tvb, offset, len, mask);
3433 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3434 tvb, offset, len, mask);
3435 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3436 tvb, offset, len, mask);
3437 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3438 tvb, offset, len, mask);
3439 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3440 tvb, offset, len, mask);
3441 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3442 tvb, offset, len, mask);
3444 offset += len;
3446 return offset;
3450 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3452 guint32 mask;
3454 mask = tvb_get_letohl(tvb, offset);
3456 offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
3458 return offset;
3461 #define SHARE_ACCESS_READ 0x00000001
3462 #define SHARE_ACCESS_WRITE 0x00000002
3463 #define SHARE_ACCESS_DELETE 0x00000004
3465 static int
3466 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3467 int offset, int len, guint32 mask)
3469 proto_item *item;
3470 proto_tree *tree;
3472 if (parent_tree) {
3473 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
3474 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3475 if (len==0)
3476 PROTO_ITEM_SET_GENERATED(item);
3478 proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3479 tvb, offset, len, mask);
3480 if (mask & SHARE_ACCESS_READ) {
3481 proto_item_append_text(item, " SHARE_READ");
3483 proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3484 tvb, offset, len, mask);
3485 if (mask & SHARE_ACCESS_WRITE) {
3486 proto_item_append_text(item, " SHARE_WRITE");
3488 proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3489 tvb, offset, len, mask);
3490 if (mask & SHARE_ACCESS_DELETE) {
3491 proto_item_append_text(item, " SHARE_DELETE");
3495 offset += len;
3497 return offset;
3501 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3503 guint32 mask;
3505 mask = tvb_get_letohl(tvb, offset);
3507 offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
3509 return offset;
3513 static int
3514 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3515 int offset, int len, guint32 mask)
3517 proto_item *item;
3518 proto_tree *tree;
3520 if (parent_tree) {
3521 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
3522 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3523 if (len==0)
3524 PROTO_ITEM_SET_GENERATED(item);
3526 * From
3528 * http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3530 proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3531 tvb, offset, len, mask);
3532 proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3533 tvb, offset, len, mask);
3534 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3535 tvb, offset, len, mask);
3536 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3537 tvb, offset, len, mask);
3538 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3539 tvb, offset, len, mask);
3540 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3541 tvb, offset, len, mask);
3542 proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3543 tvb, offset, len, mask);
3544 proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3545 tvb, offset, len, mask);
3546 proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3547 tvb, offset, len, mask);
3548 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3549 tvb, offset, len, mask);
3550 proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3551 tvb, offset, len, mask);
3552 proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3553 tvb, offset, len, mask);
3554 proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3555 tvb, offset, len, mask);
3556 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3557 tvb, offset, len, mask);
3558 proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3559 tvb, offset, len, mask);
3560 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3561 tvb, offset, len, mask);
3562 proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3563 tvb, offset, len, mask);
3564 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3565 tvb, offset, len, mask);
3566 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3567 tvb, offset, len, mask);
3568 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3569 tvb, offset, len, mask);
3571 offset += len;
3573 return offset;
3577 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3579 guint32 mask;
3581 mask = tvb_get_letohl(tvb, offset);
3583 offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
3585 return offset;
3589 /* fids are scoped by tcp session */
3590 smb_fid_info_t *
3591 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3592 int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated, smb_info_t* si)
3594 smb_saved_info_t *sip = si->sip;
3595 proto_item *it;
3596 proto_tree *tr;
3597 smb_fid_info_t *fid_info = NULL;
3598 smb_fid_info_t *suspect_fid_info = NULL;
3599 /* We need this to use an array-accessed tree */
3600 GSList *GSL_iterator;
3602 DISSECTOR_ASSERT(si);
3604 it = proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3605 if (is_generated) {
3606 PROTO_ITEM_SET_GENERATED(it);
3608 tr = proto_item_add_subtree(it, ett_smb_fid);
3609 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3611 if ((!pinfo->fd->flags.visited) && is_created) {
3612 fid_info = (smb_fid_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_fid_info_t));
3613 fid_info->opened_in = pinfo->fd->num;
3614 fid_info->closed_in = 0;
3615 fid_info->type = SMB_FID_TYPE_UNKNOWN;
3616 fid_info->fid = fid;
3617 fid_info->tid = si->tid;
3618 if (si->sip && (si->sip->extra_info_type == SMB_EI_FILEDATA)) {
3619 fid_info->fsi = (smb_fid_saved_info_t *)si->sip->extra_info;
3620 } else {
3621 fid_info->fsi = NULL;
3623 /* We don't use the fid_tree anymore to access and
3624 maintain the fid information of analyzed files.
3625 (was wmem_tree_insert32(si->ct->fid_tree, fid, fid_info);)
3626 We'll use a single list instead to keep track of the
3627 files (fid) opened.
3628 Note that the insert_sorted function allows to insert duplicates
3629 but being inside this if section should prevent it */
3630 si->ct->GSL_fid_info = g_slist_insert_sorted(
3631 si->ct->GSL_fid_info,
3632 fid_info,
3633 (GCompareFunc)fid_cmp);
3636 if (!fid_info) {
3637 /* we use the single linked list to access this fid_info
3638 (was fid_info = wmem_tree_lookup32(si->ct->fid_tree, fid);) */
3639 GSL_iterator = si->ct->GSL_fid_info;
3640 while (GSL_iterator) {
3641 suspect_fid_info = (smb_fid_info_t *)GSL_iterator->data;
3642 if (suspect_fid_info->opened_in > pinfo->fd->num) break;
3643 if ((suspect_fid_info->tid == si->tid) && (suspect_fid_info->fid == fid))
3644 fid_info = (smb_fid_info_t *)suspect_fid_info;
3645 GSL_iterator = g_slist_next(GSL_iterator);
3648 if (!fid_info) {
3649 return NULL;
3652 /* Store the fid in the transaction structure and remember if
3653 it was in the request or in the reply we saw it
3655 if (sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3656 sip->fid = fid;
3657 if (si->request) {
3658 sip->fid_seen_in_request = TRUE;
3659 } else {
3660 sip->fid_seen_in_request = FALSE;
3664 if ((!pinfo->fd->flags.visited) && is_closed) {
3665 fid_info->closed_in = pinfo->fd->num;
3668 if (fid_info->opened_in) {
3669 it = proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3670 PROTO_ITEM_SET_GENERATED(it);
3673 if (fid_info->closed_in) {
3674 it = proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3675 PROTO_ITEM_SET_GENERATED(it);
3679 if (fid_info->opened_in) {
3680 if (fid_info->fsi && fid_info->fsi->filename) {
3681 it = proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3682 PROTO_ITEM_SET_GENERATED(it);
3683 proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3684 dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
3685 dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
3686 dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
3687 dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
3688 dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
3689 it = proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
3690 PROTO_ITEM_SET_GENERATED(it);
3694 return fid_info;
3697 static int
3698 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3700 guint8 wc;
3701 guint16 bc;
3702 guint16 fid;
3703 smb_fid_info_t *fid_info = NULL; /* eo_smb needs to track this info */
3704 guint16 fattr;
3705 gboolean isdir = FALSE;
3707 WORD_COUNT;
3709 /* fid */
3710 fid = tvb_get_letohs(tvb, offset);
3712 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
3713 if (fid_info) {
3714 /* This command is used to create and open a new file or open
3715 and truncate an existing file to zero length */
3716 fid_info->end_of_file = 0;
3717 if (fid_info->fsi) {
3718 /* File Type */
3719 fattr=fid_info->fsi->file_attributes;
3720 /* XXX Volumes considered as directories */
3721 isdir = (fattr & SMB_FILE_ATTRIBUTE_DIRECTORY) || (fattr & SMB_FILE_ATTRIBUTE_VOLUME);
3722 if (isdir == 0) {
3723 fid_info->type = SMB_FID_TYPE_FILE;
3724 } else {
3725 fid_info->type = SMB_FID_TYPE_DIR;
3730 offset += 2;
3732 /* File Attributes */
3733 offset = dissect_file_attributes(tvb, tree, offset);
3735 /* last write time */
3736 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3738 /* File Size */
3739 proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3740 offset += 4;
3742 /* granted access */
3743 offset = dissect_access(tvb, tree, offset, "Granted");
3745 BYTE_COUNT;
3747 END_OF_SMB
3749 return offset;
3752 static int
3753 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3755 guint8 wc;
3756 guint16 bc;
3757 guint16 fid;
3759 WORD_COUNT;
3761 /* fid */
3762 fid = tvb_get_letohs(tvb, offset);
3763 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
3764 offset += 2;
3766 BYTE_COUNT;
3768 END_OF_SMB
3770 return offset;
3773 static int
3774 dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3776 guint8 wc;
3777 guint16 bc;
3778 guint16 fid;
3780 WORD_COUNT;
3782 /* fid */
3783 fid = tvb_get_letohs(tvb, offset);
3784 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
3785 offset += 2;
3787 BYTE_COUNT;
3789 END_OF_SMB
3791 return offset;
3794 static int
3795 dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3797 guint8 wc;
3798 guint16 bc;
3799 guint16 fid;
3801 WORD_COUNT;
3803 /* fid */
3804 fid = tvb_get_letohs(tvb, offset);
3805 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
3806 offset += 2;
3808 BYTE_COUNT;
3810 END_OF_SMB
3812 return offset;
3815 static int
3816 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3818 guint8 wc;
3819 guint16 bc;
3820 guint16 fid;
3822 WORD_COUNT;
3824 /* fid */
3825 fid = tvb_get_letohs(tvb, offset);
3826 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
3827 offset += 2;
3829 BYTE_COUNT;
3831 END_OF_SMB
3833 return offset;
3836 static int
3837 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3839 guint8 wc;
3840 guint16 bc;
3841 guint16 fid;
3843 WORD_COUNT;
3845 /* fid */
3846 fid = tvb_get_letohs(tvb, offset);
3847 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
3848 offset += 2;
3850 BYTE_COUNT;
3852 END_OF_SMB
3854 return offset;
3857 static int
3858 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3860 guint8 wc;
3861 guint16 bc;
3862 guint16 fid;
3863 smb_fid_info_t *fid_info = NULL; /* eo_smb needs to track this info */
3864 guint16 fattr;
3865 gboolean isdir = FALSE;
3867 WORD_COUNT;
3869 /* fid */
3870 fid = tvb_get_letohs(tvb, offset);
3871 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
3872 if (fid_info) {
3873 /* This command is used to create and open a new file or open
3874 and truncate an existing file to zero length */
3875 fid_info->end_of_file = 0;
3876 if (fid_info->fsi) {
3877 /* File Type */
3878 fattr=fid_info->fsi->file_attributes;
3879 /* XXX Volumes considered as directories */
3880 isdir = (fattr & SMB_FILE_ATTRIBUTE_DIRECTORY) || (fattr & SMB_FILE_ATTRIBUTE_VOLUME);
3881 if (isdir == 0) {
3882 fid_info->type = SMB_FID_TYPE_FILE;
3883 } else {
3884 fid_info->type = SMB_FID_TYPE_DIR;
3889 offset += 2;
3891 BYTE_COUNT;
3893 END_OF_SMB
3895 return offset;
3898 static int
3899 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3901 int fn_len;
3902 const char *fn;
3903 guint8 wc;
3904 guint16 bc;
3905 smb_fid_saved_info_t *fsi; /* eo_smb needs to track this info */
3906 guint32 file_attributes = 0;
3908 DISSECTOR_ASSERT(si);
3910 WORD_COUNT;
3912 /* file attributes */
3913 /* We read the two lower bytes into the four-bytes file-attributes, because they are compatible */
3914 file_attributes = tvb_get_letohs(tvb, offset);
3915 offset = dissect_file_attributes(tvb, tree, offset);
3917 /* creation time */
3918 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3920 BYTE_COUNT;
3922 /* buffer format */
3923 CHECK_BYTE_COUNT(1);
3924 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3925 COUNT_BYTES(1);
3927 /* File Name */
3928 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3929 FALSE, FALSE, &bc);
3930 if (fn == NULL)
3931 goto endofcommand;
3932 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3933 fn);
3934 COUNT_BYTES(fn_len);
3936 /* store it for the fid->name/openframe/closeframe matching in
3937 * dissect_smb_fid() called from the response.
3939 if ((!pinfo->fd->flags.visited) && si->sip && fn) {
3940 fsi = wmem_new(wmem_file_scope(), smb_fid_saved_info_t);
3941 fsi->filename = wmem_strdup(wmem_file_scope(), fn);
3942 fsi->create_flags = 0;
3943 fsi->access_mask = 0;
3944 fsi->file_attributes = file_attributes;
3945 fsi->share_access = 0;
3946 fsi->create_options = 0;
3947 fsi->create_disposition = 0;
3949 si->sip->extra_info_type = SMB_EI_FILEDATA;
3950 si->sip->extra_info = fsi;
3954 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3955 format_text(fn, strlen(fn)));
3957 END_OF_SMB
3959 return offset;
3962 static int
3963 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3965 guint8 wc;
3966 guint16 bc, fid;
3968 WORD_COUNT;
3970 /* fid */
3971 fid = tvb_get_letohs(tvb, offset);
3972 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
3973 offset += 2;
3975 /* last write time */
3976 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3978 BYTE_COUNT;
3980 END_OF_SMB
3982 return offset;
3985 static int
3986 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3988 int fn_len;
3989 const char *fn;
3990 guint8 wc;
3991 guint16 bc;
3993 DISSECTOR_ASSERT(si);
3995 WORD_COUNT;
3997 /* search attributes */
3998 offset = dissect_search_attributes(tvb, tree, offset);
4000 BYTE_COUNT;
4002 /* buffer format */
4003 CHECK_BYTE_COUNT(1);
4004 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4005 COUNT_BYTES(1);
4007 /* file name */
4008 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4009 FALSE, FALSE, &bc);
4011 if ((!pinfo->fd->flags.visited) && si->sip) {
4012 si->sip->extra_info_type = SMB_EI_FILENAME;
4013 si->sip->extra_info = wmem_strdup(wmem_file_scope(), fn);
4016 if (fn == NULL)
4017 goto endofcommand;
4018 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4019 fn);
4020 COUNT_BYTES(fn_len);
4022 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4023 format_text(fn, strlen(fn)));
4025 END_OF_SMB
4027 return offset;
4030 static int
4031 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4033 int fn_len;
4034 const char *fn, *old_name = NULL, *new_name = NULL;
4035 guint8 wc;
4036 guint16 bc;
4037 smb_rename_saved_info_t *rni = NULL;
4039 DISSECTOR_ASSERT(si);
4041 WORD_COUNT;
4043 /* search attributes */
4044 offset = dissect_search_attributes(tvb, tree, offset);
4046 BYTE_COUNT;
4048 /* buffer format */
4049 CHECK_BYTE_COUNT(1);
4050 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4051 COUNT_BYTES(1);
4053 /* old file name */
4054 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4055 FALSE, FALSE, &bc);
4056 if (fn == NULL)
4057 goto endofcommand;
4058 old_name = fn;
4059 proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
4060 fn);
4061 COUNT_BYTES(fn_len);
4063 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
4064 format_text(fn, strlen(fn)));
4066 /* buffer format */
4067 CHECK_BYTE_COUNT(1);
4068 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4069 COUNT_BYTES(1);
4071 /* file name */
4072 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4073 FALSE, FALSE, &bc);
4074 if (fn == NULL)
4075 goto endofcommand;
4076 new_name = fn;
4077 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4078 fn);
4079 COUNT_BYTES(fn_len);
4081 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
4082 format_text(fn, strlen(fn)));
4084 END_OF_SMB
4086 /* save the offset/len for this transaction */
4087 if (si->sip && !pinfo->fd->flags.visited) {
4088 rni = (smb_rename_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_rename_saved_info_t));
4089 rni->old_name = wmem_strdup(wmem_file_scope(), old_name);
4090 rni->new_name = wmem_strdup(wmem_file_scope(), new_name);
4092 si->sip->extra_info_type = SMB_EI_RENAMEDATA;
4093 si->sip->extra_info = rni;
4096 return offset;
4099 static int
4100 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4102 int fn_len;
4103 const char *fn;
4104 guint8 wc;
4105 guint16 bc;
4107 DISSECTOR_ASSERT(si);
4109 WORD_COUNT;
4111 /* search attributes */
4112 offset = dissect_search_attributes(tvb, tree, offset);
4114 proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
4115 offset += 2;
4117 proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4118 offset += 4;
4120 BYTE_COUNT;
4122 /* buffer format */
4123 CHECK_BYTE_COUNT(1);
4124 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4125 COUNT_BYTES(1);
4127 /* old file name */
4128 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4129 FALSE, FALSE, &bc);
4130 if (fn == NULL)
4131 goto endofcommand;
4132 proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
4133 fn);
4134 COUNT_BYTES(fn_len);
4136 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
4137 format_text(fn, strlen(fn)));
4139 /* buffer format */
4140 CHECK_BYTE_COUNT(1);
4141 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4142 COUNT_BYTES(1);
4144 /* file name */
4145 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4146 FALSE, FALSE, &bc);
4147 if (fn == NULL)
4148 goto endofcommand;
4149 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4150 fn);
4151 COUNT_BYTES(fn_len);
4153 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
4154 format_text(fn, strlen(fn)));
4156 END_OF_SMB
4158 return offset;
4162 static int
4163 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4165 guint16 bc;
4166 guint8 wc;
4167 const char *fn;
4168 int fn_len;
4170 DISSECTOR_ASSERT(si);
4172 WORD_COUNT;
4174 BYTE_COUNT;
4176 /* Buffer Format */
4177 CHECK_BYTE_COUNT(1);
4178 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4179 COUNT_BYTES(1);
4181 /* File Name */
4182 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4183 FALSE, FALSE, &bc);
4184 if (fn == NULL)
4185 goto endofcommand;
4186 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4187 fn);
4188 COUNT_BYTES(fn_len);
4190 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4191 format_text(fn, strlen(fn)));
4193 END_OF_SMB
4195 return offset;
4198 static int
4199 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
4201 guint16 bc;
4202 guint8 wc;
4204 WORD_COUNT;
4206 /* File Attributes */
4207 offset = dissect_file_attributes(tvb, tree, offset);
4209 /* Last Write Time */
4210 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4212 /* File Size */
4213 proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4214 offset += 4;
4216 /* 10 reserved bytes */
4217 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
4218 offset += 10;
4220 BYTE_COUNT;
4222 END_OF_SMB
4224 return offset;
4227 static int
4228 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4230 int fn_len;
4231 const char *fn;
4232 guint8 wc;
4233 guint16 bc;
4235 DISSECTOR_ASSERT(si);
4237 WORD_COUNT;
4239 /* file attributes */
4240 offset = dissect_file_attributes(tvb, tree, offset);
4242 /* last write time */
4243 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4245 /* 10 reserved bytes */
4246 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
4247 offset += 10;
4249 BYTE_COUNT;
4251 /* buffer format */
4252 CHECK_BYTE_COUNT(1);
4253 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4254 COUNT_BYTES(1);
4256 /* file name */
4257 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4258 FALSE, FALSE, &bc);
4259 if (fn == NULL)
4260 goto endofcommand;
4261 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4262 fn);
4263 COUNT_BYTES(fn_len);
4265 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4266 format_text(fn, strlen(fn)));
4268 END_OF_SMB
4270 return offset;
4273 typedef struct _rw_info_t {
4274 guint64 offset;
4275 guint32 len;
4276 guint16 fid;
4277 } rw_info_t;
4279 static int
4280 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4282 guint8 wc;
4283 guint16 cnt = 0, bc;
4284 guint32 ofs = 0;
4285 unsigned int fid;
4286 rw_info_t *rwi = NULL;
4288 WORD_COUNT;
4290 /* fid */
4291 fid = tvb_get_letohs(tvb, offset);
4292 dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
4293 offset += 2;
4295 /* read count */
4296 cnt = tvb_get_letohs(tvb, offset);
4297 proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4298 offset += 2;
4300 /* offset */
4301 ofs = tvb_get_letohl(tvb, offset);
4302 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4303 offset += 4;
4305 col_append_fstr(pinfo->cinfo, COL_INFO,
4306 ", %u byte%s at offset %u", cnt,
4307 (cnt == 1) ? "" : "s", ofs);
4309 /* remaining */
4310 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4311 offset += 2;
4313 /* save the offset/len for this transaction */
4314 if (si->sip && !pinfo->fd->flags.visited) {
4315 rwi = wmem_new(wmem_file_scope(), rw_info_t);
4316 rwi->offset = ofs;
4317 rwi->len = cnt;
4318 rwi->fid = fid;
4319 si->sip->extra_info_type = SMB_EI_RWINFO;
4320 si->sip->extra_info = rwi;
4323 BYTE_COUNT;
4325 END_OF_SMB
4327 return offset;
4331 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4333 int tvblen;
4335 if (bc > datalen) {
4336 /* We have some initial padding bytes. */
4337 /* XXX - use the data offset here instead? */
4338 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4339 ENC_NA);
4340 offset += bc-datalen;
4341 bc = datalen;
4343 tvblen = tvb_length_remaining(tvb, offset);
4344 if (bc > tvblen) {
4345 proto_tree_add_bytes_format_value(tree, hf_smb_file_data, tvb, offset, tvblen, NULL, "Incomplete. Only %d of %u bytes", tvblen, bc);
4346 offset += tvblen;
4347 } else {
4348 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, ENC_NA);
4349 offset += bc;
4351 return offset;
4354 static int
4355 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4356 proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
4358 int tvblen;
4359 tvbuff_t *dcerpc_tvb;
4361 if (bc > datalen) {
4362 /* We have some initial padding bytes. */
4363 /* XXX - use the data offset here instead? */
4364 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4365 ENC_NA);
4366 offset += bc-datalen;
4367 bc = datalen;
4369 tvblen = tvb_length_remaining(tvb, offset);
4370 dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4371 dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4372 if (bc > tvblen)
4373 offset += tvblen;
4374 else
4375 offset += bc;
4376 return offset;
4380 * transporting DCERPC over SMB seems to be implemented in various
4381 * ways. We might just assume it can be done by an almost random
4382 * mix of Trans/Read/Write calls
4384 * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4385 * and let him sort them out
4387 static int
4388 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4389 proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4390 guint16 datalen, guint32 ofs, guint16 fid, smb_info_t *si)
4392 DISSECTOR_ASSERT(si);
4394 if ( (si->sip && (si->sip->flags & SMB_SIF_TID_IS_IPC)) && (ofs == 0) ) {
4395 /* dcerpc call */
4396 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4397 top_tree, offset, bc, datalen, fid);
4398 } else {
4399 /* ordinary file data */
4400 return dissect_file_data(tvb, tree, offset, bc, datalen);
4404 static int
4405 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4407 guint16 cnt = 0, bc;
4408 guint8 wc;
4409 int fid = 0;
4410 guint32 datalen=0,dataoffset=0;
4411 guint32 tvblen;
4412 rw_info_t *rwi = NULL;
4414 DISSECTOR_ASSERT(si);
4416 WORD_COUNT;
4418 /* read count */
4419 cnt = tvb_get_letohs(tvb, offset);
4420 proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4421 offset += 2;
4423 /* 8 reserved bytes */
4424 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, ENC_NA);
4425 offset += 8;
4426 BYTE_COUNT;
4428 /* buffer format */
4429 CHECK_BYTE_COUNT(1);
4430 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4431 COUNT_BYTES(1);
4433 /* data len */
4434 CHECK_BYTE_COUNT(2);
4435 proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4436 datalen = tvb_get_letohs(tvb, offset);
4437 COUNT_BYTES(2);
4438 dataoffset=offset;
4440 /* file data, might be DCERPC on a pipe */
4441 if (bc) {
4442 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4443 top_tree_global, offset, bc, bc, 0, (guint16) fid, si);
4444 bc = 0;
4447 /* If we have seen the request, then print which FID this refers to */
4448 if ((si->sip != NULL) && (si->sip->frame_req > 0) && (si->sip->extra_info_type == SMB_EI_FID)) {
4449 fid = GPOINTER_TO_INT(si->sip->extra_info);
4452 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4453 rwi = (rw_info_t *)si->sip->extra_info;
4455 if (rwi) {
4456 proto_item *it;
4458 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4460 PROTO_ITEM_SET_GENERATED(it);
4461 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4462 PROTO_ITEM_SET_GENERATED(it);
4464 /* we need the fid for the call to dcerpc below */
4465 fid = rwi->fid;
4468 /* feed the export object tap listener */
4469 tvblen = tvb_length_remaining(tvb, dataoffset);
4470 if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
4471 feed_eo_smb(SMB_COM_READ,fid,tvb,pinfo,dataoffset,datalen,rwi->len,rwi->offset, si);
4474 END_OF_SMB
4476 return offset;
4479 static int
4480 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
4482 guint16 cnt, bc;
4483 guint8 wc;
4485 WORD_COUNT;
4487 /* read count */
4488 cnt = tvb_get_letohs(tvb, offset);
4489 proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4490 offset += 2;
4492 /* 8 reserved bytes */
4493 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, ENC_NA);
4494 offset += 8;
4496 BYTE_COUNT;
4498 /* buffer format */
4499 CHECK_BYTE_COUNT(1);
4500 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4501 COUNT_BYTES(1);
4503 /* data len */
4504 CHECK_BYTE_COUNT(2);
4505 proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4506 COUNT_BYTES(2);
4508 END_OF_SMB
4510 return offset;
4515 static int
4516 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4518 guint32 ofs = 0;
4519 guint16 cnt = 0, bc, fid = 0;
4520 guint8 wc;
4521 rw_info_t *rwi = NULL;
4522 guint32 datalen=0,dataoffset=0;
4523 guint32 tvblen;
4525 DISSECTOR_ASSERT(si);
4527 WORD_COUNT;
4529 /* fid */
4530 fid = tvb_get_letohs(tvb, offset);
4531 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4532 offset += 2;
4534 /* write count */
4535 cnt = tvb_get_letohs(tvb, offset);
4536 datalen = cnt;
4537 proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4538 offset += 2;
4540 /* offset */
4541 ofs = tvb_get_letohl(tvb, offset);
4542 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4543 offset += 4;
4545 col_append_fstr(pinfo->cinfo, COL_INFO,
4546 ", %u byte%s at offset %u", cnt,
4547 (cnt == 1) ? "" : "s", ofs);
4549 /* save the offset/len for this transaction */
4550 if (si->sip && !pinfo->fd->flags.visited) {
4551 rwi = (rw_info_t *)wmem_alloc(wmem_file_scope(), sizeof(rw_info_t));
4552 rwi->offset = ofs;
4553 rwi->len = cnt;
4554 rwi->fid = fid;
4556 si->sip->extra_info_type = SMB_EI_RWINFO;
4557 si->sip->extra_info = rwi;
4559 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4560 rwi = (rw_info_t *)si->sip->extra_info;
4562 if (rwi) {
4563 proto_item *it;
4565 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4567 PROTO_ITEM_SET_GENERATED(it);
4568 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4569 PROTO_ITEM_SET_GENERATED(it);
4572 /* remaining */
4573 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4574 offset += 2;
4576 BYTE_COUNT;
4578 /* buffer format */
4579 CHECK_BYTE_COUNT(1);
4580 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4581 COUNT_BYTES(1);
4583 /* data len */
4584 CHECK_BYTE_COUNT(2);
4585 proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4586 COUNT_BYTES(2);
4587 dataoffset=offset;
4589 /* file data, might be DCERPC on a pipe */
4590 if (bc != 0) {
4591 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4592 top_tree_global, offset, bc, bc, ofs, fid, si);
4593 bc = 0;
4596 /* feed the export object tap listener */
4597 tvblen = tvb_length_remaining(tvb, dataoffset);
4598 if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
4599 feed_eo_smb(SMB_COM_WRITE,fid,tvb,pinfo,dataoffset,datalen,rwi->len,rwi->offset, si);
4602 END_OF_SMB
4604 return offset;
4607 static int
4608 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4610 guint8 wc;
4611 guint16 bc, cnt;
4612 rw_info_t *rwi = NULL;
4614 DISSECTOR_ASSERT(si);
4616 WORD_COUNT;
4618 /* write count */
4619 cnt = tvb_get_letohs(tvb, offset);
4620 proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4621 offset += 2;
4623 col_append_fstr(pinfo->cinfo, COL_INFO,
4624 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4626 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4627 rwi = (rw_info_t *)si->sip->extra_info;
4629 if (rwi) {
4630 proto_item *it;
4632 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4634 PROTO_ITEM_SET_GENERATED(it);
4635 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4636 PROTO_ITEM_SET_GENERATED(it);
4639 BYTE_COUNT;
4641 END_OF_SMB
4643 return offset;
4646 static int
4647 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4649 guint8 wc;
4650 guint16 bc, fid;
4652 WORD_COUNT;
4654 /* fid */
4655 fid = tvb_get_letohs(tvb, offset);
4656 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4657 offset += 2;
4659 /* lock count */
4660 proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4661 offset += 4;
4663 /* offset */
4664 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4665 offset += 4;
4667 BYTE_COUNT;
4669 END_OF_SMB
4671 return offset;
4674 static int
4675 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4677 int fn_len;
4678 const char *fn;
4679 guint8 wc;
4680 guint16 bc;
4682 DISSECTOR_ASSERT(si);
4684 WORD_COUNT;
4686 /* 2 reserved bytes */
4687 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
4688 offset += 2;
4690 /* Creation time */
4691 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4693 BYTE_COUNT;
4695 /* buffer format */
4696 CHECK_BYTE_COUNT(1);
4697 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4698 COUNT_BYTES(1);
4700 /* directory name */
4701 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4702 FALSE, FALSE, &bc);
4703 if (fn == NULL)
4704 goto endofcommand;
4705 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4706 fn);
4707 COUNT_BYTES(fn_len);
4709 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4710 format_text(fn, strlen(fn)));
4712 END_OF_SMB
4714 return offset;
4717 static int
4718 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4720 int fn_len;
4721 const char *fn;
4722 guint8 wc;
4723 guint16 bc, fid;
4725 DISSECTOR_ASSERT(si);
4727 WORD_COUNT;
4729 /* fid */
4730 fid = tvb_get_letohs(tvb, offset);
4731 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
4732 offset += 2;
4734 BYTE_COUNT;
4736 /* buffer format */
4737 CHECK_BYTE_COUNT(1);
4738 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4739 COUNT_BYTES(1);
4741 /* file name */
4742 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4743 FALSE, FALSE, &bc);
4744 if (fn == NULL)
4745 goto endofcommand;
4746 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4747 fn);
4748 COUNT_BYTES(fn_len);
4750 END_OF_SMB
4752 return offset;
4755 static const value_string seek_mode_vals[] = {
4756 {0, "From Start Of File"},
4757 {1, "From Current Position"},
4758 {2, "From End Of File"},
4759 {0, NULL}
4762 static int
4763 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4765 guint8 wc;
4766 guint16 bc, fid;
4768 WORD_COUNT;
4770 /* fid */
4771 fid = tvb_get_letohs(tvb, offset);
4772 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4773 offset += 2;
4775 /* Seek Mode */
4776 proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4777 offset += 2;
4779 /* offset */
4780 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4781 offset += 4;
4783 BYTE_COUNT;
4785 END_OF_SMB
4787 return offset;
4790 static int
4791 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
4793 guint8 wc;
4794 guint16 bc;
4796 WORD_COUNT;
4798 /* offset */
4799 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4800 offset += 4;
4802 BYTE_COUNT;
4804 END_OF_SMB
4806 return offset;
4809 static int
4810 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4812 guint8 wc;
4813 guint16 bc, fid;
4815 WORD_COUNT;
4817 /* fid */
4818 fid = tvb_get_letohs(tvb, offset);
4819 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4820 offset += 2;
4822 /* create time */
4823 offset = dissect_smb_datetime(tvb, tree, offset,
4824 hf_smb_create_time,
4825 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4827 /* access time */
4828 offset = dissect_smb_datetime(tvb, tree, offset,
4829 hf_smb_access_time,
4830 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4832 /* last write time */
4833 offset = dissect_smb_datetime(tvb, tree, offset,
4834 hf_smb_last_write_time,
4835 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4837 BYTE_COUNT;
4839 END_OF_SMB
4841 return offset;
4844 static int
4845 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
4847 guint8 wc;
4848 guint16 bc;
4850 WORD_COUNT;
4852 /* create time */
4853 offset = dissect_smb_datetime(tvb, tree, offset,
4854 hf_smb_create_time,
4855 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4857 /* access time */
4858 offset = dissect_smb_datetime(tvb, tree, offset,
4859 hf_smb_access_time,
4860 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4862 /* last write time */
4863 offset = dissect_smb_datetime(tvb, tree, offset,
4864 hf_smb_last_write_time,
4865 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4867 /* data size */
4868 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4869 offset += 4;
4871 /* allocation size */
4872 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4873 offset += 4;
4875 /* File Attributes */
4876 offset = dissect_file_attributes(tvb, tree, offset);
4878 BYTE_COUNT;
4880 END_OF_SMB
4882 return offset;
4885 static int
4886 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4888 guint8 wc;
4889 guint16 cnt = 0;
4890 guint16 bc, fid;
4892 WORD_COUNT;
4894 /* fid */
4895 fid = tvb_get_letohs(tvb, offset);
4896 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
4897 offset += 2;
4899 /* write count */
4900 cnt = tvb_get_letohs(tvb, offset);
4901 proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4902 offset += 2;
4904 /* offset */
4905 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4906 offset += 4;
4908 /* last write time */
4909 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4911 if (wc == 12) {
4912 /* 12 reserved bytes */
4913 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, ENC_NA);
4914 offset += 12;
4917 BYTE_COUNT;
4919 /* 1 pad byte */
4920 CHECK_BYTE_COUNT(1);
4921 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
4922 COUNT_BYTES(1);
4924 offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4925 bc = 0; /* XXX */
4927 END_OF_SMB
4929 return offset;
4932 static int
4933 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
4935 guint8 wc;
4936 guint16 bc;
4938 WORD_COUNT;
4940 /* write count */
4941 proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4942 offset += 2;
4944 BYTE_COUNT;
4946 END_OF_SMB
4948 return offset;
4951 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4952 available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4954 static gchar *
4955 smbext20_timeout_msecs_to_str(gint32 timeout)
4957 gchar *buf;
4958 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4960 if (timeout <= 0) {
4961 buf = (gchar *)wmem_alloc(wmem_packet_scope(), SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4962 if (timeout == 0) {
4963 g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4964 } else if (timeout == -1) {
4965 g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4966 } else if (timeout == -2) {
4967 g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4968 } else {
4969 g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", timeout);
4971 return buf;
4974 return time_msecs_to_str(timeout);
4977 static int
4978 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4980 guint8 wc;
4981 guint16 bc, fid;
4982 guint32 to;
4984 WORD_COUNT;
4986 /* fid */
4987 fid = tvb_get_letohs(tvb, offset);
4988 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4989 offset += 2;
4991 /* offset */
4992 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4993 offset += 4;
4995 /* max count */
4996 proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4997 offset += 2;
4999 /* min count */
5000 proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5001 offset += 2;
5003 /* timeout */
5004 to = tvb_get_letohl(tvb, offset);
5005 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5006 offset += 4;
5008 /* 2 reserved bytes */
5009 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5010 offset += 2;
5012 if (wc == 10) {
5013 /* high offset */
5014 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5015 offset += 4;
5018 BYTE_COUNT;
5020 END_OF_SMB
5022 return offset;
5025 static int
5026 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5028 guint8 wc;
5029 guint16 bc;
5031 WORD_COUNT;
5033 /* units */
5034 proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5035 offset += 2;
5037 /* bpu */
5038 proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5039 offset += 2;
5041 /* block size */
5042 proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5043 offset += 2;
5045 /* free units */
5046 proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5047 offset += 2;
5049 /* 2 reserved bytes */
5050 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5051 offset += 2;
5053 BYTE_COUNT;
5055 END_OF_SMB
5057 return offset;
5060 static int
5061 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5063 guint8 wc;
5064 guint16 bc, fid;
5066 WORD_COUNT;
5068 /* fid */
5069 fid = tvb_get_letohs(tvb, offset);
5070 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5071 offset += 2;
5073 /* offset */
5074 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5075 offset += 4;
5077 /* max count */
5078 proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5079 offset += 2;
5081 /* min count */
5082 proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5083 offset += 2;
5085 /* 6 reserved bytes */
5086 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, ENC_NA);
5087 offset += 6;
5089 BYTE_COUNT;
5091 END_OF_SMB
5093 return offset;
5096 static int
5097 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5099 guint16 datalen = 0, bc;
5100 guint8 wc;
5102 WORD_COUNT;
5104 /* offset */
5105 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5106 offset += 4;
5108 /* count */
5109 proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5110 offset += 2;
5112 /* 2 reserved bytes */
5113 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5114 offset += 2;
5116 /* data compaction mode */
5117 proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5118 offset += 2;
5120 /* 2 reserved bytes */
5121 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5122 offset += 2;
5124 /* data len */
5125 datalen = tvb_get_letohs(tvb, offset);
5126 proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5127 offset += 2;
5129 /* data offset */
5130 proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5131 offset += 2;
5133 BYTE_COUNT;
5135 /* file data */
5136 offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5137 bc = 0;
5139 END_OF_SMB
5141 return offset;
5145 static const true_false_string tfs_write_mode_write_through = {
5146 "WRITE THROUGH requested",
5147 "Write through not requested"
5149 static const true_false_string tfs_write_mode_return_remaining = {
5150 "RETURN REMAINING (pipe/dev) requested",
5151 "DON'T return remaining (pipe/dev)"
5153 static const true_false_string tfs_write_mode_raw = {
5154 "Use WriteRawNamedPipe (pipe)",
5155 "DON'T use WriteRawNamedPipe (pipe)"
5157 static const true_false_string tfs_write_mode_message_start = {
5158 "This is the START of a MESSAGE (pipe)",
5159 "This is NOT the start of a message (pipe)"
5161 static const true_false_string tfs_write_mode_connectionless = {
5162 "CONNECTIONLESS mode requested",
5163 "Connectionless mode NOT requested"
5166 #define WRITE_MODE_CONNECTIONLESS 0x0080
5167 #define WRITE_MODE_MESSAGE_START 0x0008
5168 #define WRITE_MODE_RAW 0x0004
5169 #define WRITE_MODE_RETURN_REMAINING 0x0002
5170 #define WRITE_MODE_WRITE_THROUGH 0x0001
5172 static int
5173 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5175 guint16 mask;
5176 proto_item *item;
5177 proto_tree *tree;
5179 mask = tvb_get_letohs(tvb, offset);
5181 if (parent_tree) {
5182 item = proto_tree_add_item(parent_tree, hf_smb_write_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5183 tree = proto_item_add_subtree(item, ett_smb_rawmode);
5185 if (bm&WRITE_MODE_CONNECTIONLESS) {
5186 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
5187 tvb, offset, 2, mask);
5189 if (bm&WRITE_MODE_MESSAGE_START) {
5190 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
5191 tvb, offset, 2, mask);
5193 if (bm&WRITE_MODE_RAW) {
5194 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
5195 tvb, offset, 2, mask);
5197 if (bm&WRITE_MODE_RETURN_REMAINING) {
5198 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
5199 tvb, offset, 2, mask);
5201 if (bm&WRITE_MODE_WRITE_THROUGH) {
5202 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
5203 tvb, offset, 2, mask);
5207 offset += 2;
5208 return offset;
5211 static int
5212 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5214 guint32 to;
5215 guint16 datalen = 0, bc, fid;
5216 guint8 wc;
5218 WORD_COUNT;
5220 /* fid */
5221 fid = tvb_get_letohs(tvb, offset);
5222 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5223 offset += 2;
5225 /* total data length */
5226 proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5227 offset += 2;
5229 /* 2 reserved bytes */
5230 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5231 offset += 2;
5233 /* offset */
5234 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5235 offset += 4;
5237 /* timeout */
5238 to = tvb_get_letohl(tvb, offset);
5239 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5240 offset += 4;
5242 /* mode */
5243 offset = dissect_write_mode(tvb, tree, offset, 0x0003);
5245 /* 4 reserved bytes */
5246 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
5247 offset += 4;
5249 /* data len */
5250 datalen = tvb_get_letohs(tvb, offset);
5251 proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5252 offset += 2;
5254 /* data offset */
5255 proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5256 offset += 2;
5258 BYTE_COUNT;
5260 /* file data */
5261 /* XXX - use the data offset to determine where the data starts? */
5262 offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5263 bc = 0;
5265 END_OF_SMB
5267 return offset;
5270 static int
5271 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5273 guint8 wc;
5274 guint16 bc;
5276 WORD_COUNT;
5278 /* remaining */
5279 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5280 offset += 2;
5282 BYTE_COUNT;
5284 END_OF_SMB
5286 return offset;
5289 static int
5290 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5292 guint32 to;
5293 guint16 datalen = 0, bc, fid;
5294 guint8 wc;
5296 WORD_COUNT;
5298 /* fid */
5299 fid = tvb_get_letohs(tvb, offset);
5300 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5301 offset += 2;
5303 /* total data length */
5304 proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5305 offset += 2;
5307 /* 2 reserved bytes */
5308 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5309 offset += 2;
5311 /* offset */
5312 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5313 offset += 4;
5315 /* timeout */
5316 to = tvb_get_letohl(tvb, offset);
5317 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5318 offset += 4;
5320 /* mode */
5321 offset = dissect_write_mode(tvb, tree, offset, 0x0083);
5323 /* request mask */
5324 proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5325 offset += 4;
5327 /* data len */
5328 datalen = tvb_get_letohs(tvb, offset);
5329 proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5330 offset += 2;
5332 /* data offset */
5333 proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5334 offset += 2;
5336 BYTE_COUNT;
5338 /* file data */
5339 /* XXX - use the data offset to determine where the data starts? */
5340 offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5341 bc = 0;
5343 END_OF_SMB
5345 return offset;
5348 static int
5349 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5351 guint8 wc;
5352 guint16 bc;
5354 WORD_COUNT;
5356 /* response mask */
5357 proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5358 offset += 4;
5360 BYTE_COUNT;
5362 END_OF_SMB
5364 return offset;
5367 static int
5368 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5370 guint8 wc;
5371 guint16 bc;
5373 WORD_COUNT;
5375 /* sid */
5376 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5377 offset += 2;
5379 BYTE_COUNT;
5381 END_OF_SMB
5383 return offset;
5386 static int
5387 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo _U_,
5388 proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5389 gboolean has_find_id, smb_info_t *si)
5391 proto_item *item = NULL;
5392 proto_tree *tree = NULL;
5393 int fn_len;
5394 const char *fn;
5395 char fname[11+1];
5397 DISSECTOR_ASSERT(si);
5399 if (parent_tree) {
5400 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
5401 "Resume Key");
5402 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
5405 /* reserved byte */
5406 CHECK_BYTE_COUNT_SUBR(1);
5407 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
5408 COUNT_BYTES_SUBR(1);
5410 /* file name */
5411 fn_len = 11;
5412 fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5413 TRUE, TRUE, bcp);
5414 CHECK_STRING_SUBR(fn);
5415 /* ensure that it's null-terminated */
5416 g_strlcpy(fname, fn, 11+1);
5417 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5418 fname);
5419 COUNT_BYTES_SUBR(fn_len);
5421 if (has_find_id) {
5422 CHECK_BYTE_COUNT_SUBR(1);
5423 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5424 COUNT_BYTES_SUBR(1);
5426 /* server cookie */
5427 CHECK_BYTE_COUNT_SUBR(4);
5428 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, ENC_NA);
5429 COUNT_BYTES_SUBR(4);
5430 } else {
5431 /* server cookie */
5432 CHECK_BYTE_COUNT_SUBR(5);
5433 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, ENC_NA);
5434 COUNT_BYTES_SUBR(5);
5437 /* client cookie */
5438 CHECK_BYTE_COUNT_SUBR(4);
5439 proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, ENC_NA);
5440 COUNT_BYTES_SUBR(4);
5442 *trunc = FALSE;
5443 return offset;
5446 static int
5447 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5448 proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5449 gboolean has_find_id, smb_info_t *si)
5451 proto_item *item = NULL;
5452 proto_tree *tree = NULL;
5453 int fn_len;
5454 const char *fn;
5455 char fname[13+1];
5457 DISSECTOR_ASSERT(si);
5459 if (parent_tree) {
5460 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5461 "Directory Information");
5462 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5465 /* resume key */
5466 offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5467 trunc, has_find_id, si);
5468 if (*trunc)
5469 return offset;
5471 /* File Attributes */
5472 CHECK_BYTE_COUNT_SUBR(1);
5473 offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5474 *bcp -= 1;
5476 /* last write time */
5477 CHECK_BYTE_COUNT_SUBR(4);
5478 offset = dissect_smb_datetime(tvb, tree, offset,
5479 hf_smb_last_write_time,
5480 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5481 TRUE);
5482 *bcp -= 4;
5484 /* File Size */
5485 CHECK_BYTE_COUNT_SUBR(4);
5486 proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5487 COUNT_BYTES_SUBR(4);
5489 /* file name */
5490 fn_len = 13;
5491 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5492 TRUE, TRUE, bcp);
5493 CHECK_STRING_SUBR(fn);
5494 /* ensure that it's null-terminated */
5495 g_strlcpy(fname, fn, 13+1);
5496 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5497 fname);
5498 COUNT_BYTES_SUBR(fn_len);
5500 *trunc = FALSE;
5501 return offset;
5505 static int
5506 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5507 proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si,
5508 gboolean has_find_id)
5510 int fn_len;
5511 const char *fn;
5512 guint16 rkl;
5513 guint8 wc;
5514 guint16 bc;
5515 gboolean trunc;
5517 DISSECTOR_ASSERT(si);
5519 WORD_COUNT;
5521 /* max count */
5522 proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5523 offset += 2;
5525 /* Search Attributes */
5526 offset = dissect_search_attributes(tvb, tree, offset);
5528 BYTE_COUNT;
5530 /* buffer format */
5531 CHECK_BYTE_COUNT(1);
5532 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5533 COUNT_BYTES(1);
5535 /* file name */
5536 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5537 TRUE, FALSE, &bc);
5538 if (fn == NULL)
5539 goto endofcommand;
5540 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5541 fn);
5542 COUNT_BYTES(fn_len);
5544 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5545 format_text(fn, strlen(fn)));
5547 /* buffer format */
5548 CHECK_BYTE_COUNT(1);
5549 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5550 COUNT_BYTES(1);
5552 /* resume key length */
5553 CHECK_BYTE_COUNT(2);
5554 rkl = tvb_get_letohs(tvb, offset);
5555 proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5556 COUNT_BYTES(2);
5558 /* resume key */
5559 if (rkl) {
5560 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5561 &bc, &trunc, has_find_id, si);
5562 if (trunc)
5563 goto endofcommand;
5566 END_OF_SMB
5568 return offset;
5571 static int
5572 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo,
5573 proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5575 return dissect_search_find_request(tvb, pinfo, tree, offset,
5576 smb_tree, si, FALSE);
5579 static int
5580 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo,
5581 proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5583 return dissect_search_find_request(tvb, pinfo, tree, offset,
5584 smb_tree, si, TRUE);
5587 static int
5588 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo,
5589 proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5591 return dissect_search_find_request(tvb, pinfo, tree, offset,
5592 smb_tree, si, TRUE);
5595 static int
5596 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo,
5597 proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5598 gboolean has_find_id, smb_info_t *si)
5600 guint16 count = 0;
5601 guint8 wc;
5602 guint16 bc;
5603 gboolean trunc;
5605 WORD_COUNT;
5607 /* count */
5608 count = tvb_get_letohs(tvb, offset);
5609 proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5610 offset += 2;
5612 BYTE_COUNT;
5614 /* buffer format */
5615 CHECK_BYTE_COUNT(1);
5616 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5617 COUNT_BYTES(1);
5619 /* data len */
5620 CHECK_BYTE_COUNT(2);
5621 proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5622 COUNT_BYTES(2);
5624 while(count--) {
5625 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5626 &bc, &trunc, has_find_id, si);
5627 if (trunc)
5628 goto endofcommand;
5631 END_OF_SMB
5633 return offset;
5636 static int
5637 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5639 return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5640 FALSE, si);
5643 static int
5644 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5646 return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5647 TRUE, si);
5650 static int
5651 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5652 proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5654 guint8 wc;
5655 guint16 bc;
5656 guint16 data_len;
5658 WORD_COUNT;
5660 /* reserved */
5661 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5662 offset += 2;
5664 BYTE_COUNT;
5666 /* buffer format */
5667 CHECK_BYTE_COUNT(1);
5668 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5669 COUNT_BYTES(1);
5671 /* data len */
5672 CHECK_BYTE_COUNT(2);
5673 data_len = tvb_get_ntohs(tvb, offset);
5674 proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5675 COUNT_BYTES(2);
5677 if (data_len != 0) {
5678 CHECK_BYTE_COUNT(data_len);
5679 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5680 data_len, ENC_NA);
5681 COUNT_BYTES(data_len);
5684 END_OF_SMB
5686 return offset;
5689 static const value_string locking_ol_vals[] = {
5690 {0, "Client is not holding oplock on this file"},
5691 {1, "Level 2 oplock currently held by client"},
5692 {0, NULL}
5695 static const true_false_string tfs_lock_type_large = {
5696 "Large file locking format requested",
5697 "Large file locking format not requested"
5699 static const true_false_string tfs_lock_type_cancel = {
5700 "Cancel outstanding lock request",
5701 "Don't cancel outstanding lock request"
5703 static const true_false_string tfs_lock_type_change = {
5704 "Change lock type",
5705 "Don't change lock type"
5707 static const true_false_string tfs_lock_type_oplock = {
5708 "This is an oplock break notification/response",
5709 "This is not an oplock break notification/response"
5711 static const true_false_string tfs_lock_type_shared = {
5712 "This is a shared lock",
5713 "This is an exclusive lock"
5715 static int
5716 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5718 guint8 wc, cmd = 0xff, lt = 0, ol = 0;
5719 guint16 andxoffset = 0, un = 0, ln = 0, bc, fid, num_lock = 0, num_unlock = 0;
5720 guint32 to;
5721 proto_item *litem = NULL;
5722 proto_tree *ltree = NULL;
5723 proto_item *it = NULL;
5724 proto_tree *tr = NULL;
5725 int old_offset = offset;
5726 smb_locking_saved_info_t *ld = NULL;
5729 DISSECTOR_ASSERT(si);
5731 WORD_COUNT;
5733 /* next smb command */
5734 cmd = tvb_get_guint8(tvb, offset);
5735 if (cmd != 0xff) {
5736 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
5737 } else {
5738 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
5740 offset += 1;
5742 /* reserved byte */
5743 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
5744 offset += 1;
5746 /* andxoffset */
5747 andxoffset = tvb_get_letohs(tvb, offset);
5748 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5749 offset += 2;
5751 /* fid */
5752 fid = tvb_get_letohs(tvb, offset);
5753 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5754 offset += 2;
5756 /* lock type */
5757 lt = tvb_get_guint8(tvb, offset);
5758 if (tree) {
5759 litem = proto_tree_add_item(tree, hf_smb_lock_type, tvb, offset, 1, ENC_NA);
5760 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5762 proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5763 tvb, offset, 1, lt);
5764 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5765 tvb, offset, 1, lt);
5766 proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5767 tvb, offset, 1, lt);
5768 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5769 tvb, offset, 1, lt);
5770 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5771 tvb, offset, 1, lt);
5773 offset += 1;
5775 /* oplock level */
5776 ol = tvb_get_guint8(tvb, offset);
5777 proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5778 offset += 1;
5780 /* timeout */
5781 to = tvb_get_letohl(tvb, offset);
5782 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5783 offset += 4;
5785 /* number of unlocks */
5786 un = tvb_get_letohs(tvb, offset);
5787 num_unlock = un;
5788 proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5789 offset += 2;
5791 /* number of locks */
5792 ln = tvb_get_letohs(tvb, offset);
5793 num_lock = ln;
5794 proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5795 offset += 2;
5797 BYTE_COUNT;
5799 /* store the locking data for the response */
5800 if ((!pinfo->fd->flags.visited) && si->sip) {
5801 ld = (smb_locking_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_locking_saved_info_t));
5802 ld->type = lt;
5803 ld->oplock_level= ol;
5804 ld->num_lock = num_lock;
5805 ld->num_unlock = num_unlock;
5806 ld->locks = NULL;
5807 ld->unlocks = NULL;
5808 si->sip->extra_info_type = SMB_EI_LOCKDATA;
5809 si->sip->extra_info = ld;
5812 /* unlocks */
5813 if (un) {
5814 old_offset = offset;
5816 it = proto_tree_add_text(tree, tvb, offset, -1, "Unlocks");
5817 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5818 while(un--) {
5819 proto_item *litem_2 = NULL;
5820 proto_tree *ltree_2 = NULL;
5821 if (lt&0x10) {
5822 guint64 val;
5823 guint16 lock_pid;
5824 guint64 lock_offset;
5825 guint64 lock_length;
5827 /* large lock format */
5828 litem_2 = proto_tree_add_text(tr, tvb, offset, 20, "Unlock");
5829 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_unlock);
5831 /* PID */
5832 CHECK_BYTE_COUNT(2);
5833 lock_pid = tvb_get_letohs(tvb, offset);
5834 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5835 COUNT_BYTES(2);
5837 /* 2 reserved bytes */
5838 CHECK_BYTE_COUNT(2);
5839 proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5840 COUNT_BYTES(2);
5842 /* offset */
5843 CHECK_BYTE_COUNT(8);
5844 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5845 | tvb_get_letohl(tvb, offset+4);
5846 lock_offset = val;
5847 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
5848 COUNT_BYTES(8);
5850 /* length */
5851 CHECK_BYTE_COUNT(8);
5852 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5853 | tvb_get_letohl(tvb, offset+4);
5854 lock_length = val;
5855 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
5856 COUNT_BYTES(8);
5858 /* remember the unlock for the reply */
5859 if (ld) {
5860 smb_lock_info_t *li;
5861 li = (smb_lock_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_lock_info_t));
5862 li->next = ld->unlocks;
5863 ld->unlocks = li;
5864 li->pid = lock_pid;
5865 li->offset = lock_offset;
5866 li->length = lock_length;
5868 } else {
5869 /* normal lock format */
5870 litem_2 = proto_tree_add_text(tr, tvb, offset, 10, "Unlock");
5871 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_unlock);
5873 /* PID */
5874 CHECK_BYTE_COUNT(2);
5875 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5876 COUNT_BYTES(2);
5878 /* offset */
5879 CHECK_BYTE_COUNT(4);
5880 proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5881 COUNT_BYTES(4);
5883 /* lock count */
5884 CHECK_BYTE_COUNT(4);
5885 proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5886 COUNT_BYTES(4);
5889 proto_item_set_len(it, offset-old_offset);
5890 it = NULL;
5893 /* locks */
5894 if (ln) {
5895 old_offset = offset;
5897 it = proto_tree_add_text(tree, tvb, offset, -1, "Locks");
5898 tr = proto_item_add_subtree(it, ett_smb_locks);
5899 while(ln--) {
5900 proto_item *litem_2 = NULL;
5901 proto_tree *ltree_2 = NULL;
5902 if (lt&0x10) {
5903 guint64 val;
5904 guint16 lock_pid;
5905 guint64 lock_offset;
5906 guint64 lock_length;
5908 /* large lock format */
5909 litem_2 = proto_tree_add_text(tr, tvb, offset, 20, "Lock");
5910 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_lock);
5912 /* PID */
5913 CHECK_BYTE_COUNT(2);
5914 lock_pid = tvb_get_letohs(tvb, offset);
5915 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5916 COUNT_BYTES(2);
5918 /* 2 reserved bytes */
5919 CHECK_BYTE_COUNT(2);
5920 proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5921 COUNT_BYTES(2);
5923 /* offset */
5924 CHECK_BYTE_COUNT(8);
5925 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5926 | tvb_get_letohl(tvb, offset+4);
5927 lock_offset = val;
5928 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
5929 COUNT_BYTES(8);
5931 /* length */
5932 CHECK_BYTE_COUNT(8);
5933 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5934 | tvb_get_letohl(tvb, offset+4);
5935 lock_length = val;
5936 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
5937 COUNT_BYTES(8);
5939 /* remember the lock for the reply */
5940 if (ld) {
5941 smb_lock_info_t *li;
5942 li = (smb_lock_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_lock_info_t));
5943 li->next = ld->locks;
5944 ld->locks = li;
5945 li->pid = lock_pid;
5946 li->offset = lock_offset;
5947 li->length = lock_length;
5949 } else {
5950 /* normal lock format */
5951 litem_2 = proto_tree_add_text(tr, tvb, offset, 10, "Lock");
5952 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_lock);
5954 /* PID */
5955 CHECK_BYTE_COUNT(2);
5956 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5957 COUNT_BYTES(2);
5959 /* offset */
5960 CHECK_BYTE_COUNT(4);
5961 proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5962 COUNT_BYTES(4);
5964 /* lock count */
5965 CHECK_BYTE_COUNT(4);
5966 proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5967 COUNT_BYTES(4);
5970 proto_item_set_len(it, offset-old_offset);
5971 it = NULL;
5974 END_OF_SMB
5976 if (it != NULL) {
5978 * We ran out of byte count in the middle of dissecting
5979 * the locks or the unlocks; set the site of the item
5980 * we were dissecting.
5982 proto_item_set_len(it, offset-old_offset);
5985 if (cmd != 0xff) { /* there is an andX command */
5986 if (andxoffset < offset) {
5987 THROW(ReportedBoundsError);
5989 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
5992 return offset;
5995 static int
5996 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5998 guint8 wc, cmd = 0xff;
5999 guint16 andxoffset = 0;
6000 guint16 bc;
6002 DISSECTOR_ASSERT(si);
6004 /* print the lock info from the request */
6005 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_LOCKDATA)) {
6006 smb_locking_saved_info_t *ld;
6007 proto_item *litem = NULL;
6008 proto_tree *ltree = NULL;
6010 ld = (smb_locking_saved_info_t *)si->sip->extra_info;
6011 if (ld != NULL) {
6012 proto_item *lit;
6013 proto_tree *ltr;
6014 smb_lock_info_t *li;
6015 if (tree) {
6016 litem = proto_tree_add_item(tree, hf_smb_lock_type, tvb, 0, 0, ENC_NA);
6017 PROTO_ITEM_SET_GENERATED(litem);
6018 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
6020 proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
6021 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
6022 proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
6023 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
6024 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
6025 proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
6026 proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
6027 proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
6029 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
6030 ltr = proto_item_add_subtree(lit, ett_smb_lock);
6031 li = ld->locks;
6032 while(li) {
6033 proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
6034 proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
6035 proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
6036 li = li->next;
6038 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
6039 ltr = proto_item_add_subtree(lit, ett_smb_unlock);
6040 li = ld->unlocks;
6041 while(li) {
6042 proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
6043 proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
6044 proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
6045 li = li->next;
6051 WORD_COUNT;
6053 /* next smb command */
6054 cmd = tvb_get_guint8(tvb, offset);
6055 if (cmd != 0xff) {
6056 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6057 } else {
6058 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6060 offset += 1;
6062 /* reserved byte */
6063 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6064 offset += 1;
6066 /* andxoffset */
6067 andxoffset = tvb_get_letohs(tvb, offset);
6068 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6069 offset += 2;
6071 BYTE_COUNT;
6073 END_OF_SMB
6075 if (cmd != 0xff) { /* there is an andX command */
6076 if (andxoffset < offset) {
6077 THROW(ReportedBoundsError);
6079 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6082 return offset;
6086 const value_string oa_open_vals[] = {
6087 { 0, "No action taken?"},
6088 { 1, "The file existed and was opened"},
6089 { 2, "The file did not exist but was created"},
6090 { 3, "The file existed and was truncated"},
6091 { 0x8001, "The file existed and was opened, and an OpLock was granted"},
6092 { 0x8002, "The file did not exist but was created, and an OpLock was granted"},
6093 { 0x8003, "The file existed and was truncated, and an OpLock was granted"},
6094 {0, NULL}
6096 static const true_false_string tfs_oa_lock = {
6097 "File is currently opened only by this user",
6098 "File is opened by another user (or mode not supported by server)"
6100 static int
6101 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6103 guint16 mask;
6104 proto_item *item;
6105 proto_tree *tree;
6107 mask = tvb_get_letohs(tvb, offset);
6109 if (parent_tree) {
6110 item = proto_tree_add_item(parent_tree, hf_smb_open_action, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6111 tree = proto_item_add_subtree(item, ett_smb_open_action);
6113 proto_tree_add_boolean(tree, hf_smb_open_action_lock,
6114 tvb, offset, 2, mask);
6115 proto_tree_add_uint(tree, hf_smb_open_action_open,
6116 tvb, offset, 2, mask);
6118 offset += 2;
6120 return offset;
6123 static const true_false_string tfs_open_flags_add_info = {
6124 "Additional information requested",
6125 "Additional information not requested"
6127 static const true_false_string tfs_open_flags_ex_oplock = {
6128 "Exclusive oplock requested",
6129 "Exclusive oplock not requested"
6131 static const true_false_string tfs_open_flags_batch_oplock = {
6132 "Batch oplock requested",
6133 "Batch oplock not requested"
6135 static const true_false_string tfs_open_flags_ealen = {
6136 "Total length of EAs requested",
6137 "Total length of EAs not requested"
6139 static int
6140 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
6142 guint16 mask;
6143 proto_item *item;
6144 proto_tree *tree;
6146 mask = tvb_get_letohs(tvb, offset);
6148 if (parent_tree) {
6149 item = proto_tree_add_item(parent_tree, hf_smb_open_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6150 tree = proto_item_add_subtree(item, ett_smb_open_flags);
6152 if (bm&0x0001) {
6153 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
6154 tvb, offset, 2, mask);
6156 if (bm&0x0002) {
6157 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
6158 tvb, offset, 2, mask);
6160 if (bm&0x0004) {
6161 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
6162 tvb, offset, 2, mask);
6164 if (bm&0x0008) {
6165 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
6166 tvb, offset, 2, mask);
6170 offset += 2;
6172 return offset;
6175 /* [MS-CIFS].pdf 2.2.4.64.2 provides the last two file types, however
6176 [MS-SMB].PDF 2.2.4.9.2 elides value 4, Character mode device. */
6177 static const value_string filetype_vals[] = {
6178 { 0, "Disk file or directory"},
6179 { 1, "Named pipe in byte mode"},
6180 { 2, "Named pipe in message mode"},
6181 { 3, "Spooled printer"},
6182 { 4, "Character mode device"},
6183 { 0xFFFF, "Unknown file type"},
6184 {0, NULL}
6186 static int
6187 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6189 guint8 wc, cmd = 0xff;
6190 guint16 andxoffset = 0, bc;
6191 guint32 to;
6192 int fn_len;
6193 const char *fn;
6195 DISSECTOR_ASSERT(si);
6197 WORD_COUNT;
6199 /* next smb command */
6200 cmd = tvb_get_guint8(tvb, offset);
6201 if (cmd != 0xff) {
6202 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6203 } else {
6204 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6206 offset += 1;
6208 /* reserved byte */
6209 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6210 offset += 1;
6212 /* andxoffset */
6213 andxoffset = tvb_get_letohs(tvb, offset);
6214 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6215 offset += 2;
6217 /* open flags */
6218 offset = dissect_open_flags(tvb, tree, offset, 0x0007);
6220 /* desired access */
6221 offset = dissect_access(tvb, tree, offset, "Desired");
6223 /* Search Attributes */
6224 offset = dissect_search_attributes(tvb, tree, offset);
6226 /* File Attributes */
6227 offset = dissect_file_attributes(tvb, tree, offset);
6229 /* creation time */
6230 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
6232 /* open function */
6233 offset = dissect_open_function(tvb, tree, offset);
6235 /* allocation size */
6236 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6237 offset += 4;
6239 /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
6240 to = tvb_get_letohl(tvb, offset);
6241 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
6242 offset += 4;
6244 /* 4 reserved bytes */
6245 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
6246 offset += 4;
6248 BYTE_COUNT;
6250 /* file name */
6251 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
6252 FALSE, FALSE, &bc);
6253 if (fn == NULL)
6254 goto endofcommand;
6255 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6256 fn);
6257 COUNT_BYTES(fn_len);
6259 /* Copied this portion of code from create_andx_request
6260 to guarantee that fsi and si->sip are always correctly filled out */
6261 if ((!pinfo->fd->flags.visited) && si->sip && fn) {
6262 smb_fid_saved_info_t *fsi;
6264 fsi = (smb_fid_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_fid_saved_info_t));
6265 fsi->filename = wmem_strdup(wmem_file_scope(), fn);
6267 si->sip->extra_info_type = SMB_EI_FILEDATA;
6268 si->sip->extra_info = fsi;
6271 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
6272 format_text(fn, strlen(fn)));
6274 END_OF_SMB
6276 if (cmd != 0xff) { /* there is an andX command */
6277 if (andxoffset < offset) {
6278 THROW(ReportedBoundsError);
6280 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6283 return offset;
6286 static const true_false_string tfs_ipc_state_nonblocking = {
6287 "Reads/writes return immediately if no data available",
6288 "Reads/writes block if no data available"
6290 static const value_string ipc_state_endpoint_vals[] = {
6291 { 0, "Consumer end of pipe"},
6292 { 1, "Server end of pipe"},
6293 {0, NULL}
6295 static const value_string ipc_state_pipe_type_vals[] = {
6296 { 0, "Byte stream pipe"},
6297 { 1, "Message pipe"},
6298 {0, NULL}
6300 static const value_string ipc_state_read_mode_vals[] = {
6301 { 0, "Read pipe as a byte stream"},
6302 { 1, "Read messages from pipe"},
6303 {0, NULL}
6307 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
6308 gboolean setstate_flag)
6310 guint16 mask;
6311 proto_item *item;
6312 proto_tree *tree;
6314 mask = tvb_get_letohs(tvb, offset);
6316 if (parent_tree) {
6317 item = proto_tree_add_item(parent_tree, hf_smb_ipc_state, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6318 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
6320 proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
6321 tvb, offset, 2, mask);
6322 if (!setstate_flag) {
6323 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
6324 tvb, offset, 2, mask);
6325 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
6326 tvb, offset, 2, mask);
6328 proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
6329 tvb, offset, 2, mask);
6330 if (!setstate_flag) {
6331 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
6332 tvb, offset, 2, mask);
6336 offset += 2;
6338 return offset;
6341 static int
6342 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6344 guint8 wc, cmd = 0xff;
6345 guint16 andxoffset = 0, bc;
6346 guint16 fid;
6347 guint16 ftype;
6348 guint16 fattr;
6349 smb_fid_info_t *fid_info = NULL;
6350 gboolean isdir = FALSE;
6352 WORD_COUNT;
6354 /* next smb command */
6355 cmd = tvb_get_guint8(tvb, offset);
6356 if (cmd != 0xff) {
6357 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6358 } else {
6359 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6361 offset += 1;
6363 /* reserved byte */
6364 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6365 offset += 1;
6367 /* andxoffset */
6368 andxoffset = tvb_get_letohs(tvb, offset);
6369 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6370 offset += 2;
6372 /* fid */
6373 fid = tvb_get_letohs(tvb, offset);
6374 /* we add fid_info= to this call so that we save the result */
6375 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
6377 offset += 2;
6379 /* File Attributes */
6380 fattr = tvb_get_letohs(tvb, offset);
6381 isdir = fattr & SMB_FILE_ATTRIBUTE_DIRECTORY;
6382 offset = dissect_file_attributes(tvb, tree, offset);
6384 /* last write time */
6385 offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6387 /* File Size */
6388 /* We store the file_size in the fid_info */
6389 if (fid_info) {
6390 fid_info->end_of_file = (guint64) tvb_get_letohl(tvb, offset);
6392 proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6393 offset += 4;
6395 /* granted access */
6396 offset = dissect_access(tvb, tree, offset, "Granted");
6398 /* File Type */
6399 ftype = tvb_get_letohs(tvb, offset);
6400 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6401 offset += 2;
6402 /* Copied from dissect_nt_create_andx_response
6403 Try to remember the type of this fid so that we can dissect
6404 any future security descriptor (access mask) properly
6406 if (fid_info) {
6407 fid_info->type = SMB_FID_TYPE_UNKNOWN;
6409 if (ftype == 0) {
6410 if (isdir == 0) {
6411 if (fid_info) {
6412 fid_info->type = SMB_FID_TYPE_FILE;
6414 } else {
6415 if (fid_info) {
6416 fid_info->type = SMB_FID_TYPE_DIR;
6420 if ((ftype == 2) || (ftype == 1)) {
6421 if (fid_info) {
6422 fid_info->type = SMB_FID_TYPE_PIPE;
6426 /* IPC State */
6427 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6429 /* open_action */
6430 offset = dissect_open_action(tvb, tree, offset);
6432 /* server fid */
6433 proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6434 offset += 4;
6436 /* 2 reserved bytes */
6437 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6438 offset += 2;
6440 BYTE_COUNT;
6442 END_OF_SMB
6444 if (cmd != 0xff) { /* there is an andX command */
6445 if (andxoffset < offset) {
6446 THROW(ReportedBoundsError);
6448 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6451 return offset;
6454 static int
6455 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6457 guint8 wc, cmd = 0xff;
6458 guint16 andxoffset = 0, bc, maxcnt_low;
6459 guint32 maxcnt_high;
6460 guint32 maxcnt = 0;
6461 guint32 offsetlow, offsethigh = 0;
6462 guint64 ofs;
6463 unsigned int fid;
6464 rw_info_t *rwi = NULL;
6467 DISSECTOR_ASSERT(si);
6469 WORD_COUNT;
6471 /* next smb command */
6472 cmd = tvb_get_guint8(tvb, offset);
6473 if (cmd != 0xff) {
6474 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6475 } else {
6476 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6478 offset += 1;
6480 /* reserved byte */
6481 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6482 offset += 1;
6484 /* andxoffset */
6485 andxoffset = tvb_get_letohs(tvb, offset);
6486 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6487 offset += 2;
6489 /* fid */
6490 fid = tvb_get_letohs(tvb, offset);
6491 dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
6492 offset += 2;
6494 /* offset */
6495 offsetlow = tvb_get_letohl(tvb, offset);
6496 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6497 offset += 4;
6499 /* max count low */
6500 maxcnt_low = tvb_get_letohs(tvb, offset);
6501 proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
6502 offset += 2;
6504 /* min count */
6505 proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6506 offset += 2;
6509 * max count high
6511 * XXX - we should really only do this in case we have seen
6512 * LARGE FILE being negotiated. Unfortunately, we might not
6513 * have seen the negotiation phase in the capture....
6515 * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
6516 * it's 32 bits, but the description says "High 16 bits of
6517 * MaxCount if CAP_LARGE_READX".
6519 * The SMB File Sharing Protocol Extensions Version 2.0,
6520 * Document Version 3.3 spec doesn't speak of an extra 16
6521 * bits in max count, but it does show a 32-bit timeout
6522 * after the min count field.
6524 * The Microsoft [MS-SMB] spec shows it as a ULONG named
6525 * Timeout_or_MaxCountHigh, which is
6527 * ...extended to be treated as a union of a 32-bit
6528 * Timeout field and a 16-bit MaxCountHigh field.
6529 * When reading from a regular file, the field
6530 * MUST be interpreted as MaxCountHigh and the
6531 * two unused bytes MUST be zero. When reading from
6532 * a name[sic] pipe or I/O device, the field MUST
6533 * be interpreted as Timeout.
6535 * Timeout is a timeout in milliseconds, with 0xffffffff
6536 * and 0xfffffffe having special meaning.
6538 * MaxCountHigh is 16 bits of the MaxCountHigh value
6539 * followed by 16 bits of Reserved.
6541 * We fetch and display it as 32 bits for now.
6543 * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
6544 * bytes and we just ignore it.
6546 maxcnt_high = tvb_get_letohl(tvb, offset);
6547 if (maxcnt_high == 0xffffffff) {
6548 maxcnt_high = 0;
6549 } else {
6550 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
6553 offset += 4;
6555 maxcnt = maxcnt_high;
6556 maxcnt = (maxcnt<<16) | maxcnt_low;
6558 /* remaining */
6559 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6560 offset += 2;
6562 if (wc == 12) {
6563 /* high offset */
6564 offsethigh = tvb_get_letohl(tvb, offset);
6565 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6566 offset += 4;
6569 ofs = offsethigh;
6570 ofs = (ofs<<32) | offsetlow;
6572 col_append_fstr(pinfo->cinfo, COL_INFO,
6573 ", %u byte%s at offset %" G_GINT64_MODIFIER "u",
6574 maxcnt, (maxcnt == 1) ? "" : "s", ofs);
6576 /* save the offset/len for this transaction */
6577 if (si->sip && !pinfo->fd->flags.visited) {
6578 rwi = (rw_info_t *)wmem_alloc(wmem_file_scope(), sizeof(rw_info_t));
6579 rwi->offset = ofs;
6580 rwi->len = maxcnt;
6581 rwi->fid = fid;
6583 si->sip->extra_info_type = SMB_EI_RWINFO;
6584 si->sip->extra_info = rwi;
6586 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6587 rwi = (rw_info_t *)si->sip->extra_info;
6589 if (rwi) {
6590 proto_item *it;
6592 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6594 PROTO_ITEM_SET_GENERATED(it);
6595 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6596 PROTO_ITEM_SET_GENERATED(it);
6599 BYTE_COUNT;
6601 END_OF_SMB
6603 if (cmd != 0xff) { /* there is an andX command */
6604 if (andxoffset < offset) {
6605 THROW(ReportedBoundsError);
6607 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6610 return offset;
6613 static int
6614 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6616 guint8 wc, cmd = 0xff;
6617 guint16 andxoffset = 0, bc, datalen_low, dataoffset = 0;
6618 guint32 datalen = 0, datalen_high;
6619 rw_info_t *rwi = NULL;
6620 guint16 fid = 0; /* was int fid = 0; */
6622 guint32 tvblen;
6624 DISSECTOR_ASSERT(si);
6626 WORD_COUNT;
6628 /* next smb command */
6629 cmd = tvb_get_guint8(tvb, offset);
6630 if (cmd != 0xff) {
6631 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6632 } else {
6633 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6635 offset += 1;
6637 /* reserved byte */
6638 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6639 offset += 1;
6641 /* andxoffset */
6642 andxoffset = tvb_get_letohs(tvb, offset);
6643 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6644 offset += 2;
6646 /* If we have seen the request, then print which FID this refers to */
6647 /* first check if we have seen the request */
6648 if ((si->sip != NULL) && (si->sip->frame_req > 0) && (si->sip->extra_info_type == SMB_EI_FID)) {
6649 fid = GPOINTER_TO_INT(si->sip->extra_info);
6650 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE, si);
6653 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6654 rwi = (rw_info_t *)si->sip->extra_info;
6656 if (rwi) {
6657 proto_item *it;
6659 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6661 PROTO_ITEM_SET_GENERATED(it);
6662 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6663 PROTO_ITEM_SET_GENERATED(it);
6665 /* we need the fid for the call to dcerpc below */
6666 fid = rwi->fid;
6669 /* remaining */
6670 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6671 offset += 2;
6673 /* data compaction mode */
6674 proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6675 offset += 2;
6677 /* 2 reserved bytes */
6678 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6679 offset += 2;
6681 /* data len low */
6682 datalen_low = tvb_get_letohs(tvb, offset);
6683 proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6684 offset += 2;
6686 /* data offset */
6687 dataoffset = tvb_get_letohs(tvb, offset);
6688 proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6689 offset += 2;
6692 * XXX - the SNIA SMB spec says this is a USHORT, not a
6693 * ULONG.
6695 * XXX - we should really only do this in case we have seen
6696 * LARGE FILE being negotiated. Unfortunately, we might not
6697 * have seen the negotiation phase in the capture....
6699 /* data length high */
6700 datalen_high = tvb_get_letohl(tvb, offset);
6701 if (datalen_high == 0xffffffff) {
6702 datalen_high = 0;
6703 } else {
6704 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6706 offset += 4;
6708 datalen = datalen_high;
6709 datalen = (datalen<<16) | datalen_low;
6712 col_append_fstr(pinfo->cinfo, COL_INFO,
6713 ", %u byte%s", datalen,
6714 (datalen == 1) ? "" : "s");
6717 /* 6 reserved bytes */
6718 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, ENC_NA);
6719 offset += 6;
6721 BYTE_COUNT;
6723 /* file data, might be DCERPC on a pipe */
6724 if (bc) {
6725 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6726 top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid, si);
6727 bc = 0;
6730 /* feed the export object tap listener */
6731 tvblen = tvb_length_remaining(tvb, dataoffset);
6732 if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
6733 feed_eo_smb(SMB_COM_READ_ANDX,fid,tvb,pinfo,dataoffset,datalen,rwi->len,rwi->offset, si);
6736 END_OF_SMB
6738 if (cmd != 0xff) { /* there is an andX command */
6739 if (andxoffset < offset) {
6740 THROW(ReportedBoundsError);
6742 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6745 return offset;
6748 static int
6749 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6751 guint8 wc, cmd = 0xff;
6752 guint16 andxoffset = 0, bc, dataoffset = 0, datalen_low, datalen_high;
6753 guint32 offsetlow, offsethigh = 0;
6754 guint64 ofs;
6755 guint32 datalen = 0;
6756 guint16 fid = 0; /* was unsigned int fid = 0; */
6757 guint16 mode = 0;
6758 rw_info_t *rwi = NULL;
6760 guint32 tvblen;
6762 DISSECTOR_ASSERT(si);
6764 WORD_COUNT;
6766 /* next smb command */
6767 cmd = tvb_get_guint8(tvb, offset);
6768 if (cmd != 0xff) {
6769 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6770 } else {
6771 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6773 offset += 1;
6775 /* reserved byte */
6776 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6777 offset += 1;
6779 /* andxoffset */
6780 andxoffset = tvb_get_letohs(tvb, offset);
6781 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6782 offset += 2;
6784 /* fid */
6785 fid = tvb_get_letohs(tvb, offset);
6786 dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
6787 offset += 2;
6789 /* offset */
6790 offsetlow = tvb_get_letohl(tvb, offset);
6791 proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6792 offset += 4;
6794 /* reserved */
6795 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
6796 offset += 4;
6798 /* mode */
6799 mode = tvb_get_letohs(tvb, offset);
6800 offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6802 /* remaining */
6803 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6804 offset += 2;
6807 * XXX - we should really only do this in case we have seen
6808 * LARGE FILE being negotiated. Unfortunately, we might not
6809 * have seen the negotiation phase in the capture....
6811 /* data length high */
6812 datalen_high = tvb_get_letohs(tvb, offset);
6813 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6814 offset += 2;
6816 /* data len low */
6817 datalen_low = tvb_get_letohs(tvb, offset);
6818 proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6819 offset += 2;
6821 datalen = datalen_high;
6822 datalen = (datalen<<16) | datalen_low;
6824 /* data offset */
6825 dataoffset = tvb_get_letohs(tvb, offset);
6826 proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6827 offset += 2;
6829 if (wc == 14) {
6830 /* high offset */
6831 offsethigh = tvb_get_letohl(tvb, offset);
6832 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6833 offset += 4;
6836 ofs = offsethigh;
6837 ofs = (ofs<<32) | offsetlow;
6839 col_append_fstr(pinfo->cinfo, COL_INFO,
6840 ", %u byte%s at offset %" G_GINT64_MODIFIER "u",
6841 datalen, (datalen == 1) ? "" : "s", ofs);
6843 /* save the offset/len for this transaction */
6844 if (si->sip && !pinfo->fd->flags.visited) {
6845 rwi = (rw_info_t *)wmem_alloc(wmem_file_scope(), sizeof(rw_info_t));
6846 rwi->offset = ofs;
6847 rwi->len = datalen;
6848 rwi->fid = fid;
6850 si->sip->extra_info_type = SMB_EI_RWINFO;
6851 si->sip->extra_info = rwi;
6853 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6854 rwi = (rw_info_t *)si->sip->extra_info;
6856 if (rwi) {
6857 proto_item *it;
6859 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6861 PROTO_ITEM_SET_GENERATED(it);
6862 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6863 PROTO_ITEM_SET_GENERATED(it);
6867 BYTE_COUNT;
6869 /* if both the MessageStart and the WriteRawNamedPipe flags are set
6870 the first two bytes of the payload is the length of the data.
6871 Assume that all WriteAndX PDUs that have MESSAGE_START set to
6872 be over the IPC$ share and thus they all transport DCERPC.
6873 (if we didnt already know that from the TreeConnect call)
6875 if (mode&WRITE_MODE_MESSAGE_START) {
6876 if (mode&WRITE_MODE_RAW) {
6877 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6878 offset += 2;
6879 dataoffset += 2;
6880 bc -= 2;
6881 datalen -= 2;
6883 if (!pinfo->fd->flags.visited) {
6884 /* In case we did not see the TreeConnect call,
6885 store this TID here as well as a IPC TID
6886 so we know that future Read/Writes to this
6887 TID is (probably) DCERPC.
6889 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
6890 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6892 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6894 if (si->sip) {
6895 si->sip->flags|=SMB_SIF_TID_IS_IPC;
6899 /* file data, might be DCERPC on a pipe */
6900 if (bc != 0) {
6901 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6902 top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid, si);
6903 bc = 0;
6906 /* feed the export object tap listener */
6907 tvblen = tvb_length_remaining(tvb, dataoffset);
6908 if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
6909 feed_eo_smb(SMB_COM_WRITE_ANDX,fid,tvb,pinfo,dataoffset,datalen,rwi->len,rwi->offset, si);
6912 END_OF_SMB
6914 if (cmd != 0xff) { /* there is an andX command */
6915 if (andxoffset < offset) {
6916 THROW(ReportedBoundsError);
6918 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6921 return offset;
6924 static int
6925 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6927 guint8 wc, cmd = 0xff;
6928 guint16 andxoffset = 0, bc, count_low, count_high;
6929 guint32 count = 0;
6930 rw_info_t *rwi = NULL;
6932 DISSECTOR_ASSERT(si);
6934 WORD_COUNT;
6936 /* next smb command */
6937 cmd = tvb_get_guint8(tvb, offset);
6938 if (cmd != 0xff) {
6939 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6940 } else {
6941 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6943 offset += 1;
6945 /* reserved byte */
6946 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6947 offset += 1;
6949 /* andxoffset */
6950 andxoffset = tvb_get_letohs(tvb, offset);
6951 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6952 offset += 2;
6955 if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6956 rwi = (rw_info_t *)si->sip->extra_info;
6958 if (rwi) {
6959 proto_item *it;
6961 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6963 PROTO_ITEM_SET_GENERATED(it);
6964 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6965 PROTO_ITEM_SET_GENERATED(it);
6969 /* write count low */
6970 count_low = tvb_get_letohs(tvb, offset);
6971 proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6972 offset += 2;
6974 /* remaining */
6975 proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6976 offset += 2;
6978 /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6979 /* write count high */
6980 count_high = tvb_get_letohs(tvb, offset);
6981 proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6982 offset += 2;
6984 count = count_high;
6985 count = (count<<16) | count_low;
6987 col_append_fstr(pinfo->cinfo, COL_INFO,
6988 ", %u byte%s", count,
6989 (count == 1) ? "" : "s");
6991 /* 2 reserved bytes */
6992 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6993 offset += 2;
6995 BYTE_COUNT;
6997 END_OF_SMB
6999 if (cmd != 0xff) { /* there is an andX command */
7000 if (andxoffset < offset) {
7001 THROW(ReportedBoundsError);
7003 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7006 return offset;
7010 static const true_false_string tfs_setup_action_guest = {
7011 "Logged in as GUEST",
7012 "Not logged in as GUEST"
7014 static int
7015 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7017 guint16 mask;
7018 proto_item *item;
7019 proto_tree *tree;
7021 mask = tvb_get_letohs(tvb, offset);
7023 if (parent_tree) {
7024 item = proto_tree_add_item(parent_tree, hf_smb_setup_action, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7025 tree = proto_item_add_subtree(item, ett_smb_setup_action);
7027 proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
7028 tvb, offset, 2, mask);
7030 offset += 2;
7032 return offset;
7036 static int
7037 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7039 guint8 wc, cmd = 0xff;
7040 guint16 bc;
7041 guint16 andxoffset = 0;
7042 int an_len;
7043 const char *an;
7044 int dn_len;
7045 const char *dn;
7046 guint16 pwlen = 0;
7047 guint16 sbloblen = 0, sbloblen_short;
7048 guint16 apwlen = 0, upwlen = 0;
7049 gboolean unicodeflag;
7050 static int ntlmssp_tap_id = 0;
7051 const ntlmssp_header_t *ntlmssph;
7053 if (!ntlmssp_tap_id) {
7054 GString *error_string;
7055 /* We dont specify any callbacks at all.
7056 * Instead we manually fetch the tapped data after the
7057 * security blob has been fully dissected and before
7058 * we exit from this dissector.
7060 error_string = register_tap_listener("ntlmssp", NULL, NULL,
7061 TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
7062 if (!error_string) {
7063 ntlmssp_tap_id = find_tap_id("ntlmssp");
7064 } else {
7065 g_string_free(error_string, TRUE);
7069 DISSECTOR_ASSERT(si);
7071 WORD_COUNT;
7073 /* next smb command */
7074 cmd = tvb_get_guint8(tvb, offset);
7075 if (cmd != 0xff) {
7076 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7077 } else {
7078 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7080 offset += 1;
7082 /* reserved byte */
7083 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7084 offset += 1;
7086 /* andxoffset */
7087 andxoffset = tvb_get_letohs(tvb, offset);
7088 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7089 offset += 2;
7091 /* Maximum Buffer Size */
7092 proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7093 offset += 2;
7095 /* Maximum Multiplex Count */
7096 proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7097 offset += 2;
7099 /* VC Number */
7100 proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7101 offset += 2;
7103 /* session key */
7104 proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7105 offset += 4;
7107 switch (wc) {
7108 case 10:
7109 /* password length, ASCII*/
7110 pwlen = tvb_get_letohs(tvb, offset);
7111 proto_tree_add_uint(tree, hf_smb_password_len,
7112 tvb, offset, 2, pwlen);
7113 offset += 2;
7115 /* 4 reserved bytes */
7116 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7117 offset += 4;
7119 break;
7121 case 12:
7122 /* security blob length */
7123 sbloblen = tvb_get_letohs(tvb, offset);
7124 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7125 offset += 2;
7127 /* 4 reserved bytes */
7128 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7129 offset += 4;
7131 /* capabilities */
7132 dissect_negprot_capabilities(tvb, tree, offset);
7133 offset += 4;
7135 break;
7137 case 13:
7138 /* password length, ANSI*/
7139 apwlen = tvb_get_letohs(tvb, offset);
7140 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
7141 tvb, offset, 2, apwlen);
7142 offset += 2;
7144 /* password length, Unicode*/
7145 upwlen = tvb_get_letohs(tvb, offset);
7146 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
7147 tvb, offset, 2, upwlen);
7148 offset += 2;
7150 /* 4 reserved bytes */
7151 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7152 offset += 4;
7154 /* capabilities */
7155 dissect_negprot_capabilities(tvb, tree, offset);
7156 offset += 4;
7158 break;
7161 BYTE_COUNT;
7163 if (wc == 12) {
7164 proto_item *blob_item;
7166 /* security blob */
7167 /* If it runs past the end of the captured data, don't
7168 * try to put all of it into the protocol tree as the
7169 * raw security blob; we might get an exception on
7170 * short frames and then we will not see anything at all
7171 * of the security blob.
7173 sbloblen_short = sbloblen;
7174 if (sbloblen_short > tvb_length_remaining(tvb,offset)) {
7175 sbloblen_short = tvb_length_remaining(tvb,offset);
7177 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7178 tvb, offset, sbloblen_short,
7179 ENC_NA);
7181 /* As an optimization, because Windows is perverse,
7182 we check to see if NTLMSSP is the first part of the
7183 blob, and if so, call the NTLMSSP dissector,
7184 otherwise we call the GSS-API dissector. This is because
7185 Windows can request RAW NTLMSSP, but will happily handle
7186 a client that wraps NTLMSSP in SPNEGO
7189 if (sbloblen) {
7190 tvbuff_t *blob_tvb;
7191 proto_tree *blob_tree;
7193 blob_tree = proto_item_add_subtree(blob_item,
7194 ett_smb_secblob);
7195 CHECK_BYTE_COUNT(sbloblen);
7198 * Set the reported length of this to the reported
7199 * length of the blob, rather than the amount of
7200 * data available from the blob, so that we'll
7201 * throw the right exception if it's too short.
7203 blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
7204 sbloblen);
7206 if (si && si->ct && si->ct->raw_ntlmssp &&
7207 (tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)) {
7208 call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7209 blob_tree);
7212 else {
7213 call_dissector(gssapi_handle, blob_tvb,
7214 pinfo, blob_tree);
7217 /* If we have found a uid->acct_name mapping, store it */
7218 if (!pinfo->fd->flags.visited && si->sip) {
7219 int idx = 0;
7220 if ((ntlmssph = (ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx + 1 )) != NULL) {
7221 if (ntlmssph && (ntlmssph->type == 3)) {
7222 smb_uid_t *smb_uid;
7224 smb_uid = (smb_uid_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_uid_t));
7225 smb_uid->logged_in=-1;
7226 smb_uid->logged_out=-1;
7227 smb_uid->domain = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
7228 smb_uid->account = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
7230 si->sip->extra_info = smb_uid;
7231 si->sip->extra_info_type = SMB_EI_UID;
7236 COUNT_BYTES(sbloblen);
7239 /* OS
7240 * Eventhough this field should honour the unicode flag
7241 * some ms clients gets this wrong.
7242 * At least XP SP1 sends this in ASCII
7243 * even when the unicode flag is on.
7244 * Test if the first three bytes are "Win"
7245 * and if so just override the flag.
7247 unicodeflag = si->unicode;
7248 if ( tvb_strneql(tvb, offset, "Win", 3) == 0 ) {
7249 unicodeflag = FALSE;
7251 an = get_unicode_or_ascii_string(tvb, &offset,
7252 unicodeflag, &an_len, FALSE, FALSE, &bc);
7253 if (an == NULL)
7254 goto endofcommand;
7255 proto_tree_add_string(tree, hf_smb_os, tvb,
7256 offset, an_len, an);
7257 COUNT_BYTES(an_len);
7259 /* LANMAN */
7260 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7261 * padding/null string/whatever in front of this. W2K doesn't
7262 * appear to. I suspect that's a bug that got fixed; I also
7263 * suspect that, in practice, nobody ever looks at that field
7264 * because the bug didn't appear to get fixed until NT 5.0....
7266 * Eventhough this field should honour the unicode flag
7267 * some ms clients gets this wrong.
7268 * At least XP SP1 sends this in ASCII
7269 * even when the unicode flag is on.
7270 * Test if the first three bytes are "Win"
7271 * and if so just override the flag.
7273 unicodeflag = si->unicode;
7274 if ( tvb_strneql(tvb, offset, "Win", 3) == 0 ) {
7275 unicodeflag = FALSE;
7277 an = get_unicode_or_ascii_string(tvb, &offset,
7278 unicodeflag, &an_len, FALSE, FALSE, &bc);
7279 if (an == NULL)
7280 goto endofcommand;
7281 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7282 offset, an_len, an);
7283 COUNT_BYTES(an_len);
7285 /* Primary domain */
7286 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
7287 * byte in front of this, at least if all the strings are
7288 * ASCII and the account name is empty. Another bug?
7290 dn = get_unicode_or_ascii_string(tvb, &offset,
7291 si->unicode, &dn_len, FALSE, FALSE, &bc);
7292 if (dn == NULL)
7293 goto endofcommand;
7294 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7295 offset, dn_len, dn);
7296 COUNT_BYTES(dn_len);
7297 } else {
7298 switch (wc) {
7300 case 10:
7301 if (pwlen) {
7302 /* password, ASCII */
7303 CHECK_BYTE_COUNT(pwlen);
7304 proto_tree_add_item(tree, hf_smb_password,
7305 tvb, offset, pwlen, ENC_NA);
7306 COUNT_BYTES(pwlen);
7309 break;
7311 case 13:
7312 if (apwlen) {
7313 /* password, ANSI */
7314 CHECK_BYTE_COUNT(apwlen);
7315 proto_tree_add_item(tree, hf_smb_ansi_password,
7316 tvb, offset, apwlen, ENC_NA);
7317 COUNT_BYTES(apwlen);
7320 if (upwlen) {
7321 proto_item *item;
7323 /* password, Unicode */
7324 CHECK_BYTE_COUNT(upwlen);
7325 item = proto_tree_add_item(tree, hf_smb_unicode_password,
7326 tvb, offset, upwlen, ENC_NA);
7328 if (upwlen > 24) {
7329 proto_tree *subtree;
7330 subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
7331 dissect_ntlmv2_response(tvb, pinfo, subtree, offset, upwlen);
7334 COUNT_BYTES(upwlen);
7337 break;
7340 /* Account Name */
7341 an = get_unicode_or_ascii_string(tvb, &offset,
7342 si->unicode, &an_len, FALSE, FALSE, &bc);
7343 if (an == NULL)
7344 goto endofcommand;
7345 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
7346 an);
7347 COUNT_BYTES(an_len);
7349 /* Primary domain */
7350 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
7351 * byte in front of this, at least if all the strings are
7352 * ASCII and the account name is empty. Another bug?
7354 dn = get_unicode_or_ascii_string(tvb, &offset,
7355 si->unicode, &dn_len, FALSE, FALSE, &bc);
7356 if (dn == NULL)
7357 goto endofcommand;
7358 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7359 offset, dn_len, dn);
7360 COUNT_BYTES(dn_len);
7362 col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
7364 if (!dn[0] && !an[0])
7365 col_append_str(pinfo->cinfo, COL_INFO, "anonymous");
7366 else
7367 col_append_fstr(pinfo->cinfo, COL_INFO,
7368 "%s\\%s",
7369 format_text(dn, strlen(dn)),
7370 format_text(an, strlen(an)));
7372 /* OS */
7373 an = get_unicode_or_ascii_string(tvb, &offset,
7374 si->unicode, &an_len, FALSE, FALSE, &bc);
7375 if (an == NULL)
7376 goto endofcommand;
7377 proto_tree_add_string(tree, hf_smb_os, tvb,
7378 offset, an_len, an);
7379 COUNT_BYTES(an_len);
7381 /* LANMAN */
7382 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7383 * padding/null string/whatever in front of this. W2K doesn't
7384 * appear to. I suspect that's a bug that got fixed; I also
7385 * suspect that, in practice, nobody ever looks at that field
7386 * because the bug didn't appear to get fixed until NT 5.0....
7388 an = get_unicode_or_ascii_string(tvb, &offset,
7389 si->unicode, &an_len, FALSE, FALSE, &bc);
7390 if (an == NULL)
7391 goto endofcommand;
7392 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7393 offset, an_len, an);
7394 COUNT_BYTES(an_len);
7397 END_OF_SMB
7399 if (cmd != 0xff) { /* there is an andX command */
7400 if (andxoffset < offset) {
7401 THROW(ReportedBoundsError);
7403 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7406 return offset;
7409 static int
7410 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7412 guint8 wc, cmd = 0xff;
7413 guint16 andxoffset = 0, bc;
7414 guint16 sbloblen = 0;
7415 int an_len;
7416 const char *an;
7418 DISSECTOR_ASSERT(si);
7420 WORD_COUNT;
7422 if (!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
7423 (si->sip->extra_info_type == SMB_EI_UID)) {
7424 smb_uid_t *smb_uid;
7426 smb_uid = (smb_uid_t *)si->sip->extra_info;
7427 smb_uid->logged_in = pinfo->fd->num;
7428 wmem_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7431 /* next smb command */
7432 cmd = tvb_get_guint8(tvb, offset);
7433 if (cmd != 0xff) {
7434 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7435 } else {
7436 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7438 offset += 1;
7440 /* reserved byte */
7441 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7442 offset += 1;
7444 /* andxoffset */
7445 andxoffset = tvb_get_letohs(tvb, offset);
7446 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7447 offset += 2;
7449 /* flags */
7450 offset = dissect_setup_action(tvb, tree, offset);
7452 if (wc == 4) {
7453 /* security blob length */
7454 sbloblen = tvb_get_letohs(tvb, offset);
7455 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7456 offset += 2;
7459 BYTE_COUNT;
7461 if (wc == 4) {
7462 proto_item *blob_item;
7464 /* security blob */
7465 /* dont try to eat too much of we might get an exception on
7466 * short frames and then we will not see anything at all
7467 * of the security blob.
7469 if (sbloblen > tvb_length_remaining(tvb,offset)) {
7470 sbloblen = tvb_length_remaining(tvb,offset);
7472 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7473 tvb, offset, sbloblen, ENC_NA);
7475 if (sbloblen) {
7476 tvbuff_t *blob_tvb;
7477 proto_tree *blob_tree;
7479 blob_tree = proto_item_add_subtree(blob_item,
7480 ett_smb_secblob);
7481 CHECK_BYTE_COUNT(sbloblen);
7483 blob_tvb = tvb_new_subset(tvb, offset, sbloblen,
7484 sbloblen);
7486 if (si && si->ct && si->ct->raw_ntlmssp &&
7487 (tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)) {
7488 call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7489 blob_tree);
7492 else {
7493 call_dissector(gssapi_handle, blob_tvb, pinfo,
7494 blob_tree);
7498 COUNT_BYTES(sbloblen);
7502 /* OS */
7503 an = get_unicode_or_ascii_string(tvb, &offset,
7504 si->unicode, &an_len, FALSE, FALSE, &bc);
7505 if (an == NULL)
7506 goto endofcommand;
7507 proto_tree_add_string(tree, hf_smb_os, tvb,
7508 offset, an_len, an);
7509 COUNT_BYTES(an_len);
7511 /* LANMAN */
7512 an = get_unicode_or_ascii_string(tvb, &offset,
7513 si->unicode, &an_len, FALSE, FALSE, &bc);
7514 if (an == NULL)
7515 goto endofcommand;
7516 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7517 offset, an_len, an);
7518 COUNT_BYTES(an_len);
7520 if ((wc == 3) || (wc == 4)) {
7521 /* Primary domain */
7522 an = get_unicode_or_ascii_string(tvb, &offset,
7523 si->unicode, &an_len, FALSE, FALSE, &bc);
7524 if (an == NULL)
7525 goto endofcommand;
7526 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7527 offset, an_len, an);
7528 COUNT_BYTES(an_len);
7531 END_OF_SMB
7533 if (cmd != 0xff) { /* there is an andX command */
7534 if (andxoffset < offset) {
7535 THROW(ReportedBoundsError);
7537 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7540 return offset;
7544 static int
7545 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si _U_)
7547 guint8 wc, cmd = 0xff;
7548 guint16 andxoffset = 0;
7549 guint16 bc;
7551 WORD_COUNT;
7553 /* next smb command */
7554 cmd = tvb_get_guint8(tvb, offset);
7555 if (cmd != 0xff) {
7556 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7557 } else {
7558 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7560 offset += 1;
7562 /* reserved byte */
7563 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7564 offset += 1;
7566 /* andxoffset */
7567 andxoffset = tvb_get_letohs(tvb, offset);
7568 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7569 offset += 2;
7571 BYTE_COUNT;
7573 END_OF_SMB
7575 if (cmd != 0xff) { /* there is an andX command */
7576 if (andxoffset < offset) {
7577 THROW(ReportedBoundsError);
7579 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7582 return offset;
7586 * From [MS-SMB] - v20100711 Server Message Block (SMB) Protocol Specification
7587 * http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-SMB%5D.pdf
7588 * 2.2.4.7 SMB_COM_TREE_CONNECT_ANDX (0x75)
7591 static const true_false_string tfs_connect_support_search = {
7592 "Exclusive search bits supported",
7593 "Exclusive search bits not supported"
7595 static const true_false_string tfs_connect_support_in_dfs = {
7596 "Share is in Dfs",
7597 "Share isn't in Dfs"
7599 static const value_string connect_support_csc_mask_vals[] = {
7600 { 0, "Automatic file-to-file reintegration NOT permitted"},
7601 { 1, "Automatic file-to-file reintegration permitted"},
7602 { 2, "Offline caching allow for the share"},
7603 { 3, "Offline caching NOT allow for the share"},
7604 {0, NULL}
7606 static const true_false_string tfs_connect_support_uniquefilename = {
7607 "Client allow to cache share namespaces",
7608 "Client NOT allow to cache share namespaces"
7610 static const true_false_string tfs_connect_support_extended_signature = {
7611 "Extended signature",
7612 "NOT extended signature"
7615 static int
7616 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7618 guint16 mask;
7619 proto_item *item;
7620 proto_tree *tree;
7622 mask = tvb_get_letohs(tvb, offset);
7624 if (parent_tree) {
7625 item = proto_tree_add_item(parent_tree, hf_smb_connect_support, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7626 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
7628 proto_tree_add_boolean(tree, hf_smb_connect_support_search,
7629 tvb, offset, 2, mask);
7630 proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
7631 tvb, offset, 2, mask);
7632 proto_tree_add_uint(tree, hf_smb_connect_support_csc_mask_vals,
7633 tvb, offset, 2, mask);
7634 proto_tree_add_boolean(tree, hf_smb_connect_support_uniquefilename,
7635 tvb, offset, 2, mask);
7636 proto_tree_add_boolean(tree, hf_smb_connect_support_extended_signature,
7637 tvb, offset, 2, mask);
7640 offset += 2;
7642 return offset;
7645 static const true_false_string tfs_disconnect_tid = {
7646 "DISCONNECT TID",
7647 "Do NOT disconnect TID"
7650 static const true_false_string tfs_extended_signature = {
7651 "Extended Signature",
7652 "NOT Extended Signature"
7655 static const true_false_string tfs_extended_response = {
7656 "Extended Response",
7657 "NOT Extended Response"
7660 static int
7661 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7663 guint16 mask;
7664 proto_item *item;
7665 proto_tree *tree;
7667 mask = tvb_get_letohs(tvb, offset);
7669 if (parent_tree) {
7670 item = proto_tree_add_item(parent_tree, hf_smb_connect_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7671 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
7673 proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
7674 tvb, offset, 2, mask);
7675 proto_tree_add_boolean(tree, hf_smb_connect_flags_ext_sig,
7676 tvb, offset, 2, mask);
7677 proto_tree_add_boolean(tree, hf_smb_connect_flags_ext_resp,
7678 tvb, offset, 2, mask);
7681 offset += 2;
7683 return offset;
7686 static int
7687 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7689 guint8 wc, cmd = 0xff;
7690 guint16 bc;
7691 guint16 andxoffset = 0, pwlen = 0;
7692 int an_len;
7693 const char *an;
7695 DISSECTOR_ASSERT(si);
7697 WORD_COUNT;
7699 /* next smb command */
7700 cmd = tvb_get_guint8(tvb, offset);
7701 if (cmd != 0xff) {
7702 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7703 } else {
7704 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7706 offset += 1;
7708 /* reserved byte */
7709 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7710 offset += 1;
7712 /* andxoffset */
7713 andxoffset = tvb_get_letohs(tvb, offset);
7714 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7715 offset += 2;
7717 /* flags */
7718 offset = dissect_connect_flags(tvb, tree, offset);
7720 /* password length*/
7721 pwlen = tvb_get_letohs(tvb, offset);
7722 proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7723 offset += 2;
7725 BYTE_COUNT;
7727 /* password */
7728 CHECK_BYTE_COUNT(pwlen);
7729 proto_tree_add_item(tree, hf_smb_password,
7730 tvb, offset, pwlen, ENC_NA);
7731 COUNT_BYTES(pwlen);
7733 /* Path */
7734 an = get_unicode_or_ascii_string(tvb, &offset,
7735 si->unicode, &an_len, FALSE, FALSE, &bc);
7736 if (an == NULL)
7737 goto endofcommand;
7738 proto_tree_add_string(tree, hf_smb_path, tvb,
7739 offset, an_len, an);
7740 COUNT_BYTES(an_len);
7742 /* store it for the tid->name/openframe/closeframe matching in
7743 * dissect_smb_tid() called from the response.
7745 if ((!pinfo->fd->flags.visited) && si->sip && an) {
7746 si->sip->extra_info_type = SMB_EI_TIDNAME;
7747 si->sip->extra_info = wmem_strdup(wmem_file_scope(), an);
7750 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7751 format_text(an, strlen(an)));
7754 * NOTE: the Service string is always ASCII, even if the
7755 * "strings are Unicode" bit is set in the flags2 field
7756 * of the SMB.
7759 /* Service */
7760 /* XXX - what if this runs past bc? */
7761 an_len = tvb_strsize(tvb, offset);
7762 CHECK_BYTE_COUNT(an_len);
7763 an = tvb_get_string(wmem_packet_scope(), tvb, offset, an_len);
7764 proto_tree_add_string(tree, hf_smb_service, tvb,
7765 offset, an_len, an);
7766 COUNT_BYTES(an_len);
7768 END_OF_SMB
7770 if (cmd != 0xff) { /* there is an andX command */
7771 if (andxoffset < offset) {
7772 THROW(ReportedBoundsError);
7774 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7777 return offset;
7781 static int
7782 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7784 guint8 wc, wleft, cmd = 0xff;
7785 guint16 andxoffset = 0;
7786 guint16 bc;
7787 int an_len;
7788 int count = 0;
7789 proto_item *it = NULL;
7790 proto_tree *tr = NULL;
7791 const char *an;
7793 DISSECTOR_ASSERT(si);
7795 WORD_COUNT;
7797 wleft = wc; /* this is at least 1 */
7799 /* next smb command */
7800 cmd = tvb_get_guint8(tvb, offset);
7801 if (cmd != 0xff) {
7802 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7803 } else {
7804 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7806 offset += 1;
7808 /* reserved byte */
7809 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7810 offset += 1;
7812 wleft--;
7813 if (wleft == 0)
7814 goto bytecount;
7816 /* andxoffset */
7817 andxoffset = tvb_get_letohs(tvb, offset);
7818 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7819 offset += 2;
7820 wleft--;
7821 if (wleft == 0)
7822 goto bytecount;
7824 /* flags */
7825 offset = dissect_connect_support_bits(tvb, tree, offset);
7826 wleft--;
7828 /* XXX - I've seen captures where this is 7, but I have no
7829 idea how to dissect it. I'm guessing the third word
7830 contains connect support bits, which looks plausible
7831 from the values I've seen. */
7833 /* MaximalShareAccessRights and GuestMaximalShareAccessRights */
7834 while (wleft != 0) {
7836 * Refer to [MS-SMB] - v20100711
7837 * When a server returns extended information, the response
7838 * takes the following format, with WordCount = 7.
7839 * MaximalShareAccessRights, and GuestMaximalShareAccessRights fields
7840 * has added.
7842 if (count == 0) {
7843 it = proto_tree_add_text(tree, tvb, offset, 4,
7844 "Maximal Share Access Rights");
7845 } else {
7846 it = proto_tree_add_text(tree, tvb, offset, 4,
7847 "Guest Maximal Share Access Rights");
7849 tr = proto_item_add_subtree(it, ett_smb_nt_access_mask);
7851 offset = dissect_smb_access_mask(tvb, tr, offset);
7852 wleft -= 2;
7853 count++;
7856 BYTE_COUNT;
7859 * NOTE: even though the SNIA CIFS spec doesn't say there's
7860 * a "Service" string if there's a word count of 2, the
7861 * document at
7863 * ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7865 * (it's in an ugly format - text intended to be sent to a
7866 * printer, with backspaces and overstrikes used for boldfacing
7867 * and underlining; UNIX "col -b" can be used to strip the
7868 * overstrikes out) says there's a "Service" string there, and
7869 * some network traffic has it.
7873 * NOTE: the Service string is always ASCII, even if the
7874 * "strings are Unicode" bit is set in the flags2 field
7875 * of the SMB.
7878 /* Service */
7879 /* XXX - what if this runs past bc? */
7880 an_len = tvb_strsize(tvb, offset);
7881 CHECK_BYTE_COUNT(an_len);
7882 an = tvb_get_string(wmem_packet_scope(), tvb, offset, an_len);
7883 proto_tree_add_string(tree, hf_smb_service, tvb,
7884 offset, an_len, an);
7885 COUNT_BYTES(an_len);
7887 /* Now when we know the service type, store it so that we know it for later commands down
7888 this tree */
7889 if (!pinfo->fd->flags.visited) {
7890 /* Remove any previous entry for this TID */
7891 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
7892 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7894 if (strcmp(an,"IPC") == 0) {
7895 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7896 } else {
7897 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7902 if (wc == 3) {
7903 if (bc != 0) {
7905 * Sometimes this isn't present.
7908 /* Native FS */
7909 an = get_unicode_or_ascii_string(tvb, &offset,
7910 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7911 &bc);
7912 if (an == NULL)
7913 goto endofcommand;
7914 proto_tree_add_string(tree, hf_smb_fs, tvb,
7915 offset, an_len, an);
7916 COUNT_BYTES(an_len);
7920 END_OF_SMB
7922 if (cmd != 0xff) { /* there is an andX command */
7923 if (andxoffset < offset) {
7924 THROW(ReportedBoundsError);
7926 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7929 return offset;
7934 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7935 NT Transaction command begins here
7936 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7937 #define NT_TRANS_CREATE 1
7938 #define NT_TRANS_IOCTL 2
7939 #define NT_TRANS_SSD 3
7940 #define NT_TRANS_NOTIFY 4
7941 #define NT_TRANS_RENAME 5
7942 #define NT_TRANS_QSD 6
7943 #define NT_TRANS_GET_USER_QUOTA 7
7944 #define NT_TRANS_SET_USER_QUOTA 8
7945 static const value_string nt_cmd_vals[] = {
7946 {NT_TRANS_CREATE, "NT CREATE"},
7947 {NT_TRANS_IOCTL, "NT IOCTL"},
7948 {NT_TRANS_SSD, "NT SET SECURITY DESC"},
7949 {NT_TRANS_NOTIFY, "NT NOTIFY"},
7950 {NT_TRANS_RENAME, "NT RENAME"},
7951 {NT_TRANS_QSD, "NT QUERY SECURITY DESC"},
7952 {NT_TRANS_GET_USER_QUOTA, "NT GET USER QUOTA"},
7953 {NT_TRANS_SET_USER_QUOTA, "NT SET USER QUOTA"},
7954 {0, NULL}
7957 value_string_ext nt_cmd_vals_ext = VALUE_STRING_EXT_INIT(nt_cmd_vals);
7959 static const value_string nt_ioctl_isfsctl_vals[] = {
7960 {0, "Device IOCTL"},
7961 {1, "FS control : FSCTL"},
7962 {0, NULL}
7965 #define NT_IOCTL_FLAGS_ROOT_HANDLE 0x01
7966 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7967 "Apply the command to share root handle (MUST BE Dfs)",
7968 "Apply to this share",
7971 static const value_string nt_notify_action_vals[] = {
7972 {1, "ADDED (object was added"},
7973 {2, "REMOVED (object was removed)"},
7974 {3, "MODIFIED (object was modified)"},
7975 {4, "RENAMED_OLD_NAME (this is the old name of object)"},
7976 {5, "RENAMED_NEW_NAME (this is the new name of object)"},
7977 {6, "ADDED_STREAM (a stream was added)"},
7978 {7, "REMOVED_STREAM (a stream was removed)"},
7979 {8, "MODIFIED_STREAM (a stream was modified)"},
7980 {0, NULL}
7983 static const value_string watch_tree_vals[] = {
7984 {0, "Current directory only"},
7985 {1, "Subdirectories also"},
7986 {0, NULL}
7989 #define NT_NOTIFY_STREAM_WRITE 0x00000800
7990 #define NT_NOTIFY_STREAM_SIZE 0x00000400
7991 #define NT_NOTIFY_STREAM_NAME 0x00000200
7992 #define NT_NOTIFY_SECURITY 0x00000100
7993 #define NT_NOTIFY_EA 0x00000080
7994 #define NT_NOTIFY_CREATION 0x00000040
7995 #define NT_NOTIFY_LAST_ACCESS 0x00000020
7996 #define NT_NOTIFY_LAST_WRITE 0x00000010
7997 #define NT_NOTIFY_SIZE 0x00000008
7998 #define NT_NOTIFY_ATTRIBUTES 0x00000004
7999 #define NT_NOTIFY_DIR_NAME 0x00000002
8000 #define NT_NOTIFY_FILE_NAME 0x00000001
8001 static const true_false_string tfs_nt_notify_stream_write = {
8002 "Notify on changes to STREAM WRITE",
8003 "Do NOT notify on changes to stream write",
8005 static const true_false_string tfs_nt_notify_stream_size = {
8006 "Notify on changes to STREAM SIZE",
8007 "Do NOT notify on changes to stream size",
8009 static const true_false_string tfs_nt_notify_stream_name = {
8010 "Notify on changes to STREAM NAME",
8011 "Do NOT notify on changes to stream name",
8013 static const true_false_string tfs_nt_notify_security = {
8014 "Notify on changes to SECURITY",
8015 "Do NOT notify on changes to security",
8017 static const true_false_string tfs_nt_notify_ea = {
8018 "Notify on changes to EA",
8019 "Do NOT notify on changes to EA",
8021 static const true_false_string tfs_nt_notify_creation = {
8022 "Notify on changes to CREATION TIME",
8023 "Do NOT notify on changes to creation time",
8025 static const true_false_string tfs_nt_notify_last_access = {
8026 "Notify on changes to LAST ACCESS TIME",
8027 "Do NOT notify on changes to last access time",
8029 static const true_false_string tfs_nt_notify_last_write = {
8030 "Notify on changes to LAST WRITE TIME",
8031 "Do NOT notify on changes to last write time",
8033 static const true_false_string tfs_nt_notify_size = {
8034 "Notify on changes to SIZE",
8035 "Do NOT notify on changes to size",
8037 static const true_false_string tfs_nt_notify_attributes = {
8038 "Notify on changes to ATTRIBUTES",
8039 "Do NOT notify on changes to attributes",
8041 static const true_false_string tfs_nt_notify_dir_name = {
8042 "Notify on changes to DIR NAME",
8043 "Do NOT notify on changes to dir name",
8045 static const true_false_string tfs_nt_notify_file_name = {
8046 "Notify on changes to FILE NAME",
8047 "Do NOT notify on changes to file name",
8050 const value_string create_disposition_vals[] = {
8051 {0, "Supersede (supersede existing file (if it exists))"},
8052 {1, "Open (if file exists open it, else fail)"},
8053 {2, "Create (if file exists fail, else create it)"},
8054 {3, "Open If (if file exists open it, else create it)"},
8055 {4, "Overwrite (if file exists overwrite, else fail)"},
8056 {5, "Overwrite If (if file exists overwrite, else create it)"},
8057 {0, NULL}
8060 const value_string impersonation_level_vals[] = {
8061 {0, "Anonymous"},
8062 {1, "Identification"},
8063 {2, "Impersonation"},
8064 {3, "Delegation"},
8065 {0, NULL}
8068 static const true_false_string tfs_nt_security_flags_context_tracking = {
8069 "Security tracking mode is DYNAMIC",
8070 "Security tracking mode is STATIC",
8073 static const true_false_string tfs_nt_security_flags_effective_only = {
8074 "ONLY ENABLED aspects of the client's security context are available",
8075 "ALL aspects of the client's security context are available",
8078 static const true_false_string tfs_nt_create_bits_oplock = {
8079 "Requesting OPLOCK",
8080 "Does NOT request oplock"
8083 static const true_false_string tfs_nt_create_bits_boplock = {
8084 "Requesting BATCH OPLOCK",
8085 "Does NOT request batch oplock"
8089 * XXX - must be a directory, and can be a file, or can be a directory,
8090 * and must be a file?
8092 static const true_false_string tfs_nt_create_bits_dir = {
8093 "Target of open MUST be a DIRECTORY",
8094 "Target of open can be a file"
8097 static const true_false_string tfs_nt_create_bits_ext_resp = {
8098 "Extended responses required",
8099 "Extended responses NOT required"
8102 static const true_false_string tfs_nt_access_mask_generic_read = {
8103 "GENERIC READ is set",
8104 "Generic read is NOT set"
8106 static const true_false_string tfs_nt_access_mask_generic_write = {
8107 "GENERIC WRITE is set",
8108 "Generic write is NOT set"
8110 static const true_false_string tfs_nt_access_mask_generic_execute = {
8111 "GENERIC EXECUTE is set",
8112 "Generic execute is NOT set"
8114 static const true_false_string tfs_nt_access_mask_generic_all = {
8115 "GENERIC ALL is set",
8116 "Generic all is NOT set"
8118 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
8119 "MAXIMUM ALLOWED is set",
8120 "Maximum allowed is NOT set"
8122 static const true_false_string tfs_nt_access_mask_system_security = {
8123 "SYSTEM SECURITY is set",
8124 "System security is NOT set"
8126 static const true_false_string tfs_nt_access_mask_synchronize = {
8127 "Can wait on handle to SYNCHRONIZE on completion of I/O",
8128 "Can NOT wait on handle to synchronize on completion of I/O"
8130 static const true_false_string tfs_nt_access_mask_write_owner = {
8131 "Can WRITE OWNER (take ownership)",
8132 "Can NOT write owner (take ownership)"
8134 static const true_false_string tfs_nt_access_mask_write_dac = {
8135 "OWNER may WRITE the DAC",
8136 "Owner may NOT write to the DAC"
8138 static const true_false_string tfs_nt_access_mask_read_control = {
8139 "READ ACCESS to owner, group and ACL of the SID",
8140 "Read access is NOT granted to owner, group and ACL of the SID"
8142 static const true_false_string tfs_nt_access_mask_delete = {
8143 "DELETE access",
8144 "NO delete access"
8146 static const true_false_string tfs_nt_access_mask_write_attributes = {
8147 "WRITE ATTRIBUTES access",
8148 "NO write attributes access"
8150 static const true_false_string tfs_nt_access_mask_read_attributes = {
8151 "READ ATTRIBUTES access",
8152 "NO read attributes access"
8154 static const true_false_string tfs_nt_access_mask_delete_child = {
8155 "DELETE CHILD access",
8156 "NO delete child access"
8158 static const true_false_string tfs_nt_access_mask_execute = {
8159 "EXECUTE access",
8160 "NO execute access"
8162 static const true_false_string tfs_nt_access_mask_write_ea = {
8163 "WRITE EXTENDED ATTRIBUTES access",
8164 "NO write extended attributes access"
8166 static const true_false_string tfs_nt_access_mask_read_ea = {
8167 "READ EXTENDED ATTRIBUTES access",
8168 "NO read extended attributes access"
8170 static const true_false_string tfs_nt_access_mask_append = {
8171 "APPEND access",
8172 "NO append access"
8174 static const true_false_string tfs_nt_access_mask_write = {
8175 "WRITE access",
8176 "NO write access"
8178 static const true_false_string tfs_nt_access_mask_read = {
8179 "READ access",
8180 "NO read access"
8183 static const true_false_string tfs_nt_share_access_delete = {
8184 "Object can be shared for DELETE",
8185 "Object can NOT be shared for delete"
8187 static const true_false_string tfs_nt_share_access_write = {
8188 "Object can be shared for WRITE",
8189 "Object can NOT be shared for write"
8191 static const true_false_string tfs_nt_share_access_read = {
8192 "Object can be shared for READ",
8193 "Object can NOT be shared for read"
8196 static const value_string oplock_level_vals[] = {
8197 {0, "No oplock granted"},
8198 {1, "Exclusive oplock granted"},
8199 {2, "Batch oplock granted"},
8200 {3, "Level II oplock granted"},
8201 {0, NULL}
8204 static const value_string device_type_vals[] = {
8205 {0x00000001, "Beep"},
8206 {0x00000002, "CDROM"},
8207 {0x00000003, "CDROM Filesystem"},
8208 {0x00000004, "Controller"},
8209 {0x00000005, "Datalink"},
8210 {0x00000006, "Dfs"},
8211 {0x00000007, "Disk"},
8212 {0x00000008, "Disk Filesystem"},
8213 {0x00000009, "Filesystem"},
8214 {0x0000000a, "Inport Port"},
8215 {0x0000000b, "Keyboard"},
8216 {0x0000000c, "Mailslot"},
8217 {0x0000000d, "MIDI-In"},
8218 {0x0000000e, "MIDI-Out"},
8219 {0x0000000f, "Mouse"},
8220 {0x00000010, "Multi UNC Provider"},
8221 {0x00000011, "Named Pipe"},
8222 {0x00000012, "Network"},
8223 {0x00000013, "Network Browser"},
8224 {0x00000014, "Network Filesystem"},
8225 {0x00000015, "NULL"},
8226 {0x00000016, "Parallel Port"},
8227 {0x00000017, "Physical card"},
8228 {0x00000018, "Printer"},
8229 {0x00000019, "Scanner"},
8230 {0x0000001a, "Serial Mouse port"},
8231 {0x0000001b, "Serial port"},
8232 {0x0000001c, "Screen"},
8233 {0x0000001d, "Sound"},
8234 {0x0000001e, "Streams"},
8235 {0x0000001f, "Tape"},
8236 {0x00000020, "Tape Filesystem"},
8237 {0x00000021, "Transport"},
8238 {0x00000022, "Unknown"},
8239 {0x00000023, "Video"},
8240 {0x00000024, "Virtual Disk"},
8241 {0x00000025, "WAVE-In"},
8242 {0x00000026, "WAVE-Out"},
8243 {0x00000027, "8042 Port"},
8244 {0x00000028, "Network Redirector"},
8245 {0x00000029, "Battery"},
8246 {0x0000002a, "Bus Extender"},
8247 {0x0000002b, "Modem"},
8248 {0x0000002c, "VDM"},
8249 {0, NULL}
8252 static const value_string is_directory_vals[] = {
8253 {0, "This is NOT a directory"},
8254 {1, "This is a DIRECTORY"},
8255 {0, NULL}
8258 typedef struct _nt_trans_data {
8259 int subcmd;
8260 guint32 sd_len;
8261 guint32 ea_len;
8262 } nt_trans_data;
8266 static int
8267 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8269 guint8 mask;
8270 proto_item *item;
8271 proto_tree *tree;
8273 mask = tvb_get_guint8(tvb, offset);
8275 if (parent_tree) {
8276 item = proto_tree_add_item(parent_tree, hf_smb_nt_security_flags, tvb, offset, 1, ENC_NA);
8277 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
8279 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
8280 tvb, offset, 1, mask);
8281 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
8282 tvb, offset, 1, mask);
8285 offset += 1;
8287 return offset;
8291 * XXX - there are some more flags in the description of "ZwOpenFile()"
8292 * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
8293 * the wire as well? (The spec at
8295 * http://www.samba.org/samba/ftp/specs/smb-nt01.doc
8297 * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
8298 * via the SMB protocol. The NT redirector should convert this option
8299 * to FILE_WRITE_THROUGH."
8301 * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
8302 * values one would infer from their position in the list of flags for
8303 * "ZwOpenFile()". Most of the others probably have those values
8304 * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
8305 * which might go over the wire (for the benefit of backup/restore software).
8307 static const true_false_string tfs_nt_create_options_directory = {
8308 "File being created/opened must be a directory",
8309 "File being created/opened must not be a directory"
8311 static const true_false_string tfs_nt_create_options_write_through = {
8312 "Writes should flush buffered data before completing",
8313 "Writes need not flush buffered data before completing"
8315 static const true_false_string tfs_nt_create_options_sequential_only = {
8316 "The file will only be accessed sequentially",
8317 "The file might not only be accessed sequentially"
8319 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
8320 "NO intermediate buffering is allowed",
8321 "Intermediate buffering is allowed"
8323 static const true_false_string tfs_nt_create_options_sync_io_alert = {
8324 "All operations SYNCHRONOUS, waits subject to termination from alert",
8325 "Operations NOT necessarily synchronous"
8327 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
8328 "All operations SYNCHRONOUS, waits not subject to alert",
8329 "Operations NOT necessarily synchronous"
8331 static const true_false_string tfs_nt_create_options_non_directory = {
8332 "File being created/opened must not be a directory",
8333 "File being created/opened must be a directory"
8335 static const true_false_string tfs_nt_create_options_create_tree_connection = {
8336 "Create Tree Connections is SET",
8337 "Create Tree Connections is NOT set"
8339 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
8340 "Complete if oplocked is SET",
8341 "Complete if oplocked is NOT set"
8343 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
8344 "The client does not understand extended attributes",
8345 "The client understands extended attributes"
8347 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
8348 "The client understands only 8.3 file names",
8349 "The client understands long file names"
8351 static const true_false_string tfs_nt_create_options_random_access = {
8352 "The file will be accessed randomly",
8353 "The file will not be accessed randomly"
8355 static const true_false_string tfs_nt_create_options_delete_on_close = {
8356 "The file should be deleted when it is closed",
8357 "The file should not be deleted when it is closed"
8359 static const true_false_string tfs_nt_create_options_open_by_fileid = {
8360 "OpenByFileID bit is SET",
8361 "OpenByFileID is NOT set"
8363 static const true_false_string tfs_nt_create_options_backup_intent = {
8364 "This is a create with BACKUP INTENT",
8365 "This is a normal create"
8367 static const true_false_string tfs_nt_create_options_no_compression = {
8368 "Open/Create with NO Compression",
8369 "Compression is allowed for Open/Create"
8371 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
8372 "Reserve Opfilter is SET",
8373 "Reserve Opfilter is NOT set"
8375 static const true_false_string tfs_nt_create_options_open_reparse_point = {
8376 "Open a Reparse Point",
8377 "Normal open"
8379 static const true_false_string tfs_nt_create_options_open_no_recall = {
8380 "Open No Recall is SET",
8381 "Open no recall is NOT set"
8383 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
8384 "This is an OPEN FOR FREE SPACE QUERY",
8385 "This is NOT an open for free space query"
8389 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8391 guint32 mask;
8392 proto_item *item;
8393 proto_tree *tree;
8395 mask = tvb_get_letohl(tvb, offset);
8397 if (parent_tree) {
8398 item = proto_tree_add_item(parent_tree, hf_smb_nt_notify_completion_filter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8399 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
8401 proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
8402 tvb, offset, 4, mask);
8403 proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
8404 tvb, offset, 4, mask);
8405 proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
8406 tvb, offset, 4, mask);
8407 proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
8408 tvb, offset, 4, mask);
8409 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
8410 tvb, offset, 4, mask);
8411 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
8412 tvb, offset, 4, mask);
8413 proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
8414 tvb, offset, 4, mask);
8415 proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
8416 tvb, offset, 4, mask);
8417 proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
8418 tvb, offset, 4, mask);
8419 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
8420 tvb, offset, 4, mask);
8421 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
8422 tvb, offset, 4, mask);
8423 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
8424 tvb, offset, 4, mask);
8427 offset += 4;
8428 return offset;
8431 static int
8432 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8434 guint8 mask;
8435 proto_item *item;
8436 proto_tree *tree;
8438 mask = tvb_get_guint8(tvb, offset);
8440 if (parent_tree) {
8441 item = proto_tree_add_item(parent_tree, hf_smb_nt_ioctl_flags_completion_filter, tvb, offset, 1, ENC_NA);
8442 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
8444 proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
8445 tvb, offset, 1, mask);
8448 offset += 1;
8449 return offset;
8453 * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
8454 * Native API Reference".
8456 static const true_false_string tfs_nt_qsd_owner = {
8457 "Requesting OWNER security information",
8458 "NOT requesting owner security information",
8461 static const true_false_string tfs_nt_qsd_group = {
8462 "Requesting GROUP security information",
8463 "NOT requesting group security information",
8466 static const true_false_string tfs_nt_qsd_dacl = {
8467 "Requesting DACL security information",
8468 "NOT requesting DACL security information",
8471 static const true_false_string tfs_nt_qsd_sacl = {
8472 "Requesting SACL security information",
8473 "NOT requesting SACL security information",
8476 #define NT_QSD_OWNER 0x00000001
8477 #define NT_QSD_GROUP 0x00000002
8478 #define NT_QSD_DACL 0x00000004
8479 #define NT_QSD_SACL 0x00000008
8482 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8484 guint32 mask;
8485 proto_item *item;
8486 proto_tree *tree;
8488 mask = tvb_get_letohl(tvb, offset);
8490 if (parent_tree) {
8491 item = proto_tree_add_item(parent_tree, hf_smb_nt_qsd, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8492 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
8494 proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
8495 tvb, offset, 4, mask);
8496 proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
8497 tvb, offset, 4, mask);
8498 proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
8499 tvb, offset, 4, mask);
8500 proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
8501 tvb, offset, 4, mask);
8504 offset += 4;
8506 return offset;
8509 static int
8510 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8512 int old_offset, old_sid_offset;
8513 guint32 qsize;
8515 do {
8516 old_offset = offset;
8518 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8519 qsize = tvb_get_letohl(tvb, offset);
8520 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8521 COUNT_BYTES_TRANS_SUBR(4);
8523 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8524 /* length of SID */
8525 proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8526 COUNT_BYTES_TRANS_SUBR(4);
8528 /* 16 unknown bytes */
8529 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8530 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8531 offset, 8, ENC_NA);
8532 COUNT_BYTES_TRANS_SUBR(8);
8534 /* number of bytes for used quota */
8535 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8536 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8537 COUNT_BYTES_TRANS_SUBR(8);
8539 /* number of bytes for quota warning */
8540 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8541 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8542 COUNT_BYTES_TRANS_SUBR(8);
8544 /* number of bytes for quota limit */
8545 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8546 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8547 COUNT_BYTES_TRANS_SUBR(8);
8549 /* SID of the user */
8550 old_sid_offset = offset;
8551 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8552 *bcp -= (offset-old_sid_offset);
8554 if (qsize) {
8555 offset = old_offset+qsize;
8557 }while(qsize);
8560 return offset;
8564 static int
8565 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd, smb_nt_transact_info_t *nti, smb_info_t *si)
8567 proto_item *item = NULL;
8568 proto_tree *tree = NULL;
8569 int old_offset = offset;
8570 guint16 bcp = bc; /* XXX fixme */
8571 struct access_mask_info *ami = NULL;
8572 tvbuff_t *ioctl_tvb;
8574 DISSECTOR_ASSERT(si);
8576 if (parent_tree) {
8577 guint32 bytes = 0;
8578 bytes = tvb_length_remaining(tvb, offset);
8579 /*tvb_ensure_bytes_exist(tvb, offset, bc);*/
8580 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
8581 "%s Data",
8582 val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
8583 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8586 switch(ntd->subcmd) {
8587 case NT_TRANS_CREATE:
8588 /* security descriptor */
8589 if (ntd->sd_len) {
8590 offset = dissect_nt_sec_desc(
8591 tvb, offset, pinfo, tree, NULL, TRUE,
8592 ntd->sd_len, NULL);
8595 /* extended attributes */
8596 if (ntd->ea_len) {
8597 proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, ENC_NA);
8598 offset += ntd->ea_len;
8601 break;
8602 case NT_TRANS_IOCTL:
8603 /* ioctl data */
8604 ioctl_tvb = tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
8605 if (nti) {
8606 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, TRUE);
8609 offset += bc;
8611 break;
8612 case NT_TRANS_SSD:
8613 if (nti) {
8614 switch(nti->fid_type) {
8615 case SMB_FID_TYPE_FILE:
8616 ami= &smb_file_access_mask_info;
8617 break;
8618 case SMB_FID_TYPE_DIR:
8619 ami= &smb_dir_access_mask_info;
8620 break;
8624 offset = dissect_nt_sec_desc(
8625 tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
8627 if (offset < (old_offset + bc)) {
8628 offset = old_offset + bc;
8631 break;
8632 case NT_TRANS_NOTIFY:
8633 break;
8634 case NT_TRANS_RENAME:
8635 /* XXX not documented */
8636 break;
8637 case NT_TRANS_QSD:
8638 break;
8639 case NT_TRANS_GET_USER_QUOTA:
8640 /* unknown 4 bytes */
8641 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8642 offset, 4, ENC_NA);
8643 offset += 4;
8645 /* length of SID */
8646 proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8647 offset +=4;
8649 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8650 break;
8651 case NT_TRANS_SET_USER_QUOTA:
8652 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8653 break;
8656 /* ooops there were data we didnt know how to process */
8657 if ((offset-old_offset) < bc) {
8658 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8659 bc - (offset-old_offset), ENC_NA);
8660 offset += bc - (offset-old_offset);
8663 return offset;
8666 static int
8667 dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc, smb_nt_transact_info_t *nti, smb_info_t *si)
8669 proto_item *item = NULL;
8670 proto_tree *tree = NULL;
8671 guint32 fn_len, create_flags, access_mask, share_access, create_options;
8672 const char *fn;
8674 DISSECTOR_ASSERT(si);
8676 if (parent_tree) {
8677 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8678 "%s Parameters",
8679 val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
8680 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8683 switch(ntd->subcmd) {
8684 case NT_TRANS_CREATE:
8685 /* Create flags */
8686 create_flags = tvb_get_letohl(tvb, offset);
8687 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
8688 bc -= 4;
8690 /* root directory fid */
8691 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8692 COUNT_BYTES(4);
8694 /* nt access mask */
8695 access_mask = tvb_get_letohl(tvb, offset);
8696 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
8697 bc -= 4;
8699 /* allocation size */
8700 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8701 COUNT_BYTES(8);
8703 /* Extended File Attributes */
8704 offset = dissect_file_ext_attr(tvb, tree, offset);
8705 bc -= 4;
8707 /* share access */
8708 share_access = tvb_get_letohl(tvb, offset);
8709 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
8710 bc -= 4;
8712 /* create disposition */
8713 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8714 COUNT_BYTES(4);
8716 /* create options */
8717 create_options = tvb_get_letohl(tvb, offset);
8718 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
8719 bc -= 4;
8721 /* sd length */
8722 ntd->sd_len = tvb_get_letohl(tvb, offset);
8723 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8724 COUNT_BYTES(4);
8726 /* ea length */
8727 ntd->ea_len = tvb_get_letohl(tvb, offset);
8728 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8729 COUNT_BYTES(4);
8731 /* file name len */
8732 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8733 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8734 COUNT_BYTES(4);
8736 /* impersonation level */
8737 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8738 COUNT_BYTES(4);
8740 /* security flags */
8741 offset = dissect_nt_security_flags(tvb, tree, offset);
8742 bc -= 1;
8744 /* file name */
8745 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8746 if (fn != NULL) {
8747 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8748 fn);
8749 COUNT_BYTES(fn_len);
8752 break;
8753 case NT_TRANS_IOCTL:
8754 break;
8755 case NT_TRANS_SSD: {
8756 guint16 fid;
8757 smb_fid_info_t *fid_info;
8759 /* fid */
8760 fid = tvb_get_letohs(tvb, offset);
8761 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8762 offset += 2;
8763 if (nti) {
8764 if (fid_info) {
8765 nti->fid_type = fid_info->type;
8766 } else {
8767 nti->fid_type = SMB_FID_TYPE_UNKNOWN;
8771 /* 2 reserved bytes */
8772 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
8773 offset += 2;
8775 /* security information */
8776 offset = dissect_security_information_mask(tvb, tree, offset);
8777 break;
8779 case NT_TRANS_NOTIFY:
8780 break;
8781 case NT_TRANS_RENAME:
8782 /* XXX not documented */
8783 break;
8784 case NT_TRANS_QSD: {
8785 guint16 fid;
8786 smb_fid_info_t *fid_info;
8788 /* fid */
8789 fid = tvb_get_letohs(tvb, offset);
8790 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8791 offset += 2;
8792 if (nti) {
8793 if (fid_info) {
8794 nti->fid_type = fid_info->type;
8795 } else {
8796 nti->fid_type = SMB_FID_TYPE_UNKNOWN;
8800 /* 2 reserved bytes */
8801 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
8802 offset += 2;
8804 /* security information */
8805 offset = dissect_security_information_mask(tvb, tree, offset);
8806 break;
8808 case NT_TRANS_GET_USER_QUOTA:
8809 /* not decoded yet */
8810 break;
8811 case NT_TRANS_SET_USER_QUOTA:
8812 /* not decoded yet */
8813 break;
8816 return offset;
8819 static int
8820 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, smb_info_t *si)
8822 proto_item *item = NULL;
8823 proto_tree *tree = NULL;
8824 smb_nt_transact_info_t *nti = NULL;
8825 smb_saved_info_t *sip;
8827 DISSECTOR_ASSERT(si);
8828 sip = si->sip;
8829 if (sip && (sip->extra_info_type == SMB_EI_NTI)) {
8830 nti = (smb_nt_transact_info_t *)sip->extra_info;
8833 if (parent_tree) {
8834 tvb_ensure_bytes_exist(tvb, offset, len);
8835 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8836 "%s Setup",
8837 val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
8838 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8841 switch(ntd->subcmd) {
8842 case NT_TRANS_CREATE:
8843 offset += len;
8844 break;
8845 case NT_TRANS_IOCTL: {
8846 guint16 fid;
8848 /* function code */
8849 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, nti ? &nti->ioctl_function : NULL);
8851 /* fid */
8852 fid = tvb_get_letohs(tvb, offset);
8853 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8854 offset += 2;
8856 /* isfsctl */
8857 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8858 offset += 1;
8860 /* isflags */
8861 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8863 break;
8865 case NT_TRANS_SSD:
8866 offset += len;
8867 break;
8868 case NT_TRANS_NOTIFY: {
8869 guint16 fid;
8871 /* completion filter */
8872 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8874 /* fid */
8875 fid = tvb_get_letohs(tvb, offset);
8876 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8877 offset += 2;
8879 /* watch tree */
8880 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8881 offset += 1;
8883 /* reserved byte */
8884 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
8885 offset += 1;
8887 break;
8889 case NT_TRANS_RENAME:
8890 /* XXX not documented */
8891 offset += len;
8892 break;
8893 case NT_TRANS_QSD:
8894 break;
8895 case NT_TRANS_GET_USER_QUOTA:
8896 /* not decoded yet */
8897 offset += len;
8898 break;
8899 case NT_TRANS_SET_USER_QUOTA:
8900 /* not decoded yet */
8901 offset += len;
8902 break;
8905 return offset;
8909 static int
8910 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
8912 guint8 wc, sc;
8913 guint32 pc = 0, pd = 0, po = 0, dc = 0, od = 0, dd = 0;
8914 guint32 td = 0, tp = 0;
8915 smb_saved_info_t *sip;
8916 int subcmd;
8917 nt_trans_data ntd;
8918 guint16 bc;
8919 guint32 padcnt;
8920 smb_nt_transact_info_t *nti = NULL;
8921 fragment_head *r_fd = NULL;
8922 tvbuff_t *pd_tvb = NULL;
8923 gboolean save_fragmented;
8925 save_fragmented = pinfo->fragmented;
8927 ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8929 DISSECTOR_ASSERT(si);
8930 sip = si->sip;
8932 WORD_COUNT;
8934 if (wc >= 19) {
8935 /* primary request */
8936 /* max setup count */
8937 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8938 offset += 1;
8940 /* 2 reserved bytes */
8941 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
8942 offset += 2;
8943 } else {
8944 /* secondary request */
8945 /* 3 reserved bytes */
8946 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
8947 offset += 3;
8951 /* total param count */
8952 tp = tvb_get_letohl(tvb, offset);
8953 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8954 offset += 4;
8956 /* total data count */
8957 td = tvb_get_letohl(tvb, offset);
8958 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8959 offset += 4;
8961 if (wc >= 19) {
8962 /* primary request */
8963 /* max param count */
8964 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8965 offset += 4;
8967 /* max data count */
8968 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8969 offset += 4;
8972 /* param count */
8973 pc = tvb_get_letohl(tvb, offset);
8974 proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8975 offset += 4;
8977 /* param offset */
8978 po = tvb_get_letohl(tvb, offset);
8979 proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8980 offset += 4;
8982 /* param displacement */
8983 if (wc >= 19) {
8984 /* primary request*/
8985 } else {
8986 /* secondary request */
8988 proto_tree_add_item(tree, hf_smb_param_disp32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8989 offset += 4;
8992 /* data count */
8993 dc = tvb_get_letohl(tvb, offset);
8994 proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8995 offset += 4;
8997 /* data offset */
8998 od = tvb_get_letohl(tvb, offset);
8999 proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9000 offset += 4;
9002 /* data displacement */
9003 if (wc >= 19) {
9004 /* primary request */
9005 } else {
9006 /* secondary request */
9007 dd = tvb_get_letohl(tvb, offset);
9008 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9009 offset += 4;
9012 /* setup count */
9013 if (wc >= 19) {
9014 /* primary request */
9015 sc = tvb_get_guint8(tvb, offset);
9016 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9017 offset += 1;
9018 } else {
9019 /* secondary request */
9020 sc = 0;
9023 /* function */
9024 if (wc >= 19) {
9025 /* primary request */
9026 subcmd = tvb_get_letohs(tvb, offset);
9027 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
9028 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9029 val_to_str_ext_const(subcmd, &nt_cmd_vals_ext, "<unknown>"));
9031 ntd.subcmd = subcmd;
9032 if (!si->unidir && sip) {
9033 if (!pinfo->fd->flags.visited) {
9035 * Allocate a new smb_nt_transact_info_t
9036 * structure.
9038 nti = (smb_nt_transact_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_nt_transact_info_t));
9039 nti->subcmd = subcmd;
9040 nti->fid_type = SMB_FID_TYPE_UNKNOWN;
9041 sip->extra_info = nti;
9042 sip->extra_info_type = SMB_EI_NTI;
9043 } else {
9044 if (sip->extra_info_type == SMB_EI_NTI) {
9045 nti = (smb_nt_transact_info_t *)sip->extra_info;
9049 } else {
9050 /* secondary request */
9051 col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
9053 offset += 2;
9055 /* this is a padding byte */
9056 if (offset%1) {
9057 /* pad byte */
9058 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
9059 offset += 1;
9062 /* if there were any setup bytes, decode them */
9063 if (sc) {
9064 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd, si);
9065 offset += sc*2;
9068 BYTE_COUNT;
9070 /* reassembly of SMB NT Transaction data payload.
9071 In this section we do reassembly of both the data and parameters
9072 blocks of the SMB transaction command.
9074 /* do we need reassembly? */
9075 if ( (td && (td != dc)) || (tp && (tp != pc)) ) {
9076 /* oh yeah, either data or parameter section needs
9077 reassembly...
9079 pinfo->fragmented = TRUE;
9080 if (smb_trans_reassembly) {
9081 /* ...and we were told to do reassembly */
9082 if (pc) {
9083 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9084 po, pc, pd, td+tp, si);
9086 if ((r_fd == NULL) && dc) {
9087 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9088 od, dc, dd+tp, td+tp, si);
9093 /* if we got a reassembled fd structure from the reassembly routine we
9094 must create pd_tvb from it
9096 if (r_fd) {
9097 proto_item *frag_tree_item;
9099 pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
9100 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9102 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9105 if (pd_tvb) {
9106 /* we have reassembled data, grab param and data from there */
9107 dissect_nt_trans_param_request(pd_tvb, pinfo, 0, tree, tp,
9108 &ntd, (guint16) tvb_length(pd_tvb), nti, si);
9109 dissect_nt_trans_data_request(pd_tvb, pinfo, tp, tree, td, &ntd, nti, si);
9110 COUNT_BYTES(bc); /* We are done */
9111 } else {
9112 /* we do not have reassembled data, just use what we have in the
9113 packet as well as we can */
9114 /* parameters */
9115 if (po > (guint32)offset) {
9116 /* We have some initial padding bytes.
9118 padcnt = po-offset;
9119 if (padcnt > bc)
9120 padcnt = bc;
9121 CHECK_BYTE_COUNT(padcnt);
9122 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9123 COUNT_BYTES(padcnt);
9125 if (pc) {
9126 CHECK_BYTE_COUNT(pc);
9127 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti, si);
9128 COUNT_BYTES(pc);
9131 /* data */
9132 if (od > (guint32)offset) {
9133 /* We have some initial padding bytes.
9135 padcnt = od-offset;
9136 if (padcnt > bc)
9137 padcnt = bc;
9138 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9139 COUNT_BYTES(padcnt);
9141 if (dc) {
9142 CHECK_BYTE_COUNT(dc);
9143 dissect_nt_trans_data_request(
9144 tvb, pinfo, offset, tree, dc, &ntd, nti, si);
9145 COUNT_BYTES(dc);
9149 END_OF_SMB
9151 pinfo->fragmented = save_fragmented;
9152 return offset;
9157 static int
9158 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
9159 int offset, proto_tree *parent_tree, int len,
9160 nt_trans_data *ntd _U_,
9161 smb_nt_transact_info_t *nti, smb_info_t *si)
9163 proto_item *item = NULL;
9164 proto_tree *tree = NULL;
9165 guint16 bcp;
9166 struct access_mask_info *ami = NULL;
9167 tvbuff_t *ioctl_tvb;
9169 DISSECTOR_ASSERT(si);
9171 if (parent_tree) {
9172 tvb_ensure_bytes_exist(tvb, offset, len);
9173 if (nti != NULL) {
9174 item = proto_tree_add_text(parent_tree, tvb, offset, len,
9175 "%s Data",
9176 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9177 } else {
9179 * We never saw the request to which this is a
9180 * response.
9182 item = proto_tree_add_text(parent_tree, tvb, offset, len,
9183 "Unknown NT Transaction Data (matching request not seen)");
9185 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
9188 if (nti == NULL) {
9189 offset += len;
9190 return offset;
9192 switch(nti->subcmd) {
9193 case NT_TRANS_CREATE:
9194 break;
9195 case NT_TRANS_IOCTL:
9196 /* ioctl data */
9197 ioctl_tvb = tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
9198 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, FALSE);
9200 offset += len;
9202 break;
9203 case NT_TRANS_SSD:
9204 break;
9205 case NT_TRANS_NOTIFY:
9206 break;
9207 case NT_TRANS_RENAME:
9208 /* XXX not documented */
9209 break;
9210 case NT_TRANS_QSD:
9211 if (nti) {
9212 switch(nti->fid_type) {
9213 case SMB_FID_TYPE_FILE:
9214 ami= &smb_file_access_mask_info;
9215 break;
9216 case SMB_FID_TYPE_DIR:
9217 ami= &smb_dir_access_mask_info;
9218 break;
9221 offset = dissect_nt_sec_desc(
9222 tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
9223 break;
9224 case NT_TRANS_GET_USER_QUOTA:
9225 bcp = len;
9226 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
9227 break;
9228 case NT_TRANS_SET_USER_QUOTA:
9229 /* not decoded yet */
9230 break;
9233 return offset;
9236 static int
9237 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
9238 int offset, proto_tree *parent_tree,
9239 int len, nt_trans_data *ntd _U_, guint16 bc, smb_info_t *si)
9241 proto_item *item = NULL;
9242 proto_tree *tree = NULL;
9243 guint32 fn_len;
9244 const char *fn;
9245 smb_nt_transact_info_t *nti;
9246 guint16 fid;
9247 int old_offset;
9248 guint32 neo;
9249 int padcnt;
9250 smb_fid_info_t *fid_info = NULL;
9251 guint16 ftype;
9252 guint8 isdir;
9254 DISSECTOR_ASSERT(si);
9256 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9257 nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9258 else
9259 nti = NULL;
9261 if (parent_tree) {
9262 tvb_ensure_bytes_exist(tvb, offset, len);
9263 if (nti != NULL) {
9264 item = proto_tree_add_text(parent_tree, tvb, offset, len,
9265 "%s Parameters",
9266 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9267 } else {
9269 * We never saw the request to which this is a
9270 * response.
9272 item = proto_tree_add_text(parent_tree, tvb, offset, len,
9273 "Unknown NT Transaction Parameters (matching request not seen)");
9275 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
9278 if (nti == NULL) {
9279 offset += len;
9280 return offset;
9282 switch(nti->subcmd) {
9283 case NT_TRANS_CREATE:
9284 /* oplock level */
9285 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9286 offset += 1;
9288 /* reserved byte */
9289 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
9290 offset += 1;
9292 /* fid */
9293 fid = tvb_get_letohs(tvb, offset);
9294 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
9295 offset += 2;
9297 /* create action */
9298 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9299 offset += 4;
9301 /* ea error offset */
9302 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9303 offset += 4;
9305 /* create time */
9306 offset = dissect_nt_64bit_time(tvb, tree, offset,
9307 hf_smb_create_time);
9309 /* access time */
9310 offset = dissect_nt_64bit_time(tvb, tree, offset,
9311 hf_smb_access_time);
9313 /* last write time */
9314 offset = dissect_nt_64bit_time(tvb, tree, offset,
9315 hf_smb_last_write_time);
9317 /* last change time */
9318 offset = dissect_nt_64bit_time(tvb, tree, offset,
9319 hf_smb_change_time);
9321 /* Extended File Attributes */
9322 offset = dissect_file_ext_attr(tvb, tree, offset);
9324 /* allocation size */
9325 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9326 offset += 8;
9328 /* end of file */
9329 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9330 offset += 8;
9332 /* File Type */
9333 ftype = tvb_get_letohs(tvb, offset);
9334 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9335 offset += 2;
9337 /* device state */
9338 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9340 /* is directory */
9341 isdir = tvb_get_guint8(tvb, offset);
9342 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9343 offset += 1;
9345 /* Try to remember the type of this fid so that we can dissect
9346 * any future security descriptor (access mask) properly
9348 if (ftype == 0) {
9349 if (isdir == 0) {
9350 if (fid_info) {
9351 fid_info->type = SMB_FID_TYPE_FILE;
9353 } else {
9354 if (fid_info) {
9355 fid_info->type = SMB_FID_TYPE_DIR;
9359 if (ftype == 2) {
9360 if (fid_info) {
9361 fid_info->type = SMB_FID_TYPE_PIPE;
9364 break;
9365 case NT_TRANS_IOCTL:
9366 break;
9367 case NT_TRANS_SSD:
9368 break;
9369 case NT_TRANS_NOTIFY:
9370 while(len) {
9371 old_offset = offset;
9373 /* next entry offset */
9374 neo = tvb_get_letohl(tvb, offset);
9375 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9376 COUNT_BYTES(4);
9377 len -= 4;
9378 /* broken implementations */
9379 if (len < 0) break;
9381 /* action */
9382 proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9383 COUNT_BYTES(4);
9384 len -= 4;
9385 /* broken implementations */
9386 if (len < 0) break;
9388 /* file name len */
9389 fn_len = (guint32)tvb_get_letohl(tvb, offset);
9390 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9391 COUNT_BYTES(4);
9392 len -= 4;
9393 /* broken implementations */
9394 if (len < 0) break;
9396 /* file name */
9397 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
9398 if (fn == NULL)
9399 break;
9400 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9401 fn);
9402 COUNT_BYTES(fn_len);
9403 len -= fn_len;
9404 /* broken implementations */
9405 if (len < 0) break;
9407 if (neo == 0)
9408 break; /* no more structures */
9410 /* skip to next structure */
9411 padcnt = (old_offset + neo) - offset;
9412 if (padcnt < 0) {
9414 * XXX - this is bogus; flag it?
9416 padcnt = 0;
9418 if (padcnt != 0) {
9419 COUNT_BYTES(padcnt);
9420 len -= padcnt;
9421 /* broken implementations */
9422 if (len < 0) break;
9425 break;
9426 case NT_TRANS_RENAME:
9427 /* XXX not documented */
9428 break;
9429 case NT_TRANS_QSD:
9431 * This appears to be the size of the security
9432 * descriptor; the calling sequence of
9433 * "ZwQuerySecurityObject()" suggests that it would
9434 * be. The actual security descriptor wouldn't
9435 * follow if the max data count in the request
9436 * was smaller; this lets the client know how
9437 * big a buffer it needs to provide.
9439 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9440 offset += 4;
9441 break;
9442 case NT_TRANS_GET_USER_QUOTA:
9443 proto_tree_add_item(tree, hf_smb_size_returned_quota_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9444 offset += 4;
9445 break;
9446 case NT_TRANS_SET_USER_QUOTA:
9447 /* not decoded yet */
9448 break;
9451 return offset;
9454 static int
9455 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo _U_,
9456 int offset, proto_tree *parent_tree,
9457 int len, nt_trans_data *ntd _U_, smb_info_t *si)
9459 #if 0
9460 proto_item *item = NULL;
9461 proto_tree *tree = NULL;
9462 #endif
9463 smb_nt_transact_info_t *nti;
9465 DISSECTOR_ASSERT(si);
9467 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9468 nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9469 else
9470 nti = NULL;
9472 if (parent_tree) {
9473 tvb_ensure_bytes_exist(tvb, offset, len);
9474 if (nti != NULL) {
9475 /*item = */proto_tree_add_text(parent_tree, tvb, offset, len,
9476 "%s Setup",
9477 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9478 } else {
9480 * We never saw the request to which this is a
9481 * response.
9483 /*item = */proto_tree_add_text(parent_tree, tvb, offset, len,
9484 "Unknown NT Transaction Setup (matching request not seen)");
9486 /*tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);*/
9489 if (nti == NULL) {
9490 offset += len;
9491 return offset;
9493 switch(nti->subcmd) {
9494 case NT_TRANS_CREATE:
9495 break;
9496 case NT_TRANS_IOCTL:
9497 break;
9498 case NT_TRANS_SSD:
9499 break;
9500 case NT_TRANS_NOTIFY:
9501 break;
9502 case NT_TRANS_RENAME:
9503 /* XXX not documented */
9504 break;
9505 case NT_TRANS_QSD:
9506 break;
9507 case NT_TRANS_GET_USER_QUOTA:
9508 /* not decoded yet */
9509 break;
9510 case NT_TRANS_SET_USER_QUOTA:
9511 /* not decoded yet */
9512 break;
9515 return offset;
9518 static int
9519 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
9521 guint8 wc, sc;
9522 guint32 pc = 0, po = 0, pd = 0, dc = 0, od = 0, dd = 0;
9523 guint32 td = 0, tp = 0;
9524 smb_nt_transact_info_t *nti = NULL;
9525 static nt_trans_data ntd;
9526 guint16 bc;
9527 gint32 padcnt;
9528 fragment_head *r_fd = NULL;
9529 tvbuff_t *pd_tvb = NULL;
9530 gboolean save_fragmented;
9532 DISSECTOR_ASSERT(si);
9534 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9535 nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9536 else
9537 nti = NULL;
9539 /* primary request */
9540 if (nti != NULL) {
9541 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9542 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9543 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "<unknown (%u)>"));
9544 } else {
9545 proto_tree_add_uint_format_value(tree, hf_smb_nt_trans_subcmd, tvb, offset, 0, -1,
9546 "<unknown function - could not find matching request>");
9547 col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
9550 WORD_COUNT;
9552 /* 3 reserved bytes */
9553 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
9554 offset += 3;
9556 /* total param count */
9557 tp = tvb_get_letohl(tvb, offset);
9558 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9559 offset += 4;
9561 /* total data count */
9562 td = tvb_get_letohl(tvb, offset);
9563 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9564 offset += 4;
9566 /* param count */
9567 pc = tvb_get_letohl(tvb, offset);
9568 proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9569 offset += 4;
9571 /* param offset */
9572 po = tvb_get_letohl(tvb, offset);
9573 proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9574 offset += 4;
9576 /* param displacement */
9577 pd = tvb_get_letohl(tvb, offset);
9578 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
9579 offset += 4;
9581 /* data count */
9582 dc = tvb_get_letohl(tvb, offset);
9583 proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9584 offset += 4;
9586 /* data offset */
9587 od = tvb_get_letohl(tvb, offset);
9588 proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9589 offset += 4;
9591 /* data displacement */
9592 dd = tvb_get_letohl(tvb, offset);
9593 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9594 offset += 4;
9596 /* setup count */
9597 sc = tvb_get_guint8(tvb, offset);
9598 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9599 offset += 1;
9601 /* setup data */
9602 if (sc) {
9603 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd, si);
9604 offset += sc*2;
9607 BYTE_COUNT;
9609 /* reassembly of SMB NT Transaction data payload.
9610 In this section we do reassembly of both the data and parameters
9611 blocks of the SMB transaction command.
9613 save_fragmented = pinfo->fragmented;
9614 /* do we need reassembly? */
9615 if ( (td && (td != dc)) || (tp && (tp != pc)) ) {
9616 /* oh yeah, either data or parameter section needs
9617 reassembly...
9619 pinfo->fragmented = TRUE;
9620 if (smb_trans_reassembly) {
9621 /* ...and we were told to do reassembly */
9622 if (pc) {
9623 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9624 po, pc, pd, td+tp, si);
9627 if ((r_fd == NULL) && dc) {
9628 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9629 od, dc, dd+tp, td+tp, si);
9634 /* if we got a reassembled fd structure from the reassembly routine we
9635 must create pd_tvb from it
9637 if (r_fd) {
9638 proto_item *frag_tree_item;
9640 pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
9641 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9643 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9647 if (pd_tvb) {
9648 /* we have reassembled data, grab param and data from there */
9649 dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9650 &ntd, (guint16) tvb_length(pd_tvb), si);
9651 dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti, si);
9652 COUNT_BYTES(bc); /* We are done */
9653 } else {
9654 /* we do not have reassembled data, just use what we have in the
9655 packet as well as we can */
9656 /* parameters */
9657 if (po > (guint32)offset) {
9658 /* We have some initial padding bytes.
9660 padcnt = po-offset;
9661 if (padcnt > bc)
9662 padcnt = bc;
9663 CHECK_BYTE_COUNT(padcnt);
9664 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9665 COUNT_BYTES(padcnt);
9667 if (pc) {
9668 CHECK_BYTE_COUNT(pc);
9669 dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc, si);
9670 COUNT_BYTES(pc);
9673 /* data */
9674 if (od > (guint32)offset) {
9675 /* We have some initial padding bytes.
9677 padcnt = od-offset;
9678 if (padcnt > bc)
9679 padcnt = bc;
9680 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9681 COUNT_BYTES(padcnt);
9683 if (dc) {
9684 CHECK_BYTE_COUNT(dc);
9685 dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti, si);
9686 COUNT_BYTES(dc);
9689 pinfo->fragmented = save_fragmented;
9691 END_OF_SMB
9693 return offset;
9696 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9697 NT Transaction command ends here
9698 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9700 static const value_string print_mode_vals[] = {
9701 {0, "Text Mode"},
9702 {1, "Graphics Mode"},
9703 {0, NULL}
9706 static int
9707 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
9709 int fn_len;
9710 const char *fn;
9711 guint8 wc;
9712 guint16 bc;
9714 DISSECTOR_ASSERT(si);
9716 WORD_COUNT;
9718 /* setup len */
9719 proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9720 offset += 2;
9722 /* print mode */
9723 proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9724 offset += 2;
9726 BYTE_COUNT;
9728 /* buffer format */
9729 CHECK_BYTE_COUNT(1);
9730 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9731 COUNT_BYTES(1);
9733 /* print identifier */
9734 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9735 if (fn == NULL)
9736 goto endofcommand;
9737 proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9738 fn);
9739 COUNT_BYTES(fn_len);
9741 END_OF_SMB
9743 return offset;
9747 static int
9748 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
9750 int cnt;
9751 guint8 wc;
9752 guint16 bc, fid;
9754 WORD_COUNT;
9756 /* fid */
9757 fid = tvb_get_letohs(tvb, offset);
9758 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
9759 offset += 2;
9761 BYTE_COUNT;
9763 /* buffer format */
9764 CHECK_BYTE_COUNT(1);
9765 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9766 COUNT_BYTES(1);
9768 /* data len */
9769 CHECK_BYTE_COUNT(2);
9770 cnt = tvb_get_letohs(tvb, offset);
9771 proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9772 COUNT_BYTES(2);
9774 /* file data */
9775 offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9777 END_OF_SMB
9779 return offset;
9783 static const value_string print_status_vals[] = {
9784 {1, "Held or Stopped"},
9785 {2, "Printing"},
9786 {3, "Awaiting print"},
9787 {4, "In intercept"},
9788 {5, "File had error"},
9789 {6, "Printer error"},
9790 {0, NULL}
9793 static int
9794 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
9796 guint8 wc;
9797 guint16 bc;
9799 WORD_COUNT;
9801 /* max count */
9802 proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9803 offset += 2;
9805 /* start index */
9806 proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9807 offset += 2;
9809 BYTE_COUNT;
9811 END_OF_SMB
9813 return offset;
9816 static int
9817 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo _U_,
9818 proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
9820 proto_item *item = NULL;
9821 proto_tree *tree = NULL;
9822 int fn_len;
9823 const char *fn;
9825 DISSECTOR_ASSERT(si);
9827 if (parent_tree) {
9828 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9829 "Queue entry");
9830 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9833 /* queued time */
9834 CHECK_BYTE_COUNT_SUBR(4);
9835 offset = dissect_smb_datetime(tvb, tree, offset,
9836 hf_smb_print_queue_date,
9837 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9838 *bcp -= 4;
9840 /* status */
9841 CHECK_BYTE_COUNT_SUBR(1);
9842 proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9843 COUNT_BYTES_SUBR(1);
9845 /* spool file number */
9846 CHECK_BYTE_COUNT_SUBR(2);
9847 proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9848 COUNT_BYTES_SUBR(2);
9850 /* spool file size */
9851 CHECK_BYTE_COUNT_SUBR(4);
9852 proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9853 COUNT_BYTES_SUBR(4);
9855 /* reserved byte */
9856 CHECK_BYTE_COUNT_SUBR(1);
9857 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
9858 COUNT_BYTES_SUBR(1);
9860 /* file name */
9861 fn_len = 16;
9862 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9863 CHECK_STRING_SUBR(fn);
9864 proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9865 fn);
9866 COUNT_BYTES_SUBR(fn_len);
9868 *trunc = FALSE;
9869 return offset;
9872 static int
9873 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
9875 guint16 cnt = 0, len;
9876 guint8 wc;
9877 guint16 bc;
9878 gboolean trunc;
9880 WORD_COUNT;
9882 /* count */
9883 cnt = tvb_get_letohs(tvb, offset);
9884 proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9885 offset += 2;
9887 /* restart index */
9888 proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9889 offset += 2;
9891 BYTE_COUNT;
9893 /* buffer format */
9894 CHECK_BYTE_COUNT(1);
9895 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9896 COUNT_BYTES(1);
9898 /* data len */
9899 CHECK_BYTE_COUNT(2);
9900 len = tvb_get_letohs(tvb, offset);
9901 proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9902 COUNT_BYTES(2);
9904 /* queue elements */
9905 while(cnt--) {
9906 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9907 &bc, &trunc, si);
9908 if (trunc)
9909 goto endofcommand;
9912 END_OF_SMB
9914 return offset;
9918 static int
9919 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
9921 int name_len;
9922 guint16 bc;
9923 guint8 wc;
9924 guint16 message_len;
9926 WORD_COUNT;
9928 BYTE_COUNT;
9930 /* buffer format */
9931 CHECK_BYTE_COUNT(1);
9932 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9933 COUNT_BYTES(1);
9935 /* originator name */
9936 /* XXX - what if this runs past bc? */
9937 name_len = tvb_strsize(tvb, offset);
9938 CHECK_BYTE_COUNT(name_len);
9939 proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9940 name_len, ENC_ASCII|ENC_NA);
9941 COUNT_BYTES(name_len);
9943 /* buffer format */
9944 CHECK_BYTE_COUNT(1);
9945 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9946 COUNT_BYTES(1);
9948 /* destination name */
9949 /* XXX - what if this runs past bc? */
9950 name_len = tvb_strsize(tvb, offset);
9951 CHECK_BYTE_COUNT(name_len);
9952 proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9953 name_len, ENC_ASCII|ENC_NA);
9954 COUNT_BYTES(name_len);
9956 /* buffer format */
9957 CHECK_BYTE_COUNT(1);
9958 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9959 COUNT_BYTES(1);
9961 /* message len */
9962 CHECK_BYTE_COUNT(2);
9963 message_len = tvb_get_letohs(tvb, offset);
9964 proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9965 message_len);
9966 COUNT_BYTES(2);
9968 /* message */
9969 CHECK_BYTE_COUNT(message_len);
9970 proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9971 ENC_ASCII|ENC_NA);
9972 COUNT_BYTES(message_len);
9974 END_OF_SMB
9976 return offset;
9979 static int
9980 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
9982 int name_len;
9983 guint16 bc;
9984 guint8 wc;
9986 WORD_COUNT;
9988 BYTE_COUNT;
9990 /* buffer format */
9991 CHECK_BYTE_COUNT(1);
9992 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9993 COUNT_BYTES(1);
9995 /* originator name */
9996 /* XXX - what if this runs past bc? */
9997 name_len = tvb_strsize(tvb, offset);
9998 CHECK_BYTE_COUNT(name_len);
9999 proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
10000 name_len, ENC_ASCII|ENC_NA);
10001 COUNT_BYTES(name_len);
10003 /* buffer format */
10004 CHECK_BYTE_COUNT(1);
10005 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10006 COUNT_BYTES(1);
10008 /* destination name */
10009 /* XXX - what if this runs past bc? */
10010 name_len = tvb_strsize(tvb, offset);
10011 CHECK_BYTE_COUNT(name_len);
10012 proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
10013 name_len, ENC_ASCII|ENC_NA);
10014 COUNT_BYTES(name_len);
10016 END_OF_SMB
10018 return offset;
10021 static int
10022 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
10024 guint16 bc;
10025 guint8 wc;
10027 WORD_COUNT;
10029 /* message group ID */
10030 proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10031 offset += 2;
10033 BYTE_COUNT;
10035 END_OF_SMB
10037 return offset;
10040 static int
10041 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
10043 guint16 bc;
10044 guint8 wc;
10045 guint16 message_len;
10047 WORD_COUNT;
10049 BYTE_COUNT;
10051 /* buffer format */
10052 CHECK_BYTE_COUNT(1);
10053 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10054 COUNT_BYTES(1);
10056 /* message len */
10057 CHECK_BYTE_COUNT(2);
10058 message_len = tvb_get_letohs(tvb, offset);
10059 proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
10060 message_len);
10061 COUNT_BYTES(2);
10063 /* message */
10064 CHECK_BYTE_COUNT(message_len);
10065 proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
10066 ENC_ASCII|ENC_NA);
10067 COUNT_BYTES(message_len);
10069 END_OF_SMB
10071 return offset;
10074 static int
10075 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
10077 int name_len;
10078 guint16 bc;
10079 guint8 wc;
10081 WORD_COUNT;
10083 BYTE_COUNT;
10085 /* buffer format */
10086 CHECK_BYTE_COUNT(1);
10087 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10088 COUNT_BYTES(1);
10090 /* forwarded name */
10091 /* XXX - what if this runs past bc? */
10092 name_len = tvb_strsize(tvb, offset);
10093 CHECK_BYTE_COUNT(name_len);
10094 proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
10095 name_len, ENC_ASCII|ENC_NA);
10096 COUNT_BYTES(name_len);
10098 END_OF_SMB
10100 return offset;
10103 static int
10104 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
10106 int name_len;
10107 guint16 bc;
10108 guint8 wc;
10110 WORD_COUNT;
10112 BYTE_COUNT;
10114 /* buffer format */
10115 CHECK_BYTE_COUNT(1);
10116 proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10117 COUNT_BYTES(1);
10119 /* machine name */
10120 /* XXX - what if this runs past bc? */
10121 name_len = tvb_strsize(tvb, offset);
10122 CHECK_BYTE_COUNT(name_len);
10123 proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
10124 name_len, ENC_ASCII|ENC_NA);
10125 COUNT_BYTES(name_len);
10127 END_OF_SMB
10129 return offset;
10133 static int
10134 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si _U_)
10136 guint8 wc, cmd = 0xff;
10137 guint16 andxoffset = 0;
10138 guint16 bc;
10139 int fn_len;
10140 const char *fn;
10141 guint32 create_flags = 0, access_mask = 0, file_attributes = 0;
10142 guint32 share_access = 0, create_options = 0, create_disposition = 0;
10144 DISSECTOR_ASSERT(si);
10146 WORD_COUNT;
10148 /* next smb command */
10149 cmd = tvb_get_guint8(tvb, offset);
10150 if (cmd != 0xff) {
10151 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
10152 } else {
10153 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
10155 offset += 1;
10157 /* reserved byte */
10158 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10159 offset += 1;
10161 /* andxoffset */
10162 andxoffset = tvb_get_letohs(tvb, offset);
10163 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
10164 offset += 2;
10166 /* reserved byte */
10167 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10168 offset += 1;
10170 /* file name len */
10171 fn_len = tvb_get_letohs(tvb, offset);
10172 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
10173 offset += 2;
10175 /* Create flags */
10176 create_flags = tvb_get_letohl(tvb, offset);
10177 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
10179 /* root directory fid */
10180 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10181 offset += 4;
10183 /* nt access mask */
10184 access_mask = tvb_get_letohl(tvb, offset);
10185 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
10187 /* allocation size */
10188 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10189 offset += 8;
10191 /* Extended File Attributes */
10192 file_attributes = tvb_get_letohl(tvb, offset);
10193 offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
10195 /* share access */
10196 share_access = tvb_get_letohl(tvb, offset);
10197 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
10199 /* create disposition */
10200 create_disposition = tvb_get_letohl(tvb, offset);
10201 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10202 offset += 4;
10204 /* create options */
10205 create_options = tvb_get_letohl(tvb, offset);
10206 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
10208 /* impersonation level */
10209 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10210 offset += 4;
10212 /* security flags */
10213 offset = dissect_nt_security_flags(tvb, tree, offset);
10215 BYTE_COUNT;
10217 /* file name */
10218 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10219 if (fn == NULL)
10220 goto endofcommand;
10221 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10222 fn);
10223 COUNT_BYTES(fn_len);
10225 /* store it for the fid->name/openframe/closeframe matching in
10226 * dissect_smb_fid() called from the response.
10228 if ((!pinfo->fd->flags.visited) && si->sip && fn) {
10229 smb_fid_saved_info_t *fsi;
10231 fsi = (smb_fid_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_fid_saved_info_t));
10232 fsi->filename = wmem_strdup(wmem_file_scope(), fn);
10233 fsi->create_flags = create_flags;
10234 fsi->access_mask = access_mask;
10235 fsi->file_attributes = file_attributes;
10236 fsi->share_access = share_access;
10237 fsi->create_options = create_options;
10238 fsi->create_disposition = create_disposition;
10240 si->sip->extra_info_type = SMB_EI_FILEDATA;
10241 si->sip->extra_info = fsi;
10244 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10245 format_text(fn, strlen(fn)));
10247 END_OF_SMB
10249 if (cmd != 0xff) { /* there is an andX command */
10250 if (andxoffset < offset)
10251 THROW(ReportedBoundsError);
10252 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
10255 return offset;
10259 static int
10260 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
10262 guint8 wc, cmd = 0xff;
10263 guint16 andxoffset = 0;
10264 guint16 bc;
10265 guint16 fid = 0;
10266 guint16 ftype;
10267 guint8 isdir;
10268 smb_fid_info_t *fid_info = NULL;
10270 WORD_COUNT;
10272 /* next smb command */
10273 cmd = tvb_get_guint8(tvb, offset);
10274 if (cmd != 0xff) {
10275 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
10276 } else {
10277 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
10279 offset += 1;
10281 /* reserved byte */
10282 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10283 offset += 1;
10285 /* andxoffset */
10286 andxoffset = tvb_get_letohs(tvb, offset);
10287 proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
10288 offset += 2;
10290 /* oplock level */
10291 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10292 offset += 1;
10294 /* fid */
10295 fid = tvb_get_letohs(tvb, offset);
10296 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
10297 offset += 2;
10299 /* create action */
10300 /*XXX is this really the same as create disposition in the request? it looks so*/
10301 /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
10302 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10303 offset += 4;
10305 /* create time */
10306 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
10308 /* access time */
10309 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
10311 /* last write time */
10312 offset = dissect_nt_64bit_time(tvb, tree, offset,
10313 hf_smb_last_write_time);
10315 /* last change time */
10316 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
10318 /* Extended File Attributes */
10319 offset = dissect_file_ext_attr(tvb, tree, offset);
10321 /* allocation size */
10322 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10323 offset += 8;
10325 /* end of file */
10326 /* We store the end of file */
10327 if (fid_info) {
10328 fid_info->end_of_file = tvb_get_letoh64(tvb, offset);
10330 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10331 offset += 8;
10333 /* File Type */
10334 ftype = tvb_get_letohs(tvb, offset);
10335 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10336 offset += 2;
10338 /* IPC State */
10339 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
10341 /* is directory */
10342 isdir = tvb_get_guint8(tvb, offset);
10343 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10344 offset += 1;
10346 /* Do we know whether or not EXTENDED_RESPONSES are required? */
10347 /* MS-SMB 2.2.4.9.2 says that there is a Volume GUID, File ID,
10348 Maximal Access Rights and Guest Maximal Access Rights here
10349 if ExtendedResponses requested. */
10350 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_FILEDATA) &&
10351 (((smb_fid_saved_info_t *)(si->sip->extra_info))->create_flags & 0x10)) {
10352 proto_item *mar = NULL;
10353 proto_item *gmar = NULL;
10354 proto_tree *tr = NULL;
10356 /* The first field is a Volume GUID ... */
10358 proto_tree_add_item(tree, hf_smb_volume_guid,
10359 tvb, offset, 16, ENC_NA);
10360 offset += 16;
10362 /* The file ID comes next */
10363 proto_tree_add_item(tree, hf_smb_file_id_64bit,
10364 tvb, offset, 8, ENC_LITTLE_ENDIAN);
10365 offset += 8;
10367 mar = proto_tree_add_text(tree, tvb, offset, 4,
10368 "Maximal Access Rights");
10370 tr = proto_item_add_subtree(mar, ett_smb_nt_access_mask);
10372 offset = dissect_smb_access_mask(tvb, tr, offset);
10374 gmar = proto_tree_add_text(tree, tvb, offset, 4,
10375 "Guest Maximal Access Rights");
10377 tr = proto_item_add_subtree(gmar, ett_smb_nt_access_mask);
10379 offset = dissect_smb_access_mask(tvb, tr, offset);
10382 /* Try to remember the type of this fid so that we can dissect
10383 * any future security descriptor (access mask) properly
10385 if (ftype == 0) {
10386 if (isdir == 0) {
10387 if (fid_info) {
10388 fid_info->type = SMB_FID_TYPE_FILE;
10390 } else {
10391 if (fid_info) {
10392 fid_info->type = SMB_FID_TYPE_DIR;
10396 if (ftype == 2) {
10397 if (fid_info) {
10398 fid_info->type = SMB_FID_TYPE_PIPE;
10402 BYTE_COUNT;
10404 END_OF_SMB
10406 if (cmd != 0xff) { /* there is an andX command */
10407 if (andxoffset < offset)
10408 THROW(ReportedBoundsError);
10409 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
10412 /* if there was an error, add a generated filename to the tree */
10413 if (si->nt_status) {
10414 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE, si);
10417 return offset;
10421 static int
10422 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
10424 guint8 wc;
10425 guint16 bc;
10427 WORD_COUNT;
10429 BYTE_COUNT;
10431 END_OF_SMB
10433 return offset;
10436 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10437 BEGIN Transaction/Transaction2 Primary and secondary requests
10438 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
10441 static const value_string trans2_cmd_vals[] = {
10442 { 0x00, "OPEN2" },
10443 { 0x01, "FIND_FIRST2" },
10444 { 0x02, "FIND_NEXT2" },
10445 { 0x03, "QUERY_FS_INFO" },
10446 { 0x04, "SET_FS_INFO" },
10447 { 0x05, "QUERY_PATH_INFO" },
10448 { 0x06, "SET_PATH_INFO" },
10449 { 0x07, "QUERY_FILE_INFO" },
10450 { 0x08, "SET_FILE_INFO" },
10451 { 0x09, "FSCTL" },
10452 { 0x0A, "IOCTL2" },
10453 { 0x0B, "FIND_NOTIFY_FIRST" },
10454 { 0x0C, "FIND_NOTIFY_NEXT" },
10455 { 0x0D, "CREATE_DIRECTORY" },
10456 { 0x0E, "SESSION_SETUP" },
10457 { 0x0F, "Unknown (0x0f)" }, /* dummy so val_to_str_ext can do indexed lookup */
10458 { 0x10, "GET_DFS_REFERRAL" },
10459 { 0x11, "REPORT_DFS_INCONSISTENCY" },
10460 { 0, NULL }
10463 value_string_ext trans2_cmd_vals_ext = VALUE_STRING_EXT_INIT(trans2_cmd_vals);
10465 static const true_false_string tfs_tf_dtid = {
10466 "Also DISCONNECT TID",
10467 "Do NOT disconnect TID"
10469 static const true_false_string tfs_tf_owt = {
10470 "One Way Transaction (NO RESPONSE)",
10471 "Two way transaction"
10474 static const true_false_string tfs_ff2_backup = {
10475 "Find WITH backup intent",
10476 "No backup intent"
10478 static const true_false_string tfs_ff2_continue = {
10479 "CONTINUE search from previous position",
10480 "New search, do NOT continue from previous position"
10482 static const true_false_string tfs_ff2_resume = {
10483 "Return RESUME keys",
10484 "Do NOT return resume keys"
10486 static const true_false_string tfs_ff2_close_eos = {
10487 "CLOSE search if END OF SEARCH is reached",
10488 "Do NOT close search if end of search reached"
10490 static const true_false_string tfs_ff2_close = {
10491 "CLOSE search after this request",
10492 "Do NOT close search after this request"
10495 /* used by
10496 TRANS2_FIND_FIRST2
10498 static const value_string ff2_il_vals[] = {
10499 { 1, "Info Standard"},
10500 { 2, "Info Query EA Size"},
10501 { 3, "Info Query EAs From List"},
10502 { 0x0101, "Find File Directory Info"},
10503 { 0x0102, "Find File Full Directory Info"},
10504 { 0x0103, "Find File Names Info"},
10505 { 0x0104, "Find File Both Directory Info"},
10506 { 0x0105, "Find File Full Directory Info"},
10507 { 0x0106, "Find File Id Both Directory Info"},
10508 { 0x0202, "Find File Unix"},
10509 { 0x020B, "Find File Unix Info2"},
10510 {0, NULL}
10513 /* values used by :
10514 TRANS2_QUERY_PATH_INFORMATION
10515 TRANS2_QUERY_FILE_INFORMATION
10517 static const value_string qpi_loi_vals[] = {
10518 { 1, "Info Standard"},
10519 { 2, "Info Query EA Size"},
10520 { 3, "Info Query EAs From List"},
10521 { 4, "Info Query All EAs"},
10522 { 6, "Info Is Name Valid"},
10523 { 0x0101, "Query File Basic Info"},
10524 { 0x0102, "Query File Standard Info"},
10525 { 0x0103, "Query File EA Info"},
10526 { 0x0104, "Query File Name Info"},
10527 { 0x0107, "Query File All Info"},
10528 { 0x0108, "Query File Alt Name Info"},
10529 { 0x0109, "Query File Stream Info"},
10530 { 0x010b, "Query File Compression Info"},
10531 { 0x0200, "Query File Unix Basic"},
10532 { 0x0201, "Query File Unix Link"},
10533 { 0x0202, "Query File Unix Hardlink"},
10534 { 0x0204, "Query File Posix ACL"},
10535 { 0x0205, "Query File Posix XATTR"},
10536 { 0x0206, "Query File Posix Attr Flags"},
10537 { 0x0207, "Query File Posix Permissions"},
10538 { 0x0208, "Query File Posix Lock"},
10539 { 0x020b, "Query File Unix Info2"},
10540 { 1004, "Query File Basic Info"},
10541 { 1005, "Query File Standard Info"},
10542 { 1006, "Query File Internal Info"},
10543 { 1007, "Query File EA Info"},
10544 { 1009, "Query File Name Info"},
10545 { 1010, "Query File Rename Info"},
10546 { 1011, "Query File Link Info"},
10547 { 1012, "Query File Names Info"},
10548 { 1013, "Query File Disposition Info"},
10549 { 1014, "Query File Position Info"},
10550 { 1015, "Query File Full EA Info"},
10551 { 1016, "Query File Mode Info"},
10552 { 1017, "Query File Alignment Info"},
10553 { 1018, "Query File All Info"},
10554 { 1019, "Query File Allocation Info"},
10555 { 1020, "Query File End of File Info"},
10556 { 1021, "Query File Alt Name Info"},
10557 { 1022, "Query File Stream Info"},
10558 { 1023, "Query File Pipe Info"},
10559 { 1024, "Query File Pipe Local Info"},
10560 { 1025, "Query File Pipe Remote Info"},
10561 { 1026, "Query File Mailslot Query Info"},
10562 { 1027, "Query File Mailslot Set Info"},
10563 { 1028, "Query File Compression Info"},
10564 { 1029, "Query File ObjectID Info"},
10565 { 1030, "Query File Completion Info"},
10566 { 1031, "Query File Move Cluster Info"},
10567 { 1032, "Query File Quota Info"},
10568 { 1033, "Query File Reparsepoint Info"},
10569 { 1034, "Query File Network Open Info"},
10570 { 1035, "Query File Attribute Tag Info"},
10571 { 1036, "Query File Tracking Info"},
10572 { 1037, "Query File Maximum Info"},
10573 {0, NULL}
10576 /* values used by :
10577 TRANS2_SET_PATH_INFORMATION
10578 TRANS2_SET_FILE_INFORMATION
10579 (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
10580 but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
10581 well; note that they're different from the QUERY_PATH_INFORMATION
10582 and QUERY_FILE_INFORMATION values!)
10584 static const value_string spi_loi_vals[] = {
10585 { 1, "Info Standard"},
10586 { 2, "Info Set EAs"},
10587 { 4, "Info Query All EAs"},
10588 { 0x0101, "Set File Basic Info"},
10589 { 0x0102, "Set File Disposition Info"},
10590 { 0x0103, "Set File Allocation Info"},
10591 { 0x0104, "Set File End Of File Info"},
10592 { 0x0200, "Set File Unix Basic"},
10593 { 0x0201, "Set File Unix Link"},
10594 { 0x0202, "Set File Unix HardLink"},
10595 { 0x0204, "Set File Unix ACL"},
10596 { 0x0205, "Set File Unix XATTR"},
10597 { 0x0206, "Set File Unix Attr Flags"},
10598 { 0x0208, "Set File Posix Lock"},
10599 { 0x0209, "Set File Posix Open"},
10600 { 0x020a, "Set File Posix Unlink"},
10601 { 0x020b, "Set File Unix Info2"},
10602 { 1004, "Set File Basic Info"},
10603 { 1010, "Set Rename Information"},
10604 { 1013, "Set Disposition Information"},
10605 { 1014, "Set Position Information"},
10606 { 1016, "Set Mode Information"},
10607 { 1019, "Set Allocation Information"},
10608 { 1020, "Set EOF Information"},
10609 { 1023, "Set File Pipe Information"},
10610 { 1025, "Set File Pipe Remote Information"},
10611 { 1029, "Set Copy On Write Information"},
10612 { 1032, "Set OLE Class ID Information"},
10613 { 1039, "Set Inherit Context Index Information"},
10614 { 1040, "Set OLE Information (?)"},
10615 {0, NULL}
10618 static const value_string qfsi_vals[] = {
10619 { 1, "Info Allocation"},
10620 { 2, "Info Volume"},
10621 { 0x0101, "Query FS Label Info"},
10622 { 0x0102, "Query FS Volume Info"},
10623 { 0x0103, "Query FS Size Info"},
10624 { 0x0104, "Query FS Device Info"},
10625 { 0x0105, "Query FS Attribute Info"},
10626 { 0x0200, "Unix Query FS Info"},
10627 { 0x0301, "Mac Query FS Info"},
10628 { 1001, "Query FS Label Info"},
10629 { 1002, "Query FS Volume Info"},
10630 { 1003, "Query FS Size Info"},
10631 { 1004, "Query FS Device Info"},
10632 { 1005, "Query FS Attribute Info"},
10633 { 1006, "Query FS Quota Info"},
10634 { 1007, "Query Full FS Size Info"},
10635 { 1008, "Object ID Information"},
10636 {0, NULL}
10639 static const value_string sfsi_vals[] = {
10640 { 0x203, "Request Transport Encryption"},
10641 { 1006, "Set FS Quota Info"},
10642 {0, NULL}
10645 static const value_string nt_rename_vals[] = {
10646 { 0x0103, "Create Hard Link"},
10647 {0, NULL}
10651 static const value_string delete_pending_vals[] = {
10652 {0, "Normal, no pending delete"},
10653 {1, "This object has DELETE PENDING"},
10654 {0, NULL}
10657 static const value_string alignment_vals[] = {
10658 {0, "Byte alignment"},
10659 {1, "Word (16bit) alignment"},
10660 {3, "Long (32bit) alignment"},
10661 {7, "8 byte boundary alignment"},
10662 {0x0f, "16 byte boundary alignment"},
10663 {0x1f, "32 byte boundary alignment"},
10664 {0x3f, "64 byte boundary alignment"},
10665 {0x7f, "128 byte boundary alignment"},
10666 {0xff, "256 byte boundary alignment"},
10667 {0x1ff, "512 byte boundary alignment"},
10668 {0, NULL}
10671 static const true_false_string tfs_marked_for_deletion = {
10672 "File is MARKED FOR DELETION",
10673 "File is NOT marked for deletion"
10676 static const true_false_string tfs_get_dfs_server_hold_storage = {
10677 "Referral SERVER HOLDS STORAGE for the file",
10678 "Referral server does NOT hold storage for the file"
10680 static const true_false_string tfs_get_dfs_fielding = {
10681 "The server in referral is FIELDING CAPABLE",
10682 "The server in referrals is NOT fielding capable"
10685 static const true_false_string tfs_dfs_referral_flags_name_list_referral = {
10686 "A domain/DC referral response",
10687 "NOT a domain/DC referral response"
10690 static const true_false_string tfs_dfs_referral_flags_target_set_boundary = {
10691 "The first target in the target set",
10692 "NOT the first target in the target set"
10695 static const value_string dfs_referral_server_type_vals[] = {
10696 {0, "Non-root targets returned"},
10697 {1, "Root targets returns"},
10698 {0, NULL}
10702 static const true_false_string tfs_device_char_removable = {
10703 "This is a REMOVABLE device",
10704 "This is NOT a removable device"
10706 static const true_false_string tfs_device_char_read_only = {
10707 "This is a READ-ONLY device",
10708 "This is NOT a read-only device"
10710 static const true_false_string tfs_device_char_floppy = {
10711 "This is a FLOPPY DISK device",
10712 "This is NOT a floppy disk device"
10714 static const true_false_string tfs_device_char_write_once = {
10715 "This is a WRITE-ONCE device",
10716 "This is NOT a write-once device"
10718 static const true_false_string tfs_device_char_remote = {
10719 "This is a REMOTE device",
10720 "This is NOT a remote device"
10722 static const true_false_string tfs_device_char_mounted = {
10723 "This device is MOUNTED",
10724 "This device is NOT mounted"
10726 static const true_false_string tfs_device_char_virtual = {
10727 "This is a VIRTUAL device",
10728 "This is NOT a virtual device"
10732 static const true_false_string tfs_fs_attr_css = {
10733 "This FS supports CASE SENSITIVE SEARCHes",
10734 "This FS does NOT support case sensitive searches"
10736 static const true_false_string tfs_fs_attr_cpn = {
10737 "This FS supports CASE PRESERVED NAMES",
10738 "This FS does NOT support case preserved names"
10740 static const true_false_string tfs_fs_attr_uod = {
10741 "This FS supports UNICODE NAMES",
10742 "This FS does NOT support unicode names"
10744 static const true_false_string tfs_fs_attr_pacls = {
10745 "This FS supports PERSISTENT ACLs",
10746 "This FS does NOT support persistent acls"
10748 static const true_false_string tfs_fs_attr_fc = {
10749 "This FS supports COMPRESSED FILES",
10750 "This FS does NOT support compressed files"
10752 static const true_false_string tfs_fs_attr_vq = {
10753 "This FS supports VOLUME QUOTAS",
10754 "This FS does NOT support volume quotas"
10756 static const true_false_string tfs_fs_attr_srp = {
10757 "This FS supports REPARSE POINTS",
10758 "This FS does NOT support reparse points"
10760 static const true_false_string tfs_fs_attr_srs = {
10761 "This FS supports REMOTE STORAGE",
10762 "This FS does NOT support remote storage"
10764 static const true_false_string tfs_fs_attr_ssf = {
10765 "This FS supports SPARSE FILES",
10766 "This FS does NOT support sparse files"
10768 static const true_false_string tfs_fs_attr_sla = {
10769 "This FS supports LFN APIs",
10770 "This FS does NOT support lfn apis"
10772 static const true_false_string tfs_fs_attr_vic = {
10773 "This FS VOLUME IS COMPRESSED",
10774 "This FS volume is NOT compressed"
10776 static const true_false_string tfs_fs_attr_soids = {
10777 "This FS supports OIDs",
10778 "This FS does NOT support OIDs"
10780 static const true_false_string tfs_fs_attr_se = {
10781 "This FS supports ENCRYPTION",
10782 "This FS does NOT support encryption"
10784 static const true_false_string tfs_fs_attr_ns = {
10785 "This FS supports NAMED STREAMS",
10786 "This FS does NOT support named streams"
10788 static const true_false_string tfs_fs_attr_rov = {
10789 "This is a READ ONLY VOLUME",
10790 "This is a read/write volume"
10793 #define FF2_RESUME 0x0004
10795 static int
10796 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb_info_t *si)
10798 guint16 mask;
10799 proto_item *item = NULL;
10800 proto_tree *tree = NULL;
10801 smb_transact2_info_t *t2i;
10803 mask = tvb_get_letohs(tvb, offset);
10805 DISSECTOR_ASSERT(si);
10807 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
10808 t2i = (smb_transact2_info_t *)si->sip->extra_info;
10809 if (t2i != NULL) {
10810 if (!pinfo->fd->flags.visited)
10811 t2i->resume_keys = (mask & FF2_RESUME);
10815 if (parent_tree) {
10816 item = proto_tree_add_item(parent_tree, hf_smb_ff2, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10817 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10819 proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10820 tvb, offset, 2, mask);
10821 proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10822 tvb, offset, 2, mask);
10823 proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10824 tvb, offset, 2, mask);
10825 proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10826 tvb, offset, 2, mask);
10827 proto_tree_add_boolean(tree, hf_smb_ff2_close,
10828 tvb, offset, 2, mask);
10831 offset += 2;
10833 return offset;
10836 #if 0
10837 static int
10838 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10840 guint16 mask;
10841 proto_item *item;
10842 proto_tree *tree;
10844 mask = tvb_get_letohs(tvb, offset);
10846 if (parent_tree) {
10847 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10848 "IO Flag: 0x%04x", mask);
10849 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10851 proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10852 tvb, offset, 2, mask);
10853 proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10854 tvb, offset, 2, mask);
10857 offset += 2;
10859 return offset;
10861 #endif
10864 dissect_get_dfs_request_data(tvbuff_t *tvb, packet_info *pinfo,
10865 proto_tree *tree, int offset, guint16 *bcp, gboolean unicode)
10867 int fn_len;
10868 const char *fn;
10869 guint16 bc = *bcp;
10871 /* referral level */
10872 CHECK_BYTE_COUNT_TRANS(2);
10873 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10874 COUNT_BYTES_TRANS(2);
10876 /* file name */
10877 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, &bc);
10878 CHECK_STRING_TRANS(fn);
10879 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10880 fn);
10881 COUNT_BYTES_TRANS(fn_len);
10883 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10884 format_text(fn, strlen(fn)));
10886 *bcp = bc;
10887 return offset;
10890 static int
10891 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10892 proto_tree *parent_tree, int offset, int subcmd, guint16 bc, smb_info_t *si)
10894 proto_item *item = NULL;
10895 proto_tree *tree = NULL;
10896 smb_transact2_info_t *t2i;
10897 int fn_len;
10898 const char *fn;
10900 DISSECTOR_ASSERT(si);
10902 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
10903 t2i = (smb_transact2_info_t *)si->sip->extra_info;
10904 else
10905 t2i = NULL;
10907 if (parent_tree) {
10908 tvb_ensure_bytes_exist(tvb, offset, bc);
10909 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10910 "%s Parameters",
10911 val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
10912 "Unknown (0x%02x)"));
10913 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10916 switch(subcmd) {
10917 case 0x0000: /*TRANS2_OPEN2*/
10918 /* open flags */
10919 CHECK_BYTE_COUNT_TRANS(2);
10920 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10921 bc -= 2;
10923 /* desired access */
10924 CHECK_BYTE_COUNT_TRANS(2);
10925 offset = dissect_access(tvb, tree, offset, "Desired");
10926 bc -= 2;
10928 /* Search Attributes */
10929 CHECK_BYTE_COUNT_TRANS(2);
10930 offset = dissect_search_attributes(tvb, tree, offset);
10931 bc -= 2;
10933 /* File Attributes */
10934 CHECK_BYTE_COUNT_TRANS(2);
10935 offset = dissect_file_attributes(tvb, tree, offset);
10936 bc -= 2;
10938 /* create time */
10939 CHECK_BYTE_COUNT_TRANS(4);
10940 offset = dissect_smb_datetime(tvb, tree, offset,
10941 hf_smb_create_time,
10942 hf_smb_create_dos_date, hf_smb_create_dos_time,
10943 TRUE);
10944 bc -= 4;
10946 /* open function */
10947 CHECK_BYTE_COUNT_TRANS(2);
10948 offset = dissect_open_function(tvb, tree, offset);
10949 bc -= 2;
10951 /* allocation size */
10952 CHECK_BYTE_COUNT_TRANS(4);
10953 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10954 COUNT_BYTES_TRANS(4);
10956 /* 10 reserved bytes */
10957 CHECK_BYTE_COUNT_TRANS(10);
10958 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
10959 COUNT_BYTES_TRANS(10);
10961 /* file name */
10962 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10963 CHECK_STRING_TRANS(fn);
10964 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10965 fn);
10966 COUNT_BYTES_TRANS(fn_len);
10968 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10969 format_text(fn, strlen(fn)));
10970 break;
10971 case 0x0001: /*TRANS2_FIND_FIRST2*/
10972 /* Search Attributes */
10973 CHECK_BYTE_COUNT_TRANS(2);
10974 offset = dissect_search_attributes(tvb, tree, offset);
10975 bc -= 2;
10977 /* search count */
10978 CHECK_BYTE_COUNT_TRANS(2);
10979 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10980 COUNT_BYTES_TRANS(2);
10982 /* Find First2 flags */
10983 CHECK_BYTE_COUNT_TRANS(2);
10984 offset = dissect_ff2_flags(tvb, pinfo, tree, offset, si);
10985 bc -= 2;
10987 /* Find First2 information level */
10988 CHECK_BYTE_COUNT_TRANS(2);
10989 si->info_level = tvb_get_letohs(tvb, offset);
10990 if ((t2i != NULL) && !pinfo->fd->flags.visited)
10991 t2i->info_level = si->info_level;
10992 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10993 COUNT_BYTES_TRANS(2);
10995 /* storage type */
10996 CHECK_BYTE_COUNT_TRANS(4);
10997 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10998 COUNT_BYTES_TRANS(4);
11000 /* search pattern */
11001 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11002 CHECK_STRING_TRANS(fn);
11003 if (t2i && !t2i->name) {
11004 t2i->name = wmem_strdup(wmem_file_scope(), fn);
11006 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
11007 fn);
11008 COUNT_BYTES_TRANS(fn_len);
11010 col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
11011 format_text(fn, strlen(fn)));
11013 break;
11014 case 0x0002: /*TRANS2_FIND_NEXT2*/
11015 /* sid */
11016 CHECK_BYTE_COUNT_TRANS(2);
11017 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11018 COUNT_BYTES_TRANS(2);
11020 /* search count */
11021 CHECK_BYTE_COUNT_TRANS(2);
11022 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11023 COUNT_BYTES_TRANS(2);
11025 /* Find First2 information level */
11026 CHECK_BYTE_COUNT_TRANS(2);
11027 si->info_level = tvb_get_letohs(tvb, offset);
11028 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11029 t2i->info_level = si->info_level;
11030 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
11031 COUNT_BYTES_TRANS(2);
11033 /* resume key */
11034 CHECK_BYTE_COUNT_TRANS(4);
11035 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11036 COUNT_BYTES_TRANS(4);
11038 /* Find First2 flags */
11039 CHECK_BYTE_COUNT_TRANS(2);
11040 offset = dissect_ff2_flags(tvb, pinfo, tree, offset, si);
11041 bc -= 2;
11043 /* file name */
11044 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11045 CHECK_STRING_TRANS(fn);
11046 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11047 fn);
11048 COUNT_BYTES_TRANS(fn_len);
11050 col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
11051 format_text(fn, strlen(fn)));
11053 break;
11054 case 0x0003: /*TRANS2_QUERY_FS_INFORMATION*/
11055 /* level of interest */
11056 CHECK_BYTE_COUNT_TRANS(2);
11057 si->info_level = tvb_get_letohs(tvb, offset);
11058 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11059 t2i->info_level = si->info_level;
11060 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
11061 COUNT_BYTES_TRANS(2);
11063 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11064 val_to_str(si->info_level, qfsi_vals,
11065 "Unknown (0x%02x)"));
11067 break;
11068 case 0x0004: /*TRANS2_SET_FS_INFORMATION*/
11069 /* level of interest */
11070 CHECK_BYTE_COUNT_TRANS(4);
11071 si->info_level = tvb_get_letohs(tvb, offset+2);
11072 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11073 t2i->info_level = si->info_level;
11074 proto_tree_add_uint(tree, hf_smb_sfsi_information_level, tvb, offset+2, 2, si->info_level);
11075 COUNT_BYTES_TRANS(4);
11077 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11078 val_to_str(si->info_level, sfsi_vals,
11079 "Unknown (0x%02x)"));
11081 break;
11082 case 0x0005: /*TRANS2_QUERY_PATH_INFORMATION*/
11083 /* level of interest */
11084 CHECK_BYTE_COUNT_TRANS(2);
11085 si->info_level = tvb_get_letohs(tvb, offset);
11086 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11087 t2i->info_level = si->info_level;
11088 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
11089 COUNT_BYTES_TRANS(2);
11091 col_append_fstr(
11092 pinfo->cinfo, COL_INFO, ", %s",
11093 val_to_str(si->info_level, qpi_loi_vals,
11094 "Unknown (%u)"));
11096 /* 4 reserved bytes */
11097 CHECK_BYTE_COUNT_TRANS(4);
11098 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11099 COUNT_BYTES_TRANS(4);
11101 /* file name */
11102 if (si->unicode)
11103 fn = tvb_get_unicode_stringz(wmem_packet_scope(), tvb, offset, &fn_len, ENC_LITTLE_ENDIAN);
11104 else
11105 fn = tvb_get_stringz(wmem_packet_scope(), tvb, offset, &fn_len);
11107 CHECK_STRING_TRANS(fn);
11108 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11109 fn);
11110 COUNT_BYTES_TRANS(fn_len);
11111 if (t2i && !t2i->name) {
11112 t2i->name = wmem_strdup(wmem_file_scope(), fn);
11115 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11116 format_text(fn, strlen(fn)));
11118 break;
11119 case 0x0006: /*TRANS2_SET_PATH_INFORMATION*/
11120 /* level of interest */
11121 CHECK_BYTE_COUNT_TRANS(2);
11122 si->info_level = tvb_get_letohs(tvb, offset);
11123 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11124 t2i->info_level = si->info_level;
11125 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
11126 COUNT_BYTES_TRANS(2);
11128 /* 4 reserved bytes */
11129 CHECK_BYTE_COUNT_TRANS(4);
11130 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11131 COUNT_BYTES_TRANS(4);
11133 /* file name */
11134 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11135 CHECK_STRING_TRANS(fn);
11136 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11137 fn);
11138 COUNT_BYTES_TRANS(fn_len);
11140 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11141 format_text(fn, strlen(fn)));
11143 break;
11144 case 0x0007: { /*TRANS2_QUERY_FILE_INFORMATION*/
11145 guint16 fid;
11147 /* fid */
11148 CHECK_BYTE_COUNT_TRANS(2);
11149 fid = tvb_get_letohs(tvb, offset);
11150 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
11151 COUNT_BYTES_TRANS(2);
11153 /* level of interest */
11154 CHECK_BYTE_COUNT_TRANS(2);
11155 si->info_level = tvb_get_letohs(tvb, offset);
11156 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11157 t2i->info_level = si->info_level;
11158 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
11159 COUNT_BYTES_TRANS(2);
11161 col_append_fstr(
11162 pinfo->cinfo, COL_INFO, ", %s",
11163 val_to_str(si->info_level, qpi_loi_vals,
11164 "Unknown (%u)"));
11166 break;
11168 case 0x0008: { /*TRANS2_SET_FILE_INFORMATION*/
11169 guint16 fid;
11171 /* fid */
11172 CHECK_BYTE_COUNT_TRANS(2);
11173 fid = tvb_get_letohs(tvb, offset);
11174 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
11175 COUNT_BYTES_TRANS(2);
11177 /* level of interest */
11178 CHECK_BYTE_COUNT_TRANS(2);
11179 si->info_level = tvb_get_letohs(tvb, offset);
11180 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11181 t2i->info_level = si->info_level;
11182 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
11183 COUNT_BYTES_TRANS(2);
11185 #if 0
11187 * XXX - "Microsoft Networks SMB File Sharing Protocol
11188 * Extensions Version 3.0, Document Version 1.11,
11189 * July 19, 1990" says this is I/O flags, but it's
11190 * reserved in the SNIA spec, and some clients appear
11191 * to leave junk in it.
11193 * Is this some field used only if a particular
11194 * dialect was negotiated, so that clients can feel
11195 * safe not setting it if they haven't negotiated that
11196 * dialect? Or do the (non-OS/2) clients simply not care
11197 * about that particular OS/2-oriented dialect?
11200 /* IO Flag */
11201 CHECK_BYTE_COUNT_TRANS(2);
11202 offset = dissect_sfi_ioflag(tvb, tree, offset);
11203 bc -= 2;
11204 #else
11205 /* 2 reserved bytes */
11206 CHECK_BYTE_COUNT_TRANS(2);
11207 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
11208 COUNT_BYTES_TRANS(2);
11209 #endif
11211 break;
11213 case 0x0009: /*TRANS2_FSCTL*/
11214 /* this call has no parameter block in the request */
11217 * XXX - "Microsoft Networks SMB File Sharing Protocol
11218 * Extensions Version 3.0, Document Version 1.11,
11219 * July 19, 1990" says this this contains a
11220 * "File system specific parameter block". (That means
11221 * we may not be able to dissect it in any case.)
11223 break;
11224 case 0x000a: /*TRANS2_IOCTL2*/
11225 /* this call has no parameter block in the request */
11228 * XXX - "Microsoft Networks SMB File Sharing Protocol
11229 * Extensions Version 3.0, Document Version 1.11,
11230 * July 19, 1990" says this this contains a
11231 * "Device/function specific parameter block". (That
11232 * means we may not be able to dissect it in any case.)
11234 break;
11235 case 0x000b: /*TRANS2_FIND_NOTIFY_FIRST*/
11236 /* Search Attributes */
11237 CHECK_BYTE_COUNT_TRANS(2);
11238 offset = dissect_search_attributes(tvb, tree, offset);
11239 bc -= 2;
11241 /* Number of changes to wait for */
11242 CHECK_BYTE_COUNT_TRANS(2);
11243 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11244 COUNT_BYTES_TRANS(2);
11246 /* Find Notify information level */
11247 CHECK_BYTE_COUNT_TRANS(2);
11248 si->info_level = tvb_get_letohs(tvb, offset);
11249 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11250 t2i->info_level = si->info_level;
11251 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
11252 COUNT_BYTES_TRANS(2);
11254 /* 4 reserved bytes */
11255 CHECK_BYTE_COUNT_TRANS(4);
11256 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11257 COUNT_BYTES_TRANS(4);
11259 /* file name */
11260 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11261 CHECK_STRING_TRANS(fn);
11262 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11263 fn);
11264 COUNT_BYTES_TRANS(fn_len);
11266 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11267 format_text(fn, strlen(fn)));
11269 break;
11270 case 0x000c: /*TRANS2_FIND_NOTIFY_NEXT*/
11271 /* Monitor handle */
11272 CHECK_BYTE_COUNT_TRANS(2);
11273 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11274 COUNT_BYTES_TRANS(2);
11276 /* Number of changes to wait for */
11277 CHECK_BYTE_COUNT_TRANS(2);
11278 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11279 COUNT_BYTES_TRANS(2);
11281 break;
11282 case 0x000d: /*TRANS2_CREATE_DIRECTORY*/
11283 /* 4 reserved bytes */
11284 CHECK_BYTE_COUNT_TRANS(4);
11285 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11286 COUNT_BYTES_TRANS(4);
11288 /* dir name */
11289 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
11290 FALSE, FALSE, &bc);
11291 CHECK_STRING_TRANS(fn);
11292 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
11293 fn);
11294 COUNT_BYTES_TRANS(fn_len);
11296 col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
11297 format_text(fn, strlen(fn)));
11298 break;
11299 case 0x000e: /*TRANS2_SESSION_SETUP*/
11300 /* XXX unknown structure*/
11301 break;
11302 case 0x0010: /*TRANS2_GET_DFS_REFERRAL*/
11303 offset = dissect_get_dfs_request_data(tvb, pinfo, tree, offset, &bc, si->unicode);
11304 break;
11305 case 0x0011: /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11306 /* file name */
11307 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11308 CHECK_STRING_TRANS(fn);
11309 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11310 fn);
11311 COUNT_BYTES_TRANS(fn_len);
11313 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
11314 format_text(fn, strlen(fn)));
11315 break;
11318 /* ooops there were data we didnt know how to process */
11319 if (bc != 0) {
11320 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, ENC_NA);
11321 offset += bc;
11324 return offset;
11328 * XXX - just use "dissect_connect_flags()" here?
11330 static guint16
11331 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11333 guint16 mask;
11334 proto_item *item;
11335 proto_tree *tree;
11337 mask = tvb_get_letohs(tvb, offset);
11339 if (parent_tree) {
11340 item = proto_tree_add_item(parent_tree, hf_smb_transaction_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11341 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
11343 proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
11344 tvb, offset, 2, mask);
11345 proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
11346 tvb, offset, 2, mask);
11349 return mask;
11353 static int
11354 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11356 guint16 mask;
11357 proto_item *item;
11358 proto_tree *tree;
11360 mask = tvb_get_letohs(tvb, offset);
11362 if (parent_tree) {
11363 item = proto_tree_add_item(parent_tree, hf_smb_get_dfs_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11364 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
11366 proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
11367 tvb, offset, 2, mask);
11368 proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
11369 tvb, offset, 2, mask);
11372 offset += 2;
11373 return offset;
11376 static int
11377 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11379 guint16 mask;
11380 proto_item *item;
11381 proto_tree *tree;
11383 mask = tvb_get_letohs(tvb, offset);
11385 if (parent_tree) {
11386 item = proto_tree_add_item(parent_tree, hf_smb_dfs_referral_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11387 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
11389 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_name_list_referral,
11390 tvb, offset, 2, mask);
11391 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_target_set_boundary,
11392 tvb, offset, 2, mask);
11395 offset += 2;
11397 return offset;
11401 /* dfs inconsistency data (4.4.2)
11403 static int
11404 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo _U_,
11405 proto_tree *tree, int offset, guint16 *bcp, smb_info_t *si)
11407 int fn_len;
11408 const char *fn;
11410 DISSECTOR_ASSERT(si);
11412 /*XXX shouldn this data hold version and size? unclear from doc*/
11413 /* referral version */
11414 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11415 proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11416 COUNT_BYTES_TRANS_SUBR(2);
11418 /* referral size */
11419 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11420 proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11421 COUNT_BYTES_TRANS_SUBR(2);
11423 /* referral server type */
11424 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11425 proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11426 COUNT_BYTES_TRANS_SUBR(2);
11428 /* referral flags */
11429 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11430 offset = dissect_dfs_referral_flags(tvb, tree, offset);
11431 *bcp -= 2;
11433 /* node name */
11434 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11435 CHECK_STRING_TRANS_SUBR(fn);
11436 proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11437 fn);
11438 COUNT_BYTES_TRANS_SUBR(fn_len);
11440 return offset;
11443 static int
11444 dissect_dfs_referral_strings(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11445 int nstring, int stroffset, int oldoffset, int offset,
11446 guint16 bc, gboolean unicode, int *end)
11448 int istring;
11449 const char *str;
11450 int str_len; /* string length including the terminating NULL. */
11452 if (stroffset <= oldoffset)
11453 return oldoffset;
11455 bc -= (stroffset - offset);
11456 for (istring = 0; istring < nstring; istring++) {
11457 if ((gint16)bc > 0) {
11458 str = get_unicode_or_ascii_string(tvb, &stroffset, unicode, &str_len, FALSE, FALSE, &bc);
11459 CHECK_STRING_TRANS_SUBR(str);
11460 proto_tree_add_string(tree, hfindex, tvb, stroffset, str_len, str);
11461 stroffset += str_len;
11462 bc -= str_len;
11463 if (end && (*end < stroffset))
11464 *end = stroffset;
11468 return offset;
11472 static int
11473 dissect_dfs_referral_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11474 int stroffset, int oldoffset, int offset,
11475 guint16 bc, gboolean unicode, int *end)
11477 return dissect_dfs_referral_strings(tvb, tree, hfindex,
11478 1, stroffset, oldoffset, offset,
11479 bc, unicode, end);
11482 static int
11483 dissect_dfs_referral_entry_v2(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11484 guint16 refflags _U_, guint16 *bcp, gboolean unicode, int *ucstring_end)
11487 guint16 pathoffset;
11488 guint16 altpathoffset;
11489 guint16 nodeoffset;
11491 /* proximity */
11492 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11493 proto_tree_add_item(tree, hf_smb_dfs_referral_proximity, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11494 COUNT_BYTES_TRANS_SUBR(4);
11496 /* ttl */
11497 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11498 proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11499 COUNT_BYTES_TRANS_SUBR(4);
11501 /* path offset */
11502 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11503 pathoffset = tvb_get_letohs(tvb, offset);
11504 proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11505 COUNT_BYTES_TRANS_SUBR(2);
11507 /* alt path offset */
11508 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11509 altpathoffset = tvb_get_letohs(tvb, offset);
11510 proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11511 COUNT_BYTES_TRANS_SUBR(2);
11513 /* node offset */
11514 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11515 nodeoffset = tvb_get_letohs(tvb, offset);
11516 proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11517 COUNT_BYTES_TRANS_SUBR(2);
11519 /* path */
11520 if (pathoffset) {
11521 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11522 pathoffset+oldoffset, oldoffset, offset,
11523 *bcp, unicode, ucstring_end);
11526 /* alt path */
11527 if (altpathoffset) {
11528 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11529 altpathoffset+oldoffset, oldoffset, offset,
11530 *bcp, unicode, ucstring_end);
11533 /* node */
11534 if (nodeoffset) {
11535 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11536 nodeoffset+oldoffset, oldoffset, offset,
11537 *bcp, unicode, ucstring_end);
11540 return offset;
11545 static int
11546 dissect_dfs_referral_entry_v3(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11547 guint16 refflags, guint16 *bcp, gboolean unicode, int *ucstring_end)
11549 guint16 domoffset;
11550 guint16 nexpnames;
11551 guint16 expoffset;
11552 guint16 pathoffset;
11553 guint16 altpathoffset;
11554 guint16 nodeoffset;
11556 /* ttl */
11557 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11558 proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11559 COUNT_BYTES_TRANS_SUBR(4);
11561 if (refflags & REFENT_FLAGS_NAME_LIST_REFERRAL) {
11562 /* domain name offset */
11563 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11564 domoffset = tvb_get_letohs(tvb, offset);
11565 proto_tree_add_uint(tree, hf_smb_dfs_referral_domain_offset, tvb, offset, 2, domoffset);
11566 COUNT_BYTES_TRANS_SUBR(2);
11568 /* number of expanded names*/
11569 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11570 nexpnames = tvb_get_letohs(tvb, offset);
11571 proto_tree_add_uint(tree, hf_smb_dfs_referral_number_of_expnames, tvb, offset, 2, nexpnames);
11572 COUNT_BYTES_TRANS_SUBR(2);
11574 /* expanded names offset */
11575 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11576 expoffset = tvb_get_letohs(tvb, offset);
11577 proto_tree_add_uint(tree, hf_smb_dfs_referral_expnames_offset, tvb, offset, 2, expoffset);
11578 COUNT_BYTES_TRANS_SUBR(2);
11580 /* padding: zero or 16 bytes, which should be ignored by clients.
11581 * we ignore them too.
11584 /* domain name */
11585 if (domoffset) {
11586 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_domain_name,
11587 domoffset+oldoffset, oldoffset, offset,
11588 *bcp, unicode, ucstring_end);
11590 /* expanded names */
11591 if (expoffset) {
11592 proto_item *expitem = NULL;
11593 proto_tree *exptree = NULL;
11595 expitem = proto_tree_add_text(tree, tvb, offset, *bcp, "Expanded Names");
11596 exptree = proto_item_add_subtree(expitem, ett_smb_dfs_referral_expnames);
11598 dissect_dfs_referral_strings(tvb, exptree, hf_smb_dfs_referral_expname,
11599 nexpnames, expoffset+oldoffset, oldoffset, offset,
11600 *bcp, unicode, ucstring_end);
11602 } else {
11603 /* path offset */
11604 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11605 pathoffset = tvb_get_letohs(tvb, offset);
11606 proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11607 COUNT_BYTES_TRANS_SUBR(2);
11609 /* alt path offset */
11610 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11611 altpathoffset = tvb_get_letohs(tvb, offset);
11612 proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11613 COUNT_BYTES_TRANS_SUBR(2);
11615 /* node offset */
11616 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11617 nodeoffset = tvb_get_letohs(tvb, offset);
11618 proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11619 COUNT_BYTES_TRANS_SUBR(2);
11621 /* service site guid */
11622 CHECK_BYTE_COUNT_TRANS_SUBR(16);
11623 proto_tree_add_item(tree, hf_smb_dfs_referral_server_guid, tvb, offset, 16, ENC_NA);
11624 COUNT_BYTES_TRANS_SUBR(16);
11626 /* path */
11627 if (pathoffset) {
11628 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11629 pathoffset+oldoffset, oldoffset, offset,
11630 *bcp, unicode, ucstring_end);
11633 /* alt path */
11634 if (altpathoffset) {
11635 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11636 altpathoffset+oldoffset, oldoffset, offset,
11637 *bcp, unicode, ucstring_end);
11640 /* node */
11641 if (nodeoffset) {
11642 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11643 nodeoffset+oldoffset, oldoffset, offset,
11644 *bcp, unicode, ucstring_end);
11648 return offset;
11652 /* get dfs referral data (4.4.1)
11655 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo _U_,
11656 proto_tree *tree, int offset, guint16 *bcp, gboolean unicode)
11658 guint16 numref;
11659 guint16 refsize;
11660 guint16 refflags;
11661 int fn_len;
11662 const char *fn;
11663 int unklen;
11664 int ucstring_end;
11665 int ucstring_len;
11667 /* path consumed */
11668 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11669 proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11670 COUNT_BYTES_TRANS_SUBR(2);
11672 /* num referrals */
11673 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11674 numref = tvb_get_letohs(tvb, offset);
11675 proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
11676 COUNT_BYTES_TRANS_SUBR(2);
11678 /* get dfs flags */
11679 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11680 offset = dissect_get_dfs_flags(tvb, tree, offset);
11681 *bcp -= 2;
11683 /* XXX - in at least one capture there appears to be 2 bytes
11684 of stuff after the Dfs flags, perhaps so that the header
11685 in front of the referral list is a multiple of 4 bytes long. */
11686 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11687 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, ENC_NA);
11688 COUNT_BYTES_TRANS_SUBR(2);
11690 /* if there are any referrals */
11691 if (numref) {
11692 proto_item *ref_item = NULL;
11693 proto_tree *ref_tree = NULL;
11694 int old_offset = offset;
11696 if (tree) {
11697 tvb_ensure_bytes_exist(tvb, offset, *bcp);
11698 ref_item = proto_tree_add_text(tree,
11699 tvb, offset, *bcp, "Referrals");
11700 ref_tree = proto_item_add_subtree(ref_item,
11701 ett_smb_dfs_referrals);
11703 ucstring_end = -1;
11705 while(numref--) {
11706 proto_item *ri = NULL;
11707 proto_tree *rt = NULL;
11708 int old_offset_2 = offset;
11709 guint16 version;
11711 if (tree) {
11712 tvb_ensure_bytes_exist(tvb, offset, *bcp);
11713 ri = proto_tree_add_text(ref_tree,
11714 tvb, offset, *bcp, "Referral");
11715 rt = proto_item_add_subtree(ri,
11716 ett_smb_dfs_referral);
11719 /* referral version */
11720 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11721 version = tvb_get_letohs(tvb, offset);
11722 proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
11723 tvb, offset, 2, version);
11724 COUNT_BYTES_TRANS_SUBR(2);
11726 /* referral size */
11727 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11728 refsize = tvb_get_letohs(tvb, offset);
11729 proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
11730 COUNT_BYTES_TRANS_SUBR(2);
11732 /* referral server type */
11733 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11734 proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11735 COUNT_BYTES_TRANS_SUBR(2);
11737 /* referral flags */
11738 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11739 refflags = tvb_get_letohs(tvb, offset);
11740 offset = dissect_dfs_referral_flags(tvb, rt, offset);
11741 *bcp -= 2;
11743 switch(version) {
11745 case 1:
11746 /* node name */
11747 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, bcp);
11748 CHECK_STRING_TRANS_SUBR(fn);
11749 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11750 fn);
11751 COUNT_BYTES_TRANS_SUBR(fn_len);
11752 break;
11754 case 2:
11755 offset = dissect_dfs_referral_entry_v2(tvb, rt, old_offset_2, offset,
11756 refflags, bcp, unicode, &ucstring_end);
11757 break;
11758 case 3:
11759 offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
11760 refflags, bcp, unicode, &ucstring_end);
11761 break;
11762 case 4:
11763 /* V4 is extactly same as V3, except the version number and
11764 * one more ReferralEntryFlags */
11765 offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
11766 refflags, bcp, unicode, &ucstring_end);
11767 break;
11771 * Show anything beyond the length of the referral
11772 * as unknown data.
11774 unklen = (old_offset_2 + refsize) - offset;
11775 if (unklen < 0) {
11777 * XXX - the length is bogus.
11779 unklen = 0;
11781 if (unklen != 0) {
11782 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
11783 proto_tree_add_item(rt, hf_smb_unknown, tvb,
11784 offset, unklen, ENC_NA);
11785 COUNT_BYTES_TRANS_SUBR(unklen);
11788 proto_item_set_len(ri, offset-old_offset_2);
11792 * Treat the offset past the end of the last Unicode
11793 * string after the referrals (if any) as the last
11794 * offset.
11796 if (ucstring_end > offset) {
11797 ucstring_len = ucstring_end - offset;
11798 if (*bcp < ucstring_len)
11799 ucstring_len = *bcp;
11800 offset += ucstring_len;
11801 *bcp -= ucstring_len;
11803 proto_item_set_len(ref_item, offset-old_offset);
11806 return offset;
11809 /* This dissects the standard four 8-byte Windows timestamps ...
11811 static int
11812 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
11813 packet_info *pinfo _U_, proto_tree *tree,
11814 int offset, guint16 *bcp, gboolean *trunc)
11816 /* create time */
11817 CHECK_BYTE_COUNT_SUBR(8);
11818 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11819 *bcp -= 8;
11821 /* access time */
11822 CHECK_BYTE_COUNT_SUBR(8);
11823 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11824 *bcp -= 8;
11826 /* last write time */
11827 CHECK_BYTE_COUNT_SUBR(8);
11828 offset = dissect_nt_64bit_time(tvb, tree, offset,
11829 hf_smb_last_write_time);
11830 *bcp -= 8;
11832 /* last change time */
11833 CHECK_BYTE_COUNT_SUBR(8);
11834 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11835 *bcp -= 8;
11837 *trunc = FALSE;
11838 return offset;
11841 /* this dissects the SMB_INFO_STANDARD
11842 as described in 4.2.16.1 of the CIFS 1.0 specification
11843 or as described in 2.2.8.3.1 of the MS-CIFS specification for query
11844 section 2.2.8.4.1 of the MS-CIFS specification describes it for set;
11845 it says that everything past the last write time is "reserved",
11846 presumably meaning that you can fetch it but not set it
11847 for now we just use it for both query and set
11849 static int
11850 dissect_qsfi_SMB_INFO_STANDARD(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11851 int offset, guint16 *bcp, gboolean *trunc)
11853 /* create time */
11854 CHECK_BYTE_COUNT_SUBR(4);
11855 offset = dissect_smb_datetime(tvb, tree, offset,
11856 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11857 FALSE);
11858 *bcp -= 4;
11860 /* access time */
11861 CHECK_BYTE_COUNT_SUBR(4);
11862 offset = dissect_smb_datetime(tvb, tree, offset,
11863 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11864 FALSE);
11865 *bcp -= 4;
11867 /* last write time */
11868 CHECK_BYTE_COUNT_SUBR(4);
11869 offset = dissect_smb_datetime(tvb, tree, offset,
11870 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11871 FALSE);
11872 *bcp -= 4;
11874 /* data size */
11875 CHECK_BYTE_COUNT_SUBR(4);
11876 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11877 COUNT_BYTES_SUBR(4);
11879 /* allocation size */
11880 CHECK_BYTE_COUNT_SUBR(4);
11881 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11882 COUNT_BYTES_SUBR(4);
11884 /* File Attributes */
11885 CHECK_BYTE_COUNT_SUBR(2);
11886 offset = dissect_file_attributes(tvb, tree, offset);
11887 *bcp -= 2;
11890 * The MS-CIFS spec says this doesn't have an EA length field;
11891 * the SNIA CIFS spec says it does, as does the 1996
11892 * "Microsoft Networks SMB FILE SHARING PROTOCOL Document
11893 * Version 6.0p" document.
11895 * Some older SMB documents point to the documentation
11896 * for the OS/2 DosQFileInfo() API; the page at
11898 * http://cyberkinetica.homeunix.net/os2tk45/prcp/111_L2_DosQFileInfo.html
11900 * says that, for level 1 (SMB_INFO_STANDARD), there is no EA
11901 * length - that's just for level 2 (SMB_INFO_QUERY_EA_SIZE).
11903 * I've seen captures with it and without it; given the mixed
11904 * messages sent by different documents, this is not surprising.
11906 * We display it if it's there; we don't set *trunc if it's
11907 * not.
11909 * Note: in FIND_FIRST2/FIND_NEXT2, the EA length is *not*
11910 * present.
11912 if (*bcp != 0) {
11913 CHECK_BYTE_COUNT_SUBR(4);
11914 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset,
11915 4, ENC_LITTLE_ENDIAN);
11916 COUNT_BYTES_SUBR(4);
11919 *trunc = FALSE;
11920 return offset;
11923 /* this dissects the SMB_INFO_QUERY_EA_SIZE
11924 as described in 4.2.16.1 of the CIFS 1.0 specification
11925 and as described in 2.2.8.3.2 of the MS-CIFS specification
11927 static int
11928 dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11929 int offset, guint16 *bcp, gboolean *trunc)
11931 /* create time */
11932 CHECK_BYTE_COUNT_SUBR(4);
11933 offset = dissect_smb_datetime(tvb, tree, offset,
11934 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11935 FALSE);
11936 *bcp -= 4;
11938 /* access time */
11939 CHECK_BYTE_COUNT_SUBR(4);
11940 offset = dissect_smb_datetime(tvb, tree, offset,
11941 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11942 FALSE);
11943 *bcp -= 4;
11945 /* last write time */
11946 CHECK_BYTE_COUNT_SUBR(4);
11947 offset = dissect_smb_datetime(tvb, tree, offset,
11948 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11949 FALSE);
11950 *bcp -= 4;
11952 /* data size */
11953 CHECK_BYTE_COUNT_SUBR(4);
11954 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11955 COUNT_BYTES_SUBR(4);
11957 /* allocation size */
11958 CHECK_BYTE_COUNT_SUBR(4);
11959 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11960 COUNT_BYTES_SUBR(4);
11962 /* File Attributes */
11963 CHECK_BYTE_COUNT_SUBR(2);
11964 offset = dissect_file_attributes(tvb, tree, offset);
11965 *bcp -= 2;
11967 /* ea length */
11968 CHECK_BYTE_COUNT_SUBR(4);
11969 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11970 COUNT_BYTES_SUBR(4);
11972 *trunc = FALSE;
11973 return offset;
11976 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
11977 as described in 4.2.16.2
11979 static int
11980 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11981 int offset, guint16 *bcp, gboolean *trunc)
11983 guint8 name_len;
11984 guint16 data_len;
11985 /* EA size */
11987 CHECK_BYTE_COUNT_SUBR(4);
11988 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11989 COUNT_BYTES_SUBR(4);
11991 while (*bcp > 0) {
11992 proto_item *item;
11993 proto_tree *subtree;
11994 int start_offset = offset;
11995 guint8 *name;
11997 item = proto_tree_add_text(
11998 tree, tvb, offset, 0, "Extended Attribute");
11999 subtree = proto_item_add_subtree(item, ett_smb_ea);
12001 /* EA flags */
12003 CHECK_BYTE_COUNT_SUBR(1);
12004 proto_tree_add_item(
12005 subtree, hf_smb_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12006 COUNT_BYTES_SUBR(1);
12008 /* EA name length */
12010 name_len = tvb_get_guint8(tvb, offset);
12012 CHECK_BYTE_COUNT_SUBR(1);
12013 proto_tree_add_item(
12014 subtree, hf_smb_ea_name_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12015 COUNT_BYTES_SUBR(1);
12017 /* EA data length */
12019 data_len = tvb_get_letohs(tvb, offset);
12021 CHECK_BYTE_COUNT_SUBR(2);
12022 proto_tree_add_item(
12023 subtree, hf_smb_ea_data_length, tvb, offset, 2, ENC_NA);
12024 COUNT_BYTES_SUBR(2);
12026 /* EA name */
12028 name = tvb_get_string(wmem_packet_scope(), tvb, offset, name_len);
12029 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
12031 CHECK_BYTE_COUNT_SUBR(name_len + 1);
12032 proto_tree_add_item(
12033 subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
12034 ENC_ASCII|ENC_NA);
12035 COUNT_BYTES_SUBR(name_len + 1);
12037 /* EA data */
12039 CHECK_BYTE_COUNT_SUBR(data_len);
12040 proto_tree_add_item(
12041 subtree, hf_smb_ea_data, tvb, offset, data_len, ENC_NA);
12042 COUNT_BYTES_SUBR(data_len);
12044 proto_item_set_len(item, offset - start_offset);
12047 *trunc = FALSE;
12048 return offset;
12051 /* this dissects the SMB_INFO_IS_NAME_VALID
12052 as described in 4.2.16.3
12054 static int
12055 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12056 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12058 int fn_len;
12059 const char *fn;
12061 DISSECTOR_ASSERT(si);
12063 /* file name */
12064 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12065 CHECK_STRING_SUBR(fn);
12066 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12067 fn);
12068 COUNT_BYTES_SUBR(fn_len);
12070 *trunc = FALSE;
12071 return offset;
12074 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
12075 as described in 4.2.16.4
12077 static int
12078 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12079 int offset, guint16 *bcp, gboolean *trunc)
12082 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12083 if (*trunc) {
12084 return offset;
12087 /* File Attributes */
12088 CHECK_BYTE_COUNT_SUBR(4);
12089 offset = dissect_file_ext_attr(tvb, tree, offset);
12090 *bcp -= 4;
12092 *trunc = FALSE;
12093 return offset;
12096 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
12097 as described in 4.2.16.5 of the SNIA CIFS spec
12098 and section 2.2.8.3.7 of the MS-CIFS spec
12101 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12102 int offset, guint16 *bcp, gboolean *trunc)
12104 /* allocation size */
12105 CHECK_BYTE_COUNT_SUBR(8);
12106 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12107 COUNT_BYTES_SUBR(8);
12109 /* end of file */
12110 CHECK_BYTE_COUNT_SUBR(8);
12111 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12112 COUNT_BYTES_SUBR(8);
12114 /* number of links */
12115 CHECK_BYTE_COUNT_SUBR(4);
12116 proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12117 COUNT_BYTES_SUBR(4);
12119 /* delete pending */
12120 CHECK_BYTE_COUNT_SUBR(1);
12121 proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12122 COUNT_BYTES_SUBR(1);
12124 /* is directory */
12125 CHECK_BYTE_COUNT_SUBR(1);
12126 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12127 COUNT_BYTES_SUBR(1);
12129 *trunc = FALSE;
12130 return offset;
12133 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
12136 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12137 int offset, guint16 *bcp, gboolean *trunc)
12139 /* file id */
12140 CHECK_BYTE_COUNT_SUBR(8);
12141 proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12142 COUNT_BYTES_SUBR(8);
12144 *trunc = FALSE;
12145 return offset;
12148 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
12151 dissect_qsfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12152 int offset, guint16 *bcp, gboolean *trunc)
12154 /* file position */
12155 CHECK_BYTE_COUNT_SUBR(8);
12156 proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12157 COUNT_BYTES_SUBR(8);
12159 *trunc = FALSE;
12160 return offset;
12163 /* this dissects the SMB_QUERY_FILE_MODE_INFO
12166 dissect_qsfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12167 int offset, guint16 *bcp, gboolean *trunc)
12169 /* mode */
12170 CHECK_BYTE_COUNT_SUBR(4);
12171 proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12172 COUNT_BYTES_SUBR(4);
12174 *trunc = FALSE;
12175 return offset;
12178 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
12181 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12182 int offset, guint16 *bcp, gboolean *trunc)
12184 /* alignment */
12185 CHECK_BYTE_COUNT_SUBR(4);
12186 proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12187 COUNT_BYTES_SUBR(4);
12189 *trunc = FALSE;
12190 return offset;
12193 /* this dissects the SMB_QUERY_FILE_EA_INFO
12194 as described in 4.2.16.6 of the SNIA CIFS spec
12195 and 2.2.8.3.8 of the MS-CIFS spec
12198 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12199 int offset, guint16 *bcp, gboolean *trunc)
12201 /* ea length */
12202 CHECK_BYTE_COUNT_SUBR(4);
12203 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12204 COUNT_BYTES_SUBR(4);
12206 *trunc = FALSE;
12207 return offset;
12210 /* this dissects the SMB_FILE_ALLOCATION_INFO
12211 as described in 4.2.19.3 in the SNIA CIFS spec
12212 and the SMB_SET_FILE_ALLOCATION_INFO
12213 as described in 2.2.8.4.5 in the MS-CIFS spec for set (MS-CIFS doesn't
12214 say it can be queried)
12217 dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12218 int offset, guint16 *bcp, gboolean *trunc)
12220 /* allocation size */
12221 CHECK_BYTE_COUNT_SUBR(8);
12222 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12223 COUNT_BYTES_SUBR(8);
12225 *trunc = FALSE;
12226 return offset;
12229 /* this dissects the SMB_FILE_ENDOFFILE_INFO
12230 as described in 4.2.19.4 in the SNIA CIFS spec
12231 and the SMB_SET_FILE_END_OF_FILE_INFO
12232 as described in 2.2.8.4.6 in the MS-CIFS spec for set (MS-CIFS doesn't
12233 say it can be queried)
12236 dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12237 int offset, guint16 *bcp, gboolean *trunc)
12239 /* offset of end of file */
12240 CHECK_BYTE_COUNT_SUBR(8);
12241 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12242 COUNT_BYTES_SUBR(8);
12244 *trunc = FALSE;
12245 return offset;
12248 /* this dissects the SMB_QUERY_FILE_NAME_INFO
12249 as described in 4.2.16.7 of the SNIA CIFS spec
12250 and in 2.2.8.3.9 of the MS-CIFS spec
12251 this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
12252 as described in 4.2.16.9 of the SNIA CIFS spec
12253 and 2.2.8.3.11 of the MS-CIFS spec
12254 although the latter two are used to fetch the 8.3 name
12255 rather than the long name
12258 dissect_qfi_SMB_FILE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12259 int offset, guint16 *bcp, gboolean *trunc, gboolean unicode)
12261 int fn_len;
12262 const char *fn;
12264 /* file name len */
12265 CHECK_BYTE_COUNT_SUBR(4);
12266 proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12267 COUNT_BYTES_SUBR(4);
12269 /* file name */
12270 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, bcp);
12271 CHECK_STRING_SUBR(fn);
12272 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12273 fn);
12274 COUNT_BYTES_SUBR(fn_len);
12276 *trunc = FALSE;
12277 return offset;
12280 /* this dissects the SMB_QUERY_FILE_ALL_INFO
12281 as described in 2.2.8.3.8 of the MS-CIFS spec
12282 but not as described in 4.2.16.8 since SNIA spec is wrong
12284 static int
12285 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12286 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12288 guint32 fn_len;
12289 const char *fn;
12291 DISSECTOR_ASSERT(si);
12293 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12294 if (*trunc) {
12295 return offset;
12298 /* File Attributes */
12299 CHECK_BYTE_COUNT_SUBR(4);
12300 offset = dissect_file_ext_attr(tvb, tree, offset);
12301 *bcp -= 4;
12303 /* 4 pad bytes */
12304 offset += 4;
12305 *bcp -= 4;
12307 /* allocation size */
12308 CHECK_BYTE_COUNT_SUBR(8);
12309 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12310 COUNT_BYTES_SUBR(8);
12312 /* end of file */
12313 CHECK_BYTE_COUNT_SUBR(8);
12314 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12315 COUNT_BYTES_SUBR(8);
12317 /* number of links */
12318 CHECK_BYTE_COUNT_SUBR(4);
12319 proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12320 COUNT_BYTES_SUBR(4);
12322 /* delete pending */
12323 CHECK_BYTE_COUNT_SUBR(1);
12324 proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12325 COUNT_BYTES_SUBR(1);
12327 /* is directory */
12328 CHECK_BYTE_COUNT_SUBR(1);
12329 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12330 COUNT_BYTES_SUBR(1);
12332 /* 2 pad bytes */
12333 offset += 2;
12334 *bcp -= 2;
12336 /* ea length */
12337 CHECK_BYTE_COUNT_SUBR(4);
12338 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12339 COUNT_BYTES_SUBR(4);
12341 /* file name len */
12342 CHECK_BYTE_COUNT_SUBR(4);
12343 fn_len = (guint32)tvb_get_letohl(tvb, offset);
12344 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12345 COUNT_BYTES_SUBR(4);
12348 /* file name */
12349 CHECK_BYTE_COUNT_SUBR(fn_len);
12350 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
12351 if (fn != NULL) {
12352 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12353 fn);
12354 COUNT_BYTES_SUBR(fn_len);
12358 if (*trunc)
12359 return offset;
12361 return offset;
12364 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
12365 as described in 4.2.16.10 of the SNIA CIFS spec
12366 and 2.2.8.3.12 of the MS-CIFS spec
12369 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
12370 int offset, guint16 *bcp, gboolean *trunc, int unicode)
12372 proto_item *item;
12373 proto_tree *tree;
12374 int old_offset;
12375 guint32 neo;
12376 int fn_len;
12377 const char *fn;
12378 int padcnt;
12381 for (;;) {
12382 old_offset = offset;
12384 /* next entry offset */
12385 CHECK_BYTE_COUNT_SUBR(4);
12386 if (parent_tree) {
12387 tvb_ensure_bytes_exist(tvb, offset, *bcp);
12388 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
12389 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12390 } else {
12391 item = NULL;
12392 tree = NULL;
12395 neo = tvb_get_letohl(tvb, offset);
12396 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12397 COUNT_BYTES_SUBR(4);
12399 /* stream name len */
12400 CHECK_BYTE_COUNT_SUBR(4);
12401 fn_len = tvb_get_letohl(tvb, offset);
12402 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
12403 COUNT_BYTES_SUBR(4);
12405 /* stream size */
12406 CHECK_BYTE_COUNT_SUBR(8);
12407 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12408 COUNT_BYTES_SUBR(8);
12410 /* allocation size */
12411 CHECK_BYTE_COUNT_SUBR(8);
12412 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12413 COUNT_BYTES_SUBR(8);
12415 /* stream name */
12416 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
12417 CHECK_STRING_SUBR(fn);
12418 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
12419 fn);
12420 COUNT_BYTES_SUBR(fn_len);
12422 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
12423 proto_item_set_len(item, offset-old_offset);
12425 if (neo == 0)
12426 break; /* no more structures */
12428 /* skip to next structure */
12429 padcnt = (old_offset + neo) - offset;
12430 if (padcnt < 0) {
12432 * XXX - this is bogus; flag it?
12434 padcnt = 0;
12436 if (padcnt != 0) {
12437 CHECK_BYTE_COUNT_SUBR(padcnt);
12438 COUNT_BYTES_SUBR(padcnt);
12442 *trunc = FALSE;
12443 return offset;
12446 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
12447 as described in 4.2.16.11 of the SNIA CIFS spec
12448 and 2.2.8.3.13 of the MS-CIFS spec
12451 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12452 int offset, guint16 *bcp, gboolean *trunc)
12454 /* compressed file size */
12455 CHECK_BYTE_COUNT_SUBR(8);
12456 proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12457 COUNT_BYTES_SUBR(8);
12459 /* compression format */
12460 CHECK_BYTE_COUNT_SUBR(2);
12461 proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12462 COUNT_BYTES_SUBR(2);
12464 /* compression unit shift */
12465 CHECK_BYTE_COUNT_SUBR(1);
12466 proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, ENC_LITTLE_ENDIAN);
12467 COUNT_BYTES_SUBR(1);
12469 /* compression chunk shift */
12470 CHECK_BYTE_COUNT_SUBR(1);
12471 proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12472 COUNT_BYTES_SUBR(1);
12474 /* compression cluster shift */
12475 CHECK_BYTE_COUNT_SUBR(1);
12476 proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12477 COUNT_BYTES_SUBR(1);
12479 /* 3 reserved bytes */
12480 CHECK_BYTE_COUNT_SUBR(3);
12481 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
12482 COUNT_BYTES_SUBR(3);
12484 *trunc = FALSE;
12485 return offset;
12488 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
12490 static const value_string unix_file_type_vals[] = {
12491 { 0, "File" },
12492 { 1, "Directory" },
12493 { 2, "Symbolic link" },
12494 { 3, "Character device" },
12495 { 4, "Block device" },
12496 { 5, "FIFO" },
12497 { 6, "Socket" },
12498 { 0, NULL }
12501 static int
12502 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12503 int offset, guint16 *bcp, gboolean *trunc)
12505 /* End of file (file size) */
12506 CHECK_BYTE_COUNT_SUBR(8);
12507 proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12508 COUNT_BYTES_SUBR(8);
12510 /* Number of bytes */
12511 CHECK_BYTE_COUNT_SUBR(8);
12512 proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12513 COUNT_BYTES_SUBR(8);
12515 /* Last status change */
12516 CHECK_BYTE_COUNT_SUBR(8);
12517 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12518 *bcp -= 8; /* dissect_nt_64bit_time() increments offset */
12520 /* Last access time */
12521 CHECK_BYTE_COUNT_SUBR(8);
12522 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12523 *bcp -= 8;
12525 /* Last modification time */
12526 CHECK_BYTE_COUNT_SUBR(8);
12527 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12528 *bcp -= 8;
12530 /* File owner uid */
12531 CHECK_BYTE_COUNT_SUBR(8);
12532 proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12533 COUNT_BYTES_SUBR(8);
12535 /* File group gid */
12536 CHECK_BYTE_COUNT_SUBR(8);
12537 proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12538 COUNT_BYTES_SUBR(8);
12540 /* File type */
12541 CHECK_BYTE_COUNT_SUBR(4);
12542 proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12543 COUNT_BYTES_SUBR(4);
12545 /* Major device number */
12546 CHECK_BYTE_COUNT_SUBR(8);
12547 proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12548 COUNT_BYTES_SUBR(8);
12550 /* Minor device number */
12551 CHECK_BYTE_COUNT_SUBR(8);
12552 proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12553 COUNT_BYTES_SUBR(8);
12555 /* Unique id */
12556 CHECK_BYTE_COUNT_SUBR(8);
12557 proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12558 COUNT_BYTES_SUBR(8);
12560 /* Permissions */
12561 CHECK_BYTE_COUNT_SUBR(8);
12562 proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12563 COUNT_BYTES_SUBR(8);
12565 /* Nlinks */
12566 CHECK_BYTE_COUNT_SUBR(8);
12567 proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12568 COUNT_BYTES_SUBR(8);
12570 /* Sometimes there is one extra byte in the data field which I
12571 guess could be padding, but we are only using 4 or 8 byte
12572 data types so this is a bit confusing. -tpot */
12574 *trunc = FALSE;
12575 return offset;
12578 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
12580 static int
12581 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12582 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12584 const char *fn;
12585 int fn_len = 0;
12587 DISSECTOR_ASSERT(si);
12589 /* Link destination */
12591 fn = get_unicode_or_ascii_string(
12592 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12594 CHECK_STRING_SUBR(fn);
12595 proto_tree_add_string(
12596 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
12597 COUNT_BYTES_SUBR(fn_len);
12599 *trunc = FALSE;
12600 return offset;
12603 /* unix ACL
12605 static int
12606 dissect_qspi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12607 int offset, guint16 *bcp, gboolean *trunc)
12609 guint16 num_file_aces;
12610 static const int *perm_fields[] = {
12611 &hf_smb_posix_ace_perm_read,
12612 &hf_smb_posix_ace_perm_write,
12613 &hf_smb_posix_ace_perm_execute,
12614 NULL
12617 /* version */
12618 CHECK_BYTE_COUNT_SUBR(2);
12619 proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12620 COUNT_BYTES_SUBR(2);
12622 /* num file acls */
12623 CHECK_BYTE_COUNT_SUBR(2);
12624 num_file_aces = tvb_get_letohs(tvb, offset);
12625 proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12626 COUNT_BYTES_SUBR(2);
12628 /* num default acls */
12629 CHECK_BYTE_COUNT_SUBR(2);
12630 proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12631 COUNT_BYTES_SUBR(2);
12633 while(num_file_aces--) {
12634 proto_item *it;
12635 proto_tree *tr;
12636 int old_offset = offset;
12637 guint8 ace_type;
12639 it = proto_tree_add_text(tree, tvb, offset, 0, "ACE");
12640 tr = proto_item_add_subtree(it, ett_smb_posix_ace);
12642 /* ace type */
12643 CHECK_BYTE_COUNT_SUBR(1);
12644 ace_type = tvb_get_guint8(tvb, offset);
12645 proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12646 COUNT_BYTES_SUBR(1);
12648 CHECK_BYTE_COUNT_SUBR(1);
12649 proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, ENC_BIG_ENDIAN);
12650 COUNT_BYTES_SUBR(1);
12652 switch(ace_type) {
12653 case POSIX_ACE_TYPE_USER_OBJ:
12654 CHECK_BYTE_COUNT_SUBR(4);
12655 proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12656 COUNT_BYTES_SUBR(4);
12658 CHECK_BYTE_COUNT_SUBR(4);
12659 /* 4 reserved bytes */
12660 COUNT_BYTES_SUBR(4);
12661 break;
12662 case POSIX_ACE_TYPE_GROUP_OBJ:
12663 CHECK_BYTE_COUNT_SUBR(4);
12664 proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12665 COUNT_BYTES_SUBR(4);
12667 CHECK_BYTE_COUNT_SUBR(4);
12668 /* 4 reserved bytes */
12669 COUNT_BYTES_SUBR(4);
12670 break;
12672 case POSIX_ACE_TYPE_MASK:
12673 case POSIX_ACE_TYPE_OTHER:
12674 CHECK_BYTE_COUNT_SUBR(8);
12675 /* 8 reserved bytes */
12676 COUNT_BYTES_SUBR(8);
12677 break;
12679 case POSIX_ACE_TYPE_USER:
12680 CHECK_BYTE_COUNT_SUBR(4);
12681 proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12682 COUNT_BYTES_SUBR(4);
12684 CHECK_BYTE_COUNT_SUBR(4);
12685 /* 4 reserved bytes */
12686 COUNT_BYTES_SUBR(4);
12687 break;
12689 case POSIX_ACE_TYPE_GROUP:
12690 CHECK_BYTE_COUNT_SUBR(4);
12691 proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12692 COUNT_BYTES_SUBR(4);
12694 CHECK_BYTE_COUNT_SUBR(4);
12695 /* 4 reserved bytes */
12696 COUNT_BYTES_SUBR(4);
12697 break;
12698 default:
12699 proto_tree_add_text(tr, tvb, offset, 0, "Unknown posix ace type");
12700 CHECK_BYTE_COUNT_SUBR(8);
12701 /* skip 8 bytes */
12702 COUNT_BYTES_SUBR(8);
12705 proto_item_set_len(it, offset-old_offset);
12708 *trunc = FALSE;
12709 return offset;
12712 static int
12713 dissect_qspi_unix_xattr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12714 int offset, guint16 *bcp _U_, gboolean *trunc)
12716 proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12718 *trunc = FALSE;
12719 return offset;
12722 static int
12723 dissect_qspi_unix_attr_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12724 int offset, guint16 *bcp _U_, gboolean *trunc)
12726 proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12728 *trunc = FALSE;
12729 return offset;
12732 static int
12733 dissect_qpi_unix_permissions(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12734 int offset, guint16 *bcp _U_, gboolean *trunc)
12736 proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12738 *trunc = FALSE;
12739 return offset;
12742 static int
12743 dissect_qspi_unix_lock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12744 int offset, guint16 *bcp _U_, gboolean *trunc)
12746 proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12748 *trunc = FALSE;
12749 return offset;
12752 static int
12753 dissect_qspi_unix_open(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12754 int offset, guint16 *bcp _U_, gboolean *trunc)
12756 proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12758 *trunc = FALSE;
12759 return offset;
12762 static int
12763 dissect_qspi_unix_unlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12764 int offset, guint16 *bcp _U_, gboolean *trunc)
12766 proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12768 *trunc = FALSE;
12769 return offset;
12772 /* SMB_FIND_FILE_UNIX_INFO2 */
12774 #if 0
12775 static const true_false_string tfs_i2f_secure_delete = {
12776 "File should be erased such that the data is not recoverable",
12777 "File need not be erased such that the data is not recoverable"
12779 static const true_false_string tfs_i2f_enable_undelete = {
12780 "File should opt-in to a server-specific deletion recovery scheme",
12781 "File should not opt-in to a server-specific deletion recovery scheme"
12783 static const true_false_string tfs_i2f_synchronous = {
12784 "I/O to this file should be performed synchronously",
12785 "I/O to this file need not be performed synchronously"
12787 static const true_false_string tfs_i2f_immutable = {
12788 "NO changes can be made to this file",
12789 "Changes can be made to this file if permissions allow it"
12791 static const true_false_string tfs_i2f_append_only = {
12792 "Only appends can be made to this file",
12793 "Writes can be made atop existing data in this file"
12795 static const true_false_string tfs_i2f_do_not_backup = {
12796 "Backup programs should ignore this file",
12797 "Backup programs should not ignore this file"
12799 static const true_false_string tfs_i2f_no_update_atime = {
12800 "The server is not required to update the last access time on this file",
12801 "The server is required to update the last access time on this file"
12803 static const true_false_string tfs_i2f_hidden = {
12804 "User interface programs may ignore this file",
12805 "User interface programs should not ignore this file based solely on this flag"
12807 #endif
12809 static int
12810 dissect_unix_info2_file_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int hf)
12812 guint32 flags;
12813 proto_item *item = NULL;
12814 proto_tree *tree = NULL;
12816 flags = tvb_get_letohl(tvb, offset);
12818 if (parent_tree) {
12819 item = proto_tree_add_uint(parent_tree, hf, tvb, offset, 4,
12820 flags);
12821 tree = proto_item_add_subtree(item, ett_smb_info2_file_flags);
12824 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_secure_delete,
12825 tvb, offset, 4, flags);
12826 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_enable_undelete,
12827 tvb, offset, 4, flags);
12828 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_synchronous,
12829 tvb, offset, 4, flags);
12830 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_immutable,
12831 tvb, offset, 4, flags);
12832 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_append_only,
12833 tvb, offset, 4, flags);
12834 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_do_not_backup,
12835 tvb, offset, 4, flags);
12836 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_no_update_atime,
12837 tvb, offset, 4, flags);
12838 proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_hidden,
12839 tvb, offset, 4, flags);
12841 offset += 4;
12843 return offset;
12846 static int
12847 dissect_qspi_unix_info2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12848 int offset, guint16 *bcp, gboolean *trunc)
12850 /* End of file (file size) */
12851 CHECK_BYTE_COUNT_SUBR(8);
12852 proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12853 COUNT_BYTES_SUBR(8);
12855 /* Number of bytes (or blocks? The SNIA spec for UNIX basic
12856 info says "bytes", the Samba page for this says "blocks") */
12857 CHECK_BYTE_COUNT_SUBR(8);
12858 proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12859 COUNT_BYTES_SUBR(8);
12861 /* Last status change */
12862 CHECK_BYTE_COUNT_SUBR(8);
12863 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12864 *bcp -= 8;
12866 /* Last access time */
12867 CHECK_BYTE_COUNT_SUBR(8);
12868 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12869 *bcp -= 8;
12871 /* Last modification time */
12872 CHECK_BYTE_COUNT_SUBR(8);
12873 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12874 *bcp -= 8;
12876 /* File owner uid */
12877 CHECK_BYTE_COUNT_SUBR(8);
12878 proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12879 COUNT_BYTES_SUBR(8);
12881 /* File group gid */
12882 CHECK_BYTE_COUNT_SUBR(8);
12883 proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12884 COUNT_BYTES_SUBR(8);
12886 /* File type */
12887 CHECK_BYTE_COUNT_SUBR(4);
12888 proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12889 COUNT_BYTES_SUBR(4);
12891 /* Major device number */
12892 CHECK_BYTE_COUNT_SUBR(8);
12893 proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12894 COUNT_BYTES_SUBR(8);
12896 /* Minor device number */
12897 CHECK_BYTE_COUNT_SUBR(8);
12898 proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12899 COUNT_BYTES_SUBR(8);
12901 /* Unique id */
12902 CHECK_BYTE_COUNT_SUBR(8);
12903 proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12904 COUNT_BYTES_SUBR(8);
12906 /* Permissions */
12907 CHECK_BYTE_COUNT_SUBR(8);
12908 proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12909 COUNT_BYTES_SUBR(8);
12911 /* Nlinks */
12912 CHECK_BYTE_COUNT_SUBR(8);
12913 proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12914 COUNT_BYTES_SUBR(8);
12916 /* Creation time */
12917 CHECK_BYTE_COUNT_SUBR(8);
12918 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_creation_time);
12919 *bcp -= 8;
12921 /* File flags */
12922 CHECK_BYTE_COUNT_SUBR(4);
12923 offset = dissect_unix_info2_file_flags(tvb, tree, offset, hf_smb_unix_info2_file_flags);
12924 *bcp -= 4;
12926 /* File flags mask */
12927 CHECK_BYTE_COUNT_SUBR(4);
12928 offset = dissect_unix_info2_file_flags(tvb, tree, offset, hf_smb_unix_info2_file_flags_mask);
12929 *bcp -= 4;
12931 *trunc = FALSE;
12932 return offset;
12935 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
12938 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
12939 packet_info *pinfo, proto_tree *tree,
12940 int offset, guint16 *bcp, gboolean *trunc)
12943 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12944 if (*trunc) {
12945 return offset;
12948 /* allocation size */
12949 CHECK_BYTE_COUNT_SUBR(8);
12950 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12951 COUNT_BYTES_SUBR(8);
12953 /* end of file */
12954 CHECK_BYTE_COUNT_SUBR(8);
12955 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12956 COUNT_BYTES_SUBR(8);
12958 /* File Attributes */
12959 CHECK_BYTE_COUNT_SUBR(4);
12960 offset = dissect_file_ext_attr(tvb, tree, offset);
12961 *bcp -= 4;
12963 /* 4 reserved bytes */
12964 CHECK_BYTE_COUNT_SUBR(4);
12965 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12966 COUNT_BYTES_SUBR(4);
12968 *trunc = FALSE;
12969 return offset;
12972 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
12975 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
12976 packet_info *pinfo _U_, proto_tree *tree,
12977 int offset, guint16 *bcp, gboolean *trunc)
12979 /* attribute */
12980 CHECK_BYTE_COUNT_SUBR(4);
12981 proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12982 COUNT_BYTES_SUBR(4);
12984 /* reparse tag */
12985 CHECK_BYTE_COUNT_SUBR(4);
12986 proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12987 COUNT_BYTES_SUBR(4);
12989 *trunc = FALSE;
12990 return offset;
12993 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
12994 as described in 4.2.19.2
12996 static int
12997 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12998 int offset, guint16 *bcp, gboolean *trunc)
13000 /* marked for deletion? */
13001 CHECK_BYTE_COUNT_SUBR(1);
13002 proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13003 COUNT_BYTES_SUBR(1);
13005 *trunc = FALSE;
13006 return offset;
13009 /* Set File Rename Info */
13011 static const true_false_string tfs_smb_replace = {
13012 "Remove target file if it exists",
13013 "Do NOT remove target file if it exists",
13016 static int
13017 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13018 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13020 const char *fn;
13021 guint32 target_name_len;
13022 int fn_len;
13024 DISSECTOR_ASSERT(si);
13026 /* Replace flag */
13027 CHECK_BYTE_COUNT_SUBR(4);
13028 proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13029 COUNT_BYTES_SUBR(4);
13031 /* Root directory handle */
13032 CHECK_BYTE_COUNT_SUBR(4);
13033 proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13034 COUNT_BYTES_SUBR(4);
13036 /* Target name length */
13037 CHECK_BYTE_COUNT_SUBR(4);
13038 target_name_len = tvb_get_letohl(tvb, offset);
13039 proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
13040 COUNT_BYTES_SUBR(4);
13042 /* Target name */
13043 fn_len = target_name_len;
13044 fn = get_unicode_or_ascii_string(
13045 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13047 CHECK_STRING_SUBR(fn);
13048 proto_tree_add_string(
13049 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
13050 COUNT_BYTES_SUBR(fn_len);
13052 *trunc = FALSE;
13053 return offset;
13056 static int
13057 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13058 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13060 #if 0
13061 const char *fn;
13062 guint32 target_name_len;*/
13063 int fn_len;
13064 #endif
13066 DISSECTOR_ASSERT(si);
13068 /* Disposition flags */
13069 CHECK_BYTE_COUNT_SUBR(1);
13070 proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13071 COUNT_BYTES_SUBR(1);
13073 *trunc = FALSE;
13074 return offset;
13078 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13079 int offset, guint16 *bcp, gboolean *trunc)
13081 /* pipe info flag */
13082 CHECK_BYTE_COUNT_SUBR(1);
13083 proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13084 COUNT_BYTES_SUBR(1);
13086 *trunc = FALSE;
13087 return offset;
13090 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
13091 TRANS2_QUERY_FILE_INFORMATION*/
13092 static int
13093 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13094 proto_item *item, int offset, guint16 *bcp, smb_info_t *si)
13096 gboolean trunc = FALSE;
13098 if (!*bcp) {
13099 return offset;
13102 DISSECTOR_ASSERT(si);
13104 switch(si->info_level) {
13105 case 1: /*Info Standard*/
13106 offset = dissect_qsfi_SMB_INFO_STANDARD(tvb, pinfo, tree, offset, bcp,
13107 &trunc);
13108 break;
13110 case 2: /*Info Query EA Size*/
13111 offset = dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvb, pinfo, tree, offset, bcp,
13112 &trunc);
13113 break;
13114 case 3: /*Info Query EAs From List*/
13115 case 4: /*Info Query All EAs*/
13116 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13117 &trunc);
13118 break;
13119 case 6: /*Info Is Name Valid*/
13120 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
13121 &trunc, si);
13122 break;
13123 case 0x0101: /*Query File Basic Info*/
13124 case 1004: /* SMB_FILE_BASIC_INFORMATION */
13125 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
13126 &trunc);
13127 break;
13128 case 0x0102: /*Query File Standard Info*/
13129 case 1005: /* SMB_FILE_STANDARD_INFORMATION */
13130 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
13131 &trunc);
13132 break;
13133 case 1006: /* SMB_FILE_INTERNAL_INFORMATION */
13134 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
13135 &trunc);
13136 break;
13137 case 0x0103: /*Query File EA Info*/
13138 case 1007: /* SMB_FILE_EA_INFORMATION */
13139 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
13140 &trunc);
13141 break;
13142 case 0x0104: /*Query File Name Info*/
13143 case 1009: /* SMB_FILE_NAME_INFORMATION */
13144 offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
13145 &trunc, si->unicode);
13146 break;
13147 case 1014: /* SMB_FILE_POSITION_INFORMATION */
13148 offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
13149 &trunc);
13150 break;
13151 case 1016: /* SMB_FILE_MODE_INFORMATION */
13152 offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
13153 &trunc);
13154 break;
13155 case 1017: /* SMB_FILE_ALIGNMENT_INFORMATION */
13156 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
13157 &trunc);
13158 break;
13159 case 0x0107: /*Query File All Info*/
13160 case 1018: /* SMB_FILE_ALL_INFORMATION */
13161 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
13162 &trunc, si);
13163 break;
13164 case 1019: /* SMB_FILE_ALLOCATION_INFORMATION */
13165 offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
13166 &trunc);
13167 break;
13168 case 1020: /* SMB_FILE_ENDOFFILE_INFORMATION */
13169 offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
13170 &trunc);
13171 break;
13172 case 0x0108: /*Query File Alt File Info*/
13173 case 1021: /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
13174 offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
13175 &trunc, si->unicode);
13176 break;
13177 case 1022: /* SMB_FILE_STREAM_INFORMATION */
13178 si->unicode = TRUE;
13179 /* FALLTHRU */
13180 case 0x0109: /*Query File Stream Info*/
13181 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
13182 &trunc, si->unicode);
13183 break;
13184 case 0x010b: /*Query File Compression Info*/
13185 case 1028: /* SMB_FILE_COMPRESSION_INFORMATION */
13186 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
13187 &trunc);
13188 break;
13189 case 1034: /* SMB_FILE_NETWORK_OPEN_INFO */
13190 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
13191 break;
13192 case 1035: /* SMB_FILE_ATTRIBUTE_TAG_INFO */
13193 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
13194 break;
13195 case 0x0200: /* Query File Unix Basic*/
13196 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
13197 &trunc);
13198 break;
13199 case 0x0201: /* Query File Unix Link*/
13200 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13201 &trunc, si);
13202 break;
13203 case 0x0202: /* Query File Unix HardLink*/
13204 /* XXX add this from the SNIA doc */
13205 break;
13206 case 0x0204: /* Query File Unix ACL*/
13207 offset = dissect_qspi_unix_acl(tvb, pinfo, tree, offset, bcp,
13208 &trunc);
13209 break;
13210 case 0x0205: /* Query File Unix XATTR*/
13211 offset = dissect_qspi_unix_xattr(tvb, pinfo, tree, offset, bcp,
13212 &trunc);
13213 break;
13214 case 0x0206: /* Query File Unix Attr Flags*/
13215 offset = dissect_qspi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
13216 &trunc);
13217 break;
13218 case 0x0207: /* Query File Unix Permissions*/
13219 offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
13220 &trunc);
13221 break;
13222 case 0x0208: /* Query File Unix Lock*/
13223 offset = dissect_qspi_unix_lock(tvb, pinfo, tree, offset, bcp,
13224 &trunc);
13225 break;
13226 case 0x020b: /* Query File Unix Info2*/
13227 offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp,
13228 &trunc);
13229 break;
13231 default:
13232 proto_tree_add_text(tree, tvb, offset, *bcp,
13233 "Information level unknown");
13234 offset += *bcp;
13235 *bcp = 0;
13236 trunc = FALSE;
13237 break;
13240 if (trunc) {
13241 expert_add_info(pinfo, item, &ei_smb_mal_information_level);
13243 return offset;
13246 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
13247 TRANS2_SET_FILE_INFORMATION*/
13248 static int
13249 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13250 proto_item *item, int offset, guint16 *bcp, smb_info_t *si)
13252 gboolean trunc;
13254 if (!*bcp) {
13255 return offset;
13258 DISSECTOR_ASSERT(si);
13260 switch(si->info_level) {
13261 case 1: /*Info Standard*/
13262 offset = dissect_qsfi_SMB_INFO_STANDARD(tvb, pinfo, tree, offset, bcp,
13263 &trunc);
13264 break;
13265 case 2: /*Info Set EAs*/
13266 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13267 &trunc);
13268 break;
13269 case 4: /*Info Query All EAs - not in [MS-CIFS]*/
13270 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13271 &trunc);
13272 break;
13273 case 0x0101: /*Set File Basic Info*/
13274 case 1004: /* SMB_FILE_BASIC_INFORMATION */
13275 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
13276 &trunc);
13277 break;
13278 case 0x0102: /*Set File Disposition Info*/
13279 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
13280 &trunc);
13281 break;
13282 case 0x0103: /*Set File Allocation Info*/
13283 case 1019: /* Set File Allocation Information */
13284 offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
13285 &trunc);
13286 break;
13287 case 0x0104: /*Set End Of File Info*/
13288 case 1020: /* SMB_FILE_ENDOFFILE_INFORMATION */
13289 offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
13290 &trunc);
13291 break;
13292 case 0x0200: /*Set File Unix Basic. Same as query. */
13293 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
13294 &trunc);
13295 break;
13296 case 0x0201: /*Set File Unix Link. Same as query. */
13297 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13298 &trunc, si);
13299 break;
13300 case 0x0202: /*Set File Unix HardLink. Same as link query. */
13301 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13302 &trunc, si);
13303 break;
13304 case 0x0204: /* Set File Unix ACL*/
13305 offset = dissect_qspi_unix_acl(tvb, pinfo, tree, offset, bcp,
13306 &trunc);
13307 break;
13308 case 0x0205: /* Set File Unix XATTR*/
13309 offset = dissect_qspi_unix_xattr(tvb, pinfo, tree, offset, bcp,
13310 &trunc);
13311 break;
13312 case 0x0206: /* Set File Unix Attr Flags*/
13313 offset = dissect_qspi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
13314 &trunc);
13315 break;
13316 case 0x0208: /* Set File Unix Lock*/
13317 offset = dissect_qspi_unix_lock(tvb, pinfo, tree, offset, bcp,
13318 &trunc);
13319 break;
13320 case 0x0209: /* Set File Unix Open*/
13321 offset = dissect_qspi_unix_open(tvb, pinfo, tree, offset, bcp,
13322 &trunc);
13323 break;
13324 case 0x020a: /* Set File Unix Unlink*/
13325 offset = dissect_qspi_unix_unlink(tvb, pinfo, tree, offset, bcp,
13326 &trunc);
13327 break;
13328 case 0x020b: /* Set File Unix Info2*/
13329 offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp,
13330 &trunc);
13331 break;
13332 case 1010: /* Set File Rename */
13333 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
13334 &trunc, si);
13335 break;
13336 case 1013: /* Set Disposition Information */
13337 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
13338 &trunc, si);
13339 break;
13340 case 1014: /* SMB_FILE_POSITION_INFORMATION */
13341 offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
13342 &trunc);
13343 break;
13344 case 1016: /* SMB_FILE_MODE_INFORMATION */
13345 offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
13346 &trunc);
13347 break;
13348 case 1023: /* Set Pipe Info */
13349 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
13350 &trunc);
13351 break;
13352 case 1025:
13353 case 1029:
13354 case 1032:
13355 case 1039:
13356 case 1040:
13357 /* XXX: TODO, extra levels discovered by tridge */
13358 proto_tree_add_text(tree, tvb, offset, *bcp,
13359 "Information level not understood");
13360 offset += *bcp;
13361 *bcp = 0;
13362 trunc = FALSE;
13363 break;
13365 default:
13366 proto_tree_add_text(tree, tvb, offset, *bcp,
13367 "Information level unknown");
13368 offset += *bcp;
13369 *bcp = 0;
13370 trunc = FALSE;
13371 break;
13374 if (trunc) {
13375 expert_add_info(pinfo, item, &ei_smb_mal_information_level);
13377 return offset;
13381 static const true_false_string tfs_quota_flags_deny_disk = {
13382 "DENY DISK SPACE for users exceeding quota limit",
13383 "Do NOT deny disk space for users exceeding quota limit"
13385 static const true_false_string tfs_quota_flags_log_limit = {
13386 "LOG EVENT when a user exceeds their QUOTA LIMIT",
13387 "Do NOT log event when a user exceeds their quota limit"
13389 static const true_false_string tfs_quota_flags_log_warning = {
13390 "LOG EVENT when a user exceeds their WARNING LEVEL",
13391 "Do NOT log event when a user exceeds their warning level"
13393 static const true_false_string tfs_quota_flags_enabled = {
13394 "Quotas are ENABLED of this fs",
13395 "Quotas are NOT enabled on this fs"
13397 static void
13398 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13400 guint8 mask;
13401 proto_item *item;
13402 proto_tree *tree;
13404 mask = tvb_get_guint8(tvb, offset);
13406 if (parent_tree) {
13407 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
13408 "Quota Flags: 0x%02x %s", mask,
13409 mask?"Enabled":"Disabled");
13410 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
13412 proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
13413 tvb, offset, 1, mask);
13414 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
13415 tvb, offset, 1, mask);
13416 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
13417 tvb, offset, 1, mask);
13419 if (mask && (!(mask&0x01))) {
13420 proto_item *hidden_item;
13421 hidden_item = proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
13422 tvb, offset, 1, 0x01);
13423 PROTO_ITEM_SET_HIDDEN(hidden_item);
13424 } else {
13425 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
13426 tvb, offset, 1, mask);
13433 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
13435 /* first 24 bytes are unknown */
13436 CHECK_BYTE_COUNT_TRANS_SUBR(24);
13437 proto_tree_add_item(tree, hf_smb_unknown, tvb,
13438 offset, 24, ENC_NA);
13439 COUNT_BYTES_TRANS_SUBR(24);
13441 /* number of bytes for quota warning */
13442 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13443 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13444 COUNT_BYTES_TRANS_SUBR(8);
13446 /* number of bytes for quota limit */
13447 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13448 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13449 COUNT_BYTES_TRANS_SUBR(8);
13451 /* one byte of quota flags */
13452 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13453 dissect_quota_flags(tvb, tree, offset);
13454 COUNT_BYTES_TRANS_SUBR(1);
13456 /* these 7 bytes are unknown */
13457 CHECK_BYTE_COUNT_TRANS_SUBR(7);
13458 proto_tree_add_item(tree, hf_smb_unknown, tvb,
13459 offset, 7, ENC_NA);
13460 COUNT_BYTES_TRANS_SUBR(7);
13462 return offset;
13465 static int
13466 dissect_sfsi_request(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13467 int offset, guint16 *bcp, smb_info_t *si)
13469 if (!*bcp) {
13470 return offset;
13473 DISSECTOR_ASSERT(si);
13475 switch(si->info_level) {
13476 case 0x203: /* REQUEST_TRANSPORT_ENCRYPTION */ {
13477 proto_item *blob_item;
13478 tvbuff_t *blob_tvb;
13479 proto_tree *blob_tree;
13481 /* security blob */
13482 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
13483 tvb, offset,
13484 tvb_length_remaining(tvb,offset),
13485 ENC_NA);
13487 /* As an optimization, because Windows is perverse,
13488 we check to see if NTLMSSP is the first part of the
13489 blob, and if so, call the NTLMSSP dissector,
13490 otherwise we call the GSS-API dissector. This is because
13491 Windows can request RAW NTLMSSP, but will happily handle
13492 a client that wraps NTLMSSP in SPNEGO
13495 blob_tree = proto_item_add_subtree(blob_item,
13496 ett_smb_secblob);
13498 blob_tvb = tvb_new_subset_remaining(tvb, offset);
13500 if (tvb_strneql(blob_tvb, 0, "NTLMSSP", 7) == 0) {
13501 call_dissector(ntlmssp_handle, blob_tvb, pinfo, blob_tree);
13502 } else {
13503 call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
13506 offset += tvb_length_remaining(tvb,offset);
13507 *bcp = 0;
13508 break;
13510 case 1006: /* QUERY_FS_QUOTA_INFO */
13511 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13512 break;
13515 return offset;
13518 static int
13519 dissect_sfsi_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13520 int offset, guint16 *bcp, smb_info_t *si)
13522 if (!*bcp) {
13523 return offset;
13526 DISSECTOR_ASSERT(si);
13528 switch(si->info_level) {
13529 case 0x203: /* REQUEST_TRANSPORT_ENCRYPTION */ {
13530 proto_item *blob_item;
13531 tvbuff_t *blob_tvb;
13532 proto_tree *blob_tree;
13534 /* security blob */
13535 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
13536 tvb, offset,
13537 tvb_length_remaining(tvb,offset),
13538 ENC_NA);
13540 /* As an optimization, because Windows is perverse,
13541 we check to see if NTLMSSP is the first part of the
13542 blob, and if so, call the NTLMSSP dissector,
13543 otherwise we call the GSS-API dissector. This is because
13544 Windows can request RAW NTLMSSP, but will happily handle
13545 a client that wraps NTLMSSP in SPNEGO
13548 blob_tree = proto_item_add_subtree(blob_item,
13549 ett_smb_secblob);
13551 blob_tvb = tvb_new_subset_remaining(tvb, offset);
13553 if (tvb_strneql(blob_tvb, 0, "NTLMSSP", 7) == 0) {
13554 call_dissector(ntlmssp_handle, blob_tvb, pinfo, blob_tree);
13555 } else {
13556 call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
13559 offset += tvb_length_remaining(tvb,offset);
13560 *bcp = 0;
13561 break;
13563 case 1006: /* QUERY_FS_QUOTA_INFO */
13564 /* nothing */
13565 break;
13568 return offset;
13571 static int
13572 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
13573 proto_tree *parent_tree, int offset, int subcmd, guint16 dc, smb_info_t *si)
13575 proto_item *item = NULL;
13576 proto_tree *tree = NULL;
13578 DISSECTOR_ASSERT(si);
13580 if (parent_tree) {
13581 tvb_ensure_bytes_exist(tvb, offset, dc);
13582 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13583 "%s Data",
13584 val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
13585 "Unknown (0x%02x)"));
13586 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13589 switch(subcmd) {
13590 case 0x0000: /*TRANS2_OPEN2*/
13591 /* XXX dont know how to decode FEAList */
13592 break;
13593 case 0x0001: /*TRANS2_FIND_FIRST2*/
13594 /* XXX dont know how to decode FEAList */
13595 break;
13596 case 0x0002: /*TRANS2_FIND_NEXT2*/
13597 /* XXX dont know how to decode FEAList */
13598 break;
13599 case 0x0003: /*TRANS2_QUERY_FS_INFORMATION*/
13600 /* no data field in this request */
13601 break;
13602 case 0x0004: /* TRANS2_SET_FS_INFORMATION */
13603 offset = dissect_sfsi_request(tvb, pinfo, tree, offset, &dc, si);
13604 break;
13605 case 0x0005: /*TRANS2_QUERY_PATH_INFORMATION*/
13606 /* no data field in this request */
13608 * XXX - "Microsoft Networks SMB File Sharing Protocol
13609 * Extensions Version 3.0, Document Version 1.11,
13610 * July 19, 1990" says there may be "Additional
13611 * FileInfoLevel dependent information" here.
13613 * Was that just a cut-and-pasteo?
13614 * TRANS2_SET_PATH_INFORMATION *does* have that information
13615 * here.
13617 break;
13618 case 0x0006: /*TRANS2_SET_PATH_INFORMATION*/
13619 offset = dissect_spi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
13620 break;
13621 case 0x0007: /*TRANS2_QUERY_FILE_INFORMATION*/
13622 /* no data field in this request */
13624 * XXX - "Microsoft Networks SMB File Sharing Protocol
13625 * Extensions Version 3.0, Document Version 1.11,
13626 * July 19, 1990" says there may be "Additional
13627 * FileInfoLevel dependent information" here.
13629 * Was that just a cut-and-pasteo?
13630 * TRANS2_SET_FILE_INFORMATION *does* have that information
13631 * here.
13633 break;
13634 case 0x0008: /*TRANS2_SET_FILE_INFORMATION*/
13635 offset = dissect_spi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
13636 break;
13637 case 0x0009: /*TRANS2_FSCTL*/
13638 /*XXX dont know how to decode this yet */
13641 * XXX - "Microsoft Networks SMB File Sharing Protocol
13642 * Extensions Version 3.0, Document Version 1.11,
13643 * July 19, 1990" says this this contains a
13644 * "File system specific data block". (That means we
13645 * may not be able to dissect it in any case.)
13647 break;
13648 case 0x000a: /*TRANS2_IOCTL2*/
13649 /*XXX dont know how to decode this yet */
13652 * XXX - "Microsoft Networks SMB File Sharing Protocol
13653 * Extensions Version 3.0, Document Version 1.11,
13654 * July 19, 1990" says this this contains a
13655 * "Device/function specific data block". (That
13656 * means we may not be able to dissect it in any case.)
13658 break;
13659 case 0x000b: /*TRANS2_FIND_NOTIFY_FIRST*/
13660 /*XXX dont know how to decode this yet */
13663 * XXX - "Microsoft Networks SMB File Sharing Protocol
13664 * Extensions Version 3.0, Document Version 1.11,
13665 * July 19, 1990" says this this contains "additional
13666 * level dependent match data".
13668 break;
13669 case 0x000c: /*TRANS2_FIND_NOTIFY_NEXT*/
13670 /*XXX dont know how to decode this yet */
13673 * XXX - "Microsoft Networks SMB File Sharing Protocol
13674 * Extensions Version 3.0, Document Version 1.11,
13675 * July 19, 1990" says this this contains "additional
13676 * level dependent monitor information".
13678 break;
13679 case 0x000d: /*TRANS2_CREATE_DIRECTORY*/
13680 /* XXX optional FEAList, unknown what FEAList looks like*/
13681 break;
13682 case 0x000e: /*TRANS2_SESSION_SETUP*/
13683 /*XXX dont know how to decode this yet */
13684 break;
13685 case 0x0010: /*TRANS2_GET_DFS_REFERRAL*/
13686 /* no data field in this request */
13687 break;
13688 case 0x0011: /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13689 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc, si);
13690 break;
13693 /* ooops there were data we didnt know how to process */
13694 if (dc != 0) {
13695 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, ENC_NA);
13696 offset += dc;
13699 return offset;
13703 static void
13704 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
13705 proto_tree *tree)
13707 int i;
13708 int offset;
13709 guint length;
13712 * Show the setup words.
13714 if (s_tvb != NULL) {
13715 length = tvb_reported_length(s_tvb);
13716 for (i = 0, offset = 0; length >= 2;
13717 i++, offset += 2, length -= 2) {
13719 * XXX - add a setup word filterable field?
13721 proto_tree_add_uint_format(tree, hf_smb_trans_data_setup_word, s_tvb, offset, 2,
13722 tvb_get_letohs(s_tvb, offset), "Setup Word %d: 0x%04x", i, tvb_get_letohs(s_tvb, offset));
13727 * Show the parameters, if any.
13729 if (p_tvb != NULL) {
13730 length = tvb_reported_length(p_tvb);
13731 if (length != 0) {
13732 proto_tree_add_item(tree, hf_smb_trans_data_parameters, p_tvb, 0, length, ENC_NA);
13737 * Show the data, if any.
13739 if (d_tvb != NULL) {
13740 length = tvb_reported_length(d_tvb);
13741 if (length != 0) {
13742 proto_tree_add_item(tree, hf_smb_trans_data, d_tvb, 0, length, ENC_NA);
13747 /* This routine handles the following 4 calls
13748 Transaction 0x25
13749 Transaction Secondary 0x26
13750 Transaction2 0x32
13751 Transaction2 Secondary 0x33
13753 static int
13754 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
13756 guint8 wc, sc = 0;
13757 int so = offset;
13758 int sl = 0;
13759 int spo = offset;
13760 int spc = 0;
13761 guint16 od = 0, po = 0, pc = 0, dc = 0, pd, dd = 0;
13762 int subcmd = -1;
13763 guint32 to;
13764 int an_len;
13765 const char *an = NULL;
13766 smb_transact2_info_t *t2i;
13767 smb_transact_info_t *tri;
13768 guint16 bc;
13769 int padcnt;
13770 gboolean dissected_trans;
13772 DISSECTOR_ASSERT(si);
13774 WORD_COUNT;
13776 if (wc == 8) {
13777 /*secondary client request*/
13779 /* total param count, only a 16bit integer here*/
13780 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13781 offset += 2;
13783 /* total data count , only 16bit integer here*/
13784 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13785 offset += 2;
13787 /* param count */
13788 pc = tvb_get_letohs(tvb, offset);
13789 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13790 offset += 2;
13792 /* param offset */
13793 po = tvb_get_letohs(tvb, offset);
13794 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13795 offset += 2;
13797 /* param disp */
13798 pd = tvb_get_letohs(tvb, offset);
13799 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13800 offset += 2;
13802 /* data count */
13803 dc = tvb_get_letohs(tvb, offset);
13804 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13805 offset += 2;
13807 /* data offset */
13808 od = tvb_get_letohs(tvb, offset);
13809 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13810 offset += 2;
13812 /* data disp */
13813 dd = tvb_get_letohs(tvb, offset);
13814 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13815 offset += 2;
13817 if (si->cmd == SMB_COM_TRANSACTION2) {
13818 guint16 fid;
13820 /* fid */
13821 fid = tvb_get_letohs(tvb, offset);
13822 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
13824 offset += 2;
13827 /* There are no setup words. */
13828 so = offset;
13829 sl = 0;
13830 } else {
13831 /* it is not a secondary request */
13833 /* total param count , only a 16 bit integer here*/
13834 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13835 offset += 2;
13837 /* total data count , only 16bit integer here*/
13838 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13839 offset += 2;
13841 /* max param count , only 16bit integer here*/
13842 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13843 offset += 2;
13845 /* max data count, only 16bit integer here*/
13846 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13847 offset += 2;
13849 /* max setup count, only 16bit integer here*/
13850 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13851 offset += 1;
13853 /* reserved byte */
13854 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
13855 offset += 1;
13857 /* transaction flags */
13858 dissect_transaction_flags(tvb, tree, offset);
13859 offset += 2;
13861 /* timeout */
13862 to = tvb_get_letohl(tvb, offset);
13863 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
13864 offset += 4;
13866 /* 2 reserved bytes */
13867 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
13868 offset += 2;
13870 /* param count */
13871 pc = tvb_get_letohs(tvb, offset);
13872 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13873 offset += 2;
13875 /* param offset */
13876 po = tvb_get_letohs(tvb, offset);
13877 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13878 offset += 2;
13880 /* data count */
13881 dc = tvb_get_letohs(tvb, offset);
13882 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13883 offset += 2;
13885 /* data offset */
13886 od = tvb_get_letohs(tvb, offset);
13887 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13888 offset += 2;
13890 /* data displacement is zero here */
13891 dd = 0;
13893 /* setup count */
13894 sc = tvb_get_guint8(tvb, offset);
13895 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13896 offset += 1;
13898 /* reserved byte */
13899 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
13900 offset += 1;
13902 /* this is where the setup bytes, if any start */
13903 so = offset;
13904 sl = sc*2;
13906 /* if there were any setup bytes, decode them */
13907 if (sc) {
13908 switch(si->cmd) {
13910 case SMB_COM_TRANSACTION2:
13911 /* TRANSACTION2 only has one setup word and
13912 that is the subcommand code.
13914 XXX - except for TRANS2_FSCTL
13915 and TRANS2_IOCTL. */
13916 subcmd = tvb_get_letohs(tvb, offset);
13917 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
13918 tvb, offset, 2, subcmd);
13919 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13920 val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
13921 "Unknown (0x%02x)"));
13923 if (!si->unidir) {
13924 if (!pinfo->fd->flags.visited && si->sip) {
13926 * Allocate a new
13927 * smb_transact2_info_t
13928 * structure.
13930 t2i = (smb_transact2_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_transact2_info_t));
13931 t2i->subcmd = subcmd;
13932 t2i->info_level = -1;
13933 t2i->resume_keys = FALSE;
13934 t2i->name = NULL;
13935 si->sip->extra_info = t2i;
13936 si->sip->extra_info_type = SMB_EI_T2I;
13941 * XXX - process TRANS2_FSCTL and
13942 * TRANS2_IOCTL setup words here.
13944 break;
13946 case SMB_COM_TRANSACTION:
13947 /* TRANSACTION setup words processed below */
13948 break;
13951 offset += sl;
13955 BYTE_COUNT;
13957 if (wc != 8) {
13958 /* primary request */
13959 /* name is NULL if transaction2 */
13960 if (si->cmd == SMB_COM_TRANSACTION) {
13961 /* Transaction Name */
13962 an = get_unicode_or_ascii_string(tvb, &offset,
13963 si->unicode, &an_len, FALSE, FALSE, &bc);
13964 if (an == NULL)
13965 goto endofcommand;
13966 tvb_ensure_bytes_exist(tvb, offset, an_len);
13967 proto_tree_add_string(tree, hf_smb_trans_name, tvb,
13968 offset, an_len, an);
13969 COUNT_BYTES(an_len);
13974 * The pipe or mailslot arguments for Transaction start with
13975 * the first setup word (or where the first setup word would
13976 * be if there were any setup words), and run to the current
13977 * offset (which could mean that there aren't any).
13979 spo = so;
13980 spc = offset - spo;
13982 /* parameters */
13983 if (po > offset) {
13984 /* We have some initial padding bytes.
13986 padcnt = po-offset;
13987 if (padcnt > bc)
13988 padcnt = bc;
13989 tvb_ensure_bytes_exist(tvb, offset, padcnt);
13990 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
13991 COUNT_BYTES(padcnt);
13993 if (pc) {
13994 CHECK_BYTE_COUNT(pc);
13995 switch(si->cmd) {
13997 case SMB_COM_TRANSACTION2:
13998 /* TRANSACTION2 parameters*/
13999 offset = dissect_transaction2_request_parameters(tvb,
14000 pinfo, tree, offset, subcmd, pc, si);
14001 bc -= pc;
14002 break;
14004 case SMB_COM_TRANSACTION:
14005 /* TRANSACTION parameters processed below */
14006 COUNT_BYTES(pc);
14007 break;
14011 /* data */
14012 if (od > offset) {
14013 /* We have some initial padding bytes.
14015 padcnt = od-offset;
14016 if (padcnt > bc)
14017 padcnt = bc;
14018 tvb_ensure_bytes_exist(tvb, offset, padcnt);
14019 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
14020 COUNT_BYTES(padcnt);
14022 if (dc) {
14023 CHECK_BYTE_COUNT(dc);
14024 switch(si->cmd) {
14026 case SMB_COM_TRANSACTION2:
14027 /* TRANSACTION2 data*/
14028 offset = dissect_transaction2_request_data(tvb, pinfo,
14029 tree, offset, subcmd, dc, si);
14030 bc -= dc;
14031 break;
14033 case SMB_COM_TRANSACTION:
14034 /* TRANSACTION data processed below */
14035 COUNT_BYTES(dc);
14036 break;
14040 /*TRANSACTION request parameters */
14041 if (si->cmd == SMB_COM_TRANSACTION) {
14042 /*XXX replace this block with a function and use that one
14043 for both requests/responses*/
14044 if (dd == 0) {
14045 tvbuff_t *p_tvb, *d_tvb, *s_tvb;
14046 tvbuff_t *sp_tvb, *pd_tvb;
14048 if (pc > 0) {
14049 if (pc>tvb_length_remaining(tvb, po)) {
14050 p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
14051 } else {
14052 p_tvb = tvb_new_subset(tvb, po, pc, pc);
14054 } else {
14055 p_tvb = NULL;
14057 if (dc > 0) {
14058 if (dc>tvb_length_remaining(tvb, od)) {
14059 d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
14060 } else {
14061 d_tvb = tvb_new_subset(tvb, od, dc, dc);
14063 } else {
14064 d_tvb = NULL;
14066 if (sl) {
14067 if (sl>tvb_length_remaining(tvb, so)) {
14068 s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
14069 } else {
14070 s_tvb = tvb_new_subset(tvb, so, sl, sl);
14072 } else {
14073 s_tvb = NULL;
14076 if (!si->unidir) {
14077 if (!pinfo->fd->flags.visited && si->sip) {
14079 * Allocate a new smb_transact_info_t
14080 * structure.
14082 tri = (smb_transact_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_transact_info_t));
14083 tri->subcmd = -1;
14084 tri->trans_subcmd = -1;
14085 tri->function = -1;
14086 tri->fid = -1;
14087 tri->lanman_cmd = 0;
14088 tri->param_descrip = NULL;
14089 tri->data_descrip = NULL;
14090 tri->aux_data_descrip = NULL;
14091 tri->info_level = -1;
14092 si->sip->extra_info = tri;
14093 si->sip->extra_info_type = SMB_EI_TRI;
14094 } else {
14096 * We already filled the structure
14097 * in; don't bother doing so again.
14099 tri = NULL;
14101 } else {
14103 * This is a unidirectional message, for
14104 * which there will be no reply; don't
14105 * bother allocating an "smb_transact_info_t"
14106 * structure for it.
14108 tri = NULL;
14110 dissected_trans = FALSE;
14111 if (an == NULL)
14112 goto endofcommand;
14113 if (strncmp("\\PIPE\\", an, 6) == 0) {
14114 if (tri != NULL)
14115 tri->subcmd = TRANSACTION_PIPE;
14118 * A tvbuff containing the setup words and
14119 * the pipe path.
14121 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
14124 * A tvbuff containing the parameters and the
14125 * data.
14127 pd_tvb = tvb_new_subset_remaining(tvb, po);
14129 dissected_trans = dissect_pipe_smb(sp_tvb,
14130 s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
14131 top_tree_global, si);
14133 /* In case we did not see the TreeConnect call,
14134 store this TID here as well as a IPC TID
14135 so we know that future Read/Writes to this
14136 TID is (probably) DCERPC.
14138 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
14139 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
14141 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
14142 } else if (strncmp("\\MAILSLOT\\", an, 10) == 0) {
14143 if (tri != NULL)
14144 tri->subcmd = TRANSACTION_MAILSLOT;
14147 * A tvbuff containing the setup words and
14148 * the mailslot path.
14150 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
14151 dissected_trans = dissect_mailslot_smb(sp_tvb,
14152 s_tvb, d_tvb, an+10, pinfo, top_tree_global, si);
14154 if (!dissected_trans)
14155 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14156 } else {
14157 col_append_str(pinfo->cinfo, COL_INFO,
14158 "[transact continuation]");
14162 END_OF_SMB
14164 return offset;
14169 static int
14170 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14171 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14173 int fn_len;
14174 const char *fn;
14175 int old_offset = offset;
14176 proto_item *item = NULL;
14177 proto_tree *tree = NULL;
14178 smb_transact2_info_t *t2i;
14179 gboolean resume_keys = FALSE;
14180 guint32 bytes_needed = 0;
14182 DISSECTOR_ASSERT(si);
14184 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14185 t2i = (smb_transact2_info_t *)si->sip->extra_info;
14186 if (t2i != NULL)
14187 resume_keys = t2i->resume_keys;
14190 if (parent_tree) {
14191 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14192 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14193 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14197 * Figure out of there are enough bytes to display the whole entry.
14198 * This consistes of 22 bytes or 26 bytes if resume_keys, followed
14199 * by a length byte and that many chars.
14201 bytes_needed = 23 + (resume_keys ? 4 : 0);
14202 tvb_ensure_bytes_exist(tvb, offset, bytes_needed);
14204 /* Now, get the length */
14205 fn_len = tvb_get_guint8(tvb, offset + bytes_needed - 1);
14206 tvb_ensure_bytes_exist(tvb, offset, bytes_needed + fn_len);
14208 if (resume_keys) {
14209 /* resume key */
14210 CHECK_BYTE_COUNT_SUBR(4);
14211 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14212 COUNT_BYTES_SUBR(4);
14215 /* create time */
14216 CHECK_BYTE_COUNT_SUBR(4);
14217 offset = dissect_smb_datetime(tvb, tree, offset,
14218 hf_smb_create_time,
14219 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14220 *bcp -= 4;
14222 /* access time */
14223 CHECK_BYTE_COUNT_SUBR(4);
14224 offset = dissect_smb_datetime(tvb, tree, offset,
14225 hf_smb_access_time,
14226 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14227 *bcp -= 4;
14229 /* last write time */
14230 CHECK_BYTE_COUNT_SUBR(4);
14231 offset = dissect_smb_datetime(tvb, tree, offset,
14232 hf_smb_last_write_time,
14233 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14234 *bcp -= 4;
14236 /* data size */
14237 CHECK_BYTE_COUNT_SUBR(4);
14238 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14239 COUNT_BYTES_SUBR(4);
14241 /* allocation size */
14242 CHECK_BYTE_COUNT_SUBR(4);
14243 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14244 COUNT_BYTES_SUBR(4);
14246 /* File Attributes */
14247 CHECK_BYTE_COUNT_SUBR(2);
14248 offset = dissect_file_attributes(tvb, tree, offset);
14249 *bcp -= 2;
14251 /* file name len */
14252 CHECK_BYTE_COUNT_SUBR(1);
14253 fn_len = tvb_get_guint8(tvb, offset);
14254 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14255 COUNT_BYTES_SUBR(1);
14256 if (si->unicode)
14257 fn_len += 2; /* include terminating '\0' */
14258 else
14259 fn_len++; /* include terminating '\0' */
14261 /* file name */
14262 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14263 CHECK_STRING_SUBR(fn);
14264 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14265 fn);
14266 COUNT_BYTES_SUBR(fn_len);
14268 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14269 format_text(fn, strlen(fn)));
14271 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14272 proto_item_set_len(item, offset-old_offset);
14274 *trunc = FALSE;
14275 return offset;
14278 static int
14279 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14280 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14282 int fn_len;
14283 const char *fn;
14284 int old_offset = offset;
14285 proto_item *item = NULL;
14286 proto_tree *tree = NULL;
14287 smb_transact2_info_t *t2i;
14288 gboolean resume_keys = FALSE;
14289 guint32 bytes_needed = 0;
14291 DISSECTOR_ASSERT(si);
14293 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14294 t2i = (smb_transact2_info_t *)si->sip->extra_info;
14295 if (t2i != NULL)
14296 resume_keys = t2i->resume_keys;
14299 if (parent_tree) {
14300 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14301 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14302 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14306 * Figure out of there are enough bytes to display the whole entry.
14307 * This consistes of 26 bytes or 30 bytes if resume_keys, followed
14308 * by a length byte and that many chars.
14310 bytes_needed = 27 + (resume_keys ? 4 : 0);
14311 tvb_ensure_bytes_exist(tvb, offset, bytes_needed);
14313 /* Now, get the length */
14314 fn_len = tvb_get_guint8(tvb, offset + bytes_needed - 1);
14315 tvb_ensure_bytes_exist(tvb, offset, bytes_needed + fn_len);
14317 if (resume_keys) {
14318 /* resume key */
14319 CHECK_BYTE_COUNT_SUBR(4);
14320 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14321 COUNT_BYTES_SUBR(4);
14324 /* create time */
14325 CHECK_BYTE_COUNT_SUBR(4);
14326 offset = dissect_smb_datetime(tvb, tree, offset,
14327 hf_smb_create_time,
14328 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14329 *bcp -= 4;
14331 /* access time */
14332 CHECK_BYTE_COUNT_SUBR(4);
14333 offset = dissect_smb_datetime(tvb, tree, offset,
14334 hf_smb_access_time,
14335 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14336 *bcp -= 4;
14338 /* last write time */
14339 CHECK_BYTE_COUNT_SUBR(4);
14340 offset = dissect_smb_datetime(tvb, tree, offset,
14341 hf_smb_last_write_time,
14342 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14343 *bcp -= 4;
14345 /* data size */
14346 CHECK_BYTE_COUNT_SUBR(4);
14347 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14348 COUNT_BYTES_SUBR(4);
14350 /* allocation size */
14351 CHECK_BYTE_COUNT_SUBR(4);
14352 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14353 COUNT_BYTES_SUBR(4);
14355 /* File Attributes */
14356 CHECK_BYTE_COUNT_SUBR(2);
14357 offset = dissect_file_attributes(tvb, tree, offset);
14358 *bcp -= 2;
14360 /* ea length */
14361 CHECK_BYTE_COUNT_SUBR(4);
14362 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14363 COUNT_BYTES_SUBR(4);
14365 /* file name len */
14366 CHECK_BYTE_COUNT_SUBR(1);
14367 fn_len = tvb_get_guint8(tvb, offset);
14368 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14369 COUNT_BYTES_SUBR(1);
14370 if (si->unicode)
14371 fn_len += 2; /* include terminating '\0' */
14372 else
14373 fn_len++; /* include terminating '\0' */
14375 /* file name */
14376 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14377 CHECK_STRING_SUBR(fn);
14378 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14379 fn);
14380 COUNT_BYTES_SUBR(fn_len);
14382 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14383 format_text(fn, strlen(fn)));
14385 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14386 proto_item_set_len(item, offset-old_offset);
14388 *trunc = FALSE;
14389 return offset;
14393 * According to MS-CIFS 2.2.8.1.3 this is like the function above with the
14394 * addition of the list of EA name value pairs before the file name.
14396 * The EAs are formatted as an SMB_FEA as in 2.2.1.2.2. We will deal with
14397 * this soon.
14399 static int
14400 dissect_4_3_4_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14401 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14403 int fn_len;
14404 const char *fn;
14405 int old_offset = offset;
14406 int ea_size = 0;
14407 proto_item *item = NULL;
14408 proto_tree *tree = NULL;
14409 smb_transact2_info_t *t2i;
14410 gboolean resume_keys = FALSE;
14413 DISSECTOR_ASSERT(si);
14415 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14416 t2i = (smb_transact2_info_t *)si->sip->extra_info;
14417 if (t2i != NULL)
14418 resume_keys = t2i->resume_keys;
14421 if (parent_tree) {
14422 tvb_ensure_bytes_exist(tvb, offset, *bcp);
14423 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14424 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14425 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14428 if (resume_keys) {
14429 /* resume key */
14430 CHECK_BYTE_COUNT_SUBR(4);
14431 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14432 COUNT_BYTES_SUBR(4);
14435 /* create time */
14436 CHECK_BYTE_COUNT_SUBR(4);
14437 offset = dissect_smb_datetime(tvb, tree, offset,
14438 hf_smb_create_time,
14439 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14440 *bcp -= 4;
14442 /* access time */
14443 CHECK_BYTE_COUNT_SUBR(4);
14444 offset = dissect_smb_datetime(tvb, tree, offset,
14445 hf_smb_access_time,
14446 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14447 *bcp -= 4;
14449 /* last write time */
14450 CHECK_BYTE_COUNT_SUBR(4);
14451 offset = dissect_smb_datetime(tvb, tree, offset,
14452 hf_smb_last_write_time,
14453 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14454 *bcp -= 4;
14456 /* data size */
14457 CHECK_BYTE_COUNT_SUBR(4);
14458 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14459 COUNT_BYTES_SUBR(4);
14461 /* allocation size */
14462 CHECK_BYTE_COUNT_SUBR(4);
14463 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14464 COUNT_BYTES_SUBR(4);
14466 /* File Attributes */
14467 CHECK_BYTE_COUNT_SUBR(2);
14468 offset = dissect_file_attributes(tvb, tree, offset);
14469 *bcp -= 2;
14471 /* ea length */
14472 CHECK_BYTE_COUNT_SUBR(4);
14473 ea_size = tvb_get_letohl(tvb, offset);
14474 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14475 COUNT_BYTES_SUBR(4);
14477 /* The EAs ... they are formatted as in MS-CIFS 2.2.1.2.2 */
14478 proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, ea_size, NULL,"EAs");
14479 COUNT_BYTES_SUBR(ea_size);
14480 *bcp -= ea_size;
14482 /* file name len */
14483 CHECK_BYTE_COUNT_SUBR(1);
14484 fn_len = tvb_get_guint8(tvb, offset);
14485 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14486 COUNT_BYTES_SUBR(1);
14487 if (si->unicode)
14488 fn_len += 2; /* include terminating '\0' */
14489 else
14490 fn_len++; /* include terminating '\0' */
14492 /* file name */
14493 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14494 CHECK_STRING_SUBR(fn);
14495 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14496 fn);
14497 COUNT_BYTES_SUBR(fn_len);
14499 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14500 format_text(fn, strlen(fn)));
14502 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14503 proto_item_set_len(item, offset-old_offset);
14505 return offset;
14508 static int
14509 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14510 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14512 int fn_len;
14513 const char *fn;
14514 int old_offset = offset;
14515 proto_item *item = NULL;
14516 proto_tree *tree = NULL;
14517 guint32 neo;
14518 int padcnt;
14520 DISSECTOR_ASSERT(si);
14523 * We check this first before adding the sub-tree so things do not
14524 * get ugly.
14527 /* next entry offset */
14528 CHECK_BYTE_COUNT_SUBR(4);
14529 neo = tvb_get_letohl(tvb, offset);
14531 /* Ensure we have the bytes we need, which is up to neo */
14532 tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14534 if (parent_tree) {
14535 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14536 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14537 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14541 * We assume that the presence of a next entry offset implies the
14542 * absence of a resume key, as appears to be the case for 4.3.4.6.
14545 CHECK_BYTE_COUNT_SUBR(4);
14546 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14547 COUNT_BYTES_SUBR(4);
14549 /* file index */
14550 CHECK_BYTE_COUNT_SUBR(4);
14551 proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14552 COUNT_BYTES_SUBR(4);
14554 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14555 if (*trunc) {
14556 return offset;
14559 /* end of file */
14560 CHECK_BYTE_COUNT_SUBR(8);
14561 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14562 COUNT_BYTES_SUBR(8);
14564 /* allocation size */
14565 CHECK_BYTE_COUNT_SUBR(8);
14566 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14567 COUNT_BYTES_SUBR(8);
14569 /* Extended File Attributes */
14570 CHECK_BYTE_COUNT_SUBR(4);
14571 offset = dissect_file_ext_attr(tvb, tree, offset);
14572 *bcp -= 4;
14574 /* file name len */
14575 CHECK_BYTE_COUNT_SUBR(4);
14576 fn_len = tvb_get_letohl(tvb, offset);
14577 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14578 COUNT_BYTES_SUBR(4);
14580 /* file name */
14581 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14582 CHECK_STRING_SUBR(fn);
14583 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14584 fn);
14585 COUNT_BYTES_SUBR(fn_len);
14587 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14588 format_text(fn, strlen(fn)));
14590 /* skip to next structure */
14591 if (neo) {
14592 padcnt = (old_offset + neo) - offset;
14593 if (padcnt < 0) {
14595 * XXX - this is bogus; flag it?
14597 padcnt = 0;
14599 if (padcnt != 0) {
14600 CHECK_BYTE_COUNT_SUBR(padcnt);
14601 COUNT_BYTES_SUBR(padcnt);
14605 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14606 proto_item_set_len(item, offset-old_offset);
14608 *trunc = FALSE;
14609 return offset;
14612 static int
14613 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14614 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14616 int fn_len;
14617 const char *fn;
14618 int old_offset = offset;
14619 proto_item *item = NULL;
14620 proto_tree *tree = NULL;
14621 guint32 neo;
14622 int padcnt;
14624 DISSECTOR_ASSERT(si);
14627 * We check this first before adding the sub-tree so things do not
14628 * get ugly.
14631 /* next entry offset */
14632 CHECK_BYTE_COUNT_SUBR(4);
14633 neo = tvb_get_letohl(tvb, offset);
14635 /* Ensure we have the bytes we need, which is up to neo */
14636 tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14638 if (parent_tree) {
14639 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14640 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14641 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14645 * We assume that the presence of a next entry offset implies the
14646 * absence of a resume key, as appears to be the case for 4.3.4.6.
14649 CHECK_BYTE_COUNT_SUBR(4);
14650 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14651 COUNT_BYTES_SUBR(4);
14653 /* file index */
14654 CHECK_BYTE_COUNT_SUBR(4);
14655 proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14656 COUNT_BYTES_SUBR(4);
14658 /* standard 8-byte timestamps */
14659 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14660 if (*trunc) {
14661 return offset;
14664 /* end of file */
14665 CHECK_BYTE_COUNT_SUBR(8);
14666 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14667 COUNT_BYTES_SUBR(8);
14669 /* allocation size */
14670 CHECK_BYTE_COUNT_SUBR(8);
14671 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14672 COUNT_BYTES_SUBR(8);
14674 /* Extended File Attributes */
14675 CHECK_BYTE_COUNT_SUBR(4);
14676 offset = dissect_file_ext_attr(tvb, tree, offset);
14677 *bcp -= 4;
14679 /* file name len */
14680 CHECK_BYTE_COUNT_SUBR(4);
14681 fn_len = tvb_get_letohl(tvb, offset);
14682 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14683 COUNT_BYTES_SUBR(4);
14685 /* ea length */
14686 CHECK_BYTE_COUNT_SUBR(4);
14687 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14688 COUNT_BYTES_SUBR(4);
14690 /* file name */
14691 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14692 CHECK_STRING_SUBR(fn);
14693 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14694 fn);
14695 COUNT_BYTES_SUBR(fn_len);
14697 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14698 format_text(fn, strlen(fn)));
14700 /* skip to next structure */
14701 if (neo) {
14702 padcnt = (old_offset + neo) - offset;
14703 if (padcnt < 0) {
14705 * XXX - this is bogus; flag it?
14707 padcnt = 0;
14709 if (padcnt != 0) {
14710 CHECK_BYTE_COUNT_SUBR(padcnt);
14711 COUNT_BYTES_SUBR(padcnt);
14715 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14716 proto_item_set_len(item, offset-old_offset);
14718 *trunc = FALSE;
14719 return offset;
14722 static int
14723 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14724 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14726 int fn_len, sfn_len;
14727 const char *fn, *sfn;
14728 int old_offset = offset;
14729 proto_item *item = NULL;
14730 proto_tree *tree = NULL;
14731 guint32 neo;
14732 int padcnt;
14734 DISSECTOR_ASSERT(si);
14737 * We check this first before adding the sub-tree so things do not
14738 * get ugly.
14741 /* next entry offset */
14742 CHECK_BYTE_COUNT_SUBR(4);
14743 neo = tvb_get_letohl(tvb, offset);
14745 /* Ensure we have the bytes we need, which is up to neo */
14746 tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14748 if (parent_tree) {
14749 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14750 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14751 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14755 * XXX - I have not seen any of these that contain a resume
14756 * key, even though some of the requests had the "return resume
14757 * key" flag set.
14760 CHECK_BYTE_COUNT_SUBR(4);
14761 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14762 COUNT_BYTES_SUBR(4);
14764 /* file index */
14765 CHECK_BYTE_COUNT_SUBR(4);
14766 proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14767 COUNT_BYTES_SUBR(4);
14769 /* dissect standard 8-byte timestamps */
14770 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14771 if (*trunc) {
14772 return offset;
14775 /* end of file */
14776 CHECK_BYTE_COUNT_SUBR(8);
14777 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14778 COUNT_BYTES_SUBR(8);
14780 /* allocation size */
14781 CHECK_BYTE_COUNT_SUBR(8);
14782 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14783 COUNT_BYTES_SUBR(8);
14785 /* Extended File Attributes */
14786 CHECK_BYTE_COUNT_SUBR(4);
14787 offset = dissect_file_ext_attr(tvb, tree, offset);
14788 *bcp -= 4;
14790 /* file name len */
14791 CHECK_BYTE_COUNT_SUBR(4);
14792 fn_len = tvb_get_letohl(tvb, offset);
14793 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14794 COUNT_BYTES_SUBR(4);
14797 * EA length.
14799 * XXX - in one captures, this has the topmost bit set, and the
14800 * rest of the bits have the value 7. Is the topmost bit being
14801 * set some indication that the value *isn't* the length of
14802 * the EAs?
14804 CHECK_BYTE_COUNT_SUBR(4);
14805 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14806 COUNT_BYTES_SUBR(4);
14808 /* short file name len */
14809 CHECK_BYTE_COUNT_SUBR(1);
14810 sfn_len = tvb_get_guint8(tvb, offset);
14811 proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
14812 COUNT_BYTES_SUBR(1);
14814 /* reserved byte */
14815 CHECK_BYTE_COUNT_SUBR(1);
14816 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
14817 COUNT_BYTES_SUBR(1);
14819 /* short file name - it's not always in Unicode */
14820 sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
14821 CHECK_STRING_SUBR(sfn);
14822 proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
14823 sfn);
14824 COUNT_BYTES_SUBR(24);
14826 /* file name */
14827 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14828 CHECK_STRING_SUBR(fn);
14829 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14830 fn);
14831 COUNT_BYTES_SUBR(fn_len);
14833 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14834 format_text(fn, strlen(fn)));
14836 /* skip to next structure */
14837 if (neo) {
14838 padcnt = (old_offset + neo) - offset;
14839 if (padcnt < 0) {
14841 * XXX - this is bogus; flag it?
14843 padcnt = 0;
14845 if (padcnt != 0) {
14846 CHECK_BYTE_COUNT_SUBR(padcnt);
14847 COUNT_BYTES_SUBR(padcnt);
14851 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14852 proto_item_set_len(item, offset-old_offset);
14854 *trunc = FALSE;
14855 return offset;
14858 static int
14859 dissect_4_3_4_6full(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14860 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14862 int fn_len;
14863 const char *fn;
14864 int old_offset = offset;
14865 proto_item *item = NULL;
14866 proto_tree *tree = NULL;
14867 guint32 neo;
14868 int padcnt;
14870 DISSECTOR_ASSERT(si);
14873 * We check this first before adding the sub-tree so things do not
14874 * get ugly.
14877 /* next entry offset */
14878 CHECK_BYTE_COUNT_SUBR(4);
14879 neo = tvb_get_letohl(tvb, offset);
14881 /* Ensure we have the bytes we need, which is up to neo */
14882 tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14884 if (parent_tree) {
14885 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14886 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14887 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14891 * XXX - I have not seen any of these that contain a resume
14892 * key, even though some of the requests had the "return resume
14893 * key" flag set.
14896 CHECK_BYTE_COUNT_SUBR(4);
14897 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14898 COUNT_BYTES_SUBR(4);
14900 /* file index */
14901 CHECK_BYTE_COUNT_SUBR(4);
14902 proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14903 COUNT_BYTES_SUBR(4);
14905 /* dissect standard 8-byte timestamps */
14906 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14907 if (*trunc) {
14908 return offset;
14911 /* end of file */
14912 CHECK_BYTE_COUNT_SUBR(8);
14913 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14914 COUNT_BYTES_SUBR(8);
14916 /* allocation size */
14917 CHECK_BYTE_COUNT_SUBR(8);
14918 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14919 COUNT_BYTES_SUBR(8);
14921 /* Extended File Attributes */
14922 CHECK_BYTE_COUNT_SUBR(4);
14923 offset = dissect_file_ext_attr(tvb, tree, offset);
14924 *bcp -= 4;
14926 /* file name len */
14927 CHECK_BYTE_COUNT_SUBR(4);
14928 fn_len = tvb_get_letohl(tvb, offset);
14929 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14930 COUNT_BYTES_SUBR(4);
14933 * EA length.
14935 * XXX - in one captures, this has the topmost bit set, and the
14936 * rest of the bits have the value 7. Is the topmost bit being
14937 * set some indication that the value *isn't* the length of
14938 * the EAs?
14940 CHECK_BYTE_COUNT_SUBR(4);
14941 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14942 COUNT_BYTES_SUBR(4);
14944 /* skip 4 bytes */
14945 COUNT_BYTES_SUBR(4);
14947 CHECK_BYTE_COUNT_SUBR(8);
14948 proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14949 COUNT_BYTES_SUBR(8);
14951 /* file name */
14952 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14953 CHECK_STRING_SUBR(fn);
14954 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14955 fn);
14956 COUNT_BYTES_SUBR(fn_len);
14958 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14959 format_text(fn, strlen(fn)));
14961 /* skip to next structure */
14962 if (neo) {
14963 padcnt = (old_offset + neo) - offset;
14964 if (padcnt < 0) {
14966 * XXX - this is bogus; flag it?
14968 padcnt = 0;
14970 if (padcnt != 0) {
14971 CHECK_BYTE_COUNT_SUBR(padcnt);
14972 COUNT_BYTES_SUBR(padcnt);
14976 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14977 proto_item_set_len(item, offset-old_offset);
14979 *trunc = FALSE;
14980 return offset;
14983 static int
14984 dissect_4_3_4_6_id_both(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14985 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14987 int fn_len, sfn_len;
14988 const char *fn, *sfn;
14989 int old_offset = offset;
14990 proto_item *item = NULL;
14991 proto_tree *tree = NULL;
14992 guint32 neo;
14993 int padcnt;
14995 DISSECTOR_ASSERT(si);
14998 * We check this first before adding the sub-tree so things do not
14999 * get ugly.
15002 /* next entry offset */
15003 CHECK_BYTE_COUNT_SUBR(4);
15004 neo = tvb_get_letohl(tvb, offset);
15006 /* Ensure we have the bytes we need, which is up to neo */
15007 tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15009 if (parent_tree) {
15010 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
15011 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15012 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
15016 * XXX - I have not seen any of these that contain a resume
15017 * key, even though some of the requests had the "return resume
15018 * key" flag set.
15021 CHECK_BYTE_COUNT_SUBR(4);
15022 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15023 COUNT_BYTES_SUBR(4);
15025 /* file index */
15026 CHECK_BYTE_COUNT_SUBR(4);
15027 proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15028 COUNT_BYTES_SUBR(4);
15030 /* dissect standard 8-byte timestamps */
15031 offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
15032 if (*trunc) {
15033 return offset;
15036 /* end of file */
15037 CHECK_BYTE_COUNT_SUBR(8);
15038 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15039 COUNT_BYTES_SUBR(8);
15041 /* allocation size */
15042 CHECK_BYTE_COUNT_SUBR(8);
15043 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15044 COUNT_BYTES_SUBR(8);
15046 /* Extended File Attributes */
15047 CHECK_BYTE_COUNT_SUBR(4);
15048 offset = dissect_file_ext_attr(tvb, tree, offset);
15049 *bcp -= 4;
15051 /* file name len */
15052 CHECK_BYTE_COUNT_SUBR(4);
15053 fn_len = tvb_get_letohl(tvb, offset);
15054 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15055 COUNT_BYTES_SUBR(4);
15058 * EA length.
15060 * XXX - in one captures, this has the topmost bit set, and the
15061 * rest of the bits have the value 7. Is the topmost bit being
15062 * set some indication that the value *isn't* the length of
15063 * the EAs?
15065 CHECK_BYTE_COUNT_SUBR(4);
15066 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15067 COUNT_BYTES_SUBR(4);
15069 /* short file name len */
15070 CHECK_BYTE_COUNT_SUBR(1);
15071 sfn_len = tvb_get_guint8(tvb, offset);
15072 proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
15073 COUNT_BYTES_SUBR(1);
15075 /* reserved byte */
15076 CHECK_BYTE_COUNT_SUBR(1);
15077 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
15078 COUNT_BYTES_SUBR(1);
15080 /* short file name - it's not always in Unicode */
15081 sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
15082 CHECK_STRING_SUBR(sfn);
15083 proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
15084 sfn);
15085 COUNT_BYTES_SUBR(24);
15087 /* reserved bytes */
15088 CHECK_BYTE_COUNT_SUBR(2);
15089 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
15090 COUNT_BYTES_SUBR(2);
15092 /* file id */
15093 CHECK_BYTE_COUNT_SUBR(8);
15094 proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15095 COUNT_BYTES_SUBR(8);
15097 /* file name */
15098 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15099 CHECK_STRING_SUBR(fn);
15100 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15101 fn);
15102 COUNT_BYTES_SUBR(fn_len);
15104 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15105 format_text(fn, strlen(fn)));
15107 /* skip to next structure */
15108 if (neo) {
15109 padcnt = (old_offset + neo) - offset;
15110 if (padcnt < 0) {
15112 * XXX - this is bogus; flag it?
15114 padcnt = 0;
15116 if (padcnt != 0) {
15117 CHECK_BYTE_COUNT_SUBR(padcnt);
15118 COUNT_BYTES_SUBR(padcnt);
15122 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
15123 proto_item_set_len(item, offset-old_offset);
15125 *trunc = FALSE;
15126 return offset;
15129 static int
15130 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
15131 int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15133 int fn_len;
15134 const char *fn;
15135 int old_offset = offset;
15136 proto_item *item = NULL;
15137 proto_tree *tree = NULL;
15138 guint32 neo;
15139 int padcnt;
15141 DISSECTOR_ASSERT(si);
15144 * We check this first before adding the sub-tree so things do not
15145 * get ugly.
15148 /* next entry offset */
15149 CHECK_BYTE_COUNT_SUBR(4);
15150 neo = tvb_get_letohl(tvb, offset);
15152 /* Ensure we have the bytes we need, which is up to neo */
15153 tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15155 if (parent_tree) {
15156 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
15157 val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15158 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
15162 * We assume that the presence of a next entry offset implies the
15163 * absence of a resume key, as appears to be the case for 4.3.4.6.
15166 CHECK_BYTE_COUNT_SUBR(4);
15167 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15168 COUNT_BYTES_SUBR(4);
15170 /* file index */
15171 CHECK_BYTE_COUNT_SUBR(4);
15172 proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15173 COUNT_BYTES_SUBR(4);
15175 /* file name len */
15176 CHECK_BYTE_COUNT_SUBR(4);
15177 fn_len = tvb_get_letohl(tvb, offset);
15178 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15179 COUNT_BYTES_SUBR(4);
15181 /* file name */
15182 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15183 CHECK_STRING_SUBR(fn);
15184 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15185 fn);
15186 COUNT_BYTES_SUBR(fn_len);
15188 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15189 format_text(fn, strlen(fn)));
15191 /* skip to next structure */
15192 if (neo) {
15193 padcnt = (old_offset + neo) - offset;
15194 if (padcnt < 0) {
15196 * XXX - this is bogus; flag it?
15198 padcnt = 0;
15200 if (padcnt != 0) {
15201 CHECK_BYTE_COUNT_SUBR(padcnt);
15202 COUNT_BYTES_SUBR(padcnt);
15206 proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
15207 proto_item_set_len(item, offset-old_offset);
15209 *trunc = FALSE;
15210 return offset;
15213 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
15215 static int
15216 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo,
15217 proto_tree *tree, int offset, guint16 *bcp,
15218 gboolean *trunc, smb_info_t *si)
15220 const char *fn;
15221 int fn_len;
15222 int pad;
15224 DISSECTOR_ASSERT(si);
15226 /* NextEntryOffset */
15227 CHECK_BYTE_COUNT_SUBR(4);
15228 proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15229 COUNT_BYTES_SUBR(4);
15231 /* ResumeKey */
15232 CHECK_BYTE_COUNT_SUBR(4);
15233 proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15234 COUNT_BYTES_SUBR(4);
15236 /* Unix basic info */
15237 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, trunc);
15238 if (*trunc)
15239 return offset;
15241 /* Name */
15243 fn = get_unicode_or_ascii_string(
15244 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
15246 CHECK_STRING_SUBR(fn);
15247 proto_tree_add_string(
15248 tree, hf_smb_unix_file_name, tvb, offset, fn_len, fn);
15249 COUNT_BYTES_SUBR(fn_len);
15251 /* Pad to 4 bytes */
15253 if (offset % 4) {
15254 pad = 4 - (offset % 4);
15255 COUNT_BYTES_SUBR(pad);
15258 *trunc = FALSE;
15259 return offset;
15262 static int
15263 dissect_find_file_unix_info2(tvbuff_t *tvb, packet_info *pinfo,
15264 proto_tree *tree, int offset, guint16 *bcp,
15265 gboolean *trunc, smb_info_t *si)
15267 const char *fn;
15268 guint32 namelen;
15269 int fn_len;
15270 int pad;
15272 DISSECTOR_ASSERT(si);
15274 /* NextEntryOffset */
15275 CHECK_BYTE_COUNT_SUBR(4);
15276 proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15277 COUNT_BYTES_SUBR(4);
15279 /* ResumeKey */
15280 CHECK_BYTE_COUNT_SUBR(4);
15281 proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15282 COUNT_BYTES_SUBR(4);
15284 /* Unix Info2 */
15285 offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp, trunc);
15286 if (*trunc)
15287 return offset;
15289 /* Name length */
15290 CHECK_BYTE_COUNT_SUBR(4);
15291 namelen = tvb_get_letohl(tvb, offset);
15292 proto_tree_add_uint(tree, hf_smb_unix_file_name_length, tvb, offset, 4, namelen);
15293 COUNT_BYTES_SUBR(4);
15295 /* Name */
15298 * namelen could be > 2^31-1; this will catch that.
15299 * The length argument to get_unicode_or_ascii_string() is an
15300 * int, not an unsigned int, so we have to worry about that.
15302 tvb_ensure_bytes_exist(tvb, offset, namelen);
15303 fn_len = namelen;
15304 fn = get_unicode_or_ascii_string(
15305 tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
15307 CHECK_STRING_SUBR(fn);
15308 proto_tree_add_string(
15309 tree, hf_smb_unix_file_name, tvb, offset, fn_len, fn);
15310 COUNT_BYTES_SUBR(fn_len);
15312 /* Pad to 4 bytes */
15314 if (offset % 4) {
15315 pad = 4 - (offset % 4);
15316 COUNT_BYTES_SUBR(pad);
15319 *trunc = FALSE;
15320 return offset;
15323 /*dissect the data block for TRANS2_FIND_FIRST2*/
15324 static int
15325 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
15326 proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15328 if (!*bcp) {
15329 return offset;
15332 DISSECTOR_ASSERT(si);
15334 switch(si->info_level) {
15335 case 1: /*Info Standard*/
15336 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
15337 trunc, si);
15338 break;
15339 case 2: /*Info Query EA Size*/
15340 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
15341 trunc, si);
15342 break;
15343 case 3: /* Info Query EAs From List same as
15344 * InfoQueryEASize.
15345 * Not according to MS-CIFS 2.2.8.1.3. RJS
15347 offset = dissect_4_3_4_3(tvb, pinfo, tree, offset, bcp,
15348 trunc, si);
15349 break;
15350 case 0x0101: /*Find File Directory Info*/
15351 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
15352 trunc, si);
15353 break;
15354 case 0x0102: /*Find File Full Directory Info*/
15355 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
15356 trunc, si);
15357 break;
15358 case 0x0103: /*Find File Names Info*/
15359 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
15360 trunc, si);
15361 break;
15362 case 0x0104: /*Find File Both Directory Info*/
15363 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
15364 trunc, si);
15365 break;
15366 case 0x0105: /*Find File Full Directory Info*/
15367 offset = dissect_4_3_4_6full(tvb, pinfo, tree, offset, bcp,
15368 trunc, si);
15369 break;
15370 case 0x0106: /*Find File Id Both Directory Info*/
15371 offset = dissect_4_3_4_6_id_both(tvb, pinfo, tree, offset, bcp,
15372 trunc, si);
15373 break;
15374 case 0x0202: /*Find File Unix*/
15375 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
15376 trunc, si);
15377 break;
15378 case 0x020B: /*Find File Unix Info2*/
15379 offset = dissect_find_file_unix_info2(tvb, pinfo, tree, offset, bcp,
15380 trunc, si);
15381 break;
15382 default: /* unknown info level */
15383 *trunc = FALSE;
15384 break;
15386 return offset;
15390 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
15391 static int
15392 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15394 guint32 mask;
15395 proto_item *item;
15396 proto_tree *tree;
15398 mask = tvb_get_letohl(tvb, offset);
15400 if (parent_tree) {
15401 item = proto_tree_add_item(parent_tree, hf_smb_fs_attr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15402 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
15404 /* case sensitive search */
15405 proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
15406 tvb, offset, 4, mask);
15407 /* case preserved names */
15408 proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
15409 tvb, offset, 4, mask);
15410 /* unicode on disk */
15411 proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
15412 tvb, offset, 4, mask);
15413 /* persistent acls */
15414 proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
15415 tvb, offset, 4, mask);
15416 /* file compression */
15417 proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
15418 tvb, offset, 4, mask);
15419 /* volume quotas */
15420 proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
15421 tvb, offset, 4, mask);
15422 /* sparse files */
15423 proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
15424 tvb, offset, 4, mask);
15425 /* reparse points */
15426 proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
15427 tvb, offset, 4, mask);
15428 /* remote storage */
15429 proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
15430 tvb, offset, 4, mask);
15431 /* lfn apis */
15432 proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
15433 tvb, offset, 4, mask);
15434 /* volume is compressed */
15435 proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
15436 tvb, offset, 4, mask);
15437 /* support oids */
15438 proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
15439 tvb, offset, 4, mask);
15440 /* encryption */
15441 proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
15442 tvb, offset, 4, mask);
15443 /* named streams */
15444 proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
15445 tvb, offset, 4, mask);
15446 /* read only volume */
15447 proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
15448 tvb, offset, 4, mask);
15451 offset += 4;
15452 return offset;
15456 static int
15457 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15459 guint32 mask;
15460 proto_item *item;
15461 proto_tree *tree;
15463 mask = tvb_get_letohl(tvb, offset);
15465 if (parent_tree) {
15466 item = proto_tree_add_item(parent_tree, hf_smb_device_char, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15467 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
15469 proto_tree_add_boolean(tree, hf_smb_device_char_removable,
15470 tvb, offset, 4, mask);
15471 proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
15472 tvb, offset, 4, mask);
15473 proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
15474 tvb, offset, 4, mask);
15475 proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
15476 tvb, offset, 4, mask);
15477 proto_tree_add_boolean(tree, hf_smb_device_char_remote,
15478 tvb, offset, 4, mask);
15479 proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
15480 tvb, offset, 4, mask);
15481 proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
15482 tvb, offset, 4, mask);
15485 offset += 4;
15486 return offset;
15489 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
15491 static const true_false_string tfs_smb_mac_access_ctrl = {
15492 "Macintosh Access Control Supported",
15493 "Macintosh Access Control Not Supported"
15496 static const true_false_string tfs_smb_mac_getset_comments = {
15497 "Macintosh Get & Set Comments Supported",
15498 "Macintosh Get & Set Comments Not Supported"
15501 static const true_false_string tfs_smb_mac_desktopdb_calls = {
15502 "Macintosh Get & Set Desktop Database Info Supported",
15503 "Macintosh Get & Set Desktop Database Info Supported"
15506 static const true_false_string tfs_smb_mac_unique_ids = {
15507 "Macintosh Unique IDs Supported",
15508 "Macintosh Unique IDs Not Supported"
15511 static const true_false_string tfs_smb_mac_streams = {
15512 "Macintosh and Streams Extensions Not Supported",
15513 "Macintosh and Streams Extensions Supported"
15517 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
15519 int fn_len, vll;
15520 const char *fn;
15522 /* create time */
15523 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15524 offset = dissect_nt_64bit_time(tvb, tree, offset,
15525 hf_smb_create_time);
15526 *bcp -= 8;
15528 /* volume serial number */
15529 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15530 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15531 COUNT_BYTES_TRANS_SUBR(4);
15533 /* volume label length */
15534 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15535 vll = tvb_get_letohl(tvb, offset);
15536 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
15537 COUNT_BYTES_TRANS_SUBR(4);
15539 /* 2 reserved bytes */
15540 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15541 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
15542 COUNT_BYTES_TRANS_SUBR(2);
15544 /* label */
15545 fn_len = vll;
15546 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
15547 CHECK_STRING_TRANS_SUBR(fn);
15548 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15549 fn);
15550 COUNT_BYTES_TRANS_SUBR(fn_len);
15552 return offset;
15556 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15558 /* allocation size */
15559 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15560 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15561 COUNT_BYTES_TRANS_SUBR(8);
15563 /* free allocation units */
15564 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15565 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15566 COUNT_BYTES_TRANS_SUBR(8);
15568 /* sectors per unit */
15569 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15570 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15571 COUNT_BYTES_TRANS_SUBR(4);
15573 /* bytes per sector */
15574 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15575 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15576 COUNT_BYTES_TRANS_SUBR(4);
15578 return offset;
15582 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15584 /* device type */
15585 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15586 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15587 COUNT_BYTES_TRANS_SUBR(4);
15589 /* device characteristics */
15590 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15591 offset = dissect_device_characteristics(tvb, tree, offset);
15592 *bcp -= 4;
15594 return offset;
15598 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
15600 int fn_len, fnl;
15601 const char *fn;
15603 /* FS attributes */
15604 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15605 offset = dissect_fs_attributes(tvb, tree, offset);
15606 *bcp -= 4;
15608 /* max name len */
15609 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15610 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15611 COUNT_BYTES_TRANS_SUBR(4);
15613 /* fs name length */
15614 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15615 fnl = tvb_get_letohl(tvb, offset);
15616 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
15617 COUNT_BYTES_TRANS_SUBR(4);
15619 /* label */
15620 fn_len = fnl;
15621 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
15622 CHECK_STRING_TRANS_SUBR(fn);
15623 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
15624 fn);
15625 COUNT_BYTES_TRANS_SUBR(fn_len);
15627 return offset;
15631 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
15633 CHECK_BYTE_COUNT_TRANS_SUBR(64);
15635 dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
15637 COUNT_BYTES_TRANS_SUBR(64);
15639 return offset;
15643 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15645 /* allocation size */
15646 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15647 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15648 COUNT_BYTES_TRANS_SUBR(8);
15650 /* caller free allocation units */
15651 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15652 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15653 COUNT_BYTES_TRANS_SUBR(8);
15655 /* actual free allocation units */
15656 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15657 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15658 COUNT_BYTES_TRANS_SUBR(8);
15660 /* sectors per unit */
15661 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15662 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15663 COUNT_BYTES_TRANS_SUBR(4);
15665 /* bytes per sector */
15666 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15667 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15668 COUNT_BYTES_TRANS_SUBR(4);
15670 return offset;
15673 static int
15674 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
15675 int offset, guint16 *bcp, smb_info_t *si)
15677 int fn_len, vll;
15678 const char *fn;
15679 guint support = 0;
15680 proto_item *item = NULL;
15681 proto_tree *ti = NULL;
15683 if (!*bcp) {
15684 return offset;
15687 DISSECTOR_ASSERT(si);
15689 switch(si->info_level) {
15690 case 1: /* SMB_INFO_ALLOCATION */
15691 /* filesystem id */
15692 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15693 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15694 COUNT_BYTES_TRANS_SUBR(4);
15696 /* sectors per unit */
15697 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15698 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15699 COUNT_BYTES_TRANS_SUBR(4);
15701 /* units */
15702 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15703 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15704 COUNT_BYTES_TRANS_SUBR(4);
15706 /* avail units */
15707 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15708 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15709 COUNT_BYTES_TRANS_SUBR(4);
15711 /* bytes per sector, only 16bit integer here */
15712 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15713 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
15714 COUNT_BYTES_TRANS_SUBR(2);
15716 break;
15717 case 2: /* SMB_INFO_VOLUME */
15718 /* volume serial number */
15719 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15720 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15721 COUNT_BYTES_TRANS_SUBR(4);
15723 /* volume label length, only one byte here */
15724 CHECK_BYTE_COUNT_TRANS_SUBR(1);
15725 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
15726 COUNT_BYTES_TRANS_SUBR(1);
15728 /* label */
15729 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
15730 CHECK_STRING_TRANS_SUBR(fn);
15731 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15732 fn);
15733 COUNT_BYTES_TRANS_SUBR(fn_len);
15735 break;
15736 case 0x0101: /* SMB_QUERY_FS_LABEL_INFO */
15737 case 1002: /* SMB_FS_LABEL_INFORMATION */
15738 /* volume label length */
15739 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15740 vll = tvb_get_letohl(tvb, offset);
15741 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
15742 COUNT_BYTES_TRANS_SUBR(4);
15744 /* label */
15745 fn_len = vll;
15746 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15747 CHECK_STRING_TRANS_SUBR(fn);
15748 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15749 fn);
15750 COUNT_BYTES_TRANS_SUBR(fn_len);
15752 break;
15753 case 0x0102: /* SMB_QUERY_FS_VOLUME_INFO */
15754 case 1001: /* SMB_FS_VOLUME_INFORMATION */
15755 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
15756 break;
15757 case 0x0103: /* SMB_QUERY_FS_SIZE_INFO */
15758 case 1003: /* SMB_FS_SIZE_INFORMATION */
15759 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
15760 break;
15761 case 0x0104: /* SMB_QUERY_FS_DEVICE_INFO */
15762 case 1004: /* SMB_FS_DEVICE_INFORMATION */
15763 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
15764 break;
15765 case 0x0105: /* SMB_QUERY_FS_ATTRIBUTE_INFO */
15766 case 1005: /* SMB_FS_ATTRIBUTE_INFORMATION */
15767 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
15768 break;
15769 case 0x200: { /* SMB_QUERY_CIFS_UNIX_INFO */
15770 proto_item *item_2 = NULL;
15771 proto_tree *subtree = NULL;
15773 /* MajorVersionNumber */
15774 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15775 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
15776 COUNT_BYTES_TRANS_SUBR(2);
15778 /* MinorVersionNumber */
15779 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15780 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
15781 COUNT_BYTES_TRANS_SUBR(2);
15783 /* Capability */
15785 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15787 if (tree) {
15788 item_2 = proto_tree_add_item(tree, hf_smb_unix_capability, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15789 subtree = proto_item_add_subtree(
15790 item_2, ett_smb_unix_capabilities);
15793 proto_tree_add_item(
15794 subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8,
15795 ENC_LITTLE_ENDIAN);
15797 proto_tree_add_item(
15798 subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8,
15799 ENC_LITTLE_ENDIAN);
15801 COUNT_BYTES_TRANS_SUBR(8);
15803 break;
15805 case 0x301: /* MAC_QUERY_FS_INFO */
15806 /* Create time */
15807 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15808 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
15809 *bcp -= 8;
15810 /* Modify Time */
15811 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15812 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
15813 *bcp -= 8;
15814 /* Backup Time */
15815 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15816 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
15817 *bcp -= 8;
15818 /* Allocation blocks */
15819 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15820 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
15821 offset,
15822 4, ENC_LITTLE_ENDIAN);
15823 COUNT_BYTES_TRANS_SUBR(4);
15824 /* Allocation Block Size */
15825 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15826 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
15827 offset, 4, ENC_LITTLE_ENDIAN);
15828 COUNT_BYTES_TRANS_SUBR(4);
15829 /* Free Block Count */
15830 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15831 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
15832 offset, 4, ENC_LITTLE_ENDIAN);
15833 COUNT_BYTES_TRANS_SUBR(4);
15834 /* Finder Info ... */
15835 CHECK_BYTE_COUNT_TRANS_SUBR(32);
15836 proto_tree_add_bytes_format_value(tree, hf_smb_mac_fndrinfo, tvb,
15837 offset, 32, NULL,
15838 "%s",
15839 tvb_format_text(tvb, offset, 32));
15840 COUNT_BYTES_TRANS_SUBR(32);
15841 /* Number Files */
15842 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15843 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
15844 offset, 4, ENC_LITTLE_ENDIAN);
15845 COUNT_BYTES_TRANS_SUBR(4);
15846 /* Number of Root Directories */
15847 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15848 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
15849 offset, 4, ENC_LITTLE_ENDIAN);
15850 COUNT_BYTES_TRANS_SUBR(4);
15851 /* Number of files */
15852 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15853 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
15854 offset, 4, ENC_LITTLE_ENDIAN);
15855 COUNT_BYTES_TRANS_SUBR(4);
15856 /* Dir Count */
15857 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15858 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
15859 offset, 4, ENC_LITTLE_ENDIAN);
15860 COUNT_BYTES_TRANS_SUBR(4);
15861 /* Mac Support Flags */
15862 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15863 support = tvb_get_letohl(tvb, offset);
15864 item = proto_tree_add_item(tree, hf_smb_mac_sup, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15865 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
15866 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
15867 tvb, offset, 4, support);
15868 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
15869 tvb, offset, 4, support);
15870 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
15871 tvb, offset, 4, support);
15872 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
15873 tvb, offset, 4, support);
15874 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
15875 tvb, offset, 4, support);
15876 COUNT_BYTES_TRANS_SUBR(4);
15877 break;
15878 case 1006: /* QUERY_FS_QUOTA_INFO */
15879 offset = dissect_nt_quota(tvb, tree, offset, bcp);
15880 break;
15881 case 1007: /* SMB_FS_FULL_SIZE_INFORMATION */
15882 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
15883 break;
15884 case 1008: /* Query Object ID */ {
15885 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
15886 break;
15890 return offset;
15893 static int
15894 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
15895 proto_tree *parent_tree, smb_info_t *si)
15897 proto_item *item = NULL;
15898 proto_tree *tree = NULL;
15899 smb_transact2_info_t *t2i;
15900 int count;
15901 gboolean trunc;
15902 int offset = 0;
15903 guint16 dc;
15905 dc = tvb_reported_length(tvb);
15907 DISSECTOR_ASSERT(si);
15909 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
15910 t2i = (smb_transact2_info_t *)si->sip->extra_info;
15911 else
15912 t2i = NULL;
15914 if (parent_tree) {
15915 if ((t2i != NULL) && (t2i->subcmd != -1)) {
15916 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
15917 "%s Data",
15918 val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
15919 "Unknown (0x%02x)"));
15920 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
15921 } else {
15922 proto_tree_add_text(parent_tree, tvb, offset, dc,
15923 "Unknown Transaction2 Data");
15927 if (t2i == NULL) {
15928 offset += dc;
15929 return offset;
15931 switch(t2i->subcmd) {
15932 case 0x0000: /*TRANS2_OPEN2*/
15933 /* XXX not implemented yet. See SNIA doc */
15934 break;
15935 case 0x0001: /*TRANS2_FIND_FIRST2*/
15936 /* returned data */
15937 count = si->info_count;
15939 if (count == -1) {
15940 break;
15943 if (count) {
15944 col_append_str(pinfo->cinfo, COL_INFO,
15945 ", Files:");
15948 while(count--) {
15949 offset = dissect_ff2_response_data(tvb, pinfo, tree,
15950 offset, &dc, &trunc, si);
15951 if (trunc)
15952 break;
15954 break;
15955 case 0x0002: /*TRANS2_FIND_NEXT2*/
15956 /* returned data */
15957 count = si->info_count;
15959 if (count == -1) {
15960 break;
15962 if (count) {
15963 col_append_str(pinfo->cinfo, COL_INFO,
15964 ", Files:");
15967 while(count--) {
15968 offset = dissect_ff2_response_data(tvb, pinfo, tree,
15969 offset, &dc, &trunc, si);
15970 if (trunc)
15971 break;
15973 break;
15974 case 0x0003: /*TRANS2_QUERY_FS_INFORMATION*/
15975 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc, si);
15976 break;
15977 case 0x0004: /*TRANS2_SET_FS_INFORMATION*/
15978 offset = dissect_sfsi_response(tvb, pinfo, tree, offset, &dc, si);
15979 break;
15980 case 0x0005: /*TRANS2_QUERY_PATH_INFORMATION*/
15981 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
15982 break;
15983 case 0x0006: /*TRANS2_SET_PATH_INFORMATION*/
15984 /* no data in this response */
15985 break;
15986 case 0x0007: /*TRANS2_QUERY_FILE_INFORMATION*/
15987 /* identical to QUERY_PATH_INFO */
15988 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
15989 break;
15990 case 0x0008: /*TRANS2_SET_FILE_INFORMATION*/
15991 /* no data in this response */
15992 break;
15993 case 0x0009: /*TRANS2_FSCTL*/
15994 /* XXX dont know how to dissect this one (yet)*/
15997 * XXX - "Microsoft Networks SMB File Sharing Protocol
15998 * Extensions Version 3.0, Document Version 1.11,
15999 * July 19, 1990" says this this contains a
16000 * "File system specific return data block".
16001 * (That means we may not be able to dissect it in any
16002 * case.)
16004 break;
16005 case 0x000a: /*TRANS2_IOCTL2*/
16006 /* XXX dont know how to dissect this one (yet)*/
16009 * XXX - "Microsoft Networks SMB File Sharing Protocol
16010 * Extensions Version 3.0, Document Version 1.11,
16011 * July 19, 1990" says this this contains a
16012 * "Device/function specific return data block".
16013 * (That means we may not be able to dissect it in any
16014 * case.)
16016 break;
16017 case 0x000b: /*TRANS2_FIND_NOTIFY_FIRST*/
16018 /* XXX dont know how to dissect this one (yet)*/
16021 * XXX - "Microsoft Networks SMB File Sharing Protocol
16022 * Extensions Version 3.0, Document Version 1.11,
16023 * July 19, 1990" says this this contains "the level
16024 * dependent information about the changes which
16025 * occurred".
16027 break;
16028 case 0x000c: /*TRANS2_FIND_NOTIFY_NEXT*/
16029 /* XXX dont know how to dissect this one (yet)*/
16032 * XXX - "Microsoft Networks SMB File Sharing Protocol
16033 * Extensions Version 3.0, Document Version 1.11,
16034 * July 19, 1990" says this this contains "the level
16035 * dependent information about the changes which
16036 * occurred".
16038 break;
16039 case 0x000d: /*TRANS2_CREATE_DIRECTORY*/
16040 /* no data in this response */
16041 break;
16042 case 0x000e: /*TRANS2_SESSION_SETUP*/
16043 /* XXX dont know how to dissect this one (yet)*/
16044 break;
16045 case 0x0010: /*TRANS2_GET_DFS_REFERRAL*/
16046 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc, si->unicode);
16047 break;
16048 case 0x0011: /*TRANS2_REPORT_DFS_INCONSISTENCY*/
16049 /* the SNIA spec appears to say the response has no data */
16050 break;
16051 case -1:
16053 * We don't know what the matching request was; don't
16054 * bother putting anything else into the tree for the data.
16056 offset += dc;
16057 dc = 0;
16058 break;
16061 /* ooops there were data we didnt know how to process */
16062 if (dc != 0) {
16063 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, ENC_NA);
16064 offset += dc;
16067 return offset;
16071 static int
16072 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb_info_t *si)
16074 proto_item *item = NULL;
16075 proto_tree *tree = NULL;
16076 smb_transact2_info_t *t2i;
16077 guint16 fid;
16078 int lno;
16079 int offset = 0;
16080 int pc;
16082 pc = tvb_reported_length(tvb);
16084 DISSECTOR_ASSERT(si);
16086 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
16087 t2i = (smb_transact2_info_t *)si->sip->extra_info;
16088 else
16089 t2i = NULL;
16091 if (parent_tree) {
16092 if ((t2i != NULL) && (t2i->subcmd != -1)) {
16093 item = proto_tree_add_text(parent_tree, tvb, offset, pc,
16094 "%s Parameters",
16095 val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
16096 "Unknown (0x%02x)"));
16097 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
16098 } else {
16099 proto_tree_add_text(parent_tree, tvb, offset, pc,
16100 "Unknown Transaction2 Parameters");
16104 if (t2i == NULL) {
16105 offset += pc;
16106 return offset;
16108 switch(t2i->subcmd) {
16109 case 0x00: /*TRANS2_OPEN2*/
16110 /* fid */
16111 fid = tvb_get_letohs(tvb, offset);
16112 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
16113 offset += 2;
16116 * XXX - Microsoft Networks SMB File Sharing Protocol
16117 * Extensions Version 3.0, Document Version 1.11,
16118 * July 19, 1990 says that the file attributes, create
16119 * time (which it says is the last modification time),
16120 * data size, granted access, file type, and IPC state
16121 * are returned only if bit 0 is set in the open flags,
16122 * and that the EA length is returned only if bit 3
16123 * is set in the open flags. Does that mean that,
16124 * at least in that SMB dialect, those fields are not
16125 * present in the reply parameters if the bits in
16126 * question aren't set?
16129 /* File Attributes */
16130 offset = dissect_file_attributes(tvb, tree, offset);
16132 /* create time */
16133 offset = dissect_smb_datetime(tvb, tree, offset,
16134 hf_smb_create_time,
16135 hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
16137 /* data size */
16138 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16139 offset += 4;
16141 /* granted access */
16142 offset = dissect_access(tvb, tree, offset, "Granted");
16144 /* File Type */
16145 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16146 offset += 2;
16148 /* IPC State */
16149 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
16151 /* open_action */
16152 offset = dissect_open_action(tvb, tree, offset);
16154 /* server unique file ID */
16155 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16156 offset += 4;
16158 /* ea error offset, only a 16 bit integer here */
16159 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16160 offset += 2;
16162 /* ea length */
16163 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16164 offset += 4;
16166 break;
16167 case 0x01: /*TRANS2_FIND_FIRST2*/
16168 /* Find First2 information level */
16169 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
16171 /* sid */
16172 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16173 offset += 2;
16175 /* search count */
16176 si->info_count = tvb_get_letohs(tvb, offset);
16177 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
16178 offset += 2;
16180 /* end of search */
16181 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16182 offset += 2;
16184 /* ea error offset, only a 16 bit integer here */
16185 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16186 offset += 2;
16188 /* last name offset */
16189 lno = tvb_get_letohs(tvb, offset);
16190 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
16191 offset += 2;
16193 break;
16194 case 0x02: /*TRANS2_FIND_NEXT2*/
16195 /* search count */
16196 si->info_count = tvb_get_letohs(tvb, offset);
16197 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
16198 offset += 2;
16200 /* end of search */
16201 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16202 offset += 2;
16204 /* ea_error_offset, only a 16 bit integer here*/
16205 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16206 offset += 2;
16208 /* last name offset */
16209 lno = tvb_get_letohs(tvb, offset);
16210 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
16211 offset += 2;
16213 break;
16214 case 0x03: /*TRANS2_QUERY_FS_INFORMATION*/
16215 /* no parameter block here */
16216 break;
16217 case 0x05: /*TRANS2_QUERY_PATH_INFORMATION*/
16218 /* ea_error_offset, only a 16 bit integer here*/
16219 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16220 offset += 2;
16222 break;
16223 case 0x06: /*TRANS2_SET_PATH_INFORMATION*/
16224 /* ea_error_offset, only a 16 bit integer here*/
16225 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16226 offset += 2;
16228 break;
16229 case 0x07: /*TRANS2_QUERY_FILE_INFORMATION*/
16230 /* ea_error_offset, only a 16 bit integer here*/
16231 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16232 offset += 2;
16234 break;
16235 case 0x08: /*TRANS2_SET_FILE_INFORMATION*/
16236 /* ea_error_offset, only a 16 bit integer here*/
16237 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16238 offset += 2;
16240 break;
16241 case 0x09: /*TRANS2_FSCTL*/
16242 /* XXX dont know how to dissect this one (yet)*/
16245 * XXX - "Microsoft Networks SMB File Sharing Protocol
16246 * Extensions Version 3.0, Document Version 1.11,
16247 * July 19, 1990" says this this contains a
16248 * "File system specific return parameter block".
16249 * (That means we may not be able to dissect it in any
16250 * case.)
16252 break;
16253 case 0x0a: /*TRANS2_IOCTL2*/
16254 /* XXX dont know how to dissect this one (yet)*/
16257 * XXX - "Microsoft Networks SMB File Sharing Protocol
16258 * Extensions Version 3.0, Document Version 1.11,
16259 * July 19, 1990" says this this contains a
16260 * "Device/function specific return parameter block".
16261 * (That means we may not be able to dissect it in any
16262 * case.)
16264 break;
16265 case 0x0b: /*TRANS2_FIND_NOTIFY_FIRST*/
16266 /* Find Notify information level */
16267 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
16269 /* Monitor handle */
16270 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16271 offset += 2;
16273 /* Change count */
16274 si->info_count = tvb_get_letohs(tvb, offset);
16275 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
16276 offset += 2;
16278 /* ea_error_offset, only a 16 bit integer here*/
16279 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16280 offset += 2;
16282 break;
16283 case 0x0c: /*TRANS2_FIND_NOTIFY_NEXT*/
16284 /* Find Notify information level */
16285 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
16287 /* Change count */
16288 si->info_count = tvb_get_letohs(tvb, offset);
16289 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
16290 offset += 2;
16292 /* ea_error_offset, only a 16 bit integer here*/
16293 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16294 offset += 2;
16296 break;
16297 case 0x0d: /*TRANS2_CREATE_DIRECTORY*/
16298 /* ea error offset, only a 16 bit integer here */
16299 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16300 offset += 2;
16302 break;
16303 case 0x0e: /*TRANS2_SESSION_SETUP*/
16304 /* XXX dont know how to dissect this one (yet)*/
16305 break;
16306 case 0x10: /*TRANS2_GET_DFS_REFERRAL*/
16307 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
16308 break;
16309 case 0x11: /*TRANS2_REPORT_DFS_INCONSISTENCY*/
16310 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
16311 break;
16312 case -1:
16314 * We don't know what the matching request was; don't
16315 * bother putting anything else into the tree for the data.
16317 offset += pc;
16318 break;
16321 /* ooops there were data we didnt know how to process */
16322 if (offset < pc) {
16323 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, ENC_NA);
16324 offset += pc-offset;
16326 return offset;
16330 static int
16331 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
16333 guint8 sc, wc;
16334 guint16 od = 0, po = 0, pc = 0, pd = 0, dc = 0, dd = 0, td = 0, tp = 0;
16335 smb_transact2_info_t *t2i = NULL;
16336 guint16 bc;
16337 int padcnt;
16338 gboolean dissected_trans;
16339 fragment_head *r_fd = NULL;
16340 tvbuff_t *pd_tvb = NULL, *d_tvb = NULL, *p_tvb = NULL;
16341 tvbuff_t *s_tvb = NULL, *sp_tvb = NULL;
16342 gboolean save_fragmented;
16343 proto_item *item;
16345 DISSECTOR_ASSERT(si);
16347 switch(si->cmd) {
16348 case SMB_COM_TRANSACTION2:
16349 /* transaction2 */
16350 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
16351 t2i = (smb_transact2_info_t *)si->sip->extra_info;
16352 } else
16353 t2i = NULL;
16354 if (t2i == NULL) {
16356 * We didn't see the matching request, so we don't
16357 * know what type of transaction this is.
16359 proto_tree_add_uint_format_value(tree, hf_smb_trans2_subcmd, tvb, 0, 0, -1,
16360 "<UNKNOWN> since request packet wasn't seen");
16361 col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
16362 } else {
16363 si->info_level = t2i->info_level;
16364 if (t2i->subcmd == -1) {
16366 * We didn't manage to extract the subcommand
16367 * from the matching request (perhaps because
16368 * the frame was short), so we don't know what
16369 * type of transaction this is.
16371 proto_tree_add_uint_format_value(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd,
16372 "<UNKNOWN> since transaction code wasn't found in request packet");
16373 col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
16374 } else {
16375 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
16376 switch (t2i->subcmd) {
16378 case 0x0001: /* FIND_FIRST2 */
16379 if (t2i->info_level == -1)
16380 item = proto_tree_add_uint_format_value(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level,
16381 "<UNKNOWN> since information level wasn't found in request packet");
16382 else
16383 item = proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
16384 PROTO_ITEM_SET_GENERATED(item);
16385 if (t2i->name) {
16386 item = proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
16387 PROTO_ITEM_SET_GENERATED(item);
16389 break;
16391 case 0x0005: /* QUERY_PATH_INFORMATION */
16392 if (t2i->info_level == -1)
16393 item = proto_tree_add_uint_format_value(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level,
16394 "<UNKNOWN> since information level wasn't found in request packet");
16395 else
16396 item = proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
16397 PROTO_ITEM_SET_GENERATED(item);
16398 if (t2i->name) {
16399 item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
16400 PROTO_ITEM_SET_GENERATED(item);
16402 break;
16404 case 0x0007: /* QUERY_FILE_INFORMATION */
16405 if (t2i->info_level == -1)
16406 item = proto_tree_add_uint_format_value(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level,
16407 "<UNKNOWN> since information level wasn't found in request packet");
16408 else
16409 item = proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
16410 PROTO_ITEM_SET_GENERATED(item);
16411 break;
16413 case 0x0003: /* QUERY_FS_INFORMATION */
16414 if (t2i->info_level == -1)
16415 item = proto_tree_add_uint_format_value(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level,
16416 "<UNKNOWN> since information level wasn't found in request packet");
16417 else
16418 item = proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
16419 PROTO_ITEM_SET_GENERATED(item);
16420 break;
16422 case 0x0004: /* SET_FS_INFORMATION */
16423 if (t2i->info_level == -1)
16424 item = proto_tree_add_uint_format_value(tree, hf_smb_sfsi_information_level, tvb, 0, 0, si->info_level,
16425 "<UNKNOWN> since information level wasn't found in request packet");
16426 else
16427 item = proto_tree_add_uint(tree, hf_smb_sfsi_information_level, tvb, 0, 0, si->info_level);
16428 PROTO_ITEM_SET_GENERATED(item);
16429 break;
16432 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
16433 val_to_str_ext(t2i->subcmd,
16434 &trans2_cmd_vals_ext,
16435 "<unknown (0x%02x)>"));
16438 break;
16441 WORD_COUNT;
16443 /* total param count, only a 16bit integer here */
16444 tp = tvb_get_letohs(tvb, offset);
16445 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
16446 offset += 2;
16448 /* total data count, only a 16 bit integer here */
16449 td = tvb_get_letohs(tvb, offset);
16450 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
16451 offset += 2;
16453 /* 2 reserved bytes */
16454 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
16455 offset += 2;
16457 /* param count */
16458 pc = tvb_get_letohs(tvb, offset);
16459 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
16460 offset += 2;
16462 /* param offset */
16463 po = tvb_get_letohs(tvb, offset);
16464 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
16465 offset += 2;
16467 /* param disp */
16468 pd = tvb_get_letohs(tvb, offset);
16469 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
16470 offset += 2;
16472 /* data count */
16473 dc = tvb_get_letohs(tvb, offset);
16474 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
16475 offset += 2;
16477 /* data offset */
16478 od = tvb_get_letohs(tvb, offset);
16479 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
16480 offset += 2;
16482 /* data disp */
16483 dd = tvb_get_letohs(tvb, offset);
16484 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
16485 offset += 2;
16487 /* setup count */
16488 sc = tvb_get_guint8(tvb, offset);
16489 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
16490 offset += 1;
16492 /* reserved byte */
16493 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
16494 offset += 1;
16497 /* if there were any setup bytes, put them in a tvb for later */
16498 if (sc) {
16499 if ((2*sc) > tvb_length_remaining(tvb, offset)) {
16500 s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
16501 } else {
16502 s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
16504 sp_tvb = tvb_new_subset_remaining(tvb, offset);
16505 } else {
16506 s_tvb = NULL;
16507 sp_tvb = NULL;
16509 offset += 2*sc;
16512 BYTE_COUNT;
16515 /* reassembly of SMB Transaction data payload.
16516 In this section we do reassembly of both the data and parameters
16517 blocks of the SMB transaction command.
16519 save_fragmented = pinfo->fragmented;
16520 /* do we need reassembly? */
16521 if ( (td!=dc) || (tp!=pc) ) {
16522 /* oh yeah, either data or parameter section needs
16523 reassembly
16525 pinfo->fragmented = TRUE;
16526 if (smb_trans_reassembly) {
16527 /* ...and we were told to do reassembly */
16528 if (pc) {
16529 r_fd = smb_trans_defragment(tree, pinfo, tvb,
16530 po, pc, pd, td+tp, si);
16533 if ((r_fd == NULL) && dc) {
16534 r_fd = smb_trans_defragment(tree, pinfo, tvb,
16535 od, dc, dd+tp, td+tp, si);
16540 /* if we got a reassembled fd structure from the reassembly routine we must
16541 create pd_tvb from it
16543 if (r_fd) {
16544 proto_item *frag_tree_item;
16546 pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
16547 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
16548 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
16552 if (pd_tvb) {
16553 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
16554 if (tp) {
16555 p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
16557 if (td) {
16558 d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
16560 } else {
16561 /* It was not reassembled. Do as best as we can.
16562 * in this case we always try to dissect the stuff if
16563 * data and param displacement is 0. i.e. for the first
16564 * (and maybe only) packet.
16566 if ( (pd == 0) && (dd == 0) ) {
16567 int min;
16568 int reported_min;
16569 min = MIN(pc,tvb_length_remaining(tvb,po));
16570 reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
16571 if (min && reported_min) {
16572 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
16574 min = MIN(dc,tvb_length_remaining(tvb,od));
16575 reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
16576 if (min && reported_min) {
16577 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
16580 * A tvbuff containing the parameters
16581 * and the data.
16582 * XXX - check pc and dc as well?
16584 if (tvb_length_remaining(tvb, po)) {
16585 pd_tvb = tvb_new_subset_remaining(tvb, po);
16592 /* parameters */
16593 if (po > offset) {
16594 /* We have some padding bytes.
16596 padcnt = po-offset;
16597 if (padcnt > bc)
16598 padcnt = bc;
16599 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
16600 COUNT_BYTES(padcnt);
16602 if ((si->cmd == SMB_COM_TRANSACTION2) && p_tvb) {
16603 /* TRANSACTION2 parameters*/
16604 dissect_transaction2_response_parameters(p_tvb, pinfo, tree, si);
16606 COUNT_BYTES(pc);
16609 /* data */
16610 if (od > offset) {
16611 /* We have some initial padding bytes.
16613 padcnt = od-offset;
16614 if (padcnt > bc)
16615 padcnt = bc;
16616 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
16617 COUNT_BYTES(padcnt);
16620 * If the data count is bigger than the count of bytes
16621 * remaining, clamp it so that the count of bytes remaining
16622 * doesn't go negative.
16624 if (dc > bc)
16625 dc = bc;
16626 COUNT_BYTES(dc);
16630 /* from now on, everything is in separate tvbuffs so we dont count
16631 the bytes with COUNT_BYTES any more.
16632 neither do we reference offset any more (which by now points to the
16633 first byte AFTER this PDU */
16636 if ((si->cmd == SMB_COM_TRANSACTION2) && d_tvb) {
16637 /* TRANSACTION2 parameters*/
16638 dissect_transaction2_response_data(d_tvb, pinfo, tree, si);
16642 if (si->cmd == SMB_COM_TRANSACTION) {
16643 smb_transact_info_t *tri;
16645 dissected_trans = FALSE;
16646 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_TRI))
16647 tri = (smb_transact_info_t *)si->sip->extra_info;
16648 else
16649 tri = NULL;
16650 if (tri != NULL) {
16651 switch(tri->subcmd) {
16653 case TRANSACTION_PIPE:
16654 /* This function is safe to call for
16655 s_tvb == sp_tvb == NULL, i.e. if we don't
16656 know them at this point.
16657 It's also safe to call if "p_tvb"
16658 or "d_tvb" are null.
16660 if ( pd_tvb) {
16661 dissected_trans = dissect_pipe_smb(
16662 sp_tvb, s_tvb, pd_tvb, p_tvb,
16663 d_tvb, NULL, pinfo, top_tree_global, si);
16665 break;
16667 case TRANSACTION_MAILSLOT:
16668 /* This one should be safe to call
16669 even if s_tvb and sp_tvb is NULL
16671 if (d_tvb) {
16672 dissected_trans = dissect_mailslot_smb(
16673 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
16674 top_tree_global, si);
16676 break;
16679 if (!dissected_trans) {
16680 /* This one is safe to call for s_tvb == p_tvb == d_tvb == NULL */
16681 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
16686 if ( (p_tvb == 0) && (d_tvb == 0) ) {
16687 col_append_str(pinfo->cinfo, COL_INFO,
16688 "[transact continuation]");
16691 pinfo->fragmented = save_fragmented;
16692 END_OF_SMB
16694 return offset;
16698 static int
16699 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
16701 guint8 wc;
16702 guint16 bc;
16704 WORD_COUNT;
16706 /* Monitor handle */
16707 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16708 offset += 2;
16710 BYTE_COUNT;
16712 END_OF_SMB
16714 return offset;
16717 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16718 END Transaction/Transaction2 Primary and secondary requests
16719 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
16722 static int
16723 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
16725 guint8 wc;
16726 guint16 bc;
16728 WORD_COUNT;
16730 if (wc != 0) {
16731 tvb_ensure_bytes_exist(tvb, offset, wc*2);
16732 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
16733 offset += wc*2;
16736 BYTE_COUNT;
16738 if (bc != 0) {
16739 tvb_ensure_bytes_exist(tvb, offset, bc);
16740 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
16741 offset += bc;
16742 bc = 0;
16745 END_OF_SMB
16747 return offset;
16750 typedef struct _smb_function {
16751 int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
16752 int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
16753 } smb_function;
16755 static smb_function smb_dissector[256] = {
16756 /* 0x00 Create Dir*/ {dissect_old_dir_request , dissect_empty},
16757 /* 0x01 Delete Dir*/ {dissect_old_dir_request , dissect_empty},
16758 /* 0x02 Open File*/ {dissect_open_file_request , dissect_open_file_response},
16759 /* 0x03 Create File*/ {dissect_create_file_request , dissect_create_file_response},
16760 /* 0x04 Close File*/ {dissect_close_file_request , dissect_empty},
16761 /* 0x05 Flush File*/ {dissect_flush_file_request , dissect_empty},
16762 /* 0x06 Delete File*/ {dissect_delete_file_request , dissect_empty},
16763 /* 0x07 Rename File*/ {dissect_rename_file_request , dissect_rename_file_response},
16764 /* 0x08 Query Info*/ {dissect_query_information_request , dissect_query_information_response},
16765 /* 0x09 Set Info*/ {dissect_set_information_request , dissect_empty},
16766 /* 0x0a Read File*/ {dissect_read_file_request , dissect_read_file_response},
16767 /* 0x0b Write File*/ {dissect_write_file_request , dissect_write_file_response},
16768 /* 0x0c Lock Byte Range*/ {dissect_lock_request , dissect_empty},
16769 /* 0x0d Unlock Byte Range*/ {dissect_lock_request , dissect_empty},
16770 /* 0x0e Create Temp*/ {dissect_create_temporary_request , dissect_create_temporary_response},
16771 /* 0x0f Create New*/ {dissect_create_file_request , dissect_create_new_response},
16773 /* 0x10 Check Dir*/ {dissect_old_dir_request , dissect_empty},
16774 /* 0x11 Process Exit*/ {dissect_empty , dissect_empty},
16775 /* 0x12 Seek File*/ {dissect_seek_file_request , dissect_seek_file_response},
16776 /* 0x13 Lock And Read*/ {dissect_read_file_request , dissect_lock_and_read_response},
16777 /* 0x14 Write And Unlock*/ {dissect_write_file_request , dissect_write_file_response},
16778 /* 0x15 */ {dissect_unknown , dissect_unknown},
16779 /* 0x16 */ {dissect_unknown , dissect_unknown},
16780 /* 0x17 */ {dissect_unknown , dissect_unknown},
16781 /* 0x18 */ {dissect_unknown , dissect_unknown},
16782 /* 0x19 */ {dissect_unknown , dissect_unknown},
16783 /* 0x1a Read Raw*/ {dissect_read_raw_request , dissect_unknown},
16784 /* 0x1b Read MPX*/ {dissect_read_mpx_request , dissect_read_mpx_response},
16785 /* 0x1c Read MPX Secondary*/ {dissect_unknown , dissect_unknown},
16786 /* 0x1d Write Raw*/ {dissect_write_raw_request , dissect_write_raw_response},
16787 /* 0x1e Write MPX*/ {dissect_write_mpx_request , dissect_write_mpx_response},
16788 /* 0x1f Write MPX Secondary*/ {dissect_unknown , dissect_unknown},
16790 /* 0x20 Write Complete*/ {dissect_unknown , dissect_write_and_close_response},
16791 /* 0x21 */ {dissect_unknown , dissect_unknown},
16792 /* 0x22 Set Info2*/ {dissect_set_information2_request , dissect_empty},
16793 /* 0x23 Query Info2*/ {dissect_query_information2_request , dissect_query_information2_response},
16794 /* 0x24 Locking And X*/ {dissect_locking_andx_request , dissect_locking_andx_response},
16795 /* 0x25 Transaction*/ {dissect_transaction_request , dissect_transaction_response},
16796 /* 0x26 Transaction Secondary*/ {dissect_transaction_request , dissect_unknown}, /*This SMB has no response */
16797 /* 0x27 IOCTL*/ {dissect_unknown , dissect_unknown},
16798 /* 0x28 IOCTL Secondary*/ {dissect_unknown , dissect_unknown},
16799 /* 0x29 Copy File*/ {dissect_copy_request , dissect_move_copy_response},
16800 /* 0x2a Move File*/ {dissect_move_request , dissect_move_copy_response},
16801 /* 0x2b Echo*/ {dissect_echo_request , dissect_echo_response},
16802 /* 0x2c Write And Close*/ {dissect_write_and_close_request , dissect_write_and_close_response},
16803 /* 0x2d Open And X*/ {dissect_open_andx_request , dissect_open_andx_response},
16804 /* 0x2e Read And X*/ {dissect_read_andx_request , dissect_read_andx_response},
16805 /* 0x2f Write And X*/ {dissect_write_andx_request , dissect_write_andx_response},
16807 /* 0x30 */ {dissect_unknown , dissect_unknown},
16808 /* 0x31 Close And Tree Disconnect */ {dissect_close_file_request , dissect_empty},
16809 /* 0x32 Transaction2*/ {dissect_transaction_request , dissect_transaction_response},
16810 /* 0x33 Transaction2 Secondary*/ {dissect_transaction_request , dissect_unknown}, /*This SMB has no response */
16811 /* 0x34 Find Close2*/ {dissect_sid , dissect_empty},
16812 /* 0x35 Find Notify Close*/ {dissect_find_notify_close , dissect_empty},
16813 /* 0x36 */ {dissect_unknown, dissect_unknown},
16814 /* 0x37 */ {dissect_unknown, dissect_unknown},
16815 /* 0x38 */ {dissect_unknown, dissect_unknown},
16816 /* 0x39 */ {dissect_unknown, dissect_unknown},
16817 /* 0x3a */ {dissect_unknown, dissect_unknown},
16818 /* 0x3b */ {dissect_unknown, dissect_unknown},
16819 /* 0x3c */ {dissect_unknown, dissect_unknown},
16820 /* 0x3d */ {dissect_unknown, dissect_unknown},
16821 /* 0x3e */ {dissect_unknown, dissect_unknown},
16822 /* 0x3f */ {dissect_unknown, dissect_unknown},
16824 /* 0x40 */ {dissect_unknown, dissect_unknown},
16825 /* 0x41 */ {dissect_unknown, dissect_unknown},
16826 /* 0x42 */ {dissect_unknown, dissect_unknown},
16827 /* 0x43 */ {dissect_unknown, dissect_unknown},
16828 /* 0x44 */ {dissect_unknown, dissect_unknown},
16829 /* 0x45 */ {dissect_unknown, dissect_unknown},
16830 /* 0x46 */ {dissect_unknown, dissect_unknown},
16831 /* 0x47 */ {dissect_unknown, dissect_unknown},
16832 /* 0x48 */ {dissect_unknown, dissect_unknown},
16833 /* 0x49 */ {dissect_unknown, dissect_unknown},
16834 /* 0x4a */ {dissect_unknown, dissect_unknown},
16835 /* 0x4b */ {dissect_unknown, dissect_unknown},
16836 /* 0x4c */ {dissect_unknown, dissect_unknown},
16837 /* 0x4d */ {dissect_unknown, dissect_unknown},
16838 /* 0x4e */ {dissect_unknown, dissect_unknown},
16839 /* 0x4f */ {dissect_unknown, dissect_unknown},
16841 /* 0x50 */ {dissect_unknown, dissect_unknown},
16842 /* 0x51 */ {dissect_unknown, dissect_unknown},
16843 /* 0x52 */ {dissect_unknown, dissect_unknown},
16844 /* 0x53 */ {dissect_unknown, dissect_unknown},
16845 /* 0x54 */ {dissect_unknown, dissect_unknown},
16846 /* 0x55 */ {dissect_unknown, dissect_unknown},
16847 /* 0x56 */ {dissect_unknown, dissect_unknown},
16848 /* 0x57 */ {dissect_unknown, dissect_unknown},
16849 /* 0x58 */ {dissect_unknown, dissect_unknown},
16850 /* 0x59 */ {dissect_unknown, dissect_unknown},
16851 /* 0x5a */ {dissect_unknown, dissect_unknown},
16852 /* 0x5b */ {dissect_unknown, dissect_unknown},
16853 /* 0x5c */ {dissect_unknown, dissect_unknown},
16854 /* 0x5d */ {dissect_unknown, dissect_unknown},
16855 /* 0x5e */ {dissect_unknown, dissect_unknown},
16856 /* 0x5f */ {dissect_unknown, dissect_unknown},
16858 /* 0x60 */ {dissect_unknown, dissect_unknown},
16859 /* 0x61 */ {dissect_unknown, dissect_unknown},
16860 /* 0x62 */ {dissect_unknown, dissect_unknown},
16861 /* 0x63 */ {dissect_unknown, dissect_unknown},
16862 /* 0x64 */ {dissect_unknown, dissect_unknown},
16863 /* 0x65 */ {dissect_unknown, dissect_unknown},
16864 /* 0x66 */ {dissect_unknown, dissect_unknown},
16865 /* 0x67 */ {dissect_unknown, dissect_unknown},
16866 /* 0x68 */ {dissect_unknown, dissect_unknown},
16867 /* 0x69 */ {dissect_unknown, dissect_unknown},
16868 /* 0x6a */ {dissect_unknown, dissect_unknown},
16869 /* 0x6b */ {dissect_unknown, dissect_unknown},
16870 /* 0x6c */ {dissect_unknown, dissect_unknown},
16871 /* 0x6d */ {dissect_unknown, dissect_unknown},
16872 /* 0x6e */ {dissect_unknown, dissect_unknown},
16873 /* 0x6f */ {dissect_unknown, dissect_unknown},
16875 /* 0x70 Tree Connect*/ {dissect_tree_connect_request , dissect_tree_connect_response},
16876 /* 0x71 Tree Disconnect*/ {dissect_empty , dissect_empty},
16877 /* 0x72 Negotiate Protocol*/ {dissect_negprot_request , dissect_negprot_response},
16878 /* 0x73 Session Setup And X*/ {dissect_session_setup_andx_request , dissect_session_setup_andx_response},
16879 /* 0x74 Logoff And X*/ {dissect_empty_andx , dissect_empty_andx},
16880 /* 0x75 Tree Connect And X*/ {dissect_tree_connect_andx_request , dissect_tree_connect_andx_response},
16881 /* 0x76 */ {dissect_unknown, dissect_unknown},
16882 /* 0x77 */ {dissect_unknown, dissect_unknown},
16883 /* 0x78 */ {dissect_unknown, dissect_unknown},
16884 /* 0x79 */ {dissect_unknown, dissect_unknown},
16885 /* 0x7a */ {dissect_unknown, dissect_unknown},
16886 /* 0x7b */ {dissect_unknown, dissect_unknown},
16887 /* 0x7c */ {dissect_unknown, dissect_unknown},
16888 /* 0x7d */ {dissect_unknown, dissect_unknown},
16889 /* 0x7e */ {dissect_unknown, dissect_unknown},
16890 /* 0x7f */ {dissect_unknown, dissect_unknown},
16892 /* 0x80 Query Info Disk*/ {dissect_empty , dissect_query_information_disk_response},
16893 /* 0x81 Search Dir*/ {dissect_search_dir_request , dissect_search_dir_response},
16894 /* 0x82 Find*/ {dissect_find_request , dissect_find_response},
16895 /* 0x83 Find Unique*/ {dissect_find_request , dissect_find_response},
16896 /* 0x84 Find Close*/ {dissect_find_close_request , dissect_find_close_response},
16897 /* 0x85 */ {dissect_unknown, dissect_unknown},
16898 /* 0x86 */ {dissect_unknown, dissect_unknown},
16899 /* 0x87 */ {dissect_unknown, dissect_unknown},
16900 /* 0x88 */ {dissect_unknown, dissect_unknown},
16901 /* 0x89 */ {dissect_unknown, dissect_unknown},
16902 /* 0x8a */ {dissect_unknown, dissect_unknown},
16903 /* 0x8b */ {dissect_unknown, dissect_unknown},
16904 /* 0x8c */ {dissect_unknown, dissect_unknown},
16905 /* 0x8d */ {dissect_unknown, dissect_unknown},
16906 /* 0x8e */ {dissect_unknown, dissect_unknown},
16907 /* 0x8f */ {dissect_unknown, dissect_unknown},
16909 /* 0x90 */ {dissect_unknown, dissect_unknown},
16910 /* 0x91 */ {dissect_unknown, dissect_unknown},
16911 /* 0x92 */ {dissect_unknown, dissect_unknown},
16912 /* 0x93 */ {dissect_unknown, dissect_unknown},
16913 /* 0x94 */ {dissect_unknown, dissect_unknown},
16914 /* 0x95 */ {dissect_unknown, dissect_unknown},
16915 /* 0x96 */ {dissect_unknown, dissect_unknown},
16916 /* 0x97 */ {dissect_unknown, dissect_unknown},
16917 /* 0x98 */ {dissect_unknown, dissect_unknown},
16918 /* 0x99 */ {dissect_unknown, dissect_unknown},
16919 /* 0x9a */ {dissect_unknown, dissect_unknown},
16920 /* 0x9b */ {dissect_unknown, dissect_unknown},
16921 /* 0x9c */ {dissect_unknown, dissect_unknown},
16922 /* 0x9d */ {dissect_unknown, dissect_unknown},
16923 /* 0x9e */ {dissect_unknown, dissect_unknown},
16924 /* 0x9f */ {dissect_unknown, dissect_unknown},
16926 /* 0xa0 NT Transaction*/ {dissect_nt_transaction_request , dissect_nt_transaction_response},
16927 /* 0xa1 NT Trans secondary*/ {dissect_nt_transaction_request , dissect_nt_transaction_response},
16928 /* 0xa2 NT CreateAndX*/ {dissect_nt_create_andx_request , dissect_nt_create_andx_response},
16929 /* 0xa3 */ {dissect_unknown , dissect_unknown},
16930 /* 0xa4 NT Cancel*/ {dissect_nt_cancel_request , dissect_unknown}, /*no response to this one*/
16931 /* 0xa5 NT Rename*/ {dissect_nt_rename_file_request , dissect_empty},
16932 /* 0xa6 */ {dissect_unknown, dissect_unknown},
16933 /* 0xa7 */ {dissect_unknown, dissect_unknown},
16934 /* 0xa8 */ {dissect_unknown, dissect_unknown},
16935 /* 0xa9 */ {dissect_unknown, dissect_unknown},
16936 /* 0xaa */ {dissect_unknown, dissect_unknown},
16937 /* 0xab */ {dissect_unknown, dissect_unknown},
16938 /* 0xac */ {dissect_unknown, dissect_unknown},
16939 /* 0xad */ {dissect_unknown, dissect_unknown},
16940 /* 0xae */ {dissect_unknown, dissect_unknown},
16941 /* 0xaf */ {dissect_unknown, dissect_unknown},
16943 /* 0xb0 */ {dissect_unknown, dissect_unknown},
16944 /* 0xb1 */ {dissect_unknown, dissect_unknown},
16945 /* 0xb2 */ {dissect_unknown, dissect_unknown},
16946 /* 0xb3 */ {dissect_unknown, dissect_unknown},
16947 /* 0xb4 */ {dissect_unknown, dissect_unknown},
16948 /* 0xb5 */ {dissect_unknown, dissect_unknown},
16949 /* 0xb6 */ {dissect_unknown, dissect_unknown},
16950 /* 0xb7 */ {dissect_unknown, dissect_unknown},
16951 /* 0xb8 */ {dissect_unknown, dissect_unknown},
16952 /* 0xb9 */ {dissect_unknown, dissect_unknown},
16953 /* 0xba */ {dissect_unknown, dissect_unknown},
16954 /* 0xbb */ {dissect_unknown, dissect_unknown},
16955 /* 0xbc */ {dissect_unknown, dissect_unknown},
16956 /* 0xbd */ {dissect_unknown, dissect_unknown},
16957 /* 0xbe */ {dissect_unknown, dissect_unknown},
16958 /* 0xbf */ {dissect_unknown, dissect_unknown},
16960 /* 0xc0 Open Print File*/ {dissect_open_print_file_request , dissect_open_print_file_response},
16961 /* 0xc1 Write Print File*/ {dissect_write_print_file_request , dissect_empty},
16962 /* 0xc2 Close Print File*/ {dissect_close_print_file_request , dissect_empty},
16963 /* 0xc3 Get Print Queue*/ {dissect_get_print_queue_request , dissect_get_print_queue_response},
16964 /* 0xc4 */ {dissect_unknown, dissect_unknown},
16965 /* 0xc5 */ {dissect_unknown, dissect_unknown},
16966 /* 0xc6 */ {dissect_unknown, dissect_unknown},
16967 /* 0xc7 */ {dissect_unknown, dissect_unknown},
16968 /* 0xc8 */ {dissect_unknown, dissect_unknown},
16969 /* 0xc9 */ {dissect_unknown, dissect_unknown},
16970 /* 0xca */ {dissect_unknown, dissect_unknown},
16971 /* 0xcb */ {dissect_unknown, dissect_unknown},
16972 /* 0xcc */ {dissect_unknown, dissect_unknown},
16973 /* 0xcd */ {dissect_unknown, dissect_unknown},
16974 /* 0xce */ {dissect_unknown, dissect_unknown},
16975 /* 0xcf */ {dissect_unknown, dissect_unknown},
16977 /* 0xd0 Send Single Block Message*/ {dissect_send_single_block_message_request , dissect_empty},
16978 /* 0xd1 Send Broadcast Message*/ {dissect_send_single_block_message_request , dissect_empty},
16979 /* 0xd2 Forward User Name*/ {dissect_forwarded_name , dissect_empty},
16980 /* 0xd3 Cancel Forward*/ {dissect_forwarded_name , dissect_empty},
16981 /* 0xd4 Get Machine Name*/ {dissect_empty , dissect_get_machine_name_response},
16982 /* 0xd5 Send Start of Multi-block Message*/ {dissect_send_multi_block_message_start_request , dissect_message_group_id},
16983 /* 0xd6 Send End of Multi-block Message*/ {dissect_message_group_id , dissect_empty},
16984 /* 0xd7 Send Text of Multi-block Message*/ {dissect_send_multi_block_message_text_request , dissect_empty},
16985 /* 0xd8 SMBreadbulk*/ {dissect_unknown , dissect_unknown},
16986 /* 0xd9 SMBwritebulk*/ {dissect_unknown , dissect_unknown},
16987 /* 0xda SMBwritebulkdata*/ {dissect_unknown , dissect_unknown},
16988 /* 0xdb */ {dissect_unknown, dissect_unknown},
16989 /* 0xdc */ {dissect_unknown, dissect_unknown},
16990 /* 0xdd */ {dissect_unknown, dissect_unknown},
16991 /* 0xde */ {dissect_unknown, dissect_unknown},
16992 /* 0xdf */ {dissect_unknown, dissect_unknown},
16994 /* 0xe0 */ {dissect_unknown, dissect_unknown},
16995 /* 0xe1 */ {dissect_unknown, dissect_unknown},
16996 /* 0xe2 */ {dissect_unknown, dissect_unknown},
16997 /* 0xe3 */ {dissect_unknown, dissect_unknown},
16998 /* 0xe4 */ {dissect_unknown, dissect_unknown},
16999 /* 0xe5 */ {dissect_unknown, dissect_unknown},
17000 /* 0xe6 */ {dissect_unknown, dissect_unknown},
17001 /* 0xe7 */ {dissect_unknown, dissect_unknown},
17002 /* 0xe8 */ {dissect_unknown, dissect_unknown},
17003 /* 0xe9 */ {dissect_unknown, dissect_unknown},
17004 /* 0xea */ {dissect_unknown, dissect_unknown},
17005 /* 0xeb */ {dissect_unknown, dissect_unknown},
17006 /* 0xec */ {dissect_unknown, dissect_unknown},
17007 /* 0xed */ {dissect_unknown, dissect_unknown},
17008 /* 0xee */ {dissect_unknown, dissect_unknown},
17009 /* 0xef */ {dissect_unknown, dissect_unknown},
17011 /* 0xf0 */ {dissect_unknown, dissect_unknown},
17012 /* 0xf1 */ {dissect_unknown, dissect_unknown},
17013 /* 0xf2 */ {dissect_unknown, dissect_unknown},
17014 /* 0xf3 */ {dissect_unknown, dissect_unknown},
17015 /* 0xf4 */ {dissect_unknown, dissect_unknown},
17016 /* 0xf5 */ {dissect_unknown, dissect_unknown},
17017 /* 0xf6 */ {dissect_unknown, dissect_unknown},
17018 /* 0xf7 */ {dissect_unknown, dissect_unknown},
17019 /* 0xf8 */ {dissect_unknown, dissect_unknown},
17020 /* 0xf9 */ {dissect_unknown, dissect_unknown},
17021 /* 0xfa */ {dissect_unknown, dissect_unknown},
17022 /* 0xfb */ {dissect_unknown, dissect_unknown},
17023 /* 0xfc */ {dissect_unknown, dissect_unknown},
17024 /* 0xfd */ {dissect_unknown, dissect_unknown},
17025 /* 0xfe */ {dissect_unknown, dissect_unknown},
17026 /* 0xff */ {dissect_unknown, dissect_unknown},
17029 static int
17030 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu, smb_info_t *si)
17032 smb_saved_info_t *sip;
17033 void *saved_pinfo_private_data = pinfo->private_data;
17034 pinfo->private_data = si;
17036 DISSECTOR_ASSERT(si);
17038 if (cmd!=0xff) {
17039 proto_item *cmd_item;
17040 proto_tree *cmd_tree;
17041 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
17043 if (first_pdu) {
17044 col_append_fstr(pinfo->cinfo, COL_INFO,
17045 "%s %s",
17046 val_to_str_ext(cmd, &smb_cmd_vals_ext, "Unknown (0x%02x)"),
17047 (si->request)? "Request" : "Response");
17048 } else {
17049 col_append_fstr(pinfo->cinfo, COL_INFO,
17050 "; %s",
17051 val_to_str_ext(cmd, &smb_cmd_vals_ext, "Unknown (0x%02x)"));
17054 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
17055 "%s %s (0x%02x)",
17056 val_to_str_ext_const(cmd, &smb_cmd_vals_ext, "Unknown"),
17057 (si->request)?"Request":"Response",
17058 cmd);
17060 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
17062 /* we track FIDs on a per transaction basis.
17063 if this was a request and the fid was seen in a reply
17064 we add a "generated" fid tree for this pdu and v.v.
17066 sip = si->sip;
17067 if (sip && sip->fid) {
17068 if ( (si->request && (!sip->fid_seen_in_request))
17069 || ((!si->request) && sip->fid_seen_in_request) ) {
17070 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE, si);
17074 dissector = (si->request)?
17075 smb_dissector[cmd].request:smb_dissector[cmd].response;
17077 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree, si);
17079 if (!tvb_offset_exists(tvb, offset-1)) {
17080 THROW(ReportedBoundsError);
17082 proto_item_set_end(cmd_item, tvb, offset);
17084 pinfo->private_data = saved_pinfo_private_data;
17085 return offset;
17088 static const value_string smb_cmd_vals[] = {
17089 { 0x00, "Create Directory" },
17090 { 0x01, "Delete Directory" },
17091 { 0x02, "Open" },
17092 { 0x03, "Create" },
17093 { 0x04, "Close" },
17094 { 0x05, "Flush" },
17095 { 0x06, "Delete" },
17096 { 0x07, "Rename" },
17097 { 0x08, "Query Information" },
17098 { 0x09, "Set Information" },
17099 { 0x0A, "Read" },
17100 { 0x0B, "Write" },
17101 { 0x0C, "Lock Byte Range" },
17102 { 0x0D, "Unlock Byte Range" },
17103 { 0x0E, "Create Temp" },
17104 { 0x0F, "Create New" },
17105 { 0x10, "Check Directory" },
17106 { 0x11, "Process Exit" },
17107 { 0x12, "Seek" },
17108 { 0x13, "Lock And Read" },
17109 { 0x14, "Write And Unlock" },
17110 { 0x15, "unknown-0x15" },
17111 { 0x16, "unknown-0x16" },
17112 { 0x17, "unknown-0x17" },
17113 { 0x18, "unknown-0x18" },
17114 { 0x19, "unknown-0x19" },
17115 { 0x1A, "Read Raw" },
17116 { 0x1B, "Read MPX" },
17117 { 0x1C, "Read MPX Secondary" },
17118 { 0x1D, "Write Raw" },
17119 { 0x1E, "Write MPX" },
17120 { 0x1F, "Write MPX Secondary" },
17121 { 0x20, "Write Complete" },
17124 * To quote
17126 * http://msdn.microsoft.com/en-us/library/ee442098.aspx
17128 * "This command was introduced in the NT LAN Manager dialect, and
17129 * was reserved but not implemented.
17131 * Clients SHOULD NOT send requests using this command code, and
17132 * servers receiving requests with this command code SHOULD return
17133 * STATUS_NOT_IMPLEMENTED (ERRDOS/ERRbadfunc)."
17135 { 0x21, "Query Server (reserved)" },
17137 { 0x22, "Set Information2" },
17138 { 0x23, "Query Information2" },
17139 { 0x24, "Locking AndX" },
17140 { 0x25, "Trans" },
17141 { 0x26, "Trans Secondary" },
17142 { 0x27, "IOCTL" },
17143 { 0x28, "IOCTL Secondary" },
17144 { 0x29, "Copy" },
17145 { 0x2A, "Move" },
17146 { 0x2B, "Echo" },
17147 { 0x2C, "Write And Close" },
17148 { 0x2D, "Open AndX" },
17149 { 0x2E, "Read AndX" },
17150 { 0x2F, "Write AndX" },
17153 * To quote
17155 * http://msdn.microsoft.com/en-us/library/ee442127.aspx
17157 * "This command was reserved but not implemented. It was also never
17158 * defined. It is listed in [SNIA], but it is not defined in that
17159 * document and does not appear in any other references.
17161 * Clients SHOULD NOT send requests using this command code, and
17162 * servers receiving requests with this command code SHOULD return
17163 * STATUS_NOT_IMPLEMENTED (ERRDOC/ERRbadfunc)."
17165 { 0x30, "New File Size (reserved)" },
17167 { 0x31, "Close And Tree Disconnect" },
17168 { 0x32, "Trans2" },
17169 { 0x33, "Trans2 Secondary" },
17170 { 0x34, "Find Close2" },
17171 { 0x35, "Find Notify Close" },
17172 { 0x70, "Tree Connect" },
17173 { 0x71, "Tree Disconnect" },
17174 { 0x72, "Negotiate Protocol" },
17175 { 0x73, "Session Setup AndX" },
17176 { 0x74, "Logoff AndX" },
17177 { 0x75, "Tree Connect AndX" },
17178 { 0x80, "Query Information Disk" },
17179 { 0x81, "Search" },
17180 { 0x82, "Find" },
17181 { 0x83, "Find Unique" },
17182 { 0x84, "Find Close" },
17183 { 0xA0, "NT Trans" },
17184 { 0xA1, "NT Trans Secondary" },
17185 { 0xA2, "NT Create AndX" },
17186 { 0xA3, "unknown-0xA3" },
17187 { 0xA4, "NT Cancel" },
17188 { 0xA5, "NT Rename" },
17189 { 0xC0, "Open Print File" },
17190 { 0xC1, "Write Print File" },
17191 { 0xC2, "Close Print File" },
17192 { 0xC3, "Get Print Queue" },
17193 { 0xD0, "Send Single Block Message" },
17194 { 0xD1, "Send Broadcast Message" },
17195 { 0xD2, "Forward User Name" },
17196 { 0xD3, "Cancel Forward" },
17197 { 0xD4, "Get Machine Name" },
17198 { 0xD5, "Send Start of Multi-block Message" },
17199 { 0xD6, "Send End of Multi-block Message" },
17200 { 0xD7, "Send Text of Multi-block Message" },
17201 { 0xD8, "SMBreadbulk" },
17202 { 0xD9, "SMBwritebulk" },
17203 { 0xDA, "SMBwritebulkdata" },
17204 { 0xFE, "SMBinvalid" },
17205 { 0x00, NULL },
17208 value_string_ext smb_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb_cmd_vals);
17211 static void
17212 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
17214 conv_tables_t *ct = (conv_tables_t *)ctarg;
17216 if (ct->unmatched)
17217 g_hash_table_destroy(ct->unmatched);
17218 if (ct->matched)
17219 g_hash_table_destroy(ct->matched);
17220 if (ct->primaries)
17221 g_hash_table_destroy(ct->primaries);
17222 if (ct->tid_service)
17223 g_hash_table_destroy(ct->tid_service);
17224 if (ct->GSL_fid_info)
17225 g_slist_free(ct->GSL_fid_info);
17226 g_free(ct);
17229 static void
17230 smb_init_protocol(void)
17233 * Free the hash tables attached to the conversation table
17234 * structures, and then free the list of conversation table
17235 * data structures.
17237 if (conv_tables) {
17238 g_slist_foreach(conv_tables, free_hash_tables, NULL);
17239 g_slist_free(conv_tables);
17240 conv_tables = NULL;
17244 static const value_string errcls_types[] = {
17245 { SMB_SUCCESS, "Success"},
17246 { SMB_ERRDOS, "DOS Error"},
17247 { SMB_ERRSRV, "Server Error"},
17248 { SMB_ERRHRD, "Hardware Error"},
17249 { SMB_ERRCMD, "Command Error - Not an SMB format command"},
17250 { 0, NULL }
17253 /* Error codes for the ERRSRV class */
17255 static const value_string SRV_errors[] = {
17256 {SMBE_error, "Non specific error code"},
17257 {SMBE_badpw, "Bad password"},
17258 {SMBE_badtype, "Reserved"},
17259 {SMBE_access, "No permissions to perform the requested operation"},
17260 {SMBE_invnid, "TID invalid"},
17261 {SMBE_invnetname, "Invalid network name. Service not found"},
17262 {SMBE_invdevice, "Invalid device"},
17263 {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
17264 {SMBE_qfull, "Print queue full"},
17265 {SMBE_qtoobig, "Queued item too big"},
17266 {SMBE_qeof, "EOF on print queue dump"},
17267 {SMBE_invpfid, "Invalid print file in smb_fid"},
17268 {SMBE_smbcmd, "Unrecognised command"},
17269 {SMBE_srverror, "SMB server internal error"},
17270 {SMBE_filespecs, "Fid and pathname invalid combination"},
17271 {SMBE_badlink, "Bad link in request ???"},
17272 {SMBE_badpermits, "Access specified for a file is not valid"},
17273 {SMBE_badpid, "Bad process id in request"},
17274 {SMBE_setattrmode, "Attribute mode invalid"},
17275 {SMBE_paused, "Message server paused"},
17276 {SMBE_msgoff, "Not receiving messages"},
17277 {SMBE_noroom, "No room for message"},
17278 {SMBE_rmuns, "Too many remote usernames"},
17279 {SMBE_timeout, "Operation timed out"},
17280 {SMBE_noresource, "No resources currently available for request."},
17281 {SMBE_toomanyuids, "Too many userids"},
17282 {SMBE_baduid, "Bad userid"},
17283 {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
17284 {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
17285 {SMBE_contMPX, "Resume MPX mode"},
17286 {SMBE_badPW, "Bad Password???"},
17287 {SMBE_nosupport, "Operation not supported"},
17288 { 0, NULL}
17291 /* Error codes for the ERRHRD class */
17293 static const value_string HRD_errors[] = {
17294 {SMBE_nowrite, "Read only media"},
17295 {SMBE_badunit, "Unknown device"},
17296 {SMBE_notready, "Drive not ready"},
17297 {SMBE_badcmd, "Unknown command"},
17298 {SMBE_data, "Data (CRC) error"},
17299 {SMBE_badreq, "Bad request structure length"},
17300 {SMBE_seek, "Seek error"},
17301 {SMBE_badmedia, "Unknown media type"},
17302 {SMBE_badsector, "Sector not found"},
17303 {SMBE_nopaper, "Printer out of paper"},
17304 {SMBE_write, "Write fault"},
17305 {SMBE_read, "Read fault"},
17306 {SMBE_general, "General failure"},
17307 {SMBE_badshare, "A open conflicts with an existing open"},
17308 {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
17309 {SMBE_wrongdisk, "The wrong disk was found in a drive"},
17310 {SMBE_FCBunavail, "No FCBs are available to process request"},
17311 {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
17312 {SMBE_diskfull, "Disk full???"},
17313 {0, NULL}
17316 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
17319 switch (errcls) {
17321 case SMB_SUCCESS:
17323 return("No Error"); /* No error ??? */
17325 case SMB_ERRDOS:
17327 return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
17329 case SMB_ERRSRV:
17331 return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
17333 case SMB_ERRHRD:
17335 return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
17337 default:
17339 return("Unknown error class!");
17345 static const true_false_string tfs_smb_flags_lock = {
17346 "Lock&Read, Write&Unlock are supported",
17347 "Lock&Read, Write&Unlock are not supported"
17349 static const true_false_string tfs_smb_flags_receive_buffer = {
17350 "Receive buffer has been posted",
17351 "Receive buffer has not been posted"
17353 static const true_false_string tfs_smb_flags_caseless = {
17354 "Path names are caseless",
17355 "Path names are case sensitive"
17357 static const true_false_string tfs_smb_flags_canon = {
17358 "Pathnames are canonicalized",
17359 "Pathnames are not canonicalized"
17361 static const true_false_string tfs_smb_flags_oplock = {
17362 "OpLock requested/granted",
17363 "OpLock not requested/granted"
17365 static const true_false_string tfs_smb_flags_notify = {
17366 "Notify client on all modifications",
17367 "Notify client only on open"
17369 static const true_false_string tfs_smb_flags_response = {
17370 "Message is a response to the client/redirector",
17371 "Message is a request to the server"
17374 static int
17375 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
17377 guint8 mask;
17378 proto_item *item;
17379 proto_tree *tree;
17381 mask = tvb_get_guint8(tvb, offset);
17383 if (parent_tree) {
17384 item = proto_tree_add_item(parent_tree, hf_smb_flags, tvb, offset, 1, ENC_NA);
17385 tree = proto_item_add_subtree(item, ett_smb_flags);
17387 proto_tree_add_boolean(tree, hf_smb_flags_response,
17388 tvb, offset, 1, mask);
17389 proto_tree_add_boolean(tree, hf_smb_flags_notify,
17390 tvb, offset, 1, mask);
17391 proto_tree_add_boolean(tree, hf_smb_flags_oplock,
17392 tvb, offset, 1, mask);
17393 proto_tree_add_boolean(tree, hf_smb_flags_canon,
17394 tvb, offset, 1, mask);
17395 proto_tree_add_boolean(tree, hf_smb_flags_caseless,
17396 tvb, offset, 1, mask);
17397 proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
17398 tvb, offset, 1, mask);
17399 proto_tree_add_boolean(tree, hf_smb_flags_lock,
17400 tvb, offset, 1, mask);
17403 offset += 1;
17404 return offset;
17409 static const true_false_string tfs_smb_flags2_long_names_allowed = {
17410 "Long file names are allowed in the response",
17411 "Long file names are not allowed in the response"
17413 static const true_false_string tfs_smb_flags2_ea = {
17414 "Extended attributes are supported",
17415 "Extended attributes are not supported"
17417 static const true_false_string tfs_smb_flags2_sec_sig = {
17418 "Security signatures are supported",
17419 "Security signatures are not supported"
17421 static const true_false_string tfs_smb_flags2_compressed = {
17422 "Compression is requested",
17423 "Compression is not requested"
17425 static const true_false_string tfs_smb_flags2_sec_sig_required = {
17426 "Security signatures are required",
17427 "Security signatures are not required"
17429 static const true_false_string tfs_smb_flags2_long_names_used = {
17430 "Path names in request are long file names",
17431 "Path names in request are not long file names"
17433 static const true_false_string tfs_smb_flags2_reparse_path = {
17434 "The request uses a @GMT reparse path",
17435 "The request does not use a @GMT reparse path"
17437 static const true_false_string tfs_smb_flags2_esn = {
17438 "Extended security negotiation is supported",
17439 "Extended security negotiation is not supported"
17441 static const true_false_string tfs_smb_flags2_dfs = {
17442 "Resolve pathnames with Dfs",
17443 "Don't resolve pathnames with Dfs"
17445 static const true_false_string tfs_smb_flags2_roe = {
17446 "Permit reads if execute-only",
17447 "Don't permit reads if execute-only"
17449 static const true_false_string tfs_smb_flags2_nt_error = {
17450 "Error codes are NT error codes",
17451 "Error codes are DOS error codes"
17453 static const true_false_string tfs_smb_flags2_string = {
17454 "Strings are Unicode",
17455 "Strings are ASCII"
17457 static int
17458 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
17460 guint16 mask;
17461 proto_item *item;
17462 proto_tree *tree;
17464 mask = tvb_get_letohs(tvb, offset);
17466 if (parent_tree) {
17467 item = proto_tree_add_item(parent_tree, hf_smb_flags2, tvb, offset, 2, ENC_LITTLE_ENDIAN);
17468 tree = proto_item_add_subtree(item, ett_smb_flags2);
17470 proto_tree_add_boolean(tree, hf_smb_flags2_string,
17471 tvb, offset, 2, mask);
17472 proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
17473 tvb, offset, 2, mask);
17474 proto_tree_add_boolean(tree, hf_smb_flags2_roe,
17475 tvb, offset, 2, mask);
17476 proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
17477 tvb, offset, 2, mask);
17478 proto_tree_add_boolean(tree, hf_smb_flags2_esn,
17479 tvb, offset, 2, mask);
17480 proto_tree_add_boolean(tree, hf_smb_flags2_reparse_path,
17481 tvb, offset, 2, mask);
17482 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
17483 tvb, offset, 2, mask);
17484 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig_required,
17485 tvb, offset, 2, mask);
17486 proto_tree_add_boolean(tree, hf_smb_flags2_compressed,
17487 tvb, offset, 2, mask);
17488 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
17489 tvb, offset, 2, mask);
17490 proto_tree_add_boolean(tree, hf_smb_flags2_ea,
17491 tvb, offset, 2, mask);
17492 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
17493 tvb, offset, 2, mask);
17495 offset += 2;
17496 return offset;
17501 #define SMB_FLAGS_DIRN 0x80
17504 static void
17505 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
17507 int offset = 0;
17508 proto_item *item = NULL, *hitem = NULL;
17509 proto_tree *tree = NULL, *htree = NULL;
17510 proto_item *tmp_item = NULL;
17511 guint8 flags;
17512 guint16 flags2;
17513 smb_info_t *si;
17514 smb_saved_info_t *sip = NULL;
17515 smb_saved_info_key_t key;
17516 smb_saved_info_key_t *new_key;
17517 guint8 errclass = 0;
17518 guint16 errcode = 0;
17519 guint32 pid_mid;
17520 conversation_t *conversation;
17521 nstime_t t, deltat;
17523 si = wmem_new0(wmem_packet_scope(), smb_info_t);
17525 top_tree_global = parent_tree;
17527 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
17528 col_clear(pinfo->cinfo, COL_INFO);
17530 /* start off using the local variable, we will allocate a new one if we
17531 need to*/
17532 si->cmd = tvb_get_guint8(tvb, offset+4);
17533 flags = tvb_get_guint8(tvb, offset+9);
17535 * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
17536 * the direction flag appears never to be set, even for what appear
17537 * to be replies. Do some SMB servers fail to set that flag,
17538 * under the assumption that the client knows it's a reply because
17539 * it received it?
17541 si->request = !(flags&SMB_FLAGS_DIRN);
17542 flags2 = tvb_get_letohs(tvb, offset+10);
17543 if (flags2 & 0x8000) {
17544 si->unicode = TRUE; /* Mark them as Unicode */
17545 } else {
17546 si->unicode = FALSE;
17548 si->tid = tvb_get_letohs(tvb, offset+24);
17549 si->pid = tvb_get_letohs(tvb, offset+26);
17550 si->uid = tvb_get_letohs(tvb, offset+28);
17551 si->mid = tvb_get_letohs(tvb, offset+30);
17552 pid_mid = (si->pid << 16) | si->mid;
17553 si->info_level = -1;
17554 si->info_count = -1;
17556 if (parent_tree) {
17557 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
17558 -1, ENC_NA);
17559 tree = proto_item_add_subtree(item, ett_smb);
17561 hitem = proto_tree_add_text(tree, tvb, offset, 32,
17562 "SMB Header");
17564 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
17567 proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
17568 offset += 4; /* Skip the marker */
17570 /* find which conversation we are part of and get the tables for that
17571 conversation*/
17572 conversation = find_or_create_conversation(pinfo);
17573 /* see if we already have the smb data for this conversation */
17574 si->ct = (conv_tables_t *)conversation_get_proto_data(conversation, proto_smb);
17575 if (!si->ct) {
17576 /* No, not yet. create it and attach it to the conversation */
17577 si->ct = (conv_tables_t *)g_malloc(sizeof(conv_tables_t));
17579 conv_tables = g_slist_prepend(conv_tables, si->ct);
17580 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
17581 smb_saved_info_equal_matched);
17582 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
17583 smb_saved_info_equal_unmatched);
17584 /* We used the same key format as the unmatched entries */
17585 si->ct->primaries = g_hash_table_new(
17586 smb_saved_info_hash_unmatched,
17587 smb_saved_info_equal_unmatched);
17588 si->ct->tid_service = g_hash_table_new(
17589 smb_saved_info_hash_unmatched,
17590 smb_saved_info_equal_unmatched);
17591 si->ct->raw_ntlmssp = 0;
17593 si->ct->fid_tree = wmem_tree_new(wmem_file_scope());
17594 si->ct->tid_tree = wmem_tree_new(wmem_file_scope());
17595 si->ct->uid_tree = wmem_tree_new(wmem_file_scope());
17596 /* Initialize the GSL_fid_info for this ct */
17597 si->ct->GSL_fid_info = NULL;
17598 conversation_add_proto_data(conversation, proto_smb, si->ct);
17601 if ( (si->request)
17602 && (si->mid == 0)
17603 && (si->uid == 0)
17604 && (si->pid == 0)
17605 && (si->tid == 0) ) {
17606 /* this is a broadcast SMB packet, there will not be a reply.
17607 We dont need to do anything
17609 si->unidir = TRUE;
17610 } else if ( (si->cmd == SMB_COM_NT_CANCEL) /* NT Cancel */
17611 || (si->cmd == SMB_COM_TRANSACTION_SECONDARY) /* Transaction Secondary */
17612 || (si->cmd == SMB_COM_TRANSACTION2_SECONDARY) /* Transaction2 Secondary */
17613 || (si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)) { /* NT Transaction Secondary */
17614 /* Ok, we got a special request type. This request is either
17615 an NT Cancel or a continuation relative to a real request
17616 in an earlier packet. In either case, we don't expect any
17617 responses to this packet. For continuations, any later
17618 responses we see really just belong to the original request.
17619 Anyway, we want to remember this packet somehow and
17620 remember which original request it is associated with so
17621 we can say nice things such as "This is a Cancellation to
17622 the request in frame x", but we don't want the
17623 request/response matching to get messed up.
17625 The only thing we do in this case is trying to find which original
17626 request we match with and insert an entry for this "special"
17627 request for later reference. We continue to reference the original
17628 requests smb_saved_info_t but we dont touch it or change anything
17629 in it.
17632 si->unidir = TRUE; /*we dont expect an answer to this one*/
17634 if (!pinfo->fd->flags.visited) {
17635 /* try to find which original call we match and if we
17636 find it add us to the matched table. Dont touch
17637 anything else since we dont want this one to mess
17638 up the request/response matching. We still consider
17639 the initial call the real request and this is only
17640 some sort of continuation.
17642 /* we only check the unmatched table and assume that the
17643 last seen MID matching ours is the right one.
17644 This can fail but is better than nothing
17646 sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17647 if (sip!=NULL) {
17648 new_key = (smb_saved_info_key_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_key_t));
17649 new_key->frame = pinfo->fd->num;
17650 new_key->pid_mid = pid_mid;
17651 g_hash_table_insert(si->ct->matched, new_key,
17652 sip);
17653 } else {
17654 if ((si->cmd == SMB_COM_TRANSACTION_SECONDARY) ||
17655 (si->cmd == SMB_COM_TRANSACTION2_SECONDARY) ||
17656 (si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)) {
17657 sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
17660 } else {
17661 /* we have seen this packet before; check the
17662 matching table
17664 key.frame = pinfo->fd->num;
17665 key.pid_mid = pid_mid;
17666 sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->matched, &key);
17667 if (sip == NULL) {
17669 We didn't find it.
17670 Too bad, unfortunately there is not really much we can
17671 do now since this means that we never saw the initial
17672 request.
17678 if (sip && sip->frame_req) {
17679 switch(si->cmd) {
17680 case SMB_COM_NT_CANCEL:
17681 tmp_item = proto_tree_add_uint(htree, hf_smb_cancel_to,
17682 tvb, 0, 0, sip->frame_req);
17683 PROTO_ITEM_SET_GENERATED(tmp_item);
17684 break;
17685 case SMB_COM_TRANSACTION_SECONDARY:
17686 case SMB_COM_TRANSACTION2_SECONDARY:
17687 case SMB_COM_NT_TRANSACT_SECONDARY:
17688 tmp_item = proto_tree_add_uint(htree, hf_smb_continuation_to,
17689 tvb, 0, 0, sip->frame_req);
17690 PROTO_ITEM_SET_GENERATED(tmp_item);
17691 break;
17693 } else {
17694 switch(si->cmd) {
17695 case SMB_COM_NT_CANCEL:
17696 proto_tree_add_text(htree, tvb, 0, 0,
17697 "Cancellation to: <unknown frame>");
17698 break;
17699 case SMB_COM_TRANSACTION_SECONDARY:
17700 case SMB_COM_TRANSACTION2_SECONDARY:
17701 case SMB_COM_NT_TRANSACT_SECONDARY:
17702 proto_tree_add_text(htree, tvb, 0, 0,
17703 "Continuation to: <unknown frame>");
17704 break;
17707 } else { /* normal bidirectional request or response */
17708 si->unidir = FALSE;
17710 if (!pinfo->fd->flags.visited) {
17711 /* first see if we find an unmatched smb "equal" to
17712 the current one
17714 sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17715 if (sip!=NULL) {
17716 gboolean cmd_match = FALSE;
17719 * Make sure the SMB we found was the
17720 * same command, or a different command
17721 * that's another valid type of reply
17722 * to that command.
17724 if (si->cmd == sip->cmd) {
17725 cmd_match = TRUE;
17727 else if (si->cmd == SMB_COM_NT_CANCEL) {
17728 cmd_match = TRUE;
17730 else if ((si->cmd == SMB_COM_TRANSACTION_SECONDARY)
17731 && (sip->cmd == SMB_COM_TRANSACTION)) {
17732 cmd_match = TRUE;
17734 else if ((si->cmd == SMB_COM_TRANSACTION2_SECONDARY)
17735 && (sip->cmd == SMB_COM_TRANSACTION2)) {
17736 cmd_match = TRUE;
17738 else if ((si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)
17739 && (sip->cmd == SMB_COM_NT_TRANSACT)) {
17740 cmd_match = TRUE;
17743 if ( (si->request) || (!cmd_match) ) {
17744 /* We are processing an SMB request but there was already
17745 another "identical" smb request we had not matched yet.
17746 This must mean that either we have a retransmission or that the
17747 response to the previous one was lost and the client has reused
17748 the MID for this conversation. In either case it's not much more
17749 we can do than forget the old request and concentrate on the
17750 present one instead.
17752 We also do this cleanup if we see that the cmd in the original
17753 request in sip->cmd is not compatible with the current cmd.
17754 This is to prevent matching errors such as if there were two
17755 SMBs of different cmds but with identical MID and PID values and
17756 if wireshark lost the first reply and the second request.
17758 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17759 sip = NULL; /* XXX should free it as well */
17760 } else {
17761 /* we have found a response to some
17762 request we have seen earlier.
17763 What we do now depends on whether
17764 this is the first response to that
17765 request we see (id frame_res == 0) or
17766 if it's a response to a request
17767 for which we've seen an earlier
17768 response that's continued.
17770 if ((sip->frame_res == 0) ||
17771 (sip->flags & SMB_SIF_IS_CONTINUED)) {
17772 /* OK, it is the first response
17773 we have seen to this packet,
17774 or it's a continuation of
17775 a response we've seen. */
17776 sip->frame_res = pinfo->fd->num;
17777 new_key = (smb_saved_info_key_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_key_t));
17778 new_key->frame = sip->frame_res;
17779 new_key->pid_mid = pid_mid;
17780 g_hash_table_insert(si->ct->matched, new_key, sip);
17781 /* We remove the entry for unmatched since we have found a match.
17782 * We have to do this since the MID value wraps so quickly (effective only 10 bits)
17783 * and if there is packetloss in the trace (maybe due to large holes
17784 * created by a sniffer device not being able to keep up
17785 * with the line rate.
17786 * There is a real possibility that the following would occur which is painful :
17787 * 1, -> Request MID:5
17788 * 2, <- Response MID:5
17789 * 3, -> Request MID:5 (missing from capture)
17790 * 4, <- Response MID:5
17791 * We DONT want #4 to be presented as a response to #1
17793 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17794 } else {
17795 /* We have already seen another response to this MID.
17796 Since the MID in reality is only something like 10 bits
17797 this probably means that we just have a MID that is being
17798 reused due to the small MID space and that this is a new
17799 command we did not see the original request for.
17801 sip = NULL;
17804 } else {
17805 if ((si->cmd == SMB_COM_TRANSACTION) ||
17806 (si->cmd == SMB_COM_TRANSACTION2) ||
17807 (si->cmd == SMB_COM_NT_TRANSACT)) {
17808 sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
17811 if (si->request) {
17812 sip = (smb_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_t));
17813 sip->frame_req = pinfo->fd->num;
17814 sip->frame_res = 0;
17815 sip->req_time = pinfo->fd->abs_ts;
17816 sip->flags = 0;
17817 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
17818 == (void *)TID_IPC) {
17819 sip->flags |= SMB_SIF_TID_IS_IPC;
17821 sip->cmd = si->cmd;
17822 sip->extra_info = NULL;
17823 sip->extra_info_type = SMB_EI_NONE;
17824 sip->fid = 0;
17825 sip->fid_seen_in_request = 0;
17826 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
17827 new_key = (smb_saved_info_key_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_key_t));
17828 new_key->frame = sip->frame_req;
17829 new_key->pid_mid = pid_mid;
17830 g_hash_table_insert(si->ct->matched, new_key, sip);
17832 /* If it is a TRANSACT cmd, insert in hash */
17833 if ((si->cmd == SMB_COM_TRANSACTION) ||
17834 (si->cmd == SMB_COM_TRANSACTION2) ||
17835 (si->cmd == SMB_COM_NT_TRANSACT)) {
17836 g_hash_table_insert(si->ct->primaries, GUINT_TO_POINTER(pid_mid), sip);
17839 } else {
17840 /* we have seen this packet before; check the
17841 matching table.
17842 If we haven't yet seen the reply, we won't
17843 find the info for it; we don't need it, as
17844 we only use it to save information, and, as
17845 we've seen this packet before, we've already
17846 saved the information.
17848 key.frame = pinfo->fd->num;
17849 key.pid_mid = pid_mid;
17850 sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->matched, &key);
17855 * Pass the "sip" on to subdissectors through "si".
17857 si->sip = sip;
17859 if (sip != NULL) {
17861 * Put in fields for the frame number of the frame to which
17862 * this is a response or the frame with the response to this
17863 * frame - if we know the frame number (i.e., it's not 0).
17865 if (si->request) {
17866 if (sip->frame_res != 0) {
17867 tmp_item = proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
17868 PROTO_ITEM_SET_GENERATED(tmp_item);
17870 } else {
17871 if (sip->frame_req != 0) {
17872 tmp_item = proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
17873 PROTO_ITEM_SET_GENERATED(tmp_item);
17874 t = pinfo->fd->abs_ts;
17875 nstime_delta(&deltat, &t, &sip->req_time);
17876 tmp_item = proto_tree_add_time(htree, hf_smb_time, tvb,
17877 0, 0, &deltat);
17878 PROTO_ITEM_SET_GENERATED(tmp_item);
17883 /* smb command */
17884 proto_tree_add_uint(htree, hf_smb_cmd, tvb, offset, 1, si->cmd);
17885 offset += 1;
17887 if (flags2 & 0x4000) {
17888 /* handle NT 32 bit error code */
17890 si->nt_status = tvb_get_letohl(tvb, offset);
17892 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
17893 ENC_LITTLE_ENDIAN);
17894 offset += 4;
17896 } else {
17897 /* handle DOS error code & class */
17898 errclass = tvb_get_guint8(tvb, offset);
17899 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
17900 errclass);
17901 offset += 1;
17903 /* reserved byte */
17904 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
17905 offset += 1;
17907 /* error code */
17908 /* XXX - the type of this field depends on the value of
17909 * "errcls", so there is isn't a single value_string array
17910 * fo it, so there can't be a single field for it.
17912 errcode = tvb_get_letohs(tvb, offset);
17913 proto_tree_add_uint_format_value(htree, hf_smb_error_code, tvb,
17914 offset, 2, errcode, "%s",
17915 decode_smb_error(errclass, errcode));
17916 offset += 2;
17919 /* flags */
17920 offset = dissect_smb_flags(tvb, htree, offset);
17922 /* flags2 */
17923 offset = dissect_smb_flags2(tvb, htree, offset);
17926 * The document at
17928 * http://www.samba.org/samba/ftp/specs/smbpub.txt
17930 * (a text version of "Microsoft Networks SMB FILE SHARING
17931 * PROTOCOL, Document Version 6.0p") says that:
17933 * the first 2 bytes of these 12 bytes are, for NT Create and X,
17934 * the "High Part of PID";
17936 * the next four bytes are reserved;
17938 * the next four bytes are, for SMB-over-IPX (with no
17939 * NetBIOS involved) two bytes of Session ID and two bytes
17940 * of SequenceNumber.
17942 * Network Monitor 2.x dissects the four bytes before the Session ID
17943 * as a "Key", and the two bytes after the SequenceNumber as
17944 * a "Group ID".
17946 * The "High Part of PID" has been seen in calls other than NT
17947 * Create and X, although most of them appear to be I/O on DCE RPC
17948 * pipes opened with the NT Create and X in question.
17950 proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, ENC_LITTLE_ENDIAN);
17951 offset += 2;
17953 if ((pinfo->ptype == PT_IPX) &&
17954 ((pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_SERVER) ||
17955 (pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_REDIR) ||
17956 (pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_MESSENGER))) {
17958 * This is SMB-over-IPX.
17959 * XXX - do we have to worry about "sequenced commands",
17960 * as per the Samba document? They say that for
17961 * "unsequenced commands" (with a sequence number of 0),
17962 * the Mid must be unique, but perhaps the Mid doesn't
17963 * have to be unique for sequenced commands. In at least
17964 * one capture with SMB-over-IPX, however, the Mids
17965 * are unique even for sequenced commands.
17967 /* Key */
17968 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
17969 ENC_LITTLE_ENDIAN);
17970 offset += 4;
17972 /* Session ID */
17973 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
17974 ENC_LITTLE_ENDIAN);
17975 offset += 2;
17977 /* Sequence number */
17978 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
17979 ENC_LITTLE_ENDIAN);
17980 offset += 2;
17982 /* Group ID */
17983 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
17984 ENC_LITTLE_ENDIAN);
17985 offset += 2;
17986 } else {
17988 * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
17989 * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
17990 * bytes after the "High part of PID" are an 8-byte
17991 * signature ...
17993 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, ENC_NA);
17994 offset += 8;
17996 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
17997 offset += 2;
18000 /* TID
18001 * TreeConnectAndX(0x75) is special, here it is the mere fact of
18002 * having a response that means that the share was mapped and we
18003 * need to track it
18005 if (!pinfo->fd->flags.visited && (si->cmd == 0x75) && !si->request) {
18006 offset = dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE, si);
18007 } else {
18008 offset = dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE, si);
18011 /* PID */
18012 proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
18013 offset += 2;
18015 /* UID */
18016 offset = dissect_smb_uid(tvb, htree, offset, si);
18018 /* MID */
18019 proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
18020 offset += 2;
18022 /* tap the packet before the dissectors are called so we still get
18023 the tap listener called even if there is an exception.
18025 tap_queue_packet(smb_tap, pinfo, si);
18026 dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE, si);
18028 /* Append error info from this packet to info string. */
18029 if (!si->request) {
18030 if (flags2 & 0x4000) {
18032 * The status is an NT status code; was there
18033 * an error?
18035 if ((si->nt_status & 0xC0000000) == 0xC0000000) {
18037 * Yes.
18039 col_append_fstr(
18040 pinfo->cinfo, COL_INFO, ", Error: %s",
18041 val_to_str(si->nt_status, NT_errors,
18042 "Unknown (0x%08X)"));
18044 } else {
18046 * The status is a DOS error class and code; was
18047 * there an error?
18049 if (errclass != SMB_SUCCESS) {
18051 * Yes.
18053 col_append_fstr(
18054 pinfo->cinfo, COL_INFO, ", Error: %s",
18055 decode_smb_error(errclass, errcode));
18061 static gboolean
18062 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
18064 /* must check that this really is a smb packet */
18065 if (tvb_length(tvb) < 4)
18066 return FALSE;
18068 if ( (tvb_get_guint8(tvb, 0) != 0xff)
18069 || (tvb_get_guint8(tvb, 1) != 'S')
18070 || (tvb_get_guint8(tvb, 2) != 'M')
18071 || (tvb_get_guint8(tvb, 3) != 'B') ) {
18072 return FALSE;
18075 dissect_smb(tvb, pinfo, parent_tree);
18076 return TRUE;
18079 void
18080 proto_register_smb(void)
18082 static hf_register_info hf[] = {
18083 { &hf_smb_cmd,
18084 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
18085 &smb_cmd_vals_ext, 0x0, NULL, HFILL }},
18087 { &hf_smb_andxcmd,
18088 { "AndXCommand", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
18089 &smb_cmd_vals_ext, 0x0, NULL, HFILL }},
18091 { &hf_smb_trans2_subcmd,
18092 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
18093 &trans2_cmd_vals_ext, 0, "Subcommand for TRANSACTION2", HFILL }},
18095 { &hf_smb_nt_trans_subcmd,
18096 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
18097 &nt_cmd_vals_ext, 0, "Function for NT Transaction", HFILL }},
18099 { &hf_smb_word_count,
18100 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
18101 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
18103 { &hf_smb_byte_count,
18104 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
18105 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
18107 { &hf_smb_response_to,
18108 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
18109 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
18111 { &hf_smb_time,
18112 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
18113 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
18115 { &hf_smb_response_in,
18116 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
18117 NULL, 0, "The response to this packet is in this packet", HFILL }},
18119 { &hf_smb_continuation_to,
18120 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
18121 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
18123 { &hf_smb_nt_status,
18124 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
18125 VALS(NT_errors), 0, "NT Status code", HFILL }},
18127 { &hf_smb_error_class,
18128 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
18129 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
18131 { &hf_smb_error_code,
18132 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
18133 NULL, 0, "DOS Error Code", HFILL }},
18135 { &hf_smb_reserved,
18136 { "Reserved", "smb.reserved", FT_BYTES, BASE_NONE,
18137 NULL, 0, "Reserved bytes, must be zero", HFILL }},
18139 { &hf_smb_sig,
18140 { "Signature", "smb.signature", FT_BYTES, BASE_NONE,
18141 NULL, 0, "Signature bytes", HFILL }},
18143 { &hf_smb_key,
18144 { "Key", "smb.key", FT_UINT32, BASE_HEX,
18145 NULL, 0, "SMB-over-IPX Key", HFILL }},
18147 { &hf_smb_session_id,
18148 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
18149 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
18151 { &hf_smb_sequence_num,
18152 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
18153 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
18155 { &hf_smb_group_id,
18156 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
18157 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
18159 { &hf_smb_pid,
18160 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
18161 NULL, 0, NULL, HFILL }},
18163 { &hf_smb_pid_high,
18164 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
18165 NULL, 0, "Process ID High Bytes", HFILL }},
18167 { &hf_smb_tid,
18168 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
18169 NULL, 0, NULL, HFILL }},
18171 { &hf_smb_uid,
18172 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
18173 NULL, 0, NULL, HFILL }},
18175 { &hf_smb_mid,
18176 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
18177 NULL, 0, NULL, HFILL }},
18179 { &hf_smb_flags,
18180 { "Flags", "smb.flags", FT_UINT8, BASE_HEX,
18181 NULL, 0x0, NULL, HFILL }},
18183 { &hf_smb_flags_lock,
18184 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
18185 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
18187 { &hf_smb_flags_receive_buffer,
18188 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
18189 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
18191 { &hf_smb_flags_caseless,
18192 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
18193 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
18195 { &hf_smb_flags_canon,
18196 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
18197 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
18199 { &hf_smb_flags_oplock,
18200 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
18201 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
18203 { &hf_smb_flags_notify,
18204 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
18205 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
18207 { &hf_smb_flags_response,
18208 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
18209 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
18211 { &hf_smb_flags2,
18212 { "Flags2", "smb.flags2", FT_UINT16, BASE_HEX,
18213 NULL, 0x0, NULL, HFILL }},
18215 { &hf_smb_flags2_long_names_allowed,
18216 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
18217 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
18219 { &hf_smb_flags2_ea,
18220 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
18221 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
18223 { &hf_smb_flags2_sec_sig,
18224 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
18225 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
18227 { &hf_smb_flags2_compressed,
18228 { "Compressed", "smb.flags2.compressed", FT_BOOLEAN, 16,
18229 TFS(&tfs_smb_flags2_compressed), 0x0008, "Is compression requested?", HFILL }},
18231 { &hf_smb_flags2_sec_sig_required,
18232 { "Security Signatures Required", "smb.flags2.sec_sig_required", FT_BOOLEAN, 16,
18233 TFS(&tfs_smb_flags2_sec_sig_required), 0x0010, "Are security signatures required?", HFILL }},
18235 { &hf_smb_flags2_long_names_used,
18236 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
18237 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
18239 { &hf_smb_flags2_reparse_path,
18240 { "Reparse Path", "smb.flags2.reparse_path", FT_BOOLEAN, 16,
18241 TFS(&tfs_smb_flags2_reparse_path), 0x0400, "The request uses a @GMT reparse path", HFILL }},
18243 { &hf_smb_flags2_esn,
18244 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
18245 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
18247 { &hf_smb_flags2_dfs,
18248 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
18249 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
18251 { &hf_smb_flags2_roe,
18252 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
18253 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
18255 { &hf_smb_flags2_nt_error,
18256 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
18257 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
18259 { &hf_smb_flags2_string,
18260 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
18261 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
18263 { &hf_smb_buffer_format,
18264 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
18265 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
18267 { &hf_smb_dialect,
18268 { "Dialect", "smb.dialect", FT_STRING, BASE_NONE,
18269 NULL, 0x0, NULL, HFILL }},
18271 { &hf_smb_dialect_name,
18272 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
18273 NULL, 0, "Name of dialect", HFILL }},
18275 { &hf_smb_dialect_index,
18276 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
18277 NULL, 0, "Index of selected dialect", HFILL }},
18279 { &hf_smb_max_trans_buf_size,
18280 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
18281 NULL, 0, "Maximum transmit buffer size", HFILL }},
18283 { &hf_smb_max_mpx_count,
18284 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
18285 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
18287 { &hf_smb_max_vcs_num,
18288 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
18289 NULL, 0, "Maximum VCs between client and server", HFILL }},
18291 { &hf_smb_session_key,
18292 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
18293 NULL, 0, "Unique token identifying this session", HFILL }},
18295 { &hf_smb_server_timezone,
18296 { "Server Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
18297 NULL, 0, "Current timezone at server.", HFILL }},
18299 { &hf_smb_encryption_key_length,
18300 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
18301 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
18303 { &hf_smb_encryption_key,
18304 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_NONE,
18305 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
18307 { &hf_smb_primary_domain,
18308 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
18309 NULL, 0, "The server's primary domain", HFILL }},
18311 { &hf_smb_server,
18312 { "Server", "smb.server", FT_STRING, BASE_NONE,
18313 NULL, 0, "The name of the DC/server", HFILL }},
18315 { &hf_smb_max_raw_buf_size,
18316 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
18317 NULL, 0, "Maximum raw buffer size", HFILL }},
18319 { &hf_smb_server_guid,
18320 { "Server GUID", "smb.server_guid", FT_GUID, BASE_NONE,
18321 NULL, 0, "Globally unique identifier for this server", HFILL }},
18323 { &hf_smb_volume_guid,
18324 { "Volume GUID", "smb.volume_guid", FT_GUID, BASE_NONE,
18325 NULL, 0, "Globally unique identifer for this volume", HFILL }},
18327 { &hf_smb_security_blob_len,
18328 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
18329 NULL, 0, NULL, HFILL }},
18331 { &hf_smb_security_blob,
18332 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_NONE,
18333 NULL, 0, NULL, HFILL }},
18335 { &hf_smb_sm16,
18336 { "Security Mode", "smb.sm", FT_UINT16, BASE_HEX,
18337 NULL, 0x0, NULL, HFILL }},
18339 { &hf_smb_sm_mode16,
18340 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
18341 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
18343 { &hf_smb_sm_password16,
18344 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
18345 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
18347 { &hf_smb_sm,
18348 { "Security Mode", "smb.sm", FT_UINT8, BASE_HEX,
18349 NULL, 0x0, NULL, HFILL }},
18351 { &hf_smb_sm_mode,
18352 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
18353 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
18355 { &hf_smb_sm_password,
18356 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
18357 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
18359 { &hf_smb_sm_signatures,
18360 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
18361 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
18363 { &hf_smb_sm_sig_required,
18364 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
18365 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
18367 { &hf_smb_rm,
18368 { "Raw Mode", "smb.rm", FT_UINT16, BASE_HEX,
18369 NULL, 0x0, NULL, HFILL }},
18371 { &hf_smb_rm_read,
18372 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
18373 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
18375 { &hf_smb_rm_write,
18376 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
18377 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
18379 { &hf_smb_server_date_time,
18380 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18381 NULL, 0, "Current date and time at server", HFILL }},
18383 { &hf_smb_server_smb_date,
18384 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
18385 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
18387 { &hf_smb_server_smb_time,
18388 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
18389 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
18391 { &hf_smb_server_cap,
18392 { "Capabilities", "smb.server_cap", FT_UINT32, BASE_HEX,
18393 NULL, 0x0, NULL, HFILL }},
18395 { &hf_smb_server_cap_raw_mode,
18396 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
18397 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
18399 { &hf_smb_server_cap_mpx_mode,
18400 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
18401 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
18403 { &hf_smb_server_cap_unicode,
18404 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
18405 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
18407 { &hf_smb_server_cap_large_files,
18408 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
18409 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
18411 { &hf_smb_server_cap_nt_smbs,
18412 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
18413 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
18415 { &hf_smb_server_cap_rpc_remote_apis,
18416 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
18417 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
18419 { &hf_smb_server_cap_nt_status,
18420 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
18421 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
18423 { &hf_smb_server_cap_level_ii_oplocks,
18424 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
18425 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
18427 { &hf_smb_server_cap_lock_and_read,
18428 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
18429 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
18431 { &hf_smb_server_cap_nt_find,
18432 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
18433 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
18435 { &hf_smb_server_cap_dfs,
18436 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
18437 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
18439 { &hf_smb_server_cap_infolevel_passthru,
18440 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
18441 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
18443 { &hf_smb_server_cap_large_readx,
18444 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
18445 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
18447 { &hf_smb_server_cap_large_writex,
18448 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
18449 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
18451 { &hf_smb_server_cap_lwio,
18452 { "LWIO", "smb.server_cap.lwio", FT_BOOLEAN, 32,
18453 TFS(&tfs_server_cap_lwio), SERVER_CAP_LWIO,
18454 "Is IOCTL/FSCTL supported", HFILL }},
18456 { &hf_smb_server_cap_unix,
18457 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
18458 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
18460 { &hf_smb_server_cap_compressed_data,
18461 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
18462 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
18464 { &hf_smb_server_cap_dynamic_reauth,
18465 { "Dynamic Reauth", "smb.server_cap.dynamic_reauth", FT_BOOLEAN, 32,
18466 TFS(&tfs_server_cap_dynamic_reauth), SERVER_CAP_DYNAMIC_REAUTH,
18467 "Is dynamic reauth supported?", HFILL }},
18469 { &hf_smb_server_cap_extended_security,
18470 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
18471 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
18473 { &hf_smb_system_time,
18474 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18475 NULL, 0, NULL, HFILL }},
18477 { &hf_smb_unknown,
18478 { "Unknown Data", "smb.unknown_data", FT_BYTES, BASE_NONE,
18479 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
18481 { &hf_smb_dir_name,
18482 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
18483 NULL, 0, "SMB Directory Name", HFILL }},
18485 { &hf_smb_echo_count,
18486 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
18487 NULL, 0, "Number of times to echo data back", HFILL }},
18489 { &hf_smb_echo_data,
18490 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_NONE,
18491 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
18493 { &hf_smb_echo_seq_num,
18494 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
18495 NULL, 0, "Sequence number for this echo response", HFILL }},
18497 { &hf_smb_max_buf_size,
18498 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
18499 NULL, 0, "Max client buffer size", HFILL }},
18501 { &hf_smb_path,
18502 { "Path", "smb.path", FT_STRING, BASE_NONE,
18503 NULL, 0, "Path. Server name and share name", HFILL }},
18505 { &hf_smb_service,
18506 { "Service", "smb.service", FT_STRING, BASE_NONE,
18507 NULL, 0, "Service name", HFILL }},
18509 { &hf_smb_password,
18510 { "Password", "smb.password", FT_BYTES, BASE_NONE,
18511 NULL, 0, NULL, HFILL }},
18513 { &hf_smb_ansi_password,
18514 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
18515 NULL, 0, NULL, HFILL }},
18517 { &hf_smb_unicode_password,
18518 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
18519 NULL, 0, NULL, HFILL }},
18521 { &hf_smb_move_flags,
18522 { "Flags", "smb.move.flags", FT_UINT16, BASE_HEX,
18523 NULL, 0x0, NULL, HFILL }},
18525 { &hf_smb_move_flags_file,
18526 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
18527 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
18529 { &hf_smb_move_flags_dir,
18530 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
18531 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
18533 { &hf_smb_move_flags_verify,
18534 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
18535 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
18537 { &hf_smb_files_moved,
18538 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
18539 NULL, 0, "Number of files moved", HFILL }},
18541 { &hf_smb_copy_flags,
18542 { "Flags", "smb.copy.flags", FT_UINT16, BASE_HEX,
18543 NULL, 0x0, NULL, HFILL }},
18545 { &hf_smb_copy_flags_file,
18546 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
18547 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
18549 { &hf_smb_copy_flags_dir,
18550 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
18551 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
18553 { &hf_smb_copy_flags_dest_mode,
18554 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
18555 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
18557 { &hf_smb_copy_flags_source_mode,
18558 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
18559 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
18561 { &hf_smb_copy_flags_verify,
18562 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
18563 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
18565 { &hf_smb_copy_flags_tree_copy,
18566 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
18567 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
18569 { &hf_smb_copy_flags_ea_action,
18570 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
18571 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
18573 { &hf_smb_count,
18574 { "Count", "smb.count", FT_UINT32, BASE_DEC,
18575 NULL, 0, "Count number of items/bytes", HFILL }},
18577 { &hf_smb_count_low,
18578 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
18579 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
18581 { &hf_smb_count_high,
18582 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
18583 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
18585 { &hf_smb_file_name,
18586 { "File Name", "smb.file", FT_STRING, BASE_NONE,
18587 NULL, 0, NULL, HFILL }},
18589 { &hf_smb_open_function,
18590 { "Open Function", "smb.open.function", FT_UINT16, BASE_HEX,
18591 NULL, 0x0, NULL, HFILL }},
18593 { &hf_smb_open_function_create,
18594 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
18595 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
18597 { &hf_smb_open_function_open,
18598 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
18599 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
18601 { &hf_smb_fid,
18602 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
18603 NULL, 0, "FID: File ID", HFILL }},
18605 { &hf_smb_file_attr_16bit,
18606 { "File Attributes", "smb.file_attribute", FT_UINT16, BASE_HEX,
18607 NULL, 0x0, NULL, HFILL }},
18609 { &hf_smb_file_attr_8bit,
18610 { "File Attributes", "smb.file_attribute", FT_UINT8, BASE_HEX,
18611 NULL, 0x0, NULL, HFILL }},
18613 { &hf_smb_file_attr_read_only_16bit,
18614 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
18615 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18617 { &hf_smb_file_attr_read_only_8bit,
18618 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
18619 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18621 { &hf_smb_file_attr_hidden_16bit,
18622 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
18623 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18625 { &hf_smb_file_attr_hidden_8bit,
18626 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
18627 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18629 { &hf_smb_file_attr_system_16bit,
18630 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
18631 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18633 { &hf_smb_file_attr_system_8bit,
18634 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
18635 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18637 { &hf_smb_file_attr_volume_16bit,
18638 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
18639 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18641 { &hf_smb_file_attr_volume_8bit,
18642 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
18643 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
18645 { &hf_smb_file_attr_directory_16bit,
18646 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
18647 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18649 { &hf_smb_file_attr_directory_8bit,
18650 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
18651 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18653 { &hf_smb_file_attr_archive_16bit,
18654 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
18655 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18657 { &hf_smb_file_attr_archive_8bit,
18658 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
18659 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18661 #if 0
18662 { &hf_smb_file_attr_device,
18663 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
18664 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18666 { &hf_smb_file_attr_normal,
18667 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
18668 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18670 { &hf_smb_file_attr_temporary,
18671 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
18672 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18674 { &hf_smb_file_attr_sparse,
18675 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
18676 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18678 { &hf_smb_file_attr_reparse,
18679 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
18680 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18682 { &hf_smb_file_attr_compressed,
18683 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
18684 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18686 { &hf_smb_file_attr_offline,
18687 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
18688 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18690 { &hf_smb_file_attr_not_content_indexed,
18691 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
18692 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18694 { &hf_smb_file_attr_encrypted,
18695 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
18696 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18697 #endif
18699 { &hf_smb_file_size,
18700 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
18701 NULL, 0, NULL, HFILL }},
18703 { &hf_smb_search_attribute,
18704 { "Search Attributes", "smb.search.attribute", FT_UINT16, BASE_HEX,
18705 NULL, 0x0, NULL, HFILL }},
18707 { &hf_smb_search_attribute_read_only,
18708 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
18709 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
18711 { &hf_smb_search_attribute_hidden,
18712 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
18713 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
18715 { &hf_smb_search_attribute_system,
18716 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
18717 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
18719 { &hf_smb_search_attribute_volume,
18720 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
18721 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
18723 { &hf_smb_search_attribute_directory,
18724 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
18725 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
18727 { &hf_smb_search_attribute_archive,
18728 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
18729 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
18731 { &hf_smb_access_mode,
18732 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
18733 VALS(da_access_vals), 0x0007, NULL, HFILL }},
18735 { &hf_smb_access_sharing,
18736 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
18737 VALS(da_sharing_vals), 0x0070, NULL, HFILL }},
18739 { &hf_smb_access_locality,
18740 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
18741 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
18743 { &hf_smb_access_caching,
18744 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
18745 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
18747 { &hf_smb_access_writetru,
18748 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
18749 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
18751 { &hf_smb_create_time,
18752 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18753 NULL, 0, "Creation Time", HFILL }},
18755 { &hf_smb_modify_time,
18756 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18757 NULL, 0, "Modification Time", HFILL }},
18759 { &hf_smb_backup_time,
18760 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18761 NULL, 0, "Backup time", HFILL}},
18763 { &hf_smb_mac_alloc_block_count,
18764 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
18765 NULL, 0, NULL, HFILL}},
18767 { &hf_smb_mac_alloc_block_size,
18768 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
18769 NULL, 0, "Allocation Block Size", HFILL}},
18771 { &hf_smb_mac_free_block_count,
18772 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
18773 NULL, 0, NULL, HFILL}},
18775 { &hf_smb_mac_root_file_count,
18776 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
18777 NULL, 0, NULL, HFILL}},
18779 { &hf_smb_mac_root_dir_count,
18780 { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
18781 NULL, 0, NULL, HFILL}},
18783 { &hf_smb_mac_file_count,
18784 { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
18785 NULL, 0, "File Count", HFILL}},
18787 { &hf_smb_mac_dir_count,
18788 { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
18789 NULL, 0, "Directory Count", HFILL}},
18791 { &hf_smb_mac_sup,
18792 { "Mac Support Flags", "smb.mac", FT_UINT32, BASE_HEX,
18793 NULL, 0x0, NULL, HFILL }},
18795 { &hf_smb_mac_sup_access_ctrl,
18796 { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
18797 TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
18799 { &hf_smb_mac_sup_getset_comments,
18800 { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
18801 TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
18803 { &hf_smb_mac_sup_desktopdb_calls,
18804 { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
18805 TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
18807 { &hf_smb_mac_sup_unique_ids,
18808 { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
18809 TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
18811 { &hf_smb_mac_sup_streams,
18812 { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
18813 TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
18815 { &hf_smb_create_dos_date,
18816 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
18817 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
18819 { &hf_smb_create_dos_time,
18820 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
18821 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
18823 { &hf_smb_last_write_time,
18824 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18825 NULL, 0, "Time this file was last written to", HFILL }},
18827 { &hf_smb_last_write_dos_date,
18828 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
18829 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
18831 { &hf_smb_last_write_dos_time,
18832 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
18833 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
18835 { &hf_smb_old_file_name,
18836 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
18837 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
18839 { &hf_smb_offset,
18840 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
18841 NULL, 0, "Offset in file", HFILL }},
18843 { &hf_smb_remaining,
18844 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
18845 NULL, 0, "Remaining number of bytes", HFILL }},
18847 { &hf_smb_padding,
18848 { "Padding", "smb.padding", FT_BYTES, BASE_NONE,
18849 NULL, 0, "Padding or unknown data", HFILL }},
18851 { &hf_smb_file_data,
18852 { "File Data", "smb.file_data", FT_BYTES, BASE_NONE,
18853 NULL, 0, "Data read/written to the file", HFILL }},
18855 #if 0
18856 { &hf_smb_raw_ea_data,
18857 { "EA Data", "smb.ea_data", FT_BYTES, BASE_NONE,
18858 NULL, 0, "Data in EA list", HFILL }},
18859 #endif
18861 { &hf_smb_mac_fndrinfo,
18862 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_NONE,
18863 NULL, 0, NULL, HFILL}},
18865 { &hf_smb_total_data_len,
18866 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
18867 NULL, 0, "Total length of data", HFILL }},
18869 { &hf_smb_data_len,
18870 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
18871 NULL, 0, "Length of data", HFILL }},
18873 { &hf_smb_data_len_low,
18874 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
18875 NULL, 0, "Length of data, Low 16 bits", HFILL }},
18877 { &hf_smb_data_len_high,
18878 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
18879 NULL, 0, "Length of data, High 16 bits", HFILL }},
18881 { &hf_smb_seek_mode,
18882 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
18883 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
18885 { &hf_smb_access_time,
18886 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18887 NULL, 0, "Last Access Time", HFILL }},
18889 { &hf_smb_access_dos_date,
18890 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
18891 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
18893 { &hf_smb_access_dos_time,
18894 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
18895 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
18897 { &hf_smb_data_size,
18898 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
18899 NULL, 0, NULL, HFILL }},
18901 { &hf_smb_alloc_size,
18902 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
18903 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
18905 { &hf_smb_max_count,
18906 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
18907 NULL, 0, "Maximum Count", HFILL }},
18909 { &hf_smb_max_count_low,
18910 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
18911 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
18913 { &hf_smb_max_count_high,
18914 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
18915 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
18917 { &hf_smb_min_count,
18918 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
18919 NULL, 0, "Minimum Count", HFILL }},
18921 { &hf_smb_timeout,
18922 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
18923 NULL, 0, "Timeout in milliseconds", HFILL }},
18925 { &hf_smb_high_offset,
18926 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
18927 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
18929 { &hf_smb_units,
18930 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
18931 NULL, 0, "Total number of units at server", HFILL }},
18933 { &hf_smb_bpu,
18934 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
18935 NULL, 0, "Blocks per unit at server", HFILL }},
18937 { &hf_smb_blocksize,
18938 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
18939 NULL, 0, "Block size (in bytes) at server", HFILL }},
18941 { &hf_smb_freeunits,
18942 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
18943 NULL, 0, "Number of free units at server", HFILL }},
18945 { &hf_smb_data_offset,
18946 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
18947 NULL, 0, NULL, HFILL }},
18949 { &hf_smb_dcm,
18950 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
18951 NULL, 0, NULL, HFILL }},
18953 { &hf_smb_request_mask,
18954 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
18955 NULL, 0, "Connectionless mode mask", HFILL }},
18957 { &hf_smb_response_mask,
18958 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
18959 NULL, 0, "Connectionless mode mask", HFILL }},
18961 { &hf_smb_search_id,
18962 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
18963 NULL, 0, "Search ID, handle for find operations", HFILL }},
18965 { &hf_smb_write_mode,
18966 { "Write Mode", "smb.write.mode", FT_UINT16, BASE_HEX,
18967 NULL, 0x0, NULL, HFILL }},
18969 { &hf_smb_write_mode_write_through,
18970 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
18971 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
18973 { &hf_smb_write_mode_return_remaining,
18974 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
18975 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
18977 { &hf_smb_write_mode_raw,
18978 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
18979 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
18981 { &hf_smb_write_mode_message_start,
18982 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
18983 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
18985 { &hf_smb_write_mode_connectionless,
18986 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
18987 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
18989 { &hf_smb_resume_key_len,
18990 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
18991 NULL, 0, NULL, HFILL }},
18993 { &hf_smb_resume_find_id,
18994 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
18995 NULL, 0, "Handle for Find operation", HFILL }},
18997 { &hf_smb_resume_server_cookie,
18998 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_NONE,
18999 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
19001 { &hf_smb_resume_client_cookie,
19002 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_NONE,
19003 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
19005 { &hf_smb_andxoffset,
19006 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
19007 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
19009 { &hf_smb_lock_type,
19010 { "Lock Type", "smb.lock.type", FT_UINT8, BASE_HEX,
19011 NULL, 0x0, NULL, HFILL }},
19013 { &hf_smb_lock_type_large,
19014 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
19015 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
19017 { &hf_smb_lock_type_cancel,
19018 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
19019 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
19021 { &hf_smb_lock_type_change,
19022 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
19023 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
19025 { &hf_smb_lock_type_oplock,
19026 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
19027 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
19029 { &hf_smb_lock_type_shared,
19030 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
19031 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
19033 { &hf_smb_locking_ol,
19034 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
19035 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
19037 { &hf_smb_number_of_locks,
19038 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
19039 NULL, 0, "Number of lock requests in this request", HFILL }},
19041 { &hf_smb_number_of_unlocks,
19042 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
19043 NULL, 0, "Number of unlock requests in this request", HFILL }},
19045 { &hf_smb_lock_long_length,
19046 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
19047 NULL, 0, "Length of lock/unlock region", HFILL }},
19049 { &hf_smb_lock_long_offset,
19050 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
19051 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
19053 { &hf_smb_file_type,
19054 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
19055 VALS(filetype_vals), 0, "Type of file", HFILL }},
19057 { &hf_smb_ipc_state,
19058 { "IPC State", "smb.ipc_state", FT_UINT16, BASE_HEX,
19059 NULL, 0x0, NULL, HFILL }},
19061 { &hf_smb_ipc_state_nonblocking,
19062 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
19063 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
19065 { &hf_smb_ipc_state_endpoint,
19066 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
19067 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
19069 { &hf_smb_ipc_state_pipe_type,
19070 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
19071 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
19073 { &hf_smb_ipc_state_read_mode,
19074 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
19075 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
19077 { &hf_smb_ipc_state_icount,
19078 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
19079 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
19081 { &hf_smb_server_fid,
19082 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
19083 NULL, 0, "Server unique File ID", HFILL }},
19085 { &hf_smb_open_flags,
19086 { "Flags", "smb.open.flags", FT_UINT16, BASE_HEX,
19087 NULL, 0x0, NULL, HFILL }},
19089 { &hf_smb_open_flags_add_info,
19090 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
19091 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
19093 { &hf_smb_open_flags_ex_oplock,
19094 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
19095 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
19097 { &hf_smb_open_flags_batch_oplock,
19098 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
19099 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
19101 { &hf_smb_open_flags_ealen,
19102 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
19103 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
19105 { &hf_smb_open_action,
19106 { "Action", "smb.open.action", FT_UINT16, BASE_HEX,
19107 NULL, 0x0, NULL, HFILL }},
19109 { &hf_smb_open_action_open,
19110 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
19111 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
19113 { &hf_smb_open_action_lock,
19114 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
19115 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
19117 { &hf_smb_vc_num,
19118 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
19119 NULL, 0, NULL, HFILL }},
19121 { &hf_smb_password_len,
19122 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
19123 NULL, 0, "Length of password", HFILL }},
19125 { &hf_smb_ansi_password_len,
19126 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
19127 NULL, 0, "Length of ANSI password", HFILL }},
19129 { &hf_smb_unicode_password_len,
19130 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
19131 NULL, 0, "Length of Unicode password", HFILL }},
19133 { &hf_smb_account,
19134 { "Account", "smb.account", FT_STRING, BASE_NONE,
19135 NULL, 0, "Account, username", HFILL }},
19137 { &hf_smb_os,
19138 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
19139 NULL, 0, "Which OS we are running", HFILL }},
19141 { &hf_smb_lanman,
19142 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
19143 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
19145 { &hf_smb_setup_action,
19146 { "Action", "smb.setup.action", FT_UINT16, BASE_HEX,
19147 NULL, 0x0, NULL, HFILL }},
19149 { &hf_smb_setup_action_guest,
19150 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
19151 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
19153 { &hf_smb_fs,
19154 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
19155 NULL, 0, NULL, HFILL }},
19157 { &hf_smb_connect_flags,
19158 { "Flags", "smb.connect.flags", FT_UINT16, BASE_HEX,
19159 NULL, 0x0, NULL, HFILL }},
19161 { &hf_smb_connect_flags_dtid,
19162 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
19163 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
19165 { &hf_smb_connect_flags_ext_sig,
19166 { "Extended Signature", "smb.connect.flags.extendedsig", FT_BOOLEAN, 16,
19167 TFS(&tfs_extended_signature), 0x0004, "Extended signature?", HFILL }},
19169 { &hf_smb_connect_flags_ext_resp,
19170 { "Extended Response", "smb.connect.flags.extendedresp", FT_BOOLEAN, 16,
19171 TFS(&tfs_extended_response), 0x0008, "Extended response?", HFILL }},
19173 { &hf_smb_connect_support,
19174 { "Optional Support", "smb.connect.support", FT_UINT16, BASE_HEX,
19175 NULL, 0x0, NULL, HFILL }},
19177 { &hf_smb_connect_support_search,
19178 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
19179 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
19181 { &hf_smb_connect_support_in_dfs,
19182 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
19183 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
19185 { &hf_smb_connect_support_csc_mask_vals,
19186 { "CSC Mask", "smb.connect.support.cscmask", FT_UINT16, BASE_DEC,
19187 VALS(connect_support_csc_mask_vals), 0x000c, "CSC mask?", HFILL }},
19189 { &hf_smb_connect_support_uniquefilename,
19190 { "Unique File Name", "smb.connect.support.uniqfilename", FT_BOOLEAN, 16,
19191 TFS(&tfs_connect_support_uniquefilename), 0x0010, "Unique file name supported?", HFILL }},
19193 { &hf_smb_connect_support_extended_signature,
19194 { "Extended Signatures", "smb.connect.support.extendedsig", FT_BOOLEAN, 16,
19195 TFS(&tfs_connect_support_extended_signature), 0x0020, "Extended signatures?", HFILL }},
19197 { &hf_smb_max_setup_count,
19198 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
19199 NULL, 0, "Maximum number of setup words to return", HFILL }},
19201 { &hf_smb_total_param_count,
19202 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
19203 NULL, 0, "Total number of parameter bytes", HFILL }},
19205 { &hf_smb_total_data_count,
19206 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
19207 NULL, 0, "Total number of data bytes", HFILL }},
19209 { &hf_smb_max_param_count,
19210 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
19211 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
19213 { &hf_smb_max_data_count,
19214 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
19215 NULL, 0, "Maximum number of data bytes to return", HFILL }},
19217 { &hf_smb_param_disp16,
19218 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
19219 NULL, 0, "Displacement of these parameter bytes", HFILL }},
19221 { &hf_smb_param_count16,
19222 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
19223 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
19225 { &hf_smb_param_offset16,
19226 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
19227 NULL, 0, "Offset (from header start) to parameters", HFILL }},
19229 { &hf_smb_param_disp32,
19230 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
19231 NULL, 0, "Displacement of these parameter bytes", HFILL }},
19233 { &hf_smb_param_count32,
19234 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
19235 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
19237 { &hf_smb_param_offset32,
19238 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
19239 NULL, 0, "Offset (from header start) to parameters", HFILL }},
19241 { &hf_smb_data_count16,
19242 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
19243 NULL, 0, "Number of data bytes in this buffer", HFILL }},
19245 { &hf_smb_data_disp16,
19246 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
19247 NULL, 0, NULL, HFILL }},
19249 { &hf_smb_data_offset16,
19250 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
19251 NULL, 0, NULL, HFILL }},
19253 { &hf_smb_data_count32,
19254 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
19255 NULL, 0, "Number of data bytes in this buffer", HFILL }},
19257 { &hf_smb_data_disp32,
19258 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
19259 NULL, 0, NULL, HFILL }},
19261 { &hf_smb_data_offset32,
19262 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
19263 NULL, 0, NULL, HFILL }},
19265 { &hf_smb_setup_count,
19266 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
19267 NULL, 0, "Number of setup words in this buffer", HFILL }},
19269 { &hf_smb_nt_ioctl_isfsctl,
19270 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
19271 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
19273 { &hf_smb_nt_ioctl_flags_completion_filter,
19274 { "Completion Filter", "smb.nt.ioctl.completion_filter", FT_UINT8, BASE_HEX,
19275 NULL, 0x0, NULL, HFILL }},
19277 { &hf_smb_nt_ioctl_flags_root_handle,
19278 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
19279 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
19281 { &hf_smb_nt_notify_action,
19282 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
19283 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
19285 { &hf_smb_nt_notify_watch_tree,
19286 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
19287 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
19290 { &hf_smb_nt_notify_completion_filter,
19291 { "Completion Filter", "smb.nt.notify.completion_filter", FT_UINT32, BASE_HEX,
19292 NULL, 0x0, NULL, HFILL }},
19293 { &hf_smb_nt_notify_file_name,
19294 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
19295 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
19297 { &hf_smb_nt_notify_dir_name,
19298 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
19299 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
19301 { &hf_smb_nt_notify_attributes,
19302 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
19303 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
19305 { &hf_smb_nt_notify_size,
19306 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
19307 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
19309 { &hf_smb_nt_notify_last_write,
19310 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
19311 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
19313 { &hf_smb_nt_notify_last_access,
19314 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
19315 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
19317 { &hf_smb_nt_notify_creation,
19318 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
19319 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
19321 { &hf_smb_nt_notify_ea,
19322 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
19323 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
19325 { &hf_smb_nt_notify_security,
19326 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
19327 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
19329 { &hf_smb_nt_notify_stream_name,
19330 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
19331 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
19333 { &hf_smb_nt_notify_stream_size,
19334 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
19335 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
19337 { &hf_smb_nt_notify_stream_write,
19338 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
19339 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
19342 { &hf_smb_root_dir_fid,
19343 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
19344 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
19346 { &hf_smb_alloc_size64,
19347 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
19348 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
19350 { &hf_smb_nt_create_disposition,
19351 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
19352 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
19354 { &hf_smb_sd_length,
19355 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
19356 NULL, 0, "Total length of security descriptor", HFILL }},
19358 { &hf_smb_ea_list_length,
19359 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
19360 NULL, 0, "Total length of extended attributes", HFILL }},
19362 { &hf_smb_ea_flags,
19363 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
19364 NULL, 0, NULL, HFILL }},
19366 { &hf_smb_ea_name_length,
19367 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
19368 NULL, 0, NULL, HFILL }},
19370 { &hf_smb_ea_data_length,
19371 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
19372 NULL, 0, NULL, HFILL }},
19374 { &hf_smb_ea_name,
19375 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
19376 NULL, 0, NULL, HFILL }},
19378 { &hf_smb_ea_data,
19379 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
19380 NULL, 0, NULL, HFILL }},
19382 { &hf_smb_file_name_len,
19383 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
19384 NULL, 0, "Length of File Name", HFILL }},
19386 { &hf_smb_nt_impersonation_level,
19387 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
19388 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
19390 { &hf_smb_nt_security_flags,
19391 { "Security Flags", "smb.security.flags", FT_UINT8, BASE_HEX,
19392 NULL, 0x0, NULL, HFILL }},
19394 { &hf_smb_nt_security_flags_context_tracking,
19395 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
19396 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
19398 { &hf_smb_nt_security_flags_effective_only,
19399 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
19400 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
19402 { &hf_smb_nt_access_mask_generic_read,
19403 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
19404 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
19406 { &hf_smb_nt_access_mask_generic_write,
19407 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
19408 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
19410 { &hf_smb_nt_access_mask_generic_execute,
19411 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
19412 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
19414 { &hf_smb_nt_access_mask_generic_all,
19415 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
19416 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
19418 { &hf_smb_nt_access_mask_maximum_allowed,
19419 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
19420 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
19422 { &hf_smb_nt_access_mask_system_security,
19423 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
19424 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
19426 { &hf_smb_nt_access_mask_synchronize,
19427 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
19428 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
19430 { &hf_smb_nt_access_mask_write_owner,
19431 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
19432 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
19434 { &hf_smb_nt_access_mask_write_dac,
19435 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
19436 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
19438 { &hf_smb_nt_access_mask_read_control,
19439 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
19440 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
19442 { &hf_smb_nt_access_mask_delete,
19443 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
19444 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
19446 { &hf_smb_nt_access_mask_write_attributes,
19447 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
19448 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
19450 { &hf_smb_nt_access_mask_read_attributes,
19451 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
19452 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
19454 { &hf_smb_nt_access_mask_delete_child,
19455 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
19456 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
19459 * "Execute" for files, "traverse" for directories.
19461 { &hf_smb_nt_access_mask_execute,
19462 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
19463 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
19465 { &hf_smb_nt_access_mask_write_ea,
19466 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
19467 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
19469 { &hf_smb_nt_access_mask_read_ea,
19470 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
19471 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
19474 * "Append data" for files, "add subdirectory" for directories,
19475 * "create pipe instance" for named pipes.
19477 { &hf_smb_nt_access_mask_append,
19478 { "Append", "smb.access.append", FT_BOOLEAN, 32,
19479 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
19482 * "Write data" for files and pipes, "add file" for directory.
19484 { &hf_smb_nt_access_mask_write,
19485 { "Write", "smb.access.write", FT_BOOLEAN, 32,
19486 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
19489 * "Read data" for files and pipes, "list directory" for directory.
19491 { &hf_smb_nt_access_mask_read,
19492 { "Read", "smb.access.read", FT_BOOLEAN, 32,
19493 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
19495 { &hf_smb_nt_create_bits_oplock,
19496 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
19497 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
19499 { &hf_smb_nt_create_bits_boplock,
19500 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
19501 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
19503 { &hf_smb_nt_create_bits_dir,
19504 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
19505 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
19507 { &hf_smb_nt_create_bits_ext_resp,
19508 { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
19509 TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
19511 { &hf_smb_nt_create_options_directory_file,
19512 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
19513 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
19515 { &hf_smb_nt_create_options_write_through,
19516 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
19517 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
19519 { &hf_smb_nt_create_options_sequential_only,
19520 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
19521 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will access to this file only be sequential?", HFILL }},
19523 { &hf_smb_nt_create_options_no_intermediate_buffering,
19524 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
19525 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
19527 { &hf_smb_nt_create_options_sync_io_alert,
19528 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
19529 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
19531 { &hf_smb_nt_create_options_sync_io_nonalert,
19532 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
19533 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
19535 { &hf_smb_nt_create_options_non_directory_file,
19536 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
19537 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
19539 { &hf_smb_nt_create_options_create_tree_connection,
19540 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
19541 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
19543 { &hf_smb_nt_create_options_complete_if_oplocked,
19544 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
19545 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
19547 { &hf_smb_nt_create_options_no_ea_knowledge,
19548 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
19549 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
19551 { &hf_smb_nt_create_options_eight_dot_three_only,
19552 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
19553 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
19555 { &hf_smb_nt_create_options_random_access,
19556 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
19557 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
19559 { &hf_smb_nt_create_options_delete_on_close,
19560 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
19561 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
19562 { &hf_smb_nt_create_options_open_by_fileid,
19563 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
19564 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
19566 { &hf_smb_nt_create_options_backup_intent,
19567 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
19568 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
19570 { &hf_smb_nt_create_options_no_compression,
19571 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
19572 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
19574 { &hf_smb_nt_create_options_reserve_opfilter,
19575 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
19576 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
19578 { &hf_smb_nt_create_options_open_reparse_point,
19579 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
19580 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
19582 { &hf_smb_nt_create_options_open_no_recall,
19583 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
19584 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
19586 { &hf_smb_nt_create_options_open_for_free_space_query,
19587 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
19588 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
19590 { &hf_smb_nt_share_access_read,
19591 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
19592 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
19594 { &hf_smb_nt_share_access_write,
19595 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
19596 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
19598 { &hf_smb_nt_share_access_delete,
19599 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
19600 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, NULL, HFILL }},
19602 { &hf_smb_file_eattr,
19603 { "File Attributes", "smb.file_attribute", FT_UINT32, BASE_HEX,
19604 NULL, 0x0, NULL, HFILL }},
19606 { &hf_smb_file_eattr_read_only,
19607 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
19608 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
19610 { &hf_smb_file_eattr_hidden,
19611 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
19612 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
19614 { &hf_smb_file_eattr_system,
19615 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
19616 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
19618 { &hf_smb_file_eattr_volume,
19619 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
19620 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
19622 { &hf_smb_file_eattr_directory,
19623 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
19624 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
19626 { &hf_smb_file_eattr_archive,
19627 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
19628 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
19630 { &hf_smb_file_eattr_device,
19631 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
19632 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
19634 { &hf_smb_file_eattr_normal,
19635 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
19636 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
19638 { &hf_smb_file_eattr_temporary,
19639 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
19640 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
19642 { &hf_smb_file_eattr_sparse,
19643 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
19644 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
19646 { &hf_smb_file_eattr_reparse,
19647 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
19648 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
19650 { &hf_smb_file_eattr_compressed,
19651 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
19652 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
19654 { &hf_smb_file_eattr_offline,
19655 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
19656 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
19658 { &hf_smb_file_eattr_not_content_indexed,
19659 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
19660 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
19662 { &hf_smb_file_eattr_encrypted,
19663 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
19664 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
19666 { &hf_smb_size_returned_quota_data,
19667 { "Size of returned Quota data", "smb.size_returned_quota_data", FT_UINT32, BASE_DEC,
19668 NULL, 0x0, NULL, HFILL }},
19670 { &hf_smb_sec_desc_len,
19671 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
19672 NULL, 0, "Security Descriptor Length", HFILL }},
19674 { &hf_smb_nt_qsd,
19675 { "Security Information", "smb.nt_qsd", FT_UINT32, BASE_HEX,
19676 NULL, 0x0, NULL, HFILL }},
19678 { &hf_smb_nt_qsd_owner,
19679 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
19680 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security information being queried?", HFILL }},
19682 { &hf_smb_nt_qsd_group,
19683 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
19684 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security information being queried?", HFILL }},
19686 { &hf_smb_nt_qsd_dacl,
19687 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
19688 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security information being queried?", HFILL }},
19690 { &hf_smb_nt_qsd_sacl,
19691 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
19692 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security information being queried?", HFILL }},
19694 { &hf_smb_extended_attributes,
19695 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_NONE,
19696 NULL, 0, NULL, HFILL }},
19698 { &hf_smb_oplock_level,
19699 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
19700 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
19702 { &hf_smb_create_action,
19703 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
19704 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
19706 { &hf_smb_file_id,
19707 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
19708 NULL, 0, NULL, HFILL }},
19710 { &hf_smb_file_id_64bit,
19711 { "Server unique 64-bit file ID", "smb.create.file_id_64b", FT_UINT64, BASE_HEX,
19712 NULL, 0, NULL, HFILL }},
19714 { &hf_smb_ea_error_offset,
19715 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
19716 NULL, 0, "Offset into EA list if EA error", HFILL }},
19718 { &hf_smb_end_of_file,
19719 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
19720 NULL, 0, "Offset to the first free byte in the file", HFILL }},
19722 { &hf_smb_replace,
19723 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
19724 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
19726 { &hf_smb_root_dir_handle,
19727 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
19728 NULL, 0, NULL, HFILL }},
19730 { &hf_smb_target_name_len,
19731 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
19732 NULL, 0, "Length of target file name", HFILL }},
19734 { &hf_smb_target_name,
19735 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
19736 NULL, 0, "Target file name", HFILL }},
19738 { &hf_smb_device_type,
19739 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
19740 VALS(device_type_vals), 0, "Type of device", HFILL }},
19742 { &hf_smb_is_directory,
19743 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
19744 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
19746 { &hf_smb_next_entry_offset,
19747 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
19748 NULL, 0, "Offset to next entry", HFILL }},
19750 { &hf_smb_change_time,
19751 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19752 NULL, 0, "Last Change Time", HFILL }},
19754 { &hf_smb_setup_len,
19755 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
19756 NULL, 0, "Length of printer setup data", HFILL }},
19758 { &hf_smb_print_mode,
19759 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
19760 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
19762 { &hf_smb_print_identifier,
19763 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
19764 NULL, 0, "Identifier string for this print job", HFILL }},
19766 { &hf_smb_restart_index,
19767 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
19768 NULL, 0, "Index of entry after last returned", HFILL }},
19770 { &hf_smb_print_queue_date,
19771 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19772 NULL, 0, "Date when this entry was queued", HFILL }},
19774 { &hf_smb_print_queue_dos_date,
19775 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
19776 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
19778 { &hf_smb_print_queue_dos_time,
19779 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
19780 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
19782 { &hf_smb_print_status,
19783 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
19784 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
19786 { &hf_smb_print_spool_file_number,
19787 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
19788 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
19790 { &hf_smb_print_spool_file_size,
19791 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
19792 NULL, 0, "Number of bytes in spool file", HFILL }},
19794 { &hf_smb_print_spool_file_name,
19795 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
19796 NULL, 0, "Name of client that submitted this job", HFILL }},
19798 { &hf_smb_start_index,
19799 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
19800 NULL, 0, "First queue entry to return", HFILL }},
19802 { &hf_smb_originator_name,
19803 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
19804 NULL, 0, "Name of sender of message", HFILL }},
19806 { &hf_smb_destination_name,
19807 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
19808 NULL, 0, "Name of recipient of message", HFILL }},
19810 { &hf_smb_message_len,
19811 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
19812 NULL, 0, "Length of message", HFILL }},
19814 { &hf_smb_message,
19815 { "Message", "smb.message", FT_STRING, BASE_NONE,
19816 NULL, 0, "Message text", HFILL }},
19818 { &hf_smb_mgid,
19819 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
19820 NULL, 0, "Message group ID for multi-block messages", HFILL }},
19822 { &hf_smb_forwarded_name,
19823 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
19824 NULL, 0, "Recipient name being forwarded", HFILL }},
19826 { &hf_smb_machine_name,
19827 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
19828 NULL, 0, "Name of target machine", HFILL }},
19830 { &hf_smb_cancel_to,
19831 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
19832 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
19834 { &hf_smb_trans_name,
19835 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
19836 NULL, 0, "Name of transaction", HFILL }},
19838 { &hf_smb_transaction_flags,
19839 { "Flags", "smb.transaction.flags", FT_UINT16, BASE_HEX,
19840 NULL, 0x0, NULL, HFILL }},
19842 { &hf_smb_transaction_flags_dtid,
19843 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
19844 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
19846 { &hf_smb_transaction_flags_owt,
19847 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
19848 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
19850 { &hf_smb_search_count,
19851 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
19852 NULL, 0, "Maximum number of search entries to return", HFILL }},
19854 { &hf_smb_search_pattern,
19855 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
19856 NULL, 0, NULL, HFILL }},
19858 { &hf_smb_ff2,
19859 { "Flags", "smb.find_first2.flags", FT_UINT16, BASE_HEX,
19860 NULL, 0x0, NULL, HFILL }},
19862 { &hf_smb_ff2_backup,
19863 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
19864 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
19866 { &hf_smb_ff2_continue,
19867 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
19868 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
19870 { &hf_smb_ff2_resume,
19871 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
19872 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
19874 { &hf_smb_ff2_close_eos,
19875 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
19876 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
19878 { &hf_smb_ff2_close,
19879 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
19880 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
19882 { &hf_smb_ff2_information_level,
19883 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
19884 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
19886 { &hf_smb_qpi_loi,
19887 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
19888 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
19890 { &hf_smb_spi_loi,
19891 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
19892 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
19894 #if 0
19895 { &hf_smb_sfi_writetru,
19896 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
19897 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
19899 { &hf_smb_sfi_caching,
19900 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
19901 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
19902 #endif
19904 { &hf_smb_storage_type,
19905 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
19906 NULL, 0, "Type of storage", HFILL }},
19908 { &hf_smb_resume,
19909 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
19910 NULL, 0, NULL, HFILL }},
19912 { &hf_smb_max_referral_level,
19913 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
19914 NULL, 0, "Latest referral version number understood", HFILL }},
19916 { &hf_smb_qfsi_information_level,
19917 { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX,
19918 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
19920 { &hf_smb_sfsi_information_level,
19921 { "Level of Interest", "smb.sfsi_loi", FT_UINT16, BASE_HEX,
19922 VALS(sfsi_vals), 0, "Level of interest for SET_FS_INFORMATION2 command", HFILL }},
19924 { &hf_smb_nt_rename_level,
19925 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
19926 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
19928 { &hf_smb_cluster_count,
19929 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
19930 NULL, 0, "Number of clusters", HFILL }},
19932 { &hf_smb_number_of_links,
19933 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
19934 NULL, 0, "Number of hard links to the file", HFILL }},
19936 { &hf_smb_delete_pending,
19937 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
19938 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
19940 { &hf_smb_index_number,
19941 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
19942 NULL, 0, "File system unique identifier", HFILL }},
19944 { &hf_smb_position,
19945 { "Position", "smb.position", FT_UINT64, BASE_DEC,
19946 NULL, 0, "File position", HFILL }},
19948 #if 0
19949 { &hf_smb_current_offset,
19950 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
19951 NULL, 0, "Current offset in the file", HFILL }},
19952 #endif
19954 { &hf_smb_t2_alignment,
19955 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
19956 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
19958 { &hf_smb_t2_stream_name_length,
19959 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
19960 NULL, 0, "Length of stream name", HFILL }},
19962 { &hf_smb_t2_stream_size,
19963 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
19964 NULL, 0, "Size of the stream in number of bytes", HFILL }},
19966 { &hf_smb_t2_stream_name,
19967 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
19968 NULL, 0, "Name of the stream", HFILL }},
19970 { &hf_smb_t2_compressed_file_size,
19971 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
19972 NULL, 0, "Size of the compressed file", HFILL }},
19974 { &hf_smb_t2_compressed_format,
19975 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
19976 NULL, 0, "Compression algorithm used", HFILL }},
19978 { &hf_smb_t2_compressed_unit_shift,
19979 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
19980 NULL, 0, "Size of the stream in number of bytes", HFILL }},
19982 { &hf_smb_t2_compressed_chunk_shift,
19983 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
19984 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
19986 { &hf_smb_t2_compressed_cluster_shift,
19987 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
19988 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
19990 { &hf_smb_t2_marked_for_deletion,
19991 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
19992 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
19994 { &hf_smb_dfs_path_consumed,
19995 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
19996 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
19998 { &hf_smb_dfs_num_referrals,
19999 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
20000 NULL, 0, "Number of referrals in this pdu", HFILL }},
20002 { &hf_smb_get_dfs_flags,
20003 { "Flags", "smb.dfs.flags", FT_UINT16, BASE_HEX,
20004 NULL, 0x0, NULL, HFILL }},
20006 { &hf_smb_get_dfs_server_hold_storage,
20007 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
20008 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
20010 { &hf_smb_get_dfs_fielding,
20011 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
20012 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
20014 { &hf_smb_dfs_referral_version,
20015 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
20016 NULL, 0, "Version of referral element", HFILL }},
20018 { &hf_smb_dfs_referral_size,
20019 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
20020 NULL, 0, "Size of referral element", HFILL }},
20022 { &hf_smb_dfs_referral_server_type,
20023 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
20024 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
20026 { &hf_smb_dfs_referral_flags,
20027 { "Flags", "smb.dfs.referral.flags", FT_UINT16, BASE_HEX,
20028 NULL, 0x0, NULL, HFILL }},
20030 { &hf_smb_dfs_referral_flags_name_list_referral,
20031 { "NameListReferral", "smb.dfs.referral.flags.name_list_referral", FT_BOOLEAN, 16,
20032 TFS(&tfs_dfs_referral_flags_name_list_referral), REFENT_FLAGS_NAME_LIST_REFERRAL, "Is a domain/DC referral response?", HFILL }},
20034 { &hf_smb_dfs_referral_flags_target_set_boundary,
20035 { "TargetSetBoundary", "smb.dfs.referral.flags.target_set_boundary", FT_BOOLEAN, 16,
20036 TFS(&tfs_dfs_referral_flags_target_set_boundary), REFENT_FLAGS_TARGET_SET_BOUNDARY, "Is this a first target in the target set?", HFILL }},
20038 { &hf_smb_dfs_referral_node_offset,
20039 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
20040 NULL, 0, "Offset of name of entity to visit next", HFILL }},
20042 { &hf_smb_dfs_referral_node,
20043 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
20044 NULL, 0, "Name of entity to visit next", HFILL }},
20046 { &hf_smb_dfs_referral_proximity,
20047 { "Proximity", "smb.dfs.referral.proximity", FT_UINT32, BASE_DEC,
20048 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
20050 { &hf_smb_dfs_referral_ttl,
20051 { "TTL", "smb.dfs.referral.ttl", FT_UINT32, BASE_DEC,
20052 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
20054 { &hf_smb_dfs_referral_path_offset,
20055 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
20056 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20058 { &hf_smb_dfs_referral_path,
20059 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
20060 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
20062 { &hf_smb_dfs_referral_alt_path_offset,
20063 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
20064 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
20066 { &hf_smb_dfs_referral_alt_path,
20067 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
20068 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
20070 { &hf_smb_dfs_referral_domain_offset,
20071 { "Domain Offset", "smb.dfs.referral.domain_offset", FT_UINT16, BASE_DEC,
20072 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20074 { &hf_smb_dfs_referral_number_of_expnames,
20075 { "Number of Expanded Names", "smb.dfs.referral.number_of_expnames", FT_UINT16, BASE_DEC,
20076 NULL, 0, NULL, HFILL }},
20078 { &hf_smb_dfs_referral_expnames_offset,
20079 { "Expanded Names Offset", "smb.dfs.referral.expnames_offset", FT_UINT16, BASE_DEC,
20080 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20082 { &hf_smb_dfs_referral_domain_name,
20083 { "Domain Name", "smb.dfs.referral.domain_name", FT_STRING, BASE_NONE,
20084 NULL, 0, "Dfs referral domain name", HFILL }},
20086 { &hf_smb_dfs_referral_expname,
20087 { "Expanded Name", "smb.dfs.referral.expname", FT_STRING, BASE_NONE,
20088 NULL, 0, "Dfs expanded name", HFILL }},
20090 { &hf_smb_dfs_referral_server_guid,
20091 { "Server GUID", "smb.dfs.referral.server_guid", FT_GUID, BASE_NONE,
20092 NULL, 0, "Globally unique identifier for this server", HFILL }},
20094 { &hf_smb_end_of_search,
20095 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
20096 NULL, 0, "Was last entry returned?", HFILL }},
20098 { &hf_smb_last_name_offset,
20099 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
20100 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
20102 { &hf_smb_fn_information_level,
20103 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
20104 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
20106 { &hf_smb_monitor_handle,
20107 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
20108 NULL, 0, "Handle for Find Notify operations", HFILL }},
20110 { &hf_smb_change_count,
20111 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
20112 NULL, 0, "Number of changes to wait for", HFILL }},
20114 { &hf_smb_file_index,
20115 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
20116 NULL, 0, NULL, HFILL }},
20118 { &hf_smb_short_file_name,
20119 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
20120 NULL, 0, "Short (8.3) File Name", HFILL }},
20122 { &hf_smb_short_file_name_len,
20123 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
20124 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
20126 { &hf_smb_fs_id,
20127 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
20128 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
20130 { &hf_smb_sector_unit,
20131 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
20132 NULL, 0, "Sectors per allocation unit", HFILL }},
20134 { &hf_smb_fs_units,
20135 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
20136 NULL, 0, "Total number of units on this filesystem", HFILL }},
20138 { &hf_smb_fs_sector,
20139 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
20140 NULL, 0, NULL, HFILL }},
20142 { &hf_smb_avail_units,
20143 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
20144 NULL, 0, "Total number of available units on this filesystem", HFILL }},
20146 { &hf_smb_volume_serial_num,
20147 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
20148 NULL, 0, NULL, HFILL }},
20150 { &hf_smb_volume_label_len,
20151 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
20152 NULL, 0, "Length of volume label", HFILL }},
20154 { &hf_smb_volume_label,
20155 { "Label", "smb.volume.label", FT_STRING, BASE_NONE,
20156 NULL, 0, "Volume label", HFILL }},
20158 { &hf_smb_free_alloc_units64,
20159 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
20160 NULL, 0, "Number of free allocation units", HFILL }},
20162 { &hf_smb_caller_free_alloc_units64,
20163 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
20164 NULL, 0, "Number of caller free allocation units", HFILL }},
20166 { &hf_smb_actual_free_alloc_units64,
20167 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
20168 NULL, 0, "Number of actual free allocation units", HFILL }},
20170 { &hf_smb_soft_quota_limit,
20171 { "(Soft) Quota Threshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
20172 NULL, 0, "Soft Quota threshold", HFILL }},
20174 { &hf_smb_hard_quota_limit,
20175 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
20176 NULL, 0, "Hard Quota limit", HFILL }},
20178 { &hf_smb_user_quota_used,
20179 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
20180 NULL, 0, "How much Quota is used by this user", HFILL }},
20182 { &hf_smb_max_name_len,
20183 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
20184 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
20186 { &hf_smb_fs_name_len,
20187 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
20188 NULL, 0, "Length of filesystem name in bytes", HFILL }},
20190 { &hf_smb_fs_name,
20191 { "FS Name", "smb.fs_name", FT_STRING, BASE_NONE,
20192 NULL, 0, "Name of filesystem", HFILL }},
20194 { &hf_smb_device_char,
20195 { "Device Characteristics", "smb.device", FT_UINT32, BASE_HEX,
20196 NULL, 0x0, NULL, HFILL }},
20198 { &hf_smb_device_char_removable,
20199 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
20200 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
20202 { &hf_smb_device_char_read_only,
20203 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
20204 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
20206 { &hf_smb_device_char_floppy,
20207 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
20208 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
20210 { &hf_smb_device_char_write_once,
20211 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
20212 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
20214 { &hf_smb_device_char_remote,
20215 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
20216 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
20218 { &hf_smb_device_char_mounted,
20219 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
20220 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
20222 { &hf_smb_device_char_virtual,
20223 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
20224 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
20226 { &hf_smb_fs_attr,
20227 { "FS Attributes", "smb.fs_attr", FT_UINT32, BASE_HEX,
20228 NULL, 0x0, NULL, HFILL }},
20230 { &hf_smb_fs_attr_css,
20231 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
20232 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
20234 { &hf_smb_fs_attr_cpn,
20235 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
20236 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
20238 { &hf_smb_fs_attr_uod,
20239 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
20240 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
20242 { &hf_smb_fs_attr_pacls,
20243 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
20244 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
20246 { &hf_smb_fs_attr_fc,
20247 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
20248 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
20250 { &hf_smb_fs_attr_vq,
20251 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
20252 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
20254 { &hf_smb_fs_attr_ssf,
20255 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
20256 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
20258 { &hf_smb_fs_attr_srp,
20259 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
20260 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
20262 { &hf_smb_fs_attr_srs,
20263 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
20264 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
20266 { &hf_smb_fs_attr_sla,
20267 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
20268 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
20270 { &hf_smb_fs_attr_vic,
20271 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
20272 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
20274 { &hf_smb_fs_attr_soids,
20275 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
20276 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
20278 { &hf_smb_fs_attr_se,
20279 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
20280 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
20282 { &hf_smb_fs_attr_ns,
20283 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
20284 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
20286 { &hf_smb_fs_attr_rov,
20287 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
20288 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
20290 { &hf_smb_length_of_sid,
20291 { "Length of SID", "smb.length_of_sid", FT_UINT32, BASE_DEC,
20292 NULL, 0x0, NULL, HFILL }},
20294 { &hf_smb_user_quota_offset,
20295 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
20296 NULL, 0, "Relative offset to next user quota structure", HFILL }},
20298 { &hf_smb_pipe_write_len,
20299 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
20300 NULL, 0, "Number of bytes written to pipe", HFILL }},
20302 { &hf_smb_quota_flags_deny_disk,
20303 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
20304 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
20306 { &hf_smb_quota_flags_log_limit,
20307 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
20308 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
20310 { &hf_smb_quota_flags_log_warning,
20311 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
20312 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
20314 { &hf_smb_quota_flags_enabled,
20315 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
20316 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
20318 { &hf_smb_segment_overlap,
20319 { "Fragment overlap", "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20320 "Fragment overlaps with other fragments", HFILL }},
20322 { &hf_smb_segment_overlap_conflict,
20323 { "Conflicting data in fragment overlap", "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20324 "Overlapping fragments contained conflicting data", HFILL }},
20326 { &hf_smb_segment_multiple_tails,
20327 { "Multiple tail fragments found", "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20328 "Several tails were found when defragmenting the packet", HFILL }},
20330 { &hf_smb_segment_too_long_fragment,
20331 { "Fragment too long", "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20332 "Fragment contained data past end of packet", HFILL }},
20334 { &hf_smb_segment_error,
20335 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20336 "Defragmentation error due to illegal fragments", HFILL }},
20338 { &hf_smb_segment_count,
20339 { "Fragment count", "smb.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
20340 NULL, HFILL }},
20342 { &hf_smb_reassembled_length,
20343 { "Reassembled SMB length", "smb.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
20344 "The total length of the reassembled payload", HFILL }},
20346 { &hf_smb_opened_in,
20347 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20348 "The frame this fid was opened", HFILL }},
20350 { &hf_smb_closed_in,
20351 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20352 "The frame this fid was closed", HFILL }},
20354 { &hf_smb_mapped_in,
20355 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20356 "The frame this share was mapped", HFILL }},
20358 { &hf_smb_unmapped_in,
20359 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20360 "The frame this share was unmapped", HFILL }},
20362 { &hf_smb_segment,
20363 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20364 NULL, HFILL }},
20366 { &hf_smb_segments,
20367 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
20368 NULL, HFILL }},
20370 { &hf_smb_unix_major_version,
20371 { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
20372 NULL, 0, "UNIX Major Version", HFILL }},
20374 { &hf_smb_unix_minor_version,
20375 { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
20376 NULL, 0, "UNIX Minor Version", HFILL }},
20378 { &hf_smb_unix_capability,
20379 { "Capabilities", "smb.unix.capability", FT_UINT64, BASE_HEX,
20380 NULL, 0x0, NULL, HFILL }},
20382 { &hf_smb_unix_capability_fcntl,
20383 { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
20384 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20386 { &hf_smb_unix_capability_posix_acl,
20387 { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
20388 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20390 { &hf_smb_file_access_mask_read_data,
20391 { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
20392 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20394 { &hf_smb_file_access_mask_write_data,
20395 { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
20396 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20398 { &hf_smb_file_access_mask_append_data,
20399 { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
20400 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20402 { &hf_smb_file_access_mask_read_ea,
20403 { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
20404 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20406 { &hf_smb_file_access_mask_write_ea,
20407 { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
20408 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20410 { &hf_smb_file_access_mask_execute,
20411 { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
20412 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20414 { &hf_smb_file_access_mask_read_attribute,
20415 { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
20416 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20418 { &hf_smb_file_access_mask_write_attribute,
20419 { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
20420 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20422 { &hf_smb_dir_access_mask_list,
20423 { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
20424 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20426 { &hf_smb_dir_access_mask_add_file,
20427 { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
20428 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20430 { &hf_smb_dir_access_mask_add_subdir,
20431 { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
20432 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20434 { &hf_smb_dir_access_mask_read_ea,
20435 { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
20436 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20438 { &hf_smb_dir_access_mask_write_ea,
20439 { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
20440 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20442 { &hf_smb_dir_access_mask_traverse,
20443 { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
20444 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20446 { &hf_smb_dir_access_mask_delete_child,
20447 { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
20448 TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
20450 { &hf_smb_dir_access_mask_read_attribute,
20451 { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
20452 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20454 { &hf_smb_dir_access_mask_write_attribute,
20455 { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
20456 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20458 { &hf_smb_unix_file_link_dest,
20459 { "Link destination", "smb.unix.file.link_dest", FT_STRING,
20460 BASE_NONE, NULL, 0, NULL, HFILL }},
20462 { &hf_smb_unix_file_size,
20463 { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
20464 NULL, 0, NULL, HFILL }},
20466 { &hf_smb_unix_file_num_bytes,
20467 { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
20468 NULL, 0, "Number of bytes used to store the file", HFILL }},
20470 { &hf_smb_unix_file_last_status,
20471 { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20472 NULL, 0, NULL, HFILL }},
20474 { &hf_smb_unix_file_last_access,
20475 { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20476 NULL, 0, NULL, HFILL }},
20478 { &hf_smb_unix_file_last_change,
20479 { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20480 NULL, 0, NULL, HFILL }},
20482 { &hf_smb_unix_file_creation_time,
20483 { "Creation time", "smb.unix.file.crtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20484 NULL, 0, NULL, HFILL }},
20486 { &hf_smb_unix_file_uid,
20487 { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
20488 NULL, 0, NULL, HFILL }},
20490 { &hf_smb_unix_file_gid,
20491 { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
20492 NULL, 0, NULL, HFILL }},
20494 { &hf_smb_unix_file_type,
20495 { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
20496 VALS(unix_file_type_vals), 0, NULL, HFILL }},
20498 { &hf_smb_unix_file_dev_major,
20499 { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
20500 NULL, 0, NULL, HFILL }},
20502 { &hf_smb_unix_file_dev_minor,
20503 { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
20504 NULL, 0, NULL, HFILL }},
20506 { &hf_smb_unix_file_unique_id,
20507 { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
20508 NULL, 0, NULL, HFILL }},
20510 { &hf_smb_unix_file_permissions,
20511 { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
20512 NULL, 0, NULL, HFILL }},
20514 { &hf_smb_unix_file_nlinks,
20515 { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
20516 NULL, 0, NULL, HFILL }},
20518 { &hf_smb_unix_info2_file_flags,
20519 { "Flags", "smb.unix_info2.file.flags", FT_UINT32, BASE_HEX,
20520 NULL, 0, NULL, HFILL }},
20522 { &hf_smb_unix_info2_file_flags_mask,
20523 { "Flags mask", "smb.unix_info2.file.flags_mask", FT_UINT32, BASE_HEX,
20524 NULL, 0, NULL, HFILL }},
20526 { &hf_smb_unix_info2_file_flags_secure_delete,
20527 { "Secure delete", "smb.unix_info2.file.flags.secure_delete", FT_BOOLEAN, 32,
20528 NULL, 0x00000001, NULL, HFILL }},
20530 { &hf_smb_unix_info2_file_flags_enable_undelete,
20531 { "Enable undelete", "smb.unix_info2.file.flags.enable_undelete", FT_BOOLEAN, 32,
20532 NULL, 0x00000002, NULL, HFILL }},
20534 { &hf_smb_unix_info2_file_flags_synchronous,
20535 { "Synchronous", "smb.unix_info2.file.flags.synchronous", FT_BOOLEAN, 32,
20536 NULL, 0x00000004, NULL, HFILL }},
20538 { &hf_smb_unix_info2_file_flags_immutable,
20539 { "Immutable", "smb.unix_info2.file.flags.immutable", FT_BOOLEAN, 32,
20540 NULL, 0x00000008, NULL, HFILL }},
20542 { &hf_smb_unix_info2_file_flags_append_only,
20543 { "Append-only", "smb.unix_info2.file.flags.append_only", FT_BOOLEAN, 32,
20544 NULL, 0x00000010, NULL, HFILL }},
20546 { &hf_smb_unix_info2_file_flags_do_not_backup,
20547 { "Do not backup", "smb.unix_info2.file.flags.do_not_backup", FT_BOOLEAN, 32,
20548 NULL, 0x00000020, NULL, HFILL }},
20550 { &hf_smb_unix_info2_file_flags_no_update_atime,
20551 { "Don't update atime", "smb.unix_info2.file.flags.no_update_atime", FT_BOOLEAN, 32,
20552 NULL, 0x00000040, NULL, HFILL }},
20554 { &hf_smb_unix_info2_file_flags_hidden,
20555 { "Hidden", "smb.unix_info2.file.flags.hidden", FT_BOOLEAN, 32,
20556 NULL, 0x00000080, NULL, HFILL }},
20558 { &hf_smb_unix_file_name_length,
20559 { "File name length", "smb.unix.file.name_length", FT_UINT32, BASE_DEC,
20560 NULL, 0, NULL, HFILL }},
20562 { &hf_smb_unix_file_name,
20563 { "File name", "smb.unix.file.name", FT_STRING,
20564 BASE_NONE, NULL, 0, NULL, HFILL }},
20566 { &hf_smb_unix_find_file_nextoffset,
20567 { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
20568 NULL, 0, NULL, HFILL }},
20570 { &hf_smb_unix_find_file_resumekey,
20571 { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
20572 NULL, 0, NULL, HFILL }},
20574 { &hf_smb_create_flags,
20575 { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
20576 NULL, 0, NULL, HFILL }},
20578 { &hf_smb_create_options,
20579 { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
20580 NULL, 0, NULL, HFILL }},
20582 { &hf_smb_share_access,
20583 { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
20584 NULL, 0, NULL, HFILL }},
20586 { &hf_smb_access_mask,
20587 { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
20588 NULL, 0, NULL, HFILL }},
20590 { &hf_smb_mode,
20591 { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
20592 NULL, 0, NULL, HFILL }},
20594 { &hf_smb_attribute,
20595 { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
20596 NULL, 0, NULL, HFILL }},
20598 { &hf_smb_reparse_tag,
20599 { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
20600 NULL, 0, NULL, HFILL }},
20602 { &hf_smb_disposition_delete_on_close,
20603 { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
20604 TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
20606 { &hf_smb_pipe_info_flag,
20607 { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
20608 TFS(&tfs_pipe_info_flag), 0x01, NULL, HFILL }},
20610 { &hf_smb_logged_in,
20611 { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_NONE,
20612 NULL, 0, NULL, HFILL }},
20614 { &hf_smb_logged_out,
20615 { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_NONE,
20616 NULL, 0, NULL, HFILL }},
20618 { &hf_smb_file_rw_offset,
20619 { "File Offset", "smb.file.rw.offset", FT_UINT64, BASE_DEC,
20620 NULL, 0, NULL, HFILL }},
20622 { &hf_smb_file_rw_length,
20623 { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
20624 NULL, 0, NULL, HFILL }},
20626 { &hf_smb_posix_acl_version,
20627 { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
20628 NULL, 0, NULL, HFILL }},
20630 { &hf_smb_posix_num_file_aces,
20631 { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
20632 NULL, 0, NULL, HFILL }},
20634 { &hf_smb_posix_num_def_aces,
20635 { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
20636 NULL, 0, NULL, HFILL }},
20638 { &hf_smb_posix_ace_type,
20639 { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
20640 VALS(ace_type_vals), 0, NULL, HFILL }},
20642 { &hf_smb_posix_ace_flags,
20643 { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
20644 NULL, 0, NULL, HFILL }},
20646 { &hf_smb_posix_ace_perm_read,
20647 {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
20648 NULL, 0x04, NULL, HFILL}},
20650 { &hf_smb_posix_ace_perm_write,
20651 {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
20652 NULL, 0x02, NULL, HFILL}},
20654 { &hf_smb_posix_ace_perm_execute,
20655 {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
20656 NULL, 0x01, NULL, HFILL}},
20658 { &hf_smb_posix_ace_perm_owner_uid,
20659 { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
20660 NULL, 0, NULL, HFILL }},
20662 { &hf_smb_posix_ace_perm_owner_gid,
20663 { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
20664 NULL, 0, NULL, HFILL }},
20666 { &hf_smb_posix_ace_perm_uid,
20667 { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
20668 NULL, 0, NULL, HFILL }},
20670 { &hf_smb_posix_ace_perm_gid,
20671 { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
20672 NULL, 0, NULL, HFILL }},
20674 { &hf_smb_trans_data_setup_word,
20675 { "Setup Word", "smb.trans_data.setup_word", FT_UINT16, BASE_HEX,
20676 NULL, 0x0, NULL, HFILL }},
20678 { &hf_smb_trans_data_parameters,
20679 { "Parameters", "smb.trans_data.parameters", FT_BYTES, BASE_NONE,
20680 NULL, 0x0, NULL, HFILL }},
20682 { &hf_smb_trans_data,
20683 { "Data", "smb.trans_data", FT_BYTES, BASE_NONE,
20684 NULL, 0x0, NULL, HFILL }},
20687 static gint *ett[] = {
20688 &ett_smb,
20689 &ett_smb_fid,
20690 &ett_smb_tid,
20691 &ett_smb_uid,
20692 &ett_smb_hdr,
20693 &ett_smb_command,
20694 &ett_smb_fileattributes,
20695 &ett_smb_capabilities,
20696 &ett_smb_aflags,
20697 &ett_smb_dialect,
20698 &ett_smb_dialects,
20699 &ett_smb_mode,
20700 &ett_smb_rawmode,
20701 &ett_smb_flags,
20702 &ett_smb_flags2,
20703 &ett_smb_desiredaccess,
20704 &ett_smb_search,
20705 &ett_smb_file,
20706 &ett_smb_openfunction,
20707 &ett_smb_filetype,
20708 &ett_smb_openaction,
20709 &ett_smb_writemode,
20710 &ett_smb_lock_type,
20711 &ett_smb_ssetupandxaction,
20712 &ett_smb_optionsup,
20713 &ett_smb_time_date,
20714 &ett_smb_move_copy_flags,
20715 &ett_smb_file_attributes,
20716 &ett_smb_search_resume_key,
20717 &ett_smb_search_dir_info,
20718 &ett_smb_unlocks,
20719 &ett_smb_unlock,
20720 &ett_smb_locks,
20721 &ett_smb_lock,
20722 &ett_smb_open_flags,
20723 &ett_smb_ipc_state,
20724 &ett_smb_open_action,
20725 &ett_smb_setup_action,
20726 &ett_smb_connect_flags,
20727 &ett_smb_connect_support_bits,
20728 &ett_smb_nt_access_mask,
20729 &ett_smb_nt_create_bits,
20730 &ett_smb_nt_create_options,
20731 &ett_smb_nt_share_access,
20732 &ett_smb_nt_security_flags,
20733 &ett_smb_nt_trans_setup,
20734 &ett_smb_nt_trans_data,
20735 &ett_smb_nt_trans_param,
20736 &ett_smb_nt_notify_completion_filter,
20737 &ett_smb_nt_ioctl_flags,
20738 &ett_smb_security_information_mask,
20739 &ett_smb_print_queue_entry,
20740 &ett_smb_transaction_flags,
20741 &ett_smb_transaction_params,
20742 &ett_smb_find_first2_flags,
20743 #if 0
20744 &ett_smb_ioflag,
20745 #endif
20746 &ett_smb_transaction_data,
20747 &ett_smb_stream_info,
20748 &ett_smb_dfs_referrals,
20749 &ett_smb_dfs_referral,
20750 &ett_smb_dfs_referral_flags,
20751 &ett_smb_dfs_referral_expnames,
20752 &ett_smb_get_dfs_flags,
20753 &ett_smb_ff2_data,
20754 &ett_smb_device_characteristics,
20755 &ett_smb_fs_attributes,
20756 &ett_smb_segments,
20757 &ett_smb_segment,
20758 &ett_smb_quotaflags,
20759 &ett_smb_secblob,
20760 &ett_smb_mac_support_flags,
20761 &ett_smb_unicode_password,
20762 &ett_smb_ea,
20763 &ett_smb_unix_capabilities,
20764 &ett_smb_posix_ace,
20765 &ett_smb_posix_ace_perms,
20766 &ett_smb_info2_file_flags
20769 static ei_register_info ei[] = {
20770 { &ei_smb_mal_information_level, { "smb.information_level.malformed", PI_MALFORMED, PI_ERROR, "Information level structure goes past the end of the transation data.", EXPFILL }},
20771 { &ei_smb_not_implemented, { "smb.not_implemented", PI_UNDECODED, PI_WARN, "Not Implemented yet", EXPFILL }},
20774 module_t *smb_module;
20775 expert_module_t* expert_smb;
20777 proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
20778 "SMB", "smb");
20779 proto_register_subtree_array(ett, array_length(ett));
20780 proto_register_field_array(proto_smb, hf, array_length(hf));
20781 expert_smb = expert_register_protocol(proto_smb);
20782 expert_register_field_array(expert_smb, ei, array_length(ei));
20784 proto_do_register_windows_common(proto_smb);
20786 register_init_routine(&smb_init_protocol);
20787 smb_module = prefs_register_protocol(proto_smb, NULL);
20788 prefs_register_bool_preference(smb_module, "trans_reassembly",
20789 "Reassemble SMB Transaction payload",
20790 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
20791 &smb_trans_reassembly);
20792 prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
20793 "Reassemble DCERPC over SMB",
20794 "Whether the dissector should reassemble DCERPC over SMB commands",
20795 &smb_dcerpc_reassembly);
20796 prefs_register_bool_preference(smb_module, "sid_name_snooping",
20797 "Snoop SID to Name mappings",
20798 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
20799 &sid_name_snooping);
20801 /* For display of SIDs and RIDs in Hex option */
20802 prefs_register_bool_preference(smb_module, "sid_display_hex",
20803 "Display SIDs in Hex",
20804 "Whether the dissector should display SIDs and RIDs in hexadecimal rather than decimal",
20805 &sid_display_hex);
20807 /* Will Export Object take name as fid ? */
20808 prefs_register_bool_preference(smb_module, "eosmb_take_name_as_fid",
20809 "Use the full file name as File ID when exporting an SMB object",
20810 "Whether the export object functionality will take the full path file name as file identifier",
20811 &eosmb_take_name_as_fid);
20813 register_init_routine(smb_trans_reassembly_init);
20814 smb_tap = register_tap("smb");
20816 /* Register the tap for the "Export Object" function */
20817 smb_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
20819 register_dissector("smb", dissect_smb, proto_smb);
20822 void
20823 proto_reg_handoff_smb(void)
20825 dissector_handle_t smb_handle;
20827 gssapi_handle = find_dissector("gssapi");
20828 ntlmssp_handle = find_dissector("ntlmssp");
20830 heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
20831 heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
20832 heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
20834 smb_handle = find_dissector("smb");
20835 dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
20836 dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
20837 dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER, smb_handle);
20838 dissector_add_uint("spp.socket", IDP_SOCKET_SMB, smb_handle);
20842 * Editor modelines - http://www.wireshark.org/tools/modelines.html
20844 * Local variables:
20845 * c-basic-offset: 8
20846 * tab-width: 8
20847 * indent-tabs-mode: t
20848 * End:
20850 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
20851 * :indentSize=8:tabSize=8:noTabs=false: