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
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copied from packet-pop.c
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
14 
15 #include "config.h"
16 
17 #include <epan/packet.h>
18 #include <epan/exceptions.h>
19 #include <epan/strutil.h>
20 #include <epan/prefs.h>
21 #include <epan/reassemble.h>
22 #include <epan/tap.h>
23 #include <epan/srt_table.h>
24 #include <epan/expert.h>
25 #include <epan/to_str.h>
26 #include <epan/export_object.h>
27 
28 #include "packet-windows-common.h"
29 #include "packet-smb.h"
30 #include "packet-ipx.h"
31 #include "packet-idp.h"
32 #include "packet-smb-common.h"
33 #include "packet-smb-mailslot.h"
34 #include "packet-smb-pipe.h"
35 #include "packet-ntlmssp.h"
36 #include "packet-smb2.h"
37 
38 void proto_register_smb(void);
39 void proto_reg_handoff_smb(void);
40 
41 /*
42  * Various specifications and documents about SMB can be found in
43  *
44  *	ftp://ftp.microsoft.com/developr/drg/CIFS/
45  *
46  * and a CIFS specification from the Storage Networking Industry Association
47  * can be found on a link from the page at
48  *
49  *	http://www.snia.org/tech_activities/CIFS
50  *
51  * (it supercedes the document at
52  *
53  *	ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
54  *
55  * ).
56  *
57  * There are also some Open Group publications documenting CIFS available
58  * for download; catalog entries for them are at:
59  *
60  *	http://www.opengroup.org/products/publications/catalog/c209.htm
61  *
62  *	http://www.opengroup.org/products/publications/catalog/c195.htm
63  *
64  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
65  * can be found at
66  *
67  *	http://www.samba.org/samba/ftp/specs/smb-nt01.doc
68  *
69  * (or, presumably a similar path under the Samba mirrors).  As the
70  * ".doc" indicates, it's a Word document.  Some of the specs from the
71  * Microsoft FTP site can be found in the
72  *
73  *	http://www.samba.org/samba/ftp/specs/
74  *
75  * directory as well.
76  *
77  * Beware - these specs may have errors.
78  *
79  * Microsoft's public protocol specifications, including MS-CIFS and
80  * other SMB-related specifications, can be found at
81  *
82  *	http://msdn.microsoft.com/en-us/library/cc216513.aspx
83  *
84  * See also
85  *
86  *	https://wiki.samba.org/index.php/UNIX_Extensions
87  */
88 
89 /* DFS referral entry flags */
90 #define REFENT_FLAGS_NAME_LIST_REFERRAL  0x0002
91 #define REFENT_FLAGS_TARGET_SET_BOUNDARY 0x0004
92 
93 
94 static int proto_smb = -1;
95 static int hf_smb_cmd = -1;
96 static int hf_smb_andxcmd = -1;
97 static int hf_smb_mapped_in = -1;
98 static int hf_smb_unmapped_in = -1;
99 static int hf_smb_opened_in = -1;
100 static int hf_smb_closed_in = -1;
101 static int hf_smb_key = -1;
102 static int hf_smb_session_id = -1;
103 static int hf_smb_sequence_num = -1;
104 static int hf_smb_group_id = -1;
105 static int hf_smb_pid = -1;
106 static int hf_smb_tid = -1;
107 static int hf_smb_uid = -1;
108 static int hf_smb_mid = -1;
109 static int hf_smb_pid_high = -1;
110 static int hf_smb_sig = -1;
111 static int hf_smb_response_to = -1;
112 static int hf_smb_time = -1;
113 static int hf_smb_response_in = -1;
114 static int hf_smb_continuation_to = -1;
115 static int hf_smb_nt_status = -1;
116 static int hf_smb_error_class = -1;
117 static int hf_smb_error_code = -1;
118 static int hf_smb_reserved = -1;
119 static int hf_smb_create_flags = -1;
120 static int hf_smb_create_options = -1;
121 static int hf_smb_share_access = -1;
122 static int hf_smb_access_mask = -1;
123 static int hf_smb_flags = -1;
124 static int hf_smb_flags_lock = -1;
125 static int hf_smb_flags_receive_buffer = -1;
126 static int hf_smb_flags_caseless = -1;
127 static int hf_smb_flags_canon = -1;
128 static int hf_smb_flags_oplock = -1;
129 static int hf_smb_flags_notify = -1;
130 static int hf_smb_flags_response = -1;
131 static int hf_smb_flags2 = -1;
132 static int hf_smb_flags2_long_names_allowed = -1;
133 static int hf_smb_flags2_ea = -1;
134 static int hf_smb_flags2_sec_sig = -1;
135 static int hf_smb_flags2_compressed = -1;
136 static int hf_smb_flags2_sec_sig_required = -1;
137 static int hf_smb_flags2_long_names_used = -1;
138 static int hf_smb_flags2_reparse_path = -1;
139 static int hf_smb_flags2_esn = -1;
140 static int hf_smb_flags2_dfs = -1;
141 static int hf_smb_flags2_roe = -1;
142 static int hf_smb_flags2_nt_error = -1;
143 static int hf_smb_flags2_string = -1;
144 static int hf_smb_word_count = -1;
145 static int hf_smb_byte_count = -1;
146 static int hf_smb_buffer_format = -1;
147 static int hf_smb_dialect = -1;
148 static int hf_smb_dialect_name = -1;
149 static int hf_smb_dialect_index = -1;
150 static int hf_smb_max_trans_buf_size = -1;
151 static int hf_smb_max_mpx_count = -1;
152 static int hf_smb_max_vcs_num = -1;
153 static int hf_smb_session_key = -1;
154 static int hf_smb_server_timezone = -1;
155 static int hf_smb_challenge_length = -1;
156 static int hf_smb_challenge = -1;
157 static int hf_smb_primary_domain = -1;
158 static int hf_smb_server = -1;
159 static int hf_smb_max_raw_buf_size = -1;
160 static int hf_smb_server_guid = -1;
161 static int hf_smb_volume_guid = -1;
162 static int hf_smb_security_blob_len = -1;
163 static int hf_smb_security_blob = -1;
164 static int hf_smb_sm16 = -1;
165 static int hf_smb_sm_mode16 = -1;
166 static int hf_smb_sm_password16 = -1;
167 static int hf_smb_sm = -1;
168 static int hf_smb_sm_mode = -1;
169 static int hf_smb_sm_password = -1;
170 static int hf_smb_sm_signatures = -1;
171 static int hf_smb_sm_sig_required = -1;
172 static int hf_smb_rm = -1;
173 static int hf_smb_rm_read = -1;
174 static int hf_smb_rm_write = -1;
175 static int hf_smb_server_date_time = -1;
176 static int hf_smb_server_smb_date = -1;
177 static int hf_smb_server_smb_time = -1;
178 static int hf_smb_server_cap = -1;
179 static int hf_smb_server_cap_raw_mode = -1;
180 static int hf_smb_server_cap_mpx_mode = -1;
181 static int hf_smb_server_cap_unicode = -1;
182 static int hf_smb_server_cap_large_files = -1;
183 static int hf_smb_server_cap_nt_smbs = -1;
184 static int hf_smb_server_cap_rpc_remote_apis = -1;
185 static int hf_smb_server_cap_nt_status = -1;
186 static int hf_smb_server_cap_level_ii_oplocks = -1;
187 static int hf_smb_server_cap_lock_and_read = -1;
188 static int hf_smb_server_cap_nt_find = -1;
189 static int hf_smb_server_cap_dfs = -1;
190 static int hf_smb_server_cap_infolevel_passthru = -1;
191 static int hf_smb_server_cap_large_readx = -1;
192 static int hf_smb_server_cap_large_writex = -1;
193 static int hf_smb_server_cap_lwio = -1;
194 static int hf_smb_server_cap_unix = -1;
195 static int hf_smb_server_cap_compressed_data = -1;
196 static int hf_smb_server_cap_dynamic_reauth = -1;
197 static int hf_smb_server_cap_extended_security = -1;
198 static int hf_smb_system_time = -1;
199 static int hf_smb_unknown = -1;
200 static int hf_smb_dir_name = -1;
201 static int hf_smb_echo_count = -1;
202 static int hf_smb_echo_data = -1;
203 static int hf_smb_echo_seq_num = -1;
204 static int hf_smb_max_buf_size = -1;
205 static int hf_smb_password = -1;
206 static int hf_smb_password_len = -1;
207 static int hf_smb_ansi_password = -1;
208 static int hf_smb_ansi_password_len = -1;
209 static int hf_smb_unicode_password = -1;
210 static int hf_smb_unicode_password_len = -1;
211 static int hf_smb_path = -1;
212 static int hf_smb_service = -1;
213 static int hf_smb_move_flags = -1;
214 static int hf_smb_move_flags_file = -1;
215 static int hf_smb_move_flags_dir = -1;
216 static int hf_smb_move_flags_verify = -1;
217 static int hf_smb_files_moved = -1;
218 static int hf_smb_file_access_mask_read_data = -1;
219 static int hf_smb_file_access_mask_write_data = -1;
220 static int hf_smb_file_access_mask_append_data = -1;
221 static int hf_smb_file_access_mask_read_ea = -1;
222 static int hf_smb_file_access_mask_write_ea = -1;
223 static int hf_smb_file_access_mask_execute = -1;
224 static int hf_smb_file_access_mask_read_attribute = -1;
225 static int hf_smb_file_access_mask_write_attribute = -1;
226 static int hf_smb_dir_access_mask_list = -1;
227 static int hf_smb_dir_access_mask_add_file = -1;
228 static int hf_smb_dir_access_mask_add_subdir = -1;
229 static int hf_smb_dir_access_mask_read_ea = -1;
230 static int hf_smb_dir_access_mask_write_ea = -1;
231 static int hf_smb_dir_access_mask_traverse = -1;
232 static int hf_smb_dir_access_mask_delete_child = -1;
233 static int hf_smb_dir_access_mask_read_attribute = -1;
234 static int hf_smb_dir_access_mask_write_attribute = -1;
235 static int hf_smb_copy_flags = -1;
236 static int hf_smb_copy_flags_file = -1;
237 static int hf_smb_copy_flags_dir = -1;
238 static int hf_smb_copy_flags_dest_mode = -1;
239 static int hf_smb_copy_flags_source_mode = -1;
240 static int hf_smb_copy_flags_verify = -1;
241 static int hf_smb_copy_flags_tree_copy = -1;
242 static int hf_smb_copy_flags_ea_action = -1;
243 static int hf_smb_count = -1;
244 static int hf_smb_count_low = -1;
245 static int hf_smb_count_high = -1;
246 static int hf_smb_file_name = -1;
247 static int hf_smb_open_function = -1;
248 static int hf_smb_open_function_open = -1;
249 static int hf_smb_open_function_create = -1;
250 static int hf_smb_fid = -1;
251 static int hf_smb_file_attr_16bit = -1;
252 static int hf_smb_file_attr_8bit = -1;
253 static int hf_smb_file_attr_read_only_16bit = -1;
254 static int hf_smb_file_attr_read_only_8bit = -1;
255 static int hf_smb_file_attr_hidden_16bit = -1;
256 static int hf_smb_file_attr_hidden_8bit = -1;
257 static int hf_smb_file_attr_system_16bit = -1;
258 static int hf_smb_file_attr_system_8bit = -1;
259 static int hf_smb_file_attr_volume_16bit = -1;
260 static int hf_smb_file_attr_volume_8bit = -1;
261 static int hf_smb_file_attr_directory_16bit = -1;
262 static int hf_smb_file_attr_directory_8bit = -1;
263 static int hf_smb_file_attr_archive_16bit = -1;
264 static int hf_smb_file_attr_archive_8bit = -1;
265 #if 0
266 static int hf_smb_file_attr_device = -1;
267 static int hf_smb_file_attr_normal = -1;
268 static int hf_smb_file_attr_temporary = -1;
269 static int hf_smb_file_attr_sparse = -1;
270 static int hf_smb_file_attr_reparse = -1;
271 static int hf_smb_file_attr_compressed = -1;
272 static int hf_smb_file_attr_offline = -1;
273 static int hf_smb_file_attr_not_content_indexed = -1;
274 static int hf_smb_file_attr_encrypted = -1;
275 #endif
276 static int hf_smb_file_size = -1;
277 static int hf_smb_search_attribute = -1;
278 static int hf_smb_search_attribute_read_only = -1;
279 static int hf_smb_search_attribute_hidden = -1;
280 static int hf_smb_search_attribute_system = -1;
281 static int hf_smb_search_attribute_volume = -1;
282 static int hf_smb_search_attribute_directory = -1;
283 static int hf_smb_search_attribute_archive = -1;
284 static int hf_smb_access_mode = -1;
285 static int hf_smb_access_sharing = -1;
286 static int hf_smb_access_locality = -1;
287 static int hf_smb_access_caching = -1;
288 static int hf_smb_access_writetru = -1;
289 static int hf_smb_desired_access = -1;
290 static int hf_smb_granted_access = -1;
291 static int hf_smb_create_time = -1;
292 static int hf_smb_modify_time = -1;
293 static int hf_smb_backup_time = -1;
294 static int hf_smb_mac_alloc_block_count = -1;
295 static int hf_smb_mac_alloc_block_size = -1;
296 static int hf_smb_mac_free_block_count = -1;
297 static int hf_smb_mac_fndrinfo = -1;
298 static int hf_smb_mac_root_file_count = -1;
299 static int hf_smb_mac_root_dir_count = -1;
300 static int hf_smb_mac_file_count = -1;
301 static int hf_smb_mac_dir_count = -1;
302 static int hf_smb_mac_sup = -1;
303 static int hf_smb_mac_sup_access_ctrl = -1;
304 static int hf_smb_mac_sup_getset_comments = -1;
305 static int hf_smb_mac_sup_desktopdb_calls = -1;
306 static int hf_smb_mac_sup_unique_ids = -1;
307 static int hf_smb_mac_sup_streams = -1;
308 static int hf_smb_create_dos_date = -1;
309 static int hf_smb_create_dos_time = -1;
310 static int hf_smb_last_write_time = -1;
311 static int hf_smb_last_write_dos_date = -1;
312 static int hf_smb_last_write_dos_time = -1;
313 static int hf_smb_access_time = -1;
314 static int hf_smb_access_dos_date = -1;
315 static int hf_smb_access_dos_time = -1;
316 static int hf_smb_old_file_name = -1;
317 static int hf_smb_offset = -1;
318 static int hf_smb_remaining = -1;
319 static int hf_smb_padding = -1;
320 static int hf_smb_file_data = -1;
321 /* static int hf_smb_raw_ea_data = -1; */
322 static int hf_smb_total_data_len = -1;
323 static int hf_smb_data_len = -1;
324 static int hf_smb_data_len_low = -1;
325 static int hf_smb_data_len_high = -1;
326 static int hf_smb_seek_mode = -1;
327 static int hf_smb_data_size = -1;
328 static int hf_smb_alloc_size = -1;
329 static int hf_smb_alloc_size64 = -1;
330 static int hf_smb_max_count = -1;
331 static int hf_smb_max_count_low = -1;
332 static int hf_smb_max_count_high = -1;
333 static int hf_smb_min_count = -1;
334 static int hf_smb_timeout = -1;
335 static int hf_smb_high_offset = -1;
336 static int hf_smb_units = -1;
337 static int hf_smb_bpu = -1;
338 static int hf_smb_blocksize = -1;
339 static int hf_smb_freeunits = -1;
340 static int hf_smb_data_offset = -1;
341 static int hf_smb_dcm = -1;
342 static int hf_smb_request_mask = -1;
343 static int hf_smb_response_mask = -1;
344 static int hf_smb_search_id = -1;
345 static int hf_smb_write_mode = -1;
346 static int hf_smb_write_mode_write_through = -1;
347 static int hf_smb_write_mode_return_remaining = -1;
348 static int hf_smb_write_mode_raw = -1;
349 static int hf_smb_write_mode_message_start = -1;
350 static int hf_smb_write_mode_connectionless = -1;
351 static int hf_smb_resume_key_len = -1;
352 static int hf_smb_resume_find_id = -1;
353 static int hf_smb_resume_server_cookie = -1;
354 static int hf_smb_resume_client_cookie = -1;
355 static int hf_smb_andxoffset = -1;
356 static int hf_smb_lock_type = -1;
357 static int hf_smb_lock_type_large = -1;
358 static int hf_smb_lock_type_cancel = -1;
359 static int hf_smb_lock_type_change = -1;
360 static int hf_smb_lock_type_oplock = -1;
361 static int hf_smb_lock_type_shared = -1;
362 static int hf_smb_locking_ol = -1;
363 static int hf_smb_number_of_locks = -1;
364 static int hf_smb_number_of_unlocks = -1;
365 static int hf_smb_lock_long_offset = -1;
366 static int hf_smb_lock_long_length = -1;
367 static int hf_smb_file_type = -1;
368 static int hf_smb_ipc_state = -1;
369 static int hf_smb_ipc_state_nonblocking = -1;
370 static int hf_smb_ipc_state_endpoint = -1;
371 static int hf_smb_ipc_state_pipe_type = -1;
372 static int hf_smb_ipc_state_read_mode = -1;
373 static int hf_smb_ipc_state_icount = -1;
374 static int hf_smb_server_fid = -1;
375 static int hf_smb_open_flags = -1;
376 static int hf_smb_open_flags_add_info = -1;
377 static int hf_smb_open_flags_ex_oplock = -1;
378 static int hf_smb_open_flags_batch_oplock = -1;
379 static int hf_smb_open_flags_ealen = -1;
380 static int hf_smb_open_action = -1;
381 static int hf_smb_open_action_open = -1;
382 static int hf_smb_open_action_lock = -1;
383 static int hf_smb_vc_num = -1;
384 static int hf_smb_account = -1;
385 static int hf_smb_os = -1;
386 static int hf_smb_lanman = -1;
387 static int hf_smb_setup_action = -1;
388 static int hf_smb_setup_action_guest = -1;
389 static int hf_smb_fs = -1;
390 static int hf_smb_connect_flags = -1;
391 static int hf_smb_connect_flags_dtid = -1;
392 static int hf_smb_connect_flags_ext_sig = -1;
393 static int hf_smb_connect_flags_ext_resp = -1;
394 static int hf_smb_connect_support = -1;
395 static int hf_smb_connect_support_search = -1;
396 static int hf_smb_connect_support_in_dfs = -1;
397 static int hf_smb_connect_support_csc_mask_vals = -1;
398 static int hf_smb_connect_support_uniquefilename = -1;
399 static int hf_smb_connect_support_extended_signature = -1;
400 static int hf_smb_max_setup_count = -1;
401 static int hf_smb_total_param_count = -1;
402 static int hf_smb_total_data_count = -1;
403 static int hf_smb_max_param_count = -1;
404 static int hf_smb_max_data_count = -1;
405 static int hf_smb_param_disp16 = -1;
406 static int hf_smb_param_count16 = -1;
407 static int hf_smb_param_offset16 = -1;
408 static int hf_smb_param_disp32 = -1;
409 static int hf_smb_param_count32 = -1;
410 static int hf_smb_param_offset32 = -1;
411 static int hf_smb_data_disp16 = -1;
412 static int hf_smb_data_count16 = -1;
413 static int hf_smb_data_offset16 = -1;
414 static int hf_smb_data_disp32 = -1;
415 static int hf_smb_data_count32 = -1;
416 static int hf_smb_data_offset32 = -1;
417 static int hf_smb_setup_count = -1;
418 static int hf_smb_nt_trans_subcmd = -1;
419 static int hf_smb_nt_ioctl_isfsctl = -1;
420 static int hf_smb_nt_ioctl_flags_completion_filter = -1;
421 static int hf_smb_nt_ioctl_flags_root_handle = -1;
422 static int hf_smb_nt_notify_action = -1;
423 static int hf_smb_nt_notify_watch_tree = -1;
424 static int hf_smb_nt_notify_completion_filter = -1;
425 static int hf_smb_nt_notify_stream_write = -1;
426 static int hf_smb_nt_notify_stream_size = -1;
427 static int hf_smb_nt_notify_stream_name = -1;
428 static int hf_smb_nt_notify_security = -1;
429 static int hf_smb_nt_notify_ea = -1;
430 static int hf_smb_nt_notify_creation = -1;
431 static int hf_smb_nt_notify_last_access = -1;
432 static int hf_smb_nt_notify_last_write = -1;
433 static int hf_smb_nt_notify_size = -1;
434 static int hf_smb_nt_notify_attributes = -1;
435 static int hf_smb_nt_notify_dir_name = -1;
436 static int hf_smb_nt_notify_file_name = -1;
437 static int hf_smb_root_dir_fid = -1;
438 static int hf_smb_nt_create_disposition = -1;
439 static int hf_smb_sd_length = -1;
440 static int hf_smb_ea_list_length = -1;
441 static int hf_smb_ea_flags = -1;
442 static int hf_smb_ea_name_length = -1;
443 static int hf_smb_ea_data_length = -1;
444 static int hf_smb_ea_name = -1;
445 static int hf_smb_ea_data = -1;
446 static int hf_smb_file_name_len = -1;
447 static int hf_smb_nt_impersonation_level = -1;
448 static int hf_smb_nt_security_flags = -1;
449 static int hf_smb_nt_security_flags_context_tracking = -1;
450 static int hf_smb_nt_security_flags_effective_only = -1;
451 static int hf_smb_nt_access_mask_generic_read = -1;
452 static int hf_smb_nt_access_mask_generic_write = -1;
453 static int hf_smb_nt_access_mask_generic_execute = -1;
454 static int hf_smb_nt_access_mask_generic_all = -1;
455 static int hf_smb_nt_access_mask_maximum_allowed = -1;
456 static int hf_smb_nt_access_mask_system_security = -1;
457 static int hf_smb_nt_access_mask_synchronize = -1;
458 static int hf_smb_nt_access_mask_write_owner = -1;
459 static int hf_smb_nt_access_mask_write_dac = -1;
460 static int hf_smb_nt_access_mask_read_control = -1;
461 static int hf_smb_nt_access_mask_delete = -1;
462 static int hf_smb_nt_access_mask_write_attributes = -1;
463 static int hf_smb_nt_access_mask_read_attributes = -1;
464 static int hf_smb_nt_access_mask_delete_child = -1;
465 static int hf_smb_nt_access_mask_execute = -1;
466 static int hf_smb_nt_access_mask_write_ea = -1;
467 static int hf_smb_nt_access_mask_read_ea = -1;
468 static int hf_smb_nt_access_mask_append = -1;
469 static int hf_smb_nt_access_mask_write = -1;
470 static int hf_smb_nt_access_mask_read = -1;
471 static int hf_smb_nt_create_bits_oplock = -1;
472 static int hf_smb_nt_create_bits_boplock = -1;
473 static int hf_smb_nt_create_bits_dir = -1;
474 static int hf_smb_nt_create_bits_ext_resp = -1;
475 static int hf_smb_nt_create_options_directory_file = -1;
476 static int hf_smb_nt_create_options_write_through = -1;
477 static int hf_smb_nt_create_options_sequential_only = -1;
478 static int hf_smb_nt_create_options_no_intermediate_buffering = -1;
479 static int hf_smb_nt_create_options_sync_io_alert = -1;
480 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
481 static int hf_smb_nt_create_options_non_directory_file = -1;
482 static int hf_smb_nt_create_options_create_tree_connection = -1;
483 static int hf_smb_nt_create_options_complete_if_oplocked = -1;
484 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
485 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
486 static int hf_smb_nt_create_options_random_access = -1;
487 static int hf_smb_nt_create_options_delete_on_close = -1;
488 static int hf_smb_nt_create_options_open_by_fileid = -1;
489 static int hf_smb_nt_create_options_backup_intent = -1;
490 static int hf_smb_nt_create_options_no_compression = -1;
491 static int hf_smb_nt_create_options_reserve_opfilter = -1;
492 static int hf_smb_nt_create_options_open_reparse_point = -1;
493 static int hf_smb_nt_create_options_open_no_recall = -1;
494 static int hf_smb_nt_create_options_open_for_free_space_query = -1;
495 static int hf_smb_nt_share_access_read = -1;
496 static int hf_smb_nt_share_access_write = -1;
497 static int hf_smb_nt_share_access_delete = -1;
498 static int hf_smb_file_eattr = -1;
499 static int hf_smb_file_eattr_read_only = -1;
500 static int hf_smb_file_eattr_hidden = -1;
501 static int hf_smb_file_eattr_system = -1;
502 static int hf_smb_file_eattr_volume = -1;
503 static int hf_smb_file_eattr_directory = -1;
504 static int hf_smb_file_eattr_archive = -1;
505 static int hf_smb_file_eattr_device = -1;
506 static int hf_smb_file_eattr_normal = -1;
507 static int hf_smb_file_eattr_temporary = -1;
508 static int hf_smb_file_eattr_sparse = -1;
509 static int hf_smb_file_eattr_reparse = -1;
510 static int hf_smb_file_eattr_compressed = -1;
511 static int hf_smb_file_eattr_offline = -1;
512 static int hf_smb_file_eattr_not_content_indexed = -1;
513 static int hf_smb_file_eattr_encrypted = -1;
514 static int hf_smb_size_returned_quota_data = -1;
515 static int hf_smb_sec_desc_len = -1;
516 static int hf_smb_nt_qsd = -1;
517 static int hf_smb_nt_qsd_owner = -1;
518 static int hf_smb_nt_qsd_group = -1;
519 static int hf_smb_nt_qsd_dacl = -1;
520 static int hf_smb_nt_qsd_sacl = -1;
521 static int hf_smb_extended_attributes = -1;
522 static int hf_smb_oplock_level = -1;
523 static int hf_smb_response_type = -1;
524 static int hf_smb_create_action = -1;
525 static int hf_smb_file_id = -1;
526 static int hf_smb_file_id_64bit = -1;
527 static int hf_smb_ea_error_offset = -1;
528 static int hf_smb_end_of_file = -1;
529 static int hf_smb_replace = -1;
530 static int hf_smb_root_dir_handle = -1;
531 static int hf_smb_target_name_len = -1;
532 static int hf_smb_target_name = -1;
533 static int hf_smb_device_type = -1;
534 static int hf_smb_is_directory = -1;
535 static int hf_smb_next_entry_offset = -1;
536 static int hf_smb_change_time = -1;
537 static int hf_smb_setup_len = -1;
538 static int hf_smb_print_mode = -1;
539 static int hf_smb_print_identifier = -1;
540 static int hf_smb_restart_index = -1;
541 static int hf_smb_print_queue_date = -1;
542 static int hf_smb_print_queue_dos_date = -1;
543 static int hf_smb_print_queue_dos_time = -1;
544 static int hf_smb_print_status = -1;
545 static int hf_smb_print_spool_file_number = -1;
546 static int hf_smb_print_spool_file_size = -1;
547 static int hf_smb_print_spool_file_name = -1;
548 static int hf_smb_start_index = -1;
549 static int hf_smb_originator_name = -1;
550 static int hf_smb_destination_name = -1;
551 static int hf_smb_message_len = -1;
552 static int hf_smb_message = -1;
553 static int hf_smb_mgid = -1;
554 static int hf_smb_forwarded_name = -1;
555 static int hf_smb_machine_name = -1;
556 static int hf_smb_cancel_to = -1;
557 static int hf_smb_trans2_subcmd = -1;
558 static int hf_smb_trans_name = -1;
559 static int hf_smb_transaction_flags = -1;
560 static int hf_smb_transaction_flags_dtid = -1;
561 static int hf_smb_transaction_flags_owt = -1;
562 static int hf_smb_search_count = -1;
563 static int hf_smb_search_pattern = -1;
564 static int hf_smb_ff2 = -1;
565 static int hf_smb_ff2_backup = -1;
566 static int hf_smb_ff2_continue = -1;
567 static int hf_smb_ff2_resume = -1;
568 static int hf_smb_ff2_close_eos = -1;
569 static int hf_smb_ff2_close = -1;
570 static int hf_smb_ff2_information_level = -1;
571 static int hf_smb_qpi_loi = -1;
572 static int hf_smb_spi_loi = -1;
573 #if 0
574 static int hf_smb_sfi = -1;
575 static int hf_smb_sfi_writetru = -1;
576 static int hf_smb_sfi_caching = -1;
577 #endif
578 static int hf_smb_storage_type = -1;
579 static int hf_smb_resume = -1;
580 static int hf_smb_max_referral_level = -1;
581 static int hf_smb_qfsi_information_level = -1;
582 static int hf_smb_sfsi_information_level = -1;
583 static int hf_smb_number_of_links = -1;
584 static int hf_smb_delete_pending = -1;
585 static int hf_smb_index_number = -1;
586 static int hf_smb_position = -1;
587 /* static int hf_smb_current_offset = -1; */
588 static int hf_smb_t2_alignment = -1;
589 static int hf_smb_t2_stream_name_length = -1;
590 static int hf_smb_t2_stream_size = -1;
591 static int hf_smb_t2_stream_name = -1;
592 static int hf_smb_t2_compressed_file_size = -1;
593 static int hf_smb_t2_compressed_format = -1;
594 static int hf_smb_t2_compressed_unit_shift = -1;
595 static int hf_smb_t2_compressed_chunk_shift = -1;
596 static int hf_smb_t2_compressed_cluster_shift = -1;
597 static int hf_smb_t2_marked_for_deletion = -1;
598 static int hf_smb_dfs_path_consumed = -1;
599 static int hf_smb_dfs_num_referrals = -1;
600 static int hf_smb_get_dfs_flags = -1;
601 static int hf_smb_get_dfs_server_hold_storage = -1;
602 static int hf_smb_get_dfs_fielding = -1;
603 static int hf_smb_dfs_referral_version = -1;
604 static int hf_smb_dfs_referral_size = -1;
605 static int hf_smb_dfs_referral_server_type = -1;
606 static int hf_smb_dfs_referral_flags = -1;
607 static int hf_smb_dfs_referral_flags_name_list_referral = -1;
608 static int hf_smb_dfs_referral_flags_target_set_boundary = -1;
609 static int hf_smb_dfs_referral_node_offset = -1;
610 static int hf_smb_dfs_referral_node = -1;
611 static int hf_smb_dfs_referral_proximity = -1;
612 static int hf_smb_dfs_referral_ttl = -1;
613 static int hf_smb_dfs_referral_path_offset = -1;
614 static int hf_smb_dfs_referral_path = -1;
615 static int hf_smb_dfs_referral_alt_path_offset = -1;
616 static int hf_smb_dfs_referral_alt_path = -1;
617 static int hf_smb_dfs_referral_domain_offset = -1;
618 static int hf_smb_dfs_referral_number_of_expnames = -1;
619 static int hf_smb_dfs_referral_expnames_offset = -1;
620 static int hf_smb_dfs_referral_domain_name = -1;
621 static int hf_smb_dfs_referral_expname = -1;
622 static int hf_smb_dfs_referral_server_guid = -1;
623 static int hf_smb_end_of_search = -1;
624 static int hf_smb_last_name_offset = -1;
625 static int hf_smb_fn_information_level = -1;
626 static int hf_smb_monitor_handle = -1;
627 static int hf_smb_change_count = -1;
628 static int hf_smb_file_index = -1;
629 static int hf_smb_short_file_name = -1;
630 static int hf_smb_short_file_name_len = -1;
631 static int hf_smb_fs_id = -1;
632 static int hf_smb_sector_unit = -1;
633 static int hf_smb_fs_units = -1;
634 static int hf_smb_fs_sector = -1;
635 static int hf_smb_avail_units = -1;
636 static int hf_smb_volume_serial_num = -1;
637 static int hf_smb_volume_label_len = -1;
638 static int hf_smb_volume_label = -1;
639 static int hf_smb_free_alloc_units64 = -1;
640 static int hf_smb_caller_free_alloc_units64 = -1;
641 static int hf_smb_actual_free_alloc_units64 = -1;
642 static int hf_smb_max_name_len = -1;
643 static int hf_smb_fs_name_len = -1;
644 static int hf_smb_fs_name = -1;
645 static int hf_smb_device_char = -1;
646 static int hf_smb_device_char_removable = -1;
647 static int hf_smb_device_char_read_only = -1;
648 static int hf_smb_device_char_floppy = -1;
649 static int hf_smb_device_char_write_once = -1;
650 static int hf_smb_device_char_remote = -1;
651 static int hf_smb_device_char_mounted = -1;
652 static int hf_smb_device_char_virtual = -1;
653 static int hf_smb_device_char_secure_open = -1;
654 static int hf_smb_device_char_ts = -1;
655 static int hf_smb_device_char_webdav = -1;
656 static int hf_smb_device_char_aat = -1;
657 static int hf_smb_device_char_portable = -1;
658 static int hf_smb_fs_attr = -1;
659 static int hf_smb_fs_attr_css = -1;
660 static int hf_smb_fs_attr_cpn = -1;
661 static int hf_smb_fs_attr_uod = -1;
662 static int hf_smb_fs_attr_pacls = -1;
663 static int hf_smb_fs_attr_fc = -1;
664 static int hf_smb_fs_attr_vq = -1;
665 static int hf_smb_fs_attr_ssf = -1;
666 static int hf_smb_fs_attr_srp = -1;
667 static int hf_smb_fs_attr_srs = -1;
668 static int hf_smb_fs_attr_sla = -1;
669 static int hf_smb_fs_attr_vic = -1;
670 static int hf_smb_fs_attr_soids = -1;
671 static int hf_smb_fs_attr_se = -1;
672 static int hf_smb_fs_attr_ns = -1;
673 static int hf_smb_fs_attr_rov = -1;
674 static int hf_smb_fs_attr_swo = -1;
675 static int hf_smb_fs_attr_st = -1;
676 static int hf_smb_fs_attr_shl = -1;
677 static int hf_smb_fs_attr_sis = -1;
678 static int hf_smb_fs_attr_sbr = -1;
679 static int hf_smb_fs_attr_ssv = -1;
680 static int hf_smb_quota_flags = -1;
681 static int hf_smb_quota_flags_enabled = -1;
682 static int hf_smb_quota_flags_deny_disk = -1;
683 static int hf_smb_quota_flags_log_limit = -1;
684 static int hf_smb_quota_flags_log_warning = -1;
685 static int hf_smb_soft_quota_limit = -1;
686 static int hf_smb_hard_quota_limit = -1;
687 static int hf_smb_user_quota_used = -1;
688 static int hf_smb_user_quota_change_time = -1;
689 static int hf_smb_length_of_sid = -1;
690 static int hf_smb_user_quota_offset = -1;
691 static int hf_smb_nt_rename_level = -1;
692 static int hf_smb_cluster_count = -1;
693 static int hf_smb_segments = -1;
694 static int hf_smb_segment = -1;
695 static int hf_smb_segment_overlap = -1;
696 static int hf_smb_segment_overlap_conflict = -1;
697 static int hf_smb_segment_multiple_tails = -1;
698 static int hf_smb_segment_too_long_fragment = -1;
699 static int hf_smb_segment_error = -1;
700 static int hf_smb_segment_count = -1;
701 static int hf_smb_reassembled_length = -1;
702 static int hf_smb_pipe_write_len = -1;
703 static int hf_smb_unix_major_version = -1;
704 static int hf_smb_unix_minor_version = -1;
705 static int hf_smb_unix_capability = -1;
706 static int hf_smb_unix_capability_fcntl = -1;
707 static int hf_smb_unix_capability_posix_acl = -1;
708 static int hf_smb_unix_capability_xattr = -1;
709 static int hf_smb_unix_capability_attr = -1;
710 static int hf_smb_unix_capability_posix_paths = -1;
711 static int hf_smb_unix_capability_posix_path_ops = -1;
712 static int hf_smb_unix_capability_large_read = -1;
713 static int hf_smb_unix_capability_large_write = -1;
714 static int hf_smb_unix_capability_encryption = -1;
715 static int hf_smb_unix_capability_mandatory_crypto = -1;
716 static int hf_smb_unix_capability_proxy = -1;
717 static int hf_smb_unix_file_link_dest = -1;
718 static int hf_smb_unix_file_size = -1;
719 static int hf_smb_unix_file_num_bytes = -1;
720 static int hf_smb_unix_file_last_status = -1;
721 static int hf_smb_unix_file_last_access = -1;
722 static int hf_smb_unix_file_last_change = -1;
723 static int hf_smb_unix_file_creation_time = -1;
724 static int hf_smb_unix_file_uid = -1;
725 static int hf_smb_unix_file_gid = -1;
726 static int hf_smb_unix_file_type = -1;
727 static int hf_smb_unix_file_dev_major = -1;
728 static int hf_smb_unix_file_dev_minor = -1;
729 static int hf_smb_unix_file_unique_id = -1;
730 static int hf_smb_unix_file_permissions = -1;
731 static int hf_smb_unix_file_nlinks = -1;
732 static int hf_smb_unix_info2_file_flags = -1;
733 static int hf_smb_unix_info2_file_flags_mask = -1;
734 static int hf_smb_unix_info2_file_flags_secure_delete = -1;
735 static int hf_smb_unix_info2_file_flags_enable_undelete = -1;
736 static int hf_smb_unix_info2_file_flags_synchronous = -1;
737 static int hf_smb_unix_info2_file_flags_immutable = -1;
738 static int hf_smb_unix_info2_file_flags_append_only = -1;
739 static int hf_smb_unix_info2_file_flags_do_not_backup = -1;
740 static int hf_smb_unix_info2_file_flags_no_update_atime = -1;
741 static int hf_smb_unix_info2_file_flags_hidden = -1;
742 static int hf_smb_unix_file_name_length = -1;
743 static int hf_smb_unix_file_name = -1;
744 static int hf_smb_unix_find_file_nextoffset = -1;
745 static int hf_smb_unix_find_file_resumekey = -1;
746 static int hf_smb_unix_whoami_mapflags = -1;
747 static int hf_smb_unix_whoami_mapflags_mask = -1;
748 static int hf_smb_unix_whoami_num_supl_gids = -1;
749 static int hf_smb_unix_whoami_num_supl_sids = -1;
750 static int hf_smb_unix_whoami_sids_buflen = -1;
751 static int hf_smb_disposition_delete_on_close = -1;
752 static int hf_smb_pipe_info_flag = -1;
753 static int hf_smb_mode = -1;
754 static int hf_smb_attribute = -1;
755 static int hf_smb_reparse_tag = -1;
756 static int hf_smb_logged_in = -1;
757 static int hf_smb_logged_out = -1;
758 static int hf_smb_file_rw_offset = -1;
759 static int hf_smb_file_rw_length = -1;
760 static int hf_smb_posix_acl_version = -1;
761 static int hf_smb_posix_num_file_aces = -1;
762 static int hf_smb_posix_num_def_aces = -1;
763 static int hf_smb_posix_ace_type = -1;
764 static int hf_smb_posix_ace_flags = -1;
765 static int hf_smb_posix_ace_perm_read = -1;
766 static int hf_smb_posix_ace_perm_write = -1;
767 static int hf_smb_posix_ace_perm_execute = -1;
768 static int hf_smb_posix_ace_perm_owner_uid = -1;
769 static int hf_smb_posix_ace_perm_owner_gid = -1;
770 static int hf_smb_posix_ace_perm_uid = -1;
771 static int hf_smb_posix_ace_perm_gid = -1;
772 static int hf_smb_trans_data_setup_word = -1;
773 static int hf_smb_trans_data_parameters = -1;
774 static int hf_smb_trans_data = -1;
775 static int hf_smb_extra_byte_parameters = -1;
776 static int hf_smb_file_access_mask_full_control = -1;
777 static int hf_smb_dir_access_mask_full_control = -1;
778 static int hf_smb_word_unk_response_format = -1;
779 static int hf_smb_nt_transaction_setup = -1;
780 static int hf_smb_server_component = -1;
781 static int hf_smb_byte_parameters = -1;
782 static int hf_smb_word_parameters = -1;
783 
784 static gint ett_smb = -1;
785 static gint ett_smb_fid = -1;
786 static gint ett_smb_tid = -1;
787 static gint ett_smb_uid = -1;
788 static gint ett_smb_hdr = -1;
789 static gint ett_smb_command = -1;
790 static gint ett_smb_fileattributes = -1;
791 static gint ett_smb_capabilities = -1;
792 static gint ett_smb_aflags = -1;
793 static gint ett_smb_dialect = -1;
794 static gint ett_smb_dialects = -1;
795 static gint ett_smb_mode = -1;
796 static gint ett_smb_rawmode = -1;
797 static gint ett_smb_flags = -1;
798 static gint ett_smb_flags2 = -1;
799 static gint ett_smb_desiredaccess = -1;
800 static gint ett_smb_search = -1;
801 static gint ett_smb_file = -1;
802 static gint ett_smb_openfunction = -1;
803 static gint ett_smb_filetype = -1;
804 static gint ett_smb_openaction = -1;
805 static gint ett_smb_writemode = -1;
806 static gint ett_smb_lock_type = -1;
807 static gint ett_smb_ssetupandxaction = -1;
808 static gint ett_smb_optionsup = -1;
809 static gint ett_smb_time_date = -1;
810 static gint ett_smb_move_copy_flags = -1;
811 static gint ett_smb_file_attributes = -1;
812 static gint ett_smb_search_resume_key = -1;
813 static gint ett_smb_search_dir_info = -1;
814 static gint ett_smb_unlocks = -1;
815 static gint ett_smb_unlock = -1;
816 static gint ett_smb_locks = -1;
817 static gint ett_smb_lock = -1;
818 static gint ett_smb_open_flags = -1;
819 static gint ett_smb_ipc_state = -1;
820 static gint ett_smb_open_action = -1;
821 static gint ett_smb_setup_action = -1;
822 static gint ett_smb_connect_flags = -1;
823 static gint ett_smb_connect_support_bits = -1;
824 static gint ett_smb_nt_access_mask = -1;
825 static gint ett_smb_nt_create_bits = -1;
826 static gint ett_smb_nt_create_options = -1;
827 static gint ett_smb_nt_share_access = -1;
828 static gint ett_smb_nt_security_flags = -1;
829 static gint ett_smb_nt_trans_setup = -1;
830 static gint ett_smb_nt_trans_data = -1;
831 static gint ett_smb_nt_trans_param = -1;
832 static gint ett_smb_nt_notify_completion_filter = -1;
833 static gint ett_smb_nt_ioctl_flags = -1;
834 static gint ett_smb_security_information_mask = -1;
835 static gint ett_smb_print_queue_entry = -1;
836 static gint ett_smb_transaction_flags = -1;
837 static gint ett_smb_transaction_params = -1;
838 static gint ett_smb_find_first2_flags = -1;
839 static gint ett_smb_mac_support_flags = -1;
840 #if 0
841 static gint ett_smb_ioflag = -1;
842 #endif
843 static gint ett_smb_transaction_data = -1;
844 static gint ett_smb_stream_info = -1;
845 static gint ett_smb_dfs_referrals = -1;
846 static gint ett_smb_dfs_referral = -1;
847 static gint ett_smb_dfs_referral_flags = -1;
848 static gint ett_smb_dfs_referral_expnames = -1;
849 static gint ett_smb_get_dfs_flags = -1;
850 static gint ett_smb_ff2_data = -1;
851 static gint ett_smb_device_characteristics = -1;
852 static gint ett_smb_fs_attributes = -1;
853 static gint ett_smb_segments = -1;
854 static gint ett_smb_segment = -1;
855 static gint ett_smb_quotaflags = -1;
856 static gint ett_smb_secblob = -1;
857 static gint ett_smb_unicode_password = -1;
858 static gint ett_smb_ea = -1;
859 static gint ett_smb_unix_capabilities = -1;
860 static gint ett_smb_unix_whoami_gids = -1;
861 static gint ett_smb_unix_whoami_sids = -1;
862 static gint ett_smb_posix_ace = -1;
863 static gint ett_smb_posix_ace_perms = -1;
864 static gint ett_smb_info2_file_flags = -1;
865 
866 static expert_field ei_smb_missing_word_parameters = EI_INIT;
867 static expert_field ei_smb_mal_information_level = EI_INIT;
868 static expert_field ei_smb_not_implemented = EI_INIT;
869 static expert_field ei_smb_nt_transaction_setup = EI_INIT;
870 static expert_field ei_smb_posix_ace_type = EI_INIT;
871 static expert_field ei_smb_info_level_unknown = EI_INIT;
872 static expert_field ei_smb_info_level_not_understood = EI_INIT;
873 
874 static int smb_tap = -1;
875 static int smb_eo_tap = -1;
876 
877 static dissector_handle_t smb_handle;
878 static dissector_handle_t gssapi_handle;
879 static dissector_handle_t ntlmssp_handle;
880 
881 static const fragment_items smb_frag_items = {
882 	&ett_smb_segment,
883 	&ett_smb_segments,
884 
885 	&hf_smb_segments,
886 	&hf_smb_segment,
887 	&hf_smb_segment_overlap,
888 	&hf_smb_segment_overlap_conflict,
889 	&hf_smb_segment_multiple_tails,
890 	&hf_smb_segment_too_long_fragment,
891 	&hf_smb_segment_error,
892 	&hf_smb_segment_count,
893 	NULL,
894 	&hf_smb_reassembled_length,
895 	/* Reassembled data field */
896 	NULL,
897 	"segments"
898 };
899 
900 static proto_tree *top_tree_global = NULL;     /* ugly */
901 
902 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);
903 
904 #define SMB_NUM_PROCEDURES     256
905 #define SMB_SRT_TABLE_INDEX    0
906 #define TRANS2_SRT_TABLE_INDEX 1
907 #define NT_SRT_TABLE_INDEX     2
908 
909 static void
smbstat_init(struct register_srt * srt _U_,GArray * srt_array)910 smbstat_init(struct register_srt* srt _U_, GArray* srt_array)
911 {
912 	srt_stat_table *smb_srt_table;
913 	srt_stat_table *trans2_srt_table;
914 	srt_stat_table *nt_srt_table;
915 	guint32 i;
916 
917 	smb_srt_table = init_srt_table("SMB Commands", NULL, srt_array, SMB_NUM_PROCEDURES, "Commands", "smb.cmd", NULL);
918 	trans2_srt_table = init_srt_table("Transaction2 Sub-Commands", NULL, srt_array, SMB_NUM_PROCEDURES, "Transaction2 Commands", "smb.trans2.cmd", NULL);
919 	nt_srt_table = init_srt_table("NT Transaction Sub-Commands", NULL, srt_array, SMB_NUM_PROCEDURES, "NT Transaction Sub-Commands", "smb.nt.function", NULL);
920 	for (i = 0; i < SMB_NUM_PROCEDURES; i++)
921 	{
922 		init_srt_table_row(smb_srt_table, i, val_to_str_ext_const(i, &smb_cmd_vals_ext, "<unknown>"));
923 		init_srt_table_row(trans2_srt_table, i, val_to_str_ext_const(i, &trans2_cmd_vals_ext, "<unknown>"));
924 		init_srt_table_row(nt_srt_table, i, val_to_str_ext_const(i, &nt_cmd_vals_ext, "<unknown>"));
925 	}
926 }
927 
928 static tap_packet_status
smbstat_packet(void * pss,packet_info * pinfo,epan_dissect_t * edt _U_,const void * prv)929 smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
930 {
931 	guint i = 0;
932 	srt_stat_table *smb_srt_table;
933 	srt_data_t *data = (srt_data_t *)pss;
934 	const smb_info_t *si = (const smb_info_t *)prv;
935 
936 	/* we are only interested in reply packets */
937 	if (si->request) {
938 		return TAP_PACKET_DONT_REDRAW;
939 	}
940 	/* if we havnt seen the request, just ignore it */
941 	if (!si->sip) {
942 		return TAP_PACKET_DONT_REDRAW;
943 	}
944 
945 	if (si->cmd == 0xA0 && si->sip->extra_info_type == SMB_EI_NTI) {
946 		smb_nt_transact_info_t *sti = (smb_nt_transact_info_t *)si->sip->extra_info;
947 
948 		/*nt transaction*/
949 		if (sti) {
950 			i = NT_SRT_TABLE_INDEX;
951 			smb_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
952 			add_srt_table_data(smb_srt_table, sti->subcmd, &si->sip->req_time, pinfo);
953 		}
954 	} else if (si->cmd == 0x32 && si->sip->extra_info_type == SMB_EI_T2I) {
955 		smb_transact2_info_t *st2i = (smb_transact2_info_t *)si->sip->extra_info;
956 
957 		/*transaction2*/
958 		if (st2i) {
959 			i = TRANS2_SRT_TABLE_INDEX;
960 			smb_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
961 			add_srt_table_data(smb_srt_table, st2i->subcmd, &si->sip->req_time, pinfo);
962 		}
963 	} else {
964 		i = SMB_SRT_TABLE_INDEX;
965 		smb_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
966 		add_srt_table_data(smb_srt_table, si->cmd, &si->sip->req_time, pinfo);
967 	}
968 
969 	return TAP_PACKET_REDRAW;
970 
971 }
972 
973 /*
974  * Export object functionality
975  */
976 /* These flags show what kind of data the object contains
977    (designed to be or'ed) */
978 #define SMB_EO_CONTAINS_NOTHING         0x00
979 #define SMB_EO_CONTAINS_READS           0x01
980 #define SMB_EO_CONTAINS_WRITES          0x02
981 #define SMB_EO_CONTAINS_READSANDWRITES  0x03
982 
983 static const value_string smb_eo_contains_string[] = {
984 	{SMB_EO_CONTAINS_NOTHING,            ""   },
985 	{SMB_EO_CONTAINS_READS,              "R"  },
986 	{SMB_EO_CONTAINS_WRITES,             "W"  },
987 	{SMB_EO_CONTAINS_READSANDWRITES,     "R&W"},
988 	{0, NULL}
989 };
990 
991 /* Strings that describes the SMB object type */
992 static const value_string smb_fid_types[] = {
993 	{SMB_FID_TYPE_UNKNOWN,"UNKNOWN"},
994 	{SMB_FID_TYPE_FILE,"FILE"},
995 	{SMB_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"},
996 	{SMB_FID_TYPE_PIPE,"PIPE (Not Implemented)"},
997 	{0, NULL}
998 };
999 
1000 static const value_string smb2_fid_types[] = {
1001 	{SMB2_FID_TYPE_UNKNOWN,"UNKNOWN"},
1002 	{SMB2_FID_TYPE_FILE,"FILE"},
1003 	{SMB2_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"},
1004 	{SMB2_FID_TYPE_PIPE,"PIPE (Not Implemented)"},
1005 	{SMB2_FID_TYPE_OTHER,"OTHER (Not Implemented)"},
1006 	{0, NULL}
1007 };
1008 
1009 
1010 /* This struct contains the relationship between
1011 	the row# in the export_object window and the file being captured;
1012 	the row# in this GSList will match the row# in the entry list */
1013 
1014 typedef struct _active_file {
1015 	guint16   tid, uid;
1016 	guint32   fid;              /* 16-bit fid (smb) or 32-bit compressed fid (smb2) */
1017 	guint64   file_length;      /* The last free reported offset. We treat it as the file length */
1018 	guint64   data_gathered;    /* The actual total of data gathered */
1019 	guint8    flag_contains;    /* What kind of data it contains     */
1020 	GSList   *free_chunk_list;  /* A list of virtual "holes" in the file stream stored in memory */
1021 	gboolean  is_out_of_memory; /* TRUE if we cannot allocate memory for this file */
1022 } active_file ;
1023 
1024 /* This is the GSList that will contain all the files that we are tracking */
1025 static GSList    *GSL_active_files = NULL;
1026 
1027 /* We define a free chunk in a file as an start offset and end offset
1028 	Consider a free chunk as a "hole" in a file that we are capturing */
1029 typedef struct _free_chunk {
1030 	guint64 start_offset;
1031 	guint64 end_offset;
1032 } free_chunk;
1033 
1034 /* insert_chunk function will recalculate the free_chunk_list, the data_size,
1035 	the end_of_file, and the data_gathered as appropriate.
1036 	It will also insert the data chunk that is coming in the right
1037 	place of the file in memory.
1038 	HINTS:
1039 	file->data_gathered		contains the real data gathered independently from the file length
1040 	file->file_length		contains the length of the file in memory, i.e.,
1041 							the last offset captured. In most cases, the real
1042 							file length would be different.
1043 */
1044 static void
insert_chunk(active_file * file,export_object_entry_t * entry,const smb_eo_t * eo_info)1045 insert_chunk(active_file   *file, export_object_entry_t *entry, const smb_eo_t *eo_info)
1046 {
1047 	gint       nfreechunks      = g_slist_length(file->free_chunk_list);
1048 	gint       i;
1049 	free_chunk *current_free_chunk;
1050 	free_chunk *new_free_chunk;
1051 	guint64     chunk_offset     = eo_info->smb_file_offset;
1052 	guint64     chunk_length     = eo_info->payload_len;
1053 	guint64     chunk_end_offset = chunk_offset + chunk_length-1;
1054 	/* Size of file in memory */
1055 	guint64     calculated_size  = chunk_offset + chunk_length;
1056 	gpointer    dest_memory_addr;
1057 
1058 	/* Let's recalculate the file length and data gathered */
1059 	if ((file->data_gathered == 0) && (nfreechunks == 0)) {
1060 		/* If this is the first entry for this file, we first create an initial free chunk */
1061 		new_free_chunk = g_new(free_chunk, 1);
1062 		new_free_chunk->start_offset = 0;
1063 		new_free_chunk->end_offset = MAX(file->file_length, chunk_end_offset+1) - 1;
1064 		file->free_chunk_list = NULL;
1065 		file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk);
1066 		nfreechunks += 1;
1067 	} else {
1068 		if (chunk_end_offset > file->file_length-1) {
1069 			new_free_chunk = g_new(free_chunk, 1);
1070 			new_free_chunk->start_offset = file->file_length;
1071 			new_free_chunk->end_offset = chunk_end_offset;
1072 			file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk);
1073 			nfreechunks += 1;
1074 		}
1075 	}
1076 	file->file_length = MAX(file->file_length, chunk_end_offset+1);
1077 
1078 	/* Recalculate each free chunk according with the incoming data chunk */
1079 	for (i=0; i<nfreechunks; i++) {
1080 		current_free_chunk = (free_chunk *)g_slist_nth_data(file->free_chunk_list, i);
1081 		/* 1. data chunk before the free chunk? */
1082 		/* -> free chunk is not altered and no new data gathered */
1083 		if (chunk_end_offset<current_free_chunk->start_offset) {
1084 			continue;
1085 		}
1086 		/* 2. data chunk overlaps the first part of free_chunk */
1087 		/* -> free chunk shrinks from the beginning */
1088 		if (chunk_offset<=current_free_chunk->start_offset && chunk_end_offset>=current_free_chunk->start_offset && chunk_end_offset<current_free_chunk->end_offset) {
1089 			file->data_gathered += chunk_end_offset-current_free_chunk->start_offset+1;
1090 			current_free_chunk->start_offset=chunk_end_offset+1;
1091 			continue;
1092 		}
1093 		/* 3. data chunk overlaps completely the free chunk */
1094 		/* -> free chunk is removed */
1095 		if (chunk_offset<=current_free_chunk->start_offset && chunk_end_offset>=current_free_chunk->end_offset) {
1096 			file->data_gathered += current_free_chunk->end_offset-current_free_chunk->start_offset+1;
1097 			file->free_chunk_list = g_slist_remove(file->free_chunk_list, current_free_chunk);
1098 			nfreechunks -= 1;
1099 			if (nfreechunks == 0) { /* The free chunk list is empty */
1100 				g_slist_free(file->free_chunk_list);
1101 				file->free_chunk_list = NULL;
1102 				break;
1103 			}
1104 			i--;
1105 			continue;
1106 		}
1107 		/* 4. data chunk is inside the free chunk */
1108 		/* -> free chunk is split into two */
1109 		if (chunk_offset>current_free_chunk->start_offset && chunk_end_offset<current_free_chunk->end_offset) {
1110 			new_free_chunk = g_new(free_chunk, 1);
1111 			new_free_chunk->start_offset = chunk_end_offset + 1;
1112 			new_free_chunk->end_offset = current_free_chunk->end_offset;
1113 			current_free_chunk->end_offset = chunk_offset-1;
1114 			file->free_chunk_list = g_slist_insert(file->free_chunk_list, new_free_chunk, i + 1);
1115 			file->data_gathered += chunk_length;
1116 			continue;
1117 		}
1118 		/* 5.- data chunk overlaps the end part of free chunk */
1119 		/* -> free chunk shrinks from the end */
1120 		if (chunk_offset>current_free_chunk->start_offset && chunk_offset<=current_free_chunk->end_offset && chunk_end_offset>=current_free_chunk->end_offset) {
1121 			file->data_gathered += current_free_chunk->end_offset-chunk_offset+1;
1122 			current_free_chunk->end_offset = chunk_offset-1;
1123 			continue;
1124 		}
1125 		/* 6.- data chunk is after the free chunk */
1126 		/* -> free chunk is not altered and no new data gathered */
1127 		if (chunk_offset>current_free_chunk->end_offset) {
1128 			continue;
1129 		}
1130 	}
1131 
1132 	/* Now, let's insert the data chunk into memory
1133 	   ...first, we shall be able to allocate the memory */
1134 	if (!entry->payload_data) {
1135 		/* This is a New file */
1136 		if (calculated_size > G_MAXUINT32) {
1137 			/*
1138 			 * The argument to g_try_malloc() is
1139 			 * a gsize, however the maximum size of a file
1140 			 * is 32-bit.  If the calculated size is
1141 			 * bigger than that, we just say the attempt
1142 			 * to allocate memory failed.
1143 			 */
1144 			entry->payload_data = NULL;
1145 		} else {
1146 			entry->payload_data = (guint8 *)g_try_malloc((gsize)calculated_size);
1147 			entry->payload_len  = (size_t)calculated_size;
1148 		}
1149 		if (!entry->payload_data) {
1150 			/* Memory error */
1151 			file->is_out_of_memory = TRUE;
1152 		}
1153 	} else {
1154 		/* This is an existing file in memory */
1155 		if (calculated_size > (guint64) entry->payload_len &&
1156 			!file->is_out_of_memory) {
1157 			/* We need more memory */
1158 			if (calculated_size > G_MAXUINT32) {
1159 				/*
1160 				 * As for g_try_malloc(), so for
1161 				 * g_try_realloc().
1162 				 */
1163 				dest_memory_addr = NULL;
1164 			} else {
1165 				dest_memory_addr = g_try_realloc(
1166 					entry->payload_data,
1167 					(gsize)calculated_size);
1168 			}
1169 			if (!dest_memory_addr) {
1170 				/* Memory error */
1171 				file->is_out_of_memory = TRUE;
1172 				/* We don't have memory for this file.
1173 				   Free the current file content from memory */
1174 				g_free(entry->payload_data);
1175 				entry->payload_data = NULL;
1176 				entry->payload_len = 0;
1177 			} else {
1178 				entry->payload_data = (guint8 *)dest_memory_addr;
1179 				entry->payload_len = (size_t)calculated_size;
1180 			}
1181 		}
1182 	}
1183 	/* ...then, put the chunk of the file in the right place */
1184 	if (!file->is_out_of_memory) {
1185 		dest_memory_addr = entry->payload_data + chunk_offset;
1186 		memmove(dest_memory_addr, eo_info->payload_data, eo_info->payload_len);
1187 	}
1188 }
1189 
1190 /* We use this function to obtain the index in the GSL of a given file */
1191 static int
find_incoming_file(GSList * GSL_active_files_p,active_file * incoming_file)1192 find_incoming_file(GSList *GSL_active_files_p, active_file *incoming_file)
1193 {
1194 	int          i, row, last;
1195 	active_file *in_list_file;
1196 
1197 	row  = -1;
1198 	last = g_slist_length(GSL_active_files_p) - 1;
1199 
1200 	/* We lookup in reverse order because it is more likely that the file
1201 		is one of the latest */
1202 	for (i=last; i>=0; i--) {
1203 		in_list_file = (active_file *)g_slist_nth_data(GSL_active_files_p, i);
1204 		/* The best-working criteria of two identical files is that the file
1205 			that is the same of the file that we are analyzing is the last one
1206 			in the list that has the same tid and the same fid */
1207 		/* note that we have excluded in_list_file->uid == incoming_file->uid
1208 			from the comparison, because a file can be opened by different
1209 			SMB users and it is still the same file */
1210 		if (in_list_file->tid == incoming_file->tid &&
1211 			in_list_file->fid == incoming_file->fid) {
1212 			row = i;
1213 			break;
1214 		}
1215 	}
1216 
1217 	return row;
1218 }
1219 
1220 static tap_packet_status
smb_eo_packet(void * tapdata,packet_info * pinfo,epan_dissect_t * edt _U_,const void * data)1221 smb_eo_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
1222 {
1223 	export_object_list_t   *object_list = (export_object_list_t *)tapdata;
1224 	const smb_eo_t         *eo_info     = (const smb_eo_t *)data;
1225 
1226 	export_object_entry_t  *entry;
1227 	export_object_entry_t  *current_entry;
1228 	active_file             incoming_file;
1229 	gint                    active_row;
1230 	active_file            *new_file;
1231 	active_file            *current_file;
1232 	guint8                  contains;
1233 	gboolean                is_supported_filetype;
1234 	gfloat                  percent;
1235 
1236 	const gchar            *aux_smb_fid_type_string;
1237 
1238 	if (eo_info->smbversion==1) {
1239 		/* Is this an eo_smb supported file_type? (right now we only support FILE) */
1240 		is_supported_filetype = (eo_info->fid_type == SMB_FID_TYPE_FILE);
1241 		aux_smb_fid_type_string = val_to_str_const(eo_info->fid_type, smb_fid_types, "?");
1242 
1243 		/* What kind of data this packet contains? */
1244 		switch(eo_info->cmd) {
1245 		case SMB_COM_READ_ANDX:
1246 		case SMB_COM_READ:
1247 			contains = SMB_EO_CONTAINS_READS;
1248 			break;
1249 		case SMB_COM_WRITE_ANDX:
1250 		case SMB_COM_WRITE:
1251 			contains = SMB_EO_CONTAINS_WRITES;
1252 			break;
1253 		default:
1254 			contains = SMB_EO_CONTAINS_NOTHING;
1255 			break;
1256 		}
1257 	} else {
1258 		/* Is this an eo_smb supported file_type? (right now we only support FILE) */
1259 		is_supported_filetype = (eo_info->fid_type == SMB2_FID_TYPE_FILE );
1260 		aux_smb_fid_type_string = val_to_str_const(eo_info->fid_type, smb2_fid_types, "?");
1261 
1262 		/* What kind of data this packet contains? */
1263 		switch(eo_info->cmd) {
1264 		case SMB2_COM_READ:
1265 			contains = SMB_EO_CONTAINS_READS;
1266 			break;
1267 		case SMB2_COM_WRITE:
1268 			contains = SMB_EO_CONTAINS_WRITES;
1269 			break;
1270 		default:
1271 			contains = SMB_EO_CONTAINS_NOTHING;
1272 			break;
1273 		}
1274 	}
1275 
1276 
1277 	/* Is this data from an already tracked file or not? */
1278 	incoming_file.tid = eo_info->tid;
1279 	incoming_file.uid = eo_info->uid;
1280 	incoming_file.fid = eo_info->fid;
1281 	active_row = find_incoming_file(GSL_active_files, &incoming_file);
1282 
1283 	if (active_row == -1) { /* This is a new-tracked file */
1284 		/* Construct the entry in the list of active files */
1285 		entry = g_new(export_object_entry_t, 1);
1286 		entry->payload_data = NULL;
1287 		entry->payload_len = 0;
1288 		new_file = g_new(active_file, 1);
1289 		new_file->tid = incoming_file.tid;
1290 		new_file->uid = incoming_file.uid;
1291 		new_file->fid = incoming_file.fid;
1292 		new_file->file_length = eo_info->end_of_file;
1293 		new_file->flag_contains = contains;
1294 		new_file->free_chunk_list = NULL;
1295 		new_file->data_gathered = 0;
1296 		new_file->is_out_of_memory = FALSE;
1297 		entry->pkt_num = pinfo->num;
1298 
1299 		entry->hostname=g_filename_display_name(eo_info->hostname);
1300 		entry->filename=g_filename_display_name(eo_info->filename);
1301 
1302 		/* Insert the first chunk in the chunk list of this file */
1303 		if (is_supported_filetype) {
1304 			insert_chunk(new_file, entry, eo_info);
1305 		}
1306 
1307 		if (new_file->is_out_of_memory) {
1308 			entry->content_type =
1309 				g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]",
1310 								aux_smb_fid_type_string,
1311 								new_file->data_gathered,
1312 								new_file->file_length,
1313 								try_val_to_str(contains, smb_eo_contains_string));
1314 		} else {
1315 			if (new_file->file_length > 0) {
1316 				percent = (gfloat) (100*new_file->data_gathered/new_file->file_length);
1317 			} else {
1318 				percent = 0.0f;
1319 			}
1320 
1321 			entry->content_type =
1322 				g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]",
1323 								aux_smb_fid_type_string,
1324 								new_file->data_gathered,
1325 								new_file->file_length,
1326 								try_val_to_str(contains, smb_eo_contains_string),
1327 								percent);
1328 		}
1329 
1330 		object_list->add_entry(object_list->gui_data, entry);
1331 		GSL_active_files = g_slist_append(GSL_active_files, new_file);
1332 	}
1333 	else if (is_supported_filetype) {
1334 		current_file = (active_file *)g_slist_nth_data(GSL_active_files, active_row);
1335 		/* Recalculate the current file flags */
1336 		current_file->flag_contains = current_file->flag_contains|contains;
1337 		current_entry = object_list->get_entry(object_list->gui_data, active_row);
1338 
1339 		insert_chunk(current_file, current_entry, eo_info);
1340 
1341 		/* Modify the current_entry object_type string */
1342 		if (current_file->is_out_of_memory) {
1343 			current_entry->content_type =
1344 				g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]",
1345 								aux_smb_fid_type_string,
1346 								current_file->data_gathered,
1347 								current_file->file_length,
1348 								try_val_to_str(current_file->flag_contains, smb_eo_contains_string));
1349 		} else {
1350 			percent = (gfloat) (100*current_file->data_gathered/current_file->file_length);
1351 			current_entry->content_type =
1352 				g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]",
1353 								aux_smb_fid_type_string,
1354 								current_file->data_gathered,
1355 								current_file->file_length,
1356 								try_val_to_str(current_file->flag_contains, smb_eo_contains_string),
1357 								percent);
1358 		}
1359 	}
1360 
1361 	return TAP_PACKET_REDRAW; /* State changed - window should be redrawn */
1362 }
1363 
1364 /* This is the eo_reset_cb function that is used in the export_object module
1365    to cleanup any previous private data of the export object functionality before perform
1366    the eo_reset function or when the window closes */
1367 static void
smb_eo_cleanup(void)1368 smb_eo_cleanup(void)
1369 {
1370 	int          i, last;
1371 	active_file *in_list_file;
1372 
1373 	/* Free any previous data structures used in previous invocation to the
1374 		export_object_smb function */
1375 	last = g_slist_length(GSL_active_files);
1376 	if (GSL_active_files) {
1377 		for (i=last-1; i>=0; i--) {
1378 			in_list_file = (active_file *)g_slist_nth_data(GSL_active_files, i);
1379 			if (in_list_file->free_chunk_list) {
1380 				g_slist_free(in_list_file->free_chunk_list);
1381 				in_list_file->free_chunk_list = NULL;
1382 			}
1383 			g_free(in_list_file);
1384 		}
1385 		g_slist_free(GSL_active_files);
1386 		GSL_active_files = NULL;
1387 	}
1388 }
1389 
1390 /*
1391  * Macros for use in the main dissector routines for an SMB.
1392  */
1393 
1394 #define WORD_COUNT	\
1395 	/* Word Count */				\
1396 	wc = tvb_get_guint8(tvb, offset);		\
1397 	proto_tree_add_uint(tree, hf_smb_word_count,	\
1398 		tvb, offset, 1, wc);			\
1399 	offset += 1;					\
1400 	if (wc == 0) goto bytecount;
1401 
1402 #define BYTE_COUNT	\
1403 	bytecount:					\
1404 	bc = tvb_get_letohs(tvb, offset);		\
1405 	proto_tree_add_uint(tree, hf_smb_byte_count,	\
1406 			tvb, offset, 2, bc);		\
1407 	offset += 2;					\
1408 	if (bc == 0) goto endofcommand;
1409 
1410 #define CHECK_BYTE_COUNT(len)	\
1411 	if (bc < len) goto endofcommand;
1412 
1413 #define COUNT_BYTES(len)	{\
1414 	int tmp;		\
1415 	tmp = len;		\
1416 	offset += tmp;		\
1417 	bc -= tmp;			\
1418 	}
1419 
1420 #define END_OF_SMB	\
1421 	if (bc != 0) { \
1422 		gint bc_remaining; \
1423 		bc_remaining = tvb_reported_length_remaining(tvb, offset); \
1424 		if ( ((gint)bc) > bc_remaining) { \
1425 			bc = bc_remaining; \
1426 		} \
1427 		if (bc) { \
1428 			proto_tree_add_item(tree, hf_smb_extra_byte_parameters, tvb, offset, bc, ENC_NA);		\
1429 		} \
1430 		offset += bc;				\
1431 	}						\
1432 	endofcommand:
1433 
1434 /*
1435  * Macros for use in routines called by them.
1436  */
1437 #define CHECK_BYTE_COUNT_SUBR(len)	\
1438 	if (*bcp < len) {		\
1439 		*trunc = TRUE;		\
1440 		return offset;		\
1441 	}
1442 
1443 #define CHECK_STRING_SUBR(fn)	\
1444 	if (fn == NULL) {	\
1445 		*trunc = TRUE;	\
1446 		return offset;	\
1447 	}
1448 
1449 #define COUNT_BYTES_SUBR(len)	\
1450 	offset += len;		\
1451 	*bcp -= len;
1452 
1453 /*
1454  * Macros for use when dissecting transaction parameters and data
1455  */
1456 #define CHECK_BYTE_COUNT_TRANS(len)	\
1457 	if (bc < len) return offset;
1458 
1459 #define CHECK_STRING_TRANS(fn)	\
1460 	if (fn == NULL) return offset;
1461 
1462 #define COUNT_BYTES_TRANS(len)	\
1463 	offset += len;		\
1464 	bc -= len;
1465 
1466 /*
1467  * Macros for use in subrroutines dissecting transaction parameters or data
1468  */
1469 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)	\
1470 	if (*bcp < len) return offset;
1471 
1472 #define CHECK_STRING_TRANS_SUBR(fn)	\
1473 	if (fn == NULL) return offset;
1474 
1475 #define COUNT_BYTES_TRANS_SUBR(len)	\
1476 	offset += len;			\
1477 	*bcp -= len;
1478 
1479 gboolean sid_display_hex = FALSE;
1480 gboolean sid_name_snooping = FALSE;
1481 
1482 /* ExportObject preferences variable */
1483 gboolean eosmb_take_name_as_fid = FALSE ;
1484 /* Utility to get an str reprensenting ipv4 or ipv6 address */
tree_ip_str(packet_info * pinfo,guint16 cmd)1485 const gchar *tree_ip_str(packet_info *pinfo, guint16 cmd) {
1486 	const gchar	*buf;
1487 
1488 	if (	cmd == SMB_COM_READ_ANDX ||
1489 		cmd == SMB_COM_READ ||
1490 		cmd == SMB2_COM_READ) {
1491 		buf = address_to_str(wmem_packet_scope(), &pinfo->src);
1492 	} else {
1493 		buf = address_to_str(wmem_packet_scope(), &pinfo->dst);
1494 	}
1495 
1496 	return buf;
1497 }
1498 
1499 
1500 /* ExportObject feed function*/
1501 static void
feed_eo_smb(guint16 cmd,guint16 fid,tvbuff_t * tvb,packet_info * pinfo,guint16 dataoffset,guint32 datalen,guint32 chunk_len,guint64 file_offset,smb_info_t * si)1502 feed_eo_smb(guint16 cmd, guint16 fid, tvbuff_t * tvb, packet_info *pinfo, guint16 dataoffset, guint32 datalen, guint32 chunk_len,
1503 			guint64 file_offset, smb_info_t *si) {
1504 
1505 	smb_eo_t        *eo_info; /* 	eo_info variable to pass info. to
1506 					export object and aux */
1507 	smb_tid_info_t  *tid_info = NULL;
1508 	smb_fid_info_t  *fid_info = NULL;
1509 	smb_fid_info_t  *suspect_fid_info = NULL;
1510 	tvbuff_t        *data_tvb;
1511 	GSList          *GSL_iterator;
1512 
1513 	/* Create a new tvb to point to the payload data */
1514 	data_tvb = tvb_new_subset_length(tvb, dataoffset, datalen);
1515 	/* Create the eo_info to pass to the listener */
1516 	eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
1517 
1518 	/* Try to get fid_info and tid_info */
1519 	if (fid_info == NULL) {
1520 		GSL_iterator = si->ct->GSL_fid_info;
1521 		while (GSL_iterator) {
1522 			suspect_fid_info = (smb_fid_info_t *)GSL_iterator->data;
1523 			if (suspect_fid_info->opened_in > pinfo->num) break;
1524 			if ((suspect_fid_info->tid == si->tid) && (suspect_fid_info->fid == fid))
1525 				fid_info = suspect_fid_info;
1526 			GSL_iterator = g_slist_next(GSL_iterator);
1527 			}
1528 		}
1529 
1530 
1531 	tid_info = (smb_tid_info_t *)wmem_tree_lookup32(si->ct->tid_tree, si->tid);
1532 
1533 	/* Construct the eo_info structure */
1534 	eo_info->smbversion = 1;
1535 	if (tid_info) {
1536 		if (tid_info->filename) {
1537 			eo_info->hostname = tid_info->filename;
1538 		} else {
1539 			eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN", tree_ip_str(pinfo, cmd));
1540 		}
1541 	}
1542 	else            eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i", tree_ip_str(pinfo, cmd), si->tid);
1543 	if (fid_info) {
1544 		eo_info->filename = NULL;
1545 		if (fid_info->fsi)
1546 			if (fid_info->fsi->filename)
1547 				eo_info->filename = (gchar *) fid_info->fsi->filename;
1548 		if (!eo_info->filename) eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\FILEID_%i", fid);
1549 		eo_info->fid_type = fid_info->type;
1550 		eo_info->end_of_file = fid_info->end_of_file;
1551 	} else {
1552 		eo_info->fid_type = SMB_FID_TYPE_UNKNOWN;
1553 		eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\FILEID_%i", fid);
1554 		eo_info->end_of_file = 0;
1555 	}
1556 	if (eosmb_take_name_as_fid) {
1557 		eo_info->fid = g_str_hash(eo_info->filename);
1558 	} else {
1559 		eo_info->fid = fid;
1560 	}
1561 	eo_info->tid = si->tid;
1562 	eo_info->uid = si->uid;
1563 	eo_info->payload_len = datalen;
1564 	eo_info->payload_data = tvb_get_ptr(data_tvb, 0, datalen);
1565 	eo_info->smb_file_offset = file_offset;
1566 	eo_info->smb_chunk_len = chunk_len;
1567 	eo_info->cmd = cmd;
1568 	/* Queue data to the listener */
1569 
1570 	tap_queue_packet(smb_eo_tap, pinfo, eo_info);
1571 } /* feed_eo_smb */
1572 
1573 /* Compare function to maintain the GSL_fid_info ordered
1574    Order criteria: packet where the fid was opened */
1575 static gint
fid_cmp(smb_fid_info_t * fida,smb_fid_info_t * fidb)1576 fid_cmp(smb_fid_info_t *fida, smb_fid_info_t *fidb)
1577 {
1578 	return (fida->opened_in - fidb->opened_in);
1579 }
1580 
1581 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1582    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
1583    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1584 static gboolean smb_trans_reassembly = TRUE;
1585 gboolean smb_dcerpc_reassembly = TRUE;
1586 
1587 static reassembly_table smb_trans_reassembly_table;
1588 
1589 static fragment_head *
smb_trans_defragment(proto_tree * tree _U_,packet_info * pinfo,tvbuff_t * tvb,int offset,guint count,guint pos,guint totlen,smb_info_t * si)1590 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
1591 		     int offset, guint count, guint pos, guint totlen, smb_info_t *si)
1592 {
1593 	fragment_head *fd_head = NULL;
1594 	int            more_frags;
1595 
1596 	/* Don't pass the reassembly code data that doesn't exist */
1597 	/* Fail if some or all of the fragment is located beyond the total length */
1598 	if ( !tvb_bytes_exist(tvb, offset, count) || (pos > totlen) || (count > totlen) || ((pos + count) > totlen)) {
1599 		THROW(ReportedBoundsError);
1600 	}
1601 
1602 	more_frags = totlen > (pos + count);
1603 
1604 	DISSECTOR_ASSERT(si);
1605 
1606 	if (si->sip == NULL) {
1607 		/*
1608 		 * We don't have the frame number of the request.
1609 		 */
1610 		return NULL;
1611 	}
1612 
1613 	if (!pinfo->fd->visited) {
1614 		fd_head = fragment_add(&smb_trans_reassembly_table, tvb, offset,
1615 				       pinfo, si->sip->frame_req, NULL,
1616 				       pos, count, more_frags);
1617 	} else {
1618 		fd_head = fragment_get(&smb_trans_reassembly_table,
1619 				       pinfo, si->sip->frame_req, NULL);
1620 	}
1621 
1622 	if (!fd_head || !(fd_head->flags & FD_DEFRAGMENTED)) {
1623 		/* This is continued - mark it as such, so we recognize
1624 		   continuation responses.
1625 		*/
1626 		si->sip->flags |= SMB_SIF_IS_CONTINUED;
1627 	} else {
1628 		/* We've finished reassembling, so there are no more
1629 		   continuation responses.
1630 		*/
1631 		si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
1632 	}
1633 
1634 	/* we only show the defragmented packet for the first fragment,
1635 	   or else we might end up with dissecting one HUGE transaction PDU
1636 	   a LOT of times. (first fragment is the only one containing the setup
1637 	   bytes)
1638 	   I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
1639 	   SMBs. Takes a LOT of time dissecting and is not fun.
1640 	*/
1641 	if ( (pos == 0) && fd_head && (fd_head->flags & FD_DEFRAGMENTED)) {
1642 		return fd_head;
1643 	} else {
1644 		return NULL;
1645 	}
1646 }
1647 
1648 
1649 
1650 
1651 
1652 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1653    These variables and functions are used to match
1654    responses with calls
1655    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1656 /*
1657  * The information we need to save about a request in order to show the
1658  * frame number of the request in the dissection of the reply.
1659  */
1660 typedef struct  {
1661 	guint32	frame;
1662 	guint32 pid_mid;
1663 } smb_saved_info_key_t;
1664 
1665 /* unmatched smb_saved_info structures.
1666    For unmatched smb_saved_info structures we store the smb_saved_info
1667    structure using the MID and the PID as the key.
1668 
1669    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
1670    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
1671    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
1672 */
1673 static gint
smb_saved_info_equal_unmatched(gconstpointer k1,gconstpointer k2)1674 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
1675 {
1676 	register guint32 key1 = GPOINTER_TO_UINT(k1);
1677 	register guint32 key2 = GPOINTER_TO_UINT(k2);
1678 	return key1 == key2;
1679 }
1680 static guint
smb_saved_info_hash_unmatched(gconstpointer k)1681 smb_saved_info_hash_unmatched(gconstpointer k)
1682 {
1683 	register guint32 key = GPOINTER_TO_UINT(k);
1684 	return key;
1685 }
1686 
1687 /* matched smb_saved_info structures.
1688    For matched smb_saved_info structures we store the smb_saved_info
1689    structure twice in the table using the frame number, and a combination
1690    of the MID and the PID, as the key.
1691    The frame number is guaranteed to be unique but if ever someone makes
1692    some change that will renumber the frames in a capture we are in BIG trouble.
1693    This is not likely though since that would break (among other things) all the
1694    reassembly routines as well.
1695 
1696    We also need the MID as there may be more than one SMB request or reply
1697    in a single frame, and we also need the PID as there may be more than
1698    one outstanding request with the same MID and different PIDs.
1699 */
1700 static gint
smb_saved_info_equal_matched(gconstpointer k1,gconstpointer k2)1701 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1702 {
1703 	const smb_saved_info_key_t *key1 = (const smb_saved_info_key_t *)k1;
1704 	const smb_saved_info_key_t *key2 = (const smb_saved_info_key_t *)k2;
1705 	return (key1->frame == key2->frame) && (key1->pid_mid == key2->pid_mid);
1706 }
1707 static guint
smb_saved_info_hash_matched(gconstpointer k)1708 smb_saved_info_hash_matched(gconstpointer k)
1709 {
1710 	const smb_saved_info_key_t *key = (const smb_saved_info_key_t *)k;
1711 	return key->frame + key->pid_mid;
1712 }
1713 
1714 static GSList *conv_tables = NULL;
1715 
1716 
1717 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1718    End of request/response matching functions
1719    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1720 
1721 /* Max string length for displaying Unicode strings.  */
1722 #define	MAX_UNICODE_STR_LEN	256
1723 
1724 /* Turn a little-endian Unicode '\0'-terminated string into a string we
1725    can display.
1726    XXX - for now, we just handle the ISO 8859-1 characters.
1727    If exactlen==TRUE then us_lenp contains the exact len of the string in
1728    bytes. It might not be null terminated !
1729    bc specifies the number of bytes in the byte parameters; Windows 2000,
1730    at least, appears, in some cases, to put only 1 byte of 0 at the end
1731    of a Unicode string if the byte count
1732 */
1733 static gchar *
unicode_to_str(tvbuff_t * tvb,int offset,int * us_lenp,gboolean exactlen,guint16 bc)1734 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
1735 	       guint16 bc)
1736 {
1737 	gchar    *cur;
1738 	gchar    *p;
1739 	guint16   uchar;
1740 	int       len;
1741 	int       us_len;
1742 	gboolean  overflow = FALSE;
1743 
1744 	cur=(gchar *)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN+3+1);
1745 	p = cur;
1746 	len = MAX_UNICODE_STR_LEN;
1747 	us_len = 0;
1748 	for (;;) {
1749 		if (bc == 0)
1750 			break;
1751 
1752 		if (bc == 1) {
1753 			/* XXX - explain this */
1754 			if (!exactlen)
1755 				us_len += 1;	/* this is a one-byte null terminator */
1756 			break;
1757 		}
1758 
1759 		uchar = tvb_get_letohs(tvb, offset);
1760 		if (uchar == 0) {
1761 			us_len += 2;	/* this is a two-byte null terminator */
1762 			break;
1763 		}
1764 
1765 		if (len > 0) {
1766 			if ((uchar & 0xFF00) == 0)
1767 				*p++ = (gchar) uchar;	/* ISO 8859-1 */
1768 			else
1769 				*p++ = '?';	/* not 8859-1 */
1770 			len--;
1771 		} else
1772 			overflow = TRUE;
1773 
1774 		offset += 2;
1775 		bc -= 2;
1776 		us_len += 2;
1777 
1778 		if(exactlen){
1779 			if(us_len>= *us_lenp){
1780 				break;
1781 			}
1782 		}
1783 	}
1784 	if (overflow) {
1785 		/* Note that we're not showing the full string.  */
1786 		*p++ = '.';
1787 		*p++ = '.';
1788 		*p++ = '.';
1789 	}
1790 
1791 	*p = '\0';
1792 	*us_lenp = us_len;
1793 
1794 	return cur;
1795 }
1796 
1797 /* nopad == TRUE : Do not add any padding before this string
1798  * exactlen == TRUE : len contains the exact len of the string in bytes.
1799  * bc: pointer to variable with amount of data left in the byte parameters
1800  *   region
1801  */
1802 static const gchar *
get_unicode_or_ascii_string(tvbuff_t * tvb,int * offsetp,gboolean useunicode,int * len,gboolean nopad,gboolean exactlen,guint16 * bcp)1803 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
1804 			    gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,
1805 			    guint16 *bcp)
1806 {
1807 	gchar       *cur;
1808 	const gchar *string;
1809 	int          string_len = 0;
1810 	int          copylen;
1811 	gboolean     overflow   = FALSE;
1812 
1813 	if (*bcp == 0) {
1814 		/* Not enough data in buffer */
1815 		return NULL;
1816 	}
1817 
1818 	if (useunicode) {
1819 		if ((!nopad) && (*offsetp % 2)) {
1820 			(*offsetp)++;   /* Looks like a pad byte there sometimes */
1821 			(*bcp)--;
1822 
1823 			if (*bcp == 0) {
1824 				/* Not enough data in buffer */
1825 				return NULL;
1826 			}
1827 		}
1828 
1829 		if(exactlen){
1830 			string_len = *len;
1831 			if (string_len < 0) {
1832 				/* This probably means it's a very large unsigned number; just set
1833 				   it to the largest signed number, so that we throw the appropriate
1834 				   exception. */
1835 				string_len = INT_MAX;
1836 			}
1837 		}
1838 
1839 		string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
1840 
1841 	} else {
1842 		if(exactlen){
1843 			/*
1844 			 * The string we return must be null-terminated.
1845 			 */
1846 			cur=(gchar *)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN+3+1);
1847 			copylen = *len;
1848 
1849 			if (copylen < 0) {
1850 				/* This probably means it's a very large unsigned number; just set
1851 				   it to the largest signed number, so that we throw the appropriate
1852 				   exception. */
1853 				copylen = INT_MAX;
1854 			}
1855 
1856 			tvb_ensure_bytes_exist(tvb, *offsetp, copylen);
1857 
1858 			if (copylen > MAX_UNICODE_STR_LEN) {
1859 				copylen = MAX_UNICODE_STR_LEN;
1860 				overflow = TRUE;
1861 			}
1862 
1863 			tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
1864 			cur[copylen] = '\0';
1865 
1866 			if (overflow)
1867 				(void) g_strlcat(cur, "...",MAX_UNICODE_STR_LEN+3+1);
1868 
1869 			string_len = *len;
1870 			string = cur;
1871 		} else {
1872 			string = tvb_get_const_stringz(tvb, *offsetp, &string_len);
1873 		}
1874 	}
1875 
1876 	*len = string_len;
1877 	return string;
1878 }
1879 
1880 typedef struct _smb_uid_t {
1881 	char *domain;
1882 	char *account;
1883 	int   logged_in;
1884 	int   logged_out;
1885 } smb_uid_t;
1886 
1887 static void
smb_file_specific_rights(tvbuff_t * tvb,gint offset,proto_tree * tree,guint32 mask)1888 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1889 {
1890 	static int * const mask_flags[] = {
1891 		&hf_smb_file_access_mask_write_attribute,
1892 		&hf_smb_file_access_mask_read_attribute,
1893 		&hf_smb_file_access_mask_execute,
1894 		&hf_smb_file_access_mask_write_ea,
1895 		&hf_smb_file_access_mask_read_ea,
1896 		&hf_smb_file_access_mask_append_data,
1897 		&hf_smb_file_access_mask_write_data,
1898 		&hf_smb_file_access_mask_read_data,
1899 		NULL
1900 	};
1901 
1902 	mask &= 0x0000ffff;
1903 	if (mask == 0x000001ff) {
1904 		proto_tree_add_uint(tree, hf_smb_file_access_mask_full_control, tvb, offset, 4, mask);
1905 	}
1906 
1907 	proto_tree_add_bitmask_list_value(tree, tvb, offset, 4, mask_flags, mask);
1908 }
1909 static struct access_mask_info smb_file_access_mask_info = {
1910 	"FILE",				/* Name of specific rights */
1911 	smb_file_specific_rights,	/* Dissection function */
1912 	NULL,				/* Generic mapping table */
1913 	NULL				/* Standard mapping table */
1914 };
1915 
1916 
1917 static void
smb_dir_specific_rights(tvbuff_t * tvb,gint offset,proto_tree * tree,guint32 mask)1918 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1919 {
1920 	static int * const mask_flags[] = {
1921 		&hf_smb_dir_access_mask_write_attribute,
1922 		&hf_smb_dir_access_mask_read_attribute,
1923 		&hf_smb_dir_access_mask_delete_child,
1924 		&hf_smb_dir_access_mask_traverse,
1925 		&hf_smb_dir_access_mask_write_ea,
1926 		&hf_smb_dir_access_mask_read_ea,
1927 		&hf_smb_dir_access_mask_add_subdir,
1928 		&hf_smb_dir_access_mask_add_file,
1929 		&hf_smb_dir_access_mask_list,
1930 		NULL
1931 	};
1932 
1933 	mask &= 0x0000ffff;
1934 	if (mask == 0x000001ff) {
1935 		proto_tree_add_uint(tree, hf_smb_dir_access_mask_full_control, tvb, offset, 4, mask);
1936 	}
1937 
1938 	proto_tree_add_bitmask_list_value(tree, tvb, offset, 4, mask_flags, mask);
1939 }
1940 static struct access_mask_info smb_dir_access_mask_info = {
1941 	"DIR",				/* Name of specific rights */
1942 	smb_dir_specific_rights,	/* Dissection function */
1943 	NULL,				/* Generic mapping table */
1944 	NULL				/* Standard mapping table */
1945 };
1946 
1947 
1948 
1949 static const value_string buffer_format_vals[] = {
1950 	{1,     "Data Block"},
1951 	{2,     "Dialect"},
1952 	{3,     "Pathname"},
1953 	{4,     "ASCII"},
1954 	{5,     "Variable Block"},
1955 	{0,     NULL}
1956 };
1957 
1958 #define POSIX_ACE_TYPE_USER_OBJ		0x01
1959 #define POSIX_ACE_TYPE_USER		0x02
1960 #define POSIX_ACE_TYPE_GROUP_OBJ	0x04
1961 #define POSIX_ACE_TYPE_GROUP		0x08
1962 #define POSIX_ACE_TYPE_MASK		0x10
1963 #define POSIX_ACE_TYPE_OTHER		0x20
1964 static const value_string ace_type_vals[] = {
1965 	{POSIX_ACE_TYPE_USER_OBJ,	"User Obj"},
1966 	{POSIX_ACE_TYPE_USER,		"User"},
1967 	{POSIX_ACE_TYPE_GROUP_OBJ,	"Group Obj"},
1968 	{POSIX_ACE_TYPE_GROUP,		"Group"},
1969 	{POSIX_ACE_TYPE_MASK,		"Mask"},
1970 	{POSIX_ACE_TYPE_OTHER,		"Other"},
1971 	{0,     NULL}
1972 };
1973 
1974 /*
1975  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1976  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1977  * January 1, 1970, 00:00:00 GMT.
1978  *
1979  * This means we have to do some extra work to convert it.  This code is
1980  * based on the Samba code:
1981  *
1982  *	Unix SMB/Netbios implementation.
1983  *	Version 1.9.
1984  *	time handling functions
1985  *	Copyright (C) Andrew Tridgell 1992-1998
1986  */
1987 
1988 /*
1989  * Yield the difference between *A and *B, in seconds, ignoring leap
1990  * seconds.
1991  */
1992 #define TM_YEAR_BASE 1900
1993 
1994 static int
tm_diff(struct tm * a,struct tm * b)1995 tm_diff(struct tm *a, struct tm *b)
1996 {
1997 	int ay = a->tm_year + (TM_YEAR_BASE - 1);
1998 	int by = b->tm_year + (TM_YEAR_BASE - 1);
1999 	int intervening_leap_days =
2000 	    (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
2001 	int years = ay - by;
2002 	int days =
2003 	    365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
2004 	int hours = 24*days + (a->tm_hour - b->tm_hour);
2005 	int minutes = 60*hours + (a->tm_min - b->tm_min);
2006 	int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
2007 
2008 	return seconds;
2009 }
2010 
2011 /*
2012  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
2013  * determined.
2014  */
2015 static int
TimeZone(time_t t)2016 TimeZone(time_t t)
2017 {
2018 	struct tm *tm = gmtime(&t);
2019 	struct tm  tm_utc;
2020 
2021 	if (tm == NULL)
2022 		return 0;
2023 	tm_utc = *tm;
2024 	tm = localtime(&t);
2025 	if (tm == NULL)
2026 		return 0;
2027 	return tm_diff(&tm_utc, tm);
2028 }
2029 
2030 /*
2031  * Return the same value as TimeZone, but it should be more efficient.
2032  *
2033  * We keep a table of DST offsets to prevent calling localtime() on each
2034  * call of this function. This saves a LOT of time on many unixes.
2035  *
2036  * Updated by Paul Eggert <eggert@twinsun.com>
2037  */
2038 #ifndef CHAR_BIT
2039 #define CHAR_BIT 8
2040 #endif
2041 
2042 #ifndef TIME_T_MIN
2043 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
2044 		    : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
2045 #endif
2046 #ifndef TIME_T_MAX
2047 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
2048 #endif
2049 
2050 static int
TimeZoneFaster(time_t t)2051 TimeZoneFaster(time_t t)
2052 {
2053 	static struct dst_table {time_t start, end; int zone;} *tdt;
2054 	static struct dst_table *dst_table = NULL;
2055 	static int table_size = 0;
2056 	int        i;
2057 	int        zone = 0;
2058 
2059 	if (t == 0)
2060 		t = time(NULL);
2061 
2062 	/* Tunis has a 8 day DST region, we need to be careful ... */
2063 #define MAX_DST_WIDTH (365*24*60*60)
2064 #define MAX_DST_SKIP (7*24*60*60)
2065 
2066 	for (i = 0; i < table_size; i++) {
2067 		if ((t >= dst_table[i].start) && (t <= dst_table[i].end))
2068 			break;
2069 	}
2070 
2071 	if (i < table_size) {
2072 		zone = dst_table[i].zone;
2073 	} else {
2074 		time_t low, high;
2075 
2076 		zone = TimeZone(t);
2077 		if (dst_table == NULL)
2078 			tdt = (struct dst_table *)g_malloc(sizeof(dst_table[0])*(i+1));
2079 		else
2080 			tdt = (struct dst_table *)g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
2081 		if (tdt == NULL) {
2082 			g_free(dst_table);
2083 			table_size = 0;
2084 		} else {
2085 			dst_table = tdt;
2086 			table_size++;
2087 
2088 			dst_table[i].zone = zone;
2089 			dst_table[i].start = dst_table[i].end = t;
2090 
2091 			/* no entry will cover more than 6 months */
2092 			low = t - MAX_DST_WIDTH/2;
2093 			/* XXX - what if t < MAX_DST_WIDTH/2? */
2094 
2095 			high = t + MAX_DST_WIDTH/2;
2096 			/* XXX - what if this overflows? */
2097 
2098 			/*
2099 			 * Widen the new entry using two bisection searches.
2100 			 */
2101 			while (low+60*60 < dst_table[i].start) {
2102 				if (dst_table[i].start - low > MAX_DST_SKIP*2)
2103 					t = dst_table[i].start - MAX_DST_SKIP;
2104 				else
2105 					t = low + (dst_table[i].start-low)/2;
2106 				if (TimeZone(t) == zone)
2107 					dst_table[i].start = t;
2108 				else
2109 					low = t;
2110 			}
2111 
2112 			while (high-60*60 > dst_table[i].end) {
2113 				if (high - dst_table[i].end > MAX_DST_SKIP*2)
2114 					t = dst_table[i].end + MAX_DST_SKIP;
2115 				else
2116 					t = high - (high-dst_table[i].end)/2;
2117 				if (TimeZone(t) == zone)
2118 					dst_table[i].end = t;
2119 				else
2120 					high = t;
2121 			}
2122 		}
2123 	}
2124 	return zone;
2125 }
2126 
2127 /*
2128  * Return the UTC offset in seconds west of UTC, adjusted for extra time
2129  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
2130  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
2131  * daylight savings transitions because some local times are ambiguous.
2132  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
2133  */
2134 static int
LocTimeDiff(time_t lt)2135 LocTimeDiff(time_t lt)
2136 {
2137 	int    d = TimeZoneFaster(lt);
2138 	time_t t = lt + d;
2139 
2140 	/* if overflow occurred, ignore all the adjustments so far */
2141 	if (((t < lt) ^ (d < 0)))
2142 		t = lt;
2143 
2144 	/*
2145 	 * Now t should be close enough to the true UTC to yield the
2146 	 * right answer.
2147 	 */
2148 	return TimeZoneFaster(t);
2149 }
2150 
2151 static int
dissect_smb_UTIME(tvbuff_t * tvb,proto_tree * tree,int offset,int hf_date)2152 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
2153 {
2154 	guint32  timeval;
2155 	nstime_t ts;
2156 
2157 	ts.secs = timeval = tvb_get_letohl(tvb, offset);
2158 	ts.nsecs = 0;
2159 	if (timeval == 0xffffffff) {
2160 		proto_tree_add_time_format_value(tree, hf_date, tvb, offset, 4, &ts,
2161 		    "No time specified (0xffffffff)");
2162 		offset += 4;
2163 		return offset;
2164 	}
2165 
2166 	/*
2167 	 * We add the local time offset.
2168 	 */
2169 	ts.secs = timeval + LocTimeDiff(timeval);
2170 
2171 	proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
2172 	offset += 4;
2173 
2174 	return offset;
2175 }
2176 
2177 static int
dissect_smb_datetime(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int hf_date,int hf_dos_date,int hf_dos_time,gboolean time_first)2178 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
2179     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
2180 {
2181 	guint16     dos_time, dos_date;
2182 	proto_item *item = NULL;
2183 	proto_tree *tree = NULL;
2184 	struct tm   tm;
2185 	time_t      t;
2186 	nstime_t    tv;
2187 
2188 	static const int mday_noleap[12] = {
2189 		31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
2190 	};
2191 	static const int mday_leap[12] = {
2192 		31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
2193 	};
2194 
2195 #define ISLEAP(y) ((((y) % 4) == 0) && ((((y) % 100) != 0) || (((y) % 400) == 0)))
2196 
2197 	if (time_first) {
2198 		dos_time = tvb_get_letohs(tvb, offset);
2199 		dos_date = tvb_get_letohs(tvb, offset+2);
2200 	} else {
2201 		dos_date = tvb_get_letohs(tvb, offset);
2202 		dos_time = tvb_get_letohs(tvb, offset+2);
2203 	}
2204 
2205 	if (((dos_date == 0xffff) && (dos_time == 0xffff)) ||
2206 	    ((dos_date == 0) && (dos_time == 0))) {
2207 		/*
2208 		 * No date/time specified.
2209 		 */
2210 		if (parent_tree) {
2211 			tv.secs = 0;
2212 			tv.nsecs = 0;
2213 			proto_tree_add_time_format_value(parent_tree, hf_date, tvb, offset, 4,
2214 			    &tv, "No time specified (0x%08x)",
2215 			    ((dos_date << 16) | dos_time));
2216 		}
2217 		offset += 4;
2218 		return offset;
2219 	}
2220 
2221 	tm.tm_sec   = (dos_time & 0x1f) * 2;
2222 	tm.tm_min   = (dos_time>>5)  & 0x3f;
2223 	tm.tm_hour  = (dos_time>>11) & 0x1f;
2224 	tm.tm_mday  = dos_date & 0x1f;
2225 	tm.tm_mon   = ((dos_date>>5) & 0x0f) - 1;
2226 	tm.tm_year  = ((dos_date>>9) & 0x7f) + 1980 - 1900;
2227 	tm.tm_isdst = -1;
2228 
2229 	/*
2230 	 * Do some sanity checks before calling "mktime()";
2231 	 * "mktime()" doesn't do them, it "normalizes" out-of-range
2232 	 * values.
2233 	 */
2234 	if ((tm.tm_sec > 59) || (tm.tm_min > 59) || (tm.tm_hour > 23) ||
2235 	    (tm.tm_mon < 0) || (tm.tm_mon > 11) ||
2236 	    (ISLEAP(tm.tm_year + 1900) ?
2237 	     (tm.tm_mday > mday_leap[tm.tm_mon]) :
2238 	     (tm.tm_mday > mday_noleap[tm.tm_mon])) ||
2239 	    ((t = mktime(&tm)) == -1)) {
2240 		/*
2241 		 * Invalid date/time.
2242 		 */
2243 		if (parent_tree) {
2244 			tv.secs = 0;
2245 			tv.nsecs = 0;
2246 			item = proto_tree_add_time_format_value(parent_tree, hf_date, tvb, offset, 4,
2247 			    &tv, "Invalid time (0x%08x)", ((dos_date << 16) | dos_time));
2248 			tree = proto_item_add_subtree(item, ett_smb_time_date);
2249 			if (time_first) {
2250 				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);
2251 				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);
2252 			} else {
2253 				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);
2254 				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);
2255 			}
2256 		}
2257 		offset += 4;
2258 		return offset;
2259 	}
2260 
2261 	tv.secs = t;
2262 	tv.nsecs = 0;
2263 
2264 	if (parent_tree) {
2265 		item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
2266 		tree = proto_item_add_subtree(item, ett_smb_time_date);
2267 		if (time_first) {
2268 			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);
2269 			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);
2270 		} else {
2271 			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);
2272 			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);
2273 		}
2274 	}
2275 
2276 	offset += 4;
2277 
2278 	return offset;
2279 }
2280 
2281 static const true_false_string tfs_disposition_delete_on_close = {
2282 	"DELETE this file when closed",
2283 	"Normal access, do not delete on close"
2284 };
2285 
2286 static const true_false_string tfs_pipe_info_flag = {
2287 	"SET NAMED PIPE mode",
2288 	"Clear NAMED PIPE mode"
2289 };
2290 
2291 
2292 static const value_string da_access_vals[] = {
2293 	{ 0,		"Open for reading"},
2294 	{ 1,		"Open for writing"},
2295 	{ 2,		"Open for reading and writing"},
2296 	{ 3,		"Open for execute"},
2297 	{0, NULL}
2298 };
2299 static const value_string da_sharing_vals[] = {
2300 	{ 0,		"Compatibility mode"},
2301 	{ 1,		"Deny read/write/execute (exclusive)"},
2302 	{ 2,		"Deny write"},
2303 	{ 3,		"Deny read/execute"},
2304 	{ 4,		"Deny none"},
2305 	{0, NULL}
2306 };
2307 static const value_string da_locality_vals[] = {
2308 	{ 0,		"Locality of reference unknown"},
2309 	{ 1,		"Mainly sequential access"},
2310 	{ 2,		"Mainly random access"},
2311 	{ 3,		"Random access with some locality"},
2312 	{0, NULL}
2313 };
2314 static const true_false_string tfs_da_caching = {
2315 	"Do not cache this file",
2316 	"Caching permitted on this file"
2317 };
2318 static const true_false_string tfs_da_writetru = {
2319 	"Write through enabled",
2320 	"Write through disabled"
2321 };
2322 static int
dissect_access(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int hf_access)2323 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int hf_access)
2324 {
2325 	static int * const flags[] = {
2326 		&hf_smb_access_writetru,
2327 		&hf_smb_access_caching,
2328 		&hf_smb_access_locality,
2329 		&hf_smb_access_sharing,
2330 		&hf_smb_access_mode,
2331 		NULL
2332 	};
2333 
2334 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_access, ett_smb_desiredaccess, flags, ENC_LITTLE_ENDIAN);
2335 	offset += 2;
2336 
2337 	return offset;
2338 }
2339 
2340 #define SMB_FILE_ATTRIBUTE_READ_ONLY			0x00000001
2341 #define SMB_FILE_ATTRIBUTE_HIDDEN			0x00000002
2342 #define SMB_FILE_ATTRIBUTE_SYSTEM			0x00000004
2343 #define SMB_FILE_ATTRIBUTE_VOLUME			0x00000008
2344 #define SMB_FILE_ATTRIBUTE_DIRECTORY			0x00000010
2345 #define SMB_FILE_ATTRIBUTE_ARCHIVE			0x00000020
2346 #define SMB_FILE_ATTRIBUTE_DEVICE			0x00000040
2347 #define SMB_FILE_ATTRIBUTE_NORMAL			0x00000080
2348 #define SMB_FILE_ATTRIBUTE_TEMPORARY			0x00000100
2349 #define SMB_FILE_ATTRIBUTE_SPARSE			0x00000200
2350 #define SMB_FILE_ATTRIBUTE_REPARSE			0x00000400
2351 #define SMB_FILE_ATTRIBUTE_COMPRESSED			0x00000800
2352 #define SMB_FILE_ATTRIBUTE_OFFLINE			0x00001000
2353 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED		0x00002000
2354 #define SMB_FILE_ATTRIBUTE_ENCRYPTED			0x00004000
2355 
2356 static const true_false_string tfs_file_attribute_read_only = {
2357 	"READ ONLY",
2358 	"NOT read only",
2359 };
2360 static const true_false_string tfs_file_attribute_hidden = {
2361 	"HIDDEN",
2362 	"NOT hidden"
2363 };
2364 static const true_false_string tfs_file_attribute_system = {
2365 	"SYSTEM file/dir",
2366 	"NOT a system file/dir"
2367 };
2368 static const true_false_string tfs_file_attribute_volume = {
2369 	"VOLUME ID",
2370 	"NOT a volume ID"
2371 };
2372 static const true_false_string tfs_file_attribute_directory = {
2373 	"DIRECTORY",
2374 	"NOT a directory"
2375 };
2376 static const true_false_string tfs_file_attribute_archive = {
2377 	"Modified since last ARCHIVE",
2378 	"Has NOT been modified since last archive"
2379 };
2380 static const true_false_string tfs_file_attribute_device = {
2381 	"A DEVICE",
2382 	"NOT a device"
2383 };
2384 static const true_false_string tfs_file_attribute_normal = {
2385 	"An ordinary file/dir",
2386 	"Has some attribute set"
2387 };
2388 static const true_false_string tfs_file_attribute_temporary = {
2389 	"A TEMPORARY file",
2390 	"NOT a temporary file"
2391 };
2392 static const true_false_string tfs_file_attribute_sparse = {
2393 	"A SPARSE file",
2394 	"NOT a sparse file"
2395 };
2396 static const true_false_string tfs_file_attribute_reparse = {
2397 	"Has an associated REPARSE POINT",
2398 	"Does NOT have an associated reparse point"
2399 };
2400 static const true_false_string tfs_file_attribute_compressed = {
2401 	"COMPRESSED",
2402 	"Uncompressed"
2403 };
2404 static const true_false_string tfs_file_attribute_offline = {
2405 	"OFFLINE",
2406 	"Online"
2407 };
2408 static const true_false_string tfs_file_attribute_not_content_indexed = {
2409 	"CONTENT INDEXED",
2410 	"NOT content indexed"
2411 };
2412 static const true_false_string tfs_file_attribute_encrypted = {
2413 	"This is an ENCRYPTED file",
2414 	"This is NOT an encrypted file"
2415 };
2416 
2417 /*
2418  * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
2419  * section 2.2.1.2.4 of [MS-CIFS], in cases where it's just file attributes,
2420  * not search attributes.
2421  */
2422 static int
dissect_file_attributes(tvbuff_t * tvb,proto_tree * parent_tree,int offset)2423 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2424 {
2425 	static int * const flags[] = {
2426 		&hf_smb_file_attr_archive_16bit,
2427 		&hf_smb_file_attr_directory_16bit,
2428 		&hf_smb_file_attr_volume_16bit,
2429 		&hf_smb_file_attr_system_16bit,
2430 		&hf_smb_file_attr_hidden_16bit,
2431 		&hf_smb_file_attr_read_only_16bit,
2432 		NULL
2433 	};
2434 
2435 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_file_attr_16bit, ett_smb_file_attributes, flags, ENC_LITTLE_ENDIAN);
2436 	offset += 2;
2437 
2438 	return offset;
2439 }
2440 
2441 /*
2442  * 3.11 in the SNIA CIFS spec
2443  * SMB_EXT_FILE_ATTR, section 2.2.1.2.3 in the [MS-CIFS] spec
2444  */
2445 static int
dissect_file_ext_attr_bits(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int len,guint32 mask)2446 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
2447     int len, guint32 mask)
2448 {
2449 	proto_item *item;
2450 	/*
2451 	 * XXX - Network Monitor disagrees on some of the
2452 	 * bits, e.g. the bits above temporary are "atomic write"
2453 	 * and "transaction write", and it says nothing about the
2454 	 * bits above that.
2455 	 *
2456 	 * Does the Win32 API documentation, or the NT Native API book,
2457 	 * suggest anything?
2458 	 */
2459 	static int * const mask_fields[] = {
2460 		&hf_smb_file_eattr_read_only,
2461 		&hf_smb_file_eattr_hidden,
2462 		&hf_smb_file_eattr_system,
2463 		&hf_smb_file_eattr_volume,
2464 		&hf_smb_file_eattr_directory,
2465 		&hf_smb_file_eattr_archive,
2466 		&hf_smb_file_eattr_device,
2467 		&hf_smb_file_eattr_normal,
2468 		&hf_smb_file_eattr_temporary,
2469 		&hf_smb_file_eattr_sparse,
2470 		&hf_smb_file_eattr_reparse,
2471 		&hf_smb_file_eattr_compressed,
2472 		&hf_smb_file_eattr_offline,
2473 		&hf_smb_file_eattr_not_content_indexed,
2474 		&hf_smb_file_eattr_encrypted,
2475 		NULL
2476 	};
2477 
2478 	item = proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
2479 			hf_smb_file_eattr, ett_smb_file_attributes, mask_fields, mask, BMT_NO_APPEND);
2480 	if (len == 0)
2481 		proto_item_set_generated(item);
2482 
2483 	offset += len;
2484 
2485 	return offset;
2486 }
2487 
2488 /* 3.11 */
2489 static int
dissect_file_ext_attr(tvbuff_t * tvb,proto_tree * parent_tree,int offset)2490 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2491 {
2492 	guint32 mask;
2493 
2494 	mask = tvb_get_letohl(tvb, offset);
2495 
2496 	offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
2497 
2498 	return offset;
2499 }
2500 
2501 static int
dissect_dir_info_file_attributes(tvbuff_t * tvb,proto_tree * parent_tree,int offset)2502 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2503 {
2504 	static int * const flags[] = {
2505 		&hf_smb_file_attr_read_only_8bit,
2506 		&hf_smb_file_attr_hidden_8bit,
2507 		&hf_smb_file_attr_system_8bit,
2508 		&hf_smb_file_attr_volume_8bit,
2509 		&hf_smb_file_attr_directory_8bit,
2510 		&hf_smb_file_attr_archive_8bit,
2511 		NULL
2512 	};
2513 
2514 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_file_attr_8bit, ett_smb_file_attributes, flags, ENC_NA);
2515 	offset += 1;
2516 
2517 	return offset;
2518 }
2519 
2520 static const true_false_string tfs_search_attribute_read_only = {
2521 	"Include READ ONLY files in search results",
2522 	"Do NOT include read only files in search results",
2523 };
2524 static const true_false_string tfs_search_attribute_hidden = {
2525 	"Include HIDDEN files in search results",
2526 	"Do NOT include hidden files in search results"
2527 };
2528 static const true_false_string tfs_search_attribute_system = {
2529 	"Include SYSTEM files in search results",
2530 	"Do NOT include system files in search results"
2531 };
2532 static const true_false_string tfs_search_attribute_volume = {
2533 	"Include VOLUME IDs in search results",
2534 	"Do NOT include volume IDs in search results"
2535 };
2536 static const true_false_string tfs_search_attribute_directory = {
2537 	"Include DIRECTORIES in search results",
2538 	"Do NOT include directories in search results"
2539 };
2540 static const true_false_string tfs_search_attribute_archive = {
2541 	"Include ARCHIVE files in search results",
2542 	"Do NOT include archive files in search results"
2543 };
2544 
2545 /*
2546  * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
2547  * section 2.2.1.2.4 of [MS-CIFS], in cases where it's search attributes.
2548  */
2549 static int
dissect_search_attributes(tvbuff_t * tvb,proto_tree * parent_tree,int offset)2550 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2551 {
2552 	static int * const flags[] = {
2553 		&hf_smb_search_attribute_read_only,
2554 		&hf_smb_search_attribute_hidden,
2555 		&hf_smb_search_attribute_system,
2556 		&hf_smb_search_attribute_volume,
2557 		&hf_smb_search_attribute_directory,
2558 		&hf_smb_search_attribute_archive,
2559 		NULL
2560 	};
2561 
2562 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_search_attribute, ett_smb_search, flags, ENC_LITTLE_ENDIAN);
2563 	offset += 2;
2564 
2565 	return offset;
2566 }
2567 
2568 #if 0
2569 /*
2570  * XXX - this isn't used.
2571  * Is this used for anything?  NT Create AndX doesn't use it.
2572  * Is there some 16-bit attribute field with more bits than Read Only,
2573  * Hidden, System, Volume ID, Directory, and Archive?
2574  */
2575 static int
2576 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2577 {
2578 	static int * const flags[] = {
2579 		&hf_smb_file_attr_read_only_16bit,
2580 		&hf_smb_file_attr_hidden_16bit,
2581 		&hf_smb_file_attr_system_16bit,
2582 		&hf_smb_file_attr_volume_16bit,
2583 		&hf_smb_file_attr_directory_16bit,
2584 		&hf_smb_file_attr_archive_16bit,
2585 		&hf_smb_file_attr_device,
2586 		&hf_smb_file_attr_normal,
2587 		&hf_smb_file_attr_temporary,
2588 		&hf_smb_file_attr_sparse,
2589 		&hf_smb_file_attr_reparse,
2590 		&hf_smb_file_attr_compressed,
2591 		&hf_smb_file_attr_offline,
2592 		&hf_smb_file_attr_not_content_indexed,
2593 		&hf_smb_file_attr_encrypted,
2594 		NULL
2595 	};
2596 
2597 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_file_eattr, ett_smb_file_attributes, flags, ENC_LITTLE_ENDIAN);
2598 	offset += 2;
2599 
2600 	return offset;
2601 }
2602 #endif
2603 
2604 
2605 #define SERVER_CAP_RAW_MODE            0x00000001
2606 #define SERVER_CAP_MPX_MODE            0x00000002
2607 #define SERVER_CAP_UNICODE             0x00000004
2608 #define SERVER_CAP_LARGE_FILES         0x00000008
2609 #define SERVER_CAP_NT_SMBS             0x00000010
2610 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
2611 #define SERVER_CAP_STATUS32            0x00000040
2612 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
2613 #define SERVER_CAP_LOCK_AND_READ       0x00000100
2614 #define SERVER_CAP_NT_FIND             0x00000200
2615 #define SERVER_CAP_DFS                 0x00001000
2616 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
2617 #define SERVER_CAP_LARGE_READX         0x00004000
2618 #define SERVER_CAP_LARGE_WRITEX        0x00008000
2619 #define SERVER_CAP_LWIO                0x00010000
2620 #define SERVER_CAP_UNIX                0x00800000
2621 #define SERVER_CAP_COMPRESSED_DATA     0x02000000
2622 #define SERVER_CAP_DYNAMIC_REAUTH      0x20000000
2623 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
2624 
2625 static const true_false_string tfs_server_cap_raw_mode = {
2626 	"Read Raw and Write Raw are supported",
2627 	"Read Raw and Write Raw are not supported"
2628 };
2629 static const true_false_string tfs_server_cap_mpx_mode = {
2630 	"Read Mpx and Write Mpx are supported",
2631 	"Read Mpx and Write Mpx are not supported"
2632 };
2633 static const true_false_string tfs_server_cap_unicode = {
2634 	"Unicode strings are supported",
2635 	"Unicode strings are not supported"
2636 };
2637 static const true_false_string tfs_server_cap_large_files = {
2638 	"Large files are supported",
2639 	"Large files are not supported",
2640 };
2641 static const true_false_string tfs_server_cap_nt_smbs = {
2642 	"NT SMBs are supported",
2643 	"NT SMBs are not supported"
2644 };
2645 static const true_false_string tfs_server_cap_rpc_remote_apis = {
2646 	"RPC remote APIs are supported",
2647 	"RPC remote APIs are not supported"
2648 };
2649 static const true_false_string tfs_server_cap_nt_status = {
2650 	"NT status codes are supported",
2651 	"NT status codes are not supported"
2652 };
2653 static const true_false_string tfs_server_cap_level_ii_oplocks = {
2654 	"Level 2 oplocks are supported",
2655 	"Level 2 oplocks are not supported"
2656 };
2657 static const true_false_string tfs_server_cap_lock_and_read = {
2658 	"Lock and Read is supported",
2659 	"Lock and Read is not supported"
2660 };
2661 static const true_false_string tfs_server_cap_nt_find = {
2662 	"NT Find is supported",
2663 	"NT Find is not supported"
2664 };
2665 static const true_false_string tfs_server_cap_dfs = {
2666 	"Dfs is supported",
2667 	"Dfs is not supported"
2668 };
2669 static const true_false_string tfs_server_cap_infolevel_passthru = {
2670 	"NT information level request passthrough is supported",
2671 	"NT information level request passthrough is not supported"
2672 };
2673 static const true_false_string tfs_server_cap_large_readx = {
2674 	"Large Read andX is supported",
2675 	"Large Read andX is not supported"
2676 };
2677 static const true_false_string tfs_server_cap_large_writex = {
2678 	"Large Write andX is supported",
2679 	"Large Write andX is not supported"
2680 };
2681 static const true_false_string tfs_server_cap_lwio = {
2682 	"LWIO ioctl/fsctl is supported",
2683 	"LWIO ioctl/fsctl is not supported"
2684 };
2685 static const true_false_string tfs_server_cap_unix = {
2686 	"UNIX extensions are supported",
2687 	"UNIX extensions are not supported"
2688 };
2689 static const true_false_string tfs_server_cap_compressed_data = {
2690 	"Compressed data transfer is supported",
2691 	"Compressed data transfer is not supported"
2692 };
2693 static const true_false_string tfs_server_cap_dynamic_reauth = {
2694 	"Dynamic Reauth is supported",
2695 	"Dynamic Reauth is not supported"
2696 };
2697 static const true_false_string tfs_server_cap_extended_security = {
2698 	"Extended security exchanges are supported",
2699 	"Extended security exchanges are not supported"
2700 };
2701 static int
dissect_negprot_capabilities(tvbuff_t * tvb,proto_tree * parent_tree,int offset)2702 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2703 {
2704 	guint32     mask;
2705 
2706 	static int * const flags[] = {
2707 		&hf_smb_server_cap_raw_mode,
2708 		&hf_smb_server_cap_mpx_mode,
2709 		&hf_smb_server_cap_unicode,
2710 		&hf_smb_server_cap_large_files,
2711 		&hf_smb_server_cap_nt_smbs,
2712 		&hf_smb_server_cap_rpc_remote_apis,
2713 		&hf_smb_server_cap_nt_status,
2714 		&hf_smb_server_cap_level_ii_oplocks,
2715 		&hf_smb_server_cap_lock_and_read,
2716 		&hf_smb_server_cap_nt_find,
2717 		&hf_smb_server_cap_dfs,
2718 		&hf_smb_server_cap_infolevel_passthru,
2719 		&hf_smb_server_cap_large_readx,
2720 		&hf_smb_server_cap_large_writex,
2721 		&hf_smb_server_cap_lwio,
2722 		&hf_smb_server_cap_unix,
2723 		&hf_smb_server_cap_compressed_data,
2724 		&hf_smb_server_cap_dynamic_reauth,
2725 		&hf_smb_server_cap_extended_security,
2726 		NULL
2727 	};
2728 
2729 	mask = tvb_get_letohl(tvb, offset);
2730 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_server_cap, ett_smb_capabilities, flags, ENC_LITTLE_ENDIAN);
2731 
2732 	return mask;
2733 }
2734 
2735 #define RAWMODE_READ   0x01
2736 #define RAWMODE_WRITE  0x02
2737 static const true_false_string tfs_rm_read = {
2738 	"Read Raw is supported",
2739 	"Read Raw is not supported"
2740 };
2741 static const true_false_string tfs_rm_write = {
2742 	"Write Raw is supported",
2743 	"Write Raw is not supported"
2744 };
2745 
2746 static int
dissect_negprot_rawmode(tvbuff_t * tvb,proto_tree * parent_tree,int offset)2747 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2748 {
2749 	static int * const flags[] = {
2750 		&hf_smb_rm_read,
2751 		&hf_smb_rm_write,
2752 		NULL
2753 	};
2754 
2755 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_rm, ett_smb_rawmode, flags, ENC_LITTLE_ENDIAN);
2756 
2757 	offset += 2;
2758 
2759 	return offset;
2760 }
2761 
2762 #define SECURITY_MODE_MODE             0x01
2763 #define SECURITY_MODE_PASSWORD         0x02
2764 #define SECURITY_MODE_SIGNATURES       0x04
2765 #define SECURITY_MODE_SIG_REQUIRED     0x08
2766 static const true_false_string tfs_sm_mode = {
2767 	"USER security mode",
2768 	"SHARE security mode"
2769 };
2770 static const true_false_string tfs_sm_password = {
2771 	"ENCRYPTED password. Use challenge/response",
2772 	"PLAINTEXT password"
2773 };
2774 static const true_false_string tfs_sm_signatures = {
2775 	"Security signatures ENABLED",
2776 	"Security signatures NOT enabled"
2777 };
2778 static const true_false_string tfs_sm_sig_required = {
2779 	"Security signatures REQUIRED",
2780 	"Security signatures NOT required"
2781 };
2782 
2783 static int
dissect_negprot_security_mode(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int wc)2784 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2785 {
2786 	static int * const flags13[] = {
2787 		&hf_smb_sm_mode16,
2788 		&hf_smb_sm_password16,
2789 		NULL
2790 	};
2791 	static int * const flags17[] = {
2792 		&hf_smb_sm_mode,
2793 		&hf_smb_sm_password,
2794 		&hf_smb_sm_signatures,
2795 		&hf_smb_sm_sig_required,
2796 		NULL
2797 	};
2798 
2799 	switch(wc) {
2800 	case 13:
2801 		proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_sm16, ett_smb_mode, flags13, ENC_LITTLE_ENDIAN);
2802 		offset += 2;
2803 		break;
2804 
2805 	case 17:
2806 		proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_sm, ett_smb_mode, flags17, ENC_LITTLE_ENDIAN);
2807 		offset += 1;
2808 		break;
2809 	}
2810 
2811 	return offset;
2812 }
2813 
2814 #define MAX_DIALECTS 20
2815 struct negprot_dialects {
2816 	int   num;
2817 	char *name[MAX_DIALECTS+1];
2818 };
2819 
2820 static int
dissect_negprot_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)2821 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2822 {
2823 	proto_tree *tr = NULL;
2824 	proto_item *ti;
2825 	guint16     bc;
2826 	guint8      wc;
2827 	struct negprot_dialects *dialects = NULL;
2828 
2829 	DISSECTOR_ASSERT(si);
2830 
2831 	WORD_COUNT;
2832 
2833 	BYTE_COUNT;
2834 
2835 	tr = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb_dialects, &ti, "Requested Dialects");
2836 
2837 	if (!pinfo->fd->visited && si->sip) {
2838 		dialects = wmem_new(wmem_file_scope(), struct negprot_dialects);
2839 		dialects->num = 0;
2840 		si->sip->extra_info_type = SMB_EI_DIALECTS;
2841 		si->sip->extra_info = dialects;
2842 	}
2843 
2844 	while (bc) {
2845 		int len;
2846 		const guint8 *str;
2847 		proto_item *dit = NULL;
2848 		proto_tree *dtr = NULL;
2849 
2850 		/* XXX - what if this runs past bc? */
2851 		tvb_ensure_bytes_exist(tvb, offset+1, 1);
2852 		str = tvb_get_const_stringz(tvb, offset+1, &len);
2853 
2854 		if (tr) {
2855 			dit = proto_tree_add_string(tr, hf_smb_dialect, tvb, offset, len+1, str);
2856 			dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2857 		}
2858 
2859 		/* Buffer Format */
2860 		CHECK_BYTE_COUNT(1);
2861 		proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2862 			ENC_LITTLE_ENDIAN);
2863 		COUNT_BYTES(1);
2864 
2865 		/*Dialect Name */
2866 		CHECK_BYTE_COUNT(len);
2867 		proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2868 			len, str);
2869 		COUNT_BYTES(len);
2870 
2871 		if (!pinfo->fd->visited && dialects && (dialects->num < MAX_DIALECTS)) {
2872 			dialects->name[dialects->num++] = wmem_strdup(wmem_file_scope(), str);
2873 		}
2874 	}
2875 	proto_item_set_len(ti, bc);
2876 
2877 	END_OF_SMB
2878 
2879 	return offset;
2880 }
2881 
2882 static int
dissect_negprot_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)2883 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2884 {
2885 	guint8      wc;
2886 	guint16     dialect;
2887 	const char *dn;
2888 	int         dn_len;
2889 	guint16     bc;
2890 	guint16     chl          = 0;
2891 	guint32     caps         = 0;
2892 	gint16      tz;
2893 	const char *dialect_name = NULL;
2894 	struct negprot_dialects *dialects = NULL;
2895 
2896 	DISSECTOR_ASSERT(si);
2897 
2898 	WORD_COUNT;
2899 
2900 	/* Dialect Index */
2901 	dialect = tvb_get_letohs(tvb, offset);
2902 
2903 	if (si->sip && (si->sip->extra_info_type == SMB_EI_DIALECTS)) {
2904 		dialects = (struct negprot_dialects *)si->sip->extra_info;
2905 		if (dialect < dialects->num) {
2906 			dialect_name = dialects->name[dialect];
2907 		}
2908 	}
2909 	if (!dialect_name) {
2910 		dialect_name = "unknown";
2911 	}
2912 
2913 	switch(wc) {
2914 	case 1:
2915 		if (dialect == 0xffff) {
2916 			/*
2917 			 * Server doesn't support any of the dialects the
2918 			 * client listed.
2919 			 */
2920 			proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2921 				tvb, offset, 2, dialect,
2922 				"-1, server does not support any of the listed dialects");
2923 		} else {
2924 			/*
2925 			 * A dialect was selected; this should be
2926 			 * Core Protocol.
2927 			 */
2928 			proto_tree_add_uint(tree, hf_smb_dialect_index,
2929 				tvb, offset, 2, dialect);
2930 		}
2931 		break;
2932 	case 13:
2933 		/*
2934 		 * Server selected a dialect from LAN Manager 1.0 through
2935 		 * LAN Manager 2.1.
2936 		 */
2937 		proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2938 			tvb, offset, 2, dialect,
2939 			"%u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2940 		break;
2941 	case 17:
2942 		/*
2943 		 * Server selected NT LAN Manager.
2944 		 */
2945 		proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2946 			tvb, offset, 2, dialect,
2947 			"%u: %s", dialect, dialect_name);
2948 		break;
2949 	default:
2950 		proto_tree_add_item(tree, hf_smb_word_unk_response_format, tvb, offset, wc*2, ENC_NA);
2951 		offset += wc*2;
2952 		goto bytecount;
2953 	}
2954 	offset += 2;
2955 
2956 	switch(wc) {
2957 	case 13:
2958 		/*
2959 		 * Server selected a dialect from LAN Manager 1.0 through
2960 		 * LAN Manager 2.1.
2961 		 */
2962 
2963 		/* Security Mode */
2964 		offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2965 
2966 		/* Maximum Transmit Buffer Size */
2967 		proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2968 			tvb, offset, 2, ENC_LITTLE_ENDIAN);
2969 		offset += 2;
2970 
2971 		/* Maximum Multiplex Count */
2972 		proto_tree_add_item(tree, hf_smb_max_mpx_count,
2973 			tvb, offset, 2, ENC_LITTLE_ENDIAN);
2974 		offset += 2;
2975 
2976 		/* Maximum Vcs Number */
2977 		proto_tree_add_item(tree, hf_smb_max_vcs_num,
2978 			tvb, offset, 2, ENC_LITTLE_ENDIAN);
2979 		offset += 2;
2980 
2981 		/* raw mode */
2982 		offset = dissect_negprot_rawmode(tvb, tree, offset);
2983 
2984 		/* session key */
2985 		proto_tree_add_item(tree, hf_smb_session_key,
2986 			tvb, offset, 4, ENC_LITTLE_ENDIAN);
2987 		offset += 4;
2988 
2989 		/* current time and date at server */
2990 		offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2991 		    TRUE);
2992 
2993 		/* time zone */
2994 		tz = tvb_get_letohs(tvb, offset);
2995 		proto_tree_add_int_format_value(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "%d min from UTC", tz);
2996 		offset += 2;
2997 
2998 		/*
2999 		 * The LAN Manager 1 and 2.0 specs say these are the
3000 		 * first 2 of 4 reserved bytes; the LAN Manager 2.1
3001 		 * spec says it's a 2-byte encryption key (challenge)
3002 		 * length.
3003 		 */
3004 		chl = tvb_get_letohs(tvb, offset);
3005 		proto_tree_add_uint(tree, hf_smb_challenge_length, tvb, offset, 2, chl);
3006 		offset += 2;
3007 
3008 		/* 2 reserved bytes */
3009 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
3010 		offset += 2;
3011 
3012 		break;
3013 
3014 	case 17:
3015 		/*
3016 		 * Server selected NT LAN Manager.
3017 		 */
3018 
3019 		/* Security Mode */
3020 		offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
3021 
3022 		/* Maximum Multiplex Count */
3023 		proto_tree_add_item(tree, hf_smb_max_mpx_count,
3024 			tvb, offset, 2, ENC_LITTLE_ENDIAN);
3025 		offset += 2;
3026 
3027 		/* Maximum Vcs Number */
3028 		proto_tree_add_item(tree, hf_smb_max_vcs_num,
3029 			tvb, offset, 2, ENC_LITTLE_ENDIAN);
3030 		offset += 2;
3031 
3032 		/* Maximum Transmit Buffer Size */
3033 		proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
3034 			tvb, offset, 4, ENC_LITTLE_ENDIAN);
3035 		offset += 4;
3036 
3037 		/* maximum raw buffer size */
3038 		proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
3039 			tvb, offset, 4, ENC_LITTLE_ENDIAN);
3040 		offset += 4;
3041 
3042 		/* session key */
3043 		proto_tree_add_item(tree, hf_smb_session_key,
3044 			tvb, offset, 4, ENC_LITTLE_ENDIAN);
3045 		offset += 4;
3046 
3047 		/* server capabilities */
3048 		caps = dissect_negprot_capabilities(tvb, tree, offset);
3049 		offset += 4;
3050 
3051 		/* system time */
3052 		offset = dissect_nt_64bit_time(tvb, tree, offset,
3053 				hf_smb_system_time);
3054 
3055 		/* time zone */
3056 		tz = tvb_get_letohs(tvb, offset);
3057 		proto_tree_add_int_format_value(tree, hf_smb_server_timezone,
3058 			tvb, offset, 2, tz,
3059 			"%d min from UTC", tz);
3060 		offset += 2;
3061 
3062 		/* challenge length */
3063 		chl = tvb_get_guint8(tvb, offset);
3064 		proto_tree_add_uint(tree, hf_smb_challenge_length,
3065 			tvb, offset, 1, chl);
3066 		offset += 1;
3067 
3068 		break;
3069 	}
3070 
3071 	BYTE_COUNT;
3072 
3073 	switch(wc) {
3074 	case 13:
3075 		/*
3076 		 * Server selected a dialect from LAN Manager 1.0 through
3077 		 * LAN Manager 2.1.
3078 		 */
3079 
3080 		/* encrypted challenge/response data */
3081 		if (chl) {
3082 			CHECK_BYTE_COUNT(chl);
3083 			proto_tree_add_item(tree, hf_smb_challenge, tvb, offset, chl, ENC_NA);
3084 			COUNT_BYTES(chl);
3085 		}
3086 
3087 		/*
3088 		 * Primary domain.
3089 		 *
3090 		 * XXX - not present if negotiated dialect isn't
3091 		 * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
3092 		 * have to see the request, or assume what dialect strings
3093 		 * were sent, to determine that.
3094 		 *
3095 		 * Is this something other than a primary domain if the
3096 		 * negotiated dialect is Windows for Workgroups 3.1a?
3097 		 * It appears to be 8 bytes of binary data in at least
3098 		 * one capture - is that an encryption key or something
3099 		 * such as that?
3100 		 */
3101 		dn = get_unicode_or_ascii_string(tvb, &offset,
3102 			si->unicode, &dn_len, FALSE, FALSE, &bc);
3103 		if (dn == NULL)
3104 			goto endofcommand;
3105 		proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
3106 			offset, dn_len, dn);
3107 		COUNT_BYTES(dn_len);
3108 		break;
3109 
3110 	case 17:
3111 		/*
3112 		 * Server selected NT LAN Manager.
3113 		 */
3114 		if (!(caps & SERVER_CAP_EXTENDED_SECURITY)) {
3115 			/* encrypted challenge/response data */
3116 			/* XXX - is this aligned on an even boundary? */
3117 			if (chl) {
3118 				CHECK_BYTE_COUNT(chl);
3119 				proto_tree_add_item(tree, hf_smb_challenge,
3120 					tvb, offset, chl, ENC_NA);
3121 				COUNT_BYTES(chl);
3122 			}
3123 
3124 			/* domain */
3125 			/*
3126 			 * This string is special; at least in some captures,
3127 			 * it's in Unicode, even if "Unicode strings" isn't
3128 			 * set in the flags2 field.  If the "Unicode support"
3129 			 * flag is set in the server capabilities field,
3130 			 * that seems to indicate that it's in Unicode for
3131 			 * those captures.
3132 			 *
3133 			 * So fetch it in Unicode either if it's set in the
3134 			 * flags2 field *or* in the capabilities field.
3135 			 *
3136 			 * XXX - I've seen captures where "Unicode strings"
3137 			 * isn't set, "Unicode support" is set in the server
3138 			 * capabilities field, and the primary domain string
3139 			 * is in the local code page; that may just have
3140 			 * a buggy server, though.
3141 			 *
3142 			 * Clients tend, at least according to the
3143 			 * footnote in MS-CIFS for the DomainName field
3144 			 * in the Negotiate response, to ignore that
3145 			 * field, so maybe servers put extra bytes in
3146 			 * there without clients noticing.
3147 			 */
3148 			si->unicode = (caps & SERVER_CAP_UNICODE) || si->unicode;
3149 
3150 			/*
3151 			 * If we're fetching Unicode strings:
3152 			 *
3153 			 *   This string is NOT padded to be 16-bit
3154 			 *   aligned; it's unaligned in some captures.
3155 			 *
3156 			 *   However, it sometimes has an extra byte
3157 			 *   before it.  If the byte count is not a
3158 			 *   multiple of 2, there must be an extra byte
3159 			 *   somewhere; it appears to be the byte just
3160 			 *   before this string, so check for an odd
3161 			 *   byte count, and skip that byte.
3162 			 *
3163 			 * If we're fetching local code page strings:
3164 			 *
3165 			 *   In some cases there appears to be an extra
3166 			 *   byte before it.  It's not clear what
3167 			 *   indicates its presence, if anything.
3168 			 *
3169 			 *   However, at least one of those cases
3170 			 *   was one of the "the server set the
3171 			 *   Unicode support flag in capabilities,
3172 			 *   but sent the domain name in the local
3173 			 *   code page" captures mentioned above,
3174 			 *   so maybe it was just a buggy server.
3175 			 *
3176 			 * Again, as noted above, clients may just
3177 			 * ignore that field, leaving servers "free"
3178 			 * to mess it up.
3179 			 */
3180 			if (si->unicode && (bc % 2) != 0) {
3181 				/* Skip the padding */
3182 				CHECK_BYTE_COUNT(1);
3183 				COUNT_BYTES(1);
3184 			}
3185 			dn = get_unicode_or_ascii_string(tvb,
3186 				&offset, si->unicode, &dn_len, TRUE, FALSE,
3187 				&bc);
3188 			if (dn == NULL)
3189 				goto endofcommand;
3190 			proto_tree_add_string(tree, hf_smb_primary_domain,
3191 				tvb, offset, dn_len, dn);
3192 			COUNT_BYTES(dn_len);
3193 
3194 			/* server name, seen in w2k pro capture */
3195 			dn = get_unicode_or_ascii_string(tvb,
3196 				&offset, si->unicode, &dn_len, TRUE, FALSE,
3197 				&bc);
3198 			if (dn == NULL)
3199 				goto endofcommand;
3200 			proto_tree_add_string(tree, hf_smb_server,
3201 				tvb, offset, dn_len, dn);
3202 			COUNT_BYTES(dn_len);
3203 
3204 		} else {
3205 			proto_item *blob_item;
3206 			guint16 sbloblen;
3207 
3208 			/* guid */
3209 			/* XXX - show it in the standard Microsoft format
3210 			   for GUIDs? */
3211 			CHECK_BYTE_COUNT(16);
3212 			proto_tree_add_item(tree, hf_smb_server_guid,
3213 				tvb, offset, 16, ENC_NA);
3214 			COUNT_BYTES(16);
3215 
3216 			/* security blob */
3217 			/* If it runs past the end of the captured data, don't
3218 			 * try to put all of it into the protocol tree as the
3219 			 * raw security blob; we might get an exception on
3220 			 * short frames and then we will not see anything at all
3221 			 * of the security blob.
3222 			 */
3223 			sbloblen = bc;
3224 			if (sbloblen > tvb_reported_length_remaining(tvb, offset)) {
3225 				sbloblen = tvb_reported_length_remaining(tvb, offset);
3226 			}
3227 			blob_item = proto_tree_add_item(
3228 				tree, hf_smb_security_blob,
3229 				tvb, offset, sbloblen, ENC_NA);
3230 
3231 			/*
3232 			 * If Extended security and BCC == 16, then raw
3233 			 * NTLMSSP is in use. We need to save this info
3234 			 */
3235 
3236 			if (bc) {
3237 				tvbuff_t *gssapi_tvb;
3238 				proto_tree *gssapi_tree;
3239 
3240 				gssapi_tree = proto_item_add_subtree(
3241 					blob_item, ett_smb_secblob);
3242 
3243 				/*
3244 				 * Set the reported length of this to
3245 				 * the reported length of the blob,
3246 				 * rather than the amount of data
3247 				 * available from the blob, so that
3248 				 * we'll throw the right exception if
3249 				 * it's too short.
3250 				 */
3251 				gssapi_tvb = tvb_new_subset_length_caplen(
3252 					tvb, offset, sbloblen, bc);
3253 
3254 				call_dissector(
3255 					gssapi_handle, gssapi_tvb, pinfo,
3256 					gssapi_tree);
3257 
3258 				if (si->ct)
3259 				  si->ct->raw_ntlmssp = 0;
3260 
3261 				COUNT_BYTES(bc);
3262 			}
3263 			else {
3264 
3265 			  /*
3266 			   * There is no blob. We just have to make sure
3267 			   * that subsequent routines know to call the
3268 			   * right things ...
3269 			   */
3270 
3271 			if (si->ct)
3272 				si->ct->raw_ntlmssp = 1;
3273 
3274 			}
3275 		}
3276 		break;
3277 	}
3278 
3279 	END_OF_SMB
3280 
3281 	return offset;
3282 }
3283 
3284 
3285 static int
dissect_old_dir_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3286 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3287 {
3288 	int         dn_len;
3289 	const char *dn;
3290 	guint8      wc;
3291 	guint16     bc;
3292 
3293 	DISSECTOR_ASSERT(si);
3294 
3295 	WORD_COUNT;
3296 
3297 	BYTE_COUNT;
3298 
3299 	/* buffer format */
3300 	CHECK_BYTE_COUNT(1);
3301 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3302 	COUNT_BYTES(1);
3303 
3304 	/* dir name */
3305 	dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
3306 		FALSE, FALSE, &bc);
3307 
3308 	if ((!pinfo->fd->visited) && si->sip) {
3309 		si->sip->extra_info_type = SMB_EI_FILENAME;
3310 		si->sip->extra_info = wmem_strdup(wmem_file_scope(), dn);
3311 	}
3312 
3313 	if (dn == NULL)
3314 		goto endofcommand;
3315 	proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
3316 		dn);
3317 	COUNT_BYTES(dn_len);
3318 
3319 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
3320 		    format_text(wmem_packet_scope(), (const guchar *)dn, strlen(dn)));
3321 
3322 	END_OF_SMB
3323 
3324 	return offset;
3325 }
3326 
3327 static int
dissect_empty(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3328 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3329 {
3330 	guint8      wc;
3331 	guint16     bc;
3332 	proto_item *item = NULL;
3333 
3334 	DISSECTOR_ASSERT(si);
3335 
3336 	if (si->sip && (si->sip->extra_info_type == SMB_EI_FILENAME)) {
3337 		item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, (const char *)si->sip->extra_info);
3338 		proto_item_set_generated(item);
3339 	}
3340 
3341 
3342 	WORD_COUNT;
3343 
3344 	BYTE_COUNT;
3345 
3346 	END_OF_SMB
3347 
3348 	return offset;
3349 }
3350 
3351 static int
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)3352 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)
3353 {
3354 	guint8      wc;
3355 	guint16     bc;
3356 	proto_item *item = NULL;
3357 
3358 	DISSECTOR_ASSERT(si);
3359 
3360 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RENAMEDATA)) {
3361 		smb_rename_saved_info_t *rni = (smb_rename_saved_info_t *)si->sip->extra_info;
3362 
3363 		item = proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
3364 		proto_item_set_generated(item);
3365 		item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
3366 		proto_item_set_generated(item);
3367 	}
3368 
3369 
3370 	WORD_COUNT;
3371 
3372 	BYTE_COUNT;
3373 
3374 	END_OF_SMB
3375 
3376 	return offset;
3377 }
3378 
3379 static int
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_)3380 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_)
3381 {
3382 	guint16 ec, bc;
3383 	guint8  wc;
3384 
3385 	WORD_COUNT;
3386 
3387 	/* echo count */
3388 	ec = tvb_get_letohs(tvb, offset);
3389 	proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
3390 	offset += 2;
3391 
3392 	BYTE_COUNT;
3393 
3394 	if (bc != 0) {
3395 		/* echo data */
3396 		proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, ENC_NA);
3397 		COUNT_BYTES(bc);
3398 	}
3399 
3400 	END_OF_SMB
3401 
3402 	return offset;
3403 }
3404 
3405 static int
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_)3406 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_)
3407 {
3408 	guint16 bc;
3409 	guint8  wc;
3410 
3411 	WORD_COUNT;
3412 
3413 	/* echo sequence number */
3414 	proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3415 	offset += 2;
3416 
3417 	BYTE_COUNT;
3418 
3419 	if (bc != 0) {
3420 		/* echo data */
3421 		proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, ENC_NA);
3422 		COUNT_BYTES(bc);
3423 	}
3424 
3425 	END_OF_SMB
3426 
3427 	return offset;
3428 }
3429 
3430 static int
dissect_tree_connect_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3431 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3432 {
3433 	int         an_len, pwlen;
3434 	const char *an;
3435 	guint8      wc;
3436 	guint16     bc;
3437 
3438 	DISSECTOR_ASSERT(si);
3439 
3440 	WORD_COUNT;
3441 
3442 	BYTE_COUNT;
3443 
3444 	/* buffer format */
3445 	CHECK_BYTE_COUNT(1);
3446 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3447 	COUNT_BYTES(1);
3448 
3449 	/* Path */
3450 	an = get_unicode_or_ascii_string(tvb, &offset,
3451 		si->unicode, &an_len, FALSE, FALSE, &bc);
3452 	if (an == NULL)
3453 		goto endofcommand;
3454 	proto_tree_add_string(tree, hf_smb_path, tvb,
3455 		offset, an_len, an);
3456 	COUNT_BYTES(an_len);
3457 
3458 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3459 		    format_text(wmem_packet_scope(), (const guchar*)an, strlen(an)));
3460 
3461 	/* buffer format */
3462 	CHECK_BYTE_COUNT(1);
3463 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3464 	COUNT_BYTES(1);
3465 
3466 	/* password, ANSI */
3467 	/* XXX - what if this runs past bc? */
3468 	pwlen = tvb_strsize(tvb, offset);
3469 	CHECK_BYTE_COUNT(pwlen);
3470 	proto_tree_add_item(tree, hf_smb_password,
3471 		tvb, offset, pwlen, ENC_NA);
3472 	COUNT_BYTES(pwlen);
3473 
3474 	/* buffer format */
3475 	CHECK_BYTE_COUNT(1);
3476 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3477 	COUNT_BYTES(1);
3478 
3479 	/* Service */
3480 	/*
3481 	 * XXX - the SNIA CIFS spec "Strings that are never passed in
3482 	 * Unicode are: ... The service name string in the
3483 	 * Tree_Connect_AndX SMB".  Is that claim false?
3484 	 */
3485 	an = get_unicode_or_ascii_string(tvb, &offset,
3486 		si->unicode, &an_len, FALSE, FALSE, &bc);
3487 	if (an == NULL)
3488 		goto endofcommand;
3489 	proto_tree_add_string(tree, hf_smb_service, tvb,
3490 		offset, an_len, an);
3491 	COUNT_BYTES(an_len);
3492 
3493 	END_OF_SMB
3494 
3495 	return offset;
3496 }
3497 
3498 static int
dissect_smb_uid(tvbuff_t * tvb,proto_tree * parent_tree,int offset,smb_info_t * si)3499 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
3500 {
3501 	proto_item *item, *subitem;
3502 	proto_tree *tree;
3503 	smb_uid_t  *smb_uid = NULL;
3504 
3505 	item = proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
3506 	tree = proto_item_add_subtree(item, ett_smb_uid);
3507 
3508 	smb_uid = (smb_uid_t *)wmem_tree_lookup32(si->ct->uid_tree, si->uid);
3509 	if (smb_uid) {
3510 		if (smb_uid->domain && smb_uid->account)
3511 			proto_item_append_text(item, "  (");
3512 		if (smb_uid->domain) {
3513 			proto_item_append_text(item, "%s", smb_uid->domain);
3514 			subitem = proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
3515 			proto_item_set_generated(subitem);
3516 		}
3517 		if (smb_uid->account) {
3518 			proto_item_append_text(item, "\\%s", smb_uid->account);
3519 			subitem = proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
3520 			proto_item_set_generated(subitem);
3521 		}
3522 		if (smb_uid->domain && smb_uid->account)
3523 			proto_item_append_text(item, ")");
3524 		if (smb_uid->logged_in > 0) {
3525 			subitem = proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
3526 			proto_item_set_generated(subitem);
3527 		}
3528 		if (smb_uid->logged_out > 0) {
3529 			subitem = proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
3530 			proto_item_set_generated(subitem);
3531 		}
3532 	}
3533 	offset += 2;
3534 
3535 	return offset;
3536 }
3537 
3538 static int
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)3539 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)
3540 {
3541 	proto_item     *it;
3542 	proto_tree     *tr;
3543 	smb_tid_info_t *tid_info = NULL;
3544 
3545 	DISSECTOR_ASSERT(si);
3546 
3547 	/* tid */
3548 	it = proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
3549 	tr = proto_item_add_subtree(it, ett_smb_tid);
3550 	offset += 2;
3551 
3552 	if ((!pinfo->fd->visited) && is_created) {
3553 		tid_info = wmem_new(wmem_file_scope(), smb_tid_info_t);
3554 		tid_info->opened_in = pinfo->num;
3555 		tid_info->closed_in = 0;
3556 		tid_info->type = SMB_FID_TYPE_UNKNOWN;
3557 		if (si->sip && (si->sip->extra_info_type == SMB_EI_TIDNAME)) {
3558 			tid_info->filename = (char *)si->sip->extra_info;
3559 		} else {
3560 			tid_info->filename = NULL;
3561 		}
3562 		wmem_tree_insert32(si->ct->tid_tree, tid, tid_info);
3563 	}
3564 
3565 	if (!tid_info) {
3566 		tid_info = (smb_tid_info_t *)wmem_tree_lookup32_le(si->ct->tid_tree, tid);
3567 	}
3568 	if (!tid_info) {
3569 		return offset;
3570 	}
3571 
3572 	if ((!pinfo->fd->visited) && is_closed) {
3573 		tid_info->closed_in = pinfo->num;
3574 	}
3575 
3576 	if (tid_info->opened_in) {
3577 		if (tid_info->filename) {
3578 			proto_item_append_text(it, "  (%s)", tid_info->filename);
3579 
3580 			it = proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
3581 			proto_item_set_generated(it);
3582 		}
3583 
3584 		it = proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
3585 		proto_item_set_generated(it);
3586 	}
3587 	if (tid_info->closed_in) {
3588 		it = proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
3589 		proto_item_set_generated(it);
3590 	}
3591 
3592 
3593 	return offset;
3594 }
3595 
3596 static int
dissect_tree_connect_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3597 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3598 {
3599 	guint8  wc;
3600 	guint16 bc;
3601 
3602 	WORD_COUNT;
3603 
3604 	/* Maximum Buffer Size */
3605 	proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3606 	offset += 2;
3607 
3608 	/* tid */
3609 	offset = dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE, si);
3610 
3611 	BYTE_COUNT;
3612 
3613 	END_OF_SMB
3614 
3615 	return offset;
3616 }
3617 
3618 
3619 static const true_false_string tfs_of_create = {
3620 	"Create file if it does not exist",
3621 	"Fail if file does not exist"
3622 };
3623 static const value_string of_open[] = {
3624 	{ 0,		"Fail if file exists"},
3625 	{ 1,		"Open file if it exists"},
3626 	{ 2,		"Truncate file if it exists"},
3627 	{0, NULL}
3628 };
3629 static int
dissect_open_function(tvbuff_t * tvb,proto_tree * parent_tree,int offset)3630 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3631 {
3632 	static int * const flags[] = {
3633 		&hf_smb_open_function_create,
3634 		&hf_smb_open_function_open,
3635 		NULL
3636 	};
3637 
3638 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_open_function, ett_smb_openfunction, flags, ENC_LITTLE_ENDIAN);
3639 	offset += 2;
3640 
3641 	return offset;
3642 }
3643 
3644 
3645 static const true_false_string tfs_mf_file = {
3646 	"Target must be a file",
3647 	"Target needn't be a file"
3648 };
3649 static const true_false_string tfs_mf_dir = {
3650 	"Target must be a directory",
3651 	"Target needn't be a directory"
3652 };
3653 static const true_false_string tfs_mf_verify = {
3654 	"MUST verify all writes",
3655 	"Don't have to verify writes"
3656 };
3657 static int
dissect_move_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)3658 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3659 {
3660 	static int * const flags[] = {
3661 		&hf_smb_move_flags_verify,
3662 		&hf_smb_move_flags_dir,
3663 		&hf_smb_move_flags_file,
3664 		NULL
3665 	};
3666 
3667 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_move_flags, ett_smb_move_copy_flags, flags, ENC_LITTLE_ENDIAN);
3668 	offset += 2;
3669 
3670 	return offset;
3671 }
3672 
3673 static const true_false_string tfs_cf_mode = {
3674 	"ASCII",
3675 	"Binary"
3676 };
3677 static const true_false_string tfs_cf_tree_copy = {
3678 	"Copy is a tree copy",
3679 	"Copy is a file copy"
3680 };
3681 static const true_false_string tfs_cf_ea_action = {
3682 	"Fail copy",
3683 	"Discard EAs"
3684 };
3685 static int
dissect_copy_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)3686 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3687 {
3688 	static int * const flags[] = {
3689 		&hf_smb_copy_flags_ea_action,
3690 		&hf_smb_copy_flags_tree_copy,
3691 		&hf_smb_copy_flags_verify,
3692 		&hf_smb_copy_flags_source_mode,
3693 		&hf_smb_copy_flags_dest_mode,
3694 		&hf_smb_copy_flags_dir,
3695 		&hf_smb_copy_flags_file,
3696 		NULL
3697 	};
3698 
3699 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_copy_flags, ett_smb_move_copy_flags, flags, ENC_LITTLE_ENDIAN);
3700 	offset += 2;
3701 
3702 	return offset;
3703 }
3704 
3705 static int
dissect_move_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3706 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3707 {
3708 	int         fn_len;
3709 	guint16     tid;
3710 	guint16     bc;
3711 	guint8      wc;
3712 	const char *fn;
3713 
3714 	DISSECTOR_ASSERT(si);
3715 
3716 	WORD_COUNT;
3717 
3718 	/* tid */
3719 	tid = tvb_get_letohs(tvb, offset);
3720 	offset = dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE, si);
3721 
3722 	/* open function */
3723 	offset = dissect_open_function(tvb, tree, offset);
3724 
3725 	/* move flags */
3726 	offset = dissect_move_flags(tvb, tree, offset);
3727 
3728 	BYTE_COUNT;
3729 
3730 	/* buffer format */
3731 	CHECK_BYTE_COUNT(1);
3732 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3733 	COUNT_BYTES(1);
3734 
3735 	/* file name */
3736 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3737 		FALSE, FALSE, &bc);
3738 	if (fn == NULL)
3739 		goto endofcommand;
3740 	proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3741 		fn_len,	fn, "Old File Name: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3742 	COUNT_BYTES(fn_len);
3743 
3744 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3745 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3746 
3747 	/* buffer format */
3748 	CHECK_BYTE_COUNT(1);
3749 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3750 	COUNT_BYTES(1);
3751 
3752 	/* file name */
3753 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3754 		FALSE, FALSE, &bc);
3755 	if (fn == NULL)
3756 		goto endofcommand;
3757 	proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3758 		fn_len,	fn, "New File Name: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3759 	COUNT_BYTES(fn_len);
3760 
3761 	col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3762 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3763 
3764 	END_OF_SMB
3765 
3766 	return offset;
3767 }
3768 
3769 static int
dissect_copy_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3770 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3771 {
3772 	int         fn_len;
3773 	guint16     tid;
3774 	guint16     bc;
3775 	guint8      wc;
3776 	const char *fn;
3777 
3778 	DISSECTOR_ASSERT(si);
3779 
3780 	WORD_COUNT;
3781 
3782 	/* tid */
3783 	tid = tvb_get_letohs(tvb, offset);
3784 	offset = dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE, si);
3785 
3786 	/* open function */
3787 	offset = dissect_open_function(tvb, tree, offset);
3788 
3789 	/* copy flags */
3790 	offset = dissect_copy_flags(tvb, tree, offset);
3791 
3792 	BYTE_COUNT;
3793 
3794 	/* buffer format */
3795 	CHECK_BYTE_COUNT(1);
3796 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3797 	COUNT_BYTES(1);
3798 
3799 	/* file name */
3800 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3801 		FALSE, FALSE, &bc);
3802 	if (fn == NULL)
3803 		goto endofcommand;
3804 	proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3805 		fn_len, fn, "Source File Name: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3806 	COUNT_BYTES(fn_len);
3807 
3808 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3809 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3810 
3811 	/* buffer format */
3812 	CHECK_BYTE_COUNT(1);
3813 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3814 	COUNT_BYTES(1);
3815 
3816 	/* file name */
3817 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3818 		FALSE, FALSE, &bc);
3819 	if (fn == NULL)
3820 		goto endofcommand;
3821 	proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3822 		fn_len, fn, "Destination File Name: %s",
3823 		format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3824 	COUNT_BYTES(fn_len);
3825 
3826 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3827 
3828 	END_OF_SMB
3829 
3830 	return offset;
3831 }
3832 
3833 static int
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)3834 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)
3835 {
3836 	int         fn_len;
3837 	const char *fn;
3838 	guint8      wc;
3839 	guint16     bc;
3840 
3841 	DISSECTOR_ASSERT(si);
3842 
3843 	WORD_COUNT;
3844 
3845 	/* # of files moved */
3846 	proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3847 	offset += 2;
3848 
3849 	BYTE_COUNT;
3850 
3851 	/* buffer format */
3852 	CHECK_BYTE_COUNT(1);
3853 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3854 	COUNT_BYTES(1);
3855 
3856 	/* file name */
3857 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3858 		FALSE, FALSE, &bc);
3859 	if (fn == NULL)
3860 		goto endofcommand;
3861 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3862 		fn);
3863 	COUNT_BYTES(fn_len);
3864 
3865 	END_OF_SMB
3866 
3867 	return offset;
3868 }
3869 
3870 static int
dissect_open_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)3871 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3872 {
3873 	int         fn_len;
3874 	const char *fn;
3875 	guint8      wc;
3876 	guint16     bc;
3877 	smb_fid_saved_info_t *fsi; /* eo_smb needs to track this info */
3878 
3879 	DISSECTOR_ASSERT(si);
3880 
3881 	WORD_COUNT;
3882 
3883 	/* desired access */
3884 	offset = dissect_access(tvb, tree, offset, hf_smb_desired_access);
3885 
3886 	/* Search Attributes */
3887 	offset = dissect_search_attributes(tvb, tree, offset);
3888 
3889 	BYTE_COUNT;
3890 
3891 	/* buffer format */
3892 	CHECK_BYTE_COUNT(1);
3893 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3894 	COUNT_BYTES(1);
3895 
3896 	/* file name */
3897 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3898 		FALSE, FALSE, &bc);
3899 	if (fn == NULL)
3900 		goto endofcommand;
3901 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3902 		fn);
3903 	COUNT_BYTES(fn_len);
3904 
3905 	/* store it for the fid->name/openframe/closeframe matching in
3906 	* dissect_smb_fid()   called from the response.
3907 	*/
3908 	if ((!pinfo->fd->visited) && si->sip && fn) {
3909 		fsi			= wmem_new0(wmem_file_scope(), smb_fid_saved_info_t);
3910 		fsi->filename		= wmem_strdup(wmem_file_scope(), fn);
3911 
3912 		si->sip->extra_info_type = SMB_EI_FILEDATA;
3913 		si->sip->extra_info      = fsi;
3914 	}
3915 
3916 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3917 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
3918 
3919 	END_OF_SMB
3920 
3921 	return offset;
3922 }
3923 
3924 
3925 
3926 static int
dissect_nt_create_bits(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int len,guint32 mask)3927 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3928     int len, guint32 mask)
3929 {
3930 	proto_item *item = NULL;
3931 	/*
3932 	 * XXX - it's 0x00000016 in at least one capture, but
3933 	 * Network Monitor doesn't say what the 0x00000010 bit is.
3934 	 * Does the Win32 API documentation, or NT Native API book,
3935 	 * suggest anything?
3936 	 *
3937 	 * That is the extended response desired bit ... RJS, from Samba
3938 	 * Well, maybe. Samba thinks it is, and uses it to encode
3939 	 * OpLock granted as the high order bit of the Action field
3940 	 * in the response. However, Windows does not do that. Or at least
3941 	 * Win2K doesn't.
3942 	 */
3943 	static int * const fields[] = {
3944 		&hf_smb_nt_create_bits_oplock,
3945 		&hf_smb_nt_create_bits_boplock,
3946 		&hf_smb_nt_create_bits_dir,
3947 		&hf_smb_nt_create_bits_ext_resp,
3948 		NULL
3949 	};
3950 
3951 	item = proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset, hf_smb_create_flags, ett_smb_nt_create_bits,
3952 							fields, mask, BMT_NO_APPEND);
3953 
3954 	if (len == 0)
3955 		proto_item_set_generated(item);
3956 
3957 	offset += len;
3958 
3959 	return offset;
3960 }
3961 
3962 /* FIXME: need to call dissect_nt_access_mask() instead */
3963 static int
dissect_smb_access_mask_bits(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int len,guint32 mask)3964 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3965     int offset, int len, guint32 mask)
3966 {
3967 	proto_item *item;
3968 	/*
3969 	 * Some of these bits come from
3970 	 *
3971 	 *	http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3972 	 *
3973 	 * and others come from the section on ZwOpenFile in "Windows(R)
3974 	 * NT(R)/2000 Native API Reference".
3975 	 */
3976 	static int * const fields[] = {
3977 		&hf_smb_nt_access_mask_read,
3978 		&hf_smb_nt_access_mask_write,
3979 		&hf_smb_nt_access_mask_append,
3980 		&hf_smb_nt_access_mask_read_ea,
3981 		&hf_smb_nt_access_mask_write_ea,
3982 		&hf_smb_nt_access_mask_execute,
3983 		&hf_smb_nt_access_mask_delete_child,
3984 		&hf_smb_nt_access_mask_read_attributes,
3985 		&hf_smb_nt_access_mask_write_attributes,
3986 		&hf_smb_nt_access_mask_delete,
3987 		&hf_smb_nt_access_mask_read_control,
3988 		&hf_smb_nt_access_mask_write_dac,
3989 		&hf_smb_nt_access_mask_write_owner,
3990 		&hf_smb_nt_access_mask_synchronize,
3991 		&hf_smb_nt_access_mask_system_security,
3992 		&hf_smb_nt_access_mask_maximum_allowed,
3993 		&hf_smb_nt_access_mask_generic_all,
3994 		&hf_smb_nt_access_mask_generic_execute,
3995 		&hf_smb_nt_access_mask_generic_write,
3996 		&hf_smb_nt_access_mask_generic_read,
3997 		NULL
3998 	};
3999 
4000 	item = proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset, hf_smb_access_mask, ett_smb_nt_access_mask,
4001 							fields, mask, BMT_NO_APPEND);
4002 
4003 	if (len == 0)
4004 		proto_item_set_generated(item);
4005 	offset += len;
4006 
4007 	return offset;
4008 }
4009 
4010 int
dissect_smb_access_mask(tvbuff_t * tvb,proto_tree * parent_tree,int offset)4011 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4012 {
4013 	guint32 mask;
4014 
4015 	mask = tvb_get_letohl(tvb, offset);
4016 
4017 	offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
4018 
4019 	return offset;
4020 }
4021 
4022 #define SHARE_ACCESS_READ	0x00000001
4023 #define SHARE_ACCESS_WRITE	0x00000002
4024 #define SHARE_ACCESS_DELETE	0x00000004
4025 
4026 static int
dissect_nt_share_access_bits(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int len,guint32 mask)4027 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
4028     int offset, int len, guint32 mask)
4029 {
4030 	proto_item *item;
4031 	static int * const fields[] = {
4032 		&hf_smb_nt_share_access_read,
4033 		&hf_smb_nt_share_access_write,
4034 		&hf_smb_nt_share_access_delete,
4035 		NULL
4036 	};
4037 
4038 	item = proto_tree_add_bitmask_value(parent_tree, tvb, offset, hf_smb_share_access, ett_smb_nt_share_access, fields, mask);
4039 
4040 	if (len == 0)
4041 		proto_item_set_generated(item);
4042 
4043 	offset += len;
4044 
4045 	return offset;
4046 }
4047 
4048 int
dissect_nt_share_access(tvbuff_t * tvb,proto_tree * parent_tree,int offset)4049 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4050 {
4051 	guint32 mask;
4052 
4053 	mask = tvb_get_letohl(tvb, offset);
4054 
4055 	offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
4056 
4057 	return offset;
4058 }
4059 
4060 
4061 static int
dissect_nt_create_options_bits(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int len,guint32 mask)4062 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
4063     int offset, int len, guint32 mask)
4064 {
4065 	proto_item *item;
4066 	/*
4067 	 * From
4068 	 *
4069 	 *	http://www.samba.org/samba/ftp/specs/smb-nt01.doc
4070 	 */
4071 	static int * const fields[] = {
4072 		&hf_smb_nt_create_options_directory_file,
4073 		&hf_smb_nt_create_options_write_through,
4074 		&hf_smb_nt_create_options_sequential_only,
4075 		&hf_smb_nt_create_options_no_intermediate_buffering,
4076 		&hf_smb_nt_create_options_sync_io_alert,
4077 		&hf_smb_nt_create_options_sync_io_nonalert,
4078 		&hf_smb_nt_create_options_non_directory_file,
4079 		&hf_smb_nt_create_options_create_tree_connection,
4080 		&hf_smb_nt_create_options_complete_if_oplocked,
4081 		&hf_smb_nt_create_options_no_ea_knowledge,
4082 		&hf_smb_nt_create_options_eight_dot_three_only,
4083 		&hf_smb_nt_create_options_random_access,
4084 		&hf_smb_nt_create_options_delete_on_close,
4085 		&hf_smb_nt_create_options_open_by_fileid,
4086 		&hf_smb_nt_create_options_backup_intent,
4087 		&hf_smb_nt_create_options_no_compression,
4088 		&hf_smb_nt_create_options_reserve_opfilter,
4089 		&hf_smb_nt_create_options_open_reparse_point,
4090 		&hf_smb_nt_create_options_open_no_recall,
4091 		&hf_smb_nt_create_options_open_for_free_space_query,
4092 		NULL
4093 	};
4094 
4095 	item = proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset, hf_smb_create_options, ett_smb_nt_create_options, fields, mask, BMT_NO_APPEND);
4096 	if (len == 0)
4097 		proto_item_set_generated(item);
4098 
4099 	offset += len;
4100 
4101 	return offset;
4102 }
4103 
4104 int
dissect_nt_create_options(tvbuff_t * tvb,proto_tree * parent_tree,int offset)4105 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4106 {
4107 	guint32 mask;
4108 
4109 	mask = tvb_get_letohl(tvb, offset);
4110 
4111 	offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
4112 
4113 	return offset;
4114 }
4115 
4116 
4117 /* fids are scoped by tcp session */
4118 smb_fid_info_t *
dissect_smb_fid(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,int len,guint16 fid,gboolean is_created,gboolean is_closed,gboolean is_generated,smb_info_t * si)4119 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
4120     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated, smb_info_t* si)
4121 {
4122 	smb_saved_info_t *sip;
4123 	proto_item       *it;
4124 	proto_tree       *tr;
4125 	smb_fid_info_t   *fid_info         = NULL;
4126 	smb_fid_info_t   *suspect_fid_info = NULL;
4127 	/* We need this to use an array-accessed tree */
4128 	GSList           *GSL_iterator;
4129 
4130 	DISSECTOR_ASSERT(si);
4131 
4132 	sip = si->sip;
4133 
4134 	it = proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
4135 	if (is_generated) {
4136 		proto_item_set_generated(it);
4137 	}
4138 	tr = proto_item_add_subtree(it, ett_smb_fid);
4139 	col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
4140 
4141 	if ((!pinfo->fd->visited) && is_created) {
4142 		fid_info = wmem_new(wmem_file_scope(), smb_fid_info_t);
4143 		fid_info->opened_in = pinfo->num;
4144 		fid_info->closed_in = 0;
4145 		fid_info->type = SMB_FID_TYPE_UNKNOWN;
4146 		fid_info->fid = fid;
4147 		fid_info->tid = si->tid;
4148 		if (si->sip && (si->sip->extra_info_type == SMB_EI_FILEDATA)) {
4149 			fid_info->fsi = (smb_fid_saved_info_t *)si->sip->extra_info;
4150 		} else {
4151 			fid_info->fsi = NULL;
4152 		}
4153 		/* We don't use the fid_tree anymore to access and
4154 		   maintain the fid information of analyzed files.
4155 		   (was wmem_tree_insert32(si->ct->fid_tree, fid, fid_info);)
4156 		   We'll use a single list instead to keep track of the
4157 		   files (fid) opened.
4158 		   Note that the insert_sorted function allows to insert duplicates
4159 		   but being inside this if section should prevent it */
4160 		si->ct->GSL_fid_info = g_slist_insert_sorted(
4161 					si->ct->GSL_fid_info,
4162 					fid_info,
4163 					(GCompareFunc)fid_cmp);
4164 	}
4165 
4166 	if (!fid_info) {
4167 		/* we use the single linked list to access this fid_info
4168 		   (was fid_info = wmem_tree_lookup32(si->ct->fid_tree, fid);) */
4169 		GSL_iterator = si->ct->GSL_fid_info;
4170 		while (GSL_iterator) {
4171 			suspect_fid_info = (smb_fid_info_t *)GSL_iterator->data;
4172 			if (suspect_fid_info->opened_in > pinfo->num) break;
4173 			if ((suspect_fid_info->tid == si->tid) && (suspect_fid_info->fid == fid))
4174 				fid_info = (smb_fid_info_t *)suspect_fid_info;
4175 			GSL_iterator = g_slist_next(GSL_iterator);
4176 		}
4177 	}
4178 	if (!fid_info) {
4179 		return NULL;
4180 	}
4181 
4182 	/* Store the fid in the transaction structure and remember if
4183 	   it was in the request or in the reply we saw it
4184 	 */
4185 	if (sip && (!is_generated) && (!pinfo->fd->visited)) {
4186 		sip->fid = fid;
4187 		if (si->request) {
4188 			sip->fid_seen_in_request = TRUE;
4189 		} else {
4190 			sip->fid_seen_in_request = FALSE;
4191 		}
4192 	}
4193 
4194 	if ((!pinfo->fd->visited) && is_closed) {
4195 		fid_info->closed_in = pinfo->num;
4196 	}
4197 
4198 	if (fid_info->opened_in) {
4199 		it = proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
4200 		proto_item_set_generated(it);
4201 	}
4202 
4203 	if (fid_info->closed_in) {
4204 		it = proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
4205 		proto_item_set_generated(it);
4206 	}
4207 
4208 
4209 	if (fid_info->opened_in) {
4210 		if (fid_info->fsi && fid_info->fsi->filename) {
4211 			it = proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
4212 			proto_item_set_generated(it);
4213 			proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
4214 			dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
4215 			dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
4216 			dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
4217 			dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
4218 			dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
4219 			it = proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
4220 			proto_item_set_generated(it);
4221 		}
4222 	}
4223 
4224 	return fid_info;
4225 }
4226 
4227 static int
dissect_open_file_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4228 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4229 {
4230 	guint8  wc;
4231 	guint16 bc;
4232 	guint16 fid;
4233 	smb_fid_info_t *fid_info   = NULL; /* eo_smb needs to track this info */
4234 	guint16         fattr;
4235 	gboolean                isdir      = FALSE;
4236 
4237 	WORD_COUNT;
4238 
4239 	/* fid */
4240 	fid = tvb_get_letohs(tvb, offset);
4241 
4242 	fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
4243 	if (fid_info) {
4244 		/* This command is used to create and open a new file or open
4245 		and truncate an existing file to zero length */
4246 		fid_info->end_of_file = 0;
4247 		if (fid_info->fsi) {
4248 			/* File Type */
4249 			fattr = fid_info->fsi->file_attributes;
4250 			/* XXX Volumes considered as directories */
4251 			isdir = (fattr & SMB_FILE_ATTRIBUTE_DIRECTORY) || (fattr & SMB_FILE_ATTRIBUTE_VOLUME);
4252 			if (isdir == 0) {
4253 				fid_info->type = SMB_FID_TYPE_FILE;
4254 			} else {
4255 				fid_info->type = SMB_FID_TYPE_DIR;
4256 			}
4257 		}
4258 	}
4259 
4260 	offset += 2;
4261 
4262 	/* File Attributes */
4263 	offset = dissect_file_attributes(tvb, tree, offset);
4264 
4265 	/* last write time */
4266 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4267 
4268 	/* File Size */
4269 	proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4270 	offset += 4;
4271 
4272 	/* granted access */
4273 	offset = dissect_access(tvb, tree, offset, hf_smb_granted_access);
4274 
4275 	BYTE_COUNT;
4276 
4277 	END_OF_SMB
4278 
4279 	return offset;
4280 }
4281 
4282 static int
dissect_query_information2_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4283 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4284 {
4285 	guint8  wc;
4286 	guint16 bc;
4287 	guint16 fid;
4288 
4289 	WORD_COUNT;
4290 
4291 	/* fid */
4292 	fid = tvb_get_letohs(tvb, offset);
4293 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4294 	offset += 2;
4295 
4296 	BYTE_COUNT;
4297 
4298 	END_OF_SMB
4299 
4300 	return offset;
4301 }
4302 
4303 static int
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)4304 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)
4305 {
4306 	guint8  wc;
4307 	guint16 bc;
4308 	guint16 fid;
4309 
4310 	WORD_COUNT;
4311 
4312 	/* fid */
4313 	fid = tvb_get_letohs(tvb, offset);
4314 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
4315 	offset += 2;
4316 
4317 	BYTE_COUNT;
4318 
4319 	END_OF_SMB
4320 
4321 	return offset;
4322 }
4323 
4324 static int
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)4325 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)
4326 {
4327 	guint8  wc;
4328 	guint16 bc;
4329 	guint16 fid;
4330 
4331 	WORD_COUNT;
4332 
4333 	/* fid */
4334 	fid = tvb_get_letohs(tvb, offset);
4335 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4336 	offset += 2;
4337 
4338 	BYTE_COUNT;
4339 
4340 	END_OF_SMB
4341 
4342 	return offset;
4343 }
4344 
4345 static int
dissect_create_new_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4346 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4347 {
4348 	guint8  wc;
4349 	guint16 bc;
4350 	guint16 fid;
4351 
4352 	WORD_COUNT;
4353 
4354 	/* fid */
4355 	fid = tvb_get_letohs(tvb, offset);
4356 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
4357 	offset += 2;
4358 
4359 	BYTE_COUNT;
4360 
4361 	END_OF_SMB
4362 
4363 	return offset;
4364 }
4365 
4366 static int
dissect_flush_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4367 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4368 {
4369 	guint8  wc;
4370 	guint16 bc;
4371 	guint16 fid;
4372 
4373 	WORD_COUNT;
4374 
4375 	/* fid */
4376 	fid = tvb_get_letohs(tvb, offset);
4377 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4378 	offset += 2;
4379 
4380 	BYTE_COUNT;
4381 
4382 	END_OF_SMB
4383 
4384 	return offset;
4385 }
4386 
4387 static int
dissect_create_file_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4388 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4389 {
4390 	guint8  wc;
4391 	guint16 bc;
4392 	guint16 fid;
4393 	smb_fid_info_t *fid_info   = NULL; /* eo_smb needs to track this info */
4394 	guint16         fattr;
4395 	gboolean		isdir      = FALSE;
4396 
4397 	WORD_COUNT;
4398 
4399 	/* fid */
4400 	fid = tvb_get_letohs(tvb, offset);
4401 	fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
4402 	if (fid_info) {
4403 		/* This command is used to create and open a new file or open
4404 		and truncate an existing file to zero length */
4405 		fid_info->end_of_file = 0;
4406 		if (fid_info->fsi) {
4407 			/* File Type */
4408 			fattr = fid_info->fsi->file_attributes;
4409 			/* XXX Volumes considered as directories */
4410 			isdir = (fattr & SMB_FILE_ATTRIBUTE_DIRECTORY) || (fattr & SMB_FILE_ATTRIBUTE_VOLUME);
4411 			if (isdir == 0) {
4412 				fid_info->type = SMB_FID_TYPE_FILE;
4413 			} else {
4414 				fid_info->type = SMB_FID_TYPE_DIR;
4415 			}
4416 		}
4417 	}
4418 
4419 	offset += 2;
4420 
4421 	BYTE_COUNT;
4422 
4423 	END_OF_SMB
4424 
4425 	return offset;
4426 }
4427 
4428 static int
dissect_create_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4429 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4430 {
4431 	int         fn_len;
4432 	const char *fn;
4433 	guint8      wc;
4434 	guint16     bc;
4435 	smb_fid_saved_info_t *fsi; /* eo_smb needs to track this info */
4436 	guint32		file_attributes = 0;
4437 
4438 	DISSECTOR_ASSERT(si);
4439 
4440 	WORD_COUNT;
4441 
4442 	/* file attributes */
4443 	/* We read the two lower bytes into the four-bytes file-attributes, because they are compatible */
4444 	file_attributes = tvb_get_letohs(tvb, offset);
4445 	offset = dissect_file_attributes(tvb, tree, offset);
4446 
4447 	/* creation time */
4448 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4449 
4450 	BYTE_COUNT;
4451 
4452 	/* buffer format */
4453 	CHECK_BYTE_COUNT(1);
4454 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4455 	COUNT_BYTES(1);
4456 
4457 	/* File Name */
4458 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4459 		FALSE, FALSE, &bc);
4460 	if (fn == NULL)
4461 		goto endofcommand;
4462 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4463 		fn);
4464 	COUNT_BYTES(fn_len);
4465 
4466 	/* store it for the fid->name/openframe/closeframe matching in
4467 	* dissect_smb_fid()   called from the response.
4468 	*/
4469 	if ((!pinfo->fd->visited) && si->sip && fn) {
4470 		fsi			= wmem_new0(wmem_file_scope(), smb_fid_saved_info_t);
4471 		fsi->filename		= wmem_strdup(wmem_file_scope(), fn);
4472 		fsi->file_attributes	= file_attributes;
4473 
4474 		si->sip->extra_info_type = SMB_EI_FILEDATA;
4475 		si->sip->extra_info      = fsi;
4476 	}
4477 
4478 
4479 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4480 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4481 
4482 	END_OF_SMB
4483 
4484 	return offset;
4485 }
4486 
4487 static int
dissect_close_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4488 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4489 {
4490 	guint8  wc;
4491 	guint16 bc, fid;
4492 
4493 	WORD_COUNT;
4494 
4495 	/* fid */
4496 	fid = tvb_get_letohs(tvb, offset);
4497 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
4498 	offset += 2;
4499 
4500 	/* last write time */
4501 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4502 
4503 	BYTE_COUNT;
4504 
4505 	END_OF_SMB
4506 
4507 	return offset;
4508 }
4509 
4510 static int
dissect_delete_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4511 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4512 {
4513 	int         fn_len;
4514 	const char *fn;
4515 	guint8      wc;
4516 	guint16     bc;
4517 
4518 	DISSECTOR_ASSERT(si);
4519 
4520 	WORD_COUNT;
4521 
4522 	/* search attributes */
4523 	offset = dissect_search_attributes(tvb, tree, offset);
4524 
4525 	BYTE_COUNT;
4526 
4527 	/* buffer format */
4528 	CHECK_BYTE_COUNT(1);
4529 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4530 	COUNT_BYTES(1);
4531 
4532 	/* file name */
4533 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4534 		FALSE, FALSE, &bc);
4535 
4536 	if ((!pinfo->fd->visited) && si->sip) {
4537 		si->sip->extra_info_type = SMB_EI_FILENAME;
4538 		si->sip->extra_info = wmem_strdup(wmem_file_scope(), fn);
4539 	}
4540 
4541 	if (fn == NULL)
4542 		goto endofcommand;
4543 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4544 		fn);
4545 	COUNT_BYTES(fn_len);
4546 
4547 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4548 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4549 
4550 	END_OF_SMB
4551 
4552 	return offset;
4553 }
4554 
4555 static int
dissect_rename_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4556 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4557 {
4558 	int         fn_len;
4559 	const char *fn, *old_name = NULL, *new_name = NULL;
4560 	guint8      wc;
4561 	guint16     bc;
4562 	smb_rename_saved_info_t *rni = NULL;
4563 
4564 	DISSECTOR_ASSERT(si);
4565 
4566 	WORD_COUNT;
4567 
4568 	/* search attributes */
4569 	offset = dissect_search_attributes(tvb, tree, offset);
4570 
4571 	BYTE_COUNT;
4572 
4573 	/* buffer format */
4574 	CHECK_BYTE_COUNT(1);
4575 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4576 	COUNT_BYTES(1);
4577 
4578 	/* old file name */
4579 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4580 		FALSE, FALSE, &bc);
4581 	if (fn == NULL)
4582 		goto endofcommand;
4583 	old_name = fn;
4584 	proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
4585 		fn);
4586 	COUNT_BYTES(fn_len);
4587 
4588 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
4589 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4590 
4591 	/* buffer format */
4592 	CHECK_BYTE_COUNT(1);
4593 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4594 	COUNT_BYTES(1);
4595 
4596 	/* file name */
4597 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4598 		FALSE, FALSE, &bc);
4599 	if (fn == NULL)
4600 		goto endofcommand;
4601 	new_name = fn;
4602 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4603 		fn);
4604 	COUNT_BYTES(fn_len);
4605 
4606 	col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
4607 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4608 
4609 	END_OF_SMB
4610 
4611 	/* save the offset/len for this transaction */
4612 	if (si->sip && !pinfo->fd->visited) {
4613 		rni = wmem_new(wmem_file_scope(), smb_rename_saved_info_t);
4614 		rni->old_name = wmem_strdup(wmem_file_scope(), old_name);
4615 		rni->new_name = wmem_strdup(wmem_file_scope(), new_name);
4616 
4617 		si->sip->extra_info_type = SMB_EI_RENAMEDATA;
4618 		si->sip->extra_info = rni;
4619 	}
4620 
4621 	return offset;
4622 }
4623 
4624 static int
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)4625 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)
4626 {
4627 	int         fn_len;
4628 	const char *fn;
4629 	guint8      wc;
4630 	guint16     bc;
4631 
4632 	DISSECTOR_ASSERT(si);
4633 
4634 	WORD_COUNT;
4635 
4636 	/* search attributes */
4637 	offset = dissect_search_attributes(tvb, tree, offset);
4638 
4639 	proto_tree_add_item(tree, hf_smb_nt_rename_level, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4640 	offset += 2;
4641 
4642 	proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4643 	offset += 4;
4644 
4645 	BYTE_COUNT;
4646 
4647 	/* buffer format */
4648 	CHECK_BYTE_COUNT(1);
4649 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4650 	COUNT_BYTES(1);
4651 
4652 	/* old file name */
4653 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4654 		FALSE, FALSE, &bc);
4655 	if (fn == NULL)
4656 		goto endofcommand;
4657 	proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
4658 		fn);
4659 	COUNT_BYTES(fn_len);
4660 
4661 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
4662 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4663 
4664 	/* buffer format */
4665 	CHECK_BYTE_COUNT(1);
4666 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4667 	COUNT_BYTES(1);
4668 
4669 	/* file name */
4670 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4671 		FALSE, FALSE, &bc);
4672 	if (fn == NULL)
4673 		goto endofcommand;
4674 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4675 		fn);
4676 	COUNT_BYTES(fn_len);
4677 
4678 	col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
4679 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4680 
4681 	END_OF_SMB
4682 
4683 	return offset;
4684 }
4685 
4686 
4687 static int
dissect_query_information_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4688 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4689 {
4690 	guint16     bc;
4691 	guint8      wc;
4692 	const char *fn;
4693 	int         fn_len;
4694 
4695 	DISSECTOR_ASSERT(si);
4696 
4697 	WORD_COUNT;
4698 
4699 	BYTE_COUNT;
4700 
4701 	/* Buffer Format */
4702 	CHECK_BYTE_COUNT(1);
4703 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4704 	COUNT_BYTES(1);
4705 
4706 	/* File Name */
4707 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4708 		FALSE, FALSE, &bc);
4709 	if (fn == NULL)
4710 		goto endofcommand;
4711 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4712 		fn);
4713 	COUNT_BYTES(fn_len);
4714 
4715 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4716 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4717 
4718 	END_OF_SMB
4719 
4720 	return offset;
4721 }
4722 
4723 static int
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_)4724 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_)
4725 {
4726 	guint16 bc;
4727 	guint8  wc;
4728 
4729 	WORD_COUNT;
4730 
4731 	/* File Attributes */
4732 	offset = dissect_file_attributes(tvb, tree, offset);
4733 
4734 	/* Last Write Time */
4735 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4736 
4737 	/* File Size */
4738 	proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4739 	offset += 4;
4740 
4741 	/* 10 reserved bytes */
4742 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
4743 	offset += 10;
4744 
4745 	BYTE_COUNT;
4746 
4747 	END_OF_SMB
4748 
4749 	return offset;
4750 }
4751 
4752 static int
dissect_set_information_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4753 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4754 {
4755 	int         fn_len;
4756 	const char *fn;
4757 	guint8      wc;
4758 	guint16     bc;
4759 
4760 	DISSECTOR_ASSERT(si);
4761 
4762 	WORD_COUNT;
4763 
4764 	/* file attributes */
4765 	offset = dissect_file_attributes(tvb, tree, offset);
4766 
4767 	/* last write time */
4768 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4769 
4770 	/* 10 reserved bytes */
4771 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
4772 	offset += 10;
4773 
4774 	BYTE_COUNT;
4775 
4776 	/* buffer format */
4777 	CHECK_BYTE_COUNT(1);
4778 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4779 	COUNT_BYTES(1);
4780 
4781 	/* file name */
4782 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4783 		FALSE, FALSE, &bc);
4784 	if (fn == NULL)
4785 		goto endofcommand;
4786 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4787 		fn);
4788 	COUNT_BYTES(fn_len);
4789 
4790 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4791 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
4792 
4793 	END_OF_SMB
4794 
4795 	return offset;
4796 }
4797 
4798 typedef struct _rw_info_t {
4799 	guint64 offset;
4800 	guint32 len;
4801 	guint16 fid;
4802 } rw_info_t;
4803 
4804 static int
dissect_read_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4805 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4806 {
4807 	guint8       wc;
4808 	guint16      cnt = 0, bc;
4809 	guint32      ofs = 0;
4810 	unsigned int fid;
4811 	rw_info_t    *rwi                   = NULL;
4812 
4813 	WORD_COUNT;
4814 
4815 	/* fid */
4816 	fid = tvb_get_letohs(tvb, offset);
4817 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
4818 	offset += 2;
4819 
4820 	/* read count */
4821 	cnt = tvb_get_letohs(tvb, offset);
4822 	proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4823 	offset += 2;
4824 
4825 	/* offset */
4826 	ofs = tvb_get_letohl(tvb, offset);
4827 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4828 	offset += 4;
4829 
4830 	col_append_fstr(pinfo->cinfo, COL_INFO,
4831 				", %u byte%s at offset %u", cnt,
4832 				(cnt == 1) ? "" : "s", ofs);
4833 
4834 	/* remaining */
4835 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4836 	offset += 2;
4837 
4838 	/* save the offset/len for this transaction */
4839 	if (si->sip && !pinfo->fd->visited) {
4840 		rwi = wmem_new(wmem_file_scope(), rw_info_t);
4841 		rwi->offset = ofs;
4842 		rwi->len = cnt;
4843 		rwi->fid = fid;
4844 		si->sip->extra_info_type = SMB_EI_RWINFO;
4845 		si->sip->extra_info = rwi;
4846 	}
4847 
4848 	BYTE_COUNT;
4849 
4850 	END_OF_SMB
4851 
4852 	return offset;
4853 }
4854 
4855 int
dissect_file_data(tvbuff_t * tvb,proto_tree * tree,int offset,guint16 bc,guint16 datalen)4856 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4857 {
4858 	int tvblen;
4859 
4860 	if (bc > datalen) {
4861 		/* We have some initial padding bytes. */
4862 		/* XXX - use the data offset here instead? */
4863 		proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4864 			ENC_NA);
4865 		offset += bc-datalen;
4866 		bc = datalen;
4867 	}
4868 	tvblen = tvb_reported_length_remaining(tvb, offset);
4869 	if (bc > tvblen) {
4870 		proto_tree_add_bytes_format_value(tree, hf_smb_file_data, tvb, offset, tvblen, NULL, "Incomplete. Only %d of %u bytes", tvblen, bc);
4871 		offset += tvblen;
4872 	} else {
4873 		proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, ENC_NA);
4874 		offset += bc;
4875 	}
4876 	return offset;
4877 }
4878 
4879 static int
dissect_file_data_dcerpc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * top_tree,int offset,guint16 bc,guint16 datalen,guint16 fid,void * data)4880 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4881     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid,
4882     void *data)
4883 {
4884 	int       tvblen;
4885 	tvbuff_t *dcerpc_tvb;
4886 
4887 	if (bc > datalen) {
4888 		/* We have some initial padding bytes. */
4889 		/* XXX - use the data offset here instead? */
4890 		proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4891 			ENC_NA);
4892 		offset += bc-datalen;
4893 		bc = datalen;
4894 	}
4895 	tvblen = tvb_reported_length_remaining(tvb, offset);
4896 	dcerpc_tvb = tvb_new_subset_length_caplen(tvb, offset, tvblen, bc);
4897 	dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid, data);
4898 	if (bc > tvblen)
4899 		offset += tvblen;
4900 	else
4901 		offset += bc;
4902 	return offset;
4903 }
4904 
4905 /*
4906  * transporting DCERPC over SMB seems to be implemented in various
4907  * ways. We might just assume it can be done by an almost random
4908  * mix of Trans/Read/Write calls
4909  *
4910  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4911  * and let him sort them out
4912  */
4913 static int
dissect_file_data_maybe_dcerpc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * top_tree,int offset,guint16 bc,guint16 datalen,guint32 ofs,guint16 fid,smb_info_t * si)4914 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4915     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4916     guint16 datalen, guint32 ofs, guint16 fid, smb_info_t *si)
4917 {
4918 	DISSECTOR_ASSERT(si);
4919 
4920 	if ( (si->sip && (si->sip->flags & SMB_SIF_TID_IS_IPC)) && (ofs == 0) ) {
4921 		/* dcerpc call */
4922 		return dissect_file_data_dcerpc(tvb, pinfo, tree,
4923 		    top_tree, offset, bc, datalen, fid, si);
4924 	} else {
4925 		/* ordinary file data */
4926 		return dissect_file_data(tvb, tree, offset, bc, datalen);
4927 	}
4928 }
4929 
4930 static int
dissect_read_file_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)4931 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4932 {
4933 	guint16    cnt	   = 0, bc;
4934 	guint8     wc;
4935 	int        fid	   = 0;
4936 	guint32	   datalen = 0, dataoffset = 0;
4937 	guint32	   tvblen;
4938 	rw_info_t *rwi     = NULL;
4939 
4940 	DISSECTOR_ASSERT(si);
4941 
4942 	WORD_COUNT;
4943 
4944 	/* read count */
4945 	cnt = tvb_get_letohs(tvb, offset);
4946 	proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4947 	offset += 2;
4948 
4949 	/* 8 reserved bytes */
4950 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, ENC_NA);
4951 	offset += 8;
4952 	BYTE_COUNT;
4953 
4954 	/* buffer format */
4955 	CHECK_BYTE_COUNT(1);
4956 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4957 	COUNT_BYTES(1);
4958 
4959 	/* data len */
4960 	CHECK_BYTE_COUNT(2);
4961 	proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4962 	datalen = tvb_get_letohs(tvb, offset);
4963 	COUNT_BYTES(2);
4964 	dataoffset = offset;
4965 
4966 	/* file data, might be DCERPC on a pipe */
4967 	if (bc) {
4968 		offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4969 		    top_tree_global, offset, bc, bc, 0, (guint16) fid, si);
4970 		bc = 0;
4971 	}
4972 
4973 	/* If we have seen the request, then print which FID this refers to */
4974 	if ((si->sip != NULL) && (si->sip->frame_req > 0) && (si->sip->extra_info_type == SMB_EI_FID)) {
4975 		fid = GPOINTER_TO_INT(si->sip->extra_info);
4976 	}
4977 
4978 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4979 		rwi = (rw_info_t *)si->sip->extra_info;
4980 	}
4981 	if (rwi) {
4982 		proto_item *it;
4983 
4984 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4985 
4986 		proto_item_set_generated(it);
4987 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4988 		proto_item_set_generated(it);
4989 
4990 		/* we need the fid for the call to dcerpc below */
4991 		fid = rwi->fid;
4992 	}
4993 
4994 	/* feed the export object tap listener */
4995 	tvblen = tvb_reported_length_remaining(tvb, dataoffset);
4996 	if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
4997 		feed_eo_smb(SMB_COM_READ, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
4998 	}
4999 
5000 	END_OF_SMB
5001 
5002 	return offset;
5003 }
5004 
5005 static int
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_)5006 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_)
5007 {
5008 	guint16 cnt, bc;
5009 	guint8  wc;
5010 
5011 	WORD_COUNT;
5012 
5013 	/* read count */
5014 	cnt = tvb_get_letohs(tvb, offset);
5015 	proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
5016 	offset += 2;
5017 
5018 	/* 8 reserved bytes */
5019 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, ENC_NA);
5020 	offset += 8;
5021 
5022 	BYTE_COUNT;
5023 
5024 	/* buffer format */
5025 	CHECK_BYTE_COUNT(1);
5026 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5027 	COUNT_BYTES(1);
5028 
5029 	/* data len */
5030 	CHECK_BYTE_COUNT(2);
5031 	proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5032 	COUNT_BYTES(2);
5033 
5034 	END_OF_SMB
5035 
5036 	return offset;
5037 }
5038 
5039 
5040 
5041 static int
dissect_write_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5042 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5043 {
5044 	guint32    ofs	   = 0;
5045 	guint16    cnt	   = 0, bc, fid = 0;
5046 	guint8     wc;
5047 	rw_info_t *rwi	   = NULL;
5048 	guint32	   datalen = 0, dataoffset = 0;
5049 	guint32	   tvblen;
5050 
5051 	DISSECTOR_ASSERT(si);
5052 
5053 	WORD_COUNT;
5054 
5055 	/* fid */
5056 	fid = tvb_get_letohs(tvb, offset);
5057 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5058 	offset += 2;
5059 
5060 	/* write count */
5061 	cnt = tvb_get_letohs(tvb, offset);
5062 	datalen = cnt;
5063 	proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
5064 	offset += 2;
5065 
5066 	/* offset */
5067 	ofs = tvb_get_letohl(tvb, offset);
5068 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5069 	offset += 4;
5070 
5071 	col_append_fstr(pinfo->cinfo, COL_INFO,
5072 				", %u byte%s at offset %u", cnt,
5073 				(cnt == 1) ? "" : "s", ofs);
5074 
5075 	/* save the offset/len for this transaction */
5076 	if (si->sip && !pinfo->fd->visited) {
5077 		rwi	    = wmem_new(wmem_file_scope(), rw_info_t);
5078 		rwi->offset = ofs;
5079 		rwi->len    = cnt;
5080 		rwi->fid    = fid;
5081 
5082 		si->sip->extra_info_type = SMB_EI_RWINFO;
5083 		si->sip->extra_info	 = rwi;
5084 	}
5085 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
5086 		rwi = (rw_info_t *)si->sip->extra_info;
5087 	}
5088 	if (rwi) {
5089 		proto_item *it;
5090 
5091 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
5092 
5093 		proto_item_set_generated(it);
5094 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
5095 		proto_item_set_generated(it);
5096 	}
5097 
5098 	/* remaining */
5099 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5100 	offset += 2;
5101 
5102 	BYTE_COUNT;
5103 
5104 	/* buffer format */
5105 	CHECK_BYTE_COUNT(1);
5106 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5107 	COUNT_BYTES(1);
5108 
5109 	/* data len */
5110 	CHECK_BYTE_COUNT(2);
5111 	proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5112 	COUNT_BYTES(2);
5113 	dataoffset = offset;
5114 
5115 	/* file data, might be DCERPC on a pipe */
5116 	if (bc != 0) {
5117 		offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5118 		    top_tree_global, offset, bc, bc, ofs, fid, si);
5119 		bc = 0;
5120 	}
5121 
5122 	/* feed the export object tap listener */
5123 	tvblen = tvb_reported_length_remaining(tvb, dataoffset);
5124 	if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
5125 		feed_eo_smb(SMB_COM_WRITE, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
5126 	}
5127 
5128 	END_OF_SMB
5129 
5130 	return offset;
5131 }
5132 
5133 static int
dissect_write_file_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5134 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5135 {
5136 	guint8      wc;
5137 	guint16     bc, cnt;
5138 	rw_info_t  *rwi = NULL;
5139 
5140 	DISSECTOR_ASSERT(si);
5141 
5142 	WORD_COUNT;
5143 
5144 	/* write count */
5145 	cnt = tvb_get_letohs(tvb, offset);
5146 	proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5147 	offset += 2;
5148 
5149 	col_append_fstr(pinfo->cinfo, COL_INFO,
5150 				", %u byte%s", cnt, (cnt == 1) ? "" : "s");
5151 
5152 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
5153 		rwi = (rw_info_t *)si->sip->extra_info;
5154 	}
5155 	if (rwi) {
5156 		proto_item *it;
5157 
5158 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
5159 
5160 		proto_item_set_generated(it);
5161 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
5162 		proto_item_set_generated(it);
5163 	}
5164 
5165 	BYTE_COUNT;
5166 
5167 	END_OF_SMB
5168 
5169 	return offset;
5170 }
5171 
5172 static int
dissect_lock_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5173 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5174 {
5175 	guint8  wc;
5176 	guint16 bc, fid;
5177 
5178 	WORD_COUNT;
5179 
5180 	/* fid */
5181 	fid = tvb_get_letohs(tvb, offset);
5182 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5183 	offset += 2;
5184 
5185 	/* lock count */
5186 	proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5187 	offset += 4;
5188 
5189 	/* offset */
5190 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5191 	offset += 4;
5192 
5193 	BYTE_COUNT;
5194 
5195 	END_OF_SMB
5196 
5197 	return offset;
5198 }
5199 
5200 static int
dissect_create_temporary_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5201 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5202 {
5203 	int         fn_len;
5204 	const char *fn;
5205 	guint8      wc;
5206 	guint16     bc;
5207 
5208 	DISSECTOR_ASSERT(si);
5209 
5210 	WORD_COUNT;
5211 
5212 	/* 2 reserved bytes */
5213 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5214 	offset += 2;
5215 
5216 	/* Creation time */
5217 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5218 
5219 	BYTE_COUNT;
5220 
5221 	/* buffer format */
5222 	CHECK_BYTE_COUNT(1);
5223 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5224 	COUNT_BYTES(1);
5225 
5226 	/*
5227 	 * Directory name.
5228 	 *
5229 	 * MS-CIFS says this is a "null-terminated string", without saying
5230 	 * it's always ASCII, so we honor the "Unicode strings" flag.
5231 	 */
5232 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5233 		FALSE, FALSE, &bc);
5234 	if (fn == NULL)
5235 		goto endofcommand;
5236 	proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
5237 		fn);
5238 	COUNT_BYTES(fn_len);
5239 
5240 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
5241 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
5242 
5243 	END_OF_SMB
5244 
5245 	return offset;
5246 }
5247 
5248 static int
dissect_create_temporary_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5249 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5250 {
5251 	int         fn_len;
5252 	const char *fn;
5253 	guint8      wc;
5254 	guint16     bc, fid;
5255 
5256 	DISSECTOR_ASSERT(si);
5257 
5258 	WORD_COUNT;
5259 
5260 	/* fid */
5261 	fid = tvb_get_letohs(tvb, offset);
5262 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
5263 	offset += 2;
5264 
5265 	BYTE_COUNT;
5266 
5267 	/*
5268 	 * File name.
5269 	 *
5270 	 * MS-CIFS says "The string SHOULD be a null-terminated array of
5271 	 * ASCII characters.", so we ignore the "Unicode strings" flag.
5272 	 */
5273 	fn = get_unicode_or_ascii_string(tvb, &offset, FALSE, &fn_len,
5274 		TRUE, FALSE, &bc);
5275 	if (fn == NULL)
5276 		goto endofcommand;
5277 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5278 		fn);
5279 	COUNT_BYTES(fn_len);
5280 
5281 	END_OF_SMB
5282 
5283 	return offset;
5284 }
5285 
5286 static const value_string seek_mode_vals[] = {
5287 	{0,	"From Start Of File"},
5288 	{1,	"From Current Position"},
5289 	{2,	"From End Of File"},
5290 	{0,	NULL}
5291 };
5292 
5293 static int
dissect_seek_file_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5294 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5295 {
5296 	guint8  wc;
5297 	guint16 bc, fid;
5298 
5299 	WORD_COUNT;
5300 
5301 	/* fid */
5302 	fid = tvb_get_letohs(tvb, offset);
5303 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5304 	offset += 2;
5305 
5306 	/* Seek Mode */
5307 	proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5308 	offset += 2;
5309 
5310 	/* offset */
5311 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5312 	offset += 4;
5313 
5314 	BYTE_COUNT;
5315 
5316 	END_OF_SMB
5317 
5318 	return offset;
5319 }
5320 
5321 static int
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_)5322 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_)
5323 {
5324 	guint8  wc;
5325 	guint16 bc;
5326 
5327 	WORD_COUNT;
5328 
5329 	/* offset */
5330 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5331 	offset += 4;
5332 
5333 	BYTE_COUNT;
5334 
5335 	END_OF_SMB
5336 
5337 	return offset;
5338 }
5339 
5340 static int
dissect_set_information2_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5341 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5342 {
5343 	guint8  wc;
5344 	guint16 bc, fid;
5345 
5346 	WORD_COUNT;
5347 
5348 	/* fid */
5349 	fid = tvb_get_letohs(tvb, offset);
5350 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5351 	offset += 2;
5352 
5353 	/* create time */
5354 	offset = dissect_smb_datetime(tvb, tree, offset,
5355 		hf_smb_create_time,
5356 		hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
5357 
5358 	/* access time */
5359 	offset = dissect_smb_datetime(tvb, tree, offset,
5360 		hf_smb_access_time,
5361 		hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
5362 
5363 	/* last write time */
5364 	offset = dissect_smb_datetime(tvb, tree, offset,
5365 		hf_smb_last_write_time,
5366 		hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
5367 
5368 	BYTE_COUNT;
5369 
5370 	END_OF_SMB
5371 
5372 	return offset;
5373 }
5374 
5375 static int
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_)5376 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_)
5377 {
5378 	guint8  wc;
5379 	guint16 bc;
5380 
5381 	WORD_COUNT;
5382 
5383 	/* create time */
5384 	offset = dissect_smb_datetime(tvb, tree, offset,
5385 		hf_smb_create_time,
5386 		hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
5387 
5388 	/* access time */
5389 	offset = dissect_smb_datetime(tvb, tree, offset,
5390 		hf_smb_access_time,
5391 		hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
5392 
5393 	/* last write time */
5394 	offset = dissect_smb_datetime(tvb, tree, offset,
5395 		hf_smb_last_write_time,
5396 		hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
5397 
5398 	/* data size */
5399 	proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5400 	offset += 4;
5401 
5402 	/* allocation size */
5403 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5404 	offset += 4;
5405 
5406 	/* File Attributes */
5407 	offset = dissect_file_attributes(tvb, tree, offset);
5408 
5409 	BYTE_COUNT;
5410 
5411 	END_OF_SMB
5412 
5413 	return offset;
5414 }
5415 
5416 static int
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)5417 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)
5418 {
5419 	guint8  wc;
5420 	guint16 cnt = 0;
5421 	guint16 bc, fid;
5422 
5423 	WORD_COUNT;
5424 
5425 	/* fid */
5426 	fid = tvb_get_letohs(tvb, offset);
5427 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
5428 	offset += 2;
5429 
5430 	/* write count */
5431 	cnt = tvb_get_letohs(tvb, offset);
5432 	proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
5433 	offset += 2;
5434 
5435 	/* offset */
5436 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5437 	offset += 4;
5438 
5439 	/* last write time */
5440 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5441 
5442 	if (wc == 12) {
5443 		/* 12 reserved bytes */
5444 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, ENC_NA);
5445 		offset += 12;
5446 	}
5447 
5448 	BYTE_COUNT;
5449 
5450 	/* 1 pad byte */
5451 	CHECK_BYTE_COUNT(1);
5452 	proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
5453 	COUNT_BYTES(1);
5454 
5455 	offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
5456 	bc = 0;	/* XXX */
5457 
5458 	END_OF_SMB
5459 
5460 	return offset;
5461 }
5462 
5463 static int
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_)5464 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_)
5465 {
5466 	guint8  wc;
5467 	guint16 bc;
5468 
5469 	WORD_COUNT;
5470 
5471 	/* write count */
5472 	proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5473 	offset += 2;
5474 
5475 	BYTE_COUNT;
5476 
5477 	END_OF_SMB
5478 
5479 	return offset;
5480 }
5481 
5482 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
5483    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
5484 */
5485 static gchar *
smbext20_timeout_msecs_to_str(gint32 timeout)5486 smbext20_timeout_msecs_to_str(gint32 timeout)
5487 {
5488 	gchar *buf;
5489 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
5490 
5491 	if (timeout <= 0) {
5492 		buf = (gchar *)wmem_alloc(wmem_packet_scope(), SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
5493 		if (timeout == 0) {
5494 			g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
5495 		} else if (timeout == -1) {
5496 			g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
5497 		} else if (timeout == -2) {
5498 			g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
5499 		} else {
5500 			g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", timeout);
5501 		}
5502 		return buf;
5503 	}
5504 
5505 	return signed_time_msecs_to_str(wmem_packet_scope(), timeout);
5506 }
5507 
5508 static int
dissect_read_raw_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5509 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5510 {
5511 	guint8  wc;
5512 	guint16 bc, fid;
5513 	guint32 to;
5514 
5515 	WORD_COUNT;
5516 
5517 	/* fid */
5518 	fid = tvb_get_letohs(tvb, offset);
5519 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5520 	offset += 2;
5521 
5522 	/* offset */
5523 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5524 	offset += 4;
5525 
5526 	/* max count */
5527 	proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5528 	offset += 2;
5529 
5530 	/* min count */
5531 	proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5532 	offset += 2;
5533 
5534 	/* timeout */
5535 	to = tvb_get_letohl(tvb, offset);
5536 	proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5537 	offset += 4;
5538 
5539 	/* 2 reserved bytes */
5540 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5541 	offset += 2;
5542 
5543 	if (wc == 10) {
5544 		/* high offset */
5545 		proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5546 		offset += 4;
5547 	}
5548 
5549 	BYTE_COUNT;
5550 
5551 	END_OF_SMB
5552 
5553 	return offset;
5554 }
5555 
5556 static int
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_)5557 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_)
5558 {
5559 	guint8  wc;
5560 	guint16 bc;
5561 
5562 	WORD_COUNT;
5563 
5564 	/* units */
5565 	proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5566 	offset += 2;
5567 
5568 	/* bpu */
5569 	proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5570 	offset += 2;
5571 
5572 	/* block size */
5573 	proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5574 	offset += 2;
5575 
5576 	/* free units */
5577 	proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5578 	offset += 2;
5579 
5580 	/* 2 reserved bytes */
5581 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5582 	offset += 2;
5583 
5584 	BYTE_COUNT;
5585 
5586 	END_OF_SMB
5587 
5588 	return offset;
5589 }
5590 
5591 static int
dissect_read_mpx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5592 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5593 {
5594 	guint8  wc;
5595 	guint16 bc, fid;
5596 
5597 	WORD_COUNT;
5598 
5599 	/* fid */
5600 	fid = tvb_get_letohs(tvb, offset);
5601 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5602 	offset += 2;
5603 
5604 	/* offset */
5605 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5606 	offset += 4;
5607 
5608 	/* max count */
5609 	proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5610 	offset += 2;
5611 
5612 	/* min count */
5613 	proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5614 	offset += 2;
5615 
5616 	/* 6 reserved bytes */
5617 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, ENC_NA);
5618 	offset += 6;
5619 
5620 	BYTE_COUNT;
5621 
5622 	END_OF_SMB
5623 
5624 	return offset;
5625 }
5626 
5627 static int
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_)5628 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_)
5629 {
5630 	guint16 datalen = 0, bc;
5631 	guint8  wc;
5632 
5633 	WORD_COUNT;
5634 
5635 	/* offset */
5636 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5637 	offset += 4;
5638 
5639 	/* count */
5640 	proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5641 	offset += 2;
5642 
5643 	/* 2 reserved bytes */
5644 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5645 	offset += 2;
5646 
5647 	/* data compaction mode */
5648 	proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5649 	offset += 2;
5650 
5651 	/* 2 reserved bytes */
5652 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5653 	offset += 2;
5654 
5655 	/* data len */
5656 	datalen = tvb_get_letohs(tvb, offset);
5657 	proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5658 	offset += 2;
5659 
5660 	/* data offset */
5661 	proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5662 	offset += 2;
5663 
5664 	BYTE_COUNT;
5665 
5666 	/* file data */
5667 	offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5668 	bc = 0;
5669 
5670 	END_OF_SMB
5671 
5672 	return offset;
5673 }
5674 
5675 
5676 static const true_false_string tfs_write_mode_write_through = {
5677 	"WRITE THROUGH requested",
5678 	"Write through not requested"
5679 };
5680 static const true_false_string tfs_write_mode_return_remaining = {
5681 	"RETURN REMAINING (pipe/dev) requested",
5682 	"DON'T return remaining (pipe/dev)"
5683 };
5684 static const true_false_string tfs_write_mode_raw = {
5685 	"Use WriteRawNamedPipe (pipe)",
5686 	"DON'T use WriteRawNamedPipe (pipe)"
5687 };
5688 static const true_false_string tfs_write_mode_message_start = {
5689 	"This is the START of a MESSAGE (pipe)",
5690 	"This is NOT the start of a message (pipe)"
5691 };
5692 static const true_false_string tfs_write_mode_connectionless = {
5693 	"CONNECTIONLESS mode requested",
5694 	"Connectionless mode NOT requested"
5695 };
5696 
5697 #define WRITE_MODE_CONNECTIONLESS	0x0080
5698 #define WRITE_MODE_MESSAGE_START	0x0008
5699 #define WRITE_MODE_RAW			0x0004
5700 #define WRITE_MODE_RETURN_REMAINING	0x0002
5701 #define WRITE_MODE_WRITE_THROUGH	0x0001
5702 
5703 static int
dissect_write_mode(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int bm)5704 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5705 {
5706 	guint16     mask;
5707 	proto_item *item;
5708 	proto_tree *tree;
5709 
5710 	mask = tvb_get_letohs(tvb, offset);
5711 
5712 	if (parent_tree) {
5713 		item = proto_tree_add_item(parent_tree, hf_smb_write_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5714 		tree = proto_item_add_subtree(item, ett_smb_rawmode);
5715 
5716 		if (bm&WRITE_MODE_CONNECTIONLESS) {
5717 			proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
5718 				tvb, offset, 2, mask);
5719 		}
5720 		if (bm&WRITE_MODE_MESSAGE_START) {
5721 			proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
5722 				tvb, offset, 2, mask);
5723 				}
5724 		if (bm&WRITE_MODE_RAW) {
5725 			proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
5726 				tvb, offset, 2, mask);
5727 		}
5728 		if (bm&WRITE_MODE_RETURN_REMAINING) {
5729 			proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
5730 				tvb, offset, 2, mask);
5731 		}
5732 		if (bm&WRITE_MODE_WRITE_THROUGH) {
5733 			proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
5734 				tvb, offset, 2, mask);
5735 		}
5736 	}
5737 
5738 	offset += 2;
5739 	return offset;
5740 }
5741 
5742 static int
dissect_write_raw_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5743 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5744 {
5745 	guint32 to;
5746 	guint16 datalen = 0, bc, fid;
5747 	guint8  wc;
5748 
5749 	WORD_COUNT;
5750 
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;
5755 
5756 	/* total data length */
5757 	proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5758 	offset += 2;
5759 
5760 	/* 2 reserved bytes */
5761 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5762 	offset += 2;
5763 
5764 	/* offset */
5765 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5766 	offset += 4;
5767 
5768 	/* timeout */
5769 	to = tvb_get_letohl(tvb, offset);
5770 	proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5771 	offset += 4;
5772 
5773 	/* mode */
5774 	offset = dissect_write_mode(tvb, tree, offset, 0x0003);
5775 
5776 	/* 4 reserved bytes */
5777 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
5778 	offset += 4;
5779 
5780 	/* data len */
5781 	datalen = tvb_get_letohs(tvb, offset);
5782 	proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5783 	offset += 2;
5784 
5785 	/* data offset */
5786 	proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5787 	offset += 2;
5788 
5789 	BYTE_COUNT;
5790 
5791 	/* file data */
5792 	/* XXX - use the data offset to determine where the data starts? */
5793 	offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5794 	bc = 0;
5795 
5796 	END_OF_SMB
5797 
5798 	return offset;
5799 }
5800 
5801 static int
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_)5802 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_)
5803 {
5804 	guint8  wc;
5805 	guint16 bc;
5806 
5807 	WORD_COUNT;
5808 
5809 	/* remaining */
5810 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5811 	offset += 2;
5812 
5813 	BYTE_COUNT;
5814 
5815 	END_OF_SMB
5816 
5817 	return offset;
5818 }
5819 
5820 static int
dissect_write_mpx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)5821 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5822 {
5823 	guint32 to;
5824 	guint16 datalen = 0, bc, fid;
5825 	guint8  wc;
5826 
5827 	WORD_COUNT;
5828 
5829 	/* fid */
5830 	fid = tvb_get_letohs(tvb, offset);
5831 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5832 	offset += 2;
5833 
5834 	/* total data length */
5835 	proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5836 	offset += 2;
5837 
5838 	/* 2 reserved bytes */
5839 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5840 	offset += 2;
5841 
5842 	/* offset */
5843 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5844 	offset += 4;
5845 
5846 	/* timeout */
5847 	to = tvb_get_letohl(tvb, offset);
5848 	proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5849 	offset += 4;
5850 
5851 	/* mode */
5852 	offset = dissect_write_mode(tvb, tree, offset, 0x0083);
5853 
5854 	/* request mask */
5855 	proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5856 	offset += 4;
5857 
5858 	/* data len */
5859 	datalen = tvb_get_letohs(tvb, offset);
5860 	proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5861 	offset += 2;
5862 
5863 	/* data offset */
5864 	proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5865 	offset += 2;
5866 
5867 	BYTE_COUNT;
5868 
5869 	/* file data */
5870 	/* XXX - use the data offset to determine where the data starts? */
5871 	offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5872 	bc = 0;
5873 
5874 	END_OF_SMB
5875 
5876 	return offset;
5877 }
5878 
5879 static int
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_)5880 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_)
5881 {
5882 	guint8  wc;
5883 	guint16 bc;
5884 
5885 	WORD_COUNT;
5886 
5887 	/* response mask */
5888 	proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5889 	offset += 4;
5890 
5891 	BYTE_COUNT;
5892 
5893 	END_OF_SMB
5894 
5895 	return offset;
5896 }
5897 
5898 static int
dissect_sid(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si _U_)5899 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5900 {
5901 	guint8  wc;
5902 	guint16 bc;
5903 
5904 	WORD_COUNT;
5905 
5906 	/* sid */
5907 	proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5908 	offset += 2;
5909 
5910 	BYTE_COUNT;
5911 
5912 	END_OF_SMB
5913 
5914 	return offset;
5915 }
5916 
5917 static int
dissect_search_resume_key(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,gboolean has_find_id,smb_info_t * si)5918 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo _U_,
5919     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5920     gboolean has_find_id, smb_info_t *si)
5921 {
5922 	proto_tree *tree;
5923 	int         fn_len;
5924 	const char *fn;
5925 	char        fname[11+1];
5926 
5927 	DISSECTOR_ASSERT(si);
5928 
5929 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, 21,
5930 			ett_smb_search_resume_key, NULL, "Resume Key");
5931 
5932 	/* reserved byte */
5933 	CHECK_BYTE_COUNT_SUBR(1);
5934 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
5935 	COUNT_BYTES_SUBR(1);
5936 
5937 	/* file name */
5938 	fn_len = 11;
5939 	fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5940 		TRUE, TRUE, bcp);
5941 	CHECK_STRING_SUBR(fn);
5942 	/* ensure that it's null-terminated */
5943 	(void) g_strlcpy(fname, fn, 11+1);
5944 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5945 		fname);
5946 	COUNT_BYTES_SUBR(fn_len);
5947 
5948 	if (has_find_id) {
5949 		CHECK_BYTE_COUNT_SUBR(1);
5950 		proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5951 		COUNT_BYTES_SUBR(1);
5952 
5953 		/* server cookie */
5954 		CHECK_BYTE_COUNT_SUBR(4);
5955 		proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, ENC_NA);
5956 		COUNT_BYTES_SUBR(4);
5957 	} else {
5958 		/* server cookie */
5959 		CHECK_BYTE_COUNT_SUBR(5);
5960 		proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, ENC_NA);
5961 		COUNT_BYTES_SUBR(5);
5962 	}
5963 
5964 	/* client cookie */
5965 	CHECK_BYTE_COUNT_SUBR(4);
5966 	proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, ENC_NA);
5967 	COUNT_BYTES_SUBR(4);
5968 
5969 	*trunc = FALSE;
5970 	return offset;
5971 }
5972 
5973 static int
dissect_search_dir_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,gboolean has_find_id,smb_info_t * si)5974 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5975     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5976     gboolean has_find_id, smb_info_t *si)
5977 {
5978 	proto_tree *tree;
5979 	int         fn_len;
5980 	const char *fn;
5981 	char        fname[13+1];
5982 
5983 	DISSECTOR_ASSERT(si);
5984 
5985 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, 43,
5986 			ett_smb_search_dir_info, NULL, "Directory Information");
5987 
5988 	/* resume key */
5989 	offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5990 	    trunc, has_find_id, si);
5991 	if (*trunc)
5992 		return offset;
5993 
5994 	/* File Attributes */
5995 	CHECK_BYTE_COUNT_SUBR(1);
5996 	offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5997 	*bcp -= 1;
5998 
5999 	/* last write time */
6000 	CHECK_BYTE_COUNT_SUBR(4);
6001 	offset = dissect_smb_datetime(tvb, tree, offset,
6002 		hf_smb_last_write_time,
6003 		hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
6004 		TRUE);
6005 	*bcp -= 4;
6006 
6007 	/* File Size */
6008 	CHECK_BYTE_COUNT_SUBR(4);
6009 	proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6010 	COUNT_BYTES_SUBR(4);
6011 
6012 	/* file name */
6013 	/* XXX - [MS-CIFS] says this is 13 *bytes*, suggesting that it's
6014 	   in an OEM code page (i.e., ASCII superset), not Unicode in
6015 	   UTF-16 encoding.  Is it *ever* Unicode? */
6016 	fn_len = 13;
6017 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
6018 		TRUE, TRUE, bcp);
6019 	CHECK_STRING_SUBR(fn);
6020 	/* ensure that it's null-terminated */
6021 	(void) g_strlcpy(fname, fn, 13+1);
6022 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6023 		fname);
6024 	COUNT_BYTES_SUBR(fn_len);
6025 
6026 	*trunc = FALSE;
6027 	return offset;
6028 }
6029 
6030 
6031 static int
dissect_search_find_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si,gboolean has_find_id)6032 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
6033     proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si,
6034     gboolean has_find_id)
6035 {
6036 	int         fn_len;
6037 	const char *fn;
6038 	guint16     rkl;
6039 	guint8      wc;
6040 	guint16     bc;
6041 	gboolean    trunc;
6042 
6043 	DISSECTOR_ASSERT(si);
6044 
6045 	WORD_COUNT;
6046 
6047 	/* max count */
6048 	proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6049 	offset += 2;
6050 
6051 	/* Search Attributes */
6052 	offset = dissect_search_attributes(tvb, tree, offset);
6053 
6054 	BYTE_COUNT;
6055 
6056 	/* buffer format */
6057 	CHECK_BYTE_COUNT(1);
6058 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6059 	COUNT_BYTES(1);
6060 
6061 	/* file name */
6062 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
6063 		TRUE, FALSE, &bc);
6064 	if (fn == NULL)
6065 		goto endofcommand;
6066 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6067 		fn);
6068 	COUNT_BYTES(fn_len);
6069 
6070 	col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
6071 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
6072 
6073 	/* buffer format */
6074 	CHECK_BYTE_COUNT(1);
6075 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6076 	COUNT_BYTES(1);
6077 
6078 	/* resume key length */
6079 	CHECK_BYTE_COUNT(2);
6080 	rkl = tvb_get_letohs(tvb, offset);
6081 	proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
6082 	COUNT_BYTES(2);
6083 
6084 	/* resume key */
6085 	if (rkl) {
6086 		offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
6087 		    &bc, &trunc, has_find_id, si);
6088 		if (trunc)
6089 			goto endofcommand;
6090 	}
6091 
6092 	END_OF_SMB
6093 
6094 	return offset;
6095 }
6096 
6097 static int
dissect_search_dir_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6098 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo,
6099     proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6100 {
6101 	return dissect_search_find_request(tvb, pinfo, tree, offset,
6102 	    smb_tree, si, FALSE);
6103 }
6104 
6105 static int
dissect_find_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6106 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo,
6107     proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6108 {
6109 	return dissect_search_find_request(tvb, pinfo, tree, offset,
6110 	    smb_tree, si, TRUE);
6111 }
6112 
6113 static int
dissect_find_close_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6114 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo,
6115     proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6116 {
6117 	return dissect_search_find_request(tvb, pinfo, tree, offset,
6118 	    smb_tree, si, TRUE);
6119 }
6120 
6121 static int
dissect_search_find_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,gboolean has_find_id,smb_info_t * si)6122 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo,
6123     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
6124     gboolean has_find_id, smb_info_t *si)
6125 {
6126 	guint16  count = 0;
6127 	guint8   wc;
6128 	guint16  bc;
6129 	gboolean trunc;
6130 
6131 	WORD_COUNT;
6132 
6133 	/* count */
6134 	count = tvb_get_letohs(tvb, offset);
6135 	proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
6136 	offset += 2;
6137 
6138 	BYTE_COUNT;
6139 
6140 	/* buffer format */
6141 	CHECK_BYTE_COUNT(1);
6142 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6143 	COUNT_BYTES(1);
6144 
6145 	/* data len */
6146 	CHECK_BYTE_COUNT(2);
6147 	proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6148 	COUNT_BYTES(2);
6149 
6150 	while (count--) {
6151 		offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
6152 		    &bc, &trunc, has_find_id, si);
6153 		if (trunc)
6154 			goto endofcommand;
6155 	}
6156 
6157 	END_OF_SMB
6158 
6159 	return offset;
6160 }
6161 
6162 static int
dissect_search_dir_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6163 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6164 {
6165 	return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
6166 	    FALSE, si);
6167 }
6168 
6169 static int
dissect_find_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6170 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6171 {
6172 	return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
6173 	    TRUE, si);
6174 }
6175 
6176 static int
dissect_find_close_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si _U_)6177 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
6178     proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
6179 {
6180 	guint8  wc;
6181 	guint16 bc;
6182 	guint16 data_len;
6183 
6184 	WORD_COUNT;
6185 
6186 	/* reserved */
6187 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6188 	offset += 2;
6189 
6190 	BYTE_COUNT;
6191 
6192 	/* buffer format */
6193 	CHECK_BYTE_COUNT(1);
6194 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6195 	COUNT_BYTES(1);
6196 
6197 	/* data len */
6198 	CHECK_BYTE_COUNT(2);
6199 	data_len = tvb_get_ntohs(tvb, offset);
6200 	proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
6201 	COUNT_BYTES(2);
6202 
6203 	if (data_len != 0) {
6204 		CHECK_BYTE_COUNT(data_len);
6205 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
6206 		    data_len, ENC_NA);
6207 		COUNT_BYTES(data_len);
6208 	}
6209 
6210 	END_OF_SMB
6211 
6212 	return offset;
6213 }
6214 
6215 static const value_string locking_ol_vals[] = {
6216 	{0,	"Client is not holding oplock on this file"},
6217 	{1,	"Level 2 oplock currently held by client"},
6218 	{0, NULL}
6219 };
6220 
6221 static const true_false_string tfs_lock_type_large = {
6222 	"Large file locking format requested",
6223 	"Large file locking format not requested"
6224 };
6225 static const true_false_string tfs_lock_type_cancel = {
6226 	"Cancel outstanding lock request",
6227 	"Don't cancel outstanding lock request"
6228 };
6229 static const true_false_string tfs_lock_type_change = {
6230 	"Change lock type",
6231 	"Don't change lock type"
6232 };
6233 static const true_false_string tfs_lock_type_oplock = {
6234 	"This is an oplock break notification/response",
6235 	"This is not an oplock break notification/response"
6236 };
6237 static const true_false_string tfs_lock_type_shared = {
6238 	"This is a shared lock",
6239 	"This is an exclusive lock"
6240 };
6241 static int
dissect_locking_andx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6242 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6243 {
6244 	guint8      wc, cmd    = 0xff, lt = 0, ol = 0;
6245 	guint16     andxoffset = 0, un = 0, ln = 0, bc, fid, num_lock = 0, num_unlock = 0;
6246 	guint32     to;
6247 	proto_item *it         = NULL;
6248 	proto_tree *tr         = NULL;
6249 	int         old_offset = offset;
6250 	smb_locking_saved_info_t *ld = NULL;
6251 	static int * const locks[] = {
6252 		&hf_smb_lock_type_large,
6253 		&hf_smb_lock_type_cancel,
6254 		&hf_smb_lock_type_change,
6255 		&hf_smb_lock_type_oplock,
6256 		&hf_smb_lock_type_shared,
6257 		NULL
6258 	};
6259 
6260 	DISSECTOR_ASSERT(si);
6261 
6262 	WORD_COUNT;
6263 
6264 	/* next smb command */
6265 	cmd = tvb_get_guint8(tvb, offset);
6266 	if (cmd != 0xff) {
6267 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6268 	} else {
6269 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6270 	}
6271 	offset += 1;
6272 
6273 	/* reserved byte */
6274 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6275 	offset += 1;
6276 
6277 	/* andxoffset */
6278 	andxoffset = tvb_get_letohs(tvb, offset);
6279 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6280 	offset += 2;
6281 
6282 	/* fid */
6283 	fid = tvb_get_letohs(tvb, offset);
6284 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
6285 	offset += 2;
6286 
6287 	/* lock type */
6288 	lt = tvb_get_guint8(tvb, offset);
6289 	proto_tree_add_bitmask(tree, tvb, offset, hf_smb_lock_type, ett_smb_lock_type, locks, ENC_NA);
6290 	offset += 1;
6291 
6292 	/* oplock level */
6293 	ol = tvb_get_guint8(tvb, offset);
6294 	proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
6295 	offset += 1;
6296 
6297 	/* timeout */
6298 	to = tvb_get_letohl(tvb, offset);
6299 	proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
6300 	offset += 4;
6301 
6302 	/* number of unlocks */
6303 	un = tvb_get_letohs(tvb, offset);
6304 	num_unlock = un;
6305 	proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
6306 	offset += 2;
6307 
6308 	/* number of locks */
6309 	ln = tvb_get_letohs(tvb, offset);
6310 	num_lock = ln;
6311 	proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
6312 	offset += 2;
6313 
6314 	BYTE_COUNT;
6315 
6316 	/* store the locking data for the response */
6317 	if ((!pinfo->fd->visited) && si->sip) {
6318 		ld = wmem_new(wmem_file_scope(), smb_locking_saved_info_t);
6319 		ld->type	 = lt;
6320 		ld->oplock_level = ol;
6321 		ld->num_lock	 = num_lock;
6322 		ld->num_unlock	 = num_unlock;
6323 		ld->locks	 = NULL;
6324 		ld->unlocks	 = NULL;
6325 		si->sip->extra_info_type = SMB_EI_LOCKDATA;
6326 		si->sip->extra_info      = ld;
6327 	}
6328 
6329 	/* unlocks */
6330 	if (un) {
6331 		old_offset = offset;
6332 
6333 		tr = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb_unlocks, &it, "Unlocks");
6334 		while (un--) {
6335 			proto_tree *ltree_2;
6336 			if (lt&0x10) {
6337 				guint64 val;
6338 				guint16 lock_pid;
6339 				guint64 lock_offset;
6340 				guint64 lock_length;
6341 
6342 				/* large lock format */
6343 				ltree_2 = proto_tree_add_subtree(tr, tvb, offset, 20, ett_smb_unlock, NULL, "Unlock");
6344 
6345 				/* PID */
6346 				CHECK_BYTE_COUNT(2);
6347 				lock_pid = tvb_get_letohs(tvb, offset);
6348 				proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6349 				COUNT_BYTES(2);
6350 
6351 				/* 2 reserved bytes */
6352 				CHECK_BYTE_COUNT(2);
6353 				proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6354 				COUNT_BYTES(2);
6355 
6356 				/* offset */
6357 				CHECK_BYTE_COUNT(8);
6358 				val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
6359 				    | tvb_get_letohl(tvb, offset+4);
6360 				lock_offset = val;
6361 				proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
6362 				COUNT_BYTES(8);
6363 
6364 				/* length */
6365 				CHECK_BYTE_COUNT(8);
6366 				val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
6367 				    | tvb_get_letohl(tvb, offset+4);
6368 				lock_length = val;
6369 				proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
6370 				COUNT_BYTES(8);
6371 
6372 				/* remember the unlock for the reply */
6373 				if (ld) {
6374 					smb_lock_info_t *li;
6375 					li = wmem_new(wmem_file_scope(), smb_lock_info_t);
6376 					li->next = ld->unlocks;
6377 					ld->unlocks = li;
6378 					li->pid = lock_pid;
6379 					li->offset = lock_offset;
6380 					li->length = lock_length;
6381 				}
6382 			} else {
6383 				/* normal lock format */
6384 				ltree_2 = proto_tree_add_subtree(tr, tvb, offset, 10, ett_smb_unlock, NULL, "Unlock");
6385 
6386 				/* PID */
6387 				CHECK_BYTE_COUNT(2);
6388 				proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6389 				COUNT_BYTES(2);
6390 
6391 				/* offset */
6392 				CHECK_BYTE_COUNT(4);
6393 				proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6394 				COUNT_BYTES(4);
6395 
6396 				/* lock count */
6397 				CHECK_BYTE_COUNT(4);
6398 				proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6399 				COUNT_BYTES(4);
6400 			}
6401 		}
6402 		proto_item_set_len(it, offset-old_offset);
6403 		it = NULL;
6404 	}
6405 
6406 	/* locks */
6407 	if (ln) {
6408 		old_offset = offset;
6409 
6410 		tr = proto_tree_add_subtree(tree, tvb, offset, -1, ett_smb_locks, &it, "Locks");
6411 		while (ln--) {
6412 			proto_tree *ltree_2;
6413 			if (lt&0x10) {
6414 				guint64 val;
6415 				guint16 lock_pid;
6416 				guint64 lock_offset;
6417 				guint64 lock_length;
6418 
6419 				/* large lock format */
6420 				ltree_2 = proto_tree_add_subtree(tr, tvb, offset, 20, ett_smb_lock, NULL, "Lock");
6421 
6422 				/* PID */
6423 				CHECK_BYTE_COUNT(2);
6424 				lock_pid = tvb_get_letohs(tvb, offset);
6425 				proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6426 				COUNT_BYTES(2);
6427 
6428 				/* 2 reserved bytes */
6429 				CHECK_BYTE_COUNT(2);
6430 				proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6431 				COUNT_BYTES(2);
6432 
6433 				/* offset */
6434 				CHECK_BYTE_COUNT(8);
6435 				val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
6436 				    | tvb_get_letohl(tvb, offset+4);
6437 				lock_offset = val;
6438 				proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
6439 				COUNT_BYTES(8);
6440 
6441 				/* length */
6442 				CHECK_BYTE_COUNT(8);
6443 				val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
6444 				    | tvb_get_letohl(tvb, offset+4);
6445 				lock_length = val;
6446 				proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
6447 				COUNT_BYTES(8);
6448 
6449 				/* remember the lock for the reply */
6450 				if (ld) {
6451 					smb_lock_info_t *li;
6452 					li = wmem_new(wmem_file_scope(), smb_lock_info_t);
6453 					li->next = ld->locks;
6454 					ld->locks = li;
6455 					li->pid = lock_pid;
6456 					li->offset = lock_offset;
6457 					li->length = lock_length;
6458 				}
6459 			} else {
6460 				/* normal lock format */
6461 				ltree_2 = proto_tree_add_subtree(tr, tvb, offset, 10, ett_smb_lock, NULL, "Lock");
6462 
6463 				/* PID */
6464 				CHECK_BYTE_COUNT(2);
6465 				proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6466 				COUNT_BYTES(2);
6467 
6468 				/* offset */
6469 				CHECK_BYTE_COUNT(4);
6470 				proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6471 				COUNT_BYTES(4);
6472 
6473 				/* lock count */
6474 				CHECK_BYTE_COUNT(4);
6475 				proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6476 				COUNT_BYTES(4);
6477 			}
6478 		}
6479 		proto_item_set_len(it, offset-old_offset);
6480 		it = NULL;
6481 	}
6482 
6483 	END_OF_SMB
6484 
6485 	if (it != NULL) {
6486 		/*
6487 		 * We ran out of byte count in the middle of dissecting
6488 		 * the locks or the unlocks; set the site of the item
6489 		 * we were dissecting.
6490 		 */
6491 		proto_item_set_len(it, offset-old_offset);
6492 	}
6493 
6494 	if (cmd != 0xff) { 	/* there is an andX command */
6495 		if (andxoffset < offset) {
6496 			THROW(ReportedBoundsError);
6497 		}
6498 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6499 	}
6500 
6501 	return offset;
6502 }
6503 
6504 static int
dissect_locking_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6505 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6506 {
6507 	guint8      wc, cmd    = 0xff;
6508 	guint16     andxoffset = 0;
6509 	guint16     bc;
6510 
6511 	DISSECTOR_ASSERT(si);
6512 
6513 	/* print the lock info from the request */
6514 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_LOCKDATA)) {
6515 		smb_locking_saved_info_t *ld;
6516 		proto_item *litem = NULL;
6517 		proto_tree *ltree = NULL;
6518 
6519 		ld = (smb_locking_saved_info_t *)si->sip->extra_info;
6520 		if (ld != NULL) {
6521 			proto_tree *ltr;
6522 			smb_lock_info_t *li;
6523 			if (tree) {
6524 				litem = proto_tree_add_uint(tree, hf_smb_lock_type, tvb, 0, 0, ld->type);
6525 				proto_item_set_generated(litem);
6526 				ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
6527 
6528 				proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
6529 				proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
6530 				proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
6531 				proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
6532 				proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
6533 				proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
6534 				proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
6535 				proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
6536 
6537 				ltr = proto_tree_add_subtree(ltree, tvb, 0, 0, ett_smb_lock, NULL, "Locks");
6538 				li = ld->locks;
6539 				while (li) {
6540 					proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
6541 					proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
6542 					proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
6543 					li = li->next;
6544 				}
6545 				ltr = proto_tree_add_subtree(ltree, tvb, 0, 0, ett_smb_unlock, NULL, "Unlocks");
6546 				li = ld->unlocks;
6547 				while (li) {
6548 					proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
6549 					proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
6550 					proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
6551 					li = li->next;
6552 				}
6553 			}
6554 		}
6555 	}
6556 
6557 	WORD_COUNT;
6558 
6559 	/* next smb command */
6560 	cmd = tvb_get_guint8(tvb, offset);
6561 	if (cmd != 0xff) {
6562 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6563 	} else {
6564 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6565 	}
6566 	offset += 1;
6567 
6568 	/* reserved byte */
6569 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6570 	offset += 1;
6571 
6572 	/* andxoffset */
6573 	andxoffset = tvb_get_letohs(tvb, offset);
6574 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6575 	offset += 2;
6576 
6577 	BYTE_COUNT;
6578 
6579 	END_OF_SMB
6580 
6581 	if (cmd != 0xff) { 	/* there is an andX command */
6582 		if (andxoffset < offset) {
6583 			THROW(ReportedBoundsError);
6584 		}
6585 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6586 	}
6587 
6588 	return offset;
6589 }
6590 
6591 
6592 const value_string oa_open_vals[] = {
6593 	{ 0,		"No action taken?"},
6594 	{ 1,		"The file existed and was opened"},
6595 	{ 2,		"The file did not exist but was created"},
6596 	{ 3,		"The file existed and was truncated"},
6597 	{ 0x8001,	"The file existed and was opened, and an OpLock was granted"},
6598 	{ 0x8002,	"The file did not exist but was created, and an OpLock was granted"},
6599 	{ 0x8003,	"The file existed and was truncated, and an OpLock was granted"},
6600 	{0,	NULL}
6601 };
6602 static const true_false_string tfs_oa_lock = {
6603 	"File is currently opened only by this user",
6604 	"File is opened by another user (or mode not supported by server)"
6605 };
6606 static int
dissect_open_action(tvbuff_t * tvb,proto_tree * parent_tree,int offset)6607 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6608 {
6609 	static int * const flags[] = {
6610 		&hf_smb_open_action_lock,
6611 		&hf_smb_open_action_open,
6612 		NULL
6613 	};
6614 
6615 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_open_action, ett_smb_open_action, flags, ENC_LITTLE_ENDIAN);
6616 	offset += 2;
6617 
6618 	return offset;
6619 }
6620 
6621 static const true_false_string tfs_open_flags_add_info = {
6622 	"Additional information requested",
6623 	"Additional information not requested"
6624 };
6625 static const true_false_string tfs_open_flags_ex_oplock = {
6626 	"Exclusive oplock requested",
6627 	"Exclusive oplock not requested"
6628 };
6629 static const true_false_string tfs_open_flags_batch_oplock = {
6630 	"Batch oplock requested",
6631 	"Batch oplock not requested"
6632 };
6633 static const true_false_string tfs_open_flags_ealen = {
6634 	"Total length of EAs requested",
6635 	"Total length of EAs not requested"
6636 };
6637 static int
dissect_open_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int bm)6638 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
6639 {
6640 	guint16     mask;
6641 	proto_item *item;
6642 	proto_tree *tree;
6643 
6644 	mask = tvb_get_letohs(tvb, offset);
6645 
6646 	if (parent_tree) {
6647 		item = proto_tree_add_item(parent_tree, hf_smb_open_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6648 		tree = proto_item_add_subtree(item, ett_smb_open_flags);
6649 
6650 		if (bm&0x0001) {
6651 			proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
6652 				tvb, offset, 2, mask);
6653 		}
6654 		if (bm&0x0002) {
6655 			proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
6656 				tvb, offset, 2, mask);
6657 		}
6658 		if (bm&0x0004) {
6659 			proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
6660 				tvb, offset, 2, mask);
6661 		}
6662 		if (bm&0x0008) {
6663 			proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
6664 				tvb, offset, 2, mask);
6665 		}
6666 	}
6667 
6668 	offset += 2;
6669 
6670 	return offset;
6671 }
6672 
6673 /* [MS-CIFS].pdf 2.2.4.64.2 provides the last two file types, however
6674    [MS-SMB].PDF 2.2.4.9.2 elides value 4, Character mode device.  */
6675 static const value_string filetype_vals[] = {
6676 	{ 0,		"Disk file or directory"},
6677 	{ 1,		"Named pipe in byte mode"},
6678 	{ 2,		"Named pipe in message mode"},
6679 	{ 3,		"Spooled printer"},
6680 	{ 4,		"Character mode device"},
6681 	{ 0xFFFF,	"Unknown file type"},
6682 	{0, NULL}
6683 };
6684 static int
dissect_open_andx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6685 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6686 {
6687 	guint8      wc, cmd    = 0xff;
6688 	guint16     andxoffset = 0, bc;
6689 	guint32     to;
6690 	int         fn_len;
6691 	const char *fn;
6692 
6693 	DISSECTOR_ASSERT(si);
6694 
6695 	WORD_COUNT;
6696 
6697 	/* next smb command */
6698 	cmd = tvb_get_guint8(tvb, offset);
6699 	if (cmd != 0xff) {
6700 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6701 	} else {
6702 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6703 	}
6704 	offset += 1;
6705 
6706 	/* reserved byte */
6707 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6708 	offset += 1;
6709 
6710 	/* andxoffset */
6711 	andxoffset = tvb_get_letohs(tvb, offset);
6712 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6713 	offset += 2;
6714 
6715 	/* open flags */
6716 	offset = dissect_open_flags(tvb, tree, offset, 0x0007);
6717 
6718 	/* desired access */
6719 	offset = dissect_access(tvb, tree, offset, hf_smb_desired_access);
6720 
6721 	/* Search Attributes */
6722 	offset = dissect_search_attributes(tvb, tree, offset);
6723 
6724 	/* File Attributes */
6725 	offset = dissect_file_attributes(tvb, tree, offset);
6726 
6727 	/* creation time */
6728 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
6729 
6730 	/* open function */
6731 	offset = dissect_open_function(tvb, tree, offset);
6732 
6733 	/* allocation size */
6734 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6735 	offset += 4;
6736 
6737 	/* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
6738 	to = tvb_get_letohl(tvb, offset);
6739 	proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
6740 	offset += 4;
6741 
6742 	/* 4 reserved bytes */
6743 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
6744 	offset += 4;
6745 
6746 	BYTE_COUNT;
6747 
6748 	/* file name */
6749 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
6750 		FALSE, FALSE, &bc);
6751 	if (fn == NULL)
6752 		goto endofcommand;
6753 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6754 		fn);
6755 	COUNT_BYTES(fn_len);
6756 
6757 	/* Copied this portion of code from create_andx_request
6758 	   to guarantee that fsi and si->sip are always correctly filled out */
6759 	if ((!pinfo->fd->visited) && si->sip && fn) {
6760 		smb_fid_saved_info_t *fsi;
6761 
6762 		fsi = wmem_new0(wmem_file_scope(), smb_fid_saved_info_t);
6763 		fsi->filename = wmem_strdup(wmem_file_scope(), fn);
6764 
6765 		si->sip->extra_info_type = SMB_EI_FILEDATA;
6766 		si->sip->extra_info = fsi;
6767 	}
6768 
6769 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
6770 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
6771 
6772 	END_OF_SMB
6773 
6774 	if (cmd != 0xff) { 	/* there is an andX command */
6775 		if (andxoffset < offset) {
6776 			THROW(ReportedBoundsError);
6777 		}
6778 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6779 	}
6780 
6781 	return offset;
6782 }
6783 
6784 static const true_false_string tfs_ipc_state_nonblocking = {
6785 	"Reads/writes return immediately if no data available",
6786 	"Reads/writes block if no data available"
6787 };
6788 static const value_string ipc_state_endpoint_vals[] = {
6789 	{ 0,		"Consumer end of pipe"},
6790 	{ 1,		"Server end of pipe"},
6791 	{0,	NULL}
6792 };
6793 static const value_string ipc_state_pipe_type_vals[] = {
6794 	{ 0,		"Byte stream pipe"},
6795 	{ 1,		"Message pipe"},
6796 	{0,	NULL}
6797 };
6798 static const value_string ipc_state_read_mode_vals[] = {
6799 	{ 0,		"Read pipe as a byte stream"},
6800 	{ 1,		"Read messages from pipe"},
6801 	{0,	NULL}
6802 };
6803 
6804 int
dissect_ipc_state(tvbuff_t * tvb,proto_tree * parent_tree,int offset,gboolean setstate_flag)6805 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset, gboolean setstate_flag)
6806 {
6807 	static int * const setstate_flags[] = {
6808 		&hf_smb_ipc_state_nonblocking,
6809 		&hf_smb_ipc_state_read_mode,
6810 		NULL
6811 	};
6812 	static int * const not_setstate_flags[] = {
6813 		&hf_smb_ipc_state_nonblocking,
6814 		&hf_smb_ipc_state_endpoint,
6815 		&hf_smb_ipc_state_pipe_type,
6816 		&hf_smb_ipc_state_read_mode,
6817 		&hf_smb_ipc_state_icount,
6818 		NULL
6819 	};
6820 
6821 	if (!setstate_flag) {
6822 		proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_ipc_state, ett_smb_ipc_state, not_setstate_flags, ENC_LITTLE_ENDIAN);
6823 	} else {
6824 		proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_ipc_state, ett_smb_ipc_state, setstate_flags, ENC_LITTLE_ENDIAN);
6825 	}
6826 	offset += 2;
6827 
6828 	return offset;
6829 }
6830 
6831 static int
dissect_open_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6832 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6833 {
6834 	guint8          wc, cmd    = 0xff;
6835 	guint16         andxoffset = 0, bc;
6836 	guint16         fid;
6837 	guint16         ftype;
6838 	guint16         fattr;
6839 	smb_fid_info_t *fid_info   = NULL;
6840 	gboolean        isdir      = FALSE;
6841 
6842 	WORD_COUNT;
6843 
6844 	/* next smb command */
6845 	cmd = tvb_get_guint8(tvb, offset);
6846 	if (cmd != 0xff) {
6847 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6848 	} else {
6849 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6850 	}
6851 	offset += 1;
6852 
6853 	/* reserved byte */
6854 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6855 	offset += 1;
6856 
6857 	/* andxoffset */
6858 	andxoffset = tvb_get_letohs(tvb, offset);
6859 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6860 	offset += 2;
6861 
6862 	/* fid */
6863 	fid = tvb_get_letohs(tvb, offset);
6864 	/* we add fid_info= to this call so that we save the result */
6865 	fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
6866 
6867 	offset += 2;
6868 
6869 	/* File Attributes */
6870 	fattr = tvb_get_letohs(tvb, offset);
6871 	isdir = fattr & SMB_FILE_ATTRIBUTE_DIRECTORY;
6872 	offset = dissect_file_attributes(tvb, tree, offset);
6873 
6874 	/* last write time */
6875 	offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6876 
6877 	/* File Size */
6878 	/* We store the file_size in the fid_info */
6879 	if (fid_info) {
6880 		fid_info->end_of_file = (guint64) tvb_get_letohl(tvb, offset);
6881 	}
6882 	proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6883 	offset += 4;
6884 
6885 	/* granted access */
6886 	offset = dissect_access(tvb, tree, offset, hf_smb_granted_access);
6887 
6888 	/* File Type */
6889 	ftype = tvb_get_letohs(tvb, offset);
6890 	proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6891 	offset += 2;
6892 	/* Copied from dissect_nt_create_andx_response
6893 	   Try to remember the type of this fid so that we can dissect
6894 	   any future security descriptor (access mask) properly
6895 	*/
6896 	if (fid_info) {
6897 		fid_info->type = SMB_FID_TYPE_UNKNOWN;
6898 	}
6899 	if (ftype == 0) {
6900 		if (isdir == 0) {
6901 			if (fid_info) {
6902 				fid_info->type = SMB_FID_TYPE_FILE;
6903 			}
6904 		} else {
6905 			if (fid_info) {
6906 				fid_info->type = SMB_FID_TYPE_DIR;
6907 			}
6908 		}
6909 	}
6910 	if ((ftype == 2) || (ftype == 1)) {
6911 		if (fid_info) {
6912 			fid_info->type = SMB_FID_TYPE_PIPE;
6913 		}
6914 	}
6915 
6916 	/* IPC State */
6917 	offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6918 
6919 	/* open_action */
6920 	offset = dissect_open_action(tvb, tree, offset);
6921 
6922 	/* server fid */
6923 	proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6924 	offset += 4;
6925 
6926 	/* 2 reserved bytes */
6927 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6928 	offset += 2;
6929 
6930 	/* [MS-SMB] 2.2.4.1.2 Server Response Extensions */
6931 	if (wc == 19) {
6932 		proto_tree *tr = NULL;
6933 
6934 		tr = proto_tree_add_subtree(tree, tvb, offset, 4,
6935 			ett_smb_nt_access_mask, NULL, "Maximal Access Rights");
6936 		offset = dissect_smb_access_mask(tvb, tr, offset);
6937 
6938 		tr = proto_tree_add_subtree(tree, tvb, offset, 4,
6939 			ett_smb_nt_access_mask, NULL, "Guest Maximal Access Rights");
6940 		offset = dissect_smb_access_mask(tvb, tr, offset);
6941 	}
6942 
6943 	BYTE_COUNT;
6944 
6945 	END_OF_SMB
6946 
6947 	if (cmd != 0xff) { 	/* there is an andX command */
6948 		if (andxoffset < offset) {
6949 			THROW(ReportedBoundsError);
6950 		}
6951 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6952 	}
6953 
6954 	return offset;
6955 }
6956 
6957 static int
dissect_read_andx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)6958 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6959 {
6960 	guint8        wc, cmd               = 0xff;
6961 	guint16       andxoffset            = 0, bc, maxcnt_low;
6962 	guint32       maxcnt_high;
6963 	guint32       maxcnt                = 0;
6964 	guint32       offsetlow, offsethigh = 0;
6965 	guint64       ofs;
6966 	unsigned int  fid;
6967 	rw_info_t    *rwi                   = NULL;
6968 
6969 
6970 	DISSECTOR_ASSERT(si);
6971 
6972 	WORD_COUNT;
6973 
6974 	/* next smb command */
6975 	cmd = tvb_get_guint8(tvb, offset);
6976 	if (cmd != 0xff) {
6977 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6978 	} else {
6979 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6980 	}
6981 	offset += 1;
6982 
6983 	/* reserved byte */
6984 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6985 	offset += 1;
6986 
6987 	/* andxoffset */
6988 	andxoffset = tvb_get_letohs(tvb, offset);
6989 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6990 	offset += 2;
6991 
6992 	/* fid */
6993 	fid = tvb_get_letohs(tvb, offset);
6994 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
6995 	offset += 2;
6996 
6997 	/* offset */
6998 	offsetlow = tvb_get_letohl(tvb, offset);
6999 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7000 	offset += 4;
7001 
7002 	/* max count low */
7003 	maxcnt_low = tvb_get_letohs(tvb, offset);
7004 	proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
7005 	offset += 2;
7006 
7007 	/* min count */
7008 	proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7009 	offset += 2;
7010 
7011 	/*
7012 	 * max count high
7013 	 *
7014 	 * XXX - we should really only do this in case we have seen
7015 	 * LARGE FILE being negotiated.  Unfortunately, we might not
7016 	 * have seen the negotiation phase in the capture....
7017 	 *
7018 	 * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
7019 	 * it's 32 bits, but the description says "High 16 bits of
7020 	 * MaxCount if CAP_LARGE_READX".
7021 	 *
7022 	 * The SMB File Sharing Protocol Extensions Version 2.0,
7023 	 * Document Version 3.3 spec doesn't speak of an extra 16
7024 	 * bits in max count, but it does show a 32-bit timeout
7025 	 * after the min count field.
7026 	 *
7027 	 * The Microsoft [MS-SMB] spec shows it as a ULONG named
7028 	 * Timeout_or_MaxCountHigh, which is
7029 	 *
7030 	 *	...extended to be treated as a union of a 32-bit
7031 	 *	Timeout field and a 16-bit MaxCountHigh field.
7032 	 *	When reading from a regular file, the field
7033 	 *	MUST be interpreted as MaxCountHigh and the
7034 	 *	two unused bytes MUST be zero.  When reading from
7035 	 *	a name[sic] pipe or I/O device, the field MUST
7036 	 *	be interpreted as Timeout.
7037 	 *
7038 	 * Timeout is a timeout in milliseconds, with 0xffffffff
7039 	 * and 0xfffffffe having special meaning.
7040 	 *
7041 	 * MaxCountHigh is 16 bits of the MaxCountHigh value
7042 	 * followed by 16 bits of Reserved.
7043 	 *
7044 	 * We fetch and display it as 32 bits for now.
7045 	 *
7046 	 * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
7047 	 * bytes and we just ignore it.
7048 	 */
7049 	maxcnt_high = tvb_get_letohl(tvb, offset);
7050 	if (maxcnt_high == 0xffffffff) {
7051 		maxcnt_high = 0;
7052 	} else {
7053 		proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
7054 	}
7055 
7056 	offset += 4;
7057 
7058 	maxcnt = maxcnt_high;
7059 	maxcnt = (maxcnt<<16) | maxcnt_low;
7060 
7061 	/* remaining */
7062 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7063 	offset += 2;
7064 
7065 	if (wc == 12) {
7066 		/* high offset */
7067 		offsethigh = tvb_get_letohl(tvb, offset);
7068 		proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7069 		offset += 4;
7070 	}
7071 
7072 	ofs = offsethigh;
7073 	ofs = (ofs<<32) | offsetlow;
7074 
7075 	col_append_fstr(pinfo->cinfo, COL_INFO,
7076 				", %u byte%s at offset %" G_GINT64_MODIFIER "u",
7077 				maxcnt, (maxcnt == 1) ? "" : "s", ofs);
7078 
7079 	/* save the offset/len for this transaction */
7080 	if (si->sip && !pinfo->fd->visited) {
7081 		rwi = wmem_new(wmem_file_scope(), rw_info_t);
7082 		rwi->offset = ofs;
7083 		rwi->len = maxcnt;
7084 		rwi->fid = fid;
7085 
7086 		si->sip->extra_info_type = SMB_EI_RWINFO;
7087 		si->sip->extra_info = rwi;
7088 	}
7089 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
7090 		rwi = (rw_info_t *)si->sip->extra_info;
7091 	}
7092 	if (rwi) {
7093 		proto_item *it;
7094 
7095 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
7096 
7097 		proto_item_set_generated(it);
7098 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
7099 		proto_item_set_generated(it);
7100 	}
7101 
7102 	BYTE_COUNT;
7103 
7104 	END_OF_SMB
7105 
7106 	if (cmd != 0xff) { 	/* there is an andX command */
7107 		if (andxoffset < offset) {
7108 			THROW(ReportedBoundsError);
7109 		}
7110 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7111 	}
7112 
7113 	return offset;
7114 }
7115 
7116 static int
dissect_read_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)7117 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7118 {
7119 	guint8      wc, cmd    = 0xff;
7120 	guint16     andxoffset = 0, bc, datalen_low, dataoffset = 0;
7121 	guint32     datalen    = 0, datalen_high;
7122 	rw_info_t  *rwi        = NULL;
7123 	guint16 fid            = 0; /* was int fid = 0; */
7124 
7125 	guint32 tvblen;
7126 
7127 	DISSECTOR_ASSERT(si);
7128 
7129 	WORD_COUNT;
7130 
7131 	/* next smb command */
7132 	cmd = tvb_get_guint8(tvb, offset);
7133 	if (cmd != 0xff) {
7134 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7135 	} else {
7136 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7137 	}
7138 	offset += 1;
7139 
7140 	/* reserved byte */
7141 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7142 	offset += 1;
7143 
7144 	/* andxoffset */
7145 	andxoffset = tvb_get_letohs(tvb, offset);
7146 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7147 	offset += 2;
7148 
7149 	/* If we have seen the request, then print which FID this refers to */
7150 	/* first check if we have seen the request */
7151 	if ((si->sip != NULL) && (si->sip->frame_req > 0) && (si->sip->extra_info_type == SMB_EI_FID)) {
7152 		fid = GPOINTER_TO_INT(si->sip->extra_info);
7153 		dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE, si);
7154 	}
7155 
7156 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
7157 		rwi = (rw_info_t *)si->sip->extra_info;
7158 	}
7159 	if (rwi) {
7160 		proto_item *it;
7161 
7162 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
7163 
7164 		proto_item_set_generated(it);
7165 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
7166 		proto_item_set_generated(it);
7167 
7168 		/* we need the fid for the call to dcerpc below */
7169 		fid = rwi->fid;
7170 	}
7171 
7172 	/* remaining */
7173 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7174 	offset += 2;
7175 
7176 	/* data compaction mode */
7177 	proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7178 	offset += 2;
7179 
7180 	/* 2 reserved bytes */
7181 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
7182 	offset += 2;
7183 
7184 	/* data len low */
7185 	datalen_low = tvb_get_letohs(tvb, offset);
7186 	proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
7187 	offset += 2;
7188 
7189 	/* data offset */
7190 	dataoffset = tvb_get_letohs(tvb, offset);
7191 	proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
7192 	offset += 2;
7193 
7194 	/*
7195 	 * XXX - the SNIA SMB spec says this is a USHORT, not a
7196 	 * ULONG.
7197 	 *
7198 	 * XXX - we should really only do this in case we have seen
7199 	 * LARGE FILE being negotiated.  Unfortunately, we might not
7200 	 * have seen the negotiation phase in the capture....
7201 	 */
7202 	/* data length high */
7203 	datalen_high = tvb_get_letohl(tvb, offset);
7204 	if (datalen_high == 0xffffffff) {
7205 		datalen_high = 0;
7206 	} else {
7207 		proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
7208 	}
7209 	offset += 4;
7210 
7211 	datalen = datalen_high;
7212 	datalen = (datalen<<16) | datalen_low;
7213 
7214 
7215 	col_append_fstr(pinfo->cinfo, COL_INFO,
7216 				", %u byte%s", datalen,
7217 				(datalen == 1) ? "" : "s");
7218 
7219 
7220 	/* 6 reserved bytes */
7221 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, ENC_NA);
7222 	offset += 6;
7223 
7224 	BYTE_COUNT;
7225 
7226 	/* file data, might be DCERPC on a pipe */
7227 	if (bc) {
7228 		offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
7229 		    top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid, si);
7230 		bc = 0;
7231 	}
7232 
7233 	/* feed the export object tap listener */
7234 	tvblen = tvb_reported_length_remaining(tvb, dataoffset);
7235 	if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
7236 		feed_eo_smb(SMB_COM_READ_ANDX, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
7237 	}
7238 
7239 	END_OF_SMB
7240 
7241 	if (cmd != 0xff) {   /* there is an andX command */
7242 		if (andxoffset < offset) {
7243 			THROW(ReportedBoundsError);
7244 		}
7245 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7246 	}
7247 
7248 	return offset;
7249 }
7250 
7251 static int
dissect_write_andx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)7252 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7253 {
7254 	guint8          wc, cmd               = 0xff;
7255 	guint16         andxoffset            = 0, bc, dataoffset = 0, datalen_low, datalen_high;
7256 	guint32         offsetlow, offsethigh = 0;
7257 	guint64         ofs;
7258 	guint32         datalen               = 0;
7259 	guint16 fid                           = 0; /* was unsigned int fid = 0; */
7260 	guint16         mode                  = 0;
7261 	rw_info_t      *rwi                   = NULL;
7262 
7263 	guint32		tvblen;
7264 
7265 	DISSECTOR_ASSERT(si);
7266 
7267 	WORD_COUNT;
7268 
7269 	/* next smb command */
7270 	cmd = tvb_get_guint8(tvb, offset);
7271 	if (cmd != 0xff) {
7272 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7273 	} else {
7274 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7275 	}
7276 	offset += 1;
7277 
7278 	/* reserved byte */
7279 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7280 	offset += 1;
7281 
7282 	/* andxoffset */
7283 	andxoffset = tvb_get_letohs(tvb, offset);
7284 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7285 	offset += 2;
7286 
7287 	/* fid */
7288 	fid = tvb_get_letohs(tvb, offset);
7289 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
7290 	offset += 2;
7291 
7292 	/* offset */
7293 	offsetlow = tvb_get_letohl(tvb, offset);
7294 	proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7295 	offset += 4;
7296 
7297 	/* reserved */
7298 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7299 	offset += 4;
7300 
7301 	/* mode */
7302 	mode = tvb_get_letohs(tvb, offset);
7303 	offset = dissect_write_mode(tvb, tree, offset, 0x000f);
7304 
7305 	/* remaining */
7306 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7307 	offset += 2;
7308 
7309 	/*
7310 	 * XXX - we should really only do this in case we have seen
7311 	 * LARGE FILE being negotiated.  Unfortunately, we might not
7312 	 * have seen the negotiation phase in the capture....
7313 	 */
7314 	/* data length high */
7315 	datalen_high = tvb_get_letohs(tvb, offset);
7316 	proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
7317 	offset += 2;
7318 
7319 	/* data len low */
7320 	datalen_low = tvb_get_letohs(tvb, offset);
7321 	proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
7322 	offset += 2;
7323 
7324 	datalen = datalen_high;
7325 	datalen = (datalen<<16) | datalen_low;
7326 
7327 	/* data offset */
7328 	dataoffset = tvb_get_letohs(tvb, offset);
7329 	proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
7330 	offset += 2;
7331 
7332 	if (wc == 14) {
7333 		/* high offset */
7334 		offsethigh = tvb_get_letohl(tvb, offset);
7335 		proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7336 		offset += 4;
7337 	}
7338 
7339 	ofs = offsethigh;
7340 	ofs = (ofs<<32) | offsetlow;
7341 
7342 	col_append_fstr(pinfo->cinfo, COL_INFO,
7343 				", %u byte%s at offset %" G_GINT64_MODIFIER "u",
7344 				datalen, (datalen == 1) ? "" : "s", ofs);
7345 
7346 	/* save the offset/len for this transaction */
7347 	if (si->sip && !pinfo->fd->visited) {
7348 		rwi	    = wmem_new(wmem_file_scope(), rw_info_t);
7349 		rwi->offset = ofs;
7350 		rwi->len    = datalen;
7351 		rwi->fid    = fid;
7352 
7353 		si->sip->extra_info_type = SMB_EI_RWINFO;
7354 		si->sip->extra_info = rwi;
7355 	}
7356 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
7357 		rwi = (rw_info_t *)si->sip->extra_info;
7358 	}
7359 	if (rwi) {
7360 		proto_item *it;
7361 
7362 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
7363 
7364 		proto_item_set_generated(it);
7365 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
7366 		proto_item_set_generated(it);
7367 	}
7368 
7369 
7370 	BYTE_COUNT;
7371 
7372 	/* if both the MessageStart and the  WriteRawNamedPipe flags are set
7373 	   the first two bytes of the payload is the length of the data.
7374 	   Assume that all WriteAndX PDUs that have MESSAGE_START set to
7375 	   be over the IPC$ share and thus they all transport DCERPC.
7376 	   (if we didn't already know that from the TreeConnect call)
7377 	*/
7378 	if (mode&WRITE_MODE_MESSAGE_START) {
7379 		if (mode&WRITE_MODE_RAW) {
7380 			proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7381 			offset += 2;
7382 			dataoffset += 2;
7383 			bc -= 2;
7384 			datalen -= 2;
7385 		}
7386 		if (!pinfo->fd->visited) {
7387 			/* In case we did not see the TreeConnect call,
7388 			   store this TID here as well as a IPC TID
7389 			   so we know that future Read/Writes to this
7390 			   TID is (probably) DCERPC.
7391 			*/
7392 			if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
7393 				g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7394 			}
7395 			g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7396 		}
7397 		if (si->sip) {
7398 			si->sip->flags |= SMB_SIF_TID_IS_IPC;
7399 		}
7400 	}
7401 
7402 	/* file data, might be DCERPC on a pipe */
7403 	if (bc != 0) {
7404 		offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
7405 		    top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid, si);
7406 		bc = 0;
7407 	}
7408 
7409 	/* feed the export object tap listener */
7410 	tvblen = tvb_reported_length_remaining(tvb, dataoffset);
7411 	if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
7412 		feed_eo_smb(SMB_COM_WRITE_ANDX, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
7413 	}
7414 
7415 	END_OF_SMB
7416 
7417 	if (cmd != 0xff) { 	/* there is an andX command */
7418 		if (andxoffset < offset) {
7419 			THROW(ReportedBoundsError);
7420 		}
7421 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7422 	}
7423 
7424 	return offset;
7425 }
7426 
7427 static int
dissect_write_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)7428 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7429 {
7430 	guint8      wc, cmd    = 0xff;
7431 	guint16     andxoffset = 0, bc, count_low, count_high;
7432 	guint32     count      = 0;
7433 	rw_info_t  *rwi        = NULL;
7434 
7435 	DISSECTOR_ASSERT(si);
7436 
7437 	WORD_COUNT;
7438 
7439 	/* next smb command */
7440 	cmd = tvb_get_guint8(tvb, offset);
7441 	if (cmd != 0xff) {
7442 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7443 	} else {
7444 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7445 	}
7446 	offset += 1;
7447 
7448 	/* reserved byte */
7449 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7450 	offset += 1;
7451 
7452 	/* andxoffset */
7453 	andxoffset = tvb_get_letohs(tvb, offset);
7454 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7455 	offset += 2;
7456 
7457 
7458 	if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
7459 		rwi = (rw_info_t *)si->sip->extra_info;
7460 	}
7461 	if (rwi) {
7462 		proto_item *it;
7463 
7464 		it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
7465 
7466 		proto_item_set_generated(it);
7467 		it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
7468 		proto_item_set_generated(it);
7469 	}
7470 
7471 
7472 	/* write count low */
7473 	count_low = tvb_get_letohs(tvb, offset);
7474 	proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
7475 	offset += 2;
7476 
7477 	/* remaining */
7478 	proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7479 	offset += 2;
7480 
7481 	/* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
7482 	/* write count high */
7483 	count_high = tvb_get_letohs(tvb, offset);
7484 	proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
7485 	offset += 2;
7486 
7487 	count = count_high;
7488 	count = (count<<16) | count_low;
7489 
7490 	col_append_fstr(pinfo->cinfo, COL_INFO,
7491 				", %u byte%s", count,
7492 				(count == 1) ? "" : "s");
7493 
7494 	/* 2 reserved bytes */
7495 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
7496 	offset += 2;
7497 
7498 	BYTE_COUNT;
7499 
7500 	END_OF_SMB
7501 
7502 	if (cmd != 0xff) { 	/* there is an andX command */
7503 		if (andxoffset < offset) {
7504 			THROW(ReportedBoundsError);
7505 		}
7506 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7507 	}
7508 
7509 	return offset;
7510 }
7511 
7512 
7513 static const true_false_string tfs_setup_action_guest = {
7514 	"Logged in as GUEST",
7515 	"Not logged in as GUEST"
7516 };
7517 static int
dissect_setup_action(tvbuff_t * tvb,proto_tree * parent_tree,int offset)7518 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7519 {
7520 	static int * const flags[] = {
7521 		&hf_smb_setup_action_guest,
7522 		NULL
7523 	};
7524 
7525 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_setup_action, ett_smb_setup_action, flags, ENC_LITTLE_ENDIAN);
7526 	offset += 2;
7527 
7528 	return offset;
7529 }
7530 
7531 
7532 static int
dissect_session_setup_andx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)7533 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7534 {
7535 	guint8      wc, cmd        = 0xff;
7536 	guint16     bc;
7537 	guint16     andxoffset     = 0;
7538 	int         an_len;
7539 	const char *an;
7540 	int         dn_len;
7541 	const char *dn;
7542 	guint16     pwlen          = 0;
7543 	guint16     sbloblen       = 0, sbloblen_short;
7544 	guint16     apwlen         = 0, upwlen = 0;
7545 	gboolean    unicodeflag;
7546 	static int  ntlmssp_tap_id = 0;
7547 	const ntlmssp_header_t *ntlmssph;
7548 
7549 	if (!ntlmssp_tap_id) {
7550 		GString *error_string;
7551 		/* We don't specify any callbacks at all.
7552 		 * Instead we manually fetch the tapped data after the
7553 		 * security blob has been fully dissected and before
7554 		 * we exit from this dissector.
7555 		 */
7556 		error_string = register_tap_listener("ntlmssp", NULL, NULL,
7557 		    TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL, NULL);
7558 		if (!error_string) {
7559 			ntlmssp_tap_id = find_tap_id("ntlmssp");
7560 		} else {
7561 			g_string_free(error_string, TRUE);
7562 		}
7563 	}
7564 
7565 	DISSECTOR_ASSERT(si);
7566 
7567 	WORD_COUNT;
7568 
7569 	/* next smb command */
7570 	cmd = tvb_get_guint8(tvb, offset);
7571 	if (cmd != 0xff) {
7572 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7573 	} else {
7574 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7575 	}
7576 	offset += 1;
7577 
7578 	/* reserved byte */
7579 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7580 	offset += 1;
7581 
7582 	/* andxoffset */
7583 	andxoffset = tvb_get_letohs(tvb, offset);
7584 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7585 	offset += 2;
7586 
7587 	/* Maximum Buffer Size */
7588 	proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7589 	offset += 2;
7590 
7591 	/* Maximum Multiplex Count */
7592 	proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7593 	offset += 2;
7594 
7595 	/* VC Number */
7596 	proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7597 	offset += 2;
7598 
7599 	/* session key */
7600 	proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7601 	offset += 4;
7602 
7603 	switch (wc) {
7604 	case 10:
7605 		/* password length, ASCII*/
7606 		pwlen = tvb_get_letohs(tvb, offset);
7607 		proto_tree_add_uint(tree, hf_smb_password_len,
7608 			tvb, offset, 2, pwlen);
7609 		offset += 2;
7610 
7611 		/* 4 reserved bytes */
7612 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7613 		offset += 4;
7614 
7615 		break;
7616 
7617 	case 12:
7618 		/* security blob length */
7619 		sbloblen = tvb_get_letohs(tvb, offset);
7620 		proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7621 		offset += 2;
7622 
7623 		/* 4 reserved bytes */
7624 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7625 		offset += 4;
7626 
7627 		/* capabilities */
7628 		dissect_negprot_capabilities(tvb, tree, offset);
7629 		offset += 4;
7630 
7631 		break;
7632 
7633 	case 13:
7634 		/* password length, ANSI*/
7635 		apwlen = tvb_get_letohs(tvb, offset);
7636 		proto_tree_add_uint(tree, hf_smb_ansi_password_len,
7637 			tvb, offset, 2, apwlen);
7638 		offset += 2;
7639 
7640 		/* password length, Unicode*/
7641 		upwlen = tvb_get_letohs(tvb, offset);
7642 		proto_tree_add_uint(tree, hf_smb_unicode_password_len,
7643 			tvb, offset, 2, upwlen);
7644 		offset += 2;
7645 
7646 		/* 4 reserved bytes */
7647 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7648 		offset += 4;
7649 
7650 		/* capabilities */
7651 		dissect_negprot_capabilities(tvb, tree, offset);
7652 		offset += 4;
7653 
7654 		break;
7655 	}
7656 
7657 	BYTE_COUNT;
7658 
7659 	if (wc == 12) {
7660 		proto_item *blob_item;
7661 
7662 		/* security blob */
7663 		/* If it runs past the end of the captured data, don't
7664 		 * try to put all of it into the protocol tree as the
7665 		 * raw security blob; we might get an exception on
7666 		 * short frames and then we will not see anything at all
7667 		 * of the security blob.
7668 		 */
7669 		sbloblen_short = sbloblen;
7670 		if (sbloblen_short > tvb_reported_length_remaining(tvb, offset)) {
7671 			sbloblen_short = tvb_reported_length_remaining(tvb, offset);
7672 		}
7673 		blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7674 						tvb, offset, sbloblen_short,
7675 						ENC_NA);
7676 
7677 		/* As an optimization, because Windows is perverse,
7678 		   we check to see if NTLMSSP is the first part of the
7679 		   blob, and if so, call the NTLMSSP dissector,
7680 		   otherwise we call the GSS-API dissector. This is because
7681 		   Windows can request RAW NTLMSSP, but will happily handle
7682 		   a client that wraps NTLMSSP in SPNEGO
7683 		*/
7684 
7685 		if (sbloblen) {
7686 			tvbuff_t *blob_tvb;
7687 			proto_tree *blob_tree;
7688 
7689 			blob_tree = proto_item_add_subtree(blob_item,
7690 							   ett_smb_secblob);
7691 			CHECK_BYTE_COUNT(sbloblen);
7692 
7693 			/*
7694 			 * Set the reported length of this to the reported
7695 			 * length of the blob, rather than the amount of
7696 			 * data available from the blob, so that we'll
7697 			 * throw the right exception if it's too short.
7698 			 */
7699 			blob_tvb = tvb_new_subset_length_caplen(tvb, offset, sbloblen_short,
7700 						  sbloblen);
7701 
7702 			if (si && si->ct && si->ct->raw_ntlmssp &&
7703 			    (tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)) {
7704 			  call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7705 					 blob_tree);
7706 
7707 			}
7708 			else {
7709 			  call_dissector(gssapi_handle, blob_tvb,
7710 					 pinfo, blob_tree);
7711 			}
7712 
7713 			/* If we have found a uid->acct_name mapping, store it */
7714 			if (!pinfo->fd->visited && si->sip) {
7715 				int idx = 0;
7716 				if ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx + 1 )) != NULL) {
7717 					if (ntlmssph && (ntlmssph->type == 3)) {
7718 						smb_uid_t *smb_uid;
7719 
7720 						smb_uid = wmem_new(wmem_file_scope(), smb_uid_t);
7721 						smb_uid->logged_in  = -1;
7722 						smb_uid->logged_out = -1;
7723 						smb_uid->domain  = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
7724 						smb_uid->account = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
7725 
7726 						si->sip->extra_info = smb_uid;
7727 						si->sip->extra_info_type = SMB_EI_UID;
7728 					}
7729 				}
7730 			}
7731 
7732 			COUNT_BYTES(sbloblen);
7733 		}
7734 
7735 		/* OS
7736 		 * Eventhough this field should honour the unicode flag
7737 		 * some ms clients gets this wrong.
7738 		 * At least XP SP1 sends this in ASCII
7739 		 * even when the unicode flag is on.
7740 		 * Test if the first three bytes are "Win"
7741 		 * and if so just override the flag.
7742 		 */
7743 		unicodeflag = si->unicode;
7744 		if ( tvb_strneql(tvb, offset, "Win", 3) == 0 ) {
7745 			unicodeflag = FALSE;
7746 		}
7747 		an = get_unicode_or_ascii_string(tvb, &offset,
7748 			unicodeflag, &an_len, FALSE, FALSE, &bc);
7749 		if (an == NULL)
7750 			goto endofcommand;
7751 		proto_tree_add_string(tree, hf_smb_os, tvb,
7752 			offset, an_len, an);
7753 		COUNT_BYTES(an_len);
7754 
7755 		/* LANMAN */
7756 		/* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7757 		 * padding/null string/whatever in front of this. W2K doesn't
7758 		 * appear to. I suspect that's a bug that got fixed; I also
7759 		 * suspect that, in practice, nobody ever looks at that field
7760 		 * because the bug didn't appear to get fixed until NT 5.0....
7761 		 *
7762 		 * Eventhough this field should honour the unicode flag
7763 		 * some ms clients gets this wrong.
7764 		 * At least XP SP1 sends this in ASCII
7765 		 * even when the unicode flag is on.
7766 		 * Test if the first three bytes are "Win"
7767 		 * and if so just override the flag.
7768 		 */
7769 		unicodeflag = si->unicode;
7770 		if ( tvb_strneql(tvb, offset, "Win", 3) == 0 ) {
7771 			unicodeflag = FALSE;
7772 		}
7773 		an = get_unicode_or_ascii_string(tvb, &offset,
7774 			unicodeflag, &an_len, FALSE, FALSE, &bc);
7775 		if (an == NULL)
7776 			goto endofcommand;
7777 		proto_tree_add_string(tree, hf_smb_lanman, tvb,
7778 			offset, an_len, an);
7779 		COUNT_BYTES(an_len);
7780 
7781 		/* Primary domain */
7782 		/* XXX - pre-W2K NT systems sometimes appear to stick an extra
7783 		 * byte in front of this, at least if all the strings are
7784 		 * ASCII and the account name is empty. Another bug?
7785 		 */
7786 		dn = get_unicode_or_ascii_string(tvb, &offset,
7787 			si->unicode, &dn_len, FALSE, FALSE, &bc);
7788 		if (dn == NULL)
7789 			goto endofcommand;
7790 		proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7791 			offset, dn_len, dn);
7792 		COUNT_BYTES(dn_len);
7793 	} else {
7794 		switch (wc) {
7795 
7796 		case 10:
7797 			if (pwlen) {
7798 				/* password, ASCII */
7799 				CHECK_BYTE_COUNT(pwlen);
7800 				proto_tree_add_item(tree, hf_smb_password,
7801 					tvb, offset, pwlen, ENC_NA);
7802 				COUNT_BYTES(pwlen);
7803 			}
7804 
7805 			break;
7806 
7807 		case 13:
7808 			if (apwlen) {
7809 				/* password, ANSI */
7810 				CHECK_BYTE_COUNT(apwlen);
7811 				proto_tree_add_item(tree, hf_smb_ansi_password,
7812 					tvb, offset, apwlen, ENC_NA);
7813 				COUNT_BYTES(apwlen);
7814 			}
7815 
7816 			if (upwlen) {
7817 				proto_item *item;
7818 
7819 				/* password, Unicode */
7820 				CHECK_BYTE_COUNT(upwlen);
7821 				item = proto_tree_add_item(tree, hf_smb_unicode_password,
7822 					tvb, offset, upwlen, ENC_NA);
7823 
7824 				if (upwlen > 24) {
7825 					proto_tree *subtree;
7826 					subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
7827 					dissect_ntlmv2_response(tvb, pinfo, subtree, offset, upwlen);
7828 				}
7829 
7830 				COUNT_BYTES(upwlen);
7831 			}
7832 
7833 			break;
7834 		}
7835 
7836 		/* Account Name */
7837 		an = get_unicode_or_ascii_string(tvb, &offset,
7838 			si->unicode, &an_len, FALSE, FALSE, &bc);
7839 		if (an == NULL)
7840 			goto endofcommand;
7841 		proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
7842 			an);
7843 		COUNT_BYTES(an_len);
7844 
7845 		/* Primary domain */
7846 		/* XXX - pre-W2K NT systems sometimes appear to stick an extra
7847 		 * byte in front of this, at least if all the strings are
7848 		 * ASCII and the account name is empty. Another bug?
7849 		 */
7850 		dn = get_unicode_or_ascii_string(tvb, &offset,
7851 			si->unicode, &dn_len, FALSE, FALSE, &bc);
7852 		if (dn == NULL)
7853 			goto endofcommand;
7854 		proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7855 			offset, dn_len, dn);
7856 		COUNT_BYTES(dn_len);
7857 
7858 		col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
7859 
7860 		if (!dn[0] && !an[0])
7861 			col_append_str(pinfo->cinfo, COL_INFO, "anonymous");
7862 		else
7863 			col_append_fstr(pinfo->cinfo, COL_INFO,
7864 					"%s\\%s",
7865 					format_text(wmem_packet_scope(), (const guchar*)dn, strlen(dn)),
7866 					format_text(wmem_packet_scope(), (const guchar*)an, strlen(an)));
7867 
7868 		/* OS */
7869 		an = get_unicode_or_ascii_string(tvb, &offset,
7870 			si->unicode, &an_len, FALSE, FALSE, &bc);
7871 		if (an == NULL)
7872 			goto endofcommand;
7873 		proto_tree_add_string(tree, hf_smb_os, tvb,
7874 			offset, an_len, an);
7875 		COUNT_BYTES(an_len);
7876 
7877 		/* LANMAN */
7878 		/* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7879 		 * padding/null string/whatever in front of this. W2K doesn't
7880 		 * appear to. I suspect that's a bug that got fixed; I also
7881 		 * suspect that, in practice, nobody ever looks at that field
7882 		 * because the bug didn't appear to get fixed until NT 5.0....
7883 		 */
7884 		an = get_unicode_or_ascii_string(tvb, &offset,
7885 			si->unicode, &an_len, FALSE, FALSE, &bc);
7886 		if (an == NULL)
7887 			goto endofcommand;
7888 		proto_tree_add_string(tree, hf_smb_lanman, tvb,
7889 			offset, an_len, an);
7890 		COUNT_BYTES(an_len);
7891 	}
7892 
7893 	END_OF_SMB
7894 
7895 	if (cmd != 0xff) { 	/* there is an andX command */
7896 		if (andxoffset < offset) {
7897 			THROW(ReportedBoundsError);
7898 		}
7899 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7900 	}
7901 
7902 	return offset;
7903 }
7904 
7905 static int
dissect_session_setup_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)7906 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7907 {
7908 	guint8      wc, cmd    = 0xff;
7909 	guint16     andxoffset = 0, bc;
7910 	guint16     sbloblen   = 0;
7911 	int         an_len;
7912 	const char *an;
7913 
7914 	DISSECTOR_ASSERT(si);
7915 
7916 	WORD_COUNT;
7917 
7918 	if (!pinfo->fd->visited && si->sip && si->sip->extra_info &&
7919 	    (si->sip->extra_info_type == SMB_EI_UID)) {
7920 		smb_uid_t *smb_uid;
7921 
7922 		smb_uid = (smb_uid_t *)si->sip->extra_info;
7923 		smb_uid->logged_in = pinfo->num;
7924 		wmem_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7925 	}
7926 
7927 	/* next smb command */
7928 	cmd = tvb_get_guint8(tvb, offset);
7929 	if (cmd != 0xff) {
7930 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7931 	} else {
7932 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7933 	}
7934 	offset += 1;
7935 
7936 	/* reserved byte */
7937 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7938 	offset += 1;
7939 
7940 	/* andxoffset */
7941 	andxoffset = tvb_get_letohs(tvb, offset);
7942 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7943 	offset += 2;
7944 
7945 	/* flags */
7946 	offset = dissect_setup_action(tvb, tree, offset);
7947 
7948 	if (wc == 4) {
7949 		/* security blob length */
7950 		sbloblen = tvb_get_letohs(tvb, offset);
7951 		proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7952 		offset += 2;
7953 	}
7954 
7955 	BYTE_COUNT;
7956 
7957 	if (wc == 4) {
7958 		proto_item *blob_item;
7959 
7960 		/* security blob */
7961 		/* don't try to eat too much of we might get an exception on
7962 		 * short frames and then we will not see anything at all
7963 		 * of the security blob.
7964 		 */
7965 		if (sbloblen > tvb_reported_length_remaining(tvb, offset)) {
7966 			sbloblen = tvb_reported_length_remaining(tvb, offset);
7967 		}
7968 		blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7969 						tvb, offset, sbloblen, ENC_NA);
7970 
7971 		if (sbloblen) {
7972 			tvbuff_t *blob_tvb;
7973 			proto_tree *blob_tree;
7974 
7975 			blob_tree = proto_item_add_subtree(blob_item,
7976 							   ett_smb_secblob);
7977 			CHECK_BYTE_COUNT(sbloblen);
7978 
7979 			blob_tvb = tvb_new_subset_length(tvb, offset, sbloblen);
7980 
7981 			if (si && si->ct && si->ct->raw_ntlmssp &&
7982 			    (tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)) {
7983 			  call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7984 					 blob_tree);
7985 
7986 			}
7987 			else {
7988 			  call_dissector(gssapi_handle, blob_tvb, pinfo,
7989 					 blob_tree);
7990 
7991 			}
7992 
7993 			COUNT_BYTES(sbloblen);
7994 		}
7995 	}
7996 
7997 	/* OS */
7998 	an = get_unicode_or_ascii_string(tvb, &offset,
7999 		si->unicode, &an_len, FALSE, FALSE, &bc);
8000 	if (an == NULL)
8001 		goto endofcommand;
8002 	proto_tree_add_string(tree, hf_smb_os, tvb,
8003 		offset, an_len, an);
8004 	COUNT_BYTES(an_len);
8005 
8006 	/* LANMAN */
8007 	an = get_unicode_or_ascii_string(tvb, &offset,
8008 		si->unicode, &an_len, FALSE, FALSE, &bc);
8009 	if (an == NULL)
8010 		goto endofcommand;
8011 	proto_tree_add_string(tree, hf_smb_lanman, tvb,
8012 		offset, an_len, an);
8013 	COUNT_BYTES(an_len);
8014 
8015 	if ((wc == 3) || (wc == 4)) {
8016 		/* Primary domain */
8017 		an = get_unicode_or_ascii_string(tvb, &offset,
8018 			si->unicode, &an_len, FALSE, FALSE, &bc);
8019 		if (an == NULL)
8020 			goto endofcommand;
8021 		proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
8022 			offset, an_len, an);
8023 		COUNT_BYTES(an_len);
8024 	}
8025 
8026 	END_OF_SMB
8027 
8028 	if (cmd != 0xff) { 	/* there is an andX command */
8029 		if (andxoffset < offset) {
8030 			THROW(ReportedBoundsError);
8031 		}
8032 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
8033 	}
8034 
8035 	return offset;
8036 }
8037 
8038 
8039 static int
dissect_empty_andx(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si _U_)8040 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si _U_)
8041 {
8042 	guint8	wc, cmd    = 0xff;
8043 	guint16 andxoffset = 0;
8044 	guint16 bc;
8045 
8046 	WORD_COUNT;
8047 
8048 	/* next smb command */
8049 	cmd = tvb_get_guint8(tvb, offset);
8050 	if (cmd != 0xff) {
8051 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
8052 	} else {
8053 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
8054 	}
8055 	offset += 1;
8056 
8057 	/* reserved byte */
8058 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
8059 	offset += 1;
8060 
8061 	/* andxoffset */
8062 	andxoffset = tvb_get_letohs(tvb, offset);
8063 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8064 	offset += 2;
8065 
8066 	BYTE_COUNT;
8067 
8068 	END_OF_SMB
8069 
8070 	if (cmd != 0xff) { 	/* there is an andX command */
8071 		if (andxoffset < offset) {
8072 			THROW(ReportedBoundsError);
8073 		}
8074 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
8075 	}
8076 
8077 	return offset;
8078 }
8079 
8080 	/*
8081 	 * From [MS-SMB] - v20100711 Server Message Block (SMB) Protocol Specification
8082 	 * http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-SMB%5D.pdf
8083 	 * 2.2.4.7 SMB_COM_TREE_CONNECT_ANDX (0x75)
8084 	 */
8085 
8086 static const true_false_string tfs_connect_support_search = {
8087 	"Exclusive search bits supported",
8088 	"Exclusive search bits not supported"
8089 };
8090 static const true_false_string tfs_connect_support_in_dfs = {
8091 	"Share is in Dfs",
8092 	"Share isn't in Dfs"
8093 };
8094 static const value_string connect_support_csc_mask_vals[] = {
8095 	{ 0,	"Automatic file-to-file reintegration NOT permitted"},
8096 	{ 1,	"Automatic file-to-file reintegration permitted"},
8097 	{ 2,	"Offline caching allow for the share"},
8098 	{ 3,	"Offline caching NOT allow for the share"},
8099 	{0, NULL}
8100 };
8101 static const true_false_string tfs_connect_support_uniquefilename = {
8102 	"Client allowed to cache share namespaces",
8103 	"Client NOT allowed to cache share namespaces"
8104 };
8105 static const true_false_string tfs_connect_support_extended_signature = {
8106 	"Extended signature",
8107 	"NOT extended signature"
8108 };
8109 
8110 static int
dissect_connect_support_bits(tvbuff_t * tvb,proto_tree * parent_tree,int offset)8111 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8112 {
8113 	static int * const flags[] = {
8114 		&hf_smb_connect_support_search,
8115 		&hf_smb_connect_support_in_dfs,
8116 		&hf_smb_connect_support_csc_mask_vals,
8117 		&hf_smb_connect_support_uniquefilename,
8118 		&hf_smb_connect_support_extended_signature,
8119 		NULL
8120 	};
8121 
8122 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_connect_support, ett_smb_connect_support_bits, flags, ENC_LITTLE_ENDIAN);
8123 	offset += 2;
8124 
8125 	return offset;
8126 }
8127 
8128 static const true_false_string tfs_disconnect_tid = {
8129 	"DISCONNECT TID",
8130 	"Do NOT disconnect TID"
8131 };
8132 
8133 static const true_false_string tfs_extended_signature = {
8134 	"Extended Signature",
8135 	"NOT Extended Signature"
8136 };
8137 
8138 static const true_false_string tfs_extended_response = {
8139 	"Extended Response",
8140 	"NOT Extended Response"
8141 };
8142 
8143 static int
dissect_connect_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)8144 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8145 {
8146 	static int * const flags[] = {
8147 		&hf_smb_connect_flags_dtid,
8148 		&hf_smb_connect_flags_ext_sig,
8149 		&hf_smb_connect_flags_ext_resp,
8150 		NULL
8151 	};
8152 
8153 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_connect_flags, ett_smb_connect_flags, flags, ENC_LITTLE_ENDIAN);
8154 	offset += 2;
8155 
8156 	return offset;
8157 }
8158 
8159 static int
dissect_tree_connect_andx_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)8160 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
8161 {
8162 	guint8        wc, cmd    = 0xff;
8163 	guint16       bc;
8164 	guint16       andxoffset = 0, pwlen = 0;
8165 	int           an_len;
8166 	const guint8 *an;
8167 
8168 	DISSECTOR_ASSERT(si);
8169 
8170 	WORD_COUNT;
8171 
8172 	/* next smb command */
8173 	cmd = tvb_get_guint8(tvb, offset);
8174 	if (cmd != 0xff) {
8175 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
8176 	} else {
8177 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
8178 	}
8179 	offset += 1;
8180 
8181 	/* reserved byte */
8182 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
8183 	offset += 1;
8184 
8185 	/* andxoffset */
8186 	andxoffset = tvb_get_letohs(tvb, offset);
8187 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8188 	offset += 2;
8189 
8190 	/* flags */
8191 	offset = dissect_connect_flags(tvb, tree, offset);
8192 
8193 	/* password length*/
8194 	pwlen = tvb_get_letohs(tvb, offset);
8195 	proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
8196 	offset += 2;
8197 
8198 	BYTE_COUNT;
8199 
8200 	/* password */
8201 	CHECK_BYTE_COUNT(pwlen);
8202 	proto_tree_add_item(tree, hf_smb_password,
8203 		tvb, offset, pwlen, ENC_NA);
8204 	COUNT_BYTES(pwlen);
8205 
8206 	/* Path */
8207 	an = get_unicode_or_ascii_string(tvb, &offset,
8208 		si->unicode, &an_len, FALSE, FALSE, &bc);
8209 	if (an == NULL)
8210 		goto endofcommand;
8211 	proto_tree_add_string(tree, hf_smb_path, tvb,
8212 		offset, an_len, an);
8213 	COUNT_BYTES(an_len);
8214 
8215 	/* store it for the tid->name/openframe/closeframe matching in
8216 	 * dissect_smb_tid()   called from the response.
8217 	 */
8218 	if ((!pinfo->fd->visited) && si->sip && an) {
8219 		si->sip->extra_info_type = SMB_EI_TIDNAME;
8220 		si->sip->extra_info = wmem_strdup(wmem_file_scope(), an);
8221 	}
8222 
8223 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8224 		    format_text(wmem_packet_scope(), (const guchar*)an, strlen(an)));
8225 
8226 	/*
8227 	 * NOTE: the Service string is always ASCII, even if the
8228 	 * "strings are Unicode" bit is set in the flags2 field
8229 	 * of the SMB.
8230 	 */
8231 
8232 	/* Service */
8233 	/* XXX - what if this runs past bc? */
8234 	an_len = tvb_strsize(tvb, offset);
8235 	CHECK_BYTE_COUNT(an_len);
8236 	proto_tree_add_item_ret_string(tree, hf_smb_service, tvb,
8237 		offset, an_len, ENC_ASCII|ENC_NA, wmem_packet_scope(), &an);
8238 	COUNT_BYTES(an_len);
8239 
8240 	END_OF_SMB
8241 
8242 	if (cmd != 0xff) { 	/* there is an andX command */
8243 		if (andxoffset < offset) {
8244 			THROW(ReportedBoundsError);
8245 		}
8246 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
8247 	}
8248 
8249 	return offset;
8250 }
8251 
8252 
8253 static int
dissect_tree_connect_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)8254 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
8255 {
8256 	guint8        wc, cmd = 0xff;
8257 	guint16       andxoffset     = 0;
8258 	guint16       bc;
8259 	int           an_len;
8260 	const guint8 *an;
8261 
8262 	DISSECTOR_ASSERT(si);
8263 
8264 	WORD_COUNT;
8265 
8266 	/* next smb command */
8267 	cmd = tvb_get_guint8(tvb, offset);
8268 	if (cmd != 0xff) {
8269 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
8270 	} else {
8271 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
8272 	}
8273 	offset += 1;
8274 
8275 	/* reserved byte */
8276 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
8277 	offset += 1;
8278 
8279 	/* andxoffset */
8280 	andxoffset = tvb_get_letohs(tvb, offset);
8281 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8282 	offset += 2;
8283 
8284 	/* There are three valid formats of tree connect response.
8285 	   All have the first two words: andx_cmd, andx_off,
8286 	   and then have additional words as follows:
8287 		wc=2: (ancient LanMan -- no more words)
8288 		wc=3: (NT, non-ext) opt_support
8289 		wc=7: (NT, extended) opt_support,
8290 			tree_access(2w), guest_access(2w)
8291 	   byte_count follows those words as usual */
8292 
8293 	if (wc >= 3) {
8294 		/* flags */
8295 		offset = dissect_connect_support_bits(tvb, tree, offset);
8296 	}
8297 
8298 	if (wc == 7) {
8299 		/*
8300 		 * Refer to [MS-SMB] - v20100711
8301 		 * When a server returns extended information, the response
8302 		 * takes the following format, with WordCount = 7.
8303 		 * MaximalShareAccessRights, and GuestMaximalShareAccessRights fields
8304 		 * has added.
8305 		 */
8306 		proto_tree *tr;
8307 		tr = proto_tree_add_subtree(tree, tvb, offset, 4,
8308 			ett_smb_nt_access_mask, NULL, "Maximal Share Access Rights");
8309 		offset = dissect_smb_access_mask(tvb, tr, offset);
8310 
8311 		tr = proto_tree_add_subtree(tree, tvb, offset, 4,
8312 			ett_smb_nt_access_mask, NULL, "Guest Maximal Share Access Rights");
8313 		offset = dissect_smb_access_mask(tvb, tr, offset);
8314 	}
8315 
8316 	BYTE_COUNT;
8317 
8318 	/*
8319 	 * NOTE: even though the SNIA CIFS spec doesn't say there's
8320 	 * a "Service" string if there's a word count of 2, the
8321 	 * document at
8322 	 *
8323 	 *	ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
8324 	 *
8325 	 * (it's in an ugly format - text intended to be sent to a
8326 	 * printer, with backspaces and overstrikes used for boldfacing
8327 	 * and underlining; UNIX "col -b" can be used to strip the
8328 	 * overstrikes out) says there's a "Service" string there, and
8329 	 * some network traffic has it.
8330 	 */
8331 
8332 	/*
8333 	 * NOTE: the Service string is always ASCII, even if the
8334 	 * "strings are Unicode" bit is set in the flags2 field
8335 	 * of the SMB.
8336 	 */
8337 
8338 	/* Service */
8339 	/* XXX - what if this runs past bc? */
8340 	an_len = tvb_strsize(tvb, offset);
8341 	CHECK_BYTE_COUNT(an_len);
8342 	proto_tree_add_item_ret_string(tree, hf_smb_service, tvb,
8343 		offset, an_len, ENC_ASCII|ENC_NA, wmem_packet_scope(), &an);
8344 	COUNT_BYTES(an_len);
8345 
8346 	/* Now when we know the service type, store it so that we know it for later commands down
8347 	   this tree */
8348 	if (!pinfo->fd->visited) {
8349 		/* Remove any previous entry for this TID */
8350 		if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
8351 			g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
8352 		}
8353 		if (strcmp(an, "IPC") == 0) {
8354 			g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
8355 		} else {
8356 			g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
8357 		}
8358 	}
8359 
8360 	if (bc != 0) {
8361 		/*
8362 		 * Sometimes this isn't present.
8363 		 */
8364 
8365 		/* Native FS */
8366 		an = get_unicode_or_ascii_string(tvb, &offset,
8367 			si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
8368 			&bc);
8369 		if (an == NULL)
8370 			goto endofcommand;
8371 		proto_tree_add_string(tree, hf_smb_fs, tvb,
8372 			offset, an_len, an);
8373 		COUNT_BYTES(an_len);
8374 	}
8375 
8376 	END_OF_SMB
8377 
8378 	if (cmd != 0xff) { 	/* there is an andX command */
8379 		if (andxoffset < offset) {
8380 			THROW(ReportedBoundsError);
8381 		}
8382 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
8383 	}
8384 
8385 	return offset;
8386 }
8387 
8388 
8389 
8390 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8391    NT Transaction command  begins here
8392    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8393 #define NT_TRANS_CREATE		1
8394 #define NT_TRANS_IOCTL		2
8395 #define NT_TRANS_SSD		3
8396 #define NT_TRANS_NOTIFY		4
8397 #define NT_TRANS_RENAME		5
8398 #define NT_TRANS_QSD		6
8399 #define NT_TRANS_GET_USER_QUOTA	7
8400 #define NT_TRANS_SET_USER_QUOTA 8
8401 static const value_string nt_cmd_vals[] = {
8402 	{NT_TRANS_CREATE,		"NT CREATE"},
8403 	{NT_TRANS_IOCTL,		"NT IOCTL"},
8404 	{NT_TRANS_SSD,			"NT SET SECURITY DESC"},
8405 	{NT_TRANS_NOTIFY,		"NT NOTIFY"},
8406 	{NT_TRANS_RENAME,		"NT RENAME"},
8407 	{NT_TRANS_QSD,			"NT QUERY SECURITY DESC"},
8408 	{NT_TRANS_GET_USER_QUOTA,	"NT GET USER QUOTA"},
8409 	{NT_TRANS_SET_USER_QUOTA,	"NT SET USER QUOTA"},
8410 	{0, NULL}
8411 };
8412 value_string_ext nt_cmd_vals_ext = VALUE_STRING_EXT_INIT(nt_cmd_vals);
8413 
8414 static const value_string nt_ioctl_isfsctl_vals[] = {
8415 	{0,	"Device IOCTL"},
8416 	{1,	"FS control : FSCTL"},
8417 	{0, NULL}
8418 };
8419 
8420 #define NT_IOCTL_FLAGS_ROOT_HANDLE	0x01
8421 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
8422 	"Apply the command to share root handle (MUST BE Dfs)",
8423 	"Apply to this share",
8424 };
8425 
8426 static const value_string nt_notify_action_vals[] = {
8427 	{1,	"ADDED (object was added"},
8428 	{2,	"REMOVED (object was removed)"},
8429 	{3,	"MODIFIED (object was modified)"},
8430 	{4,	"RENAMED_OLD_NAME (this is the old name of object)"},
8431 	{5,	"RENAMED_NEW_NAME (this is the new name of object)"},
8432 	{6,	"ADDED_STREAM (a stream was added)"},
8433 	{7,	"REMOVED_STREAM (a stream was removed)"},
8434 	{8,	"MODIFIED_STREAM (a stream was modified)"},
8435 	{0, NULL}
8436 };
8437 
8438 static const value_string watch_tree_vals[] = {
8439 	{0,	"Current directory only"},
8440 	{1,	"Subdirectories also"},
8441 	{0, NULL}
8442 };
8443 
8444 #define NT_NOTIFY_STREAM_WRITE	0x00000800
8445 #define NT_NOTIFY_STREAM_SIZE	0x00000400
8446 #define NT_NOTIFY_STREAM_NAME	0x00000200
8447 #define NT_NOTIFY_SECURITY	0x00000100
8448 #define NT_NOTIFY_EA		0x00000080
8449 #define NT_NOTIFY_CREATION	0x00000040
8450 #define NT_NOTIFY_LAST_ACCESS	0x00000020
8451 #define NT_NOTIFY_LAST_WRITE	0x00000010
8452 #define NT_NOTIFY_SIZE		0x00000008
8453 #define NT_NOTIFY_ATTRIBUTES	0x00000004
8454 #define NT_NOTIFY_DIR_NAME	0x00000002
8455 #define NT_NOTIFY_FILE_NAME	0x00000001
8456 static const true_false_string tfs_nt_notify_stream_write = {
8457 	"Notify on changes to STREAM WRITE",
8458 	"Do NOT notify on changes to stream write",
8459 };
8460 static const true_false_string tfs_nt_notify_stream_size = {
8461 	"Notify on changes to STREAM SIZE",
8462 	"Do NOT notify on changes to stream size",
8463 };
8464 static const true_false_string tfs_nt_notify_stream_name = {
8465 	"Notify on changes to STREAM NAME",
8466 	"Do NOT notify on changes to stream name",
8467 };
8468 static const true_false_string tfs_nt_notify_security = {
8469 	"Notify on changes to SECURITY",
8470 	"Do NOT notify on changes to security",
8471 };
8472 static const true_false_string tfs_nt_notify_ea = {
8473 	"Notify on changes to EA",
8474 	"Do NOT notify on changes to EA",
8475 };
8476 static const true_false_string tfs_nt_notify_creation = {
8477 	"Notify on changes to CREATION TIME",
8478 	"Do NOT notify on changes to creation time",
8479 };
8480 static const true_false_string tfs_nt_notify_last_access = {
8481 	"Notify on changes to LAST ACCESS TIME",
8482 	"Do NOT notify on changes to last access time",
8483 };
8484 static const true_false_string tfs_nt_notify_last_write = {
8485 	"Notify on changes to LAST WRITE TIME",
8486 	"Do NOT notify on changes to last write time",
8487 };
8488 static const true_false_string tfs_nt_notify_size = {
8489 	"Notify on changes to SIZE",
8490 	"Do NOT notify on changes to size",
8491 };
8492 static const true_false_string tfs_nt_notify_attributes = {
8493 	"Notify on changes to ATTRIBUTES",
8494 	"Do NOT notify on changes to attributes",
8495 };
8496 static const true_false_string tfs_nt_notify_dir_name = {
8497 	"Notify on changes to DIR NAME",
8498 	"Do NOT notify on changes to dir name",
8499 };
8500 static const true_false_string tfs_nt_notify_file_name = {
8501 	"Notify on changes to FILE NAME",
8502 	"Do NOT notify on changes to file name",
8503 };
8504 
8505 const value_string create_disposition_vals[] = {
8506 	{0,	"Supersede (supersede existing file (if it exists))"},
8507 	{1,	"Open (if file exists open it, else fail)"},
8508 	{2,	"Create (if file exists fail, else create it)"},
8509 	{3,	"Open If (if file exists open it, else create it)"},
8510 	{4,	"Overwrite (if file exists overwrite, else fail)"},
8511 	{5,	"Overwrite If (if file exists overwrite, else create it)"},
8512 	{0, NULL}
8513 };
8514 
8515 const value_string impersonation_level_vals[] = {
8516 	{0,	"Anonymous"},
8517 	{1,	"Identification"},
8518 	{2,	"Impersonation"},
8519 	{3,	"Delegation"},
8520 	{0, NULL}
8521 };
8522 
8523 static const true_false_string tfs_nt_security_flags_context_tracking = {
8524 	"Security tracking mode is DYNAMIC",
8525 	"Security tracking mode is STATIC",
8526 };
8527 
8528 static const true_false_string tfs_nt_security_flags_effective_only = {
8529 	"ONLY ENABLED aspects of the client's security context are available",
8530 	"ALL aspects of the client's security context are available",
8531 };
8532 
8533 static const true_false_string tfs_nt_create_bits_oplock = {
8534 	"Requesting OPLOCK",
8535 	"Does NOT request oplock"
8536 };
8537 
8538 static const true_false_string tfs_nt_create_bits_boplock = {
8539 	"Requesting BATCH OPLOCK",
8540 	"Does NOT request batch oplock"
8541 };
8542 
8543 /*
8544  * XXX - must be a directory, and can be a file, or can be a directory,
8545  * and must be a file?
8546  */
8547 static const true_false_string tfs_nt_create_bits_dir = {
8548 	"Target of open MUST be a DIRECTORY",
8549 	"Target of open can be a file"
8550 };
8551 
8552 static const true_false_string tfs_nt_create_bits_ext_resp = {
8553 	"Extended responses required",
8554 	"Extended responses NOT required"
8555 };
8556 
8557 static const true_false_string tfs_nt_access_mask_generic_read = {
8558 	"GENERIC READ is set",
8559 	"Generic read is NOT set"
8560 };
8561 static const true_false_string tfs_nt_access_mask_generic_write = {
8562 	"GENERIC WRITE is set",
8563 	"Generic write is NOT set"
8564 };
8565 static const true_false_string tfs_nt_access_mask_generic_execute = {
8566 	"GENERIC EXECUTE is set",
8567 	"Generic execute is NOT set"
8568 };
8569 static const true_false_string tfs_nt_access_mask_generic_all = {
8570 	"GENERIC ALL is set",
8571 	"Generic all is NOT set"
8572 };
8573 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
8574 	"MAXIMUM ALLOWED is set",
8575 	"Maximum allowed is NOT set"
8576 };
8577 static const true_false_string tfs_nt_access_mask_system_security = {
8578 	"SYSTEM SECURITY is set",
8579 	"System security is NOT set"
8580 };
8581 static const true_false_string tfs_nt_access_mask_synchronize = {
8582 	"Can wait on handle to SYNCHRONIZE on completion of I/O",
8583 	"Can NOT wait on handle to synchronize on completion of I/O"
8584 };
8585 static const true_false_string tfs_nt_access_mask_write_owner = {
8586 	"Can WRITE OWNER (take ownership)",
8587 	"Can NOT write owner (take ownership)"
8588 };
8589 static const true_false_string tfs_nt_access_mask_write_dac = {
8590 	"OWNER may WRITE the DAC",
8591 	"Owner may NOT write to the DAC"
8592 };
8593 static const true_false_string tfs_nt_access_mask_read_control = {
8594 	"READ ACCESS to owner, group and ACL of the SID",
8595 	"Read access is NOT granted to owner, group and ACL of the SID"
8596 };
8597 static const true_false_string tfs_nt_access_mask_delete = {
8598 	"DELETE access",
8599 	"NO delete access"
8600 };
8601 static const true_false_string tfs_nt_access_mask_write_attributes = {
8602 	"WRITE ATTRIBUTES access",
8603 	"NO write attributes access"
8604 };
8605 static const true_false_string tfs_nt_access_mask_read_attributes = {
8606 	"READ ATTRIBUTES access",
8607 	"NO read attributes access"
8608 };
8609 static const true_false_string tfs_nt_access_mask_delete_child = {
8610 	"DELETE CHILD access",
8611 	"NO delete child access"
8612 };
8613 static const true_false_string tfs_nt_access_mask_execute = {
8614 	"EXECUTE access",
8615 	"NO execute access"
8616 };
8617 static const true_false_string tfs_nt_access_mask_write_ea = {
8618 	"WRITE EXTENDED ATTRIBUTES access",
8619 	"NO write extended attributes access"
8620 };
8621 static const true_false_string tfs_nt_access_mask_read_ea = {
8622 	"READ EXTENDED ATTRIBUTES access",
8623 	"NO read extended attributes access"
8624 };
8625 static const true_false_string tfs_nt_access_mask_append = {
8626 	"APPEND access",
8627 	"NO append access"
8628 };
8629 static const true_false_string tfs_nt_access_mask_write = {
8630 	"WRITE access",
8631 	"NO write access"
8632 };
8633 static const true_false_string tfs_nt_access_mask_read = {
8634 	"READ access",
8635 	"NO read access"
8636 };
8637 
8638 static const true_false_string tfs_nt_share_access_delete = {
8639 	"Object can be shared for DELETE",
8640 	"Object can NOT be shared for delete"
8641 };
8642 static const true_false_string tfs_nt_share_access_write = {
8643 	"Object can be shared for WRITE",
8644 	"Object can NOT be shared for write"
8645 };
8646 static const true_false_string tfs_nt_share_access_read = {
8647 	"Object can be shared for READ",
8648 	"Object can NOT be shared for read"
8649 };
8650 
8651 static const value_string oplock_level_vals[] = {
8652 	{0,	"No oplock granted"},
8653 	{1,	"Exclusive oplock granted"},
8654 	{2,	"Batch oplock granted"},
8655 	{3,	"Level II oplock granted"},
8656 	{0, NULL}
8657 };
8658 
8659 static const value_string response_type_vals[] = {
8660 	{0x00,	"Non-extended response"},
8661 	{0x01,	"Extended response"},
8662 	{0, NULL}
8663 };
8664 
8665 static const value_string device_type_vals[] = {
8666 	{0x00000001,	"Beep"},
8667 	{0x00000002,	"CDROM"},
8668 	{0x00000003,	"CDROM Filesystem"},
8669 	{0x00000004,	"Controller"},
8670 	{0x00000005,	"Datalink"},
8671 	{0x00000006,	"Dfs"},
8672 	{0x00000007,	"Disk"},
8673 	{0x00000008,	"Disk Filesystem"},
8674 	{0x00000009,	"Filesystem"},
8675 	{0x0000000a,	"Inport Port"},
8676 	{0x0000000b,	"Keyboard"},
8677 	{0x0000000c,	"Mailslot"},
8678 	{0x0000000d,	"MIDI-In"},
8679 	{0x0000000e,	"MIDI-Out"},
8680 	{0x0000000f,	"Mouse"},
8681 	{0x00000010,	"Multi UNC Provider"},
8682 	{0x00000011,	"Named Pipe"},
8683 	{0x00000012,	"Network"},
8684 	{0x00000013,	"Network Browser"},
8685 	{0x00000014,	"Network Filesystem"},
8686 	{0x00000015,	"NULL"},
8687 	{0x00000016,	"Parallel Port"},
8688 	{0x00000017,	"Physical card"},
8689 	{0x00000018,	"Printer"},
8690 	{0x00000019,	"Scanner"},
8691 	{0x0000001a,	"Serial Mouse port"},
8692 	{0x0000001b,	"Serial port"},
8693 	{0x0000001c,	"Screen"},
8694 	{0x0000001d,	"Sound"},
8695 	{0x0000001e,	"Streams"},
8696 	{0x0000001f,	"Tape"},
8697 	{0x00000020,	"Tape Filesystem"},
8698 	{0x00000021,	"Transport"},
8699 	{0x00000022,	"Unknown"},
8700 	{0x00000023,	"Video"},
8701 	{0x00000024,	"Virtual Disk"},
8702 	{0x00000025,	"WAVE-In"},
8703 	{0x00000026,	"WAVE-Out"},
8704 	{0x00000027,	"8042 Port"},
8705 	{0x00000028,	"Network Redirector"},
8706 	{0x00000029,	"Battery"},
8707 	{0x0000002a,	"Bus Extender"},
8708 	{0x0000002b,	"Modem"},
8709 	{0x0000002c,	"VDM"},
8710 	{0,	NULL}
8711 };
8712 static value_string_ext device_type_vals_ext = VALUE_STRING_EXT_INIT(device_type_vals);
8713 
8714 static const value_string is_directory_vals[] = {
8715 	{0,	"This is NOT a directory"},
8716 	{1,	"This is a DIRECTORY"},
8717 	{0, NULL}
8718 };
8719 
8720 static int
dissect_nt_security_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)8721 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8722 {
8723 	static int * const flags[] = {
8724 		&hf_smb_nt_security_flags_context_tracking,
8725 		&hf_smb_nt_security_flags_effective_only,
8726 		NULL
8727 	};
8728 
8729 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_nt_security_flags, ett_smb_nt_security_flags, flags, ENC_NA);
8730 	offset += 1;
8731 
8732 	return offset;
8733 }
8734 
8735 /*
8736  * XXX - there are some more flags in the description of "ZwOpenFile()"
8737  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
8738  * the wire as well?  (The spec at
8739  *
8740  *	http://www.samba.org/samba/ftp/specs/smb-nt01.doc
8741  *
8742  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
8743  * via the SMB protocol.  The NT redirector should convert this option
8744  * to FILE_WRITE_THROUGH."
8745  *
8746  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
8747  * values one would infer from their position in the list of flags for
8748  * "ZwOpenFile()".  Most of the others probably have those values
8749  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
8750  * which might go over the wire (for the benefit of backup/restore software).
8751  */
8752 static const true_false_string tfs_nt_create_options_directory = {
8753 	"File being created/opened must be a directory",
8754 	"File being created/opened must not be a directory"
8755 };
8756 static const true_false_string tfs_nt_create_options_write_through = {
8757 	"Writes should flush buffered data before completing",
8758 	"Writes need not flush buffered data before completing"
8759 };
8760 static const true_false_string tfs_nt_create_options_sequential_only = {
8761 	"The file will only be accessed sequentially",
8762 	"The file might not only be accessed sequentially"
8763 };
8764 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
8765 	"NO intermediate buffering is allowed",
8766 	"Intermediate buffering is allowed"
8767 };
8768 static const true_false_string tfs_nt_create_options_sync_io_alert = {
8769 	"All operations SYNCHRONOUS, waits subject to termination from alert",
8770 	"Operations NOT necessarily synchronous"
8771 };
8772 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
8773 	"All operations SYNCHRONOUS, waits not subject to alert",
8774 	"Operations NOT necessarily synchronous"
8775 };
8776 static const true_false_string tfs_nt_create_options_non_directory = {
8777 	"File being created/opened must not be a directory",
8778 	"File being created/opened must be a directory"
8779 };
8780 static const true_false_string tfs_nt_create_options_create_tree_connection = {
8781 	"Create Tree Connections is SET",
8782 	"Create Tree Connections is NOT set"
8783 };
8784 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
8785 	"Complete if oplocked is SET",
8786 	"Complete if oplocked is NOT set"
8787 };
8788 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
8789 	"The client does not understand extended attributes",
8790 	"The client understands extended attributes"
8791 };
8792 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
8793 	"The client understands only 8.3 file names",
8794 	"The client understands long file names"
8795 };
8796 static const true_false_string tfs_nt_create_options_random_access = {
8797 	"The file will be accessed randomly",
8798 	"The file will not be accessed randomly"
8799 };
8800 static const true_false_string tfs_nt_create_options_delete_on_close = {
8801 	"The file should be deleted when it is closed",
8802 	"The file should not be deleted when it is closed"
8803 };
8804 static const true_false_string tfs_nt_create_options_open_by_fileid = {
8805 	"OpenByFileID bit is SET",
8806 	"OpenByFileID is NOT set"
8807 };
8808 static const true_false_string tfs_nt_create_options_backup_intent = {
8809 	"This is a create with BACKUP INTENT",
8810 	"This is a normal create"
8811 };
8812 static const true_false_string tfs_nt_create_options_no_compression = {
8813 	"Open/Create with NO Compression",
8814 	"Compression is allowed for Open/Create"
8815 };
8816 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
8817 	"Reserve Opfilter is SET",
8818 	"Reserve Opfilter is NOT set"
8819 };
8820 static const true_false_string tfs_nt_create_options_open_reparse_point = {
8821 	"Open a Reparse Point",
8822 	"Normal open"
8823 };
8824 static const true_false_string tfs_nt_create_options_open_no_recall = {
8825 	"Open No Recall is SET",
8826 	"Open no recall is NOT set"
8827 };
8828 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
8829 	"This is an OPEN FOR FREE SPACE QUERY",
8830 	"This is NOT an open for free space query"
8831 };
8832 
8833 int
dissect_nt_notify_completion_filter(tvbuff_t * tvb,proto_tree * parent_tree,int offset)8834 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8835 {
8836 	static int * const flags[] = {
8837 		&hf_smb_nt_notify_file_name,
8838 		&hf_smb_nt_notify_dir_name,
8839 		&hf_smb_nt_notify_attributes,
8840 		&hf_smb_nt_notify_size,
8841 		&hf_smb_nt_notify_last_write,
8842 		&hf_smb_nt_notify_last_access,
8843 		&hf_smb_nt_notify_creation,
8844 		&hf_smb_nt_notify_ea,
8845 		&hf_smb_nt_notify_security,
8846 		&hf_smb_nt_notify_stream_name,
8847 		&hf_smb_nt_notify_stream_size,
8848 		&hf_smb_nt_notify_stream_write,
8849 		NULL
8850 	};
8851 
8852 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_nt_notify_completion_filter, ett_smb_nt_notify_completion_filter, flags, ENC_LITTLE_ENDIAN);
8853 	offset += 4;
8854 
8855 	return offset;
8856 }
8857 
8858 static int
dissect_nt_ioctl_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)8859 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8860 {
8861 	static int * const flags[] = {
8862 		&hf_smb_nt_ioctl_flags_root_handle,
8863 		NULL
8864 	};
8865 
8866 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_nt_ioctl_flags_completion_filter, ett_smb_nt_ioctl_flags, flags, ENC_NA);
8867 	offset += 1;
8868 
8869 	return offset;
8870 }
8871 
8872 /*
8873  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
8874  * Native API Reference".
8875  */
8876 static const true_false_string tfs_nt_qsd_owner = {
8877 	"Requesting OWNER security information",
8878 	"NOT requesting owner security information",
8879 };
8880 
8881 static const true_false_string tfs_nt_qsd_group = {
8882 	"Requesting GROUP security information",
8883 	"NOT requesting group security information",
8884 };
8885 
8886 static const true_false_string tfs_nt_qsd_dacl = {
8887 	"Requesting DACL security information",
8888 	"NOT requesting DACL security information",
8889 };
8890 
8891 static const true_false_string tfs_nt_qsd_sacl = {
8892 	"Requesting SACL security information",
8893 	"NOT requesting SACL security information",
8894 };
8895 
8896 #define NT_QSD_OWNER	0x00000001
8897 #define NT_QSD_GROUP	0x00000002
8898 #define NT_QSD_DACL	0x00000004
8899 #define NT_QSD_SACL	0x00000008
8900 
8901 int
dissect_security_information_mask(tvbuff_t * tvb,proto_tree * parent_tree,int offset)8902 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8903 {
8904 	static int * const flags[] = {
8905 		&hf_smb_nt_qsd_owner,
8906 		&hf_smb_nt_qsd_group,
8907 		&hf_smb_nt_qsd_dacl,
8908 		&hf_smb_nt_qsd_sacl,
8909 		NULL
8910 	};
8911 
8912 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_nt_qsd, ett_smb_security_information_mask, flags, ENC_LITTLE_ENDIAN);
8913 	offset += 4;
8914 
8915 	return offset;
8916 }
8917 
8918 int
dissect_nt_user_quota(tvbuff_t * tvb,proto_tree * tree,int offset,guint16 * bcp)8919 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8920 {
8921 	int     old_offset, old_sid_offset;
8922 	guint32 qsize;
8923 
8924 	do {
8925 		old_offset = offset;
8926 
8927 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
8928 		qsize = tvb_get_letohl(tvb, offset);
8929 		proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8930 		COUNT_BYTES_TRANS_SUBR(4);
8931 
8932 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
8933 		/* length of SID */
8934 		proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8935 		COUNT_BYTES_TRANS_SUBR(4);
8936 
8937 		/* change time */
8938 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
8939 		offset = dissect_nt_64bit_time(tvb, tree, offset,
8940 			hf_smb_user_quota_change_time);
8941 
8942 		/* number of bytes for used quota */
8943 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
8944 		proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8945 		COUNT_BYTES_TRANS_SUBR(8);
8946 
8947 		/* number of bytes for quota warning */
8948 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
8949 		proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8950 		COUNT_BYTES_TRANS_SUBR(8);
8951 
8952 		/* number of bytes for quota limit */
8953 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
8954 		proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8955 		COUNT_BYTES_TRANS_SUBR(8);
8956 
8957 		/* SID of the user */
8958 		old_sid_offset = offset;
8959 		offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8960 		*bcp -= (offset-old_sid_offset);
8961 
8962 		if (qsize) {
8963 			offset = old_offset+qsize;
8964 		}
8965 	}while (qsize);
8966 
8967 
8968 	return offset;
8969 }
8970 
8971 
8972 int
dissect_nt_get_user_quota(tvbuff_t * tvb,proto_tree * tree,int offset,guint32 * bcp)8973 dissect_nt_get_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint32 *bcp)
8974 {
8975 	int     old_offset, old_sid_offset;
8976 	guint32 qsize;
8977 
8978 	do {
8979 		old_offset = offset;
8980 
8981 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
8982 		qsize = tvb_get_letohl(tvb, offset);
8983 		proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8984 		COUNT_BYTES_TRANS_SUBR(4);
8985 
8986 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
8987 		/* length of SID */
8988 		proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8989 		COUNT_BYTES_TRANS_SUBR(4);
8990 
8991 		/* SID of the user */
8992 		old_sid_offset = offset;
8993 		offset = dissect_nt_sid(tvb, offset, tree, "SID", NULL, -1);
8994 		*bcp -= (offset-old_sid_offset);
8995 
8996 		if (qsize) {
8997 			offset = old_offset+qsize;
8998 		}
8999 	}while (qsize);
9000 
9001 
9002 	return offset;
9003 }
9004 
9005 
9006 static int
dissect_nt_trans_data_request(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * parent_tree,int bc,smb_nt_transact_info_t * nti,smb_info_t * si,int subcmd,guint32 sd_len,guint32 ea_len)9007 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, smb_nt_transact_info_t *nti, smb_info_t *si, int subcmd, guint32 sd_len, guint32 ea_len)
9008 {
9009 	proto_tree              *tree;
9010 	int                      old_offset = offset;
9011 	guint16                  bcp        = bc; /* XXX fixme */
9012 	struct access_mask_info *ami        = NULL;
9013 	tvbuff_t                *ioctl_tvb;
9014 
9015 	DISSECTOR_ASSERT(si);
9016 
9017 	tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, -1,
9018 				ett_smb_nt_trans_data, NULL, "%s Data",
9019 				val_to_str_ext(subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
9020 
9021 	switch(subcmd) {
9022 	case NT_TRANS_CREATE:
9023 		/* security descriptor */
9024 		if (sd_len) {
9025 		        offset = dissect_nt_sec_desc(
9026 				tvb, offset, pinfo, tree, NULL, TRUE,
9027 				sd_len, NULL);
9028 		}
9029 
9030 		/* extended attributes */
9031 		if (ea_len) {
9032 			proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ea_len, ENC_NA);
9033 			offset += ea_len;
9034 		}
9035 
9036 		break;
9037 	case NT_TRANS_IOCTL:
9038 		/* ioctl data */
9039 		ioctl_tvb = tvb_new_subset_length_caplen(tvb, offset, MIN((int)bc, tvb_reported_length_remaining(tvb, offset)), bc);
9040 		if (nti) {
9041 			dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, TRUE, NULL);
9042 		}
9043 
9044 		offset += bc;
9045 
9046 		break;
9047 	case NT_TRANS_SSD:
9048 		if (nti) {
9049 			switch(nti->fid_type) {
9050 			case SMB_FID_TYPE_FILE:
9051 				ami = &smb_file_access_mask_info;
9052 				break;
9053 			case SMB_FID_TYPE_DIR:
9054 				ami = &smb_dir_access_mask_info;
9055 				break;
9056 			}
9057 		}
9058 
9059 		offset = dissect_nt_sec_desc(
9060 			tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
9061 
9062 		if (offset < (old_offset + bc)) {
9063 			offset = old_offset + bc;
9064 		}
9065 
9066 		break;
9067 	case NT_TRANS_NOTIFY:
9068 		break;
9069 	case NT_TRANS_RENAME:
9070 		/* XXX not documented */
9071 		break;
9072 	case NT_TRANS_QSD:
9073 		break;
9074 	case NT_TRANS_GET_USER_QUOTA:
9075 		/* unknown 4 bytes */
9076 		proto_tree_add_item(tree, hf_smb_unknown, tvb,
9077 			    offset, 4, ENC_NA);
9078 		offset += 4;
9079 
9080 		/* length of SID */
9081 		proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9082 		offset +=4;
9083 
9084 		offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
9085 		break;
9086 	case NT_TRANS_SET_USER_QUOTA:
9087 		offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
9088 		break;
9089 	}
9090 
9091 	/* ooops there were data we didn't know how to process */
9092 	if ((offset-old_offset) < bc) {
9093 		proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9094 		    bc - (offset-old_offset), ENC_NA);
9095 		offset += bc - (offset-old_offset);
9096 	}
9097 
9098 	return offset;
9099 }
9100 
9101 static int
dissect_nt_trans_param_request(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * parent_tree,int len,guint16 bc,smb_nt_transact_info_t * nti,smb_info_t * si,int subcmd,guint32 * sd_len,guint32 * ea_len)9102 dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, guint16 bc, smb_nt_transact_info_t *nti, smb_info_t *si, int subcmd, guint32 *sd_len, guint32 *ea_len)
9103 {
9104 	proto_tree *tree;
9105 	guint32     fn_len, create_flags, access_mask, share_access, create_options;
9106 	const char *fn;
9107 
9108 	DISSECTOR_ASSERT(si);
9109 
9110 	tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, len,
9111 				ett_smb_nt_trans_param, NULL, "%s Parameters",
9112 				val_to_str_ext(subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
9113 
9114 	switch(subcmd) {
9115 	case NT_TRANS_CREATE:
9116 		/* Create flags */
9117 		create_flags = tvb_get_letohl(tvb, offset);
9118 		offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
9119 		bc -= 4;
9120 
9121 		/* root directory fid */
9122 		proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9123 		COUNT_BYTES(4);
9124 
9125 		/* nt access mask */
9126 		access_mask = tvb_get_letohl(tvb, offset);
9127 		offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
9128 		bc -= 4;
9129 
9130 		/* allocation size */
9131 		proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9132 		COUNT_BYTES(8);
9133 
9134 		/* Extended File Attributes */
9135 		offset = dissect_file_ext_attr(tvb, tree, offset);
9136 		bc -= 4;
9137 
9138 		/* share access */
9139 		share_access = tvb_get_letohl(tvb, offset);
9140 		offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
9141 		bc -= 4;
9142 
9143 		/* create disposition */
9144 		proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9145 		COUNT_BYTES(4);
9146 
9147 		/* create options */
9148 		create_options = tvb_get_letohl(tvb, offset);
9149 		offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
9150 		bc -= 4;
9151 
9152 		/* sd length */
9153 		proto_tree_add_item_ret_uint(tree, hf_smb_sd_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, sd_len);
9154 		COUNT_BYTES(4);
9155 
9156 		/* ea length */
9157 		proto_tree_add_item_ret_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, ea_len);
9158 		COUNT_BYTES(4);
9159 
9160 		/* file name len */
9161 		fn_len = (guint32)tvb_get_letohl(tvb, offset);
9162 		proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9163 		COUNT_BYTES(4);
9164 
9165 		/* impersonation level */
9166 		proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9167 		COUNT_BYTES(4);
9168 
9169 		/* security flags */
9170 		offset = dissect_nt_security_flags(tvb, tree, offset);
9171 		bc -= 1;
9172 
9173 		/* May need to skip alignment padding. */
9174 		if (offset&1) {
9175 			/* pad byte */
9176 			proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
9177 			offset += 1;
9178 		}
9179 
9180 		/* file name */
9181 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
9182 		if (fn != NULL) {
9183 			proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9184 				fn);
9185 			COUNT_BYTES(fn_len);
9186 		}
9187 
9188 		break;
9189 	case NT_TRANS_IOCTL:
9190 		break;
9191 	case NT_TRANS_SSD: {
9192 		guint16 fid;
9193 		smb_fid_info_t *fid_info;
9194 
9195 		/* fid */
9196 		fid = tvb_get_letohs(tvb, offset);
9197 		fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
9198 		offset += 2;
9199 		if (nti) {
9200 			if (fid_info) {
9201 				nti->fid_type = fid_info->type;
9202 			} else {
9203 				nti->fid_type = SMB_FID_TYPE_UNKNOWN;
9204 			}
9205 		}
9206 
9207 		/* 2 reserved bytes */
9208 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
9209 		offset += 2;
9210 
9211 		/* security information */
9212 		offset = dissect_security_information_mask(tvb, tree, offset);
9213 		break;
9214 	}
9215 	case NT_TRANS_NOTIFY:
9216 		break;
9217 	case NT_TRANS_RENAME:
9218 		/* XXX not documented */
9219 		break;
9220 	case NT_TRANS_QSD: {
9221 		guint16 fid;
9222 		smb_fid_info_t *fid_info;
9223 
9224 		/* fid */
9225 		fid = tvb_get_letohs(tvb, offset);
9226 		fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
9227 		offset += 2;
9228 		if (nti) {
9229 			if (fid_info) {
9230 				nti->fid_type = fid_info->type;
9231 			} else {
9232 				nti->fid_type = SMB_FID_TYPE_UNKNOWN;
9233 			}
9234 		}
9235 
9236 		/* 2 reserved bytes */
9237 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
9238 		offset += 2;
9239 
9240 		/* security information */
9241 		offset = dissect_security_information_mask(tvb, tree, offset);
9242 		break;
9243 	}
9244 	case NT_TRANS_GET_USER_QUOTA:
9245 		/* not decoded yet */
9246 		break;
9247 	case NT_TRANS_SET_USER_QUOTA:
9248 		/* not decoded yet */
9249 		break;
9250 	}
9251 
9252 	return offset;
9253 }
9254 
9255 static int
dissect_nt_trans_setup_request(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * parent_tree,int len,smb_info_t * si,int subcmd)9256 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, smb_info_t *si, int subcmd)
9257 {
9258 	proto_tree             *tree;
9259 	smb_nt_transact_info_t *nti  = NULL;
9260 	smb_saved_info_t       *sip;
9261 
9262 	DISSECTOR_ASSERT(si);
9263 	sip = si->sip;
9264 	if (sip && (sip->extra_info_type == SMB_EI_NTI)) {
9265 		nti = (smb_nt_transact_info_t *)sip->extra_info;
9266 	}
9267 
9268 	tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, len,
9269 				ett_smb_nt_trans_setup, NULL, "%s Setup",
9270 				val_to_str_ext(subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
9271 
9272 	switch(subcmd) {
9273 	case NT_TRANS_CREATE:
9274 		offset += len;
9275 		break;
9276 	case NT_TRANS_IOCTL: {
9277 		guint16 fid;
9278 
9279 		/* function code */
9280 		offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, nti ? &nti->ioctl_function : NULL);
9281 
9282 		/* fid */
9283 		fid = tvb_get_letohs(tvb, offset);
9284 		dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
9285 		offset += 2;
9286 
9287 		/* isfsctl */
9288 		proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9289 		offset += 1;
9290 
9291 		/* isflags */
9292 		offset = dissect_nt_ioctl_flags(tvb, tree, offset);
9293 
9294 		break;
9295 	}
9296 	case NT_TRANS_SSD:
9297 		offset += len;
9298 		break;
9299 	case NT_TRANS_NOTIFY: {
9300 		guint16 fid;
9301 
9302 		/* completion filter */
9303 		offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
9304 
9305 		/* fid */
9306 		fid = tvb_get_letohs(tvb, offset);
9307 		dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
9308 		offset += 2;
9309 
9310 		/* watch tree */
9311 		proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9312 		offset += 1;
9313 
9314 		/* reserved byte */
9315 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
9316 		offset += 1;
9317 
9318 		break;
9319 	}
9320 	case NT_TRANS_RENAME:
9321 		/* XXX not documented */
9322 		offset += len;
9323 		break;
9324 	case NT_TRANS_QSD:
9325 		break;
9326 	case NT_TRANS_GET_USER_QUOTA:
9327 		/* not decoded yet */
9328 		offset += len;
9329 		break;
9330 	case NT_TRANS_SET_USER_QUOTA:
9331 		/* not decoded yet */
9332 		offset += len;
9333 		break;
9334 	}
9335 
9336 	return offset;
9337 }
9338 
9339 
9340 static int
dissect_nt_transaction_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)9341 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
9342 {
9343 	guint8                  wc, sc;
9344 	guint32                 pc     = 0, pd = 0, po = 0, dc = 0, od = 0, dd = 0;
9345 	guint32                 td     = 0, tp = 0;
9346 	smb_saved_info_t       *sip;
9347 	int                     subcmd;
9348 	guint32                 sd_len, ea_len;
9349 	guint16                 bc;
9350 	guint32                 padcnt;
9351 	smb_nt_transact_info_t *nti    = NULL;
9352 	fragment_head          *r_fd   = NULL;
9353 	tvbuff_t               *pd_tvb = NULL;
9354 	gboolean                save_fragmented;
9355 
9356 	save_fragmented = pinfo->fragmented;
9357 
9358 	subcmd = 0;
9359 	sd_len = 0;
9360 	ea_len = 0;
9361 
9362 	DISSECTOR_ASSERT(si);
9363 	sip = si->sip;
9364 
9365 	WORD_COUNT;
9366 
9367 	if (wc >= 19) {
9368 		/* primary request */
9369 		/* max setup count */
9370 		proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9371 		offset += 1;
9372 
9373 		/* 2 reserved bytes */
9374 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
9375 		offset += 2;
9376 	} else {
9377 		/* secondary request */
9378 		/* 3 reserved bytes */
9379 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
9380 		offset += 3;
9381 	}
9382 
9383 
9384 	/* total param count */
9385 	tp = tvb_get_letohl(tvb, offset);
9386 	proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9387 	offset += 4;
9388 
9389 	/* total data count */
9390 	td = tvb_get_letohl(tvb, offset);
9391 	proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9392 	offset += 4;
9393 
9394 	if (wc >= 19) {
9395 		/* primary request */
9396 		/* max param count */
9397 		proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9398 		offset += 4;
9399 
9400 		/* max data count */
9401 		proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9402 		offset += 4;
9403 	}
9404 
9405 	/* param count */
9406 	pc = tvb_get_letohl(tvb, offset);
9407 	proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9408 	offset += 4;
9409 
9410 	/* param offset */
9411 	po = tvb_get_letohl(tvb, offset);
9412 	proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9413 	offset += 4;
9414 
9415 	/* param displacement */
9416 	if (wc >= 19) {
9417 		/* primary request*/
9418 	} else {
9419 		/* secondary request */
9420 
9421 		proto_tree_add_item(tree, hf_smb_param_disp32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9422 		offset += 4;
9423 	}
9424 
9425 	/* data count */
9426 	dc = tvb_get_letohl(tvb, offset);
9427 	proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9428 	offset += 4;
9429 
9430 	/* data offset */
9431 	od = tvb_get_letohl(tvb, offset);
9432 	proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9433 	offset += 4;
9434 
9435 	/* data displacement */
9436 	if (wc >= 19) {
9437 		/* primary request */
9438 	} else {
9439 		/* secondary request */
9440 		dd = tvb_get_letohl(tvb, offset);
9441 		proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9442 		offset += 4;
9443 	}
9444 
9445 	/* setup count */
9446 	if (wc >= 19) {
9447 		/* primary request */
9448 		sc = tvb_get_guint8(tvb, offset);
9449 		proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9450 		offset += 1;
9451 	} else {
9452 		/* secondary request */
9453 		sc = 0;
9454 	}
9455 
9456 	/* function */
9457 	if (wc >= 19) {
9458 		/* primary request */
9459 		subcmd = tvb_get_letohs(tvb, offset);
9460 		proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
9461 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9462 				val_to_str_ext_const(subcmd, &nt_cmd_vals_ext, "<unknown>"));
9463 
9464 		if (!si->unidir && sip) {
9465 			if (!pinfo->fd->visited) {
9466 				/*
9467 				 * Allocate a new smb_nt_transact_info_t
9468 				 * structure.
9469 				 */
9470 				nti = wmem_new(wmem_file_scope(), smb_nt_transact_info_t);
9471 				nti->subcmd = subcmd;
9472 				nti->fid_type = SMB_FID_TYPE_UNKNOWN;
9473 				nti->ioctl_function = 0;
9474 				sip->extra_info = nti;
9475 				sip->extra_info_type = SMB_EI_NTI;
9476 			} else {
9477 				if (sip->extra_info_type == SMB_EI_NTI) {
9478 					nti = (smb_nt_transact_info_t *)sip->extra_info;
9479 				}
9480 			}
9481 		}
9482 	} else {
9483 		/* secondary request */
9484 		col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
9485 	}
9486 	offset += 2;
9487 
9488 #if 0	/* XXX this is a padding byte?  I don't think so. -gwr */
9489 	if (offset&1) {
9490 		/* pad byte */
9491 	        proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
9492 		offset += 1;
9493 	}
9494 #endif
9495 
9496 	/* if there were any setup bytes, decode them */
9497 	if (sc) {
9498 		dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, si, subcmd);
9499 		offset += sc*2;
9500 	}
9501 
9502 	/*
9503 	 * Do we really need to even look at the byte count here?
9504 	 * Servers normally use byte_count only when assembling the
9505 	 * setup, parameters, and data segments.  Once we know
9506 	 * how long each of those are, we should dissect them
9507 	 * using the lengths determined during assembly.
9508 	 */
9509 	BYTE_COUNT;
9510 
9511 	/* reassembly of SMB NT Transaction data payload.
9512 	   In this section we do reassembly of both the data and parameters
9513 	   blocks of the SMB transaction command.
9514 	*/
9515 	/* do we need reassembly? */
9516 	if ( (td && (td != dc)) || (tp && (tp != pc)) ) {
9517 		/* oh yeah, either data or parameter section needs
9518 		   reassembly...
9519 		*/
9520 		pinfo->fragmented = TRUE;
9521 		if (smb_trans_reassembly) {
9522 			/* ...and we were told to do reassembly */
9523 			if (pc) {
9524 				r_fd = smb_trans_defragment(tree, pinfo, tvb,
9525 							     po, pc, pd, td+tp, si);
9526 			}
9527 			if ((r_fd == NULL) && dc) {
9528 				r_fd = smb_trans_defragment(tree, pinfo, tvb,
9529 							     od, dc, dd+tp, td+tp, si);
9530 			}
9531 		}
9532 	}
9533 
9534 	/* if we got a reassembled fd structure from the reassembly routine we
9535 	   must create pd_tvb from it
9536 	*/
9537 	if (r_fd) {
9538 		proto_item *frag_tree_item;
9539 
9540 		pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
9541 		add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9542 
9543 		show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9544 	}
9545 
9546 	if (pd_tvb) {
9547 	  /* we have reassembled data, grab param and data from there */
9548 	  dissect_nt_trans_param_request(pd_tvb, pinfo, 0, tree, tp,
9549 					 (guint16) tvb_reported_length(pd_tvb),
9550 					 nti, si, subcmd, &sd_len, &ea_len);
9551 	  dissect_nt_trans_data_request(pd_tvb, pinfo, tp, tree, td, nti, si,
9552 					subcmd, sd_len, ea_len);
9553 	  COUNT_BYTES(bc); /* We are done */
9554 	} else {
9555 	  /* we do not have reassembled data, just use what we have in the
9556 	     packet as well as we can */
9557 	  /* parameters */
9558 	  if (po > (guint32)offset) {
9559 		/* We have some initial padding bytes.
9560 		*/
9561 		padcnt = po-offset;
9562 		if (padcnt > bc)
9563 			padcnt = bc;
9564 		CHECK_BYTE_COUNT(padcnt);
9565 	        proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9566 		COUNT_BYTES(padcnt);
9567 	  }
9568 	  if (pc) {
9569 		CHECK_BYTE_COUNT(pc);
9570 		dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, bc,
9571 					       nti, si, subcmd, &sd_len, &ea_len);
9572 		COUNT_BYTES(pc);
9573 	  }
9574 
9575 	  /* data */
9576 	  if (od > (guint32)offset) {
9577 		/* We have some initial padding bytes.
9578 		*/
9579 		padcnt = od-offset;
9580 		if (padcnt > bc)
9581 			padcnt = bc;
9582 	        proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9583 		COUNT_BYTES(padcnt);
9584 	  }
9585 	  if (dc) {
9586 		CHECK_BYTE_COUNT(dc);
9587 		dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc,
9588 					      nti, si, subcmd, sd_len, ea_len);
9589 		COUNT_BYTES(dc);
9590 	  }
9591 	}
9592 
9593 	END_OF_SMB
9594 
9595 	pinfo->fragmented = save_fragmented;
9596 	return offset;
9597 }
9598 
9599 
9600 
9601 static int
dissect_nt_trans_data_response(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * parent_tree,int len,smb_nt_transact_info_t * nti,smb_info_t * si)9602 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
9603 			       int offset, proto_tree *parent_tree, int len,
9604 			       smb_nt_transact_info_t *nti, smb_info_t *si)
9605 {
9606 	proto_tree              *tree = NULL;
9607 	guint16                  bcp;
9608 	struct access_mask_info *ami  = NULL;
9609 	tvbuff_t                *ioctl_tvb;
9610 
9611 	DISSECTOR_ASSERT(si);
9612 
9613 	if (parent_tree) {
9614 		if (nti != NULL) {
9615 			tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, len,
9616 				ett_smb_nt_trans_data, NULL, "%s Data",
9617 				val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9618 		} else {
9619 			/*
9620 			 * We never saw the request to which this is a
9621 			 * response.
9622 			 */
9623 			tree = proto_tree_add_subtree(parent_tree, tvb, offset, len,
9624 				ett_smb_nt_trans_data, NULL, "Unknown NT Transaction Data (matching request not seen)");
9625 		}
9626 	}
9627 
9628 	if (nti == NULL) {
9629 		offset += len;
9630 		return offset;
9631 	}
9632 	switch(nti->subcmd) {
9633 	case NT_TRANS_CREATE:
9634 		break;
9635 	case NT_TRANS_IOCTL:
9636 		/* ioctl data */
9637 		ioctl_tvb = tvb_new_subset_length_caplen(tvb, offset, MIN((int)len, tvb_reported_length_remaining(tvb, offset)), len);
9638 		dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, FALSE, NULL);
9639 
9640 		offset += len;
9641 
9642 		break;
9643 	case NT_TRANS_SSD:
9644 		break;
9645 	case NT_TRANS_NOTIFY:
9646 		break;
9647 	case NT_TRANS_RENAME:
9648 		/* XXX not documented */
9649 		break;
9650 	case NT_TRANS_QSD:
9651 		if (nti) {
9652 			switch(nti->fid_type) {
9653 			case SMB_FID_TYPE_FILE:
9654 				ami = &smb_file_access_mask_info;
9655 				break;
9656 			case SMB_FID_TYPE_DIR:
9657 				ami = &smb_dir_access_mask_info;
9658 				break;
9659 			}
9660 		}
9661 		offset = dissect_nt_sec_desc(
9662 			tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
9663 		break;
9664 	case NT_TRANS_GET_USER_QUOTA:
9665 		bcp = len;
9666 		offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
9667 		break;
9668 	case NT_TRANS_SET_USER_QUOTA:
9669 		/* not decoded yet */
9670 		break;
9671 	}
9672 
9673 	return offset;
9674 }
9675 
9676 static int
dissect_nt_trans_param_response(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * parent_tree,int len,guint16 bc,smb_info_t * si)9677 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
9678 				int offset, proto_tree *parent_tree,
9679 				int len, guint16 bc, smb_info_t *si)
9680 {
9681 	proto_tree             *tree     = NULL;
9682 	guint32                 fn_len;
9683 	const char             *fn;
9684 	smb_nt_transact_info_t *nti;
9685 	guint16                 fid;
9686 	int                     old_offset;
9687 	guint32                 neo;
9688 	int                     padcnt;
9689 	smb_fid_info_t         *fid_info = NULL;
9690 	guint16                 ftype;
9691 	guint8                  isdir;
9692 	guint8                  ext_resp = 0;
9693 
9694 	DISSECTOR_ASSERT(si);
9695 
9696 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9697 		nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9698 	else
9699 		nti = NULL;
9700 
9701 	if (parent_tree) {
9702 		if (nti != NULL) {
9703 			tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, len,
9704 				ett_smb_nt_trans_param, NULL, "%s Parameters",
9705 				val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9706 		} else {
9707 			/*
9708 			 * We never saw the request to which this is a
9709 			 * response.
9710 			 */
9711 			tree = proto_tree_add_subtree(parent_tree, tvb, offset, len,
9712 				ett_smb_nt_trans_param, NULL, "Unknown NT Transaction Parameters (matching request not seen)");
9713 		}
9714 	}
9715 
9716 	if (nti == NULL) {
9717 		offset += len;
9718 		return offset;
9719 	}
9720 	switch(nti->subcmd) {
9721 	case NT_TRANS_CREATE:
9722 		/* oplock level */
9723 	        proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9724 		offset += 1;
9725 
9726 		/* response type, as per MS-SMB 2.2.7.1.2 */
9727 		ext_resp = tvb_get_guint8(tvb, offset);
9728 	        proto_tree_add_item(tree, hf_smb_response_type, tvb, offset, 1, ENC_NA);
9729 		offset += 1;
9730 
9731 		/* fid */
9732 		fid = tvb_get_letohs(tvb, offset);
9733 		fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
9734 		offset += 2;
9735 
9736 		/* create action */
9737 		proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9738 		offset += 4;
9739 
9740 		/* ea error offset */
9741 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9742 		offset += 4;
9743 
9744 		/* create time */
9745 		offset = dissect_nt_64bit_time(tvb, tree, offset,
9746 			hf_smb_create_time);
9747 
9748 		/* access time */
9749 		offset = dissect_nt_64bit_time(tvb, tree, offset,
9750 			hf_smb_access_time);
9751 
9752 		/* last write time */
9753 		offset = dissect_nt_64bit_time(tvb, tree, offset,
9754 			hf_smb_last_write_time);
9755 
9756 		/* last change time */
9757 		offset = dissect_nt_64bit_time(tvb, tree, offset,
9758 			hf_smb_change_time);
9759 
9760 		/* Extended File Attributes */
9761 		offset = dissect_file_ext_attr(tvb, tree, offset);
9762 
9763 		/* allocation size */
9764 		proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9765 		offset += 8;
9766 
9767 		/* end of file */
9768 		proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9769 		offset += 8;
9770 
9771 		/* File Type */
9772 		ftype = tvb_get_letohs(tvb, offset);
9773 		proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9774 		offset += 2;
9775 
9776 		/* device state */
9777 		offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9778 
9779 		/* is directory */
9780 		isdir = tvb_get_guint8(tvb, offset);
9781 		proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9782 		offset += 1;
9783 
9784 		/* decode extended response per [MS-SMB] 2.2.7.1.2
9785 		   (volume_guid, file_id, max_acc, guest_acc)
9786 		   Just like dissect_nt_create_andx_response */
9787 		if (ext_resp != 0) {
9788 			proto_tree *tr = NULL;
9789 
9790 			/* The first field is a Volume GUID ... */
9791 			proto_tree_add_item(tree, hf_smb_volume_guid,
9792 					    tvb, offset, 16, ENC_NA);
9793 			offset += 16;
9794 
9795 			/* The file ID comes next */
9796 			proto_tree_add_item(tree, hf_smb_file_id_64bit,
9797 					    tvb, offset, 8, ENC_LITTLE_ENDIAN);
9798 			offset += 8;
9799 
9800 			tr = proto_tree_add_subtree(tree, tvb, offset, 4,
9801 				ett_smb_nt_access_mask, NULL, "Maximal Access Rights");
9802 			offset = dissect_smb_access_mask(tvb, tr, offset);
9803 
9804 			tr = proto_tree_add_subtree(tree, tvb, offset, 4,
9805 				ett_smb_nt_access_mask, NULL, "Guest Maximal Access Rights");
9806 			offset = dissect_smb_access_mask(tvb, tr, offset);
9807 		}
9808 
9809 		/* Try to remember the type of this fid so that we can dissect
9810 		 * any future security descriptor (access mask) properly
9811 		 */
9812 		if (ftype == 0) {
9813 			if (isdir == 0) {
9814 				if (fid_info) {
9815 					fid_info->type = SMB_FID_TYPE_FILE;
9816 				}
9817 			} else {
9818 				if (fid_info) {
9819 					fid_info->type = SMB_FID_TYPE_DIR;
9820 				}
9821 			}
9822 		}
9823 		if (ftype == 2) {
9824 			if (fid_info) {
9825 				fid_info->type = SMB_FID_TYPE_PIPE;
9826 			}
9827 		}
9828 		break;
9829 	case NT_TRANS_IOCTL:
9830 		break;
9831 	case NT_TRANS_SSD:
9832 		break;
9833 	case NT_TRANS_NOTIFY:
9834 		while (len) {
9835 			old_offset = offset;
9836 
9837 			/* next entry offset */
9838 			neo = tvb_get_letohl(tvb, offset);
9839 			proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9840 			COUNT_BYTES(4);
9841 			len -= 4;
9842 			/* broken implementations */
9843 			if (len < 0) break;
9844 
9845 			/* action */
9846 			proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9847 			COUNT_BYTES(4);
9848 			len -= 4;
9849 			/* broken implementations */
9850 			if (len < 0) break;
9851 
9852 			/* file name len */
9853 			fn_len = (guint32)tvb_get_letohl(tvb, offset);
9854 			proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9855 			COUNT_BYTES(4);
9856 			len -= 4;
9857 			/* broken implementations */
9858 			if (len < 0) break;
9859 
9860 			/* file name */
9861 			fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
9862 			if (fn == NULL)
9863 				break;
9864 			proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9865 				fn);
9866 			COUNT_BYTES(fn_len);
9867 			len -= fn_len;
9868 			/* broken implementations */
9869 			if (len < 0) break;
9870 
9871 			if (neo == 0)
9872 				break;	/* no more structures */
9873 
9874 			/* skip to next structure */
9875 			padcnt = (old_offset + neo) - offset;
9876 			if (padcnt < 0) {
9877 				/*
9878 				 * XXX - this is bogus; flag it?
9879 				 */
9880 				padcnt = 0;
9881 			}
9882 			if (padcnt != 0) {
9883 				COUNT_BYTES(padcnt);
9884 				len -= padcnt;
9885 				/* broken implementations */
9886 				if (len < 0) break;
9887 			}
9888 		}
9889 		break;
9890 	case NT_TRANS_RENAME:
9891 		/* XXX not documented */
9892 		break;
9893 	case NT_TRANS_QSD:
9894 		/*
9895 		 * This appears to be the size of the security
9896 		 * descriptor; the calling sequence of
9897 		 * "ZwQuerySecurityObject()" suggests that it would
9898 		 * be.  The actual security descriptor wouldn't
9899 		 * follow if the max data count in the request
9900 		 * was smaller; this lets the client know how
9901 		 * big a buffer it needs to provide.
9902 		 */
9903 		proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9904 		offset += 4;
9905 		break;
9906 	case NT_TRANS_GET_USER_QUOTA:
9907 		proto_tree_add_item(tree, hf_smb_size_returned_quota_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9908 		offset += 4;
9909 		break;
9910 	case NT_TRANS_SET_USER_QUOTA:
9911 		/* not decoded yet */
9912 		break;
9913 	}
9914 
9915 	return offset;
9916 }
9917 
9918 static int
dissect_nt_trans_setup_response(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * parent_tree,int len,smb_info_t * si)9919 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
9920 				int offset, proto_tree *parent_tree,
9921 				int len, smb_info_t *si)
9922 {
9923 	smb_nt_transact_info_t *nti;
9924 
9925 	DISSECTOR_ASSERT(si);
9926 
9927 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9928 		nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9929 	else
9930 		nti = NULL;
9931 
9932 	if (parent_tree) {
9933 		if (nti != NULL) {
9934 			proto_tree_add_bytes_format(parent_tree, hf_smb_nt_transaction_setup, tvb, offset, len,
9935 				NULL, "%s Setup",
9936 				val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9937 		} else {
9938 			/*
9939 			 * We never saw the request to which this is a
9940 			 * response.
9941 			 */
9942 			proto_tree_add_expert(parent_tree, pinfo, &ei_smb_nt_transaction_setup, tvb, offset, len);
9943 		}
9944 	}
9945 
9946 	if (nti == NULL) {
9947 		offset += len;
9948 		return offset;
9949 	}
9950 	switch(nti->subcmd) {
9951 	case NT_TRANS_CREATE:
9952 		break;
9953 	case NT_TRANS_IOCTL:
9954 		break;
9955 	case NT_TRANS_SSD:
9956 		break;
9957 	case NT_TRANS_NOTIFY:
9958 		break;
9959 	case NT_TRANS_RENAME:
9960 		/* XXX not documented */
9961 		break;
9962 	case NT_TRANS_QSD:
9963 		break;
9964 	case NT_TRANS_GET_USER_QUOTA:
9965 		/* not decoded yet */
9966 		break;
9967 	case NT_TRANS_SET_USER_QUOTA:
9968 		/* not decoded yet */
9969 		break;
9970 	}
9971 
9972 	return offset;
9973 }
9974 
9975 static int
dissect_nt_transaction_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)9976 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
9977 {
9978 	guint8                  wc, sc;
9979 	guint32                 pc     = 0, po = 0, pd = 0, dc = 0, od = 0, dd = 0;
9980 	guint32                 td     = 0, tp = 0;
9981 	smb_nt_transact_info_t *nti    = NULL;
9982 	guint16                 bc;
9983 	gint32                  padcnt;
9984 	fragment_head          *r_fd   = NULL;
9985 	tvbuff_t               *pd_tvb = NULL;
9986 	gboolean                save_fragmented;
9987 
9988 	DISSECTOR_ASSERT(si);
9989 
9990 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9991 		nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9992 	else
9993 		nti = NULL;
9994 
9995 	/* primary request */
9996 	if (nti != NULL) {
9997 		proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9998 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9999 				val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "<unknown (%u)>"));
10000 	} else {
10001 		proto_tree_add_uint_format_value(tree, hf_smb_nt_trans_subcmd, tvb, offset, 0, -1,
10002 			"<unknown function - could not find matching request>");
10003 		col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
10004 	}
10005 
10006 	WORD_COUNT;
10007 
10008 	/* 3 reserved bytes */
10009 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
10010 	offset += 3;
10011 
10012 	/* total param count */
10013 	tp = tvb_get_letohl(tvb, offset);
10014 	proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
10015 	offset += 4;
10016 
10017 	/* total data count */
10018 	td = tvb_get_letohl(tvb, offset);
10019 	proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
10020 	offset += 4;
10021 
10022 	/* param count */
10023 	pc = tvb_get_letohl(tvb, offset);
10024 	proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
10025 	offset += 4;
10026 
10027 	/* param offset */
10028 	po = tvb_get_letohl(tvb, offset);
10029 	proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
10030 	offset += 4;
10031 
10032 	/* param displacement */
10033 	pd = tvb_get_letohl(tvb, offset);
10034 	proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
10035 	offset += 4;
10036 
10037 	/* data count */
10038 	dc = tvb_get_letohl(tvb, offset);
10039 	proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
10040 	offset += 4;
10041 
10042 	/* data offset */
10043 	od = tvb_get_letohl(tvb, offset);
10044 	proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
10045 	offset += 4;
10046 
10047 	/* data displacement */
10048 	dd = tvb_get_letohl(tvb, offset);
10049 	proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
10050 	offset += 4;
10051 
10052 	/* setup count */
10053 	sc = tvb_get_guint8(tvb, offset);
10054 	proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
10055 	offset += 1;
10056 
10057 	/* setup data */
10058 	if (sc) {
10059 		dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, si);
10060 		offset += sc*2;
10061 	}
10062 
10063 	BYTE_COUNT;
10064 
10065 	/* reassembly of SMB NT Transaction data payload.
10066 	   In this section we do reassembly of both the data and parameters
10067 	   blocks of the SMB transaction command.
10068 	*/
10069 	save_fragmented = pinfo->fragmented;
10070 	/* do we need reassembly? */
10071 	if ( (td && (td != dc)) || (tp && (tp != pc)) ) {
10072 		/* oh yeah, either data or parameter section needs
10073 		   reassembly...
10074 		*/
10075 		pinfo->fragmented = TRUE;
10076 		if (smb_trans_reassembly) {
10077 			/* ...and we were told to do reassembly */
10078 			if (pc) {
10079 				r_fd = smb_trans_defragment(tree, pinfo, tvb,
10080 							     po, pc, pd, td+tp, si);
10081 
10082 			}
10083 			if ((r_fd == NULL) && dc) {
10084 				r_fd = smb_trans_defragment(tree, pinfo, tvb,
10085 							     od, dc, dd+tp, td+tp, si);
10086 			}
10087 		}
10088 	}
10089 
10090 	/* if we got a reassembled fd structure from the reassembly routine we
10091 	   must create pd_tvb from it
10092 	*/
10093 	if (r_fd) {
10094 		proto_item *frag_tree_item;
10095 
10096 		pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
10097 		add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
10098 
10099 		show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
10100 	}
10101 
10102 
10103 	if (pd_tvb) {
10104 	  /* we have reassembled data, grab param and data from there */
10105 	  dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
10106 					  (guint16) tvb_reported_length(pd_tvb), si);
10107 	  dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, nti, si);
10108 	  COUNT_BYTES(bc); /* We are done */
10109 	} else {
10110 	  /* we do not have reassembled data, just use what we have in the
10111 	     packet as well as we can */
10112 	  /* parameters */
10113 	  if (po > (guint32)offset) {
10114 	    /* We have some initial padding bytes.
10115 	     */
10116 	    padcnt = po-offset;
10117 	    if (padcnt > bc)
10118 	      padcnt = bc;
10119 	    CHECK_BYTE_COUNT(padcnt);
10120 	    proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
10121 	    COUNT_BYTES(padcnt);
10122 	  }
10123 	  if (pc) {
10124 	    CHECK_BYTE_COUNT(pc);
10125 	    dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, bc, si);
10126 	    COUNT_BYTES(pc);
10127 	  }
10128 
10129 	  /* data */
10130 	  if (od > (guint32)offset) {
10131 	    /* We have some initial padding bytes.
10132 	     */
10133 	    padcnt = od-offset;
10134 	    if (padcnt > bc)
10135 	      padcnt = bc;
10136 	    proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
10137 	    COUNT_BYTES(padcnt);
10138 	  }
10139 	  if (dc) {
10140 	    CHECK_BYTE_COUNT(dc);
10141 	    dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, nti, si);
10142 	    COUNT_BYTES(dc);
10143 	  }
10144 	}
10145 	pinfo->fragmented = save_fragmented;
10146 
10147 	END_OF_SMB
10148 
10149 	return offset;
10150 }
10151 
10152 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10153    NT Transaction command  ends here
10154    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
10155 
10156 static const value_string print_mode_vals[] = {
10157 	{0,	"Text Mode"},
10158 	{1,	"Graphics Mode"},
10159 	{0, NULL}
10160 };
10161 
10162 static int
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)10163 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)
10164 {
10165 	int         fn_len;
10166 	const char *fn;
10167 	guint8      wc;
10168 	guint16     bc;
10169 
10170 	DISSECTOR_ASSERT(si);
10171 
10172 	WORD_COUNT;
10173 
10174 	/* setup len */
10175 	proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10176 	offset += 2;
10177 
10178 	/* print mode */
10179 	proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10180 	offset += 2;
10181 
10182 	BYTE_COUNT;
10183 
10184 	/* buffer format */
10185 	CHECK_BYTE_COUNT(1);
10186 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10187 	COUNT_BYTES(1);
10188 
10189 	/* print identifier */
10190 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
10191 	if (fn == NULL)
10192 		goto endofcommand;
10193 	proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
10194 		fn);
10195 	COUNT_BYTES(fn_len);
10196 
10197 	END_OF_SMB
10198 
10199 	return offset;
10200 }
10201 
10202 
10203 static int
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)10204 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)
10205 {
10206 	int     cnt;
10207 	guint8  wc;
10208 	guint16 bc, fid;
10209 
10210 	WORD_COUNT;
10211 
10212 	/* fid */
10213 	fid = tvb_get_letohs(tvb, offset);
10214 	dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
10215 	offset += 2;
10216 
10217 	BYTE_COUNT;
10218 
10219 	/* buffer format */
10220 	CHECK_BYTE_COUNT(1);
10221 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10222 	COUNT_BYTES(1);
10223 
10224 	/* data len */
10225 	CHECK_BYTE_COUNT(2);
10226 	cnt = tvb_get_letohs(tvb, offset);
10227 	proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
10228 	COUNT_BYTES(2);
10229 
10230 	/* file data */
10231 	offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
10232 
10233 	END_OF_SMB
10234 
10235 	return offset;
10236 }
10237 
10238 
10239 static const value_string print_status_vals[] = {
10240 	{1,	"Held or Stopped"},
10241 	{2,	"Printing"},
10242 	{3,	"Awaiting print"},
10243 	{4,	"In intercept"},
10244 	{5,	"File had error"},
10245 	{6,	"Printer error"},
10246 	{0, NULL}
10247 };
10248 
10249 static int
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_)10250 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_)
10251 {
10252 	guint8  wc;
10253 	guint16 bc;
10254 
10255 	WORD_COUNT;
10256 
10257 	/* max count */
10258 	proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10259 	offset += 2;
10260 
10261 	/* start index */
10262 	proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10263 	offset += 2;
10264 
10265 	BYTE_COUNT;
10266 
10267 	END_OF_SMB
10268 
10269 	return offset;
10270 }
10271 
10272 static int
dissect_print_queue_element(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)10273 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo _U_,
10274     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
10275 {
10276 	proto_tree *tree;
10277 	int         fn_len;
10278 	const char *fn;
10279 
10280 	DISSECTOR_ASSERT(si);
10281 
10282 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, 28,
10283 			ett_smb_print_queue_entry, NULL, "Queue entry");
10284 
10285 	/* queued time */
10286 	CHECK_BYTE_COUNT_SUBR(4);
10287 	offset = dissect_smb_datetime(tvb, tree, offset,
10288 		hf_smb_print_queue_date,
10289 		hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
10290 	*bcp -= 4;
10291 
10292 	/* status */
10293 	CHECK_BYTE_COUNT_SUBR(1);
10294 	proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10295 	COUNT_BYTES_SUBR(1);
10296 
10297 	/* spool file number */
10298 	CHECK_BYTE_COUNT_SUBR(2);
10299 	proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10300 	COUNT_BYTES_SUBR(2);
10301 
10302 	/* spool file size */
10303 	CHECK_BYTE_COUNT_SUBR(4);
10304 	proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10305 	COUNT_BYTES_SUBR(4);
10306 
10307 	/* reserved byte */
10308 	CHECK_BYTE_COUNT_SUBR(1);
10309 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10310 	COUNT_BYTES_SUBR(1);
10311 
10312 	/* file name */
10313 	fn_len = 16;
10314 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
10315 	CHECK_STRING_SUBR(fn);
10316 	proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
10317 		fn);
10318 	COUNT_BYTES_SUBR(fn_len);
10319 
10320 	*trunc = FALSE;
10321 	return offset;
10322 }
10323 
10324 static int
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_)10325 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_)
10326 {
10327 	guint16  cnt = 0, len;
10328 	guint8   wc;
10329 	guint16  bc;
10330 	gboolean trunc;
10331 
10332 	WORD_COUNT;
10333 
10334 	/* count */
10335 	cnt = tvb_get_letohs(tvb, offset);
10336 	proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
10337 	offset += 2;
10338 
10339 	/* restart index */
10340 	proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10341 	offset += 2;
10342 
10343 	BYTE_COUNT;
10344 
10345 	/* buffer format */
10346 	CHECK_BYTE_COUNT(1);
10347 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10348 	COUNT_BYTES(1);
10349 
10350 	/* data len */
10351 	CHECK_BYTE_COUNT(2);
10352 	len = tvb_get_letohs(tvb, offset);
10353 	proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
10354 	COUNT_BYTES(2);
10355 
10356 	/* queue elements */
10357 	while (cnt--) {
10358 		offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
10359 		    &bc, &trunc, si);
10360 		if (trunc)
10361 			goto endofcommand;
10362 	}
10363 
10364 	END_OF_SMB
10365 
10366 	return offset;
10367 }
10368 
10369 
10370 static int
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_)10371 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_)
10372 {
10373 	int     name_len;
10374 	guint16 bc;
10375 	guint8  wc;
10376 	guint16 message_len;
10377 
10378 	WORD_COUNT;
10379 
10380 	BYTE_COUNT;
10381 
10382 	/* buffer format */
10383 	CHECK_BYTE_COUNT(1);
10384 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10385 	COUNT_BYTES(1);
10386 
10387 	/* originator name */
10388 	/* XXX - what if this runs past bc? */
10389 	name_len = tvb_strsize(tvb, offset);
10390 	CHECK_BYTE_COUNT(name_len);
10391 	proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
10392 	    name_len, ENC_ASCII|ENC_NA);
10393 	COUNT_BYTES(name_len);
10394 
10395 	/* buffer format */
10396 	CHECK_BYTE_COUNT(1);
10397 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10398 	COUNT_BYTES(1);
10399 
10400 	/* destination name */
10401 	/* XXX - what if this runs past bc? */
10402 	name_len = tvb_strsize(tvb, offset);
10403 	CHECK_BYTE_COUNT(name_len);
10404 	proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
10405 	    name_len, ENC_ASCII|ENC_NA);
10406 	COUNT_BYTES(name_len);
10407 
10408 	/* buffer format */
10409 	CHECK_BYTE_COUNT(1);
10410 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10411 	COUNT_BYTES(1);
10412 
10413 	/* message len */
10414 	CHECK_BYTE_COUNT(2);
10415 	message_len = tvb_get_letohs(tvb, offset);
10416 	proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
10417 	    message_len);
10418 	COUNT_BYTES(2);
10419 
10420 	/* message */
10421 	CHECK_BYTE_COUNT(message_len);
10422 	proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
10423 	    ENC_ASCII|ENC_NA);
10424 	COUNT_BYTES(message_len);
10425 
10426 	END_OF_SMB
10427 
10428 	return offset;
10429 }
10430 
10431 static int
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_)10432 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_)
10433 {
10434 	int     name_len;
10435 	guint16 bc;
10436 	guint8  wc;
10437 
10438 	WORD_COUNT;
10439 
10440 	BYTE_COUNT;
10441 
10442 	/* buffer format */
10443 	CHECK_BYTE_COUNT(1);
10444 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10445 	COUNT_BYTES(1);
10446 
10447 	/* originator name */
10448 	/* XXX - what if this runs past bc? */
10449 	name_len = tvb_strsize(tvb, offset);
10450 	CHECK_BYTE_COUNT(name_len);
10451 	proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
10452 	    name_len, ENC_ASCII|ENC_NA);
10453 	COUNT_BYTES(name_len);
10454 
10455 	/* buffer format */
10456 	CHECK_BYTE_COUNT(1);
10457 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10458 	COUNT_BYTES(1);
10459 
10460 	/* destination name */
10461 	/* XXX - what if this runs past bc? */
10462 	name_len = tvb_strsize(tvb, offset);
10463 	CHECK_BYTE_COUNT(name_len);
10464 	proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
10465 	    name_len, ENC_ASCII|ENC_NA);
10466 	COUNT_BYTES(name_len);
10467 
10468 	END_OF_SMB
10469 
10470 	return offset;
10471 }
10472 
10473 static int
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_)10474 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_)
10475 {
10476 	guint16 bc;
10477 	guint8  wc;
10478 
10479 	WORD_COUNT;
10480 
10481 	/* message group ID */
10482 	proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10483 	offset += 2;
10484 
10485 	BYTE_COUNT;
10486 
10487 	END_OF_SMB
10488 
10489 	return offset;
10490 }
10491 
10492 static int
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_)10493 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_)
10494 {
10495 	guint16 bc;
10496 	guint8  wc;
10497 	guint16 message_len;
10498 
10499 	WORD_COUNT;
10500 
10501 	BYTE_COUNT;
10502 
10503 	/* buffer format */
10504 	CHECK_BYTE_COUNT(1);
10505 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10506 	COUNT_BYTES(1);
10507 
10508 	/* message len */
10509 	CHECK_BYTE_COUNT(2);
10510 	message_len = tvb_get_letohs(tvb, offset);
10511 	proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
10512 	    message_len);
10513 	COUNT_BYTES(2);
10514 
10515 	/* message */
10516 	CHECK_BYTE_COUNT(message_len);
10517 	proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
10518 	    ENC_ASCII|ENC_NA);
10519 	COUNT_BYTES(message_len);
10520 
10521 	END_OF_SMB
10522 
10523 	return offset;
10524 }
10525 
10526 static int
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_)10527 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_)
10528 {
10529 	int     name_len;
10530 	guint16 bc;
10531 	guint8  wc;
10532 
10533 	WORD_COUNT;
10534 
10535 	BYTE_COUNT;
10536 
10537 	/* buffer format */
10538 	CHECK_BYTE_COUNT(1);
10539 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10540 	COUNT_BYTES(1);
10541 
10542 	/* forwarded name */
10543 	/* XXX - what if this runs past bc? */
10544 	name_len = tvb_strsize(tvb, offset);
10545 	CHECK_BYTE_COUNT(name_len);
10546 	proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
10547 	    name_len, ENC_ASCII|ENC_NA);
10548 	COUNT_BYTES(name_len);
10549 
10550 	END_OF_SMB
10551 
10552 	return offset;
10553 }
10554 
10555 static int
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_)10556 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_)
10557 {
10558 	int     name_len;
10559 	guint16 bc;
10560 	guint8  wc;
10561 
10562 	WORD_COUNT;
10563 
10564 	BYTE_COUNT;
10565 
10566 	/* buffer format */
10567 	CHECK_BYTE_COUNT(1);
10568 	proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10569 	COUNT_BYTES(1);
10570 
10571 	/* machine name */
10572 	/* XXX - what if this runs past bc? */
10573 	name_len = tvb_strsize(tvb, offset);
10574 	CHECK_BYTE_COUNT(name_len);
10575 	proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
10576 	    name_len, ENC_ASCII|ENC_NA);
10577 	COUNT_BYTES(name_len);
10578 
10579 	END_OF_SMB
10580 
10581 	return offset;
10582 }
10583 
10584 
10585 static int
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_)10586 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_)
10587 {
10588 	guint8      wc, cmd      = 0xff;
10589 	guint16     andxoffset   = 0;
10590 	guint16     bc;
10591 	int         fn_len       = -1;
10592 	const char *fn;
10593 	guint32     create_flags = 0, access_mask = 0, file_attributes = 0;
10594 	guint32     share_access = 0, create_options = 0, create_disposition = 0;
10595 
10596 	DISSECTOR_ASSERT(si);
10597 
10598 	WORD_COUNT;
10599 
10600 	/* next smb command */
10601 	cmd = tvb_get_guint8(tvb, offset);
10602 	if (cmd != 0xff) {
10603 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
10604 	} else {
10605 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
10606 	}
10607 	offset += 1;
10608 
10609 	/* reserved byte */
10610 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10611 	offset += 1;
10612 
10613 	/* andxoffset */
10614 	andxoffset = tvb_get_letohs(tvb, offset);
10615 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
10616 	offset += 2;
10617 
10618 	/* reserved byte */
10619 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10620 	offset += 1;
10621 
10622 	/* file name len */
10623 	fn_len = tvb_get_letohs(tvb, offset);
10624 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
10625 	offset += 2;
10626 
10627 	/* Create flags */
10628 	create_flags = tvb_get_letohl(tvb, offset);
10629 	offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
10630 
10631 	/* root directory fid */
10632 	proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10633 	offset += 4;
10634 
10635 	/* nt access mask */
10636 	access_mask = tvb_get_letohl(tvb, offset);
10637 	offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
10638 
10639 	/* allocation size */
10640 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10641 	offset += 8;
10642 
10643 	/* Extended File Attributes */
10644 	file_attributes = tvb_get_letohl(tvb, offset);
10645 	offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
10646 
10647 	/* share access */
10648 	share_access = tvb_get_letohl(tvb, offset);
10649 	offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
10650 
10651 	/* create disposition */
10652 	create_disposition = tvb_get_letohl(tvb, offset);
10653 	proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10654 	offset += 4;
10655 
10656 	/* create options */
10657 	create_options = tvb_get_letohl(tvb, offset);
10658 	offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
10659 
10660 	/* impersonation level */
10661 	proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10662 	offset += 4;
10663 
10664 	/* security flags */
10665 	offset = dissect_nt_security_flags(tvb, tree, offset);
10666 
10667 	BYTE_COUNT;
10668 
10669 	/* file name */
10670 	if (fn_len == -1) {
10671 		/*
10672 		 * We never set the file name length, perhaps because
10673 		 * the word count was zero.  This is not a valid
10674 		 * packet.
10675 		 */
10676 		proto_tree_add_expert(tree, pinfo, &ei_smb_missing_word_parameters,
10677 		    tvb, 0, 0);
10678 		goto endofcommand;
10679 	}
10680 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10681 	if (fn == NULL)
10682 		goto endofcommand;
10683 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10684 		fn);
10685 	COUNT_BYTES(fn_len);
10686 
10687 	/* store it for the fid->name/openframe/closeframe matching in
10688 	 * dissect_smb_fid()   called from the response.
10689 	 */
10690 	if ((!pinfo->fd->visited) && si->sip && fn) {
10691 		smb_fid_saved_info_t *fsi;
10692 
10693 		fsi			 = wmem_new(wmem_file_scope(), smb_fid_saved_info_t);
10694 		fsi->filename		 = wmem_strdup(wmem_file_scope(), fn);
10695 		fsi->create_flags	 = create_flags;
10696 		fsi->access_mask	 = access_mask;
10697 		fsi->file_attributes	 = file_attributes;
10698 		fsi->share_access	 = share_access;
10699 		fsi->create_options	 = create_options;
10700 		fsi->create_disposition	 = create_disposition;
10701 
10702 		si->sip->extra_info_type = SMB_EI_FILEDATA;
10703 		si->sip->extra_info	 = fsi;
10704 	}
10705 
10706 	col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10707 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
10708 
10709 	END_OF_SMB
10710 
10711 	if (cmd != 0xff) { 	/* there is an andX command */
10712 		if (andxoffset < offset)
10713 			THROW(ReportedBoundsError);
10714 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
10715 	}
10716 
10717 	return offset;
10718 }
10719 
10720 
10721 static int
dissect_nt_create_andx_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree,smb_info_t * si)10722 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
10723 {
10724 	guint8          wc, cmd    = 0xff;
10725 	guint16         andxoffset = 0;
10726 	guint16         bc;
10727 	guint16         fid        = 0;
10728 	guint16         ftype;
10729 	guint8          isdir;
10730 	smb_fid_info_t *fid_info   = NULL;
10731 
10732 	WORD_COUNT;
10733 
10734 	/* next smb command */
10735 	cmd = tvb_get_guint8(tvb, offset);
10736 	if (cmd != 0xff) {
10737 		proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
10738 	} else {
10739 		proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
10740 	}
10741 	offset += 1;
10742 
10743 	/* reserved byte */
10744 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10745 	offset += 1;
10746 
10747 	/* andxoffset */
10748 	andxoffset = tvb_get_letohs(tvb, offset);
10749 	proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
10750 	offset += 2;
10751 
10752 	/* oplock level */
10753 	proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10754 	offset += 1;
10755 
10756 	/* fid */
10757 	fid = tvb_get_letohs(tvb, offset);
10758 	fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
10759 	offset += 2;
10760 
10761 	/* create action */
10762 	/*XXX is this really the same as create disposition in the request? it looks so*/
10763 	/* No, it is not. It is the same as the create action from an Open&X request ... RJS */
10764 	proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10765 	offset += 4;
10766 
10767 	/* create time */
10768 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
10769 
10770 	/* access time */
10771 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
10772 
10773 	/* last write time */
10774 	offset = dissect_nt_64bit_time(tvb, tree, offset,
10775 		hf_smb_last_write_time);
10776 
10777 	/* last change time */
10778 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
10779 
10780 	/* Extended File Attributes */
10781 	offset = dissect_file_ext_attr(tvb, tree, offset);
10782 
10783 	/* allocation size */
10784 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10785 	offset += 8;
10786 
10787 	/* end of file */
10788 	/* We store the end of file */
10789 	if (fid_info) {
10790 		fid_info->end_of_file = tvb_get_letoh64(tvb, offset);
10791 	}
10792 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10793 	offset += 8;
10794 
10795 	/* File Type */
10796 	ftype = tvb_get_letohs(tvb, offset);
10797 	proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10798 	offset += 2;
10799 
10800 	/* IPC State */
10801 	offset = dissect_ipc_state(tvb, tree, offset, FALSE);
10802 
10803 	/* is directory */
10804 	isdir = tvb_get_guint8(tvb, offset);
10805 	proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10806 	offset += 1;
10807 
10808 	/* Always use the word count to decide if this is an "extended" response.
10809 	   When the server doesn't support the 0x10 flag, it will send a normal
10810 	   34 word response, so the word count is the only way to tell which of
10811 	   the response formats we have.  MS-SMB 2.2.4.9.2
10812 	   Also note that the extended format is actually 50 words, but in a
10813 	   "windows behavior note" they say Windows sets word count to 42.
10814 	   Handle anything 42 or larger as "extended" format. */
10815 	if (wc >= 42) {
10816 		proto_tree *tr = NULL;
10817 
10818 		/* The first field is a Volume GUID ... */
10819 		proto_tree_add_item(tree, hf_smb_volume_guid,
10820 				    tvb, offset, 16, ENC_NA);
10821 		offset += 16;
10822 
10823 		/* The file ID comes next */
10824 		proto_tree_add_item(tree, hf_smb_file_id_64bit,
10825 				    tvb, offset, 8, ENC_LITTLE_ENDIAN);
10826 		offset += 8;
10827 
10828 		tr = proto_tree_add_subtree(tree, tvb, offset, 4,
10829 					  ett_smb_nt_access_mask, NULL, "Maximal Access Rights");
10830 
10831 		offset = dissect_smb_access_mask(tvb, tr, offset);
10832 
10833 		tr = proto_tree_add_subtree(tree, tvb, offset, 4,
10834 					   ett_smb_nt_access_mask, NULL, "Guest Maximal Access Rights");
10835 
10836 		offset = dissect_smb_access_mask(tvb, tr, offset);
10837 	}
10838 
10839 	/* Try to remember the type of this fid so that we can dissect
10840 	 * any future security descriptor (access mask) properly
10841 	 */
10842 	if (ftype == 0) {
10843 		if (isdir == 0) {
10844 			if (fid_info) {
10845 				fid_info->type = SMB_FID_TYPE_FILE;
10846 			}
10847 		} else {
10848 			if (fid_info) {
10849 				fid_info->type = SMB_FID_TYPE_DIR;
10850 			}
10851 		}
10852 	}
10853 	if (ftype == 2) {
10854 		if (fid_info) {
10855 			fid_info->type = SMB_FID_TYPE_PIPE;
10856 		}
10857 	}
10858 
10859 	BYTE_COUNT;
10860 
10861 	END_OF_SMB
10862 
10863 	if (cmd != 0xff) { 	/* there is an andX command */
10864 		if (andxoffset < offset)
10865 			THROW(ReportedBoundsError);
10866 		dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
10867 	}
10868 
10869 	/* if there was an error, add a generated filename to the tree */
10870 	if (si->nt_status) {
10871 		dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE, si);
10872 	}
10873 
10874 	return offset;
10875 }
10876 
10877 
10878 static int
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_)10879 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_)
10880 {
10881 	guint8  wc;
10882 	guint16 bc;
10883 
10884 	WORD_COUNT;
10885 
10886 	BYTE_COUNT;
10887 
10888 	END_OF_SMB
10889 
10890 	return offset;
10891 }
10892 
10893 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10894    BEGIN Transaction/Transaction2 Primary and secondary requests
10895    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
10896 
10897 
10898 static const value_string trans2_cmd_vals[] = {
10899 	{ 0x00,		"OPEN2" },
10900 	{ 0x01,		"FIND_FIRST2" },
10901 	{ 0x02,		"FIND_NEXT2" },
10902 	{ 0x03,		"QUERY_FS_INFO" },
10903 	{ 0x04,		"SET_FS_INFO" },
10904 	{ 0x05,		"QUERY_PATH_INFO" },
10905 	{ 0x06,		"SET_PATH_INFO" },
10906 	{ 0x07,		"QUERY_FILE_INFO" },
10907 	{ 0x08,		"SET_FILE_INFO" },
10908 	{ 0x09,		"FSCTL" },
10909 	{ 0x0A,		"IOCTL2" },
10910 	{ 0x0B,		"FIND_NOTIFY_FIRST" },
10911 	{ 0x0C,		"FIND_NOTIFY_NEXT" },
10912 	{ 0x0D,		"CREATE_DIRECTORY" },
10913 	{ 0x0E,		"SESSION_SETUP" },
10914 	{ 0x0F,		"Unknown (0x0f)" },  /* dummy so val_to_str_ext can do indexed lookup */
10915 	{ 0x10,		"GET_DFS_REFERRAL" },
10916 	{ 0x11,		"REPORT_DFS_INCONSISTENCY" },
10917 	{ 0,    NULL }
10918 };
10919 value_string_ext trans2_cmd_vals_ext = VALUE_STRING_EXT_INIT(trans2_cmd_vals);
10920 
10921 static const true_false_string tfs_tf_dtid = {
10922 	"Also DISCONNECT TID",
10923 	"Do NOT disconnect TID"
10924 };
10925 static const true_false_string tfs_tf_owt = {
10926 	"One Way Transaction (NO RESPONSE)",
10927 	"Two way transaction"
10928 };
10929 
10930 static const true_false_string tfs_ff2_backup = {
10931 	"Find WITH backup intent",
10932 	"No backup intent"
10933 };
10934 static const true_false_string tfs_ff2_continue = {
10935 	"CONTINUE search from previous position",
10936 	"New search, do NOT continue from previous position"
10937 };
10938 static const true_false_string tfs_ff2_resume = {
10939 	"Return RESUME keys",
10940 	"Do NOT return resume keys"
10941 };
10942 static const true_false_string tfs_ff2_close_eos = {
10943 	"CLOSE search if END OF SEARCH is reached",
10944 	"Do NOT close search if end of search reached"
10945 };
10946 static const true_false_string tfs_ff2_close = {
10947 	"CLOSE search after this request",
10948 	"Do NOT close search after this request"
10949 };
10950 
10951 /* used by
10952    TRANS2_FIND_FIRST2
10953 */
10954 static const value_string ff2_il_vals[] = {
10955 	{ 1,		"Info Standard"},
10956 	{ 2,		"Info Query EA Size"},
10957 	{ 3,		"Info Query EAs From List"},
10958 	{ 0x0101,	"Find File Directory Info"},
10959 	{ 0x0102,	"Find File Full Directory Info"},
10960 	{ 0x0103,	"Find File Names Info"},
10961 	{ 0x0104,	"Find File Both Directory Info"},
10962 	{ 0x0105,	"Find File Full Directory Info"},
10963 	{ 0x0106,	"Find File Id Both Directory Info"},
10964 	{ 0x0202,	"Find File Unix"},
10965 	{ 0x020B,	"Find File Unix Info2"},
10966 	{0, NULL}
10967 };
10968 
10969 /* values used by :
10970 	TRANS2_QUERY_PATH_INFORMATION
10971 	TRANS2_QUERY_FILE_INFORMATION
10972 */
10973 static const value_string qpi_loi_vals[] = {
10974 	{ 1,		"Info Standard"},
10975 	{ 2,		"Info Query EA Size"},
10976 	{ 3,		"Info Query EAs From List"},
10977 	{ 4,		"Info Query All EAs"},
10978 	{ 6,		"Info Is Name Valid"},
10979 	{ 0x0101,	"Query File Basic Info"},
10980 	{ 0x0102,	"Query File Standard Info"},
10981 	{ 0x0103,	"Query File EA Info"},
10982 	{ 0x0104,	"Query File Name Info"},
10983 	{ 0x0107,	"Query File All Info"},
10984 	{ 0x0108,	"Query File Alt Name Info"},
10985 	{ 0x0109,	"Query File Stream Info"},
10986 	{ 0x010b,	"Query File Compression Info"},
10987 	{ 0x0200,	"Query File Unix Basic"},
10988 	{ 0x0201,	"Query File Unix Link"},
10989 	{ 0x0202,	"Query File Unix Hardlink"},
10990 	{ 0x0204,	"Query File Posix ACL"},
10991 	{ 0x0205,	"Query File Posix XATTR"},
10992 	{ 0x0206,	"Query File Posix Attr Flags"},
10993 	{ 0x0207,	"Query File Posix Permissions"},
10994 	{ 0x0208,	"Query File Posix Lock"},
10995 	{ 0x020b,	"Query File Unix Info2"},
10996 	{ 1004,		"Query File Basic Info"},
10997 	{ 1005,		"Query File Standard Info"},
10998 	{ 1006,		"Query File Internal Info"},
10999 	{ 1007,		"Query File EA Info"},
11000 	{ 1009,		"Query File Name Info"},
11001 	{ 1010,		"Query File Rename Info"},
11002 	{ 1011,		"Query File Link Info"},
11003 	{ 1012,		"Query File Names Info"},
11004 	{ 1013,		"Query File Disposition Info"},
11005 	{ 1014,		"Query File Position Info"},
11006 	{ 1015,		"Query File Full EA Info"},
11007 	{ 1016,		"Query File Mode Info"},
11008 	{ 1017,		"Query File Alignment Info"},
11009 	{ 1018,		"Query File All Info"},
11010 	{ 1019,		"Query File Allocation Info"},
11011 	{ 1020,		"Query File End of File Info"},
11012 	{ 1021,		"Query File Alt Name Info"},
11013 	{ 1022,		"Query File Stream Info"},
11014 	{ 1023,		"Query File Pipe Info"},
11015 	{ 1024,		"Query File Pipe Local Info"},
11016 	{ 1025,		"Query File Pipe Remote Info"},
11017 	{ 1026,		"Query File Mailslot Query Info"},
11018 	{ 1027,		"Query File Mailslot Set Info"},
11019 	{ 1028,		"Query File Compression Info"},
11020 	{ 1029,		"Query File ObjectID Info"},
11021 	{ 1030,		"Query File Completion Info"},
11022 	{ 1031,		"Query File Move Cluster Info"},
11023 	{ 1032,		"Query File Quota Info"},
11024 	{ 1033,		"Query File Reparsepoint Info"},
11025 	{ 1034,		"Query File Network Open Info"},
11026 	{ 1035,		"Query File Attribute Tag Info"},
11027 	{ 1036,		"Query File Tracking Info"},
11028 	{ 1037,		"Query File Maximum Info"},
11029 	{0, NULL}
11030 };
11031 static value_string_ext qpi_loi_vals_ext = VALUE_STRING_EXT_INIT(qpi_loi_vals);
11032 
11033 /* values used by :
11034 	TRANS2_SET_PATH_INFORMATION
11035 	TRANS2_SET_FILE_INFORMATION
11036 	(the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
11037 	but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
11038 	well; note that they're different from the QUERY_PATH_INFORMATION
11039 	and QUERY_FILE_INFORMATION values!)
11040 */
11041 static const value_string spi_loi_vals[] = {
11042 	{ 1,		"Info Standard"},
11043 	{ 2,		"Info Set EAs"},
11044 	{ 4,		"Info Query All EAs"},
11045 	{ 0x0101,	"Set File Basic Info"},
11046 	{ 0x0102,	"Set File Disposition Info"},
11047 	{ 0x0103,	"Set File Allocation Info"},
11048 	{ 0x0104,	"Set File End Of File Info"},
11049 	{ 0x0200,	"Set File Unix Basic"},
11050 	{ 0x0201,	"Set File Unix Link"},
11051 	{ 0x0202,	"Set File Unix HardLink"},
11052 	{ 0x0204,	"Set File Unix ACL"},
11053 	{ 0x0205,	"Set File Unix XATTR"},
11054 	{ 0x0206,	"Set File Unix Attr Flags"},
11055 	{ 0x0208,	"Set File Posix Lock"},
11056 	{ 0x0209,	"Set File Posix Open"},
11057 	{ 0x020a,	"Set File Posix Unlink"},
11058 	{ 0x020b,	"Set File Unix Info2"},
11059 	{ 1004,         "Set File Basic Info"},
11060 	{ 1010,         "Set Rename Information"},
11061 	{ 1013,         "Set Disposition Information"},
11062 	{ 1014,         "Set Position Information"},
11063 	{ 1016,         "Set Mode Information"},
11064 	{ 1019,         "Set Allocation Information"},
11065 	{ 1020,         "Set EOF Information"},
11066 	{ 1023,         "Set File Pipe Information"},
11067 	{ 1025,         "Set File Pipe Remote Information"},
11068 	{ 1029,         "Set Copy On Write Information"},
11069 	{ 1032,         "Set OLE Class ID Information"},
11070 	{ 1039,         "Set Inherit Context Index Information"},
11071 	{ 1040,         "Set OLE Information (?)"},
11072 	{0, NULL}
11073 };
11074 static value_string_ext spi_loi_vals_ext = VALUE_STRING_EXT_INIT(spi_loi_vals);
11075 
11076 static const value_string qfsi_vals[] = {
11077 	{ 1,		"Info Allocation"},
11078 	{ 2,		"Info Volume"},
11079 	{ 0x0101,	"Query FS Label Info"},
11080 	{ 0x0102,	"Query FS Volume Info"},
11081 	{ 0x0103,	"Query FS Size Info"},
11082 	{ 0x0104,	"Query FS Device Info"},
11083 	{ 0x0105,	"Query FS Attribute Info"},
11084 	{ 0x0200,       "Unix Query FS Info"},
11085 	{ 0x0202,       "Unix Query POSIX whoami"},
11086 	{ 0x0301,	"Mac Query FS Info"},
11087 	{ 1001,		"Query FS Label Info"},
11088 	{ 1002,		"Query FS Volume Info"},
11089 	{ 1003,		"Query FS Size Info"},
11090 	{ 1004,		"Query FS Device Info"},
11091 	{ 1005,		"Query FS Attribute Info"},
11092 	{ 1006,		"Query FS Quota Info"},
11093 	{ 1007,		"Query Full FS Size Info"},
11094 	{ 1008,         "Object ID Information"},
11095 	{0, NULL}
11096 };
11097 static value_string_ext qfsi_vals_ext = VALUE_STRING_EXT_INIT(qfsi_vals);
11098 
11099 static const value_string sfsi_vals[] = {
11100 	{ 0x203,	"Request Transport Encryption"},
11101 	{ 1006,		"Set FS Quota Info"},
11102 	{0, NULL}
11103 };
11104 
11105 static const value_string nt_rename_vals[] = {
11106 	{ 0x0103,	"Create Hard Link"},
11107 	{0, NULL}
11108 };
11109 
11110 
11111 static const value_string delete_pending_vals[] = {
11112 	{0,	"Normal, no pending delete"},
11113 	{1,	"This object has DELETE PENDING"},
11114 	{0, NULL}
11115 };
11116 
11117 static const value_string alignment_vals[] = {
11118 	{0,	"Byte alignment"},
11119 	{1,	"Word (16bit) alignment"},
11120 	{3,	"Long (32bit) alignment"},
11121 	{7,	"8 byte boundary alignment"},
11122 	{0x0f,	"16 byte boundary alignment"},
11123 	{0x1f,	"32 byte boundary alignment"},
11124 	{0x3f,	"64 byte boundary alignment"},
11125 	{0x7f,	"128 byte boundary alignment"},
11126 	{0xff,	"256 byte boundary alignment"},
11127 	{0x1ff,	"512 byte boundary alignment"},
11128 	{0, NULL}
11129 };
11130 
11131 static const true_false_string tfs_marked_for_deletion = {
11132 	"File is MARKED FOR DELETION",
11133 	"File is NOT marked for deletion"
11134 };
11135 
11136 static const true_false_string tfs_get_dfs_server_hold_storage = {
11137 	"Referral SERVER HOLDS STORAGE for the file",
11138 	"Referral server does NOT hold storage for the file"
11139 };
11140 static const true_false_string tfs_get_dfs_fielding = {
11141 	"The server in referral is FIELDING CAPABLE",
11142 	"The server in referrals is NOT fielding capable"
11143 };
11144 
11145 static const true_false_string tfs_dfs_referral_flags_name_list_referral = {
11146 	"A domain/DC referral response",
11147 	"NOT a domain/DC referral response"
11148 };
11149 
11150 static const true_false_string tfs_dfs_referral_flags_target_set_boundary = {
11151 	"The first target in the target set",
11152 	"NOT the first target in the target set"
11153 };
11154 
11155 static const value_string dfs_referral_server_type_vals[] = {
11156 	{0,	"Non-root targets returned"},
11157 	{1,	"Root targets returns"},
11158 	{0, NULL}
11159 };
11160 
11161 
11162 static const true_false_string tfs_device_char_removable = {
11163 	"This is a REMOVABLE device",
11164 	"This is NOT a removable device"
11165 };
11166 static const true_false_string tfs_device_char_read_only = {
11167 	"This is a READ-ONLY device",
11168 	"This is NOT a read-only device"
11169 };
11170 static const true_false_string tfs_device_char_floppy = {
11171 	"This is a FLOPPY DISK device",
11172 	"This is NOT a floppy disk device"
11173 };
11174 static const true_false_string tfs_device_char_write_once = {
11175 	"This is a WRITE-ONCE device",
11176 	"This is NOT a write-once device"
11177 };
11178 static const true_false_string tfs_device_char_remote = {
11179 	"This is a REMOTE device",
11180 	"This is NOT a remote device"
11181 };
11182 static const true_false_string tfs_device_char_mounted = {
11183 	"This device is MOUNTED",
11184 	"This device is NOT mounted"
11185 };
11186 static const true_false_string tfs_device_char_virtual = {
11187 	"This is a VIRTUAL device",
11188 	"This is NOT a virtual device"
11189 };
11190 static const true_false_string tfs_device_char_secure_open = {
11191 	"This device supports SECURE OPEN",
11192 	"This device does NOT support secure open"
11193 };
11194 static const true_false_string tfs_device_char_ts = {
11195 	"This is a TERMINAL SERVICES device",
11196 	"This is NOT a terminal services device"
11197 };
11198 static const true_false_string tfs_device_char_webdav = {
11199 	"This is a WEBDAV device",
11200 	"This is NOT a webdav device"
11201 };
11202 static const true_false_string tfs_device_char_portable = {
11203 	"This is a PORTABLE device",
11204 	"This is NOT a portable device"
11205 };
11206 static const true_false_string tfs_device_char_aat = {
11207 	"This device ALLOWS APPCONTAINER TRAVERSAL",
11208 	"This device does NOT allow appcontainer traversal"
11209 };
11210 
11211 static const true_false_string tfs_fs_attr_css = {
11212 	"This FS supports CASE SENSITIVE SEARCHes",
11213 	"This FS does NOT support case sensitive searches"
11214 };
11215 static const true_false_string tfs_fs_attr_cpn = {
11216 	"This FS supports CASE PRESERVED NAMES",
11217 	"This FS does NOT support case preserved names"
11218 };
11219 static const true_false_string tfs_fs_attr_uod = {
11220 	"This FS supports UNICODE NAMES",
11221 	"This FS does NOT support unicode names"
11222 };
11223 static const true_false_string tfs_fs_attr_pacls = {
11224 	"This FS supports PERSISTENT ACLs",
11225 	"This FS does NOT support persistent acls"
11226 };
11227 static const true_false_string tfs_fs_attr_fc = {
11228 	"This FS supports COMPRESSED FILES",
11229 	"This FS does NOT support compressed files"
11230 };
11231 static const true_false_string tfs_fs_attr_vq = {
11232 	"This FS supports VOLUME QUOTAS",
11233 	"This FS does NOT support volume quotas"
11234 };
11235 static const true_false_string tfs_fs_attr_srp = {
11236 	"This FS supports REPARSE POINTS",
11237 	"This FS does NOT support reparse points"
11238 };
11239 static const true_false_string tfs_fs_attr_srs = {
11240 	"This FS supports REMOTE STORAGE",
11241 	"This FS does NOT support remote storage"
11242 };
11243 static const true_false_string tfs_fs_attr_ssf = {
11244 	"This FS supports SPARSE FILES",
11245 	"This FS does NOT support sparse files"
11246 };
11247 static const true_false_string tfs_fs_attr_sla = {
11248 	"This FS supports LFN APIs",
11249 	"This FS does NOT support lfn apis"
11250 };
11251 static const true_false_string tfs_fs_attr_vic = {
11252 	"This FS VOLUME IS COMPRESSED",
11253 	"This FS volume is NOT compressed"
11254 };
11255 static const true_false_string tfs_fs_attr_soids = {
11256 	"This FS supports OIDs",
11257 	"This FS does NOT support OIDs"
11258 };
11259 static const true_false_string tfs_fs_attr_se = {
11260 	"This FS supports ENCRYPTION",
11261 	"This FS does NOT support encryption"
11262 };
11263 static const true_false_string tfs_fs_attr_ns = {
11264 	"This FS supports NAMED STREAMS",
11265 	"This FS does NOT support named streams"
11266 };
11267 static const true_false_string tfs_fs_attr_rov = {
11268 	"This is a READ ONLY VOLUME",
11269 	"This is a read/write volume"
11270 };
11271 static const true_false_string tfs_fs_attr_swo = {
11272 	"This is a SEQUENTIAL WRITE ONCE VOLUME",
11273 	"This is NOT a sequential write once volume"
11274 };
11275 static const true_false_string tfs_fs_attr_st = {
11276 	"This filesystem supports TRANSACTIONS",
11277 	"This filesystem does NOT support transactions"
11278 };
11279 static const true_false_string tfs_fs_attr_shl = {
11280 	"This filesystem supports HARD LINKS",
11281 	"This filesystem does NOT support hard links"
11282 };
11283 static const true_false_string tfs_fs_attr_sis = {
11284 	"This filesystem supports INTEGRITY STREAMS",
11285 	"This filesystem does NOT support integrity streams"
11286 };
11287 static const true_false_string tfs_fs_attr_sbr = {
11288 	"This filesystem supports BLOCK REFCOUNTING",
11289 	"This filesystem does NOT support block refcounting"
11290 };
11291 static const true_false_string tfs_fs_attr_ssv = {
11292 	"This filesystem supports SPARSE VDL",
11293 	"This filesystem does NOT support sparse vdl"
11294 };
11295 
11296 #define FF2_RESUME	0x0004
11297 
11298 static int
dissect_ff2_flags(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,smb_info_t * si)11299 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb_info_t *si)
11300 {
11301 	guint16               mask;
11302 	smb_transact2_info_t *t2i;
11303 	static int * const flags[] = {
11304 		&hf_smb_ff2_backup,
11305 		&hf_smb_ff2_continue,
11306 		&hf_smb_ff2_resume,
11307 		&hf_smb_ff2_close_eos,
11308 		&hf_smb_ff2_close,
11309 		NULL
11310 	};
11311 
11312 	mask = tvb_get_letohs(tvb, offset);
11313 
11314 	DISSECTOR_ASSERT(si);
11315 
11316 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
11317 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
11318 		if (t2i != NULL) {
11319 			if (!pinfo->fd->visited)
11320 				t2i->resume_keys = (mask & FF2_RESUME);
11321 		}
11322 	}
11323 
11324 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_ff2, ett_smb_find_first2_flags, flags, ENC_LITTLE_ENDIAN);
11325 	offset += 2;
11326 
11327 	return offset;
11328 }
11329 
11330 #if 0
11331 static int
11332 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11333 {
11334 	static int * const flags[] = {
11335 		&hf_smb_sfi_writetru,
11336 		&hf_smb_sfi_caching,
11337 		NULL
11338 	};
11339 
11340 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_sfi, ett_smb_ioflag, flags, ENC_LITTLE_ENDIAN);
11341 	offset += 2;
11342 
11343 	return offset;
11344 }
11345 #endif
11346 
11347 int
dissect_get_dfs_request_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean unicode)11348 dissect_get_dfs_request_data(tvbuff_t *tvb, packet_info *pinfo,
11349     proto_tree *tree, int offset, guint16 *bcp, gboolean unicode)
11350 {
11351 	int         fn_len;
11352 	const char *fn;
11353 	guint16     bc = *bcp;
11354 
11355 	/* referral level */
11356 	CHECK_BYTE_COUNT_TRANS(2);
11357 	proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11358 	COUNT_BYTES_TRANS(2);
11359 
11360 	/* file name */
11361 	fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, &bc);
11362 	CHECK_STRING_TRANS(fn);
11363 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11364 		fn);
11365 	COUNT_BYTES_TRANS(fn_len);
11366 
11367 	col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
11368 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11369 
11370 	*bcp = bc;
11371 	return offset;
11372 }
11373 
11374 static int
dissect_transaction2_request_parameters(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,int subcmd,guint16 bc,smb_info_t * si)11375 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
11376     proto_tree *parent_tree, int offset, int subcmd, guint16 bc, smb_info_t *si)
11377 {
11378 	proto_tree           *tree;
11379 	smb_transact2_info_t *t2i;
11380 	int                   fn_len;
11381 	const char           *fn;
11382 
11383 	DISSECTOR_ASSERT(si);
11384 
11385 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
11386 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
11387 	else
11388 		t2i = NULL;
11389 
11390 	tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, bc,
11391 				ett_smb_transaction_params, NULL, "%s Parameters",
11392 				val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
11393 					       "Unknown (0x%02x)"));
11394 
11395 	switch(subcmd) {
11396 	case 0x0000:	/*TRANS2_OPEN2*/
11397 		/* open flags */
11398 		CHECK_BYTE_COUNT_TRANS(2);
11399 		offset = dissect_open_flags(tvb, tree, offset, 0x000f);
11400 		bc -= 2;
11401 
11402 		/* desired access */
11403 		CHECK_BYTE_COUNT_TRANS(2);
11404 		offset = dissect_access(tvb, tree, offset, hf_smb_desired_access);
11405 		bc -= 2;
11406 
11407 		/* Search Attributes */
11408 		CHECK_BYTE_COUNT_TRANS(2);
11409 		offset = dissect_search_attributes(tvb, tree, offset);
11410 		bc -= 2;
11411 
11412 		/* File Attributes */
11413 		CHECK_BYTE_COUNT_TRANS(2);
11414 		offset = dissect_file_attributes(tvb, tree, offset);
11415 		bc -= 2;
11416 
11417 		/* create time */
11418 		CHECK_BYTE_COUNT_TRANS(4);
11419 		offset = dissect_smb_datetime(tvb, tree, offset,
11420 			hf_smb_create_time,
11421 			hf_smb_create_dos_date, hf_smb_create_dos_time,
11422 			TRUE);
11423 		bc -= 4;
11424 
11425 		/* open function */
11426 		CHECK_BYTE_COUNT_TRANS(2);
11427 		offset = dissect_open_function(tvb, tree, offset);
11428 		bc -= 2;
11429 
11430 		/* allocation size */
11431 		CHECK_BYTE_COUNT_TRANS(4);
11432 		proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11433 		COUNT_BYTES_TRANS(4);
11434 
11435 		/* 10 reserved bytes */
11436 		CHECK_BYTE_COUNT_TRANS(10);
11437 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
11438 		COUNT_BYTES_TRANS(10);
11439 
11440 		/* file name */
11441 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11442 		CHECK_STRING_TRANS(fn);
11443 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11444 			fn);
11445 		COUNT_BYTES_TRANS(fn_len);
11446 
11447 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11448 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11449 		break;
11450 	case 0x0001:	/*TRANS2_FIND_FIRST2*/
11451 		/* Search Attributes */
11452 		CHECK_BYTE_COUNT_TRANS(2);
11453 		offset = dissect_search_attributes(tvb, tree, offset);
11454 		bc -= 2;
11455 
11456 		/* search count */
11457 		CHECK_BYTE_COUNT_TRANS(2);
11458 		proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11459 		COUNT_BYTES_TRANS(2);
11460 
11461 		/* Find First2 flags */
11462 		CHECK_BYTE_COUNT_TRANS(2);
11463 		offset = dissect_ff2_flags(tvb, pinfo, tree, offset, si);
11464 		bc -= 2;
11465 
11466 		/* Find First2 information level */
11467 		CHECK_BYTE_COUNT_TRANS(2);
11468 		si->info_level = tvb_get_letohs(tvb, offset);
11469 		if ((t2i != NULL) && !pinfo->fd->visited)
11470 			t2i->info_level = si->info_level;
11471 		proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
11472 		COUNT_BYTES_TRANS(2);
11473 
11474 		/* storage type */
11475 		CHECK_BYTE_COUNT_TRANS(4);
11476 		proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11477 		COUNT_BYTES_TRANS(4);
11478 
11479 		/* search pattern */
11480 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11481 		CHECK_STRING_TRANS(fn);
11482 		if (t2i && !t2i->name) {
11483 			t2i->name = wmem_strdup(wmem_file_scope(), fn);
11484 		}
11485 		proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
11486 			fn);
11487 		COUNT_BYTES_TRANS(fn_len);
11488 
11489 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
11490 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11491 
11492 		break;
11493 	case 0x0002:	/*TRANS2_FIND_NEXT2*/
11494 		/* sid */
11495 		CHECK_BYTE_COUNT_TRANS(2);
11496 		proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11497 		COUNT_BYTES_TRANS(2);
11498 
11499 		/* search count */
11500 		CHECK_BYTE_COUNT_TRANS(2);
11501 		proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11502 		COUNT_BYTES_TRANS(2);
11503 
11504 		/* Find First2 information level */
11505 		CHECK_BYTE_COUNT_TRANS(2);
11506 		si->info_level = tvb_get_letohs(tvb, offset);
11507 		if ((t2i != NULL) && !pinfo->fd->visited)
11508 			t2i->info_level = si->info_level;
11509 		proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
11510 		COUNT_BYTES_TRANS(2);
11511 
11512 		/* resume key */
11513 		CHECK_BYTE_COUNT_TRANS(4);
11514 		proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11515 		COUNT_BYTES_TRANS(4);
11516 
11517 		/* Find First2 flags */
11518 		CHECK_BYTE_COUNT_TRANS(2);
11519 		offset = dissect_ff2_flags(tvb, pinfo, tree, offset, si);
11520 		bc -= 2;
11521 
11522 		/* file name */
11523 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11524 		CHECK_STRING_TRANS(fn);
11525 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11526 			fn);
11527 		COUNT_BYTES_TRANS(fn_len);
11528 
11529 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
11530 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11531 
11532 		break;
11533 	case 0x0003:	/*TRANS2_QUERY_FS_INFORMATION*/
11534 		/* level of interest */
11535 		CHECK_BYTE_COUNT_TRANS(2);
11536 		si->info_level = tvb_get_letohs(tvb, offset);
11537 		if ((t2i != NULL) && !pinfo->fd->visited)
11538 			t2i->info_level = si->info_level;
11539 		proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
11540 		COUNT_BYTES_TRANS(2);
11541 
11542 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11543 					val_to_str_ext(si->info_level, &qfsi_vals_ext,
11544 						   "Unknown (0x%02x)"));
11545 
11546 		break;
11547 	case 0x0004:	/*TRANS2_SET_FS_INFORMATION*/
11548 		/* level of interest */
11549 		CHECK_BYTE_COUNT_TRANS(4);
11550 		si->info_level = tvb_get_letohs(tvb, offset+2);
11551 		if ((t2i != NULL) && !pinfo->fd->visited)
11552 			t2i->info_level = si->info_level;
11553 		proto_tree_add_uint(tree, hf_smb_sfsi_information_level, tvb, offset+2, 2, si->info_level);
11554 		COUNT_BYTES_TRANS(4);
11555 
11556 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11557 					val_to_str(si->info_level, sfsi_vals,
11558 						   "Unknown (0x%02x)"));
11559 
11560 		break;
11561 	case 0x0005:	/*TRANS2_QUERY_PATH_INFORMATION*/
11562 		/* level of interest */
11563 		CHECK_BYTE_COUNT_TRANS(2);
11564 		si->info_level = tvb_get_letohs(tvb, offset);
11565 		if ((t2i != NULL) && !pinfo->fd->visited)
11566 			t2i->info_level = si->info_level;
11567 		proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
11568 		COUNT_BYTES_TRANS(2);
11569 
11570 		col_append_fstr(
11571 				pinfo->cinfo, COL_INFO, ", %s",
11572 				val_to_str_ext(si->info_level, &qpi_loi_vals_ext,
11573 					   "Unknown (%u)"));
11574 
11575 		/* 4 reserved bytes */
11576 		CHECK_BYTE_COUNT_TRANS(4);
11577 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11578 		COUNT_BYTES_TRANS(4);
11579 
11580 		/* file name */
11581 		fn = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &fn_len, (si->unicode ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_ASCII|ENC_NA));
11582 
11583 		CHECK_STRING_TRANS(fn);
11584 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11585 			fn);
11586 		COUNT_BYTES_TRANS(fn_len);
11587 		if (t2i && !t2i->name) {
11588 			t2i->name = wmem_strdup(wmem_file_scope(), fn);
11589 		}
11590 
11591 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11592 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11593 
11594 		break;
11595 	case 0x0006:	/*TRANS2_SET_PATH_INFORMATION*/
11596 		/* level of interest */
11597 		CHECK_BYTE_COUNT_TRANS(2);
11598 		si->info_level = tvb_get_letohs(tvb, offset);
11599 		if ((t2i != NULL) && !pinfo->fd->visited)
11600 			t2i->info_level = si->info_level;
11601 		proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
11602 		COUNT_BYTES_TRANS(2);
11603 
11604 		/* 4 reserved bytes */
11605 		CHECK_BYTE_COUNT_TRANS(4);
11606 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11607 		COUNT_BYTES_TRANS(4);
11608 
11609 		/* file name */
11610 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11611 		CHECK_STRING_TRANS(fn);
11612 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11613 			fn);
11614 		COUNT_BYTES_TRANS(fn_len);
11615 
11616 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11617 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11618 
11619 		break;
11620 	case 0x0007: {	/*TRANS2_QUERY_FILE_INFORMATION*/
11621 		guint16 fid;
11622 
11623 		/* fid */
11624 		CHECK_BYTE_COUNT_TRANS(2);
11625 		fid = tvb_get_letohs(tvb, offset);
11626 		dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
11627 		COUNT_BYTES_TRANS(2);
11628 
11629 		/* level of interest */
11630 		CHECK_BYTE_COUNT_TRANS(2);
11631 		si->info_level = tvb_get_letohs(tvb, offset);
11632 		if ((t2i != NULL) && !pinfo->fd->visited)
11633 			t2i->info_level = si->info_level;
11634 		proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
11635 		COUNT_BYTES_TRANS(2);
11636 
11637 		col_append_fstr(
11638 				pinfo->cinfo, COL_INFO, ", %s",
11639 				val_to_str_ext(si->info_level, &qpi_loi_vals_ext,
11640 					   "Unknown (%u)"));
11641 
11642 		break;
11643 	}
11644 	case 0x0008: {	/*TRANS2_SET_FILE_INFORMATION*/
11645 		guint16 fid;
11646 
11647 		/* fid */
11648 		CHECK_BYTE_COUNT_TRANS(2);
11649 		fid = tvb_get_letohs(tvb, offset);
11650 		dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
11651 		COUNT_BYTES_TRANS(2);
11652 
11653 		/* level of interest */
11654 		CHECK_BYTE_COUNT_TRANS(2);
11655 		si->info_level = tvb_get_letohs(tvb, offset);
11656 		if ((t2i != NULL) && !pinfo->fd->visited)
11657 			t2i->info_level = si->info_level;
11658 		proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
11659 		COUNT_BYTES_TRANS(2);
11660 
11661 #if 0
11662 		/*
11663 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
11664 		 * Extensions Version 3.0, Document Version 1.11,
11665 		 * July 19, 1990" says this is I/O flags, but it's
11666 		 * reserved in the SNIA spec, and some clients appear
11667 		 * to leave junk in it.
11668 		 *
11669 		 * Is this some field used only if a particular
11670 		 * dialect was negotiated, so that clients can feel
11671 		 * safe not setting it if they haven't negotiated that
11672 		 * dialect?  Or do the (non-OS/2) clients simply not care
11673 		 * about that particular OS/2-oriented dialect?
11674 		 */
11675 
11676 		/* IO Flag */
11677 		CHECK_BYTE_COUNT_TRANS(2);
11678 		offset = dissect_sfi_ioflag(tvb, tree, offset);
11679 		bc -= 2;
11680 #else
11681 		/* 2 reserved bytes */
11682 		CHECK_BYTE_COUNT_TRANS(2);
11683 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
11684 		COUNT_BYTES_TRANS(2);
11685 #endif
11686 
11687 		break;
11688 	}
11689 	case 0x0009:	/*TRANS2_FSCTL*/
11690 		/* this call has no parameter block in the request */
11691 
11692 		/*
11693 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
11694 		 * Extensions Version 3.0, Document Version 1.11,
11695 		 * July 19, 1990" says this this contains a
11696 		 * "File system specific parameter block".  (That means
11697 		 * we may not be able to dissect it in any case.)
11698 		 */
11699 		break;
11700 	case 0x000a:	/*TRANS2_IOCTL2*/
11701 		/* this call has no parameter block in the request */
11702 
11703 		/*
11704 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
11705 		 * Extensions Version 3.0, Document Version 1.11,
11706 		 * July 19, 1990" says this this contains a
11707 		 * "Device/function specific parameter block".  (That
11708 		 * means we may not be able to dissect it in any case.)
11709 		 */
11710 		break;
11711 	case 0x000b:	/*TRANS2_FIND_NOTIFY_FIRST*/
11712 		/* Search Attributes */
11713 		CHECK_BYTE_COUNT_TRANS(2);
11714 		offset = dissect_search_attributes(tvb, tree, offset);
11715 		bc -= 2;
11716 
11717 		/* Number of changes to wait for */
11718 		CHECK_BYTE_COUNT_TRANS(2);
11719 		proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11720 		COUNT_BYTES_TRANS(2);
11721 
11722 		/* Find Notify information level */
11723 		CHECK_BYTE_COUNT_TRANS(2);
11724 		si->info_level = tvb_get_letohs(tvb, offset);
11725 		if ((t2i != NULL) && !pinfo->fd->visited)
11726 			t2i->info_level = si->info_level;
11727 		proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
11728 		COUNT_BYTES_TRANS(2);
11729 
11730 		/* 4 reserved bytes */
11731 		CHECK_BYTE_COUNT_TRANS(4);
11732 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11733 		COUNT_BYTES_TRANS(4);
11734 
11735 		/* file name */
11736 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11737 		CHECK_STRING_TRANS(fn);
11738 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11739 			fn);
11740 		COUNT_BYTES_TRANS(fn_len);
11741 
11742 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11743 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11744 
11745 		break;
11746 	case 0x000c:	/*TRANS2_FIND_NOTIFY_NEXT*/
11747 		/* Monitor handle */
11748 		CHECK_BYTE_COUNT_TRANS(2);
11749 		proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11750 		COUNT_BYTES_TRANS(2);
11751 
11752 		/* Number of changes to wait for */
11753 		CHECK_BYTE_COUNT_TRANS(2);
11754 		proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11755 		COUNT_BYTES_TRANS(2);
11756 
11757 		break;
11758 	case 0x000d:	/*TRANS2_CREATE_DIRECTORY*/
11759 		/* 4 reserved bytes */
11760 		CHECK_BYTE_COUNT_TRANS(4);
11761 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11762 		COUNT_BYTES_TRANS(4);
11763 
11764 		/* dir name */
11765 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
11766 			FALSE, FALSE, &bc);
11767 		CHECK_STRING_TRANS(fn);
11768 		proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
11769 			fn);
11770 		COUNT_BYTES_TRANS(fn_len);
11771 
11772 		col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
11773 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11774 		break;
11775 	case 0x000e:	/*TRANS2_SESSION_SETUP*/
11776 		/* XXX unknown structure*/
11777 		break;
11778 	case 0x0010:	/*TRANS2_GET_DFS_REFERRAL*/
11779 		offset = dissect_get_dfs_request_data(tvb, pinfo, tree, offset, &bc, si->unicode);
11780 		break;
11781 	case 0x0011:	/*TRANS2_REPORT_DFS_INCONSISTENCY*/
11782 		/* file name */
11783 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11784 		CHECK_STRING_TRANS(fn);
11785 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11786 			fn);
11787 		COUNT_BYTES_TRANS(fn_len);
11788 
11789 		col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
11790 			    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
11791 		break;
11792 	}
11793 
11794 	/* ooops there were data we didn't know how to process */
11795 	if (bc != 0) {
11796 		proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, ENC_NA);
11797 		offset += bc;
11798 	}
11799 
11800 	return offset;
11801 }
11802 
11803 /*
11804  * XXX - just use "dissect_connect_flags()" here?
11805  */
11806 static guint16
dissect_transaction_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)11807 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11808 {
11809 	guint16     mask;
11810 	static int * const flags[] = {
11811 		&hf_smb_transaction_flags_owt,
11812 		&hf_smb_transaction_flags_dtid,
11813 		NULL
11814 	};
11815 
11816 	mask = tvb_get_letohs(tvb, offset);
11817 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_transaction_flags, ett_smb_transaction_flags, flags, ENC_LITTLE_ENDIAN);
11818 
11819 	return mask;
11820 }
11821 
11822 
11823 static int
dissect_get_dfs_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)11824 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11825 {
11826 	static int * const flags[] = {
11827 		&hf_smb_get_dfs_server_hold_storage,
11828 		&hf_smb_get_dfs_fielding,
11829 		NULL
11830 	};
11831 
11832 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_get_dfs_flags, ett_smb_get_dfs_flags, flags, ENC_LITTLE_ENDIAN);
11833 
11834 	offset += 2;
11835 	return offset;
11836 }
11837 
11838 static int
dissect_dfs_referral_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)11839 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11840 {
11841 	static int * const flags[] = {
11842 		&hf_smb_dfs_referral_flags_name_list_referral,
11843 		&hf_smb_dfs_referral_flags_target_set_boundary,
11844 		NULL
11845 	};
11846 
11847 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_dfs_referral_flags, ett_smb_dfs_referral_flags, flags, ENC_LITTLE_ENDIAN);
11848 	offset += 2;
11849 
11850 	return offset;
11851 }
11852 
11853 
11854 /* dfs inconsistency data  (4.4.2)
11855 */
11856 static int
dissect_dfs_inconsistency_data(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,smb_info_t * si)11857 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo _U_,
11858     proto_tree *tree, int offset, guint16 *bcp, smb_info_t *si)
11859 {
11860 	int         fn_len;
11861 	const char *fn;
11862 
11863 	DISSECTOR_ASSERT(si);
11864 
11865 	/*XXX shouldn this data hold version and size? unclear from doc*/
11866 	/* referral version */
11867 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11868 	proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11869 	COUNT_BYTES_TRANS_SUBR(2);
11870 
11871 	/* referral size */
11872 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11873 	proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11874 	COUNT_BYTES_TRANS_SUBR(2);
11875 
11876 	/* referral server type */
11877 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11878 	proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11879 	COUNT_BYTES_TRANS_SUBR(2);
11880 
11881 	/* referral flags */
11882 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11883 	offset = dissect_dfs_referral_flags(tvb, tree, offset);
11884 	*bcp  -= 2;
11885 
11886 	/* node name */
11887 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11888 	CHECK_STRING_TRANS_SUBR(fn);
11889 	proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11890 		fn);
11891 	COUNT_BYTES_TRANS_SUBR(fn_len);
11892 
11893 	return offset;
11894 }
11895 
11896 static int
dissect_dfs_referral_strings(tvbuff_t * tvb,proto_tree * tree,int hfindex,int nstring,int stroffset,int oldoffset,int offset,guint16 bc,gboolean unicode,int * end)11897 dissect_dfs_referral_strings(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11898 			     int nstring, int stroffset, int oldoffset, int offset,
11899 			     guint16 bc, gboolean unicode, int *end)
11900 {
11901 	int         istring;
11902 	const char *str;
11903 	int         str_len;    /* string length including the terminating NULL. */
11904 
11905 	if (stroffset <= oldoffset)
11906 		return oldoffset;
11907 
11908 	bc -= (stroffset - offset);
11909 	for (istring = 0; istring < nstring; istring++) {
11910 		if ((gint16)bc > 0) {
11911 			str = get_unicode_or_ascii_string(tvb, &stroffset, unicode, &str_len, FALSE, FALSE, &bc);
11912 			CHECK_STRING_TRANS_SUBR(str);
11913 			proto_tree_add_string(tree, hfindex, tvb, stroffset, str_len, str);
11914 			stroffset += str_len;
11915 			bc -= str_len;
11916 			if (end && (*end < stroffset))
11917 				*end = stroffset;
11918 		}
11919 	}
11920 
11921 	return offset;
11922 }
11923 
11924 
11925 static int
dissect_dfs_referral_string(tvbuff_t * tvb,proto_tree * tree,int hfindex,int stroffset,int oldoffset,int offset,guint16 bc,gboolean unicode,int * end)11926 dissect_dfs_referral_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11927 			    int stroffset, int oldoffset, int offset,
11928 			    guint16 bc, gboolean unicode, int *end)
11929 {
11930 	return dissect_dfs_referral_strings(tvb, tree, hfindex,
11931 					   1, stroffset, oldoffset, offset,
11932 					   bc, unicode, end);
11933 }
11934 
11935 static int
dissect_dfs_referral_entry_v2(tvbuff_t * tvb,proto_tree * tree,int oldoffset,int offset,guint16 refflags _U_,guint16 * bcp,gboolean unicode,int * ucstring_end)11936 dissect_dfs_referral_entry_v2(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11937 			      guint16 refflags _U_, guint16 *bcp, gboolean unicode, int *ucstring_end)
11938 {
11939 
11940 	guint16 pathoffset;
11941 	guint16 altpathoffset;
11942 	guint16 nodeoffset;
11943 
11944 	/* proximity */
11945 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
11946 	proto_tree_add_item(tree, hf_smb_dfs_referral_proximity, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11947 	COUNT_BYTES_TRANS_SUBR(4);
11948 
11949 	/* ttl */
11950 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
11951 	proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11952 	COUNT_BYTES_TRANS_SUBR(4);
11953 
11954 	/* path offset */
11955 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11956 	pathoffset = tvb_get_letohs(tvb, offset);
11957 	proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11958 	COUNT_BYTES_TRANS_SUBR(2);
11959 
11960 	/* alt path offset */
11961 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11962 	altpathoffset = tvb_get_letohs(tvb, offset);
11963 	proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11964 	COUNT_BYTES_TRANS_SUBR(2);
11965 
11966 	/* node offset */
11967 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
11968 	nodeoffset = tvb_get_letohs(tvb, offset);
11969 	proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11970 	COUNT_BYTES_TRANS_SUBR(2);
11971 
11972 	/* path */
11973 	if (pathoffset) {
11974 		dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11975 					    pathoffset+oldoffset, oldoffset, offset,
11976 					    *bcp, unicode, ucstring_end);
11977 	}
11978 
11979 	/* alt path */
11980 	if (altpathoffset) {
11981 		dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11982 					    altpathoffset+oldoffset, oldoffset, offset,
11983 					    *bcp, unicode, ucstring_end);
11984 	}
11985 
11986 	/* node */
11987 	if (nodeoffset) {
11988 		dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11989 					    nodeoffset+oldoffset, oldoffset, offset,
11990 					    *bcp, unicode, ucstring_end);
11991 	}
11992 
11993 	return offset;
11994 
11995 }
11996 
11997 
11998 static int
dissect_dfs_referral_entry_v3(tvbuff_t * tvb,proto_tree * tree,int oldoffset,int offset,guint16 refflags,guint16 * bcp,gboolean unicode,int * ucstring_end)11999 dissect_dfs_referral_entry_v3(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
12000 			      guint16 refflags, guint16 *bcp, gboolean unicode, int *ucstring_end)
12001 {
12002 	guint16 domoffset;
12003 	guint16 nexpnames;
12004 	guint16 expoffset;
12005 	guint16 pathoffset;
12006 	guint16 altpathoffset;
12007 	guint16 nodeoffset;
12008 
12009 	/* ttl */
12010 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
12011 	proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12012 	COUNT_BYTES_TRANS_SUBR(4);
12013 
12014 	if (refflags & REFENT_FLAGS_NAME_LIST_REFERRAL) {
12015 		/* domain name offset */
12016 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
12017 		domoffset = tvb_get_letohs(tvb, offset);
12018 		proto_tree_add_uint(tree, hf_smb_dfs_referral_domain_offset, tvb, offset, 2, domoffset);
12019 		COUNT_BYTES_TRANS_SUBR(2);
12020 
12021 		/* number of expanded names*/
12022 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
12023 		nexpnames = tvb_get_letohs(tvb, offset);
12024 		proto_tree_add_uint(tree, hf_smb_dfs_referral_number_of_expnames, tvb, offset, 2, nexpnames);
12025 		COUNT_BYTES_TRANS_SUBR(2);
12026 
12027 		/* expanded names offset */
12028 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
12029 		expoffset = tvb_get_letohs(tvb, offset);
12030 		proto_tree_add_uint(tree, hf_smb_dfs_referral_expnames_offset, tvb, offset, 2, expoffset);
12031 		COUNT_BYTES_TRANS_SUBR(2);
12032 
12033 		/* padding: zero or 16 bytes, which should be ignored by clients.
12034 		 * we ignore them too.
12035 		 */
12036 
12037 		/* domain name */
12038 		if (domoffset) {
12039 			dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_domain_name,
12040 						    domoffset+oldoffset, oldoffset, offset,
12041 						    *bcp, unicode, ucstring_end);
12042 		}
12043 		/* expanded names */
12044 		if (expoffset) {
12045 			proto_tree *exptree;
12046 
12047 			exptree = proto_tree_add_subtree(tree, tvb, offset, *bcp, ett_smb_dfs_referral_expnames, NULL, "Expanded Names");
12048 
12049 			dissect_dfs_referral_strings(tvb, exptree, hf_smb_dfs_referral_expname,
12050 						     nexpnames, expoffset+oldoffset, oldoffset, offset,
12051 						     *bcp, unicode, ucstring_end);
12052 		}
12053 	} else {
12054 		/* path offset */
12055 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
12056 		pathoffset = tvb_get_letohs(tvb, offset);
12057 		proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
12058 		COUNT_BYTES_TRANS_SUBR(2);
12059 
12060 		/* alt path offset */
12061 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
12062 		altpathoffset = tvb_get_letohs(tvb, offset);
12063 		proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
12064 		COUNT_BYTES_TRANS_SUBR(2);
12065 
12066 		/* node offset */
12067 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
12068 		nodeoffset = tvb_get_letohs(tvb, offset);
12069 		proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
12070 		COUNT_BYTES_TRANS_SUBR(2);
12071 
12072 		/* service site guid */
12073 		CHECK_BYTE_COUNT_TRANS_SUBR(16);
12074 		proto_tree_add_item(tree, hf_smb_dfs_referral_server_guid, tvb, offset, 16, ENC_NA);
12075 		COUNT_BYTES_TRANS_SUBR(16);
12076 
12077 		/* path */
12078 		if (pathoffset) {
12079 			dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
12080 						    pathoffset+oldoffset, oldoffset, offset,
12081 						    *bcp, unicode, ucstring_end);
12082 		}
12083 
12084 		/* alt path */
12085 		if (altpathoffset) {
12086 			dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
12087 						    altpathoffset+oldoffset, oldoffset, offset,
12088 						    *bcp, unicode, ucstring_end);
12089 		}
12090 
12091 		/* node */
12092 		if (nodeoffset) {
12093 			dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
12094 						    nodeoffset+oldoffset, oldoffset, offset,
12095 						    *bcp, unicode, ucstring_end);
12096 		}
12097 	}
12098 
12099 	return offset;
12100 
12101 }
12102 
12103 /* get dfs referral data  (4.4.1)
12104 */
12105 int
dissect_get_dfs_referral_data(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean unicode)12106 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo _U_,
12107     proto_tree *tree, int offset, guint16 *bcp, gboolean unicode)
12108 {
12109 	guint16     numref;
12110 	guint16     refsize;
12111 	guint16     refflags;
12112 	int         fn_len;
12113 	const char *fn;
12114 	int         unklen;
12115 	int         ucstring_end;
12116 	int         ucstring_len;
12117 
12118 	/* path consumed */
12119 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
12120 	proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12121 	COUNT_BYTES_TRANS_SUBR(2);
12122 
12123 	/* num referrals */
12124 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
12125 	numref = tvb_get_letohs(tvb, offset);
12126 	proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
12127 	COUNT_BYTES_TRANS_SUBR(2);
12128 
12129 	/* get dfs flags */
12130 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
12131 	offset = dissect_get_dfs_flags(tvb, tree, offset);
12132 	*bcp -= 2;
12133 
12134 	/* XXX - in at least one capture there appears to be 2 bytes
12135 	   of stuff after the Dfs flags, perhaps so that the header
12136 	   in front of the referral list is a multiple of 4 bytes long. */
12137 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
12138 	proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, ENC_NA);
12139 	COUNT_BYTES_TRANS_SUBR(2);
12140 
12141 	/* if there are any referrals */
12142 	if (numref) {
12143 		proto_item *ref_item;
12144 		proto_tree *ref_tree;
12145 		int old_offset = offset;
12146 
12147 		ref_tree = proto_tree_add_subtree(tree,
12148 				tvb, offset, *bcp, ett_smb_dfs_referrals, &ref_item, "Referrals");
12149 		ucstring_end = -1;
12150 
12151 		while (numref--) {
12152 			proto_item *ri;
12153 			proto_tree *rt;
12154 			int old_offset_2 = offset;
12155 			guint16 version;
12156 
12157 			rt = proto_tree_add_subtree(ref_tree,
12158 					tvb, offset, *bcp, ett_smb_dfs_referral, &ri, "Referral");
12159 
12160 			/* referral version */
12161 			CHECK_BYTE_COUNT_TRANS_SUBR(2);
12162 			version = tvb_get_letohs(tvb, offset);
12163 			proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
12164 				tvb, offset, 2, version);
12165 			COUNT_BYTES_TRANS_SUBR(2);
12166 
12167 			/* referral size */
12168 			CHECK_BYTE_COUNT_TRANS_SUBR(2);
12169 			refsize = tvb_get_letohs(tvb, offset);
12170 			proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
12171 			COUNT_BYTES_TRANS_SUBR(2);
12172 
12173 			/* referral server type */
12174 			CHECK_BYTE_COUNT_TRANS_SUBR(2);
12175 			proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12176 			COUNT_BYTES_TRANS_SUBR(2);
12177 
12178 			/* referral flags */
12179 			CHECK_BYTE_COUNT_TRANS_SUBR(2);
12180 			refflags = tvb_get_letohs(tvb, offset);
12181 			offset = dissect_dfs_referral_flags(tvb, rt, offset);
12182 			*bcp -= 2;
12183 
12184 			switch(version) {
12185 
12186 			case 1:
12187 				/* node name */
12188 				fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, bcp);
12189 				CHECK_STRING_TRANS_SUBR(fn);
12190 				proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
12191 					fn);
12192 				COUNT_BYTES_TRANS_SUBR(fn_len);
12193 				break;
12194 
12195 			case 2:
12196 				offset = dissect_dfs_referral_entry_v2(tvb, rt, old_offset_2, offset,
12197 								       refflags, bcp, unicode, &ucstring_end);
12198 				break;
12199 			case 3:
12200 				offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
12201 								       refflags, bcp, unicode, &ucstring_end);
12202 				break;
12203 			case 4:
12204 				/* V4 is extactly same as V3, except the version number and
12205 				 * one more ReferralEntryFlags */
12206 				offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
12207 								       refflags, bcp, unicode, &ucstring_end);
12208 				break;
12209 			}
12210 
12211 			/*
12212 			 * Show anything beyond the length of the referral
12213 			 * as unknown data.
12214 			 */
12215 			unklen = (old_offset_2 + refsize) - offset;
12216 			if (unklen < 0) {
12217 				/*
12218 				 * XXX - the length is bogus.
12219 				 */
12220 				unklen = 0;
12221 			}
12222 			if (unklen != 0) {
12223 				CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
12224 				proto_tree_add_item(rt, hf_smb_unknown, tvb,
12225 				    offset, unklen, ENC_NA);
12226 				COUNT_BYTES_TRANS_SUBR(unklen);
12227 			}
12228 
12229 			proto_item_set_len(ri, offset-old_offset_2);
12230 		}
12231 
12232 		/*
12233 		 * Treat the offset past the end of the last Unicode
12234 		 * string after the referrals (if any) as the last
12235 		 * offset.
12236 		 */
12237 		if (ucstring_end > offset) {
12238 			ucstring_len = ucstring_end - offset;
12239 			if (*bcp < ucstring_len)
12240 				ucstring_len = *bcp;
12241 			offset += ucstring_len;
12242 			*bcp -= ucstring_len;
12243 		}
12244 		proto_item_set_len(ref_item, offset-old_offset);
12245 	}
12246 
12247 	return offset;
12248 }
12249 
12250 /* This dissects the standard four 8-byte Windows timestamps ...
12251  */
12252 static int
dissect_smb_standard_8byte_timestamps(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12253 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
12254     packet_info *pinfo _U_, proto_tree *tree,
12255     int offset, guint16 *bcp, gboolean *trunc)
12256 {
12257 	/* create time */
12258 	CHECK_BYTE_COUNT_SUBR(8);
12259 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
12260 	*bcp -= 8;
12261 
12262 	/* access time */
12263 	CHECK_BYTE_COUNT_SUBR(8);
12264 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
12265 	*bcp -= 8;
12266 
12267 	/* last write time */
12268 	CHECK_BYTE_COUNT_SUBR(8);
12269 	offset = dissect_nt_64bit_time(tvb, tree, offset,
12270 		hf_smb_last_write_time);
12271 	*bcp -= 8;
12272 
12273 	/* last change time */
12274 	CHECK_BYTE_COUNT_SUBR(8);
12275 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
12276 	*bcp -= 8;
12277 
12278 	*trunc = FALSE;
12279 	return offset;
12280 }
12281 
12282 /* this dissects the SMB_INFO_STANDARD
12283    as described in 4.2.16.1 of the CIFS 1.0 specification
12284    or as described in 2.2.8.3.1 of the MS-CIFS specification for query
12285    section 2.2.8.4.1 of the MS-CIFS specification describes it for set;
12286    it says that everything past the last write time is "reserved",
12287    presumably meaning that you can fetch it but not set it
12288    for now we just use it for both query and set
12289 */
12290 static int
dissect_qsfi_SMB_INFO_STANDARD(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12291 dissect_qsfi_SMB_INFO_STANDARD(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12292     int offset, guint16 *bcp, gboolean *trunc)
12293 {
12294 	/* create time */
12295 	CHECK_BYTE_COUNT_SUBR(4);
12296 	offset = dissect_smb_datetime(tvb, tree, offset,
12297 		hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
12298 		FALSE);
12299 	*bcp -= 4;
12300 
12301 	/* access time */
12302 	CHECK_BYTE_COUNT_SUBR(4);
12303 	offset = dissect_smb_datetime(tvb, tree, offset,
12304 		hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
12305 		FALSE);
12306 	*bcp -= 4;
12307 
12308 	/* last write time */
12309 	CHECK_BYTE_COUNT_SUBR(4);
12310 	offset = dissect_smb_datetime(tvb, tree, offset,
12311 		hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
12312 		FALSE);
12313 	*bcp -= 4;
12314 
12315 	/* data size */
12316 	CHECK_BYTE_COUNT_SUBR(4);
12317 	proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12318 	COUNT_BYTES_SUBR(4);
12319 
12320 	/* allocation size */
12321 	CHECK_BYTE_COUNT_SUBR(4);
12322 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12323 	COUNT_BYTES_SUBR(4);
12324 
12325 	/* File Attributes */
12326 	CHECK_BYTE_COUNT_SUBR(2);
12327 	offset = dissect_file_attributes(tvb, tree, offset);
12328 	*bcp -= 2;
12329 
12330 	/*
12331 	 * The MS-CIFS spec says this doesn't have an EA length field;
12332 	 * the SNIA CIFS spec says it does, as does the 1996
12333 	 * "Microsoft Networks SMB FILE SHARING PROTOCOL Document
12334 	 * Version 6.0p" document.
12335 	 *
12336 	 * Some older SMB documents point to the documentation
12337 	 * for the OS/2 DosQFileInfo() API; the page at
12338 	 *
12339 	 *	http://cyberkinetica.homeunix.net/os2tk45/prcp/111_L2_DosQFileInfo.html
12340 	 *
12341 	 * says that, for level 1 (SMB_INFO_STANDARD), there is no EA
12342 	 * length - that's just for level 2 (SMB_INFO_QUERY_EA_SIZE).
12343 	 *
12344 	 * I've seen captures with it and without it; given the mixed
12345 	 * messages sent by different documents, this is not surprising.
12346 	 *
12347 	 * We display it if it's there; we don't set *trunc if it's
12348 	 * not.
12349 	 *
12350 	 * Note: in FIND_FIRST2/FIND_NEXT2, the EA length is *not*
12351 	 * present.
12352 	 */
12353 	if (*bcp != 0) {
12354 		CHECK_BYTE_COUNT_SUBR(4);
12355 		proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset,
12356 		    4, ENC_LITTLE_ENDIAN);
12357 		COUNT_BYTES_SUBR(4);
12358 	}
12359 
12360 	*trunc = FALSE;
12361 	return offset;
12362 }
12363 
12364 /* this dissects the SMB_INFO_QUERY_EA_SIZE
12365    as described in 4.2.16.1 of the CIFS 1.0 specification
12366    and as described in 2.2.8.3.2 of the MS-CIFS specification
12367 */
12368 static int
dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12369 dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12370     int offset, guint16 *bcp, gboolean *trunc)
12371 {
12372 	/* create time */
12373 	CHECK_BYTE_COUNT_SUBR(4);
12374 	offset = dissect_smb_datetime(tvb, tree, offset,
12375 		hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
12376 		FALSE);
12377 	*bcp -= 4;
12378 
12379 	/* access time */
12380 	CHECK_BYTE_COUNT_SUBR(4);
12381 	offset = dissect_smb_datetime(tvb, tree, offset,
12382 		hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
12383 		FALSE);
12384 	*bcp -= 4;
12385 
12386 	/* last write time */
12387 	CHECK_BYTE_COUNT_SUBR(4);
12388 	offset = dissect_smb_datetime(tvb, tree, offset,
12389 		hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
12390 		FALSE);
12391 	*bcp -= 4;
12392 
12393 	/* data size */
12394 	CHECK_BYTE_COUNT_SUBR(4);
12395 	proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12396 	COUNT_BYTES_SUBR(4);
12397 
12398 	/* allocation size */
12399 	CHECK_BYTE_COUNT_SUBR(4);
12400 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12401 	COUNT_BYTES_SUBR(4);
12402 
12403 	/* File Attributes */
12404 	CHECK_BYTE_COUNT_SUBR(2);
12405 	offset = dissect_file_attributes(tvb, tree, offset);
12406 	*bcp -= 2;
12407 
12408 	/* ea length */
12409 	CHECK_BYTE_COUNT_SUBR(4);
12410 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12411 	COUNT_BYTES_SUBR(4);
12412 
12413 	*trunc = FALSE;
12414 	return offset;
12415 }
12416 
12417 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
12418    as described in 4.2.16.2
12419 */
12420 static int
dissect_4_2_16_2(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12421 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12422     int offset, guint16 *bcp, gboolean *trunc)
12423 {
12424 	guint8  name_len;
12425 	guint16 data_len;
12426 	/* EA size */
12427 
12428 	CHECK_BYTE_COUNT_SUBR(4);
12429 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12430 	COUNT_BYTES_SUBR(4);
12431 
12432 	while (*bcp > 0) {
12433 		proto_item *item;
12434 		proto_tree *subtree;
12435 		char *display_string;
12436 		int start_offset = offset;
12437 
12438 		subtree = proto_tree_add_subtree(
12439 			tree, tvb, offset, 0, ett_smb_ea, &item, "Extended Attribute");
12440 
12441 		/* EA flags */
12442 
12443 		CHECK_BYTE_COUNT_SUBR(1);
12444 		proto_tree_add_item(
12445 			subtree, hf_smb_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12446 		COUNT_BYTES_SUBR(1);
12447 
12448 		/* EA name length */
12449 
12450 		name_len = tvb_get_guint8(tvb, offset);
12451 
12452 		CHECK_BYTE_COUNT_SUBR(1);
12453 		proto_tree_add_item(
12454 			subtree, hf_smb_ea_name_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12455 		COUNT_BYTES_SUBR(1);
12456 
12457 		/* EA data length */
12458 
12459 		data_len = tvb_get_letohs(tvb, offset);
12460 
12461 		CHECK_BYTE_COUNT_SUBR(2);
12462 		proto_tree_add_item(
12463 			subtree, hf_smb_ea_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12464 		COUNT_BYTES_SUBR(2);
12465 
12466 		/* EA name */
12467 
12468 		CHECK_BYTE_COUNT_SUBR(name_len + 1);
12469 		proto_tree_add_item_ret_display_string(
12470 			subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
12471 			ENC_ASCII|ENC_NA,
12472 			wmem_packet_scope(), &display_string);
12473 		proto_item_append_text(item, ": %s", display_string);
12474 		COUNT_BYTES_SUBR(name_len + 1);
12475 
12476 		/* EA data */
12477 
12478 		CHECK_BYTE_COUNT_SUBR(data_len);
12479 		proto_tree_add_item(
12480 			subtree, hf_smb_ea_data, tvb, offset, data_len, ENC_NA);
12481 		COUNT_BYTES_SUBR(data_len);
12482 
12483 		proto_item_set_len(item, offset - start_offset);
12484 	}
12485 
12486 	*trunc = FALSE;
12487 	return offset;
12488 }
12489 
12490 /* this dissects the SMB_INFO_IS_NAME_VALID
12491    as described in 4.2.16.3
12492 */
12493 static int
dissect_4_2_16_3(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)12494 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12495     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12496 {
12497 	int         fn_len;
12498 	const char *fn;
12499 
12500 	DISSECTOR_ASSERT(si);
12501 
12502 	/* file name */
12503 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12504 	CHECK_STRING_SUBR(fn);
12505 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12506 		fn);
12507 	COUNT_BYTES_SUBR(fn_len);
12508 
12509 	*trunc = FALSE;
12510 	return offset;
12511 }
12512 
12513 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
12514    as described in 4.2.16.4
12515 */
12516 static int
dissect_4_2_16_4(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12517 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12518     int offset, guint16 *bcp, gboolean *trunc)
12519 {
12520 
12521 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12522 	if (*trunc) {
12523 	  return offset;
12524 	}
12525 
12526 	/* File Attributes */
12527 	CHECK_BYTE_COUNT_SUBR(4);
12528 	offset = dissect_file_ext_attr(tvb, tree, offset);
12529 	*bcp -= 4;
12530 
12531 	*trunc = FALSE;
12532 	return offset;
12533 }
12534 
12535 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
12536    as described in 4.2.16.5 of the SNIA CIFS spec
12537    and section 2.2.8.3.7 of the MS-CIFS spec
12538 */
12539 int
dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12540 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12541     int offset, guint16 *bcp, gboolean *trunc)
12542 {
12543 	/* allocation size */
12544 	CHECK_BYTE_COUNT_SUBR(8);
12545 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12546 	COUNT_BYTES_SUBR(8);
12547 
12548 	/* end of file */
12549 	CHECK_BYTE_COUNT_SUBR(8);
12550 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12551 	COUNT_BYTES_SUBR(8);
12552 
12553 	/* number of links */
12554 	CHECK_BYTE_COUNT_SUBR(4);
12555 	proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12556 	COUNT_BYTES_SUBR(4);
12557 
12558 	/* delete pending */
12559 	CHECK_BYTE_COUNT_SUBR(1);
12560 	proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12561 	COUNT_BYTES_SUBR(1);
12562 
12563 	/* is directory */
12564 	CHECK_BYTE_COUNT_SUBR(1);
12565 	proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12566 	COUNT_BYTES_SUBR(1);
12567 
12568 	*trunc = FALSE;
12569 	return offset;
12570 }
12571 
12572 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
12573 */
12574 int
dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12575 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12576     int offset, guint16 *bcp, gboolean *trunc)
12577 {
12578 	/* file id */
12579 	CHECK_BYTE_COUNT_SUBR(8);
12580 	proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12581 	COUNT_BYTES_SUBR(8);
12582 
12583 	*trunc = FALSE;
12584 	return offset;
12585 }
12586 
12587 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
12588 */
12589 int
dissect_qsfi_SMB_FILE_POSITION_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12590 dissect_qsfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12591     int offset, guint16 *bcp, gboolean *trunc)
12592 {
12593 	/* file position */
12594 	CHECK_BYTE_COUNT_SUBR(8);
12595 	proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12596 	COUNT_BYTES_SUBR(8);
12597 
12598 	*trunc = FALSE;
12599 	return offset;
12600 }
12601 
12602 /* this dissects the SMB_QUERY_FILE_MODE_INFO
12603 */
12604 int
dissect_qsfi_SMB_FILE_MODE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12605 dissect_qsfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12606     int offset, guint16 *bcp, gboolean *trunc)
12607 {
12608 	/* mode */
12609 	CHECK_BYTE_COUNT_SUBR(4);
12610 	proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12611 	COUNT_BYTES_SUBR(4);
12612 
12613 	*trunc = FALSE;
12614 	return offset;
12615 }
12616 
12617 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
12618 */
12619 int
dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12620 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12621     int offset, guint16 *bcp, gboolean *trunc)
12622 {
12623 	/* alignment */
12624 	CHECK_BYTE_COUNT_SUBR(4);
12625 	proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12626 	COUNT_BYTES_SUBR(4);
12627 
12628 	*trunc = FALSE;
12629 	return offset;
12630 }
12631 
12632 /* this dissects the SMB_QUERY_FILE_EA_INFO
12633    as described in 4.2.16.6 of the SNIA CIFS spec
12634    and 2.2.8.3.8 of the MS-CIFS spec
12635 */
12636 int
dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12637 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12638     int offset, guint16 *bcp, gboolean *trunc)
12639 {
12640 	/* ea length */
12641 	CHECK_BYTE_COUNT_SUBR(4);
12642 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12643 	COUNT_BYTES_SUBR(4);
12644 
12645 	*trunc = FALSE;
12646 	return offset;
12647 }
12648 
12649 /* this dissects the SMB_FILE_ALLOCATION_INFO
12650    as described in 4.2.19.3 in the SNIA CIFS spec
12651    and the SMB_SET_FILE_ALLOCATION_INFO
12652    as described in 2.2.8.4.5 in the MS-CIFS spec for set (MS-CIFS doesn't
12653    say it can be queried)
12654 */
12655 int
dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12656 dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12657     int offset, guint16 *bcp, gboolean *trunc)
12658 {
12659 	/* allocation size */
12660 	CHECK_BYTE_COUNT_SUBR(8);
12661 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12662 	COUNT_BYTES_SUBR(8);
12663 
12664 	*trunc = FALSE;
12665 	return offset;
12666 }
12667 
12668 /* this dissects the SMB_FILE_ENDOFFILE_INFO
12669    as described in 4.2.19.4 in the SNIA CIFS spec
12670    and the SMB_SET_FILE_END_OF_FILE_INFO
12671    as described in 2.2.8.4.6 in the MS-CIFS spec for set (MS-CIFS doesn't
12672    say it can be queried)
12673 */
12674 int
dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12675 dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12676     int offset, guint16 *bcp, gboolean *trunc)
12677 {
12678 	/* offset of end of file */
12679 	CHECK_BYTE_COUNT_SUBR(8);
12680 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12681 	COUNT_BYTES_SUBR(8);
12682 
12683 	*trunc = FALSE;
12684 	return offset;
12685 }
12686 
12687 /* this dissects the SMB_QUERY_FILE_NAME_INFO
12688    as described in 4.2.16.7 of the SNIA CIFS spec
12689    and in 2.2.8.3.9 of the MS-CIFS spec
12690    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
12691    as described in 4.2.16.9 of the SNIA CIFS spec
12692    and 2.2.8.3.11 of the MS-CIFS spec
12693    although the latter two are used to fetch the 8.3 name
12694    rather than the long name
12695 */
12696 int
dissect_qfi_SMB_FILE_NAME_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,gboolean unicode)12697 dissect_qfi_SMB_FILE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12698     int offset, guint16 *bcp, gboolean *trunc, gboolean unicode)
12699 {
12700 	int         fn_len;
12701 	const char *fn;
12702 
12703 	/* file name len */
12704 	CHECK_BYTE_COUNT_SUBR(4);
12705 	proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12706 	COUNT_BYTES_SUBR(4);
12707 
12708 	/* file name */
12709 	fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, bcp);
12710 	CHECK_STRING_SUBR(fn);
12711 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12712 		fn);
12713 	COUNT_BYTES_SUBR(fn_len);
12714 
12715 	*trunc = FALSE;
12716 	return offset;
12717 }
12718 
12719 /* this dissects the SMB_QUERY_FILE_ALL_INFO
12720    as described in 2.2.8.3.8 of the MS-CIFS spec
12721    but not as described in 4.2.16.8 since SNIA spec is wrong
12722 */
12723 static int
dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)12724 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12725     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12726 {
12727 	guint32     fn_len;
12728 	const char *fn;
12729 
12730 	DISSECTOR_ASSERT(si);
12731 
12732 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12733 	if (*trunc) {
12734 	  return offset;
12735 	}
12736 
12737 	/* File Attributes */
12738 	CHECK_BYTE_COUNT_SUBR(4);
12739 	offset = dissect_file_ext_attr(tvb, tree, offset);
12740 	*bcp   -= 4;
12741 
12742 	/* 4 pad bytes */
12743 	offset += 4;
12744 	*bcp   -= 4;
12745 
12746 	/* allocation size */
12747 	CHECK_BYTE_COUNT_SUBR(8);
12748 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12749 	COUNT_BYTES_SUBR(8);
12750 
12751 	/* end of file */
12752 	CHECK_BYTE_COUNT_SUBR(8);
12753 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12754 	COUNT_BYTES_SUBR(8);
12755 
12756 	/* number of links */
12757 	CHECK_BYTE_COUNT_SUBR(4);
12758 	proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12759 	COUNT_BYTES_SUBR(4);
12760 
12761 	/* delete pending */
12762 	CHECK_BYTE_COUNT_SUBR(1);
12763 	proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12764 	COUNT_BYTES_SUBR(1);
12765 
12766 	/* is directory */
12767 	CHECK_BYTE_COUNT_SUBR(1);
12768 	proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12769 	COUNT_BYTES_SUBR(1);
12770 
12771 	/* 2 pad bytes */
12772 	offset += 2;
12773 	*bcp   -= 2;
12774 
12775 	/* ea length */
12776 	CHECK_BYTE_COUNT_SUBR(4);
12777 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12778 	COUNT_BYTES_SUBR(4);
12779 
12780 	/* file name len */
12781 	CHECK_BYTE_COUNT_SUBR(4);
12782 	fn_len = (guint32)tvb_get_letohl(tvb, offset);
12783 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12784 	COUNT_BYTES_SUBR(4);
12785 
12786 
12787 	/* file name */
12788 	CHECK_BYTE_COUNT_SUBR(fn_len);
12789 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
12790 	if (fn != NULL) {
12791 		proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12792 			fn);
12793 		COUNT_BYTES_SUBR(fn_len);
12794 	}
12795 
12796 
12797 	if (*trunc)
12798 		return offset;
12799 
12800 	return offset;
12801 }
12802 
12803 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
12804    as described in 4.2.16.10 of the SNIA CIFS spec
12805    and 2.2.8.3.12 of the MS-CIFS spec
12806 */
12807 int
dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,int unicode)12808 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
12809     int offset, guint16 *bcp, gboolean *trunc, int unicode)
12810 {
12811 	proto_item *item;
12812 	proto_tree *tree;
12813 	int         old_offset;
12814 	guint32     neo;
12815 	int         fn_len;
12816 	const char *fn;
12817 	int         padcnt;
12818 
12819 
12820 	for (;;) {
12821 		old_offset = offset;
12822 
12823 		/* next entry offset */
12824 		CHECK_BYTE_COUNT_SUBR(4);
12825 		tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item, "Stream Info");
12826 
12827 		neo = tvb_get_letohl(tvb, offset);
12828 		proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12829 		COUNT_BYTES_SUBR(4);
12830 
12831 		/* stream name len */
12832 		CHECK_BYTE_COUNT_SUBR(4);
12833 		fn_len = tvb_get_letohl(tvb, offset);
12834 		proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
12835 		COUNT_BYTES_SUBR(4);
12836 
12837 		/* stream size */
12838 		CHECK_BYTE_COUNT_SUBR(8);
12839 		proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12840 		COUNT_BYTES_SUBR(8);
12841 
12842 		/* allocation size */
12843 		CHECK_BYTE_COUNT_SUBR(8);
12844 		proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12845 		COUNT_BYTES_SUBR(8);
12846 
12847 		/* stream name */
12848 		fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
12849 		CHECK_STRING_SUBR(fn);
12850 		proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
12851 			fn);
12852 		COUNT_BYTES_SUBR(fn_len);
12853 
12854 		proto_item_append_text(item, ": %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
12855 		proto_item_set_len(item, offset-old_offset);
12856 
12857 		if (neo == 0)
12858 			break;	/* no more structures */
12859 
12860 		/* skip to next structure */
12861 		padcnt = (old_offset + neo) - offset;
12862 		if (padcnt < 0) {
12863 			/*
12864 			 * XXX - this is bogus; flag it?
12865 			 */
12866 			padcnt = 0;
12867 		}
12868 		if (padcnt != 0) {
12869 			CHECK_BYTE_COUNT_SUBR(padcnt);
12870 			COUNT_BYTES_SUBR(padcnt);
12871 		}
12872 	}
12873 
12874 	*trunc = FALSE;
12875 	return offset;
12876 }
12877 
12878 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
12879    as described in 4.2.16.11 of the SNIA CIFS spec
12880    and 2.2.8.3.13 of the MS-CIFS spec
12881 */
12882 int
dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12883 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12884     int offset, guint16 *bcp, gboolean *trunc)
12885 {
12886 	/* compressed file size */
12887 	CHECK_BYTE_COUNT_SUBR(8);
12888 	proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12889 	COUNT_BYTES_SUBR(8);
12890 
12891 	/* compression format */
12892 	CHECK_BYTE_COUNT_SUBR(2);
12893 	proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12894 	COUNT_BYTES_SUBR(2);
12895 
12896 	/* compression unit shift */
12897 	CHECK_BYTE_COUNT_SUBR(1);
12898 	proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12899 	COUNT_BYTES_SUBR(1);
12900 
12901 	/* compression chunk shift */
12902 	CHECK_BYTE_COUNT_SUBR(1);
12903 	proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12904 	COUNT_BYTES_SUBR(1);
12905 
12906 	/* compression cluster shift */
12907 	CHECK_BYTE_COUNT_SUBR(1);
12908 	proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12909 	COUNT_BYTES_SUBR(1);
12910 
12911 	/* 3 reserved bytes */
12912 	CHECK_BYTE_COUNT_SUBR(3);
12913 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
12914 	COUNT_BYTES_SUBR(3);
12915 
12916 	*trunc = FALSE;
12917 	return offset;
12918 }
12919 
12920 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
12921 
12922 static const value_string unix_file_type_vals[] = {
12923 	{ 0, "File" },
12924 	{ 1, "Directory" },
12925 	{ 2, "Symbolic link" },
12926 	{ 3, "Character device" },
12927 	{ 4, "Block device" },
12928 	{ 5, "FIFO" },
12929 	{ 6, "Socket" },
12930 	{ 0, NULL }
12931 };
12932 
12933 static int
dissect_4_2_16_12(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)12934 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12935 		  int offset, guint16 *bcp, gboolean *trunc)
12936 {
12937 	/* End of file (file size) */
12938 	CHECK_BYTE_COUNT_SUBR(8);
12939 	proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12940 	COUNT_BYTES_SUBR(8);
12941 
12942 	/* Number of bytes */
12943 	CHECK_BYTE_COUNT_SUBR(8);
12944 	proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12945 	COUNT_BYTES_SUBR(8);
12946 
12947 	/* Last status change */
12948 	CHECK_BYTE_COUNT_SUBR(8);
12949 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12950 	*bcp -= 8;		/* dissect_nt_64bit_time() increments offset */
12951 
12952 	/* Last access time */
12953 	CHECK_BYTE_COUNT_SUBR(8);
12954 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12955 	*bcp -= 8;
12956 
12957 	/* Last modification time */
12958 	CHECK_BYTE_COUNT_SUBR(8);
12959 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12960 	*bcp -= 8;
12961 
12962 	/* File owner uid */
12963 	CHECK_BYTE_COUNT_SUBR(8);
12964 	proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12965 	COUNT_BYTES_SUBR(8);
12966 
12967 	/* File group gid */
12968 	CHECK_BYTE_COUNT_SUBR(8);
12969 	proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12970 	COUNT_BYTES_SUBR(8);
12971 
12972 	/* File type */
12973 	CHECK_BYTE_COUNT_SUBR(4);
12974 	proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12975 	COUNT_BYTES_SUBR(4);
12976 
12977 	/* Major device number */
12978 	CHECK_BYTE_COUNT_SUBR(8);
12979 	proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12980 	COUNT_BYTES_SUBR(8);
12981 
12982 	/* Minor device number */
12983 	CHECK_BYTE_COUNT_SUBR(8);
12984 	proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12985 	COUNT_BYTES_SUBR(8);
12986 
12987 	/* Unique id */
12988 	CHECK_BYTE_COUNT_SUBR(8);
12989 	proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12990 	COUNT_BYTES_SUBR(8);
12991 
12992 	/* Permissions */
12993 	CHECK_BYTE_COUNT_SUBR(8);
12994 	proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12995 	COUNT_BYTES_SUBR(8);
12996 
12997 	/* Nlinks */
12998 	CHECK_BYTE_COUNT_SUBR(8);
12999 	proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13000 	COUNT_BYTES_SUBR(8);
13001 
13002 	/* Sometimes there is one extra byte in the data field which I
13003 	   guess could be padding, but we are only using 4 or 8 byte
13004 	   data types so this is a bit confusing. -tpot */
13005 
13006 	*trunc = FALSE;
13007 	return offset;
13008 }
13009 
13010 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
13011 
13012 static int
dissect_4_2_16_13(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)13013 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13014 		  int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13015 {
13016 	const char *fn;
13017 	int         fn_len = 0;
13018 
13019 	DISSECTOR_ASSERT(si);
13020 
13021 	/* Link destination */
13022 
13023 	fn = get_unicode_or_ascii_string(
13024 		tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13025 
13026 	CHECK_STRING_SUBR(fn);
13027 	proto_tree_add_string(
13028 		tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13029 	COUNT_BYTES_SUBR(fn_len);
13030 
13031 	*trunc = FALSE;
13032 	return offset;
13033 }
13034 
13035 /* unix ACL
13036 */
13037 static int
dissect_qspi_unix_acl(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)13038 dissect_qspi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13039 		  int offset, guint16 *bcp, gboolean *trunc)
13040 {
13041 	guint16 num_file_aces;
13042 	static int * const perm_fields[] = {
13043 		&hf_smb_posix_ace_perm_read,
13044 		&hf_smb_posix_ace_perm_write,
13045 		&hf_smb_posix_ace_perm_execute,
13046 		NULL
13047 	};
13048 
13049 	/* version */
13050 	CHECK_BYTE_COUNT_SUBR(2);
13051 	proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13052 	COUNT_BYTES_SUBR(2);
13053 
13054 	/* num file acls */
13055 	CHECK_BYTE_COUNT_SUBR(2);
13056 	num_file_aces = tvb_get_letohs(tvb, offset);
13057 	proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13058 	COUNT_BYTES_SUBR(2);
13059 
13060 	/* num default acls */
13061 	CHECK_BYTE_COUNT_SUBR(2);
13062 	proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13063 	COUNT_BYTES_SUBR(2);
13064 
13065 	while (num_file_aces--) {
13066 		proto_item *it, *type_item;
13067 		proto_tree *tr;
13068 		int old_offset = offset;
13069 		guint8 ace_type;
13070 
13071 		tr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_smb_posix_ace, &it, "ACE");
13072 
13073 		/* ace type */
13074 		CHECK_BYTE_COUNT_SUBR(1);
13075 		ace_type = tvb_get_guint8(tvb, offset);
13076 		type_item = proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13077 		COUNT_BYTES_SUBR(1);
13078 
13079 		CHECK_BYTE_COUNT_SUBR(1);
13080 		proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, ENC_BIG_ENDIAN);
13081 		COUNT_BYTES_SUBR(1);
13082 
13083 		switch(ace_type) {
13084 		case POSIX_ACE_TYPE_USER_OBJ:
13085 			CHECK_BYTE_COUNT_SUBR(4);
13086 			proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13087 			COUNT_BYTES_SUBR(4);
13088 
13089 			CHECK_BYTE_COUNT_SUBR(4);
13090 			/* 4 reserved bytes */
13091 			COUNT_BYTES_SUBR(4);
13092 			break;
13093 		case POSIX_ACE_TYPE_GROUP_OBJ:
13094 			CHECK_BYTE_COUNT_SUBR(4);
13095 			proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13096 			COUNT_BYTES_SUBR(4);
13097 
13098 			CHECK_BYTE_COUNT_SUBR(4);
13099 			/* 4 reserved bytes */
13100 			COUNT_BYTES_SUBR(4);
13101 			break;
13102 
13103 		case POSIX_ACE_TYPE_MASK:
13104 		case POSIX_ACE_TYPE_OTHER:
13105 			CHECK_BYTE_COUNT_SUBR(8);
13106 			/* 8 reserved bytes */
13107 			COUNT_BYTES_SUBR(8);
13108 			break;
13109 
13110 		case POSIX_ACE_TYPE_USER:
13111 			CHECK_BYTE_COUNT_SUBR(4);
13112 			proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13113 			COUNT_BYTES_SUBR(4);
13114 
13115 			CHECK_BYTE_COUNT_SUBR(4);
13116 			/* 4 reserved bytes */
13117 			COUNT_BYTES_SUBR(4);
13118 			break;
13119 
13120 		case POSIX_ACE_TYPE_GROUP:
13121 			CHECK_BYTE_COUNT_SUBR(4);
13122 			proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13123 			COUNT_BYTES_SUBR(4);
13124 
13125 			CHECK_BYTE_COUNT_SUBR(4);
13126 			/* 4 reserved bytes */
13127 			COUNT_BYTES_SUBR(4);
13128 			break;
13129 		default:
13130 			expert_add_info(pinfo, type_item, &ei_smb_posix_ace_type);
13131 			CHECK_BYTE_COUNT_SUBR(8);
13132 			/* skip 8 bytes */
13133 			COUNT_BYTES_SUBR(8);
13134 		}
13135 
13136 		proto_item_set_len(it, offset-old_offset);
13137 	}
13138 
13139 	*trunc = FALSE;
13140 	return offset;
13141 }
13142 
13143 static int
dissect_qspi_unix_xattr(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp _U_,gboolean * trunc)13144 dissect_qspi_unix_xattr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
13145 		  int offset, guint16 *bcp _U_, gboolean *trunc)
13146 {
13147 	proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
13148 
13149 	*trunc = FALSE;
13150 	return offset;
13151 }
13152 
13153 static int
dissect_qspi_unix_attr_flags(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp _U_,gboolean * trunc)13154 dissect_qspi_unix_attr_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
13155 		  int offset, guint16 *bcp _U_, gboolean *trunc)
13156 {
13157 	proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
13158 
13159 	*trunc = FALSE;
13160 	return offset;
13161 }
13162 
13163 static int
dissect_qpi_unix_permissions(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp _U_,gboolean * trunc)13164 dissect_qpi_unix_permissions(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
13165 		  int offset, guint16 *bcp _U_, gboolean *trunc)
13166 {
13167 	proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
13168 
13169 	*trunc = FALSE;
13170 	return offset;
13171 }
13172 
13173 static int
dissect_qspi_unix_lock(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp _U_,gboolean * trunc)13174 dissect_qspi_unix_lock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
13175 		  int offset, guint16 *bcp _U_, gboolean *trunc)
13176 {
13177 	proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
13178 
13179 	*trunc = FALSE;
13180 	return offset;
13181 }
13182 
13183 static int
dissect_qspi_unix_open(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp _U_,gboolean * trunc)13184 dissect_qspi_unix_open(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
13185 		  int offset, guint16 *bcp _U_, gboolean *trunc)
13186 {
13187 	proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
13188 
13189 	*trunc = FALSE;
13190 	return offset;
13191 }
13192 
13193 static int
dissect_qspi_unix_unlink(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp _U_,gboolean * trunc)13194 dissect_qspi_unix_unlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
13195 		  int offset, guint16 *bcp _U_, gboolean *trunc)
13196 {
13197 	proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
13198 
13199 	*trunc = FALSE;
13200 	return offset;
13201 }
13202 
13203 /* SMB_FIND_FILE_UNIX_INFO2 */
13204 
13205 #if 0
13206 static const true_false_string tfs_i2f_secure_delete = {
13207 	"File should be erased such that the data is not recoverable",
13208 	"File need not be erased such that the data is not recoverable"
13209 };
13210 static const true_false_string tfs_i2f_enable_undelete = {
13211 	"File should opt-in to a server-specific deletion recovery scheme",
13212 	"File should not opt-in to a server-specific deletion recovery scheme"
13213 };
13214 static const true_false_string tfs_i2f_synchronous = {
13215 	"I/O to this file should be performed synchronously",
13216 	"I/O to this file need not be performed synchronously"
13217 };
13218 static const true_false_string tfs_i2f_immutable = {
13219 	"NO changes can be made to this file",
13220 	"Changes can be made to this file if permissions allow it"
13221 };
13222 static const true_false_string tfs_i2f_append_only = {
13223 	"Only appends can be made to this file",
13224 	"Writes can be made atop existing data in this file"
13225 };
13226 static const true_false_string tfs_i2f_do_not_backup = {
13227 	"Backup programs should ignore this file",
13228 	"Backup programs should not ignore this file"
13229 };
13230 static const true_false_string tfs_i2f_no_update_atime = {
13231 	"The server is not required to update the last access time on this file",
13232 	"The server is required to update the last access time on this file"
13233 };
13234 static const true_false_string tfs_i2f_hidden = {
13235 	"User interface programs may ignore this file",
13236 	"User interface programs should not ignore this file based solely on this flag"
13237 };
13238 #endif
13239 
13240 static int
dissect_unix_info2_file_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset,int hf)13241 dissect_unix_info2_file_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int hf)
13242 {
13243 	static int * const flags[] = {
13244 		&hf_smb_unix_info2_file_flags_secure_delete,
13245 		&hf_smb_unix_info2_file_flags_enable_undelete,
13246 		&hf_smb_unix_info2_file_flags_synchronous,
13247 		&hf_smb_unix_info2_file_flags_immutable,
13248 		&hf_smb_unix_info2_file_flags_append_only,
13249 		&hf_smb_unix_info2_file_flags_do_not_backup,
13250 		&hf_smb_unix_info2_file_flags_no_update_atime,
13251 		&hf_smb_unix_info2_file_flags_hidden,
13252 		NULL
13253 	};
13254 
13255 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf, ett_smb_info2_file_flags, flags, ENC_LITTLE_ENDIAN);
13256 	offset += 4;
13257 
13258 	return offset;
13259 }
13260 
13261 static int
dissect_qspi_unix_info2(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)13262 dissect_qspi_unix_info2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13263 		  int offset, guint16 *bcp, gboolean *trunc)
13264 {
13265 	/* End of file (file size) */
13266 	CHECK_BYTE_COUNT_SUBR(8);
13267 	proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13268 	COUNT_BYTES_SUBR(8);
13269 
13270 	/* Number of bytes (or blocks?  The SNIA spec for UNIX basic
13271 	   info says "bytes", the Samba page for this says "blocks") */
13272 	CHECK_BYTE_COUNT_SUBR(8);
13273 	proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13274 	COUNT_BYTES_SUBR(8);
13275 
13276 	/* Last status change */
13277 	CHECK_BYTE_COUNT_SUBR(8);
13278 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13279 	*bcp -= 8;
13280 
13281 	/* Last access time */
13282 	CHECK_BYTE_COUNT_SUBR(8);
13283 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13284 	*bcp -= 8;
13285 
13286 	/* Last modification time */
13287 	CHECK_BYTE_COUNT_SUBR(8);
13288 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13289 	*bcp -= 8;
13290 
13291 	/* File owner uid */
13292 	CHECK_BYTE_COUNT_SUBR(8);
13293 	proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13294 	COUNT_BYTES_SUBR(8);
13295 
13296 	/* File group gid */
13297 	CHECK_BYTE_COUNT_SUBR(8);
13298 	proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13299 	COUNT_BYTES_SUBR(8);
13300 
13301 	/* File type */
13302 	CHECK_BYTE_COUNT_SUBR(4);
13303 	proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13304 	COUNT_BYTES_SUBR(4);
13305 
13306 	/* Major device number */
13307 	CHECK_BYTE_COUNT_SUBR(8);
13308 	proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13309 	COUNT_BYTES_SUBR(8);
13310 
13311 	/* Minor device number */
13312 	CHECK_BYTE_COUNT_SUBR(8);
13313 	proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13314 	COUNT_BYTES_SUBR(8);
13315 
13316 	/* Unique id */
13317 	CHECK_BYTE_COUNT_SUBR(8);
13318 	proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13319 	COUNT_BYTES_SUBR(8);
13320 
13321 	/* Permissions */
13322 	CHECK_BYTE_COUNT_SUBR(8);
13323 	proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13324 	COUNT_BYTES_SUBR(8);
13325 
13326 	/* Nlinks */
13327 	CHECK_BYTE_COUNT_SUBR(8);
13328 	proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13329 	COUNT_BYTES_SUBR(8);
13330 
13331 	/* Creation time */
13332 	CHECK_BYTE_COUNT_SUBR(8);
13333 	offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_creation_time);
13334 	*bcp -= 8;
13335 
13336 	/* File flags */
13337 	CHECK_BYTE_COUNT_SUBR(4);
13338 	offset = dissect_unix_info2_file_flags(tvb, tree, offset, hf_smb_unix_info2_file_flags);
13339 	*bcp -= 4;
13340 
13341 	/* File flags mask */
13342 	CHECK_BYTE_COUNT_SUBR(4);
13343 	offset = dissect_unix_info2_file_flags(tvb, tree, offset, hf_smb_unix_info2_file_flags_mask);
13344 	*bcp -= 4;
13345 
13346 	*trunc = FALSE;
13347 	return offset;
13348 }
13349 
13350 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
13351 */
13352 int
dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)13353 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
13354     packet_info *pinfo, proto_tree *tree,
13355     int offset, guint16 *bcp, gboolean *trunc)
13356 {
13357 
13358 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
13359 	if (*trunc) {
13360 		return offset;
13361 	}
13362 
13363 	/* allocation size */
13364 	CHECK_BYTE_COUNT_SUBR(8);
13365 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13366 	COUNT_BYTES_SUBR(8);
13367 
13368 	/* end of file */
13369 	CHECK_BYTE_COUNT_SUBR(8);
13370 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13371 	COUNT_BYTES_SUBR(8);
13372 
13373 	/* File Attributes */
13374 	CHECK_BYTE_COUNT_SUBR(4);
13375 	offset = dissect_file_ext_attr(tvb, tree, offset);
13376 	*bcp -= 4;
13377 
13378 	/* 4 reserved bytes */
13379 	CHECK_BYTE_COUNT_SUBR(4);
13380 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
13381 	COUNT_BYTES_SUBR(4);
13382 
13383 	*trunc = FALSE;
13384 	return offset;
13385 }
13386 
13387 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
13388 */
13389 int
dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)13390 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
13391     packet_info *pinfo _U_, proto_tree *tree,
13392     int offset, guint16 *bcp, gboolean *trunc)
13393 {
13394 	/* attribute */
13395 	CHECK_BYTE_COUNT_SUBR(4);
13396 	proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13397 	COUNT_BYTES_SUBR(4);
13398 
13399 	/* reparse tag */
13400 	CHECK_BYTE_COUNT_SUBR(4);
13401 	proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13402 	COUNT_BYTES_SUBR(4);
13403 
13404 	*trunc = FALSE;
13405 	return offset;
13406 }
13407 
13408 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
13409    as described in 4.2.19.2
13410 */
13411 static int
dissect_4_2_19_2(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)13412 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13413     int offset, guint16 *bcp, gboolean *trunc)
13414 {
13415 	/* marked for deletion? */
13416 	CHECK_BYTE_COUNT_SUBR(1);
13417 	proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13418 	COUNT_BYTES_SUBR(1);
13419 
13420 	*trunc = FALSE;
13421 	return offset;
13422 }
13423 
13424 /* Set File Rename Info */
13425 
13426 static const true_false_string tfs_smb_replace = {
13427 	"Remove target file if it exists",
13428 	"Do NOT remove target file if it exists",
13429 };
13430 
13431 static int
dissect_rename_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)13432 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13433 		    int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13434 {
13435 	const char *fn;
13436 	guint32     target_name_len;
13437 	int         fn_len;
13438 
13439 	DISSECTOR_ASSERT(si);
13440 
13441 	/* Replace flag */
13442 	CHECK_BYTE_COUNT_SUBR(4);
13443 	proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13444 	COUNT_BYTES_SUBR(4);
13445 
13446 	/* Root directory handle */
13447 	CHECK_BYTE_COUNT_SUBR(4);
13448 	proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13449 	COUNT_BYTES_SUBR(4);
13450 
13451 	/* Target name length */
13452 	CHECK_BYTE_COUNT_SUBR(4);
13453 	target_name_len = tvb_get_letohl(tvb, offset);
13454 	proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
13455 	COUNT_BYTES_SUBR(4);
13456 
13457 	/* Target name */
13458 	fn_len = target_name_len;
13459 	fn = get_unicode_or_ascii_string(
13460 		tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13461 
13462 	CHECK_STRING_SUBR(fn);
13463 	proto_tree_add_string(
13464 		tree, hf_smb_target_name, tvb, offset, fn_len, fn);
13465 	COUNT_BYTES_SUBR(fn_len);
13466 
13467 	*trunc = FALSE;
13468 	return offset;
13469 }
13470 
13471 static int
dissect_disposition_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)13472 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13473 		    int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13474 {
13475 #if 0
13476 	const char *fn;
13477 	guint32     target_name_len;*/
13478 	int         fn_len;
13479 #endif
13480 
13481 	DISSECTOR_ASSERT(si);
13482 
13483 	/* Disposition flags */
13484 	CHECK_BYTE_COUNT_SUBR(1);
13485 	proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13486 	COUNT_BYTES_SUBR(1);
13487 
13488 	*trunc = FALSE;
13489 	return offset;
13490 }
13491 
13492 int
dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc)13493 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13494 		    int offset, guint16 *bcp, gboolean *trunc)
13495 {
13496 	/* pipe info flag */
13497 	CHECK_BYTE_COUNT_SUBR(1);
13498 	proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13499 	COUNT_BYTES_SUBR(1);
13500 
13501 	*trunc = FALSE;
13502 	return offset;
13503 }
13504 
13505 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
13506   TRANS2_QUERY_FILE_INFORMATION*/
13507 static int
dissect_qpi_loi_vals(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_item * item,int offset,guint16 * bcp,smb_info_t * si)13508 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13509     proto_item *item, int offset, guint16 *bcp, smb_info_t *si)
13510 {
13511 	gboolean    trunc = FALSE;
13512 
13513 	if (!*bcp) {
13514 		return offset;
13515 	}
13516 
13517 	DISSECTOR_ASSERT(si);
13518 
13519 	switch(si->info_level) {
13520 	case 1:		/*Info Standard*/
13521 		offset = dissect_qsfi_SMB_INFO_STANDARD(tvb, pinfo, tree, offset, bcp,
13522 		    &trunc);
13523 		break;
13524 
13525 	case 2:		/*Info Query EA Size*/
13526 		offset = dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvb, pinfo, tree, offset, bcp,
13527 		    &trunc);
13528 		break;
13529 	case 3:		/*Info Query EAs From List*/
13530 	case 4:		/*Info Query All EAs*/
13531 		offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13532 		    &trunc);
13533 		break;
13534 	case 6:		/*Info Is Name Valid*/
13535 		offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
13536 		    &trunc, si);
13537 		break;
13538 	case 0x0101:	/*Query File Basic Info*/
13539 	case 1004:	/* SMB_FILE_BASIC_INFORMATION */
13540 		offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
13541 		    &trunc);
13542 		break;
13543 	case 0x0102:	/*Query File Standard Info*/
13544 	case 1005:	/* SMB_FILE_STANDARD_INFORMATION */
13545 		offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
13546 		    &trunc);
13547 		break;
13548 	case 1006:	/* SMB_FILE_INTERNAL_INFORMATION */
13549 		offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
13550 		    &trunc);
13551 		break;
13552 	case 0x0103:	/*Query File EA Info*/
13553 	case 1007:	/* SMB_FILE_EA_INFORMATION */
13554 		offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
13555 		    &trunc);
13556 		break;
13557 	case 0x0104:	/*Query File Name Info*/
13558 	case 1009:	/* SMB_FILE_NAME_INFORMATION */
13559 		offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
13560 		    &trunc, si->unicode);
13561 		break;
13562 	case 1014:	/* SMB_FILE_POSITION_INFORMATION */
13563 		offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
13564 		    &trunc);
13565 		break;
13566 	case 1016:	/* SMB_FILE_MODE_INFORMATION */
13567 		offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
13568 		    &trunc);
13569 		break;
13570 	case 1017:	/* SMB_FILE_ALIGNMENT_INFORMATION */
13571 		offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
13572 		    &trunc);
13573 		break;
13574 	case 0x0107:	/*Query File All Info*/
13575 	case 1018:	/* SMB_FILE_ALL_INFORMATION */
13576 		offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
13577 		    &trunc, si);
13578 		break;
13579 	case 1019:	/* SMB_FILE_ALLOCATION_INFORMATION */
13580 		offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
13581 		    &trunc);
13582 		break;
13583 	case 1020:	/* SMB_FILE_ENDOFFILE_INFORMATION */
13584 		offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
13585 		    &trunc);
13586 		break;
13587 	case 0x0108:	/*Query File Alt File Info*/
13588 	case 1021:	/* SMB_FILE_ALTERNATE_NAME_INFORMATION */
13589 		offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
13590 		    &trunc, si->unicode);
13591 		break;
13592 	case 1022:	/* SMB_FILE_STREAM_INFORMATION */
13593 		si->unicode = TRUE;
13594 		/* FALLTHRU */
13595 	case 0x0109:	/*Query File Stream Info*/
13596 		offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
13597 		    &trunc, si->unicode);
13598 		break;
13599 	case 0x010b:	/*Query File Compression Info*/
13600 	case 1028:	/* SMB_FILE_COMPRESSION_INFORMATION */
13601 		offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
13602 		    &trunc);
13603 		break;
13604 	case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
13605 		offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
13606 		break;
13607 	case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
13608 		offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
13609 		break;
13610 	case 0x0200:	/* Query File Unix Basic*/
13611 		offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
13612 					   &trunc);
13613 		break;
13614 	case 0x0201:	/* Query File Unix Link*/
13615 		offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13616 					   &trunc, si);
13617 		break;
13618 	case 0x0202:	/* Query File Unix HardLink*/
13619 		/* XXX add this from the SNIA doc */
13620 		break;
13621 	case 0x0204:	/* Query File Unix ACL*/
13622 		offset = dissect_qspi_unix_acl(tvb, pinfo, tree, offset, bcp,
13623 					   &trunc);
13624 		break;
13625 	case 0x0205:	/* Query File Unix XATTR*/
13626 		offset = dissect_qspi_unix_xattr(tvb, pinfo, tree, offset, bcp,
13627 					   &trunc);
13628 		break;
13629 	case 0x0206:	/* Query File Unix Attr Flags*/
13630 		offset = dissect_qspi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
13631 					   &trunc);
13632 		break;
13633 	case 0x0207:	/* Query File Unix Permissions*/
13634 		offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
13635 					   &trunc);
13636 		break;
13637 	case 0x0208:	/* Query File Unix Lock*/
13638 		offset = dissect_qspi_unix_lock(tvb, pinfo, tree, offset, bcp,
13639 					   &trunc);
13640 		break;
13641 	case 0x020b:	/* Query File Unix Info2*/
13642 		offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp,
13643 					   &trunc);
13644 		break;
13645 
13646 	default:
13647 		proto_tree_add_expert(tree, pinfo, &ei_smb_info_level_unknown, tvb, offset, *bcp);
13648 		offset += *bcp;
13649 		*bcp = 0;
13650 		trunc = FALSE;
13651 		break;
13652 	}
13653 
13654 	if (trunc) {
13655 		expert_add_info(pinfo, item, &ei_smb_mal_information_level);
13656 	}
13657 	return offset;
13658 }
13659 
13660 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
13661   TRANS2_SET_FILE_INFORMATION*/
13662 static int
dissect_spi_loi_vals(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_item * item,int offset,guint16 * bcp,smb_info_t * si)13663 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13664     proto_item *item, int offset, guint16 *bcp, smb_info_t *si)
13665 {
13666 	gboolean    trunc;
13667 
13668 	if (!*bcp) {
13669 		return offset;
13670 	}
13671 
13672 	DISSECTOR_ASSERT(si);
13673 
13674 	switch(si->info_level) {
13675 	case 1:		/*Info Standard*/
13676 		offset = dissect_qsfi_SMB_INFO_STANDARD(tvb, pinfo, tree, offset, bcp,
13677 		    &trunc);
13678 		break;
13679 	case 2:		/*Info Set EAs*/
13680 		offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13681 		    &trunc);
13682 		break;
13683 	case 4:		/*Info Query All EAs - not in [MS-CIFS]*/
13684 		offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13685 		    &trunc);
13686 		break;
13687 	case 0x0101:	/*Set File Basic Info*/
13688 	case 1004:	/* SMB_FILE_BASIC_INFORMATION */
13689 		offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
13690 		    &trunc);
13691 		break;
13692 	case 0x0102:	/*Set File Disposition Info*/
13693 		offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
13694 		    &trunc);
13695 		break;
13696 	case 0x0103:	/*Set File Allocation Info*/
13697 	case 1019:	/* Set File Allocation Information */
13698 		offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
13699 		    &trunc);
13700 		break;
13701 	case 0x0104:	/*Set End Of File Info*/
13702 	case 1020:	/* SMB_FILE_ENDOFFILE_INFORMATION */
13703 		offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
13704 		    &trunc);
13705 		break;
13706 	case 0x0200:	/*Set File Unix Basic.  Same as query. */
13707 		offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
13708 		    &trunc);
13709 		break;
13710 	case 0x0201:	/*Set File Unix Link.  Same as query. */
13711 		offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13712 		    &trunc, si);
13713 		break;
13714 	case 0x0202:	/*Set File Unix HardLink.  Same as link query. */
13715 		offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13716 		    &trunc, si);
13717 		break;
13718 	case 0x0204:	/* Set File Unix ACL*/
13719 		offset = dissect_qspi_unix_acl(tvb, pinfo, tree, offset, bcp,
13720 					   &trunc);
13721 		break;
13722 	case 0x0205:	/* Set File Unix XATTR*/
13723 		offset = dissect_qspi_unix_xattr(tvb, pinfo, tree, offset, bcp,
13724 					   &trunc);
13725 		break;
13726 	case 0x0206:	/* Set File Unix Attr Flags*/
13727 		offset = dissect_qspi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
13728 					   &trunc);
13729 		break;
13730 	case 0x0208:	/* Set File Unix Lock*/
13731 		offset = dissect_qspi_unix_lock(tvb, pinfo, tree, offset, bcp,
13732 					   &trunc);
13733 		break;
13734 	case 0x0209:	/* Set File Unix Open*/
13735 		offset = dissect_qspi_unix_open(tvb, pinfo, tree, offset, bcp,
13736 					   &trunc);
13737 		break;
13738 	case 0x020a:	/* Set File Unix Unlink*/
13739 		offset = dissect_qspi_unix_unlink(tvb, pinfo, tree, offset, bcp,
13740 					   &trunc);
13741 		break;
13742 	case 0x020b:	/* Set File Unix Info2*/
13743 		offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp,
13744 					   &trunc);
13745 		break;
13746 	case 1010:	/* Set File Rename */
13747 		offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
13748 		    &trunc, si);
13749 		break;
13750 	case 1013: /* Set Disposition Information */
13751 		offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
13752 		    &trunc, si);
13753 		break;
13754 	case 1014:	/* SMB_FILE_POSITION_INFORMATION */
13755 		offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
13756 		    &trunc);
13757 		break;
13758 	case 1016:	/* SMB_FILE_MODE_INFORMATION */
13759 		offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
13760 		    &trunc);
13761 		break;
13762 	case 1023: /* Set Pipe Info */
13763 		offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
13764 		    &trunc);
13765 		break;
13766 	case 1025:
13767 	case 1029:
13768 	case 1032:
13769 	case 1039:
13770 	case 1040:
13771 		/* XXX: TODO, extra levels discovered by tridge */
13772 		proto_tree_add_expert(tree, pinfo, &ei_smb_info_level_not_understood, tvb, offset, *bcp);
13773 		offset += *bcp;
13774 		*bcp = 0;
13775 		trunc = FALSE;
13776 		break;
13777 
13778 	default:
13779 		proto_tree_add_expert(tree, pinfo, &ei_smb_info_level_unknown, tvb, offset, *bcp);
13780 		offset += *bcp;
13781 		*bcp = 0;
13782 		trunc = FALSE;
13783 		break;
13784 	}
13785 
13786 	if (trunc) {
13787 		expert_add_info(pinfo, item, &ei_smb_mal_information_level);
13788 	}
13789 	return offset;
13790 }
13791 
13792 
13793 static const true_false_string tfs_quota_flags_deny_disk = {
13794 	"DENY DISK SPACE for users exceeding quota limit",
13795 	"Do NOT deny disk space for users exceeding quota limit"
13796 };
13797 static const true_false_string tfs_quota_flags_log_limit = {
13798 	"LOG EVENT when a user exceeds their QUOTA LIMIT",
13799 	"Do NOT log event when a user exceeds their quota limit"
13800 };
13801 static const true_false_string tfs_quota_flags_log_warning = {
13802 	"LOG EVENT when a user exceeds their WARNING LEVEL",
13803 	"Do NOT log event when a user exceeds their warning level"
13804 };
13805 static const true_false_string tfs_quota_flags_enabled = {
13806 	"Quotas are ENABLED of this fs",
13807 	"Quotas are NOT enabled on this fs"
13808 };
13809 static void
dissect_quota_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)13810 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13811 {
13812 	static int * const mask[] = {
13813 		&hf_smb_quota_flags_deny_disk,
13814 		&hf_smb_quota_flags_log_warning,
13815 		&hf_smb_quota_flags_log_limit,
13816 		&hf_smb_quota_flags_enabled,
13817 		NULL
13818 	};
13819 
13820 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_quota_flags,
13821 							ett_smb_quotaflags, mask, ENC_NA);
13822 }
13823 
13824 int
dissect_nt_quota(tvbuff_t * tvb,proto_tree * tree,int offset,guint16 * bcp)13825 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
13826 {
13827 	/* first 24 bytes are unknown */
13828 	CHECK_BYTE_COUNT_TRANS_SUBR(24);
13829 	proto_tree_add_item(tree, hf_smb_unknown, tvb,
13830 		    offset, 24, ENC_NA);
13831 	COUNT_BYTES_TRANS_SUBR(24);
13832 
13833 	/* number of bytes for quota warning */
13834 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
13835 	proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13836 	COUNT_BYTES_TRANS_SUBR(8);
13837 
13838 	/* number of bytes for quota limit */
13839 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
13840 	proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13841 	COUNT_BYTES_TRANS_SUBR(8);
13842 
13843 	/* one byte of quota flags */
13844 	CHECK_BYTE_COUNT_TRANS_SUBR(1);
13845 	dissect_quota_flags(tvb, tree, offset);
13846 	COUNT_BYTES_TRANS_SUBR(1);
13847 
13848 	/* these 7 bytes are unknown */
13849 	CHECK_BYTE_COUNT_TRANS_SUBR(7);
13850 	proto_tree_add_item(tree, hf_smb_unknown, tvb,
13851 		    offset, 7, ENC_NA);
13852 	COUNT_BYTES_TRANS_SUBR(7);
13853 
13854 	return offset;
13855 }
13856 
13857 static int
dissect_sfsi_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,smb_info_t * si)13858 dissect_sfsi_request(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13859     int offset, guint16 *bcp, smb_info_t *si)
13860 {
13861 	if (!*bcp) {
13862 		return offset;
13863 	}
13864 
13865 	DISSECTOR_ASSERT(si);
13866 
13867 	switch(si->info_level) {
13868 	case 0x203: /* REQUEST_TRANSPORT_ENCRYPTION */ {
13869 		proto_item *blob_item;
13870 		tvbuff_t *blob_tvb;
13871 		proto_tree *blob_tree;
13872 
13873 		/* security blob */
13874 		blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
13875 						tvb, offset,
13876 						tvb_reported_length_remaining(tvb, offset),
13877 						ENC_NA);
13878 
13879 		/* As an optimization, because Windows is perverse,
13880 		   we check to see if NTLMSSP is the first part of the
13881 		   blob, and if so, call the NTLMSSP dissector,
13882 		   otherwise we call the GSS-API dissector. This is because
13883 		   Windows can request RAW NTLMSSP, but will happily handle
13884 		   a client that wraps NTLMSSP in SPNEGO
13885 		*/
13886 
13887 		blob_tree = proto_item_add_subtree(blob_item,
13888 						   ett_smb_secblob);
13889 
13890 		blob_tvb = tvb_new_subset_remaining(tvb, offset);
13891 
13892 		if (tvb_strneql(blob_tvb, 0, "NTLMSSP", 7) == 0) {
13893 			call_dissector(ntlmssp_handle, blob_tvb, pinfo, blob_tree);
13894 		} else {
13895 			call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
13896 		}
13897 
13898 		offset += tvb_reported_length_remaining(tvb, offset);
13899 		*bcp = 0;
13900 		break;
13901 	}
13902 	case 1006:	/* QUERY_FS_QUOTA_INFO */
13903 		offset = dissect_nt_quota(tvb, tree, offset, bcp);
13904 		break;
13905 	}
13906 
13907 	return offset;
13908 }
13909 
13910 static int
dissect_sfsi_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,smb_info_t * si)13911 dissect_sfsi_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13912     int offset, guint16 *bcp, smb_info_t *si)
13913 {
13914 	if (!*bcp) {
13915 		return offset;
13916 	}
13917 
13918 	DISSECTOR_ASSERT(si);
13919 
13920 	switch(si->info_level) {
13921 	case 0x203: /* REQUEST_TRANSPORT_ENCRYPTION */ {
13922 		proto_item *blob_item;
13923 		tvbuff_t *blob_tvb;
13924 		proto_tree *blob_tree;
13925 
13926 		/* security blob */
13927 		blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
13928 						tvb, offset,
13929 						tvb_reported_length_remaining(tvb, offset),
13930 						ENC_NA);
13931 
13932 		/* As an optimization, because Windows is perverse,
13933 		   we check to see if NTLMSSP is the first part of the
13934 		   blob, and if so, call the NTLMSSP dissector,
13935 		   otherwise we call the GSS-API dissector. This is because
13936 		   Windows can request RAW NTLMSSP, but will happily handle
13937 		   a client that wraps NTLMSSP in SPNEGO
13938 		*/
13939 
13940 		blob_tree = proto_item_add_subtree(blob_item,
13941 						   ett_smb_secblob);
13942 
13943 		blob_tvb = tvb_new_subset_remaining(tvb, offset);
13944 
13945 		if (tvb_strneql(blob_tvb, 0, "NTLMSSP", 7) == 0) {
13946 			call_dissector(ntlmssp_handle, blob_tvb, pinfo, blob_tree);
13947 		} else {
13948 			call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
13949 		}
13950 
13951 		offset += tvb_reported_length_remaining(tvb, offset);
13952 		*bcp = 0;
13953 		break;
13954 	}
13955 	case 1006:	/* QUERY_FS_QUOTA_INFO */
13956 		/* nothing */
13957 		break;
13958 	}
13959 
13960 	return offset;
13961 }
13962 
13963 static int
dissect_transaction2_request_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,int subcmd,guint16 dc,smb_info_t * si)13964 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
13965     proto_tree *parent_tree, int offset, int subcmd, guint16 dc, smb_info_t *si)
13966 {
13967 	proto_item *item;
13968 	proto_tree *tree;
13969 
13970 	DISSECTOR_ASSERT(si);
13971 
13972 	tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, dc,
13973 				ett_smb_transaction_data, &item, "%s Data",
13974 				val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
13975 					       "Unknown (0x%02x)"));
13976 
13977 	switch(subcmd) {
13978 	case 0x0000:	/*TRANS2_OPEN2*/
13979 		/* XXX don't know how to decode FEAList */
13980 		break;
13981 	case 0x0001:	/*TRANS2_FIND_FIRST2*/
13982 		/* XXX don't know how to decode FEAList */
13983 		break;
13984 	case 0x0002:	/*TRANS2_FIND_NEXT2*/
13985 		/* XXX don't know how to decode FEAList */
13986 		break;
13987 	case 0x0003:	/*TRANS2_QUERY_FS_INFORMATION*/
13988 		/* no data field in this request */
13989 		break;
13990 	case 0x0004:	/* TRANS2_SET_FS_INFORMATION */
13991 		offset = dissect_sfsi_request(tvb, pinfo, tree, offset, &dc, si);
13992 		break;
13993 	case 0x0005:	/*TRANS2_QUERY_PATH_INFORMATION*/
13994 		/* no data field in this request */
13995 		/*
13996 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
13997 		 * Extensions Version 3.0, Document Version 1.11,
13998 		 * July 19, 1990" says there may be "Additional
13999 		 * FileInfoLevel dependent information" here.
14000 		 *
14001 		 * Was that just a cut-and-pasteo?
14002 		 * TRANS2_SET_PATH_INFORMATION *does* have that information
14003 		 * here.
14004 		 */
14005 		break;
14006 	case 0x0006:	/*TRANS2_SET_PATH_INFORMATION*/
14007 		offset = dissect_spi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
14008 		break;
14009 	case 0x0007:	/*TRANS2_QUERY_FILE_INFORMATION*/
14010 		/* no data field in this request */
14011 		/*
14012 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
14013 		 * Extensions Version 3.0, Document Version 1.11,
14014 		 * July 19, 1990" says there may be "Additional
14015 		 * FileInfoLevel dependent information" here.
14016 		 *
14017 		 * Was that just a cut-and-pasteo?
14018 		 * TRANS2_SET_FILE_INFORMATION *does* have that information
14019 		 * here.
14020 		 */
14021 		break;
14022 	case 0x0008:	/*TRANS2_SET_FILE_INFORMATION*/
14023 		offset = dissect_spi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
14024 		break;
14025 	case 0x0009:	/*TRANS2_FSCTL*/
14026 		/*XXX don't know how to decode this yet */
14027 
14028 		/*
14029 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
14030 		 * Extensions Version 3.0, Document Version 1.11,
14031 		 * July 19, 1990" says this this contains a
14032 		 * "File system specific data block".  (That means we
14033 		 * may not be able to dissect it in any case.)
14034 		 */
14035 		break;
14036 	case 0x000a:	/*TRANS2_IOCTL2*/
14037 		/*XXX don't know how to decode this yet */
14038 
14039 		/*
14040 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
14041 		 * Extensions Version 3.0, Document Version 1.11,
14042 		 * July 19, 1990" says this this contains a
14043 		 * "Device/function specific data block".  (That
14044 		 * means we may not be able to dissect it in any case.)
14045 		 */
14046 		break;
14047 	case 0x000b:	/*TRANS2_FIND_NOTIFY_FIRST*/
14048 		/*XXX don't know how to decode this yet */
14049 
14050 		/*
14051 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
14052 		 * Extensions Version 3.0, Document Version 1.11,
14053 		 * July 19, 1990" says this this contains "additional
14054 		 * level dependent match data".
14055 		 */
14056 		break;
14057 	case 0x000c:	/*TRANS2_FIND_NOTIFY_NEXT*/
14058 		/*XXX don't know how to decode this yet */
14059 
14060 		/*
14061 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
14062 		 * Extensions Version 3.0, Document Version 1.11,
14063 		 * July 19, 1990" says this this contains "additional
14064 		 * level dependent monitor information".
14065 		 */
14066 		break;
14067 	case 0x000d:	/*TRANS2_CREATE_DIRECTORY*/
14068 		/* XXX optional FEAList, unknown what FEAList looks like*/
14069 		break;
14070 	case 0x000e:	/*TRANS2_SESSION_SETUP*/
14071 		/*XXX don't know how to decode this yet */
14072 		break;
14073 	case 0x0010:	/*TRANS2_GET_DFS_REFERRAL*/
14074 		/* no data field in this request */
14075 		break;
14076 	case 0x0011:	/*TRANS2_REPORT_DFS_INCONSISTENCY*/
14077 		offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc, si);
14078 		break;
14079 	}
14080 
14081 	/* ooops there were data we didn't know how to process */
14082 	if (dc != 0) {
14083 		proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, ENC_NA);
14084 		offset += dc;
14085 	}
14086 
14087 	return offset;
14088 }
14089 
14090 
14091 static void
dissect_trans_data(tvbuff_t * s_tvb,tvbuff_t * p_tvb,tvbuff_t * d_tvb,proto_tree * tree)14092 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
14093     proto_tree *tree)
14094 {
14095 	int   i;
14096 	int   offset;
14097 	guint length;
14098 
14099 	/*
14100 	 * Show the setup words.
14101 	 */
14102 	if (s_tvb != NULL) {
14103 		length = tvb_reported_length(s_tvb);
14104 		for (i = 0, offset = 0; length >= 2;
14105 		    i++, offset += 2, length -= 2) {
14106 			/*
14107 			 * XXX - add a setup word filterable field?
14108 			 */
14109 			proto_tree_add_uint_format(tree, hf_smb_trans_data_setup_word, s_tvb, offset, 2,
14110 			    tvb_get_letohs(s_tvb, offset), "Setup Word %d: 0x%04x", i, tvb_get_letohs(s_tvb, offset));
14111 		}
14112 	}
14113 
14114 	/*
14115 	 * Show the parameters, if any.
14116 	 */
14117 	if (p_tvb != NULL) {
14118 		length = tvb_reported_length(p_tvb);
14119 		if (length != 0) {
14120 			proto_tree_add_item(tree, hf_smb_trans_data_parameters, p_tvb, 0, length, ENC_NA);
14121 		}
14122 	}
14123 
14124 	/*
14125 	 * Show the data, if any.
14126 	 */
14127 	if (d_tvb != NULL) {
14128 		length = tvb_reported_length(d_tvb);
14129 		if (length != 0) {
14130 			proto_tree_add_item(tree, hf_smb_trans_data, d_tvb, 0, length, ENC_NA);
14131 		}
14132 	}
14133 }
14134 
14135 /* This routine handles the following 4 calls
14136    Transaction  0x25
14137    Transaction Secondary 0x26
14138    Transaction2 0x32
14139    Transaction2 Secondary 0x33
14140 */
14141 static int
dissect_transaction_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)14142 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
14143 {
14144 	guint8                wc, sc = 0;
14145 	int                   so     = offset;
14146 	int                   sl     = 0;
14147 	int                   spo    = offset;
14148 	int                   spc    = 0;
14149 	guint16               od     = 0, po = 0, pc = 0, dc = 0, pd, dd = 0;
14150 	int                   subcmd = -1;
14151 	guint32               to;
14152 	int                   an_len;
14153 	const char           *an     = NULL;
14154 	smb_transact2_info_t *t2i;
14155 	smb_transact_info_t  *tri;
14156 	guint16               bc;
14157 	int                   padcnt;
14158 	gboolean              dissected_trans;
14159 
14160 	DISSECTOR_ASSERT(si);
14161 
14162 	WORD_COUNT;
14163 
14164 	if (wc == 8 || (wc == 9 && si->cmd == SMB_COM_TRANSACTION2_SECONDARY)) {
14165 		/*secondary client request*/
14166 
14167 		/* total param count, only a 16bit integer here*/
14168 		proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14169 		offset += 2;
14170 
14171 		/* total data count , only 16bit integer here*/
14172 		proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14173 		offset += 2;
14174 
14175 		/* param count */
14176 		pc = tvb_get_letohs(tvb, offset);
14177 		proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14178 		offset += 2;
14179 
14180 		/* param offset */
14181 		po = tvb_get_letohs(tvb, offset);
14182 		proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14183 		offset += 2;
14184 
14185 		/* param disp */
14186 		pd = tvb_get_letohs(tvb, offset);
14187 		proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14188 		offset += 2;
14189 
14190 		/* data count */
14191 		dc = tvb_get_letohs(tvb, offset);
14192 		proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14193 		offset += 2;
14194 
14195 		/* data offset */
14196 		od = tvb_get_letohs(tvb, offset);
14197 		proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14198 		offset += 2;
14199 
14200 		/* data disp */
14201 		dd = tvb_get_letohs(tvb, offset);
14202 		proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14203 		offset += 2;
14204 
14205 		if (si->cmd == SMB_COM_TRANSACTION2 || si->cmd == SMB_COM_TRANSACTION2_SECONDARY) {
14206 			guint16 fid;
14207 
14208 			/* fid */
14209 			fid = tvb_get_letohs(tvb, offset);
14210 			dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
14211 
14212 			offset += 2;
14213 		}
14214 
14215 		/* There are no setup words. */
14216 		so = offset;
14217 		sl = 0;
14218 	} else {
14219 		/* it is not a secondary request */
14220 
14221 		/* total param count , only a 16 bit integer here*/
14222 		proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14223 		offset += 2;
14224 
14225 		/* total data count , only 16bit integer here*/
14226 		proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14227 		offset += 2;
14228 
14229 		/* max param count , only 16bit integer here*/
14230 		proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14231 		offset += 2;
14232 
14233 		/* max data count, only 16bit integer here*/
14234 		proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14235 		offset += 2;
14236 
14237 		/* max setup count, only 16bit integer here*/
14238 		proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, ENC_NA);
14239 		offset += 1;
14240 
14241 		/* reserved byte */
14242 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
14243 		offset += 1;
14244 
14245 		/* transaction flags */
14246 		dissect_transaction_flags(tvb, tree, offset);
14247 		offset += 2;
14248 
14249 		/* timeout */
14250 		to = tvb_get_letohl(tvb, offset);
14251 		proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
14252 		offset += 4;
14253 
14254 		/* 2 reserved bytes */
14255 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
14256 		offset += 2;
14257 
14258 		/* param count */
14259 		pc = tvb_get_letohs(tvb, offset);
14260 		proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14261 		offset += 2;
14262 
14263 		/* param offset */
14264 		po = tvb_get_letohs(tvb, offset);
14265 		proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14266 		offset += 2;
14267 
14268 		/* data count */
14269 		dc = tvb_get_letohs(tvb, offset);
14270 		proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14271 		offset += 2;
14272 
14273 		/* data offset */
14274 		od = tvb_get_letohs(tvb, offset);
14275 		proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14276 		offset += 2;
14277 
14278 		/* data displacement is zero here */
14279 		dd = 0;
14280 
14281 		/* setup count */
14282 		sc = tvb_get_guint8(tvb, offset);
14283 		proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14284 		offset += 1;
14285 
14286 		/* reserved byte */
14287 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
14288 		offset += 1;
14289 
14290 		/* this is where the setup bytes, if any start */
14291 		so = offset;
14292 		sl = sc*2;
14293 
14294 		/* if there were any setup bytes, decode them */
14295 		if (sc) {
14296 			switch(si->cmd) {
14297 
14298 			case SMB_COM_TRANSACTION2:
14299 				/* TRANSACTION2 only has one setup word and
14300 				   that is the subcommand code.
14301 
14302 				   XXX - except for TRANS2_FSCTL
14303 				   and TRANS2_IOCTL. */
14304 				subcmd = tvb_get_letohs(tvb, offset);
14305 				proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
14306 				    tvb, offset, 2, subcmd);
14307 				col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14308  					    val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
14309 							   "Unknown (0x%02x)"));
14310 
14311 				if (!si->unidir) {
14312 					if (!pinfo->fd->visited && si->sip) {
14313 						/*
14314 						 * Allocate a new
14315 						 * smb_transact2_info_t
14316 						 * structure.
14317 						 */
14318 						t2i = wmem_new(wmem_file_scope(), smb_transact2_info_t);
14319 						t2i->subcmd = subcmd;
14320 						t2i->info_level = -1;
14321 						t2i->resume_keys = FALSE;
14322 						t2i->name = NULL;
14323 						si->sip->extra_info = t2i;
14324 						si->sip->extra_info_type = SMB_EI_T2I;
14325 					}
14326 				}
14327 
14328 				/*
14329 				 * XXX - process TRANS2_FSCTL and
14330 				 * TRANS2_IOCTL setup words here.
14331 				 */
14332 				break;
14333 
14334 			case SMB_COM_TRANSACTION:
14335 				/* TRANSACTION setup words processed below */
14336 				break;
14337 			}
14338 
14339 			offset += sl;
14340 		}
14341 	}
14342 
14343 	BYTE_COUNT;
14344 
14345 	if (wc != 8) {
14346 		/* primary request */
14347 		/* name is NULL if transaction2 */
14348 		if (si->cmd == SMB_COM_TRANSACTION) {
14349 			/* Transaction Name */
14350 			an = get_unicode_or_ascii_string(tvb, &offset,
14351 				si->unicode, &an_len, FALSE, FALSE, &bc);
14352 			if (an == NULL)
14353 				goto endofcommand;
14354 			proto_tree_add_string(tree, hf_smb_trans_name, tvb,
14355 				offset, an_len, an);
14356 			COUNT_BYTES(an_len);
14357 		}
14358 	}
14359 
14360 	/*
14361 	 * The pipe or mailslot arguments for Transaction start with
14362 	 * the first setup word (or where the first setup word would
14363 	 * be if there were any setup words), and run to the current
14364 	 * offset (which could mean that there aren't any).
14365 	 */
14366 	spo = so;
14367 	spc = offset - spo;
14368 
14369 	/* parameters */
14370 	if (po > offset) {
14371 		/* We have some initial padding bytes.
14372 		*/
14373 		padcnt = po-offset;
14374 		if (padcnt > bc)
14375 			padcnt = bc;
14376 		proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
14377 		COUNT_BYTES(padcnt);
14378 	}
14379 	if (pc) {
14380 		CHECK_BYTE_COUNT(pc);
14381 		switch(si->cmd) {
14382 
14383 		case SMB_COM_TRANSACTION2:
14384 			/* TRANSACTION2 parameters*/
14385 			offset = dissect_transaction2_request_parameters(tvb,
14386 			    pinfo, tree, offset, subcmd, pc, si);
14387 			bc -= pc;
14388 			break;
14389 
14390 		case SMB_COM_TRANSACTION:
14391 			/* TRANSACTION parameters processed below */
14392 			COUNT_BYTES(pc);
14393 			break;
14394 		}
14395 	}
14396 
14397 	/* data */
14398 	if (od > offset) {
14399 		/* We have some initial padding bytes.
14400 		*/
14401 		padcnt = od-offset;
14402 		if (padcnt > bc)
14403 			padcnt = bc;
14404 		proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
14405 		COUNT_BYTES(padcnt);
14406 	}
14407 	if (dc) {
14408 		CHECK_BYTE_COUNT(dc);
14409 		switch(si->cmd) {
14410 
14411 		case SMB_COM_TRANSACTION2:
14412 			/* TRANSACTION2 data*/
14413 			offset = dissect_transaction2_request_data(tvb, pinfo,
14414 			    tree, offset, subcmd, dc, si);
14415 			bc -= dc;
14416 			break;
14417 
14418 		case SMB_COM_TRANSACTION:
14419 			/* TRANSACTION data processed below */
14420 			COUNT_BYTES(dc);
14421 			break;
14422 		}
14423 	}
14424 
14425 	/*TRANSACTION request parameters */
14426 	if (si->cmd == SMB_COM_TRANSACTION) {
14427 		/*XXX replace this block with a function and use that one
14428 		     for both requests/responses*/
14429 		if (dd == 0) {
14430 			tvbuff_t *p_tvb, *d_tvb, *s_tvb;
14431 			tvbuff_t *sp_tvb, *pd_tvb;
14432 
14433 			if (pc > 0) {
14434 				if (pc>tvb_reported_length_remaining(tvb, po)) {
14435 					p_tvb = tvb_new_subset_length_caplen(tvb, po, tvb_reported_length_remaining(tvb, po), pc);
14436 				} else {
14437 					p_tvb = tvb_new_subset_length(tvb, po, pc);
14438 				}
14439 			} else {
14440 				p_tvb = NULL;
14441 			}
14442 			if (dc > 0) {
14443 				if (dc>tvb_reported_length_remaining(tvb, od)) {
14444 					d_tvb = tvb_new_subset_length_caplen(tvb, od, tvb_reported_length_remaining(tvb, od), dc);
14445 				} else {
14446 					d_tvb = tvb_new_subset_length(tvb, od, dc);
14447 				}
14448 			} else {
14449 				d_tvb = NULL;
14450 			}
14451 			if (sl) {
14452 				if (sl>tvb_reported_length_remaining(tvb, so)) {
14453 					s_tvb = tvb_new_subset_length_caplen(tvb, so, tvb_reported_length_remaining(tvb, so), sl);
14454 				} else {
14455 					s_tvb = tvb_new_subset_length(tvb, so, sl);
14456 				}
14457 			} else {
14458 				s_tvb = NULL;
14459 			}
14460 
14461 			if (!si->unidir) {
14462 				if (!pinfo->fd->visited && si->sip) {
14463 					/*
14464 					 * Allocate a new smb_transact_info_t
14465 					 * structure.
14466 					 */
14467 					tri = wmem_new(wmem_file_scope(), smb_transact_info_t);
14468 					tri->subcmd = -1;
14469 					tri->trans_subcmd = -1;
14470 					tri->function = -1;
14471 					tri->fid = -1;
14472 					tri->lanman_cmd = 0;
14473 					tri->param_descrip = NULL;
14474 					tri->data_descrip = NULL;
14475 					tri->aux_data_descrip = NULL;
14476 					tri->info_level = -1;
14477 					si->sip->extra_info = tri;
14478 					si->sip->extra_info_type = SMB_EI_TRI;
14479 				} else {
14480 					/*
14481 					 * We already filled the structure
14482 					 * in; don't bother doing so again.
14483 					 */
14484 					tri = NULL;
14485 				}
14486 			} else {
14487 				/*
14488 				 * This is a unidirectional message, for
14489 				 * which there will be no reply; don't
14490 				 * bother allocating an "smb_transact_info_t"
14491 				 * structure for it.
14492 				 */
14493 				tri = NULL;
14494 			}
14495 			dissected_trans = FALSE;
14496 			if (an == NULL)
14497 				goto endofcommand;
14498 			if (strncmp("\\PIPE\\", an, 6) == 0) {
14499 				if (tri != NULL)
14500 					tri->subcmd = TRANSACTION_PIPE;
14501 
14502 				/*
14503 				 * A tvbuff containing the setup words and
14504 				 * the pipe path.
14505 				 */
14506 				sp_tvb = tvb_new_subset_length(tvb, spo, spc);
14507 
14508 				/*
14509 				 * A tvbuff containing the parameters and the
14510 				 * data.
14511 				 */
14512 				pd_tvb = tvb_new_subset_remaining(tvb, po);
14513 
14514 				dissected_trans = dissect_pipe_smb(sp_tvb,
14515 				    s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
14516 				    top_tree_global, si);
14517 
14518 				/* In case we did not see the TreeConnect call,
14519 				   store this TID here as well as a IPC TID
14520 				   so we know that future Read/Writes to this
14521 				   TID is (probably) DCERPC.
14522 				*/
14523 				if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
14524 					g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
14525 				}
14526 				g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
14527 			} else if (strncmp("\\MAILSLOT\\", an, 10) == 0) {
14528 				if (tri != NULL)
14529 					tri->subcmd = TRANSACTION_MAILSLOT;
14530 
14531 				/*
14532 				 * A tvbuff containing the setup words and
14533 				 * the mailslot path.
14534 				 */
14535 				sp_tvb = tvb_new_subset_length(tvb, spo, spc);
14536 				dissected_trans = dissect_mailslot_smb(sp_tvb,
14537 				    s_tvb, d_tvb, an+10, pinfo, top_tree_global, si);
14538 			}
14539 			if (!dissected_trans)
14540 				dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14541 		} else {
14542 			col_append_str(pinfo->cinfo, COL_INFO,
14543 					"[transact continuation]");
14544 		}
14545 	}
14546 
14547 	END_OF_SMB
14548 
14549 	return offset;
14550 }
14551 
14552 
14553 
14554 static int
dissect_4_3_4_1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)14555 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14556     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14557 {
14558 	int                   fn_len;
14559 	const char           *fn;
14560 	int                   old_offset  = offset;
14561 	proto_item           *item;
14562 	proto_tree           *tree;
14563 	smb_transact2_info_t *t2i;
14564 	gboolean              resume_keys = FALSE;
14565 	guint32               bytes_needed = 0;
14566 
14567 	DISSECTOR_ASSERT(si);
14568 
14569 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14570 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
14571 		if (t2i != NULL)
14572 			resume_keys = t2i->resume_keys;
14573 	}
14574 
14575 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
14576 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14577 
14578 	/*
14579 	 * Figure out of there are enough bytes to display the whole entry.
14580 	 * This consistes of 22 bytes or 26 bytes if resume_keys, followed
14581 	 * by a length byte and that many chars.
14582 	 */
14583 	bytes_needed = 23 + (resume_keys ? 4 : 0);
14584 	tvb_ensure_bytes_exist(tvb, offset, bytes_needed);
14585 
14586 	/* Now, get the length */
14587 	fn_len = tvb_get_guint8(tvb, offset + bytes_needed - 1);
14588 	tvb_ensure_bytes_exist(tvb, offset, bytes_needed + fn_len);
14589 
14590 	if (resume_keys) {
14591 		/* resume key */
14592 		CHECK_BYTE_COUNT_SUBR(4);
14593 		proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14594 		COUNT_BYTES_SUBR(4);
14595 	}
14596 
14597 	/* create time */
14598 	CHECK_BYTE_COUNT_SUBR(4);
14599 	offset = dissect_smb_datetime(tvb, tree, offset,
14600 		hf_smb_create_time,
14601 		hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14602 	*bcp -= 4;
14603 
14604 	/* access time */
14605 	CHECK_BYTE_COUNT_SUBR(4);
14606 	offset = dissect_smb_datetime(tvb, tree, offset,
14607 		hf_smb_access_time,
14608 		hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14609 	*bcp -= 4;
14610 
14611 	/* last write time */
14612 	CHECK_BYTE_COUNT_SUBR(4);
14613 	offset = dissect_smb_datetime(tvb, tree, offset,
14614 		hf_smb_last_write_time,
14615 		hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14616 	*bcp -= 4;
14617 
14618 	/* data size */
14619 	CHECK_BYTE_COUNT_SUBR(4);
14620 	proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14621 	COUNT_BYTES_SUBR(4);
14622 
14623 	/* allocation size */
14624 	CHECK_BYTE_COUNT_SUBR(4);
14625 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14626 	COUNT_BYTES_SUBR(4);
14627 
14628 	/* File Attributes */
14629 	CHECK_BYTE_COUNT_SUBR(2);
14630 	offset = dissect_file_attributes(tvb, tree, offset);
14631 	*bcp -= 2;
14632 
14633 	/* file name len */
14634 	CHECK_BYTE_COUNT_SUBR(1);
14635 	fn_len = tvb_get_guint8(tvb, offset);
14636 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14637 	COUNT_BYTES_SUBR(1);
14638 	if (si->unicode)
14639 		fn_len += 2;	/* include terminating '\0' */
14640 	else
14641 		fn_len++;	/* include terminating '\0' */
14642 
14643 	/* file name */
14644 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14645 	CHECK_STRING_SUBR(fn);
14646 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14647 		fn);
14648 	COUNT_BYTES_SUBR(fn_len);
14649 
14650 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14651 		    format_text(wmem_packet_scope(), fn, strlen(fn)));
14652 
14653 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14654 	proto_item_set_len(item, offset-old_offset);
14655 
14656 	*trunc = FALSE;
14657 	return offset;
14658 }
14659 
14660 static int
dissect_4_3_4_2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)14661 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14662     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14663 {
14664 	int                   fn_len;
14665 	const char           *fn;
14666 	int                   old_offset  = offset;
14667 	proto_item           *item;
14668 	proto_tree           *tree;
14669 	smb_transact2_info_t *t2i;
14670 	gboolean              resume_keys = FALSE;
14671 	guint32               bytes_needed = 0;
14672 
14673 	DISSECTOR_ASSERT(si);
14674 
14675 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14676 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
14677 		if (t2i != NULL)
14678 			resume_keys = t2i->resume_keys;
14679 	}
14680 
14681 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
14682 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14683 
14684 	/*
14685 	 * Figure out of there are enough bytes to display the whole entry.
14686 	 * This consistes of 26 bytes or 30 bytes if resume_keys, followed
14687 	 * by a length byte and that many chars.
14688 	 */
14689 	bytes_needed = 27 + (resume_keys ? 4 : 0);
14690 	tvb_ensure_bytes_exist(tvb, offset, bytes_needed);
14691 
14692 	/* Now, get the length */
14693 	fn_len = tvb_get_guint8(tvb, offset + bytes_needed - 1);
14694 	tvb_ensure_bytes_exist(tvb, offset, bytes_needed + fn_len);
14695 
14696 	if (resume_keys) {
14697 		/* resume key */
14698 		CHECK_BYTE_COUNT_SUBR(4);
14699 		proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14700 		COUNT_BYTES_SUBR(4);
14701 	}
14702 
14703 	/* create time */
14704 	CHECK_BYTE_COUNT_SUBR(4);
14705 	offset = dissect_smb_datetime(tvb, tree, offset,
14706 		hf_smb_create_time,
14707 		hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14708 	*bcp -= 4;
14709 
14710 	/* access time */
14711 	CHECK_BYTE_COUNT_SUBR(4);
14712 	offset = dissect_smb_datetime(tvb, tree, offset,
14713 		hf_smb_access_time,
14714 		hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14715 	*bcp -= 4;
14716 
14717 	/* last write time */
14718 	CHECK_BYTE_COUNT_SUBR(4);
14719 	offset = dissect_smb_datetime(tvb, tree, offset,
14720 		hf_smb_last_write_time,
14721 		hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14722 	*bcp -= 4;
14723 
14724 	/* data size */
14725 	CHECK_BYTE_COUNT_SUBR(4);
14726 	proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14727 	COUNT_BYTES_SUBR(4);
14728 
14729 	/* allocation size */
14730 	CHECK_BYTE_COUNT_SUBR(4);
14731 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14732 	COUNT_BYTES_SUBR(4);
14733 
14734 	/* File Attributes */
14735 	CHECK_BYTE_COUNT_SUBR(2);
14736 	offset = dissect_file_attributes(tvb, tree, offset);
14737 	*bcp -= 2;
14738 
14739 	/* ea length */
14740 	CHECK_BYTE_COUNT_SUBR(4);
14741 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14742 	COUNT_BYTES_SUBR(4);
14743 
14744 	/* file name len */
14745 	CHECK_BYTE_COUNT_SUBR(1);
14746 	fn_len = tvb_get_guint8(tvb, offset);
14747 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14748 	COUNT_BYTES_SUBR(1);
14749 
14750 	/* file name */
14751 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
14752 	CHECK_STRING_SUBR(fn);
14753 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14754 		fn);
14755 	COUNT_BYTES_SUBR(fn_len);
14756 
14757 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14758 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14759 
14760 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14761 
14762 	/*
14763 	 * To quote the footnote for FileName in Section 2.2.8.1.2:
14764 	 *
14765 	 *  Windows NT servers always append a single NULL padding byte
14766 	 *  to the FileName field. The length of this additional byte
14767 	 *  is not included in the value of the FileNameLength field.
14768 	 *
14769 	 * That's "single byte", not "UTF-16 null character".
14770 	 *
14771 	 * XXX - what about other servers?  Do we need to somehow
14772 	 * determine whether the server is a "Windows NT server" or
14773 	 * not?
14774 	 */
14775 	CHECK_BYTE_COUNT_SUBR(1);
14776 	COUNT_BYTES_SUBR(1);
14777 
14778 	proto_item_set_len(item, offset-old_offset);
14779 
14780 	*trunc = FALSE;
14781 	return offset;
14782 }
14783 
14784 /*
14785  * According to MS-CIFS 2.2.8.1.3 this is like the function above with the
14786  * addition of the list of EA name value pairs before the file name.
14787  *
14788  * The EAs are formatted as an SMB_FEA as in 2.2.1.2.2. We will deal with
14789  * this soon.
14790  */
14791 static int
dissect_4_3_4_3(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)14792 dissect_4_3_4_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14793     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14794 {
14795 	int                   fn_len;
14796 	const char           *fn;
14797 	int                   old_offset  = offset;
14798 	int		     ea_size = 0;
14799 	proto_item           *item;
14800 	proto_tree           *tree;
14801 	smb_transact2_info_t *t2i;
14802 	gboolean              resume_keys = FALSE;
14803 
14804 
14805 	DISSECTOR_ASSERT(si);
14806 
14807 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14808 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
14809 		if (t2i != NULL)
14810 			resume_keys = t2i->resume_keys;
14811 	}
14812 
14813 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
14814 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14815 
14816 	if (resume_keys) {
14817 		/* resume key */
14818 		CHECK_BYTE_COUNT_SUBR(4);
14819 		proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14820 		COUNT_BYTES_SUBR(4);
14821 	}
14822 
14823 	/* create time */
14824 	CHECK_BYTE_COUNT_SUBR(4);
14825 	offset = dissect_smb_datetime(tvb, tree, offset,
14826 		hf_smb_create_time,
14827 		hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14828 	*bcp -= 4;
14829 
14830 	/* access time */
14831 	CHECK_BYTE_COUNT_SUBR(4);
14832 	offset = dissect_smb_datetime(tvb, tree, offset,
14833 		hf_smb_access_time,
14834 		hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14835 	*bcp -= 4;
14836 
14837 	/* last write time */
14838 	CHECK_BYTE_COUNT_SUBR(4);
14839 	offset = dissect_smb_datetime(tvb, tree, offset,
14840 		hf_smb_last_write_time,
14841 		hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14842 	*bcp -= 4;
14843 
14844 	/* data size */
14845 	CHECK_BYTE_COUNT_SUBR(4);
14846 	proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14847 	COUNT_BYTES_SUBR(4);
14848 
14849 	/* allocation size */
14850 	CHECK_BYTE_COUNT_SUBR(4);
14851 	proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14852 	COUNT_BYTES_SUBR(4);
14853 
14854 	/* File Attributes */
14855 	CHECK_BYTE_COUNT_SUBR(2);
14856 	offset = dissect_file_attributes(tvb, tree, offset);
14857 	*bcp -= 2;
14858 
14859 	/* ea length */
14860 	CHECK_BYTE_COUNT_SUBR(4);
14861 	ea_size = tvb_get_letohl(tvb, offset);
14862 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14863 	COUNT_BYTES_SUBR(4);
14864 
14865 	/* The EAs ... they are formatted as in MS-CIFS 2.2.1.2.2 */
14866 	proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, ea_size, NULL, "EAs");
14867 	COUNT_BYTES_SUBR(ea_size);
14868 	*bcp -= ea_size;
14869 
14870 	/* file name len */
14871 	CHECK_BYTE_COUNT_SUBR(1);
14872 	fn_len = tvb_get_guint8(tvb, offset);
14873 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14874 	COUNT_BYTES_SUBR(1);
14875 	if (si->unicode)
14876 		fn_len += 2;	/* include terminating '\0' */
14877 	else
14878 		fn_len++;	/* include terminating '\0' */
14879 
14880 	/* file name */
14881 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14882 	CHECK_STRING_SUBR(fn);
14883 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14884 		fn);
14885 	COUNT_BYTES_SUBR(fn_len);
14886 
14887 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14888 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14889 
14890 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14891 	proto_item_set_len(item, offset-old_offset);
14892 
14893 	return offset;
14894 }
14895 
14896 static int
dissect_4_3_4_4(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)14897 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14898     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14899 {
14900 	int         fn_len;
14901 	const char *fn;
14902 	int         old_offset = offset;
14903 	proto_item *item;
14904 	proto_tree *tree;
14905 	guint32     neo;
14906 	int         padcnt;
14907 
14908 	DISSECTOR_ASSERT(si);
14909 
14910 	/*
14911 	 * We check this first before adding the sub-tree so things do not
14912 	 * get ugly.
14913 	 */
14914 
14915 	/* next entry offset */
14916 	CHECK_BYTE_COUNT_SUBR(4);
14917 	neo = tvb_get_letohl(tvb, offset);
14918 
14919 	/* Ensure we have the bytes we need, which is up to neo */
14920 	tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14921 
14922 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
14923 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14924 
14925 	/*
14926 	 * We assume that the presence of a next entry offset implies the
14927 	 * absence of a resume key, as appears to be the case for 4.3.4.6.
14928 	 */
14929 
14930 	CHECK_BYTE_COUNT_SUBR(4);
14931 	proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14932 	COUNT_BYTES_SUBR(4);
14933 
14934 	/* file index */
14935 	CHECK_BYTE_COUNT_SUBR(4);
14936 	proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14937 	COUNT_BYTES_SUBR(4);
14938 
14939 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14940 	if (*trunc) {
14941 		return offset;
14942 	}
14943 
14944 	/* end of file */
14945 	CHECK_BYTE_COUNT_SUBR(8);
14946 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14947 	COUNT_BYTES_SUBR(8);
14948 
14949 	/* allocation size */
14950 	CHECK_BYTE_COUNT_SUBR(8);
14951 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14952 	COUNT_BYTES_SUBR(8);
14953 
14954 	/* Extended File Attributes */
14955 	CHECK_BYTE_COUNT_SUBR(4);
14956 	offset = dissect_file_ext_attr(tvb, tree, offset);
14957 	*bcp -= 4;
14958 
14959 	/* file name len */
14960 	CHECK_BYTE_COUNT_SUBR(4);
14961 	fn_len = tvb_get_letohl(tvb, offset);
14962 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14963 	COUNT_BYTES_SUBR(4);
14964 
14965 	/* file name */
14966 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14967 	CHECK_STRING_SUBR(fn);
14968 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14969 		fn);
14970 	COUNT_BYTES_SUBR(fn_len);
14971 
14972 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14973 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14974 
14975 	/* skip to next structure */
14976 	if (neo) {
14977 		padcnt = (old_offset + neo) - offset;
14978 		if (padcnt < 0) {
14979 			/*
14980 			 * XXX - this is bogus; flag it?
14981 			 */
14982 			padcnt = 0;
14983 		}
14984 		if (padcnt != 0) {
14985 			CHECK_BYTE_COUNT_SUBR(padcnt);
14986 			COUNT_BYTES_SUBR(padcnt);
14987 		}
14988 	}
14989 
14990 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
14991 	proto_item_set_len(item, offset-old_offset);
14992 
14993 	*trunc = FALSE;
14994 	return offset;
14995 }
14996 
14997 static int
dissect_4_3_4_5(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)14998 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14999     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15000 {
15001 	int         fn_len;
15002 	const char *fn;
15003 	int         old_offset = offset;
15004 	proto_item *item;
15005 	proto_tree *tree;
15006 	guint32     neo;
15007 	int         padcnt;
15008 
15009 	DISSECTOR_ASSERT(si);
15010 
15011 	/*
15012 	 * We check this first before adding the sub-tree so things do not
15013 	 * get ugly.
15014 	 */
15015 
15016 	/* next entry offset */
15017 	CHECK_BYTE_COUNT_SUBR(4);
15018 	neo = tvb_get_letohl(tvb, offset);
15019 
15020 	/* Ensure we have the bytes we need, which is up to neo */
15021 	tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15022 
15023 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
15024 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15025 
15026 	/*
15027 	 * We assume that the presence of a next entry offset implies the
15028 	 * absence of a resume key, as appears to be the case for 4.3.4.6.
15029 	 */
15030 
15031 	CHECK_BYTE_COUNT_SUBR(4);
15032 	proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15033 	COUNT_BYTES_SUBR(4);
15034 
15035 	/* file index */
15036 	CHECK_BYTE_COUNT_SUBR(4);
15037 	proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15038 	COUNT_BYTES_SUBR(4);
15039 
15040 	/* standard 8-byte timestamps */
15041 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
15042 	if (*trunc) {
15043 		return offset;
15044 	}
15045 
15046 	/* end of file */
15047 	CHECK_BYTE_COUNT_SUBR(8);
15048 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15049 	COUNT_BYTES_SUBR(8);
15050 
15051 	/* allocation size */
15052 	CHECK_BYTE_COUNT_SUBR(8);
15053 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15054 	COUNT_BYTES_SUBR(8);
15055 
15056 	/* Extended File Attributes */
15057 	CHECK_BYTE_COUNT_SUBR(4);
15058 	offset = dissect_file_ext_attr(tvb, tree, offset);
15059 	*bcp -= 4;
15060 
15061 	/* file name len */
15062 	CHECK_BYTE_COUNT_SUBR(4);
15063 	fn_len = tvb_get_letohl(tvb, offset);
15064 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15065 	COUNT_BYTES_SUBR(4);
15066 
15067 	/* ea length */
15068 	CHECK_BYTE_COUNT_SUBR(4);
15069 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15070 	COUNT_BYTES_SUBR(4);
15071 
15072 	/* file name */
15073 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15074 	CHECK_STRING_SUBR(fn);
15075 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15076 		fn);
15077 	COUNT_BYTES_SUBR(fn_len);
15078 
15079 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15080 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15081 
15082 	/* skip to next structure */
15083 	if (neo) {
15084 		padcnt = (old_offset + neo) - offset;
15085 		if (padcnt < 0) {
15086 			/*
15087 			 * XXX - this is bogus; flag it?
15088 			 */
15089 			padcnt = 0;
15090 		}
15091 		if (padcnt != 0) {
15092 			CHECK_BYTE_COUNT_SUBR(padcnt);
15093 			COUNT_BYTES_SUBR(padcnt);
15094 		}
15095 	}
15096 
15097 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15098 	proto_item_set_len(item, offset-old_offset);
15099 
15100 	*trunc = FALSE;
15101 	return offset;
15102 }
15103 
15104 static int
dissect_4_3_4_6(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15105 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
15106     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15107 {
15108 	int         fn_len, sfn_len;
15109 	const char *fn, *sfn;
15110 	int         old_offset = offset;
15111 	proto_item *item;
15112 	proto_tree *tree;
15113 	guint32     neo;
15114 	int         padcnt;
15115 
15116 	DISSECTOR_ASSERT(si);
15117 
15118 	/*
15119 	 * We check this first before adding the sub-tree so things do not
15120 	 * get ugly.
15121 	 */
15122 
15123 	/* next entry offset */
15124 	CHECK_BYTE_COUNT_SUBR(4);
15125 	neo = tvb_get_letohl(tvb, offset);
15126 
15127 	/* Ensure we have the bytes we need, which is up to neo */
15128 	tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15129 
15130 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
15131 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15132 
15133 	/*
15134 	 * XXX - I have not seen any of these that contain a resume
15135 	 * key, even though some of the requests had the "return resume
15136 	 * key" flag set.
15137 	 */
15138 
15139 	CHECK_BYTE_COUNT_SUBR(4);
15140 	proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15141 	COUNT_BYTES_SUBR(4);
15142 
15143 	/* file index */
15144 	CHECK_BYTE_COUNT_SUBR(4);
15145 	proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15146 	COUNT_BYTES_SUBR(4);
15147 
15148 	/* dissect standard 8-byte timestamps */
15149 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
15150 	if (*trunc) {
15151 	  return offset;
15152 	}
15153 
15154 	/* end of file */
15155 	CHECK_BYTE_COUNT_SUBR(8);
15156 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15157 	COUNT_BYTES_SUBR(8);
15158 
15159 	/* allocation size */
15160 	CHECK_BYTE_COUNT_SUBR(8);
15161 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15162 	COUNT_BYTES_SUBR(8);
15163 
15164 	/* Extended File Attributes */
15165 	CHECK_BYTE_COUNT_SUBR(4);
15166 	offset = dissect_file_ext_attr(tvb, tree, offset);
15167 	*bcp -= 4;
15168 
15169 	/* file name len */
15170 	CHECK_BYTE_COUNT_SUBR(4);
15171 	fn_len = tvb_get_letohl(tvb, offset);
15172 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15173 	COUNT_BYTES_SUBR(4);
15174 
15175 	/*
15176 	 * EA length.
15177 	 *
15178 	 * XXX - in one captures, this has the topmost bit set, and the
15179 	 * rest of the bits have the value 7.  Is the topmost bit being
15180 	 * set some indication that the value *isn't* the length of
15181 	 * the EAs?
15182 	 */
15183 	CHECK_BYTE_COUNT_SUBR(4);
15184 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15185 	COUNT_BYTES_SUBR(4);
15186 
15187 	/* short file name len */
15188 	CHECK_BYTE_COUNT_SUBR(1);
15189 	sfn_len = tvb_get_guint8(tvb, offset);
15190 	proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
15191 	COUNT_BYTES_SUBR(1);
15192 
15193 	/* reserved byte */
15194 	CHECK_BYTE_COUNT_SUBR(1);
15195 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
15196 	COUNT_BYTES_SUBR(1);
15197 
15198 	/* short file name - it's not always in Unicode */
15199 	sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
15200 	CHECK_STRING_SUBR(sfn);
15201 	proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
15202 		sfn);
15203 	COUNT_BYTES_SUBR(24);
15204 
15205 	/* file name */
15206 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15207 	CHECK_STRING_SUBR(fn);
15208 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15209 		fn);
15210 	COUNT_BYTES_SUBR(fn_len);
15211 
15212 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15213 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15214 
15215 	/* skip to next structure */
15216 	if (neo) {
15217 		padcnt = (old_offset + neo) - offset;
15218 		if (padcnt < 0) {
15219 			/*
15220 			 * XXX - this is bogus; flag it?
15221 			 */
15222 			padcnt = 0;
15223 		}
15224 		if (padcnt != 0) {
15225 			CHECK_BYTE_COUNT_SUBR(padcnt);
15226 			COUNT_BYTES_SUBR(padcnt);
15227 		}
15228 	}
15229 
15230 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15231 	proto_item_set_len(item, offset-old_offset);
15232 
15233 	*trunc = FALSE;
15234 	return offset;
15235 }
15236 
15237 static int
dissect_4_3_4_6full(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15238 dissect_4_3_4_6full(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
15239     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15240 {
15241 	int         fn_len;
15242 	const char *fn;
15243 	int         old_offset = offset;
15244 	proto_item *item;
15245 	proto_tree *tree;
15246 	guint32     neo;
15247 	int         padcnt;
15248 
15249 	DISSECTOR_ASSERT(si);
15250 
15251 	/*
15252 	 * We check this first before adding the sub-tree so things do not
15253 	 * get ugly.
15254 	 */
15255 
15256 	/* next entry offset */
15257 	CHECK_BYTE_COUNT_SUBR(4);
15258 	neo = tvb_get_letohl(tvb, offset);
15259 
15260 	/* Ensure we have the bytes we need, which is up to neo */
15261 	tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15262 
15263 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
15264 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15265 
15266 	/*
15267 	 * XXX - I have not seen any of these that contain a resume
15268 	 * key, even though some of the requests had the "return resume
15269 	 * key" flag set.
15270 	 */
15271 
15272 	CHECK_BYTE_COUNT_SUBR(4);
15273 	proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15274 	COUNT_BYTES_SUBR(4);
15275 
15276 	/* file index */
15277 	CHECK_BYTE_COUNT_SUBR(4);
15278 	proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15279 	COUNT_BYTES_SUBR(4);
15280 
15281 	/* dissect standard 8-byte timestamps */
15282 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
15283 	if (*trunc) {
15284 	  return offset;
15285 	}
15286 
15287 	/* end of file */
15288 	CHECK_BYTE_COUNT_SUBR(8);
15289 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15290 	COUNT_BYTES_SUBR(8);
15291 
15292 	/* allocation size */
15293 	CHECK_BYTE_COUNT_SUBR(8);
15294 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15295 	COUNT_BYTES_SUBR(8);
15296 
15297 	/* Extended File Attributes */
15298 	CHECK_BYTE_COUNT_SUBR(4);
15299 	offset = dissect_file_ext_attr(tvb, tree, offset);
15300 	*bcp -= 4;
15301 
15302 	/* file name len */
15303 	CHECK_BYTE_COUNT_SUBR(4);
15304 	fn_len = tvb_get_letohl(tvb, offset);
15305 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15306 	COUNT_BYTES_SUBR(4);
15307 
15308 	/*
15309 	 * EA length.
15310 	 *
15311 	 * XXX - in one captures, this has the topmost bit set, and the
15312 	 * rest of the bits have the value 7.  Is the topmost bit being
15313 	 * set some indication that the value *isn't* the length of
15314 	 * the EAs?
15315 	 */
15316 	CHECK_BYTE_COUNT_SUBR(4);
15317 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15318 	COUNT_BYTES_SUBR(4);
15319 
15320 	/* skip 4 bytes */
15321 	COUNT_BYTES_SUBR(4);
15322 
15323 	CHECK_BYTE_COUNT_SUBR(8);
15324 	proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15325 	COUNT_BYTES_SUBR(8);
15326 
15327 	/* file name */
15328 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15329 	CHECK_STRING_SUBR(fn);
15330 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15331 		fn);
15332 	COUNT_BYTES_SUBR(fn_len);
15333 
15334 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15335 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15336 
15337 	/* skip to next structure */
15338 	if (neo) {
15339 		padcnt = (old_offset + neo) - offset;
15340 		if (padcnt < 0) {
15341 			/*
15342 			 * XXX - this is bogus; flag it?
15343 			 */
15344 			padcnt = 0;
15345 		}
15346 		if (padcnt != 0) {
15347 			CHECK_BYTE_COUNT_SUBR(padcnt);
15348 			COUNT_BYTES_SUBR(padcnt);
15349 		}
15350 	}
15351 
15352 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15353 	proto_item_set_len(item, offset-old_offset);
15354 
15355 	*trunc = FALSE;
15356 	return offset;
15357 }
15358 
15359 static int
dissect_4_3_4_6_id_both(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15360 dissect_4_3_4_6_id_both(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
15361     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15362 {
15363 	int         fn_len, sfn_len;
15364 	const char *fn, *sfn;
15365 	int         old_offset = offset;
15366 	proto_item *item;
15367 	proto_tree *tree;
15368 	guint32     neo;
15369 	int         padcnt;
15370 
15371 	DISSECTOR_ASSERT(si);
15372 
15373 	/*
15374 	 * We check this first before adding the sub-tree so things do not
15375 	 * get ugly.
15376 	 */
15377 
15378 	/* next entry offset */
15379 	CHECK_BYTE_COUNT_SUBR(4);
15380 	neo = tvb_get_letohl(tvb, offset);
15381 
15382 	/* Ensure we have the bytes we need, which is up to neo */
15383 	tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15384 
15385 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
15386 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15387 
15388 	/*
15389 	 * XXX - I have not seen any of these that contain a resume
15390 	 * key, even though some of the requests had the "return resume
15391 	 * key" flag set.
15392 	 */
15393 
15394 	CHECK_BYTE_COUNT_SUBR(4);
15395 	proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15396 	COUNT_BYTES_SUBR(4);
15397 
15398 	/* file index */
15399 	CHECK_BYTE_COUNT_SUBR(4);
15400 	proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15401 	COUNT_BYTES_SUBR(4);
15402 
15403 	/* dissect standard 8-byte timestamps */
15404 	offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
15405 	if (*trunc) {
15406 	  return offset;
15407 	}
15408 
15409 	/* end of file */
15410 	CHECK_BYTE_COUNT_SUBR(8);
15411 	proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15412 	COUNT_BYTES_SUBR(8);
15413 
15414 	/* allocation size */
15415 	CHECK_BYTE_COUNT_SUBR(8);
15416 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15417 	COUNT_BYTES_SUBR(8);
15418 
15419 	/* Extended File Attributes */
15420 	CHECK_BYTE_COUNT_SUBR(4);
15421 	offset = dissect_file_ext_attr(tvb, tree, offset);
15422 	*bcp -= 4;
15423 
15424 	/* file name len */
15425 	CHECK_BYTE_COUNT_SUBR(4);
15426 	fn_len = tvb_get_letohl(tvb, offset);
15427 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15428 	COUNT_BYTES_SUBR(4);
15429 
15430 	/*
15431 	 * EA length.
15432 	 *
15433 	 * XXX - in one captures, this has the topmost bit set, and the
15434 	 * rest of the bits have the value 7.  Is the topmost bit being
15435 	 * set some indication that the value *isn't* the length of
15436 	 * the EAs?
15437 	 */
15438 	CHECK_BYTE_COUNT_SUBR(4);
15439 	proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15440 	COUNT_BYTES_SUBR(4);
15441 
15442 	/* short file name len */
15443 	CHECK_BYTE_COUNT_SUBR(1);
15444 	sfn_len = tvb_get_guint8(tvb, offset);
15445 	proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
15446 	COUNT_BYTES_SUBR(1);
15447 
15448 	/* reserved byte */
15449 	CHECK_BYTE_COUNT_SUBR(1);
15450 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
15451 	COUNT_BYTES_SUBR(1);
15452 
15453 	/* short file name - it's not always in Unicode */
15454 	sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
15455 	CHECK_STRING_SUBR(sfn);
15456 	proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
15457 		sfn);
15458 	COUNT_BYTES_SUBR(24);
15459 
15460 	/* reserved bytes */
15461 	CHECK_BYTE_COUNT_SUBR(2);
15462 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
15463 	COUNT_BYTES_SUBR(2);
15464 
15465 	/* file id */
15466 	CHECK_BYTE_COUNT_SUBR(8);
15467 	proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15468 	COUNT_BYTES_SUBR(8);
15469 
15470 	/* file name */
15471 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15472 	CHECK_STRING_SUBR(fn);
15473 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15474 		fn);
15475 	COUNT_BYTES_SUBR(fn_len);
15476 
15477 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15478 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15479 
15480 	/* skip to next structure */
15481 	if (neo) {
15482 		padcnt = (old_offset + neo) - offset;
15483 		if (padcnt < 0) {
15484 			/*
15485 			 * XXX - this is bogus; flag it?
15486 			 */
15487 			padcnt = 0;
15488 		}
15489 		if (padcnt != 0) {
15490 			CHECK_BYTE_COUNT_SUBR(padcnt);
15491 			COUNT_BYTES_SUBR(padcnt);
15492 		}
15493 	}
15494 
15495 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15496 	proto_item_set_len(item, offset-old_offset);
15497 
15498 	*trunc = FALSE;
15499 	return offset;
15500 }
15501 
15502 static int
dissect_4_3_4_7(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15503 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
15504     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15505 {
15506 	int         fn_len;
15507 	const char *fn;
15508 	int         old_offset = offset;
15509 	proto_item *item;
15510 	proto_tree *tree;
15511 	guint32     neo;
15512 	int         padcnt;
15513 
15514 	DISSECTOR_ASSERT(si);
15515 
15516 	/*
15517 	 * We check this first before adding the sub-tree so things do not
15518 	 * get ugly.
15519 	 */
15520 
15521 	/* next entry offset */
15522 	CHECK_BYTE_COUNT_SUBR(4);
15523 	neo = tvb_get_letohl(tvb, offset);
15524 
15525 	/* Ensure we have the bytes we need, which is up to neo */
15526 	tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15527 
15528 	tree = proto_tree_add_subtree(parent_tree, tvb, offset, *bcp, ett_smb_ff2_data, &item,
15529 		    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15530 
15531 	/*
15532 	 * We assume that the presence of a next entry offset implies the
15533 	 * absence of a resume key, as appears to be the case for 4.3.4.6.
15534 	 */
15535 
15536 	CHECK_BYTE_COUNT_SUBR(4);
15537 	proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15538 	COUNT_BYTES_SUBR(4);
15539 
15540 	/* file index */
15541 	CHECK_BYTE_COUNT_SUBR(4);
15542 	proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15543 	COUNT_BYTES_SUBR(4);
15544 
15545 	/* file name len */
15546 	CHECK_BYTE_COUNT_SUBR(4);
15547 	fn_len = tvb_get_letohl(tvb, offset);
15548 	proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15549 	COUNT_BYTES_SUBR(4);
15550 
15551 	/* file name */
15552 	fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15553 	CHECK_STRING_SUBR(fn);
15554 	proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15555 		fn);
15556 	COUNT_BYTES_SUBR(fn_len);
15557 
15558 	col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15559 		    format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15560 
15561 	/* skip to next structure */
15562 	if (neo) {
15563 		padcnt = (old_offset + neo) - offset;
15564 		if (padcnt < 0) {
15565 			/*
15566 			 * XXX - this is bogus; flag it?
15567 			 */
15568 			padcnt = 0;
15569 		}
15570 		if (padcnt != 0) {
15571 			CHECK_BYTE_COUNT_SUBR(padcnt);
15572 			COUNT_BYTES_SUBR(padcnt);
15573 		}
15574 	}
15575 
15576 	proto_item_append_text(item, " File: %s", format_text(wmem_packet_scope(), (const guchar*)fn, strlen(fn)));
15577 	proto_item_set_len(item, offset-old_offset);
15578 
15579 	*trunc = FALSE;
15580 	return offset;
15581 }
15582 
15583 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
15584 
15585 static int
dissect_4_3_4_8(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15586 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo,
15587 		proto_tree *tree, int offset, guint16 *bcp,
15588 		gboolean *trunc, smb_info_t *si)
15589 {
15590 	const char *fn;
15591 	int         fn_len;
15592 	int         pad;
15593 
15594 	DISSECTOR_ASSERT(si);
15595 
15596 	/* NextEntryOffset */
15597 	CHECK_BYTE_COUNT_SUBR(4);
15598 	proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15599 	COUNT_BYTES_SUBR(4);
15600 
15601 	/* ResumeKey */
15602 	CHECK_BYTE_COUNT_SUBR(4);
15603 	proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15604 	COUNT_BYTES_SUBR(4);
15605 
15606 	/* Unix basic info */
15607 	offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, trunc);
15608 	if (*trunc)
15609 		return offset;
15610 
15611 	/* Name */
15612 
15613 	fn = get_unicode_or_ascii_string(
15614 		tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
15615 
15616 	CHECK_STRING_SUBR(fn);
15617 	proto_tree_add_string(
15618 		tree, hf_smb_unix_file_name, tvb, offset, fn_len, fn);
15619 	COUNT_BYTES_SUBR(fn_len);
15620 
15621 	/* Pad to 4 bytes */
15622 
15623 	if (offset % 4) {
15624 		pad = 4 - (offset % 4);
15625 		COUNT_BYTES_SUBR(pad);
15626 	}
15627 
15628 	*trunc = FALSE;
15629 	return offset;
15630 }
15631 
15632 static int
dissect_find_file_unix_info2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15633 dissect_find_file_unix_info2(tvbuff_t *tvb, packet_info *pinfo,
15634 			     proto_tree *tree, int offset, guint16 *bcp,
15635 			     gboolean *trunc, smb_info_t *si)
15636 {
15637 	const char *fn;
15638 	guint32     namelen;
15639 	int         fn_len;
15640 	int         pad;
15641 
15642 	DISSECTOR_ASSERT(si);
15643 
15644 	/* NextEntryOffset */
15645 	CHECK_BYTE_COUNT_SUBR(4);
15646 	proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15647 	COUNT_BYTES_SUBR(4);
15648 
15649 	/* ResumeKey */
15650 	CHECK_BYTE_COUNT_SUBR(4);
15651 	proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15652 	COUNT_BYTES_SUBR(4);
15653 
15654 	/* Unix Info2 */
15655 	offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp, trunc);
15656 	if (*trunc)
15657 		return offset;
15658 
15659 	/* Name length */
15660 	CHECK_BYTE_COUNT_SUBR(4);
15661 	namelen = tvb_get_letohl(tvb, offset);
15662 	proto_tree_add_uint(tree, hf_smb_unix_file_name_length, tvb, offset, 4, namelen);
15663 	COUNT_BYTES_SUBR(4);
15664 
15665 	/* Name */
15666 
15667 	/*
15668 	 * namelen could be > 2^31-1; this will catch that.
15669 	 * The length argument to get_unicode_or_ascii_string() is an
15670 	 * int, not an unsigned int, so we have to worry about that.
15671 	 */
15672 	tvb_ensure_bytes_exist(tvb, offset, namelen);
15673 	fn_len = namelen;
15674 	fn = get_unicode_or_ascii_string(
15675 		tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
15676 
15677 	CHECK_STRING_SUBR(fn);
15678 	proto_tree_add_string(
15679 		tree, hf_smb_unix_file_name, tvb, offset, fn_len, fn);
15680 	COUNT_BYTES_SUBR(fn_len);
15681 
15682 	/* Pad to 4 bytes */
15683 
15684 	if (offset % 4) {
15685 		pad = 4 - (offset % 4);
15686 		CHECK_BYTE_COUNT_SUBR(pad);
15687 		COUNT_BYTES_SUBR(pad);
15688 	}
15689 
15690 	*trunc = FALSE;
15691 	return offset;
15692 }
15693 
15694 /*dissect the data block for TRANS2_FIND_FIRST2*/
15695 static int
dissect_ff2_response_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,gboolean * trunc,smb_info_t * si)15696 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
15697     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15698 {
15699 	if (!*bcp) {
15700 		*trunc = FALSE;
15701 		return offset;
15702 	}
15703 
15704 	DISSECTOR_ASSERT(si);
15705 
15706 	switch(si->info_level) {
15707 	case 1:		/*Info Standard*/
15708 		offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
15709 		    trunc, si);
15710 		break;
15711 	case 2:		/*Info Query EA Size*/
15712 		offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
15713 		    trunc, si);
15714 		break;
15715 	case 3:		/* Info Query EAs From List same as
15716 			 * InfoQueryEASize.
15717 			 * Not according to MS-CIFS 2.2.8.1.3. RJS
15718 			 */
15719 		offset = dissect_4_3_4_3(tvb, pinfo, tree, offset, bcp,
15720 		    trunc, si);
15721 		break;
15722 	case 0x0101:	/*Find File Directory Info*/
15723 		offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
15724 		    trunc, si);
15725 		break;
15726 	case 0x0102:	/*Find File Full Directory Info*/
15727 		offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
15728 		    trunc, si);
15729 		break;
15730 	case 0x0103:	/*Find File Names Info*/
15731 		offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
15732 		    trunc, si);
15733 		break;
15734 	case 0x0104:	/*Find File Both Directory Info*/
15735 		offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
15736 		    trunc, si);
15737 		break;
15738 	case 0x0105:	/*Find File Full Directory Info*/
15739 		offset = dissect_4_3_4_6full(tvb, pinfo, tree, offset, bcp,
15740 		    trunc, si);
15741 		break;
15742 	case 0x0106:	/*Find File Id Both Directory Info*/
15743 		offset = dissect_4_3_4_6_id_both(tvb, pinfo, tree, offset, bcp,
15744 		    trunc, si);
15745 		break;
15746 	case 0x0202:	/*Find File Unix*/
15747 		offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
15748 		    trunc, si);
15749 		break;
15750 	case 0x020B:	/*Find File Unix Info2*/
15751 		offset = dissect_find_file_unix_info2(tvb, pinfo, tree, offset, bcp,
15752 		    trunc, si);
15753 		break;
15754 	default:	/* unknown info level */
15755 		*trunc = FALSE;
15756 		break;
15757 	}
15758 	return offset;
15759 }
15760 
15761 
15762 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
15763 static int
dissect_fs_attributes(tvbuff_t * tvb,proto_tree * parent_tree,int offset)15764 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15765 {
15766 	static int * const flags[] = {
15767 		/* case sensitive search */
15768 		&hf_smb_fs_attr_css,
15769 		/* case preserved names */
15770 		&hf_smb_fs_attr_cpn,
15771 		/* unicode on disk */
15772 		&hf_smb_fs_attr_uod,
15773 		/* persistent acls */
15774 		&hf_smb_fs_attr_pacls,
15775 		/* file compression */
15776 		&hf_smb_fs_attr_fc,
15777 		/* volume quotas */
15778 		&hf_smb_fs_attr_vq,
15779 		/* sparse files */
15780 		&hf_smb_fs_attr_ssf,
15781 		/* reparse points */
15782 		&hf_smb_fs_attr_srp,
15783 		/* remote storage */
15784 		&hf_smb_fs_attr_srs,
15785 		/* lfn apis */
15786 		&hf_smb_fs_attr_sla,
15787 		/* volume is compressed */
15788 		&hf_smb_fs_attr_vic,
15789 		/* support oids */
15790 		&hf_smb_fs_attr_soids,
15791 		/* encryption */
15792 		&hf_smb_fs_attr_se,
15793 		/* named streams */
15794 		&hf_smb_fs_attr_ns,
15795 		/* read only volume */
15796 		&hf_smb_fs_attr_rov,
15797 		/* sequential write once */
15798 		&hf_smb_fs_attr_swo,
15799 		/* supports transactions */
15800 		&hf_smb_fs_attr_st,
15801 		/* supports hard links */
15802 		&hf_smb_fs_attr_shl,
15803 		/* supports integrity streams */
15804 		&hf_smb_fs_attr_sis,
15805 		/* supports block refcounting */
15806 		&hf_smb_fs_attr_sbr,
15807 		/* supports sparse vdl */
15808 		&hf_smb_fs_attr_ssv,
15809 		NULL
15810 	};
15811 
15812 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_fs_attr, ett_smb_fs_attributes, flags, ENC_LITTLE_ENDIAN);
15813 	offset += 4;
15814 
15815 	return offset;
15816 }
15817 
15818 
15819 static int
dissect_device_characteristics(tvbuff_t * tvb,proto_tree * parent_tree,int offset)15820 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15821 {
15822 	static int * const mask[] = {
15823 		&hf_smb_device_char_removable,
15824 		&hf_smb_device_char_read_only,
15825 		&hf_smb_device_char_floppy,
15826 		&hf_smb_device_char_write_once,
15827 		&hf_smb_device_char_remote,
15828 		&hf_smb_device_char_mounted,
15829 		&hf_smb_device_char_virtual,
15830 		&hf_smb_device_char_secure_open,
15831 		&hf_smb_device_char_ts,
15832 		&hf_smb_device_char_webdav,
15833 		&hf_smb_device_char_portable,
15834 		&hf_smb_device_char_aat,
15835 		NULL
15836 	};
15837 
15838 	proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_smb_device_char,
15839 			ett_smb_device_characteristics, mask, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
15840 
15841 	offset += 4;
15842 	return offset;
15843 }
15844 
15845 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
15846 
15847 static const true_false_string tfs_smb_mac_access_ctrl = {
15848 	"Macintosh Access Control Supported",
15849 	"Macintosh Access Control Not Supported"
15850 };
15851 
15852 static const true_false_string tfs_smb_mac_getset_comments = {
15853 	"Macintosh Get & Set Comments Supported",
15854 	"Macintosh Get & Set Comments Not Supported"
15855 };
15856 
15857 static const true_false_string tfs_smb_mac_desktopdb_calls = {
15858 	"Macintosh Get & Set Desktop Database Info Supported",
15859 	"Macintosh Get & Set Desktop Database Info Not Supported"
15860 };
15861 
15862 static const true_false_string tfs_smb_mac_unique_ids = {
15863 	"Macintosh Unique IDs Supported",
15864 	"Macintosh Unique IDs Not Supported"
15865 };
15866 
15867 static const true_false_string tfs_smb_mac_streams = {
15868 	"Macintosh and Streams Extensions Not Supported",
15869 	"Macintosh and Streams Extensions Supported"
15870 };
15871 
15872 int
dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp,int unicode)15873 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
15874 {
15875 	int         fn_len, vll;
15876 	const char *fn;
15877 
15878 	/* create time */
15879 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
15880 	offset = dissect_nt_64bit_time(tvb, tree, offset,
15881 		hf_smb_create_time);
15882 	*bcp -= 8;
15883 
15884 	/* volume serial number */
15885 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15886 	proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15887 	COUNT_BYTES_TRANS_SUBR(4);
15888 
15889 	/* volume label length */
15890 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15891 	vll = tvb_get_letohl(tvb, offset);
15892 	proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
15893 	COUNT_BYTES_TRANS_SUBR(4);
15894 
15895 	/* 2 reserved bytes */
15896 	CHECK_BYTE_COUNT_TRANS_SUBR(2);
15897 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
15898 	COUNT_BYTES_TRANS_SUBR(2);
15899 
15900 	/* label */
15901 	fn_len = vll;
15902 	fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
15903 	CHECK_STRING_TRANS_SUBR(fn);
15904 	proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15905 		fn);
15906 	COUNT_BYTES_TRANS_SUBR(fn_len);
15907 
15908 	return offset;
15909 }
15910 
15911 int
dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp)15912 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15913 {
15914 	/* allocation size */
15915 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
15916 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15917 	COUNT_BYTES_TRANS_SUBR(8);
15918 
15919 	/* free allocation units */
15920 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
15921 	proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15922 	COUNT_BYTES_TRANS_SUBR(8);
15923 
15924 	/* sectors per unit */
15925 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15926 	proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15927 	COUNT_BYTES_TRANS_SUBR(4);
15928 
15929 	/* bytes per sector */
15930 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15931 	proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15932 	COUNT_BYTES_TRANS_SUBR(4);
15933 
15934 	return offset;
15935 }
15936 
15937 int
dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp)15938 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15939 {
15940 	/* device type */
15941 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15942 	proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15943 	COUNT_BYTES_TRANS_SUBR(4);
15944 
15945 	/* device characteristics */
15946 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15947 	offset = dissect_device_characteristics(tvb, tree, offset);
15948 	*bcp -= 4;
15949 
15950 	return offset;
15951 }
15952 
15953 int
dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp)15954 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15955 {
15956 	int         fn_len, fnl;
15957 	const char *fn;
15958 
15959 	/* FS attributes */
15960 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15961 	offset = dissect_fs_attributes(tvb, tree, offset);
15962 	*bcp -= 4;
15963 
15964 	/* max name len */
15965 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15966 	proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15967 	COUNT_BYTES_TRANS_SUBR(4);
15968 
15969 	/* fs name length */
15970 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
15971 	fnl = tvb_get_letohl(tvb, offset);
15972 	proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
15973 	COUNT_BYTES_TRANS_SUBR(4);
15974 
15975 	/* label */
15976 	fn_len = fnl;
15977 	fn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &fn_len, FALSE, TRUE, bcp);
15978 	CHECK_STRING_TRANS_SUBR(fn);
15979 	proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
15980 		fn);
15981 	COUNT_BYTES_TRANS_SUBR(fn_len);
15982 
15983 	return offset;
15984 }
15985 
15986 int
dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp)15987 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
15988 {
15989 	CHECK_BYTE_COUNT_TRANS_SUBR(64);
15990 
15991 	dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
15992 
15993 	COUNT_BYTES_TRANS_SUBR(64);
15994 
15995 	return offset;
15996 }
15997 
15998 int
dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,guint16 * bcp)15999 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
16000 {
16001 	/* allocation size */
16002 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
16003 	proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
16004 	COUNT_BYTES_TRANS_SUBR(8);
16005 
16006 	/* caller free allocation units */
16007 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
16008 	proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
16009 	COUNT_BYTES_TRANS_SUBR(8);
16010 
16011 	/* actual free allocation units */
16012 	CHECK_BYTE_COUNT_TRANS_SUBR(8);
16013 	proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
16014 	COUNT_BYTES_TRANS_SUBR(8);
16015 
16016 	/* sectors per unit */
16017 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
16018 	proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16019 	COUNT_BYTES_TRANS_SUBR(4);
16020 
16021 	/* bytes per sector */
16022 	CHECK_BYTE_COUNT_TRANS_SUBR(4);
16023 	proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16024 	COUNT_BYTES_TRANS_SUBR(4);
16025 
16026 	return offset;
16027 }
16028 
16029 static int
dissect_qfsi_vals(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,guint16 * bcp,smb_info_t * si)16030 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
16031     int offset, guint16 *bcp, smb_info_t *si)
16032 {
16033 	int         fn_len, vll;
16034 	const char *fn;
16035 
16036 	if (!*bcp) {
16037 		return offset;
16038 	}
16039 
16040 	DISSECTOR_ASSERT(si);
16041 
16042 	switch(si->info_level) {
16043 	case 1:		/* SMB_INFO_ALLOCATION */
16044 		/* filesystem id */
16045 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16046 		proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16047 		COUNT_BYTES_TRANS_SUBR(4);
16048 
16049 		/* sectors per unit */
16050 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16051 		proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16052 		COUNT_BYTES_TRANS_SUBR(4);
16053 
16054 		/* units */
16055 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16056 		proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16057 		COUNT_BYTES_TRANS_SUBR(4);
16058 
16059 		/* avail units */
16060 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16061 		proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16062 		COUNT_BYTES_TRANS_SUBR(4);
16063 
16064 		/* bytes per sector, only 16bit integer here */
16065 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
16066 		proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16067 		COUNT_BYTES_TRANS_SUBR(2);
16068 
16069 		break;
16070 	case 2:		/* SMB_INFO_VOLUME */
16071 		/* volume serial number */
16072 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16073 		proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16074 		COUNT_BYTES_TRANS_SUBR(4);
16075 
16076 		/* volume label length, only one byte here */
16077 		CHECK_BYTE_COUNT_TRANS_SUBR(1);
16078 		proto_tree_add_item(tree, hf_smb_volume_label_len, tvb, offset, 1, ENC_NA);
16079 		COUNT_BYTES_TRANS_SUBR(1);
16080 
16081 		/* label - not aligned! */
16082 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, bcp);
16083 		CHECK_STRING_TRANS_SUBR(fn);
16084 		proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
16085 			fn);
16086 		COUNT_BYTES_TRANS_SUBR(fn_len);
16087 
16088 		break;
16089 	case 0x0101:	/* SMB_QUERY_FS_LABEL_INFO */
16090 	case 1002:	/* SMB_FS_LABEL_INFORMATION */
16091 		/* volume label length */
16092 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16093 		vll = tvb_get_letohl(tvb, offset);
16094 		proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
16095 		COUNT_BYTES_TRANS_SUBR(4);
16096 
16097 		/* label */
16098 		fn_len = vll;
16099 		fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
16100 		CHECK_STRING_TRANS_SUBR(fn);
16101 		proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
16102 			fn);
16103 		COUNT_BYTES_TRANS_SUBR(fn_len);
16104 
16105 		break;
16106 	case 0x0102:	/* SMB_QUERY_FS_VOLUME_INFO */
16107 	case 1001:	/* SMB_FS_VOLUME_INFORMATION */
16108 		offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
16109 		break;
16110 	case 0x0103:	/* SMB_QUERY_FS_SIZE_INFO */
16111 	case 1003:	/* SMB_FS_SIZE_INFORMATION */
16112 		offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
16113 		break;
16114 	case 0x0104:	/* SMB_QUERY_FS_DEVICE_INFO */
16115 	case 1004:	/* SMB_FS_DEVICE_INFORMATION */
16116 		offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
16117 		break;
16118 	case 0x0105:	/* SMB_QUERY_FS_ATTRIBUTE_INFO */
16119 	case 1005:	/* SMB_FS_ATTRIBUTE_INFORMATION */
16120 		offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp);
16121 		break;
16122 	case 0x200: {	/* SMB_QUERY_CIFS_UNIX_INFO */
16123 		proto_item *item_2 = NULL;
16124 		proto_tree *subtree = NULL;
16125 
16126 		/* MajorVersionNumber */
16127 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
16128 		proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16129 		COUNT_BYTES_TRANS_SUBR(2);
16130 
16131 		/* MinorVersionNumber */
16132 		CHECK_BYTE_COUNT_TRANS_SUBR(2);
16133 		proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16134 		COUNT_BYTES_TRANS_SUBR(2);
16135 
16136 		/* Capability */
16137 
16138 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
16139 
16140 		if (tree) {
16141 			item_2 = proto_tree_add_item(tree, hf_smb_unix_capability, tvb, offset, 8, ENC_LITTLE_ENDIAN);
16142 			subtree = proto_item_add_subtree(
16143 				item_2, ett_smb_unix_capabilities);
16144 		}
16145 
16146 		proto_tree_add_item(
16147 			subtree, hf_smb_unix_capability_fcntl, tvb, offset, 4,
16148 			ENC_LITTLE_ENDIAN);
16149 
16150 		proto_tree_add_item(
16151 			subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 4,
16152 			ENC_LITTLE_ENDIAN);
16153 
16154 		proto_tree_add_item(
16155 			subtree, hf_smb_unix_capability_xattr, tvb, offset, 4,
16156 			ENC_LITTLE_ENDIAN);
16157 
16158 		proto_tree_add_item(
16159 			subtree, hf_smb_unix_capability_attr, tvb, offset, 4,
16160 			ENC_LITTLE_ENDIAN);
16161 
16162 		proto_tree_add_item(
16163 			subtree, hf_smb_unix_capability_posix_paths, tvb, offset, 4,
16164 			ENC_LITTLE_ENDIAN);
16165 
16166 		proto_tree_add_item(
16167 			subtree, hf_smb_unix_capability_posix_path_ops, tvb, offset, 4,
16168 			ENC_LITTLE_ENDIAN);
16169 
16170 		proto_tree_add_item(
16171 			subtree, hf_smb_unix_capability_large_read, tvb, offset, 4,
16172 			ENC_LITTLE_ENDIAN);
16173 
16174 		proto_tree_add_item(
16175 			subtree, hf_smb_unix_capability_large_write, tvb, offset, 4,
16176 			ENC_LITTLE_ENDIAN);
16177 
16178 		proto_tree_add_item(
16179 			subtree, hf_smb_unix_capability_encryption, tvb, offset, 4,
16180 			ENC_LITTLE_ENDIAN);
16181 
16182 		proto_tree_add_item(
16183 			subtree, hf_smb_unix_capability_mandatory_crypto, tvb, offset, 4,
16184 			ENC_LITTLE_ENDIAN);
16185 
16186 		proto_tree_add_item(
16187 			subtree, hf_smb_unix_capability_proxy, tvb, offset, 4,
16188 			ENC_LITTLE_ENDIAN);
16189 
16190 		COUNT_BYTES_TRANS_SUBR(8);
16191 
16192 		break;
16193 	}
16194 
16195 	case 0x202: {	/* SMB_QUERY_POSIX_WHOAMI */
16196 		proto_tree *st_gids;
16197 		guint32     num_gids;
16198 		guint       i;
16199 		proto_tree *st_sids;
16200 		int         old_sid_offset;
16201 		guint32     num_sids;
16202 		guint32     sids_buflen;
16203 
16204 		/* Mapping flags */
16205 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16206 		proto_tree_add_item(tree, hf_smb_unix_whoami_mapflags,
16207 				tvb, offset, 4, ENC_LITTLE_ENDIAN);
16208 		COUNT_BYTES_TRANS_SUBR(4);
16209 
16210 		/* Mapping flags mask */
16211 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16212 		proto_tree_add_item(tree, hf_smb_unix_whoami_mapflags_mask,
16213 				tvb, offset, 4, ENC_LITTLE_ENDIAN);
16214 		COUNT_BYTES_TRANS_SUBR(4);
16215 
16216 		/* primary UID */
16217 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
16218 		proto_tree_add_item(tree, hf_smb_unix_file_uid,
16219 				tvb, offset, 8, ENC_LITTLE_ENDIAN);
16220 		COUNT_BYTES_TRANS_SUBR(8);
16221 
16222 		/* primary GID */
16223 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
16224 		proto_tree_add_item(tree, hf_smb_unix_file_gid,
16225 				tvb, offset, 8, ENC_LITTLE_ENDIAN);
16226 		COUNT_BYTES_TRANS_SUBR(8);
16227 
16228 		/* number of supplementary GIDs */
16229 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16230 		num_gids = tvb_get_letohl(tvb, offset);
16231 		proto_tree_add_item(tree, hf_smb_unix_whoami_num_supl_gids,
16232 				tvb, offset, 4, ENC_LITTLE_ENDIAN);
16233 		COUNT_BYTES_TRANS_SUBR(4);
16234 
16235 		/* number of supplementary SIDs */
16236 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16237 		num_sids = tvb_get_letohl(tvb, offset);
16238 		proto_tree_add_item(tree, hf_smb_unix_whoami_num_supl_sids,
16239 				tvb, offset, 4, ENC_LITTLE_ENDIAN);
16240 		COUNT_BYTES_TRANS_SUBR(4);
16241 
16242 		/* supplementary SIDs buffer length */
16243 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16244 		sids_buflen = tvb_get_letohl(tvb, offset);
16245 		proto_tree_add_item(tree, hf_smb_unix_whoami_sids_buflen,
16246 				tvb, offset, 4, ENC_LITTLE_ENDIAN);
16247 		COUNT_BYTES_TRANS_SUBR(4);
16248 
16249 		/* pad / reserved (must be zero) */
16250 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16251 		proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
16252 		COUNT_BYTES_TRANS_SUBR(4);
16253 
16254 
16255 		/* GIDs */
16256 		st_gids = proto_tree_add_subtree(tree, tvb, offset, num_gids * 8,
16257 				ett_smb_unix_whoami_gids, NULL, "Supplementary UNIX GIDs");
16258 
16259 		for (i = 0; i < num_gids; i++) {
16260 			CHECK_BYTE_COUNT_TRANS_SUBR(8);
16261 			proto_tree_add_item(st_gids, hf_smb_unix_file_gid,
16262 					tvb, offset, 8, ENC_LITTLE_ENDIAN);
16263 			COUNT_BYTES_TRANS_SUBR(8);
16264 		}
16265 
16266 		/* SIDs */
16267 		st_sids = proto_tree_add_subtree(tree, tvb, offset, sids_buflen,
16268 				ett_smb_unix_whoami_sids, NULL, "List of SIDs");
16269 
16270 		for (i = 0; i < num_sids; i++) {
16271 			old_sid_offset = offset;
16272 			offset = dissect_nt_sid(tvb, offset, st_sids, "SID", NULL, -1);
16273 			CHECK_BYTE_COUNT_TRANS_SUBR(offset-old_sid_offset);
16274 			*bcp -= (offset - old_sid_offset);
16275 		}
16276 
16277 		break;
16278 	}
16279 
16280 	case 0x301: { 	/* MAC_QUERY_FS_INFO */
16281 		static int * const support_flags[] = {
16282 			&hf_smb_mac_sup_access_ctrl,
16283 			&hf_smb_mac_sup_getset_comments,
16284 			&hf_smb_mac_sup_desktopdb_calls,
16285 			&hf_smb_mac_sup_unique_ids,
16286 			&hf_smb_mac_sup_streams,
16287 			NULL
16288 		};
16289 
16290 		/* Create time */
16291 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
16292 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
16293 		*bcp -= 8;
16294 		/* Modify Time */
16295 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
16296 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
16297 		*bcp -= 8;
16298 		/* Backup Time */
16299 		CHECK_BYTE_COUNT_TRANS_SUBR(8);
16300 		offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
16301 		*bcp -= 8;
16302 		/* Allocation blocks */
16303 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16304 		proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
16305 				    offset,
16306 				    4, ENC_LITTLE_ENDIAN);
16307 		COUNT_BYTES_TRANS_SUBR(4);
16308 		/* Allocation Block Size */
16309 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16310 		proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
16311 				    offset, 4, ENC_LITTLE_ENDIAN);
16312 		COUNT_BYTES_TRANS_SUBR(4);
16313 		/* Free Block Count */
16314 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16315 		proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
16316 				    offset, 4, ENC_LITTLE_ENDIAN);
16317 		COUNT_BYTES_TRANS_SUBR(4);
16318 		/* Finder Info ... */
16319 		CHECK_BYTE_COUNT_TRANS_SUBR(32);
16320 		proto_tree_add_bytes_format_value(tree, hf_smb_mac_fndrinfo, tvb,
16321 					    offset, 32, NULL,
16322 					    "%s",
16323 					    tvb_format_text(pinfo->pool, tvb, offset, 32));
16324 		COUNT_BYTES_TRANS_SUBR(32);
16325 		/* Number Files */
16326 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16327 		proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
16328 				    offset, 4, ENC_LITTLE_ENDIAN);
16329 		COUNT_BYTES_TRANS_SUBR(4);
16330 		/* Number of Root Directories */
16331 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16332 		proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
16333 				    offset, 4, ENC_LITTLE_ENDIAN);
16334 		COUNT_BYTES_TRANS_SUBR(4);
16335 		/* Number of files */
16336 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16337 		proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
16338 				    offset, 4, ENC_LITTLE_ENDIAN);
16339 		COUNT_BYTES_TRANS_SUBR(4);
16340 		/* Dir Count */
16341 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16342 		proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
16343 				    offset, 4, ENC_LITTLE_ENDIAN);
16344 		COUNT_BYTES_TRANS_SUBR(4);
16345 		/* Mac Support Flags */
16346 		CHECK_BYTE_COUNT_TRANS_SUBR(4);
16347 		proto_tree_add_bitmask(tree, tvb, offset, hf_smb_mac_sup, ett_smb_mac_support_flags, support_flags, ENC_LITTLE_ENDIAN);
16348 		COUNT_BYTES_TRANS_SUBR(4);
16349 		break;
16350 	}
16351 	case 1006:	/* QUERY_FS_QUOTA_INFO */
16352 		offset = dissect_nt_quota(tvb, tree, offset, bcp);
16353 		break;
16354 	case 1007:	/* SMB_FS_FULL_SIZE_INFORMATION */
16355 		offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
16356 		break;
16357 	case 1008: /* Query Object ID */ {
16358 		offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
16359 		break;
16360 	    }
16361 	}
16362 
16363 	return offset;
16364 }
16365 
16366 static int
dissect_transaction2_response_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb_info_t * si)16367 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
16368     proto_tree *parent_tree, smb_info_t *si)
16369 {
16370 	proto_item           *item   = NULL;
16371 	proto_tree           *tree   = NULL;
16372 	smb_transact2_info_t *t2i;
16373 	int                   count;
16374 	gboolean              trunc;
16375 	int                   offset = 0;
16376 	guint16               dc;
16377 
16378 	dc = tvb_reported_length(tvb);
16379 
16380 	DISSECTOR_ASSERT(si);
16381 
16382 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
16383 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
16384 	else
16385 		t2i = NULL;
16386 
16387 	if (parent_tree) {
16388 		if ((t2i != NULL) && (t2i->subcmd != -1)) {
16389 			tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, dc,
16390 				ett_smb_transaction_data, &item, "%s Data",
16391 				val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
16392 					       "Unknown (0x%02x)"));
16393 		} else {
16394 			tree = proto_tree_add_subtree(parent_tree, tvb, offset, dc,
16395 					ett_smb_transaction_data, &item, "Unknown Transaction2 Data");
16396 		}
16397 	}
16398 
16399 	if (t2i == NULL) {
16400 		offset += dc;
16401 		return offset;
16402 	}
16403 	switch(t2i->subcmd) {
16404 	case 0x0000:	/*TRANS2_OPEN2*/
16405 		/* XXX not implemented yet. See SNIA doc */
16406 		break;
16407 	case 0x0001:	/*TRANS2_FIND_FIRST2*/
16408 		/* returned data */
16409 		count = si->info_count;
16410 
16411 		if (count == -1) {
16412 			break;
16413 		}
16414 
16415 		if (count) {
16416 			col_append_str(pinfo->cinfo, COL_INFO,
16417 				       ", Files:");
16418 		}
16419 
16420 		while (count--) {
16421 			offset = dissect_ff2_response_data(tvb, pinfo, tree,
16422 							   offset, &dc, &trunc, si);
16423 			if (trunc)
16424 				break;
16425 		}
16426 		break;
16427 	case 0x0002:	/*TRANS2_FIND_NEXT2*/
16428 		/* returned data */
16429 		count = si->info_count;
16430 
16431 		if (count == -1) {
16432 			break;
16433 		}
16434 		if (count) {
16435 			col_append_str(pinfo->cinfo, COL_INFO,
16436 				       ", Files:");
16437 		}
16438 
16439 		while (count--) {
16440 			offset = dissect_ff2_response_data(tvb, pinfo, tree,
16441 				offset, &dc, &trunc, si);
16442 			if (trunc)
16443 				break;
16444 		}
16445 		break;
16446 	case 0x0003:	/*TRANS2_QUERY_FS_INFORMATION*/
16447 		offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc, si);
16448 		break;
16449 	case 0x0004:	/*TRANS2_SET_FS_INFORMATION*/
16450 		offset = dissect_sfsi_response(tvb, pinfo, tree, offset, &dc, si);
16451 		break;
16452 	case 0x0005:	/*TRANS2_QUERY_PATH_INFORMATION*/
16453 		offset = dissect_qpi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
16454 		break;
16455 	case 0x0006:	/*TRANS2_SET_PATH_INFORMATION*/
16456 		/* no data in this response */
16457 		break;
16458 	case 0x0007:	/*TRANS2_QUERY_FILE_INFORMATION*/
16459 		/* identical to QUERY_PATH_INFO */
16460 		offset = dissect_qpi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
16461 		break;
16462 	case 0x0008:	/*TRANS2_SET_FILE_INFORMATION*/
16463 		/* no data in this response */
16464 		break;
16465 	case 0x0009:	/*TRANS2_FSCTL*/
16466 		/* XXX don't know how to dissect this one (yet)*/
16467 
16468 		/*
16469 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
16470 		 * Extensions Version 3.0, Document Version 1.11,
16471 		 * July 19, 1990" says this this contains a
16472 		 * "File system specific return data block".
16473 		 * (That means we may not be able to dissect it in any
16474 		 * case.)
16475 		 */
16476 		break;
16477 	case 0x000a:	/*TRANS2_IOCTL2*/
16478 		/* XXX don't know how to dissect this one (yet)*/
16479 
16480 		/*
16481 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
16482 		 * Extensions Version 3.0, Document Version 1.11,
16483 		 * July 19, 1990" says this this contains a
16484 		 * "Device/function specific return data block".
16485 		 * (That means we may not be able to dissect it in any
16486 		 * case.)
16487 		 */
16488 		break;
16489 	case 0x000b:	/*TRANS2_FIND_NOTIFY_FIRST*/
16490 		/* XXX don't know how to dissect this one (yet)*/
16491 
16492 		/*
16493 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
16494 		 * Extensions Version 3.0, Document Version 1.11,
16495 		 * July 19, 1990" says this this contains "the level
16496 		 * dependent information about the changes which
16497 		 * occurred".
16498 		 */
16499 		break;
16500 	case 0x000c:	/*TRANS2_FIND_NOTIFY_NEXT*/
16501 		/* XXX don't know how to dissect this one (yet)*/
16502 
16503 		/*
16504 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
16505 		 * Extensions Version 3.0, Document Version 1.11,
16506 		 * July 19, 1990" says this this contains "the level
16507 		 * dependent information about the changes which
16508 		 * occurred".
16509 		 */
16510 		break;
16511 	case 0x000d:	/*TRANS2_CREATE_DIRECTORY*/
16512 		/* no data in this response */
16513 		break;
16514 	case 0x000e:	/*TRANS2_SESSION_SETUP*/
16515 		/* XXX don't know how to dissect this one (yet)*/
16516 		break;
16517 	case 0x0010:	/*TRANS2_GET_DFS_REFERRAL*/
16518 		offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc, si->unicode);
16519 		break;
16520 	case 0x0011:	/*TRANS2_REPORT_DFS_INCONSISTENCY*/
16521 		/* the SNIA spec appears to say the response has no data */
16522 		break;
16523 	case -1:
16524 		/*
16525 		 * We don't know what the matching request was; don't
16526 		 * bother putting anything else into the tree for the data.
16527 		 */
16528 		offset += dc;
16529 		dc = 0;
16530 		break;
16531 	}
16532 
16533 	/* ooops there were data we didn't know how to process */
16534 	if (dc != 0) {
16535 		proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, ENC_NA);
16536 		offset += dc;
16537 	}
16538 
16539 	return offset;
16540 }
16541 
16542 
16543 static int
dissect_transaction2_response_parameters(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,smb_info_t * si)16544 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb_info_t *si)
16545 {
16546 	proto_item           *item   = NULL;
16547 	proto_tree           *tree   = NULL;
16548 	smb_transact2_info_t *t2i;
16549 	guint16               fid;
16550 	int                   lno;
16551 	int                   offset = 0;
16552 	int                   pc;
16553 
16554 	pc = tvb_reported_length(tvb);
16555 
16556 	DISSECTOR_ASSERT(si);
16557 
16558 	if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
16559 		t2i = (smb_transact2_info_t *)si->sip->extra_info;
16560 	else
16561 		t2i = NULL;
16562 
16563 	if (parent_tree) {
16564 		if ((t2i != NULL) && (t2i->subcmd != -1)) {
16565 			tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, pc,
16566 				ett_smb_transaction_params, &item, "%s Parameters",
16567 				val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
16568 					       "Unknown (0x%02x)"));
16569 		} else {
16570 			tree = proto_tree_add_subtree(parent_tree, tvb, offset, pc,
16571 				ett_smb_transaction_params, &item, "Unknown Transaction2 Parameters");
16572 		}
16573 	}
16574 
16575 	if (t2i == NULL) {
16576 		offset += pc;
16577 		return offset;
16578 	}
16579 	switch(t2i->subcmd) {
16580 	case 0x00:	/*TRANS2_OPEN2*/
16581 		/* fid */
16582 		fid = tvb_get_letohs(tvb, offset);
16583 		dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
16584 		offset += 2;
16585 
16586 		/*
16587 		 * XXX - Microsoft Networks SMB File Sharing Protocol
16588 		 * Extensions Version 3.0, Document Version 1.11,
16589 		 * July 19, 1990 says that the file attributes, create
16590 		 * time (which it says is the last modification time),
16591 		 * data size, granted access, file type, and IPC state
16592 		 * are returned only if bit 0 is set in the open flags,
16593 		 * and that the EA length is returned only if bit 3
16594 		 * is set in the open flags.  Does that mean that,
16595 		 * at least in that SMB dialect, those fields are not
16596 		 * present in the reply parameters if the bits in
16597 		 * question aren't set?
16598 		 */
16599 
16600 		/* File Attributes */
16601 		offset = dissect_file_attributes(tvb, tree, offset);
16602 
16603 		/* create time */
16604 		offset = dissect_smb_datetime(tvb, tree, offset,
16605 			hf_smb_create_time,
16606 			hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
16607 
16608 		/* data size */
16609 		proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16610 		offset += 4;
16611 
16612 		/* granted access */
16613 		offset = dissect_access(tvb, tree, offset, hf_smb_granted_access);
16614 
16615 		/* File Type */
16616 		proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16617 		offset += 2;
16618 
16619 		/* IPC State */
16620 		offset = dissect_ipc_state(tvb, tree, offset, FALSE);
16621 
16622 		/* open_action */
16623 		offset = dissect_open_action(tvb, tree, offset);
16624 
16625 		/* server unique file ID */
16626 		proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16627 		offset += 4;
16628 
16629 		/* ea error offset, only a 16 bit integer here */
16630 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16631 		offset += 2;
16632 
16633 		/* ea length */
16634 		proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16635 		offset += 4;
16636 
16637 		break;
16638 	case 0x01:	/*TRANS2_FIND_FIRST2*/
16639 		/* Find First2 information level */
16640 		proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
16641 
16642 		/* sid */
16643 		proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16644 		offset += 2;
16645 
16646 		/* search count */
16647 		si->info_count = tvb_get_letohs(tvb, offset);
16648 		proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
16649 		offset += 2;
16650 
16651 		/* end of search */
16652 		proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16653 		offset += 2;
16654 
16655 		/* ea error offset, only a 16 bit integer here */
16656 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16657 		offset += 2;
16658 
16659 		/* last name offset */
16660 		lno = tvb_get_letohs(tvb, offset);
16661 		proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
16662 		offset += 2;
16663 
16664 		break;
16665 	case 0x02:	/*TRANS2_FIND_NEXT2*/
16666 		/* search count */
16667 		si->info_count = tvb_get_letohs(tvb, offset);
16668 		proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
16669 		offset += 2;
16670 
16671 		/* end of search */
16672 		proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16673 		offset += 2;
16674 
16675 		/* ea_error_offset, only a 16 bit integer here*/
16676 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16677 		offset += 2;
16678 
16679 		/* last name offset */
16680 		lno = tvb_get_letohs(tvb, offset);
16681 		proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
16682 		offset += 2;
16683 
16684 		break;
16685 	case 0x03:	/*TRANS2_QUERY_FS_INFORMATION*/
16686 		/* no parameter block here */
16687 		break;
16688 	case 0x05:	/*TRANS2_QUERY_PATH_INFORMATION*/
16689 		/* ea_error_offset, only a 16 bit integer here*/
16690 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16691 		offset += 2;
16692 
16693 		break;
16694 	case 0x06:	/*TRANS2_SET_PATH_INFORMATION*/
16695 		/* ea_error_offset, only a 16 bit integer here*/
16696 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16697 		offset += 2;
16698 
16699 		break;
16700 	case 0x07:	/*TRANS2_QUERY_FILE_INFORMATION*/
16701 		/* ea_error_offset, only a 16 bit integer here*/
16702 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16703 		offset += 2;
16704 
16705 		break;
16706 	case 0x08:	/*TRANS2_SET_FILE_INFORMATION*/
16707 		/* ea_error_offset, only a 16 bit integer here*/
16708 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16709 		offset += 2;
16710 
16711 		break;
16712 	case 0x09:	/*TRANS2_FSCTL*/
16713 		/* XXX don't know how to dissect this one (yet)*/
16714 
16715 		/*
16716 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
16717 		 * Extensions Version 3.0, Document Version 1.11,
16718 		 * July 19, 1990" says this this contains a
16719 		 * "File system specific return parameter block".
16720 		 * (That means we may not be able to dissect it in any
16721 		 * case.)
16722 		 */
16723 		break;
16724 	case 0x0a:	/*TRANS2_IOCTL2*/
16725 		/* XXX don't know how to dissect this one (yet)*/
16726 
16727 		/*
16728 		 * XXX - "Microsoft Networks SMB File Sharing Protocol
16729 		 * Extensions Version 3.0, Document Version 1.11,
16730 		 * July 19, 1990" says this this contains a
16731 		 * "Device/function specific return parameter block".
16732 		 * (That means we may not be able to dissect it in any
16733 		 * case.)
16734 		 */
16735 		break;
16736 	case 0x0b:	/*TRANS2_FIND_NOTIFY_FIRST*/
16737 		/* Find Notify information level */
16738 		proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
16739 
16740 		/* Monitor handle */
16741 		proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16742 		offset += 2;
16743 
16744 		/* Change count */
16745 		si->info_count = tvb_get_letohs(tvb, offset);
16746 		proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
16747 		offset += 2;
16748 
16749 		/* ea_error_offset, only a 16 bit integer here*/
16750 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16751 		offset += 2;
16752 
16753 		break;
16754 	case 0x0c:	/*TRANS2_FIND_NOTIFY_NEXT*/
16755 		/* Find Notify information level */
16756 		proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
16757 
16758 		/* Change count */
16759 		si->info_count = tvb_get_letohs(tvb, offset);
16760 		proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
16761 		offset += 2;
16762 
16763 		/* ea_error_offset, only a 16 bit integer here*/
16764 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16765 		offset += 2;
16766 
16767 		break;
16768 	case 0x0d:	/*TRANS2_CREATE_DIRECTORY*/
16769 		/* ea error offset, only a 16 bit integer here */
16770 		proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16771 		offset += 2;
16772 
16773 		break;
16774 	case 0x0e:	/*TRANS2_SESSION_SETUP*/
16775 		/* XXX don't know how to dissect this one (yet)*/
16776 		break;
16777 	case 0x10:	/*TRANS2_GET_DFS_REFERRAL*/
16778 		/* XXX don't know how to dissect this one (yet) see SNIA doc*/
16779 		break;
16780 	case 0x11:	/*TRANS2_REPORT_DFS_INCONSISTENCY*/
16781 		/* XXX don't know how to dissect this one (yet) see SNIA doc*/
16782 		break;
16783 	case -1:
16784 		/*
16785 		 * We don't know what the matching request was; don't
16786 		 * bother putting anything else into the tree for the data.
16787 		 */
16788 		offset += pc;
16789 		break;
16790 	}
16791 
16792 	/* ooops there were data we didn't know how to process */
16793 	if (offset < pc) {
16794 		proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, ENC_NA);
16795 		offset += pc-offset;
16796 	}
16797 	return offset;
16798 }
16799 
16800 
16801 static int
dissect_transaction_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si)16802 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
16803 {
16804 	guint8                sc, wc;
16805 	guint16               od     = 0, po = 0, pc = 0, pd = 0, dc = 0, dd = 0, td = 0, tp = 0;
16806 	smb_transact2_info_t *t2i    = NULL;
16807 	guint16               bc;
16808 	int                   padcnt;
16809 	gboolean              dissected_trans;
16810 	fragment_head        *r_fd   = NULL;
16811 	tvbuff_t             *pd_tvb = NULL, *d_tvb = NULL, *p_tvb = NULL;
16812 	tvbuff_t             *s_tvb  = NULL, *sp_tvb = NULL;
16813 	gboolean              save_fragmented;
16814 	proto_item           *item;
16815 
16816 	DISSECTOR_ASSERT(si);
16817 
16818 	switch(si->cmd) {
16819 	case SMB_COM_TRANSACTION2:
16820 		/* transaction2 */
16821 		if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
16822 			t2i = (smb_transact2_info_t *)si->sip->extra_info;
16823 		} else
16824 			t2i = NULL;
16825 		if (t2i == NULL) {
16826 			/*
16827 			 * We didn't see the matching request, so we don't
16828 			 * know what type of transaction this is.
16829 			 */
16830 			proto_tree_add_uint_format_value(tree, hf_smb_trans2_subcmd, tvb, 0, 0, -1,
16831 				"<UNKNOWN> since request packet wasn't seen");
16832 			col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
16833 		} else {
16834 			si->info_level = t2i->info_level;
16835 			if (t2i->subcmd == -1) {
16836 				/*
16837 				 * We didn't manage to extract the subcommand
16838 				 * from the matching request (perhaps because
16839 				 * the frame was short), so we don't know what
16840 				 * type of transaction this is.
16841 				 */
16842 				proto_tree_add_uint_format_value(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd,
16843 					"<UNKNOWN> since transaction code wasn't found in request packet");
16844 				col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
16845 			} else {
16846 				proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
16847 				switch (t2i->subcmd) {
16848 
16849 				case 0x0001:	/* FIND_FIRST2 */
16850 					if (t2i->info_level == -1)
16851 						item = proto_tree_add_uint_format_value(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level,
16852 										"<UNKNOWN> since information level wasn't found in request packet");
16853 					else
16854 						item = proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
16855 					proto_item_set_generated(item);
16856 					if (t2i->name) {
16857 						item = proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
16858 						proto_item_set_generated(item);
16859 					}
16860 					break;
16861 
16862 				case 0x0005:	/* QUERY_PATH_INFORMATION */
16863 					if (t2i->info_level == -1)
16864 						item = proto_tree_add_uint_format_value(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level,
16865 										"<UNKNOWN> since information level wasn't found in request packet");
16866 					else
16867 						item = proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
16868 					proto_item_set_generated(item);
16869 					if (t2i->name) {
16870 						item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
16871 						proto_item_set_generated(item);
16872 					}
16873 					break;
16874 
16875 				case 0x0007:	/* QUERY_FILE_INFORMATION */
16876 					if (t2i->info_level == -1)
16877 						item = proto_tree_add_uint_format_value(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level,
16878 										"<UNKNOWN> since information level wasn't found in request packet");
16879 					else
16880 						item = proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
16881 					proto_item_set_generated(item);
16882 					break;
16883 
16884 				case 0x0003:	/* QUERY_FS_INFORMATION */
16885 					if (t2i->info_level == -1)
16886 						item = proto_tree_add_uint_format_value(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level,
16887 										"<UNKNOWN> since information level wasn't found in request packet");
16888 					else
16889 						item = proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
16890 					proto_item_set_generated(item);
16891 					break;
16892 
16893 				case 0x0004:	/* SET_FS_INFORMATION */
16894 					if (t2i->info_level == -1)
16895 						item = proto_tree_add_uint_format_value(tree, hf_smb_sfsi_information_level, tvb, 0, 0, si->info_level,
16896 										"<UNKNOWN> since information level wasn't found in request packet");
16897 					else
16898 						item = proto_tree_add_uint(tree, hf_smb_sfsi_information_level, tvb, 0, 0, si->info_level);
16899 					proto_item_set_generated(item);
16900 					break;
16901 				}
16902 
16903 				col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
16904 						val_to_str_ext(t2i->subcmd,
16905 							       &trans2_cmd_vals_ext,
16906 							       "<unknown (0x%02x)>"));
16907 			}
16908 		}
16909 		break;
16910 	}
16911 
16912 	WORD_COUNT;
16913 
16914 	/* total param count, only a 16bit integer here */
16915 	tp = tvb_get_letohs(tvb, offset);
16916 	proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
16917 	offset += 2;
16918 
16919 	/* total data count, only a 16 bit integer here */
16920 	td = tvb_get_letohs(tvb, offset);
16921 	proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
16922 	offset += 2;
16923 
16924 	/* 2 reserved bytes */
16925 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
16926 	offset += 2;
16927 
16928 	/* param count */
16929 	pc = tvb_get_letohs(tvb, offset);
16930 	proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
16931 	offset += 2;
16932 
16933 	/* param offset */
16934 	po = tvb_get_letohs(tvb, offset);
16935 	proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
16936 	offset += 2;
16937 
16938 	/* param disp */
16939 	pd = tvb_get_letohs(tvb, offset);
16940 	proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
16941 	offset += 2;
16942 
16943 	/* data count */
16944 	dc = tvb_get_letohs(tvb, offset);
16945 	proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
16946 	offset += 2;
16947 
16948 	/* data offset */
16949 	od = tvb_get_letohs(tvb, offset);
16950 	proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
16951 	offset += 2;
16952 
16953 	/* data disp */
16954 	dd = tvb_get_letohs(tvb, offset);
16955 	proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
16956 	offset += 2;
16957 
16958 	/* setup count */
16959 	sc = tvb_get_guint8(tvb, offset);
16960 	proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
16961 	offset += 1;
16962 
16963 	/* reserved byte */
16964 	proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
16965 	offset += 1;
16966 
16967 
16968 	/* if there were any setup bytes, put them in a tvb for later */
16969 	if (sc) {
16970 		if ((2*sc) > tvb_reported_length_remaining(tvb, offset)) {
16971 			s_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_reported_length_remaining(tvb, offset), 2*sc);
16972 		} else {
16973 			s_tvb = tvb_new_subset_length(tvb, offset, 2*sc);
16974 		}
16975 		sp_tvb = tvb_new_subset_remaining(tvb, offset);
16976 	} else {
16977 		s_tvb  = NULL;
16978 		sp_tvb = NULL;
16979 	}
16980 	offset += 2*sc;
16981 
16982 
16983 	BYTE_COUNT;
16984 
16985 
16986 	/* reassembly of SMB Transaction data payload.
16987 	   In this section we do reassembly of both the data and parameters
16988 	   blocks of the SMB transaction command.
16989 	*/
16990 	save_fragmented = pinfo->fragmented;
16991 	/* do we need reassembly? */
16992 	if ( (td != dc) || (tp != pc) ) {
16993 		/* oh yeah, either data or parameter section needs
16994 		   reassembly
16995 		*/
16996 		pinfo->fragmented = TRUE;
16997 		if (smb_trans_reassembly) {
16998 			/* ...and we were told to do reassembly */
16999 			if (pc) {
17000 				r_fd = smb_trans_defragment(tree, pinfo, tvb,
17001 							     po, pc, pd, td+tp, si);
17002 
17003 			}
17004 			if ((r_fd == NULL) && dc) {
17005 				r_fd = smb_trans_defragment(tree, pinfo, tvb,
17006 							     od, dc, dd+tp, td+tp, si);
17007 			}
17008 		}
17009 	}
17010 
17011 	/* if we got a reassembled fd structure from the reassembly routine we must
17012 	   create pd_tvb from it
17013 	*/
17014 	if (r_fd) {
17015 		proto_item *frag_tree_item;
17016 
17017 		pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
17018 		add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
17019 		show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
17020 	}
17021 
17022 
17023 	if (pd_tvb) {
17024 		/* OK we have reassembled data, extract d_tvb and p_tvb from it */
17025 		if (tp) {
17026 			p_tvb = tvb_new_subset_length(pd_tvb, 0, tp);
17027 		}
17028 		if (td) {
17029 			d_tvb = tvb_new_subset_length(pd_tvb, tp, td);
17030 		}
17031 	} else {
17032 		/* It was not reassembled. Do as best as we can.
17033 		 * in this case we always try to dissect the stuff if
17034 		 * data and param displacement is 0. i.e. for the first
17035 		 * (and maybe only) packet.
17036 		 */
17037 		if ( (pd == 0) && (dd == 0) ) {
17038 			int min;
17039 			int reported_min;
17040 			min = MIN(pc, tvb_reported_length_remaining(tvb, po));
17041 			reported_min = MIN(pc, tvb_reported_length_remaining(tvb, po));
17042 			if (min && reported_min) {
17043 				p_tvb = tvb_new_subset_length_caplen(tvb, po, min, reported_min);
17044 			}
17045 			min = MIN(dc, tvb_reported_length_remaining(tvb, od));
17046 			reported_min = MIN(dc, tvb_reported_length_remaining(tvb, od));
17047 			if (min && reported_min) {
17048 				d_tvb = tvb_new_subset_length_caplen(tvb, od, min, reported_min);
17049 			}
17050 			/*
17051 			 * A tvbuff containing the parameters
17052 			 * and the data.
17053 			 * XXX - check pc and dc as well?
17054 			 */
17055 			if (tvb_reported_length_remaining(tvb, po)) {
17056 				pd_tvb = tvb_new_subset_remaining(tvb, po);
17057 			}
17058 		}
17059 	}
17060 
17061 
17062 
17063 	/* parameters */
17064 	if (po > offset) {
17065 		/* We have some padding bytes.
17066 		*/
17067 		padcnt = po-offset;
17068 		if (padcnt > bc)
17069 			padcnt = bc;
17070 		proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
17071 		COUNT_BYTES(padcnt);
17072 	}
17073 	if ((si->cmd == SMB_COM_TRANSACTION2) && p_tvb) {
17074 		/* TRANSACTION2 parameters*/
17075 		dissect_transaction2_response_parameters(p_tvb, pinfo, tree, si);
17076 	}
17077 	COUNT_BYTES(pc);
17078 
17079 
17080 	/* data */
17081 	if (od > offset) {
17082 		/* We have some initial padding bytes.
17083 		*/
17084 		padcnt = od-offset;
17085 		if (padcnt > bc)
17086 			padcnt = bc;
17087 		proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
17088 		COUNT_BYTES(padcnt);
17089 	}
17090 	/*
17091 	 * If the data count is bigger than the count of bytes
17092 	 * remaining, clamp it so that the count of bytes remaining
17093 	 * doesn't go negative.
17094 	 */
17095 	if (dc > bc)
17096 		dc = bc;
17097 	COUNT_BYTES(dc);
17098 
17099 
17100 
17101 	/* from now on, everything is in separate tvbuffs so we don't count
17102 	   the bytes with COUNT_BYTES any more.
17103 	   neither do we reference offset any more (which by now points to the
17104 	   first byte AFTER this PDU */
17105 
17106 
17107 	if ((si->cmd == SMB_COM_TRANSACTION2) && d_tvb) {
17108 		/* TRANSACTION2 parameters*/
17109 		dissect_transaction2_response_data(d_tvb, pinfo, tree, si);
17110 	}
17111 
17112 
17113 	if (si->cmd == SMB_COM_TRANSACTION) {
17114 		smb_transact_info_t *tri;
17115 
17116 		dissected_trans = FALSE;
17117 		if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_TRI))
17118 			tri = (smb_transact_info_t *)si->sip->extra_info;
17119 		else
17120 			tri = NULL;
17121 		if (tri != NULL) {
17122 			switch(tri->subcmd) {
17123 
17124 			case TRANSACTION_PIPE:
17125 				/* This function is safe to call for
17126 				   s_tvb == sp_tvb == NULL, i.e. if we don't
17127 				   know them at this point.
17128 				   It's also safe to call if "p_tvb"
17129 				   or "d_tvb" are null.
17130 				*/
17131 				if ( pd_tvb) {
17132 					dissected_trans = dissect_pipe_smb(
17133 						sp_tvb, s_tvb, pd_tvb, p_tvb,
17134 						d_tvb, NULL, pinfo, top_tree_global, si);
17135 				}
17136 				break;
17137 
17138 			case TRANSACTION_MAILSLOT:
17139 				/* This one should be safe to call
17140 				   even if s_tvb and sp_tvb is NULL
17141 				*/
17142 				if (d_tvb) {
17143 					dissected_trans = dissect_mailslot_smb(
17144 						sp_tvb, s_tvb, d_tvb, NULL, pinfo,
17145 						top_tree_global, si);
17146 				}
17147 				break;
17148 			}
17149 		}
17150 		if (!dissected_trans) {
17151 			/* This one is safe to call for s_tvb == p_tvb == d_tvb == NULL */
17152 			dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
17153 		}
17154 	}
17155 
17156 
17157 	if ( (p_tvb == 0) && (d_tvb == 0) ) {
17158 		col_append_str(pinfo->cinfo, COL_INFO,
17159 				       "[transact continuation]");
17160 	}
17161 
17162 	pinfo->fragmented = save_fragmented;
17163 	END_OF_SMB
17164 
17165 	return offset;
17166 }
17167 
17168 
17169 static int
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_)17170 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_)
17171 {
17172 	guint8  wc;
17173 	guint16 bc;
17174 
17175 	WORD_COUNT;
17176 
17177 	/* Monitor handle */
17178 	proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
17179 	offset += 2;
17180 
17181 	BYTE_COUNT;
17182 
17183 	END_OF_SMB
17184 
17185 	return offset;
17186 }
17187 
17188 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
17189    END Transaction/Transaction2 Primary and secondary requests
17190    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
17191 
17192 
17193 static int
dissect_unknown(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,proto_tree * smb_tree _U_,smb_info_t * si _U_)17194 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
17195 {
17196 	guint8  wc;
17197 	guint16 bc;
17198 
17199 	WORD_COUNT;
17200 
17201 	if (wc != 0) {
17202 		proto_tree_add_item(tree, hf_smb_word_parameters, tvb, offset, wc*2, ENC_NA);
17203 		offset += wc*2;
17204 	}
17205 
17206 	BYTE_COUNT;
17207 
17208 	if (bc != 0) {
17209 		proto_tree_add_item(tree, hf_smb_byte_parameters, tvb, offset, bc, ENC_NA);
17210 		offset += bc;
17211 		bc = 0;
17212 	}
17213 
17214 	END_OF_SMB
17215 
17216 	return offset;
17217 }
17218 
17219 typedef struct _smb_function {
17220 	int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
17221 	int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
17222 } smb_function;
17223 
17224 static smb_function smb_dissector[256] = {
17225 	/* 0x00 Create Dir*/                 {dissect_old_dir_request            , dissect_empty},
17226 	/* 0x01 Delete Dir*/                 {dissect_old_dir_request            , dissect_empty},
17227 	/* 0x02 Open File*/                  {dissect_open_file_request          , dissect_open_file_response},
17228 	/* 0x03 Create File*/                {dissect_create_file_request        , dissect_create_file_response},
17229 	/* 0x04 Close File*/                 {dissect_close_file_request         , dissect_empty},
17230 	/* 0x05 Flush File*/                 {dissect_flush_file_request         , dissect_empty},
17231 	/* 0x06 Delete File*/                {dissect_delete_file_request        , dissect_empty},
17232 	/* 0x07 Rename File*/                {dissect_rename_file_request        , dissect_rename_file_response},
17233 	/* 0x08 Query Info*/                 {dissect_query_information_request  , dissect_query_information_response},
17234 	/* 0x09 Set Info*/                   {dissect_set_information_request    , dissect_empty},
17235 	/* 0x0a Read File*/                  {dissect_read_file_request          , dissect_read_file_response},
17236 	/* 0x0b Write File*/                 {dissect_write_file_request         , dissect_write_file_response},
17237 	/* 0x0c Lock Byte Range*/            {dissect_lock_request               , dissect_empty},
17238 	/* 0x0d Unlock Byte Range*/          {dissect_lock_request               , dissect_empty},
17239 	/* 0x0e Create Temp*/                {dissect_create_temporary_request   , dissect_create_temporary_response},
17240 	/* 0x0f Create New*/                 {dissect_create_file_request        , dissect_create_new_response},
17241 
17242 	/* 0x10 Check Dir*/                  {dissect_old_dir_request            , dissect_empty},
17243 	/* 0x11 Process Exit*/               {dissect_empty                      , dissect_empty},
17244 	/* 0x12 Seek File*/                  {dissect_seek_file_request          , dissect_seek_file_response},
17245 	/* 0x13 Lock And Read*/              {dissect_read_file_request          , dissect_lock_and_read_response},
17246 	/* 0x14 Write And Unlock*/           {dissect_write_file_request         , dissect_write_file_response},
17247 	/* 0x15 */                           {dissect_unknown                    , dissect_unknown},
17248 	/* 0x16 */                           {dissect_unknown                    , dissect_unknown},
17249 	/* 0x17 */                           {dissect_unknown                    , dissect_unknown},
17250 	/* 0x18 */                           {dissect_unknown                    , dissect_unknown},
17251 	/* 0x19 */                           {dissect_unknown                    , dissect_unknown},
17252 	/* 0x1a Read Raw*/                   {dissect_read_raw_request           , dissect_unknown},
17253 	/* 0x1b Read MPX*/                   {dissect_read_mpx_request           , dissect_read_mpx_response},
17254 	/* 0x1c Read MPX Secondary*/         {dissect_unknown                    , dissect_unknown},
17255 	/* 0x1d Write Raw*/                  {dissect_write_raw_request          , dissect_write_raw_response},
17256 	/* 0x1e Write MPX*/                  {dissect_write_mpx_request          , dissect_write_mpx_response},
17257 	/* 0x1f Write MPX Secondary*/        {dissect_unknown                    , dissect_unknown},
17258 
17259 	/* 0x20 Write Complete*/             {dissect_unknown                    , dissect_write_and_close_response},
17260 	/* 0x21 */                           {dissect_unknown                    , dissect_unknown},
17261 	/* 0x22 Set Info2*/                  {dissect_set_information2_request   , dissect_empty},
17262 	/* 0x23 Query Info2*/                {dissect_query_information2_request , dissect_query_information2_response},
17263 	/* 0x24 Locking And X*/              {dissect_locking_andx_request       , dissect_locking_andx_response},
17264 	/* 0x25 Transaction*/                {dissect_transaction_request        , dissect_transaction_response},
17265 	/* 0x26 Transaction Secondary*/      {dissect_transaction_request        , dissect_unknown}, /*This SMB has no response */
17266 	/* 0x27 IOCTL*/                      {dissect_unknown                    , dissect_unknown},
17267 	/* 0x28 IOCTL Secondary*/            {dissect_unknown                    , dissect_unknown},
17268 	/* 0x29 Copy File*/                  {dissect_copy_request               , dissect_move_copy_response},
17269 	/* 0x2a Move File*/                  {dissect_move_request               , dissect_move_copy_response},
17270 	/* 0x2b Echo*/                       {dissect_echo_request               , dissect_echo_response},
17271 	/* 0x2c Write And Close*/            {dissect_write_and_close_request    , dissect_write_and_close_response},
17272 	/* 0x2d Open And X*/                 {dissect_open_andx_request          , dissect_open_andx_response},
17273 	/* 0x2e Read And X*/                 {dissect_read_andx_request          , dissect_read_andx_response},
17274 	/* 0x2f Write And X*/                {dissect_write_andx_request         , dissect_write_andx_response},
17275 
17276 	/* 0x30 */                           {dissect_unknown                    , dissect_unknown},
17277 	/* 0x31 Close And Tree Disconnect */ {dissect_close_file_request         , dissect_empty},
17278 	/* 0x32 Transaction2*/	             {dissect_transaction_request        , dissect_transaction_response},
17279 	/* 0x33 Transaction2 Secondary*/     {dissect_transaction_request        , dissect_unknown}, /*This SMB has no response */
17280 	/* 0x34 Find Close2*/                {dissect_sid                        , dissect_empty},
17281 	/* 0x35 Find Notify Close*/          {dissect_find_notify_close          , dissect_empty},
17282 	/* 0x36 */  {dissect_unknown, dissect_unknown},
17283 	/* 0x37 */  {dissect_unknown, dissect_unknown},
17284 	/* 0x38 */  {dissect_unknown, dissect_unknown},
17285 	/* 0x39 */  {dissect_unknown, dissect_unknown},
17286 	/* 0x3a */  {dissect_unknown, dissect_unknown},
17287 	/* 0x3b */  {dissect_unknown, dissect_unknown},
17288 	/* 0x3c */  {dissect_unknown, dissect_unknown},
17289 	/* 0x3d */  {dissect_unknown, dissect_unknown},
17290 	/* 0x3e */  {dissect_unknown, dissect_unknown},
17291 	/* 0x3f */  {dissect_unknown, dissect_unknown},
17292 
17293 	/* 0x40 */  {dissect_unknown, dissect_unknown},
17294 	/* 0x41 */  {dissect_unknown, dissect_unknown},
17295 	/* 0x42 */  {dissect_unknown, dissect_unknown},
17296 	/* 0x43 */  {dissect_unknown, dissect_unknown},
17297 	/* 0x44 */  {dissect_unknown, dissect_unknown},
17298 	/* 0x45 */  {dissect_unknown, dissect_unknown},
17299 	/* 0x46 */  {dissect_unknown, dissect_unknown},
17300 	/* 0x47 */  {dissect_unknown, dissect_unknown},
17301 	/* 0x48 */  {dissect_unknown, dissect_unknown},
17302 	/* 0x49 */  {dissect_unknown, dissect_unknown},
17303 	/* 0x4a */  {dissect_unknown, dissect_unknown},
17304 	/* 0x4b */  {dissect_unknown, dissect_unknown},
17305 	/* 0x4c */  {dissect_unknown, dissect_unknown},
17306 	/* 0x4d */  {dissect_unknown, dissect_unknown},
17307 	/* 0x4e */  {dissect_unknown, dissect_unknown},
17308 	/* 0x4f */  {dissect_unknown, dissect_unknown},
17309 
17310 	/* 0x50 */  {dissect_unknown, dissect_unknown},
17311 	/* 0x51 */  {dissect_unknown, dissect_unknown},
17312 	/* 0x52 */  {dissect_unknown, dissect_unknown},
17313 	/* 0x53 */  {dissect_unknown, dissect_unknown},
17314 	/* 0x54 */  {dissect_unknown, dissect_unknown},
17315 	/* 0x55 */  {dissect_unknown, dissect_unknown},
17316 	/* 0x56 */  {dissect_unknown, dissect_unknown},
17317 	/* 0x57 */  {dissect_unknown, dissect_unknown},
17318 	/* 0x58 */  {dissect_unknown, dissect_unknown},
17319 	/* 0x59 */  {dissect_unknown, dissect_unknown},
17320 	/* 0x5a */  {dissect_unknown, dissect_unknown},
17321 	/* 0x5b */  {dissect_unknown, dissect_unknown},
17322 	/* 0x5c */  {dissect_unknown, dissect_unknown},
17323 	/* 0x5d */  {dissect_unknown, dissect_unknown},
17324 	/* 0x5e */  {dissect_unknown, dissect_unknown},
17325 	/* 0x5f */  {dissect_unknown, dissect_unknown},
17326 
17327 	/* 0x60 */  {dissect_unknown, dissect_unknown},
17328 	/* 0x61 */  {dissect_unknown, dissect_unknown},
17329 	/* 0x62 */  {dissect_unknown, dissect_unknown},
17330 	/* 0x63 */  {dissect_unknown, dissect_unknown},
17331 	/* 0x64 */  {dissect_unknown, dissect_unknown},
17332 	/* 0x65 */  {dissect_unknown, dissect_unknown},
17333 	/* 0x66 */  {dissect_unknown, dissect_unknown},
17334 	/* 0x67 */  {dissect_unknown, dissect_unknown},
17335 	/* 0x68 */  {dissect_unknown, dissect_unknown},
17336 	/* 0x69 */  {dissect_unknown, dissect_unknown},
17337 	/* 0x6a */  {dissect_unknown, dissect_unknown},
17338 	/* 0x6b */  {dissect_unknown, dissect_unknown},
17339 	/* 0x6c */  {dissect_unknown, dissect_unknown},
17340 	/* 0x6d */  {dissect_unknown, dissect_unknown},
17341 	/* 0x6e */  {dissect_unknown, dissect_unknown},
17342 	/* 0x6f */  {dissect_unknown, dissect_unknown},
17343 
17344 	/* 0x70 Tree Connect*/	             {dissect_tree_connect_request       , dissect_tree_connect_response},
17345 	/* 0x71 Tree Disconnect*/	     {dissect_empty                      , dissect_empty},
17346 	/* 0x72 Negotiate Protocol*/	     {dissect_negprot_request            , dissect_negprot_response},
17347 	/* 0x73 Session Setup And X*/        {dissect_session_setup_andx_request , dissect_session_setup_andx_response},
17348 	/* 0x74 Logoff And X*/	             {dissect_empty_andx                 , dissect_empty_andx},
17349 	/* 0x75 Tree Connect And X*/         {dissect_tree_connect_andx_request  , dissect_tree_connect_andx_response},
17350 	/* 0x76 */  {dissect_unknown, dissect_unknown},
17351 	/* 0x77 */  {dissect_unknown, dissect_unknown},
17352 	/* 0x78 */  {dissect_unknown, dissect_unknown},
17353 	/* 0x79 */  {dissect_unknown, dissect_unknown},
17354 	/* 0x7a */  {dissect_unknown, dissect_unknown},
17355 	/* 0x7b */  {dissect_unknown, dissect_unknown},
17356 	/* 0x7c */  {dissect_unknown, dissect_unknown},
17357 	/* 0x7d */  {dissect_unknown, dissect_unknown},
17358 	/* 0x7e */  {dissect_unknown, dissect_unknown},
17359 	/* 0x7f */  {dissect_unknown, dissect_unknown},
17360 
17361 	/* 0x80 Query Info Disk*/            {dissect_empty              , dissect_query_information_disk_response},
17362 	/* 0x81 Search Dir*/                 {dissect_search_dir_request , dissect_search_dir_response},
17363 	/* 0x82 Find*/                       {dissect_find_request       , dissect_find_response},
17364 	/* 0x83 Find Unique*/                {dissect_find_request       , dissect_find_response},
17365 	/* 0x84 Find Close*/                 {dissect_find_close_request , dissect_find_close_response},
17366 	/* 0x85 */  {dissect_unknown, dissect_unknown},
17367 	/* 0x86 */  {dissect_unknown, dissect_unknown},
17368 	/* 0x87 */  {dissect_unknown, dissect_unknown},
17369 	/* 0x88 */  {dissect_unknown, dissect_unknown},
17370 	/* 0x89 */  {dissect_unknown, dissect_unknown},
17371 	/* 0x8a */  {dissect_unknown, dissect_unknown},
17372 	/* 0x8b */  {dissect_unknown, dissect_unknown},
17373 	/* 0x8c */  {dissect_unknown, dissect_unknown},
17374 	/* 0x8d */  {dissect_unknown, dissect_unknown},
17375 	/* 0x8e */  {dissect_unknown, dissect_unknown},
17376 	/* 0x8f */  {dissect_unknown, dissect_unknown},
17377 
17378 	/* 0x90 */  {dissect_unknown, dissect_unknown},
17379 	/* 0x91 */  {dissect_unknown, dissect_unknown},
17380 	/* 0x92 */  {dissect_unknown, dissect_unknown},
17381 	/* 0x93 */  {dissect_unknown, dissect_unknown},
17382 	/* 0x94 */  {dissect_unknown, dissect_unknown},
17383 	/* 0x95 */  {dissect_unknown, dissect_unknown},
17384 	/* 0x96 */  {dissect_unknown, dissect_unknown},
17385 	/* 0x97 */  {dissect_unknown, dissect_unknown},
17386 	/* 0x98 */  {dissect_unknown, dissect_unknown},
17387 	/* 0x99 */  {dissect_unknown, dissect_unknown},
17388 	/* 0x9a */  {dissect_unknown, dissect_unknown},
17389 	/* 0x9b */  {dissect_unknown, dissect_unknown},
17390 	/* 0x9c */  {dissect_unknown, dissect_unknown},
17391 	/* 0x9d */  {dissect_unknown, dissect_unknown},
17392 	/* 0x9e */  {dissect_unknown, dissect_unknown},
17393 	/* 0x9f */  {dissect_unknown, dissect_unknown},
17394 
17395 	/* 0xa0 NT Transaction*/             {dissect_nt_transaction_request , dissect_nt_transaction_response},
17396 	/* 0xa1 NT Trans secondary*/         {dissect_nt_transaction_request , dissect_nt_transaction_response},
17397 	/* 0xa2 NT CreateAndX*/              {dissect_nt_create_andx_request , dissect_nt_create_andx_response},
17398 	/* 0xa3 */  {dissect_unknown, dissect_unknown},
17399 	/* 0xa4 NT Cancel*/	             {dissect_nt_cancel_request      , dissect_unknown}, /*no response to this one*/
17400 	/* 0xa5 NT Rename*/                  {dissect_nt_rename_file_request , dissect_empty},
17401 	/* 0xa6 */  {dissect_unknown, dissect_unknown},
17402 	/* 0xa7 */  {dissect_unknown, dissect_unknown},
17403 	/* 0xa8 */  {dissect_unknown, dissect_unknown},
17404 	/* 0xa9 */  {dissect_unknown, dissect_unknown},
17405 	/* 0xaa */  {dissect_unknown, dissect_unknown},
17406 	/* 0xab */  {dissect_unknown, dissect_unknown},
17407 	/* 0xac */  {dissect_unknown, dissect_unknown},
17408 	/* 0xad */  {dissect_unknown, dissect_unknown},
17409 	/* 0xae */  {dissect_unknown, dissect_unknown},
17410 	/* 0xaf */  {dissect_unknown, dissect_unknown},
17411 
17412 	/* 0xb0 */  {dissect_unknown, dissect_unknown},
17413 	/* 0xb1 */  {dissect_unknown, dissect_unknown},
17414 	/* 0xb2 */  {dissect_unknown, dissect_unknown},
17415 	/* 0xb3 */  {dissect_unknown, dissect_unknown},
17416 	/* 0xb4 */  {dissect_unknown, dissect_unknown},
17417 	/* 0xb5 */  {dissect_unknown, dissect_unknown},
17418 	/* 0xb6 */  {dissect_unknown, dissect_unknown},
17419 	/* 0xb7 */  {dissect_unknown, dissect_unknown},
17420 	/* 0xb8 */  {dissect_unknown, dissect_unknown},
17421 	/* 0xb9 */  {dissect_unknown, dissect_unknown},
17422 	/* 0xba */  {dissect_unknown, dissect_unknown},
17423 	/* 0xbb */  {dissect_unknown, dissect_unknown},
17424 	/* 0xbc */  {dissect_unknown, dissect_unknown},
17425 	/* 0xbd */  {dissect_unknown, dissect_unknown},
17426 	/* 0xbe */  {dissect_unknown, dissect_unknown},
17427 	/* 0xbf */  {dissect_unknown, dissect_unknown},
17428 
17429 	/* 0xc0 Open Print File*/            {dissect_open_print_file_request  , dissect_open_print_file_response},
17430 	/* 0xc1 Write Print File*/           {dissect_write_print_file_request , dissect_empty},
17431 	/* 0xc2 Close Print File*/           {dissect_close_print_file_request , dissect_empty},
17432 	/* 0xc3 Get Print Queue*/            {dissect_get_print_queue_request  , dissect_get_print_queue_response},
17433 	/* 0xc4 */  {dissect_unknown, dissect_unknown},
17434 	/* 0xc5 */  {dissect_unknown, dissect_unknown},
17435 	/* 0xc6 */  {dissect_unknown, dissect_unknown},
17436 	/* 0xc7 */  {dissect_unknown, dissect_unknown},
17437 	/* 0xc8 */  {dissect_unknown, dissect_unknown},
17438 	/* 0xc9 */  {dissect_unknown, dissect_unknown},
17439 	/* 0xca */  {dissect_unknown, dissect_unknown},
17440 	/* 0xcb */  {dissect_unknown, dissect_unknown},
17441 	/* 0xcc */  {dissect_unknown, dissect_unknown},
17442 	/* 0xcd */  {dissect_unknown, dissect_unknown},
17443 	/* 0xce */  {dissect_unknown, dissect_unknown},
17444 	/* 0xcf */  {dissect_unknown, dissect_unknown},
17445 
17446 	/* 0xd0 Send Single Block Message*/         {dissect_send_single_block_message_request      , dissect_empty},
17447 	/* 0xd1 Send Broadcast Message*/            {dissect_send_single_block_message_request      , dissect_empty},
17448 	/* 0xd2 Forward User Name*/                 {dissect_forwarded_name                         , dissect_empty},
17449 	/* 0xd3 Cancel Forward*/                    {dissect_forwarded_name                         , dissect_empty},
17450 	/* 0xd4 Get Machine Name*/                  {dissect_empty                                  , dissect_get_machine_name_response},
17451 	/* 0xd5 Send Start of Multi-block Message*/ {dissect_send_multi_block_message_start_request , dissect_message_group_id},
17452 	/* 0xd6 Send End of Multi-block Message*/   {dissect_message_group_id                       , dissect_empty},
17453 	/* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request  , dissect_empty},
17454 	/* 0xd8 SMBreadbulk*/                       {dissect_unknown                                , dissect_unknown},
17455 	/* 0xd9 SMBwritebulk*/                      {dissect_unknown                                , dissect_unknown},
17456 	/* 0xda SMBwritebulkdata*/                  {dissect_unknown                                , dissect_unknown},
17457 	/* 0xdb */  {dissect_unknown, dissect_unknown},
17458 	/* 0xdc */  {dissect_unknown, dissect_unknown},
17459 	/* 0xdd */  {dissect_unknown, dissect_unknown},
17460 	/* 0xde */  {dissect_unknown, dissect_unknown},
17461 	/* 0xdf */  {dissect_unknown, dissect_unknown},
17462 
17463 	/* 0xe0 */  {dissect_unknown, dissect_unknown},
17464 	/* 0xe1 */  {dissect_unknown, dissect_unknown},
17465 	/* 0xe2 */  {dissect_unknown, dissect_unknown},
17466 	/* 0xe3 */  {dissect_unknown, dissect_unknown},
17467 	/* 0xe4 */  {dissect_unknown, dissect_unknown},
17468 	/* 0xe5 */  {dissect_unknown, dissect_unknown},
17469 	/* 0xe6 */  {dissect_unknown, dissect_unknown},
17470 	/* 0xe7 */  {dissect_unknown, dissect_unknown},
17471 	/* 0xe8 */  {dissect_unknown, dissect_unknown},
17472 	/* 0xe9 */  {dissect_unknown, dissect_unknown},
17473 	/* 0xea */  {dissect_unknown, dissect_unknown},
17474 	/* 0xeb */  {dissect_unknown, dissect_unknown},
17475 	/* 0xec */  {dissect_unknown, dissect_unknown},
17476 	/* 0xed */  {dissect_unknown, dissect_unknown},
17477 	/* 0xee */  {dissect_unknown, dissect_unknown},
17478 	/* 0xef */  {dissect_unknown, dissect_unknown},
17479 
17480 	/* 0xf0 */  {dissect_unknown, dissect_unknown},
17481 	/* 0xf1 */  {dissect_unknown, dissect_unknown},
17482 	/* 0xf2 */  {dissect_unknown, dissect_unknown},
17483 	/* 0xf3 */  {dissect_unknown, dissect_unknown},
17484 	/* 0xf4 */  {dissect_unknown, dissect_unknown},
17485 	/* 0xf5 */  {dissect_unknown, dissect_unknown},
17486 	/* 0xf6 */  {dissect_unknown, dissect_unknown},
17487 	/* 0xf7 */  {dissect_unknown, dissect_unknown},
17488 	/* 0xf8 */  {dissect_unknown, dissect_unknown},
17489 	/* 0xf9 */  {dissect_unknown, dissect_unknown},
17490 	/* 0xfa */  {dissect_unknown, dissect_unknown},
17491 	/* 0xfb */  {dissect_unknown, dissect_unknown},
17492 	/* 0xfc */  {dissect_unknown, dissect_unknown},
17493 	/* 0xfd */  {dissect_unknown, dissect_unknown},
17494 	/* 0xfe */  {dissect_unknown, dissect_unknown},
17495 	/* 0xff */  {dissect_unknown, dissect_unknown},
17496 };
17497 
17498 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)17499 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu, smb_info_t *si)
17500 {
17501 	smb_saved_info_t *sip;
17502 
17503 	DISSECTOR_ASSERT(si);
17504 
17505 	if (cmd != 0xff) {
17506 		proto_item *cmd_item;
17507 		proto_tree *cmd_tree;
17508 		int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
17509 
17510 		if (first_pdu) {
17511 			col_append_fstr(pinfo->cinfo, COL_INFO,
17512 				"%s %s",
17513 				val_to_str_ext(cmd, &smb_cmd_vals_ext, "Unknown (0x%02x)"),
17514 				(si->request)? "Request" : "Response");
17515 		} else {
17516 			col_append_fstr(pinfo->cinfo, COL_INFO,
17517 				"; %s",
17518 				val_to_str_ext(cmd, &smb_cmd_vals_ext, "Unknown (0x%02x)"));
17519 		}
17520 
17521 		cmd_tree = proto_tree_add_subtree_format(smb_tree, tvb, offset, -1,
17522 			ett_smb_command, &cmd_item, "%s %s (0x%02x)",
17523 			val_to_str_ext_const(cmd, &smb_cmd_vals_ext, "Unknown"),
17524 			(si->request)?"Request":"Response",
17525 			cmd);
17526 
17527 		/* we track FIDs on a per transaction basis.
17528 		   if this was a request and the fid was seen in a reply
17529 		   we add a "generated" fid tree for this pdu and v.v.
17530 		 */
17531 		sip = si->sip;
17532 		if (sip && sip->fid) {
17533 			if ( (si->request && (!sip->fid_seen_in_request))
17534 			     || ((!si->request) && sip->fid_seen_in_request) ) {
17535 				dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE, si);
17536 			}
17537 		}
17538 
17539 		dissector = (si->request) ?
17540 			smb_dissector[cmd].request : smb_dissector[cmd].response;
17541 
17542 		offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree, si);
17543 
17544 		if (!tvb_offset_exists(tvb, offset-1)) {
17545 			THROW(ReportedBoundsError);
17546 		}
17547 		proto_item_set_end(cmd_item, tvb, offset);
17548 	}
17549 	return offset;
17550 }
17551 
17552 static const value_string smb_cmd_vals[] = {
17553 	{ 0x00, "Create Directory" },
17554 	{ 0x01, "Delete Directory" },
17555 	{ 0x02, "Open" },
17556 	{ 0x03, "Create" },
17557 	{ 0x04, "Close" },
17558 	{ 0x05, "Flush" },
17559 	{ 0x06, "Delete" },
17560 	{ 0x07, "Rename" },
17561 	{ 0x08, "Query Information" },
17562 	{ 0x09, "Set Information" },
17563 	{ 0x0A, "Read" },
17564 	{ 0x0B, "Write" },
17565 	{ 0x0C, "Lock Byte Range" },
17566 	{ 0x0D, "Unlock Byte Range" },
17567 	{ 0x0E, "Create Temp" },
17568 	{ 0x0F, "Create New" },
17569 	{ 0x10, "Check Directory" },
17570 	{ 0x11, "Process Exit" },
17571 	{ 0x12, "Seek" },
17572 	{ 0x13, "Lock And Read" },
17573 	{ 0x14, "Write And Unlock" },
17574 	{ 0x15, "unknown-0x15" },
17575 	{ 0x16, "unknown-0x16" },
17576 	{ 0x17, "unknown-0x17" },
17577 	{ 0x18, "unknown-0x18" },
17578 	{ 0x19, "unknown-0x19" },
17579 	{ 0x1A, "Read Raw" },
17580 	{ 0x1B, "Read MPX" },
17581 	{ 0x1C, "Read MPX Secondary" },
17582 	{ 0x1D, "Write Raw" },
17583 	{ 0x1E, "Write MPX" },
17584 	{ 0x1F, "Write MPX Secondary" },
17585 	{ 0x20, "Write Complete" },
17586 
17587 	/*
17588 	 * To quote
17589 	 *
17590 	 *    http://msdn.microsoft.com/en-us/library/ee442098.aspx
17591 	 *
17592 	 * "This command was introduced in the NT LAN Manager dialect, and
17593 	 * was reserved but not implemented.
17594 	 *
17595 	 * Clients SHOULD NOT send requests using this command code, and
17596 	 * servers receiving requests with this command code SHOULD return
17597 	 * STATUS_NOT_IMPLEMENTED (ERRDOS/ERRbadfunc)."
17598 	 */
17599 	{ 0x21, "Query Server (reserved)" },
17600 
17601 	{ 0x22, "Set Information2" },
17602 	{ 0x23, "Query Information2" },
17603 	{ 0x24, "Locking AndX" },
17604 	{ 0x25, "Trans" },
17605 	{ 0x26, "Trans Secondary" },
17606 	{ 0x27, "IOCTL" },
17607 	{ 0x28, "IOCTL Secondary" },
17608 	{ 0x29, "Copy" },
17609 	{ 0x2A, "Move" },
17610 	{ 0x2B, "Echo" },
17611 	{ 0x2C, "Write And Close" },
17612 	{ 0x2D, "Open AndX" },
17613 	{ 0x2E, "Read AndX" },
17614 	{ 0x2F, "Write AndX" },
17615 
17616 	/*
17617 	 * To quote
17618 	 *
17619 	 *    http://msdn.microsoft.com/en-us/library/ee442127.aspx
17620 	 *
17621 	 * "This command was reserved but not implemented. It was also never
17622 	 * defined. It is listed in [SNIA], but it is not defined in that
17623 	 * document and does not appear in any other references.
17624 	 *
17625 	 * Clients SHOULD NOT send requests using this command code, and
17626 	 * servers receiving requests with this command code SHOULD return
17627 	 * STATUS_NOT_IMPLEMENTED (ERRDOC/ERRbadfunc)."
17628 	 */
17629 	{ 0x30, "New File Size (reserved)" },
17630 
17631 	{ 0x31, "Close And Tree Disconnect" },
17632 	{ 0x32, "Trans2" },
17633 	{ 0x33, "Trans2 Secondary" },
17634 	{ 0x34, "Find Close2" },
17635 	{ 0x35, "Find Notify Close" },
17636 	{ 0x70, "Tree Connect" },
17637 	{ 0x71, "Tree Disconnect" },
17638 	{ 0x72, "Negotiate Protocol" },
17639 	{ 0x73, "Session Setup AndX" },
17640 	{ 0x74, "Logoff AndX" },
17641 	{ 0x75, "Tree Connect AndX" },
17642 	{ 0x80, "Query Information Disk" },
17643 	{ 0x81, "Search" },
17644 	{ 0x82, "Find" },
17645 	{ 0x83, "Find Unique" },
17646 	{ 0x84, "Find Close" },
17647 	{ 0xA0, "NT Trans" },
17648 	{ 0xA1, "NT Trans Secondary" },
17649 	{ 0xA2, "NT Create AndX" },
17650 	{ 0xA3, "unknown-0xA3" },
17651 	{ 0xA4, "NT Cancel" },
17652 	{ 0xA5, "NT Rename" },
17653 	{ 0xC0, "Open Print File" },
17654 	{ 0xC1, "Write Print File" },
17655 	{ 0xC2, "Close Print File" },
17656 	{ 0xC3, "Get Print Queue" },
17657 	{ 0xD0, "Send Single Block Message" },
17658 	{ 0xD1, "Send Broadcast Message" },
17659 	{ 0xD2, "Forward User Name" },
17660 	{ 0xD3, "Cancel Forward" },
17661 	{ 0xD4, "Get Machine Name" },
17662 	{ 0xD5, "Send Start of Multi-block Message" },
17663 	{ 0xD6, "Send End of Multi-block Message" },
17664 	{ 0xD7, "Send Text of Multi-block Message" },
17665 	{ 0xD8, "SMBreadbulk" },
17666 	{ 0xD9, "SMBwritebulk" },
17667 	{ 0xDA, "SMBwritebulkdata" },
17668 	{ 0xFE, "SMBinvalid" },
17669 	{ 0x00, NULL },
17670 };
17671 value_string_ext smb_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb_cmd_vals);
17672 
17673 
17674 static void
free_hash_tables(gpointer ctarg,gpointer user_data _U_)17675 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
17676 {
17677 	conv_tables_t *ct = (conv_tables_t *)ctarg;
17678 
17679 	if (ct->unmatched)
17680 		g_hash_table_destroy(ct->unmatched);
17681 	if (ct->matched)
17682 		g_hash_table_destroy(ct->matched);
17683 	if (ct->primaries)
17684 		g_hash_table_destroy(ct->primaries);
17685 	if (ct->tid_service)
17686 		g_hash_table_destroy(ct->tid_service);
17687 	g_slist_free(ct->GSL_fid_info);
17688 	g_free(ct);
17689 }
17690 
17691 static void
smb_cleanup(void)17692 smb_cleanup(void)
17693 {
17694 	if (conv_tables) {
17695 		g_slist_foreach(conv_tables, free_hash_tables, NULL);
17696 		g_slist_free(conv_tables);
17697 		conv_tables = NULL;
17698 	}
17699 }
17700 
17701 static const value_string errcls_types[] = {
17702 	{ SMB_SUCCESS, "Success"},
17703 	{ SMB_ERRDOS,  "DOS Error"},
17704 	{ SMB_ERRSRV,  "Server Error"},
17705 	{ SMB_ERRHRD,  "Hardware Error"},
17706 	{ SMB_ERRCMD,  "Command Error - Not an SMB format command"},
17707 	{ 0, NULL }
17708 };
17709 
17710 /* Error codes for the ERRSRV class */
17711 
17712 #define SRV_errors_VALUE_STRING_LIST(XXX)				\
17713 	XXX( SMBE_SRV_error,          1, "Non specific error code")	\
17714 	XXX( SMBE_SRV_badpw,          2, "Bad password")		\
17715 	XXX( SMBE_SRV_badtype,        3, "Reserved")			\
17716 	XXX( SMBE_SRV_access,         4, "No permissions to perform the requested operation") \
17717 	XXX( SMBE_SRV_invnid,         5, "TID invalid")			\
17718 	XXX( SMBE_SRV_invnetname,     6, "Invalid network name. Service not found") \
17719 	XXX( SMBE_SRV_invdevice,      7, "Invalid device")		\
17720 	XXX( SMBE_SRV_unknownsmb,    22, "Unknown SMB, from NT 3.5 response") \
17721 	XXX( SMBE_SRV_qfull,         49, "Print queue full")		\
17722 	XXX( SMBE_SRV_qtoobig,       50, "Queued item too big")		\
17723 	XXX( SMBE_SRV_qeof,          51, "EOF in print queue dump")	\
17724 	XXX( SMBE_SRV_invpfid,       52, "Invalid print file in smb_fid") \
17725 	XXX( SMBE_SRV_smbcmd,        64, "Unrecognised command")	\
17726 	XXX( SMBE_SRV_srverror,      65, "SMB server internal error")	\
17727 	XXX( SMBE_SRV_filespecs,     67, "Fid and pathname invalid combination") \
17728 	XXX( SMBE_SRV_badlink,       68, "Bad link in request ???")	\
17729 	XXX( SMBE_SRV_badpermits,    69, "Access specified for a file is not valid") \
17730 	XXX( SMBE_SRV_badpid,        70, "Bad process id in request")	\
17731 	XXX( SMBE_SRV_setattrmode,   71, "Attribute mode invalid")	\
17732 	XXX( SMBE_SRV_paused,        81, "Message server paused")	\
17733 	XXX( SMBE_SRV_msgoff,        82, "Not receiving messages")	\
17734 	XXX( SMBE_SRV_noroom,        83, "No room for message")		\
17735 	XXX( SMBE_SRV_rmuns,         87, "Too many remote usernames")	\
17736 	XXX( SMBE_SRV_timeout,       88, "Operation timed out")		\
17737 	XXX( SMBE_SRV_noresource,    89, "No resources currently available for request.") \
17738 	XXX( SMBE_SRV_toomanyuids,   90, "Too many userids")		\
17739 	XXX( SMBE_SRV_baduid,        91, "Bad userid")			\
17740 	XXX( SMBE_SRV_useMPX,       250, "Temporarily unable to use raw mode, use MPX mode") \
17741 	XXX( SMBE_SRV_useSTD,       251, "Temporarily unable to use raw mode, use standard mode") \
17742 	XXX( SMBE_SRV_contMPX,      252, "Resume MPX mode")		\
17743 	XXX( SMBE_SRV_badPW,        253, "Bad Password???")		\
17744 	XXX( SMBE_SRV_nosupport, 0xFFFF, "Operation not supported")
17745 
17746 #if 0 /* Values not needed */
17747 VALUE_STRING_ENUM(SRV_errors);
17748 #endif
17749 VALUE_STRING_ARRAY(SRV_errors);
17750 static value_string_ext SRV_errors_ext = VALUE_STRING_EXT_INIT(SRV_errors);
17751 
17752 
17753 /* Error codes for the ERRHRD class */
17754 
17755 #define HRD_errors_VALUE_STRING_LIST(XXX)				\
17756 	XXX( SMBE_HRD_nowrite,     19, "Read only media")		\
17757 	XXX( SMBE_HRD_badunit,     20, "Unknown device")		\
17758 	XXX( SMBE_HRD_notready,    21, "Drive not ready")		\
17759 	XXX( SMBE_HRD_badcmd,      22, "Unknown command")		\
17760 	XXX( SMBE_HRD_data,        23, "Data (CRC) error")		\
17761 	XXX( SMBE_HRD_badreq,      24, "Bad request structure length")	\
17762 	XXX( SMBE_HRD_seek,        25, "Seek error")			\
17763 	XXX( SMBE_HRD_badmedia,    26, "Unknown media type")		\
17764 	XXX( SMBE_HRD_badsector,   27, "Sector not found")		\
17765 	XXX( SMBE_HRD_nopaper,     28, "Printer out of paper")		\
17766 	XXX( SMBE_HRD_write,       29, "Write fault")			\
17767 	XXX( SMBE_HRD_read,        30, "Read fault")			\
17768 	XXX( SMBE_HRD_general,     31, "General failure")		\
17769 	/* -- (really part of ERRDOS class ??) -- */			\
17770 	XXX( SMBE_HRD_badshare,    32, "An open conflicts with an existing open") \
17771 	XXX( SMBE_HRD_lock,        33, "Lock conflict/invalid mode, or unlock of another process's lock") \
17772 	/* -- --*/							\
17773 	XXX( SMBE_HRD_wrongdisk,   34, "The wrong disk was found in a drive") \
17774 	XXX( SMBE_HRD_FCBunavail,  35, "No FCBs are available to process request") \
17775 	XXX( SMBE_HRD_sharebufexc, 36, "A sharing buffer has been exceeded") \
17776 	XXX( SMBE_HRD_diskfull,    39, "Disk full???")
17777 
17778 #if 0 /* Values not needed */
17779 VALUE_STRING_ENUM(HRD_errors);
17780 #endif
17781 VALUE_STRING_ARRAY(HRD_errors);
17782 static value_string_ext HRD_errors_ext = VALUE_STRING_EXT_INIT(HRD_errors);
17783 
decode_smb_error(guint8 errcls,guint16 errcode)17784 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
17785 {
17786 
17787 	switch (errcls) {
17788 
17789 	case SMB_SUCCESS:
17790 
17791 		return("No Error");   /* No error ??? */
17792 
17793 	case SMB_ERRDOS:
17794 
17795 		return(val_to_str_ext(errcode, &DOS_errors_ext, "Unknown DOS error (%x)"));
17796 
17797 	case SMB_ERRSRV:
17798 
17799 		return(val_to_str_ext(errcode, &SRV_errors_ext, "Unknown SRV error (%x)"));
17800 
17801 	case SMB_ERRHRD:
17802 
17803 		return(val_to_str_ext(errcode, &HRD_errors_ext, "Unknown HRD error (%x)"));
17804 
17805 	default:
17806 
17807 		return("Unknown error class!");
17808 
17809 	}
17810 
17811 }
17812 
17813 static const true_false_string tfs_smb_flags_lock = {
17814 	"Lock&Read, Write&Unlock are supported",
17815 	"Lock&Read, Write&Unlock are not supported"
17816 };
17817 static const true_false_string tfs_smb_flags_receive_buffer = {
17818 	"Receive buffer has been posted",
17819 	"Receive buffer has not been posted"
17820 };
17821 static const true_false_string tfs_smb_flags_caseless = {
17822 	"Path names are caseless",
17823 	"Path names are case sensitive"
17824 };
17825 static const true_false_string tfs_smb_flags_canon = {
17826 	"Pathnames are canonicalized",
17827 	"Pathnames are not canonicalized"
17828 };
17829 static const true_false_string tfs_smb_flags_oplock = {
17830 	"OpLock requested/granted",
17831 	"OpLock not requested/granted"
17832 };
17833 static const true_false_string tfs_smb_flags_notify = {
17834 	"Notify client on all modifications",
17835 	"Notify client only on open"
17836 };
17837 static const true_false_string tfs_smb_flags_response = {
17838 	"Message is a response to the client/redirector",
17839 	"Message is a request to the server"
17840 };
17841 
17842 static int
dissect_smb_flags(tvbuff_t * tvb,proto_tree * parent_tree,int offset)17843 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
17844 {
17845 	static int * const flags[] = {
17846 		&hf_smb_flags_response,
17847 		&hf_smb_flags_notify,
17848 		&hf_smb_flags_oplock,
17849 		&hf_smb_flags_canon,
17850 		&hf_smb_flags_caseless,
17851 		&hf_smb_flags_receive_buffer,
17852 		&hf_smb_flags_lock,
17853 		NULL
17854 	};
17855 
17856 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_flags, ett_smb_flags, flags, ENC_NA);
17857 	offset += 1;
17858 
17859 	return offset;
17860 }
17861 
17862 
17863 
17864 static const true_false_string tfs_smb_flags2_long_names_allowed = {
17865 	"Long file names are allowed in the response",
17866 	"Long file names are not allowed in the response"
17867 };
17868 static const true_false_string tfs_smb_flags2_ea = {
17869 	"Extended attributes are supported",
17870 	"Extended attributes are not supported"
17871 };
17872 static const true_false_string tfs_smb_flags2_sec_sig = {
17873 	"Security signatures are supported",
17874 	"Security signatures are not supported"
17875 };
17876 static const true_false_string tfs_smb_flags2_compressed = {
17877 	"Compression is requested",
17878 	"Compression is not requested"
17879 };
17880 static const true_false_string tfs_smb_flags2_sec_sig_required = {
17881 	"Security signatures are required",
17882 	"Security signatures are not required"
17883 };
17884 static const true_false_string tfs_smb_flags2_long_names_used = {
17885 	"Path names in request are long file names",
17886 	"Path names in request are not long file names"
17887 };
17888 static const true_false_string tfs_smb_flags2_reparse_path = {
17889 	"The request uses a @GMT reparse path",
17890 	"The request does not use a @GMT reparse path"
17891 };
17892 static const true_false_string tfs_smb_flags2_esn = {
17893 	"Extended security negotiation is supported",
17894 	"Extended security negotiation is not supported"
17895 };
17896 static const true_false_string tfs_smb_flags2_dfs = {
17897 	"Resolve pathnames with Dfs",
17898 	"Don't resolve pathnames with Dfs"
17899 };
17900 static const true_false_string tfs_smb_flags2_roe = {
17901 	"Permit reads if execute-only",
17902 	"Don't permit reads if execute-only"
17903 };
17904 static const true_false_string tfs_smb_flags2_nt_error = {
17905 	"Error codes are NT error codes",
17906 	"Error codes are DOS error codes"
17907 };
17908 static const true_false_string tfs_smb_flags2_string = {
17909 	"Strings are Unicode",
17910 	"Strings are ASCII"
17911 };
17912 static int
dissect_smb_flags2(tvbuff_t * tvb,proto_tree * parent_tree,int offset)17913 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
17914 {
17915 	static int * const flags[] = {
17916 		&hf_smb_flags2_string,
17917 		&hf_smb_flags2_nt_error,
17918 		&hf_smb_flags2_roe,
17919 		&hf_smb_flags2_dfs,
17920 		&hf_smb_flags2_esn,
17921 		&hf_smb_flags2_reparse_path,
17922 		&hf_smb_flags2_long_names_used,
17923 		&hf_smb_flags2_sec_sig_required,
17924 		&hf_smb_flags2_compressed,
17925 		&hf_smb_flags2_sec_sig,
17926 		&hf_smb_flags2_ea,
17927 		&hf_smb_flags2_long_names_allowed,
17928 		NULL
17929 	};
17930 
17931 	proto_tree_add_bitmask(parent_tree, tvb, offset, hf_smb_flags2, ett_smb_flags2, flags, ENC_LITTLE_ENDIAN);
17932 	offset += 2;
17933 
17934 	return offset;
17935 }
17936 
17937 
17938 
17939 #define SMB_FLAGS_DIRN 0x80
17940 
17941 
17942 static int
dissect_smb(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)17943 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
17944 {
17945 	int                   offset   = 0;
17946 	proto_item           *item;
17947 	proto_tree           *tree, *htree;
17948 	proto_item           *tmp_item = NULL;
17949 	guint8                flags;
17950 	guint16               flags2;
17951 	smb_info_t 	     *si;
17952 	smb_saved_info_t     *sip      = NULL;
17953 	smb_saved_info_key_t  key;
17954 	smb_saved_info_key_t *new_key;
17955 	guint8                errclass = 0;
17956 	guint16               errcode  = 0;
17957 	guint32               pid_mid;
17958 	conversation_t       *conversation;
17959 	nstime_t              t, deltat;
17960 
17961 	si = wmem_new0(wmem_packet_scope(), smb_info_t);
17962 
17963 	top_tree_global = parent_tree;
17964 
17965 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
17966 	col_clear(pinfo->cinfo, COL_INFO);
17967 
17968 	/* start off using the local variable, we will allocate a new one if we
17969 	   need to*/
17970 	si->cmd = tvb_get_guint8(tvb, offset+4);
17971 	flags = tvb_get_guint8(tvb, offset+9);
17972 	/*
17973 	 * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
17974 	 * the direction flag appears never to be set, even for what appear
17975 	 * to be replies.  Do some SMB servers fail to set that flag,
17976 	 * under the assumption that the client knows it's a reply because
17977 	 * it received it?
17978 	 */
17979 	si->request = !(flags&SMB_FLAGS_DIRN);
17980 	flags2 = tvb_get_letohs(tvb, offset+10);
17981 	if (flags2 & 0x8000) {
17982 		si->unicode = TRUE; /* Mark them as Unicode */
17983 	} else {
17984 		si->unicode = FALSE;
17985 	}
17986 	si->tid = tvb_get_letohs(tvb, offset+24);
17987 	si->pid = tvb_get_letohs(tvb, offset+26);
17988 	si->uid = tvb_get_letohs(tvb, offset+28);
17989 	si->mid = tvb_get_letohs(tvb, offset+30);
17990 	pid_mid = (si->pid << 16) | si->mid;
17991 	si->info_level = -1;
17992 	si->info_count = -1;
17993 
17994 	item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
17995 			-1, ENC_NA);
17996 	tree = proto_item_add_subtree(item, ett_smb);
17997 
17998 	htree = proto_tree_add_subtree(tree, tvb, offset, 32,
17999 			ett_smb_hdr, NULL, "SMB Header");
18000 
18001 
18002 	proto_tree_add_uint_format_value(htree, hf_smb_server_component, tvb, offset, 4, tvb_get_letohl(tvb, offset), "SMB");
18003 	offset += 4;  /* Skip the marker */
18004 
18005 	/* find which conversation we are part of and get the tables for that
18006 	   conversation*/
18007 	conversation = find_or_create_conversation(pinfo);
18008 	/* see if we already have the smb data for this conversation */
18009 	si->ct = (conv_tables_t *)conversation_get_proto_data(conversation, proto_smb);
18010 	if (!si->ct) {
18011 		/* No, not yet. create it and attach it to the conversation */
18012 		si->ct = g_new(conv_tables_t, 1);
18013 
18014 		conv_tables = g_slist_prepend(conv_tables, si->ct);
18015 		si->ct->matched = g_hash_table_new(smb_saved_info_hash_matched,
18016 			smb_saved_info_equal_matched);
18017 		si->ct->unmatched = g_hash_table_new(smb_saved_info_hash_unmatched,
18018 			smb_saved_info_equal_unmatched);
18019 		/* We used the same key format as the unmatched entries */
18020 		si->ct->primaries = g_hash_table_new(
18021 			smb_saved_info_hash_unmatched,
18022 			smb_saved_info_equal_unmatched);
18023 		si->ct->tid_service = g_hash_table_new(
18024 			smb_saved_info_hash_unmatched,
18025 			smb_saved_info_equal_unmatched);
18026 		si->ct->raw_ntlmssp = 0;
18027 
18028 		si->ct->fid_tree = wmem_tree_new(wmem_file_scope());
18029 		si->ct->tid_tree = wmem_tree_new(wmem_file_scope());
18030 		si->ct->uid_tree = wmem_tree_new(wmem_file_scope());
18031 		/* Initialize the GSL_fid_info for this ct */
18032 		si->ct->GSL_fid_info = NULL;
18033 		conversation_add_proto_data(conversation, proto_smb, si->ct);
18034 	}
18035 
18036 	if ( (si->request)
18037 	    &&  (si->mid == 0)
18038 	    &&  (si->uid == 0)
18039 	    &&  (si->pid == 0)
18040 	    &&  (si->tid == 0) ) {
18041 		/* this is a broadcast SMB packet, there will not be a reply.
18042 		   We don't need to do anything
18043 		*/
18044 		si->unidir = TRUE;
18045 	} else if ( (si->cmd == SMB_COM_NT_CANCEL)                  /* NT Cancel */
18046 		   || (si->cmd == SMB_COM_TRANSACTION_SECONDARY)    /* Transaction Secondary */
18047 		   || (si->cmd == SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
18048 		   || (si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)) { /* NT Transaction Secondary */
18049 		/* Ok, we got a special request type. This request is either
18050 		   an NT Cancel or a continuation relative to a real request
18051 		   in an earlier packet.  In either case, we don't expect any
18052 		   responses to this packet.  For continuations, any later
18053 		   responses we see really just belong to the original request.
18054 		   Anyway, we want to remember this packet somehow and
18055 		   remember which original request it is associated with so
18056 		   we can say nice things such as "This is a Cancellation to
18057 		   the request in frame x", but we don't want the
18058 		   request/response matching to get messed up.
18059 
18060 		   The only thing we do in this case is trying to find which original
18061 		   request we match with and insert an entry for this "special"
18062 		   request for later reference. We continue to reference the original
18063 		   requests smb_saved_info_t but we don't touch it or change anything
18064 		   in it.
18065 		*/
18066 
18067 		si->unidir = TRUE;  /*we don't expect an answer to this one*/
18068 
18069 		if (!pinfo->fd->visited) {
18070 			/* try to find which original call we match and if we
18071 			   find it add us to the matched table. Don't touch
18072 			   anything else since we don't want this one to mess
18073 			   up the request/response matching. We still consider
18074 			   the initial call the real request and this is only
18075 			   some sort of continuation.
18076 			*/
18077 			/* we only check the unmatched table and assume that the
18078 			   last seen MID matching ours is the right one.
18079 			   This can fail but is better than nothing
18080 			*/
18081 			sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
18082 			if (sip != NULL) {
18083 				new_key = wmem_new(wmem_file_scope(), smb_saved_info_key_t);
18084 				new_key->frame = pinfo->num;
18085 				new_key->pid_mid = pid_mid;
18086 				g_hash_table_insert(si->ct->matched, new_key,
18087 				    sip);
18088 			} else {
18089 				if ((si->cmd == SMB_COM_TRANSACTION_SECONDARY)  ||
18090 				    (si->cmd == SMB_COM_TRANSACTION2_SECONDARY) ||
18091 				    (si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)) {
18092 					sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
18093 				}
18094 			}
18095 		} else {
18096 			/* we have seen this packet before; check the
18097 			   matching table
18098 			*/
18099 			key.frame = pinfo->num;
18100 			key.pid_mid = pid_mid;
18101 			sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->matched, &key);
18102 			if (sip == NULL) {
18103 			/*
18104 			  We didn't find it.
18105 			  Too bad, unfortunately there is not really much we can
18106 			  do now since this means that we never saw the initial
18107 			  request.
18108 			 */
18109 			}
18110 		}
18111 
18112 
18113 		if (sip && sip->frame_req) {
18114 			switch(si->cmd) {
18115 			case SMB_COM_NT_CANCEL:
18116 				tmp_item = proto_tree_add_uint(htree, hf_smb_cancel_to,
18117 						    tvb, 0, 0, sip->frame_req);
18118 				proto_item_set_generated(tmp_item);
18119 				break;
18120 			case SMB_COM_TRANSACTION_SECONDARY:
18121 			case SMB_COM_TRANSACTION2_SECONDARY:
18122 			case SMB_COM_NT_TRANSACT_SECONDARY:
18123 				tmp_item = proto_tree_add_uint(htree, hf_smb_continuation_to,
18124 						    tvb, 0, 0, sip->frame_req);
18125 				proto_item_set_generated(tmp_item);
18126 				break;
18127 			}
18128 		} else {
18129 			switch(si->cmd) {
18130 			case SMB_COM_NT_CANCEL:
18131 				proto_tree_add_uint_format_value(htree, hf_smb_cancel_to, tvb, 0, 0, 0, "<unknown frame>");
18132 				break;
18133 			case SMB_COM_TRANSACTION_SECONDARY:
18134 			case SMB_COM_TRANSACTION2_SECONDARY:
18135 			case SMB_COM_NT_TRANSACT_SECONDARY:
18136 				proto_tree_add_uint_format_value(htree, hf_smb_continuation_to, tvb, 0, 0, 0, "<unknown frame>");
18137 				break;
18138 			}
18139 		}
18140 	} else { /* normal bidirectional request or response */
18141 		si->unidir = FALSE;
18142 
18143 		if (!pinfo->fd->visited) {
18144 			/* first see if we find an unmatched smb "equal" to
18145 			   the current one
18146 			*/
18147 			sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
18148 			if (sip != NULL) {
18149 				gboolean cmd_match = FALSE;
18150 
18151 				/*
18152 				 * Make sure the SMB we found was the
18153 				 * same command, or a different command
18154 				 * that's another valid type of reply
18155 				 * to that command.
18156 				 */
18157 				if (si->cmd == sip->cmd) {
18158 					cmd_match = TRUE;
18159 				}
18160 				else if (si->cmd == SMB_COM_NT_CANCEL) {
18161 					cmd_match = TRUE;
18162 				}
18163 				else if ((si->cmd == SMB_COM_TRANSACTION_SECONDARY)
18164 				     && (sip->cmd == SMB_COM_TRANSACTION)) {
18165 					cmd_match = TRUE;
18166 				}
18167 				else if ((si->cmd == SMB_COM_TRANSACTION2_SECONDARY)
18168 				     && (sip->cmd == SMB_COM_TRANSACTION2)) {
18169 					cmd_match = TRUE;
18170 				}
18171 				else if ((si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)
18172 				     && (sip->cmd == SMB_COM_NT_TRANSACT)) {
18173 					cmd_match = TRUE;
18174 				}
18175 
18176 				if ( (si->request) || (!cmd_match) ) {
18177 					/* We are processing an SMB request but there was already
18178 					   another "identical" smb request we had not matched yet.
18179 					   This must mean that either we have a retransmission or that the
18180 					   response to the previous one was lost and the client has reused
18181 					   the MID for this conversation. In either case it's not much more
18182 					   we can do than forget the old request and concentrate on the
18183 					   present one instead.
18184 
18185 					   We also do this cleanup if we see that the cmd in the original
18186 					   request in sip->cmd is not compatible with the current cmd.
18187 					   This is to prevent matching errors such as if there were two
18188 					   SMBs of different cmds but with identical MID and PID values and
18189 					   if wireshark lost the first reply and the second request.
18190 					*/
18191 					g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
18192 					sip = NULL; /* XXX should free it as well */
18193 				} else {
18194 					/* we have found a response to some
18195 					   request we have seen earlier.
18196 					   What we do now depends on whether
18197 					   this is the first response to that
18198 					   request we see (id frame_res == 0) or
18199 					   if it's a response to a request
18200 					   for which we've seen an earlier
18201 					   response that's continued.
18202 					*/
18203 					if ((sip->frame_res == 0) ||
18204 					    (sip->flags & SMB_SIF_IS_CONTINUED)) {
18205 						/* OK, it is the first response
18206 						   we have seen to this packet,
18207 						   or it's a continuation of
18208 						   a response we've seen. */
18209 						sip->frame_res = pinfo->num;
18210 						new_key = wmem_new(wmem_file_scope(), smb_saved_info_key_t);
18211 						new_key->frame = sip->frame_res;
18212 						new_key->pid_mid = pid_mid;
18213 						g_hash_table_insert(si->ct->matched, new_key, sip);
18214 						/* We remove the entry for unmatched since we have found a match.
18215 						 * We have to do this since the MID value wraps so quickly (effective only 10 bits)
18216 						 * and if there is packetloss in the trace (maybe due to large holes
18217 						 * created by a sniffer device not being able to keep up
18218 						 * with the line rate.
18219 						 * There is a real possibility that the following would occur which is painful :
18220 						 * 1, -> Request  MID:5
18221 						 * 2, <- Response MID:5
18222 						 * 3, -> Request  MID:5 (missing from capture)
18223 						 * 4, <- Response MID:5
18224 						 * We DON'T want #4 to be presented as a response to #1
18225 						 */
18226 						g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
18227 					} else {
18228 						/* We have already seen another response to this MID.
18229 						   Since the MID in reality is only something like 10 bits
18230 						   this probably means that we just have a MID that is being
18231 						   reused due to the small MID space and that this is a new
18232 						   command we did not see the original request for.
18233 						*/
18234 						sip = NULL;
18235 					}
18236 				}
18237 			} else {
18238 				if ((si->cmd == SMB_COM_TRANSACTION)  ||
18239 				    (si->cmd == SMB_COM_TRANSACTION2) ||
18240 				    (si->cmd == SMB_COM_NT_TRANSACT)) {
18241 					sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
18242 				}
18243 			}
18244 			if (si->request) {
18245 				sip = wmem_new(wmem_file_scope(), smb_saved_info_t);
18246 				sip->frame_req = pinfo->num;
18247 				sip->frame_res = 0;
18248 				sip->req_time = pinfo->abs_ts;
18249 				sip->flags = 0;
18250 				if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
18251 				    == (void *)TID_IPC) {
18252 					sip->flags |= SMB_SIF_TID_IS_IPC;
18253 				}
18254 				sip->cmd = si->cmd;
18255 				sip->extra_info = NULL;
18256 				sip->extra_info_type = SMB_EI_NONE;
18257 				sip->fid = 0;
18258 				sip->fid_seen_in_request = 0;
18259 				g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
18260 				new_key = wmem_new(wmem_file_scope(), smb_saved_info_key_t);
18261 				new_key->frame = sip->frame_req;
18262 				new_key->pid_mid = pid_mid;
18263 				g_hash_table_insert(si->ct->matched, new_key, sip);
18264 
18265 				/* If it is a TRANSACT cmd, insert in hash */
18266 				if ((si->cmd == SMB_COM_TRANSACTION)  ||
18267 				    (si->cmd == SMB_COM_TRANSACTION2) ||
18268 				    (si->cmd == SMB_COM_NT_TRANSACT)) {
18269 					g_hash_table_insert(si->ct->primaries, GUINT_TO_POINTER(pid_mid), sip);
18270 				}
18271 			}
18272 		} else {
18273 			/* we have seen this packet before; check the
18274 			   matching table.
18275 			   If we haven't yet seen the reply, we won't
18276 			   find the info for it; we don't need it, as
18277 			   we only use it to save information, and, as
18278 			   we've seen this packet before, we've already
18279 			   saved the information.
18280 			*/
18281 			key.frame = pinfo->num;
18282 			key.pid_mid = pid_mid;
18283 			sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->matched, &key);
18284 		}
18285 	}
18286 
18287 	/*
18288 	 * Pass the "sip" on to subdissectors through "si".
18289 	 */
18290 	si->sip = sip;
18291 
18292 	if (sip != NULL) {
18293 		/*
18294 		 * Put in fields for the frame number of the frame to which
18295 		 * this is a response or the frame with the response to this
18296 		 * frame - if we know the frame number (i.e., it's not 0).
18297 		 */
18298 		if (si->request) {
18299 			if (sip->frame_res != 0) {
18300 				tmp_item = proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
18301 				proto_item_set_generated(tmp_item);
18302 			}
18303 		} else {
18304 			if (sip->frame_req != 0) {
18305 				tmp_item = proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
18306 				proto_item_set_generated(tmp_item);
18307 				t = pinfo->abs_ts;
18308 				nstime_delta(&deltat, &t, &sip->req_time);
18309 				tmp_item = proto_tree_add_time(htree, hf_smb_time, tvb,
18310 				    0, 0, &deltat);
18311 				proto_item_set_generated(tmp_item);
18312 			}
18313 		}
18314 	}
18315 
18316 	/* smb command */
18317 	proto_tree_add_uint(htree, hf_smb_cmd, tvb, offset, 1, si->cmd);
18318 	offset += 1;
18319 
18320 	if (flags2 & 0x4000) {
18321 		/* handle NT 32 bit error code */
18322 
18323 		si->nt_status = tvb_get_letohl(tvb, offset);
18324 
18325 		proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
18326 			ENC_LITTLE_ENDIAN);
18327 		offset += 4;
18328 
18329 	} else {
18330 		/* handle DOS error code & class */
18331 		errclass = tvb_get_guint8(tvb, offset);
18332 		proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
18333 			errclass);
18334 		offset += 1;
18335 
18336 		/* reserved byte */
18337 		proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
18338 		offset += 1;
18339 
18340 		/* error code */
18341 		/* XXX - the type of this field depends on the value of
18342 		 * "errcls", so there is isn't a single value_string array
18343 		 * fo it, so there can't be a single field for it.
18344 		 */
18345 		errcode = tvb_get_letohs(tvb, offset);
18346 		proto_tree_add_uint_format_value(htree, hf_smb_error_code, tvb,
18347 			offset, 2, errcode, "%s",
18348 			decode_smb_error(errclass, errcode));
18349 		offset += 2;
18350 	}
18351 
18352 	/* flags */
18353 	offset = dissect_smb_flags(tvb, htree, offset);
18354 
18355 	/* flags2 */
18356 	offset = dissect_smb_flags2(tvb, htree, offset);
18357 
18358 	/*
18359 	 * The document at
18360 	 *
18361 	 *	http://www.samba.org/samba/ftp/specs/smbpub.txt
18362 	 *
18363 	 * (a text version of "Microsoft Networks SMB FILE SHARING
18364 	 * PROTOCOL, Document Version 6.0p") says that:
18365 	 *
18366 	 *	the first 2 bytes of these 12 bytes are, for NT Create and X,
18367 	 *	the "High Part of PID";
18368 	 *
18369 	 *	the next four bytes are reserved;
18370 	 *
18371 	 *	the next four bytes are, for SMB-over-IPX (with no
18372 	 *	NetBIOS involved) two bytes of Session ID and two bytes
18373 	 *	of SequenceNumber.
18374 	 *
18375 	 * Network Monitor 2.x dissects the four bytes before the Session ID
18376 	 * as a "Key", and the two bytes after the SequenceNumber as
18377 	 * a "Group ID".
18378 	 *
18379 	 * The "High Part of PID" has been seen in calls other than NT
18380 	 * Create and X, although most of them appear to be I/O on DCE RPC
18381 	 * pipes opened with the NT Create and X in question.
18382 	 */
18383 	proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, ENC_LITTLE_ENDIAN);
18384 	offset += 2;
18385 
18386 	if ((pinfo->ptype == PT_IPX) &&
18387 	    ((pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_SERVER) ||
18388 	     (pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_REDIR)  ||
18389 	     (pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_MESSENGER))) {
18390 		/*
18391 		 * This is SMB-over-IPX.
18392 		 * XXX - do we have to worry about "sequenced commands",
18393 		 * as per the Samba document?  They say that for
18394 		 * "unsequenced commands" (with a sequence number of 0),
18395 		 * the Mid must be unique, but perhaps the Mid doesn't
18396 		 * have to be unique for sequenced commands.  In at least
18397 		 * one capture with SMB-over-IPX, however, the Mids
18398 		 * are unique even for sequenced commands.
18399 		 */
18400 		/* Key */
18401 		proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
18402 		    ENC_LITTLE_ENDIAN);
18403 		offset += 4;
18404 
18405 		/* Session ID */
18406 		proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
18407 		    ENC_LITTLE_ENDIAN);
18408 		offset += 2;
18409 
18410 		/* Sequence number */
18411 		proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
18412 		    ENC_LITTLE_ENDIAN);
18413 		offset += 2;
18414 
18415 		/* Group ID */
18416 		proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
18417 		    ENC_LITTLE_ENDIAN);
18418 		offset += 2;
18419 	} else {
18420 		/*
18421 		 * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
18422 		 * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
18423 		 * bytes after the "High part of PID" are an 8-byte
18424 		 * signature ...
18425 		 */
18426 		proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, ENC_NA);
18427 		offset += 8;
18428 
18429 		proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
18430 		offset += 2;
18431 	}
18432 
18433 	/* TID
18434 	 * TreeConnectAndX(0x75) is special, here it is the mere fact of
18435 	 * having a response that means that the share was mapped and we
18436 	 * need to track it
18437 	 */
18438 	if (!pinfo->fd->visited && (si->cmd == 0x75) && !si->request) {
18439 		offset = dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE, si);
18440 	} else {
18441 		offset = dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE, si);
18442 	}
18443 
18444 	/* PID */
18445 	proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
18446 	offset += 2;
18447 
18448 	/* UID */
18449 	offset = dissect_smb_uid(tvb, htree, offset, si);
18450 
18451 	/* MID */
18452 	proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
18453 	offset += 2;
18454 
18455 	/* tap the packet before the dissectors are called so we still get
18456 	   the tap listener called even if there is an exception.
18457 	*/
18458 	tap_queue_packet(smb_tap, pinfo, si);
18459 	dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE, si);
18460 
18461 	/* Append error info from this packet to info string. */
18462 	if (!si->request) {
18463 		if (flags2 & 0x4000) {
18464 			/*
18465 			 * The status is an NT status code; was there
18466 			 * an error?
18467 			 */
18468 			if ((si->nt_status & 0xC0000000) == 0xC0000000) {
18469 				/*
18470 				 * Yes.
18471 				 */
18472 				col_append_fstr(
18473 					pinfo->cinfo, COL_INFO, ", Error: %s",
18474 					val_to_str_ext(si->nt_status, &NT_errors_ext,
18475 					    "Unknown (0x%08X)"));
18476 			}
18477 		} else {
18478 			/*
18479 			 * The status is a DOS error class and code; was
18480 			 * there an error?
18481 			 */
18482 			if (errclass != SMB_SUCCESS) {
18483 				/*
18484 				 * Yes.
18485 				 */
18486 				col_append_fstr(
18487 					pinfo->cinfo, COL_INFO, ", Error: %s",
18488 					decode_smb_error(errclass, errcode));
18489 			}
18490 		}
18491 	}
18492 	return tvb_captured_length(tvb);
18493 }
18494 
18495 static gboolean
dissect_smb_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * parent_tree,void * data _U_)18496 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
18497 {
18498 	/* must check that this really is a smb packet */
18499 	if (tvb_reported_length(tvb) < 4)
18500 		return FALSE;
18501 
18502 	if ( (tvb_get_guint8(tvb, 0) != 0xff)
18503 	    || (tvb_get_guint8(tvb, 1) != 'S')
18504 	    || (tvb_get_guint8(tvb, 2) != 'M')
18505 	    || (tvb_get_guint8(tvb, 3) != 'B') ) {
18506 		return FALSE;
18507 	}
18508 
18509 	dissect_smb(tvb, pinfo, parent_tree, data);
18510 	return TRUE;
18511 }
18512 
18513 void
proto_register_smb(void)18514 proto_register_smb(void)
18515 {
18516 	static hf_register_info hf[] = {
18517 	{ &hf_smb_cmd,
18518 		{ "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
18519 		&smb_cmd_vals_ext, 0x0, NULL, HFILL }},
18520 
18521 	{ &hf_smb_andxcmd,
18522 		{ "AndXCommand", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
18523 		&smb_cmd_vals_ext, 0x0, NULL, HFILL }},
18524 
18525 	{ &hf_smb_trans2_subcmd,
18526 		{ "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
18527 		&trans2_cmd_vals_ext, 0, "Subcommand for TRANSACTION2", HFILL }},
18528 
18529 	{ &hf_smb_nt_trans_subcmd,
18530 		{ "Function", "smb.nt.function", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
18531 		&nt_cmd_vals_ext, 0, "Function for NT Transaction", HFILL }},
18532 
18533 	{ &hf_smb_word_count,
18534 		{ "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
18535 		NULL, 0x0, "Word Count, count of parameter words", HFILL }},
18536 
18537 	{ &hf_smb_byte_count,
18538 		{ "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
18539 		NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
18540 
18541 	{ &hf_smb_response_to,
18542 		{ "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
18543 		NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
18544 
18545 	{ &hf_smb_time,
18546 		{ "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
18547 		NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
18548 
18549 	{ &hf_smb_response_in,
18550 		{ "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
18551 		NULL, 0, "The response to this packet is in this packet", HFILL }},
18552 
18553 	{ &hf_smb_continuation_to,
18554 		{ "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
18555 		NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
18556 
18557 	{ &hf_smb_nt_status,
18558 		{ "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
18559 		&NT_errors_ext, 0, "NT Status code", HFILL }},
18560 
18561 	{ &hf_smb_error_class,
18562 		{ "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
18563 		VALS(errcls_types), 0, "DOS Error Class", HFILL }},
18564 
18565 	{ &hf_smb_error_code,
18566 		{ "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
18567 		NULL, 0, "DOS Error Code", HFILL }},
18568 
18569 	{ &hf_smb_reserved,
18570 		{ "Reserved", "smb.reserved", FT_BYTES, BASE_NONE,
18571 		NULL, 0, "Reserved bytes, must be zero", HFILL }},
18572 
18573 	{ &hf_smb_sig,
18574 		{ "Signature", "smb.signature", FT_BYTES, BASE_NONE,
18575 		NULL, 0, "Signature bytes", HFILL }},
18576 
18577 	{ &hf_smb_key,
18578 		{ "Key", "smb.key", FT_UINT32, BASE_HEX,
18579 		NULL, 0, "SMB-over-IPX Key", HFILL }},
18580 
18581 	{ &hf_smb_session_id,
18582 		{ "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
18583 		NULL, 0, "SMB-over-IPX Session ID", HFILL }},
18584 
18585 	{ &hf_smb_sequence_num,
18586 		{ "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
18587 		NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
18588 
18589 	{ &hf_smb_group_id,
18590 		{ "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
18591 		NULL, 0, "SMB-over-IPX Group ID", HFILL }},
18592 
18593 	{ &hf_smb_pid,
18594 		{ "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
18595 		NULL, 0, NULL, HFILL }},
18596 
18597 	{ &hf_smb_pid_high,
18598 		{ "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
18599 		NULL, 0, "Process ID High Bytes", HFILL }},
18600 
18601 	{ &hf_smb_tid,
18602 		{ "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
18603 		NULL, 0, NULL, HFILL }},
18604 
18605 	{ &hf_smb_uid,
18606 		{ "User ID", "smb.uid", FT_UINT16, BASE_DEC,
18607 		NULL, 0, NULL, HFILL }},
18608 
18609 	{ &hf_smb_mid,
18610 		{ "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
18611 		NULL, 0, NULL, HFILL }},
18612 
18613 	{ &hf_smb_flags,
18614 		{ "Flags", "smb.flags", FT_UINT8, BASE_HEX,
18615 		NULL, 0x0, NULL, HFILL }},
18616 
18617 	{ &hf_smb_flags_lock,
18618 		{ "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
18619 		TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
18620 
18621 	{ &hf_smb_flags_receive_buffer,
18622 		{ "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
18623 		TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
18624 
18625 	{ &hf_smb_flags_caseless,
18626 		{ "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
18627 		TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
18628 
18629 	{ &hf_smb_flags_canon,
18630 		{ "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
18631 		TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
18632 
18633 	{ &hf_smb_flags_oplock,
18634 		{ "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
18635 		TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
18636 
18637 	{ &hf_smb_flags_notify,
18638 		{ "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
18639 		TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
18640 
18641 	{ &hf_smb_flags_response,
18642 		{ "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
18643 		TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
18644 
18645 	{ &hf_smb_flags2,
18646 		{ "Flags2", "smb.flags2", FT_UINT16, BASE_HEX,
18647 		NULL, 0x0, NULL, HFILL }},
18648 
18649 	{ &hf_smb_flags2_long_names_allowed,
18650 		{ "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
18651 		TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
18652 
18653 	{ &hf_smb_flags2_ea,
18654 		{ "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
18655 		TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
18656 
18657 	{ &hf_smb_flags2_sec_sig,
18658 		{ "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
18659 		TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
18660 
18661 	{ &hf_smb_flags2_compressed,
18662 		{ "Compressed", "smb.flags2.compressed", FT_BOOLEAN, 16,
18663 		TFS(&tfs_smb_flags2_compressed), 0x0008, "Is compression requested?", HFILL }},
18664 
18665 	{ &hf_smb_flags2_sec_sig_required,
18666 		{ "Security Signatures Required", "smb.flags2.sec_sig_required", FT_BOOLEAN, 16,
18667 		TFS(&tfs_smb_flags2_sec_sig_required), 0x0010, "Are security signatures required?", HFILL }},
18668 
18669 	{ &hf_smb_flags2_long_names_used,
18670 		{ "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
18671 		TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
18672 
18673 	{ &hf_smb_flags2_reparse_path,
18674 		{ "Reparse Path", "smb.flags2.reparse_path", FT_BOOLEAN, 16,
18675 		TFS(&tfs_smb_flags2_reparse_path), 0x0400, "The request uses a @GMT reparse path", HFILL }},
18676 
18677 	{ &hf_smb_flags2_esn,
18678 		{ "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
18679 		TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
18680 
18681 	{ &hf_smb_flags2_dfs,
18682 		{ "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
18683 		TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
18684 
18685 	{ &hf_smb_flags2_roe,
18686 		{ "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
18687 		TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
18688 
18689 	{ &hf_smb_flags2_nt_error,
18690 		{ "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
18691 		TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
18692 
18693 	{ &hf_smb_flags2_string,
18694 		{ "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
18695 		TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
18696 
18697 	{ &hf_smb_buffer_format,
18698 		{ "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
18699 		VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
18700 
18701 	{ &hf_smb_dialect,
18702 		{ "Dialect", "smb.dialect", FT_STRING, STR_UNICODE,
18703 		NULL, 0x0, NULL, HFILL }},
18704 
18705 	{ &hf_smb_dialect_name,
18706 		{ "Name", "smb.dialect.name", FT_STRING, STR_UNICODE,
18707 		NULL, 0, "Name of dialect", HFILL }},
18708 
18709 	{ &hf_smb_dialect_index,
18710 		{ "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
18711 		NULL, 0, "Index of selected dialect", HFILL }},
18712 
18713 	{ &hf_smb_max_trans_buf_size,
18714 		{ "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
18715 		NULL, 0, "Maximum transmit buffer size", HFILL }},
18716 
18717 	{ &hf_smb_max_mpx_count,
18718 		{ "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
18719 		NULL, 0, "Maximum pending multiplexed requests", HFILL }},
18720 
18721 	{ &hf_smb_max_vcs_num,
18722 		{ "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
18723 		NULL, 0, "Maximum VCs between client and server", HFILL }},
18724 
18725 	{ &hf_smb_session_key,
18726 		{ "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
18727 		NULL, 0, "Unique token identifying this session", HFILL }},
18728 
18729 	{ &hf_smb_server_timezone,
18730 		{ "Server Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
18731 		NULL, 0, "Current timezone at server.", HFILL }},
18732 
18733 	{ &hf_smb_challenge_length,
18734 		{ "Challenge Length", "smb.challenge_length", FT_UINT16, BASE_DEC,
18735 		NULL, 0, "Challenge_length (must be 0 if not LM2.1 dialect)", HFILL }},
18736 
18737 	{ &hf_smb_challenge,
18738 		{ "Challenge", "smb.challenge", FT_BYTES, BASE_NONE,
18739 		NULL, 0, "Challenge Data (for LM2.1 dialect)", HFILL }},
18740 
18741 	{ &hf_smb_primary_domain,
18742 		{ "Primary Domain", "smb.primary_domain", FT_STRING, STR_UNICODE,
18743 		NULL, 0, "The server's primary domain", HFILL }},
18744 
18745 	{ &hf_smb_server,
18746 		{ "Server", "smb.server", FT_STRING, STR_UNICODE,
18747 		NULL, 0, "The name of the DC/server", HFILL }},
18748 
18749 	{ &hf_smb_max_raw_buf_size,
18750 		{ "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
18751 		NULL, 0, "Maximum raw buffer size", HFILL }},
18752 
18753 	{ &hf_smb_server_guid,
18754 		{ "Server GUID", "smb.server_guid", FT_GUID, BASE_NONE,
18755 		NULL, 0, "Globally unique identifier for this server", HFILL }},
18756 
18757 	{ &hf_smb_volume_guid,
18758 		{ "Volume GUID", "smb.volume_guid", FT_GUID, BASE_NONE,
18759 		NULL, 0, "Globally unique identifier for this volume", HFILL }},
18760 
18761 	{ &hf_smb_security_blob_len,
18762 		{ "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
18763 		NULL, 0, NULL, HFILL }},
18764 
18765 	{ &hf_smb_security_blob,
18766 		{ "Security Blob", "smb.security_blob", FT_BYTES, BASE_NONE,
18767 		NULL, 0, NULL, HFILL }},
18768 
18769 	{ &hf_smb_sm16,
18770 		{ "Security Mode", "smb.sm", FT_UINT16, BASE_HEX,
18771 		NULL, 0x0, NULL, HFILL }},
18772 
18773 	{ &hf_smb_sm_mode16,
18774 		{ "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
18775 		TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
18776 
18777 	{ &hf_smb_sm_password16,
18778 		{ "Password", "smb.sm.password", FT_BOOLEAN, 16,
18779 		TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
18780 
18781 	{ &hf_smb_sm,
18782 		{ "Security Mode", "smb.sm", FT_UINT8, BASE_HEX,
18783 		NULL, 0x0, NULL, HFILL }},
18784 
18785 	{ &hf_smb_sm_mode,
18786 		{ "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
18787 		TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
18788 
18789 	{ &hf_smb_sm_password,
18790 		{ "Password", "smb.sm.password", FT_BOOLEAN, 8,
18791 		TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
18792 
18793 	{ &hf_smb_sm_signatures,
18794 		{ "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
18795 		TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
18796 
18797 	{ &hf_smb_sm_sig_required,
18798 		{ "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
18799 		TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
18800 
18801 	{ &hf_smb_rm,
18802 		{ "Raw Mode", "smb.rm", FT_UINT16, BASE_HEX,
18803 		NULL, 0x0, NULL, HFILL }},
18804 
18805 	{ &hf_smb_rm_read,
18806 		{ "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
18807 		TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
18808 
18809 	{ &hf_smb_rm_write,
18810 		{ "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
18811 		TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
18812 
18813 	{ &hf_smb_server_date_time,
18814 		{ "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18815 		NULL, 0, "Current date and time at server", HFILL }},
18816 
18817 	{ &hf_smb_server_smb_date,
18818 		{ "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
18819 		NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
18820 
18821 	{ &hf_smb_server_smb_time,
18822 		{ "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
18823 		NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
18824 
18825 	{ &hf_smb_server_cap,
18826 		{ "Capabilities", "smb.server_cap", FT_UINT32, BASE_HEX,
18827 		NULL, 0x0, NULL, HFILL }},
18828 
18829 	{ &hf_smb_server_cap_raw_mode,
18830 		{ "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
18831 		TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
18832 
18833 	{ &hf_smb_server_cap_mpx_mode,
18834 		{ "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
18835 		TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
18836 
18837 	{ &hf_smb_server_cap_unicode,
18838 		{ "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
18839 		TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
18840 
18841 	{ &hf_smb_server_cap_large_files,
18842 		{ "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
18843 		TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
18844 
18845 	{ &hf_smb_server_cap_nt_smbs,
18846 		{ "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
18847 		TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
18848 
18849 	{ &hf_smb_server_cap_rpc_remote_apis,
18850 		{ "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
18851 		TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
18852 
18853 	{ &hf_smb_server_cap_nt_status,
18854 		{ "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
18855 		TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
18856 
18857 	{ &hf_smb_server_cap_level_ii_oplocks,
18858 		{ "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
18859 		TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
18860 
18861 	{ &hf_smb_server_cap_lock_and_read,
18862 		{ "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
18863 		TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
18864 
18865 	{ &hf_smb_server_cap_nt_find,
18866 		{ "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
18867 		TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
18868 
18869 	{ &hf_smb_server_cap_dfs,
18870 		{ "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
18871 		TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
18872 
18873 	{ &hf_smb_server_cap_infolevel_passthru,
18874 		{ "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
18875 		TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
18876 
18877 	{ &hf_smb_server_cap_large_readx,
18878 		{ "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
18879 		TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
18880 
18881 	{ &hf_smb_server_cap_large_writex,
18882 		{ "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
18883 		TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
18884 
18885 	{ &hf_smb_server_cap_lwio,
18886 		{ "LWIO", "smb.server_cap.lwio", FT_BOOLEAN, 32,
18887 		TFS(&tfs_server_cap_lwio), SERVER_CAP_LWIO,
18888 		"Is IOCTL/FSCTL supported", HFILL }},
18889 
18890 	{ &hf_smb_server_cap_unix,
18891 		{ "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
18892 		TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
18893 
18894 	{ &hf_smb_server_cap_compressed_data,
18895 		{ "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
18896 		TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
18897 
18898 	{ &hf_smb_server_cap_dynamic_reauth,
18899 		{ "Dynamic Reauth", "smb.server_cap.dynamic_reauth", FT_BOOLEAN, 32,
18900 		TFS(&tfs_server_cap_dynamic_reauth), SERVER_CAP_DYNAMIC_REAUTH,
18901 		"Is dynamic reauth supported?", HFILL }},
18902 
18903 	{ &hf_smb_server_cap_extended_security,
18904 		{ "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
18905 		TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
18906 
18907 	{ &hf_smb_system_time,
18908 		{ "System Time", "smb.system.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18909 		NULL, 0, NULL, HFILL }},
18910 
18911 	{ &hf_smb_unknown,
18912 		{ "Unknown Data", "smb.unknown_data", FT_BYTES, BASE_NONE,
18913 		NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
18914 
18915 	{ &hf_smb_dir_name,
18916 		{ "Directory", "smb.dir_name", FT_STRING, STR_UNICODE,
18917 		NULL, 0, "SMB Directory Name", HFILL }},
18918 
18919 	{ &hf_smb_echo_count,
18920 		{ "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
18921 		NULL, 0, "Number of times to echo data back", HFILL }},
18922 
18923 	{ &hf_smb_echo_data,
18924 		{ "Echo Data", "smb.echo.data", FT_BYTES, BASE_NONE,
18925 		NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
18926 
18927 	{ &hf_smb_echo_seq_num,
18928 		{ "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
18929 		NULL, 0, "Sequence number for this echo response", HFILL }},
18930 
18931 	{ &hf_smb_max_buf_size,
18932 		{ "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
18933 		NULL, 0, "Max client buffer size", HFILL }},
18934 
18935 	{ &hf_smb_path,
18936 		{ "Path", "smb.path", FT_STRING, STR_UNICODE,
18937 		NULL, 0, "Path. Server name and share name", HFILL }},
18938 
18939 	{ &hf_smb_service,
18940 		{ "Service", "smb.service", FT_STRING, STR_UNICODE,
18941 		NULL, 0, "Service name", HFILL }},
18942 
18943 	{ &hf_smb_password,
18944 		{ "Password", "smb.password", FT_BYTES, BASE_NONE,
18945 		NULL, 0, NULL, HFILL }},
18946 
18947 	{ &hf_smb_ansi_password,
18948 		{ "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
18949 		NULL, 0, NULL, HFILL }},
18950 
18951 	{ &hf_smb_unicode_password,
18952 		{ "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
18953 		NULL, 0, NULL, HFILL }},
18954 
18955 	{ &hf_smb_move_flags,
18956 		{ "Flags", "smb.move.flags", FT_UINT16, BASE_HEX,
18957 		NULL, 0x0, NULL, HFILL }},
18958 
18959 	{ &hf_smb_move_flags_file,
18960 		{ "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
18961 		TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
18962 
18963 	{ &hf_smb_move_flags_dir,
18964 		{ "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
18965 		TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
18966 
18967 	{ &hf_smb_move_flags_verify,
18968 		{ "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
18969 		TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
18970 
18971 	{ &hf_smb_files_moved,
18972 		{ "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
18973 		NULL, 0, "Number of files moved", HFILL }},
18974 
18975 	{ &hf_smb_copy_flags,
18976 		{ "Flags", "smb.copy.flags", FT_UINT16, BASE_HEX,
18977 		NULL, 0x0, NULL, HFILL }},
18978 
18979 	{ &hf_smb_copy_flags_file,
18980 		{ "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
18981 		TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
18982 
18983 	{ &hf_smb_copy_flags_dir,
18984 		{ "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
18985 		TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
18986 
18987 	{ &hf_smb_copy_flags_dest_mode,
18988 		{ "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
18989 		TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
18990 
18991 	{ &hf_smb_copy_flags_source_mode,
18992 		{ "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
18993 		TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
18994 
18995 	{ &hf_smb_copy_flags_verify,
18996 		{ "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
18997 		TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
18998 
18999 	{ &hf_smb_copy_flags_tree_copy,
19000 		{ "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
19001 		TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
19002 
19003 	{ &hf_smb_copy_flags_ea_action,
19004 		{ "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
19005 		TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
19006 
19007 	{ &hf_smb_count,
19008 		{ "Count", "smb.count", FT_UINT32, BASE_DEC,
19009 		NULL, 0, "Count number of items/bytes", HFILL }},
19010 
19011 	{ &hf_smb_count_low,
19012 		{ "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
19013 		NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
19014 
19015 	{ &hf_smb_count_high,
19016 		{ "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
19017 		NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
19018 
19019 	{ &hf_smb_file_name,
19020 		{ "File Name", "smb.file", FT_STRING, STR_UNICODE,
19021 		NULL, 0, NULL, HFILL }},
19022 
19023 	{ &hf_smb_open_function,
19024 		{ "Open Function", "smb.open.function", FT_UINT16, BASE_HEX,
19025 		NULL, 0x0, NULL, HFILL }},
19026 
19027 	{ &hf_smb_open_function_create,
19028 		{ "Create", "smb.open.function.create", FT_BOOLEAN, 16,
19029 		TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
19030 
19031 	{ &hf_smb_open_function_open,
19032 		{ "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
19033 		VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
19034 
19035 	{ &hf_smb_fid,
19036 		{ "FID", "smb.fid", FT_UINT16, BASE_HEX,
19037 		NULL, 0, "FID: File ID", HFILL }},
19038 
19039 	{ &hf_smb_file_attr_16bit,
19040 		{ "File Attributes", "smb.file_attribute", FT_UINT16, BASE_HEX,
19041 		NULL, 0x0, NULL, HFILL }},
19042 
19043 	{ &hf_smb_file_attr_8bit,
19044 		{ "File Attributes", "smb.file_attribute", FT_UINT8, BASE_HEX,
19045 		NULL, 0x0, NULL, HFILL }},
19046 
19047 	{ &hf_smb_file_attr_read_only_16bit,
19048 		{ "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
19049 		TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
19050 
19051 	{ &hf_smb_file_attr_read_only_8bit,
19052 		{ "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
19053 		TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
19054 
19055 	{ &hf_smb_file_attr_hidden_16bit,
19056 		{ "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
19057 		TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
19058 
19059 	{ &hf_smb_file_attr_hidden_8bit,
19060 		{ "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
19061 		TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
19062 
19063 	{ &hf_smb_file_attr_system_16bit,
19064 		{ "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
19065 		TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
19066 
19067 	{ &hf_smb_file_attr_system_8bit,
19068 		{ "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
19069 		TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
19070 
19071 	{ &hf_smb_file_attr_volume_16bit,
19072 		{ "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
19073 		TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
19074 
19075 	{ &hf_smb_file_attr_volume_8bit,
19076 		{ "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
19077 		TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
19078 
19079 	{ &hf_smb_file_attr_directory_16bit,
19080 		{ "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
19081 		TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
19082 
19083 	{ &hf_smb_file_attr_directory_8bit,
19084 		{ "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
19085 		TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
19086 
19087 	{ &hf_smb_file_attr_archive_16bit,
19088 		{ "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
19089 		TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
19090 
19091 	{ &hf_smb_file_attr_archive_8bit,
19092 		{ "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
19093 		TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
19094 
19095 #if 0
19096 	{ &hf_smb_file_attr_device,
19097 		{ "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
19098 		TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
19099 
19100 	{ &hf_smb_file_attr_normal,
19101 		{ "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
19102 		TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
19103 
19104 	{ &hf_smb_file_attr_temporary,
19105 		{ "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
19106 		TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
19107 
19108 	{ &hf_smb_file_attr_sparse,
19109 		{ "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
19110 		TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
19111 
19112 	{ &hf_smb_file_attr_reparse,
19113 		{ "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
19114 		TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
19115 
19116 	{ &hf_smb_file_attr_compressed,
19117 		{ "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
19118 		TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
19119 
19120 	{ &hf_smb_file_attr_offline,
19121 		{ "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
19122 		TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
19123 
19124 	{ &hf_smb_file_attr_not_content_indexed,
19125 		{ "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
19126 		TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
19127 
19128 	{ &hf_smb_file_attr_encrypted,
19129 		{ "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
19130 		TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
19131 #endif
19132 
19133 	{ &hf_smb_file_size,
19134 		{ "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
19135 		NULL, 0, NULL, HFILL }},
19136 
19137 	{ &hf_smb_search_attribute,
19138 		{ "Search Attributes", "smb.search.attribute", FT_UINT16, BASE_HEX,
19139 		NULL, 0x0, NULL, HFILL }},
19140 
19141 	{ &hf_smb_search_attribute_read_only,
19142 		{ "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
19143 		TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
19144 
19145 	{ &hf_smb_search_attribute_hidden,
19146 		{ "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
19147 		TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
19148 
19149 	{ &hf_smb_search_attribute_system,
19150 		{ "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
19151 		TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
19152 
19153 	{ &hf_smb_search_attribute_volume,
19154 		{ "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
19155 		TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
19156 
19157 	{ &hf_smb_search_attribute_directory,
19158 		{ "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
19159 		TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
19160 
19161 	{ &hf_smb_search_attribute_archive,
19162 		{ "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
19163 		TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
19164 
19165 	{ &hf_smb_access_mode,
19166 		{ "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
19167 		VALS(da_access_vals), 0x0007, NULL, HFILL }},
19168 
19169 	{ &hf_smb_access_sharing,
19170 		{ "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
19171 		VALS(da_sharing_vals), 0x0070, NULL, HFILL }},
19172 
19173 	{ &hf_smb_access_locality,
19174 		{ "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
19175 		VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
19176 
19177 	{ &hf_smb_access_caching,
19178 		{ "Caching", "smb.access.caching", FT_BOOLEAN, 16,
19179 		TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
19180 
19181 	{ &hf_smb_desired_access,
19182 		{ "Desired Access", "smb.access.desired", FT_UINT16, BASE_HEX,
19183 		NULL, 0x0, NULL, HFILL }},
19184 
19185 	{ &hf_smb_granted_access,
19186 		{ "Granted Access", "smb.access.granted", FT_UINT16, BASE_HEX,
19187 		NULL, 0x0, NULL, HFILL }},
19188 
19189 	{ &hf_smb_access_writetru,
19190 		{ "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
19191 		TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
19192 
19193 	{ &hf_smb_create_time,
19194 		{ "Created", "smb.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19195 		NULL, 0, "Creation Time", HFILL }},
19196 
19197 	{ &hf_smb_modify_time,
19198 	        { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19199 		  NULL, 0, "Modification Time", HFILL }},
19200 
19201 	{ &hf_smb_backup_time,
19202 	        { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19203 		  NULL, 0, "Backup time", HFILL}},
19204 
19205 	{ &hf_smb_mac_alloc_block_count,
19206 	        { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
19207 		  NULL, 0, NULL, HFILL}},
19208 
19209 	{ &hf_smb_mac_alloc_block_size,
19210 	        { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
19211 		  NULL, 0, "Allocation Block Size", HFILL}},
19212 
19213 	{ &hf_smb_mac_free_block_count,
19214 	        { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
19215 		  NULL, 0, NULL, HFILL}},
19216 
19217 	{ &hf_smb_mac_root_file_count,
19218 	        { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
19219 	        NULL, 0, NULL, HFILL}},
19220 
19221 	{ &hf_smb_mac_root_dir_count,
19222 	  { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
19223 	    NULL, 0, NULL, HFILL}},
19224 
19225 	{ &hf_smb_mac_file_count,
19226 	  { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
19227 	    NULL, 0, "File Count", HFILL}},
19228 
19229 	{ &hf_smb_mac_dir_count,
19230 	  { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
19231 	    NULL, 0, "Directory Count", HFILL}},
19232 
19233 	{ &hf_smb_mac_sup,
19234 	  { "Mac Support Flags", "smb.mac", FT_UINT32, BASE_HEX,
19235 	    NULL, 0x0, NULL, HFILL }},
19236 
19237 	{ &hf_smb_mac_sup_access_ctrl,
19238 	  { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
19239 	    TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
19240 
19241 	{ &hf_smb_mac_sup_getset_comments,
19242 	  { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
19243 	    TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
19244 
19245 	{ &hf_smb_mac_sup_desktopdb_calls,
19246 	  { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
19247 	    TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
19248 
19249 	{ &hf_smb_mac_sup_unique_ids,
19250 	  { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
19251 	    TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
19252 
19253 	{ &hf_smb_mac_sup_streams,
19254 	  { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
19255 	    TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
19256 
19257 	{ &hf_smb_create_dos_date,
19258 		{ "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
19259 		NULL, 0, "Create Date, SMB_DATE format", HFILL }},
19260 
19261 	{ &hf_smb_create_dos_time,
19262 		{ "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
19263 		NULL, 0, "Create Time, SMB_TIME format", HFILL }},
19264 
19265 	{ &hf_smb_last_write_time,
19266 		{ "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19267 		NULL, 0, "Time this file was last written to", HFILL }},
19268 
19269 	{ &hf_smb_last_write_dos_date,
19270 		{ "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
19271 		NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
19272 
19273 	{ &hf_smb_last_write_dos_time,
19274 		{ "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
19275 		NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
19276 
19277 	{ &hf_smb_old_file_name,
19278 		{ "Old File Name", "smb.old_file", FT_STRING, STR_UNICODE,
19279 		NULL, 0, "Old File Name (When renaming a file)", HFILL }},
19280 
19281 	{ &hf_smb_offset,
19282 		{ "Offset", "smb.offset", FT_UINT32, BASE_DEC,
19283 		NULL, 0, "Offset in file", HFILL }},
19284 
19285 	{ &hf_smb_remaining,
19286 		{ "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
19287 		NULL, 0, "Remaining number of bytes", HFILL }},
19288 
19289 	{ &hf_smb_padding,
19290 		{ "Padding", "smb.padding", FT_BYTES, BASE_NONE,
19291 		NULL, 0, "Padding or unknown data", HFILL }},
19292 
19293 	{ &hf_smb_file_data,
19294 		{ "File Data", "smb.file_data", FT_BYTES, BASE_NONE,
19295 		NULL, 0, "Data read/written to the file", HFILL }},
19296 
19297 #if 0
19298 	{ &hf_smb_raw_ea_data,
19299 		{ "EA Data", "smb.ea_data", FT_BYTES, BASE_NONE,
19300 		NULL, 0, "Data in EA list", HFILL }},
19301 #endif
19302 
19303 	{ &hf_smb_mac_fndrinfo,
19304 	        { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_NONE,
19305 		  NULL, 0, NULL, HFILL}},
19306 
19307 	{ &hf_smb_total_data_len,
19308 		{ "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
19309 		NULL, 0, "Total length of data", HFILL }},
19310 
19311 	{ &hf_smb_data_len,
19312 		{ "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
19313 		NULL, 0, "Length of data", HFILL }},
19314 
19315 	{ &hf_smb_data_len_low,
19316 		{ "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
19317 		NULL, 0, "Length of data, Low 16 bits", HFILL }},
19318 
19319 	{ &hf_smb_data_len_high,
19320 		{ "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
19321 		NULL, 0, "Length of data, High 16 bits", HFILL }},
19322 
19323 	{ &hf_smb_seek_mode,
19324 		{ "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
19325 		VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
19326 
19327 	{ &hf_smb_access_time,
19328 		{ "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19329 		NULL, 0, "Last Access Time", HFILL }},
19330 
19331 	{ &hf_smb_access_dos_date,
19332 		{ "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
19333 		NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
19334 
19335 	{ &hf_smb_access_dos_time,
19336 		{ "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
19337 		NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
19338 
19339 	{ &hf_smb_data_size,
19340 		{ "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
19341 		NULL, 0, NULL, HFILL }},
19342 
19343 	{ &hf_smb_alloc_size,
19344 		{ "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
19345 		NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
19346 
19347 	{ &hf_smb_max_count,
19348 		{ "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
19349 		NULL, 0, "Maximum Count", HFILL }},
19350 
19351 	{ &hf_smb_max_count_low,
19352 		{ "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
19353 		NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
19354 
19355 	{ &hf_smb_max_count_high,
19356 		{ "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
19357 		NULL, 0, "Maximum Count, High 16 bits", HFILL }},
19358 
19359 	{ &hf_smb_min_count,
19360 		{ "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
19361 		NULL, 0, "Minimum Count", HFILL }},
19362 
19363 	{ &hf_smb_timeout,
19364 		{ "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
19365 		NULL, 0, "Timeout in milliseconds", HFILL }},
19366 
19367 	{ &hf_smb_high_offset,
19368 		{ "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
19369 		NULL, 0, "High 32 Bits Of File Offset", HFILL }},
19370 
19371 	{ &hf_smb_units,
19372 		{ "Total Units", "smb.units", FT_UINT16, BASE_DEC,
19373 		NULL, 0, "Total number of units at server", HFILL }},
19374 
19375 	{ &hf_smb_bpu,
19376 		{ "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
19377 		NULL, 0, "Blocks per unit at server", HFILL }},
19378 
19379 	{ &hf_smb_blocksize,
19380 		{ "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
19381 		NULL, 0, "Block size (in bytes) at server", HFILL }},
19382 
19383 	{ &hf_smb_freeunits,
19384 		{ "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
19385 		NULL, 0, "Number of free units at server", HFILL }},
19386 
19387 	{ &hf_smb_data_offset,
19388 		{ "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
19389 		NULL, 0, NULL, HFILL }},
19390 
19391 	{ &hf_smb_dcm,
19392 		{ "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
19393 		NULL, 0, NULL, HFILL }},
19394 
19395 	{ &hf_smb_request_mask,
19396 		{ "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
19397 		NULL, 0, "Connectionless mode mask", HFILL }},
19398 
19399 	{ &hf_smb_response_mask,
19400 		{ "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
19401 		NULL, 0, "Connectionless mode mask", HFILL }},
19402 
19403 	{ &hf_smb_search_id,
19404 		{ "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
19405 		NULL, 0, "Search ID, handle for find operations", HFILL }},
19406 
19407 	{ &hf_smb_write_mode,
19408 		{ "Write Mode", "smb.write.mode", FT_UINT16, BASE_HEX,
19409 		NULL, 0x0, NULL, HFILL }},
19410 
19411 	{ &hf_smb_write_mode_write_through,
19412 		{ "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
19413 		TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
19414 
19415 	{ &hf_smb_write_mode_return_remaining,
19416 		{ "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
19417 		TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
19418 
19419 	{ &hf_smb_write_mode_raw,
19420 		{ "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
19421 		TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
19422 
19423 	{ &hf_smb_write_mode_message_start,
19424 		{ "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
19425 		TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
19426 
19427 	{ &hf_smb_write_mode_connectionless,
19428 		{ "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
19429 		TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
19430 
19431 	{ &hf_smb_resume_key_len,
19432 		{ "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
19433 		NULL, 0, NULL, HFILL }},
19434 
19435 	{ &hf_smb_resume_find_id,
19436 		{ "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
19437 		NULL, 0, "Handle for Find operation", HFILL }},
19438 
19439 	{ &hf_smb_resume_server_cookie,
19440 		{ "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_NONE,
19441 		NULL, 0, "Cookie, must not be modified by the client", HFILL }},
19442 
19443 	{ &hf_smb_resume_client_cookie,
19444 		{ "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_NONE,
19445 		NULL, 0, "Cookie, must not be modified by the server", HFILL }},
19446 
19447 	{ &hf_smb_andxoffset,
19448 		{ "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
19449 		NULL, 0, "Offset to next command in this SMB packet", HFILL }},
19450 
19451 	{ &hf_smb_lock_type,
19452 		{ "Lock Type", "smb.lock.type", FT_UINT8, BASE_HEX,
19453 		NULL, 0x0, NULL, HFILL }},
19454 
19455 	{ &hf_smb_lock_type_large,
19456 		{ "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
19457 		TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
19458 
19459 	{ &hf_smb_lock_type_cancel,
19460 		{ "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
19461 		TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
19462 
19463 	{ &hf_smb_lock_type_change,
19464 		{ "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
19465 		TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
19466 
19467 	{ &hf_smb_lock_type_oplock,
19468 		{ "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
19469 		TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
19470 
19471 	{ &hf_smb_lock_type_shared,
19472 		{ "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
19473 		TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
19474 
19475 	{ &hf_smb_locking_ol,
19476 		{ "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
19477 		VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
19478 
19479 	{ &hf_smb_number_of_locks,
19480 		{ "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
19481 		NULL, 0, "Number of lock requests in this request", HFILL }},
19482 
19483 	{ &hf_smb_number_of_unlocks,
19484 		{ "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
19485 		NULL, 0, "Number of unlock requests in this request", HFILL }},
19486 
19487 	{ &hf_smb_lock_long_length,
19488 		{ "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
19489 		NULL, 0, "Length of lock/unlock region", HFILL }},
19490 
19491 	{ &hf_smb_lock_long_offset,
19492 		{ "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
19493 		NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
19494 
19495 	{ &hf_smb_file_type,
19496 		{ "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
19497 		VALS(filetype_vals), 0, "Type of file", HFILL }},
19498 
19499 	{ &hf_smb_ipc_state,
19500 		{ "IPC State", "smb.ipc_state", FT_UINT16, BASE_HEX,
19501 		NULL, 0x0, NULL, HFILL }},
19502 
19503 	{ &hf_smb_ipc_state_nonblocking,
19504 		{ "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
19505 		TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
19506 
19507 	{ &hf_smb_ipc_state_endpoint,
19508 		{ "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
19509 		VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
19510 
19511 	{ &hf_smb_ipc_state_pipe_type,
19512 		{ "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
19513 		VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
19514 
19515 	{ &hf_smb_ipc_state_read_mode,
19516 		{ "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
19517 		VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
19518 
19519 	{ &hf_smb_ipc_state_icount,
19520 		{ "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
19521 		NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
19522 
19523 	{ &hf_smb_server_fid,
19524 		{ "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
19525 		NULL, 0, "Server unique File ID", HFILL }},
19526 
19527 	{ &hf_smb_open_flags,
19528 		{ "Flags", "smb.open.flags", FT_UINT16, BASE_HEX,
19529 		NULL, 0x0, NULL, HFILL }},
19530 
19531 	{ &hf_smb_open_flags_add_info,
19532 		{ "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
19533 		TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
19534 
19535 	{ &hf_smb_open_flags_ex_oplock,
19536 		{ "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
19537 		TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
19538 
19539 	{ &hf_smb_open_flags_batch_oplock,
19540 		{ "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
19541 		TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
19542 
19543 	{ &hf_smb_open_flags_ealen,
19544 		{ "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
19545 		TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
19546 
19547 	{ &hf_smb_open_action,
19548 		{ "Action", "smb.open.action", FT_UINT16, BASE_HEX,
19549 		NULL, 0x0, NULL, HFILL }},
19550 
19551 	{ &hf_smb_open_action_open,
19552 		{ "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
19553 		VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
19554 
19555 	{ &hf_smb_open_action_lock,
19556 		{ "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
19557 		TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
19558 
19559 	{ &hf_smb_vc_num,
19560 		{ "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
19561 		NULL, 0, NULL, HFILL }},
19562 
19563 	{ &hf_smb_password_len,
19564 		{ "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
19565 		NULL, 0, "Length of password", HFILL }},
19566 
19567 	{ &hf_smb_ansi_password_len,
19568 		{ "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
19569 		NULL, 0, "Length of ANSI password", HFILL }},
19570 
19571 	{ &hf_smb_unicode_password_len,
19572 		{ "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
19573 		NULL, 0, "Length of Unicode password", HFILL }},
19574 
19575 	{ &hf_smb_account,
19576 		{ "Account", "smb.account", FT_STRING, STR_UNICODE,
19577 		NULL, 0, "Account, username", HFILL }},
19578 
19579 	{ &hf_smb_os,
19580 		{ "Native OS", "smb.native_os", FT_STRING, STR_UNICODE,
19581 		NULL, 0, "Which OS we are running", HFILL }},
19582 
19583 	{ &hf_smb_lanman,
19584 		{ "Native LAN Manager", "smb.native_lanman", FT_STRING, STR_UNICODE,
19585 		NULL, 0, "Which LANMAN protocol we are running", HFILL }},
19586 
19587 	{ &hf_smb_setup_action,
19588 		{ "Action", "smb.setup.action", FT_UINT16, BASE_HEX,
19589 		NULL, 0x0, NULL, HFILL }},
19590 
19591 	{ &hf_smb_setup_action_guest,
19592 		{ "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
19593 		TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
19594 
19595 	{ &hf_smb_fs,
19596 		{ "Native File System", "smb.native_fs", FT_STRING, STR_UNICODE,
19597 		NULL, 0, NULL, HFILL }},
19598 
19599 	{ &hf_smb_connect_flags,
19600 		{ "Flags", "smb.connect.flags", FT_UINT16, BASE_HEX,
19601 		NULL, 0x0, NULL, HFILL }},
19602 
19603 	{ &hf_smb_connect_flags_dtid,
19604 		{ "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
19605 		TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
19606 
19607 	{ &hf_smb_connect_flags_ext_sig,
19608 		{ "Extended Signature", "smb.connect.flags.extendedsig", FT_BOOLEAN, 16,
19609 		TFS(&tfs_extended_signature), 0x0004, "Extended signature?", HFILL }},
19610 
19611 	{ &hf_smb_connect_flags_ext_resp,
19612 		{ "Extended Response", "smb.connect.flags.extendedresp", FT_BOOLEAN, 16,
19613 		TFS(&tfs_extended_response), 0x0008, "Extended response?", HFILL }},
19614 
19615 	{ &hf_smb_connect_support,
19616 		{ "Optional Support", "smb.connect.support", FT_UINT16, BASE_HEX,
19617 		NULL, 0x0, NULL, HFILL }},
19618 
19619 	{ &hf_smb_connect_support_search,
19620 		{ "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
19621 		TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
19622 
19623 	{ &hf_smb_connect_support_in_dfs,
19624 		{ "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
19625 		TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
19626 
19627 	{ &hf_smb_connect_support_csc_mask_vals,
19628 		{ "CSC Mask", "smb.connect.support.cscmask", FT_UINT16, BASE_DEC,
19629 		VALS(connect_support_csc_mask_vals), 0x000c, "CSC mask?", HFILL }},
19630 
19631 	{ &hf_smb_connect_support_uniquefilename,
19632 		{ "Unique File Name", "smb.connect.support.uniqfilename", FT_BOOLEAN, 16,
19633 		TFS(&tfs_connect_support_uniquefilename), 0x0010, "Unique file name supported?", HFILL }},
19634 
19635 	{ &hf_smb_connect_support_extended_signature,
19636 		{ "Extended Signatures", "smb.connect.support.extendedsig", FT_BOOLEAN, 16,
19637 		TFS(&tfs_connect_support_extended_signature), 0x0020, "Extended signatures?", HFILL }},
19638 
19639 	{ &hf_smb_max_setup_count,
19640 		{ "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
19641 		NULL, 0, "Maximum number of setup words to return", HFILL }},
19642 
19643 	{ &hf_smb_total_param_count,
19644 		{ "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
19645 		NULL, 0, "Total number of parameter bytes", HFILL }},
19646 
19647 	{ &hf_smb_total_data_count,
19648 		{ "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
19649 		NULL, 0, "Total number of data bytes", HFILL }},
19650 
19651 	{ &hf_smb_max_param_count,
19652 		{ "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
19653 		NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
19654 
19655 	{ &hf_smb_max_data_count,
19656 		{ "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
19657 		NULL, 0, "Maximum number of data bytes to return", HFILL }},
19658 
19659 	{ &hf_smb_param_disp16,
19660 		{ "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
19661 		NULL, 0, "Displacement of these parameter bytes", HFILL }},
19662 
19663 	{ &hf_smb_param_count16,
19664 		{ "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
19665 		NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
19666 
19667 	{ &hf_smb_param_offset16,
19668 		{ "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
19669 		NULL, 0, "Offset (from header start) to parameters", HFILL }},
19670 
19671 	{ &hf_smb_param_disp32,
19672 		{ "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
19673 		NULL, 0, "Displacement of these parameter bytes", HFILL }},
19674 
19675 	{ &hf_smb_param_count32,
19676 		{ "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
19677 		NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
19678 
19679 	{ &hf_smb_param_offset32,
19680 		{ "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
19681 		NULL, 0, "Offset (from header start) to parameters", HFILL }},
19682 
19683 	{ &hf_smb_data_count16,
19684 		{ "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
19685 		NULL, 0, "Number of data bytes in this buffer", HFILL }},
19686 
19687 	{ &hf_smb_data_disp16,
19688 		{ "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
19689 		NULL, 0, NULL, HFILL }},
19690 
19691 	{ &hf_smb_data_offset16,
19692 		{ "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
19693 		NULL, 0, NULL, HFILL }},
19694 
19695 	{ &hf_smb_data_count32,
19696 		{ "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
19697 		NULL, 0, "Number of data bytes in this buffer", HFILL }},
19698 
19699 	{ &hf_smb_data_disp32,
19700 		{ "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
19701 		NULL, 0, NULL, HFILL }},
19702 
19703 	{ &hf_smb_data_offset32,
19704 		{ "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
19705 		NULL, 0, NULL, HFILL }},
19706 
19707 	{ &hf_smb_setup_count,
19708 		{ "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
19709 		NULL, 0, "Number of setup words in this buffer", HFILL }},
19710 
19711 	{ &hf_smb_nt_ioctl_isfsctl,
19712 		{ "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
19713 		VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
19714 
19715 	{ &hf_smb_nt_ioctl_flags_completion_filter,
19716 		{ "Completion Filter", "smb.nt.ioctl.completion_filter", FT_UINT8, BASE_HEX,
19717 		NULL, 0x0, NULL, HFILL }},
19718 
19719 	{ &hf_smb_nt_ioctl_flags_root_handle,
19720 		{ "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
19721 		TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
19722 
19723 	{ &hf_smb_nt_notify_action,
19724 		{ "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
19725 		VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
19726 
19727 	{ &hf_smb_nt_notify_watch_tree,
19728 		{ "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
19729 		VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
19730 
19731 
19732 	{ &hf_smb_nt_notify_completion_filter,
19733 		{ "Completion Filter", "smb.nt.notify.completion_filter", FT_UINT32, BASE_HEX,
19734 		NULL, 0x0, NULL, HFILL }},
19735 	{ &hf_smb_nt_notify_file_name,
19736 		{ "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
19737 		TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
19738 
19739 	{ &hf_smb_nt_notify_dir_name,
19740 		{ "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
19741 		TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
19742 
19743 	{ &hf_smb_nt_notify_attributes,
19744 		{ "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
19745 		TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
19746 
19747 	{ &hf_smb_nt_notify_size,
19748 		{ "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
19749 		TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
19750 
19751 	{ &hf_smb_nt_notify_last_write,
19752 		{ "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
19753 		TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
19754 
19755 	{ &hf_smb_nt_notify_last_access,
19756 		{ "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
19757 		TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
19758 
19759 	{ &hf_smb_nt_notify_creation,
19760 		{ "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
19761 		TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
19762 
19763 	{ &hf_smb_nt_notify_ea,
19764 		{ "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
19765 		TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
19766 
19767 	{ &hf_smb_nt_notify_security,
19768 		{ "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
19769 		TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
19770 
19771 	{ &hf_smb_nt_notify_stream_name,
19772 		{ "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
19773 		TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
19774 
19775 	{ &hf_smb_nt_notify_stream_size,
19776 		{ "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
19777 		TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
19778 
19779 	{ &hf_smb_nt_notify_stream_write,
19780 		{ "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
19781 		TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
19782 
19783 
19784 	{ &hf_smb_root_dir_fid,
19785 		{ "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
19786 		NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
19787 
19788 	{ &hf_smb_alloc_size64,
19789 		{ "Allocation Size", "smb.alloc_size64", FT_UINT64, BASE_DEC,
19790 		NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
19791 
19792 	{ &hf_smb_nt_create_disposition,
19793 		{ "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
19794 		VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
19795 
19796 	{ &hf_smb_sd_length,
19797 		{ "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
19798 		NULL, 0, "Total length of security descriptor", HFILL }},
19799 
19800 	{ &hf_smb_ea_list_length,
19801 		{ "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
19802 		NULL, 0, "Total length of extended attributes", HFILL }},
19803 
19804 	{ &hf_smb_ea_flags,
19805 		{ "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
19806 		NULL, 0, NULL, HFILL }},
19807 
19808 	{ &hf_smb_ea_name_length,
19809 		{ "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
19810 		NULL, 0, NULL, HFILL }},
19811 
19812 	{ &hf_smb_ea_data_length,
19813 		{ "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
19814 		NULL, 0, NULL, HFILL }},
19815 
19816 	{ &hf_smb_ea_name,
19817 		{ "EA Name", "smb.ea.name", FT_STRING, STR_UNICODE,
19818 		NULL, 0, NULL, HFILL }},
19819 
19820 	{ &hf_smb_ea_data,
19821 		{ "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE|BASE_SHOW_ASCII_PRINTABLE,
19822 		NULL, 0, NULL, HFILL }},
19823 
19824 	{ &hf_smb_file_name_len,
19825 		{ "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
19826 		NULL, 0, "Length of File Name", HFILL }},
19827 
19828 	{ &hf_smb_nt_impersonation_level,
19829 		{ "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
19830 		VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
19831 
19832 	{ &hf_smb_nt_security_flags,
19833 		{ "Security Flags", "smb.security.flags", FT_UINT8, BASE_HEX,
19834 		NULL, 0x0, NULL, HFILL }},
19835 
19836 	{ &hf_smb_nt_security_flags_context_tracking,
19837 		{ "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
19838 		TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
19839 
19840 	{ &hf_smb_nt_security_flags_effective_only,
19841 		{ "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
19842 		TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
19843 
19844 	{ &hf_smb_nt_access_mask_generic_read,
19845 		{ "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
19846 		TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
19847 
19848 	{ &hf_smb_nt_access_mask_generic_write,
19849 		{ "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
19850 		TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
19851 
19852 	{ &hf_smb_nt_access_mask_generic_execute,
19853 		{ "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
19854 		TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
19855 
19856 	{ &hf_smb_nt_access_mask_generic_all,
19857 		{ "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
19858 		TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
19859 
19860 	{ &hf_smb_nt_access_mask_maximum_allowed,
19861 		{ "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
19862 		TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
19863 
19864 	{ &hf_smb_nt_access_mask_system_security,
19865 		{ "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
19866 		TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
19867 
19868 	{ &hf_smb_nt_access_mask_synchronize,
19869 		{ "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
19870 		TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
19871 
19872 	{ &hf_smb_nt_access_mask_write_owner,
19873 		{ "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
19874 		TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
19875 
19876 	{ &hf_smb_nt_access_mask_write_dac,
19877 		{ "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
19878 		TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
19879 
19880 	{ &hf_smb_nt_access_mask_read_control,
19881 		{ "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
19882 		TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
19883 
19884 	{ &hf_smb_nt_access_mask_delete,
19885 		{ "Delete", "smb.access.delete", FT_BOOLEAN, 32,
19886 		TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
19887 
19888 	{ &hf_smb_nt_access_mask_write_attributes,
19889 		{ "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
19890 		TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
19891 
19892 	{ &hf_smb_nt_access_mask_read_attributes,
19893 		{ "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
19894 		TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
19895 
19896 	{ &hf_smb_nt_access_mask_delete_child,
19897 		{ "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
19898 		TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
19899 
19900 	/*
19901 	 * "Execute" for files, "traverse" for directories.
19902 	 */
19903 	{ &hf_smb_nt_access_mask_execute,
19904 		{ "Execute", "smb.access.execute", FT_BOOLEAN, 32,
19905 		TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
19906 
19907 	{ &hf_smb_nt_access_mask_write_ea,
19908 		{ "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
19909 		TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
19910 
19911 	{ &hf_smb_nt_access_mask_read_ea,
19912 		{ "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
19913 		TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
19914 
19915 	/*
19916 	 * "Append data" for files, "add subdirectory" for directories,
19917 	 * "create pipe instance" for named pipes.
19918 	 */
19919 	{ &hf_smb_nt_access_mask_append,
19920 		{ "Append", "smb.access.append", FT_BOOLEAN, 32,
19921 		TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
19922 
19923 	/*
19924 	 * "Write data" for files and pipes, "add file" for directory.
19925 	 */
19926 	{ &hf_smb_nt_access_mask_write,
19927 		{ "Write", "smb.access.write", FT_BOOLEAN, 32,
19928 		TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
19929 
19930 	/*
19931 	 * "Read data" for files and pipes, "list directory" for directory.
19932 	 */
19933 	{ &hf_smb_nt_access_mask_read,
19934 		{ "Read", "smb.access.read", FT_BOOLEAN, 32,
19935 		TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
19936 
19937 	{ &hf_smb_nt_create_bits_oplock,
19938 		{ "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
19939 		TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
19940 
19941 	{ &hf_smb_nt_create_bits_boplock,
19942 		{ "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
19943 		TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
19944 
19945 	{ &hf_smb_nt_create_bits_dir,
19946 		{ "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
19947 		TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
19948 
19949 	{ &hf_smb_nt_create_bits_ext_resp,
19950 	  { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
19951 	    TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
19952 
19953 	{ &hf_smb_nt_create_options_directory_file,
19954 		{ "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
19955 		TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
19956 
19957 	{ &hf_smb_nt_create_options_write_through,
19958 		{ "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
19959 		TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
19960 
19961 	{ &hf_smb_nt_create_options_sequential_only,
19962 		{ "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
19963 		TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will access to this file only be sequential?", HFILL }},
19964 
19965 	{ &hf_smb_nt_create_options_no_intermediate_buffering,
19966 		{ "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
19967 		TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
19968 
19969 	{ &hf_smb_nt_create_options_sync_io_alert,
19970 		{ "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
19971 		TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
19972 
19973 	{ &hf_smb_nt_create_options_sync_io_nonalert,
19974 		{ "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
19975 		TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
19976 
19977 	{ &hf_smb_nt_create_options_non_directory_file,
19978 		{ "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
19979 		TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
19980 
19981 	{ &hf_smb_nt_create_options_create_tree_connection,
19982 		{ "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
19983 		TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
19984 
19985 	{ &hf_smb_nt_create_options_complete_if_oplocked,
19986 		{ "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
19987 		TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
19988 
19989 	{ &hf_smb_nt_create_options_no_ea_knowledge,
19990 		{ "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
19991 		TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
19992 
19993 	{ &hf_smb_nt_create_options_eight_dot_three_only,
19994 		{ "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
19995 		TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
19996 
19997 	{ &hf_smb_nt_create_options_random_access,
19998 		{ "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
19999 		TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
20000 
20001 	{ &hf_smb_nt_create_options_delete_on_close,
20002 		{ "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
20003 		TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
20004 	{ &hf_smb_nt_create_options_open_by_fileid,
20005 		{ "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
20006 		TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
20007 
20008 	{ &hf_smb_nt_create_options_backup_intent,
20009 		{ "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
20010 		TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
20011 
20012 	{ &hf_smb_nt_create_options_no_compression,
20013 		{ "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
20014 		TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
20015 
20016 	{ &hf_smb_nt_create_options_reserve_opfilter,
20017 		{ "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
20018 		TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
20019 
20020 	{ &hf_smb_nt_create_options_open_reparse_point,
20021 		{ "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
20022 		TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
20023 
20024 	{ &hf_smb_nt_create_options_open_no_recall,
20025 		{ "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
20026 		TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
20027 
20028 	{ &hf_smb_nt_create_options_open_for_free_space_query,
20029 		{ "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
20030 		TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
20031 
20032 	{ &hf_smb_nt_share_access_read,
20033 		{ "Read", "smb.share.access.read", FT_BOOLEAN, 32,
20034 		TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
20035 
20036 	{ &hf_smb_nt_share_access_write,
20037 		{ "Write", "smb.share.access.write", FT_BOOLEAN, 32,
20038 		TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
20039 
20040 	{ &hf_smb_nt_share_access_delete,
20041 		{ "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
20042 		TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, NULL, HFILL }},
20043 
20044 	{ &hf_smb_file_eattr,
20045 		{ "File Attributes", "smb.file_attribute", FT_UINT32, BASE_HEX,
20046 		NULL, 0x0, NULL, HFILL }},
20047 
20048 	{ &hf_smb_file_eattr_read_only,
20049 		{ "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
20050 		TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
20051 
20052 	{ &hf_smb_file_eattr_hidden,
20053 		{ "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
20054 		TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
20055 
20056 	{ &hf_smb_file_eattr_system,
20057 		{ "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
20058 		TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
20059 
20060 	{ &hf_smb_file_eattr_volume,
20061 		{ "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
20062 		TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
20063 
20064 	{ &hf_smb_file_eattr_directory,
20065 		{ "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
20066 		TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
20067 
20068 	{ &hf_smb_file_eattr_archive,
20069 		{ "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
20070 		TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
20071 
20072 	{ &hf_smb_file_eattr_device,
20073 		{ "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
20074 		TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
20075 
20076 	{ &hf_smb_file_eattr_normal,
20077 		{ "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
20078 		TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
20079 
20080 	{ &hf_smb_file_eattr_temporary,
20081 		{ "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
20082 		TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
20083 
20084 	{ &hf_smb_file_eattr_sparse,
20085 		{ "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
20086 		TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
20087 
20088 	{ &hf_smb_file_eattr_reparse,
20089 		{ "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
20090 		TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
20091 
20092 	{ &hf_smb_file_eattr_compressed,
20093 		{ "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
20094 		TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
20095 
20096 	{ &hf_smb_file_eattr_offline,
20097 		{ "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
20098 		TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
20099 
20100 	{ &hf_smb_file_eattr_not_content_indexed,
20101 		{ "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
20102 		TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
20103 
20104 	{ &hf_smb_file_eattr_encrypted,
20105 		{ "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
20106 		TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
20107 
20108 	{ &hf_smb_size_returned_quota_data,
20109 		{ "Size of returned Quota data", "smb.size_returned_quota_data", FT_UINT32, BASE_DEC,
20110 		NULL, 0x0, NULL, HFILL }},
20111 
20112 	{ &hf_smb_sec_desc_len,
20113 		{ "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
20114 		NULL, 0, "Security Descriptor Length", HFILL }},
20115 
20116 	{ &hf_smb_nt_qsd,
20117 		{ "Security Information", "smb.nt_qsd", FT_UINT32, BASE_HEX,
20118 		NULL, 0x0, NULL, HFILL }},
20119 
20120 	{ &hf_smb_nt_qsd_owner,
20121 		{ "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
20122 		TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security information being queried?", HFILL }},
20123 
20124 	{ &hf_smb_nt_qsd_group,
20125 		{ "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
20126 		TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security information being queried?", HFILL }},
20127 
20128 	{ &hf_smb_nt_qsd_dacl,
20129 		{ "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
20130 		TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security information being queried?", HFILL }},
20131 
20132 	{ &hf_smb_nt_qsd_sacl,
20133 		{ "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
20134 		TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security information being queried?", HFILL }},
20135 
20136 	{ &hf_smb_extended_attributes,
20137 		{ "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_NONE,
20138 		NULL, 0, NULL, HFILL }},
20139 
20140 	{ &hf_smb_oplock_level,
20141 		{ "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
20142 		VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
20143 
20144 	{ &hf_smb_response_type,
20145 		{ "Response type", "smb.response_type", FT_UINT8, BASE_HEX,
20146 		VALS(response_type_vals), 0, "NT Transaction Create response type", HFILL }},
20147 
20148 	{ &hf_smb_create_action,
20149 		{ "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
20150 		VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
20151 
20152 	{ &hf_smb_file_id,
20153 		{ "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
20154 		NULL, 0, NULL, HFILL }},
20155 
20156 	{ &hf_smb_file_id_64bit,
20157 		{ "Server unique 64-bit file ID", "smb.create.file_id_64b", FT_UINT64, BASE_HEX,
20158 		NULL, 0, NULL, HFILL }},
20159 
20160 	{ &hf_smb_ea_error_offset,
20161 		{ "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
20162 		NULL, 0, "Offset into EA list if EA error", HFILL }},
20163 
20164 	{ &hf_smb_end_of_file,
20165 		{ "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
20166 		NULL, 0, "Offset to the first free byte in the file", HFILL }},
20167 
20168 	{ &hf_smb_replace,
20169 		{ "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
20170 		TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
20171 
20172 	{ &hf_smb_root_dir_handle,
20173 		{ "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
20174 		NULL, 0, NULL, HFILL }},
20175 
20176 	{ &hf_smb_target_name_len,
20177 		{ "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
20178 		NULL, 0, "Length of target file name", HFILL }},
20179 
20180 	{ &hf_smb_target_name,
20181 		{ "Target name", "smb.target_name", FT_STRING, STR_UNICODE,
20182 		NULL, 0, "Target file name", HFILL }},
20183 
20184 	{ &hf_smb_device_type,
20185 		{ "Device Type", "smb.device.type", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
20186 		&device_type_vals_ext, 0, "Type of device", HFILL }},
20187 
20188 	{ &hf_smb_is_directory,
20189 		{ "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
20190 		VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
20191 
20192 	{ &hf_smb_next_entry_offset,
20193 		{ "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
20194 		NULL, 0, "Offset to next entry", HFILL }},
20195 
20196 	{ &hf_smb_change_time,
20197 		{ "Change", "smb.change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20198 		NULL, 0, "Last Change Time", HFILL }},
20199 
20200 	{ &hf_smb_setup_len,
20201 		{ "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
20202 		NULL, 0, "Length of printer setup data", HFILL }},
20203 
20204 	{ &hf_smb_print_mode,
20205 		{ "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
20206 		VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
20207 
20208 	{ &hf_smb_print_identifier,
20209 		{ "Identifier", "smb.print.identifier", FT_STRING, STR_UNICODE,
20210 		NULL, 0, "Identifier string for this print job", HFILL }},
20211 
20212 	{ &hf_smb_restart_index,
20213 		{ "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
20214 		NULL, 0, "Index of entry after last returned", HFILL }},
20215 
20216 	{ &hf_smb_print_queue_date,
20217 		{ "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20218 		NULL, 0, "Date when this entry was queued", HFILL }},
20219 
20220 	{ &hf_smb_print_queue_dos_date,
20221 		{ "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
20222 		NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
20223 
20224 	{ &hf_smb_print_queue_dos_time,
20225 		{ "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
20226 		NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
20227 
20228 	{ &hf_smb_print_status,
20229 		{ "Status", "smb.print.status", FT_UINT8, BASE_HEX,
20230 		VALS(print_status_vals), 0, "Status of this entry", HFILL }},
20231 
20232 	{ &hf_smb_print_spool_file_number,
20233 		{ "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
20234 		NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
20235 
20236 	{ &hf_smb_print_spool_file_size,
20237 		{ "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
20238 		NULL, 0, "Number of bytes in spool file", HFILL }},
20239 
20240 	{ &hf_smb_print_spool_file_name,
20241 		{ "Name", "smb.print.spool.name", FT_STRINGZ, STR_UNICODE,
20242 		NULL, 0, "Name of client that submitted this job", HFILL }},
20243 
20244 	{ &hf_smb_start_index,
20245 		{ "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
20246 		NULL, 0, "First queue entry to return", HFILL }},
20247 
20248 	{ &hf_smb_originator_name,
20249 		{ "Originator Name", "smb.originator_name", FT_STRINGZ, STR_UNICODE,
20250 		NULL, 0, "Name of sender of message", HFILL }},
20251 
20252 	{ &hf_smb_destination_name,
20253 		{ "Destination Name", "smb.destination_name", FT_STRINGZ, STR_UNICODE,
20254 		NULL, 0, "Name of recipient of message", HFILL }},
20255 
20256 	{ &hf_smb_message_len,
20257 		{ "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
20258 		NULL, 0, "Length of message", HFILL }},
20259 
20260 	{ &hf_smb_message,
20261 		{ "Message", "smb.message", FT_STRING, STR_UNICODE,
20262 		NULL, 0, "Message text", HFILL }},
20263 
20264 	{ &hf_smb_mgid,
20265 		{ "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
20266 		NULL, 0, "Message group ID for multi-block messages", HFILL }},
20267 
20268 	{ &hf_smb_forwarded_name,
20269 		{ "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, STR_UNICODE,
20270 		NULL, 0, "Recipient name being forwarded", HFILL }},
20271 
20272 	{ &hf_smb_machine_name,
20273 		{ "Machine Name", "smb.machine_name", FT_STRINGZ, STR_UNICODE,
20274 		NULL, 0, "Name of target machine", HFILL }},
20275 
20276 	{ &hf_smb_cancel_to,
20277 		{ "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
20278 		NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
20279 
20280 	{ &hf_smb_trans_name,
20281 		{ "Transaction Name", "smb.trans_name", FT_STRING, STR_UNICODE,
20282 		NULL, 0, "Name of transaction", HFILL }},
20283 
20284 	{ &hf_smb_transaction_flags,
20285 		{ "Flags", "smb.transaction.flags", FT_UINT16, BASE_HEX,
20286 		NULL, 0x0, NULL, HFILL }},
20287 
20288 	{ &hf_smb_transaction_flags_dtid,
20289 		{ "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
20290 		TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
20291 
20292 	{ &hf_smb_transaction_flags_owt,
20293 		{ "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
20294 		TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
20295 
20296 	{ &hf_smb_search_count,
20297 		{ "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
20298 		NULL, 0, "Maximum number of search entries to return", HFILL }},
20299 
20300 	{ &hf_smb_search_pattern,
20301 		{ "Search Pattern", "smb.search_pattern", FT_STRING, STR_UNICODE,
20302 		NULL, 0, NULL, HFILL }},
20303 
20304 	{ &hf_smb_ff2,
20305 		{ "Flags", "smb.find_first2.flags", FT_UINT16, BASE_HEX,
20306 		NULL, 0x0, NULL, HFILL }},
20307 
20308 	{ &hf_smb_ff2_backup,
20309 		{ "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
20310 		TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
20311 
20312 	{ &hf_smb_ff2_continue,
20313 		{ "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
20314 		TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
20315 
20316 	{ &hf_smb_ff2_resume,
20317 		{ "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
20318 		TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
20319 
20320 	{ &hf_smb_ff2_close_eos,
20321 		{ "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
20322 		TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
20323 
20324 	{ &hf_smb_ff2_close,
20325 		{ "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
20326 		TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
20327 
20328 	{ &hf_smb_ff2_information_level,
20329 		{ "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
20330 		VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
20331 
20332 	{ &hf_smb_qpi_loi,
20333 		{ "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
20334 		VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
20335 
20336 	{ &hf_smb_spi_loi,
20337 		{ "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
20338 		&spi_loi_vals_ext, 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
20339 
20340 #if 0
20341 	{ &hf_smb_sfi,
20342 		{ "IO Flag", "smb.sfi_flags", FT_UINT16, BASE_HEX,
20343 		NULL, 0x0, NULL, HFILL }},
20344 
20345 	{ &hf_smb_sfi_writetru,
20346 		{ "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
20347 		TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
20348 
20349 	{ &hf_smb_sfi_caching,
20350 		{ "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
20351 		TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
20352 #endif
20353 
20354 	{ &hf_smb_storage_type,
20355 		{ "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
20356 		NULL, 0, "Type of storage", HFILL }},
20357 
20358 	{ &hf_smb_resume,
20359 		{ "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
20360 		NULL, 0, NULL, HFILL }},
20361 
20362 	{ &hf_smb_max_referral_level,
20363 		{ "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
20364 		NULL, 0, "Latest referral version number understood", HFILL }},
20365 
20366 	{ &hf_smb_qfsi_information_level,
20367 		{ "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX | BASE_EXT_STRING,
20368 		&qfsi_vals_ext, 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
20369 
20370 	{ &hf_smb_sfsi_information_level,
20371 		{ "Level of Interest", "smb.sfsi_loi", FT_UINT16, BASE_HEX,
20372 		VALS(sfsi_vals), 0, "Level of interest for SET_FS_INFORMATION2 command", HFILL }},
20373 
20374 	{ &hf_smb_nt_rename_level,
20375 		{ "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
20376 		VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
20377 
20378 	{ &hf_smb_cluster_count,
20379 		{ "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
20380 		NULL, 0, "Number of clusters", HFILL }},
20381 
20382 	{ &hf_smb_number_of_links,
20383 		{ "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
20384 		NULL, 0, "Number of hard links to the file", HFILL }},
20385 
20386 	{ &hf_smb_delete_pending,
20387 		{ "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
20388 		VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
20389 
20390 	{ &hf_smb_index_number,
20391 		{ "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
20392 		NULL, 0, "File system unique identifier", HFILL }},
20393 
20394 	{ &hf_smb_position,
20395 		{ "Position", "smb.position", FT_UINT64, BASE_DEC,
20396 		NULL, 0, "File position", HFILL }},
20397 
20398 #if 0
20399 	{ &hf_smb_current_offset,
20400 		{ "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
20401 		NULL, 0, "Current offset in the file", HFILL }},
20402 #endif
20403 
20404 	{ &hf_smb_t2_alignment,
20405 		{ "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
20406 		VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
20407 
20408 	{ &hf_smb_t2_stream_name_length,
20409 		{ "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
20410 		NULL, 0, "Length of stream name", HFILL }},
20411 
20412 	{ &hf_smb_t2_stream_size,
20413 		{ "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
20414 		NULL, 0, "Size of the stream in number of bytes", HFILL }},
20415 
20416 	{ &hf_smb_t2_stream_name,
20417 		{ "Stream Name", "smb.stream_name", FT_STRING, STR_UNICODE,
20418 		NULL, 0, "Name of the stream", HFILL }},
20419 
20420 	{ &hf_smb_t2_compressed_file_size,
20421 		{ "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
20422 		NULL, 0, "Size of the compressed file", HFILL }},
20423 
20424 	{ &hf_smb_t2_compressed_format,
20425 		{ "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
20426 		NULL, 0, "Compression algorithm used", HFILL }},
20427 
20428 	{ &hf_smb_t2_compressed_unit_shift,
20429 		{ "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
20430 		NULL, 0, "Size of the stream in number of bytes", HFILL }},
20431 
20432 	{ &hf_smb_t2_compressed_chunk_shift,
20433 		{ "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
20434 		NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
20435 
20436 	{ &hf_smb_t2_compressed_cluster_shift,
20437 		{ "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
20438 		NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
20439 
20440 	{ &hf_smb_t2_marked_for_deletion,
20441 		{ "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
20442 		TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
20443 
20444 	{ &hf_smb_dfs_path_consumed,
20445 		{ "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
20446 		NULL, 0, "Number of RequestFilename bytes client", HFILL }},
20447 
20448 	{ &hf_smb_dfs_num_referrals,
20449 		{ "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
20450 		NULL, 0, "Number of referrals in this pdu", HFILL }},
20451 
20452 	{ &hf_smb_get_dfs_flags,
20453 		{ "Flags", "smb.dfs.flags", FT_UINT16, BASE_HEX,
20454 		NULL, 0x0, NULL, HFILL }},
20455 
20456 	{ &hf_smb_get_dfs_server_hold_storage,
20457 		{ "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
20458 		TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
20459 
20460 	{ &hf_smb_get_dfs_fielding,
20461 		{ "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
20462 		TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
20463 
20464 	{ &hf_smb_dfs_referral_version,
20465 		{ "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
20466 		NULL, 0, "Version of referral element", HFILL }},
20467 
20468 	{ &hf_smb_dfs_referral_size,
20469 		{ "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
20470 		NULL, 0, "Size of referral element", HFILL }},
20471 
20472 	{ &hf_smb_dfs_referral_server_type,
20473 		{ "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
20474 		VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
20475 
20476 	{ &hf_smb_dfs_referral_flags,
20477 		{ "Flags", "smb.dfs.referral.flags", FT_UINT16, BASE_HEX,
20478 		NULL, 0x0, NULL, HFILL }},
20479 
20480 	{ &hf_smb_dfs_referral_flags_name_list_referral,
20481 		{ "NameListReferral", "smb.dfs.referral.flags.name_list_referral", FT_BOOLEAN, 16,
20482 		TFS(&tfs_dfs_referral_flags_name_list_referral), REFENT_FLAGS_NAME_LIST_REFERRAL, "Is a domain/DC referral response?", HFILL }},
20483 
20484 	{ &hf_smb_dfs_referral_flags_target_set_boundary,
20485 		{ "TargetSetBoundary", "smb.dfs.referral.flags.target_set_boundary", FT_BOOLEAN, 16,
20486 		TFS(&tfs_dfs_referral_flags_target_set_boundary), REFENT_FLAGS_TARGET_SET_BOUNDARY, "Is this a first target in the target set?", HFILL }},
20487 
20488 	{ &hf_smb_dfs_referral_node_offset,
20489 		{ "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
20490 		NULL, 0, "Offset of name of entity to visit next", HFILL }},
20491 
20492 	{ &hf_smb_dfs_referral_node,
20493 		{ "Node", "smb.dfs.referral.node", FT_STRING, STR_UNICODE,
20494 		NULL, 0, "Name of entity to visit next", HFILL }},
20495 
20496 	{ &hf_smb_dfs_referral_proximity,
20497 		{ "Proximity", "smb.dfs.referral.proximity", FT_UINT32, BASE_DEC,
20498 		NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
20499 
20500 	{ &hf_smb_dfs_referral_ttl,
20501 		{ "TTL", "smb.dfs.referral.ttl", FT_UINT32, BASE_DEC,
20502 		NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
20503 
20504 	{ &hf_smb_dfs_referral_path_offset,
20505 		{ "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
20506 		NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20507 
20508 	{ &hf_smb_dfs_referral_path,
20509 		{ "Path", "smb.dfs.referral.path", FT_STRING, STR_UNICODE,
20510 		NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
20511 
20512 	{ &hf_smb_dfs_referral_alt_path_offset,
20513 		{ "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
20514 		NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
20515 
20516 	{ &hf_smb_dfs_referral_alt_path,
20517 		{ "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, STR_UNICODE,
20518 		NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
20519 
20520 	{ &hf_smb_dfs_referral_domain_offset,
20521 		{ "Domain Offset", "smb.dfs.referral.domain_offset", FT_UINT16, BASE_DEC,
20522 		NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20523 
20524 	{ &hf_smb_dfs_referral_number_of_expnames,
20525 		{ "Number of Expanded Names", "smb.dfs.referral.number_of_expnames", FT_UINT16, BASE_DEC,
20526 		NULL, 0, NULL, HFILL }},
20527 
20528 	{ &hf_smb_dfs_referral_expnames_offset,
20529 		{ "Expanded Names Offset", "smb.dfs.referral.expnames_offset", FT_UINT16, BASE_DEC,
20530 		NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20531 
20532 	{ &hf_smb_dfs_referral_domain_name,
20533 		{ "Domain Name", "smb.dfs.referral.domain_name", FT_STRING, STR_UNICODE,
20534 		NULL, 0, "Dfs referral domain name", HFILL }},
20535 
20536 	{ &hf_smb_dfs_referral_expname,
20537 		{ "Expanded Name", "smb.dfs.referral.expname", FT_STRING, STR_UNICODE,
20538 		NULL, 0, "Dfs expanded name", HFILL }},
20539 
20540 	{ &hf_smb_dfs_referral_server_guid,
20541 		{ "Server GUID", "smb.dfs.referral.server_guid", FT_GUID, BASE_NONE,
20542 		NULL, 0, "Globally unique identifier for this server", HFILL }},
20543 
20544 	{ &hf_smb_end_of_search,
20545 		{ "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
20546 		NULL, 0, "Was last entry returned?", HFILL }},
20547 
20548 	{ &hf_smb_last_name_offset,
20549 		{ "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
20550 		NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
20551 
20552 	{ &hf_smb_fn_information_level,
20553 		{ "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
20554 		NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
20555 
20556 	{ &hf_smb_monitor_handle,
20557 		{ "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
20558 		NULL, 0, "Handle for Find Notify operations", HFILL }},
20559 
20560 	{ &hf_smb_change_count,
20561 		{ "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
20562 		NULL, 0, "Number of changes to wait for", HFILL }},
20563 
20564 	{ &hf_smb_file_index,
20565 		{ "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
20566 		NULL, 0, NULL, HFILL }},
20567 
20568 	{ &hf_smb_short_file_name,
20569 		{ "Short File Name", "smb.short_file", FT_STRING, STR_UNICODE,
20570 		NULL, 0, "Short (8.3) File Name", HFILL }},
20571 
20572 	{ &hf_smb_short_file_name_len,
20573 		{ "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
20574 		NULL, 0, "Length of Short (8.3) File Name", HFILL }},
20575 
20576 	{ &hf_smb_fs_id,
20577 		{ "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
20578 		NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
20579 
20580 	{ &hf_smb_sector_unit,
20581 		{ "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
20582 		NULL, 0, "Sectors per allocation unit", HFILL }},
20583 
20584 	{ &hf_smb_fs_units,
20585 		{ "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
20586 		NULL, 0, "Total number of units on this filesystem", HFILL }},
20587 
20588 	{ &hf_smb_fs_sector,
20589 		{ "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
20590 		NULL, 0, NULL, HFILL }},
20591 
20592 	{ &hf_smb_avail_units,
20593 		{ "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
20594 		NULL, 0, "Total number of available units on this filesystem", HFILL }},
20595 
20596 	{ &hf_smb_volume_serial_num,
20597 		{ "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
20598 		NULL, 0, NULL, HFILL }},
20599 
20600 	{ &hf_smb_volume_label_len,
20601 		{ "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
20602 		NULL, 0, "Length of volume label", HFILL }},
20603 
20604 	{ &hf_smb_volume_label,
20605 		{ "Label", "smb.volume.label", FT_STRING, STR_UNICODE,
20606 		NULL, 0, "Volume label", HFILL }},
20607 
20608 	{ &hf_smb_free_alloc_units64,
20609 		{ "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
20610 		NULL, 0, "Number of free allocation units", HFILL }},
20611 
20612 	{ &hf_smb_caller_free_alloc_units64,
20613 		{ "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
20614 		NULL, 0, "Number of caller free allocation units", HFILL }},
20615 
20616 	{ &hf_smb_actual_free_alloc_units64,
20617 		{ "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
20618 		NULL, 0, "Number of actual free allocation units", HFILL }},
20619 
20620 	{ &hf_smb_soft_quota_limit,
20621 		{ "(Soft) Quota Threshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
20622 		NULL, 0, "Soft Quota threshold", HFILL }},
20623 
20624 	{ &hf_smb_hard_quota_limit,
20625 		{ "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
20626 		NULL, 0, "Hard Quota limit", HFILL }},
20627 
20628 	{ &hf_smb_user_quota_used,
20629 		{ "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
20630 		NULL, 0, "How much Quota is used by this user", HFILL }},
20631 
20632 	{ &hf_smb_max_name_len,
20633 		{ "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
20634 		NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
20635 
20636 	{ &hf_smb_fs_name_len,
20637 		{ "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
20638 		NULL, 0, "Length of filesystem name in bytes", HFILL }},
20639 
20640 	{ &hf_smb_fs_name,
20641 		{ "FS Name", "smb.fs_name", FT_STRING, STR_UNICODE,
20642 		NULL, 0, "Name of filesystem", HFILL }},
20643 
20644 	{ &hf_smb_device_char,
20645 		{ "Device Characteristics", "smb.device", FT_UINT32, BASE_HEX,
20646 		NULL, 0x0, NULL, HFILL }},
20647 
20648 	{ &hf_smb_device_char_removable,
20649 		{ "Removable", "smb.device.removable", FT_BOOLEAN, 32,
20650 		TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
20651 
20652 	{ &hf_smb_device_char_read_only,
20653 		{ "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
20654 		TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
20655 
20656 	{ &hf_smb_device_char_floppy,
20657 		{ "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
20658 		TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
20659 
20660 	{ &hf_smb_device_char_write_once,
20661 		{ "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
20662 		TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
20663 
20664 	{ &hf_smb_device_char_remote,
20665 		{ "Remote", "smb.device.remote", FT_BOOLEAN, 32,
20666 		TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
20667 
20668 	{ &hf_smb_device_char_mounted,
20669 		{ "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
20670 		TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
20671 
20672 	{ &hf_smb_device_char_virtual,
20673 		{ "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
20674 		TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
20675 
20676 	{ &hf_smb_device_char_secure_open,
20677 		{ "Secure Open", "smb.device.secure_open", FT_BOOLEAN, 32,
20678 		TFS(&tfs_device_char_secure_open), 0x00000100, "Is this a secure open device", HFILL }},
20679 
20680 	{ &hf_smb_device_char_ts,
20681 		{ "Terminal Services", "smb.device.ts", FT_BOOLEAN, 32,
20682 		TFS(&tfs_device_char_ts), 0x00001000, "Is this a terminal services device", HFILL }},
20683 
20684 	{ &hf_smb_device_char_webdav,
20685 		{ "Webdav", "smb.device.webdav", FT_BOOLEAN, 32,
20686 		TFS(&tfs_device_char_webdav), 0x00002000, "Is this a WEBDAV device", HFILL }},
20687 
20688 	{ &hf_smb_device_char_aat,
20689 		{ "Allow Appcontainer Traversal", "smb.device.aat", FT_BOOLEAN, 32,
20690 		TFS(&tfs_device_char_aat), 0x00020000, "Does this device allow appcontainer traversal", HFILL }},
20691 
20692 	{ &hf_smb_device_char_portable,
20693 		{ "Portable", "smb.device.portable", FT_BOOLEAN, 32,
20694 		TFS(&tfs_device_char_portable), 0x00004000, "Is this a portable device", HFILL }},
20695 
20696 	{ &hf_smb_fs_attr,
20697 		{ "FS Attributes", "smb.fs_attr", FT_UINT32, BASE_HEX,
20698 		NULL, 0x0, NULL, HFILL }},
20699 
20700 	{ &hf_smb_fs_attr_css,
20701 		{ "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
20702 		TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
20703 
20704 	{ &hf_smb_fs_attr_cpn,
20705 		{ "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
20706 		TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
20707 
20708 	{ &hf_smb_fs_attr_uod,
20709 		{ "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
20710 		TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
20711 
20712 	{ &hf_smb_fs_attr_pacls,
20713 		{ "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
20714 		TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
20715 
20716 	{ &hf_smb_fs_attr_fc,
20717 		{ "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
20718 		TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
20719 
20720 	{ &hf_smb_fs_attr_vq,
20721 		{ "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
20722 		TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
20723 
20724 	{ &hf_smb_fs_attr_ssf,
20725 		{ "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
20726 		TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
20727 
20728 	{ &hf_smb_fs_attr_srp,
20729 		{ "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
20730 		TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
20731 
20732 	{ &hf_smb_fs_attr_srs,
20733 		{ "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
20734 		TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
20735 
20736 	{ &hf_smb_fs_attr_sla,
20737 		{ "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
20738 		TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
20739 
20740 	{ &hf_smb_fs_attr_vic,
20741 		{ "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
20742 		TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
20743 
20744 	{ &hf_smb_fs_attr_soids,
20745 		{ "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
20746 		TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
20747 
20748 	{ &hf_smb_fs_attr_se,
20749 		{ "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
20750 		TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
20751 
20752 	{ &hf_smb_fs_attr_ns,
20753 		{ "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
20754 		TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
20755 
20756 	{ &hf_smb_fs_attr_rov,
20757 		{ "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
20758 		TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
20759 
20760 	{ &hf_smb_fs_attr_swo,
20761 		{ "Sequential Write Once", "smb.fs_attr.swo", FT_BOOLEAN, 32,
20762 		TFS(&tfs_fs_attr_swo), 0x00100000, "Is this FS on a sequential write once volume?", HFILL }},
20763 
20764 	{ &hf_smb_fs_attr_st,
20765 		{ "Transactions", "smb.fs_attr.st", FT_BOOLEAN, 32,
20766 		TFS(&tfs_fs_attr_st), 0x00200000, "Does this FS support transactions?", HFILL }},
20767 
20768 	{ &hf_smb_fs_attr_shl,
20769 		{ "Hard Links", "smb.fs_attr.shl", FT_BOOLEAN, 32,
20770 		TFS(&tfs_fs_attr_shl), 0x00400000, "Does this FS support hard links?", HFILL }},
20771 
20772 	{ &hf_smb_fs_attr_sis,
20773 		{ "Integrity Streams", "smb.fs_attr.sis", FT_BOOLEAN, 32,
20774 		TFS(&tfs_fs_attr_sis), 0x04000000, "Does this FS support integrity streams?", HFILL }},
20775 
20776 	{ &hf_smb_fs_attr_sbr,
20777 		{ "Block Refcounting", "smb.fs_attr.sbr", FT_BOOLEAN, 32,
20778 		TFS(&tfs_fs_attr_sbr), 0x08000000, "Does this FS support block refcounting?", HFILL }},
20779 
20780 	{ &hf_smb_fs_attr_ssv,
20781 		{ "Sparse VDL", "smb.fs_attr.ssv", FT_BOOLEAN, 32,
20782 		TFS(&tfs_fs_attr_ssv), 0x10000000, "Does this FS support sparse VDL?", HFILL }},
20783 
20784 	{ &hf_smb_user_quota_change_time,
20785 		{ "Change Time", "smb.quota.user.change_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20786 		NULL, 0x0, "The last time the quota was changed", HFILL }},
20787 
20788 	{ &hf_smb_length_of_sid,
20789 		{ "Length of SID", "smb.length_of_sid", FT_UINT32, BASE_DEC,
20790 		NULL, 0x0, NULL, HFILL }},
20791 
20792 	{ &hf_smb_user_quota_offset,
20793 		{ "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
20794 		NULL, 0, "Relative offset to next user quota structure", HFILL }},
20795 
20796 	{ &hf_smb_pipe_write_len,
20797 		{ "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
20798 		NULL, 0, "Number of bytes written to pipe", HFILL }},
20799 
20800 	{ &hf_smb_quota_flags_deny_disk,
20801 		{ "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
20802 		TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
20803 
20804 	{ &hf_smb_quota_flags_log_limit,
20805 		{ "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
20806 		TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
20807 
20808 	{ &hf_smb_quota_flags_log_warning,
20809 		{ "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
20810 		TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
20811 
20812 	{ &hf_smb_quota_flags,
20813 		{ "Quota Flags", "smb.quota.flags", FT_UINT8, BASE_HEX,
20814 		NULL, 0x0, NULL, HFILL }},
20815 
20816 	{ &hf_smb_quota_flags_enabled,
20817 		{ "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
20818 		TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
20819 
20820 	{ &hf_smb_segment_overlap,
20821 		{ "Fragment overlap",	"smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20822 			"Fragment overlaps with other fragments", HFILL }},
20823 
20824 	{ &hf_smb_segment_overlap_conflict,
20825 		{ "Conflicting data in fragment overlap",	"smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20826 			"Overlapping fragments contained conflicting data", HFILL }},
20827 
20828 	{ &hf_smb_segment_multiple_tails,
20829 		{ "Multiple tail fragments found",	"smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20830 			"Several tails were found when defragmenting the packet", HFILL }},
20831 
20832 	{ &hf_smb_segment_too_long_fragment,
20833 		{ "Fragment too long",	"smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20834 			"Fragment contained data past end of packet", HFILL }},
20835 
20836 	{ &hf_smb_segment_error,
20837 		{ "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20838 			"Defragmentation error due to illegal fragments", HFILL }},
20839 
20840 	{ &hf_smb_segment_count,
20841 		{ "Fragment count", "smb.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
20842 			NULL, HFILL }},
20843 
20844 	{ &hf_smb_reassembled_length,
20845 		{ "Reassembled SMB length", "smb.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
20846 			"The total length of the reassembled payload", HFILL }},
20847 
20848 	{ &hf_smb_opened_in,
20849 		{ "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20850 			"The frame this fid was opened", HFILL }},
20851 
20852 	{ &hf_smb_closed_in,
20853 		{ "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20854 			"The frame this fid was closed", HFILL }},
20855 
20856 	{ &hf_smb_mapped_in,
20857 		{ "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20858 			"The frame this share was mapped", HFILL }},
20859 
20860 	{ &hf_smb_unmapped_in,
20861 		{ "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20862 			"The frame this share was unmapped", HFILL }},
20863 
20864 	{ &hf_smb_segment,
20865 		{ "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20866 			NULL, HFILL }},
20867 
20868 	{ &hf_smb_segments,
20869 		{ "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
20870 			NULL, HFILL }},
20871 
20872 	{ &hf_smb_unix_major_version,
20873 	  { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
20874 	    NULL, 0, "UNIX Major Version", HFILL }},
20875 
20876 	{ &hf_smb_unix_minor_version,
20877 	  { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
20878 	    NULL, 0, "UNIX Minor Version", HFILL }},
20879 
20880 	{ &hf_smb_unix_capability,
20881 		{ "Capabilities", "smb.unix.capability", FT_UINT64, BASE_HEX,
20882 		NULL, 0x0, NULL, HFILL }},
20883 
20884 	{ &hf_smb_unix_capability_fcntl,
20885 	  { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
20886 		TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20887 
20888 	{ &hf_smb_unix_capability_posix_acl,
20889 	  { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
20890 		TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20891 
20892 	{ &hf_smb_unix_capability_xattr,
20893 	  { "EA Capability", "smb.unix.capability.ea", FT_BOOLEAN, 32,
20894 		TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20895 
20896 	{ &hf_smb_unix_capability_attr,
20897 	  { "Additional Attributes Capability", "smb.unix.capability.attr", FT_BOOLEAN, 32,
20898 		TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20899 
20900 	{ &hf_smb_unix_capability_posix_paths,
20901 	  { "POSIX Pathnames Capability", "smb.unix.capability.posix_paths", FT_BOOLEAN, 32,
20902 		TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20903 
20904 	{ &hf_smb_unix_capability_posix_path_ops,
20905 	  { "POSIX Path Operations Capability", "smb.unix.capability.posix_path_ops", FT_BOOLEAN, 32,
20906 		TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20907 
20908 	{ &hf_smb_unix_capability_large_read,
20909 	  { "Large Read Capability", "smb.unix.capability.large_read", FT_BOOLEAN, 32,
20910 		TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
20911 
20912 	{ &hf_smb_unix_capability_large_write,
20913 	  { "Large Write Capability", "smb.unix.capability.large_write", FT_BOOLEAN, 32,
20914 		TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20915 
20916 	{ &hf_smb_unix_capability_encryption,
20917 	  { "Encryption Capability", "smb.unix.capability.encryption", FT_BOOLEAN, 32,
20918 		TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20919 
20920 	{ &hf_smb_unix_capability_mandatory_crypto,
20921 	  { "Mandatory Encryption Capability", "smb.unix.capability.mandatory_crypto", FT_BOOLEAN, 32,
20922 		TFS(&tfs_set_notset), 0x00000200, NULL, HFILL }},
20923 
20924 	{ &hf_smb_unix_capability_proxy,
20925 	  { "Proxy Capability", "smb.unix.capability.proxy", FT_BOOLEAN, 32,
20926 		TFS(&tfs_set_notset), 0x00000400, NULL, HFILL }},
20927 
20928 	{ &hf_smb_file_access_mask_read_data,
20929 	  { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
20930 		TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20931 
20932 	{ &hf_smb_file_access_mask_write_data,
20933 	  { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
20934 		TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20935 
20936 	{ &hf_smb_file_access_mask_append_data,
20937 	  { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
20938 		TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20939 
20940 	{ &hf_smb_file_access_mask_read_ea,
20941 	  { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
20942 		TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20943 
20944 	{ &hf_smb_file_access_mask_write_ea,
20945 	  { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
20946 		TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20947 
20948 	{ &hf_smb_file_access_mask_execute,
20949 	  { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
20950 		TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20951 
20952 	{ &hf_smb_file_access_mask_read_attribute,
20953 	  { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
20954 		TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20955 
20956 	{ &hf_smb_file_access_mask_write_attribute,
20957 	  { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
20958 		TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20959 
20960 	{ &hf_smb_dir_access_mask_list,
20961 	  { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
20962 		TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20963 
20964 	{ &hf_smb_dir_access_mask_add_file,
20965 	  { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
20966 		TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20967 
20968 	{ &hf_smb_dir_access_mask_add_subdir,
20969 	  { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
20970 		TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20971 
20972 	{ &hf_smb_dir_access_mask_read_ea,
20973 	  { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
20974 		TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20975 
20976 	{ &hf_smb_dir_access_mask_write_ea,
20977 	  { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
20978 		TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20979 
20980 	{ &hf_smb_dir_access_mask_traverse,
20981 	  { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
20982 		TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20983 
20984 	{ &hf_smb_dir_access_mask_delete_child,
20985 	  { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
20986 		TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
20987 
20988 	{ &hf_smb_dir_access_mask_read_attribute,
20989 	  { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
20990 		TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20991 
20992 	{ &hf_smb_dir_access_mask_write_attribute,
20993 	  { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
20994 		TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20995 
20996 	{ &hf_smb_unix_file_link_dest,
20997 	  { "Link destination", "smb.unix.file.link_dest", FT_STRING,
20998 	    BASE_NONE, NULL, 0, NULL, HFILL }},
20999 
21000 	{ &hf_smb_unix_file_size,
21001 	  { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
21002 	    NULL, 0, NULL, HFILL }},
21003 
21004 	{ &hf_smb_unix_file_num_bytes,
21005 	  { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
21006 	    NULL, 0, "Number of bytes used to store the file", HFILL }},
21007 
21008 	{ &hf_smb_unix_file_last_status,
21009 	  { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
21010 	    NULL, 0, NULL, HFILL }},
21011 
21012 	{ &hf_smb_unix_file_last_access,
21013 	  { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
21014 	    NULL, 0, NULL, HFILL }},
21015 
21016 	{ &hf_smb_unix_file_last_change,
21017 	  { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
21018 	    NULL, 0, NULL, HFILL }},
21019 
21020 	{ &hf_smb_unix_file_creation_time,
21021 	  { "Creation time", "smb.unix.file.crtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
21022 	    NULL, 0, NULL, HFILL }},
21023 
21024 	{ &hf_smb_unix_file_uid,
21025 	  { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
21026 	    NULL, 0, NULL, HFILL }},
21027 
21028 	{ &hf_smb_unix_file_gid,
21029 	  { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
21030 	    NULL, 0, NULL, HFILL }},
21031 
21032 	{ &hf_smb_unix_file_type,
21033 	  { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
21034 	    VALS(unix_file_type_vals), 0, NULL, HFILL }},
21035 
21036 	{ &hf_smb_unix_file_dev_major,
21037 	  { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
21038 	    NULL, 0, NULL, HFILL }},
21039 
21040 	{ &hf_smb_unix_file_dev_minor,
21041 	  { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
21042 	    NULL, 0, NULL, HFILL }},
21043 
21044 	{ &hf_smb_unix_file_unique_id,
21045 	  { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
21046 	    NULL, 0, NULL, HFILL }},
21047 
21048 	{ &hf_smb_unix_file_permissions,
21049 	  { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
21050 	    NULL, 0, NULL, HFILL }},
21051 
21052 	{ &hf_smb_unix_file_nlinks,
21053 	  { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
21054 	    NULL, 0, NULL, HFILL }},
21055 
21056 	{ &hf_smb_unix_info2_file_flags,
21057 	  { "Flags", "smb.unix_info2.file.flags", FT_UINT32, BASE_HEX,
21058 	     NULL, 0, NULL, HFILL }},
21059 
21060 	{ &hf_smb_unix_info2_file_flags_mask,
21061 	  { "Flags mask", "smb.unix_info2.file.flags_mask", FT_UINT32, BASE_HEX,
21062 	     NULL, 0, NULL, HFILL }},
21063 
21064 	{ &hf_smb_unix_info2_file_flags_secure_delete,
21065 	  { "Secure delete", "smb.unix_info2.file.flags.secure_delete", FT_BOOLEAN, 32,
21066 	     NULL, 0x00000001, NULL, HFILL }},
21067 
21068 	{ &hf_smb_unix_info2_file_flags_enable_undelete,
21069 	  { "Enable undelete", "smb.unix_info2.file.flags.enable_undelete", FT_BOOLEAN, 32,
21070 	     NULL, 0x00000002, NULL, HFILL }},
21071 
21072 	{ &hf_smb_unix_info2_file_flags_synchronous,
21073 	  { "Synchronous", "smb.unix_info2.file.flags.synchronous", FT_BOOLEAN, 32,
21074 	     NULL, 0x00000004, NULL, HFILL }},
21075 
21076 	{ &hf_smb_unix_info2_file_flags_immutable,
21077 	  { "Immutable", "smb.unix_info2.file.flags.immutable", FT_BOOLEAN, 32,
21078 	     NULL, 0x00000008, NULL, HFILL }},
21079 
21080 	{ &hf_smb_unix_info2_file_flags_append_only,
21081 	  { "Append-only", "smb.unix_info2.file.flags.append_only", FT_BOOLEAN, 32,
21082 	     NULL, 0x00000010, NULL, HFILL }},
21083 
21084 	{ &hf_smb_unix_info2_file_flags_do_not_backup,
21085 	  { "Do not backup", "smb.unix_info2.file.flags.do_not_backup", FT_BOOLEAN, 32,
21086 	     NULL, 0x00000020, NULL, HFILL }},
21087 
21088 	{ &hf_smb_unix_info2_file_flags_no_update_atime,
21089 	  { "Don't update atime", "smb.unix_info2.file.flags.no_update_atime", FT_BOOLEAN, 32,
21090 	     NULL, 0x00000040, NULL, HFILL }},
21091 
21092 	{ &hf_smb_unix_info2_file_flags_hidden,
21093 	  { "Hidden", "smb.unix_info2.file.flags.hidden", FT_BOOLEAN, 32,
21094 	     NULL, 0x00000080, NULL, HFILL }},
21095 
21096 	{ &hf_smb_unix_file_name_length,
21097 	  { "File name length", "smb.unix.file.name_length", FT_UINT32, BASE_DEC,
21098 	     NULL, 0, NULL, HFILL }},
21099 
21100 	{ &hf_smb_unix_file_name,
21101 	  { "File name", "smb.unix.file.name", FT_STRING,
21102 	    STR_UNICODE, NULL, 0, NULL, HFILL }},
21103 
21104 	{ &hf_smb_unix_find_file_nextoffset,
21105 	  { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
21106 	    NULL, 0, NULL, HFILL }},
21107 
21108 	{ &hf_smb_unix_find_file_resumekey,
21109 	  { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
21110 	    NULL, 0, NULL, HFILL }},
21111 
21112 	{ &hf_smb_unix_whoami_mapflags,
21113 	  { "UNIX whoami mapping flags", "smb.unix.whoami.mapflags", FT_UINT32, BASE_DEC,
21114 	    NULL, 0, NULL, HFILL }},
21115 
21116 	{ &hf_smb_unix_whoami_mapflags_mask,
21117 	  { "UNIX whoami mapping flags mask", "smb.unix.whoami.mapflags_mask", FT_UINT32, BASE_DEC,
21118 	    NULL, 0, NULL, HFILL }},
21119 
21120 	{ &hf_smb_unix_whoami_num_supl_gids,
21121 	  { "Number of supplementary UNIX GIDs", "smb.unix.whoami.num_gids", FT_UINT32, BASE_DEC,
21122 	    NULL, 0, NULL, HFILL }},
21123 
21124 	{ &hf_smb_unix_whoami_num_supl_sids,
21125 	  { "Number of supplementary SIDs", "smb.unix.whoami.num_sids", FT_UINT32, BASE_DEC,
21126 	    NULL, 0, NULL, HFILL }},
21127 
21128 	{ &hf_smb_unix_whoami_sids_buflen,
21129 	  { "Supplementary SIDs buffer length", "smb.unix.whoami.sids_buflen", FT_UINT32, BASE_DEC,
21130 	    NULL, 0, NULL, HFILL }},
21131 
21132 	{ &hf_smb_create_flags,
21133 	  { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
21134 	    NULL, 0, NULL, HFILL }},
21135 
21136 	{ &hf_smb_create_options,
21137 	  { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
21138 	    NULL, 0, NULL, HFILL }},
21139 
21140 	{ &hf_smb_share_access,
21141 	  { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
21142 	    NULL, 0, NULL, HFILL }},
21143 
21144 	{ &hf_smb_access_mask,
21145 	  { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
21146 	    NULL, 0, NULL, HFILL }},
21147 
21148 	{ &hf_smb_mode,
21149 	  { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
21150 	    NULL, 0, NULL, HFILL }},
21151 
21152 	{ &hf_smb_attribute,
21153 	  { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
21154 	    NULL, 0, NULL, HFILL }},
21155 
21156 	{ &hf_smb_reparse_tag,
21157 	  { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
21158 	    NULL, 0, NULL, HFILL }},
21159 
21160 	{ &hf_smb_disposition_delete_on_close,
21161 	  { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
21162 	    TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
21163 
21164 	{ &hf_smb_pipe_info_flag,
21165 	  { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
21166 	    TFS(&tfs_pipe_info_flag), 0x01, NULL, HFILL }},
21167 
21168 	{ &hf_smb_logged_in,
21169 	  { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_NONE,
21170 	    NULL, 0, NULL, HFILL }},
21171 
21172 	{ &hf_smb_logged_out,
21173 	  { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_NONE,
21174 	    NULL, 0, NULL, HFILL }},
21175 
21176 	{ &hf_smb_file_rw_offset,
21177 	  { "File Offset", "smb.file.rw.offset", FT_UINT64, BASE_DEC,
21178 	    NULL, 0, NULL, HFILL }},
21179 
21180 	{ &hf_smb_file_rw_length,
21181 	  { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
21182 	    NULL, 0, NULL, HFILL }},
21183 
21184 	{ &hf_smb_posix_acl_version,
21185 	  { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
21186 	    NULL, 0, NULL, HFILL }},
21187 
21188 	{ &hf_smb_posix_num_file_aces,
21189 	  { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
21190 	    NULL, 0, NULL, HFILL }},
21191 
21192 	{ &hf_smb_posix_num_def_aces,
21193 	  { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
21194 	    NULL, 0, NULL, HFILL }},
21195 
21196 	{ &hf_smb_posix_ace_type,
21197 	  { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
21198 	    VALS(ace_type_vals), 0, NULL, HFILL }},
21199 
21200 	{ &hf_smb_posix_ace_flags,
21201 	  { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
21202 	    NULL, 0, NULL, HFILL }},
21203 
21204 	{ &hf_smb_posix_ace_perm_read,
21205 	  {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
21206 	   NULL, 0x04, NULL, HFILL}},
21207 
21208 	{ &hf_smb_posix_ace_perm_write,
21209 	  {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
21210 	   NULL, 0x02, NULL, HFILL}},
21211 
21212 	{ &hf_smb_posix_ace_perm_execute,
21213 	  {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
21214 	   NULL, 0x01, NULL, HFILL}},
21215 
21216 	{ &hf_smb_posix_ace_perm_owner_uid,
21217 	  { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
21218 	    NULL, 0, NULL, HFILL }},
21219 
21220 	{ &hf_smb_posix_ace_perm_owner_gid,
21221 	  { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
21222 	    NULL, 0, NULL, HFILL }},
21223 
21224 	{ &hf_smb_posix_ace_perm_uid,
21225 	  { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
21226 	    NULL, 0, NULL, HFILL }},
21227 
21228 	{ &hf_smb_posix_ace_perm_gid,
21229 	  { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
21230 	    NULL, 0, NULL, HFILL }},
21231 
21232 	{ &hf_smb_trans_data_setup_word,
21233 		{ "Setup Word", "smb.trans_data.setup_word", FT_UINT16, BASE_HEX,
21234 		NULL, 0x0, NULL, HFILL }},
21235 
21236 	{ &hf_smb_trans_data_parameters,
21237 		{ "Parameters", "smb.trans_data.parameters", FT_BYTES, BASE_NONE,
21238 		NULL, 0x0, NULL, HFILL }},
21239 
21240 	{ &hf_smb_trans_data,
21241 		{ "Data", "smb.trans_data", FT_BYTES, BASE_NONE,
21242 		NULL, 0x0, NULL, HFILL }},
21243 
21244 	{ &hf_smb_extra_byte_parameters,
21245 		{ "Extra byte parameters", "smb.extra_byte_parameters", FT_BYTES, BASE_NONE,
21246 		NULL, 0x0, NULL, HFILL }},
21247 
21248 	{ &hf_smb_file_access_mask_full_control,
21249 		{ "FULL CONTROL", "smb.file.accessmask.full_control", FT_UINT32, BASE_HEX,
21250 		NULL, 0x000001ff, NULL, HFILL }},
21251 
21252 	{ &hf_smb_dir_access_mask_full_control,
21253 		{ "FULL CONTROL", "smb.dir.accessmask.full_control", FT_UINT32, BASE_HEX,
21254 		NULL, 0x000001ff, NULL, HFILL }},
21255 
21256 	{ &hf_smb_word_unk_response_format,
21257 		{ "Words for unknown response format", "smb.word_unk_response_format", FT_BYTES, BASE_NONE,
21258 		NULL, 0x0, NULL, HFILL }},
21259 
21260 	{ &hf_smb_nt_transaction_setup,
21261 		{ "NT Transaction Setup", "smb.nt_transaction_setup", FT_BYTES, BASE_NONE,
21262 		NULL, 0x0, NULL, HFILL }},
21263 
21264 	{ &hf_smb_server_component,
21265 		{ "Server Component", "smb.server_component", FT_UINT32, BASE_HEX,
21266 		NULL, 0x0, NULL, HFILL }},
21267 
21268 	{ &hf_smb_byte_parameters,
21269 		{ "Byte parameters", "smb.byte_parameters", FT_BYTES, BASE_NONE,
21270 		NULL, 0x0, NULL, HFILL }},
21271 
21272 	{ &hf_smb_word_parameters,
21273 		{ "Word parameters", "smb.word_parameters", FT_BYTES, BASE_NONE,
21274 		NULL, 0x0, NULL, HFILL }},
21275 	};
21276 
21277 	static gint *ett[] = {
21278 		&ett_smb,
21279 		&ett_smb_fid,
21280 		&ett_smb_tid,
21281 		&ett_smb_uid,
21282 		&ett_smb_hdr,
21283 		&ett_smb_command,
21284 		&ett_smb_fileattributes,
21285 		&ett_smb_capabilities,
21286 		&ett_smb_aflags,
21287 		&ett_smb_dialect,
21288 		&ett_smb_dialects,
21289 		&ett_smb_mode,
21290 		&ett_smb_rawmode,
21291 		&ett_smb_flags,
21292 		&ett_smb_flags2,
21293 		&ett_smb_desiredaccess,
21294 		&ett_smb_search,
21295 		&ett_smb_file,
21296 		&ett_smb_openfunction,
21297 		&ett_smb_filetype,
21298 		&ett_smb_openaction,
21299 		&ett_smb_writemode,
21300 		&ett_smb_lock_type,
21301 		&ett_smb_ssetupandxaction,
21302 		&ett_smb_optionsup,
21303 		&ett_smb_time_date,
21304 		&ett_smb_move_copy_flags,
21305 		&ett_smb_file_attributes,
21306 		&ett_smb_search_resume_key,
21307 		&ett_smb_search_dir_info,
21308 		&ett_smb_unlocks,
21309 		&ett_smb_unlock,
21310 		&ett_smb_locks,
21311 		&ett_smb_lock,
21312 		&ett_smb_open_flags,
21313 		&ett_smb_ipc_state,
21314 		&ett_smb_open_action,
21315 		&ett_smb_setup_action,
21316 		&ett_smb_connect_flags,
21317 		&ett_smb_connect_support_bits,
21318 		&ett_smb_nt_access_mask,
21319 		&ett_smb_nt_create_bits,
21320 		&ett_smb_nt_create_options,
21321 		&ett_smb_nt_share_access,
21322 		&ett_smb_nt_security_flags,
21323 		&ett_smb_nt_trans_setup,
21324 		&ett_smb_nt_trans_data,
21325 		&ett_smb_nt_trans_param,
21326 		&ett_smb_nt_notify_completion_filter,
21327 		&ett_smb_nt_ioctl_flags,
21328 		&ett_smb_security_information_mask,
21329 		&ett_smb_print_queue_entry,
21330 		&ett_smb_transaction_flags,
21331 		&ett_smb_transaction_params,
21332 		&ett_smb_find_first2_flags,
21333 #if 0
21334 		&ett_smb_ioflag,
21335 #endif
21336 		&ett_smb_transaction_data,
21337 		&ett_smb_stream_info,
21338 		&ett_smb_dfs_referrals,
21339 		&ett_smb_dfs_referral,
21340 		&ett_smb_dfs_referral_flags,
21341 		&ett_smb_dfs_referral_expnames,
21342 		&ett_smb_get_dfs_flags,
21343 		&ett_smb_ff2_data,
21344 		&ett_smb_device_characteristics,
21345 		&ett_smb_fs_attributes,
21346 		&ett_smb_segments,
21347 		&ett_smb_segment,
21348 		&ett_smb_quotaflags,
21349 		&ett_smb_secblob,
21350 		&ett_smb_mac_support_flags,
21351 		&ett_smb_unicode_password,
21352 		&ett_smb_ea,
21353 		&ett_smb_unix_capabilities,
21354 		&ett_smb_unix_whoami_gids,
21355 		&ett_smb_unix_whoami_sids,
21356 		&ett_smb_posix_ace,
21357 		&ett_smb_posix_ace_perms,
21358 		&ett_smb_info2_file_flags
21359 	};
21360 
21361 	static ei_register_info ei[] = {
21362 		{ &ei_smb_missing_word_parameters, {"smb.missing_word_parameters", PI_MALFORMED, PI_ERROR, "The word parameters are missing, so the byte parameters cannot be dissected.", EXPFILL }},
21363 		{ &ei_smb_mal_information_level, { "smb.information_level.malformed", PI_MALFORMED, PI_ERROR, "Information level structure goes past the end of the transaction data.", EXPFILL }},
21364 		{ &ei_smb_not_implemented, { "smb.not_implemented", PI_UNDECODED, PI_WARN, "Not Implemented yet", EXPFILL }},
21365 		{ &ei_smb_nt_transaction_setup, { "smb.nt_transaction_setup.unknown", PI_PROTOCOL, PI_NOTE, "Unknown NT Transaction Setup (matching request not seen)", EXPFILL }},
21366 		{ &ei_smb_posix_ace_type, { "smb.posix_acl.ace_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown posix ace type", EXPFILL }},
21367 		{ &ei_smb_info_level_unknown, { "smb.info_level_unknown", PI_PROTOCOL, PI_WARN, "Information level unknown", EXPFILL }},
21368 		{ &ei_smb_info_level_not_understood, { "smb.info_level_not_understood", PI_PROTOCOL, PI_WARN, "Information level not understood", EXPFILL }},
21369 	};
21370 
21371 	module_t *smb_module;
21372 	expert_module_t* expert_smb;
21373 
21374 	proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
21375 	    "SMB", "smb");
21376 	proto_register_subtree_array(ett, array_length(ett));
21377 	proto_register_field_array(proto_smb, hf, array_length(hf));
21378 	expert_smb = expert_register_protocol(proto_smb);
21379 	expert_register_field_array(expert_smb, ei, array_length(ei));
21380 
21381 	proto_do_register_windows_common(proto_smb);
21382 
21383 	register_cleanup_routine(&smb_cleanup);
21384 	smb_module = prefs_register_protocol(proto_smb, NULL);
21385 	prefs_register_bool_preference(smb_module, "trans_reassembly",
21386 		"Reassemble SMB Transaction payload",
21387 		"Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
21388 		&smb_trans_reassembly);
21389 	prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
21390 		"Reassemble DCERPC over SMB",
21391 		"Whether the dissector should reassemble DCERPC over SMB commands",
21392 		&smb_dcerpc_reassembly);
21393 	prefs_register_bool_preference(smb_module, "sid_name_snooping",
21394 		"Snoop SID to Name mappings",
21395 		"Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
21396 		&sid_name_snooping);
21397 
21398 	/* For display of SIDs and RIDs in Hex option */
21399 	prefs_register_bool_preference(smb_module, "sid_display_hex",
21400 		"Display SIDs in Hex",
21401 		"Whether the dissector should display SIDs and RIDs in hexadecimal rather than decimal",
21402 		&sid_display_hex);
21403 
21404 	/* Will Export Object take name as fid ? */
21405 	prefs_register_bool_preference(smb_module, "eosmb_take_name_as_fid",
21406 		"Use the full file name as File ID when exporting an SMB object",
21407 		"Whether the export object functionality will take the full path file name as file identifier",
21408 		&eosmb_take_name_as_fid);
21409 
21410 	/*
21411 	 * XXX - addresses_ports_reassembly_table_functions?
21412 	 * Probably correct for SMB-over-NBT and SMB-over-TCP,
21413 	 * as stuff from two different connections should
21414 	 * probably not be combined, but what about other
21415 	 * transports for SMB, e.g. NBF or Netware?
21416 	 */
21417 	reassembly_table_register(&smb_trans_reassembly_table,
21418 	    &addresses_reassembly_table_functions);
21419 
21420 	smb_tap = register_tap("smb");
21421 
21422 	smb_handle = register_dissector("smb", dissect_smb, proto_smb);
21423 
21424 	register_srt_table(proto_smb, NULL, 3, smbstat_packet, smbstat_init, NULL);
21425 	/* Register the tap for the "Export Object" function */
21426 	smb_eo_tap = register_export_object(proto_smb, smb_eo_packet, smb_eo_cleanup);
21427 }
21428 
21429 void
proto_reg_handoff_smb(void)21430 proto_reg_handoff_smb(void)
21431 {
21432 	gssapi_handle  = find_dissector_add_dependency("gssapi", proto_smb);
21433 	ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_smb);
21434 
21435 	heur_dissector_add("netbios", dissect_smb_heur, "SMB over Netbios", "smb_netbios", proto_smb, HEURISTIC_ENABLE);
21436 	heur_dissector_add("smb_direct", dissect_smb_heur, "SMB over SMB Direct", "smb_smb_direct", proto_smb, HEURISTIC_ENABLE);
21437 	heur_dissector_add("cotp", dissect_smb_heur, "SMB over COTP", "smb_cotp", proto_smb, HEURISTIC_ENABLE);
21438 	heur_dissector_add("vines_spp", dissect_smb_heur, "SMB over Vines", "smb_vines", proto_smb, HEURISTIC_ENABLE);
21439 
21440 	dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
21441 	dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
21442 	dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER, smb_handle);
21443 	dissector_add_uint("spp.socket", IDP_SOCKET_SMB, smb_handle);
21444 }
21445 
21446 /*
21447  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
21448  *
21449  * Local variables:
21450  * c-basic-offset: 8
21451  * tab-width: 8
21452  * indent-tabs-mode: t
21453  * End:
21454  *
21455  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
21456  * :indentSize=8:tabSize=8:noTabs=false:
21457  */
21458