packet-smb.c: real fix for https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5778
[metze/wireshark/wip.git] / epan / dissectors / packet-smb.c
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  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27  */
28
29 #include "config.h"
30
31 #include <glib.h>
32
33 #include <epan/packet.h>
34 #include <epan/exceptions.h>
35 #include <epan/conversation.h>
36 #include <epan/wmem/wmem.h>
37 #include <epan/dissectors/packet-smb.h>
38 #include <epan/strutil.h>
39 #include <epan/prefs.h>
40 #include <epan/reassemble.h>
41 #include <epan/tap.h>
42 #include <epan/expert.h>
43 #include <epan/to_str.h>
44
45 #include "packet-ipx.h"
46 #include "packet-idp.h"
47
48 #include "packet-windows-common.h"
49 #include "packet-smb.h"
50 #include "packet-smb-common.h"
51 #include "packet-smb-mailslot.h"
52 #include "packet-smb-pipe.h"
53 #include "packet-dcerpc.h"
54 #include "packet-ntlmssp.h"
55 #include "packet-smb2.h"
56
57 void proto_register_smb(void);
58 void proto_reg_handoff_smb(void);
59
60 /*
61  * Various specifications and documents about SMB can be found in
62  *
63  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
64  *
65  * and a CIFS specification from the Storage Networking Industry Association
66  * can be found on a link from the page at
67  *
68  *      http://www.snia.org/tech_activities/CIFS
69  *
70  * (it supercedes the document at
71  *
72  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
73  *
74  * ).
75  *
76  * There are also some Open Group publications documenting CIFS available
77  * for download; catalog entries for them are at:
78  *
79  *      http://www.opengroup.org/products/publications/catalog/c209.htm
80  *
81  *      http://www.opengroup.org/products/publications/catalog/c195.htm
82  *
83  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
84  * can be found at
85  *
86  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
87  *
88  * (or, presumably a similar path under the Samba mirrors).  As the
89  * ".doc" indicates, it's a Word document.  Some of the specs from the
90  * Microsoft FTP site can be found in the
91  *
92  *      http://www.samba.org/samba/ftp/specs/
93  *
94  * directory as well.
95  *
96  * Beware - these specs may have errors.
97  *
98  * Microsoft's public protocol specifications, including MS-CIFS and
99  * other SMB-related specifications, can be found at
100  *
101  *      http://msdn.microsoft.com/en-us/library/cc216513.aspx
102  *
103  * See also
104  *
105  *      https://wiki.samba.org/index.php/UNIX_Extensions
106  */
107
108 /* DFS referral entry flags */
109 #define REFENT_FLAGS_NAME_LIST_REFERRAL  0x0002
110 #define REFENT_FLAGS_TARGET_SET_BOUNDARY 0x0004
111
112
113 static int proto_smb = -1;
114 static int hf_smb_cmd = -1;
115 static int hf_smb_andxcmd = -1;
116 static int hf_smb_mapped_in = -1;
117 static int hf_smb_unmapped_in = -1;
118 static int hf_smb_opened_in = -1;
119 static int hf_smb_closed_in = -1;
120 static int hf_smb_key = -1;
121 static int hf_smb_session_id = -1;
122 static int hf_smb_sequence_num = -1;
123 static int hf_smb_group_id = -1;
124 static int hf_smb_pid = -1;
125 static int hf_smb_tid = -1;
126 static int hf_smb_uid = -1;
127 static int hf_smb_mid = -1;
128 static int hf_smb_pid_high = -1;
129 static int hf_smb_sig = -1;
130 static int hf_smb_response_to = -1;
131 static int hf_smb_time = -1;
132 static int hf_smb_response_in = -1;
133 static int hf_smb_continuation_to = -1;
134 static int hf_smb_nt_status = -1;
135 static int hf_smb_error_class = -1;
136 static int hf_smb_error_code = -1;
137 static int hf_smb_reserved = -1;
138 static int hf_smb_create_flags = -1;
139 static int hf_smb_create_options = -1;
140 static int hf_smb_share_access = -1;
141 static int hf_smb_access_mask = -1;
142 static int hf_smb_flags = -1;
143 static int hf_smb_flags_lock = -1;
144 static int hf_smb_flags_receive_buffer = -1;
145 static int hf_smb_flags_caseless = -1;
146 static int hf_smb_flags_canon = -1;
147 static int hf_smb_flags_oplock = -1;
148 static int hf_smb_flags_notify = -1;
149 static int hf_smb_flags_response = -1;
150 static int hf_smb_flags2 = -1;
151 static int hf_smb_flags2_long_names_allowed = -1;
152 static int hf_smb_flags2_ea = -1;
153 static int hf_smb_flags2_sec_sig = -1;
154 static int hf_smb_flags2_compressed = -1;
155 static int hf_smb_flags2_sec_sig_required = -1;
156 static int hf_smb_flags2_long_names_used = -1;
157 static int hf_smb_flags2_reparse_path = -1;
158 static int hf_smb_flags2_esn = -1;
159 static int hf_smb_flags2_dfs = -1;
160 static int hf_smb_flags2_roe = -1;
161 static int hf_smb_flags2_nt_error = -1;
162 static int hf_smb_flags2_string = -1;
163 static int hf_smb_word_count = -1;
164 static int hf_smb_byte_count = -1;
165 static int hf_smb_buffer_format = -1;
166 static int hf_smb_dialect = -1;
167 static int hf_smb_dialect_name = -1;
168 static int hf_smb_dialect_index = -1;
169 static int hf_smb_max_trans_buf_size = -1;
170 static int hf_smb_max_mpx_count = -1;
171 static int hf_smb_max_vcs_num = -1;
172 static int hf_smb_session_key = -1;
173 static int hf_smb_server_timezone = -1;
174 static int hf_smb_encryption_key_length = -1;
175 static int hf_smb_encryption_key = -1;
176 static int hf_smb_primary_domain = -1;
177 static int hf_smb_server = -1;
178 static int hf_smb_max_raw_buf_size = -1;
179 static int hf_smb_server_guid = -1;
180 static int hf_smb_volume_guid = -1;
181 static int hf_smb_security_blob_len = -1;
182 static int hf_smb_security_blob = -1;
183 static int hf_smb_sm16 = -1;
184 static int hf_smb_sm_mode16 = -1;
185 static int hf_smb_sm_password16 = -1;
186 static int hf_smb_sm = -1;
187 static int hf_smb_sm_mode = -1;
188 static int hf_smb_sm_password = -1;
189 static int hf_smb_sm_signatures = -1;
190 static int hf_smb_sm_sig_required = -1;
191 static int hf_smb_rm = -1;
192 static int hf_smb_rm_read = -1;
193 static int hf_smb_rm_write = -1;
194 static int hf_smb_server_date_time = -1;
195 static int hf_smb_server_smb_date = -1;
196 static int hf_smb_server_smb_time = -1;
197 static int hf_smb_server_cap = -1;
198 static int hf_smb_server_cap_raw_mode = -1;
199 static int hf_smb_server_cap_mpx_mode = -1;
200 static int hf_smb_server_cap_unicode = -1;
201 static int hf_smb_server_cap_large_files = -1;
202 static int hf_smb_server_cap_nt_smbs = -1;
203 static int hf_smb_server_cap_rpc_remote_apis = -1;
204 static int hf_smb_server_cap_nt_status = -1;
205 static int hf_smb_server_cap_level_ii_oplocks = -1;
206 static int hf_smb_server_cap_lock_and_read = -1;
207 static int hf_smb_server_cap_nt_find = -1;
208 static int hf_smb_server_cap_dfs = -1;
209 static int hf_smb_server_cap_infolevel_passthru = -1;
210 static int hf_smb_server_cap_large_readx = -1;
211 static int hf_smb_server_cap_large_writex = -1;
212 static int hf_smb_server_cap_lwio = -1;
213 static int hf_smb_server_cap_unix = -1;
214 static int hf_smb_server_cap_compressed_data = -1;
215 static int hf_smb_server_cap_dynamic_reauth = -1;
216 static int hf_smb_server_cap_extended_security = -1;
217 static int hf_smb_system_time = -1;
218 static int hf_smb_unknown = -1;
219 static int hf_smb_dir_name = -1;
220 static int hf_smb_echo_count = -1;
221 static int hf_smb_echo_data = -1;
222 static int hf_smb_echo_seq_num = -1;
223 static int hf_smb_max_buf_size = -1;
224 static int hf_smb_password = -1;
225 static int hf_smb_password_len = -1;
226 static int hf_smb_ansi_password = -1;
227 static int hf_smb_ansi_password_len = -1;
228 static int hf_smb_unicode_password = -1;
229 static int hf_smb_unicode_password_len = -1;
230 static int hf_smb_path = -1;
231 static int hf_smb_service = -1;
232 static int hf_smb_move_flags = -1;
233 static int hf_smb_move_flags_file = -1;
234 static int hf_smb_move_flags_dir = -1;
235 static int hf_smb_move_flags_verify = -1;
236 static int hf_smb_files_moved = -1;
237 static int hf_smb_file_access_mask_read_data = -1;
238 static int hf_smb_file_access_mask_write_data = -1;
239 static int hf_smb_file_access_mask_append_data = -1;
240 static int hf_smb_file_access_mask_read_ea = -1;
241 static int hf_smb_file_access_mask_write_ea = -1;
242 static int hf_smb_file_access_mask_execute = -1;
243 static int hf_smb_file_access_mask_read_attribute = -1;
244 static int hf_smb_file_access_mask_write_attribute = -1;
245 static int hf_smb_dir_access_mask_list = -1;
246 static int hf_smb_dir_access_mask_add_file = -1;
247 static int hf_smb_dir_access_mask_add_subdir = -1;
248 static int hf_smb_dir_access_mask_read_ea = -1;
249 static int hf_smb_dir_access_mask_write_ea = -1;
250 static int hf_smb_dir_access_mask_traverse = -1;
251 static int hf_smb_dir_access_mask_delete_child = -1;
252 static int hf_smb_dir_access_mask_read_attribute = -1;
253 static int hf_smb_dir_access_mask_write_attribute = -1;
254 static int hf_smb_copy_flags = -1;
255 static int hf_smb_copy_flags_file = -1;
256 static int hf_smb_copy_flags_dir = -1;
257 static int hf_smb_copy_flags_dest_mode = -1;
258 static int hf_smb_copy_flags_source_mode = -1;
259 static int hf_smb_copy_flags_verify = -1;
260 static int hf_smb_copy_flags_tree_copy = -1;
261 static int hf_smb_copy_flags_ea_action = -1;
262 static int hf_smb_count = -1;
263 static int hf_smb_count_low = -1;
264 static int hf_smb_count_high = -1;
265 static int hf_smb_file_name = -1;
266 static int hf_smb_open_function = -1;
267 static int hf_smb_open_function_open = -1;
268 static int hf_smb_open_function_create = -1;
269 static int hf_smb_fid = -1;
270 static int hf_smb_file_attr_16bit = -1;
271 static int hf_smb_file_attr_8bit = -1;
272 static int hf_smb_file_attr_read_only_16bit = -1;
273 static int hf_smb_file_attr_read_only_8bit = -1;
274 static int hf_smb_file_attr_hidden_16bit = -1;
275 static int hf_smb_file_attr_hidden_8bit = -1;
276 static int hf_smb_file_attr_system_16bit = -1;
277 static int hf_smb_file_attr_system_8bit = -1;
278 static int hf_smb_file_attr_volume_16bit = -1;
279 static int hf_smb_file_attr_volume_8bit = -1;
280 static int hf_smb_file_attr_directory_16bit = -1;
281 static int hf_smb_file_attr_directory_8bit = -1;
282 static int hf_smb_file_attr_archive_16bit = -1;
283 static int hf_smb_file_attr_archive_8bit = -1;
284 #if 0
285 static int hf_smb_file_attr_device = -1;
286 static int hf_smb_file_attr_normal = -1;
287 static int hf_smb_file_attr_temporary = -1;
288 static int hf_smb_file_attr_sparse = -1;
289 static int hf_smb_file_attr_reparse = -1;
290 static int hf_smb_file_attr_compressed = -1;
291 static int hf_smb_file_attr_offline = -1;
292 static int hf_smb_file_attr_not_content_indexed = -1;
293 static int hf_smb_file_attr_encrypted = -1;
294 #endif
295 static int hf_smb_file_size = -1;
296 static int hf_smb_search_attribute = -1;
297 static int hf_smb_search_attribute_read_only = -1;
298 static int hf_smb_search_attribute_hidden = -1;
299 static int hf_smb_search_attribute_system = -1;
300 static int hf_smb_search_attribute_volume = -1;
301 static int hf_smb_search_attribute_directory = -1;
302 static int hf_smb_search_attribute_archive = -1;
303 static int hf_smb_access_mode = -1;
304 static int hf_smb_access_sharing = -1;
305 static int hf_smb_access_locality = -1;
306 static int hf_smb_access_caching = -1;
307 static int hf_smb_access_writetru = -1;
308 static int hf_smb_create_time = -1;
309 static int hf_smb_modify_time = -1;
310 static int hf_smb_backup_time = -1;
311 static int hf_smb_mac_alloc_block_count = -1;
312 static int hf_smb_mac_alloc_block_size = -1;
313 static int hf_smb_mac_free_block_count = -1;
314 static int hf_smb_mac_fndrinfo = -1;
315 static int hf_smb_mac_root_file_count = -1;
316 static int hf_smb_mac_root_dir_count = -1;
317 static int hf_smb_mac_file_count = -1;
318 static int hf_smb_mac_dir_count = -1;
319 static int hf_smb_mac_sup = -1;
320 static int hf_smb_mac_sup_access_ctrl = -1;
321 static int hf_smb_mac_sup_getset_comments = -1;
322 static int hf_smb_mac_sup_desktopdb_calls = -1;
323 static int hf_smb_mac_sup_unique_ids = -1;
324 static int hf_smb_mac_sup_streams = -1;
325 static int hf_smb_create_dos_date = -1;
326 static int hf_smb_create_dos_time = -1;
327 static int hf_smb_last_write_time = -1;
328 static int hf_smb_last_write_dos_date = -1;
329 static int hf_smb_last_write_dos_time = -1;
330 static int hf_smb_access_time = -1;
331 static int hf_smb_access_dos_date = -1;
332 static int hf_smb_access_dos_time = -1;
333 static int hf_smb_old_file_name = -1;
334 static int hf_smb_offset = -1;
335 static int hf_smb_remaining = -1;
336 static int hf_smb_padding = -1;
337 static int hf_smb_file_data = -1;
338 /* static int hf_smb_raw_ea_data = -1; */
339 static int hf_smb_total_data_len = -1;
340 static int hf_smb_data_len = -1;
341 static int hf_smb_data_len_low = -1;
342 static int hf_smb_data_len_high = -1;
343 static int hf_smb_seek_mode = -1;
344 static int hf_smb_data_size = -1;
345 static int hf_smb_alloc_size = -1;
346 static int hf_smb_alloc_size64 = -1;
347 static int hf_smb_max_count = -1;
348 static int hf_smb_max_count_low = -1;
349 static int hf_smb_max_count_high = -1;
350 static int hf_smb_min_count = -1;
351 static int hf_smb_timeout = -1;
352 static int hf_smb_high_offset = -1;
353 static int hf_smb_units = -1;
354 static int hf_smb_bpu = -1;
355 static int hf_smb_blocksize = -1;
356 static int hf_smb_freeunits = -1;
357 static int hf_smb_data_offset = -1;
358 static int hf_smb_dcm = -1;
359 static int hf_smb_request_mask = -1;
360 static int hf_smb_response_mask = -1;
361 static int hf_smb_search_id = -1;
362 static int hf_smb_write_mode = -1;
363 static int hf_smb_write_mode_write_through = -1;
364 static int hf_smb_write_mode_return_remaining = -1;
365 static int hf_smb_write_mode_raw = -1;
366 static int hf_smb_write_mode_message_start = -1;
367 static int hf_smb_write_mode_connectionless = -1;
368 static int hf_smb_resume_key_len = -1;
369 static int hf_smb_resume_find_id = -1;
370 static int hf_smb_resume_server_cookie = -1;
371 static int hf_smb_resume_client_cookie = -1;
372 static int hf_smb_andxoffset = -1;
373 static int hf_smb_lock_type = -1;
374 static int hf_smb_lock_type_large = -1;
375 static int hf_smb_lock_type_cancel = -1;
376 static int hf_smb_lock_type_change = -1;
377 static int hf_smb_lock_type_oplock = -1;
378 static int hf_smb_lock_type_shared = -1;
379 static int hf_smb_locking_ol = -1;
380 static int hf_smb_number_of_locks = -1;
381 static int hf_smb_number_of_unlocks = -1;
382 static int hf_smb_lock_long_offset = -1;
383 static int hf_smb_lock_long_length = -1;
384 static int hf_smb_file_type = -1;
385 static int hf_smb_ipc_state = -1;
386 static int hf_smb_ipc_state_nonblocking = -1;
387 static int hf_smb_ipc_state_endpoint = -1;
388 static int hf_smb_ipc_state_pipe_type = -1;
389 static int hf_smb_ipc_state_read_mode = -1;
390 static int hf_smb_ipc_state_icount = -1;
391 static int hf_smb_server_fid = -1;
392 static int hf_smb_open_flags = -1;
393 static int hf_smb_open_flags_add_info = -1;
394 static int hf_smb_open_flags_ex_oplock = -1;
395 static int hf_smb_open_flags_batch_oplock = -1;
396 static int hf_smb_open_flags_ealen = -1;
397 static int hf_smb_open_action = -1;
398 static int hf_smb_open_action_open = -1;
399 static int hf_smb_open_action_lock = -1;
400 static int hf_smb_vc_num = -1;
401 static int hf_smb_account = -1;
402 static int hf_smb_os = -1;
403 static int hf_smb_lanman = -1;
404 static int hf_smb_setup_action = -1;
405 static int hf_smb_setup_action_guest = -1;
406 static int hf_smb_fs = -1;
407 static int hf_smb_connect_flags = -1;
408 static int hf_smb_connect_flags_dtid = -1;
409 static int hf_smb_connect_flags_ext_sig = -1;
410 static int hf_smb_connect_flags_ext_resp = -1;
411 static int hf_smb_connect_support = -1;
412 static int hf_smb_connect_support_search = -1;
413 static int hf_smb_connect_support_in_dfs = -1;
414 static int hf_smb_connect_support_csc_mask_vals = -1;
415 static int hf_smb_connect_support_uniquefilename = -1;
416 static int hf_smb_connect_support_extended_signature = -1;
417 static int hf_smb_max_setup_count = -1;
418 static int hf_smb_total_param_count = -1;
419 static int hf_smb_total_data_count = -1;
420 static int hf_smb_max_param_count = -1;
421 static int hf_smb_max_data_count = -1;
422 static int hf_smb_param_disp16 = -1;
423 static int hf_smb_param_count16 = -1;
424 static int hf_smb_param_offset16 = -1;
425 static int hf_smb_param_disp32 = -1;
426 static int hf_smb_param_count32 = -1;
427 static int hf_smb_param_offset32 = -1;
428 static int hf_smb_data_disp16 = -1;
429 static int hf_smb_data_count16 = -1;
430 static int hf_smb_data_offset16 = -1;
431 static int hf_smb_data_disp32 = -1;
432 static int hf_smb_data_count32 = -1;
433 static int hf_smb_data_offset32 = -1;
434 static int hf_smb_setup_count = -1;
435 static int hf_smb_nt_trans_subcmd = -1;
436 static int hf_smb_nt_ioctl_isfsctl = -1;
437 static int hf_smb_nt_ioctl_flags_completion_filter = -1;
438 static int hf_smb_nt_ioctl_flags_root_handle = -1;
439 static int hf_smb_nt_notify_action = -1;
440 static int hf_smb_nt_notify_watch_tree = -1;
441 static int hf_smb_nt_notify_completion_filter = -1;
442 static int hf_smb_nt_notify_stream_write = -1;
443 static int hf_smb_nt_notify_stream_size = -1;
444 static int hf_smb_nt_notify_stream_name = -1;
445 static int hf_smb_nt_notify_security = -1;
446 static int hf_smb_nt_notify_ea = -1;
447 static int hf_smb_nt_notify_creation = -1;
448 static int hf_smb_nt_notify_last_access = -1;
449 static int hf_smb_nt_notify_last_write = -1;
450 static int hf_smb_nt_notify_size = -1;
451 static int hf_smb_nt_notify_attributes = -1;
452 static int hf_smb_nt_notify_dir_name = -1;
453 static int hf_smb_nt_notify_file_name = -1;
454 static int hf_smb_root_dir_fid = -1;
455 static int hf_smb_nt_create_disposition = -1;
456 static int hf_smb_sd_length = -1;
457 static int hf_smb_ea_list_length = -1;
458 static int hf_smb_ea_flags = -1;
459 static int hf_smb_ea_name_length = -1;
460 static int hf_smb_ea_data_length = -1;
461 static int hf_smb_ea_name = -1;
462 static int hf_smb_ea_data = -1;
463 static int hf_smb_file_name_len = -1;
464 static int hf_smb_nt_impersonation_level = -1;
465 static int hf_smb_nt_security_flags = -1;
466 static int hf_smb_nt_security_flags_context_tracking = -1;
467 static int hf_smb_nt_security_flags_effective_only = -1;
468 static int hf_smb_nt_access_mask_generic_read = -1;
469 static int hf_smb_nt_access_mask_generic_write = -1;
470 static int hf_smb_nt_access_mask_generic_execute = -1;
471 static int hf_smb_nt_access_mask_generic_all = -1;
472 static int hf_smb_nt_access_mask_maximum_allowed = -1;
473 static int hf_smb_nt_access_mask_system_security = -1;
474 static int hf_smb_nt_access_mask_synchronize = -1;
475 static int hf_smb_nt_access_mask_write_owner = -1;
476 static int hf_smb_nt_access_mask_write_dac = -1;
477 static int hf_smb_nt_access_mask_read_control = -1;
478 static int hf_smb_nt_access_mask_delete = -1;
479 static int hf_smb_nt_access_mask_write_attributes = -1;
480 static int hf_smb_nt_access_mask_read_attributes = -1;
481 static int hf_smb_nt_access_mask_delete_child = -1;
482 static int hf_smb_nt_access_mask_execute = -1;
483 static int hf_smb_nt_access_mask_write_ea = -1;
484 static int hf_smb_nt_access_mask_read_ea = -1;
485 static int hf_smb_nt_access_mask_append = -1;
486 static int hf_smb_nt_access_mask_write = -1;
487 static int hf_smb_nt_access_mask_read = -1;
488 static int hf_smb_nt_create_bits_oplock = -1;
489 static int hf_smb_nt_create_bits_boplock = -1;
490 static int hf_smb_nt_create_bits_dir = -1;
491 static int hf_smb_nt_create_bits_ext_resp = -1;
492 static int hf_smb_nt_create_options_directory_file = -1;
493 static int hf_smb_nt_create_options_write_through = -1;
494 static int hf_smb_nt_create_options_sequential_only = -1;
495 static int hf_smb_nt_create_options_no_intermediate_buffering = -1;
496 static int hf_smb_nt_create_options_sync_io_alert = -1;
497 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
498 static int hf_smb_nt_create_options_non_directory_file = -1;
499 static int hf_smb_nt_create_options_create_tree_connection = -1;
500 static int hf_smb_nt_create_options_complete_if_oplocked = -1;
501 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
502 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
503 static int hf_smb_nt_create_options_random_access = -1;
504 static int hf_smb_nt_create_options_delete_on_close = -1;
505 static int hf_smb_nt_create_options_open_by_fileid = -1;
506 static int hf_smb_nt_create_options_backup_intent = -1;
507 static int hf_smb_nt_create_options_no_compression = -1;
508 static int hf_smb_nt_create_options_reserve_opfilter = -1;
509 static int hf_smb_nt_create_options_open_reparse_point = -1;
510 static int hf_smb_nt_create_options_open_no_recall = -1;
511 static int hf_smb_nt_create_options_open_for_free_space_query = -1;
512 static int hf_smb_nt_share_access_read = -1;
513 static int hf_smb_nt_share_access_write = -1;
514 static int hf_smb_nt_share_access_delete = -1;
515 static int hf_smb_file_eattr = -1;
516 static int hf_smb_file_eattr_read_only = -1;
517 static int hf_smb_file_eattr_hidden = -1;
518 static int hf_smb_file_eattr_system = -1;
519 static int hf_smb_file_eattr_volume = -1;
520 static int hf_smb_file_eattr_directory = -1;
521 static int hf_smb_file_eattr_archive = -1;
522 static int hf_smb_file_eattr_device = -1;
523 static int hf_smb_file_eattr_normal = -1;
524 static int hf_smb_file_eattr_temporary = -1;
525 static int hf_smb_file_eattr_sparse = -1;
526 static int hf_smb_file_eattr_reparse = -1;
527 static int hf_smb_file_eattr_compressed = -1;
528 static int hf_smb_file_eattr_offline = -1;
529 static int hf_smb_file_eattr_not_content_indexed = -1;
530 static int hf_smb_file_eattr_encrypted = -1;
531 static int hf_smb_size_returned_quota_data = -1;
532 static int hf_smb_sec_desc_len = -1;
533 static int hf_smb_nt_qsd = -1;
534 static int hf_smb_nt_qsd_owner = -1;
535 static int hf_smb_nt_qsd_group = -1;
536 static int hf_smb_nt_qsd_dacl = -1;
537 static int hf_smb_nt_qsd_sacl = -1;
538 static int hf_smb_extended_attributes = -1;
539 static int hf_smb_oplock_level = -1;
540 static int hf_smb_create_action = -1;
541 static int hf_smb_file_id = -1;
542 static int hf_smb_file_id_64bit = -1;
543 static int hf_smb_ea_error_offset = -1;
544 static int hf_smb_end_of_file = -1;
545 static int hf_smb_replace = -1;
546 static int hf_smb_root_dir_handle = -1;
547 static int hf_smb_target_name_len = -1;
548 static int hf_smb_target_name = -1;
549 static int hf_smb_device_type = -1;
550 static int hf_smb_is_directory = -1;
551 static int hf_smb_next_entry_offset = -1;
552 static int hf_smb_change_time = -1;
553 static int hf_smb_setup_len = -1;
554 static int hf_smb_print_mode = -1;
555 static int hf_smb_print_identifier = -1;
556 static int hf_smb_restart_index = -1;
557 static int hf_smb_print_queue_date = -1;
558 static int hf_smb_print_queue_dos_date = -1;
559 static int hf_smb_print_queue_dos_time = -1;
560 static int hf_smb_print_status = -1;
561 static int hf_smb_print_spool_file_number = -1;
562 static int hf_smb_print_spool_file_size = -1;
563 static int hf_smb_print_spool_file_name = -1;
564 static int hf_smb_start_index = -1;
565 static int hf_smb_originator_name = -1;
566 static int hf_smb_destination_name = -1;
567 static int hf_smb_message_len = -1;
568 static int hf_smb_message = -1;
569 static int hf_smb_mgid = -1;
570 static int hf_smb_forwarded_name = -1;
571 static int hf_smb_machine_name = -1;
572 static int hf_smb_cancel_to = -1;
573 static int hf_smb_trans2_subcmd = -1;
574 static int hf_smb_trans_name = -1;
575 static int hf_smb_transaction_flags = -1;
576 static int hf_smb_transaction_flags_dtid = -1;
577 static int hf_smb_transaction_flags_owt = -1;
578 static int hf_smb_search_count = -1;
579 static int hf_smb_search_pattern = -1;
580 static int hf_smb_ff2 = -1;
581 static int hf_smb_ff2_backup = -1;
582 static int hf_smb_ff2_continue = -1;
583 static int hf_smb_ff2_resume = -1;
584 static int hf_smb_ff2_close_eos = -1;
585 static int hf_smb_ff2_close = -1;
586 static int hf_smb_ff2_information_level = -1;
587 static int hf_smb_qpi_loi = -1;
588 static int hf_smb_spi_loi = -1;
589 #if 0
590 static int hf_smb_sfi_writetru = -1;
591 static int hf_smb_sfi_caching = -1;
592 #endif
593 static int hf_smb_storage_type = -1;
594 static int hf_smb_resume = -1;
595 static int hf_smb_max_referral_level = -1;
596 static int hf_smb_qfsi_information_level = -1;
597 static int hf_smb_sfsi_information_level = -1;
598 static int hf_smb_number_of_links = -1;
599 static int hf_smb_delete_pending = -1;
600 static int hf_smb_index_number = -1;
601 static int hf_smb_position = -1;
602 /* static int hf_smb_current_offset = -1; */
603 static int hf_smb_t2_alignment = -1;
604 static int hf_smb_t2_stream_name_length = -1;
605 static int hf_smb_t2_stream_size = -1;
606 static int hf_smb_t2_stream_name = -1;
607 static int hf_smb_t2_compressed_file_size = -1;
608 static int hf_smb_t2_compressed_format = -1;
609 static int hf_smb_t2_compressed_unit_shift = -1;
610 static int hf_smb_t2_compressed_chunk_shift = -1;
611 static int hf_smb_t2_compressed_cluster_shift = -1;
612 static int hf_smb_t2_marked_for_deletion = -1;
613 static int hf_smb_dfs_path_consumed = -1;
614 static int hf_smb_dfs_num_referrals = -1;
615 static int hf_smb_get_dfs_flags = -1;
616 static int hf_smb_get_dfs_server_hold_storage = -1;
617 static int hf_smb_get_dfs_fielding = -1;
618 static int hf_smb_dfs_referral_version = -1;
619 static int hf_smb_dfs_referral_size = -1;
620 static int hf_smb_dfs_referral_server_type = -1;
621 static int hf_smb_dfs_referral_flags = -1;
622 static int hf_smb_dfs_referral_flags_name_list_referral = -1;
623 static int hf_smb_dfs_referral_flags_target_set_boundary = -1;
624 static int hf_smb_dfs_referral_node_offset = -1;
625 static int hf_smb_dfs_referral_node = -1;
626 static int hf_smb_dfs_referral_proximity = -1;
627 static int hf_smb_dfs_referral_ttl = -1;
628 static int hf_smb_dfs_referral_path_offset = -1;
629 static int hf_smb_dfs_referral_path = -1;
630 static int hf_smb_dfs_referral_alt_path_offset = -1;
631 static int hf_smb_dfs_referral_alt_path = -1;
632 static int hf_smb_dfs_referral_domain_offset = -1;
633 static int hf_smb_dfs_referral_number_of_expnames = -1;
634 static int hf_smb_dfs_referral_expnames_offset = -1;
635 static int hf_smb_dfs_referral_domain_name = -1;
636 static int hf_smb_dfs_referral_expname = -1;
637 static int hf_smb_dfs_referral_server_guid = -1;
638 static int hf_smb_end_of_search = -1;
639 static int hf_smb_last_name_offset = -1;
640 static int hf_smb_fn_information_level = -1;
641 static int hf_smb_monitor_handle = -1;
642 static int hf_smb_change_count = -1;
643 static int hf_smb_file_index = -1;
644 static int hf_smb_short_file_name = -1;
645 static int hf_smb_short_file_name_len = -1;
646 static int hf_smb_fs_id = -1;
647 static int hf_smb_sector_unit = -1;
648 static int hf_smb_fs_units = -1;
649 static int hf_smb_fs_sector = -1;
650 static int hf_smb_avail_units = -1;
651 static int hf_smb_volume_serial_num = -1;
652 static int hf_smb_volume_label_len = -1;
653 static int hf_smb_volume_label = -1;
654 static int hf_smb_free_alloc_units64 = -1;
655 static int hf_smb_caller_free_alloc_units64 = -1;
656 static int hf_smb_actual_free_alloc_units64 = -1;
657 static int hf_smb_max_name_len = -1;
658 static int hf_smb_fs_name_len = -1;
659 static int hf_smb_fs_name = -1;
660 static int hf_smb_device_char = -1;
661 static int hf_smb_device_char_removable = -1;
662 static int hf_smb_device_char_read_only = -1;
663 static int hf_smb_device_char_floppy = -1;
664 static int hf_smb_device_char_write_once = -1;
665 static int hf_smb_device_char_remote = -1;
666 static int hf_smb_device_char_mounted = -1;
667 static int hf_smb_device_char_virtual = -1;
668 static int hf_smb_fs_attr = -1;
669 static int hf_smb_fs_attr_css = -1;
670 static int hf_smb_fs_attr_cpn = -1;
671 static int hf_smb_fs_attr_uod = -1;
672 static int hf_smb_fs_attr_pacls = -1;
673 static int hf_smb_fs_attr_fc = -1;
674 static int hf_smb_fs_attr_vq = -1;
675 static int hf_smb_fs_attr_ssf = -1;
676 static int hf_smb_fs_attr_srp = -1;
677 static int hf_smb_fs_attr_srs = -1;
678 static int hf_smb_fs_attr_sla = -1;
679 static int hf_smb_fs_attr_vic = -1;
680 static int hf_smb_fs_attr_soids = -1;
681 static int hf_smb_fs_attr_se = -1;
682 static int hf_smb_fs_attr_ns = -1;
683 static int hf_smb_fs_attr_rov = -1;
684 static int hf_smb_quota_flags_enabled = -1;
685 static int hf_smb_quota_flags_deny_disk = -1;
686 static int hf_smb_quota_flags_log_limit = -1;
687 static int hf_smb_quota_flags_log_warning = -1;
688 static int hf_smb_soft_quota_limit = -1;
689 static int hf_smb_hard_quota_limit = -1;
690 static int hf_smb_user_quota_used = -1;
691 static int hf_smb_length_of_sid = -1;
692 static int hf_smb_user_quota_offset = -1;
693 static int hf_smb_nt_rename_level = -1;
694 static int hf_smb_cluster_count = -1;
695 static int hf_smb_segments = -1;
696 static int hf_smb_segment = -1;
697 static int hf_smb_segment_overlap = -1;
698 static int hf_smb_segment_overlap_conflict = -1;
699 static int hf_smb_segment_multiple_tails = -1;
700 static int hf_smb_segment_too_long_fragment = -1;
701 static int hf_smb_segment_error = -1;
702 static int hf_smb_segment_count = -1;
703 static int hf_smb_reassembled_length = -1;
704 static int hf_smb_pipe_write_len = -1;
705 static int hf_smb_unix_major_version = -1;
706 static int hf_smb_unix_minor_version = -1;
707 static int hf_smb_unix_capability = -1;
708 static int hf_smb_unix_capability_fcntl = -1;
709 static int hf_smb_unix_capability_posix_acl = -1;
710 static int hf_smb_unix_capability_xattr = -1;
711 static int hf_smb_unix_capability_attr = -1;
712 static int hf_smb_unix_capability_posix_paths = -1;
713 static int hf_smb_unix_capability_posix_path_ops = -1;
714 static int hf_smb_unix_capability_large_read = -1;
715 static int hf_smb_unix_capability_large_write = -1;
716 static int hf_smb_unix_capability_encrpytion = -1;
717 static int hf_smb_unix_capability_mandatory_crypto = -1;
718 static int hf_smb_unix_capability_proxy = -1;
719 static int hf_smb_unix_file_link_dest = -1;
720 static int hf_smb_unix_file_size = -1;
721 static int hf_smb_unix_file_num_bytes = -1;
722 static int hf_smb_unix_file_last_status = -1;
723 static int hf_smb_unix_file_last_access = -1;
724 static int hf_smb_unix_file_last_change = -1;
725 static int hf_smb_unix_file_creation_time = -1;
726 static int hf_smb_unix_file_uid = -1;
727 static int hf_smb_unix_file_gid = -1;
728 static int hf_smb_unix_file_type = -1;
729 static int hf_smb_unix_file_dev_major = -1;
730 static int hf_smb_unix_file_dev_minor = -1;
731 static int hf_smb_unix_file_unique_id = -1;
732 static int hf_smb_unix_file_permissions = -1;
733 static int hf_smb_unix_file_nlinks = -1;
734 static int hf_smb_unix_info2_file_flags = -1;
735 static int hf_smb_unix_info2_file_flags_mask = -1;
736 static int hf_smb_unix_info2_file_flags_secure_delete = -1;
737 static int hf_smb_unix_info2_file_flags_enable_undelete = -1;
738 static int hf_smb_unix_info2_file_flags_synchronous = -1;
739 static int hf_smb_unix_info2_file_flags_immutable = -1;
740 static int hf_smb_unix_info2_file_flags_append_only = -1;
741 static int hf_smb_unix_info2_file_flags_do_not_backup = -1;
742 static int hf_smb_unix_info2_file_flags_no_update_atime = -1;
743 static int hf_smb_unix_info2_file_flags_hidden = -1;
744 static int hf_smb_unix_file_name_length = -1;
745 static int hf_smb_unix_file_name = -1;
746 static int hf_smb_unix_find_file_nextoffset = -1;
747 static int hf_smb_unix_find_file_resumekey = -1;
748 static int hf_smb_unix_whoami_mapflags = -1;
749 static int hf_smb_unix_whoami_mapflags_mask = -1;
750 static int hf_smb_unix_whoami_num_supl_gids = -1;
751 static int hf_smb_unix_whoami_num_supl_sids = -1;
752 static int hf_smb_unix_whoami_sids_buflen = -1;
753 static int hf_smb_disposition_delete_on_close = -1;
754 static int hf_smb_pipe_info_flag = -1;
755 static int hf_smb_mode = -1;
756 static int hf_smb_attribute = -1;
757 static int hf_smb_reparse_tag = -1;
758 static int hf_smb_logged_in = -1;
759 static int hf_smb_logged_out = -1;
760 static int hf_smb_file_rw_offset = -1;
761 static int hf_smb_file_rw_length = -1;
762 static int hf_smb_posix_acl_version = -1;
763 static int hf_smb_posix_num_file_aces = -1;
764 static int hf_smb_posix_num_def_aces = -1;
765 static int hf_smb_posix_ace_type = -1;
766 static int hf_smb_posix_ace_flags = -1;
767 static int hf_smb_posix_ace_perm_read = -1;
768 static int hf_smb_posix_ace_perm_write = -1;
769 static int hf_smb_posix_ace_perm_execute = -1;
770 static int hf_smb_posix_ace_perm_owner_uid = -1;
771 static int hf_smb_posix_ace_perm_owner_gid = -1;
772 static int hf_smb_posix_ace_perm_uid = -1;
773 static int hf_smb_posix_ace_perm_gid = -1;
774 static int hf_smb_trans_data_setup_word = -1;
775 static int hf_smb_trans_data_parameters = -1;
776 static int hf_smb_trans_data = -1;
777
778 static gint ett_smb = -1;
779 static gint ett_smb_fid = -1;
780 static gint ett_smb_tid = -1;
781 static gint ett_smb_uid = -1;
782 static gint ett_smb_hdr = -1;
783 static gint ett_smb_command = -1;
784 static gint ett_smb_fileattributes = -1;
785 static gint ett_smb_capabilities = -1;
786 static gint ett_smb_aflags = -1;
787 static gint ett_smb_dialect = -1;
788 static gint ett_smb_dialects = -1;
789 static gint ett_smb_mode = -1;
790 static gint ett_smb_rawmode = -1;
791 static gint ett_smb_flags = -1;
792 static gint ett_smb_flags2 = -1;
793 static gint ett_smb_desiredaccess = -1;
794 static gint ett_smb_search = -1;
795 static gint ett_smb_file = -1;
796 static gint ett_smb_openfunction = -1;
797 static gint ett_smb_filetype = -1;
798 static gint ett_smb_openaction = -1;
799 static gint ett_smb_writemode = -1;
800 static gint ett_smb_lock_type = -1;
801 static gint ett_smb_ssetupandxaction = -1;
802 static gint ett_smb_optionsup = -1;
803 static gint ett_smb_time_date = -1;
804 static gint ett_smb_move_copy_flags = -1;
805 static gint ett_smb_file_attributes = -1;
806 static gint ett_smb_search_resume_key = -1;
807 static gint ett_smb_search_dir_info = -1;
808 static gint ett_smb_unlocks = -1;
809 static gint ett_smb_unlock = -1;
810 static gint ett_smb_locks = -1;
811 static gint ett_smb_lock = -1;
812 static gint ett_smb_open_flags = -1;
813 static gint ett_smb_ipc_state = -1;
814 static gint ett_smb_open_action = -1;
815 static gint ett_smb_setup_action = -1;
816 static gint ett_smb_connect_flags = -1;
817 static gint ett_smb_connect_support_bits = -1;
818 static gint ett_smb_nt_access_mask = -1;
819 static gint ett_smb_nt_create_bits = -1;
820 static gint ett_smb_nt_create_options = -1;
821 static gint ett_smb_nt_share_access = -1;
822 static gint ett_smb_nt_security_flags = -1;
823 static gint ett_smb_nt_trans_setup = -1;
824 static gint ett_smb_nt_trans_data = -1;
825 static gint ett_smb_nt_trans_param = -1;
826 static gint ett_smb_nt_notify_completion_filter = -1;
827 static gint ett_smb_nt_ioctl_flags = -1;
828 static gint ett_smb_security_information_mask = -1;
829 static gint ett_smb_print_queue_entry = -1;
830 static gint ett_smb_transaction_flags = -1;
831 static gint ett_smb_transaction_params = -1;
832 static gint ett_smb_find_first2_flags = -1;
833 static gint ett_smb_mac_support_flags = -1;
834 #if 0
835 static gint ett_smb_ioflag = -1;
836 #endif
837 static gint ett_smb_transaction_data = -1;
838 static gint ett_smb_stream_info = -1;
839 static gint ett_smb_dfs_referrals = -1;
840 static gint ett_smb_dfs_referral = -1;
841 static gint ett_smb_dfs_referral_flags = -1;
842 static gint ett_smb_dfs_referral_expnames = -1;
843 static gint ett_smb_get_dfs_flags = -1;
844 static gint ett_smb_ff2_data = -1;
845 static gint ett_smb_device_characteristics = -1;
846 static gint ett_smb_fs_attributes = -1;
847 static gint ett_smb_segments = -1;
848 static gint ett_smb_segment = -1;
849 static gint ett_smb_quotaflags = -1;
850 static gint ett_smb_secblob = -1;
851 static gint ett_smb_unicode_password = -1;
852 static gint ett_smb_ea = -1;
853 static gint ett_smb_unix_capabilities = -1;
854 static gint ett_smb_unix_whoami_gids = -1;
855 static gint ett_smb_unix_whoami_sids = -1;
856 static gint ett_smb_posix_ace = -1;
857 static gint ett_smb_posix_ace_perms = -1;
858 static gint ett_smb_info2_file_flags = -1;
859
860 static expert_field ei_smb_mal_information_level = EI_INIT;
861 static expert_field ei_smb_not_implemented = EI_INIT;
862
863 static int smb_tap = -1;
864 static int smb_eo_tap = -1;
865
866 static dissector_handle_t gssapi_handle;
867 static dissector_handle_t ntlmssp_handle;
868
869 static const fragment_items smb_frag_items = {
870         &ett_smb_segment,
871         &ett_smb_segments,
872
873         &hf_smb_segments,
874         &hf_smb_segment,
875         &hf_smb_segment_overlap,
876         &hf_smb_segment_overlap_conflict,
877         &hf_smb_segment_multiple_tails,
878         &hf_smb_segment_too_long_fragment,
879         &hf_smb_segment_error,
880         &hf_smb_segment_count,
881         NULL,
882         &hf_smb_reassembled_length,
883         /* Reassembled data field */
884         NULL,
885         "segments"
886 };
887
888 static proto_tree *top_tree_global = NULL;     /* ugly */
889
890 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);
891
892 /*
893  * Macros for use in the main dissector routines for an SMB.
894  */
895
896 #define WORD_COUNT      \
897         /* Word Count */                                \
898         wc = tvb_get_guint8(tvb, offset);               \
899         proto_tree_add_uint(tree, hf_smb_word_count,    \
900                 tvb, offset, 1, wc);                    \
901         offset += 1;                                    \
902         if (wc == 0) goto bytecount;
903
904 #define BYTE_COUNT      \
905         bytecount:                                      \
906         bc = tvb_get_letohs(tvb, offset);               \
907         proto_tree_add_uint(tree, hf_smb_byte_count,    \
908                         tvb, offset, 2, bc);            \
909         offset += 2;                                    \
910         if (bc == 0) goto endofcommand;
911
912 #define CHECK_BYTE_COUNT(len)   \
913         if (bc < len) goto endofcommand;
914
915 #define COUNT_BYTES(len)   {\
916         int tmp;            \
917         tmp = len;          \
918         offset += tmp;      \
919         bc -= tmp;          \
920         }
921
922 #define END_OF_SMB      \
923         if (bc != 0) { \
924                 gint bc_remaining; \
925                 bc_remaining = tvb_length_remaining(tvb, offset); \
926                 if ( ((gint)bc) > bc_remaining) { \
927                         bc = bc_remaining; \
928                 } \
929                 if (bc) { \
930                         tvb_ensure_bytes_exist(tvb, offset, bc); \
931                         proto_tree_add_text(tree, tvb, offset, bc, \
932                             "Extra byte parameters");           \
933                 } \
934                 offset += bc;                           \
935         }                                               \
936         endofcommand:
937
938 /*
939  * Macros for use in routines called by them.
940  */
941 #define CHECK_BYTE_COUNT_SUBR(len)      \
942         if (*bcp < len) {               \
943                 *trunc = TRUE;          \
944                 return offset;          \
945         }
946
947 #define CHECK_STRING_SUBR(fn)   \
948         if (fn == NULL) {       \
949                 *trunc = TRUE;  \
950                 return offset;  \
951         }
952
953 #define COUNT_BYTES_SUBR(len)   \
954         offset += len;          \
955         *bcp -= len;
956
957 /*
958  * Macros for use when dissecting transaction parameters and data
959  */
960 #define CHECK_BYTE_COUNT_TRANS(len)     \
961         if (bc < len) return offset;
962
963 #define CHECK_STRING_TRANS(fn)  \
964         if (fn == NULL) return offset;
965
966 #define COUNT_BYTES_TRANS(len)  \
967         offset += len;          \
968         bc -= len;
969
970 /*
971  * Macros for use in subrroutines dissecting transaction parameters or data
972  */
973 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
974         if (*bcp < len) return offset;
975
976 #define CHECK_STRING_TRANS_SUBR(fn)     \
977         if (fn == NULL) return offset;
978
979 #define COUNT_BYTES_TRANS_SUBR(len)     \
980         offset += len;                  \
981         *bcp -= len;
982
983 gboolean sid_display_hex = FALSE;
984 gboolean sid_name_snooping = FALSE;
985
986 /* ExportObject preferences variable */
987 gboolean eosmb_take_name_as_fid = FALSE ;
988 /* Utility to get an str reprensenting ipv4 or ipv6 address */
989 const gchar *tree_ip_str(packet_info *pinfo, guint16 cmd) {
990         const gchar     *buf;
991
992         if (pinfo->src.type == AT_IPv4) {
993                 if (    cmd == SMB_COM_READ_ANDX ||
994                         cmd == SMB_COM_READ ||
995                         cmd == SMB2_COM_READ) {
996                         buf = ip_to_str((const guint8 *)pinfo->src.data);
997                 } else {
998                         buf = ip_to_str((const guint8 *)pinfo->dst.data);
999                 }
1000         } else {
1001                 if (    cmd == SMB_COM_READ_ANDX ||
1002                         cmd == SMB_COM_READ ||
1003                         cmd == SMB2_COM_READ) {
1004                         buf = ip6_to_str((const struct e_in6_addr *)pinfo->src.data);
1005                 } else {
1006                         buf = ip6_to_str((const struct e_in6_addr *)pinfo->dst.data);
1007                 }
1008         }
1009
1010         return buf;
1011 }
1012
1013
1014 /* ExportObject feed function*/
1015 static void
1016 feed_eo_smb(guint16 cmd, guint16 fid, tvbuff_t * tvb, packet_info *pinfo, guint16 dataoffset, guint32 datalen, guint32 chunk_len,
1017                         guint64 file_offset, smb_info_t *si) {
1018
1019         smb_eo_t        *eo_info; /*    eo_info variable to pass info. to
1020                                         export object and aux */
1021         smb_tid_info_t  *tid_info = NULL;
1022         smb_fid_info_t  *fid_info = NULL;
1023         smb_fid_info_t  *suspect_fid_info = NULL;
1024         tvbuff_t        *data_tvb;
1025         GSList          *GSL_iterator;
1026
1027         /* Create a new tvb to point to the payload data */
1028         data_tvb = tvb_new_subset(tvb, dataoffset, datalen, datalen);
1029         /* Create the eo_info to pass to the listener */
1030         eo_info = wmem_new(wmem_packet_scope(), smb_eo_t);
1031
1032         /* Try to get fid_info and tid_info */
1033         if (fid_info == NULL) {
1034                 GSL_iterator = si->ct->GSL_fid_info;
1035                 while (GSL_iterator) {
1036                         suspect_fid_info = (smb_fid_info_t *)GSL_iterator->data;
1037                         if (suspect_fid_info->opened_in > pinfo->fd->num) break;
1038                         if ((suspect_fid_info->tid == si->tid) && (suspect_fid_info->fid == fid))
1039                                 fid_info = suspect_fid_info;
1040                         GSL_iterator = g_slist_next(GSL_iterator);
1041                         }
1042                 }
1043
1044
1045         tid_info = (smb_tid_info_t *)wmem_tree_lookup32(si->ct->tid_tree, si->tid);
1046
1047         /* Construct the eo_info structure */
1048         eo_info->smbversion = 1;
1049         if (tid_info) {
1050                 if (tid_info->filename) {
1051                         eo_info->hostname = tid_info->filename;
1052                 } else {
1053                         eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_UNKNOWN", tree_ip_str(pinfo, cmd));
1054                 }
1055         }
1056         else            eo_info->hostname = wmem_strdup_printf(wmem_packet_scope(), "\\\\%s\\TREEID_%i", tree_ip_str(pinfo, cmd), si->tid);
1057         if (fid_info) {
1058                 eo_info->filename = NULL;
1059                 if (fid_info->fsi)
1060                         if (fid_info->fsi->filename)
1061                                 eo_info->filename = (gchar *) fid_info->fsi->filename;
1062                 if (!eo_info->filename) eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\FILEID_%i", fid);
1063                 eo_info->fid_type = fid_info->type;
1064                 eo_info->end_of_file = fid_info->end_of_file;
1065         } else {
1066                 eo_info->fid_type = SMB_FID_TYPE_UNKNOWN;
1067                 eo_info->filename = wmem_strdup_printf(wmem_packet_scope(), "\\FILEID_%i", fid);
1068                 eo_info->end_of_file = 0;
1069         }
1070         if (eosmb_take_name_as_fid) {
1071                 eo_info->fid = g_str_hash(eo_info->filename);
1072         } else {
1073                 eo_info->fid = fid;
1074         }
1075         eo_info->tid = si->tid;
1076         eo_info->uid = si->uid;
1077         eo_info->payload_len = datalen;
1078         eo_info->payload_data = tvb_get_ptr(data_tvb, 0, datalen);
1079         eo_info->smb_file_offset = file_offset;
1080         eo_info->smb_chunk_len = chunk_len;
1081         eo_info->cmd = cmd;
1082         /* Queue data to the listener */
1083
1084         tap_queue_packet(smb_eo_tap, pinfo, eo_info);
1085 } /* feed_eo_smb */
1086
1087 /* Compare funtion to maintain the GSL_fid_info ordered
1088    Order criteria: packet where the fid was opened */
1089 static gint
1090 fid_cmp(smb_fid_info_t *fida, smb_fid_info_t *fidb)
1091 {
1092         return (fida->opened_in - fidb->opened_in);
1093 }
1094
1095 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1096    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
1097    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1098 static gboolean smb_trans_reassembly = TRUE;
1099 gboolean smb_dcerpc_reassembly = TRUE;
1100
1101 static reassembly_table smb_trans_reassembly_table;
1102
1103 static void
1104 smb_trans_reassembly_init(void)
1105 {
1106         /*
1107          * XXX - addresses_ports_reassembly_table_functions?
1108          * Probably correct for SMB-over-NBT and SMB-over-TCP,
1109          * as stuff from two different connections should
1110          * probably not be combined, but what about other
1111          * transports for SMB, e.g. NBF or Netware?
1112          */
1113         reassembly_table_init(&smb_trans_reassembly_table,
1114             &addresses_reassembly_table_functions);
1115 }
1116
1117 static fragment_head *
1118 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
1119                      int offset, guint count, guint pos, guint totlen, smb_info_t *si)
1120 {
1121         fragment_head *fd_head = NULL;
1122         int            more_frags;
1123
1124         /* Don't pass the reassembly code data that doesn't exist */
1125         /* Fail if some or all of the fragment is located beyond the total length */
1126         if ( !tvb_bytes_exist(tvb, offset, count) || (pos > totlen) || (count > totlen) || ((pos + count) > totlen)) {
1127                 THROW(ReportedBoundsError);
1128         }
1129
1130         more_frags = totlen > (pos + count);
1131
1132         DISSECTOR_ASSERT(si);
1133
1134         if (si->sip == NULL) {
1135                 /*
1136                  * We don't have the frame number of the request.
1137                  */
1138                 return NULL;
1139         }
1140
1141         if (!pinfo->fd->flags.visited) {
1142                 fd_head = fragment_add(&smb_trans_reassembly_table, tvb, offset,
1143                                        pinfo, si->sip->frame_req, NULL,
1144                                        pos, count, more_frags);
1145         } else {
1146                 fd_head = fragment_get(&smb_trans_reassembly_table,
1147                                        pinfo, si->sip->frame_req, NULL);
1148         }
1149
1150         if (!fd_head || !(fd_head->flags & FD_DEFRAGMENTED)) {
1151                 /* This is continued - mark it as such, so we recognize
1152                    continuation responses.
1153                 */
1154                 si->sip->flags |= SMB_SIF_IS_CONTINUED;
1155         } else {
1156                 /* We've finished reassembling, so there are no more
1157                    continuation responses.
1158                 */
1159                 si->sip->flags &= ~SMB_SIF_IS_CONTINUED;
1160         }
1161
1162         /* we only show the defragmented packet for the first fragment,
1163            or else we might end up with dissecting one HUGE transaction PDU
1164            a LOT of times. (first fragment is the only one containing the setup
1165            bytes)
1166            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
1167            SMBs. Takes a LOT of time dissecting and is not fun.
1168         */
1169         if ( (pos == 0) && fd_head && (fd_head->flags & FD_DEFRAGMENTED)) {
1170                 return fd_head;
1171         } else {
1172                 return NULL;
1173         }
1174 }
1175
1176
1177
1178
1179
1180 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1181    These variables and functions are used to match
1182    responses with calls
1183    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1184 /*
1185  * The information we need to save about a request in order to show the
1186  * frame number of the request in the dissection of the reply.
1187  */
1188 typedef struct  {
1189         guint32 frame;
1190         guint32 pid_mid;
1191 } smb_saved_info_key_t;
1192
1193 /* unmatched smb_saved_info structures.
1194    For unmatched smb_saved_info structures we store the smb_saved_info
1195    structure using the MID and the PID as the key.
1196
1197    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
1198    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
1199    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
1200 */
1201 static gint
1202 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
1203 {
1204         register guint32 key1 = GPOINTER_TO_UINT(k1);
1205         register guint32 key2 = GPOINTER_TO_UINT(k2);
1206         return key1 == key2;
1207 }
1208 static guint
1209 smb_saved_info_hash_unmatched(gconstpointer k)
1210 {
1211         register guint32 key = GPOINTER_TO_UINT(k);
1212         return key;
1213 }
1214
1215 /* matched smb_saved_info structures.
1216    For matched smb_saved_info structures we store the smb_saved_info
1217    structure twice in the table using the frame number, and a combination
1218    of the MID and the PID, as the key.
1219    The frame number is guaranteed to be unique but if ever someone makes
1220    some change that will renumber the frames in a capture we are in BIG trouble.
1221    This is not likely though since that would break (among other things) all the
1222    reassembly routines as well.
1223
1224    We also need the MID as there may be more than one SMB request or reply
1225    in a single frame, and we also need the PID as there may be more than
1226    one outstanding request with the same MID and different PIDs.
1227 */
1228 static gint
1229 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
1230 {
1231         const smb_saved_info_key_t *key1 = (const smb_saved_info_key_t *)k1;
1232         const smb_saved_info_key_t *key2 = (const smb_saved_info_key_t *)k2;
1233         return (key1->frame == key2->frame) && (key1->pid_mid == key2->pid_mid);
1234 }
1235 static guint
1236 smb_saved_info_hash_matched(gconstpointer k)
1237 {
1238         const smb_saved_info_key_t *key = (const smb_saved_info_key_t *)k;
1239         return key->frame + key->pid_mid;
1240 }
1241
1242 static GSList *conv_tables = NULL;
1243
1244
1245 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1246    End of request/response matching functions
1247    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
1248
1249
1250
1251 typedef struct _smb_uid_t {
1252         char *domain;
1253         char *account;
1254         int   logged_in;
1255         int   logged_out;
1256 } smb_uid_t;
1257
1258 static void
1259 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1260 {
1261         mask &= 0x0000ffff;
1262         if (mask == 0x000001ff) {
1263                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1264         }
1265
1266
1267         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_attribute, tvb, offset, 4, mask);
1268         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_attribute, tvb, offset, 4, mask);
1269         proto_tree_add_boolean(tree, hf_smb_file_access_mask_execute, tvb, offset, 4, mask);
1270         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_ea, tvb, offset, 4, mask);
1271         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_ea, tvb, offset, 4, mask);
1272         proto_tree_add_boolean(tree, hf_smb_file_access_mask_append_data, tvb, offset, 4, mask);
1273         proto_tree_add_boolean(tree, hf_smb_file_access_mask_write_data, tvb, offset, 4, mask);
1274         proto_tree_add_boolean(tree, hf_smb_file_access_mask_read_data, tvb, offset, 4, mask);
1275 }
1276 struct access_mask_info smb_file_access_mask_info = {
1277         "FILE",                         /* Name of specific rights */
1278         smb_file_specific_rights,       /* Dissection function */
1279         NULL,                           /* Generic mapping table */
1280         NULL                            /* Standard mapping table */
1281 };
1282
1283
1284 static void
1285 smb_dir_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
1286 {
1287         mask &= 0x0000ffff;
1288         if (mask == 0x000001ff) {
1289                 proto_tree_add_text(tree, tvb, offset, 4, "[FULL CONTROL]");
1290         }
1291
1292
1293         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_attribute, tvb, offset, 4, mask);
1294         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_attribute, tvb, offset, 4, mask);
1295         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_delete_child, tvb, offset, 4, mask);
1296         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_traverse, tvb, offset, 4, mask);
1297         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_write_ea, tvb, offset, 4, mask);
1298         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_read_ea, tvb, offset, 4, mask);
1299         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_subdir, tvb, offset, 4, mask);
1300         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_add_file, tvb, offset, 4, mask);
1301         proto_tree_add_boolean(tree, hf_smb_dir_access_mask_list, tvb, offset, 4, mask);
1302 }
1303 struct access_mask_info smb_dir_access_mask_info = {
1304         "DIR",                          /* Name of specific rights */
1305         smb_dir_specific_rights,        /* Dissection function */
1306         NULL,                           /* Generic mapping table */
1307         NULL                            /* Standard mapping table */
1308 };
1309
1310
1311
1312 static const value_string buffer_format_vals[] = {
1313         {1,     "Data Block"},
1314         {2,     "Dialect"},
1315         {3,     "Pathname"},
1316         {4,     "ASCII"},
1317         {5,     "Variable Block"},
1318         {0,     NULL}
1319 };
1320
1321 #define POSIX_ACE_TYPE_USER_OBJ         0x01
1322 #define POSIX_ACE_TYPE_USER             0x02
1323 #define POSIX_ACE_TYPE_GROUP_OBJ        0x04
1324 #define POSIX_ACE_TYPE_GROUP            0x08
1325 #define POSIX_ACE_TYPE_MASK             0x10
1326 #define POSIX_ACE_TYPE_OTHER            0x20
1327 static const value_string ace_type_vals[] = {
1328         {POSIX_ACE_TYPE_USER_OBJ,       "User Obj"},
1329         {POSIX_ACE_TYPE_USER,           "User"},
1330         {POSIX_ACE_TYPE_GROUP_OBJ,      "Group Obj"},
1331         {POSIX_ACE_TYPE_GROUP,          "Group"},
1332         {POSIX_ACE_TYPE_MASK,           "Mask"},
1333         {POSIX_ACE_TYPE_OTHER,          "Other"},
1334         {0,     NULL}
1335 };
1336
1337 /*
1338  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1339  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1340  * January 1, 1970, 00:00:00 GMT.
1341  *
1342  * This means we have to do some extra work to convert it.  This code is
1343  * based on the Samba code:
1344  *
1345  *      Unix SMB/Netbios implementation.
1346  *      Version 1.9.
1347  *      time handling functions
1348  *      Copyright (C) Andrew Tridgell 1992-1998
1349  */
1350
1351 /*
1352  * Yield the difference between *A and *B, in seconds, ignoring leap
1353  * seconds.
1354  */
1355 #define TM_YEAR_BASE 1900
1356
1357 static int
1358 tm_diff(struct tm *a, struct tm *b)
1359 {
1360         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1361         int by = b->tm_year + (TM_YEAR_BASE - 1);
1362         int intervening_leap_days =
1363             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1364         int years = ay - by;
1365         int days =
1366             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1367         int hours = 24*days + (a->tm_hour - b->tm_hour);
1368         int minutes = 60*hours + (a->tm_min - b->tm_min);
1369         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1370
1371         return seconds;
1372 }
1373
1374 /*
1375  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1376  * determined.
1377  */
1378 static int
1379 TimeZone(time_t t)
1380 {
1381         struct tm *tm = gmtime(&t);
1382         struct tm  tm_utc;
1383
1384         if (tm == NULL)
1385                 return 0;
1386         tm_utc = *tm;
1387         tm = localtime(&t);
1388         if (tm == NULL)
1389                 return 0;
1390         return tm_diff(&tm_utc, tm);
1391 }
1392
1393 /*
1394  * Return the same value as TimeZone, but it should be more efficient.
1395  *
1396  * We keep a table of DST offsets to prevent calling localtime() on each
1397  * call of this function. This saves a LOT of time on many unixes.
1398  *
1399  * Updated by Paul Eggert <eggert@twinsun.com>
1400  */
1401 #ifndef CHAR_BIT
1402 #define CHAR_BIT 8
1403 #endif
1404
1405 #ifndef TIME_T_MIN
1406 #define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1407                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
1408 #endif
1409 #ifndef TIME_T_MAX
1410 #define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN))
1411 #endif
1412
1413 static int
1414 TimeZoneFaster(time_t t)
1415 {
1416         static struct dst_table {time_t start, end; int zone;} *tdt;
1417         static struct dst_table *dst_table = NULL;
1418         static int table_size = 0;
1419         int        i;
1420         int        zone = 0;
1421
1422         if (t == 0)
1423                 t = time(NULL);
1424
1425         /* Tunis has a 8 day DST region, we need to be careful ... */
1426 #define MAX_DST_WIDTH (365*24*60*60)
1427 #define MAX_DST_SKIP (7*24*60*60)
1428
1429         for (i = 0; i < table_size; i++) {
1430                 if ((t >= dst_table[i].start) && (t <= dst_table[i].end))
1431                         break;
1432         }
1433
1434         if (i < table_size) {
1435                 zone = dst_table[i].zone;
1436         } else {
1437                 time_t low, high;
1438
1439                 zone = TimeZone(t);
1440                 if (dst_table == NULL)
1441                         tdt = (struct dst_table *)g_malloc(sizeof(dst_table[0])*(i+1));
1442                 else
1443                         tdt = (struct dst_table *)g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1444                 if (tdt == NULL) {
1445                         g_free(dst_table);
1446                         table_size = 0;
1447                 } else {
1448                         dst_table = tdt;
1449                         table_size++;
1450
1451                         dst_table[i].zone = zone;
1452                         dst_table[i].start = dst_table[i].end = t;
1453
1454                         /* no entry will cover more than 6 months */
1455                         low = t - MAX_DST_WIDTH/2;
1456                         /* XXX - what if t < MAX_DST_WIDTH/2? */
1457
1458                         high = t + MAX_DST_WIDTH/2;
1459                         /* XXX - what if this overflows? */
1460
1461                         /*
1462                          * Widen the new entry using two bisection searches.
1463                          */
1464                         while (low+60*60 < dst_table[i].start) {
1465                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1466                                         t = dst_table[i].start - MAX_DST_SKIP;
1467                                 else
1468                                         t = low + (dst_table[i].start-low)/2;
1469                                 if (TimeZone(t) == zone)
1470                                         dst_table[i].start = t;
1471                                 else
1472                                         low = t;
1473                         }
1474
1475                         while (high-60*60 > dst_table[i].end) {
1476                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1477                                         t = dst_table[i].end + MAX_DST_SKIP;
1478                                 else
1479                                         t = high - (high-dst_table[i].end)/2;
1480                                 if (TimeZone(t) == zone)
1481                                         dst_table[i].end = t;
1482                                 else
1483                                         high = t;
1484                         }
1485                 }
1486         }
1487         return zone;
1488 }
1489
1490 /*
1491  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1492  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1493  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1494  * daylight savings transitions because some local times are ambiguous.
1495  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1496  */
1497 static int
1498 LocTimeDiff(time_t lt)
1499 {
1500         int    d = TimeZoneFaster(lt);
1501         time_t t = lt + d;
1502
1503         /* if overflow occurred, ignore all the adjustments so far */
1504         if (((t < lt) ^ (d < 0)))
1505                 t = lt;
1506
1507         /*
1508          * Now t should be close enough to the true UTC to yield the
1509          * right answer.
1510          */
1511         return TimeZoneFaster(t);
1512 }
1513
1514 static int
1515 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1516 {
1517         guint32  timeval;
1518         nstime_t ts;
1519
1520         ts.secs = timeval = tvb_get_letohl(tvb, offset);
1521         ts.nsecs = 0;
1522         if (timeval == 0xffffffff) {
1523                 proto_tree_add_time_format_value(tree, hf_date, tvb, offset, 4, &ts,
1524                     "No time specified (0xffffffff)");
1525                 offset += 4;
1526                 return offset;
1527         }
1528
1529         /*
1530          * We add the local time offset.
1531          */
1532         ts.secs = timeval + LocTimeDiff(timeval);
1533
1534         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1535         offset += 4;
1536
1537         return offset;
1538 }
1539
1540 static int
1541 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1542     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1543 {
1544         guint16     dos_time, dos_date;
1545         proto_item *item = NULL;
1546         proto_tree *tree = NULL;
1547         struct tm   tm;
1548         time_t      t;
1549         nstime_t    tv;
1550
1551         static const int mday_noleap[12] = {
1552                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1553         };
1554         static const int mday_leap[12] = {
1555                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1556         };
1557
1558 #define ISLEAP(y) ((((y) % 4) == 0) && ((((y) % 100) != 0) || (((y) % 400) == 0)))
1559
1560         if (time_first) {
1561                 dos_time = tvb_get_letohs(tvb, offset);
1562                 dos_date = tvb_get_letohs(tvb, offset+2);
1563         } else {
1564                 dos_date = tvb_get_letohs(tvb, offset);
1565                 dos_time = tvb_get_letohs(tvb, offset+2);
1566         }
1567
1568         if (((dos_date == 0xffff) && (dos_time == 0xffff)) ||
1569             ((dos_date == 0) && (dos_time == 0))) {
1570                 /*
1571                  * No date/time specified.
1572                  */
1573                 if (parent_tree) {
1574                         tv.secs = 0;
1575                         tv.nsecs = 0;
1576                         proto_tree_add_time_format_value(parent_tree, hf_date, tvb, offset, 4,
1577                             &tv, "No time specified (0x%08x)",
1578                             ((dos_date << 16) | dos_time));
1579                 }
1580                 offset += 4;
1581                 return offset;
1582         }
1583
1584         tm.tm_sec   = (dos_time & 0x1f) * 2;
1585         tm.tm_min   = (dos_time>>5)  & 0x3f;
1586         tm.tm_hour  = (dos_time>>11) & 0x1f;
1587         tm.tm_mday  = dos_date & 0x1f;
1588         tm.tm_mon   = ((dos_date>>5) & 0x0f) - 1;
1589         tm.tm_year  = ((dos_date>>9) & 0x7f) + 1980 - 1900;
1590         tm.tm_isdst = -1;
1591
1592         /*
1593          * Do some sanity checks before calling "mktime()";
1594          * "mktime()" doesn't do them, it "normalizes" out-of-range
1595          * values.
1596          */
1597         if ((tm.tm_sec > 59) || (tm.tm_min > 59) || (tm.tm_hour > 23) ||
1598             (tm.tm_mon < 0) || (tm.tm_mon > 11) ||
1599             (ISLEAP(tm.tm_year + 1900) ?
1600              (tm.tm_mday > mday_leap[tm.tm_mon]) :
1601              (tm.tm_mday > mday_noleap[tm.tm_mon])) ||
1602             ((t = mktime(&tm)) == -1)) {
1603                 /*
1604                  * Invalid date/time.
1605                  */
1606                 if (parent_tree) {
1607                         tv.secs = 0;
1608                         tv.nsecs = 0;
1609                         item = proto_tree_add_time_format_value(parent_tree, hf_date, tvb, offset, 4,
1610                             &tv, "Invalid time (0x%08x)", ((dos_date << 16) | dos_time));
1611                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1612                         if (time_first) {
1613                                 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);
1614                                 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);
1615                         } else {
1616                                 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);
1617                                 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1618                         }
1619                 }
1620                 offset += 4;
1621                 return offset;
1622         }
1623
1624         tv.secs = t;
1625         tv.nsecs = 0;
1626
1627         if (parent_tree) {
1628                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1629                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1630                 if (time_first) {
1631                         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);
1632                         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);
1633                 } else {
1634                         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);
1635                         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);
1636                 }
1637         }
1638
1639         offset += 4;
1640
1641         return offset;
1642 }
1643
1644 static const true_false_string tfs_disposition_delete_on_close = {
1645         "DELETE this file when closed",
1646         "Normal access, do not delete on close"
1647 };
1648
1649 static const true_false_string tfs_pipe_info_flag = {
1650         "SET NAMED PIPE mode",
1651         "Clear NAMED PIPE mode"
1652 };
1653
1654
1655 static const value_string da_access_vals[] = {
1656         { 0,            "Open for reading"},
1657         { 1,            "Open for writing"},
1658         { 2,            "Open for reading and writing"},
1659         { 3,            "Open for execute"},
1660         {0, NULL}
1661 };
1662 static const value_string da_sharing_vals[] = {
1663         { 0,            "Compatibility mode"},
1664         { 1,            "Deny read/write/execute (exclusive)"},
1665         { 2,            "Deny write"},
1666         { 3,            "Deny read/execute"},
1667         { 4,            "Deny none"},
1668         {0, NULL}
1669 };
1670 static const value_string da_locality_vals[] = {
1671         { 0,            "Locality of reference unknown"},
1672         { 1,            "Mainly sequential access"},
1673         { 2,            "Mainly random access"},
1674         { 3,            "Random access with some locality"},
1675         {0, NULL}
1676 };
1677 static const true_false_string tfs_da_caching = {
1678         "Do not cache this file",
1679         "Caching permitted on this file"
1680 };
1681 static const true_false_string tfs_da_writetru = {
1682         "Write through enabled",
1683         "Write through disabled"
1684 };
1685 static int
1686 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
1687 {
1688         guint16     mask;
1689         proto_item *item;
1690         proto_tree *tree;
1691
1692         mask = tvb_get_letohs(tvb, offset);
1693
1694         if (parent_tree) {
1695                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1696                         "%s Access: 0x%04x", type, mask);
1697                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1698
1699                 proto_tree_add_boolean(tree, hf_smb_access_writetru,
1700                         tvb, offset, 2, mask);
1701                 proto_tree_add_boolean(tree, hf_smb_access_caching,
1702                         tvb, offset, 2, mask);
1703                 proto_tree_add_uint(tree, hf_smb_access_locality,
1704                         tvb, offset, 2, mask);
1705                 proto_tree_add_uint(tree, hf_smb_access_sharing,
1706                         tvb, offset, 2, mask);
1707                 proto_tree_add_uint(tree, hf_smb_access_mode,
1708                         tvb, offset, 2, mask);
1709         }
1710
1711         offset += 2;
1712
1713         return offset;
1714 }
1715
1716 #define SMB_FILE_ATTRIBUTE_READ_ONLY                    0x00000001
1717 #define SMB_FILE_ATTRIBUTE_HIDDEN                               0x00000002
1718 #define SMB_FILE_ATTRIBUTE_SYSTEM                               0x00000004
1719 #define SMB_FILE_ATTRIBUTE_VOLUME                               0x00000008
1720 #define SMB_FILE_ATTRIBUTE_DIRECTORY                    0x00000010
1721 #define SMB_FILE_ATTRIBUTE_ARCHIVE                              0x00000020
1722 #define SMB_FILE_ATTRIBUTE_DEVICE                               0x00000040
1723 #define SMB_FILE_ATTRIBUTE_NORMAL                               0x00000080
1724 #define SMB_FILE_ATTRIBUTE_TEMPORARY                    0x00000100
1725 #define SMB_FILE_ATTRIBUTE_SPARSE                               0x00000200
1726 #define SMB_FILE_ATTRIBUTE_REPARSE                              0x00000400
1727 #define SMB_FILE_ATTRIBUTE_COMPRESSED                   0x00000800
1728 #define SMB_FILE_ATTRIBUTE_OFFLINE                              0x00001000
1729 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1730 #define SMB_FILE_ATTRIBUTE_ENCRYPTED                    0x00004000
1731
1732 static const true_false_string tfs_file_attribute_read_only = {
1733         "READ ONLY",
1734         "NOT read only",
1735 };
1736 static const true_false_string tfs_file_attribute_hidden = {
1737         "HIDDEN",
1738         "NOT hidden"
1739 };
1740 static const true_false_string tfs_file_attribute_system = {
1741         "SYSTEM file/dir",
1742         "NOT a system file/dir"
1743 };
1744 static const true_false_string tfs_file_attribute_volume = {
1745         "VOLUME ID",
1746         "NOT a volume ID"
1747 };
1748 static const true_false_string tfs_file_attribute_directory = {
1749         "DIRECTORY",
1750         "NOT a directory"
1751 };
1752 static const true_false_string tfs_file_attribute_archive = {
1753         "Modified since last ARCHIVE",
1754         "Has NOT been modified since last archive"
1755 };
1756 static const true_false_string tfs_file_attribute_device = {
1757         "A DEVICE",
1758         "NOT a device"
1759 };
1760 static const true_false_string tfs_file_attribute_normal = {
1761         "An ordinary file/dir",
1762         "Has some attribute set"
1763 };
1764 static const true_false_string tfs_file_attribute_temporary = {
1765         "A TEMPORARY file",
1766         "NOT a temporary file"
1767 };
1768 static const true_false_string tfs_file_attribute_sparse = {
1769         "A SPARSE file",
1770         "NOT a sparse file"
1771 };
1772 static const true_false_string tfs_file_attribute_reparse = {
1773         "Has an associated REPARSE POINT",
1774         "Does NOT have an associated reparse point"
1775 };
1776 static const true_false_string tfs_file_attribute_compressed = {
1777         "COMPRESSED",
1778         "Uncompressed"
1779 };
1780 static const true_false_string tfs_file_attribute_offline = {
1781         "OFFLINE",
1782         "Online"
1783 };
1784 static const true_false_string tfs_file_attribute_not_content_indexed = {
1785         "CONTENT INDEXED",
1786         "NOT content indexed"
1787 };
1788 static const true_false_string tfs_file_attribute_encrypted = {
1789         "This is an ENCRYPTED file",
1790         "This is NOT an encrypted file"
1791 };
1792
1793 /*
1794  * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
1795  * section 2.2.1.2.4 of [MS-CIFS], in cases where it's just file attributes,
1796  * not search attributes.
1797  */
1798 static int
1799 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1800 {
1801         guint16     mask;
1802         proto_item *item;
1803         proto_tree *tree;
1804
1805         mask = tvb_get_letohs(tvb, offset);
1806
1807         if (parent_tree) {
1808                 item = proto_tree_add_item(parent_tree, hf_smb_file_attr_16bit, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1809                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1810
1811                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1812                                 tvb, offset, 2, mask);
1813                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1814                                 tvb, offset, 2, mask);
1815                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1816                                 tvb, offset, 2, mask);
1817                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1818                                 tvb, offset, 2, mask);
1819                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1820                                 tvb, offset, 2, mask);
1821                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1822                                 tvb, offset, 2, mask);
1823         }
1824
1825         offset += 2;
1826
1827         return offset;
1828 }
1829
1830 /*
1831  * 3.11 in the SNIA CIFS spec
1832  * SMB_EXT_FILE_ATTR, section 2.2.1.2.3 in the [MS-CIFS] spec
1833  */
1834 static int
1835 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1836     int len, guint32 mask)
1837 {
1838         proto_item *item;
1839         proto_tree *tree;
1840
1841         if (parent_tree) {
1842                 item = proto_tree_add_uint(parent_tree, hf_smb_file_eattr, tvb, offset, len, mask);
1843                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1844                 if (len == 0)
1845                         PROTO_ITEM_SET_GENERATED(item);
1846                 /*
1847                  * XXX - Network Monitor disagrees on some of the
1848                  * bits, e.g. the bits above temporary are "atomic write"
1849                  * and "transaction write", and it says nothing about the
1850                  * bits above that.
1851                  *
1852                  * Does the Win32 API documentation, or the NT Native API book,
1853                  * suggest anything?
1854                  */
1855                 proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1856                         tvb, offset, len, mask);
1857                 proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1858                         tvb, offset, len, mask);
1859                 proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1860                         tvb, offset, len, mask);
1861                 proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1862                         tvb, offset, len, mask);
1863                 proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1864                         tvb, offset, len, mask);
1865                 proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1866                         tvb, offset, len, mask);
1867                 proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1868                         tvb, offset, len, mask);
1869                 proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1870                         tvb, offset, len, mask);
1871                 proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1872                         tvb, offset, len, mask);
1873                 proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1874                         tvb, offset, len, mask);
1875                 proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1876                         tvb, offset, len, mask);
1877                 proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1878                         tvb, offset, len, mask);
1879                 proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1880                         tvb, offset, len, mask);
1881                 proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1882                         tvb, offset, len, mask);
1883                 proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1884                         tvb, offset, len, mask);
1885         }
1886
1887         offset += len;
1888
1889         return offset;
1890 }
1891
1892 /* 3.11 */
1893 int
1894 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1895 {
1896         guint32 mask;
1897
1898         mask = tvb_get_letohl(tvb, offset);
1899
1900         offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
1901
1902         return offset;
1903 }
1904
1905 static int
1906 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1907 {
1908         guint8      mask;
1909         proto_item *item;
1910         proto_tree *tree;
1911
1912         mask = tvb_get_guint8(tvb, offset);
1913
1914         if (parent_tree) {
1915                 item = proto_tree_add_item(parent_tree, hf_smb_file_attr_8bit, tvb, offset, 1, ENC_NA);
1916                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1917
1918                 proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1919                         tvb, offset, 1, mask);
1920                 proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1921                         tvb, offset, 1, mask);
1922                 proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1923                         tvb, offset, 1, mask);
1924                 proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1925                         tvb, offset, 1, mask);
1926                 proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1927                         tvb, offset, 1, mask);
1928                 proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1929                         tvb, offset, 1, mask);
1930         }
1931
1932         offset += 1;
1933
1934         return offset;
1935 }
1936
1937 static const true_false_string tfs_search_attribute_read_only = {
1938         "Include READ ONLY files in search results",
1939         "Do NOT include read only files in search results",
1940 };
1941 static const true_false_string tfs_search_attribute_hidden = {
1942         "Include HIDDEN files in search results",
1943         "Do NOT include hidden files in search results"
1944 };
1945 static const true_false_string tfs_search_attribute_system = {
1946         "Include SYSTEM files in search results",
1947         "Do NOT include system files in search results"
1948 };
1949 static const true_false_string tfs_search_attribute_volume = {
1950         "Include VOLUME IDs in search results",
1951         "Do NOT include volume IDs in search results"
1952 };
1953 static const true_false_string tfs_search_attribute_directory = {
1954         "Include DIRECTORIES in search results",
1955         "Do NOT include directories in search results"
1956 };
1957 static const true_false_string tfs_search_attribute_archive = {
1958         "Include ARCHIVE files in search results",
1959         "Do NOT include archive files in search results"
1960 };
1961
1962 /*
1963  * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
1964  * section 2.2.1.2.4 of [MS-CIFS], in cases where it's search attributes.
1965  */
1966 static int
1967 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1968 {
1969         guint16     mask;
1970         proto_item *item;
1971         proto_tree *tree;
1972
1973         mask = tvb_get_letohs(tvb, offset);
1974
1975         if (parent_tree) {
1976                 item = proto_tree_add_item(parent_tree, hf_smb_search_attribute, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1977                 tree = proto_item_add_subtree(item, ett_smb_search);
1978
1979                 proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1980                         tvb, offset, 2, mask);
1981                 proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1982                         tvb, offset, 2, mask);
1983                 proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1984                         tvb, offset, 2, mask);
1985                 proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1986                         tvb, offset, 2, mask);
1987                 proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1988                         tvb, offset, 2, mask);
1989                 proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1990                         tvb, offset, 2, mask);
1991         }
1992
1993         offset += 2;
1994         return offset;
1995 }
1996
1997 #if 0
1998 /*
1999  * XXX - this isn't used.
2000  * Is this used for anything?  NT Create AndX doesn't use it.
2001  * Is there some 16-bit attribute field with more bits than Read Only,
2002  * Hidden, System, Volume ID, Directory, and Archive?
2003  */
2004 static int
2005 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2006 {
2007         guint32     mask;
2008         proto_item *item;
2009         proto_tree *tree;
2010
2011         mask = tvb_get_letohl(tvb, offset);
2012
2013         if (parent_tree) {
2014                 item = proto_tree_add_item(parent_tree, hf_smb_file_eattr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2015                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
2016         }
2017         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
2018                 tvb, offset, 2, mask);
2019         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
2020                 tvb, offset, 2, mask);
2021         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
2022                 tvb, offset, 2, mask);
2023         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
2024                 tvb, offset, 2, mask);
2025         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
2026                 tvb, offset, 2, mask);
2027         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
2028                 tvb, offset, 2, mask);
2029         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
2030                 tvb, offset, 2, mask);
2031         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
2032                 tvb, offset, 2, mask);
2033         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
2034                 tvb, offset, 2, mask);
2035         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
2036                 tvb, offset, 2, mask);
2037         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
2038                 tvb, offset, 2, mask);
2039         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
2040                 tvb, offset, 2, mask);
2041         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
2042                 tvb, offset, 2, mask);
2043         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
2044                 tvb, offset, 2, mask);
2045         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
2046                 tvb, offset, 2, mask);
2047
2048         offset += 2;
2049
2050         return offset;
2051 }
2052 #endif
2053
2054
2055 #define SERVER_CAP_RAW_MODE            0x00000001
2056 #define SERVER_CAP_MPX_MODE            0x00000002
2057 #define SERVER_CAP_UNICODE             0x00000004
2058 #define SERVER_CAP_LARGE_FILES         0x00000008
2059 #define SERVER_CAP_NT_SMBS             0x00000010
2060 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
2061 #define SERVER_CAP_STATUS32            0x00000040
2062 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
2063 #define SERVER_CAP_LOCK_AND_READ       0x00000100
2064 #define SERVER_CAP_NT_FIND             0x00000200
2065 #define SERVER_CAP_DFS                 0x00001000
2066 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
2067 #define SERVER_CAP_LARGE_READX         0x00004000
2068 #define SERVER_CAP_LARGE_WRITEX        0x00008000
2069 #define SERVER_CAP_LWIO                0x00010000
2070 #define SERVER_CAP_UNIX                0x00800000
2071 #define SERVER_CAP_COMPRESSED_DATA     0x02000000
2072 #define SERVER_CAP_DYNAMIC_REAUTH      0x20000000
2073 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
2074
2075 static const true_false_string tfs_server_cap_raw_mode = {
2076         "Read Raw and Write Raw are supported",
2077         "Read Raw and Write Raw are not supported"
2078 };
2079 static const true_false_string tfs_server_cap_mpx_mode = {
2080         "Read Mpx and Write Mpx are supported",
2081         "Read Mpx and Write Mpx are not supported"
2082 };
2083 static const true_false_string tfs_server_cap_unicode = {
2084         "Unicode strings are supported",
2085         "Unicode strings are not supported"
2086 };
2087 static const true_false_string tfs_server_cap_large_files = {
2088         "Large files are supported",
2089         "Large files are not supported",
2090 };
2091 static const true_false_string tfs_server_cap_nt_smbs = {
2092         "NT SMBs are supported",
2093         "NT SMBs are not supported"
2094 };
2095 static const true_false_string tfs_server_cap_rpc_remote_apis = {
2096         "RPC remote APIs are supported",
2097         "RPC remote APIs are not supported"
2098 };
2099 static const true_false_string tfs_server_cap_nt_status = {
2100         "NT status codes are supported",
2101         "NT status codes are not supported"
2102 };
2103 static const true_false_string tfs_server_cap_level_ii_oplocks = {
2104         "Level 2 oplocks are supported",
2105         "Level 2 oplocks are not supported"
2106 };
2107 static const true_false_string tfs_server_cap_lock_and_read = {
2108         "Lock and Read is supported",
2109         "Lock and Read is not supported"
2110 };
2111 static const true_false_string tfs_server_cap_nt_find = {
2112         "NT Find is supported",
2113         "NT Find is not supported"
2114 };
2115 static const true_false_string tfs_server_cap_dfs = {
2116         "Dfs is supported",
2117         "Dfs is not supported"
2118 };
2119 static const true_false_string tfs_server_cap_infolevel_passthru = {
2120         "NT information level request passthrough is supported",
2121         "NT information level request passthrough is not supported"
2122 };
2123 static const true_false_string tfs_server_cap_large_readx = {
2124         "Large Read andX is supported",
2125         "Large Read andX is not supported"
2126 };
2127 static const true_false_string tfs_server_cap_large_writex = {
2128         "Large Write andX is supported",
2129         "Large Write andX is not supported"
2130 };
2131 static const true_false_string tfs_server_cap_lwio = {
2132         "LWIO ioctl/fsctl is supported",
2133         "LWIO ioctl/fsctl is not supported"
2134 };
2135 static const true_false_string tfs_server_cap_unix = {
2136         "UNIX extensions are supported",
2137         "UNIX extensions are not supported"
2138 };
2139 static const true_false_string tfs_server_cap_compressed_data = {
2140         "Compressed data transfer is supported",
2141         "Compressed data transfer is not supported"
2142 };
2143 static const true_false_string tfs_server_cap_dynamic_reauth = {
2144         "Dynamic Reauth is supported",
2145         "Dynamic Reauth is not supported"
2146 };
2147 static const true_false_string tfs_server_cap_extended_security = {
2148         "Extended security exchanges are supported",
2149         "Extended security exchanges are not supported"
2150 };
2151 static int
2152 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2153 {
2154         guint32     mask;
2155         proto_item *item;
2156         proto_tree *tree;
2157
2158         mask = tvb_get_letohl(tvb, offset);
2159
2160         if (parent_tree) {
2161                 item = proto_tree_add_item(parent_tree, hf_smb_server_cap, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2162                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
2163
2164                 proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
2165                         tvb, offset, 4, mask);
2166                 proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
2167                         tvb, offset, 4, mask);
2168                 proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
2169                         tvb, offset, 4, mask);
2170                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
2171                         tvb, offset, 4, mask);
2172                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
2173                         tvb, offset, 4, mask);
2174                 proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
2175                         tvb, offset, 4, mask);
2176                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
2177                         tvb, offset, 4, mask);
2178                 proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
2179                         tvb, offset, 4, mask);
2180                 proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
2181                         tvb, offset, 4, mask);
2182                 proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
2183                         tvb, offset, 4, mask);
2184                 proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
2185                         tvb, offset, 4, mask);
2186                 proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
2187                         tvb, offset, 4, mask);
2188                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
2189                         tvb, offset, 4, mask);
2190                 proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
2191                         tvb, offset, 4, mask);
2192                 proto_tree_add_boolean(tree, hf_smb_server_cap_lwio,
2193                         tvb, offset, 4, mask);
2194                 proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
2195                         tvb, offset, 4, mask);
2196                 proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
2197                         tvb, offset, 4, mask);
2198                 proto_tree_add_boolean(tree, hf_smb_server_cap_dynamic_reauth,
2199                         tvb, offset, 4, mask);
2200                 proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
2201                         tvb, offset, 4, mask);
2202         }
2203
2204         return mask;
2205 }
2206
2207 #define RAWMODE_READ   0x01
2208 #define RAWMODE_WRITE  0x02
2209 static const true_false_string tfs_rm_read = {
2210         "Read Raw is supported",
2211         "Read Raw is not supported"
2212 };
2213 static const true_false_string tfs_rm_write = {
2214         "Write Raw is supported",
2215         "Write Raw is not supported"
2216 };
2217
2218 static int
2219 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2220 {
2221         guint16     mask;
2222         proto_item *item;
2223         proto_tree *tree;
2224
2225         mask = tvb_get_letohs(tvb, offset);
2226
2227         if (parent_tree) {
2228                 item = proto_tree_add_item(parent_tree, hf_smb_rm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2229                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2230
2231                 proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2232                 proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2233         }
2234
2235         offset += 2;
2236
2237         return offset;
2238 }
2239
2240 #define SECURITY_MODE_MODE             0x01
2241 #define SECURITY_MODE_PASSWORD         0x02
2242 #define SECURITY_MODE_SIGNATURES       0x04
2243 #define SECURITY_MODE_SIG_REQUIRED     0x08
2244 static const true_false_string tfs_sm_mode = {
2245         "USER security mode",
2246         "SHARE security mode"
2247 };
2248 static const true_false_string tfs_sm_password = {
2249         "ENCRYPTED password. Use challenge/response",
2250         "PLAINTEXT password"
2251 };
2252 static const true_false_string tfs_sm_signatures = {
2253         "Security signatures ENABLED",
2254         "Security signatures NOT enabled"
2255 };
2256 static const true_false_string tfs_sm_sig_required = {
2257         "Security signatures REQUIRED",
2258         "Security signatures NOT required"
2259 };
2260
2261 static int
2262 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2263 {
2264         guint16     mask = 0;
2265         proto_item *item = NULL;
2266         proto_tree *tree = NULL;
2267
2268         switch(wc) {
2269         case 13:
2270                 mask = tvb_get_letohs(tvb, offset);
2271                 item = proto_tree_add_item(parent_tree, hf_smb_sm16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2272                 tree = proto_item_add_subtree(item, ett_smb_mode);
2273                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2274                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2275                 offset += 2;
2276                 break;
2277
2278         case 17:
2279                 mask = tvb_get_guint8(tvb, offset);
2280                 item = proto_tree_add_item(parent_tree, hf_smb_sm, tvb, offset, 1, ENC_NA);
2281                 tree = proto_item_add_subtree(item, ett_smb_mode);
2282                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2283                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2284                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2285                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2286                 offset += 1;
2287                 break;
2288         }
2289
2290         return offset;
2291 }
2292
2293 #define MAX_DIALECTS 20
2294 struct negprot_dialects {
2295         int   num;
2296         char *name[MAX_DIALECTS+1];
2297 };
2298
2299 static int
2300 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2301 {
2302         proto_item *it = NULL;
2303         proto_tree *tr = NULL;
2304         guint16     bc;
2305         guint8      wc;
2306         struct negprot_dialects *dialects = NULL;
2307
2308         DISSECTOR_ASSERT(si);
2309
2310         WORD_COUNT;
2311
2312         BYTE_COUNT;
2313
2314         if (tree) {
2315                 tvb_ensure_bytes_exist(tvb, offset, bc);
2316                 it = proto_tree_add_text(tree, tvb, offset, bc, "Requested Dialects");
2317                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2318         }
2319
2320         if (!pinfo->fd->flags.visited && si->sip) {
2321                 dialects = wmem_new(wmem_file_scope(), struct negprot_dialects);
2322                 dialects->num = 0;
2323                 si->sip->extra_info_type = SMB_EI_DIALECTS;
2324                 si->sip->extra_info = dialects;
2325         }
2326
2327         while (bc) {
2328                 int len;
2329                 const guint8 *str;
2330                 proto_item *dit = NULL;
2331                 proto_tree *dtr = NULL;
2332
2333                 /* XXX - what if this runs past bc? */
2334                 tvb_ensure_bytes_exist(tvb, offset+1, 1);
2335                 str = tvb_get_const_stringz(tvb, offset+1, &len);
2336
2337                 if (tr) {
2338                         dit = proto_tree_add_string(tr, hf_smb_dialect, tvb, offset, len+1, str);
2339                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2340                 }
2341
2342                 /* Buffer Format */
2343                 CHECK_BYTE_COUNT(1);
2344                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2345                         ENC_LITTLE_ENDIAN);
2346                 COUNT_BYTES(1);
2347
2348                 /*Dialect Name */
2349                 CHECK_BYTE_COUNT(len);
2350                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2351                         len, str);
2352                 COUNT_BYTES(len);
2353
2354                 if (!pinfo->fd->flags.visited && dialects && (dialects->num < MAX_DIALECTS)) {
2355                         dialects->name[dialects->num++] = wmem_strdup(wmem_file_scope(), str);
2356                 }
2357         }
2358
2359
2360         END_OF_SMB
2361
2362         return offset;
2363 }
2364
2365 static int
2366 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2367 {
2368         guint8      wc;
2369         guint16     dialect;
2370         const char *dn;
2371         int         dn_len;
2372         guint16     bc;
2373         guint16     ekl          = 0;
2374         guint32     caps         = 0;
2375         gint16      tz;
2376         const char *dialect_name = NULL;
2377         struct negprot_dialects *dialects = NULL;
2378
2379         DISSECTOR_ASSERT(si);
2380
2381         WORD_COUNT;
2382
2383         /* Dialect Index */
2384         dialect = tvb_get_letohs(tvb, offset);
2385
2386         if (si->sip && (si->sip->extra_info_type == SMB_EI_DIALECTS)) {
2387                 dialects = (struct negprot_dialects *)si->sip->extra_info;
2388                 if (dialect < dialects->num) {
2389                         dialect_name = dialects->name[dialect];
2390                 }
2391         }
2392         if (!dialect_name) {
2393                 dialect_name = "unknown";
2394         }
2395
2396         switch(wc) {
2397         case 1:
2398                 if (dialect == 0xffff) {
2399                         proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2400                                 tvb, offset, 2, dialect,
2401                                 "-1, PC NETWORK PROGRAM 1.0 chosen");
2402                 } else {
2403                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2404                                 tvb, offset, 2, dialect);
2405                 }
2406                 break;
2407         case 13:
2408                 proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2409                         tvb, offset, 2, dialect,
2410                         "%u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2411                 break;
2412         case 17:
2413                 proto_tree_add_uint_format_value(tree, hf_smb_dialect_index,
2414                         tvb, offset, 2, dialect,
2415                         "%u: %s", dialect, dialect_name);
2416                 break;
2417         default:
2418                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
2419                 proto_tree_add_text(tree, tvb, offset, wc*2,
2420                         "Words for unknown response format");
2421                 offset += wc*2;
2422                 goto bytecount;
2423         }
2424         offset += 2;
2425
2426         switch(wc) {
2427         case 13:
2428                 /* Security Mode */
2429                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2430
2431                 /* Maximum Transmit Buffer Size */
2432                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2433                         tvb, offset, 2, ENC_LITTLE_ENDIAN);
2434                 offset += 2;
2435
2436                 /* Maximum Multiplex Count */
2437                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2438                         tvb, offset, 2, ENC_LITTLE_ENDIAN);
2439                 offset += 2;
2440
2441                 /* Maximum Vcs Number */
2442                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2443                         tvb, offset, 2, ENC_LITTLE_ENDIAN);
2444                 offset += 2;
2445
2446                 /* raw mode */
2447                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2448
2449                 /* session key */
2450                 proto_tree_add_item(tree, hf_smb_session_key,
2451                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
2452                 offset += 4;
2453
2454                 /* current time and date at server */
2455                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2456                     TRUE);
2457
2458                 /* time zone */
2459                 tz = tvb_get_letohs(tvb, offset);
2460                 proto_tree_add_int_format_value(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "%d min from UTC", tz);
2461                 offset += 2;
2462
2463                 /* encryption key length */
2464                 ekl = tvb_get_letohs(tvb, offset);
2465                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2466                 offset += 2;
2467
2468                 /* 2 reserved bytes */
2469                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
2470                 offset += 2;
2471
2472                 break;
2473
2474         case 17:
2475                 /* Security Mode */
2476                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2477
2478                 /* Maximum Multiplex Count */
2479                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2480                         tvb, offset, 2, ENC_LITTLE_ENDIAN);
2481                 offset += 2;
2482
2483                 /* Maximum Vcs Number */
2484                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2485                         tvb, offset, 2, ENC_LITTLE_ENDIAN);
2486                 offset += 2;
2487
2488                 /* Maximum Transmit Buffer Size */
2489                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2490                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
2491                 offset += 4;
2492
2493                 /* maximum raw buffer size */
2494                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2495                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
2496                 offset += 4;
2497
2498                 /* session key */
2499                 proto_tree_add_item(tree, hf_smb_session_key,
2500                         tvb, offset, 4, ENC_LITTLE_ENDIAN);
2501                 offset += 4;
2502
2503                 /* server capabilities */
2504                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2505                 offset += 4;
2506
2507                 /* system time */
2508                 offset = dissect_nt_64bit_time(tvb, tree, offset,
2509                                 hf_smb_system_time);
2510
2511                 /* time zone */
2512                 tz = tvb_get_letohs(tvb, offset);
2513                 proto_tree_add_int_format_value(tree, hf_smb_server_timezone,
2514                         tvb, offset, 2, tz,
2515                         "%d min from UTC", tz);
2516                 offset += 2;
2517
2518                 /* encryption key length */
2519                 ekl = tvb_get_guint8(tvb, offset);
2520                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2521                         tvb, offset, 1, ekl);
2522                 offset += 1;
2523
2524                 break;
2525         }
2526
2527         BYTE_COUNT;
2528
2529         switch(wc) {
2530         case 13:
2531                 /* challenge/response encryption key */
2532                 if (ekl) {
2533                         CHECK_BYTE_COUNT(ekl);
2534                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, ENC_NA);
2535                         COUNT_BYTES(ekl);
2536                 }
2537
2538                 /*
2539                  * Primary domain.
2540                  *
2541                  * XXX - not present if negotiated dialect isn't
2542                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2543                  * have to see the request, or assume what dialect strings
2544                  * were sent, to determine that.
2545                  *
2546                  * Is this something other than a primary domain if the
2547                  * negotiated dialect is Windows for Workgroups 3.1a?
2548                  * It appears to be 8 bytes of binary data in at least
2549                  * one capture - is that an encryption key or something
2550                  * such as that?
2551                  */
2552                 dn = get_unicode_or_ascii_string(tvb, &offset,
2553                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2554                 if (dn == NULL)
2555                         goto endofcommand;
2556                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2557                         offset, dn_len, dn);
2558                 COUNT_BYTES(dn_len);
2559                 break;
2560
2561         case 17:
2562                 if (!(caps & SERVER_CAP_EXTENDED_SECURITY)) {
2563                         /* challenge/response encryption key */
2564                         /* XXX - is this aligned on an even boundary? */
2565                         if (ekl) {
2566                                 CHECK_BYTE_COUNT(ekl);
2567                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2568                                         tvb, offset, ekl, ENC_NA);
2569                                 COUNT_BYTES(ekl);
2570                         }
2571
2572                         /* domain */
2573                         /* this string is special, unicode is flagged in caps */
2574                         /* This string is NOT padded to be 16bit aligned.
2575                            (seen in actual capture)
2576                            XXX - I've seen a capture where it appears to be
2577                            so aligned, but I've also seen captures where
2578                            it is.  The captures where it appeared to be
2579                            aligned may have been from buggy servers. */
2580                         /* However, don't get rid of existing setting */
2581                         si->unicode = (caps & SERVER_CAP_UNICODE) || si->unicode;
2582
2583                         dn = get_unicode_or_ascii_string(tvb,
2584                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2585                                 &bc);
2586                         if (dn == NULL)
2587                                 goto endofcommand;
2588                         proto_tree_add_string(tree, hf_smb_primary_domain,
2589                                 tvb, offset, dn_len, dn);
2590                         COUNT_BYTES(dn_len);
2591
2592                         /* server name, seen in w2k pro capture */
2593                         dn = get_unicode_or_ascii_string(tvb,
2594                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2595                                 &bc);
2596                         if (dn == NULL)
2597                                 goto endofcommand;
2598                         proto_tree_add_string(tree, hf_smb_server,
2599                                 tvb, offset, dn_len, dn);
2600                         COUNT_BYTES(dn_len);
2601
2602                 } else {
2603                         proto_item *blob_item;
2604                         guint16 sbloblen;
2605
2606                         /* guid */
2607                         /* XXX - show it in the standard Microsoft format
2608                            for GUIDs? */
2609                         CHECK_BYTE_COUNT(16);
2610                         proto_tree_add_item(tree, hf_smb_server_guid,
2611                                 tvb, offset, 16, ENC_NA);
2612                         COUNT_BYTES(16);
2613
2614                         /* security blob */
2615                         /* If it runs past the end of the captured data, don't
2616                          * try to put all of it into the protocol tree as the
2617                          * raw security blob; we might get an exception on
2618                          * short frames and then we will not see anything at all
2619                          * of the security blob.
2620                          */
2621                         sbloblen = bc;
2622                         if (sbloblen > tvb_length_remaining(tvb, offset)) {
2623                                 sbloblen = tvb_length_remaining(tvb, offset);
2624                         }
2625                         blob_item = proto_tree_add_item(
2626                                 tree, hf_smb_security_blob,
2627                                 tvb, offset, sbloblen, ENC_NA);
2628
2629                         /*
2630                          * If Extended security and BCC == 16, then raw
2631                          * NTLMSSP is in use. We need to save this info
2632                          */
2633
2634                         if (bc) {
2635                                 tvbuff_t *gssapi_tvb;
2636                                 proto_tree *gssapi_tree;
2637
2638                                 gssapi_tree = proto_item_add_subtree(
2639                                         blob_item, ett_smb_secblob);
2640
2641                                 /*
2642                                  * Set the reported length of this to
2643                                  * the reported length of the blob,
2644                                  * rather than the amount of data
2645                                  * available from the blob, so that
2646                                  * we'll throw the right exception if
2647                                  * it's too short.
2648                                  */
2649                                 gssapi_tvb = tvb_new_subset(
2650                                         tvb, offset, sbloblen, bc);
2651
2652                                 call_dissector(
2653                                         gssapi_handle, gssapi_tvb, pinfo,
2654                                         gssapi_tree);
2655
2656                                 if (si->ct)
2657                                   si->ct->raw_ntlmssp = 0;
2658
2659                                 COUNT_BYTES(bc);
2660                         }
2661                         else {
2662
2663                           /*
2664                            * There is no blob. We just have to make sure
2665                            * that subsequent routines know to call the
2666                            * right things ...
2667                            */
2668
2669                           if (si->ct)
2670                             si->ct->raw_ntlmssp = 1;
2671
2672                         }
2673                 }
2674                 break;
2675         }
2676
2677         END_OF_SMB
2678
2679         return offset;
2680 }
2681
2682
2683 static int
2684 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2685 {
2686         int         dn_len;
2687         const char *dn;
2688         guint8      wc;
2689         guint16     bc;
2690
2691         DISSECTOR_ASSERT(si);
2692
2693         WORD_COUNT;
2694
2695         BYTE_COUNT;
2696
2697         /* buffer format */
2698         CHECK_BYTE_COUNT(1);
2699         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2700         COUNT_BYTES(1);
2701
2702         /* dir name */
2703         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2704                 FALSE, FALSE, &bc);
2705
2706         if ((!pinfo->fd->flags.visited) && si->sip) {
2707                 si->sip->extra_info_type = SMB_EI_FILENAME;
2708                 si->sip->extra_info = wmem_strdup(wmem_file_scope(), dn);
2709         }
2710
2711         if (dn == NULL)
2712                 goto endofcommand;
2713         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2714                 dn);
2715         COUNT_BYTES(dn_len);
2716
2717         col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s",
2718                     format_text(dn, strlen(dn)));
2719
2720         END_OF_SMB
2721
2722         return offset;
2723 }
2724
2725 static int
2726 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2727 {
2728         guint8      wc;
2729         guint16     bc;
2730         proto_item *item = NULL;
2731
2732         DISSECTOR_ASSERT(si);
2733
2734         if (si->sip && (si->sip->extra_info_type == SMB_EI_FILENAME)) {
2735                 item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, (const char *)si->sip->extra_info);
2736                 PROTO_ITEM_SET_GENERATED(item);
2737         }
2738
2739
2740         WORD_COUNT;
2741
2742         BYTE_COUNT;
2743
2744         END_OF_SMB
2745
2746         return offset;
2747 }
2748
2749 static int
2750 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)
2751 {
2752         guint8      wc;
2753         guint16     bc;
2754         proto_item *item = NULL;
2755
2756         DISSECTOR_ASSERT(si);
2757
2758         if (si->sip && (si->sip->extra_info_type == SMB_EI_RENAMEDATA)) {
2759                 smb_rename_saved_info_t *rni = (smb_rename_saved_info_t *)si->sip->extra_info;
2760
2761                 item = proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
2762                 PROTO_ITEM_SET_GENERATED(item);
2763                 item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
2764                 PROTO_ITEM_SET_GENERATED(item);
2765         }
2766
2767
2768         WORD_COUNT;
2769
2770         BYTE_COUNT;
2771
2772         END_OF_SMB
2773
2774         return offset;
2775 }
2776
2777 static int
2778 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_)
2779 {
2780         guint16 ec, bc;
2781         guint8  wc;
2782
2783         WORD_COUNT;
2784
2785         /* echo count */
2786         ec = tvb_get_letohs(tvb, offset);
2787         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2788         offset += 2;
2789
2790         BYTE_COUNT;
2791
2792         if (bc != 0) {
2793                 /* echo data */
2794                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, ENC_NA);
2795                 COUNT_BYTES(bc);
2796         }
2797
2798         END_OF_SMB
2799
2800         return offset;
2801 }
2802
2803 static int
2804 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_)
2805 {
2806         guint16 bc;
2807         guint8  wc;
2808
2809         WORD_COUNT;
2810
2811         /* echo sequence number */
2812         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2813         offset += 2;
2814
2815         BYTE_COUNT;
2816
2817         if (bc != 0) {
2818                 /* echo data */
2819                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, ENC_NA);
2820                 COUNT_BYTES(bc);
2821         }
2822
2823         END_OF_SMB
2824
2825         return offset;
2826 }
2827
2828 static int
2829 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2830 {
2831         int         an_len, pwlen;
2832         const char *an;
2833         guint8      wc;
2834         guint16     bc;
2835
2836         DISSECTOR_ASSERT(si);
2837
2838         WORD_COUNT;
2839
2840         BYTE_COUNT;
2841
2842         /* buffer format */
2843         CHECK_BYTE_COUNT(1);
2844         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2845         COUNT_BYTES(1);
2846
2847         /* Path */
2848         an = get_unicode_or_ascii_string(tvb, &offset,
2849                 si->unicode, &an_len, FALSE, FALSE, &bc);
2850         if (an == NULL)
2851                 goto endofcommand;
2852         proto_tree_add_string(tree, hf_smb_path, tvb,
2853                 offset, an_len, an);
2854         COUNT_BYTES(an_len);
2855
2856         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
2857                     format_text(an, strlen(an)));
2858
2859         /* buffer format */
2860         CHECK_BYTE_COUNT(1);
2861         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2862         COUNT_BYTES(1);
2863
2864         /* password, ANSI */
2865         /* XXX - what if this runs past bc? */
2866         pwlen = tvb_strsize(tvb, offset);
2867         CHECK_BYTE_COUNT(pwlen);
2868         proto_tree_add_item(tree, hf_smb_password,
2869                 tvb, offset, pwlen, ENC_NA);
2870         COUNT_BYTES(pwlen);
2871
2872         /* buffer format */
2873         CHECK_BYTE_COUNT(1);
2874         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2875         COUNT_BYTES(1);
2876
2877         /* Service */
2878         /*
2879          * XXX - the SNIA CIFS spec "Strings that are never passed in
2880          * Unicode are: ... The service name string in the
2881          * Tree_Connect_AndX SMB".  Is that claim false?
2882          */
2883         an = get_unicode_or_ascii_string(tvb, &offset,
2884                 si->unicode, &an_len, FALSE, FALSE, &bc);
2885         if (an == NULL)
2886                 goto endofcommand;
2887         proto_tree_add_string(tree, hf_smb_service, tvb,
2888                 offset, an_len, an);
2889         COUNT_BYTES(an_len);
2890
2891         END_OF_SMB
2892
2893         return offset;
2894 }
2895
2896 static int
2897 dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
2898 {
2899         proto_item *item, *subitem;
2900         proto_tree *tree;
2901         smb_uid_t  *smb_uid = NULL;
2902
2903         item = proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
2904         tree = proto_item_add_subtree(item, ett_smb_uid);
2905
2906         smb_uid = (smb_uid_t *)wmem_tree_lookup32(si->ct->uid_tree, si->uid);
2907         if (smb_uid) {
2908                 if (smb_uid->domain && smb_uid->account)
2909                         proto_item_append_text(item, "  (");
2910                 if (smb_uid->domain) {
2911                         proto_item_append_text(item, "%s", smb_uid->domain);
2912                         subitem = proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
2913                         PROTO_ITEM_SET_GENERATED(subitem);
2914                 }
2915                 if (smb_uid->account) {
2916                         proto_item_append_text(item, "\\%s", smb_uid->account);
2917                         subitem = proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
2918                         PROTO_ITEM_SET_GENERATED(subitem);
2919                 }
2920                 if (smb_uid->domain && smb_uid->account)
2921                         proto_item_append_text(item, ")");
2922                 if (smb_uid->logged_in > 0) {
2923                         subitem = proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
2924                         PROTO_ITEM_SET_GENERATED(subitem);
2925                 }
2926                 if (smb_uid->logged_out > 0) {
2927                         subitem = proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
2928                         PROTO_ITEM_SET_GENERATED(subitem);
2929                 }
2930         }
2931         offset += 2;
2932
2933         return offset;
2934 }
2935
2936 static int
2937 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)
2938 {
2939         proto_item     *it;
2940         proto_tree     *tr;
2941         smb_tid_info_t *tid_info = NULL;
2942
2943         DISSECTOR_ASSERT(si);
2944
2945         /* tid */
2946         it = proto_tree_add_uint(tree, hf_smb_tid, tvb, offset, 2, tid);
2947         tr = proto_item_add_subtree(it, ett_smb_tid);
2948         offset += 2;
2949
2950         if ((!pinfo->fd->flags.visited) && is_created) {
2951                 tid_info = wmem_new(wmem_file_scope(), smb_tid_info_t);
2952                 tid_info->opened_in = pinfo->fd->num;
2953                 tid_info->closed_in = 0;
2954                 tid_info->type = SMB_FID_TYPE_UNKNOWN;
2955                 if (si->sip && (si->sip->extra_info_type == SMB_EI_TIDNAME)) {
2956                         tid_info->filename = (char *)si->sip->extra_info;
2957                 } else {
2958                         tid_info->filename = NULL;
2959                 }
2960                 wmem_tree_insert32(si->ct->tid_tree, tid, tid_info);
2961         }
2962
2963         if (!tid_info) {
2964                 tid_info = (smb_tid_info_t *)wmem_tree_lookup32_le(si->ct->tid_tree, tid);
2965         }
2966         if (!tid_info) {
2967                 return offset;
2968         }
2969
2970         if ((!pinfo->fd->flags.visited) && is_closed) {
2971                 tid_info->closed_in = pinfo->fd->num;
2972         }
2973
2974         if (tid_info->opened_in) {
2975                 if (tid_info->filename) {
2976                         proto_item_append_text(it, "  (%s)", tid_info->filename);
2977
2978                         it = proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
2979                         PROTO_ITEM_SET_GENERATED(it);
2980                 }
2981
2982                 it = proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
2983                 PROTO_ITEM_SET_GENERATED(it);
2984         }
2985         if (tid_info->closed_in) {
2986                 it = proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
2987                 PROTO_ITEM_SET_GENERATED(it);
2988         }
2989
2990
2991         return offset;
2992 }
2993
2994 static int
2995 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
2996 {
2997         guint8  wc;
2998         guint16 bc;
2999
3000         WORD_COUNT;
3001
3002         /* Maximum Buffer Size */
3003         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3004         offset += 2;
3005
3006         /* tid */
3007         offset = dissect_smb_tid(tvb, pinfo, tree, offset, tvb_get_letohs(tvb, offset), TRUE, FALSE, si);
3008
3009         BYTE_COUNT;
3010
3011         END_OF_SMB
3012
3013         return offset;
3014 }
3015
3016
3017 static const true_false_string tfs_of_create = {
3018         "Create file if it does not exist",
3019         "Fail if file does not exist"
3020 };
3021 static const value_string of_open[] = {
3022         { 0,            "Fail if file exists"},
3023         { 1,            "Open file if it exists"},
3024         { 2,            "Truncate file if it exists"},
3025         {0, NULL}
3026 };
3027 static int
3028 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3029 {
3030         guint16     mask;
3031         proto_item *item = NULL;
3032         proto_tree *tree = NULL;
3033
3034         mask = tvb_get_letohs(tvb, offset);
3035
3036         if (parent_tree) {
3037                 item = proto_tree_add_item(parent_tree, hf_smb_open_function, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3038                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
3039         }
3040
3041         proto_tree_add_boolean(tree, hf_smb_open_function_create,
3042                 tvb, offset, 2, mask);
3043         proto_tree_add_uint(tree, hf_smb_open_function_open,
3044                 tvb, offset, 2, mask);
3045
3046         offset += 2;
3047
3048         return offset;
3049 }
3050
3051
3052 static const true_false_string tfs_mf_file = {
3053         "Target must be a file",
3054         "Target needn't be a file"
3055 };
3056 static const true_false_string tfs_mf_dir = {
3057         "Target must be a directory",
3058         "Target needn't be a directory"
3059 };
3060 static const true_false_string tfs_mf_verify = {
3061         "MUST verify all writes",
3062         "Don't have to verify writes"
3063 };
3064 static int
3065 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3066 {
3067         guint16     mask;
3068         proto_item *item = NULL;
3069         proto_tree *tree = NULL;
3070
3071         mask = tvb_get_letohs(tvb, offset);
3072
3073         if (parent_tree) {
3074                 item = proto_tree_add_item(parent_tree, hf_smb_move_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3075                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
3076         }
3077
3078         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
3079                 tvb, offset, 2, mask);
3080         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
3081                 tvb, offset, 2, mask);
3082         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
3083                 tvb, offset, 2, mask);
3084
3085         offset += 2;
3086
3087         return offset;
3088 }
3089
3090 static const true_false_string tfs_cf_mode = {
3091         "ASCII",
3092         "Binary"
3093 };
3094 static const true_false_string tfs_cf_tree_copy = {
3095         "Copy is a tree copy",
3096         "Copy is a file copy"
3097 };
3098 static const true_false_string tfs_cf_ea_action = {
3099         "Fail copy",
3100         "Discard EAs"
3101 };
3102 static int
3103 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3104 {
3105         guint16     mask;
3106         proto_item *item = NULL;
3107         proto_tree *tree = NULL;
3108
3109         mask = tvb_get_letohs(tvb, offset);
3110
3111         if (parent_tree) {
3112                 item = proto_tree_add_item(parent_tree, hf_smb_copy_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3113                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
3114         }
3115
3116         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
3117                 tvb, offset, 2, mask);
3118         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
3119                 tvb, offset, 2, mask);
3120         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
3121                 tvb, offset, 2, mask);
3122         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
3123                 tvb, offset, 2, mask);
3124         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
3125                 tvb, offset, 2, mask);
3126         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
3127                 tvb, offset, 2, mask);
3128         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
3129                 tvb, offset, 2, mask);
3130
3131         offset += 2;
3132
3133         return offset;
3134 }
3135
3136 static int
3137 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3138 {
3139         int         fn_len;
3140         guint16     tid;
3141         guint16     bc;
3142         guint8      wc;
3143         const char *fn;
3144
3145         DISSECTOR_ASSERT(si);
3146
3147         WORD_COUNT;
3148
3149         /* tid */
3150         tid = tvb_get_letohs(tvb, offset);
3151         offset = dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE, si);
3152
3153         /* open function */
3154         offset = dissect_open_function(tvb, tree, offset);
3155
3156         /* move flags */
3157         offset = dissect_move_flags(tvb, tree, offset);
3158
3159         BYTE_COUNT;
3160
3161         /* buffer format */
3162         CHECK_BYTE_COUNT(1);
3163         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3164         COUNT_BYTES(1);
3165
3166         /* file name */
3167         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3168                 FALSE, FALSE, &bc);
3169         if (fn == NULL)
3170                 goto endofcommand;
3171         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3172                 fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
3173         COUNT_BYTES(fn_len);
3174
3175         col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
3176                     format_text(fn, strlen(fn)));
3177
3178         /* buffer format */
3179         CHECK_BYTE_COUNT(1);
3180         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3181         COUNT_BYTES(1);
3182
3183         /* file name */
3184         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3185                 FALSE, FALSE, &bc);
3186         if (fn == NULL)
3187                 goto endofcommand;
3188         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3189                 fn_len, fn, "New File Name: %s", format_text(fn, strlen(fn)));
3190         COUNT_BYTES(fn_len);
3191
3192         col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
3193                     format_text(fn, strlen(fn)));
3194
3195         END_OF_SMB
3196
3197         return offset;
3198 }
3199
3200 static int
3201 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3202 {
3203         int         fn_len;
3204         guint16     tid;
3205         guint16     bc;
3206         guint8      wc;
3207         const char *fn;
3208
3209         DISSECTOR_ASSERT(si);
3210
3211         WORD_COUNT;
3212
3213         /* tid */
3214         tid = tvb_get_letohs(tvb, offset);
3215         offset = dissect_smb_tid(tvb, pinfo, tree, offset, tid, FALSE, FALSE, si);
3216
3217         /* open function */
3218         offset = dissect_open_function(tvb, tree, offset);
3219
3220         /* copy flags */
3221         offset = dissect_copy_flags(tvb, tree, offset);
3222
3223         BYTE_COUNT;
3224
3225         /* buffer format */
3226         CHECK_BYTE_COUNT(1);
3227         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3228         COUNT_BYTES(1);
3229
3230         /* file name */
3231         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3232                 FALSE, FALSE, &bc);
3233         if (fn == NULL)
3234                 goto endofcommand;
3235         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3236                 fn_len, fn, "Source File Name: %s", format_text(fn, strlen(fn)));
3237         COUNT_BYTES(fn_len);
3238
3239         col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s",
3240                     format_text(fn, strlen(fn)));
3241
3242         /* buffer format */
3243         CHECK_BYTE_COUNT(1);
3244         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3245         COUNT_BYTES(1);
3246
3247         /* file name */
3248         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3249                 FALSE, FALSE, &bc);
3250         if (fn == NULL)
3251                 goto endofcommand;
3252         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
3253                 fn_len, fn, "Destination File Name: %s",
3254                 format_text(fn, strlen(fn)));
3255         COUNT_BYTES(fn_len);
3256
3257         col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
3258
3259         END_OF_SMB
3260
3261         return offset;
3262 }
3263
3264 static int
3265 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)
3266 {
3267         int         fn_len;
3268         const char *fn;
3269         guint8      wc;
3270         guint16     bc;
3271
3272         DISSECTOR_ASSERT(si);
3273
3274         WORD_COUNT;
3275
3276         /* # of files moved */
3277         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3278         offset += 2;
3279
3280         BYTE_COUNT;
3281
3282         /* buffer format */
3283         CHECK_BYTE_COUNT(1);
3284         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3285         COUNT_BYTES(1);
3286
3287         /* file name */
3288         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3289                 FALSE, FALSE, &bc);
3290         if (fn == NULL)
3291                 goto endofcommand;
3292         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3293                 fn);
3294         COUNT_BYTES(fn_len);
3295
3296         END_OF_SMB
3297
3298         return offset;
3299 }
3300
3301 static int
3302 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3303 {
3304         int         fn_len;
3305         const char *fn;
3306         guint8      wc;
3307         guint16     bc;
3308         smb_fid_saved_info_t *fsi; /* eo_smb needs to track this info */
3309
3310         DISSECTOR_ASSERT(si);
3311
3312         WORD_COUNT;
3313
3314         /* desired access */
3315         offset = dissect_access(tvb, tree, offset, "Desired");
3316
3317         /* Search Attributes */
3318         offset = dissect_search_attributes(tvb, tree, offset);
3319
3320         BYTE_COUNT;
3321
3322         /* buffer format */
3323         CHECK_BYTE_COUNT(1);
3324         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3325         COUNT_BYTES(1);
3326
3327         /* file name */
3328         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3329                 FALSE, FALSE, &bc);
3330         if (fn == NULL)
3331                 goto endofcommand;
3332         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3333                 fn);
3334         COUNT_BYTES(fn_len);
3335
3336         /* store it for the fid->name/openframe/closeframe matching in
3337         * dissect_smb_fid()   called from the response.
3338         */
3339         if ((!pinfo->fd->flags.visited) && si->sip && fn) {
3340                 fsi                     = wmem_new0(wmem_file_scope(), smb_fid_saved_info_t);
3341                 fsi->filename           = wmem_strdup(wmem_file_scope(), fn);
3342
3343                 si->sip->extra_info_type = SMB_EI_FILEDATA;
3344                 si->sip->extra_info      = fsi;
3345         }
3346
3347         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3348                     format_text(fn, strlen(fn)));
3349
3350         END_OF_SMB
3351
3352         return offset;
3353 }
3354
3355
3356
3357 static int
3358 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
3359     int len, guint32 mask)
3360 {
3361         proto_item *item = NULL;
3362         proto_tree *tree = NULL;
3363
3364         if (parent_tree) {
3365                 item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
3366
3367                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
3368                 if (len == 0)
3369                         PROTO_ITEM_SET_GENERATED(item);
3370         }
3371
3372         /*
3373          * XXX - it's 0x00000016 in at least one capture, but
3374          * Network Monitor doesn't say what the 0x00000010 bit is.
3375          * Does the Win32 API documentation, or NT Native API book,
3376          * suggest anything?
3377          *
3378          * That is the extended response desired bit ... RJS, from Samba
3379          * Well, maybe. Samba thinks it is, and uses it to encode
3380          * OpLock granted as the high order bit of the Action field
3381          * in the response. However, Windows does not do that. Or at least
3382          * Win2K doesn't.
3383          */
3384         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
3385                 tvb, offset, len, mask);
3386         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
3387                 tvb, offset, len, mask);
3388         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
3389                 tvb, offset, len, mask);
3390         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
3391                 tvb, offset, len, mask);
3392         offset += len;
3393
3394         return offset;
3395 }
3396
3397 /* FIXME: need to call dissect_nt_access_mask() instead */
3398 static int
3399 dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3400     int offset, int len, guint32 mask)
3401 {
3402         proto_item *item;
3403         proto_tree *tree;
3404
3405         if (parent_tree) {
3406                 item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
3407                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
3408                 if (len == 0)
3409                         PROTO_ITEM_SET_GENERATED(item);
3410                 /*
3411                  * Some of these bits come from
3412                  *
3413                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3414                  *
3415                  * and others come from the section on ZwOpenFile in "Windows(R)
3416                  * NT(R)/2000 Native API Reference".
3417                  */
3418                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
3419                         tvb, offset, len, mask);
3420                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
3421                         tvb, offset, len, mask);
3422                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
3423                         tvb, offset, len, mask);
3424                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
3425                         tvb, offset, len, mask);
3426                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
3427                         tvb, offset, len, mask);
3428                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
3429                         tvb, offset, len, mask);
3430                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
3431                         tvb, offset, len, mask);
3432                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
3433                         tvb, offset, len, mask);
3434                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
3435                         tvb, offset, len, mask);
3436                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
3437                         tvb, offset, len, mask);
3438                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
3439                         tvb, offset, len, mask);
3440                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
3441                         tvb, offset, len, mask);
3442                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
3443                         tvb, offset, len, mask);
3444                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
3445                         tvb, offset, len, mask);
3446                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
3447                         tvb, offset, len, mask);
3448                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
3449                         tvb, offset, len, mask);
3450                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
3451                         tvb, offset, len, mask);
3452                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
3453                         tvb, offset, len, mask);
3454                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
3455                         tvb, offset, len, mask);
3456                 proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
3457                         tvb, offset, len, mask);
3458         }
3459         offset += len;
3460
3461         return offset;
3462 }
3463
3464 int
3465 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3466 {
3467         guint32 mask;
3468
3469         mask = tvb_get_letohl(tvb, offset);
3470
3471         offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
3472
3473         return offset;
3474 }
3475
3476 #define SHARE_ACCESS_READ       0x00000001
3477 #define SHARE_ACCESS_WRITE      0x00000002
3478 #define SHARE_ACCESS_DELETE     0x00000004
3479
3480 static int
3481 dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3482     int offset, int len, guint32 mask)
3483 {
3484         proto_item *item;
3485         proto_tree *tree;
3486
3487         if (parent_tree) {
3488                 item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
3489                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
3490                 if (len == 0)
3491                         PROTO_ITEM_SET_GENERATED(item);
3492
3493                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
3494                         tvb, offset, len, mask);
3495                 if (mask & SHARE_ACCESS_READ) {
3496                         proto_item_append_text(item, " SHARE_READ");
3497                 }
3498                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
3499                         tvb, offset, len, mask);
3500                 if (mask & SHARE_ACCESS_WRITE) {
3501                         proto_item_append_text(item, " SHARE_WRITE");
3502                 }
3503                 proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
3504                         tvb, offset, len, mask);
3505                 if (mask & SHARE_ACCESS_DELETE) {
3506                         proto_item_append_text(item, " SHARE_DELETE");
3507                 }
3508         }
3509
3510         offset += len;
3511
3512         return offset;
3513 }
3514
3515 int
3516 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3517 {
3518         guint32 mask;
3519
3520         mask = tvb_get_letohl(tvb, offset);
3521
3522         offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
3523
3524         return offset;
3525 }
3526
3527
3528 static int
3529 dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
3530     int offset, int len, guint32 mask)
3531 {
3532         proto_item *item;
3533         proto_tree *tree;
3534
3535         if (parent_tree) {
3536                 item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
3537                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
3538                 if (len == 0)
3539                         PROTO_ITEM_SET_GENERATED(item);
3540                 /*
3541                  * From
3542                  *
3543                  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
3544                  */
3545                  proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
3546                         tvb, offset, len, mask);
3547                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
3548                         tvb, offset, len, mask);
3549                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
3550                         tvb, offset, len, mask);
3551                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
3552                         tvb, offset, len, mask);
3553                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
3554                         tvb, offset, len, mask);
3555                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
3556                         tvb, offset, len, mask);
3557                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
3558                         tvb, offset, len, mask);
3559                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
3560                         tvb, offset, len, mask);
3561                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
3562                         tvb, offset, len, mask);
3563                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
3564                         tvb, offset, len, mask);
3565                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
3566                         tvb, offset, len, mask);
3567                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
3568                         tvb, offset, len, mask);
3569                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
3570                         tvb, offset, len, mask);
3571                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
3572                         tvb, offset, len, mask);
3573                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
3574                         tvb, offset, len, mask);
3575                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
3576                         tvb, offset, len, mask);
3577                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
3578                         tvb, offset, len, mask);
3579                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
3580                         tvb, offset, len, mask);
3581                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
3582                         tvb, offset, len, mask);
3583                 proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
3584                         tvb, offset, len, mask);
3585         }
3586         offset += len;
3587
3588         return offset;
3589 }
3590
3591 int
3592 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
3593 {
3594         guint32 mask;
3595
3596         mask = tvb_get_letohl(tvb, offset);
3597
3598         offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
3599
3600         return offset;
3601 }
3602
3603
3604 /* fids are scoped by tcp session */
3605 smb_fid_info_t *
3606 dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
3607     int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated, smb_info_t* si)
3608 {
3609         smb_saved_info_t *sip              = si->sip;
3610         proto_item       *it;
3611         proto_tree       *tr;
3612         smb_fid_info_t   *fid_info         = NULL;
3613         smb_fid_info_t   *suspect_fid_info = NULL;
3614         /* We need this to use an array-accessed tree */
3615         GSList           *GSL_iterator;
3616
3617         DISSECTOR_ASSERT(si);
3618
3619         it = proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
3620         if (is_generated) {
3621                 PROTO_ITEM_SET_GENERATED(it);
3622         }
3623         tr = proto_item_add_subtree(it, ett_smb_fid);
3624         col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
3625
3626         if ((!pinfo->fd->flags.visited) && is_created) {
3627                 fid_info = wmem_new(wmem_file_scope(), smb_fid_info_t);
3628                 fid_info->opened_in = pinfo->fd->num;
3629                 fid_info->closed_in = 0;
3630                 fid_info->type = SMB_FID_TYPE_UNKNOWN;
3631                 fid_info->fid = fid;
3632                 fid_info->tid = si->tid;
3633                 if (si->sip && (si->sip->extra_info_type == SMB_EI_FILEDATA)) {
3634                         fid_info->fsi = (smb_fid_saved_info_t *)si->sip->extra_info;
3635                 } else {
3636                         fid_info->fsi = NULL;
3637                 }
3638                 /* We don't use the fid_tree anymore to access and
3639                    maintain the fid information of analyzed files.
3640                    (was wmem_tree_insert32(si->ct->fid_tree, fid, fid_info);)
3641                    We'll use a single list instead to keep track of the
3642                    files (fid) opened.
3643                    Note that the insert_sorted function allows to insert duplicates
3644                    but being inside this if section should prevent it */
3645                 si->ct->GSL_fid_info = g_slist_insert_sorted(
3646                                         si->ct->GSL_fid_info,
3647                                         fid_info,
3648                                         (GCompareFunc)fid_cmp);
3649         }
3650
3651         if (!fid_info) {
3652                 /* we use the single linked list to access this fid_info
3653                    (was fid_info = wmem_tree_lookup32(si->ct->fid_tree, fid);) */
3654                 GSL_iterator = si->ct->GSL_fid_info;
3655                 while (GSL_iterator) {
3656                         suspect_fid_info = (smb_fid_info_t *)GSL_iterator->data;
3657                         if (suspect_fid_info->opened_in > pinfo->fd->num) break;
3658                         if ((suspect_fid_info->tid == si->tid) && (suspect_fid_info->fid == fid))
3659                                 fid_info = (smb_fid_info_t *)suspect_fid_info;
3660                         GSL_iterator = g_slist_next(GSL_iterator);
3661                 }
3662         }
3663         if (!fid_info) {
3664                 return NULL;
3665         }
3666
3667         /* Store the fid in the transaction structure and remember if
3668            it was in the request or in the reply we saw it
3669          */
3670         if (sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
3671                 sip->fid = fid;
3672                 if (si->request) {
3673                         sip->fid_seen_in_request = TRUE;
3674                 } else {
3675                         sip->fid_seen_in_request = FALSE;
3676                 }
3677         }
3678
3679         if ((!pinfo->fd->flags.visited) && is_closed) {
3680                 fid_info->closed_in = pinfo->fd->num;
3681         }
3682
3683         if (fid_info->opened_in) {
3684                 it = proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
3685                 PROTO_ITEM_SET_GENERATED(it);
3686         }
3687
3688         if (fid_info->closed_in) {
3689                 it = proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
3690                 PROTO_ITEM_SET_GENERATED(it);
3691         }
3692
3693
3694         if (fid_info->opened_in) {
3695                 if (fid_info->fsi && fid_info->fsi->filename) {
3696                         it = proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
3697                         PROTO_ITEM_SET_GENERATED(it);
3698                         proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
3699                         dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
3700                         dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
3701                         dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
3702                         dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
3703                         dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
3704                         it = proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
3705                         PROTO_ITEM_SET_GENERATED(it);
3706                 }
3707         }
3708
3709         return fid_info;
3710 }
3711
3712 static int
3713 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3714 {
3715         guint8  wc;
3716         guint16 bc;
3717         guint16 fid;
3718         smb_fid_info_t *fid_info   = NULL; /* eo_smb needs to track this info */
3719         guint16         fattr;
3720         gboolean                isdir      = FALSE;
3721
3722         WORD_COUNT;
3723
3724         /* fid */
3725         fid = tvb_get_letohs(tvb, offset);
3726
3727         fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
3728         if (fid_info) {
3729                 /* This command is used to create and open a new file or open
3730                 and truncate an existing file to zero length */
3731                 fid_info->end_of_file = 0;
3732                 if (fid_info->fsi) {
3733                         /* File Type */
3734                         fattr = fid_info->fsi->file_attributes;
3735                         /* XXX Volumes considered as directories */
3736                         isdir = (fattr & SMB_FILE_ATTRIBUTE_DIRECTORY) || (fattr & SMB_FILE_ATTRIBUTE_VOLUME);
3737                         if (isdir == 0) {
3738                                 fid_info->type = SMB_FID_TYPE_FILE;
3739                         } else {
3740                                 fid_info->type = SMB_FID_TYPE_DIR;
3741                         }
3742                 }
3743         }
3744
3745         offset += 2;
3746
3747         /* File Attributes */
3748         offset = dissect_file_attributes(tvb, tree, offset);
3749
3750         /* last write time */
3751         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3752
3753         /* File Size */
3754         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3755         offset += 4;
3756
3757         /* granted access */
3758         offset = dissect_access(tvb, tree, offset, "Granted");
3759
3760         BYTE_COUNT;
3761
3762         END_OF_SMB
3763
3764         return offset;
3765 }
3766
3767 static int
3768 dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3769 {
3770         guint8  wc;
3771         guint16 bc;
3772         guint16 fid;
3773
3774         WORD_COUNT;
3775
3776         /* fid */
3777         fid = tvb_get_letohs(tvb, offset);
3778         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
3779         offset += 2;
3780
3781         BYTE_COUNT;
3782
3783         END_OF_SMB
3784
3785         return offset;
3786 }
3787
3788 static int
3789 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)
3790 {
3791         guint8  wc;
3792         guint16 bc;
3793         guint16 fid;
3794
3795         WORD_COUNT;
3796
3797         /* fid */
3798         fid = tvb_get_letohs(tvb, offset);
3799         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
3800         offset += 2;
3801
3802         BYTE_COUNT;
3803
3804         END_OF_SMB
3805
3806         return offset;
3807 }
3808
3809 static int
3810 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)
3811 {
3812         guint8  wc;
3813         guint16 bc;
3814         guint16 fid;
3815
3816         WORD_COUNT;
3817
3818         /* fid */
3819         fid = tvb_get_letohs(tvb, offset);
3820         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
3821         offset += 2;
3822
3823         BYTE_COUNT;
3824
3825         END_OF_SMB
3826
3827         return offset;
3828 }
3829
3830 static int
3831 dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3832 {
3833         guint8  wc;
3834         guint16 bc;
3835         guint16 fid;
3836
3837         WORD_COUNT;
3838
3839         /* fid */
3840         fid = tvb_get_letohs(tvb, offset);
3841         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
3842         offset += 2;
3843
3844         BYTE_COUNT;
3845
3846         END_OF_SMB
3847
3848         return offset;
3849 }
3850
3851 static int
3852 dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3853 {
3854         guint8  wc;
3855         guint16 bc;
3856         guint16 fid;
3857
3858         WORD_COUNT;
3859
3860         /* fid */
3861         fid = tvb_get_letohs(tvb, offset);
3862         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
3863         offset += 2;
3864
3865         BYTE_COUNT;
3866
3867         END_OF_SMB
3868
3869         return offset;
3870 }
3871
3872 static int
3873 dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3874 {
3875         guint8  wc;
3876         guint16 bc;
3877         guint16 fid;
3878         smb_fid_info_t *fid_info   = NULL; /* eo_smb needs to track this info */
3879         guint16         fattr;
3880         gboolean                isdir      = FALSE;
3881
3882         WORD_COUNT;
3883
3884         /* fid */
3885         fid = tvb_get_letohs(tvb, offset);
3886         fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
3887         if (fid_info) {
3888                 /* This command is used to create and open a new file or open
3889                 and truncate an existing file to zero length */
3890                 fid_info->end_of_file = 0;
3891                 if (fid_info->fsi) {
3892                         /* File Type */
3893                         fattr = fid_info->fsi->file_attributes;
3894                         /* XXX Volumes considered as directories */
3895                         isdir = (fattr & SMB_FILE_ATTRIBUTE_DIRECTORY) || (fattr & SMB_FILE_ATTRIBUTE_VOLUME);
3896                         if (isdir == 0) {
3897                                 fid_info->type = SMB_FID_TYPE_FILE;
3898                         } else {
3899                                 fid_info->type = SMB_FID_TYPE_DIR;
3900                         }
3901                 }
3902         }
3903
3904         offset += 2;
3905
3906         BYTE_COUNT;
3907
3908         END_OF_SMB
3909
3910         return offset;
3911 }
3912
3913 static int
3914 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3915 {
3916         int         fn_len;
3917         const char *fn;
3918         guint8      wc;
3919         guint16     bc;
3920         smb_fid_saved_info_t *fsi; /* eo_smb needs to track this info */
3921         guint32         file_attributes = 0;
3922
3923         DISSECTOR_ASSERT(si);
3924
3925         WORD_COUNT;
3926
3927         /* file attributes */
3928         /* We read the two lower bytes into the four-bytes file-attributes, because they are compatible */
3929         file_attributes = tvb_get_letohs(tvb, offset);
3930         offset = dissect_file_attributes(tvb, tree, offset);
3931
3932         /* creation time */
3933         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3934
3935         BYTE_COUNT;
3936
3937         /* buffer format */
3938         CHECK_BYTE_COUNT(1);
3939         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3940         COUNT_BYTES(1);
3941
3942         /* File Name */
3943         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3944                 FALSE, FALSE, &bc);
3945         if (fn == NULL)
3946                 goto endofcommand;
3947         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3948                 fn);
3949         COUNT_BYTES(fn_len);
3950
3951         /* store it for the fid->name/openframe/closeframe matching in
3952         * dissect_smb_fid()   called from the response.
3953         */
3954         if ((!pinfo->fd->flags.visited) && si->sip && fn) {
3955                 fsi                     = wmem_new0(wmem_file_scope(), smb_fid_saved_info_t);
3956                 fsi->filename           = wmem_strdup(wmem_file_scope(), fn);
3957                 fsi->file_attributes    = file_attributes;
3958
3959                 si->sip->extra_info_type = SMB_EI_FILEDATA;
3960                 si->sip->extra_info      = fsi;
3961         }
3962
3963
3964         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
3965                     format_text(fn, strlen(fn)));
3966
3967         END_OF_SMB
3968
3969         return offset;
3970 }
3971
3972 static int
3973 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3974 {
3975         guint8  wc;
3976         guint16 bc, fid;
3977
3978         WORD_COUNT;
3979
3980         /* fid */
3981         fid = tvb_get_letohs(tvb, offset);
3982         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
3983         offset += 2;
3984
3985         /* last write time */
3986         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3987
3988         BYTE_COUNT;
3989
3990         END_OF_SMB
3991
3992         return offset;
3993 }
3994
3995 static int
3996 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
3997 {
3998         int         fn_len;
3999         const char *fn;
4000         guint8      wc;
4001         guint16     bc;
4002
4003         DISSECTOR_ASSERT(si);
4004
4005         WORD_COUNT;
4006
4007         /* search attributes */
4008         offset = dissect_search_attributes(tvb, tree, offset);
4009
4010         BYTE_COUNT;
4011
4012         /* buffer format */
4013         CHECK_BYTE_COUNT(1);
4014         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4015         COUNT_BYTES(1);
4016
4017         /* file name */
4018         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4019                 FALSE, FALSE, &bc);
4020
4021         if ((!pinfo->fd->flags.visited) && si->sip) {
4022                 si->sip->extra_info_type = SMB_EI_FILENAME;
4023                 si->sip->extra_info = wmem_strdup(wmem_file_scope(), fn);
4024         }
4025
4026         if (fn == NULL)
4027                 goto endofcommand;
4028         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4029                 fn);
4030         COUNT_BYTES(fn_len);
4031
4032         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4033                     format_text(fn, strlen(fn)));
4034
4035         END_OF_SMB
4036
4037         return offset;
4038 }
4039
4040 static int
4041 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4042 {
4043         int         fn_len;
4044         const char *fn, *old_name = NULL, *new_name = NULL;
4045         guint8      wc;
4046         guint16     bc;
4047         smb_rename_saved_info_t *rni = NULL;
4048
4049         DISSECTOR_ASSERT(si);
4050
4051         WORD_COUNT;
4052
4053         /* search attributes */
4054         offset = dissect_search_attributes(tvb, tree, offset);
4055
4056         BYTE_COUNT;
4057
4058         /* buffer format */
4059         CHECK_BYTE_COUNT(1);
4060         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4061         COUNT_BYTES(1);
4062
4063         /* old file name */
4064         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4065                 FALSE, FALSE, &bc);
4066         if (fn == NULL)
4067                 goto endofcommand;
4068         old_name = fn;
4069         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
4070                 fn);
4071         COUNT_BYTES(fn_len);
4072
4073         col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
4074                     format_text(fn, strlen(fn)));
4075
4076         /* buffer format */
4077         CHECK_BYTE_COUNT(1);
4078         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4079         COUNT_BYTES(1);
4080
4081         /* file name */
4082         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4083                 FALSE, FALSE, &bc);
4084         if (fn == NULL)
4085                 goto endofcommand;
4086         new_name = fn;
4087         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4088                 fn);
4089         COUNT_BYTES(fn_len);
4090
4091         col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
4092                     format_text(fn, strlen(fn)));
4093
4094         END_OF_SMB
4095
4096         /* save the offset/len for this transaction */
4097         if (si->sip && !pinfo->fd->flags.visited) {
4098                 rni = (smb_rename_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_rename_saved_info_t));
4099                 rni->old_name = wmem_strdup(wmem_file_scope(), old_name);
4100                 rni->new_name = wmem_strdup(wmem_file_scope(), new_name);
4101
4102                 si->sip->extra_info_type = SMB_EI_RENAMEDATA;
4103                 si->sip->extra_info = rni;
4104         }
4105
4106         return offset;
4107 }
4108
4109 static int
4110 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)
4111 {
4112         int         fn_len;
4113         const char *fn;
4114         guint8      wc;
4115         guint16     bc;
4116
4117         DISSECTOR_ASSERT(si);
4118
4119         WORD_COUNT;
4120
4121         /* search attributes */
4122         offset = dissect_search_attributes(tvb, tree, offset);
4123
4124         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
4125         offset += 2;
4126
4127         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4128         offset += 4;
4129
4130         BYTE_COUNT;
4131
4132         /* buffer format */
4133         CHECK_BYTE_COUNT(1);
4134         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4135         COUNT_BYTES(1);
4136
4137         /* old file name */
4138         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4139                 FALSE, FALSE, &bc);
4140         if (fn == NULL)
4141                 goto endofcommand;
4142         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
4143                 fn);
4144         COUNT_BYTES(fn_len);
4145
4146         col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s",
4147                     format_text(fn, strlen(fn)));
4148
4149         /* buffer format */
4150         CHECK_BYTE_COUNT(1);
4151         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4152         COUNT_BYTES(1);
4153
4154         /* file name */
4155         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4156                 FALSE, FALSE, &bc);
4157         if (fn == NULL)
4158                 goto endofcommand;
4159         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4160                 fn);
4161         COUNT_BYTES(fn_len);
4162
4163         col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s",
4164                     format_text(fn, strlen(fn)));
4165
4166         END_OF_SMB
4167
4168         return offset;
4169 }
4170
4171
4172 static int
4173 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4174 {
4175         guint16     bc;
4176         guint8      wc;
4177         const char *fn;
4178         int         fn_len;
4179
4180         DISSECTOR_ASSERT(si);
4181
4182         WORD_COUNT;
4183
4184         BYTE_COUNT;
4185
4186         /* Buffer Format */
4187         CHECK_BYTE_COUNT(1);
4188         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4189         COUNT_BYTES(1);
4190
4191         /* File Name */
4192         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4193                 FALSE, FALSE, &bc);
4194         if (fn == NULL)
4195                 goto endofcommand;
4196         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4197                 fn);
4198         COUNT_BYTES(fn_len);
4199
4200         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4201                     format_text(fn, strlen(fn)));
4202
4203         END_OF_SMB
4204
4205         return offset;
4206 }
4207
4208 static int
4209 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_)
4210 {
4211         guint16 bc;
4212         guint8  wc;
4213
4214         WORD_COUNT;
4215
4216         /* File Attributes */
4217         offset = dissect_file_attributes(tvb, tree, offset);
4218
4219         /* Last Write Time */
4220         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4221
4222         /* File Size */
4223         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4224         offset += 4;
4225
4226         /* 10 reserved bytes */
4227         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
4228         offset += 10;
4229
4230         BYTE_COUNT;
4231
4232         END_OF_SMB
4233
4234         return offset;
4235 }
4236
4237 static int
4238 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4239 {
4240         int         fn_len;
4241         const char *fn;
4242         guint8      wc;
4243         guint16     bc;
4244
4245         DISSECTOR_ASSERT(si);
4246
4247         WORD_COUNT;
4248
4249         /* file attributes */
4250         offset = dissect_file_attributes(tvb, tree, offset);
4251
4252         /* last write time */
4253         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4254
4255         /* 10 reserved bytes */
4256         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
4257         offset += 10;
4258
4259         BYTE_COUNT;
4260
4261         /* buffer format */
4262         CHECK_BYTE_COUNT(1);
4263         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4264         COUNT_BYTES(1);
4265
4266         /* file name */
4267         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4268                 FALSE, FALSE, &bc);
4269         if (fn == NULL)
4270                 goto endofcommand;
4271         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4272                 fn);
4273         COUNT_BYTES(fn_len);
4274
4275         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4276                     format_text(fn, strlen(fn)));
4277
4278         END_OF_SMB
4279
4280         return offset;
4281 }
4282
4283 typedef struct _rw_info_t {
4284         guint64 offset;
4285         guint32 len;
4286         guint16 fid;
4287 } rw_info_t;
4288
4289 static int
4290 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4291 {
4292         guint8       wc;
4293         guint16      cnt = 0, bc;
4294         guint32      ofs = 0;
4295         unsigned int fid;
4296         rw_info_t    *rwi                   = NULL;
4297
4298         WORD_COUNT;
4299
4300         /* fid */
4301         fid = tvb_get_letohs(tvb, offset);
4302         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
4303         offset += 2;
4304
4305         /* read count */
4306         cnt = tvb_get_letohs(tvb, offset);
4307         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4308         offset += 2;
4309
4310         /* offset */
4311         ofs = tvb_get_letohl(tvb, offset);
4312         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4313         offset += 4;
4314
4315         col_append_fstr(pinfo->cinfo, COL_INFO,
4316                                 ", %u byte%s at offset %u", cnt,
4317                                 (cnt == 1) ? "" : "s", ofs);
4318
4319         /* remaining */
4320         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4321         offset += 2;
4322
4323         /* save the offset/len for this transaction */
4324         if (si->sip && !pinfo->fd->flags.visited) {
4325                 rwi = wmem_new(wmem_file_scope(), rw_info_t);
4326                 rwi->offset = ofs;
4327                 rwi->len = cnt;
4328                 rwi->fid = fid;
4329                 si->sip->extra_info_type = SMB_EI_RWINFO;
4330                 si->sip->extra_info = rwi;
4331         }
4332
4333         BYTE_COUNT;
4334
4335         END_OF_SMB
4336
4337         return offset;
4338 }
4339
4340 int
4341 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
4342 {
4343         int tvblen;
4344
4345         if (bc > datalen) {
4346                 /* We have some initial padding bytes. */
4347                 /* XXX - use the data offset here instead? */
4348                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4349                         ENC_NA);
4350                 offset += bc-datalen;
4351                 bc = datalen;
4352         }
4353         tvblen = tvb_length_remaining(tvb, offset);
4354         if (bc > tvblen) {
4355                 proto_tree_add_bytes_format_value(tree, hf_smb_file_data, tvb, offset, tvblen, NULL, "Incomplete. Only %d of %u bytes", tvblen, bc);
4356                 offset += tvblen;
4357         } else {
4358                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, ENC_NA);
4359                 offset += bc;
4360         }
4361         return offset;
4362 }
4363
4364 static int
4365 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4366     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
4367 {
4368         int       tvblen;
4369         tvbuff_t *dcerpc_tvb;
4370
4371         if (bc > datalen) {
4372                 /* We have some initial padding bytes. */
4373                 /* XXX - use the data offset here instead? */
4374                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
4375                         ENC_NA);
4376                 offset += bc-datalen;
4377                 bc = datalen;
4378         }
4379         tvblen = tvb_length_remaining(tvb, offset);
4380         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
4381         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
4382         if (bc > tvblen)
4383                 offset += tvblen;
4384         else
4385                 offset += bc;
4386         return offset;
4387 }
4388
4389 /*
4390  * transporting DCERPC over SMB seems to be implemented in various
4391  * ways. We might just assume it can be done by an almost random
4392  * mix of Trans/Read/Write calls
4393  *
4394  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
4395  * and let him sort them out
4396  */
4397 static int
4398 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
4399     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
4400     guint16 datalen, guint32 ofs, guint16 fid, smb_info_t *si)
4401 {
4402         DISSECTOR_ASSERT(si);
4403
4404         if ( (si->sip && (si->sip->flags & SMB_SIF_TID_IS_IPC)) && (ofs == 0) ) {
4405                 /* dcerpc call */
4406                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
4407                     top_tree, offset, bc, datalen, fid);
4408         } else {
4409                 /* ordinary file data */
4410                 return dissect_file_data(tvb, tree, offset, bc, datalen);
4411         }
4412 }
4413
4414 static int
4415 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4416 {
4417         guint16    cnt     = 0, bc;
4418         guint8     wc;
4419         int        fid     = 0;
4420         guint32    datalen = 0, dataoffset = 0;
4421         guint32    tvblen;
4422         rw_info_t *rwi     = NULL;
4423
4424         DISSECTOR_ASSERT(si);
4425
4426         WORD_COUNT;
4427
4428         /* read count */
4429         cnt = tvb_get_letohs(tvb, offset);
4430         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4431         offset += 2;
4432
4433         /* 8 reserved bytes */
4434         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, ENC_NA);
4435         offset += 8;
4436         BYTE_COUNT;
4437
4438         /* buffer format */
4439         CHECK_BYTE_COUNT(1);
4440         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4441         COUNT_BYTES(1);
4442
4443         /* data len */
4444         CHECK_BYTE_COUNT(2);
4445         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4446         datalen = tvb_get_letohs(tvb, offset);
4447         COUNT_BYTES(2);
4448         dataoffset = offset;
4449
4450         /* file data, might be DCERPC on a pipe */
4451         if (bc) {
4452                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4453                     top_tree_global, offset, bc, bc, 0, (guint16) fid, si);
4454                 bc = 0;
4455         }
4456
4457         /* If we have seen the request, then print which FID this refers to */
4458         if ((si->sip != NULL) && (si->sip->frame_req > 0) && (si->sip->extra_info_type == SMB_EI_FID)) {
4459                 fid = GPOINTER_TO_INT(si->sip->extra_info);
4460         }
4461
4462         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4463                 rwi = (rw_info_t *)si->sip->extra_info;
4464         }
4465         if (rwi) {
4466                 proto_item *it;
4467
4468                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4469
4470                 PROTO_ITEM_SET_GENERATED(it);
4471                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4472                 PROTO_ITEM_SET_GENERATED(it);
4473
4474                 /* we need the fid for the call to dcerpc below */
4475                 fid = rwi->fid;
4476         }
4477
4478         /* feed the export object tap listener */
4479         tvblen = tvb_length_remaining(tvb, dataoffset);
4480         if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
4481                 feed_eo_smb(SMB_COM_READ, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
4482         }
4483
4484         END_OF_SMB
4485
4486         return offset;
4487 }
4488
4489 static int
4490 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_)
4491 {
4492         guint16 cnt, bc;
4493         guint8  wc;
4494
4495         WORD_COUNT;
4496
4497         /* read count */
4498         cnt = tvb_get_letohs(tvb, offset);
4499         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4500         offset += 2;
4501
4502         /* 8 reserved bytes */
4503         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, ENC_NA);
4504         offset += 8;
4505
4506         BYTE_COUNT;
4507
4508         /* buffer format */
4509         CHECK_BYTE_COUNT(1);
4510         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4511         COUNT_BYTES(1);
4512
4513         /* data len */
4514         CHECK_BYTE_COUNT(2);
4515         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4516         COUNT_BYTES(2);
4517
4518         END_OF_SMB
4519
4520         return offset;
4521 }
4522
4523
4524
4525 static int
4526 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4527 {
4528         guint32    ofs     = 0;
4529         guint16    cnt     = 0, bc, fid = 0;
4530         guint8     wc;
4531         rw_info_t *rwi     = NULL;
4532         guint32    datalen = 0, dataoffset = 0;
4533         guint32    tvblen;
4534
4535         DISSECTOR_ASSERT(si);
4536
4537         WORD_COUNT;
4538
4539         /* fid */
4540         fid = tvb_get_letohs(tvb, offset);
4541         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4542         offset += 2;
4543
4544         /* write count */
4545         cnt = tvb_get_letohs(tvb, offset);
4546         datalen = cnt;
4547         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4548         offset += 2;
4549
4550         /* offset */
4551         ofs = tvb_get_letohl(tvb, offset);
4552         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4553         offset += 4;
4554
4555         col_append_fstr(pinfo->cinfo, COL_INFO,
4556                                 ", %u byte%s at offset %u", cnt,
4557                                 (cnt == 1) ? "" : "s", ofs);
4558
4559         /* save the offset/len for this transaction */
4560         if (si->sip && !pinfo->fd->flags.visited) {
4561                 rwi         = (rw_info_t *)wmem_alloc(wmem_file_scope(), sizeof(rw_info_t));
4562                 rwi->offset = ofs;
4563                 rwi->len    = cnt;
4564                 rwi->fid    = fid;
4565
4566                 si->sip->extra_info_type = SMB_EI_RWINFO;
4567                 si->sip->extra_info      = rwi;
4568         }
4569         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4570                 rwi = (rw_info_t *)si->sip->extra_info;
4571         }
4572         if (rwi) {
4573                 proto_item *it;
4574
4575                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4576
4577                 PROTO_ITEM_SET_GENERATED(it);
4578                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4579                 PROTO_ITEM_SET_GENERATED(it);
4580         }
4581
4582         /* remaining */
4583         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4584         offset += 2;
4585
4586         BYTE_COUNT;
4587
4588         /* buffer format */
4589         CHECK_BYTE_COUNT(1);
4590         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4591         COUNT_BYTES(1);
4592
4593         /* data len */
4594         CHECK_BYTE_COUNT(2);
4595         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4596         COUNT_BYTES(2);
4597         dataoffset = offset;
4598
4599         /* file data, might be DCERPC on a pipe */
4600         if (bc != 0) {
4601                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
4602                     top_tree_global, offset, bc, bc, ofs, fid, si);
4603                 bc = 0;
4604         }
4605
4606         /* feed the export object tap listener */
4607         tvblen = tvb_length_remaining(tvb, dataoffset);
4608         if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
4609                 feed_eo_smb(SMB_COM_WRITE, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
4610         }
4611
4612         END_OF_SMB
4613
4614         return offset;
4615 }
4616
4617 static int
4618 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4619 {
4620         guint8      wc;
4621         guint16     bc, cnt;
4622         rw_info_t  *rwi = NULL;
4623
4624         DISSECTOR_ASSERT(si);
4625
4626         WORD_COUNT;
4627
4628         /* write count */
4629         cnt = tvb_get_letohs(tvb, offset);
4630         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4631         offset += 2;
4632
4633         col_append_fstr(pinfo->cinfo, COL_INFO,
4634                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
4635
4636         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
4637                 rwi = (rw_info_t *)si->sip->extra_info;
4638         }
4639         if (rwi) {
4640                 proto_item *it;
4641
4642                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
4643
4644                 PROTO_ITEM_SET_GENERATED(it);
4645                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
4646                 PROTO_ITEM_SET_GENERATED(it);
4647         }
4648
4649         BYTE_COUNT;
4650
4651         END_OF_SMB
4652
4653         return offset;
4654 }
4655
4656 static int
4657 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4658 {
4659         guint8  wc;
4660         guint16 bc, fid;
4661
4662         WORD_COUNT;
4663
4664         /* fid */
4665         fid = tvb_get_letohs(tvb, offset);
4666         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4667         offset += 2;
4668
4669         /* lock count */
4670         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4671         offset += 4;
4672
4673         /* offset */
4674         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4675         offset += 4;
4676
4677         BYTE_COUNT;
4678
4679         END_OF_SMB
4680
4681         return offset;
4682 }
4683
4684 static int
4685 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4686 {
4687         int         fn_len;
4688         const char *fn;
4689         guint8      wc;
4690         guint16     bc;
4691
4692         DISSECTOR_ASSERT(si);
4693
4694         WORD_COUNT;
4695
4696         /* 2 reserved bytes */
4697         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
4698         offset += 2;
4699
4700         /* Creation time */
4701         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4702
4703         BYTE_COUNT;
4704
4705         /* buffer format */
4706         CHECK_BYTE_COUNT(1);
4707         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4708         COUNT_BYTES(1);
4709
4710         /* directory name */
4711         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4712                 FALSE, FALSE, &bc);
4713         if (fn == NULL)
4714                 goto endofcommand;
4715         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
4716                 fn);
4717         COUNT_BYTES(fn_len);
4718
4719         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
4720                     format_text(fn, strlen(fn)));
4721
4722         END_OF_SMB
4723
4724         return offset;
4725 }
4726
4727 static int
4728 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4729 {
4730         int         fn_len;
4731         const char *fn;
4732         guint8      wc;
4733         guint16     bc, fid;
4734
4735         DISSECTOR_ASSERT(si);
4736
4737         WORD_COUNT;
4738
4739         /* fid */
4740         fid = tvb_get_letohs(tvb, offset);
4741         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
4742         offset += 2;
4743
4744         BYTE_COUNT;
4745
4746         /* buffer format */
4747         CHECK_BYTE_COUNT(1);
4748         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4749         COUNT_BYTES(1);
4750
4751         /* file name */
4752         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4753                 FALSE, FALSE, &bc);
4754         if (fn == NULL)
4755                 goto endofcommand;
4756         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4757                 fn);
4758         COUNT_BYTES(fn_len);
4759
4760         END_OF_SMB
4761
4762         return offset;
4763 }
4764
4765 static const value_string seek_mode_vals[] = {
4766         {0,     "From Start Of File"},
4767         {1,     "From Current Position"},
4768         {2,     "From End Of File"},
4769         {0,     NULL}
4770 };
4771
4772 static int
4773 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4774 {
4775         guint8  wc;
4776         guint16 bc, fid;
4777
4778         WORD_COUNT;
4779
4780         /* fid */
4781         fid = tvb_get_letohs(tvb, offset);
4782         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4783         offset += 2;
4784
4785         /* Seek Mode */
4786         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4787         offset += 2;
4788
4789         /* offset */
4790         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4791         offset += 4;
4792
4793         BYTE_COUNT;
4794
4795         END_OF_SMB
4796
4797         return offset;
4798 }
4799
4800 static int
4801 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_)
4802 {
4803         guint8  wc;
4804         guint16 bc;
4805
4806         WORD_COUNT;
4807
4808         /* offset */
4809         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4810         offset += 4;
4811
4812         BYTE_COUNT;
4813
4814         END_OF_SMB
4815
4816         return offset;
4817 }
4818
4819 static int
4820 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4821 {
4822         guint8  wc;
4823         guint16 bc, fid;
4824
4825         WORD_COUNT;
4826
4827         /* fid */
4828         fid = tvb_get_letohs(tvb, offset);
4829         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4830         offset += 2;
4831
4832         /* create time */
4833         offset = dissect_smb_datetime(tvb, tree, offset,
4834                 hf_smb_create_time,
4835                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4836
4837         /* access time */
4838         offset = dissect_smb_datetime(tvb, tree, offset,
4839                 hf_smb_access_time,
4840                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4841
4842         /* last write time */
4843         offset = dissect_smb_datetime(tvb, tree, offset,
4844                 hf_smb_last_write_time,
4845                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4846
4847         BYTE_COUNT;
4848
4849         END_OF_SMB
4850
4851         return offset;
4852 }
4853
4854 static int
4855 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_)
4856 {
4857         guint8  wc;
4858         guint16 bc;
4859
4860         WORD_COUNT;
4861
4862         /* create time */
4863         offset = dissect_smb_datetime(tvb, tree, offset,
4864                 hf_smb_create_time,
4865                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
4866
4867         /* access time */
4868         offset = dissect_smb_datetime(tvb, tree, offset,
4869                 hf_smb_access_time,
4870                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
4871
4872         /* last write time */
4873         offset = dissect_smb_datetime(tvb, tree, offset,
4874                 hf_smb_last_write_time,
4875                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
4876
4877         /* data size */
4878         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4879         offset += 4;
4880
4881         /* allocation size */
4882         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4883         offset += 4;
4884
4885         /* File Attributes */
4886         offset = dissect_file_attributes(tvb, tree, offset);
4887
4888         BYTE_COUNT;
4889
4890         END_OF_SMB
4891
4892         return offset;
4893 }
4894
4895 static int
4896 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)
4897 {
4898         guint8  wc;
4899         guint16 cnt = 0;
4900         guint16 bc, fid;
4901
4902         WORD_COUNT;
4903
4904         /* fid */
4905         fid = tvb_get_letohs(tvb, offset);
4906         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE, si);
4907         offset += 2;
4908
4909         /* write count */
4910         cnt = tvb_get_letohs(tvb, offset);
4911         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
4912         offset += 2;
4913
4914         /* offset */
4915         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
4916         offset += 4;
4917
4918         /* last write time */
4919         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
4920
4921         if (wc == 12) {
4922                 /* 12 reserved bytes */
4923                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, ENC_NA);
4924                 offset += 12;
4925         }
4926
4927         BYTE_COUNT;
4928
4929         /* 1 pad byte */
4930         CHECK_BYTE_COUNT(1);
4931         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
4932         COUNT_BYTES(1);
4933
4934         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
4935         bc = 0; /* XXX */
4936
4937         END_OF_SMB
4938
4939         return offset;
4940 }
4941
4942 static int
4943 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_)
4944 {
4945         guint8  wc;
4946         guint16 bc;
4947
4948         WORD_COUNT;
4949
4950         /* write count */
4951         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4952         offset += 2;
4953
4954         BYTE_COUNT;
4955
4956         END_OF_SMB
4957
4958         return offset;
4959 }
4960
4961 /* Timeout is defined on page 117 of SMB Protocol Extensions version 2.0
4962    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
4963 */
4964 static gchar *
4965 smbext20_timeout_msecs_to_str(gint32 timeout)
4966 {
4967         gchar *buf;
4968 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
4969
4970         if (timeout <= 0) {
4971                 buf = (gchar *)wmem_alloc(wmem_packet_scope(), SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
4972                 if (timeout == 0) {
4973                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
4974                 } else if (timeout == -1) {
4975                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
4976                 } else if (timeout == -2) {
4977                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
4978                 } else {
4979                         g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", timeout);
4980                 }
4981                 return buf;
4982         }
4983
4984         return time_msecs_to_ep_str(timeout);
4985 }
4986
4987 static int
4988 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
4989 {
4990         guint8  wc;
4991         guint16 bc, fid;
4992         guint32 to;
4993
4994         WORD_COUNT;
4995
4996         /* fid */
4997         fid = tvb_get_letohs(tvb, offset);
4998         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
4999         offset += 2;
5000
5001         /* offset */
5002         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5003         offset += 4;
5004
5005         /* max count */
5006         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5007         offset += 2;
5008
5009         /* min count */
5010         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5011         offset += 2;
5012
5013         /* timeout */
5014         to = tvb_get_letohl(tvb, offset);
5015         proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5016         offset += 4;
5017
5018         /* 2 reserved bytes */
5019         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5020         offset += 2;
5021
5022         if (wc == 10) {
5023                 /* high offset */
5024                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5025                 offset += 4;
5026         }
5027
5028         BYTE_COUNT;
5029
5030         END_OF_SMB
5031
5032         return offset;
5033 }
5034
5035 static int
5036 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_)
5037 {
5038         guint8  wc;
5039         guint16 bc;
5040
5041         WORD_COUNT;
5042
5043         /* units */
5044         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5045         offset += 2;
5046
5047         /* bpu */
5048         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5049         offset += 2;
5050
5051         /* block size */
5052         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5053         offset += 2;
5054
5055         /* free units */
5056         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5057         offset += 2;
5058
5059         /* 2 reserved bytes */
5060         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5061         offset += 2;
5062
5063         BYTE_COUNT;
5064
5065         END_OF_SMB
5066
5067         return offset;
5068 }
5069
5070 static int
5071 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5072 {
5073         guint8  wc;
5074         guint16 bc, fid;
5075
5076         WORD_COUNT;
5077
5078         /* fid */
5079         fid = tvb_get_letohs(tvb, offset);
5080         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5081         offset += 2;
5082
5083         /* offset */
5084         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5085         offset += 4;
5086
5087         /* max count */
5088         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5089         offset += 2;
5090
5091         /* min count */
5092         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5093         offset += 2;
5094
5095         /* 6 reserved bytes */
5096         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, ENC_NA);
5097         offset += 6;
5098
5099         BYTE_COUNT;
5100
5101         END_OF_SMB
5102
5103         return offset;
5104 }
5105
5106 static int
5107 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_)
5108 {
5109         guint16 datalen = 0, bc;
5110         guint8  wc;
5111
5112         WORD_COUNT;
5113
5114         /* offset */
5115         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5116         offset += 4;
5117
5118         /* count */
5119         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5120         offset += 2;
5121
5122         /* 2 reserved bytes */
5123         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5124         offset += 2;
5125
5126         /* data compaction mode */
5127         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5128         offset += 2;
5129
5130         /* 2 reserved bytes */
5131         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5132         offset += 2;
5133
5134         /* data len */
5135         datalen = tvb_get_letohs(tvb, offset);
5136         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5137         offset += 2;
5138
5139         /* data offset */
5140         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5141         offset += 2;
5142
5143         BYTE_COUNT;
5144
5145         /* file data */
5146         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5147         bc = 0;
5148
5149         END_OF_SMB
5150
5151         return offset;
5152 }
5153
5154
5155 static const true_false_string tfs_write_mode_write_through = {
5156         "WRITE THROUGH requested",
5157         "Write through not requested"
5158 };
5159 static const true_false_string tfs_write_mode_return_remaining = {
5160         "RETURN REMAINING (pipe/dev) requested",
5161         "DON'T return remaining (pipe/dev)"
5162 };
5163 static const true_false_string tfs_write_mode_raw = {
5164         "Use WriteRawNamedPipe (pipe)",
5165         "DON'T use WriteRawNamedPipe (pipe)"
5166 };
5167 static const true_false_string tfs_write_mode_message_start = {
5168         "This is the START of a MESSAGE (pipe)",
5169         "This is NOT the start of a message (pipe)"
5170 };
5171 static const true_false_string tfs_write_mode_connectionless = {
5172         "CONNECTIONLESS mode requested",
5173         "Connectionless mode NOT requested"
5174 };
5175
5176 #define WRITE_MODE_CONNECTIONLESS       0x0080
5177 #define WRITE_MODE_MESSAGE_START        0x0008
5178 #define WRITE_MODE_RAW                  0x0004
5179 #define WRITE_MODE_RETURN_REMAINING     0x0002
5180 #define WRITE_MODE_WRITE_THROUGH        0x0001
5181
5182 static int
5183 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5184 {
5185         guint16     mask;
5186         proto_item *item;
5187         proto_tree *tree;
5188
5189         mask = tvb_get_letohs(tvb, offset);
5190
5191         if (parent_tree) {
5192                 item = proto_tree_add_item(parent_tree, hf_smb_write_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5193                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
5194
5195                 if (bm&WRITE_MODE_CONNECTIONLESS) {
5196                         proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
5197                                 tvb, offset, 2, mask);
5198                 }
5199                 if (bm&WRITE_MODE_MESSAGE_START) {
5200                         proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
5201                                 tvb, offset, 2, mask);
5202                                 }
5203                 if (bm&WRITE_MODE_RAW) {
5204                         proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
5205                                 tvb, offset, 2, mask);
5206                 }
5207                 if (bm&WRITE_MODE_RETURN_REMAINING) {
5208                         proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
5209                                 tvb, offset, 2, mask);
5210                 }
5211                 if (bm&WRITE_MODE_WRITE_THROUGH) {
5212                         proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
5213                                 tvb, offset, 2, mask);
5214                 }
5215         }
5216
5217         offset += 2;
5218         return offset;
5219 }
5220
5221 static int
5222 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5223 {
5224         guint32 to;
5225         guint16 datalen = 0, bc, fid;
5226         guint8  wc;
5227
5228         WORD_COUNT;
5229
5230         /* fid */
5231         fid = tvb_get_letohs(tvb, offset);
5232         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5233         offset += 2;
5234
5235         /* total data length */
5236         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5237         offset += 2;
5238
5239         /* 2 reserved bytes */
5240         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5241         offset += 2;
5242
5243         /* offset */
5244         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5245         offset += 4;
5246
5247         /* timeout */
5248         to = tvb_get_letohl(tvb, offset);
5249         proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5250         offset += 4;
5251
5252         /* mode */
5253         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
5254
5255         /* 4 reserved bytes */
5256         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
5257         offset += 4;
5258
5259         /* data len */
5260         datalen = tvb_get_letohs(tvb, offset);
5261         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5262         offset += 2;
5263
5264         /* data offset */
5265         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5266         offset += 2;
5267
5268         BYTE_COUNT;
5269
5270         /* file data */
5271         /* XXX - use the data offset to determine where the data starts? */
5272         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5273         bc = 0;
5274
5275         END_OF_SMB
5276
5277         return offset;
5278 }
5279
5280 static int
5281 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_)
5282 {
5283         guint8  wc;
5284         guint16 bc;
5285
5286         WORD_COUNT;
5287
5288         /* remaining */
5289         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5290         offset += 2;
5291
5292         BYTE_COUNT;
5293
5294         END_OF_SMB
5295
5296         return offset;
5297 }
5298
5299 static int
5300 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
5301 {
5302         guint32 to;
5303         guint16 datalen = 0, bc, fid;
5304         guint8  wc;
5305
5306         WORD_COUNT;
5307
5308         /* fid */
5309         fid = tvb_get_letohs(tvb, offset);
5310         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5311         offset += 2;
5312
5313         /* total data length */
5314         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5315         offset += 2;
5316
5317         /* 2 reserved bytes */
5318         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5319         offset += 2;
5320
5321         /* offset */
5322         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5323         offset += 4;
5324
5325         /* timeout */
5326         to = tvb_get_letohl(tvb, offset);
5327         proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5328         offset += 4;
5329
5330         /* mode */
5331         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
5332
5333         /* request mask */
5334         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5335         offset += 4;
5336
5337         /* data len */
5338         datalen = tvb_get_letohs(tvb, offset);
5339         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5340         offset += 2;
5341
5342         /* data offset */
5343         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5344         offset += 2;
5345
5346         BYTE_COUNT;
5347
5348         /* file data */
5349         /* XXX - use the data offset to determine where the data starts? */
5350         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5351         bc = 0;
5352
5353         END_OF_SMB
5354
5355         return offset;
5356 }
5357
5358 static int
5359 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_)
5360 {
5361         guint8  wc;
5362         guint16 bc;
5363
5364         WORD_COUNT;
5365
5366         /* response mask */
5367         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5368         offset += 4;
5369
5370         BYTE_COUNT;
5371
5372         END_OF_SMB
5373
5374         return offset;
5375 }
5376
5377 static int
5378 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5379 {
5380         guint8  wc;
5381         guint16 bc;
5382
5383         WORD_COUNT;
5384
5385         /* sid */
5386         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5387         offset += 2;
5388
5389         BYTE_COUNT;
5390
5391         END_OF_SMB
5392
5393         return offset;
5394 }
5395
5396 static int
5397 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo _U_,
5398     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5399     gboolean has_find_id, smb_info_t *si)
5400 {
5401         proto_item *item = NULL;
5402         proto_tree *tree = NULL;
5403         int         fn_len;
5404         const char *fn;
5405         char        fname[11+1];
5406
5407         DISSECTOR_ASSERT(si);
5408
5409         if (parent_tree) {
5410                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
5411                         "Resume Key");
5412                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
5413         }
5414
5415         /* reserved byte */
5416         CHECK_BYTE_COUNT_SUBR(1);
5417         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
5418         COUNT_BYTES_SUBR(1);
5419
5420         /* file name */
5421         fn_len = 11;
5422         fn = get_unicode_or_ascii_string(tvb, &offset, FALSE/*never Unicode*/, &fn_len,
5423                 TRUE, TRUE, bcp);
5424         CHECK_STRING_SUBR(fn);
5425         /* ensure that it's null-terminated */
5426         g_strlcpy(fname, fn, 11+1);
5427         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
5428                 fname);
5429         COUNT_BYTES_SUBR(fn_len);
5430
5431         if (has_find_id) {
5432                 CHECK_BYTE_COUNT_SUBR(1);
5433                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5434                 COUNT_BYTES_SUBR(1);
5435
5436                 /* server cookie */
5437                 CHECK_BYTE_COUNT_SUBR(4);
5438                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, ENC_NA);
5439                 COUNT_BYTES_SUBR(4);
5440         } else {
5441                 /* server cookie */
5442                 CHECK_BYTE_COUNT_SUBR(5);
5443                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, ENC_NA);
5444                 COUNT_BYTES_SUBR(5);
5445         }
5446
5447         /* client cookie */
5448         CHECK_BYTE_COUNT_SUBR(4);
5449         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, ENC_NA);
5450         COUNT_BYTES_SUBR(4);
5451
5452         *trunc = FALSE;
5453         return offset;
5454 }
5455
5456 static int
5457 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
5458     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
5459     gboolean has_find_id, smb_info_t *si)
5460 {
5461         proto_item *item = NULL;
5462         proto_tree *tree = NULL;
5463         int         fn_len;
5464         const char *fn;
5465         char        fname[13+1];
5466
5467         DISSECTOR_ASSERT(si);
5468
5469         if (parent_tree) {
5470                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
5471                         "Directory Information");
5472                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
5473         }
5474
5475         /* resume key */
5476         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
5477             trunc, has_find_id, si);
5478         if (*trunc)
5479                 return offset;
5480
5481         /* File Attributes */
5482         CHECK_BYTE_COUNT_SUBR(1);
5483         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
5484         *bcp -= 1;
5485
5486         /* last write time */
5487         CHECK_BYTE_COUNT_SUBR(4);
5488         offset = dissect_smb_datetime(tvb, tree, offset,
5489                 hf_smb_last_write_time,
5490                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
5491                 TRUE);
5492         *bcp -= 4;
5493
5494         /* File Size */
5495         CHECK_BYTE_COUNT_SUBR(4);
5496         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5497         COUNT_BYTES_SUBR(4);
5498
5499         /* file name */
5500         fn_len = 13;
5501         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5502                 TRUE, TRUE, bcp);
5503         CHECK_STRING_SUBR(fn);
5504         /* ensure that it's null-terminated */
5505         g_strlcpy(fname, fn, 13+1);
5506         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5507                 fname);
5508         COUNT_BYTES_SUBR(fn_len);
5509
5510         *trunc = FALSE;
5511         return offset;
5512 }
5513
5514
5515 static int
5516 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
5517     proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si,
5518     gboolean has_find_id)
5519 {
5520         int         fn_len;
5521         const char *fn;
5522         guint16     rkl;
5523         guint8      wc;
5524         guint16     bc;
5525         gboolean    trunc;
5526
5527         DISSECTOR_ASSERT(si);
5528
5529         WORD_COUNT;
5530
5531         /* max count */
5532         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5533         offset += 2;
5534
5535         /* Search Attributes */
5536         offset = dissect_search_attributes(tvb, tree, offset);
5537
5538         BYTE_COUNT;
5539
5540         /* buffer format */
5541         CHECK_BYTE_COUNT(1);
5542         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5543         COUNT_BYTES(1);
5544
5545         /* file name */
5546         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5547                 TRUE, FALSE, &bc);
5548         if (fn == NULL)
5549                 goto endofcommand;
5550         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5551                 fn);
5552         COUNT_BYTES(fn_len);
5553
5554         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
5555                     format_text(fn, strlen(fn)));
5556
5557         /* buffer format */
5558         CHECK_BYTE_COUNT(1);
5559         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5560         COUNT_BYTES(1);
5561
5562         /* resume key length */
5563         CHECK_BYTE_COUNT(2);
5564         rkl = tvb_get_letohs(tvb, offset);
5565         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
5566         COUNT_BYTES(2);
5567
5568         /* resume key */
5569         if (rkl) {
5570                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
5571                     &bc, &trunc, has_find_id, si);
5572                 if (trunc)
5573                         goto endofcommand;
5574         }
5575
5576         END_OF_SMB
5577
5578         return offset;
5579 }
5580
5581 static int
5582 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo,
5583     proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5584 {
5585         return dissect_search_find_request(tvb, pinfo, tree, offset,
5586             smb_tree, si, FALSE);
5587 }
5588
5589 static int
5590 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo,
5591     proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5592 {
5593         return dissect_search_find_request(tvb, pinfo, tree, offset,
5594             smb_tree, si, TRUE);
5595 }
5596
5597 static int
5598 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo,
5599     proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5600 {
5601         return dissect_search_find_request(tvb, pinfo, tree, offset,
5602             smb_tree, si, TRUE);
5603 }
5604
5605 static int
5606 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo,
5607     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
5608     gboolean has_find_id, smb_info_t *si)
5609 {
5610         guint16  count = 0;
5611         guint8   wc;
5612         guint16  bc;
5613         gboolean trunc;
5614
5615         WORD_COUNT;
5616
5617         /* count */
5618         count = tvb_get_letohs(tvb, offset);
5619         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
5620         offset += 2;
5621
5622         BYTE_COUNT;
5623
5624         /* buffer format */
5625         CHECK_BYTE_COUNT(1);
5626         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5627         COUNT_BYTES(1);
5628
5629         /* data len */
5630         CHECK_BYTE_COUNT(2);
5631         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5632         COUNT_BYTES(2);
5633
5634         while (count--) {
5635                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
5636                     &bc, &trunc, has_find_id, si);
5637                 if (trunc)
5638                         goto endofcommand;
5639         }
5640
5641         END_OF_SMB
5642
5643         return offset;
5644 }
5645
5646 static int
5647 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5648 {
5649         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5650             FALSE, si);
5651 }
5652
5653 static int
5654 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5655 {
5656         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
5657             TRUE, si);
5658 }
5659
5660 static int
5661 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
5662     proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
5663 {
5664         guint8  wc;
5665         guint16 bc;
5666         guint16 data_len;
5667
5668         WORD_COUNT;
5669
5670         /* reserved */
5671         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5672         offset += 2;
5673
5674         BYTE_COUNT;
5675
5676         /* buffer format */
5677         CHECK_BYTE_COUNT(1);
5678         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5679         COUNT_BYTES(1);
5680
5681         /* data len */
5682         CHECK_BYTE_COUNT(2);
5683         data_len = tvb_get_ntohs(tvb, offset);
5684         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
5685         COUNT_BYTES(2);
5686
5687         if (data_len != 0) {
5688                 CHECK_BYTE_COUNT(data_len);
5689                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
5690                     data_len, ENC_NA);
5691                 COUNT_BYTES(data_len);
5692         }
5693
5694         END_OF_SMB
5695
5696         return offset;
5697 }
5698
5699 static const value_string locking_ol_vals[] = {
5700         {0,     "Client is not holding oplock on this file"},
5701         {1,     "Level 2 oplock currently held by client"},
5702         {0, NULL}
5703 };
5704
5705 static const true_false_string tfs_lock_type_large = {
5706         "Large file locking format requested",
5707         "Large file locking format not requested"
5708 };
5709 static const true_false_string tfs_lock_type_cancel = {
5710         "Cancel outstanding lock request",
5711         "Don't cancel outstanding lock request"
5712 };
5713 static const true_false_string tfs_lock_type_change = {
5714         "Change lock type",
5715         "Don't change lock type"
5716 };
5717 static const true_false_string tfs_lock_type_oplock = {
5718         "This is an oplock break notification/response",
5719         "This is not an oplock break notification/response"
5720 };
5721 static const true_false_string tfs_lock_type_shared = {
5722         "This is a shared lock",
5723         "This is an exclusive lock"
5724 };
5725 static int
5726 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
5727 {
5728         guint8      wc, cmd    = 0xff, lt = 0, ol = 0;
5729         guint16     andxoffset = 0, un = 0, ln = 0, bc, fid, num_lock = 0, num_unlock = 0;
5730         guint32     to;
5731         proto_item *litem      = NULL;
5732         proto_tree *ltree      = NULL;
5733         proto_item *it         = NULL;
5734         proto_tree *tr         = NULL;
5735         int         old_offset = offset;
5736         smb_locking_saved_info_t *ld = NULL;
5737
5738
5739         DISSECTOR_ASSERT(si);
5740
5741         WORD_COUNT;
5742
5743         /* next smb command */
5744         cmd = tvb_get_guint8(tvb, offset);
5745         if (cmd != 0xff) {
5746                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
5747         } else {
5748                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
5749         }
5750         offset += 1;
5751
5752         /* reserved byte */
5753         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
5754         offset += 1;
5755
5756         /* andxoffset */
5757         andxoffset = tvb_get_letohs(tvb, offset);
5758         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5759         offset += 2;
5760
5761         /* fid */
5762         fid = tvb_get_letohs(tvb, offset);
5763         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
5764         offset += 2;
5765
5766         /* lock type */
5767         lt = tvb_get_guint8(tvb, offset);
5768         if (tree) {
5769                 litem = proto_tree_add_item(tree, hf_smb_lock_type, tvb, offset, 1, ENC_NA);
5770                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
5771
5772                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
5773                         tvb, offset, 1, lt);
5774                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
5775                         tvb, offset, 1, lt);
5776                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
5777                         tvb, offset, 1, lt);
5778                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
5779                         tvb, offset, 1, lt);
5780                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
5781                         tvb, offset, 1, lt);
5782         }
5783         offset += 1;
5784
5785         /* oplock level */
5786         ol = tvb_get_guint8(tvb, offset);
5787         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5788         offset += 1;
5789
5790         /* timeout */
5791         to = tvb_get_letohl(tvb, offset);
5792         proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
5793         offset += 4;
5794
5795         /* number of unlocks */
5796         un = tvb_get_letohs(tvb, offset);
5797         num_unlock = un;
5798         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
5799         offset += 2;
5800
5801         /* number of locks */
5802         ln = tvb_get_letohs(tvb, offset);
5803         num_lock = ln;
5804         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
5805         offset += 2;
5806
5807         BYTE_COUNT;
5808
5809         /* store the locking data for the response */
5810         if ((!pinfo->fd->flags.visited) && si->sip) {
5811                 ld = (smb_locking_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_locking_saved_info_t));
5812                 ld->type         = lt;
5813                 ld->oplock_level = ol;
5814                 ld->num_lock     = num_lock;
5815                 ld->num_unlock   = num_unlock;
5816                 ld->locks        = NULL;
5817                 ld->unlocks      = NULL;
5818                 si->sip->extra_info_type = SMB_EI_LOCKDATA;
5819                 si->sip->extra_info      = ld;
5820         }
5821
5822         /* unlocks */
5823         if (un) {
5824                 old_offset = offset;
5825
5826                 it = proto_tree_add_text(tree, tvb, offset, -1, "Unlocks");
5827                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
5828                 while (un--) {
5829                         proto_item *litem_2 = NULL;
5830                         proto_tree *ltree_2 = NULL;
5831                         if (lt&0x10) {
5832                                 guint64 val;
5833                                 guint16 lock_pid;
5834                                 guint64 lock_offset;
5835                                 guint64 lock_length;
5836
5837                                 /* large lock format */
5838                                 litem_2 = proto_tree_add_text(tr, tvb, offset, 20, "Unlock");
5839                                 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_unlock);
5840
5841                                 /* PID */
5842                                 CHECK_BYTE_COUNT(2);
5843                                 lock_pid = tvb_get_letohs(tvb, offset);
5844                                 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5845                                 COUNT_BYTES(2);
5846
5847                                 /* 2 reserved bytes */
5848                                 CHECK_BYTE_COUNT(2);
5849                                 proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5850                                 COUNT_BYTES(2);
5851
5852                                 /* offset */
5853                                 CHECK_BYTE_COUNT(8);
5854                                 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5855                                     | tvb_get_letohl(tvb, offset+4);
5856                                 lock_offset = val;
5857                                 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
5858                                 COUNT_BYTES(8);
5859
5860                                 /* length */
5861                                 CHECK_BYTE_COUNT(8);
5862                                 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5863                                     | tvb_get_letohl(tvb, offset+4);
5864                                 lock_length = val;
5865                                 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
5866                                 COUNT_BYTES(8);
5867
5868                                 /* remember the unlock for the reply */
5869                                 if (ld) {
5870                                         smb_lock_info_t *li;
5871                                         li = (smb_lock_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_lock_info_t));
5872                                         li->next = ld->unlocks;
5873                                         ld->unlocks = li;
5874                                         li->pid = lock_pid;
5875                                         li->offset = lock_offset;
5876                                         li->length = lock_length;
5877                                 }
5878                         } else {
5879                                 /* normal lock format */
5880                                 litem_2 = proto_tree_add_text(tr, tvb, offset, 10, "Unlock");
5881                                 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_unlock);
5882
5883                                 /* PID */
5884                                 CHECK_BYTE_COUNT(2);
5885                                 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5886                                 COUNT_BYTES(2);
5887
5888                                 /* offset */
5889                                 CHECK_BYTE_COUNT(4);
5890                                 proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5891                                 COUNT_BYTES(4);
5892
5893                                 /* lock count */
5894                                 CHECK_BYTE_COUNT(4);
5895                                 proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5896                                 COUNT_BYTES(4);
5897                         }
5898                 }
5899                 proto_item_set_len(it, offset-old_offset);
5900                 it = NULL;
5901         }
5902
5903         /* locks */
5904         if (ln) {
5905                 old_offset = offset;
5906
5907                 it = proto_tree_add_text(tree, tvb, offset, -1, "Locks");
5908                 tr = proto_item_add_subtree(it, ett_smb_locks);
5909                 while (ln--) {
5910                         proto_item *litem_2 = NULL;
5911                         proto_tree *ltree_2 = NULL;
5912                         if (lt&0x10) {
5913                                 guint64 val;
5914                                 guint16 lock_pid;
5915                                 guint64 lock_offset;
5916                                 guint64 lock_length;
5917
5918                                 /* large lock format */
5919                                 litem_2 = proto_tree_add_text(tr, tvb, offset, 20, "Lock");
5920                                 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_lock);
5921
5922                                 /* PID */
5923                                 CHECK_BYTE_COUNT(2);
5924                                 lock_pid = tvb_get_letohs(tvb, offset);
5925                                 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5926                                 COUNT_BYTES(2);
5927
5928                                 /* 2 reserved bytes */
5929                                 CHECK_BYTE_COUNT(2);
5930                                 proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, ENC_NA);
5931                                 COUNT_BYTES(2);
5932
5933                                 /* offset */
5934                                 CHECK_BYTE_COUNT(8);
5935                                 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5936                                     | tvb_get_letohl(tvb, offset+4);
5937                                 lock_offset = val;
5938                                 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
5939                                 COUNT_BYTES(8);
5940
5941                                 /* length */
5942                                 CHECK_BYTE_COUNT(8);
5943                                 val = ((guint64)tvb_get_letohl(tvb, offset)) << 32
5944                                     | tvb_get_letohl(tvb, offset+4);
5945                                 lock_length = val;
5946                                 proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
5947                                 COUNT_BYTES(8);
5948
5949                                 /* remember the lock for the reply */
5950                                 if (ld) {
5951                                         smb_lock_info_t *li;
5952                                         li = (smb_lock_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_lock_info_t));
5953                                         li->next = ld->locks;
5954                                         ld->locks = li;
5955                                         li->pid = lock_pid;
5956                                         li->offset = lock_offset;
5957                                         li->length = lock_length;
5958                                 }
5959                         } else {
5960                                 /* normal lock format */
5961                                 litem_2 = proto_tree_add_text(tr, tvb, offset, 10, "Lock");
5962                                 ltree_2 = proto_item_add_subtree(litem_2, ett_smb_lock);
5963
5964                                 /* PID */
5965                                 CHECK_BYTE_COUNT(2);
5966                                 proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5967                                 COUNT_BYTES(2);
5968
5969                                 /* offset */
5970                                 CHECK_BYTE_COUNT(4);
5971                                 proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5972                                 COUNT_BYTES(4);
5973
5974                                 /* lock count */
5975                                 CHECK_BYTE_COUNT(4);
5976                                 proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
5977                                 COUNT_BYTES(4);
5978                         }
5979                 }
5980                 proto_item_set_len(it, offset-old_offset);
5981                 it = NULL;
5982         }
5983
5984         END_OF_SMB
5985
5986         if (it != NULL) {
5987                 /*
5988                  * We ran out of byte count in the middle of dissecting
5989                  * the locks or the unlocks; set the site of the item
5990                  * we were dissecting.
5991                  */
5992                 proto_item_set_len(it, offset-old_offset);
5993         }
5994
5995         if (cmd != 0xff) {      /* there is an andX command */
5996                 if (andxoffset < offset) {
5997                         THROW(ReportedBoundsError);
5998                 }
5999                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6000         }
6001
6002         return offset;
6003 }
6004
6005 static int
6006 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6007 {
6008         guint8      wc, cmd    = 0xff;
6009         guint16     andxoffset = 0;
6010         guint16     bc;
6011
6012         DISSECTOR_ASSERT(si);
6013
6014         /* print the lock info from the request */
6015         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_LOCKDATA)) {
6016                 smb_locking_saved_info_t *ld;
6017                 proto_item *litem = NULL;
6018                 proto_tree *ltree = NULL;
6019
6020                 ld = (smb_locking_saved_info_t *)si->sip->extra_info;
6021                 if (ld != NULL) {
6022                         proto_item *lit;
6023                         proto_tree *ltr;
6024                         smb_lock_info_t *li;
6025                         if (tree) {
6026                                 litem = proto_tree_add_item(tree, hf_smb_lock_type, tvb, 0, 0, ENC_NA);
6027                                 PROTO_ITEM_SET_GENERATED(litem);
6028                                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
6029
6030                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
6031                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
6032                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
6033                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
6034                                 proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
6035                                 proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
6036                                 proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
6037                                 proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
6038
6039                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
6040                                 ltr = proto_item_add_subtree(lit, ett_smb_lock);
6041                                 li = ld->locks;
6042                                 while (li) {
6043                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
6044                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
6045                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
6046                                         li = li->next;
6047                                 }
6048                                 lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
6049                                 ltr = proto_item_add_subtree(lit, ett_smb_unlock);
6050                                 li = ld->unlocks;
6051                                 while (li) {
6052                                         proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
6053                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
6054                                         proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
6055                                         li = li->next;
6056                                 }
6057                         }
6058                 }
6059         }
6060
6061         WORD_COUNT;
6062
6063         /* next smb command */
6064         cmd = tvb_get_guint8(tvb, offset);
6065         if (cmd != 0xff) {
6066                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6067         } else {
6068                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6069         }
6070         offset += 1;
6071
6072         /* reserved byte */
6073         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6074         offset += 1;
6075
6076         /* andxoffset */
6077         andxoffset = tvb_get_letohs(tvb, offset);
6078         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6079         offset += 2;
6080
6081         BYTE_COUNT;
6082
6083         END_OF_SMB
6084
6085         if (cmd != 0xff) {      /* there is an andX command */
6086                 if (andxoffset < offset) {
6087                         THROW(ReportedBoundsError);
6088                 }
6089                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6090         }
6091
6092         return offset;
6093 }
6094
6095
6096 const value_string oa_open_vals[] = {
6097         { 0,            "No action taken?"},
6098         { 1,            "The file existed and was opened"},
6099         { 2,            "The file did not exist but was created"},
6100         { 3,            "The file existed and was truncated"},
6101         { 0x8001,       "The file existed and was opened, and an OpLock was granted"},
6102         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
6103         { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
6104         {0,     NULL}
6105 };
6106 static const true_false_string tfs_oa_lock = {
6107         "File is currently opened only by this user",
6108         "File is opened by another user (or mode not supported by server)"
6109 };
6110 static int
6111 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6112 {
6113         guint16     mask;
6114         proto_item *item;
6115         proto_tree *tree;
6116
6117         mask = tvb_get_letohs(tvb, offset);
6118
6119         if (parent_tree) {
6120                 item = proto_tree_add_item(parent_tree, hf_smb_open_action, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6121                 tree = proto_item_add_subtree(item, ett_smb_open_action);
6122
6123                 proto_tree_add_boolean(tree, hf_smb_open_action_lock,
6124                         tvb, offset, 2, mask);
6125                 proto_tree_add_uint(tree, hf_smb_open_action_open,
6126                         tvb, offset, 2, mask);
6127         }
6128         offset += 2;
6129
6130         return offset;
6131 }
6132
6133 static const true_false_string tfs_open_flags_add_info = {
6134         "Additional information requested",
6135         "Additional information not requested"
6136 };
6137 static const true_false_string tfs_open_flags_ex_oplock = {
6138         "Exclusive oplock requested",
6139         "Exclusive oplock not requested"
6140 };
6141 static const true_false_string tfs_open_flags_batch_oplock = {
6142         "Batch oplock requested",
6143         "Batch oplock not requested"
6144 };
6145 static const true_false_string tfs_open_flags_ealen = {
6146         "Total length of EAs requested",
6147         "Total length of EAs not requested"
6148 };
6149 static int
6150 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
6151 {
6152         guint16     mask;
6153         proto_item *item;
6154         proto_tree *tree;
6155
6156         mask = tvb_get_letohs(tvb, offset);
6157
6158         if (parent_tree) {
6159                 item = proto_tree_add_item(parent_tree, hf_smb_open_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6160                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
6161
6162                 if (bm&0x0001) {
6163                         proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
6164                                 tvb, offset, 2, mask);
6165                 }
6166                 if (bm&0x0002) {
6167                         proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
6168                                 tvb, offset, 2, mask);
6169                 }
6170                 if (bm&0x0004) {
6171                         proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
6172                                 tvb, offset, 2, mask);
6173                 }
6174                 if (bm&0x0008) {
6175                         proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
6176                                 tvb, offset, 2, mask);
6177                 }
6178         }
6179
6180         offset += 2;
6181
6182         return offset;
6183 }
6184
6185 /* [MS-CIFS].pdf 2.2.4.64.2 provides the last two file types, however
6186    [MS-SMB].PDF 2.2.4.9.2 elides value 4, Character mode device.  */
6187 static const value_string filetype_vals[] = {
6188         { 0,            "Disk file or directory"},
6189         { 1,            "Named pipe in byte mode"},
6190         { 2,            "Named pipe in message mode"},
6191         { 3,            "Spooled printer"},
6192         { 4,            "Character mode device"},
6193         { 0xFFFF,       "Unknown file type"},
6194         {0, NULL}
6195 };
6196 static int
6197 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6198 {
6199         guint8      wc, cmd    = 0xff;
6200         guint16     andxoffset = 0, bc;
6201         guint32     to;
6202         int         fn_len;
6203         const char *fn;
6204
6205         DISSECTOR_ASSERT(si);
6206
6207         WORD_COUNT;
6208
6209         /* next smb command */
6210         cmd = tvb_get_guint8(tvb, offset);
6211         if (cmd != 0xff) {
6212                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6213         } else {
6214                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6215         }
6216         offset += 1;
6217
6218         /* reserved byte */
6219         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6220         offset += 1;
6221
6222         /* andxoffset */
6223         andxoffset = tvb_get_letohs(tvb, offset);
6224         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6225         offset += 2;
6226
6227         /* open flags */
6228         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
6229
6230         /* desired access */
6231         offset = dissect_access(tvb, tree, offset, "Desired");
6232
6233         /* Search Attributes */
6234         offset = dissect_search_attributes(tvb, tree, offset);
6235
6236         /* File Attributes */
6237         offset = dissect_file_attributes(tvb, tree, offset);
6238
6239         /* creation time */
6240         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
6241
6242         /* open function */
6243         offset = dissect_open_function(tvb, tree, offset);
6244
6245         /* allocation size */
6246         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6247         offset += 4;
6248
6249         /* timeout, described at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT */
6250         to = tvb_get_letohl(tvb, offset);
6251         proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
6252         offset += 4;
6253
6254         /* 4 reserved bytes */
6255         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
6256         offset += 4;
6257
6258         BYTE_COUNT;
6259
6260         /* file name */
6261         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
6262                 FALSE, FALSE, &bc);
6263         if (fn == NULL)
6264                 goto endofcommand;
6265         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6266                 fn);
6267         COUNT_BYTES(fn_len);
6268
6269         /* Copied this portion of code from create_andx_request
6270            to guarantee that fsi and si->sip are always correctly filled out */
6271         if ((!pinfo->fd->flags.visited) && si->sip && fn) {
6272                 smb_fid_saved_info_t *fsi;
6273
6274                 fsi = wmem_new0(wmem_file_scope(), smb_fid_saved_info_t);
6275                 fsi->filename = wmem_strdup(wmem_file_scope(), fn);
6276
6277                 si->sip->extra_info_type = SMB_EI_FILEDATA;
6278                 si->sip->extra_info = fsi;
6279         }
6280
6281         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
6282                     format_text(fn, strlen(fn)));
6283
6284         END_OF_SMB
6285
6286         if (cmd != 0xff) {      /* there is an andX command */
6287                 if (andxoffset < offset) {
6288                         THROW(ReportedBoundsError);
6289                 }
6290                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6291         }
6292
6293         return offset;
6294 }
6295
6296 static const true_false_string tfs_ipc_state_nonblocking = {
6297         "Reads/writes return immediately if no data available",
6298         "Reads/writes block if no data available"
6299 };
6300 static const value_string ipc_state_endpoint_vals[] = {
6301         { 0,            "Consumer end of pipe"},
6302         { 1,            "Server end of pipe"},
6303         {0,     NULL}
6304 };
6305 static const value_string ipc_state_pipe_type_vals[] = {
6306         { 0,            "Byte stream pipe"},
6307         { 1,            "Message pipe"},
6308         {0,     NULL}
6309 };
6310 static const value_string ipc_state_read_mode_vals[] = {
6311         { 0,            "Read pipe as a byte stream"},
6312         { 1,            "Read messages from pipe"},
6313         {0,     NULL}
6314 };
6315
6316 int
6317 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
6318     gboolean setstate_flag)
6319 {
6320         guint16     mask;
6321         proto_item *item;
6322         proto_tree *tree;
6323
6324         mask = tvb_get_letohs(tvb, offset);
6325
6326         if (parent_tree) {
6327                 item = proto_tree_add_item(parent_tree, hf_smb_ipc_state, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6328                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
6329
6330                 proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
6331                         tvb, offset, 2, mask);
6332                 if (!setstate_flag) {
6333                         proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
6334                                 tvb, offset, 2, mask);
6335                         proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
6336                                 tvb, offset, 2, mask);
6337                 }
6338                 proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
6339                         tvb, offset, 2, mask);
6340                 if (!setstate_flag) {
6341                         proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
6342                                 tvb, offset, 2, mask);
6343                 }
6344         }
6345
6346         offset += 2;
6347
6348         return offset;
6349 }
6350
6351 static int
6352 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6353 {
6354         guint8          wc, cmd    = 0xff;
6355         guint16         andxoffset = 0, bc;
6356         guint16         fid;
6357         guint16         ftype;
6358         guint16         fattr;
6359         smb_fid_info_t *fid_info   = NULL;
6360         gboolean        isdir      = FALSE;
6361
6362         WORD_COUNT;
6363
6364         /* next smb command */
6365         cmd = tvb_get_guint8(tvb, offset);
6366         if (cmd != 0xff) {
6367                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6368         } else {
6369                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6370         }
6371         offset += 1;
6372
6373         /* reserved byte */
6374         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6375         offset += 1;
6376
6377         /* andxoffset */
6378         andxoffset = tvb_get_letohs(tvb, offset);
6379         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6380         offset += 2;
6381
6382         /* fid */
6383         fid = tvb_get_letohs(tvb, offset);
6384         /* we add fid_info= to this call so that we save the result */
6385         fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
6386
6387         offset += 2;
6388
6389         /* File Attributes */
6390         fattr = tvb_get_letohs(tvb, offset);
6391         isdir = fattr & SMB_FILE_ATTRIBUTE_DIRECTORY;
6392         offset = dissect_file_attributes(tvb, tree, offset);
6393
6394         /* last write time */
6395         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
6396
6397         /* File Size */
6398         /* We store the file_size in the fid_info */
6399         if (fid_info) {
6400                 fid_info->end_of_file = (guint64) tvb_get_letohl(tvb, offset);
6401         }
6402         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6403         offset += 4;
6404
6405         /* granted access */
6406         offset = dissect_access(tvb, tree, offset, "Granted");
6407
6408         /* File Type */
6409         ftype = tvb_get_letohs(tvb, offset);
6410         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6411         offset += 2;
6412         /* Copied from dissect_nt_create_andx_response
6413            Try to remember the type of this fid so that we can dissect
6414            any future security descriptor (access mask) properly
6415         */
6416         if (fid_info) {
6417                 fid_info->type = SMB_FID_TYPE_UNKNOWN;
6418         }
6419         if (ftype == 0) {
6420                 if (isdir == 0) {
6421                         if (fid_info) {
6422                                 fid_info->type = SMB_FID_TYPE_FILE;
6423                         }
6424                 } else {
6425                         if (fid_info) {
6426                                 fid_info->type = SMB_FID_TYPE_DIR;
6427                         }
6428                 }
6429         }
6430         if ((ftype == 2) || (ftype == 1)) {
6431                 if (fid_info) {
6432                         fid_info->type = SMB_FID_TYPE_PIPE;
6433                 }
6434         }
6435
6436         /* IPC State */
6437         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
6438
6439         /* open_action */
6440         offset = dissect_open_action(tvb, tree, offset);
6441
6442         /* server fid */
6443         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6444         offset += 4;
6445
6446         /* 2 reserved bytes */
6447         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6448         offset += 2;
6449
6450         BYTE_COUNT;
6451
6452         END_OF_SMB
6453
6454         if (cmd != 0xff) {      /* there is an andX command */
6455                 if (andxoffset < offset) {
6456                         THROW(ReportedBoundsError);
6457                 }
6458                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6459         }
6460
6461         return offset;
6462 }
6463
6464 static int
6465 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6466 {
6467         guint8        wc, cmd               = 0xff;
6468         guint16       andxoffset            = 0, bc, maxcnt_low;
6469         guint32       maxcnt_high;
6470         guint32       maxcnt                = 0;
6471         guint32       offsetlow, offsethigh = 0;
6472         guint64       ofs;
6473         unsigned int  fid;
6474         rw_info_t    *rwi                   = NULL;
6475
6476
6477         DISSECTOR_ASSERT(si);
6478
6479         WORD_COUNT;
6480
6481         /* next smb command */
6482         cmd = tvb_get_guint8(tvb, offset);
6483         if (cmd != 0xff) {
6484                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6485         } else {
6486                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6487         }
6488         offset += 1;
6489
6490         /* reserved byte */
6491         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6492         offset += 1;
6493
6494         /* andxoffset */
6495         andxoffset = tvb_get_letohs(tvb, offset);
6496         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6497         offset += 2;
6498
6499         /* fid */
6500         fid = tvb_get_letohs(tvb, offset);
6501         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
6502         offset += 2;
6503
6504         /* offset */
6505         offsetlow = tvb_get_letohl(tvb, offset);
6506         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6507         offset += 4;
6508
6509         /* max count low */
6510         maxcnt_low = tvb_get_letohs(tvb, offset);
6511         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
6512         offset += 2;
6513
6514         /* min count */
6515         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6516         offset += 2;
6517
6518         /*
6519          * max count high
6520          *
6521          * XXX - we should really only do this in case we have seen
6522          * LARGE FILE being negotiated.  Unfortunately, we might not
6523          * have seen the negotiation phase in the capture....
6524          *
6525          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
6526          * it's 32 bits, but the description says "High 16 bits of
6527          * MaxCount if CAP_LARGE_READX".
6528          *
6529          * The SMB File Sharing Protocol Extensions Version 2.0,
6530          * Document Version 3.3 spec doesn't speak of an extra 16
6531          * bits in max count, but it does show a 32-bit timeout
6532          * after the min count field.
6533          *
6534          * The Microsoft [MS-SMB] spec shows it as a ULONG named
6535          * Timeout_or_MaxCountHigh, which is
6536          *
6537          *      ...extended to be treated as a union of a 32-bit
6538          *      Timeout field and a 16-bit MaxCountHigh field.
6539          *      When reading from a regular file, the field
6540          *      MUST be interpreted as MaxCountHigh and the
6541          *      two unused bytes MUST be zero.  When reading from
6542          *      a name[sic] pipe or I/O device, the field MUST
6543          *      be interpreted as Timeout.
6544          *
6545          * Timeout is a timeout in milliseconds, with 0xffffffff
6546          * and 0xfffffffe having special meaning.
6547          *
6548          * MaxCountHigh is 16 bits of the MaxCountHigh value
6549          * followed by 16 bits of Reserved.
6550          *
6551          * We fetch and display it as 32 bits for now.
6552          *
6553          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
6554          * bytes and we just ignore it.
6555          */
6556         maxcnt_high = tvb_get_letohl(tvb, offset);
6557         if (maxcnt_high == 0xffffffff) {
6558                 maxcnt_high = 0;
6559         } else {
6560                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
6561         }
6562
6563         offset += 4;
6564
6565         maxcnt = maxcnt_high;
6566         maxcnt = (maxcnt<<16) | maxcnt_low;
6567
6568         /* remaining */
6569         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6570         offset += 2;
6571
6572         if (wc == 12) {
6573                 /* high offset */
6574                 offsethigh = tvb_get_letohl(tvb, offset);
6575                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6576                 offset += 4;
6577         }
6578
6579         ofs = offsethigh;
6580         ofs = (ofs<<32) | offsetlow;
6581
6582         col_append_fstr(pinfo->cinfo, COL_INFO,
6583                                 ", %u byte%s at offset %" G_GINT64_MODIFIER "u",
6584                                 maxcnt, (maxcnt == 1) ? "" : "s", ofs);
6585
6586         /* save the offset/len for this transaction */
6587         if (si->sip && !pinfo->fd->flags.visited) {
6588                 rwi = (rw_info_t *)wmem_alloc(wmem_file_scope(), sizeof(rw_info_t));
6589                 rwi->offset = ofs;
6590                 rwi->len = maxcnt;
6591                 rwi->fid = fid;
6592
6593                 si->sip->extra_info_type = SMB_EI_RWINFO;
6594                 si->sip->extra_info = rwi;
6595         }
6596         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6597                 rwi = (rw_info_t *)si->sip->extra_info;
6598         }
6599         if (rwi) {
6600                 proto_item *it;
6601
6602                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6603
6604                 PROTO_ITEM_SET_GENERATED(it);
6605                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6606                 PROTO_ITEM_SET_GENERATED(it);
6607         }
6608
6609         BYTE_COUNT;
6610
6611         END_OF_SMB
6612
6613         if (cmd != 0xff) {      /* there is an andX command */
6614                 if (andxoffset < offset) {
6615                         THROW(ReportedBoundsError);
6616                 }
6617                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6618         }
6619
6620         return offset;
6621 }
6622
6623 static int
6624 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6625 {
6626         guint8      wc, cmd    = 0xff;
6627         guint16     andxoffset = 0, bc, datalen_low, dataoffset = 0;
6628         guint32     datalen    = 0, datalen_high;
6629         rw_info_t  *rwi        = NULL;
6630         guint16 fid            = 0; /* was int fid = 0; */
6631
6632         guint32 tvblen;
6633
6634         DISSECTOR_ASSERT(si);
6635
6636         WORD_COUNT;
6637
6638         /* next smb command */
6639         cmd = tvb_get_guint8(tvb, offset);
6640         if (cmd != 0xff) {
6641                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6642         } else {
6643                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6644         }
6645         offset += 1;
6646
6647         /* reserved byte */
6648         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6649         offset += 1;
6650
6651         /* andxoffset */
6652         andxoffset = tvb_get_letohs(tvb, offset);
6653         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6654         offset += 2;
6655
6656         /* If we have seen the request, then print which FID this refers to */
6657         /* first check if we have seen the request */
6658         if ((si->sip != NULL) && (si->sip->frame_req > 0) && (si->sip->extra_info_type == SMB_EI_FID)) {
6659                 fid = GPOINTER_TO_INT(si->sip->extra_info);
6660                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE, si);
6661         }
6662
6663         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6664                 rwi = (rw_info_t *)si->sip->extra_info;
6665         }
6666         if (rwi) {
6667                 proto_item *it;
6668
6669                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6670
6671                 PROTO_ITEM_SET_GENERATED(it);
6672                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6673                 PROTO_ITEM_SET_GENERATED(it);
6674
6675                 /* we need the fid for the call to dcerpc below */
6676                 fid = rwi->fid;
6677         }
6678
6679         /* remaining */
6680         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6681         offset += 2;
6682
6683         /* data compaction mode */
6684         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6685         offset += 2;
6686
6687         /* 2 reserved bytes */
6688         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
6689         offset += 2;
6690
6691         /* data len low */
6692         datalen_low = tvb_get_letohs(tvb, offset);
6693         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6694         offset += 2;
6695
6696         /* data offset */
6697         dataoffset = tvb_get_letohs(tvb, offset);
6698         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6699         offset += 2;
6700
6701         /*
6702          * XXX - the SNIA SMB spec says this is a USHORT, not a
6703          * ULONG.
6704          *
6705          * XXX - we should really only do this in case we have seen
6706          * LARGE FILE being negotiated.  Unfortunately, we might not
6707          * have seen the negotiation phase in the capture....
6708          */
6709         /* data length high */
6710         datalen_high = tvb_get_letohl(tvb, offset);
6711         if (datalen_high == 0xffffffff) {
6712                 datalen_high = 0;
6713         } else {
6714                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
6715         }
6716         offset += 4;
6717
6718         datalen = datalen_high;
6719         datalen = (datalen<<16) | datalen_low;
6720
6721
6722         col_append_fstr(pinfo->cinfo, COL_INFO,
6723                                 ", %u byte%s", datalen,
6724                                 (datalen == 1) ? "" : "s");
6725
6726
6727         /* 6 reserved bytes */
6728         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, ENC_NA);
6729         offset += 6;
6730
6731         BYTE_COUNT;
6732
6733         /* file data, might be DCERPC on a pipe */
6734         if (bc) {
6735                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6736                     top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid, si);
6737                 bc = 0;
6738         }
6739
6740         /* feed the export object tap listener */
6741         tvblen = tvb_length_remaining(tvb, dataoffset);
6742         if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
6743                 feed_eo_smb(SMB_COM_READ_ANDX, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
6744         }
6745
6746         END_OF_SMB
6747
6748         if (cmd != 0xff) {   /* there is an andX command */
6749                 if (andxoffset < offset) {
6750                         THROW(ReportedBoundsError);
6751                 }
6752                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6753         }
6754
6755         return offset;
6756 }
6757
6758 static int
6759 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6760 {
6761         guint8          wc, cmd               = 0xff;
6762         guint16         andxoffset            = 0, bc, dataoffset = 0, datalen_low, datalen_high;
6763         guint32         offsetlow, offsethigh = 0;
6764         guint64         ofs;
6765         guint32         datalen               = 0;
6766         guint16 fid                           = 0; /* was unsigned int fid = 0; */
6767         guint16         mode                  = 0;
6768         rw_info_t      *rwi                   = NULL;
6769
6770         guint32         tvblen;
6771
6772         DISSECTOR_ASSERT(si);
6773
6774         WORD_COUNT;
6775
6776         /* next smb command */
6777         cmd = tvb_get_guint8(tvb, offset);
6778         if (cmd != 0xff) {
6779                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6780         } else {
6781                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6782         }
6783         offset += 1;
6784
6785         /* reserved byte */
6786         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6787         offset += 1;
6788
6789         /* andxoffset */
6790         andxoffset = tvb_get_letohs(tvb, offset);
6791         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6792         offset += 2;
6793
6794         /* fid */
6795         fid = tvb_get_letohs(tvb, offset);
6796         dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE, si);
6797         offset += 2;
6798
6799         /* offset */
6800         offsetlow = tvb_get_letohl(tvb, offset);
6801         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6802         offset += 4;
6803
6804         /* reserved */
6805         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
6806         offset += 4;
6807
6808         /* mode */
6809         mode = tvb_get_letohs(tvb, offset);
6810         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
6811
6812         /* remaining */
6813         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6814         offset += 2;
6815
6816         /*
6817          * XXX - we should really only do this in case we have seen
6818          * LARGE FILE being negotiated.  Unfortunately, we might not
6819          * have seen the negotiation phase in the capture....
6820          */
6821         /* data length high */
6822         datalen_high = tvb_get_letohs(tvb, offset);
6823         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
6824         offset += 2;
6825
6826         /* data len low */
6827         datalen_low = tvb_get_letohs(tvb, offset);
6828         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
6829         offset += 2;
6830
6831         datalen = datalen_high;
6832         datalen = (datalen<<16) | datalen_low;
6833
6834         /* data offset */
6835         dataoffset = tvb_get_letohs(tvb, offset);
6836         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
6837         offset += 2;
6838
6839         if (wc == 14) {
6840                 /* high offset */
6841                 offsethigh = tvb_get_letohl(tvb, offset);
6842                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
6843                 offset += 4;
6844         }
6845
6846         ofs = offsethigh;
6847         ofs = (ofs<<32) | offsetlow;
6848
6849         col_append_fstr(pinfo->cinfo, COL_INFO,
6850                                 ", %u byte%s at offset %" G_GINT64_MODIFIER "u",
6851                                 datalen, (datalen == 1) ? "" : "s", ofs);
6852
6853         /* save the offset/len for this transaction */
6854         if (si->sip && !pinfo->fd->flags.visited) {
6855                 rwi         = (rw_info_t *)wmem_alloc(wmem_file_scope(), sizeof(rw_info_t));
6856                 rwi->offset = ofs;
6857                 rwi->len    = datalen;
6858                 rwi->fid    = fid;
6859
6860                 si->sip->extra_info_type = SMB_EI_RWINFO;
6861                 si->sip->extra_info = rwi;
6862         }
6863         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6864                 rwi = (rw_info_t *)si->sip->extra_info;
6865         }
6866         if (rwi) {
6867                 proto_item *it;
6868
6869                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6870
6871                 PROTO_ITEM_SET_GENERATED(it);
6872                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6873                 PROTO_ITEM_SET_GENERATED(it);
6874         }
6875
6876
6877         BYTE_COUNT;
6878
6879         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
6880            the first two bytes of the payload is the length of the data.
6881            Assume that all WriteAndX PDUs that have MESSAGE_START set to
6882            be over the IPC$ share and thus they all transport DCERPC.
6883            (if we didnt already know that from the TreeConnect call)
6884         */
6885         if (mode&WRITE_MODE_MESSAGE_START) {
6886                 if (mode&WRITE_MODE_RAW) {
6887                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6888                         offset += 2;
6889                         dataoffset += 2;
6890                         bc -= 2;
6891                         datalen -= 2;
6892                 }
6893                 if (!pinfo->fd->flags.visited) {
6894                         /* In case we did not see the TreeConnect call,
6895                            store this TID here as well as a IPC TID
6896                            so we know that future Read/Writes to this
6897                            TID is (probably) DCERPC.
6898                         */
6899                         if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
6900                                 g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
6901                         }
6902                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
6903                 }
6904                 if (si->sip) {
6905                         si->sip->flags |= SMB_SIF_TID_IS_IPC;
6906                 }
6907         }
6908
6909         /* file data, might be DCERPC on a pipe */
6910         if (bc != 0) {
6911                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
6912                     top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid, si);
6913                 bc = 0;
6914         }
6915
6916         /* feed the export object tap listener */
6917         tvblen = tvb_length_remaining(tvb, dataoffset);
6918         if (have_tap_listener(smb_eo_tap) && (datalen == tvblen) && rwi) {
6919                 feed_eo_smb(SMB_COM_WRITE_ANDX, fid, tvb, pinfo, dataoffset, datalen, rwi->len, rwi->offset, si);
6920         }
6921
6922         END_OF_SMB
6923
6924         if (cmd != 0xff) {      /* there is an andX command */
6925                 if (andxoffset < offset) {
6926                         THROW(ReportedBoundsError);
6927                 }
6928                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
6929         }
6930
6931         return offset;
6932 }
6933
6934 static int
6935 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
6936 {
6937         guint8      wc, cmd    = 0xff;
6938         guint16     andxoffset = 0, bc, count_low, count_high;
6939         guint32     count      = 0;
6940         rw_info_t  *rwi        = NULL;
6941
6942         DISSECTOR_ASSERT(si);
6943
6944         WORD_COUNT;
6945
6946         /* next smb command */
6947         cmd = tvb_get_guint8(tvb, offset);
6948         if (cmd != 0xff) {
6949                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
6950         } else {
6951                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
6952         }
6953         offset += 1;
6954
6955         /* reserved byte */
6956         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
6957         offset += 1;
6958
6959         /* andxoffset */
6960         andxoffset = tvb_get_letohs(tvb, offset);
6961         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6962         offset += 2;
6963
6964
6965         if (si->sip && (si->sip->extra_info_type == SMB_EI_RWINFO)) {
6966                 rwi = (rw_info_t *)si->sip->extra_info;
6967         }
6968         if (rwi) {
6969                 proto_item *it;
6970
6971                 it = proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
6972
6973                 PROTO_ITEM_SET_GENERATED(it);
6974                 it = proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
6975                 PROTO_ITEM_SET_GENERATED(it);
6976         }
6977
6978
6979         /* write count low */
6980         count_low = tvb_get_letohs(tvb, offset);
6981         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
6982         offset += 2;
6983
6984         /* remaining */
6985         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, ENC_LITTLE_ENDIAN);
6986         offset += 2;
6987
6988         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
6989         /* write count high */
6990         count_high = tvb_get_letohs(tvb, offset);
6991         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
6992         offset += 2;
6993
6994         count = count_high;
6995         count = (count<<16) | count_low;
6996
6997         col_append_fstr(pinfo->cinfo, COL_INFO,
6998                                 ", %u byte%s", count,
6999                                 (count == 1) ? "" : "s");
7000
7001         /* 2 reserved bytes */
7002         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
7003         offset += 2;
7004
7005         BYTE_COUNT;
7006
7007         END_OF_SMB
7008
7009         if (cmd != 0xff) {      /* there is an andX command */
7010                 if (andxoffset < offset) {
7011                         THROW(ReportedBoundsError);
7012                 }
7013                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7014         }
7015
7016         return offset;
7017 }
7018
7019
7020 static const true_false_string tfs_setup_action_guest = {
7021         "Logged in as GUEST",
7022         "Not logged in as GUEST"
7023 };
7024 static int
7025 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7026 {
7027         guint16     mask;
7028         proto_item *item;
7029         proto_tree *tree;
7030
7031         mask = tvb_get_letohs(tvb, offset);
7032
7033         if (parent_tree) {
7034                 item = proto_tree_add_item(parent_tree, hf_smb_setup_action, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7035                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
7036
7037                 proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
7038                         tvb, offset, 2, mask);
7039         }
7040         offset += 2;
7041
7042         return offset;
7043 }
7044
7045
7046 static int
7047 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7048 {
7049         guint8      wc, cmd        = 0xff;
7050         guint16     bc;
7051         guint16     andxoffset     = 0;
7052         int         an_len;
7053         const char *an;
7054         int         dn_len;
7055         const char *dn;
7056         guint16     pwlen          = 0;
7057         guint16     sbloblen       = 0, sbloblen_short;
7058         guint16     apwlen         = 0, upwlen = 0;
7059         gboolean    unicodeflag;
7060         static int  ntlmssp_tap_id = 0;
7061         const ntlmssp_header_t *ntlmssph;
7062
7063         if (!ntlmssp_tap_id) {
7064                 GString *error_string;
7065                 /* We dont specify any callbacks at all.
7066                  * Instead we manually fetch the tapped data after the
7067                  * security blob has been fully dissected and before
7068                  * we exit from this dissector.
7069                  */
7070                 error_string = register_tap_listener("ntlmssp", NULL, NULL,
7071                     TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL);
7072                 if (!error_string) {
7073                         ntlmssp_tap_id = find_tap_id("ntlmssp");
7074                 } else {
7075                         g_string_free(error_string, TRUE);
7076                 }
7077         }
7078
7079         DISSECTOR_ASSERT(si);
7080
7081         WORD_COUNT;
7082
7083         /* next smb command */
7084         cmd = tvb_get_guint8(tvb, offset);
7085         if (cmd != 0xff) {
7086                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7087         } else {
7088                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7089         }
7090         offset += 1;
7091
7092         /* reserved byte */
7093         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7094         offset += 1;
7095
7096         /* andxoffset */
7097         andxoffset = tvb_get_letohs(tvb, offset);
7098         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7099         offset += 2;
7100
7101         /* Maximum Buffer Size */
7102         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7103         offset += 2;
7104
7105         /* Maximum Multiplex Count */
7106         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7107         offset += 2;
7108
7109         /* VC Number */
7110         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7111         offset += 2;
7112
7113         /* session key */
7114         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, ENC_LITTLE_ENDIAN);
7115         offset += 4;
7116
7117         switch (wc) {
7118         case 10:
7119                 /* password length, ASCII*/
7120                 pwlen = tvb_get_letohs(tvb, offset);
7121                 proto_tree_add_uint(tree, hf_smb_password_len,
7122                         tvb, offset, 2, pwlen);
7123                 offset += 2;
7124
7125                 /* 4 reserved bytes */
7126                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7127                 offset += 4;
7128
7129                 break;
7130
7131         case 12:
7132                 /* security blob length */
7133                 sbloblen = tvb_get_letohs(tvb, offset);
7134                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7135                 offset += 2;
7136
7137                 /* 4 reserved bytes */
7138                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7139                 offset += 4;
7140
7141                 /* capabilities */
7142                 dissect_negprot_capabilities(tvb, tree, offset);
7143                 offset += 4;
7144
7145                 break;
7146
7147         case 13:
7148                 /* password length, ANSI*/
7149                 apwlen = tvb_get_letohs(tvb, offset);
7150                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
7151                         tvb, offset, 2, apwlen);
7152                 offset += 2;
7153
7154                 /* password length, Unicode*/
7155                 upwlen = tvb_get_letohs(tvb, offset);
7156                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
7157                         tvb, offset, 2, upwlen);
7158                 offset += 2;
7159
7160                 /* 4 reserved bytes */
7161                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
7162                 offset += 4;
7163
7164                 /* capabilities */
7165                 dissect_negprot_capabilities(tvb, tree, offset);
7166                 offset += 4;
7167
7168                 break;
7169         }
7170
7171         BYTE_COUNT;
7172
7173         if (wc == 12) {
7174                 proto_item *blob_item;
7175
7176                 /* security blob */
7177                 /* If it runs past the end of the captured data, don't
7178                  * try to put all of it into the protocol tree as the
7179                  * raw security blob; we might get an exception on
7180                  * short frames and then we will not see anything at all
7181                  * of the security blob.
7182                  */
7183                 sbloblen_short = sbloblen;
7184                 if (sbloblen_short > tvb_length_remaining(tvb, offset)) {
7185                         sbloblen_short = tvb_length_remaining(tvb, offset);
7186                 }
7187                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7188                                                 tvb, offset, sbloblen_short,
7189                                                 ENC_NA);
7190
7191                 /* As an optimization, because Windows is perverse,
7192                    we check to see if NTLMSSP is the first part of the
7193                    blob, and if so, call the NTLMSSP dissector,
7194                    otherwise we call the GSS-API dissector. This is because
7195                    Windows can request RAW NTLMSSP, but will happily handle
7196                    a client that wraps NTLMSSP in SPNEGO
7197                 */
7198
7199                 if (sbloblen) {
7200                         tvbuff_t *blob_tvb;
7201                         proto_tree *blob_tree;
7202
7203                         blob_tree = proto_item_add_subtree(blob_item,
7204                                                            ett_smb_secblob);
7205                         CHECK_BYTE_COUNT(sbloblen);
7206
7207                         /*
7208                          * Set the reported length of this to the reported
7209                          * length of the blob, rather than the amount of
7210                          * data available from the blob, so that we'll
7211                          * throw the right exception if it's too short.
7212                          */
7213                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
7214                                                   sbloblen);
7215
7216                         if (si && si->ct && si->ct->raw_ntlmssp &&
7217                             (tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)) {
7218                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7219                                          blob_tree);
7220
7221                         }
7222                         else {
7223                           call_dissector(gssapi_handle, blob_tvb,
7224                                          pinfo, blob_tree);
7225                         }
7226
7227                         /* If we have found a uid->acct_name mapping, store it */
7228                         if (!pinfo->fd->flags.visited && si->sip) {
7229                                 int idx = 0;
7230                                 if ((ntlmssph = (const ntlmssp_header_t *)fetch_tapped_data(ntlmssp_tap_id, idx + 1 )) != NULL) {
7231                                         if (ntlmssph && (ntlmssph->type == 3)) {
7232                                                 smb_uid_t *smb_uid;
7233
7234                                                 smb_uid = (smb_uid_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_uid_t));
7235                                                 smb_uid->logged_in  = -1;
7236                                                 smb_uid->logged_out = -1;
7237                                                 smb_uid->domain  = wmem_strdup(wmem_file_scope(), ntlmssph->domain_name);
7238                                                 smb_uid->account = wmem_strdup(wmem_file_scope(), ntlmssph->acct_name);
7239
7240                                                 si->sip->extra_info = smb_uid;
7241                                                 si->sip->extra_info_type = SMB_EI_UID;
7242                                         }
7243                                 }
7244                         }
7245
7246                         COUNT_BYTES(sbloblen);
7247                 }
7248
7249                 /* OS
7250                  * Eventhough this field should honour the unicode flag
7251                  * some ms clients gets this wrong.
7252                  * At least XP SP1 sends this in ASCII
7253                  * even when the unicode flag is on.
7254                  * Test if the first three bytes are "Win"
7255                  * and if so just override the flag.
7256                  */
7257                 unicodeflag = si->unicode;
7258                 if ( tvb_strneql(tvb, offset, "Win", 3) == 0 ) {
7259                         unicodeflag = FALSE;
7260                 }
7261                 an = get_unicode_or_ascii_string(tvb, &offset,
7262                         unicodeflag, &an_len, FALSE, FALSE, &bc);
7263                 if (an == NULL)
7264                         goto endofcommand;
7265                 proto_tree_add_string(tree, hf_smb_os, tvb,
7266                         offset, an_len, an);
7267                 COUNT_BYTES(an_len);
7268
7269                 /* LANMAN */
7270                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7271                  * padding/null string/whatever in front of this. W2K doesn't
7272                  * appear to. I suspect that's a bug that got fixed; I also
7273                  * suspect that, in practice, nobody ever looks at that field
7274                  * because the bug didn't appear to get fixed until NT 5.0....
7275                  *
7276                  * Eventhough this field should honour the unicode flag
7277                  * some ms clients gets this wrong.
7278                  * At least XP SP1 sends this in ASCII
7279                  * even when the unicode flag is on.
7280                  * Test if the first three bytes are "Win"
7281                  * and if so just override the flag.
7282                  */
7283                 unicodeflag = si->unicode;
7284                 if ( tvb_strneql(tvb, offset, "Win", 3) == 0 ) {
7285                         unicodeflag = FALSE;
7286                 }
7287                 an = get_unicode_or_ascii_string(tvb, &offset,
7288                         unicodeflag, &an_len, FALSE, FALSE, &bc);
7289                 if (an == NULL)
7290                         goto endofcommand;
7291                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7292                         offset, an_len, an);
7293                 COUNT_BYTES(an_len);
7294
7295                 /* Primary domain */
7296                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
7297                  * byte in front of this, at least if all the strings are
7298                  * ASCII and the account name is empty. Another bug?
7299                  */
7300                 dn = get_unicode_or_ascii_string(tvb, &offset,
7301                         si->unicode, &dn_len, FALSE, FALSE, &bc);
7302                 if (dn == NULL)
7303                         goto endofcommand;
7304                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7305                         offset, dn_len, dn);
7306                 COUNT_BYTES(dn_len);
7307         } else {
7308                 switch (wc) {
7309
7310                 case 10:
7311                         if (pwlen) {
7312                                 /* password, ASCII */
7313                                 CHECK_BYTE_COUNT(pwlen);
7314                                 proto_tree_add_item(tree, hf_smb_password,
7315                                         tvb, offset, pwlen, ENC_NA);
7316                                 COUNT_BYTES(pwlen);
7317                         }
7318
7319                         break;
7320
7321                 case 13:
7322                         if (apwlen) {
7323                                 /* password, ANSI */
7324                                 CHECK_BYTE_COUNT(apwlen);
7325                                 proto_tree_add_item(tree, hf_smb_ansi_password,
7326                                         tvb, offset, apwlen, ENC_NA);
7327                                 COUNT_BYTES(apwlen);
7328                         }
7329
7330                         if (upwlen) {
7331                                 proto_item *item;
7332
7333                                 /* password, Unicode */
7334                                 CHECK_BYTE_COUNT(upwlen);
7335                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
7336                                         tvb, offset, upwlen, ENC_NA);
7337
7338                                 if (upwlen > 24) {
7339                                         proto_tree *subtree;
7340                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
7341                                         dissect_ntlmv2_response(tvb, pinfo, subtree, offset, upwlen);
7342                                 }
7343
7344                                 COUNT_BYTES(upwlen);
7345                         }
7346
7347                         break;
7348                 }
7349
7350                 /* Account Name */
7351                 an = get_unicode_or_ascii_string(tvb, &offset,
7352                         si->unicode, &an_len, FALSE, FALSE, &bc);
7353                 if (an == NULL)
7354                         goto endofcommand;
7355                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
7356                         an);
7357                 COUNT_BYTES(an_len);
7358
7359                 /* Primary domain */
7360                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
7361                  * byte in front of this, at least if all the strings are
7362                  * ASCII and the account name is empty. Another bug?
7363                  */
7364                 dn = get_unicode_or_ascii_string(tvb, &offset,
7365                         si->unicode, &dn_len, FALSE, FALSE, &bc);
7366                 if (dn == NULL)
7367                         goto endofcommand;
7368                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7369                         offset, dn_len, dn);
7370                 COUNT_BYTES(dn_len);
7371
7372                 col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
7373
7374                 if (!dn[0] && !an[0])
7375                         col_append_str(pinfo->cinfo, COL_INFO, "anonymous");
7376                 else
7377                         col_append_fstr(pinfo->cinfo, COL_INFO,
7378                                         "%s\\%s",
7379                                         format_text(dn, strlen(dn)),
7380                                         format_text(an, strlen(an)));
7381
7382                 /* OS */
7383                 an = get_unicode_or_ascii_string(tvb, &offset,
7384                         si->unicode, &an_len, FALSE, FALSE, &bc);
7385                 if (an == NULL)
7386                         goto endofcommand;
7387                 proto_tree_add_string(tree, hf_smb_os, tvb,
7388                         offset, an_len, an);
7389                 COUNT_BYTES(an_len);
7390
7391                 /* LANMAN */
7392                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
7393                  * padding/null string/whatever in front of this. W2K doesn't
7394                  * appear to. I suspect that's a bug that got fixed; I also
7395                  * suspect that, in practice, nobody ever looks at that field
7396                  * because the bug didn't appear to get fixed until NT 5.0....
7397                  */
7398                 an = get_unicode_or_ascii_string(tvb, &offset,
7399                         si->unicode, &an_len, FALSE, FALSE, &bc);
7400                 if (an == NULL)
7401                         goto endofcommand;
7402                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
7403                         offset, an_len, an);
7404                 COUNT_BYTES(an_len);
7405         }
7406
7407         END_OF_SMB
7408
7409         if (cmd != 0xff) {      /* there is an andX command */
7410                 if (andxoffset < offset) {
7411                         THROW(ReportedBoundsError);
7412                 }
7413                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7414         }
7415
7416         return offset;
7417 }
7418
7419 static int
7420 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7421 {
7422         guint8      wc, cmd    = 0xff;
7423         guint16     andxoffset = 0, bc;
7424         guint16     sbloblen   = 0;
7425         int         an_len;
7426         const char *an;
7427
7428         DISSECTOR_ASSERT(si);
7429
7430         WORD_COUNT;
7431
7432         if (!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
7433             (si->sip->extra_info_type == SMB_EI_UID)) {
7434                 smb_uid_t *smb_uid;
7435
7436                 smb_uid = (smb_uid_t *)si->sip->extra_info;
7437                 smb_uid->logged_in = pinfo->fd->num;
7438                 wmem_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
7439         }
7440
7441         /* next smb command */
7442         cmd = tvb_get_guint8(tvb, offset);
7443         if (cmd != 0xff) {
7444                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7445         } else {
7446                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7447         }
7448         offset += 1;
7449
7450         /* reserved byte */
7451         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7452         offset += 1;
7453
7454         /* andxoffset */
7455         andxoffset = tvb_get_letohs(tvb, offset);
7456         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7457         offset += 2;
7458
7459         /* flags */
7460         offset = dissect_setup_action(tvb, tree, offset);
7461
7462         if (wc == 4) {
7463                 /* security blob length */
7464                 sbloblen = tvb_get_letohs(tvb, offset);
7465                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
7466                 offset += 2;
7467         }
7468
7469         BYTE_COUNT;
7470
7471         if (wc == 4) {
7472                 proto_item *blob_item;
7473
7474                 /* security blob */
7475                 /* dont try to eat too much of we might get an exception on
7476                  * short frames and then we will not see anything at all
7477                  * of the security blob.
7478                  */
7479                 if (sbloblen > tvb_length_remaining(tvb, offset)) {
7480                         sbloblen = tvb_length_remaining(tvb, offset);
7481                 }
7482                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
7483                                                 tvb, offset, sbloblen, ENC_NA);
7484
7485                 if (sbloblen) {
7486                         tvbuff_t *blob_tvb;
7487                         proto_tree *blob_tree;
7488
7489                         blob_tree = proto_item_add_subtree(blob_item,
7490                                                            ett_smb_secblob);
7491                         CHECK_BYTE_COUNT(sbloblen);
7492
7493                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen,
7494                                                     sbloblen);
7495
7496                         if (si && si->ct && si->ct->raw_ntlmssp &&
7497                             (tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0)) {
7498                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
7499                                          blob_tree);
7500
7501                         }
7502                         else {
7503                           call_dissector(gssapi_handle, blob_tvb, pinfo,
7504                                          blob_tree);
7505
7506                         }
7507
7508                         COUNT_BYTES(sbloblen);
7509                 }
7510         }
7511
7512         /* OS */
7513         an = get_unicode_or_ascii_string(tvb, &offset,
7514                 si->unicode, &an_len, FALSE, FALSE, &bc);
7515         if (an == NULL)
7516                 goto endofcommand;
7517         proto_tree_add_string(tree, hf_smb_os, tvb,
7518                 offset, an_len, an);
7519         COUNT_BYTES(an_len);
7520
7521         /* LANMAN */
7522         an = get_unicode_or_ascii_string(tvb, &offset,
7523                 si->unicode, &an_len, FALSE, FALSE, &bc);
7524         if (an == NULL)
7525                 goto endofcommand;
7526         proto_tree_add_string(tree, hf_smb_lanman, tvb,
7527                 offset, an_len, an);
7528         COUNT_BYTES(an_len);
7529
7530         if ((wc == 3) || (wc == 4)) {
7531                 /* Primary domain */
7532                 an = get_unicode_or_ascii_string(tvb, &offset,
7533                         si->unicode, &an_len, FALSE, FALSE, &bc);
7534                 if (an == NULL)
7535                         goto endofcommand;
7536                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
7537                         offset, an_len, an);
7538                 COUNT_BYTES(an_len);
7539         }
7540
7541         END_OF_SMB
7542
7543         if (cmd != 0xff) {      /* there is an andX command */
7544                 if (andxoffset < offset) {
7545                         THROW(ReportedBoundsError);
7546                 }
7547                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7548         }
7549
7550         return offset;
7551 }
7552
7553
7554 static int
7555 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si _U_)
7556 {
7557         guint8  wc, cmd    = 0xff;
7558         guint16 andxoffset = 0;
7559         guint16 bc;
7560
7561         WORD_COUNT;
7562
7563         /* next smb command */
7564         cmd = tvb_get_guint8(tvb, offset);
7565         if (cmd != 0xff) {
7566                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7567         } else {
7568                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7569         }
7570         offset += 1;
7571
7572         /* reserved byte */
7573         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7574         offset += 1;
7575
7576         /* andxoffset */
7577         andxoffset = tvb_get_letohs(tvb, offset);
7578         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7579         offset += 2;
7580
7581         BYTE_COUNT;
7582
7583         END_OF_SMB
7584
7585         if (cmd != 0xff) {      /* there is an andX command */
7586                 if (andxoffset < offset) {
7587                         THROW(ReportedBoundsError);
7588                 }
7589                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7590         }
7591
7592         return offset;
7593 }
7594
7595         /*
7596          * From [MS-SMB] - v20100711 Server Message Block (SMB) Protocol Specification
7597          * http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-SMB%5D.pdf
7598          * 2.2.4.7 SMB_COM_TREE_CONNECT_ANDX (0x75)
7599          */
7600
7601 static const true_false_string tfs_connect_support_search = {
7602         "Exclusive search bits supported",
7603         "Exclusive search bits not supported"
7604 };
7605 static const true_false_string tfs_connect_support_in_dfs = {
7606         "Share is in Dfs",
7607         "Share isn't in Dfs"
7608 };
7609 static const value_string connect_support_csc_mask_vals[] = {
7610         { 0,    "Automatic file-to-file reintegration NOT permitted"},
7611         { 1,    "Automatic file-to-file reintegration permitted"},
7612         { 2,    "Offline caching allow for the share"},
7613         { 3,    "Offline caching NOT allow for the share"},
7614         {0, NULL}
7615 };
7616 static const true_false_string tfs_connect_support_uniquefilename = {
7617         "Client allow to cache share namespaces",
7618         "Client NOT allow to cache share namespaces"
7619 };
7620 static const true_false_string tfs_connect_support_extended_signature = {
7621         "Extended signature",
7622         "NOT extended signature"
7623 };
7624
7625 static int
7626 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7627 {
7628         guint16     mask;
7629         proto_item *item;
7630         proto_tree *tree;
7631
7632         mask = tvb_get_letohs(tvb, offset);
7633
7634         if (parent_tree) {
7635                 item = proto_tree_add_item(parent_tree, hf_smb_connect_support, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7636                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
7637
7638                 proto_tree_add_boolean(tree, hf_smb_connect_support_search,
7639                         tvb, offset, 2, mask);
7640                 proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
7641                         tvb, offset, 2, mask);
7642                 proto_tree_add_uint(tree, hf_smb_connect_support_csc_mask_vals,
7643                         tvb, offset, 2, mask);
7644                 proto_tree_add_boolean(tree, hf_smb_connect_support_uniquefilename,
7645                         tvb, offset, 2, mask);
7646                 proto_tree_add_boolean(tree, hf_smb_connect_support_extended_signature,
7647                         tvb, offset, 2, mask);
7648         }
7649
7650         offset += 2;
7651
7652         return offset;
7653 }
7654
7655 static const true_false_string tfs_disconnect_tid = {
7656         "DISCONNECT TID",
7657         "Do NOT disconnect TID"
7658 };
7659
7660 static const true_false_string tfs_extended_signature = {
7661         "Extended Signature",
7662         "NOT Extended Signature"
7663 };
7664
7665 static const true_false_string tfs_extended_response = {
7666         "Extended Response",
7667         "NOT Extended Response"
7668 };
7669
7670 static int
7671 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7672 {
7673         guint16     mask;
7674         proto_item *item;
7675         proto_tree *tree;
7676
7677         mask = tvb_get_letohs(tvb, offset);
7678
7679         if (parent_tree) {
7680                 item = proto_tree_add_item(parent_tree, hf_smb_connect_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
7681                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
7682
7683                 proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
7684                         tvb, offset, 2, mask);
7685                 proto_tree_add_boolean(tree, hf_smb_connect_flags_ext_sig,
7686                         tvb, offset, 2, mask);
7687                 proto_tree_add_boolean(tree, hf_smb_connect_flags_ext_resp,
7688                         tvb, offset, 2, mask);
7689         }
7690
7691         offset += 2;
7692
7693         return offset;
7694 }
7695
7696 static int
7697 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7698 {
7699         guint8      wc, cmd    = 0xff;
7700         guint16     bc;
7701         guint16     andxoffset = 0, pwlen = 0;
7702         int         an_len;
7703         const char *an;
7704
7705         DISSECTOR_ASSERT(si);
7706
7707         WORD_COUNT;
7708
7709         /* next smb command */
7710         cmd = tvb_get_guint8(tvb, offset);
7711         if (cmd != 0xff) {
7712                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7713         } else {
7714                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7715         }
7716         offset += 1;
7717
7718         /* reserved byte */
7719         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7720         offset += 1;
7721
7722         /* andxoffset */
7723         andxoffset = tvb_get_letohs(tvb, offset);
7724         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7725         offset += 2;
7726
7727         /* flags */
7728         offset = dissect_connect_flags(tvb, tree, offset);
7729
7730         /* password length*/
7731         pwlen = tvb_get_letohs(tvb, offset);
7732         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
7733         offset += 2;
7734
7735         BYTE_COUNT;
7736
7737         /* password */
7738         CHECK_BYTE_COUNT(pwlen);
7739         proto_tree_add_item(tree, hf_smb_password,
7740                 tvb, offset, pwlen, ENC_NA);
7741         COUNT_BYTES(pwlen);
7742
7743         /* Path */
7744         an = get_unicode_or_ascii_string(tvb, &offset,
7745                 si->unicode, &an_len, FALSE, FALSE, &bc);
7746         if (an == NULL)
7747                 goto endofcommand;
7748         proto_tree_add_string(tree, hf_smb_path, tvb,
7749                 offset, an_len, an);
7750         COUNT_BYTES(an_len);
7751
7752         /* store it for the tid->name/openframe/closeframe matching in
7753          * dissect_smb_tid()   called from the response.
7754          */
7755         if ((!pinfo->fd->flags.visited) && si->sip && an) {
7756                 si->sip->extra_info_type = SMB_EI_TIDNAME;
7757                 si->sip->extra_info = wmem_strdup(wmem_file_scope(), an);
7758         }
7759
7760         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
7761                     format_text(an, strlen(an)));
7762
7763         /*
7764          * NOTE: the Service string is always ASCII, even if the
7765          * "strings are Unicode" bit is set in the flags2 field
7766          * of the SMB.
7767          */
7768
7769         /* Service */
7770         /* XXX - what if this runs past bc? */
7771         an_len = tvb_strsize(tvb, offset);
7772         CHECK_BYTE_COUNT(an_len);
7773         an = tvb_get_string(wmem_packet_scope(), tvb, offset, an_len);
7774         proto_tree_add_string(tree, hf_smb_service, tvb,
7775                 offset, an_len, an);
7776         COUNT_BYTES(an_len);
7777
7778         END_OF_SMB
7779
7780         if (cmd != 0xff) {      /* there is an andX command */
7781                 if (andxoffset < offset) {
7782                         THROW(ReportedBoundsError);
7783                 }
7784                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7785         }
7786
7787         return offset;
7788 }
7789
7790
7791 static int
7792 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
7793 {
7794         guint8      wc, wleft, cmd = 0xff;
7795         guint16     andxoffset     = 0;
7796         guint16     bc;
7797         int         an_len;
7798         int         count          = 0;
7799         proto_item *it             = NULL;
7800         proto_tree *tr             = NULL;
7801         const char *an;
7802
7803         DISSECTOR_ASSERT(si);
7804
7805         WORD_COUNT;
7806
7807         wleft = wc;     /* this is at least 1 */
7808
7809         /* next smb command */
7810         cmd = tvb_get_guint8(tvb, offset);
7811         if (cmd != 0xff) {
7812                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
7813         } else {
7814                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
7815         }
7816         offset += 1;
7817
7818         /* reserved byte */
7819         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
7820         offset += 1;
7821
7822         wleft--;
7823         if (wleft == 0)
7824                 goto bytecount;
7825
7826         /* andxoffset */
7827         andxoffset = tvb_get_letohs(tvb, offset);
7828         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7829         offset += 2;
7830         wleft--;
7831         if (wleft == 0)
7832                 goto bytecount;
7833
7834         /* flags */
7835         offset = dissect_connect_support_bits(tvb, tree, offset);
7836         wleft--;
7837
7838         /* XXX - I've seen captures where this is 7, but I have no
7839            idea how to dissect it.  I'm guessing the third word
7840            contains connect support bits, which looks plausible
7841            from the values I've seen. */
7842
7843         /* MaximalShareAccessRights and GuestMaximalShareAccessRights */
7844         while (wleft != 0) {
7845                 /*
7846                  * Refer to [MS-SMB] - v20100711
7847                  * When a server returns extended information, the response
7848                  * takes the following format, with WordCount = 7.
7849                  * MaximalShareAccessRights, and GuestMaximalShareAccessRights fields
7850                  * has added.
7851                  */
7852                 if (count == 0) {
7853                         it = proto_tree_add_text(tree, tvb, offset, 4,
7854                                 "Maximal Share Access Rights");
7855                 } else {
7856                         it = proto_tree_add_text(tree, tvb, offset, 4,
7857                                 "Guest Maximal Share Access Rights");
7858                 }
7859                 tr = proto_item_add_subtree(it, ett_smb_nt_access_mask);
7860
7861                 offset = dissect_smb_access_mask(tvb, tr, offset);
7862                 wleft -= 2;
7863                 count++;
7864         }
7865
7866         BYTE_COUNT;
7867
7868         /*
7869          * NOTE: even though the SNIA CIFS spec doesn't say there's
7870          * a "Service" string if there's a word count of 2, the
7871          * document at
7872          *
7873          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
7874          *
7875          * (it's in an ugly format - text intended to be sent to a
7876          * printer, with backspaces and overstrikes used for boldfacing
7877          * and underlining; UNIX "col -b" can be used to strip the
7878          * overstrikes out) says there's a "Service" string there, and
7879          * some network traffic has it.
7880          */
7881
7882         /*
7883          * NOTE: the Service string is always ASCII, even if the
7884          * "strings are Unicode" bit is set in the flags2 field
7885          * of the SMB.
7886          */
7887
7888         /* Service */
7889         /* XXX - what if this runs past bc? */
7890         an_len = tvb_strsize(tvb, offset);
7891         CHECK_BYTE_COUNT(an_len);
7892         an = tvb_get_string(wmem_packet_scope(), tvb, offset, an_len);
7893         proto_tree_add_string(tree, hf_smb_service, tvb,
7894                 offset, an_len, an);
7895         COUNT_BYTES(an_len);
7896
7897         /* Now when we know the service type, store it so that we know it for later commands down
7898            this tree */
7899         if (!pinfo->fd->flags.visited) {
7900                 /* Remove any previous entry for this TID */
7901                 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
7902                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
7903                 }
7904                 if (strcmp(an, "IPC") == 0) {
7905                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
7906                 } else {
7907                         g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_NORMAL);
7908                 }
7909         }
7910
7911
7912         if (wc == 3) {
7913                 if (bc != 0) {
7914                         /*
7915                          * Sometimes this isn't present.
7916                          */
7917
7918                         /* Native FS */
7919                         an = get_unicode_or_ascii_string(tvb, &offset,
7920                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
7921                                 &bc);
7922                         if (an == NULL)
7923                                 goto endofcommand;
7924                         proto_tree_add_string(tree, hf_smb_fs, tvb,
7925                                 offset, an_len, an);
7926                         COUNT_BYTES(an_len);
7927                 }
7928         }
7929
7930         END_OF_SMB
7931
7932         if (cmd != 0xff) {      /* there is an andX command */
7933                 if (andxoffset < offset) {
7934                         THROW(ReportedBoundsError);
7935                 }
7936                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
7937         }
7938
7939         return offset;
7940 }
7941
7942
7943
7944 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7945    NT Transaction command  begins here
7946    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7947 #define NT_TRANS_CREATE         1
7948 #define NT_TRANS_IOCTL          2
7949 #define NT_TRANS_SSD            3
7950 #define NT_TRANS_NOTIFY         4
7951 #define NT_TRANS_RENAME         5
7952 #define NT_TRANS_QSD            6
7953 #define NT_TRANS_GET_USER_QUOTA 7
7954 #define NT_TRANS_SET_USER_QUOTA 8
7955 static const value_string nt_cmd_vals[] = {
7956         {NT_TRANS_CREATE,               "NT CREATE"},
7957         {NT_TRANS_IOCTL,                "NT IOCTL"},
7958         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
7959         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
7960         {NT_TRANS_RENAME,               "NT RENAME"},
7961         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
7962         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
7963         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
7964         {0, NULL}
7965 };
7966 value_string_ext nt_cmd_vals_ext = VALUE_STRING_EXT_INIT(nt_cmd_vals);
7967
7968 static const value_string nt_ioctl_isfsctl_vals[] = {
7969         {0,     "Device IOCTL"},
7970         {1,     "FS control : FSCTL"},
7971         {0, NULL}
7972 };
7973
7974 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
7975 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
7976         "Apply the command to share root handle (MUST BE Dfs)",
7977         "Apply to this share",
7978 };
7979
7980 static const value_string nt_notify_action_vals[] = {
7981         {1,     "ADDED (object was added"},
7982         {2,     "REMOVED (object was removed)"},
7983         {3,     "MODIFIED (object was modified)"},
7984         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
7985         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
7986         {6,     "ADDED_STREAM (a stream was added)"},
7987         {7,     "REMOVED_STREAM (a stream was removed)"},
7988         {8,     "MODIFIED_STREAM (a stream was modified)"},
7989         {0, NULL}
7990 };
7991
7992 static const value_string watch_tree_vals[] = {
7993         {0,     "Current directory only"},
7994         {1,     "Subdirectories also"},
7995         {0, NULL}
7996 };
7997
7998 #define NT_NOTIFY_STREAM_WRITE  0x00000800
7999 #define NT_NOTIFY_STREAM_SIZE   0x00000400
8000 #define NT_NOTIFY_STREAM_NAME   0x00000200
8001 #define NT_NOTIFY_SECURITY      0x00000100
8002 #define NT_NOTIFY_EA            0x00000080
8003 #define NT_NOTIFY_CREATION      0x00000040
8004 #define NT_NOTIFY_LAST_ACCESS   0x00000020
8005 #define NT_NOTIFY_LAST_WRITE    0x00000010
8006 #define NT_NOTIFY_SIZE          0x00000008
8007 #define NT_NOTIFY_ATTRIBUTES    0x00000004
8008 #define NT_NOTIFY_DIR_NAME      0x00000002
8009 #define NT_NOTIFY_FILE_NAME     0x00000001
8010 static const true_false_string tfs_nt_notify_stream_write = {
8011         "Notify on changes to STREAM WRITE",
8012         "Do NOT notify on changes to stream write",
8013 };
8014 static const true_false_string tfs_nt_notify_stream_size = {
8015         "Notify on changes to STREAM SIZE",
8016         "Do NOT notify on changes to stream size",
8017 };
8018 static const true_false_string tfs_nt_notify_stream_name = {
8019         "Notify on changes to STREAM NAME",
8020         "Do NOT notify on changes to stream name",
8021 };
8022 static const true_false_string tfs_nt_notify_security = {
8023         "Notify on changes to SECURITY",
8024         "Do NOT notify on changes to security",
8025 };
8026 static const true_false_string tfs_nt_notify_ea = {
8027         "Notify on changes to EA",
8028         "Do NOT notify on changes to EA",
8029 };
8030 static const true_false_string tfs_nt_notify_creation = {
8031         "Notify on changes to CREATION TIME",
8032         "Do NOT notify on changes to creation time",
8033 };
8034 static const true_false_string tfs_nt_notify_last_access = {
8035         "Notify on changes to LAST ACCESS TIME",
8036         "Do NOT notify on changes to last access time",
8037 };
8038 static const true_false_string tfs_nt_notify_last_write = {
8039         "Notify on changes to LAST WRITE TIME",
8040         "Do NOT notify on changes to last write time",
8041 };
8042 static const true_false_string tfs_nt_notify_size = {
8043         "Notify on changes to SIZE",
8044         "Do NOT notify on changes to size",
8045 };
8046 static const true_false_string tfs_nt_notify_attributes = {
8047         "Notify on changes to ATTRIBUTES",
8048         "Do NOT notify on changes to attributes",
8049 };
8050 static const true_false_string tfs_nt_notify_dir_name = {
8051         "Notify on changes to DIR NAME",
8052         "Do NOT notify on changes to dir name",
8053 };
8054 static const true_false_string tfs_nt_notify_file_name = {
8055         "Notify on changes to FILE NAME",
8056         "Do NOT notify on changes to file name",
8057 };
8058
8059 const value_string create_disposition_vals[] = {
8060         {0,     "Supersede (supersede existing file (if it exists))"},
8061         {1,     "Open (if file exists open it, else fail)"},
8062         {2,     "Create (if file exists fail, else create it)"},
8063         {3,     "Open If (if file exists open it, else create it)"},
8064         {4,     "Overwrite (if file exists overwrite, else fail)"},
8065         {5,     "Overwrite If (if file exists overwrite, else create it)"},
8066         {0, NULL}
8067 };
8068
8069 const value_string impersonation_level_vals[] = {
8070         {0,     "Anonymous"},
8071         {1,     "Identification"},
8072         {2,     "Impersonation"},
8073         {3,     "Delegation"},
8074         {0, NULL}
8075 };
8076
8077 static const true_false_string tfs_nt_security_flags_context_tracking = {
8078         "Security tracking mode is DYNAMIC",
8079         "Security tracking mode is STATIC",
8080 };
8081
8082 static const true_false_string tfs_nt_security_flags_effective_only = {
8083         "ONLY ENABLED aspects of the client's security context are available",
8084         "ALL aspects of the client's security context are available",
8085 };
8086
8087 static const true_false_string tfs_nt_create_bits_oplock = {
8088         "Requesting OPLOCK",
8089         "Does NOT request oplock"
8090 };
8091
8092 static const true_false_string tfs_nt_create_bits_boplock = {
8093         "Requesting BATCH OPLOCK",
8094         "Does NOT request batch oplock"
8095 };
8096
8097 /*
8098  * XXX - must be a directory, and can be a file, or can be a directory,
8099  * and must be a file?
8100  */
8101 static const true_false_string tfs_nt_create_bits_dir = {
8102         "Target of open MUST be a DIRECTORY",
8103         "Target of open can be a file"
8104 };
8105
8106 static const true_false_string tfs_nt_create_bits_ext_resp = {
8107         "Extended responses required",
8108         "Extended responses NOT required"
8109 };
8110
8111 static const true_false_string tfs_nt_access_mask_generic_read = {
8112         "GENERIC READ is set",
8113         "Generic read is NOT set"
8114 };
8115 static const true_false_string tfs_nt_access_mask_generic_write = {
8116         "GENERIC WRITE is set",
8117         "Generic write is NOT set"
8118 };
8119 static const true_false_string tfs_nt_access_mask_generic_execute = {
8120         "GENERIC EXECUTE is set",
8121         "Generic execute is NOT set"
8122 };
8123 static const true_false_string tfs_nt_access_mask_generic_all = {
8124         "GENERIC ALL is set",
8125         "Generic all is NOT set"
8126 };
8127 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
8128         "MAXIMUM ALLOWED is set",
8129         "Maximum allowed is NOT set"
8130 };
8131 static const true_false_string tfs_nt_access_mask_system_security = {
8132         "SYSTEM SECURITY is set",
8133         "System security is NOT set"
8134 };
8135 static const true_false_string tfs_nt_access_mask_synchronize = {
8136         "Can wait on handle to SYNCHRONIZE on completion of I/O",
8137         "Can NOT wait on handle to synchronize on completion of I/O"
8138 };
8139 static const true_false_string tfs_nt_access_mask_write_owner = {
8140         "Can WRITE OWNER (take ownership)",
8141         "Can NOT write owner (take ownership)"
8142 };
8143 static const true_false_string tfs_nt_access_mask_write_dac = {
8144         "OWNER may WRITE the DAC",
8145         "Owner may NOT write to the DAC"
8146 };
8147 static const true_false_string tfs_nt_access_mask_read_control = {
8148         "READ ACCESS to owner, group and ACL of the SID",
8149         "Read access is NOT granted to owner, group and ACL of the SID"
8150 };
8151 static const true_false_string tfs_nt_access_mask_delete = {
8152         "DELETE access",
8153         "NO delete access"
8154 };
8155 static const true_false_string tfs_nt_access_mask_write_attributes = {
8156         "WRITE ATTRIBUTES access",
8157         "NO write attributes access"
8158 };
8159 static const true_false_string tfs_nt_access_mask_read_attributes = {
8160         "READ ATTRIBUTES access",
8161         "NO read attributes access"
8162 };
8163 static const true_false_string tfs_nt_access_mask_delete_child = {
8164         "DELETE CHILD access",
8165         "NO delete child access"
8166 };
8167 static const true_false_string tfs_nt_access_mask_execute = {
8168         "EXECUTE access",
8169         "NO execute access"
8170 };
8171 static const true_false_string tfs_nt_access_mask_write_ea = {
8172         "WRITE EXTENDED ATTRIBUTES access",
8173         "NO write extended attributes access"
8174 };
8175 static const true_false_string tfs_nt_access_mask_read_ea = {
8176         "READ EXTENDED ATTRIBUTES access",
8177         "NO read extended attributes access"
8178 };
8179 static const true_false_string tfs_nt_access_mask_append = {
8180         "APPEND access",
8181         "NO append access"
8182 };
8183 static const true_false_string tfs_nt_access_mask_write = {
8184         "WRITE access",
8185         "NO write access"
8186 };
8187 static const true_false_string tfs_nt_access_mask_read = {
8188         "READ access",
8189         "NO read access"
8190 };
8191
8192 static const true_false_string tfs_nt_share_access_delete = {
8193         "Object can be shared for DELETE",
8194         "Object can NOT be shared for delete"
8195 };
8196 static const true_false_string tfs_nt_share_access_write = {
8197         "Object can be shared for WRITE",
8198         "Object can NOT be shared for write"
8199 };
8200 static const true_false_string tfs_nt_share_access_read = {
8201         "Object can be shared for READ",
8202         "Object can NOT be shared for read"
8203 };
8204
8205 static const value_string oplock_level_vals[] = {
8206         {0,     "No oplock granted"},
8207         {1,     "Exclusive oplock granted"},
8208         {2,     "Batch oplock granted"},
8209         {3,     "Level II oplock granted"},
8210         {0, NULL}
8211 };
8212
8213 static const value_string device_type_vals[] = {
8214         {0x00000001,    "Beep"},
8215         {0x00000002,    "CDROM"},
8216         {0x00000003,    "CDROM Filesystem"},
8217         {0x00000004,    "Controller"},
8218         {0x00000005,    "Datalink"},
8219         {0x00000006,    "Dfs"},
8220         {0x00000007,    "Disk"},
8221         {0x00000008,    "Disk Filesystem"},
8222         {0x00000009,    "Filesystem"},
8223         {0x0000000a,    "Inport Port"},
8224         {0x0000000b,    "Keyboard"},
8225         {0x0000000c,    "Mailslot"},
8226         {0x0000000d,    "MIDI-In"},
8227         {0x0000000e,    "MIDI-Out"},
8228         {0x0000000f,    "Mouse"},
8229         {0x00000010,    "Multi UNC Provider"},
8230         {0x00000011,    "Named Pipe"},
8231         {0x00000012,    "Network"},
8232         {0x00000013,    "Network Browser"},
8233         {0x00000014,    "Network Filesystem"},
8234         {0x00000015,    "NULL"},
8235         {0x00000016,    "Parallel Port"},
8236         {0x00000017,    "Physical card"},
8237         {0x00000018,    "Printer"},
8238         {0x00000019,    "Scanner"},
8239         {0x0000001a,    "Serial Mouse port"},
8240         {0x0000001b,    "Serial port"},
8241         {0x0000001c,    "Screen"},
8242         {0x0000001d,    "Sound"},
8243         {0x0000001e,    "Streams"},
8244         {0x0000001f,    "Tape"},
8245         {0x00000020,    "Tape Filesystem"},
8246         {0x00000021,    "Transport"},
8247         {0x00000022,    "Unknown"},
8248         {0x00000023,    "Video"},
8249         {0x00000024,    "Virtual Disk"},
8250         {0x00000025,    "WAVE-In"},
8251         {0x00000026,    "WAVE-Out"},
8252         {0x00000027,    "8042 Port"},
8253         {0x00000028,    "Network Redirector"},
8254         {0x00000029,    "Battery"},
8255         {0x0000002a,    "Bus Extender"},
8256         {0x0000002b,    "Modem"},
8257         {0x0000002c,    "VDM"},
8258         {0,     NULL}
8259 };
8260 static value_string_ext device_type_vals_ext = VALUE_STRING_EXT_INIT(device_type_vals);
8261
8262 static const value_string is_directory_vals[] = {
8263         {0,     "This is NOT a directory"},
8264         {1,     "This is a DIRECTORY"},
8265         {0, NULL}
8266 };
8267
8268 typedef struct _nt_trans_data {
8269         int     subcmd;
8270         guint32 sd_len;
8271         guint32 ea_len;
8272 } nt_trans_data;
8273
8274
8275
8276 static int
8277 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8278 {
8279         guint8      mask;
8280         proto_item *item;
8281         proto_tree *tree;
8282
8283         mask = tvb_get_guint8(tvb, offset);
8284
8285         if (parent_tree) {
8286                 item = proto_tree_add_item(parent_tree, hf_smb_nt_security_flags, tvb, offset, 1, ENC_NA);
8287                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
8288
8289                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
8290                         tvb, offset, 1, mask);
8291                 proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
8292                         tvb, offset, 1, mask);
8293         }
8294
8295         offset += 1;
8296
8297         return offset;
8298 }
8299
8300 /*
8301  * XXX - there are some more flags in the description of "ZwOpenFile()"
8302  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
8303  * the wire as well?  (The spec at
8304  *
8305  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
8306  *
8307  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
8308  * via the SMB protocol.  The NT redirector should convert this option
8309  * to FILE_WRITE_THROUGH."
8310  *
8311  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
8312  * values one would infer from their position in the list of flags for
8313  * "ZwOpenFile()".  Most of the others probably have those values
8314  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
8315  * which might go over the wire (for the benefit of backup/restore software).
8316  */
8317 static const true_false_string tfs_nt_create_options_directory = {
8318         "File being created/opened must be a directory",
8319         "File being created/opened must not be a directory"
8320 };
8321 static const true_false_string tfs_nt_create_options_write_through = {
8322         "Writes should flush buffered data before completing",
8323         "Writes need not flush buffered data before completing"
8324 };
8325 static const true_false_string tfs_nt_create_options_sequential_only = {
8326         "The file will only be accessed sequentially",
8327         "The file might not only be accessed sequentially"
8328 };
8329 static const true_false_string tfs_nt_create_options_no_intermediate_buffering = {
8330         "NO intermediate buffering is allowed",
8331         "Intermediate buffering is allowed"
8332 };
8333 static const true_false_string tfs_nt_create_options_sync_io_alert = {
8334         "All operations SYNCHRONOUS, waits subject to termination from alert",
8335         "Operations NOT necessarily synchronous"
8336 };
8337 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
8338         "All operations SYNCHRONOUS, waits not subject to alert",
8339         "Operations NOT necessarily synchronous"
8340 };
8341 static const true_false_string tfs_nt_create_options_non_directory = {
8342         "File being created/opened must not be a directory",
8343         "File being created/opened must be a directory"
8344 };
8345 static const true_false_string tfs_nt_create_options_create_tree_connection = {
8346         "Create Tree Connections is SET",
8347         "Create Tree Connections is NOT set"
8348 };
8349 static const true_false_string tfs_nt_create_options_complete_if_oplocked = {
8350         "Complete if oplocked is SET",
8351         "Complete if oplocked is NOT set"
8352 };
8353 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
8354         "The client does not understand extended attributes",
8355         "The client understands extended attributes"
8356 };
8357 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
8358         "The client understands only 8.3 file names",
8359         "The client understands long file names"
8360 };
8361 static const true_false_string tfs_nt_create_options_random_access = {
8362         "The file will be accessed randomly",
8363         "The file will not be accessed randomly"
8364 };
8365 static const true_false_string tfs_nt_create_options_delete_on_close = {
8366         "The file should be deleted when it is closed",
8367         "The file should not be deleted when it is closed"
8368 };
8369 static const true_false_string tfs_nt_create_options_open_by_fileid = {
8370         "OpenByFileID bit is SET",
8371         "OpenByFileID is NOT set"
8372 };
8373 static const true_false_string tfs_nt_create_options_backup_intent = {
8374         "This is a create with BACKUP INTENT",
8375         "This is a normal create"
8376 };
8377 static const true_false_string tfs_nt_create_options_no_compression = {
8378         "Open/Create with NO Compression",
8379         "Compression is allowed for Open/Create"
8380 };
8381 static const true_false_string tfs_nt_create_options_reserve_opfilter = {
8382         "Reserve Opfilter is SET",
8383         "Reserve Opfilter is NOT set"
8384 };
8385 static const true_false_string tfs_nt_create_options_open_reparse_point = {
8386         "Open a Reparse Point",
8387         "Normal open"
8388 };
8389 static const true_false_string tfs_nt_create_options_open_no_recall = {
8390         "Open No Recall is SET",
8391         "Open no recall is NOT set"
8392 };
8393 static const true_false_string tfs_nt_create_options_open_for_free_space_query = {
8394         "This is an OPEN FOR FREE SPACE QUERY",
8395         "This is NOT an open for free space query"
8396 };
8397
8398 int
8399 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8400 {
8401         guint32     mask;
8402         proto_item *item;
8403         proto_tree *tree;
8404
8405         mask = tvb_get_letohl(tvb, offset);
8406
8407         if (parent_tree) {
8408                 item = proto_tree_add_item(parent_tree, hf_smb_nt_notify_completion_filter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8409                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
8410
8411                 proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
8412                         tvb, offset, 4, mask);
8413                 proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
8414                         tvb, offset, 4, mask);
8415                 proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
8416                         tvb, offset, 4, mask);
8417                 proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
8418                         tvb, offset, 4, mask);
8419                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
8420                         tvb, offset, 4, mask);
8421                 proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
8422                         tvb, offset, 4, mask);
8423                 proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
8424                         tvb, offset, 4, mask);
8425                 proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
8426                         tvb, offset, 4, mask);
8427                 proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
8428                         tvb, offset, 4, mask);
8429                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
8430                         tvb, offset, 4, mask);
8431                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
8432                         tvb, offset, 4, mask);
8433                 proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
8434                         tvb, offset, 4, mask);
8435         }
8436
8437         offset += 4;
8438         return offset;
8439 }
8440
8441 static int
8442 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8443 {
8444         guint8      mask;
8445         proto_item *item;
8446         proto_tree *tree;
8447
8448         mask = tvb_get_guint8(tvb, offset);
8449
8450         if (parent_tree) {
8451                 item = proto_tree_add_item(parent_tree, hf_smb_nt_ioctl_flags_completion_filter, tvb, offset, 1, ENC_NA);
8452                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
8453
8454                 proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
8455                         tvb, offset, 1, mask);
8456         }
8457
8458         offset += 1;
8459         return offset;
8460 }
8461
8462 /*
8463  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
8464  * Native API Reference".
8465  */
8466 static const true_false_string tfs_nt_qsd_owner = {
8467         "Requesting OWNER security information",
8468         "NOT requesting owner security information",
8469 };
8470
8471 static const true_false_string tfs_nt_qsd_group = {
8472         "Requesting GROUP security information",
8473         "NOT requesting group security information",
8474 };
8475
8476 static const true_false_string tfs_nt_qsd_dacl = {
8477         "Requesting DACL security information",
8478         "NOT requesting DACL security information",
8479 };
8480
8481 static const true_false_string tfs_nt_qsd_sacl = {
8482         "Requesting SACL security information",
8483         "NOT requesting SACL security information",
8484 };
8485
8486 #define NT_QSD_OWNER    0x00000001
8487 #define NT_QSD_GROUP    0x00000002
8488 #define NT_QSD_DACL     0x00000004
8489 #define NT_QSD_SACL     0x00000008
8490
8491 int
8492 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
8493 {
8494         guint32     mask;
8495         proto_item *item;
8496         proto_tree *tree;
8497
8498         mask = tvb_get_letohl(tvb, offset);
8499
8500         if (parent_tree) {
8501                 item = proto_tree_add_item(parent_tree, hf_smb_nt_qsd, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8502                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
8503
8504                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
8505                         tvb, offset, 4, mask);
8506                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
8507                         tvb, offset, 4, mask);
8508                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
8509                         tvb, offset, 4, mask);
8510                 proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
8511                         tvb, offset, 4, mask);
8512         }
8513
8514         offset += 4;
8515
8516         return offset;
8517 }
8518
8519 static int
8520 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8521 {
8522         int     old_offset, old_sid_offset;
8523         guint32 qsize;
8524
8525         do {
8526                 old_offset = offset;
8527
8528                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8529                 qsize = tvb_get_letohl(tvb, offset);
8530                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8531                 COUNT_BYTES_TRANS_SUBR(4);
8532
8533                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8534                 /* length of SID */
8535                 proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8536                 COUNT_BYTES_TRANS_SUBR(4);
8537
8538                 /* 16 unknown bytes */
8539                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8540                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8541                             offset, 8, ENC_NA);
8542                 COUNT_BYTES_TRANS_SUBR(8);
8543
8544                 /* number of bytes for used quota */
8545                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8546                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8547                 COUNT_BYTES_TRANS_SUBR(8);
8548
8549                 /* number of bytes for quota warning */
8550                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8551                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8552                 COUNT_BYTES_TRANS_SUBR(8);
8553
8554                 /* number of bytes for quota limit */
8555                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8556                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8557                 COUNT_BYTES_TRANS_SUBR(8);
8558
8559                 /* SID of the user */
8560                 old_sid_offset = offset;
8561                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8562                 *bcp -= (offset-old_sid_offset);
8563
8564                 if (qsize) {
8565                         offset = old_offset+qsize;
8566                 }
8567         }while (qsize);
8568
8569
8570         return offset;
8571 }
8572
8573
8574 static int
8575 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd, smb_nt_transact_info_t *nti, smb_info_t *si)
8576 {
8577         proto_item              *item       = NULL;
8578         proto_tree              *tree       = NULL;
8579         int                      old_offset = offset;
8580         guint16                  bcp        = bc; /* XXX fixme */
8581         struct access_mask_info *ami        = NULL;
8582         tvbuff_t                *ioctl_tvb;
8583
8584         DISSECTOR_ASSERT(si);
8585
8586         if (parent_tree) {
8587                 guint32 bytes = 0;
8588                 bytes = tvb_length_remaining(tvb, offset);
8589                 /*tvb_ensure_bytes_exist(tvb, offset, bc);*/
8590                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
8591                                 "%s Data",
8592                                 val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
8593                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8594         }
8595
8596         switch(ntd->subcmd) {
8597         case NT_TRANS_CREATE:
8598                 /* security descriptor */
8599                 if (ntd->sd_len) {
8600                         offset = dissect_nt_sec_desc(
8601                                 tvb, offset, pinfo, tree, NULL, TRUE,
8602                                 ntd->sd_len, NULL);
8603                 }
8604
8605                 /* extended attributes */
8606                 if (ntd->ea_len) {
8607                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, ENC_NA);
8608                         offset += ntd->ea_len;
8609                 }
8610
8611                 break;
8612         case NT_TRANS_IOCTL:
8613                 /* ioctl data */
8614                 ioctl_tvb = tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
8615                 if (nti) {
8616                         dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, TRUE);
8617                 }
8618
8619                 offset += bc;
8620
8621                 break;
8622         case NT_TRANS_SSD:
8623                 if (nti) {
8624                         switch(nti->fid_type) {
8625                         case SMB_FID_TYPE_FILE:
8626                                 ami = &smb_file_access_mask_info;
8627                                 break;
8628                         case SMB_FID_TYPE_DIR:
8629                                 ami = &smb_dir_access_mask_info;
8630                                 break;
8631                         }
8632                 }
8633
8634                 offset = dissect_nt_sec_desc(
8635                         tvb, offset, pinfo, tree, NULL, TRUE, bc, ami);
8636
8637                 if (offset < (old_offset + bc)) {
8638                         offset = old_offset + bc;
8639                 }
8640
8641                 break;
8642         case NT_TRANS_NOTIFY:
8643                 break;
8644         case NT_TRANS_RENAME:
8645                 /* XXX not documented */
8646                 break;
8647         case NT_TRANS_QSD:
8648                 break;
8649         case NT_TRANS_GET_USER_QUOTA:
8650                 /* unknown 4 bytes */
8651                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8652                             offset, 4, ENC_NA);
8653                 offset += 4;
8654
8655                 /* length of SID */
8656                 proto_tree_add_item(tree, hf_smb_length_of_sid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8657                 offset +=4;
8658
8659                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8660                 break;
8661         case NT_TRANS_SET_USER_QUOTA:
8662                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8663                 break;
8664         }
8665
8666         /* ooops there were data we didnt know how to process */
8667         if ((offset-old_offset) < bc) {
8668                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8669                     bc - (offset-old_offset), ENC_NA);
8670                 offset += bc - (offset-old_offset);
8671         }
8672
8673         return offset;
8674 }
8675
8676 static int
8677 dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc, smb_nt_transact_info_t *nti, smb_info_t *si)
8678 {
8679         proto_item *item = NULL;
8680         proto_tree *tree = NULL;
8681         guint32     fn_len, create_flags, access_mask, share_access, create_options;
8682         const char *fn;
8683
8684         DISSECTOR_ASSERT(si);
8685
8686         if (parent_tree) {
8687                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8688                                 "%s Parameters",
8689                                 val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
8690                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8691         }
8692
8693         switch(ntd->subcmd) {
8694         case NT_TRANS_CREATE:
8695                 /* Create flags */
8696                 create_flags = tvb_get_letohl(tvb, offset);
8697                 offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
8698                 bc -= 4;
8699
8700                 /* root directory fid */
8701                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8702                 COUNT_BYTES(4);
8703
8704                 /* nt access mask */
8705                 access_mask = tvb_get_letohl(tvb, offset);
8706                 offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
8707                 bc -= 4;
8708
8709                 /* allocation size */
8710                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
8711                 COUNT_BYTES(8);
8712
8713                 /* Extended File Attributes */
8714                 offset = dissect_file_ext_attr(tvb, tree, offset);
8715                 bc -= 4;
8716
8717                 /* share access */
8718                 share_access = tvb_get_letohl(tvb, offset);
8719                 offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
8720                 bc -= 4;
8721
8722                 /* create disposition */
8723                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8724                 COUNT_BYTES(4);
8725
8726                 /* create options */
8727                 create_options = tvb_get_letohl(tvb, offset);
8728                 offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
8729                 bc -= 4;
8730
8731                 /* sd length */
8732                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8733                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8734                 COUNT_BYTES(4);
8735
8736                 /* ea length */
8737                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8738                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8739                 COUNT_BYTES(4);
8740
8741                 /* file name len */
8742                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8743                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8744                 COUNT_BYTES(4);
8745
8746                 /* impersonation level */
8747                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8748                 COUNT_BYTES(4);
8749
8750                 /* security flags */
8751                 offset = dissect_nt_security_flags(tvb, tree, offset);
8752                 bc -= 1;
8753
8754                 /* file name */
8755                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8756                 if (fn != NULL) {
8757                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8758                                 fn);
8759                         COUNT_BYTES(fn_len);
8760                 }
8761
8762                 break;
8763         case NT_TRANS_IOCTL:
8764                 break;
8765         case NT_TRANS_SSD: {
8766                 guint16 fid;
8767                 smb_fid_info_t *fid_info;
8768
8769                 /* fid */
8770                 fid = tvb_get_letohs(tvb, offset);
8771                 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8772                 offset += 2;
8773                 if (nti) {
8774                         if (fid_info) {
8775                                 nti->fid_type = fid_info->type;
8776                         } else {
8777                                 nti->fid_type = SMB_FID_TYPE_UNKNOWN;
8778                         }
8779                 }
8780
8781                 /* 2 reserved bytes */
8782                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
8783                 offset += 2;
8784
8785                 /* security information */
8786                 offset = dissect_security_information_mask(tvb, tree, offset);
8787                 break;
8788         }
8789         case NT_TRANS_NOTIFY:
8790                 break;
8791         case NT_TRANS_RENAME:
8792                 /* XXX not documented */
8793                 break;
8794         case NT_TRANS_QSD: {
8795                 guint16 fid;
8796                 smb_fid_info_t *fid_info;
8797
8798                 /* fid */
8799                 fid = tvb_get_letohs(tvb, offset);
8800                 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8801                 offset += 2;
8802                 if (nti) {
8803                         if (fid_info) {
8804                                 nti->fid_type = fid_info->type;
8805                         } else {
8806                                 nti->fid_type = SMB_FID_TYPE_UNKNOWN;
8807                         }
8808                 }
8809
8810                 /* 2 reserved bytes */
8811                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
8812                 offset += 2;
8813
8814                 /* security information */
8815                 offset = dissect_security_information_mask(tvb, tree, offset);
8816                 break;
8817         }
8818         case NT_TRANS_GET_USER_QUOTA:
8819                 /* not decoded yet */
8820                 break;
8821         case NT_TRANS_SET_USER_QUOTA:
8822                 /* not decoded yet */
8823                 break;
8824         }
8825
8826         return offset;
8827 }
8828
8829 static int
8830 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, smb_info_t *si)
8831 {
8832         proto_item             *item = NULL;
8833         proto_tree             *tree = NULL;
8834         smb_nt_transact_info_t *nti  = NULL;
8835         smb_saved_info_t       *sip;
8836
8837         DISSECTOR_ASSERT(si);
8838         sip = si->sip;
8839         if (sip && (sip->extra_info_type == SMB_EI_NTI)) {
8840                 nti = (smb_nt_transact_info_t *)sip->extra_info;
8841         }
8842
8843         if (parent_tree) {
8844                 tvb_ensure_bytes_exist(tvb, offset, len);
8845                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8846                                 "%s Setup",
8847                                 val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
8848                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8849         }
8850
8851         switch(ntd->subcmd) {
8852         case NT_TRANS_CREATE:
8853                 offset += len;
8854                 break;
8855         case NT_TRANS_IOCTL: {
8856                 guint16 fid;
8857
8858                 /* function code */
8859                 offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, nti ? &nti->ioctl_function : NULL);
8860
8861                 /* fid */
8862                 fid = tvb_get_letohs(tvb, offset);
8863                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8864                 offset += 2;
8865
8866                 /* isfsctl */
8867                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8868                 offset += 1;
8869
8870                 /* isflags */
8871                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8872
8873                 break;
8874         }
8875         case NT_TRANS_SSD:
8876                 offset += len;
8877                 break;
8878         case NT_TRANS_NOTIFY: {
8879                 guint16 fid;
8880
8881                 /* completion filter */
8882                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8883
8884                 /* fid */
8885                 fid = tvb_get_letohs(tvb, offset);
8886                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
8887                 offset += 2;
8888
8889                 /* watch tree */
8890                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8891                 offset += 1;
8892
8893                 /* reserved byte */
8894                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
8895                 offset += 1;
8896
8897                 break;
8898         }
8899         case NT_TRANS_RENAME:
8900                 /* XXX not documented */
8901                 offset += len;
8902                 break;
8903         case NT_TRANS_QSD:
8904                 break;
8905         case NT_TRANS_GET_USER_QUOTA:
8906                 /* not decoded yet */
8907                 offset += len;
8908                 break;
8909         case NT_TRANS_SET_USER_QUOTA:
8910                 /* not decoded yet */
8911                 offset += len;
8912                 break;
8913         }
8914
8915         return offset;
8916 }
8917
8918
8919 static int
8920 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
8921 {
8922         guint8                  wc, sc;
8923         guint32                 pc     = 0, pd = 0, po = 0, dc = 0, od = 0, dd = 0;
8924         guint32                 td     = 0, tp = 0;
8925         smb_saved_info_t       *sip;
8926         int                     subcmd;
8927         nt_trans_data           ntd;
8928         guint16                 bc;
8929         guint32                 padcnt;
8930         smb_nt_transact_info_t *nti    = NULL;
8931         fragment_head          *r_fd   = NULL;
8932         tvbuff_t               *pd_tvb = NULL;
8933         gboolean                save_fragmented;
8934
8935         save_fragmented = pinfo->fragmented;
8936
8937         ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
8938
8939         DISSECTOR_ASSERT(si);
8940         sip = si->sip;
8941
8942         WORD_COUNT;
8943
8944         if (wc >= 19) {
8945                 /* primary request */
8946                 /* max setup count */
8947                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8948                 offset += 1;
8949
8950                 /* 2 reserved bytes */
8951                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
8952                 offset += 2;
8953         } else {
8954                 /* secondary request */
8955                 /* 3 reserved bytes */
8956                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
8957                 offset += 3;
8958         }
8959
8960
8961         /* total param count */
8962         tp = tvb_get_letohl(tvb, offset);
8963         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8964         offset += 4;
8965
8966         /* total data count */
8967         td = tvb_get_letohl(tvb, offset);
8968         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8969         offset += 4;
8970
8971         if (wc >= 19) {
8972                 /* primary request */
8973                 /* max param count */
8974                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8975                 offset += 4;
8976
8977                 /* max data count */
8978                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8979                 offset += 4;
8980         }
8981
8982         /* param count */
8983         pc = tvb_get_letohl(tvb, offset);
8984         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8985         offset += 4;
8986
8987         /* param offset */
8988         po = tvb_get_letohl(tvb, offset);
8989         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8990         offset += 4;
8991
8992         /* param displacement */
8993         if (wc >= 19) {
8994                 /* primary request*/
8995         } else {
8996                 /* secondary request */
8997
8998                 proto_tree_add_item(tree, hf_smb_param_disp32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
8999                 offset += 4;
9000         }
9001
9002         /* data count */
9003         dc = tvb_get_letohl(tvb, offset);
9004         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9005         offset += 4;
9006
9007         /* data offset */
9008         od = tvb_get_letohl(tvb, offset);
9009         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9010         offset += 4;
9011
9012         /* data displacement */
9013         if (wc >= 19) {
9014                 /* primary request */
9015         } else {
9016                 /* secondary request */
9017                 dd = tvb_get_letohl(tvb, offset);
9018                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9019                 offset += 4;
9020         }
9021
9022         /* setup count */
9023         if (wc >= 19) {
9024                 /* primary request */
9025                 sc = tvb_get_guint8(tvb, offset);
9026                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9027                 offset += 1;
9028         } else {
9029                 /* secondary request */
9030                 sc = 0;
9031         }
9032
9033         /* function */
9034         if (wc >= 19) {
9035                 /* primary request */
9036                 subcmd = tvb_get_letohs(tvb, offset);
9037                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
9038                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9039                                 val_to_str_ext_const(subcmd, &nt_cmd_vals_ext, "<unknown>"));
9040
9041                 ntd.subcmd = subcmd;
9042                 if (!si->unidir && sip) {
9043                         if (!pinfo->fd->flags.visited) {
9044                                 /*
9045                                  * Allocate a new smb_nt_transact_info_t
9046                                  * structure.
9047                                  */
9048                                 nti = (smb_nt_transact_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_nt_transact_info_t));
9049                                 nti->subcmd = subcmd;
9050                                 nti->fid_type = SMB_FID_TYPE_UNKNOWN;
9051                                 sip->extra_info = nti;
9052                                 sip->extra_info_type = SMB_EI_NTI;
9053                         } else {
9054                                 if (sip->extra_info_type == SMB_EI_NTI) {
9055                                         nti = (smb_nt_transact_info_t *)sip->extra_info;
9056                                 }
9057                         }
9058                 }
9059         } else {
9060                 /* secondary request */
9061                 col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
9062         }
9063         offset += 2;
9064
9065         /* this is a padding byte */
9066         if (offset%1) {
9067                 /* pad byte */
9068                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, ENC_NA);
9069                 offset += 1;
9070         }
9071
9072         /* if there were any setup bytes, decode them */
9073         if (sc) {
9074                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd, si);
9075                 offset += sc*2;
9076         }
9077
9078         BYTE_COUNT;
9079
9080         /* reassembly of SMB NT Transaction data payload.
9081            In this section we do reassembly of both the data and parameters
9082            blocks of the SMB transaction command.
9083         */
9084         /* do we need reassembly? */
9085         if ( (td && (td != dc)) || (tp && (tp != pc)) ) {
9086                 /* oh yeah, either data or parameter section needs
9087                    reassembly...
9088                 */
9089                 pinfo->fragmented = TRUE;
9090                 if (smb_trans_reassembly) {
9091                         /* ...and we were told to do reassembly */
9092                         if (pc) {
9093                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9094                                                              po, pc, pd, td+tp, si);
9095                         }
9096                         if ((r_fd == NULL) && dc) {
9097                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9098                                                              od, dc, dd+tp, td+tp, si);
9099                         }
9100                 }
9101         }
9102
9103         /* if we got a reassembled fd structure from the reassembly routine we
9104            must create pd_tvb from it
9105         */
9106         if (r_fd) {
9107                 proto_item *frag_tree_item;
9108
9109                 pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
9110                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9111
9112                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9113         }
9114
9115         if (pd_tvb) {
9116           /* we have reassembled data, grab param and data from there */
9117           dissect_nt_trans_param_request(pd_tvb, pinfo, 0, tree, tp,
9118                                           &ntd, (guint16) tvb_length(pd_tvb), nti, si);
9119           dissect_nt_trans_data_request(pd_tvb, pinfo, tp, tree, td, &ntd, nti, si);
9120           COUNT_BYTES(bc); /* We are done */
9121         } else {
9122           /* we do not have reassembled data, just use what we have in the
9123              packet as well as we can */
9124           /* parameters */
9125           if (po > (guint32)offset) {
9126                 /* We have some initial padding bytes.
9127                 */
9128                 padcnt = po-offset;
9129                 if (padcnt > bc)
9130                         padcnt = bc;
9131                 CHECK_BYTE_COUNT(padcnt);
9132                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9133                 COUNT_BYTES(padcnt);
9134           }
9135           if (pc) {
9136                 CHECK_BYTE_COUNT(pc);
9137                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc, nti, si);
9138                 COUNT_BYTES(pc);
9139           }
9140
9141           /* data */
9142           if (od > (guint32)offset) {
9143                 /* We have some initial padding bytes.
9144                 */
9145                 padcnt = od-offset;
9146                 if (padcnt > bc)
9147                         padcnt = bc;
9148                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9149                 COUNT_BYTES(padcnt);
9150           }
9151           if (dc) {
9152                 CHECK_BYTE_COUNT(dc);
9153                 dissect_nt_trans_data_request(
9154                         tvb, pinfo, offset, tree, dc, &ntd, nti, si);
9155                 COUNT_BYTES(dc);
9156           }
9157         }
9158
9159         END_OF_SMB
9160
9161         pinfo->fragmented = save_fragmented;
9162         return offset;
9163 }
9164
9165
9166
9167 static int
9168 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
9169                                int offset, proto_tree *parent_tree, int len,
9170                                nt_trans_data *ntd _U_,
9171                                smb_nt_transact_info_t *nti, smb_info_t *si)
9172 {
9173         proto_item              *item = NULL;
9174         proto_tree              *tree = NULL;
9175         guint16                  bcp;
9176         struct access_mask_info *ami  = NULL;
9177         tvbuff_t                *ioctl_tvb;
9178
9179         DISSECTOR_ASSERT(si);
9180
9181         if (parent_tree) {
9182                 tvb_ensure_bytes_exist(tvb, offset, len);
9183                 if (nti != NULL) {
9184                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9185                                 "%s Data",
9186                                 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9187                 } else {
9188                         /*
9189                          * We never saw the request to which this is a
9190                          * response.
9191                          */
9192                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9193                                 "Unknown NT Transaction Data (matching request not seen)");
9194                 }
9195                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
9196         }
9197
9198         if (nti == NULL) {
9199                 offset += len;
9200                 return offset;
9201         }
9202         switch(nti->subcmd) {
9203         case NT_TRANS_CREATE:
9204                 break;
9205         case NT_TRANS_IOCTL:
9206                 /* ioctl data */
9207                 ioctl_tvb = tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
9208                 dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, FALSE);
9209
9210                 offset += len;
9211
9212                 break;
9213         case NT_TRANS_SSD:
9214                 break;
9215         case NT_TRANS_NOTIFY:
9216                 break;
9217         case NT_TRANS_RENAME:
9218                 /* XXX not documented */
9219                 break;
9220         case NT_TRANS_QSD:
9221                 if (nti) {
9222                         switch(nti->fid_type) {
9223                         case SMB_FID_TYPE_FILE:
9224                                 ami = &smb_file_access_mask_info;
9225                                 break;
9226                         case SMB_FID_TYPE_DIR:
9227                                 ami = &smb_dir_access_mask_info;
9228                                 break;
9229                         }
9230                 }
9231                 offset = dissect_nt_sec_desc(
9232                         tvb, offset, pinfo, tree, NULL, TRUE, len, ami);
9233                 break;
9234         case NT_TRANS_GET_USER_QUOTA:
9235                 bcp = len;
9236                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
9237                 break;
9238         case NT_TRANS_SET_USER_QUOTA:
9239                 /* not decoded yet */
9240                 break;
9241         }
9242
9243         return offset;
9244 }
9245
9246 static int
9247 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
9248                                 int offset, proto_tree *parent_tree,
9249                                 int len, nt_trans_data *ntd _U_, guint16 bc, smb_info_t *si)
9250 {
9251         proto_item             *item     = NULL;
9252         proto_tree             *tree     = NULL;
9253         guint32                 fn_len;
9254         const char             *fn;
9255         smb_nt_transact_info_t *nti;
9256         guint16                 fid;
9257         int                     old_offset;
9258         guint32                 neo;
9259         int                     padcnt;
9260         smb_fid_info_t         *fid_info = NULL;
9261         guint16                 ftype;
9262         guint8                  isdir;
9263
9264         DISSECTOR_ASSERT(si);
9265
9266         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9267                 nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9268         else
9269                 nti = NULL;
9270
9271         if (parent_tree) {
9272                 tvb_ensure_bytes_exist(tvb, offset, len);
9273                 if (nti != NULL) {
9274                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9275                                 "%s Parameters",
9276                                 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9277                 } else {
9278                         /*
9279                          * We never saw the request to which this is a
9280                          * response.
9281                          */
9282                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
9283                                 "Unknown NT Transaction Parameters (matching request not seen)");
9284                 }
9285                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
9286         }
9287
9288         if (nti == NULL) {
9289                 offset += len;
9290                 return offset;
9291         }
9292         switch(nti->subcmd) {
9293         case NT_TRANS_CREATE:
9294                 /* oplock level */
9295                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9296                 offset += 1;
9297
9298                 /* reserved byte */
9299                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
9300                 offset += 1;
9301
9302                 /* fid */
9303                 fid = tvb_get_letohs(tvb, offset);
9304                 fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
9305                 offset += 2;
9306
9307                 /* create action */
9308                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9309                 offset += 4;
9310
9311                 /* ea error offset */
9312                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9313                 offset += 4;
9314
9315                 /* create time */
9316                 offset = dissect_nt_64bit_time(tvb, tree, offset,
9317                         hf_smb_create_time);
9318
9319                 /* access time */
9320                 offset = dissect_nt_64bit_time(tvb, tree, offset,
9321                         hf_smb_access_time);
9322
9323                 /* last write time */
9324                 offset = dissect_nt_64bit_time(tvb, tree, offset,
9325                         hf_smb_last_write_time);
9326
9327                 /* last change time */
9328                 offset = dissect_nt_64bit_time(tvb, tree, offset,
9329                         hf_smb_change_time);
9330
9331                 /* Extended File Attributes */
9332                 offset = dissect_file_ext_attr(tvb, tree, offset);
9333
9334                 /* allocation size */
9335                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9336                 offset += 8;
9337
9338                 /* end of file */
9339                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
9340                 offset += 8;
9341
9342                 /* File Type */
9343                 ftype = tvb_get_letohs(tvb, offset);
9344                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9345                 offset += 2;
9346
9347                 /* device state */
9348                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9349
9350                 /* is directory */
9351                 isdir = tvb_get_guint8(tvb, offset);
9352                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9353                 offset += 1;
9354
9355                 /* Try to remember the type of this fid so that we can dissect
9356                  * any future security descriptor (access mask) properly
9357                  */
9358                 if (ftype == 0) {
9359                         if (isdir == 0) {
9360                                 if (fid_info) {
9361                                         fid_info->type = SMB_FID_TYPE_FILE;
9362                                 }
9363                         } else {
9364                                 if (fid_info) {
9365                                         fid_info->type = SMB_FID_TYPE_DIR;
9366                                 }
9367                         }
9368                 }
9369                 if (ftype == 2) {
9370                         if (fid_info) {
9371                                 fid_info->type = SMB_FID_TYPE_PIPE;
9372                         }
9373                 }
9374                 break;
9375         case NT_TRANS_IOCTL:
9376                 break;
9377         case NT_TRANS_SSD:
9378                 break;
9379         case NT_TRANS_NOTIFY:
9380                 while (len) {
9381                         old_offset = offset;
9382
9383                         /* next entry offset */
9384                         neo = tvb_get_letohl(tvb, offset);
9385                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9386                         COUNT_BYTES(4);
9387                         len -= 4;
9388                         /* broken implementations */
9389                         if (len < 0) break;
9390
9391                         /* action */
9392                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9393                         COUNT_BYTES(4);
9394                         len -= 4;
9395                         /* broken implementations */
9396                         if (len < 0) break;
9397
9398                         /* file name len */
9399                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
9400                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9401                         COUNT_BYTES(4);
9402                         len -= 4;
9403                         /* broken implementations */
9404                         if (len < 0) break;
9405
9406                         /* file name */
9407                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
9408                         if (fn == NULL)
9409                                 break;
9410                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9411                                 fn);
9412                         COUNT_BYTES(fn_len);
9413                         len -= fn_len;
9414                         /* broken implementations */
9415                         if (len < 0) break;
9416
9417                         if (neo == 0)
9418                                 break;  /* no more structures */
9419
9420                         /* skip to next structure */
9421                         padcnt = (old_offset + neo) - offset;
9422                         if (padcnt < 0) {
9423                                 /*
9424                                  * XXX - this is bogus; flag it?
9425                                  */
9426                                 padcnt = 0;
9427                         }
9428                         if (padcnt != 0) {
9429                                 COUNT_BYTES(padcnt);
9430                                 len -= padcnt;
9431                                 /* broken implementations */
9432                                 if (len < 0) break;
9433                         }
9434                 }
9435                 break;
9436         case NT_TRANS_RENAME:
9437                 /* XXX not documented */
9438                 break;
9439         case NT_TRANS_QSD:
9440                 /*
9441                  * This appears to be the size of the security
9442                  * descriptor; the calling sequence of
9443                  * "ZwQuerySecurityObject()" suggests that it would
9444                  * be.  The actual security descriptor wouldn't
9445                  * follow if the max data count in the request
9446                  * was smaller; this lets the client know how
9447                  * big a buffer it needs to provide.
9448                  */
9449                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9450                 offset += 4;
9451                 break;
9452         case NT_TRANS_GET_USER_QUOTA:
9453                 proto_tree_add_item(tree, hf_smb_size_returned_quota_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9454                 offset += 4;
9455                 break;
9456         case NT_TRANS_SET_USER_QUOTA:
9457                 /* not decoded yet */
9458                 break;
9459         }
9460
9461         return offset;
9462 }
9463
9464 static int
9465 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo _U_,
9466                                 int offset, proto_tree *parent_tree,
9467                                 int len, nt_trans_data *ntd _U_, smb_info_t *si)
9468 {
9469 #if 0
9470         proto_item             *item = NULL;
9471         proto_tree             *tree = NULL;
9472 #endif
9473         smb_nt_transact_info_t *nti;
9474
9475         DISSECTOR_ASSERT(si);
9476
9477         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9478                 nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9479         else
9480                 nti = NULL;
9481
9482         if (parent_tree) {
9483                 tvb_ensure_bytes_exist(tvb, offset, len);
9484                 if (nti != NULL) {
9485                         /*item = */proto_tree_add_text(parent_tree, tvb, offset, len,
9486                                 "%s Setup",
9487                                 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
9488                 } else {
9489                         /*
9490                          * We never saw the request to which this is a
9491                          * response.
9492                          */
9493                         /*item = */proto_tree_add_text(parent_tree, tvb, offset, len,
9494                                 "Unknown NT Transaction Setup (matching request not seen)");
9495                 }
9496                 /*tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);*/
9497         }
9498
9499         if (nti == NULL) {
9500                 offset += len;
9501                 return offset;
9502         }
9503         switch(nti->subcmd) {
9504         case NT_TRANS_CREATE:
9505                 break;
9506         case NT_TRANS_IOCTL:
9507                 break;
9508         case NT_TRANS_SSD:
9509                 break;
9510         case NT_TRANS_NOTIFY:
9511                 break;
9512         case NT_TRANS_RENAME:
9513                 /* XXX not documented */
9514                 break;
9515         case NT_TRANS_QSD:
9516                 break;
9517         case NT_TRANS_GET_USER_QUOTA:
9518                 /* not decoded yet */
9519                 break;
9520         case NT_TRANS_SET_USER_QUOTA:
9521                 /* not decoded yet */
9522                 break;
9523         }
9524
9525         return offset;
9526 }
9527
9528 static int
9529 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
9530 {
9531         guint8                  wc, sc;
9532         guint32                 pc     = 0, po = 0, pd = 0, dc = 0, od = 0, dd = 0;
9533         guint32                 td     = 0, tp = 0;
9534         smb_nt_transact_info_t *nti    = NULL;
9535         static nt_trans_data    ntd;
9536         guint16                 bc;
9537         gint32                  padcnt;
9538         fragment_head          *r_fd   = NULL;
9539         tvbuff_t               *pd_tvb = NULL;
9540         gboolean                save_fragmented;
9541
9542         DISSECTOR_ASSERT(si);
9543
9544         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_NTI))
9545                 nti = (smb_nt_transact_info_t *)si->sip->extra_info;
9546         else
9547                 nti = NULL;
9548
9549         /* primary request */
9550         if (nti != NULL) {
9551                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
9552                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
9553                                 val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "<unknown (%u)>"));
9554         } else {
9555                 proto_tree_add_uint_format_value(tree, hf_smb_nt_trans_subcmd, tvb, offset, 0, -1,
9556                         "<unknown function - could not find matching request>");
9557                 col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
9558         }
9559
9560         WORD_COUNT;
9561
9562         /* 3 reserved bytes */
9563         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
9564         offset += 3;
9565
9566         /* total param count */
9567         tp = tvb_get_letohl(tvb, offset);
9568         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
9569         offset += 4;
9570
9571         /* total data count */
9572         td = tvb_get_letohl(tvb, offset);
9573         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
9574         offset += 4;
9575
9576         /* param count */
9577         pc = tvb_get_letohl(tvb, offset);
9578         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
9579         offset += 4;
9580
9581         /* param offset */
9582         po = tvb_get_letohl(tvb, offset);
9583         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
9584         offset += 4;
9585
9586         /* param displacement */
9587         pd = tvb_get_letohl(tvb, offset);
9588         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
9589         offset += 4;
9590
9591         /* data count */
9592         dc = tvb_get_letohl(tvb, offset);
9593         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
9594         offset += 4;
9595
9596         /* data offset */
9597         od = tvb_get_letohl(tvb, offset);
9598         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
9599         offset += 4;
9600
9601         /* data displacement */
9602         dd = tvb_get_letohl(tvb, offset);
9603         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
9604         offset += 4;
9605
9606         /* setup count */
9607         sc = tvb_get_guint8(tvb, offset);
9608         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9609         offset += 1;
9610
9611         /* setup data */
9612         if (sc) {
9613                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd, si);
9614                 offset += sc*2;
9615         }
9616
9617         BYTE_COUNT;
9618
9619         /* reassembly of SMB NT Transaction data payload.
9620            In this section we do reassembly of both the data and parameters
9621            blocks of the SMB transaction command.
9622         */
9623         save_fragmented = pinfo->fragmented;
9624         /* do we need reassembly? */
9625         if ( (td && (td != dc)) || (tp && (tp != pc)) ) {
9626                 /* oh yeah, either data or parameter section needs
9627                    reassembly...
9628                 */
9629                 pinfo->fragmented = TRUE;
9630                 if (smb_trans_reassembly) {
9631                         /* ...and we were told to do reassembly */
9632                         if (pc) {
9633                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9634                                                              po, pc, pd, td+tp, si);
9635
9636                         }
9637                         if ((r_fd == NULL) && dc) {
9638                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9639                                                              od, dc, dd+tp, td+tp, si);
9640                         }
9641                 }
9642         }
9643
9644         /* if we got a reassembled fd structure from the reassembly routine we
9645            must create pd_tvb from it
9646         */
9647         if (r_fd) {
9648                 proto_item *frag_tree_item;
9649
9650                 pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
9651                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9652
9653                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
9654         }
9655
9656
9657         if (pd_tvb) {
9658           /* we have reassembled data, grab param and data from there */
9659           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9660                                           &ntd, (guint16) tvb_length(pd_tvb), si);
9661           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd, nti, si);
9662           COUNT_BYTES(bc); /* We are done */
9663         } else {
9664           /* we do not have reassembled data, just use what we have in the
9665              packet as well as we can */
9666           /* parameters */
9667           if (po > (guint32)offset) {
9668             /* We have some initial padding bytes.
9669              */
9670             padcnt = po-offset;
9671             if (padcnt > bc)
9672               padcnt = bc;
9673             CHECK_BYTE_COUNT(padcnt);
9674             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9675             COUNT_BYTES(padcnt);
9676           }
9677           if (pc) {
9678             CHECK_BYTE_COUNT(pc);
9679             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc, si);
9680             COUNT_BYTES(pc);
9681           }
9682
9683           /* data */
9684           if (od > (guint32)offset) {
9685             /* We have some initial padding bytes.
9686              */
9687             padcnt = od-offset;
9688             if (padcnt > bc)
9689               padcnt = bc;
9690             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
9691             COUNT_BYTES(padcnt);
9692           }
9693           if (dc) {
9694             CHECK_BYTE_COUNT(dc);
9695             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd, nti, si);
9696             COUNT_BYTES(dc);
9697           }
9698         }
9699         pinfo->fragmented = save_fragmented;
9700
9701         END_OF_SMB
9702
9703         return offset;
9704 }
9705
9706 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9707    NT Transaction command  ends here
9708    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9709
9710 static const value_string print_mode_vals[] = {
9711         {0,     "Text Mode"},
9712         {1,     "Graphics Mode"},
9713         {0, NULL}
9714 };
9715
9716 static int
9717 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)
9718 {
9719         int         fn_len;
9720         const char *fn;
9721         guint8      wc;
9722         guint16     bc;
9723
9724         DISSECTOR_ASSERT(si);
9725
9726         WORD_COUNT;
9727
9728         /* setup len */
9729         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9730         offset += 2;
9731
9732         /* print mode */
9733         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9734         offset += 2;
9735
9736         BYTE_COUNT;
9737
9738         /* buffer format */
9739         CHECK_BYTE_COUNT(1);
9740         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9741         COUNT_BYTES(1);
9742
9743         /* print identifier */
9744         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9745         if (fn == NULL)
9746                 goto endofcommand;
9747         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9748                 fn);
9749         COUNT_BYTES(fn_len);
9750
9751         END_OF_SMB
9752
9753         return offset;
9754 }
9755
9756
9757 static int
9758 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)
9759 {
9760         int     cnt;
9761         guint8  wc;
9762         guint16 bc, fid;
9763
9764         WORD_COUNT;
9765
9766         /* fid */
9767         fid = tvb_get_letohs(tvb, offset);
9768         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
9769         offset += 2;
9770
9771         BYTE_COUNT;
9772
9773         /* buffer format */
9774         CHECK_BYTE_COUNT(1);
9775         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9776         COUNT_BYTES(1);
9777
9778         /* data len */
9779         CHECK_BYTE_COUNT(2);
9780         cnt = tvb_get_letohs(tvb, offset);
9781         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9782         COUNT_BYTES(2);
9783
9784         /* file data */
9785         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9786
9787         END_OF_SMB
9788
9789         return offset;
9790 }
9791
9792
9793 static const value_string print_status_vals[] = {
9794         {1,     "Held or Stopped"},
9795         {2,     "Printing"},
9796         {3,     "Awaiting print"},
9797         {4,     "In intercept"},
9798         {5,     "File had error"},
9799         {6,     "Printer error"},
9800         {0, NULL}
9801 };
9802
9803 static int
9804 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_)
9805 {
9806         guint8  wc;
9807         guint16 bc;
9808
9809         WORD_COUNT;
9810
9811         /* max count */
9812         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9813         offset += 2;
9814
9815         /* start index */
9816         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9817         offset += 2;
9818
9819         BYTE_COUNT;
9820
9821         END_OF_SMB
9822
9823         return offset;
9824 }
9825
9826 static int
9827 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo _U_,
9828     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
9829 {
9830         proto_item *item = NULL;
9831         proto_tree *tree = NULL;
9832         int         fn_len;
9833         const char *fn;
9834
9835         DISSECTOR_ASSERT(si);
9836
9837         if (parent_tree) {
9838                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9839                         "Queue entry");
9840                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9841         }
9842
9843         /* queued time */
9844         CHECK_BYTE_COUNT_SUBR(4);
9845         offset = dissect_smb_datetime(tvb, tree, offset,
9846                 hf_smb_print_queue_date,
9847                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9848         *bcp -= 4;
9849
9850         /* status */
9851         CHECK_BYTE_COUNT_SUBR(1);
9852         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9853         COUNT_BYTES_SUBR(1);
9854
9855         /* spool file number */
9856         CHECK_BYTE_COUNT_SUBR(2);
9857         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9858         COUNT_BYTES_SUBR(2);
9859
9860         /* spool file size */
9861         CHECK_BYTE_COUNT_SUBR(4);
9862         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
9863         COUNT_BYTES_SUBR(4);
9864
9865         /* reserved byte */
9866         CHECK_BYTE_COUNT_SUBR(1);
9867         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
9868         COUNT_BYTES_SUBR(1);
9869
9870         /* file name */
9871         fn_len = 16;
9872         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9873         CHECK_STRING_SUBR(fn);
9874         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9875                 fn);
9876         COUNT_BYTES_SUBR(fn_len);
9877
9878         *trunc = FALSE;
9879         return offset;
9880 }
9881
9882 static int
9883 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_)
9884 {
9885         guint16  cnt = 0, len;
9886         guint8   wc;
9887         guint16  bc;
9888         gboolean trunc;
9889
9890         WORD_COUNT;
9891
9892         /* count */
9893         cnt = tvb_get_letohs(tvb, offset);
9894         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9895         offset += 2;
9896
9897         /* restart index */
9898         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
9899         offset += 2;
9900
9901         BYTE_COUNT;
9902
9903         /* buffer format */
9904         CHECK_BYTE_COUNT(1);
9905         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9906         COUNT_BYTES(1);
9907
9908         /* data len */
9909         CHECK_BYTE_COUNT(2);
9910         len = tvb_get_letohs(tvb, offset);
9911         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9912         COUNT_BYTES(2);
9913
9914         /* queue elements */
9915         while (cnt--) {
9916                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9917                     &bc, &trunc, si);
9918                 if (trunc)
9919                         goto endofcommand;
9920         }
9921
9922         END_OF_SMB
9923
9924         return offset;
9925 }
9926
9927
9928 static int
9929 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_)
9930 {
9931         int     name_len;
9932         guint16 bc;
9933         guint8  wc;
9934         guint16 message_len;
9935
9936         WORD_COUNT;
9937
9938         BYTE_COUNT;
9939
9940         /* buffer format */
9941         CHECK_BYTE_COUNT(1);
9942         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9943         COUNT_BYTES(1);
9944
9945         /* originator name */
9946         /* XXX - what if this runs past bc? */
9947         name_len = tvb_strsize(tvb, offset);
9948         CHECK_BYTE_COUNT(name_len);
9949         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9950             name_len, ENC_ASCII|ENC_NA);
9951         COUNT_BYTES(name_len);
9952
9953         /* buffer format */
9954         CHECK_BYTE_COUNT(1);
9955         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9956         COUNT_BYTES(1);
9957
9958         /* destination name */
9959         /* XXX - what if this runs past bc? */
9960         name_len = tvb_strsize(tvb, offset);
9961         CHECK_BYTE_COUNT(name_len);
9962         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9963             name_len, ENC_ASCII|ENC_NA);
9964         COUNT_BYTES(name_len);
9965
9966         /* buffer format */
9967         CHECK_BYTE_COUNT(1);
9968         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9969         COUNT_BYTES(1);
9970
9971         /* message len */
9972         CHECK_BYTE_COUNT(2);
9973         message_len = tvb_get_letohs(tvb, offset);
9974         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9975             message_len);
9976         COUNT_BYTES(2);
9977
9978         /* message */
9979         CHECK_BYTE_COUNT(message_len);
9980         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9981             ENC_ASCII|ENC_NA);
9982         COUNT_BYTES(message_len);
9983
9984         END_OF_SMB
9985
9986         return offset;
9987 }
9988
9989 static int
9990 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_)
9991 {
9992         int     name_len;
9993         guint16 bc;
9994         guint8  wc;
9995
9996         WORD_COUNT;
9997
9998         BYTE_COUNT;
9999
10000         /* buffer format */
10001         CHECK_BYTE_COUNT(1);
10002         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10003         COUNT_BYTES(1);
10004
10005         /* originator name */
10006         /* XXX - what if this runs past bc? */
10007         name_len = tvb_strsize(tvb, offset);
10008         CHECK_BYTE_COUNT(name_len);
10009         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
10010             name_len, ENC_ASCII|ENC_NA);
10011         COUNT_BYTES(name_len);
10012
10013         /* buffer format */
10014         CHECK_BYTE_COUNT(1);
10015         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10016         COUNT_BYTES(1);
10017
10018         /* destination name */
10019         /* XXX - what if this runs past bc? */
10020         name_len = tvb_strsize(tvb, offset);
10021         CHECK_BYTE_COUNT(name_len);
10022         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
10023             name_len, ENC_ASCII|ENC_NA);
10024         COUNT_BYTES(name_len);
10025
10026         END_OF_SMB
10027
10028         return offset;
10029 }
10030
10031 static int
10032 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_)
10033 {
10034         guint16 bc;
10035         guint8  wc;
10036
10037         WORD_COUNT;
10038
10039         /* message group ID */
10040         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10041         offset += 2;
10042
10043         BYTE_COUNT;
10044
10045         END_OF_SMB
10046
10047         return offset;
10048 }
10049
10050 static int
10051 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_)
10052 {
10053         guint16 bc;
10054         guint8  wc;
10055         guint16 message_len;
10056
10057         WORD_COUNT;
10058
10059         BYTE_COUNT;
10060
10061         /* buffer format */
10062         CHECK_BYTE_COUNT(1);
10063         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10064         COUNT_BYTES(1);
10065
10066         /* message len */
10067         CHECK_BYTE_COUNT(2);
10068         message_len = tvb_get_letohs(tvb, offset);
10069         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
10070             message_len);
10071         COUNT_BYTES(2);
10072
10073         /* message */
10074         CHECK_BYTE_COUNT(message_len);
10075         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
10076             ENC_ASCII|ENC_NA);
10077         COUNT_BYTES(message_len);
10078
10079         END_OF_SMB
10080
10081         return offset;
10082 }
10083
10084 static int
10085 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_)
10086 {
10087         int     name_len;
10088         guint16 bc;
10089         guint8  wc;
10090
10091         WORD_COUNT;
10092
10093         BYTE_COUNT;
10094
10095         /* buffer format */
10096         CHECK_BYTE_COUNT(1);
10097         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10098         COUNT_BYTES(1);
10099
10100         /* forwarded name */
10101         /* XXX - what if this runs past bc? */
10102         name_len = tvb_strsize(tvb, offset);
10103         CHECK_BYTE_COUNT(name_len);
10104         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
10105             name_len, ENC_ASCII|ENC_NA);
10106         COUNT_BYTES(name_len);
10107
10108         END_OF_SMB
10109
10110         return offset;
10111 }
10112
10113 static int
10114 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_)
10115 {
10116         int     name_len;
10117         guint16 bc;
10118         guint8  wc;
10119
10120         WORD_COUNT;
10121
10122         BYTE_COUNT;
10123
10124         /* buffer format */
10125         CHECK_BYTE_COUNT(1);
10126         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10127         COUNT_BYTES(1);
10128
10129         /* machine name */
10130         /* XXX - what if this runs past bc? */
10131         name_len = tvb_strsize(tvb, offset);
10132         CHECK_BYTE_COUNT(name_len);
10133         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
10134             name_len, ENC_ASCII|ENC_NA);
10135         COUNT_BYTES(name_len);
10136
10137         END_OF_SMB
10138
10139         return offset;
10140 }
10141
10142
10143 static int
10144 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_)
10145 {
10146         guint8      wc, cmd      = 0xff;
10147         guint16     andxoffset   = 0;
10148         guint16     bc;
10149         int         fn_len;
10150         const char *fn;
10151         guint32     create_flags = 0, access_mask = 0, file_attributes = 0;
10152         guint32     share_access = 0, create_options = 0, create_disposition = 0;
10153
10154         DISSECTOR_ASSERT(si);
10155
10156         WORD_COUNT;
10157
10158         /* next smb command */
10159         cmd = tvb_get_guint8(tvb, offset);
10160         if (cmd != 0xff) {
10161                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
10162         } else {
10163                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
10164         }
10165         offset += 1;
10166
10167         /* reserved byte */
10168         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10169         offset += 1;
10170
10171         /* andxoffset */
10172         andxoffset = tvb_get_letohs(tvb, offset);
10173         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
10174         offset += 2;
10175
10176         /* reserved byte */
10177         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10178         offset += 1;
10179
10180         /* file name len */
10181         fn_len = tvb_get_letohs(tvb, offset);
10182         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
10183         offset += 2;
10184
10185         /* Create flags */
10186         create_flags = tvb_get_letohl(tvb, offset);
10187         offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
10188
10189         /* root directory fid */
10190         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10191         offset += 4;
10192
10193         /* nt access mask */
10194         access_mask = tvb_get_letohl(tvb, offset);
10195         offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
10196
10197         /* allocation size */
10198         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10199         offset += 8;
10200
10201         /* Extended File Attributes */
10202         file_attributes = tvb_get_letohl(tvb, offset);
10203         offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
10204
10205         /* share access */
10206         share_access = tvb_get_letohl(tvb, offset);
10207         offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
10208
10209         /* create disposition */
10210         create_disposition = tvb_get_letohl(tvb, offset);
10211         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10212         offset += 4;
10213
10214         /* create options */
10215         create_options = tvb_get_letohl(tvb, offset);
10216         offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
10217
10218         /* impersonation level */
10219         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10220         offset += 4;
10221
10222         /* security flags */
10223         offset = dissect_nt_security_flags(tvb, tree, offset);
10224
10225         BYTE_COUNT;
10226
10227         /* file name */
10228         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10229         if (fn == NULL)
10230                 goto endofcommand;
10231         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10232                 fn);
10233         COUNT_BYTES(fn_len);
10234
10235         /* store it for the fid->name/openframe/closeframe matching in
10236          * dissect_smb_fid()   called from the response.
10237          */
10238         if ((!pinfo->fd->flags.visited) && si->sip && fn) {
10239                 smb_fid_saved_info_t *fsi;
10240
10241                 fsi                      = wmem_new(wmem_file_scope(), smb_fid_saved_info_t);
10242                 fsi->filename            = wmem_strdup(wmem_file_scope(), fn);
10243                 fsi->create_flags        = create_flags;
10244                 fsi->access_mask         = access_mask;
10245                 fsi->file_attributes     = file_attributes;
10246                 fsi->share_access        = share_access;
10247                 fsi->create_options      = create_options;
10248                 fsi->create_disposition  = create_disposition;
10249
10250                 si->sip->extra_info_type = SMB_EI_FILEDATA;
10251                 si->sip->extra_info      = fsi;
10252         }
10253
10254         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10255                     format_text(fn, strlen(fn)));
10256
10257         END_OF_SMB
10258
10259         if (cmd != 0xff) {      /* there is an andX command */
10260                 if (andxoffset < offset)
10261                         THROW(ReportedBoundsError);
10262                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
10263         }
10264
10265         return offset;
10266 }
10267
10268
10269 static int
10270 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si)
10271 {
10272         guint8          wc, cmd    = 0xff;
10273         guint16         andxoffset = 0;
10274         guint16         bc;
10275         guint16         fid        = 0;
10276         guint16         ftype;
10277         guint8          isdir;
10278         smb_fid_info_t *fid_info   = NULL;
10279
10280         WORD_COUNT;
10281
10282         /* next smb command */
10283         cmd = tvb_get_guint8(tvb, offset);
10284         if (cmd != 0xff) {
10285                 proto_tree_add_uint(tree, hf_smb_andxcmd, tvb, offset, 1, cmd);
10286         } else {
10287                 proto_tree_add_uint_format_value(tree, hf_smb_andxcmd, tvb, offset, 1, cmd, "No further commands (0xff)");
10288         }
10289         offset += 1;
10290
10291         /* reserved byte */
10292         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
10293         offset += 1;
10294
10295         /* andxoffset */
10296         andxoffset = tvb_get_letohs(tvb, offset);
10297         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
10298         offset += 2;
10299
10300         /* oplock level */
10301         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10302         offset += 1;
10303
10304         /* fid */
10305         fid = tvb_get_letohs(tvb, offset);
10306         fid_info = dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
10307         offset += 2;
10308
10309         /* create action */
10310         /*XXX is this really the same as create disposition in the request? it looks so*/
10311         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
10312         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10313         offset += 4;
10314
10315         /* create time */
10316         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
10317
10318         /* access time */
10319         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
10320
10321         /* last write time */
10322         offset = dissect_nt_64bit_time(tvb, tree, offset,
10323                 hf_smb_last_write_time);
10324
10325         /* last change time */
10326         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
10327
10328         /* Extended File Attributes */
10329         offset = dissect_file_ext_attr(tvb, tree, offset);
10330
10331         /* allocation size */
10332         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10333         offset += 8;
10334
10335         /* end of file */
10336         /* We store the end of file */
10337         if (fid_info) {
10338                 fid_info->end_of_file = tvb_get_letoh64(tvb, offset);
10339         }
10340         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
10341         offset += 8;
10342
10343         /* File Type */
10344         ftype = tvb_get_letohs(tvb, offset);
10345         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10346         offset += 2;
10347
10348         /* IPC State */
10349         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
10350
10351         /* is directory */
10352         isdir = tvb_get_guint8(tvb, offset);
10353         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10354         offset += 1;
10355
10356         /* Do we know whether or not EXTENDED_RESPONSES are required? */
10357         /* MS-SMB 2.2.4.9.2 says that there is a Volume GUID, File ID,
10358            Maximal Access Rights and Guest Maximal Access Rights here
10359            if ExtendedResponses requested. */
10360         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_FILEDATA) &&
10361             (((smb_fid_saved_info_t *)(si->sip->extra_info))->create_flags & 0x10)) {
10362                 proto_item *mar = NULL;
10363                 proto_item *gmar = NULL;
10364                 proto_tree *tr = NULL;
10365
10366                 /* The first field is a Volume GUID ... */
10367
10368                 proto_tree_add_item(tree, hf_smb_volume_guid,
10369                                     tvb, offset, 16, ENC_NA);
10370                 offset += 16;
10371
10372                 /* The file ID comes next */
10373                 proto_tree_add_item(tree, hf_smb_file_id_64bit,
10374                                     tvb, offset, 8, ENC_LITTLE_ENDIAN);
10375                 offset += 8;
10376
10377                 mar = proto_tree_add_text(tree, tvb, offset, 4,
10378                                           "Maximal Access Rights");
10379
10380                 tr = proto_item_add_subtree(mar, ett_smb_nt_access_mask);
10381
10382                 offset = dissect_smb_access_mask(tvb, tr, offset);
10383
10384                 gmar = proto_tree_add_text(tree, tvb, offset, 4,
10385                                            "Guest Maximal Access Rights");
10386
10387                 tr = proto_item_add_subtree(gmar, ett_smb_nt_access_mask);
10388
10389                 offset = dissect_smb_access_mask(tvb, tr, offset);
10390         }
10391
10392         /* Try to remember the type of this fid so that we can dissect
10393          * any future security descriptor (access mask) properly
10394          */
10395         if (ftype == 0) {
10396                 if (isdir == 0) {
10397                         if (fid_info) {
10398                                 fid_info->type = SMB_FID_TYPE_FILE;
10399                         }
10400                 } else {
10401                         if (fid_info) {
10402                                 fid_info->type = SMB_FID_TYPE_DIR;
10403                         }
10404                 }
10405         }
10406         if (ftype == 2) {
10407                 if (fid_info) {
10408                         fid_info->type = SMB_FID_TYPE_PIPE;
10409                 }
10410         }
10411
10412         BYTE_COUNT;
10413
10414         END_OF_SMB
10415
10416         if (cmd != 0xff) {      /* there is an andX command */
10417                 if (andxoffset < offset)
10418                         THROW(ReportedBoundsError);
10419                 dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE, si);
10420         }
10421
10422         /* if there was an error, add a generated filename to the tree */
10423         if (si->nt_status) {
10424                 dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE, si);
10425         }
10426
10427         return offset;
10428 }
10429
10430
10431 static int
10432 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_)
10433 {
10434         guint8  wc;
10435         guint16 bc;
10436
10437         WORD_COUNT;
10438
10439         BYTE_COUNT;
10440
10441         END_OF_SMB
10442
10443         return offset;
10444 }
10445
10446 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10447    BEGIN Transaction/Transaction2 Primary and secondary requests
10448    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
10449
10450
10451 static const value_string trans2_cmd_vals[] = {
10452         { 0x00,         "OPEN2" },
10453         { 0x01,         "FIND_FIRST2" },
10454         { 0x02,         "FIND_NEXT2" },
10455         { 0x03,         "QUERY_FS_INFO" },
10456         { 0x04,         "SET_FS_INFO" },
10457         { 0x05,         "QUERY_PATH_INFO" },
10458         { 0x06,         "SET_PATH_INFO" },
10459         { 0x07,         "QUERY_FILE_INFO" },
10460         { 0x08,         "SET_FILE_INFO" },
10461         { 0x09,         "FSCTL" },
10462         { 0x0A,         "IOCTL2" },
10463         { 0x0B,         "FIND_NOTIFY_FIRST" },
10464         { 0x0C,         "FIND_NOTIFY_NEXT" },
10465         { 0x0D,         "CREATE_DIRECTORY" },
10466         { 0x0E,         "SESSION_SETUP" },
10467         { 0x0F,         "Unknown (0x0f)" },  /* dummy so val_to_str_ext can do indexed lookup */
10468         { 0x10,         "GET_DFS_REFERRAL" },
10469         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
10470         { 0,    NULL }
10471 };
10472 value_string_ext trans2_cmd_vals_ext = VALUE_STRING_EXT_INIT(trans2_cmd_vals);
10473
10474 static const true_false_string tfs_tf_dtid = {
10475         "Also DISCONNECT TID",
10476         "Do NOT disconnect TID"
10477 };
10478 static const true_false_string tfs_tf_owt = {
10479         "One Way Transaction (NO RESPONSE)",
10480         "Two way transaction"
10481 };
10482
10483 static const true_false_string tfs_ff2_backup = {
10484         "Find WITH backup intent",
10485         "No backup intent"
10486 };
10487 static const true_false_string tfs_ff2_continue = {
10488         "CONTINUE search from previous position",
10489         "New search, do NOT continue from previous position"
10490 };
10491 static const true_false_string tfs_ff2_resume = {
10492         "Return RESUME keys",
10493         "Do NOT return resume keys"
10494 };
10495 static const true_false_string tfs_ff2_close_eos = {
10496         "CLOSE search if END OF SEARCH is reached",
10497         "Do NOT close search if end of search reached"
10498 };
10499 static const true_false_string tfs_ff2_close = {
10500         "CLOSE search after this request",
10501         "Do NOT close search after this request"
10502 };
10503
10504 /* used by
10505    TRANS2_FIND_FIRST2
10506 */
10507 static const value_string ff2_il_vals[] = {
10508         { 1,            "Info Standard"},
10509         { 2,            "Info Query EA Size"},
10510         { 3,            "Info Query EAs From List"},
10511         { 0x0101,       "Find File Directory Info"},
10512         { 0x0102,       "Find File Full Directory Info"},
10513         { 0x0103,       "Find File Names Info"},
10514         { 0x0104,       "Find File Both Directory Info"},
10515         { 0x0105,       "Find File Full Directory Info"},
10516         { 0x0106,       "Find File Id Both Directory Info"},
10517         { 0x0202,       "Find File Unix"},
10518         { 0x020B,       "Find File Unix Info2"},
10519         {0, NULL}
10520 };
10521
10522 /* values used by :
10523         TRANS2_QUERY_PATH_INFORMATION
10524         TRANS2_QUERY_FILE_INFORMATION
10525 */
10526 static const value_string qpi_loi_vals[] = {
10527         { 1,            "Info Standard"},
10528         { 2,            "Info Query EA Size"},
10529         { 3,            "Info Query EAs From List"},
10530         { 4,            "Info Query All EAs"},
10531         { 6,            "Info Is Name Valid"},
10532         { 0x0101,       "Query File Basic Info"},
10533         { 0x0102,       "Query File Standard Info"},
10534         { 0x0103,       "Query File EA Info"},
10535         { 0x0104,       "Query File Name Info"},
10536         { 0x0107,       "Query File All Info"},
10537         { 0x0108,       "Query File Alt Name Info"},
10538         { 0x0109,       "Query File Stream Info"},
10539         { 0x010b,       "Query File Compression Info"},
10540         { 0x0200,       "Query File Unix Basic"},
10541         { 0x0201,       "Query File Unix Link"},
10542         { 0x0202,       "Query File Unix Hardlink"},
10543         { 0x0204,       "Query File Posix ACL"},
10544         { 0x0205,       "Query File Posix XATTR"},
10545         { 0x0206,       "Query File Posix Attr Flags"},
10546         { 0x0207,       "Query File Posix Permissions"},
10547         { 0x0208,       "Query File Posix Lock"},
10548         { 0x020b,       "Query File Unix Info2"},
10549         { 1004,         "Query File Basic Info"},
10550         { 1005,         "Query File Standard Info"},
10551         { 1006,         "Query File Internal Info"},
10552         { 1007,         "Query File EA Info"},
10553         { 1009,         "Query File Name Info"},
10554         { 1010,         "Query File Rename Info"},
10555         { 1011,         "Query File Link Info"},
10556         { 1012,         "Query File Names Info"},
10557         { 1013,         "Query File Disposition Info"},
10558         { 1014,         "Query File Position Info"},
10559         { 1015,         "Query File Full EA Info"},
10560         { 1016,         "Query File Mode Info"},
10561         { 1017,         "Query File Alignment Info"},
10562         { 1018,         "Query File All Info"},
10563         { 1019,         "Query File Allocation Info"},
10564         { 1020,         "Query File End of File Info"},
10565         { 1021,         "Query File Alt Name Info"},
10566         { 1022,         "Query File Stream Info"},
10567         { 1023,         "Query File Pipe Info"},
10568         { 1024,         "Query File Pipe Local Info"},
10569         { 1025,         "Query File Pipe Remote Info"},
10570         { 1026,         "Query File Mailslot Query Info"},
10571         { 1027,         "Query File Mailslot Set Info"},
10572         { 1028,         "Query File Compression Info"},
10573         { 1029,         "Query File ObjectID Info"},
10574         { 1030,         "Query File Completion Info"},
10575         { 1031,         "Query File Move Cluster Info"},
10576         { 1032,         "Query File Quota Info"},
10577         { 1033,         "Query File Reparsepoint Info"},
10578         { 1034,         "Query File Network Open Info"},
10579         { 1035,         "Query File Attribute Tag Info"},
10580         { 1036,         "Query File Tracking Info"},
10581         { 1037,         "Query File Maximum Info"},
10582         {0, NULL}
10583 };
10584 static value_string_ext qpi_loi_vals_ext = VALUE_STRING_EXT_INIT(qpi_loi_vals);
10585
10586 /* values used by :
10587         TRANS2_SET_PATH_INFORMATION
10588         TRANS2_SET_FILE_INFORMATION
10589         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
10590         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
10591         well; note that they're different from the QUERY_PATH_INFORMATION
10592         and QUERY_FILE_INFORMATION values!)
10593 */
10594 static const value_string spi_loi_vals[] = {
10595         { 1,            "Info Standard"},
10596         { 2,            "Info Set EAs"},
10597         { 4,            "Info Query All EAs"},
10598         { 0x0101,       "Set File Basic Info"},
10599         { 0x0102,       "Set File Disposition Info"},
10600         { 0x0103,       "Set File Allocation Info"},
10601         { 0x0104,       "Set File End Of File Info"},
10602         { 0x0200,       "Set File Unix Basic"},
10603         { 0x0201,       "Set File Unix Link"},
10604         { 0x0202,       "Set File Unix HardLink"},
10605         { 0x0204,       "Set File Unix ACL"},
10606         { 0x0205,       "Set File Unix XATTR"},
10607         { 0x0206,       "Set File Unix Attr Flags"},
10608         { 0x0208,       "Set File Posix Lock"},
10609         { 0x0209,       "Set File Posix Open"},
10610         { 0x020a,       "Set File Posix Unlink"},
10611         { 0x020b,       "Set File Unix Info2"},
10612         { 1004,         "Set File Basic Info"},
10613         { 1010,         "Set Rename Information"},
10614         { 1013,         "Set Disposition Information"},
10615         { 1014,         "Set Position Information"},
10616         { 1016,         "Set Mode Information"},
10617         { 1019,         "Set Allocation Information"},
10618         { 1020,         "Set EOF Information"},
10619         { 1023,         "Set File Pipe Information"},
10620         { 1025,         "Set File Pipe Remote Information"},
10621         { 1029,         "Set Copy On Write Information"},
10622         { 1032,         "Set OLE Class ID Information"},
10623         { 1039,         "Set Inherit Context Index Information"},
10624         { 1040,         "Set OLE Information (?)"},
10625         {0, NULL}
10626 };
10627 static value_string_ext spi_loi_vals_ext = VALUE_STRING_EXT_INIT(spi_loi_vals);
10628
10629 static const value_string qfsi_vals[] = {
10630         { 1,            "Info Allocation"},
10631         { 2,            "Info Volume"},
10632         { 0x0101,       "Query FS Label Info"},
10633         { 0x0102,       "Query FS Volume Info"},
10634         { 0x0103,       "Query FS Size Info"},
10635         { 0x0104,       "Query FS Device Info"},
10636         { 0x0105,       "Query FS Attribute Info"},
10637         { 0x0200,       "Unix Query FS Info"},
10638         { 0x0202,       "Unix Query POSIX whoami"},
10639         { 0x0301,       "Mac Query FS Info"},
10640         { 1001,         "Query FS Label Info"},
10641         { 1002,         "Query FS Volume Info"},
10642         { 1003,         "Query FS Size Info"},
10643         { 1004,         "Query FS Device Info"},
10644         { 1005,         "Query FS Attribute Info"},
10645         { 1006,         "Query FS Quota Info"},
10646         { 1007,         "Query Full FS Size Info"},
10647         { 1008,         "Object ID Information"},
10648         {0, NULL}
10649 };
10650 static value_string_ext qfsi_vals_ext = VALUE_STRING_EXT_INIT(qfsi_vals);
10651
10652 static const value_string sfsi_vals[] = {
10653         { 0x203,        "Request Transport Encryption"},
10654         { 1006,         "Set FS Quota Info"},
10655         {0, NULL}
10656 };
10657
10658 static const value_string nt_rename_vals[] = {
10659         { 0x0103,       "Create Hard Link"},
10660         {0, NULL}
10661 };
10662
10663
10664 static const value_string delete_pending_vals[] = {
10665         {0,     "Normal, no pending delete"},
10666         {1,     "This object has DELETE PENDING"},
10667         {0, NULL}
10668 };
10669
10670 static const value_string alignment_vals[] = {
10671         {0,     "Byte alignment"},
10672         {1,     "Word (16bit) alignment"},
10673         {3,     "Long (32bit) alignment"},
10674         {7,     "8 byte boundary alignment"},
10675         {0x0f,  "16 byte boundary alignment"},
10676         {0x1f,  "32 byte boundary alignment"},
10677         {0x3f,  "64 byte boundary alignment"},
10678         {0x7f,  "128 byte boundary alignment"},
10679         {0xff,  "256 byte boundary alignment"},
10680         {0x1ff, "512 byte boundary alignment"},
10681         {0, NULL}
10682 };
10683
10684 static const true_false_string tfs_marked_for_deletion = {
10685         "File is MARKED FOR DELETION",
10686         "File is NOT marked for deletion"
10687 };
10688
10689 static const true_false_string tfs_get_dfs_server_hold_storage = {
10690         "Referral SERVER HOLDS STORAGE for the file",
10691         "Referral server does NOT hold storage for the file"
10692 };
10693 static const true_false_string tfs_get_dfs_fielding = {
10694         "The server in referral is FIELDING CAPABLE",
10695         "The server in referrals is NOT fielding capable"
10696 };
10697
10698 static const true_false_string tfs_dfs_referral_flags_name_list_referral = {
10699         "A domain/DC referral response",
10700         "NOT a domain/DC referral response"
10701 };
10702
10703 static const true_false_string tfs_dfs_referral_flags_target_set_boundary = {
10704         "The first target in the target set",
10705         "NOT the first target in the target set"
10706 };
10707
10708 static const value_string dfs_referral_server_type_vals[] = {
10709         {0,     "Non-root targets returned"},
10710         {1,     "Root targets returns"},
10711         {0, NULL}
10712 };
10713
10714
10715 static const true_false_string tfs_device_char_removable = {
10716         "This is a REMOVABLE device",
10717         "This is NOT a removable device"
10718 };
10719 static const true_false_string tfs_device_char_read_only = {
10720         "This is a READ-ONLY device",
10721         "This is NOT a read-only device"
10722 };
10723 static const true_false_string tfs_device_char_floppy = {
10724         "This is a FLOPPY DISK device",
10725         "This is NOT a floppy disk device"
10726 };
10727 static const true_false_string tfs_device_char_write_once = {
10728         "This is a WRITE-ONCE device",
10729         "This is NOT a write-once device"
10730 };
10731 static const true_false_string tfs_device_char_remote = {
10732         "This is a REMOTE device",
10733         "This is NOT a remote device"
10734 };
10735 static const true_false_string tfs_device_char_mounted = {
10736         "This device is MOUNTED",
10737         "This device is NOT mounted"
10738 };
10739 static const true_false_string tfs_device_char_virtual = {
10740         "This is a VIRTUAL device",
10741         "This is NOT a virtual device"
10742 };
10743
10744
10745 static const true_false_string tfs_fs_attr_css = {
10746         "This FS supports CASE SENSITIVE SEARCHes",
10747         "This FS does NOT support case sensitive searches"
10748 };
10749 static const true_false_string tfs_fs_attr_cpn = {
10750         "This FS supports CASE PRESERVED NAMES",
10751         "This FS does NOT support case preserved names"
10752 };
10753 static const true_false_string tfs_fs_attr_uod = {
10754         "This FS supports UNICODE NAMES",
10755         "This FS does NOT support unicode names"
10756 };
10757 static const true_false_string tfs_fs_attr_pacls = {
10758         "This FS supports PERSISTENT ACLs",
10759         "This FS does NOT support persistent acls"
10760 };
10761 static const true_false_string tfs_fs_attr_fc = {
10762         "This FS supports COMPRESSED FILES",
10763         "This FS does NOT support compressed files"
10764 };
10765 static const true_false_string tfs_fs_attr_vq = {
10766         "This FS supports VOLUME QUOTAS",
10767         "This FS does NOT support volume quotas"
10768 };
10769 static const true_false_string tfs_fs_attr_srp = {
10770         "This FS supports REPARSE POINTS",
10771         "This FS does NOT support reparse points"
10772 };
10773 static const true_false_string tfs_fs_attr_srs = {
10774         "This FS supports REMOTE STORAGE",
10775         "This FS does NOT support remote storage"
10776 };
10777 static const true_false_string tfs_fs_attr_ssf = {
10778         "This FS supports SPARSE FILES",
10779         "This FS does NOT support sparse files"
10780 };
10781 static const true_false_string tfs_fs_attr_sla = {
10782         "This FS supports LFN APIs",
10783         "This FS does NOT support lfn apis"
10784 };
10785 static const true_false_string tfs_fs_attr_vic = {
10786         "This FS VOLUME IS COMPRESSED",
10787         "This FS volume is NOT compressed"
10788 };
10789 static const true_false_string tfs_fs_attr_soids = {
10790         "This FS supports OIDs",
10791         "This FS does NOT support OIDs"
10792 };
10793 static const true_false_string tfs_fs_attr_se = {
10794         "This FS supports ENCRYPTION",
10795         "This FS does NOT support encryption"
10796 };
10797 static const true_false_string tfs_fs_attr_ns = {
10798         "This FS supports NAMED STREAMS",
10799         "This FS does NOT support named streams"
10800 };
10801 static const true_false_string tfs_fs_attr_rov = {
10802         "This is a READ ONLY VOLUME",
10803         "This is a read/write volume"
10804 };
10805
10806 #define FF2_RESUME      0x0004
10807
10808 static int
10809 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, smb_info_t *si)
10810 {
10811         guint16               mask;
10812         proto_item           *item = NULL;
10813         proto_tree           *tree = NULL;
10814         smb_transact2_info_t *t2i;
10815
10816         mask = tvb_get_letohs(tvb, offset);
10817
10818         DISSECTOR_ASSERT(si);
10819
10820         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
10821                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
10822                 if (t2i != NULL) {
10823                         if (!pinfo->fd->flags.visited)
10824                                 t2i->resume_keys = (mask & FF2_RESUME);
10825                 }
10826         }
10827
10828         if (parent_tree) {
10829                 item = proto_tree_add_item(parent_tree, hf_smb_ff2, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10830                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10831
10832                 proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10833                         tvb, offset, 2, mask);
10834                 proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10835                         tvb, offset, 2, mask);
10836                 proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10837                         tvb, offset, 2, mask);
10838                 proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10839                         tvb, offset, 2, mask);
10840                 proto_tree_add_boolean(tree, hf_smb_ff2_close,
10841                         tvb, offset, 2, mask);
10842         }
10843
10844         offset += 2;
10845
10846         return offset;
10847 }
10848
10849 #if 0
10850 static int
10851 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10852 {
10853         guint16     mask;
10854         proto_item *item;
10855         proto_tree *tree;
10856
10857         mask = tvb_get_letohs(tvb, offset);
10858
10859         if (parent_tree) {
10860                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10861                         "IO Flag: 0x%04x", mask);
10862                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10863
10864                 proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10865                         tvb, offset, 2, mask);
10866                 proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10867                         tvb, offset, 2, mask);
10868         }
10869
10870         offset += 2;
10871
10872         return offset;
10873 }
10874 #endif
10875
10876 int
10877 dissect_get_dfs_request_data(tvbuff_t *tvb, packet_info *pinfo,
10878     proto_tree *tree, int offset, guint16 *bcp, gboolean unicode)
10879 {
10880         int         fn_len;
10881         const char *fn;
10882         guint16     bc = *bcp;
10883
10884         /* referral level */
10885         CHECK_BYTE_COUNT_TRANS(2);
10886         proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10887         COUNT_BYTES_TRANS(2);
10888
10889         /* file name */
10890         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, &bc);
10891         CHECK_STRING_TRANS(fn);
10892         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10893                 fn);
10894         COUNT_BYTES_TRANS(fn_len);
10895
10896         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10897                     format_text(fn, strlen(fn)));
10898
10899         *bcp = bc;
10900         return offset;
10901 }
10902
10903 static int
10904 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10905     proto_tree *parent_tree, int offset, int subcmd, guint16 bc, smb_info_t *si)
10906 {
10907         proto_item           *item = NULL;
10908         proto_tree           *tree = NULL;
10909         smb_transact2_info_t *t2i;
10910         int                   fn_len;
10911         const char           *fn;
10912
10913         DISSECTOR_ASSERT(si);
10914
10915         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
10916                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
10917         else
10918                 t2i = NULL;
10919
10920         if (parent_tree) {
10921                 tvb_ensure_bytes_exist(tvb, offset, bc);
10922                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10923                                 "%s Parameters",
10924                                 val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
10925                                                "Unknown (0x%02x)"));
10926                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10927         }
10928
10929         switch(subcmd) {
10930         case 0x0000:    /*TRANS2_OPEN2*/
10931                 /* open flags */
10932                 CHECK_BYTE_COUNT_TRANS(2);
10933                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10934                 bc -= 2;
10935
10936                 /* desired access */
10937                 CHECK_BYTE_COUNT_TRANS(2);
10938                 offset = dissect_access(tvb, tree, offset, "Desired");
10939                 bc -= 2;
10940
10941                 /* Search Attributes */
10942                 CHECK_BYTE_COUNT_TRANS(2);
10943                 offset = dissect_search_attributes(tvb, tree, offset);
10944                 bc -= 2;
10945
10946                 /* File Attributes */
10947                 CHECK_BYTE_COUNT_TRANS(2);
10948                 offset = dissect_file_attributes(tvb, tree, offset);
10949                 bc -= 2;
10950
10951                 /* create time */
10952                 CHECK_BYTE_COUNT_TRANS(4);
10953                 offset = dissect_smb_datetime(tvb, tree, offset,
10954                         hf_smb_create_time,
10955                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10956                         TRUE);
10957                 bc -= 4;
10958
10959                 /* open function */
10960                 CHECK_BYTE_COUNT_TRANS(2);
10961                 offset = dissect_open_function(tvb, tree, offset);
10962                 bc -= 2;
10963
10964                 /* allocation size */
10965                 CHECK_BYTE_COUNT_TRANS(4);
10966                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
10967                 COUNT_BYTES_TRANS(4);
10968
10969                 /* 10 reserved bytes */
10970                 CHECK_BYTE_COUNT_TRANS(10);
10971                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, ENC_NA);
10972                 COUNT_BYTES_TRANS(10);
10973
10974                 /* file name */
10975                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10976                 CHECK_STRING_TRANS(fn);
10977                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10978                         fn);
10979                 COUNT_BYTES_TRANS(fn_len);
10980
10981                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10982                             format_text(fn, strlen(fn)));
10983                 break;
10984         case 0x0001:    /*TRANS2_FIND_FIRST2*/
10985                 /* Search Attributes */
10986                 CHECK_BYTE_COUNT_TRANS(2);
10987                 offset = dissect_search_attributes(tvb, tree, offset);
10988                 bc -= 2;
10989
10990                 /* search count */
10991                 CHECK_BYTE_COUNT_TRANS(2);
10992                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
10993                 COUNT_BYTES_TRANS(2);
10994
10995                 /* Find First2 flags */
10996                 CHECK_BYTE_COUNT_TRANS(2);
10997                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset, si);
10998                 bc -= 2;
10999
11000                 /* Find First2 information level */
11001                 CHECK_BYTE_COUNT_TRANS(2);
11002                 si->info_level = tvb_get_letohs(tvb, offset);
11003                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11004                         t2i->info_level = si->info_level;
11005                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
11006                 COUNT_BYTES_TRANS(2);
11007
11008                 /* storage type */
11009                 CHECK_BYTE_COUNT_TRANS(4);
11010                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11011                 COUNT_BYTES_TRANS(4);
11012
11013                 /* search pattern */
11014                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11015                 CHECK_STRING_TRANS(fn);
11016                 if (t2i && !t2i->name) {
11017                         t2i->name = wmem_strdup(wmem_file_scope(), fn);
11018                 }
11019                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
11020                         fn);
11021                 COUNT_BYTES_TRANS(fn_len);
11022
11023                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
11024                             format_text(fn, strlen(fn)));
11025
11026                 break;
11027         case 0x0002:    /*TRANS2_FIND_NEXT2*/
11028                 /* sid */
11029                 CHECK_BYTE_COUNT_TRANS(2);
11030                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11031                 COUNT_BYTES_TRANS(2);
11032
11033                 /* search count */
11034                 CHECK_BYTE_COUNT_TRANS(2);
11035                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11036                 COUNT_BYTES_TRANS(2);
11037
11038                 /* Find First2 information level */
11039                 CHECK_BYTE_COUNT_TRANS(2);
11040                 si->info_level = tvb_get_letohs(tvb, offset);
11041                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11042                         t2i->info_level = si->info_level;
11043                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
11044                 COUNT_BYTES_TRANS(2);
11045
11046                 /* resume key */
11047                 CHECK_BYTE_COUNT_TRANS(4);
11048                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11049                 COUNT_BYTES_TRANS(4);
11050
11051                 /* Find First2 flags */
11052                 CHECK_BYTE_COUNT_TRANS(2);
11053                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset, si);
11054                 bc -= 2;
11055
11056                 /* file name */
11057                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11058                 CHECK_STRING_TRANS(fn);
11059                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11060                         fn);
11061                 COUNT_BYTES_TRANS(fn_len);
11062
11063                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
11064                             format_text(fn, strlen(fn)));
11065
11066                 break;
11067         case 0x0003:    /*TRANS2_QUERY_FS_INFORMATION*/
11068                 /* level of interest */
11069                 CHECK_BYTE_COUNT_TRANS(2);
11070                 si->info_level = tvb_get_letohs(tvb, offset);
11071                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11072                         t2i->info_level = si->info_level;
11073                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
11074                 COUNT_BYTES_TRANS(2);
11075
11076                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11077                                         val_to_str_ext(si->info_level, &qfsi_vals_ext,
11078                                                    "Unknown (0x%02x)"));
11079
11080                 break;
11081         case 0x0004:    /*TRANS2_SET_FS_INFORMATION*/
11082                 /* level of interest */
11083                 CHECK_BYTE_COUNT_TRANS(4);
11084                 si->info_level = tvb_get_letohs(tvb, offset+2);
11085                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11086                         t2i->info_level = si->info_level;
11087                 proto_tree_add_uint(tree, hf_smb_sfsi_information_level, tvb, offset+2, 2, si->info_level);
11088                 COUNT_BYTES_TRANS(4);
11089
11090                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
11091                                         val_to_str(si->info_level, sfsi_vals,
11092                                                    "Unknown (0x%02x)"));
11093
11094                 break;
11095         case 0x0005:    /*TRANS2_QUERY_PATH_INFORMATION*/
11096                 /* level of interest */
11097                 CHECK_BYTE_COUNT_TRANS(2);
11098                 si->info_level = tvb_get_letohs(tvb, offset);
11099                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11100                         t2i->info_level = si->info_level;
11101                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
11102                 COUNT_BYTES_TRANS(2);
11103
11104                 col_append_fstr(
11105                                 pinfo->cinfo, COL_INFO, ", %s",
11106                                 val_to_str_ext(si->info_level, &qpi_loi_vals_ext,
11107                                            "Unknown (%u)"));
11108
11109                 /* 4 reserved bytes */
11110                 CHECK_BYTE_COUNT_TRANS(4);
11111                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11112                 COUNT_BYTES_TRANS(4);
11113
11114                 /* file name */
11115                 fn = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &fn_len, (si->unicode ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_ASCII|ENC_NA));
11116
11117                 CHECK_STRING_TRANS(fn);
11118                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11119                         fn);
11120                 COUNT_BYTES_TRANS(fn_len);
11121                 if (t2i && !t2i->name) {
11122                         t2i->name = wmem_strdup(wmem_file_scope(), fn);
11123                 }
11124
11125                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11126                             format_text(fn, strlen(fn)));
11127
11128                 break;
11129         case 0x0006:    /*TRANS2_SET_PATH_INFORMATION*/
11130                 /* level of interest */
11131                 CHECK_BYTE_COUNT_TRANS(2);
11132                 si->info_level = tvb_get_letohs(tvb, offset);
11133                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11134                         t2i->info_level = si->info_level;
11135                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
11136                 COUNT_BYTES_TRANS(2);
11137
11138                 /* 4 reserved bytes */
11139                 CHECK_BYTE_COUNT_TRANS(4);
11140                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11141                 COUNT_BYTES_TRANS(4);
11142
11143                 /* file name */
11144                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11145                 CHECK_STRING_TRANS(fn);
11146                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11147                         fn);
11148                 COUNT_BYTES_TRANS(fn_len);
11149
11150                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11151                             format_text(fn, strlen(fn)));
11152
11153                 break;
11154         case 0x0007: {  /*TRANS2_QUERY_FILE_INFORMATION*/
11155                 guint16 fid;
11156
11157                 /* fid */
11158                 CHECK_BYTE_COUNT_TRANS(2);
11159                 fid = tvb_get_letohs(tvb, offset);
11160                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
11161                 COUNT_BYTES_TRANS(2);
11162
11163                 /* level of interest */
11164                 CHECK_BYTE_COUNT_TRANS(2);
11165                 si->info_level = tvb_get_letohs(tvb, offset);
11166                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11167                         t2i->info_level = si->info_level;
11168                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
11169                 COUNT_BYTES_TRANS(2);
11170
11171                 col_append_fstr(
11172                                 pinfo->cinfo, COL_INFO, ", %s",
11173                                 val_to_str_ext(si->info_level, &qpi_loi_vals_ext,
11174                                            "Unknown (%u)"));
11175
11176                 break;
11177         }
11178         case 0x0008: {  /*TRANS2_SET_FILE_INFORMATION*/
11179                 guint16 fid;
11180
11181                 /* fid */
11182                 CHECK_BYTE_COUNT_TRANS(2);
11183                 fid = tvb_get_letohs(tvb, offset);
11184                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
11185                 COUNT_BYTES_TRANS(2);
11186
11187                 /* level of interest */
11188                 CHECK_BYTE_COUNT_TRANS(2);
11189                 si->info_level = tvb_get_letohs(tvb, offset);
11190                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11191                         t2i->info_level = si->info_level;
11192                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
11193                 COUNT_BYTES_TRANS(2);
11194
11195 #if 0
11196                 /*
11197                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11198                  * Extensions Version 3.0, Document Version 1.11,
11199                  * July 19, 1990" says this is I/O flags, but it's
11200                  * reserved in the SNIA spec, and some clients appear
11201                  * to leave junk in it.
11202                  *
11203                  * Is this some field used only if a particular
11204                  * dialect was negotiated, so that clients can feel
11205                  * safe not setting it if they haven't negotiated that
11206                  * dialect?  Or do the (non-OS/2) clients simply not care
11207                  * about that particular OS/2-oriented dialect?
11208                  */
11209
11210                 /* IO Flag */
11211                 CHECK_BYTE_COUNT_TRANS(2);
11212                 offset = dissect_sfi_ioflag(tvb, tree, offset);
11213                 bc -= 2;
11214 #else
11215                 /* 2 reserved bytes */
11216                 CHECK_BYTE_COUNT_TRANS(2);
11217                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
11218                 COUNT_BYTES_TRANS(2);
11219 #endif
11220
11221                 break;
11222         }
11223         case 0x0009:    /*TRANS2_FSCTL*/
11224                 /* this call has no parameter block in the request */
11225
11226                 /*
11227                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11228                  * Extensions Version 3.0, Document Version 1.11,
11229                  * July 19, 1990" says this this contains a
11230                  * "File system specific parameter block".  (That means
11231                  * we may not be able to dissect it in any case.)
11232                  */
11233                 break;
11234         case 0x000a:    /*TRANS2_IOCTL2*/
11235                 /* this call has no parameter block in the request */
11236
11237                 /*
11238                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11239                  * Extensions Version 3.0, Document Version 1.11,
11240                  * July 19, 1990" says this this contains a
11241                  * "Device/function specific parameter block".  (That
11242                  * means we may not be able to dissect it in any case.)
11243                  */
11244                 break;
11245         case 0x000b:    /*TRANS2_FIND_NOTIFY_FIRST*/
11246                 /* Search Attributes */
11247                 CHECK_BYTE_COUNT_TRANS(2);
11248                 offset = dissect_search_attributes(tvb, tree, offset);
11249                 bc -= 2;
11250
11251                 /* Number of changes to wait for */
11252                 CHECK_BYTE_COUNT_TRANS(2);
11253                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11254                 COUNT_BYTES_TRANS(2);
11255
11256                 /* Find Notify information level */
11257                 CHECK_BYTE_COUNT_TRANS(2);
11258                 si->info_level = tvb_get_letohs(tvb, offset);
11259                 if ((t2i != NULL) && !pinfo->fd->flags.visited)
11260                         t2i->info_level = si->info_level;
11261                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
11262                 COUNT_BYTES_TRANS(2);
11263
11264                 /* 4 reserved bytes */
11265                 CHECK_BYTE_COUNT_TRANS(4);
11266                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11267                 COUNT_BYTES_TRANS(4);
11268
11269                 /* file name */
11270                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11271                 CHECK_STRING_TRANS(fn);
11272                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11273                         fn);
11274                 COUNT_BYTES_TRANS(fn_len);
11275
11276                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
11277                             format_text(fn, strlen(fn)));
11278
11279                 break;
11280         case 0x000c:    /*TRANS2_FIND_NOTIFY_NEXT*/
11281                 /* Monitor handle */
11282                 CHECK_BYTE_COUNT_TRANS(2);
11283                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11284                 COUNT_BYTES_TRANS(2);
11285
11286                 /* Number of changes to wait for */
11287                 CHECK_BYTE_COUNT_TRANS(2);
11288                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11289                 COUNT_BYTES_TRANS(2);
11290
11291                 break;
11292         case 0x000d:    /*TRANS2_CREATE_DIRECTORY*/
11293                 /* 4 reserved bytes */
11294                 CHECK_BYTE_COUNT_TRANS(4);
11295                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
11296                 COUNT_BYTES_TRANS(4);
11297
11298                 /* dir name */
11299                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
11300                         FALSE, FALSE, &bc);
11301                 CHECK_STRING_TRANS(fn);
11302                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
11303                         fn);
11304                 COUNT_BYTES_TRANS(fn_len);
11305
11306                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
11307                             format_text(fn, strlen(fn)));
11308                 break;
11309         case 0x000e:    /*TRANS2_SESSION_SETUP*/
11310                 /* XXX unknown structure*/
11311                 break;
11312         case 0x0010:    /*TRANS2_GET_DFS_REFERRAL*/
11313                 offset = dissect_get_dfs_request_data(tvb, pinfo, tree, offset, &bc, si->unicode);
11314                 break;
11315         case 0x0011:    /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11316                 /* file name */
11317                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
11318                 CHECK_STRING_TRANS(fn);
11319                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11320                         fn);
11321                 COUNT_BYTES_TRANS(fn_len);
11322
11323                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
11324                             format_text(fn, strlen(fn)));
11325                 break;
11326         }
11327
11328         /* ooops there were data we didnt know how to process */
11329         if (bc != 0) {
11330                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, ENC_NA);
11331                 offset += bc;
11332         }
11333
11334         return offset;
11335 }
11336
11337 /*
11338  * XXX - just use "dissect_connect_flags()" here?
11339  */
11340 static guint16
11341 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11342 {
11343         guint16     mask;
11344         proto_item *item;
11345         proto_tree *tree;
11346
11347         mask = tvb_get_letohs(tvb, offset);
11348
11349         if (parent_tree) {
11350                 item = proto_tree_add_item(parent_tree, hf_smb_transaction_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11351                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
11352
11353                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
11354                         tvb, offset, 2, mask);
11355                 proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
11356                         tvb, offset, 2, mask);
11357         }
11358
11359         return mask;
11360 }
11361
11362
11363 static int
11364 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11365 {
11366         guint16     mask;
11367         proto_item *item;
11368         proto_tree *tree;
11369
11370         mask = tvb_get_letohs(tvb, offset);
11371
11372         if (parent_tree) {
11373                 item = proto_tree_add_item(parent_tree, hf_smb_get_dfs_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11374                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
11375
11376                 proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
11377                         tvb, offset, 2, mask);
11378                 proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
11379                         tvb, offset, 2, mask);
11380         }
11381
11382         offset += 2;
11383         return offset;
11384 }
11385
11386 static int
11387 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11388 {
11389         guint16     mask;
11390         proto_item *item;
11391         proto_tree *tree;
11392
11393         mask = tvb_get_letohs(tvb, offset);
11394
11395         if (parent_tree) {
11396                 item = proto_tree_add_item(parent_tree, hf_smb_dfs_referral_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11397                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
11398
11399                 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_name_list_referral,
11400                         tvb, offset, 2, mask);
11401                 proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_target_set_boundary,
11402                         tvb, offset, 2, mask);
11403         }
11404
11405         offset += 2;
11406
11407         return offset;
11408 }
11409
11410
11411 /* dfs inconsistency data  (4.4.2)
11412 */
11413 static int
11414 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo _U_,
11415     proto_tree *tree, int offset, guint16 *bcp, smb_info_t *si)
11416 {
11417         int         fn_len;
11418         const char *fn;
11419
11420         DISSECTOR_ASSERT(si);
11421
11422         /*XXX shouldn this data hold version and size? unclear from doc*/
11423         /* referral version */
11424         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11425         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11426         COUNT_BYTES_TRANS_SUBR(2);
11427
11428         /* referral size */
11429         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11430         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11431         COUNT_BYTES_TRANS_SUBR(2);
11432
11433         /* referral server type */
11434         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11435         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11436         COUNT_BYTES_TRANS_SUBR(2);
11437
11438         /* referral flags */
11439         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11440         offset = dissect_dfs_referral_flags(tvb, tree, offset);
11441         *bcp  -= 2;
11442
11443         /* node name */
11444         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11445         CHECK_STRING_TRANS_SUBR(fn);
11446         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11447                 fn);
11448         COUNT_BYTES_TRANS_SUBR(fn_len);
11449
11450         return offset;
11451 }
11452
11453 static int
11454 dissect_dfs_referral_strings(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11455                              int nstring, int stroffset, int oldoffset, int offset,
11456                              guint16 bc, gboolean unicode, int *end)
11457 {
11458         int         istring;
11459         const char *str;
11460         int         str_len;    /* string length including the terminating NULL. */
11461
11462         if (stroffset <= oldoffset)
11463                 return oldoffset;
11464
11465         bc -= (stroffset - offset);
11466         for (istring = 0; istring < nstring; istring++) {
11467                 if ((gint16)bc > 0) {
11468                         str = get_unicode_or_ascii_string(tvb, &stroffset, unicode, &str_len, FALSE, FALSE, &bc);
11469                         CHECK_STRING_TRANS_SUBR(str);
11470                         proto_tree_add_string(tree, hfindex, tvb, stroffset, str_len, str);
11471                         stroffset += str_len;
11472                         bc -= str_len;
11473                         if (end && (*end < stroffset))
11474                                 *end = stroffset;
11475                 }
11476         }
11477
11478         return offset;
11479 }
11480
11481
11482 static int
11483 dissect_dfs_referral_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
11484                             int stroffset, int oldoffset, int offset,
11485                             guint16 bc, gboolean unicode, int *end)
11486 {
11487         return dissect_dfs_referral_strings(tvb, tree, hfindex,
11488                                            1, stroffset, oldoffset, offset,
11489                                            bc, unicode, end);
11490 }
11491
11492 static int
11493 dissect_dfs_referral_entry_v2(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11494                               guint16 refflags _U_, guint16 *bcp, gboolean unicode, int *ucstring_end)
11495 {
11496
11497         guint16 pathoffset;
11498         guint16 altpathoffset;
11499         guint16 nodeoffset;
11500
11501         /* proximity */
11502         CHECK_BYTE_COUNT_TRANS_SUBR(4);
11503         proto_tree_add_item(tree, hf_smb_dfs_referral_proximity, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11504         COUNT_BYTES_TRANS_SUBR(4);
11505
11506         /* ttl */
11507         CHECK_BYTE_COUNT_TRANS_SUBR(4);
11508         proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11509         COUNT_BYTES_TRANS_SUBR(4);
11510
11511         /* path offset */
11512         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11513         pathoffset = tvb_get_letohs(tvb, offset);
11514         proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11515         COUNT_BYTES_TRANS_SUBR(2);
11516
11517         /* alt path offset */
11518         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11519         altpathoffset = tvb_get_letohs(tvb, offset);
11520         proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11521         COUNT_BYTES_TRANS_SUBR(2);
11522
11523         /* node offset */
11524         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11525         nodeoffset = tvb_get_letohs(tvb, offset);
11526         proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11527         COUNT_BYTES_TRANS_SUBR(2);
11528
11529         /* path */
11530         if (pathoffset) {
11531                 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11532                                             pathoffset+oldoffset, oldoffset, offset,
11533                                             *bcp, unicode, ucstring_end);
11534         }
11535
11536         /* alt path */
11537         if (altpathoffset) {
11538                 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11539                                             altpathoffset+oldoffset, oldoffset, offset,
11540                                             *bcp, unicode, ucstring_end);
11541         }
11542
11543         /* node */
11544         if (nodeoffset) {
11545                 dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11546                                             nodeoffset+oldoffset, oldoffset, offset,
11547                                             *bcp, unicode, ucstring_end);
11548         }
11549
11550         return offset;
11551
11552 }
11553
11554
11555 static int
11556 dissect_dfs_referral_entry_v3(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
11557                               guint16 refflags, guint16 *bcp, gboolean unicode, int *ucstring_end)
11558 {
11559         guint16 domoffset;
11560         guint16 nexpnames;
11561         guint16 expoffset;
11562         guint16 pathoffset;
11563         guint16 altpathoffset;
11564         guint16 nodeoffset;
11565
11566         /* ttl */
11567         CHECK_BYTE_COUNT_TRANS_SUBR(4);
11568         proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11569         COUNT_BYTES_TRANS_SUBR(4);
11570
11571         if (refflags & REFENT_FLAGS_NAME_LIST_REFERRAL) {
11572                 /* domain name offset */
11573                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11574                 domoffset = tvb_get_letohs(tvb, offset);
11575                 proto_tree_add_uint(tree, hf_smb_dfs_referral_domain_offset, tvb, offset, 2, domoffset);
11576                 COUNT_BYTES_TRANS_SUBR(2);
11577
11578                 /* number of expanded names*/
11579                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11580                 nexpnames = tvb_get_letohs(tvb, offset);
11581                 proto_tree_add_uint(tree, hf_smb_dfs_referral_number_of_expnames, tvb, offset, 2, nexpnames);
11582                 COUNT_BYTES_TRANS_SUBR(2);
11583
11584                 /* expanded names offset */
11585                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11586                 expoffset = tvb_get_letohs(tvb, offset);
11587                 proto_tree_add_uint(tree, hf_smb_dfs_referral_expnames_offset, tvb, offset, 2, expoffset);
11588                 COUNT_BYTES_TRANS_SUBR(2);
11589
11590                 /* padding: zero or 16 bytes, which should be ignored by clients.
11591                  * we ignore them too.
11592                  */
11593
11594                 /* domain name */
11595                 if (domoffset) {
11596                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_domain_name,
11597                                                     domoffset+oldoffset, oldoffset, offset,
11598                                                     *bcp, unicode, ucstring_end);
11599                 }
11600                 /* expanded names */
11601                 if (expoffset) {
11602                         proto_item *expitem = NULL;
11603                         proto_tree *exptree = NULL;
11604
11605                         expitem = proto_tree_add_text(tree, tvb, offset, *bcp, "Expanded Names");
11606                         exptree = proto_item_add_subtree(expitem, ett_smb_dfs_referral_expnames);
11607
11608                         dissect_dfs_referral_strings(tvb, exptree, hf_smb_dfs_referral_expname,
11609                                                      nexpnames, expoffset+oldoffset, oldoffset, offset,
11610                                                      *bcp, unicode, ucstring_end);
11611                 }
11612         } else {
11613                 /* path offset */
11614                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11615                 pathoffset = tvb_get_letohs(tvb, offset);
11616                 proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
11617                 COUNT_BYTES_TRANS_SUBR(2);
11618
11619                 /* alt path offset */
11620                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11621                 altpathoffset = tvb_get_letohs(tvb, offset);
11622                 proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
11623                 COUNT_BYTES_TRANS_SUBR(2);
11624
11625                 /* node offset */
11626                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11627                 nodeoffset = tvb_get_letohs(tvb, offset);
11628                 proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
11629                 COUNT_BYTES_TRANS_SUBR(2);
11630
11631                 /* service site guid */
11632                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
11633                 proto_tree_add_item(tree, hf_smb_dfs_referral_server_guid, tvb, offset, 16, ENC_NA);
11634                 COUNT_BYTES_TRANS_SUBR(16);
11635
11636                 /* path */
11637                 if (pathoffset) {
11638                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
11639                                                     pathoffset+oldoffset, oldoffset, offset,
11640                                                     *bcp, unicode, ucstring_end);
11641                 }
11642
11643                 /* alt path */
11644                 if (altpathoffset) {
11645                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
11646                                                     altpathoffset+oldoffset, oldoffset, offset,
11647                                                     *bcp, unicode, ucstring_end);
11648                 }
11649
11650                 /* node */
11651                 if (nodeoffset) {
11652                         dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
11653                                                     nodeoffset+oldoffset, oldoffset, offset,
11654                                                     *bcp, unicode, ucstring_end);
11655                 }
11656         }
11657
11658         return offset;
11659
11660 }
11661
11662 /* get dfs referral data  (4.4.1)
11663 */
11664 int
11665 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo _U_,
11666     proto_tree *tree, int offset, guint16 *bcp, gboolean unicode)
11667 {
11668         guint16     numref;
11669         guint16     refsize;
11670         guint16     refflags;
11671         int         fn_len;
11672         const char *fn;
11673         int         unklen;
11674         int         ucstring_end;
11675         int         ucstring_len;
11676
11677         /* path consumed */
11678         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11679         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11680         COUNT_BYTES_TRANS_SUBR(2);
11681
11682         /* num referrals */
11683         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11684         numref = tvb_get_letohs(tvb, offset);
11685         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
11686         COUNT_BYTES_TRANS_SUBR(2);
11687
11688         /* get dfs flags */
11689         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11690         offset = dissect_get_dfs_flags(tvb, tree, offset);
11691         *bcp -= 2;
11692
11693         /* XXX - in at least one capture there appears to be 2 bytes
11694            of stuff after the Dfs flags, perhaps so that the header
11695            in front of the referral list is a multiple of 4 bytes long. */
11696         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11697         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, ENC_NA);
11698         COUNT_BYTES_TRANS_SUBR(2);
11699
11700         /* if there are any referrals */
11701         if (numref) {
11702                 proto_item *ref_item = NULL;
11703                 proto_tree *ref_tree = NULL;
11704                 int old_offset = offset;
11705
11706                 if (tree) {
11707                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
11708                         ref_item = proto_tree_add_text(tree,
11709                                 tvb, offset, *bcp, "Referrals");
11710                         ref_tree = proto_item_add_subtree(ref_item,
11711                                 ett_smb_dfs_referrals);
11712                 }
11713                 ucstring_end = -1;
11714
11715                 while (numref--) {
11716                         proto_item *ri = NULL;
11717                         proto_tree *rt = NULL;
11718                         int old_offset_2 = offset;
11719                         guint16 version;
11720
11721                         if (tree) {
11722                                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
11723                                 ri = proto_tree_add_text(ref_tree,
11724                                         tvb, offset, *bcp, "Referral");
11725                                 rt = proto_item_add_subtree(ri,
11726                                         ett_smb_dfs_referral);
11727                         }
11728
11729                         /* referral version */
11730                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11731                         version = tvb_get_letohs(tvb, offset);
11732                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
11733                                 tvb, offset, 2, version);
11734                         COUNT_BYTES_TRANS_SUBR(2);
11735
11736                         /* referral size */
11737                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11738                         refsize = tvb_get_letohs(tvb, offset);
11739                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
11740                         COUNT_BYTES_TRANS_SUBR(2);
11741
11742                         /* referral server type */
11743                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11744                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
11745                         COUNT_BYTES_TRANS_SUBR(2);
11746
11747                         /* referral flags */
11748                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
11749                         refflags = tvb_get_letohs(tvb, offset);
11750                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
11751                         *bcp -= 2;
11752
11753                         switch(version) {
11754
11755                         case 1:
11756                                 /* node name */
11757                                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, bcp);
11758                                 CHECK_STRING_TRANS_SUBR(fn);
11759                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
11760                                         fn);
11761                                 COUNT_BYTES_TRANS_SUBR(fn_len);
11762                                 break;
11763
11764                         case 2:
11765                                 offset = dissect_dfs_referral_entry_v2(tvb, rt, old_offset_2, offset,
11766                                                                        refflags, bcp, unicode, &ucstring_end);
11767                                 break;
11768                         case 3:
11769                                 offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
11770                                                                        refflags, bcp, unicode, &ucstring_end);
11771                                 break;
11772                         case 4:
11773                                 /* V4 is extactly same as V3, except the version number and
11774                                  * one more ReferralEntryFlags */
11775                                 offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
11776                                                                        refflags, bcp, unicode, &ucstring_end);
11777                                 break;
11778                         }
11779
11780                         /*
11781                          * Show anything beyond the length of the referral
11782                          * as unknown data.
11783                          */
11784                         unklen = (old_offset_2 + refsize) - offset;
11785                         if (unklen < 0) {
11786                                 /*
11787                                  * XXX - the length is bogus.
11788                                  */
11789                                 unklen = 0;
11790                         }
11791                         if (unklen != 0) {
11792                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
11793                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
11794                                     offset, unklen, ENC_NA);
11795                                 COUNT_BYTES_TRANS_SUBR(unklen);
11796                         }
11797
11798                         proto_item_set_len(ri, offset-old_offset_2);
11799                 }
11800
11801                 /*
11802                  * Treat the offset past the end of the last Unicode
11803                  * string after the referrals (if any) as the last
11804                  * offset.
11805                  */
11806                 if (ucstring_end > offset) {
11807                         ucstring_len = ucstring_end - offset;
11808                         if (*bcp < ucstring_len)
11809                                 ucstring_len = *bcp;
11810                         offset += ucstring_len;
11811                         *bcp -= ucstring_len;
11812                 }
11813                 proto_item_set_len(ref_item, offset-old_offset);
11814         }
11815
11816         return offset;
11817 }
11818
11819 /* This dissects the standard four 8-byte Windows timestamps ...
11820  */
11821 static int
11822 dissect_smb_standard_8byte_timestamps(tvbuff_t *tvb,
11823     packet_info *pinfo _U_, proto_tree *tree,
11824     int offset, guint16 *bcp, gboolean *trunc)
11825 {
11826         /* create time */
11827         CHECK_BYTE_COUNT_SUBR(8);
11828         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
11829         *bcp -= 8;
11830
11831         /* access time */
11832         CHECK_BYTE_COUNT_SUBR(8);
11833         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_access_time);
11834         *bcp -= 8;
11835
11836         /* last write time */
11837         CHECK_BYTE_COUNT_SUBR(8);
11838         offset = dissect_nt_64bit_time(tvb, tree, offset,
11839                 hf_smb_last_write_time);
11840         *bcp -= 8;
11841
11842         /* last change time */
11843         CHECK_BYTE_COUNT_SUBR(8);
11844         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_change_time);
11845         *bcp -= 8;
11846
11847         *trunc = FALSE;
11848         return offset;
11849 }
11850
11851 /* this dissects the SMB_INFO_STANDARD
11852    as described in 4.2.16.1 of the CIFS 1.0 specification
11853    or as described in 2.2.8.3.1 of the MS-CIFS specification for query
11854    section 2.2.8.4.1 of the MS-CIFS specification describes it for set;
11855    it says that everything past the last write time is "reserved",
11856    presumably meaning that you can fetch it but not set it
11857    for now we just use it for both query and set
11858 */
11859 static int
11860 dissect_qsfi_SMB_INFO_STANDARD(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11861     int offset, guint16 *bcp, gboolean *trunc)
11862 {
11863         /* create time */
11864         CHECK_BYTE_COUNT_SUBR(4);
11865         offset = dissect_smb_datetime(tvb, tree, offset,
11866                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11867                 FALSE);
11868         *bcp -= 4;
11869
11870         /* access time */
11871         CHECK_BYTE_COUNT_SUBR(4);
11872         offset = dissect_smb_datetime(tvb, tree, offset,
11873                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11874                 FALSE);
11875         *bcp -= 4;
11876
11877         /* last write time */
11878         CHECK_BYTE_COUNT_SUBR(4);
11879         offset = dissect_smb_datetime(tvb, tree, offset,
11880                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11881                 FALSE);
11882         *bcp -= 4;
11883
11884         /* data size */
11885         CHECK_BYTE_COUNT_SUBR(4);
11886         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11887         COUNT_BYTES_SUBR(4);
11888
11889         /* allocation size */
11890         CHECK_BYTE_COUNT_SUBR(4);
11891         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11892         COUNT_BYTES_SUBR(4);
11893
11894         /* File Attributes */
11895         CHECK_BYTE_COUNT_SUBR(2);
11896         offset = dissect_file_attributes(tvb, tree, offset);
11897         *bcp -= 2;
11898
11899         /*
11900          * The MS-CIFS spec says this doesn't have an EA length field;
11901          * the SNIA CIFS spec says it does, as does the 1996
11902          * "Microsoft Networks SMB FILE SHARING PROTOCOL Document
11903          * Version 6.0p" document.
11904          *
11905          * Some older SMB documents point to the documentation
11906          * for the OS/2 DosQFileInfo() API; the page at
11907          *
11908          *      http://cyberkinetica.homeunix.net/os2tk45/prcp/111_L2_DosQFileInfo.html
11909          *
11910          * says that, for level 1 (SMB_INFO_STANDARD), there is no EA
11911          * length - that's just for level 2 (SMB_INFO_QUERY_EA_SIZE).
11912          *
11913          * I've seen captures with it and without it; given the mixed
11914          * messages sent by different documents, this is not surprising.
11915          *
11916          * We display it if it's there; we don't set *trunc if it's
11917          * not.
11918          *
11919          * Note: in FIND_FIRST2/FIND_NEXT2, the EA length is *not*
11920          * present.
11921          */
11922         if (*bcp != 0) {
11923                 CHECK_BYTE_COUNT_SUBR(4);
11924                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset,
11925                     4, ENC_LITTLE_ENDIAN);
11926                 COUNT_BYTES_SUBR(4);
11927         }
11928
11929         *trunc = FALSE;
11930         return offset;
11931 }
11932
11933 /* this dissects the SMB_INFO_QUERY_EA_SIZE
11934    as described in 4.2.16.1 of the CIFS 1.0 specification
11935    and as described in 2.2.8.3.2 of the MS-CIFS specification
11936 */
11937 static int
11938 dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11939     int offset, guint16 *bcp, gboolean *trunc)
11940 {
11941         /* create time */
11942         CHECK_BYTE_COUNT_SUBR(4);
11943         offset = dissect_smb_datetime(tvb, tree, offset,
11944                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
11945                 FALSE);
11946         *bcp -= 4;
11947
11948         /* access time */
11949         CHECK_BYTE_COUNT_SUBR(4);
11950         offset = dissect_smb_datetime(tvb, tree, offset,
11951                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
11952                 FALSE);
11953         *bcp -= 4;
11954
11955         /* last write time */
11956         CHECK_BYTE_COUNT_SUBR(4);
11957         offset = dissect_smb_datetime(tvb, tree, offset,
11958                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
11959                 FALSE);
11960         *bcp -= 4;
11961
11962         /* data size */
11963         CHECK_BYTE_COUNT_SUBR(4);
11964         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11965         COUNT_BYTES_SUBR(4);
11966
11967         /* allocation size */
11968         CHECK_BYTE_COUNT_SUBR(4);
11969         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11970         COUNT_BYTES_SUBR(4);
11971
11972         /* File Attributes */
11973         CHECK_BYTE_COUNT_SUBR(2);
11974         offset = dissect_file_attributes(tvb, tree, offset);
11975         *bcp -= 2;
11976
11977         /* ea length */
11978         CHECK_BYTE_COUNT_SUBR(4);
11979         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11980         COUNT_BYTES_SUBR(4);
11981
11982         *trunc = FALSE;
11983         return offset;
11984 }
11985
11986 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
11987    as described in 4.2.16.2
11988 */
11989 static int
11990 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11991     int offset, guint16 *bcp, gboolean *trunc)
11992 {
11993         guint8  name_len;
11994         guint16 data_len;
11995         /* EA size */
11996
11997         CHECK_BYTE_COUNT_SUBR(4);
11998         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
11999         COUNT_BYTES_SUBR(4);
12000
12001         while (*bcp > 0) {
12002                 proto_item *item;
12003                 proto_tree *subtree;
12004                 int start_offset = offset;
12005                 guint8 *name;
12006
12007                 item = proto_tree_add_text(
12008                         tree, tvb, offset, 0, "Extended Attribute");
12009                 subtree = proto_item_add_subtree(item, ett_smb_ea);
12010
12011                 /* EA flags */
12012
12013                 CHECK_BYTE_COUNT_SUBR(1);
12014                 proto_tree_add_item(
12015                         subtree, hf_smb_ea_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12016                 COUNT_BYTES_SUBR(1);
12017
12018                 /* EA name length */
12019
12020                 name_len = tvb_get_guint8(tvb, offset);
12021
12022                 CHECK_BYTE_COUNT_SUBR(1);
12023                 proto_tree_add_item(
12024                         subtree, hf_smb_ea_name_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12025                 COUNT_BYTES_SUBR(1);
12026
12027                 /* EA data length */
12028
12029                 data_len = tvb_get_letohs(tvb, offset);
12030
12031                 CHECK_BYTE_COUNT_SUBR(2);
12032                 proto_tree_add_item(
12033                         subtree, hf_smb_ea_data_length, tvb, offset, 2, ENC_NA);
12034                 COUNT_BYTES_SUBR(2);
12035
12036                 /* EA name */
12037
12038                 name = tvb_get_string(wmem_packet_scope(), tvb, offset, name_len);
12039                 proto_item_append_text(item, ": %s", format_text(name, strlen(name)));
12040
12041                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
12042                 proto_tree_add_item(
12043                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
12044                         ENC_ASCII|ENC_NA);
12045                 COUNT_BYTES_SUBR(name_len + 1);
12046
12047                 /* EA data */
12048
12049                 CHECK_BYTE_COUNT_SUBR(data_len);
12050                 proto_tree_add_item(
12051                         subtree, hf_smb_ea_data, tvb, offset, data_len, ENC_NA);
12052                 COUNT_BYTES_SUBR(data_len);
12053
12054                 proto_item_set_len(item, offset - start_offset);
12055         }
12056
12057         *trunc = FALSE;
12058         return offset;
12059 }
12060
12061 /* this dissects the SMB_INFO_IS_NAME_VALID
12062    as described in 4.2.16.3
12063 */
12064 static int
12065 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12066     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12067 {
12068         int         fn_len;
12069         const char *fn;
12070
12071         DISSECTOR_ASSERT(si);
12072
12073         /* file name */
12074         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12075         CHECK_STRING_SUBR(fn);
12076         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12077                 fn);
12078         COUNT_BYTES_SUBR(fn_len);
12079
12080         *trunc = FALSE;
12081         return offset;
12082 }
12083
12084 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
12085    as described in 4.2.16.4
12086 */
12087 static int
12088 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12089     int offset, guint16 *bcp, gboolean *trunc)
12090 {
12091
12092         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12093         if (*trunc) {
12094           return offset;
12095         }
12096
12097         /* File Attributes */
12098         CHECK_BYTE_COUNT_SUBR(4);
12099         offset = dissect_file_ext_attr(tvb, tree, offset);
12100         *bcp -= 4;
12101
12102         *trunc = FALSE;
12103         return offset;
12104 }
12105
12106 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
12107    as described in 4.2.16.5 of the SNIA CIFS spec
12108    and section 2.2.8.3.7 of the MS-CIFS spec
12109 */
12110 int
12111 dissect_qfi_SMB_FILE_STANDARD_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12112     int offset, guint16 *bcp, gboolean *trunc)
12113 {
12114         /* allocation size */
12115         CHECK_BYTE_COUNT_SUBR(8);
12116         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12117         COUNT_BYTES_SUBR(8);
12118
12119         /* end of file */
12120         CHECK_BYTE_COUNT_SUBR(8);
12121         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12122         COUNT_BYTES_SUBR(8);
12123
12124         /* number of links */
12125         CHECK_BYTE_COUNT_SUBR(4);
12126         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12127         COUNT_BYTES_SUBR(4);
12128
12129         /* delete pending */
12130         CHECK_BYTE_COUNT_SUBR(1);
12131         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12132         COUNT_BYTES_SUBR(1);
12133
12134         /* is directory */
12135         CHECK_BYTE_COUNT_SUBR(1);
12136         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12137         COUNT_BYTES_SUBR(1);
12138
12139         *trunc = FALSE;
12140         return offset;
12141 }
12142
12143 /* this dissects the SMB_QUERY_FILE_INTERNAL_INFO
12144 */
12145 int
12146 dissect_qfi_SMB_FILE_INTERNAL_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12147     int offset, guint16 *bcp, gboolean *trunc)
12148 {
12149         /* file id */
12150         CHECK_BYTE_COUNT_SUBR(8);
12151         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12152         COUNT_BYTES_SUBR(8);
12153
12154         *trunc = FALSE;
12155         return offset;
12156 }
12157
12158 /* this dissects the SMB_QUERY_FILE_POSITION_INFO
12159 */
12160 int
12161 dissect_qsfi_SMB_FILE_POSITION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12162     int offset, guint16 *bcp, gboolean *trunc)
12163 {
12164         /* file position */
12165         CHECK_BYTE_COUNT_SUBR(8);
12166         proto_tree_add_item(tree, hf_smb_position, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12167         COUNT_BYTES_SUBR(8);
12168
12169         *trunc = FALSE;
12170         return offset;
12171 }
12172
12173 /* this dissects the SMB_QUERY_FILE_MODE_INFO
12174 */
12175 int
12176 dissect_qsfi_SMB_FILE_MODE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12177     int offset, guint16 *bcp, gboolean *trunc)
12178 {
12179         /* mode */
12180         CHECK_BYTE_COUNT_SUBR(4);
12181         proto_tree_add_item(tree, hf_smb_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12182         COUNT_BYTES_SUBR(4);
12183
12184         *trunc = FALSE;
12185         return offset;
12186 }
12187
12188 /* this dissects the SMB_QUERY_FILE_ALIGNMENT_INFO
12189 */
12190 int
12191 dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12192     int offset, guint16 *bcp, gboolean *trunc)
12193 {
12194         /* alignment */
12195         CHECK_BYTE_COUNT_SUBR(4);
12196         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12197         COUNT_BYTES_SUBR(4);
12198
12199         *trunc = FALSE;
12200         return offset;
12201 }
12202
12203 /* this dissects the SMB_QUERY_FILE_EA_INFO
12204    as described in 4.2.16.6 of the SNIA CIFS spec
12205    and 2.2.8.3.8 of the MS-CIFS spec
12206 */
12207 int
12208 dissect_qfi_SMB_FILE_EA_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12209     int offset, guint16 *bcp, gboolean *trunc)
12210 {
12211         /* ea length */
12212         CHECK_BYTE_COUNT_SUBR(4);
12213         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12214         COUNT_BYTES_SUBR(4);
12215
12216         *trunc = FALSE;
12217         return offset;
12218 }
12219
12220 /* this dissects the SMB_FILE_ALLOCATION_INFO
12221    as described in 4.2.19.3 in the SNIA CIFS spec
12222    and the SMB_SET_FILE_ALLOCATION_INFO
12223    as described in 2.2.8.4.5 in the MS-CIFS spec for set (MS-CIFS doesn't
12224    say it can be queried)
12225 */
12226 int
12227 dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12228     int offset, guint16 *bcp, gboolean *trunc)
12229 {
12230         /* allocation size */
12231         CHECK_BYTE_COUNT_SUBR(8);
12232         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12233         COUNT_BYTES_SUBR(8);
12234
12235         *trunc = FALSE;
12236         return offset;
12237 }
12238
12239 /* this dissects the SMB_FILE_ENDOFFILE_INFO
12240    as described in 4.2.19.4 in the SNIA CIFS spec
12241    and the SMB_SET_FILE_END_OF_FILE_INFO
12242    as described in 2.2.8.4.6 in the MS-CIFS spec for set (MS-CIFS doesn't
12243    say it can be queried)
12244 */
12245 int
12246 dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12247     int offset, guint16 *bcp, gboolean *trunc)
12248 {
12249         /* offset of end of file */
12250         CHECK_BYTE_COUNT_SUBR(8);
12251         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12252         COUNT_BYTES_SUBR(8);
12253
12254         *trunc = FALSE;
12255         return offset;
12256 }
12257
12258 /* this dissects the SMB_QUERY_FILE_NAME_INFO
12259    as described in 4.2.16.7 of the SNIA CIFS spec
12260    and in 2.2.8.3.9 of the MS-CIFS spec
12261    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
12262    as described in 4.2.16.9 of the SNIA CIFS spec
12263    and 2.2.8.3.11 of the MS-CIFS spec
12264    although the latter two are used to fetch the 8.3 name
12265    rather than the long name
12266 */
12267 int
12268 dissect_qfi_SMB_FILE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12269     int offset, guint16 *bcp, gboolean *trunc, gboolean unicode)
12270 {
12271         int         fn_len;
12272         const char *fn;
12273
12274         /* file name len */
12275         CHECK_BYTE_COUNT_SUBR(4);
12276         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12277         COUNT_BYTES_SUBR(4);
12278
12279         /* file name */
12280         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, FALSE, bcp);
12281         CHECK_STRING_SUBR(fn);
12282         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12283                 fn);
12284         COUNT_BYTES_SUBR(fn_len);
12285
12286         *trunc = FALSE;
12287         return offset;
12288 }
12289
12290 /* this dissects the SMB_QUERY_FILE_ALL_INFO
12291    as described in 2.2.8.3.8 of the MS-CIFS spec
12292    but not as described in 4.2.16.8 since SNIA spec is wrong
12293 */
12294 static int
12295 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12296     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12297 {
12298         guint32     fn_len;
12299         const char *fn;
12300
12301         DISSECTOR_ASSERT(si);
12302
12303         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12304         if (*trunc) {
12305           return offset;
12306         }
12307
12308         /* File Attributes */
12309         CHECK_BYTE_COUNT_SUBR(4);
12310         offset = dissect_file_ext_attr(tvb, tree, offset);
12311         *bcp   -= 4;
12312
12313         /* 4 pad bytes */
12314         offset += 4;
12315         *bcp   -= 4;
12316
12317         /* allocation size */
12318         CHECK_BYTE_COUNT_SUBR(8);
12319         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12320         COUNT_BYTES_SUBR(8);
12321
12322         /* end of file */
12323         CHECK_BYTE_COUNT_SUBR(8);
12324         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12325         COUNT_BYTES_SUBR(8);
12326
12327         /* number of links */
12328         CHECK_BYTE_COUNT_SUBR(4);
12329         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12330         COUNT_BYTES_SUBR(4);
12331
12332         /* delete pending */
12333         CHECK_BYTE_COUNT_SUBR(1);
12334         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12335         COUNT_BYTES_SUBR(1);
12336
12337         /* is directory */
12338         CHECK_BYTE_COUNT_SUBR(1);
12339         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12340         COUNT_BYTES_SUBR(1);
12341
12342         /* 2 pad bytes */
12343         offset += 2;
12344         *bcp   -= 2;
12345
12346         /* ea length */
12347         CHECK_BYTE_COUNT_SUBR(4);
12348         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12349         COUNT_BYTES_SUBR(4);
12350
12351         /* file name len */
12352         CHECK_BYTE_COUNT_SUBR(4);
12353         fn_len = (guint32)tvb_get_letohl(tvb, offset);
12354         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12355         COUNT_BYTES_SUBR(4);
12356
12357
12358         /* file name */
12359         CHECK_BYTE_COUNT_SUBR(fn_len);
12360         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
12361         if (fn != NULL) {
12362                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12363                         fn);
12364                 COUNT_BYTES_SUBR(fn_len);
12365         }
12366
12367
12368         if (*trunc)
12369                 return offset;
12370
12371         return offset;
12372 }
12373
12374 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
12375    as described in 4.2.16.10 of the SNIA CIFS spec
12376    and 2.2.8.3.12 of the MS-CIFS spec
12377 */
12378 int
12379 dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
12380     int offset, guint16 *bcp, gboolean *trunc, int unicode)
12381 {
12382         proto_item *item;
12383         proto_tree *tree;
12384         int         old_offset;
12385         guint32     neo;
12386         int         fn_len;
12387         const char *fn;
12388         int         padcnt;
12389
12390
12391         for (;;) {
12392                 old_offset = offset;
12393
12394                 /* next entry offset */
12395                 CHECK_BYTE_COUNT_SUBR(4);
12396                 if (parent_tree) {
12397                         tvb_ensure_bytes_exist(tvb, offset, *bcp);
12398                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
12399                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12400                 } else {
12401                         item = NULL;
12402                         tree = NULL;
12403                 }
12404
12405                 neo = tvb_get_letohl(tvb, offset);
12406                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12407                 COUNT_BYTES_SUBR(4);
12408
12409                 /* stream name len */
12410                 CHECK_BYTE_COUNT_SUBR(4);
12411                 fn_len = tvb_get_letohl(tvb, offset);
12412                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
12413                 COUNT_BYTES_SUBR(4);
12414
12415                 /* stream size */
12416                 CHECK_BYTE_COUNT_SUBR(8);
12417                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12418                 COUNT_BYTES_SUBR(8);
12419
12420                 /* allocation size */
12421                 CHECK_BYTE_COUNT_SUBR(8);
12422                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12423                 COUNT_BYTES_SUBR(8);
12424
12425                 /* stream name */
12426                 fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
12427                 CHECK_STRING_SUBR(fn);
12428                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
12429                         fn);
12430                 COUNT_BYTES_SUBR(fn_len);
12431
12432                 proto_item_append_text(item, ": %s", format_text(fn, strlen(fn)));
12433                 proto_item_set_len(item, offset-old_offset);
12434
12435                 if (neo == 0)
12436                         break;  /* no more structures */
12437
12438                 /* skip to next structure */
12439                 padcnt = (old_offset + neo) - offset;
12440                 if (padcnt < 0) {
12441                         /*
12442                          * XXX - this is bogus; flag it?
12443                          */
12444                         padcnt = 0;
12445                 }
12446                 if (padcnt != 0) {
12447                         CHECK_BYTE_COUNT_SUBR(padcnt);
12448                         COUNT_BYTES_SUBR(padcnt);
12449                 }
12450         }
12451
12452         *trunc = FALSE;
12453         return offset;
12454 }
12455
12456 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
12457    as described in 4.2.16.11 of the SNIA CIFS spec
12458    and 2.2.8.3.13 of the MS-CIFS spec
12459 */
12460 int
12461 dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12462     int offset, guint16 *bcp, gboolean *trunc)
12463 {
12464         /* compressed file size */
12465         CHECK_BYTE_COUNT_SUBR(8);
12466         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12467         COUNT_BYTES_SUBR(8);
12468
12469         /* compression format */
12470         CHECK_BYTE_COUNT_SUBR(2);
12471         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12472         COUNT_BYTES_SUBR(2);
12473
12474         /* compression unit shift */
12475         CHECK_BYTE_COUNT_SUBR(1);
12476         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12477         COUNT_BYTES_SUBR(1);
12478
12479         /* compression chunk shift */
12480         CHECK_BYTE_COUNT_SUBR(1);
12481         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12482         COUNT_BYTES_SUBR(1);
12483
12484         /* compression cluster shift */
12485         CHECK_BYTE_COUNT_SUBR(1);
12486         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12487         COUNT_BYTES_SUBR(1);
12488
12489         /* 3 reserved bytes */
12490         CHECK_BYTE_COUNT_SUBR(3);
12491         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, ENC_NA);
12492         COUNT_BYTES_SUBR(3);
12493
12494         *trunc = FALSE;
12495         return offset;
12496 }
12497
12498 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
12499
12500 static const value_string unix_file_type_vals[] = {
12501         { 0, "File" },
12502         { 1, "Directory" },
12503         { 2, "Symbolic link" },
12504         { 3, "Character device" },
12505         { 4, "Block device" },
12506         { 5, "FIFO" },
12507         { 6, "Socket" },
12508         { 0, NULL }
12509 };
12510
12511 static int
12512 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12513                   int offset, guint16 *bcp, gboolean *trunc)
12514 {
12515         /* End of file (file size) */
12516         CHECK_BYTE_COUNT_SUBR(8);
12517         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12518         COUNT_BYTES_SUBR(8);
12519
12520         /* Number of bytes */
12521         CHECK_BYTE_COUNT_SUBR(8);
12522         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12523         COUNT_BYTES_SUBR(8);
12524
12525         /* Last status change */
12526         CHECK_BYTE_COUNT_SUBR(8);
12527         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12528         *bcp -= 8;              /* dissect_nt_64bit_time() increments offset */
12529
12530         /* Last access time */
12531         CHECK_BYTE_COUNT_SUBR(8);
12532         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12533         *bcp -= 8;
12534
12535         /* Last modification time */
12536         CHECK_BYTE_COUNT_SUBR(8);
12537         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12538         *bcp -= 8;
12539
12540         /* File owner uid */
12541         CHECK_BYTE_COUNT_SUBR(8);
12542         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12543         COUNT_BYTES_SUBR(8);
12544
12545         /* File group gid */
12546         CHECK_BYTE_COUNT_SUBR(8);
12547         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12548         COUNT_BYTES_SUBR(8);
12549
12550         /* File type */
12551         CHECK_BYTE_COUNT_SUBR(4);
12552         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12553         COUNT_BYTES_SUBR(4);
12554
12555         /* Major device number */
12556         CHECK_BYTE_COUNT_SUBR(8);
12557         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12558         COUNT_BYTES_SUBR(8);
12559
12560         /* Minor device number */
12561         CHECK_BYTE_COUNT_SUBR(8);
12562         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12563         COUNT_BYTES_SUBR(8);
12564
12565         /* Unique id */
12566         CHECK_BYTE_COUNT_SUBR(8);
12567         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12568         COUNT_BYTES_SUBR(8);
12569
12570         /* Permissions */
12571         CHECK_BYTE_COUNT_SUBR(8);
12572         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12573         COUNT_BYTES_SUBR(8);
12574
12575         /* Nlinks */
12576         CHECK_BYTE_COUNT_SUBR(8);
12577         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12578         COUNT_BYTES_SUBR(8);
12579
12580         /* Sometimes there is one extra byte in the data field which I
12581            guess could be padding, but we are only using 4 or 8 byte
12582            data types so this is a bit confusing. -tpot */
12583
12584         *trunc = FALSE;
12585         return offset;
12586 }
12587
12588 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
12589
12590 static int
12591 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12592                   int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
12593 {
12594         const char *fn;
12595         int         fn_len = 0;
12596
12597         DISSECTOR_ASSERT(si);
12598
12599         /* Link destination */
12600
12601         fn = get_unicode_or_ascii_string(
12602                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12603
12604         CHECK_STRING_SUBR(fn);
12605         proto_tree_add_string(
12606                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
12607         COUNT_BYTES_SUBR(fn_len);
12608
12609         *trunc = FALSE;
12610         return offset;
12611 }
12612
12613 /* unix ACL
12614 */
12615 static int
12616 dissect_qspi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12617                   int offset, guint16 *bcp, gboolean *trunc)
12618 {
12619         guint16 num_file_aces;
12620         static const int *perm_fields[] = {
12621                 &hf_smb_posix_ace_perm_read,
12622                 &hf_smb_posix_ace_perm_write,
12623                 &hf_smb_posix_ace_perm_execute,
12624                 NULL
12625         };
12626
12627         /* version */
12628         CHECK_BYTE_COUNT_SUBR(2);
12629         proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12630         COUNT_BYTES_SUBR(2);
12631
12632         /* num file acls */
12633         CHECK_BYTE_COUNT_SUBR(2);
12634         num_file_aces = tvb_get_letohs(tvb, offset);
12635         proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12636         COUNT_BYTES_SUBR(2);
12637
12638         /* num default acls */
12639         CHECK_BYTE_COUNT_SUBR(2);
12640         proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12641         COUNT_BYTES_SUBR(2);
12642
12643         while (num_file_aces--) {
12644                 proto_item *it;
12645                 proto_tree *tr;
12646                 int old_offset = offset;
12647                 guint8 ace_type;
12648
12649                 it = proto_tree_add_text(tree, tvb, offset, 0, "ACE");
12650                 tr = proto_item_add_subtree(it, ett_smb_posix_ace);
12651
12652                 /* ace type */
12653                 CHECK_BYTE_COUNT_SUBR(1);
12654                 ace_type = tvb_get_guint8(tvb, offset);
12655                 proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12656                 COUNT_BYTES_SUBR(1);
12657
12658                 CHECK_BYTE_COUNT_SUBR(1);
12659                 proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, ENC_BIG_ENDIAN);
12660                 COUNT_BYTES_SUBR(1);
12661
12662                 switch(ace_type) {
12663                 case POSIX_ACE_TYPE_USER_OBJ:
12664                         CHECK_BYTE_COUNT_SUBR(4);
12665                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12666                         COUNT_BYTES_SUBR(4);
12667
12668                         CHECK_BYTE_COUNT_SUBR(4);
12669                         /* 4 reserved bytes */
12670                         COUNT_BYTES_SUBR(4);
12671                         break;
12672                 case POSIX_ACE_TYPE_GROUP_OBJ:
12673                         CHECK_BYTE_COUNT_SUBR(4);
12674                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12675                         COUNT_BYTES_SUBR(4);
12676
12677                         CHECK_BYTE_COUNT_SUBR(4);
12678                         /* 4 reserved bytes */
12679                         COUNT_BYTES_SUBR(4);
12680                         break;
12681
12682                 case POSIX_ACE_TYPE_MASK:
12683                 case POSIX_ACE_TYPE_OTHER:
12684                         CHECK_BYTE_COUNT_SUBR(8);
12685                         /* 8 reserved bytes */
12686                         COUNT_BYTES_SUBR(8);
12687                         break;
12688
12689                 case POSIX_ACE_TYPE_USER:
12690                         CHECK_BYTE_COUNT_SUBR(4);
12691                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12692                         COUNT_BYTES_SUBR(4);
12693
12694                         CHECK_BYTE_COUNT_SUBR(4);
12695                         /* 4 reserved bytes */
12696                         COUNT_BYTES_SUBR(4);
12697                         break;
12698
12699                 case POSIX_ACE_TYPE_GROUP:
12700                         CHECK_BYTE_COUNT_SUBR(4);
12701                         proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12702                         COUNT_BYTES_SUBR(4);
12703
12704                         CHECK_BYTE_COUNT_SUBR(4);
12705                         /* 4 reserved bytes */
12706                         COUNT_BYTES_SUBR(4);
12707                         break;
12708                 default:
12709                         proto_tree_add_text(tr, tvb, offset, 0, "Unknown posix ace type");
12710                         CHECK_BYTE_COUNT_SUBR(8);
12711                         /* skip 8 bytes */
12712                         COUNT_BYTES_SUBR(8);
12713                 }
12714
12715                 proto_item_set_len(it, offset-old_offset);
12716         }
12717
12718         *trunc = FALSE;
12719         return offset;
12720 }
12721
12722 static int
12723 dissect_qspi_unix_xattr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12724                   int offset, guint16 *bcp _U_, gboolean *trunc)
12725 {
12726         proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12727
12728         *trunc = FALSE;
12729         return offset;
12730 }
12731
12732 static int
12733 dissect_qspi_unix_attr_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12734                   int offset, guint16 *bcp _U_, gboolean *trunc)
12735 {
12736         proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12737
12738         *trunc = FALSE;
12739         return offset;
12740 }
12741
12742 static int
12743 dissect_qpi_unix_permissions(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12744                   int offset, guint16 *bcp _U_, gboolean *trunc)
12745 {
12746         proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12747
12748         *trunc = FALSE;
12749         return offset;
12750 }
12751
12752 static int
12753 dissect_qspi_unix_lock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12754                   int offset, guint16 *bcp _U_, gboolean *trunc)
12755 {
12756         proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12757
12758         *trunc = FALSE;
12759         return offset;
12760 }
12761
12762 static int
12763 dissect_qspi_unix_open(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12764                   int offset, guint16 *bcp _U_, gboolean *trunc)
12765 {
12766         proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12767
12768         *trunc = FALSE;
12769         return offset;
12770 }
12771
12772 static int
12773 dissect_qspi_unix_unlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
12774                   int offset, guint16 *bcp _U_, gboolean *trunc)
12775 {
12776         proto_tree_add_expert(tree, pinfo, &ei_smb_not_implemented, tvb, offset, 0);
12777
12778         *trunc = FALSE;
12779         return offset;
12780 }
12781
12782 /* SMB_FIND_FILE_UNIX_INFO2 */
12783
12784 #if 0
12785 static const true_false_string tfs_i2f_secure_delete = {
12786         "File should be erased such that the data is not recoverable",
12787         "File need not be erased such that the data is not recoverable"
12788 };
12789 static const true_false_string tfs_i2f_enable_undelete = {
12790         "File should opt-in to a server-specific deletion recovery scheme",
12791         "File should not opt-in to a server-specific deletion recovery scheme"
12792 };
12793 static const true_false_string tfs_i2f_synchronous = {
12794         "I/O to this file should be performed synchronously",
12795         "I/O to this file need not be performed synchronously"
12796 };
12797 static const true_false_string tfs_i2f_immutable = {
12798         "NO changes can be made to this file",
12799         "Changes can be made to this file if permissions allow it"
12800 };
12801 static const true_false_string tfs_i2f_append_only = {
12802         "Only appends can be made to this file",
12803         "Writes can be made atop existing data in this file"
12804 };
12805 static const true_false_string tfs_i2f_do_not_backup = {
12806         "Backup programs should ignore this file",
12807         "Backup programs should not ignore this file"
12808 };
12809 static const true_false_string tfs_i2f_no_update_atime = {
12810         "The server is not required to update the last access time on this file",
12811         "The server is required to update the last access time on this file"
12812 };
12813 static const true_false_string tfs_i2f_hidden = {
12814         "User interface programs may ignore this file",
12815         "User interface programs should not ignore this file based solely on this flag"
12816 };
12817 #endif
12818
12819 static int
12820 dissect_unix_info2_file_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int hf)
12821 {
12822         guint32     flags;
12823         proto_item *item = NULL;
12824         proto_tree *tree = NULL;
12825
12826         flags = tvb_get_letohl(tvb, offset);
12827
12828         if (parent_tree) {
12829                 item = proto_tree_add_uint(parent_tree, hf, tvb, offset, 4,
12830                         flags);
12831                 tree = proto_item_add_subtree(item, ett_smb_info2_file_flags);
12832         }
12833
12834         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_secure_delete,
12835                 tvb, offset, 4, flags);
12836         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_enable_undelete,
12837                 tvb, offset, 4, flags);
12838         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_synchronous,
12839                 tvb, offset, 4, flags);
12840         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_immutable,
12841                 tvb, offset, 4, flags);
12842         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_append_only,
12843                 tvb, offset, 4, flags);
12844         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_do_not_backup,
12845                 tvb, offset, 4, flags);
12846         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_no_update_atime,
12847                 tvb, offset, 4, flags);
12848         proto_tree_add_boolean(tree, hf_smb_unix_info2_file_flags_hidden,
12849                 tvb, offset, 4, flags);
12850
12851         offset += 4;
12852
12853         return offset;
12854 }
12855
12856 static int
12857 dissect_qspi_unix_info2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
12858                   int offset, guint16 *bcp, gboolean *trunc)
12859 {
12860         /* End of file (file size) */
12861         CHECK_BYTE_COUNT_SUBR(8);
12862         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12863         COUNT_BYTES_SUBR(8);
12864
12865         /* Number of bytes (or blocks?  The SNIA spec for UNIX basic
12866            info says "bytes", the Samba page for this says "blocks") */
12867         CHECK_BYTE_COUNT_SUBR(8);
12868         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12869         COUNT_BYTES_SUBR(8);
12870
12871         /* Last status change */
12872         CHECK_BYTE_COUNT_SUBR(8);
12873         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12874         *bcp -= 8;
12875
12876         /* Last access time */
12877         CHECK_BYTE_COUNT_SUBR(8);
12878         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12879         *bcp -= 8;
12880
12881         /* Last modification time */
12882         CHECK_BYTE_COUNT_SUBR(8);
12883         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12884         *bcp -= 8;
12885
12886         /* File owner uid */
12887         CHECK_BYTE_COUNT_SUBR(8);
12888         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12889         COUNT_BYTES_SUBR(8);
12890
12891         /* File group gid */
12892         CHECK_BYTE_COUNT_SUBR(8);
12893         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12894         COUNT_BYTES_SUBR(8);
12895
12896         /* File type */
12897         CHECK_BYTE_COUNT_SUBR(4);
12898         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12899         COUNT_BYTES_SUBR(4);
12900
12901         /* Major device number */
12902         CHECK_BYTE_COUNT_SUBR(8);
12903         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12904         COUNT_BYTES_SUBR(8);
12905
12906         /* Minor device number */
12907         CHECK_BYTE_COUNT_SUBR(8);
12908         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12909         COUNT_BYTES_SUBR(8);
12910
12911         /* Unique id */
12912         CHECK_BYTE_COUNT_SUBR(8);
12913         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12914         COUNT_BYTES_SUBR(8);
12915
12916         /* Permissions */
12917         CHECK_BYTE_COUNT_SUBR(8);
12918         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12919         COUNT_BYTES_SUBR(8);
12920
12921         /* Nlinks */
12922         CHECK_BYTE_COUNT_SUBR(8);
12923         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12924         COUNT_BYTES_SUBR(8);
12925
12926         /* Creation time */
12927         CHECK_BYTE_COUNT_SUBR(8);
12928         offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_unix_file_creation_time);
12929         *bcp -= 8;
12930
12931         /* File flags */
12932         CHECK_BYTE_COUNT_SUBR(4);
12933         offset = dissect_unix_info2_file_flags(tvb, tree, offset, hf_smb_unix_info2_file_flags);
12934         *bcp -= 4;
12935
12936         /* File flags mask */
12937         CHECK_BYTE_COUNT_SUBR(4);
12938         offset = dissect_unix_info2_file_flags(tvb, tree, offset, hf_smb_unix_info2_file_flags_mask);
12939         *bcp -= 4;
12940
12941         *trunc = FALSE;
12942         return offset;
12943 }
12944
12945 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
12946 */
12947 int
12948 dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
12949     packet_info *pinfo, proto_tree *tree,
12950     int offset, guint16 *bcp, gboolean *trunc)
12951 {
12952
12953         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
12954         if (*trunc) {
12955                 return offset;
12956         }
12957
12958         /* allocation size */
12959         CHECK_BYTE_COUNT_SUBR(8);
12960         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12961         COUNT_BYTES_SUBR(8);
12962
12963         /* end of file */
12964         CHECK_BYTE_COUNT_SUBR(8);
12965         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
12966         COUNT_BYTES_SUBR(8);
12967
12968         /* File Attributes */
12969         CHECK_BYTE_COUNT_SUBR(4);
12970         offset = dissect_file_ext_attr(tvb, tree, offset);
12971         *bcp -= 4;
12972
12973         /* 4 reserved bytes */
12974         CHECK_BYTE_COUNT_SUBR(4);
12975         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12976         COUNT_BYTES_SUBR(4);
12977
12978         *trunc = FALSE;
12979         return offset;
12980 }
12981
12982 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
12983 */
12984 int
12985 dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
12986     packet_info *pinfo _U_, proto_tree *tree,
12987     int offset, guint16 *bcp, gboolean *trunc)
12988 {
12989         /* attribute */
12990         CHECK_BYTE_COUNT_SUBR(4);
12991         proto_tree_add_item(tree, hf_smb_attribute, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12992         COUNT_BYTES_SUBR(4);
12993
12994         /* reparse tag */
12995         CHECK_BYTE_COUNT_SUBR(4);
12996         proto_tree_add_item(tree, hf_smb_reparse_tag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12997         COUNT_BYTES_SUBR(4);
12998
12999         *trunc = FALSE;
13000         return offset;
13001 }
13002
13003 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
13004    as described in 4.2.19.2
13005 */
13006 static int
13007 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13008     int offset, guint16 *bcp, gboolean *trunc)
13009 {
13010         /* marked for deletion? */
13011         CHECK_BYTE_COUNT_SUBR(1);
13012         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13013         COUNT_BYTES_SUBR(1);
13014
13015         *trunc = FALSE;
13016         return offset;
13017 }
13018
13019 /* Set File Rename Info */
13020
13021 static const true_false_string tfs_smb_replace = {
13022         "Remove target file if it exists",
13023         "Do NOT remove target file if it exists",
13024 };
13025
13026 static int
13027 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13028                     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13029 {
13030         const char *fn;
13031         guint32     target_name_len;
13032         int         fn_len;
13033
13034         DISSECTOR_ASSERT(si);
13035
13036         /* Replace flag */
13037         CHECK_BYTE_COUNT_SUBR(4);
13038         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13039         COUNT_BYTES_SUBR(4);
13040
13041         /* Root directory handle */
13042         CHECK_BYTE_COUNT_SUBR(4);
13043         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, ENC_LITTLE_ENDIAN);
13044         COUNT_BYTES_SUBR(4);
13045
13046         /* Target name length */
13047         CHECK_BYTE_COUNT_SUBR(4);
13048         target_name_len = tvb_get_letohl(tvb, offset);
13049         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
13050         COUNT_BYTES_SUBR(4);
13051
13052         /* Target name */
13053         fn_len = target_name_len;
13054         fn = get_unicode_or_ascii_string(
13055                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13056
13057         CHECK_STRING_SUBR(fn);
13058         proto_tree_add_string(
13059                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
13060         COUNT_BYTES_SUBR(fn_len);
13061
13062         *trunc = FALSE;
13063         return offset;
13064 }
13065
13066 static int
13067 dissect_disposition_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13068                     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
13069 {
13070 #if 0
13071         const char *fn;
13072         guint32     target_name_len;*/
13073         int         fn_len;
13074 #endif
13075
13076         DISSECTOR_ASSERT(si);
13077
13078         /* Disposition flags */
13079         CHECK_BYTE_COUNT_SUBR(1);
13080         proto_tree_add_item(tree, hf_smb_disposition_delete_on_close, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13081         COUNT_BYTES_SUBR(1);
13082
13083         *trunc = FALSE;
13084         return offset;
13085 }
13086
13087 int
13088 dissect_sfi_SMB_FILE_PIPE_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
13089                     int offset, guint16 *bcp, gboolean *trunc)
13090 {
13091         /* pipe info flag */
13092         CHECK_BYTE_COUNT_SUBR(1);
13093         proto_tree_add_item(tree, hf_smb_pipe_info_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
13094         COUNT_BYTES_SUBR(1);
13095
13096         *trunc = FALSE;
13097         return offset;
13098 }
13099
13100 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
13101   TRANS2_QUERY_FILE_INFORMATION*/
13102 static int
13103 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13104     proto_item *item, int offset, guint16 *bcp, smb_info_t *si)
13105 {
13106         gboolean    trunc = FALSE;
13107
13108         if (!*bcp) {
13109                 return offset;
13110         }
13111
13112         DISSECTOR_ASSERT(si);
13113
13114         switch(si->info_level) {
13115         case 1:         /*Info Standard*/
13116                 offset = dissect_qsfi_SMB_INFO_STANDARD(tvb, pinfo, tree, offset, bcp,
13117                     &trunc);
13118                 break;
13119
13120         case 2:         /*Info Query EA Size*/
13121                 offset = dissect_qfi_SMB_INFO_QUERY_EA_SIZE(tvb, pinfo, tree, offset, bcp,
13122                     &trunc);
13123                 break;
13124         case 3:         /*Info Query EAs From List*/
13125         case 4:         /*Info Query All EAs*/
13126                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13127                     &trunc);
13128                 break;
13129         case 6:         /*Info Is Name Valid*/
13130                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
13131                     &trunc, si);
13132                 break;
13133         case 0x0101:    /*Query File Basic Info*/
13134         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
13135                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
13136                     &trunc);
13137                 break;
13138         case 0x0102:    /*Query File Standard Info*/
13139         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
13140                 offset = dissect_qfi_SMB_FILE_STANDARD_INFO(tvb, pinfo, tree, offset, bcp,
13141                     &trunc);
13142                 break;
13143         case 1006:      /* SMB_FILE_INTERNAL_INFORMATION */
13144                 offset = dissect_qfi_SMB_FILE_INTERNAL_INFO(tvb, pinfo, tree, offset, bcp,
13145                     &trunc);
13146                 break;
13147         case 0x0103:    /*Query File EA Info*/
13148         case 1007:      /* SMB_FILE_EA_INFORMATION */
13149                 offset = dissect_qfi_SMB_FILE_EA_INFO(tvb, pinfo, tree, offset, bcp,
13150                     &trunc);
13151                 break;
13152         case 0x0104:    /*Query File Name Info*/
13153         case 1009:      /* SMB_FILE_NAME_INFORMATION */
13154                 offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
13155                     &trunc, si->unicode);
13156                 break;
13157         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
13158                 offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
13159                     &trunc);
13160                 break;
13161         case 1016:      /* SMB_FILE_MODE_INFORMATION */
13162                 offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
13163                     &trunc);
13164                 break;
13165         case 1017:      /* SMB_FILE_ALIGNMENT_INFORMATION */
13166                 offset = dissect_qfi_SMB_FILE_ALIGNMENT_INFO(tvb, pinfo, tree, offset, bcp,
13167                     &trunc);
13168                 break;
13169         case 0x0107:    /*Query File All Info*/
13170         case 1018:      /* SMB_FILE_ALL_INFORMATION */
13171                 offset = dissect_qfi_SMB_FILE_ALL_INFO(tvb, pinfo, tree, offset, bcp,
13172                     &trunc, si);
13173                 break;
13174         case 1019:      /* SMB_FILE_ALLOCATION_INFORMATION */
13175                 offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
13176                     &trunc);
13177                 break;
13178         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
13179                 offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
13180                     &trunc);
13181                 break;
13182         case 0x0108:    /*Query File Alt File Info*/
13183         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
13184                 offset = dissect_qfi_SMB_FILE_NAME_INFO(tvb, pinfo, tree, offset, bcp,
13185                     &trunc, si->unicode);
13186                 break;
13187         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
13188                 si->unicode = TRUE;
13189                 /* FALLTHRU */
13190         case 0x0109:    /*Query File Stream Info*/
13191                 offset = dissect_qfi_SMB_FILE_STREAM_INFO(tvb, pinfo, tree, offset, bcp,
13192                     &trunc, si->unicode);
13193                 break;
13194         case 0x010b:    /*Query File Compression Info*/
13195         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
13196                 offset = dissect_qfi_SMB_FILE_COMPRESSION_INFO(tvb, pinfo, tree, offset, bcp,
13197                     &trunc);
13198                 break;
13199         case 1034:     /* SMB_FILE_NETWORK_OPEN_INFO */
13200                 offset = dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
13201                 break;
13202         case 1035:     /* SMB_FILE_ATTRIBUTE_TAG_INFO */
13203                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
13204                 break;
13205         case 0x0200:    /* Query File Unix Basic*/
13206                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
13207                                            &trunc);
13208                 break;
13209         case 0x0201:    /* Query File Unix Link*/
13210                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13211                                            &trunc, si);
13212                 break;
13213         case 0x0202:    /* Query File Unix HardLink*/
13214                 /* XXX add this from the SNIA doc */
13215                 break;
13216         case 0x0204:    /* Query File Unix ACL*/
13217                 offset = dissect_qspi_unix_acl(tvb, pinfo, tree, offset, bcp,
13218                                            &trunc);
13219                 break;
13220         case 0x0205:    /* Query File Unix XATTR*/
13221                 offset = dissect_qspi_unix_xattr(tvb, pinfo, tree, offset, bcp,
13222                                            &trunc);
13223                 break;
13224         case 0x0206:    /* Query File Unix Attr Flags*/
13225                 offset = dissect_qspi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
13226                                            &trunc);
13227                 break;
13228         case 0x0207:    /* Query File Unix Permissions*/
13229                 offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
13230                                            &trunc);
13231                 break;
13232         case 0x0208:    /* Query File Unix Lock*/
13233                 offset = dissect_qspi_unix_lock(tvb, pinfo, tree, offset, bcp,
13234                                            &trunc);
13235                 break;
13236         case 0x020b:    /* Query File Unix Info2*/
13237                 offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp,
13238                                            &trunc);
13239                 break;
13240
13241         default:
13242                 proto_tree_add_text(tree, tvb, offset, *bcp,
13243                     "Information level unknown");
13244                 offset += *bcp;
13245                 *bcp = 0;
13246                 trunc = FALSE;
13247                 break;
13248         }
13249
13250         if (trunc) {
13251                 expert_add_info(pinfo, item, &ei_smb_mal_information_level);
13252         }
13253         return offset;
13254 }
13255
13256 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
13257   TRANS2_SET_FILE_INFORMATION*/
13258 static int
13259 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13260     proto_item *item, int offset, guint16 *bcp, smb_info_t *si)
13261 {
13262         gboolean    trunc;
13263
13264         if (!*bcp) {
13265                 return offset;
13266         }
13267
13268         DISSECTOR_ASSERT(si);
13269
13270         switch(si->info_level) {
13271         case 1:         /*Info Standard*/
13272                 offset = dissect_qsfi_SMB_INFO_STANDARD(tvb, pinfo, tree, offset, bcp,
13273                     &trunc);
13274                 break;
13275         case 2:         /*Info Set EAs*/
13276                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13277                     &trunc);
13278                 break;
13279         case 4:         /*Info Query All EAs - not in [MS-CIFS]*/
13280                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
13281                     &trunc);
13282                 break;
13283         case 0x0101:    /*Set File Basic Info*/
13284         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
13285                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
13286                     &trunc);
13287                 break;
13288         case 0x0102:    /*Set File Disposition Info*/
13289                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
13290                     &trunc);
13291                 break;
13292         case 0x0103:    /*Set File Allocation Info*/
13293         case 1019:      /* Set File Allocation Information */
13294                 offset = dissect_qsfi_SMB_FILE_ALLOCATION_INFO(tvb, pinfo, tree, offset, bcp,
13295                     &trunc);
13296                 break;
13297         case 0x0104:    /*Set End Of File Info*/
13298         case 1020:      /* SMB_FILE_ENDOFFILE_INFORMATION */
13299                 offset = dissect_qsfi_SMB_FILE_ENDOFFILE_INFO(tvb, pinfo, tree, offset, bcp,
13300                     &trunc);
13301                 break;
13302         case 0x0200:    /*Set File Unix Basic.  Same as query. */
13303                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
13304                     &trunc);
13305                 break;
13306         case 0x0201:    /*Set File Unix Link.  Same as query. */
13307                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13308                     &trunc, si);
13309                 break;
13310         case 0x0202:    /*Set File Unix HardLink.  Same as link query. */
13311                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
13312                     &trunc, si);
13313                 break;
13314         case 0x0204:    /* Set File Unix ACL*/
13315                 offset = dissect_qspi_unix_acl(tvb, pinfo, tree, offset, bcp,
13316                                            &trunc);
13317                 break;
13318         case 0x0205:    /* Set File Unix XATTR*/
13319                 offset = dissect_qspi_unix_xattr(tvb, pinfo, tree, offset, bcp,
13320                                            &trunc);
13321                 break;
13322         case 0x0206:    /* Set File Unix Attr Flags*/
13323                 offset = dissect_qspi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
13324                                            &trunc);
13325                 break;
13326         case 0x0208:    /* Set File Unix Lock*/
13327                 offset = dissect_qspi_unix_lock(tvb, pinfo, tree, offset, bcp,
13328                                            &trunc);
13329                 break;
13330         case 0x0209:    /* Set File Unix Open*/
13331                 offset = dissect_qspi_unix_open(tvb, pinfo, tree, offset, bcp,
13332                                            &trunc);
13333                 break;
13334         case 0x020a:    /* Set File Unix Unlink*/
13335                 offset = dissect_qspi_unix_unlink(tvb, pinfo, tree, offset, bcp,
13336                                            &trunc);
13337                 break;
13338         case 0x020b:    /* Set File Unix Info2*/
13339                 offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp,
13340                                            &trunc);
13341                 break;
13342         case 1010:      /* Set File Rename */
13343                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
13344                     &trunc, si);
13345                 break;
13346         case 1013: /* Set Disposition Information */
13347                 offset = dissect_disposition_info(tvb, pinfo, tree, offset, bcp,
13348                     &trunc, si);
13349                 break;
13350         case 1014:      /* SMB_FILE_POSITION_INFORMATION */
13351                 offset = dissect_qsfi_SMB_FILE_POSITION_INFO(tvb, pinfo, tree, offset, bcp,
13352                     &trunc);
13353                 break;
13354         case 1016:      /* SMB_FILE_MODE_INFORMATION */
13355                 offset = dissect_qsfi_SMB_FILE_MODE_INFO(tvb, pinfo, tree, offset, bcp,
13356                     &trunc);
13357                 break;
13358         case 1023: /* Set Pipe Info */
13359                 offset = dissect_sfi_SMB_FILE_PIPE_INFO(tvb, pinfo, tree, offset, bcp,
13360                     &trunc);
13361                 break;
13362         case 1025:
13363         case 1029:
13364         case 1032:
13365         case 1039:
13366         case 1040:
13367                 /* XXX: TODO, extra levels discovered by tridge */
13368                 proto_tree_add_text(tree, tvb, offset, *bcp,
13369                     "Information level not understood");
13370                 offset += *bcp;
13371                 *bcp = 0;
13372                 trunc = FALSE;
13373                 break;
13374
13375         default:
13376                 proto_tree_add_text(tree, tvb, offset, *bcp,
13377                     "Information level unknown");
13378                 offset += *bcp;
13379                 *bcp = 0;
13380                 trunc = FALSE;
13381                 break;
13382         }
13383
13384         if (trunc) {
13385                 expert_add_info(pinfo, item, &ei_smb_mal_information_level);
13386         }
13387         return offset;
13388 }
13389
13390
13391 static const true_false_string tfs_quota_flags_deny_disk = {
13392         "DENY DISK SPACE for users exceeding quota limit",
13393         "Do NOT deny disk space for users exceeding quota limit"
13394 };
13395 static const true_false_string tfs_quota_flags_log_limit = {
13396         "LOG EVENT when a user exceeds their QUOTA LIMIT",
13397         "Do NOT log event when a user exceeds their quota limit"
13398 };
13399 static const true_false_string tfs_quota_flags_log_warning = {
13400         "LOG EVENT when a user exceeds their WARNING LEVEL",
13401         "Do NOT log event when a user exceeds their warning level"
13402 };
13403 static const true_false_string tfs_quota_flags_enabled = {
13404         "Quotas are ENABLED of this fs",
13405         "Quotas are NOT enabled on this fs"
13406 };
13407 static void
13408 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13409 {
13410         guint8      mask;
13411         proto_item *item;
13412         proto_tree *tree;
13413
13414         mask = tvb_get_guint8(tvb, offset);
13415
13416         if (parent_tree) {
13417                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
13418                         "Quota Flags: 0x%02x %s", mask,
13419                         mask?"Enabled":"Disabled");
13420                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
13421
13422                 proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
13423                         tvb, offset, 1, mask);
13424                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
13425                         tvb, offset, 1, mask);
13426                 proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
13427                         tvb, offset, 1, mask);
13428
13429                 if (mask && (!(mask&0x01))) {
13430                         proto_item *hidden_item;
13431                         hidden_item = proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
13432                                 tvb, offset, 1, 0x01);
13433                         PROTO_ITEM_SET_HIDDEN(hidden_item);
13434                 } else {
13435                         proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
13436                                 tvb, offset, 1, mask);
13437                 }
13438         }
13439
13440 }
13441
13442 int
13443 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
13444 {
13445         /* first 24 bytes are unknown */
13446         CHECK_BYTE_COUNT_TRANS_SUBR(24);
13447         proto_tree_add_item(tree, hf_smb_unknown, tvb,
13448                     offset, 24, ENC_NA);
13449         COUNT_BYTES_TRANS_SUBR(24);
13450
13451         /* number of bytes for quota warning */
13452         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13453         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13454         COUNT_BYTES_TRANS_SUBR(8);
13455
13456         /* number of bytes for quota limit */
13457         CHECK_BYTE_COUNT_TRANS_SUBR(8);
13458         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13459         COUNT_BYTES_TRANS_SUBR(8);
13460
13461         /* one byte of quota flags */
13462         CHECK_BYTE_COUNT_TRANS_SUBR(1);
13463         dissect_quota_flags(tvb, tree, offset);
13464         COUNT_BYTES_TRANS_SUBR(1);
13465
13466         /* these 7 bytes are unknown */
13467         CHECK_BYTE_COUNT_TRANS_SUBR(7);
13468         proto_tree_add_item(tree, hf_smb_unknown, tvb,
13469                     offset, 7, ENC_NA);
13470         COUNT_BYTES_TRANS_SUBR(7);
13471
13472         return offset;
13473 }
13474
13475 static int
13476 dissect_sfsi_request(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13477     int offset, guint16 *bcp, smb_info_t *si)
13478 {
13479         if (!*bcp) {
13480                 return offset;
13481         }
13482
13483         DISSECTOR_ASSERT(si);
13484
13485         switch(si->info_level) {
13486         case 0x203: /* REQUEST_TRANSPORT_ENCRYPTION */ {
13487                 proto_item *blob_item;
13488                 tvbuff_t *blob_tvb;
13489                 proto_tree *blob_tree;
13490
13491                 /* security blob */
13492                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
13493                                                 tvb, offset,
13494                                                 tvb_length_remaining(tvb, offset),
13495                                                 ENC_NA);
13496
13497                 /* As an optimization, because Windows is perverse,
13498                    we check to see if NTLMSSP is the first part of the
13499                    blob, and if so, call the NTLMSSP dissector,
13500                    otherwise we call the GSS-API dissector. This is because
13501                    Windows can request RAW NTLMSSP, but will happily handle
13502                    a client that wraps NTLMSSP in SPNEGO
13503                 */
13504
13505                 blob_tree = proto_item_add_subtree(blob_item,
13506                                                    ett_smb_secblob);
13507
13508                 blob_tvb = tvb_new_subset_remaining(tvb, offset);
13509
13510                 if (tvb_strneql(blob_tvb, 0, "NTLMSSP", 7) == 0) {
13511                         call_dissector(ntlmssp_handle, blob_tvb, pinfo, blob_tree);
13512                 } else {
13513                         call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
13514                 }
13515
13516                 offset += tvb_length_remaining(tvb, offset);
13517                 *bcp = 0;
13518                 break;
13519         }
13520         case 1006:      /* QUERY_FS_QUOTA_INFO */
13521                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13522                 break;
13523         }
13524
13525         return offset;
13526 }
13527
13528 static int
13529 dissect_sfsi_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13530     int offset, guint16 *bcp, smb_info_t *si)
13531 {
13532         if (!*bcp) {
13533                 return offset;
13534         }
13535
13536         DISSECTOR_ASSERT(si);
13537
13538         switch(si->info_level) {
13539         case 0x203: /* REQUEST_TRANSPORT_ENCRYPTION */ {
13540                 proto_item *blob_item;
13541                 tvbuff_t *blob_tvb;
13542                 proto_tree *blob_tree;
13543
13544                 /* security blob */
13545                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
13546                                                 tvb, offset,
13547                                                 tvb_length_remaining(tvb, offset),
13548                                                 ENC_NA);
13549
13550                 /* As an optimization, because Windows is perverse,
13551                    we check to see if NTLMSSP is the first part of the
13552                    blob, and if so, call the NTLMSSP dissector,
13553                    otherwise we call the GSS-API dissector. This is because
13554                    Windows can request RAW NTLMSSP, but will happily handle
13555                    a client that wraps NTLMSSP in SPNEGO
13556                 */
13557
13558                 blob_tree = proto_item_add_subtree(blob_item,
13559                                                    ett_smb_secblob);
13560
13561                 blob_tvb = tvb_new_subset_remaining(tvb, offset);
13562
13563                 if (tvb_strneql(blob_tvb, 0, "NTLMSSP", 7) == 0) {
13564                         call_dissector(ntlmssp_handle, blob_tvb, pinfo, blob_tree);
13565                 } else {
13566                         call_dissector(gssapi_handle, blob_tvb, pinfo, blob_tree);
13567                 }
13568
13569                 offset += tvb_length_remaining(tvb, offset);
13570                 *bcp = 0;
13571                 break;
13572         }
13573         case 1006:      /* QUERY_FS_QUOTA_INFO */
13574                 /* nothing */
13575                 break;
13576         }
13577
13578         return offset;
13579 }
13580
13581 static int
13582 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
13583     proto_tree *parent_tree, int offset, int subcmd, guint16 dc, smb_info_t *si)
13584 {
13585         proto_item *item = NULL;
13586         proto_tree *tree = NULL;
13587
13588         DISSECTOR_ASSERT(si);
13589
13590         if (parent_tree) {
13591                 tvb_ensure_bytes_exist(tvb, offset, dc);
13592                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13593                                 "%s Data",
13594                                 val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
13595                                                "Unknown (0x%02x)"));
13596                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13597         }
13598
13599         switch(subcmd) {
13600         case 0x0000:    /*TRANS2_OPEN2*/
13601                 /* XXX dont know how to decode FEAList */
13602                 break;
13603         case 0x0001:    /*TRANS2_FIND_FIRST2*/
13604                 /* XXX dont know how to decode FEAList */
13605                 break;
13606         case 0x0002:    /*TRANS2_FIND_NEXT2*/
13607                 /* XXX dont know how to decode FEAList */
13608                 break;
13609         case 0x0003:    /*TRANS2_QUERY_FS_INFORMATION*/
13610                 /* no data field in this request */
13611                 break;
13612         case 0x0004:    /* TRANS2_SET_FS_INFORMATION */
13613                 offset = dissect_sfsi_request(tvb, pinfo, tree, offset, &dc, si);
13614                 break;
13615         case 0x0005:    /*TRANS2_QUERY_PATH_INFORMATION*/
13616                 /* no data field in this request */
13617                 /*
13618                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13619                  * Extensions Version 3.0, Document Version 1.11,
13620                  * July 19, 1990" says there may be "Additional
13621                  * FileInfoLevel dependent information" here.
13622                  *
13623                  * Was that just a cut-and-pasteo?
13624                  * TRANS2_SET_PATH_INFORMATION *does* have that information
13625                  * here.
13626                  */
13627                 break;
13628         case 0x0006:    /*TRANS2_SET_PATH_INFORMATION*/
13629                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
13630                 break;
13631         case 0x0007:    /*TRANS2_QUERY_FILE_INFORMATION*/
13632                 /* no data field in this request */
13633                 /*
13634                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13635                  * Extensions Version 3.0, Document Version 1.11,
13636                  * July 19, 1990" says there may be "Additional
13637                  * FileInfoLevel dependent information" here.
13638                  *
13639                  * Was that just a cut-and-pasteo?
13640                  * TRANS2_SET_FILE_INFORMATION *does* have that information
13641                  * here.
13642                  */
13643                 break;
13644         case 0x0008:    /*TRANS2_SET_FILE_INFORMATION*/
13645                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
13646                 break;
13647         case 0x0009:    /*TRANS2_FSCTL*/
13648                 /*XXX dont know how to decode this yet */
13649
13650                 /*
13651                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13652                  * Extensions Version 3.0, Document Version 1.11,
13653                  * July 19, 1990" says this this contains a
13654                  * "File system specific data block".  (That means we
13655                  * may not be able to dissect it in any case.)
13656                  */
13657                 break;
13658         case 0x000a:    /*TRANS2_IOCTL2*/
13659                 /*XXX dont know how to decode this yet */
13660
13661                 /*
13662                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13663                  * Extensions Version 3.0, Document Version 1.11,
13664                  * July 19, 1990" says this this contains a
13665                  * "Device/function specific data block".  (That
13666                  * means we may not be able to dissect it in any case.)
13667                  */
13668                 break;
13669         case 0x000b:    /*TRANS2_FIND_NOTIFY_FIRST*/
13670                 /*XXX dont know how to decode this yet */
13671
13672                 /*
13673                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13674                  * Extensions Version 3.0, Document Version 1.11,
13675                  * July 19, 1990" says this this contains "additional
13676                  * level dependent match data".
13677                  */
13678                 break;
13679         case 0x000c:    /*TRANS2_FIND_NOTIFY_NEXT*/
13680                 /*XXX dont know how to decode this yet */
13681
13682                 /*
13683                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13684                  * Extensions Version 3.0, Document Version 1.11,
13685                  * July 19, 1990" says this this contains "additional
13686                  * level dependent monitor information".
13687                  */
13688                 break;
13689         case 0x000d:    /*TRANS2_CREATE_DIRECTORY*/
13690                 /* XXX optional FEAList, unknown what FEAList looks like*/
13691                 break;
13692         case 0x000e:    /*TRANS2_SESSION_SETUP*/
13693                 /*XXX dont know how to decode this yet */
13694                 break;
13695         case 0x0010:    /*TRANS2_GET_DFS_REFERRAL*/
13696                 /* no data field in this request */
13697                 break;
13698         case 0x0011:    /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13699                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc, si);
13700                 break;
13701         }
13702
13703         /* ooops there were data we didnt know how to process */
13704         if (dc != 0) {
13705                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, ENC_NA);
13706                 offset += dc;
13707         }
13708
13709         return offset;
13710 }
13711
13712
13713 static void
13714 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
13715     proto_tree *tree)
13716 {
13717         int   i;
13718         int   offset;
13719         guint length;
13720
13721         /*
13722          * Show the setup words.
13723          */
13724         if (s_tvb != NULL) {
13725                 length = tvb_reported_length(s_tvb);
13726                 for (i = 0, offset = 0; length >= 2;
13727                     i++, offset += 2, length -= 2) {
13728                         /*
13729                          * XXX - add a setup word filterable field?
13730                          */
13731                         proto_tree_add_uint_format(tree, hf_smb_trans_data_setup_word, s_tvb, offset, 2,
13732                             tvb_get_letohs(s_tvb, offset), "Setup Word %d: 0x%04x", i, tvb_get_letohs(s_tvb, offset));
13733                 }
13734         }
13735
13736         /*
13737          * Show the parameters, if any.
13738          */
13739         if (p_tvb != NULL) {
13740                 length = tvb_reported_length(p_tvb);
13741                 if (length != 0) {
13742                         proto_tree_add_item(tree, hf_smb_trans_data_parameters, p_tvb, 0, length, ENC_NA);
13743                 }
13744         }
13745
13746         /*
13747          * Show the data, if any.
13748          */
13749         if (d_tvb != NULL) {
13750                 length = tvb_reported_length(d_tvb);
13751                 if (length != 0) {
13752                         proto_tree_add_item(tree, hf_smb_trans_data, d_tvb, 0, length, ENC_NA);
13753                 }
13754         }
13755 }
13756
13757 /* This routine handles the following 4 calls
13758    Transaction  0x25
13759    Transaction Secondary 0x26
13760    Transaction2 0x32
13761    Transaction2 Secondary 0x33
13762 */
13763 static int
13764 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
13765 {
13766         guint8                wc, sc = 0;
13767         int                   so     = offset;
13768         int                   sl     = 0;
13769         int                   spo    = offset;
13770         int                   spc    = 0;
13771         guint16               od     = 0, po = 0, pc = 0, dc = 0, pd, dd = 0;
13772         int                   subcmd = -1;
13773         guint32               to;
13774         int                   an_len;
13775         const char           *an     = NULL;
13776         smb_transact2_info_t *t2i;
13777         smb_transact_info_t  *tri;
13778         guint16               bc;
13779         int                   padcnt;
13780         gboolean              dissected_trans;
13781
13782         DISSECTOR_ASSERT(si);
13783
13784         WORD_COUNT;
13785
13786         if (wc == 8) {
13787                 /*secondary client request*/
13788
13789                 /* total param count, only a 16bit integer here*/
13790                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13791                 offset += 2;
13792
13793                 /* total data count , only 16bit integer here*/
13794                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13795                 offset += 2;
13796
13797                 /* param count */
13798                 pc = tvb_get_letohs(tvb, offset);
13799                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13800                 offset += 2;
13801
13802                 /* param offset */
13803                 po = tvb_get_letohs(tvb, offset);
13804                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13805                 offset += 2;
13806
13807                 /* param disp */
13808                 pd = tvb_get_letohs(tvb, offset);
13809                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13810                 offset += 2;
13811
13812                 /* data count */
13813                 dc = tvb_get_letohs(tvb, offset);
13814                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13815                 offset += 2;
13816
13817                 /* data offset */
13818                 od = tvb_get_letohs(tvb, offset);
13819                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13820                 offset += 2;
13821
13822                 /* data disp */
13823                 dd = tvb_get_letohs(tvb, offset);
13824                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13825                 offset += 2;
13826
13827                 if (si->cmd == SMB_COM_TRANSACTION2) {
13828                         guint16 fid;
13829
13830                         /* fid */
13831                         fid = tvb_get_letohs(tvb, offset);
13832                         dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE, si);
13833
13834                         offset += 2;
13835                 }
13836
13837                 /* There are no setup words. */
13838                 so = offset;
13839                 sl = 0;
13840         } else {
13841                 /* it is not a secondary request */
13842
13843                 /* total param count , only a 16 bit integer here*/
13844                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13845                 offset += 2;
13846
13847                 /* total data count , only 16bit integer here*/
13848                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13849                 offset += 2;
13850
13851                 /* max param count , only 16bit integer here*/
13852                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13853                 offset += 2;
13854
13855                 /* max data count, only 16bit integer here*/
13856                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13857                 offset += 2;
13858
13859                 /* max setup count, only 16bit integer here*/
13860                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13861                 offset += 1;
13862
13863                 /* reserved byte */
13864                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
13865                 offset += 1;
13866
13867                 /* transaction flags */
13868                 dissect_transaction_flags(tvb, tree, offset);
13869                 offset += 2;
13870
13871                 /* timeout */
13872                 to = tvb_get_letohl(tvb, offset);
13873                 proto_tree_add_uint_format_value(tree, hf_smb_timeout, tvb, offset, 4, to, "%s", smbext20_timeout_msecs_to_str(to));
13874                 offset += 4;
13875
13876                 /* 2 reserved bytes */
13877                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
13878                 offset += 2;
13879
13880                 /* param count */
13881                 pc = tvb_get_letohs(tvb, offset);
13882                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13883                 offset += 2;
13884
13885                 /* param offset */
13886                 po = tvb_get_letohs(tvb, offset);
13887                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13888                 offset += 2;
13889
13890                 /* data count */
13891                 dc = tvb_get_letohs(tvb, offset);
13892                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13893                 offset += 2;
13894
13895                 /* data offset */
13896                 od = tvb_get_letohs(tvb, offset);
13897                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13898                 offset += 2;
13899
13900                 /* data displacement is zero here */
13901                 dd = 0;
13902
13903                 /* setup count */
13904                 sc = tvb_get_guint8(tvb, offset);
13905                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13906                 offset += 1;
13907
13908                 /* reserved byte */
13909                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
13910                 offset += 1;
13911
13912                 /* this is where the setup bytes, if any start */
13913                 so = offset;
13914                 sl = sc*2;
13915
13916                 /* if there were any setup bytes, decode them */
13917                 if (sc) {
13918                         switch(si->cmd) {
13919
13920                         case SMB_COM_TRANSACTION2:
13921                                 /* TRANSACTION2 only has one setup word and
13922                                    that is the subcommand code.
13923
13924                                    XXX - except for TRANS2_FSCTL
13925                                    and TRANS2_IOCTL. */
13926                                 subcmd = tvb_get_letohs(tvb, offset);
13927                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
13928                                     tvb, offset, 2, subcmd);
13929                                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13930                                             val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
13931                                                            "Unknown (0x%02x)"));
13932
13933                                 if (!si->unidir) {
13934                                         if (!pinfo->fd->flags.visited && si->sip) {
13935                                                 /*
13936                                                  * Allocate a new
13937                                                  * smb_transact2_info_t
13938                                                  * structure.
13939                                                  */
13940                                                 t2i = (smb_transact2_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_transact2_info_t));
13941                                                 t2i->subcmd = subcmd;
13942                                                 t2i->info_level = -1;
13943                                                 t2i->resume_keys = FALSE;
13944                                                 t2i->name = NULL;
13945                                                 si->sip->extra_info = t2i;
13946                                                 si->sip->extra_info_type = SMB_EI_T2I;
13947                                         }
13948                                 }
13949
13950                                 /*
13951                                  * XXX - process TRANS2_FSCTL and
13952                                  * TRANS2_IOCTL setup words here.
13953                                  */
13954                                 break;
13955
13956                         case SMB_COM_TRANSACTION:
13957                                 /* TRANSACTION setup words processed below */
13958                                 break;
13959                         }
13960
13961                         offset += sl;
13962                 }
13963         }
13964
13965         BYTE_COUNT;
13966
13967         if (wc != 8) {
13968                 /* primary request */
13969                 /* name is NULL if transaction2 */
13970                 if (si->cmd == SMB_COM_TRANSACTION) {
13971                         /* Transaction Name */
13972                         an = get_unicode_or_ascii_string(tvb, &offset,
13973                                 si->unicode, &an_len, FALSE, FALSE, &bc);
13974                         if (an == NULL)
13975                                 goto endofcommand;
13976                         tvb_ensure_bytes_exist(tvb, offset, an_len);
13977                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
13978                                 offset, an_len, an);
13979                         COUNT_BYTES(an_len);
13980                 }
13981         }
13982
13983         /*
13984          * The pipe or mailslot arguments for Transaction start with
13985          * the first setup word (or where the first setup word would
13986          * be if there were any setup words), and run to the current
13987          * offset (which could mean that there aren't any).
13988          */
13989         spo = so;
13990         spc = offset - spo;
13991
13992         /* parameters */
13993         if (po > offset) {
13994                 /* We have some initial padding bytes.
13995                 */
13996                 padcnt = po-offset;
13997                 if (padcnt > bc)
13998                         padcnt = bc;
13999                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
14000                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
14001                 COUNT_BYTES(padcnt);
14002         }
14003         if (pc) {
14004                 CHECK_BYTE_COUNT(pc);
14005                 switch(si->cmd) {
14006
14007                 case SMB_COM_TRANSACTION2:
14008                         /* TRANSACTION2 parameters*/
14009                         offset = dissect_transaction2_request_parameters(tvb,
14010                             pinfo, tree, offset, subcmd, pc, si);
14011                         bc -= pc;
14012                         break;
14013
14014                 case SMB_COM_TRANSACTION:
14015                         /* TRANSACTION parameters processed below */
14016                         COUNT_BYTES(pc);
14017                         break;
14018                 }
14019         }
14020
14021         /* data */
14022         if (od > offset) {
14023                 /* We have some initial padding bytes.
14024                 */
14025                 padcnt = od-offset;
14026                 if (padcnt > bc)
14027                         padcnt = bc;
14028                 tvb_ensure_bytes_exist(tvb, offset, padcnt);
14029                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
14030                 COUNT_BYTES(padcnt);
14031         }
14032         if (dc) {
14033                 CHECK_BYTE_COUNT(dc);
14034                 switch(si->cmd) {
14035
14036                 case SMB_COM_TRANSACTION2:
14037                         /* TRANSACTION2 data*/
14038                         offset = dissect_transaction2_request_data(tvb, pinfo,
14039                             tree, offset, subcmd, dc, si);
14040                         bc -= dc;
14041                         break;
14042
14043                 case SMB_COM_TRANSACTION:
14044                         /* TRANSACTION data processed below */
14045                         COUNT_BYTES(dc);
14046                         break;
14047                 }
14048         }
14049
14050         /*TRANSACTION request parameters */
14051         if (si->cmd == SMB_COM_TRANSACTION) {
14052                 /*XXX replace this block with a function and use that one
14053                      for both requests/responses*/
14054                 if (dd == 0) {
14055                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
14056                         tvbuff_t *sp_tvb, *pd_tvb;
14057
14058                         if (pc > 0) {
14059                                 if (pc>tvb_length_remaining(tvb, po)) {
14060                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
14061                                 } else {
14062                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
14063                                 }
14064                         } else {
14065                                 p_tvb = NULL;
14066                         }
14067                         if (dc > 0) {
14068                                 if (dc>tvb_length_remaining(tvb, od)) {
14069                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
14070                                 } else {
14071                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
14072                                 }
14073                         } else {
14074                                 d_tvb = NULL;
14075                         }
14076                         if (sl) {
14077                                 if (sl>tvb_length_remaining(tvb, so)) {
14078                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
14079                                 } else {
14080                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
14081                                 }
14082                         } else {
14083                                 s_tvb = NULL;
14084                         }
14085
14086                         if (!si->unidir) {
14087                                 if (!pinfo->fd->flags.visited && si->sip) {
14088                                         /*
14089                                          * Allocate a new smb_transact_info_t
14090                                          * structure.
14091                                          */
14092                                         tri = (smb_transact_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_transact_info_t));
14093                                         tri->subcmd = -1;
14094                                         tri->trans_subcmd = -1;
14095                                         tri->function = -1;
14096                                         tri->fid = -1;
14097                                         tri->lanman_cmd = 0;
14098                                         tri->param_descrip = NULL;
14099                                         tri->data_descrip = NULL;
14100                                         tri->aux_data_descrip = NULL;
14101                                         tri->info_level = -1;
14102                                         si->sip->extra_info = tri;
14103                                         si->sip->extra_info_type = SMB_EI_TRI;
14104                                 } else {
14105                                         /*
14106                                          * We already filled the structure
14107                                          * in; don't bother doing so again.
14108                                          */
14109                                         tri = NULL;
14110                                 }
14111                         } else {
14112                                 /*
14113                                  * This is a unidirectional message, for
14114                                  * which there will be no reply; don't
14115                                  * bother allocating an "smb_transact_info_t"
14116                                  * structure for it.
14117                                  */
14118                                 tri = NULL;
14119                         }
14120                         dissected_trans = FALSE;
14121                         if (an == NULL)
14122                                 goto endofcommand;
14123                         if (strncmp("\\PIPE\\", an, 6) == 0) {
14124                                 if (tri != NULL)
14125                                         tri->subcmd = TRANSACTION_PIPE;
14126
14127                                 /*
14128                                  * A tvbuff containing the setup words and
14129                                  * the pipe path.
14130                                  */
14131                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
14132
14133                                 /*
14134                                  * A tvbuff containing the parameters and the
14135                                  * data.
14136                                  */
14137                                 pd_tvb = tvb_new_subset_remaining(tvb, po);
14138
14139                                 dissected_trans = dissect_pipe_smb(sp_tvb,
14140                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
14141                                     top_tree_global, si);
14142
14143                                 /* In case we did not see the TreeConnect call,
14144                                    store this TID here as well as a IPC TID
14145                                    so we know that future Read/Writes to this
14146                                    TID is (probably) DCERPC.
14147                                 */
14148                                 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))) {
14149                                         g_hash_table_remove(si->ct->tid_service, GUINT_TO_POINTER(si->tid));
14150                                 }
14151                                 g_hash_table_insert(si->ct->tid_service, GUINT_TO_POINTER(si->tid), (void *)TID_IPC);
14152                         } else if (strncmp("\\MAILSLOT\\", an, 10) == 0) {
14153                                 if (tri != NULL)
14154                                         tri->subcmd = TRANSACTION_MAILSLOT;
14155
14156                                 /*
14157                                  * A tvbuff containing the setup words and
14158                                  * the mailslot path.
14159                                  */
14160                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
14161                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
14162                                     s_tvb, d_tvb, an+10, pinfo, top_tree_global, si);
14163                         }
14164                         if (!dissected_trans)
14165                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14166                 } else {
14167                         col_append_str(pinfo->cinfo, COL_INFO,
14168                                         "[transact continuation]");
14169                 }
14170         }
14171
14172         END_OF_SMB
14173
14174         return offset;
14175 }
14176
14177
14178
14179 static int
14180 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14181     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14182 {
14183         int                   fn_len;
14184         const char           *fn;
14185         int                   old_offset  = offset;
14186         proto_item           *item        = NULL;
14187         proto_tree           *tree        = NULL;
14188         smb_transact2_info_t *t2i;
14189         gboolean              resume_keys = FALSE;
14190         guint32               bytes_needed = 0;
14191
14192         DISSECTOR_ASSERT(si);
14193
14194         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14195                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
14196                 if (t2i != NULL)
14197                         resume_keys = t2i->resume_keys;
14198         }
14199
14200         if (parent_tree) {
14201                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14202                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14203                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14204         }
14205
14206         /*
14207          * Figure out of there are enough bytes to display the whole entry.
14208          * This consistes of 22 bytes or 26 bytes if resume_keys, followed
14209          * by a length byte and that many chars.
14210          */
14211         bytes_needed = 23 + (resume_keys ? 4 : 0);
14212         tvb_ensure_bytes_exist(tvb, offset, bytes_needed);
14213
14214         /* Now, get the length */
14215         fn_len = tvb_get_guint8(tvb, offset + bytes_needed - 1);
14216         tvb_ensure_bytes_exist(tvb, offset, bytes_needed + fn_len);
14217
14218         if (resume_keys) {
14219                 /* resume key */
14220                 CHECK_BYTE_COUNT_SUBR(4);
14221                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14222                 COUNT_BYTES_SUBR(4);
14223         }
14224
14225         /* create time */
14226         CHECK_BYTE_COUNT_SUBR(4);
14227         offset = dissect_smb_datetime(tvb, tree, offset,
14228                 hf_smb_create_time,
14229                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14230         *bcp -= 4;
14231
14232         /* access time */
14233         CHECK_BYTE_COUNT_SUBR(4);
14234         offset = dissect_smb_datetime(tvb, tree, offset,
14235                 hf_smb_access_time,
14236                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14237         *bcp -= 4;
14238
14239         /* last write time */
14240         CHECK_BYTE_COUNT_SUBR(4);
14241         offset = dissect_smb_datetime(tvb, tree, offset,
14242                 hf_smb_last_write_time,
14243                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14244         *bcp -= 4;
14245
14246         /* data size */
14247         CHECK_BYTE_COUNT_SUBR(4);
14248         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14249         COUNT_BYTES_SUBR(4);
14250
14251         /* allocation size */
14252         CHECK_BYTE_COUNT_SUBR(4);
14253         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14254         COUNT_BYTES_SUBR(4);
14255
14256         /* File Attributes */
14257         CHECK_BYTE_COUNT_SUBR(2);
14258         offset = dissect_file_attributes(tvb, tree, offset);
14259         *bcp -= 2;
14260
14261         /* file name len */
14262         CHECK_BYTE_COUNT_SUBR(1);
14263         fn_len = tvb_get_guint8(tvb, offset);
14264         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14265         COUNT_BYTES_SUBR(1);
14266         if (si->unicode)
14267                 fn_len += 2;    /* include terminating '\0' */
14268         else
14269                 fn_len++;       /* include terminating '\0' */
14270
14271         /* file name */
14272         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14273         CHECK_STRING_SUBR(fn);
14274         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14275                 fn);
14276         COUNT_BYTES_SUBR(fn_len);
14277
14278         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14279                     format_text(fn, strlen(fn)));
14280
14281         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14282         proto_item_set_len(item, offset-old_offset);
14283
14284         *trunc = FALSE;
14285         return offset;
14286 }
14287
14288 static int
14289 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14290     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14291 {
14292         int                   fn_len;
14293         const char           *fn;
14294         int                   old_offset  = offset;
14295         proto_item           *item        = NULL;
14296         proto_tree           *tree        = NULL;
14297         smb_transact2_info_t *t2i;
14298         gboolean              resume_keys = FALSE;
14299         guint32               bytes_needed = 0;
14300
14301         DISSECTOR_ASSERT(si);
14302
14303         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14304                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
14305                 if (t2i != NULL)
14306                         resume_keys = t2i->resume_keys;
14307         }
14308
14309         if (parent_tree) {
14310                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14311                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14312                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14313         }
14314
14315         /*
14316          * Figure out of there are enough bytes to display the whole entry.
14317          * This consistes of 26 bytes or 30 bytes if resume_keys, followed
14318          * by a length byte and that many chars.
14319          */
14320         bytes_needed = 27 + (resume_keys ? 4 : 0);
14321         tvb_ensure_bytes_exist(tvb, offset, bytes_needed);
14322
14323         /* Now, get the length */
14324         fn_len = tvb_get_guint8(tvb, offset + bytes_needed - 1);
14325         tvb_ensure_bytes_exist(tvb, offset, bytes_needed + fn_len);
14326
14327         if (resume_keys) {
14328                 /* resume key */
14329                 CHECK_BYTE_COUNT_SUBR(4);
14330                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14331                 COUNT_BYTES_SUBR(4);
14332         }
14333
14334         /* create time */
14335         CHECK_BYTE_COUNT_SUBR(4);
14336         offset = dissect_smb_datetime(tvb, tree, offset,
14337                 hf_smb_create_time,
14338                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14339         *bcp -= 4;
14340
14341         /* access time */
14342         CHECK_BYTE_COUNT_SUBR(4);
14343         offset = dissect_smb_datetime(tvb, tree, offset,
14344                 hf_smb_access_time,
14345                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14346         *bcp -= 4;
14347
14348         /* last write time */
14349         CHECK_BYTE_COUNT_SUBR(4);
14350         offset = dissect_smb_datetime(tvb, tree, offset,
14351                 hf_smb_last_write_time,
14352                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14353         *bcp -= 4;
14354
14355         /* data size */
14356         CHECK_BYTE_COUNT_SUBR(4);
14357         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14358         COUNT_BYTES_SUBR(4);
14359
14360         /* allocation size */
14361         CHECK_BYTE_COUNT_SUBR(4);
14362         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14363         COUNT_BYTES_SUBR(4);
14364
14365         /* File Attributes */
14366         CHECK_BYTE_COUNT_SUBR(2);
14367         offset = dissect_file_attributes(tvb, tree, offset);
14368         *bcp -= 2;
14369
14370         /* ea length */
14371         CHECK_BYTE_COUNT_SUBR(4);
14372         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14373         COUNT_BYTES_SUBR(4);
14374
14375         /* file name len */
14376         CHECK_BYTE_COUNT_SUBR(1);
14377         fn_len = tvb_get_guint8(tvb, offset);
14378         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14379         COUNT_BYTES_SUBR(1);
14380         if (si->unicode)
14381                 fn_len += 2;    /* include terminating '\0' */
14382         else
14383                 fn_len++;       /* include terminating '\0' */
14384
14385         /* file name */
14386         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14387         CHECK_STRING_SUBR(fn);
14388         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14389                 fn);
14390         COUNT_BYTES_SUBR(fn_len);
14391
14392         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14393                     format_text(fn, strlen(fn)));
14394
14395         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14396         proto_item_set_len(item, offset-old_offset);
14397
14398         *trunc = FALSE;
14399         return offset;
14400 }
14401
14402 /*
14403  * According to MS-CIFS 2.2.8.1.3 this is like the function above with the
14404  * addition of the list of EA name value pairs before the file name.
14405  *
14406  * The EAs are formatted as an SMB_FEA as in 2.2.1.2.2. We will deal with
14407  * this soon.
14408  */
14409 static int
14410 dissect_4_3_4_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14411     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14412 {
14413         int                   fn_len;
14414         const char           *fn;
14415         int                   old_offset  = offset;
14416         int                  ea_size = 0;
14417         proto_item           *item        = NULL;
14418         proto_tree           *tree        = NULL;
14419         smb_transact2_info_t *t2i;
14420         gboolean              resume_keys = FALSE;
14421
14422
14423         DISSECTOR_ASSERT(si);
14424
14425         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
14426                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
14427                 if (t2i != NULL)
14428                         resume_keys = t2i->resume_keys;
14429         }
14430
14431         if (parent_tree) {
14432                 tvb_ensure_bytes_exist(tvb, offset, *bcp);
14433                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14434                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14435                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14436         }
14437
14438         if (resume_keys) {
14439                 /* resume key */
14440                 CHECK_BYTE_COUNT_SUBR(4);
14441                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14442                 COUNT_BYTES_SUBR(4);
14443         }
14444
14445         /* create time */
14446         CHECK_BYTE_COUNT_SUBR(4);
14447         offset = dissect_smb_datetime(tvb, tree, offset,
14448                 hf_smb_create_time,
14449                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
14450         *bcp -= 4;
14451
14452         /* access time */
14453         CHECK_BYTE_COUNT_SUBR(4);
14454         offset = dissect_smb_datetime(tvb, tree, offset,
14455                 hf_smb_access_time,
14456                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
14457         *bcp -= 4;
14458
14459         /* last write time */
14460         CHECK_BYTE_COUNT_SUBR(4);
14461         offset = dissect_smb_datetime(tvb, tree, offset,
14462                 hf_smb_last_write_time,
14463                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
14464         *bcp -= 4;
14465
14466         /* data size */
14467         CHECK_BYTE_COUNT_SUBR(4);
14468         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14469         COUNT_BYTES_SUBR(4);
14470
14471         /* allocation size */
14472         CHECK_BYTE_COUNT_SUBR(4);
14473         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14474         COUNT_BYTES_SUBR(4);
14475
14476         /* File Attributes */
14477         CHECK_BYTE_COUNT_SUBR(2);
14478         offset = dissect_file_attributes(tvb, tree, offset);
14479         *bcp -= 2;
14480
14481         /* ea length */
14482         CHECK_BYTE_COUNT_SUBR(4);
14483         ea_size = tvb_get_letohl(tvb, offset);
14484         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14485         COUNT_BYTES_SUBR(4);
14486
14487         /* The EAs ... they are formatted as in MS-CIFS 2.2.1.2.2 */
14488         proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, ea_size, NULL, "EAs");
14489         COUNT_BYTES_SUBR(ea_size);
14490         *bcp -= ea_size;
14491
14492         /* file name len */
14493         CHECK_BYTE_COUNT_SUBR(1);
14494         fn_len = tvb_get_guint8(tvb, offset);
14495         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
14496         COUNT_BYTES_SUBR(1);
14497         if (si->unicode)
14498                 fn_len += 2;    /* include terminating '\0' */
14499         else
14500                 fn_len++;       /* include terminating '\0' */
14501
14502         /* file name */
14503         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14504         CHECK_STRING_SUBR(fn);
14505         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14506                 fn);
14507         COUNT_BYTES_SUBR(fn_len);
14508
14509         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14510                     format_text(fn, strlen(fn)));
14511
14512         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14513         proto_item_set_len(item, offset-old_offset);
14514
14515         return offset;
14516 }
14517
14518 static int
14519 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14520     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14521 {
14522         int         fn_len;
14523         const char *fn;
14524         int         old_offset = offset;
14525         proto_item *item       = NULL;
14526         proto_tree *tree       = NULL;
14527         guint32     neo;
14528         int         padcnt;
14529
14530         DISSECTOR_ASSERT(si);
14531
14532         /*
14533          * We check this first before adding the sub-tree so things do not
14534          * get ugly.
14535          */
14536
14537         /* next entry offset */
14538         CHECK_BYTE_COUNT_SUBR(4);
14539         neo = tvb_get_letohl(tvb, offset);
14540
14541         /* Ensure we have the bytes we need, which is up to neo */
14542         tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14543
14544         if (parent_tree) {
14545                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14546                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14547                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14548         }
14549
14550         /*
14551          * We assume that the presence of a next entry offset implies the
14552          * absence of a resume key, as appears to be the case for 4.3.4.6.
14553          */
14554
14555         CHECK_BYTE_COUNT_SUBR(4);
14556         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14557         COUNT_BYTES_SUBR(4);
14558
14559         /* file index */
14560         CHECK_BYTE_COUNT_SUBR(4);
14561         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14562         COUNT_BYTES_SUBR(4);
14563
14564         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14565         if (*trunc) {
14566                 return offset;
14567         }
14568
14569         /* end of file */
14570         CHECK_BYTE_COUNT_SUBR(8);
14571         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14572         COUNT_BYTES_SUBR(8);
14573
14574         /* allocation size */
14575         CHECK_BYTE_COUNT_SUBR(8);
14576         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14577         COUNT_BYTES_SUBR(8);
14578
14579         /* Extended File Attributes */
14580         CHECK_BYTE_COUNT_SUBR(4);
14581         offset = dissect_file_ext_attr(tvb, tree, offset);
14582         *bcp -= 4;
14583
14584         /* file name len */
14585         CHECK_BYTE_COUNT_SUBR(4);
14586         fn_len = tvb_get_letohl(tvb, offset);
14587         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14588         COUNT_BYTES_SUBR(4);
14589
14590         /* file name */
14591         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14592         CHECK_STRING_SUBR(fn);
14593         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14594                 fn);
14595         COUNT_BYTES_SUBR(fn_len);
14596
14597         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14598                     format_text(fn, strlen(fn)));
14599
14600         /* skip to next structure */
14601         if (neo) {
14602                 padcnt = (old_offset + neo) - offset;
14603                 if (padcnt < 0) {
14604                         /*
14605                          * XXX - this is bogus; flag it?
14606                          */
14607                         padcnt = 0;
14608                 }
14609                 if (padcnt != 0) {
14610                         CHECK_BYTE_COUNT_SUBR(padcnt);
14611                         COUNT_BYTES_SUBR(padcnt);
14612                 }
14613         }
14614
14615         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14616         proto_item_set_len(item, offset-old_offset);
14617
14618         *trunc = FALSE;
14619         return offset;
14620 }
14621
14622 static int
14623 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14624     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14625 {
14626         int         fn_len;
14627         const char *fn;
14628         int         old_offset = offset;
14629         proto_item *item       = NULL;
14630         proto_tree *tree       = NULL;
14631         guint32     neo;
14632         int         padcnt;
14633
14634         DISSECTOR_ASSERT(si);
14635
14636         /*
14637          * We check this first before adding the sub-tree so things do not
14638          * get ugly.
14639          */
14640
14641         /* next entry offset */
14642         CHECK_BYTE_COUNT_SUBR(4);
14643         neo = tvb_get_letohl(tvb, offset);
14644
14645         /* Ensure we have the bytes we need, which is up to neo */
14646         tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14647
14648         if (parent_tree) {
14649                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14650                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14651                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14652         }
14653
14654         /*
14655          * We assume that the presence of a next entry offset implies the
14656          * absence of a resume key, as appears to be the case for 4.3.4.6.
14657          */
14658
14659         CHECK_BYTE_COUNT_SUBR(4);
14660         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14661         COUNT_BYTES_SUBR(4);
14662
14663         /* file index */
14664         CHECK_BYTE_COUNT_SUBR(4);
14665         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14666         COUNT_BYTES_SUBR(4);
14667
14668         /* standard 8-byte timestamps */
14669         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14670         if (*trunc) {
14671                 return offset;
14672         }
14673
14674         /* end of file */
14675         CHECK_BYTE_COUNT_SUBR(8);
14676         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14677         COUNT_BYTES_SUBR(8);
14678
14679         /* allocation size */
14680         CHECK_BYTE_COUNT_SUBR(8);
14681         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14682         COUNT_BYTES_SUBR(8);
14683
14684         /* Extended File Attributes */
14685         CHECK_BYTE_COUNT_SUBR(4);
14686         offset = dissect_file_ext_attr(tvb, tree, offset);
14687         *bcp -= 4;
14688
14689         /* file name len */
14690         CHECK_BYTE_COUNT_SUBR(4);
14691         fn_len = tvb_get_letohl(tvb, offset);
14692         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14693         COUNT_BYTES_SUBR(4);
14694
14695         /* ea length */
14696         CHECK_BYTE_COUNT_SUBR(4);
14697         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14698         COUNT_BYTES_SUBR(4);
14699
14700         /* file name */
14701         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14702         CHECK_STRING_SUBR(fn);
14703         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14704                 fn);
14705         COUNT_BYTES_SUBR(fn_len);
14706
14707         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14708                     format_text(fn, strlen(fn)));
14709
14710         /* skip to next structure */
14711         if (neo) {
14712                 padcnt = (old_offset + neo) - offset;
14713                 if (padcnt < 0) {
14714                         /*
14715                          * XXX - this is bogus; flag it?
14716                          */
14717                         padcnt = 0;
14718                 }
14719                 if (padcnt != 0) {
14720                         CHECK_BYTE_COUNT_SUBR(padcnt);
14721                         COUNT_BYTES_SUBR(padcnt);
14722                 }
14723         }
14724
14725         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14726         proto_item_set_len(item, offset-old_offset);
14727
14728         *trunc = FALSE;
14729         return offset;
14730 }
14731
14732 static int
14733 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14734     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14735 {
14736         int         fn_len, sfn_len;
14737         const char *fn, *sfn;
14738         int         old_offset = offset;
14739         proto_item *item       = NULL;
14740         proto_tree *tree       = NULL;
14741         guint32     neo;
14742         int         padcnt;
14743
14744         DISSECTOR_ASSERT(si);
14745
14746         /*
14747          * We check this first before adding the sub-tree so things do not
14748          * get ugly.
14749          */
14750
14751         /* next entry offset */
14752         CHECK_BYTE_COUNT_SUBR(4);
14753         neo = tvb_get_letohl(tvb, offset);
14754
14755         /* Ensure we have the bytes we need, which is up to neo */
14756         tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14757
14758         if (parent_tree) {
14759                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14760                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14761                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14762         }
14763
14764         /*
14765          * XXX - I have not seen any of these that contain a resume
14766          * key, even though some of the requests had the "return resume
14767          * key" flag set.
14768          */
14769
14770         CHECK_BYTE_COUNT_SUBR(4);
14771         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14772         COUNT_BYTES_SUBR(4);
14773
14774         /* file index */
14775         CHECK_BYTE_COUNT_SUBR(4);
14776         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14777         COUNT_BYTES_SUBR(4);
14778
14779         /* dissect standard 8-byte timestamps */
14780         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14781         if (*trunc) {
14782           return offset;
14783         }
14784
14785         /* end of file */
14786         CHECK_BYTE_COUNT_SUBR(8);
14787         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14788         COUNT_BYTES_SUBR(8);
14789
14790         /* allocation size */
14791         CHECK_BYTE_COUNT_SUBR(8);
14792         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14793         COUNT_BYTES_SUBR(8);
14794
14795         /* Extended File Attributes */
14796         CHECK_BYTE_COUNT_SUBR(4);
14797         offset = dissect_file_ext_attr(tvb, tree, offset);
14798         *bcp -= 4;
14799
14800         /* file name len */
14801         CHECK_BYTE_COUNT_SUBR(4);
14802         fn_len = tvb_get_letohl(tvb, offset);
14803         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14804         COUNT_BYTES_SUBR(4);
14805
14806         /*
14807          * EA length.
14808          *
14809          * XXX - in one captures, this has the topmost bit set, and the
14810          * rest of the bits have the value 7.  Is the topmost bit being
14811          * set some indication that the value *isn't* the length of
14812          * the EAs?
14813          */
14814         CHECK_BYTE_COUNT_SUBR(4);
14815         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14816         COUNT_BYTES_SUBR(4);
14817
14818         /* short file name len */
14819         CHECK_BYTE_COUNT_SUBR(1);
14820         sfn_len = tvb_get_guint8(tvb, offset);
14821         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
14822         COUNT_BYTES_SUBR(1);
14823
14824         /* reserved byte */
14825         CHECK_BYTE_COUNT_SUBR(1);
14826         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
14827         COUNT_BYTES_SUBR(1);
14828
14829         /* short file name - it's not always in Unicode */
14830         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
14831         CHECK_STRING_SUBR(sfn);
14832         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
14833                 sfn);
14834         COUNT_BYTES_SUBR(24);
14835
14836         /* file name */
14837         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14838         CHECK_STRING_SUBR(fn);
14839         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14840                 fn);
14841         COUNT_BYTES_SUBR(fn_len);
14842
14843         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14844                     format_text(fn, strlen(fn)));
14845
14846         /* skip to next structure */
14847         if (neo) {
14848                 padcnt = (old_offset + neo) - offset;
14849                 if (padcnt < 0) {
14850                         /*
14851                          * XXX - this is bogus; flag it?
14852                          */
14853                         padcnt = 0;
14854                 }
14855                 if (padcnt != 0) {
14856                         CHECK_BYTE_COUNT_SUBR(padcnt);
14857                         COUNT_BYTES_SUBR(padcnt);
14858                 }
14859         }
14860
14861         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14862         proto_item_set_len(item, offset-old_offset);
14863
14864         *trunc = FALSE;
14865         return offset;
14866 }
14867
14868 static int
14869 dissect_4_3_4_6full(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14870     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14871 {
14872         int         fn_len;
14873         const char *fn;
14874         int         old_offset = offset;
14875         proto_item *item       = NULL;
14876         proto_tree *tree       = NULL;
14877         guint32     neo;
14878         int         padcnt;
14879
14880         DISSECTOR_ASSERT(si);
14881
14882         /*
14883          * We check this first before adding the sub-tree so things do not
14884          * get ugly.
14885          */
14886
14887         /* next entry offset */
14888         CHECK_BYTE_COUNT_SUBR(4);
14889         neo = tvb_get_letohl(tvb, offset);
14890
14891         /* Ensure we have the bytes we need, which is up to neo */
14892         tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
14893
14894         if (parent_tree) {
14895                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
14896                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
14897                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
14898         }
14899
14900         /*
14901          * XXX - I have not seen any of these that contain a resume
14902          * key, even though some of the requests had the "return resume
14903          * key" flag set.
14904          */
14905
14906         CHECK_BYTE_COUNT_SUBR(4);
14907         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
14908         COUNT_BYTES_SUBR(4);
14909
14910         /* file index */
14911         CHECK_BYTE_COUNT_SUBR(4);
14912         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14913         COUNT_BYTES_SUBR(4);
14914
14915         /* dissect standard 8-byte timestamps */
14916         offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
14917         if (*trunc) {
14918           return offset;
14919         }
14920
14921         /* end of file */
14922         CHECK_BYTE_COUNT_SUBR(8);
14923         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14924         COUNT_BYTES_SUBR(8);
14925
14926         /* allocation size */
14927         CHECK_BYTE_COUNT_SUBR(8);
14928         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14929         COUNT_BYTES_SUBR(8);
14930
14931         /* Extended File Attributes */
14932         CHECK_BYTE_COUNT_SUBR(4);
14933         offset = dissect_file_ext_attr(tvb, tree, offset);
14934         *bcp -= 4;
14935
14936         /* file name len */
14937         CHECK_BYTE_COUNT_SUBR(4);
14938         fn_len = tvb_get_letohl(tvb, offset);
14939         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
14940         COUNT_BYTES_SUBR(4);
14941
14942         /*
14943          * EA length.
14944          *
14945          * XXX - in one captures, this has the topmost bit set, and the
14946          * rest of the bits have the value 7.  Is the topmost bit being
14947          * set some indication that the value *isn't* the length of
14948          * the EAs?
14949          */
14950         CHECK_BYTE_COUNT_SUBR(4);
14951         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14952         COUNT_BYTES_SUBR(4);
14953
14954         /* skip 4 bytes */
14955         COUNT_BYTES_SUBR(4);
14956
14957         CHECK_BYTE_COUNT_SUBR(8);
14958         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14959         COUNT_BYTES_SUBR(8);
14960
14961         /* file name */
14962         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
14963         CHECK_STRING_SUBR(fn);
14964         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
14965                 fn);
14966         COUNT_BYTES_SUBR(fn_len);
14967
14968         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
14969                     format_text(fn, strlen(fn)));
14970
14971         /* skip to next structure */
14972         if (neo) {
14973                 padcnt = (old_offset + neo) - offset;
14974                 if (padcnt < 0) {
14975                         /*
14976                          * XXX - this is bogus; flag it?
14977                          */
14978                         padcnt = 0;
14979                 }
14980                 if (padcnt != 0) {
14981                         CHECK_BYTE_COUNT_SUBR(padcnt);
14982                         COUNT_BYTES_SUBR(padcnt);
14983                 }
14984         }
14985
14986         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
14987         proto_item_set_len(item, offset-old_offset);
14988
14989         *trunc = FALSE;
14990         return offset;
14991 }
14992
14993 static int
14994 dissect_4_3_4_6_id_both(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
14995     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
14996 {
14997         int         fn_len, sfn_len;
14998         const char *fn, *sfn;
14999         int         old_offset = offset;
15000         proto_item *item       = NULL;
15001         proto_tree *tree       = NULL;
15002         guint32     neo;
15003         int         padcnt;
15004
15005         DISSECTOR_ASSERT(si);
15006
15007         /*
15008          * We check this first before adding the sub-tree so things do not
15009          * get ugly.
15010          */
15011
15012         /* next entry offset */
15013         CHECK_BYTE_COUNT_SUBR(4);
15014         neo = tvb_get_letohl(tvb, offset);
15015
15016         /* Ensure we have the bytes we need, which is up to neo */
15017         tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15018
15019         if (parent_tree) {
15020                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
15021                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15022                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
15023         }
15024
15025         /*
15026          * XXX - I have not seen any of these that contain a resume
15027          * key, even though some of the requests had the "return resume
15028          * key" flag set.
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         /* dissect 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         /*
15068          * EA length.
15069          *
15070          * XXX - in one captures, this has the topmost bit set, and the
15071          * rest of the bits have the value 7.  Is the topmost bit being
15072          * set some indication that the value *isn't* the length of
15073          * the EAs?
15074          */
15075         CHECK_BYTE_COUNT_SUBR(4);
15076         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15077         COUNT_BYTES_SUBR(4);
15078
15079         /* short file name len */
15080         CHECK_BYTE_COUNT_SUBR(1);
15081         sfn_len = tvb_get_guint8(tvb, offset);
15082         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
15083         COUNT_BYTES_SUBR(1);
15084
15085         /* reserved byte */
15086         CHECK_BYTE_COUNT_SUBR(1);
15087         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
15088         COUNT_BYTES_SUBR(1);
15089
15090         /* short file name - it's not always in Unicode */
15091         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
15092         CHECK_STRING_SUBR(sfn);
15093         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
15094                 sfn);
15095         COUNT_BYTES_SUBR(24);
15096
15097         /* reserved bytes */
15098         CHECK_BYTE_COUNT_SUBR(2);
15099         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
15100         COUNT_BYTES_SUBR(2);
15101
15102         /* file id */
15103         CHECK_BYTE_COUNT_SUBR(8);
15104         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15105         COUNT_BYTES_SUBR(8);
15106
15107         /* file name */
15108         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15109         CHECK_STRING_SUBR(fn);
15110         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15111                 fn);
15112         COUNT_BYTES_SUBR(fn_len);
15113
15114         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15115                     format_text(fn, strlen(fn)));
15116
15117         /* skip to next structure */
15118         if (neo) {
15119                 padcnt = (old_offset + neo) - offset;
15120                 if (padcnt < 0) {
15121                         /*
15122                          * XXX - this is bogus; flag it?
15123                          */
15124                         padcnt = 0;
15125                 }
15126                 if (padcnt != 0) {
15127                         CHECK_BYTE_COUNT_SUBR(padcnt);
15128                         COUNT_BYTES_SUBR(padcnt);
15129                 }
15130         }
15131
15132         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
15133         proto_item_set_len(item, offset-old_offset);
15134
15135         *trunc = FALSE;
15136         return offset;
15137 }
15138
15139 static int
15140 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
15141     int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15142 {
15143         int         fn_len;
15144         const char *fn;
15145         int         old_offset = offset;
15146         proto_item *item       = NULL;
15147         proto_tree *tree       = NULL;
15148         guint32     neo;
15149         int         padcnt;
15150
15151         DISSECTOR_ASSERT(si);
15152
15153         /*
15154          * We check this first before adding the sub-tree so things do not
15155          * get ugly.
15156          */
15157
15158         /* next entry offset */
15159         CHECK_BYTE_COUNT_SUBR(4);
15160         neo = tvb_get_letohl(tvb, offset);
15161
15162         /* Ensure we have the bytes we need, which is up to neo */
15163         tvb_ensure_bytes_exist(tvb, offset, neo ? neo : *bcp);
15164
15165         if (parent_tree) {
15166                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
15167                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
15168                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
15169         }
15170
15171         /*
15172          * We assume that the presence of a next entry offset implies the
15173          * absence of a resume key, as appears to be the case for 4.3.4.6.
15174          */
15175
15176         CHECK_BYTE_COUNT_SUBR(4);
15177         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
15178         COUNT_BYTES_SUBR(4);
15179
15180         /* file index */
15181         CHECK_BYTE_COUNT_SUBR(4);
15182         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15183         COUNT_BYTES_SUBR(4);
15184
15185         /* file name len */
15186         CHECK_BYTE_COUNT_SUBR(4);
15187         fn_len = tvb_get_letohl(tvb, offset);
15188         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
15189         COUNT_BYTES_SUBR(4);
15190
15191         /* file name */
15192         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15193         CHECK_STRING_SUBR(fn);
15194         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
15195                 fn);
15196         COUNT_BYTES_SUBR(fn_len);
15197
15198         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
15199                     format_text(fn, strlen(fn)));
15200
15201         /* skip to next structure */
15202         if (neo) {
15203                 padcnt = (old_offset + neo) - offset;
15204                 if (padcnt < 0) {
15205                         /*
15206                          * XXX - this is bogus; flag it?
15207                          */
15208                         padcnt = 0;
15209                 }
15210                 if (padcnt != 0) {
15211                         CHECK_BYTE_COUNT_SUBR(padcnt);
15212                         COUNT_BYTES_SUBR(padcnt);
15213                 }
15214         }
15215
15216         proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
15217         proto_item_set_len(item, offset-old_offset);
15218
15219         *trunc = FALSE;
15220         return offset;
15221 }
15222
15223 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
15224
15225 static int
15226 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo,
15227                 proto_tree *tree, int offset, guint16 *bcp,
15228                 gboolean *trunc, smb_info_t *si)
15229 {
15230         const char *fn;
15231         int         fn_len;
15232         int         pad;
15233
15234         DISSECTOR_ASSERT(si);
15235
15236         /* NextEntryOffset */
15237         CHECK_BYTE_COUNT_SUBR(4);
15238         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15239         COUNT_BYTES_SUBR(4);
15240
15241         /* ResumeKey */
15242         CHECK_BYTE_COUNT_SUBR(4);
15243         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15244         COUNT_BYTES_SUBR(4);
15245
15246         /* Unix basic info */
15247         offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, trunc);
15248         if (*trunc)
15249                 return offset;
15250
15251         /* Name */
15252
15253         fn = get_unicode_or_ascii_string(
15254                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
15255
15256         CHECK_STRING_SUBR(fn);
15257         proto_tree_add_string(
15258                 tree, hf_smb_unix_file_name, tvb, offset, fn_len, fn);
15259         COUNT_BYTES_SUBR(fn_len);
15260
15261         /* Pad to 4 bytes */
15262
15263         if (offset % 4) {
15264                 pad = 4 - (offset % 4);
15265                 COUNT_BYTES_SUBR(pad);
15266         }
15267
15268         *trunc = FALSE;
15269         return offset;
15270 }
15271
15272 static int
15273 dissect_find_file_unix_info2(tvbuff_t *tvb, packet_info *pinfo,
15274                              proto_tree *tree, int offset, guint16 *bcp,
15275                              gboolean *trunc, smb_info_t *si)
15276 {
15277         const char *fn;
15278         guint32     namelen;
15279         int         fn_len;
15280         int         pad;
15281
15282         DISSECTOR_ASSERT(si);
15283
15284         /* NextEntryOffset */
15285         CHECK_BYTE_COUNT_SUBR(4);
15286         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15287         COUNT_BYTES_SUBR(4);
15288
15289         /* ResumeKey */
15290         CHECK_BYTE_COUNT_SUBR(4);
15291         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15292         COUNT_BYTES_SUBR(4);
15293
15294         /* Unix Info2 */
15295         offset = dissect_qspi_unix_info2(tvb, pinfo, tree, offset, bcp, trunc);
15296         if (*trunc)
15297                 return offset;
15298
15299         /* Name length */
15300         CHECK_BYTE_COUNT_SUBR(4);
15301         namelen = tvb_get_letohl(tvb, offset);
15302         proto_tree_add_uint(tree, hf_smb_unix_file_name_length, tvb, offset, 4, namelen);
15303         COUNT_BYTES_SUBR(4);
15304
15305         /* Name */
15306
15307         /*
15308          * namelen could be > 2^31-1; this will catch that.
15309          * The length argument to get_unicode_or_ascii_string() is an
15310          * int, not an unsigned int, so we have to worry about that.
15311          */
15312         tvb_ensure_bytes_exist(tvb, offset, namelen);
15313         fn_len = namelen;
15314         fn = get_unicode_or_ascii_string(
15315                 tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
15316
15317         CHECK_STRING_SUBR(fn);
15318         proto_tree_add_string(
15319                 tree, hf_smb_unix_file_name, tvb, offset, fn_len, fn);
15320         COUNT_BYTES_SUBR(fn_len);
15321
15322         /* Pad to 4 bytes */
15323
15324         if (offset % 4) {
15325                 pad = 4 - (offset % 4);
15326                 COUNT_BYTES_SUBR(pad);
15327         }
15328
15329         *trunc = FALSE;
15330         return offset;
15331 }
15332
15333 /*dissect the data block for TRANS2_FIND_FIRST2*/
15334 static int
15335 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
15336     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc, smb_info_t *si)
15337 {
15338         if (!*bcp) {
15339                 return offset;
15340         }
15341
15342         DISSECTOR_ASSERT(si);
15343
15344         switch(si->info_level) {
15345         case 1:         /*Info Standard*/
15346                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
15347                     trunc, si);
15348                 break;
15349         case 2:         /*Info Query EA Size*/
15350                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
15351                     trunc, si);
15352                 break;
15353         case 3:         /* Info Query EAs From List same as
15354                          * InfoQueryEASize.
15355                          * Not according to MS-CIFS 2.2.8.1.3. RJS
15356                          */
15357                 offset = dissect_4_3_4_3(tvb, pinfo, tree, offset, bcp,
15358                     trunc, si);
15359                 break;
15360         case 0x0101:    /*Find File Directory Info*/
15361                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
15362                     trunc, si);
15363                 break;
15364         case 0x0102:    /*Find File Full Directory Info*/
15365                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
15366                     trunc, si);
15367                 break;
15368         case 0x0103:    /*Find File Names Info*/
15369                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
15370                     trunc, si);
15371                 break;
15372         case 0x0104:    /*Find File Both Directory Info*/
15373                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
15374                     trunc, si);
15375                 break;
15376         case 0x0105:    /*Find File Full Directory Info*/
15377                 offset = dissect_4_3_4_6full(tvb, pinfo, tree, offset, bcp,
15378                     trunc, si);
15379                 break;
15380         case 0x0106:    /*Find File Id Both Directory Info*/
15381                 offset = dissect_4_3_4_6_id_both(tvb, pinfo, tree, offset, bcp,
15382                     trunc, si);
15383                 break;
15384         case 0x0202:    /*Find File Unix*/
15385                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
15386                     trunc, si);
15387                 break;
15388         case 0x020B:    /*Find File Unix Info2*/
15389                 offset = dissect_find_file_unix_info2(tvb, pinfo, tree, offset, bcp,
15390                     trunc, si);
15391                 break;
15392         default:        /* unknown info level */
15393                 *trunc = FALSE;
15394                 break;
15395         }
15396         return offset;
15397 }
15398
15399
15400 /* is this one just wrong and should be dissect_fs0105_attributes above ? */
15401 static int
15402 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15403 {
15404         guint32     mask;
15405         proto_item *item;
15406         proto_tree *tree;
15407
15408         mask = tvb_get_letohl(tvb, offset);
15409
15410         if (parent_tree) {
15411                 item = proto_tree_add_item(parent_tree, hf_smb_fs_attr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15412                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
15413
15414                 /* case sensitive search */
15415                 proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
15416                         tvb, offset, 4, mask);
15417                 /* case preserved names */
15418                 proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
15419                         tvb, offset, 4, mask);
15420                 /* unicode on disk */
15421                 proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
15422                         tvb, offset, 4, mask);
15423                 /* persistent acls */
15424                 proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
15425                         tvb, offset, 4, mask);
15426                 /* file compression */
15427                 proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
15428                         tvb, offset, 4, mask);
15429                 /* volume quotas */
15430                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
15431                         tvb, offset, 4, mask);
15432                 /* sparse files */
15433                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
15434                         tvb, offset, 4, mask);
15435                 /* reparse points */
15436                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
15437                         tvb, offset, 4, mask);
15438                 /* remote storage */
15439                 proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
15440                         tvb, offset, 4, mask);
15441                 /* lfn apis */
15442                 proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
15443                         tvb, offset, 4, mask);
15444                 /* volume is compressed */
15445                 proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
15446                         tvb, offset, 4, mask);
15447                 /* support oids */
15448                 proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
15449                         tvb, offset, 4, mask);
15450                 /* encryption */
15451                 proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
15452                         tvb, offset, 4, mask);
15453                 /* named streams */
15454                 proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
15455                         tvb, offset, 4, mask);
15456                 /* read only volume */
15457                 proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
15458                         tvb, offset, 4, mask);
15459         }
15460
15461         offset += 4;
15462         return offset;
15463 }
15464
15465
15466 static int
15467 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15468 {
15469         guint32     mask;
15470         proto_item *item;
15471         proto_tree *tree;
15472
15473         mask = tvb_get_letohl(tvb, offset);
15474
15475         if (parent_tree) {
15476                 item = proto_tree_add_item(parent_tree, hf_smb_device_char, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15477                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
15478
15479                 proto_tree_add_boolean(tree, hf_smb_device_char_removable,
15480                         tvb, offset, 4, mask);
15481                 proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
15482                         tvb, offset, 4, mask);
15483                 proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
15484                         tvb, offset, 4, mask);
15485                 proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
15486                         tvb, offset, 4, mask);
15487                 proto_tree_add_boolean(tree, hf_smb_device_char_remote,
15488                         tvb, offset, 4, mask);
15489                 proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
15490                         tvb, offset, 4, mask);
15491                 proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
15492                         tvb, offset, 4, mask);
15493         }
15494
15495         offset += 4;
15496         return offset;
15497 }
15498
15499 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
15500
15501 static const true_false_string tfs_smb_mac_access_ctrl = {
15502         "Macintosh Access Control Supported",
15503         "Macintosh Access Control Not Supported"
15504 };
15505
15506 static const true_false_string tfs_smb_mac_getset_comments = {
15507         "Macintosh Get & Set Comments Supported",
15508         "Macintosh Get & Set Comments Not Supported"
15509 };
15510
15511 static const true_false_string tfs_smb_mac_desktopdb_calls = {
15512         "Macintosh Get & Set Desktop Database Info Supported",
15513         "Macintosh Get & Set Desktop Database Info Supported"
15514 };
15515
15516 static const true_false_string tfs_smb_mac_unique_ids = {
15517         "Macintosh Unique IDs Supported",
15518         "Macintosh Unique IDs Not Supported"
15519 };
15520
15521 static const true_false_string tfs_smb_mac_streams = {
15522         "Macintosh and Streams Extensions Not Supported",
15523         "Macintosh and Streams Extensions Supported"
15524 };
15525
15526 int
15527 dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
15528 {
15529         int         fn_len, vll;
15530         const char *fn;
15531
15532         /* create time */
15533         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15534         offset = dissect_nt_64bit_time(tvb, tree, offset,
15535                 hf_smb_create_time);
15536         *bcp -= 8;
15537
15538         /* volume serial number */
15539         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15540         proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15541         COUNT_BYTES_TRANS_SUBR(4);
15542
15543         /* volume label length */
15544         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15545         vll = tvb_get_letohl(tvb, offset);
15546         proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
15547         COUNT_BYTES_TRANS_SUBR(4);
15548
15549         /* 2 reserved bytes */
15550         CHECK_BYTE_COUNT_TRANS_SUBR(2);
15551         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
15552         COUNT_BYTES_TRANS_SUBR(2);
15553
15554         /* label */
15555         fn_len = vll;
15556         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
15557         CHECK_STRING_TRANS_SUBR(fn);
15558         proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15559                 fn);
15560         COUNT_BYTES_TRANS_SUBR(fn_len);
15561
15562         return offset;
15563 }
15564
15565 int
15566 dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15567 {
15568         /* allocation size */
15569         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15570         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15571         COUNT_BYTES_TRANS_SUBR(8);
15572
15573         /* free allocation units */
15574         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15575         proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15576         COUNT_BYTES_TRANS_SUBR(8);
15577
15578         /* sectors per unit */
15579         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15580         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15581         COUNT_BYTES_TRANS_SUBR(4);
15582
15583         /* bytes per sector */
15584         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15585         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15586         COUNT_BYTES_TRANS_SUBR(4);
15587
15588         return offset;
15589 }
15590
15591 int
15592 dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15593 {
15594         /* device type */
15595         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15596         proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15597         COUNT_BYTES_TRANS_SUBR(4);
15598
15599         /* device characteristics */
15600         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15601         offset = dissect_device_characteristics(tvb, tree, offset);
15602         *bcp -= 4;
15603
15604         return offset;
15605 }
15606
15607 int
15608 dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
15609 {
15610         int         fn_len, fnl;
15611         const char *fn;
15612
15613         /* FS attributes */
15614         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15615         offset = dissect_fs_attributes(tvb, tree, offset);
15616         *bcp -= 4;
15617
15618         /* max name len */
15619         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15620         proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15621         COUNT_BYTES_TRANS_SUBR(4);
15622
15623         /* fs name length */
15624         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15625         fnl = tvb_get_letohl(tvb, offset);
15626         proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
15627         COUNT_BYTES_TRANS_SUBR(4);
15628
15629         /* label */
15630         fn_len = fnl;
15631         fn = get_unicode_or_ascii_string(tvb, &offset, unicode, &fn_len, FALSE, TRUE, bcp);
15632         CHECK_STRING_TRANS_SUBR(fn);
15633         proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
15634                 fn);
15635         COUNT_BYTES_TRANS_SUBR(fn_len);
15636
15637         return offset;
15638 }
15639
15640 int
15641 dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
15642 {
15643         CHECK_BYTE_COUNT_TRANS_SUBR(64);
15644
15645         dissect_smb2_FILE_OBJECTID_BUFFER(tvb, pinfo, tree, offset);
15646
15647         COUNT_BYTES_TRANS_SUBR(64);
15648
15649         return offset;
15650 }
15651
15652 int
15653 dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
15654 {
15655         /* allocation size */
15656         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15657         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15658         COUNT_BYTES_TRANS_SUBR(8);
15659
15660         /* caller free allocation units */
15661         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15662         proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15663         COUNT_BYTES_TRANS_SUBR(8);
15664
15665         /* actual free allocation units */
15666         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15667         proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15668         COUNT_BYTES_TRANS_SUBR(8);
15669
15670         /* sectors per unit */
15671         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15672         proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15673         COUNT_BYTES_TRANS_SUBR(4);
15674
15675         /* bytes per sector */
15676         CHECK_BYTE_COUNT_TRANS_SUBR(4);
15677         proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15678         COUNT_BYTES_TRANS_SUBR(4);
15679
15680         return offset;
15681 }
15682
15683 static int
15684 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
15685     int offset, guint16 *bcp, smb_info_t *si)
15686 {
15687         int         fn_len, vll;
15688         const char *fn;
15689         guint       support = 0;
15690         proto_item *item    = NULL;
15691         proto_tree *ti      = NULL;
15692
15693         if (!*bcp) {
15694                 return offset;
15695         }
15696
15697         DISSECTOR_ASSERT(si);
15698
15699         switch(si->info_level) {
15700         case 1:         /* SMB_INFO_ALLOCATION */
15701                 /* filesystem id */
15702                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15703                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15704                 COUNT_BYTES_TRANS_SUBR(4);
15705
15706                 /* sectors per unit */
15707                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15708                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15709                 COUNT_BYTES_TRANS_SUBR(4);
15710
15711                 /* units */
15712                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15713                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15714                 COUNT_BYTES_TRANS_SUBR(4);
15715
15716                 /* avail units */
15717                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15718                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15719                 COUNT_BYTES_TRANS_SUBR(4);
15720
15721                 /* bytes per sector, only 16bit integer here */
15722                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15723                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
15724                 COUNT_BYTES_TRANS_SUBR(2);
15725
15726                 break;
15727         case 2:         /* SMB_INFO_VOLUME */
15728                 /* volume serial number */
15729                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15730                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, ENC_LITTLE_ENDIAN);
15731                 COUNT_BYTES_TRANS_SUBR(4);
15732
15733                 /* volume label length, only one byte here */
15734                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
15735                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
15736                 COUNT_BYTES_TRANS_SUBR(1);
15737
15738                 /* label - not aligned! */
15739                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, bcp);
15740                 CHECK_STRING_TRANS_SUBR(fn);
15741                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15742                         fn);
15743                 COUNT_BYTES_TRANS_SUBR(fn_len);
15744
15745                 break;
15746         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
15747         case 1002:      /* SMB_FS_LABEL_INFORMATION */
15748                 /* volume label length */
15749                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15750                 vll = tvb_get_letohl(tvb, offset);
15751                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
15752                 COUNT_BYTES_TRANS_SUBR(4);
15753
15754                 /* label */
15755                 fn_len = vll;
15756                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
15757                 CHECK_STRING_TRANS_SUBR(fn);
15758                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
15759                         fn);
15760                 COUNT_BYTES_TRANS_SUBR(fn_len);
15761
15762                 break;
15763         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
15764         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
15765                 offset = dissect_qfsi_FS_VOLUME_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
15766                 break;
15767         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
15768         case 1003:      /* SMB_FS_SIZE_INFORMATION */
15769                 offset = dissect_qfsi_FS_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
15770                 break;
15771         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
15772         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
15773                 offset = dissect_qfsi_FS_DEVICE_INFO(tvb, pinfo, tree, offset, bcp);
15774                 break;
15775         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
15776         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
15777                 offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
15778                 break;
15779         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
15780                 proto_item *item_2 = NULL;
15781                 proto_tree *subtree = NULL;
15782
15783                 /* MajorVersionNumber */
15784                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15785                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
15786                 COUNT_BYTES_TRANS_SUBR(2);
15787
15788                 /* MinorVersionNumber */
15789                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
15790                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
15791                 COUNT_BYTES_TRANS_SUBR(2);
15792
15793                 /* Capability */
15794
15795                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15796
15797                 if (tree) {
15798                         item_2 = proto_tree_add_item(tree, hf_smb_unix_capability, tvb, offset, 8, ENC_LITTLE_ENDIAN);
15799                         subtree = proto_item_add_subtree(
15800                                 item_2, ett_smb_unix_capabilities);
15801                 }
15802
15803                 proto_tree_add_item(
15804                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 4,
15805                         ENC_LITTLE_ENDIAN);
15806
15807                 proto_tree_add_item(
15808                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 4,
15809                         ENC_LITTLE_ENDIAN);
15810
15811                 proto_tree_add_item(
15812                         subtree, hf_smb_unix_capability_xattr, tvb, offset, 4,
15813                         ENC_LITTLE_ENDIAN);
15814
15815                 proto_tree_add_item(
15816                         subtree, hf_smb_unix_capability_attr, tvb, offset, 4,
15817                         ENC_LITTLE_ENDIAN);
15818
15819                 proto_tree_add_item(
15820                         subtree, hf_smb_unix_capability_posix_paths, tvb, offset, 4,
15821                         ENC_LITTLE_ENDIAN);
15822
15823                 proto_tree_add_item(
15824                         subtree, hf_smb_unix_capability_posix_path_ops, tvb, offset, 4,
15825                         ENC_LITTLE_ENDIAN);
15826
15827                 proto_tree_add_item(
15828                         subtree, hf_smb_unix_capability_large_read, tvb, offset, 4,
15829                         ENC_LITTLE_ENDIAN);
15830
15831                 proto_tree_add_item(
15832                         subtree, hf_smb_unix_capability_large_write, tvb, offset, 4,
15833                         ENC_LITTLE_ENDIAN);
15834
15835                 proto_tree_add_item(
15836                         subtree, hf_smb_unix_capability_encrpytion, tvb, offset, 4,
15837                         ENC_LITTLE_ENDIAN);
15838
15839                 proto_tree_add_item(
15840                         subtree, hf_smb_unix_capability_mandatory_crypto, tvb, offset, 4,
15841                         ENC_LITTLE_ENDIAN);
15842
15843                 proto_tree_add_item(
15844                         subtree, hf_smb_unix_capability_proxy, tvb, offset, 4,
15845                         ENC_LITTLE_ENDIAN);
15846
15847                 COUNT_BYTES_TRANS_SUBR(8);
15848
15849                 break;
15850         }
15851
15852         case 0x202: {   /* SMB_QUERY_POSIX_WHOAMI */
15853                 proto_item *it_gids = NULL;
15854                 proto_tree *st_gids = NULL;
15855                 guint32     num_gids;
15856                 guint       i;
15857                 proto_item *it_sids = NULL;
15858                 proto_tree *st_sids = NULL;
15859                 int         old_sid_offset;
15860                 guint32     num_sids;
15861                 guint32     sids_buflen;
15862
15863                 /* Mapping flags */
15864                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15865                 proto_tree_add_item(tree, hf_smb_unix_whoami_mapflags,
15866                                 tvb, offset, 4, ENC_LITTLE_ENDIAN);
15867                 COUNT_BYTES_TRANS_SUBR(4);
15868
15869                 /* Mapping flags mask */
15870                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15871                 proto_tree_add_item(tree, hf_smb_unix_whoami_mapflags_mask,
15872                                 tvb, offset, 4, ENC_LITTLE_ENDIAN);
15873                 COUNT_BYTES_TRANS_SUBR(4);
15874
15875                 /* primary UID */
15876                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15877                 proto_tree_add_item(tree, hf_smb_unix_file_uid,
15878                                 tvb, offset, 8, ENC_LITTLE_ENDIAN);
15879                 COUNT_BYTES_TRANS_SUBR(8);
15880
15881                 /* primary GID */
15882                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15883                 proto_tree_add_item(tree, hf_smb_unix_file_gid,
15884                                 tvb, offset, 8, ENC_LITTLE_ENDIAN);
15885                 COUNT_BYTES_TRANS_SUBR(8);
15886
15887                 /* number of supplementary GIDs */
15888                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15889                 num_gids = tvb_get_letohl(tvb, offset);
15890                 proto_tree_add_item(tree, hf_smb_unix_whoami_num_supl_gids,
15891                                 tvb, offset, 4, ENC_LITTLE_ENDIAN);
15892                 COUNT_BYTES_TRANS_SUBR(4);
15893
15894                 /* number of supplementary SIDs */
15895                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15896                 num_sids = tvb_get_letohl(tvb, offset);
15897                 proto_tree_add_item(tree, hf_smb_unix_whoami_num_supl_sids,
15898                                 tvb, offset, 4, ENC_LITTLE_ENDIAN);
15899                 COUNT_BYTES_TRANS_SUBR(4);
15900
15901                 /* supplementary SIDs buffer length */
15902                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15903                 sids_buflen = tvb_get_letohl(tvb, offset);
15904                 proto_tree_add_item(tree, hf_smb_unix_whoami_sids_buflen,
15905                                 tvb, offset, 4, ENC_LITTLE_ENDIAN);
15906                 COUNT_BYTES_TRANS_SUBR(4);
15907
15908                 /* pad / reserved (must be zero) */
15909                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15910                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, ENC_NA);
15911                 COUNT_BYTES_TRANS_SUBR(4);
15912
15913
15914                 /* GIDs */
15915                 it_gids = proto_tree_add_text(tree, tvb, offset, num_gids * 8,
15916                                 "Supplementary UNIX GIDs");
15917                 st_gids = proto_item_add_subtree(it_gids, ett_smb_unix_whoami_gids);
15918
15919                 for (i = 0; i < num_gids; i++) {
15920                         CHECK_BYTE_COUNT_TRANS_SUBR(8);
15921                         proto_tree_add_item(st_gids, hf_smb_unix_file_gid,
15922                                         tvb, offset, 8, ENC_LITTLE_ENDIAN);
15923                         COUNT_BYTES_TRANS_SUBR(8);
15924                 }
15925
15926                 /* SIDs */
15927                 it_sids = proto_tree_add_text(tree, tvb, offset, sids_buflen,
15928                                 "List of SIDs");
15929                 st_sids = proto_item_add_subtree(it_sids, ett_smb_unix_whoami_sids);
15930
15931                 for (i = 0; i < num_sids; i++) {
15932                         old_sid_offset = offset;
15933                         offset = dissect_nt_sid(tvb, offset, st_sids, "SID", NULL, -1);
15934                         CHECK_BYTE_COUNT_TRANS_SUBR(offset-old_sid_offset);
15935                         *bcp -= (offset - old_sid_offset);
15936                 }
15937
15938                 break;
15939         }
15940
15941         case 0x301:     /* MAC_QUERY_FS_INFO */
15942                 /* Create time */
15943                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15944                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_create_time);
15945                 *bcp -= 8;
15946                 /* Modify Time */
15947                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15948                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_modify_time);
15949                 *bcp -= 8;
15950                 /* Backup Time */
15951                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
15952                 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_smb_backup_time);
15953                 *bcp -= 8;
15954                 /* Allocation blocks */
15955                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15956                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
15957                                     offset,
15958                                     4, ENC_LITTLE_ENDIAN);
15959                 COUNT_BYTES_TRANS_SUBR(4);
15960                 /* Allocation Block Size */
15961                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15962                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
15963                                     offset, 4, ENC_LITTLE_ENDIAN);
15964                 COUNT_BYTES_TRANS_SUBR(4);
15965                 /* Free Block Count */
15966                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15967                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
15968                                     offset, 4, ENC_LITTLE_ENDIAN);
15969                 COUNT_BYTES_TRANS_SUBR(4);
15970                 /* Finder Info ... */
15971                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
15972                 proto_tree_add_bytes_format_value(tree, hf_smb_mac_fndrinfo, tvb,
15973                                             offset, 32, NULL,
15974                                             "%s",
15975                                             tvb_format_text(tvb, offset, 32));
15976                 COUNT_BYTES_TRANS_SUBR(32);
15977                 /* Number Files */
15978                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15979                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
15980                                     offset, 4, ENC_LITTLE_ENDIAN);
15981                 COUNT_BYTES_TRANS_SUBR(4);
15982                 /* Number of Root Directories */
15983                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15984                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
15985                                     offset, 4, ENC_LITTLE_ENDIAN);
15986                 COUNT_BYTES_TRANS_SUBR(4);
15987                 /* Number of files */
15988                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15989                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
15990                                     offset, 4, ENC_LITTLE_ENDIAN);
15991                 COUNT_BYTES_TRANS_SUBR(4);
15992                 /* Dir Count */
15993                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15994                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
15995                                     offset, 4, ENC_LITTLE_ENDIAN);
15996                 COUNT_BYTES_TRANS_SUBR(4);
15997                 /* Mac Support Flags */
15998                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
15999                 support = tvb_get_letohl(tvb, offset);
16000                 item = proto_tree_add_item(tree, hf_smb_mac_sup, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16001                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
16002                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
16003                                        tvb, offset, 4, support);
16004                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
16005                                        tvb, offset, 4, support);
16006                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
16007                                        tvb, offset, 4, support);
16008                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
16009                                        tvb, offset, 4, support);
16010                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
16011                                        tvb, offset, 4, support);
16012                 COUNT_BYTES_TRANS_SUBR(4);
16013                 break;
16014         case 1006:      /* QUERY_FS_QUOTA_INFO */
16015                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
16016                 break;
16017         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
16018                 offset = dissect_qfsi_FS_FULL_SIZE_INFO(tvb, pinfo, tree, offset, bcp);
16019                 break;
16020         case 1008: /* Query Object ID */ {
16021                 offset = dissect_qfsi_FS_OBJECTID_INFO(tvb, pinfo, tree, offset, bcp);
16022                 break;
16023             }
16024         }
16025
16026         return offset;
16027 }
16028
16029 static int
16030 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
16031     proto_tree *parent_tree, smb_info_t *si)
16032 {
16033         proto_item           *item   = NULL;
16034         proto_tree           *tree   = NULL;
16035         smb_transact2_info_t *t2i;
16036         int                   count;
16037         gboolean              trunc;
16038         int                   offset = 0;
16039         guint16               dc;
16040
16041         dc = tvb_reported_length(tvb);
16042
16043         DISSECTOR_ASSERT(si);
16044
16045         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
16046                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
16047         else
16048                 t2i = NULL;
16049
16050         if (parent_tree) {
16051                 if ((t2i != NULL) && (t2i->subcmd != -1)) {
16052                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
16053                                 "%s Data",
16054                                 val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
16055                                                "Unknown (0x%02x)"));
16056                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
16057                 } else {
16058                         proto_tree_add_text(parent_tree, tvb, offset, dc,
16059                                             "Unknown Transaction2 Data");
16060                 }
16061         }
16062
16063         if (t2i == NULL) {
16064                 offset += dc;
16065                 return offset;
16066         }
16067         switch(t2i->subcmd) {
16068         case 0x0000:    /*TRANS2_OPEN2*/
16069                 /* XXX not implemented yet. See SNIA doc */
16070                 break;
16071         case 0x0001:    /*TRANS2_FIND_FIRST2*/
16072                 /* returned data */
16073                 count = si->info_count;
16074
16075                 if (count == -1) {
16076                         break;
16077                 }
16078
16079                 if (count) {
16080                         col_append_str(pinfo->cinfo, COL_INFO,
16081                                        ", Files:");
16082                 }
16083
16084                 while (count--) {
16085                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
16086                                                            offset, &dc, &trunc, si);
16087                         if (trunc)
16088                                 break;
16089                 }
16090                 break;
16091         case 0x0002:    /*TRANS2_FIND_NEXT2*/
16092                 /* returned data */
16093                 count = si->info_count;
16094
16095                 if (count == -1) {
16096                         break;
16097                 }
16098                 if (count) {
16099                         col_append_str(pinfo->cinfo, COL_INFO,
16100                                        ", Files:");
16101                 }
16102
16103                 while (count--) {
16104                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
16105                                 offset, &dc, &trunc, si);
16106                         if (trunc)
16107                                 break;
16108                 }
16109                 break;
16110         case 0x0003:    /*TRANS2_QUERY_FS_INFORMATION*/
16111                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc, si);
16112                 break;
16113         case 0x0004:    /*TRANS2_SET_FS_INFORMATION*/
16114                 offset = dissect_sfsi_response(tvb, pinfo, tree, offset, &dc, si);
16115                 break;
16116         case 0x0005:    /*TRANS2_QUERY_PATH_INFORMATION*/
16117                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
16118                 break;
16119         case 0x0006:    /*TRANS2_SET_PATH_INFORMATION*/
16120                 /* no data in this response */
16121                 break;
16122         case 0x0007:    /*TRANS2_QUERY_FILE_INFORMATION*/
16123                 /* identical to QUERY_PATH_INFO */
16124                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, item, offset, &dc, si);
16125                 break;
16126         case 0x0008:    /*TRANS2_SET_FILE_INFORMATION*/
16127                 /* no data in this response */
16128                 break;
16129         case 0x0009:    /*TRANS2_FSCTL*/
16130                 /* XXX dont know how to dissect this one (yet)*/
16131
16132                 /*
16133                  * XXX - "Microsoft Networks SMB File Sharing Protocol
16134                  * Extensions Version 3.0, Document Version 1.11,
16135                  * July 19, 1990" says this this contains a
16136                  * "File system specific return data block".
16137                  * (That means we may not be able to dissect it in any
16138                  * case.)
16139                  */
16140                 break;
16141         case 0x000a:    /*TRANS2_IOCTL2*/
16142                 /* XXX dont know how to dissect this one (yet)*/
16143
16144                 /*
16145                  * XXX - "Microsoft Networks SMB File Sharing Protocol
16146                  * Extensions Version 3.0, Document Version 1.11,
16147                  * July 19, 1990" says this this contains a
16148                  * "Device/function specific return data block".
16149                  * (That means we may not be able to dissect it in any
16150                  * case.)
16151                  */
16152                 break;
16153         case 0x000b:    /*TRANS2_FIND_NOTIFY_FIRST*/
16154                 /* XXX dont know how to dissect this one (yet)*/
16155
16156                 /*
16157                  * XXX - "Microsoft Networks SMB File Sharing Protocol
16158                  * Extensions Version 3.0, Document Version 1.11,
16159                  * July 19, 1990" says this this contains "the level
16160                  * dependent information about the changes which
16161                  * occurred".
16162                  */
16163                 break;
16164         case 0x000c:    /*TRANS2_FIND_NOTIFY_NEXT*/
16165                 /* XXX dont know how to dissect this one (yet)*/
16166
16167                 /*
16168                  * XXX - "Microsoft Networks SMB File Sharing Protocol
16169                  * Extensions Version 3.0, Document Version 1.11,
16170                  * July 19, 1990" says this this contains "the level
16171                  * dependent information about the changes which
16172                  * occurred".
16173                  */
16174                 break;
16175         case 0x000d:    /*TRANS2_CREATE_DIRECTORY*/
16176                 /* no data in this response */
16177                 break;
16178         case 0x000e:    /*TRANS2_SESSION_SETUP*/
16179                 /* XXX dont know how to dissect this one (yet)*/
16180                 break;
16181         case 0x0010:    /*TRANS2_GET_DFS_REFERRAL*/
16182                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc, si->unicode);
16183                 break;
16184         case 0x0011:    /*TRANS2_REPORT_DFS_INCONSISTENCY*/
16185                 /* the SNIA spec appears to say the response has no data */
16186                 break;
16187         case -1:
16188                 /*
16189                  * We don't know what the matching request was; don't
16190                  * bother putting anything else into the tree for the data.
16191                  */
16192                 offset += dc;
16193                 dc = 0;
16194                 break;
16195         }
16196
16197         /* ooops there were data we didnt know how to process */
16198         if (dc != 0) {
16199                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, ENC_NA);
16200                 offset += dc;
16201         }
16202
16203         return offset;
16204 }
16205
16206
16207 static int
16208 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb_info_t *si)
16209 {
16210         proto_item           *item   = NULL;
16211         proto_tree           *tree   = NULL;
16212         smb_transact2_info_t *t2i;
16213         guint16               fid;
16214         int                   lno;
16215         int                   offset = 0;
16216         int                   pc;
16217
16218         pc = tvb_reported_length(tvb);
16219
16220         DISSECTOR_ASSERT(si);
16221
16222         if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I))
16223                 t2i = (smb_transact2_info_t *)si->sip->extra_info;
16224         else
16225                 t2i = NULL;
16226
16227         if (parent_tree) {
16228                 if ((t2i != NULL) && (t2i->subcmd != -1)) {
16229                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
16230                                 "%s Parameters",
16231                                 val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
16232                                                "Unknown (0x%02x)"));
16233                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
16234                 } else {
16235                         proto_tree_add_text(parent_tree, tvb, offset, pc,
16236                                             "Unknown Transaction2 Parameters");
16237                 }
16238         }
16239
16240         if (t2i == NULL) {
16241                 offset += pc;
16242                 return offset;
16243         }
16244         switch(t2i->subcmd) {
16245         case 0x00:      /*TRANS2_OPEN2*/
16246                 /* fid */
16247                 fid = tvb_get_letohs(tvb, offset);
16248                 dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE, si);
16249                 offset += 2;
16250
16251                 /*
16252                  * XXX - Microsoft Networks SMB File Sharing Protocol
16253                  * Extensions Version 3.0, Document Version 1.11,
16254                  * July 19, 1990 says that the file attributes, create
16255                  * time (which it says is the last modification time),
16256                  * data size, granted access, file type, and IPC state
16257                  * are returned only if bit 0 is set in the open flags,
16258                  * and that the EA length is returned only if bit 3
16259                  * is set in the open flags.  Does that mean that,
16260                  * at least in that SMB dialect, those fields are not
16261                  * present in the reply parameters if the bits in
16262                  * question aren't set?
16263                  */
16264
16265                 /* File Attributes */
16266                 offset = dissect_file_attributes(tvb, tree, offset);
16267
16268                 /* create time */
16269                 offset = dissect_smb_datetime(tvb, tree, offset,
16270                         hf_smb_create_time,
16271                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
16272
16273                 /* data size */
16274                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16275                 offset += 4;
16276
16277                 /* granted access */
16278                 offset = dissect_access(tvb, tree, offset, "Granted");
16279
16280                 /* File Type */
16281                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16282                 offset += 2;
16283
16284                 /* IPC State */
16285                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
16286
16287                 /* open_action */
16288                 offset = dissect_open_action(tvb, tree, offset);
16289
16290                 /* server unique file ID */
16291                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16292                 offset += 4;
16293
16294                 /* ea error offset, only a 16 bit integer here */
16295                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16296                 offset += 2;
16297
16298                 /* ea length */
16299                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16300                 offset += 4;
16301
16302                 break;
16303         case 0x01:      /*TRANS2_FIND_FIRST2*/
16304                 /* Find First2 information level */
16305                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
16306
16307                 /* sid */
16308                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16309                 offset += 2;
16310
16311                 /* search count */
16312                 si->info_count = tvb_get_letohs(tvb, offset);
16313                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
16314                 offset += 2;
16315
16316                 /* end of search */
16317                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16318                 offset += 2;
16319
16320                 /* ea error offset, only a 16 bit integer here */
16321                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16322                 offset += 2;
16323
16324                 /* last name offset */
16325                 lno = tvb_get_letohs(tvb, offset);
16326                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
16327                 offset += 2;
16328
16329                 break;
16330         case 0x02:      /*TRANS2_FIND_NEXT2*/
16331                 /* search count */
16332                 si->info_count = tvb_get_letohs(tvb, offset);
16333                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
16334                 offset += 2;
16335
16336                 /* end of search */
16337                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16338                 offset += 2;
16339
16340                 /* ea_error_offset, only a 16 bit integer here*/
16341                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16342                 offset += 2;
16343
16344                 /* last name offset */
16345                 lno = tvb_get_letohs(tvb, offset);
16346                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
16347                 offset += 2;
16348
16349                 break;
16350         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
16351                 /* no parameter block here */
16352                 break;
16353         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
16354                 /* ea_error_offset, only a 16 bit integer here*/
16355                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16356                 offset += 2;
16357
16358                 break;
16359         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
16360                 /* ea_error_offset, only a 16 bit integer here*/
16361                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16362                 offset += 2;
16363
16364                 break;
16365         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
16366                 /* ea_error_offset, only a 16 bit integer here*/
16367                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16368                 offset += 2;
16369
16370                 break;
16371         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
16372                 /* ea_error_offset, only a 16 bit integer here*/
16373                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16374                 offset += 2;
16375
16376                 break;
16377         case 0x09:      /*TRANS2_FSCTL*/
16378                 /* XXX dont know how to dissect this one (yet)*/
16379
16380                 /*
16381                  * XXX - "Microsoft Networks SMB File Sharing Protocol
16382                  * Extensions Version 3.0, Document Version 1.11,
16383                  * July 19, 1990" says this this contains a
16384                  * "File system specific return parameter block".
16385                  * (That means we may not be able to dissect it in any
16386                  * case.)
16387                  */
16388                 break;
16389         case 0x0a:      /*TRANS2_IOCTL2*/
16390                 /* XXX dont know how to dissect this one (yet)*/
16391
16392                 /*
16393                  * XXX - "Microsoft Networks SMB File Sharing Protocol
16394                  * Extensions Version 3.0, Document Version 1.11,
16395                  * July 19, 1990" says this this contains a
16396                  * "Device/function specific return parameter block".
16397                  * (That means we may not be able to dissect it in any
16398                  * case.)
16399                  */
16400                 break;
16401         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
16402                 /* Find Notify information level */
16403                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
16404
16405                 /* Monitor handle */
16406                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16407                 offset += 2;
16408
16409                 /* Change count */
16410                 si->info_count = tvb_get_letohs(tvb, offset);
16411                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
16412                 offset += 2;
16413
16414                 /* ea_error_offset, only a 16 bit integer here*/
16415                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16416                 offset += 2;
16417
16418                 break;
16419         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
16420                 /* Find Notify information level */
16421                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
16422
16423                 /* Change count */
16424                 si->info_count = tvb_get_letohs(tvb, offset);
16425                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
16426                 offset += 2;
16427
16428                 /* ea_error_offset, only a 16 bit integer here*/
16429                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16430                 offset += 2;
16431
16432                 break;
16433         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
16434                 /* ea error offset, only a 16 bit integer here */
16435                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
16436                 offset += 2;
16437
16438                 break;
16439         case 0x0e:      /*TRANS2_SESSION_SETUP*/
16440                 /* XXX dont know how to dissect this one (yet)*/
16441                 break;
16442         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
16443                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
16444                 break;
16445         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
16446                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
16447                 break;
16448         case -1:
16449                 /*
16450                  * We don't know what the matching request was; don't
16451                  * bother putting anything else into the tree for the data.
16452                  */
16453                 offset += pc;
16454                 break;
16455         }
16456
16457         /* ooops there were data we didnt know how to process */
16458         if (offset < pc) {
16459                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, ENC_NA);
16460                 offset += pc-offset;
16461         }
16462         return offset;
16463 }
16464
16465
16466 static int
16467 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si)
16468 {
16469         guint8                sc, wc;
16470         guint16               od     = 0, po = 0, pc = 0, pd = 0, dc = 0, dd = 0, td = 0, tp = 0;
16471         smb_transact2_info_t *t2i    = NULL;
16472         guint16               bc;
16473         int                   padcnt;
16474         gboolean              dissected_trans;
16475         fragment_head        *r_fd   = NULL;
16476         tvbuff_t             *pd_tvb = NULL, *d_tvb = NULL, *p_tvb = NULL;
16477         tvbuff_t             *s_tvb  = NULL, *sp_tvb = NULL;
16478         gboolean              save_fragmented;
16479         proto_item           *item;
16480
16481         DISSECTOR_ASSERT(si);
16482
16483         switch(si->cmd) {
16484         case SMB_COM_TRANSACTION2:
16485                 /* transaction2 */
16486                 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_T2I)) {
16487                         t2i = (smb_transact2_info_t *)si->sip->extra_info;
16488                 } else
16489                         t2i = NULL;
16490                 if (t2i == NULL) {
16491                         /*
16492                          * We didn't see the matching request, so we don't
16493                          * know what type of transaction this is.
16494                          */
16495                         proto_tree_add_uint_format_value(tree, hf_smb_trans2_subcmd, tvb, 0, 0, -1,
16496                                 "<UNKNOWN> since request packet wasn't seen");
16497                         col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
16498                 } else {
16499                         si->info_level = t2i->info_level;
16500                         if (t2i->subcmd == -1) {
16501                                 /*
16502                                  * We didn't manage to extract the subcommand
16503                                  * from the matching request (perhaps because
16504                                  * the frame was short), so we don't know what
16505                                  * type of transaction this is.
16506                                  */
16507                                 proto_tree_add_uint_format_value(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd,
16508                                         "<UNKNOWN> since transaction code wasn't found in request packet");
16509                                 col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
16510                         } else {
16511                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
16512                                 switch (t2i->subcmd) {
16513
16514                                 case 0x0001:    /* FIND_FIRST2 */
16515                                         if (t2i->info_level == -1)
16516                                                 item = proto_tree_add_uint_format_value(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level,
16517                                                                                 "<UNKNOWN> since information level wasn't found in request packet");
16518                                         else
16519                                                 item = proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
16520                                         PROTO_ITEM_SET_GENERATED(item);
16521                                         if (t2i->name) {
16522                                                 item = proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
16523                                                 PROTO_ITEM_SET_GENERATED(item);
16524                                         }
16525                                         break;
16526
16527                                 case 0x0005:    /* QUERY_PATH_INFORMATION */
16528                                         if (t2i->info_level == -1)
16529                                                 item = proto_tree_add_uint_format_value(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level,
16530                                                                                 "<UNKNOWN> since information level wasn't found in request packet");
16531                                         else
16532                                                 item = proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
16533                                         PROTO_ITEM_SET_GENERATED(item);
16534                                         if (t2i->name) {
16535                                                 item = proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
16536                                                 PROTO_ITEM_SET_GENERATED(item);
16537                                         }
16538                                         break;
16539
16540                                 case 0x0007:    /* QUERY_FILE_INFORMATION */
16541                                         if (t2i->info_level == -1)
16542                                                 item = proto_tree_add_uint_format_value(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level,
16543                                                                                 "<UNKNOWN> since information level wasn't found in request packet");
16544                                         else
16545                                                 item = proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
16546                                         PROTO_ITEM_SET_GENERATED(item);
16547                                         break;
16548
16549                                 case 0x0003:    /* QUERY_FS_INFORMATION */
16550                                         if (t2i->info_level == -1)
16551                                                 item = proto_tree_add_uint_format_value(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level,
16552                                                                                 "<UNKNOWN> since information level wasn't found in request packet");
16553                                         else
16554                                                 item = proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
16555                                         PROTO_ITEM_SET_GENERATED(item);
16556                                         break;
16557
16558                                 case 0x0004:    /* SET_FS_INFORMATION */
16559                                         if (t2i->info_level == -1)
16560                                                 item = proto_tree_add_uint_format_value(tree, hf_smb_sfsi_information_level, tvb, 0, 0, si->info_level,
16561                                                                                 "<UNKNOWN> since information level wasn't found in request packet");
16562                                         else
16563                                                 item = proto_tree_add_uint(tree, hf_smb_sfsi_information_level, tvb, 0, 0, si->info_level);
16564                                         PROTO_ITEM_SET_GENERATED(item);
16565                                         break;
16566                                 }
16567
16568                                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
16569                                                 val_to_str_ext(t2i->subcmd,
16570                                                                &trans2_cmd_vals_ext,
16571                                                                "<unknown (0x%02x)>"));
16572                         }
16573                 }
16574                 break;
16575         }
16576
16577         WORD_COUNT;
16578
16579         /* total param count, only a 16bit integer here */
16580         tp = tvb_get_letohs(tvb, offset);
16581         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
16582         offset += 2;
16583
16584         /* total data count, only a 16 bit integer here */
16585         td = tvb_get_letohs(tvb, offset);
16586         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
16587         offset += 2;
16588
16589         /* 2 reserved bytes */
16590         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
16591         offset += 2;
16592
16593         /* param count */
16594         pc = tvb_get_letohs(tvb, offset);
16595         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
16596         offset += 2;
16597
16598         /* param offset */
16599         po = tvb_get_letohs(tvb, offset);
16600         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
16601         offset += 2;
16602
16603         /* param disp */
16604         pd = tvb_get_letohs(tvb, offset);
16605         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
16606         offset += 2;
16607
16608         /* data count */
16609         dc = tvb_get_letohs(tvb, offset);
16610         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
16611         offset += 2;
16612
16613         /* data offset */
16614         od = tvb_get_letohs(tvb, offset);
16615         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
16616         offset += 2;
16617
16618         /* data disp */
16619         dd = tvb_get_letohs(tvb, offset);
16620         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
16621         offset += 2;
16622
16623         /* setup count */
16624         sc = tvb_get_guint8(tvb, offset);
16625         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
16626         offset += 1;
16627
16628         /* reserved byte */
16629         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
16630         offset += 1;
16631
16632
16633         /* if there were any setup bytes, put them in a tvb for later */
16634         if (sc) {
16635                 if ((2*sc) > tvb_length_remaining(tvb, offset)) {
16636                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
16637                 } else {
16638                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
16639                 }
16640                 sp_tvb = tvb_new_subset_remaining(tvb, offset);
16641         } else {
16642                 s_tvb  = NULL;
16643                 sp_tvb = NULL;
16644         }
16645         offset += 2*sc;
16646
16647
16648         BYTE_COUNT;
16649
16650
16651         /* reassembly of SMB Transaction data payload.
16652            In this section we do reassembly of both the data and parameters
16653            blocks of the SMB transaction command.
16654         */
16655         save_fragmented = pinfo->fragmented;
16656         /* do we need reassembly? */
16657         if ( (td != dc) || (tp != pc) ) {
16658                 /* oh yeah, either data or parameter section needs
16659                    reassembly
16660                 */
16661                 pinfo->fragmented = TRUE;
16662                 if (smb_trans_reassembly) {
16663                         /* ...and we were told to do reassembly */
16664                         if (pc) {
16665                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
16666                                                              po, pc, pd, td+tp, si);
16667
16668                         }
16669                         if ((r_fd == NULL) && dc) {
16670                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
16671                                                              od, dc, dd+tp, td+tp, si);
16672                         }
16673                 }
16674         }
16675
16676         /* if we got a reassembled fd structure from the reassembly routine we must
16677            create pd_tvb from it
16678         */
16679         if (r_fd) {
16680                 proto_item *frag_tree_item;
16681
16682                 pd_tvb = tvb_new_chain(tvb, r_fd->tvb_data);
16683                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
16684                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
16685         }
16686
16687
16688         if (pd_tvb) {
16689                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
16690                 if (tp) {
16691                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
16692                 }
16693                 if (td) {
16694                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
16695                 }
16696         } else {
16697                 /* It was not reassembled. Do as best as we can.
16698                  * in this case we always try to dissect the stuff if
16699                  * data and param displacement is 0. i.e. for the first
16700                  * (and maybe only) packet.
16701                  */
16702                 if ( (pd == 0) && (dd == 0) ) {
16703                         int min;
16704                         int reported_min;
16705                         min = MIN(pc, tvb_length_remaining(tvb, po));
16706                         reported_min = MIN(pc, tvb_reported_length_remaining(tvb, po));
16707                         if (min && reported_min) {
16708                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
16709                         }
16710                         min = MIN(dc, tvb_length_remaining(tvb, od));
16711                         reported_min = MIN(dc, tvb_reported_length_remaining(tvb, od));
16712                         if (min && reported_min) {
16713                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
16714                         }
16715                         /*
16716                          * A tvbuff containing the parameters
16717                          * and the data.
16718                          * XXX - check pc and dc as well?
16719                          */
16720                         if (tvb_length_remaining(tvb, po)) {
16721                                 pd_tvb = tvb_new_subset_remaining(tvb, po);
16722                         }
16723                 }
16724         }
16725
16726
16727
16728         /* parameters */
16729         if (po > offset) {
16730                 /* We have some padding bytes.
16731                 */
16732                 padcnt = po-offset;
16733                 if (padcnt > bc)
16734                         padcnt = bc;
16735                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
16736                 COUNT_BYTES(padcnt);
16737         }
16738         if ((si->cmd == SMB_COM_TRANSACTION2) && p_tvb) {
16739                 /* TRANSACTION2 parameters*/
16740                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree, si);
16741         }
16742         COUNT_BYTES(pc);
16743
16744
16745         /* data */
16746         if (od > offset) {
16747                 /* We have some initial padding bytes.
16748                 */
16749                 padcnt = od-offset;
16750                 if (padcnt > bc)
16751                         padcnt = bc;
16752                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, ENC_NA);
16753                 COUNT_BYTES(padcnt);
16754         }
16755         /*
16756          * If the data count is bigger than the count of bytes
16757          * remaining, clamp it so that the count of bytes remaining
16758          * doesn't go negative.
16759          */
16760         if (dc > bc)
16761                 dc = bc;
16762         COUNT_BYTES(dc);
16763
16764
16765
16766         /* from now on, everything is in separate tvbuffs so we dont count
16767            the bytes with COUNT_BYTES any more.
16768            neither do we reference offset any more (which by now points to the
16769            first byte AFTER this PDU */
16770
16771
16772         if ((si->cmd == SMB_COM_TRANSACTION2) && d_tvb) {
16773                 /* TRANSACTION2 parameters*/
16774                 dissect_transaction2_response_data(d_tvb, pinfo, tree, si);
16775         }
16776
16777
16778         if (si->cmd == SMB_COM_TRANSACTION) {
16779                 smb_transact_info_t *tri;
16780
16781                 dissected_trans = FALSE;
16782                 if ((si->sip != NULL) && (si->sip->extra_info_type == SMB_EI_TRI))
16783                         tri = (smb_transact_info_t *)si->sip->extra_info;
16784                 else
16785                         tri = NULL;
16786                 if (tri != NULL) {
16787                         switch(tri->subcmd) {
16788
16789                         case TRANSACTION_PIPE:
16790                                 /* This function is safe to call for
16791                                    s_tvb == sp_tvb == NULL, i.e. if we don't
16792                                    know them at this point.
16793                                    It's also safe to call if "p_tvb"
16794                                    or "d_tvb" are null.
16795                                 */
16796                                 if ( pd_tvb) {
16797                                         dissected_trans = dissect_pipe_smb(
16798                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
16799                                                 d_tvb, NULL, pinfo, top_tree_global, si);
16800                                 }
16801                                 break;
16802
16803                         case TRANSACTION_MAILSLOT:
16804                                 /* This one should be safe to call
16805                                    even if s_tvb and sp_tvb is NULL
16806                                 */
16807                                 if (d_tvb) {
16808                                         dissected_trans = dissect_mailslot_smb(
16809                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
16810                                                 top_tree_global, si);
16811                                 }
16812                                 break;
16813                         }
16814                 }
16815                 if (!dissected_trans) {
16816                         /* This one is safe to call for s_tvb == p_tvb == d_tvb == NULL */
16817                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
16818                 }
16819         }
16820
16821
16822         if ( (p_tvb == 0) && (d_tvb == 0) ) {
16823                 col_append_str(pinfo->cinfo, COL_INFO,
16824                                        "[transact continuation]");
16825         }
16826
16827         pinfo->fragmented = save_fragmented;
16828         END_OF_SMB
16829
16830         return offset;
16831 }
16832
16833
16834 static int
16835 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_)
16836 {
16837         guint8  wc;
16838         guint16 bc;
16839
16840         WORD_COUNT;
16841
16842         /* Monitor handle */
16843         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
16844         offset += 2;
16845
16846         BYTE_COUNT;
16847
16848         END_OF_SMB
16849
16850         return offset;
16851 }
16852
16853 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16854    END Transaction/Transaction2 Primary and secondary requests
16855    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
16856
16857
16858 static int
16859 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_, smb_info_t *si _U_)
16860 {
16861         guint8  wc;
16862         guint16 bc;
16863
16864         WORD_COUNT;
16865
16866         if (wc != 0) {
16867                 tvb_ensure_bytes_exist(tvb, offset, wc*2);
16868                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
16869                 offset += wc*2;
16870         }
16871
16872         BYTE_COUNT;
16873
16874         if (bc != 0) {
16875                 tvb_ensure_bytes_exist(tvb, offset, bc);
16876                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
16877                 offset += bc;
16878                 bc = 0;
16879         }
16880
16881         END_OF_SMB
16882
16883         return offset;
16884 }
16885
16886 typedef struct _smb_function {
16887         int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
16888         int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
16889 } smb_function;
16890
16891 static smb_function smb_dissector[256] = {
16892   /* 0x00 Create Dir*/                 {dissect_old_dir_request            , dissect_empty},
16893   /* 0x01 Delete Dir*/                 {dissect_old_dir_request            , dissect_empty},
16894   /* 0x02 Open File*/                  {dissect_open_file_request          , dissect_open_file_response},
16895   /* 0x03 Create File*/                {dissect_create_file_request        , dissect_create_file_response},
16896   /* 0x04 Close File*/                 {dissect_close_file_request         , dissect_empty},
16897   /* 0x05 Flush File*/                 {dissect_flush_file_request         , dissect_empty},
16898   /* 0x06 Delete File*/                {dissect_delete_file_request        , dissect_empty},
16899   /* 0x07 Rename File*/                {dissect_rename_file_request        , dissect_rename_file_response},
16900   /* 0x08 Query Info*/                 {dissect_query_information_request  , dissect_query_information_response},
16901   /* 0x09 Set Info*/                   {dissect_set_information_request    , dissect_empty},
16902   /* 0x0a Read File*/                  {dissect_read_file_request          , dissect_read_file_response},
16903   /* 0x0b Write File*/                 {dissect_write_file_request         , dissect_write_file_response},
16904   /* 0x0c Lock Byte Range*/            {dissect_lock_request               , dissect_empty},
16905   /* 0x0d Unlock Byte Range*/          {dissect_lock_request               , dissect_empty},
16906   /* 0x0e Create Temp*/                {dissect_create_temporary_request   , dissect_create_temporary_response},
16907   /* 0x0f Create New*/                 {dissect_create_file_request        , dissect_create_new_response},
16908
16909   /* 0x10 Check Dir*/                  {dissect_old_dir_request            , dissect_empty},
16910   /* 0x11 Process Exit*/               {dissect_empty                      , dissect_empty},
16911   /* 0x12 Seek File*/                  {dissect_seek_file_request          , dissect_seek_file_response},
16912   /* 0x13 Lock And Read*/              {dissect_read_file_request          , dissect_lock_and_read_response},
16913   /* 0x14 Write And Unlock*/           {dissect_write_file_request         , dissect_write_file_response},
16914   /* 0x15 */                           {dissect_unknown                    , dissect_unknown},
16915   /* 0x16 */                           {dissect_unknown                    , dissect_unknown},
16916   /* 0x17 */                           {dissect_unknown                    , dissect_unknown},
16917   /* 0x18 */                           {dissect_unknown                    , dissect_unknown},
16918   /* 0x19 */                           {dissect_unknown                    , dissect_unknown},
16919   /* 0x1a Read Raw*/                   {dissect_read_raw_request           , dissect_unknown},
16920   /* 0x1b Read MPX*/                   {dissect_read_mpx_request           , dissect_read_mpx_response},
16921   /* 0x1c Read MPX Secondary*/         {dissect_unknown                    , dissect_unknown},
16922   /* 0x1d Write Raw*/                  {dissect_write_raw_request          , dissect_write_raw_response},
16923   /* 0x1e Write MPX*/                  {dissect_write_mpx_request          , dissect_write_mpx_response},
16924   /* 0x1f Write MPX Secondary*/        {dissect_unknown                    , dissect_unknown},
16925
16926   /* 0x20 Write Complete*/             {dissect_unknown                    , dissect_write_and_close_response},
16927   /* 0x21 */                           {dissect_unknown                    , dissect_unknown},
16928   /* 0x22 Set Info2*/                  {dissect_set_information2_request   , dissect_empty},
16929   /* 0x23 Query Info2*/                {dissect_query_information2_request , dissect_query_information2_response},
16930   /* 0x24 Locking And X*/              {dissect_locking_andx_request       , dissect_locking_andx_response},
16931   /* 0x25 Transaction*/                {dissect_transaction_request        , dissect_transaction_response},
16932   /* 0x26 Transaction Secondary*/      {dissect_transaction_request        , dissect_unknown}, /*This SMB has no response */
16933   /* 0x27 IOCTL*/                      {dissect_unknown                    , dissect_unknown},
16934   /* 0x28 IOCTL Secondary*/            {dissect_unknown                    , dissect_unknown},
16935   /* 0x29 Copy File*/                  {dissect_copy_request               , dissect_move_copy_response},
16936   /* 0x2a Move File*/                  {dissect_move_request               , dissect_move_copy_response},
16937   /* 0x2b Echo*/                       {dissect_echo_request               , dissect_echo_response},
16938   /* 0x2c Write And Close*/            {dissect_write_and_close_request    , dissect_write_and_close_response},
16939   /* 0x2d Open And X*/                 {dissect_open_andx_request          , dissect_open_andx_response},
16940   /* 0x2e Read And X*/                 {dissect_read_andx_request          , dissect_read_andx_response},
16941   /* 0x2f Write And X*/                {dissect_write_andx_request         , dissect_write_andx_response},
16942
16943   /* 0x30 */                           {dissect_unknown                    , dissect_unknown},
16944   /* 0x31 Close And Tree Disconnect */ {dissect_close_file_request         , dissect_empty},
16945   /* 0x32 Transaction2*/               {dissect_transaction_request        , dissect_transaction_response},
16946   /* 0x33 Transaction2 Secondary*/     {dissect_transaction_request        , dissect_unknown}, /*This SMB has no response */
16947   /* 0x34 Find Close2*/                {dissect_sid                        , dissect_empty},
16948   /* 0x35 Find Notify Close*/          {dissect_find_notify_close          , dissect_empty},
16949   /* 0x36 */  {dissect_unknown, dissect_unknown},
16950   /* 0x37 */  {dissect_unknown, dissect_unknown},
16951   /* 0x38 */  {dissect_unknown, dissect_unknown},
16952   /* 0x39 */  {dissect_unknown, dissect_unknown},
16953   /* 0x3a */  {dissect_unknown, dissect_unknown},
16954   /* 0x3b */  {dissect_unknown, dissect_unknown},
16955   /* 0x3c */  {dissect_unknown, dissect_unknown},
16956   /* 0x3d */  {dissect_unknown, dissect_unknown},
16957   /* 0x3e */  {dissect_unknown, dissect_unknown},
16958   /* 0x3f */  {dissect_unknown, dissect_unknown},
16959
16960   /* 0x40 */  {dissect_unknown, dissect_unknown},
16961   /* 0x41 */  {dissect_unknown, dissect_unknown},
16962   /* 0x42 */  {dissect_unknown, dissect_unknown},
16963   /* 0x43 */  {dissect_unknown, dissect_unknown},
16964   /* 0x44 */  {dissect_unknown, dissect_unknown},
16965   /* 0x45 */  {dissect_unknown, dissect_unknown},
16966   /* 0x46 */  {dissect_unknown, dissect_unknown},
16967   /* 0x47 */  {dissect_unknown, dissect_unknown},
16968   /* 0x48 */  {dissect_unknown, dissect_unknown},
16969   /* 0x49 */  {dissect_unknown, dissect_unknown},
16970   /* 0x4a */  {dissect_unknown, dissect_unknown},
16971   /* 0x4b */  {dissect_unknown, dissect_unknown},
16972   /* 0x4c */  {dissect_unknown, dissect_unknown},
16973   /* 0x4d */  {dissect_unknown, dissect_unknown},
16974   /* 0x4e */  {dissect_unknown, dissect_unknown},
16975   /* 0x4f */  {dissect_unknown, dissect_unknown},
16976
16977   /* 0x50 */  {dissect_unknown, dissect_unknown},
16978   /* 0x51 */  {dissect_unknown, dissect_unknown},
16979   /* 0x52 */  {dissect_unknown, dissect_unknown},
16980   /* 0x53 */  {dissect_unknown, dissect_unknown},
16981   /* 0x54 */  {dissect_unknown, dissect_unknown},
16982   /* 0x55 */  {dissect_unknown, dissect_unknown},
16983   /* 0x56 */  {dissect_unknown, dissect_unknown},
16984   /* 0x57 */  {dissect_unknown, dissect_unknown},
16985   /* 0x58 */  {dissect_unknown, dissect_unknown},
16986   /* 0x59 */  {dissect_unknown, dissect_unknown},
16987   /* 0x5a */  {dissect_unknown, dissect_unknown},
16988   /* 0x5b */  {dissect_unknown, dissect_unknown},
16989   /* 0x5c */  {dissect_unknown, dissect_unknown},
16990   /* 0x5d */  {dissect_unknown, dissect_unknown},
16991   /* 0x5e */  {dissect_unknown, dissect_unknown},
16992   /* 0x5f */  {dissect_unknown, dissect_unknown},
16993
16994   /* 0x60 */  {dissect_unknown, dissect_unknown},
16995   /* 0x61 */  {dissect_unknown, dissect_unknown},
16996   /* 0x62 */  {dissect_unknown, dissect_unknown},
16997   /* 0x63 */  {dissect_unknown, dissect_unknown},
16998   /* 0x64 */  {dissect_unknown, dissect_unknown},
16999   /* 0x65 */  {dissect_unknown, dissect_unknown},
17000   /* 0x66 */  {dissect_unknown, dissect_unknown},
17001   /* 0x67 */  {dissect_unknown, dissect_unknown},
17002   /* 0x68 */  {dissect_unknown, dissect_unknown},
17003   /* 0x69 */  {dissect_unknown, dissect_unknown},
17004   /* 0x6a */  {dissect_unknown, dissect_unknown},
17005   /* 0x6b */  {dissect_unknown, dissect_unknown},
17006   /* 0x6c */  {dissect_unknown, dissect_unknown},
17007   /* 0x6d */  {dissect_unknown, dissect_unknown},
17008   /* 0x6e */  {dissect_unknown, dissect_unknown},
17009   /* 0x6f */  {dissect_unknown, dissect_unknown},
17010
17011   /* 0x70 Tree Connect*/        {dissect_tree_connect_request       , dissect_tree_connect_response},
17012   /* 0x71 Tree Disconnect*/     {dissect_empty                      , dissect_empty},
17013   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request            , dissect_negprot_response},
17014   /* 0x73 Session Setup And X*/ {dissect_session_setup_andx_request , dissect_session_setup_andx_response},
17015   /* 0x74 Logoff And X*/        {dissect_empty_andx                 , dissect_empty_andx},
17016   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request  , dissect_tree_connect_andx_response},
17017   /* 0x76 */  {dissect_unknown, dissect_unknown},
17018   /* 0x77 */  {dissect_unknown, dissect_unknown},
17019   /* 0x78 */  {dissect_unknown, dissect_unknown},
17020   /* 0x79 */  {dissect_unknown, dissect_unknown},
17021   /* 0x7a */  {dissect_unknown, dissect_unknown},
17022   /* 0x7b */  {dissect_unknown, dissect_unknown},
17023   /* 0x7c */  {dissect_unknown, dissect_unknown},
17024   /* 0x7d */  {dissect_unknown, dissect_unknown},
17025   /* 0x7e */  {dissect_unknown, dissect_unknown},
17026   /* 0x7f */  {dissect_unknown, dissect_unknown},
17027
17028   /* 0x80 Query Info Disk*/ {dissect_empty              , dissect_query_information_disk_response},
17029   /* 0x81 Search Dir*/      {dissect_search_dir_request , dissect_search_dir_response},
17030   /* 0x82 Find*/            {dissect_find_request       , dissect_find_response},
17031   /* 0x83 Find Unique*/     {dissect_find_request       , dissect_find_response},
17032   /* 0x84 Find Close*/      {dissect_find_close_request , dissect_find_close_response},
17033   /* 0x85 */  {dissect_unknown, dissect_unknown},
17034   /* 0x86 */  {dissect_unknown, dissect_unknown},
17035   /* 0x87 */  {dissect_unknown, dissect_unknown},
17036   /* 0x88 */  {dissect_unknown, dissect_unknown},
17037   /* 0x89 */  {dissect_unknown, dissect_unknown},
17038   /* 0x8a */  {dissect_unknown, dissect_unknown},
17039   /* 0x8b */  {dissect_unknown, dissect_unknown},
17040   /* 0x8c */  {dissect_unknown, dissect_unknown},
17041   /* 0x8d */  {dissect_unknown, dissect_unknown},
17042   /* 0x8e */  {dissect_unknown, dissect_unknown},
17043   /* 0x8f */  {dissect_unknown, dissect_unknown},
17044
17045   /* 0x90 */  {dissect_unknown, dissect_unknown},
17046   /* 0x91 */  {dissect_unknown, dissect_unknown},
17047   /* 0x92 */  {dissect_unknown, dissect_unknown},
17048   /* 0x93 */  {dissect_unknown, dissect_unknown},
17049   /* 0x94 */  {dissect_unknown, dissect_unknown},
17050   /* 0x95 */  {dissect_unknown, dissect_unknown},
17051   /* 0x96 */  {dissect_unknown, dissect_unknown},
17052   /* 0x97 */  {dissect_unknown, dissect_unknown},
17053   /* 0x98 */  {dissect_unknown, dissect_unknown},
17054   /* 0x99 */  {dissect_unknown, dissect_unknown},
17055   /* 0x9a */  {dissect_unknown, dissect_unknown},
17056   /* 0x9b */  {dissect_unknown, dissect_unknown},
17057   /* 0x9c */  {dissect_unknown, dissect_unknown},
17058   /* 0x9d */  {dissect_unknown, dissect_unknown},
17059   /* 0x9e */  {dissect_unknown, dissect_unknown},
17060   /* 0x9f */  {dissect_unknown, dissect_unknown},
17061
17062   /* 0xa0 NT Transaction*/     {dissect_nt_transaction_request , dissect_nt_transaction_response},
17063   /* 0xa1 NT Trans secondary*/ {dissect_nt_transaction_request , dissect_nt_transaction_response},
17064   /* 0xa2 NT CreateAndX*/      {dissect_nt_create_andx_request , dissect_nt_create_andx_response},
17065   /* 0xa3 */                   {dissect_unknown                , dissect_unknown},
17066   /* 0xa4 NT Cancel*/          {dissect_nt_cancel_request      , dissect_unknown}, /*no response to this one*/
17067   /* 0xa5 NT Rename*/          {dissect_nt_rename_file_request , dissect_empty},
17068   /* 0xa6 */  {dissect_unknown, dissect_unknown},
17069   /* 0xa7 */  {dissect_unknown, dissect_unknown},
17070   /* 0xa8 */  {dissect_unknown, dissect_unknown},
17071   /* 0xa9 */  {dissect_unknown, dissect_unknown},
17072   /* 0xaa */  {dissect_unknown, dissect_unknown},
17073   /* 0xab */  {dissect_unknown, dissect_unknown},
17074   /* 0xac */  {dissect_unknown, dissect_unknown},
17075   /* 0xad */  {dissect_unknown, dissect_unknown},
17076   /* 0xae */  {dissect_unknown, dissect_unknown},
17077   /* 0xaf */  {dissect_unknown, dissect_unknown},
17078
17079   /* 0xb0 */  {dissect_unknown, dissect_unknown},
17080   /* 0xb1 */  {dissect_unknown, dissect_unknown},
17081   /* 0xb2 */  {dissect_unknown, dissect_unknown},
17082   /* 0xb3 */  {dissect_unknown, dissect_unknown},
17083   /* 0xb4 */  {dissect_unknown, dissect_unknown},
17084   /* 0xb5 */  {dissect_unknown, dissect_unknown},
17085   /* 0xb6 */  {dissect_unknown, dissect_unknown},
17086   /* 0xb7 */  {dissect_unknown, dissect_unknown},
17087   /* 0xb8 */  {dissect_unknown, dissect_unknown},
17088   /* 0xb9 */  {dissect_unknown, dissect_unknown},
17089   /* 0xba */  {dissect_unknown, dissect_unknown},
17090   /* 0xbb */  {dissect_unknown, dissect_unknown},
17091   /* 0xbc */  {dissect_unknown, dissect_unknown},
17092   /* 0xbd */  {dissect_unknown, dissect_unknown},
17093   /* 0xbe */  {dissect_unknown, dissect_unknown},
17094   /* 0xbf */  {dissect_unknown, dissect_unknown},
17095
17096   /* 0xc0 Open Print File*/  {dissect_open_print_file_request  , dissect_open_print_file_response},
17097   /* 0xc1 Write Print File*/ {dissect_write_print_file_request , dissect_empty},
17098   /* 0xc2 Close Print File*/ {dissect_close_print_file_request , dissect_empty},
17099   /* 0xc3 Get Print Queue*/  {dissect_get_print_queue_request  , dissect_get_print_queue_response},
17100   /* 0xc4 */  {dissect_unknown, dissect_unknown},
17101   /* 0xc5 */  {dissect_unknown, dissect_unknown},
17102   /* 0xc6 */  {dissect_unknown, dissect_unknown},
17103   /* 0xc7 */  {dissect_unknown, dissect_unknown},
17104   /* 0xc8 */  {dissect_unknown, dissect_unknown},
17105   /* 0xc9 */  {dissect_unknown, dissect_unknown},
17106   /* 0xca */  {dissect_unknown, dissect_unknown},
17107   /* 0xcb */  {dissect_unknown, dissect_unknown},
17108   /* 0xcc */  {dissect_unknown, dissect_unknown},
17109   /* 0xcd */  {dissect_unknown, dissect_unknown},
17110   /* 0xce */  {dissect_unknown, dissect_unknown},
17111   /* 0xcf */  {dissect_unknown, dissect_unknown},
17112
17113   /* 0xd0 Send Single Block Message*/         {dissect_send_single_block_message_request      , dissect_empty},
17114   /* 0xd1 Send Broadcast Message*/            {dissect_send_single_block_message_request      , dissect_empty},
17115   /* 0xd2 Forward User Name*/                 {dissect_forwarded_name                         , dissect_empty},
17116   /* 0xd3 Cancel Forward*/                    {dissect_forwarded_name                         , dissect_empty},
17117   /* 0xd4 Get Machine Name*/                  {dissect_empty                                  , dissect_get_machine_name_response},
17118   /* 0xd5 Send Start of Multi-block Message*/ {dissect_send_multi_block_message_start_request , dissect_message_group_id},
17119   /* 0xd6 Send End of Multi-block Message*/   {dissect_message_group_id                       , dissect_empty},
17120   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request  , dissect_empty},
17121   /* 0xd8 SMBreadbulk*/                       {dissect_unknown                                , dissect_unknown},
17122   /* 0xd9 SMBwritebulk*/                      {dissect_unknown                                , dissect_unknown},
17123   /* 0xda SMBwritebulkdata*/                  {dissect_unknown                                , dissect_unknown},
17124   /* 0xdb */  {dissect_unknown, dissect_unknown},
17125   /* 0xdc */  {dissect_unknown, dissect_unknown},
17126   /* 0xdd */  {dissect_unknown, dissect_unknown},
17127   /* 0xde */  {dissect_unknown, dissect_unknown},
17128   /* 0xdf */  {dissect_unknown, dissect_unknown},
17129
17130   /* 0xe0 */  {dissect_unknown, dissect_unknown},
17131   /* 0xe1 */  {dissect_unknown, dissect_unknown},
17132   /* 0xe2 */  {dissect_unknown, dissect_unknown},
17133   /* 0xe3 */  {dissect_unknown, dissect_unknown},
17134   /* 0xe4 */  {dissect_unknown, dissect_unknown},
17135   /* 0xe5 */  {dissect_unknown, dissect_unknown},
17136   /* 0xe6 */  {dissect_unknown, dissect_unknown},
17137   /* 0xe7 */  {dissect_unknown, dissect_unknown},
17138   /* 0xe8 */  {dissect_unknown, dissect_unknown},
17139   /* 0xe9 */  {dissect_unknown, dissect_unknown},
17140   /* 0xea */  {dissect_unknown, dissect_unknown},
17141   /* 0xeb */  {dissect_unknown, dissect_unknown},
17142   /* 0xec */  {dissect_unknown, dissect_unknown},
17143   /* 0xed */  {dissect_unknown, dissect_unknown},
17144   /* 0xee */  {dissect_unknown, dissect_unknown},
17145   /* 0xef */  {dissect_unknown, dissect_unknown},
17146
17147   /* 0xf0 */  {dissect_unknown, dissect_unknown},
17148   /* 0xf1 */  {dissect_unknown, dissect_unknown},
17149   /* 0xf2 */  {dissect_unknown, dissect_unknown},
17150   /* 0xf3 */  {dissect_unknown, dissect_unknown},
17151   /* 0xf4 */  {dissect_unknown, dissect_unknown},
17152   /* 0xf5 */  {dissect_unknown, dissect_unknown},
17153   /* 0xf6 */  {dissect_unknown, dissect_unknown},
17154   /* 0xf7 */  {dissect_unknown, dissect_unknown},
17155   /* 0xf8 */  {dissect_unknown, dissect_unknown},
17156   /* 0xf9 */  {dissect_unknown, dissect_unknown},
17157   /* 0xfa */  {dissect_unknown, dissect_unknown},
17158   /* 0xfb */  {dissect_unknown, dissect_unknown},
17159   /* 0xfc */  {dissect_unknown, dissect_unknown},
17160   /* 0xfd */  {dissect_unknown, dissect_unknown},
17161   /* 0xfe */  {dissect_unknown, dissect_unknown},
17162   /* 0xff */  {dissect_unknown, dissect_unknown},
17163 };
17164
17165 static int
17166 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu, smb_info_t *si)
17167 {
17168         smb_saved_info_t *sip;
17169
17170         DISSECTOR_ASSERT(si);
17171
17172         if (cmd != 0xff) {
17173                 proto_item *cmd_item;
17174                 proto_tree *cmd_tree;
17175                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, smb_info_t *si);
17176
17177                 if (first_pdu) {
17178                         col_append_fstr(pinfo->cinfo, COL_INFO,
17179                                 "%s %s",
17180                                 val_to_str_ext(cmd, &smb_cmd_vals_ext, "Unknown (0x%02x)"),
17181                                 (si->request)? "Request" : "Response");
17182                 } else {
17183                         col_append_fstr(pinfo->cinfo, COL_INFO,
17184                                 "; %s",
17185                                 val_to_str_ext(cmd, &smb_cmd_vals_ext, "Unknown (0x%02x)"));
17186                 }
17187
17188                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
17189                         "%s %s (0x%02x)",
17190                         val_to_str_ext_const(cmd, &smb_cmd_vals_ext, "Unknown"),
17191                         (si->request)?"Request":"Response",
17192                         cmd);
17193
17194                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
17195
17196                 /* we track FIDs on a per transaction basis.
17197                    if this was a request and the fid was seen in a reply
17198                    we add a "generated" fid tree for this pdu and v.v.
17199                  */
17200                 sip = si->sip;
17201                 if (sip && sip->fid) {
17202                         if ( (si->request && (!sip->fid_seen_in_request))
17203                              || ((!si->request) && sip->fid_seen_in_request) ) {
17204                                 dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE, si);
17205                         }
17206                 }
17207
17208                 dissector = (si->request) ?
17209                         smb_dissector[cmd].request : smb_dissector[cmd].response;
17210
17211                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree, si);
17212
17213                 if (!tvb_offset_exists(tvb, offset-1)) {
17214                         THROW(ReportedBoundsError);
17215                 }
17216                 proto_item_set_end(cmd_item, tvb, offset);
17217         }
17218         return offset;
17219 }
17220
17221 static const value_string smb_cmd_vals[] = {
17222         { 0x00, "Create Directory" },
17223         { 0x01, "Delete Directory" },
17224         { 0x02, "Open" },
17225         { 0x03, "Create" },
17226         { 0x04, "Close" },
17227         { 0x05, "Flush" },
17228         { 0x06, "Delete" },
17229         { 0x07, "Rename" },
17230         { 0x08, "Query Information" },
17231         { 0x09, "Set Information" },
17232         { 0x0A, "Read" },
17233         { 0x0B, "Write" },
17234         { 0x0C, "Lock Byte Range" },
17235         { 0x0D, "Unlock Byte Range" },
17236         { 0x0E, "Create Temp" },
17237         { 0x0F, "Create New" },
17238         { 0x10, "Check Directory" },
17239         { 0x11, "Process Exit" },
17240         { 0x12, "Seek" },
17241         { 0x13, "Lock And Read" },
17242         { 0x14, "Write And Unlock" },
17243         { 0x15, "unknown-0x15" },
17244         { 0x16, "unknown-0x16" },
17245         { 0x17, "unknown-0x17" },
17246         { 0x18, "unknown-0x18" },
17247         { 0x19, "unknown-0x19" },
17248         { 0x1A, "Read Raw" },
17249         { 0x1B, "Read MPX" },
17250         { 0x1C, "Read MPX Secondary" },
17251         { 0x1D, "Write Raw" },
17252         { 0x1E, "Write MPX" },
17253         { 0x1F, "Write MPX Secondary" },
17254         { 0x20, "Write Complete" },
17255
17256         /*
17257          * To quote
17258          *
17259          *    http://msdn.microsoft.com/en-us/library/ee442098.aspx
17260          *
17261          * "This command was introduced in the NT LAN Manager dialect, and
17262          * was reserved but not implemented.
17263          *
17264          * Clients SHOULD NOT send requests using this command code, and
17265          * servers receiving requests with this command code SHOULD return
17266          * STATUS_NOT_IMPLEMENTED (ERRDOS/ERRbadfunc)."
17267          */
17268         { 0x21, "Query Server (reserved)" },
17269
17270         { 0x22, "Set Information2" },
17271         { 0x23, "Query Information2" },
17272         { 0x24, "Locking AndX" },
17273         { 0x25, "Trans" },
17274         { 0x26, "Trans Secondary" },
17275         { 0x27, "IOCTL" },
17276         { 0x28, "IOCTL Secondary" },
17277         { 0x29, "Copy" },
17278         { 0x2A, "Move" },
17279         { 0x2B, "Echo" },
17280         { 0x2C, "Write And Close" },
17281         { 0x2D, "Open AndX" },
17282         { 0x2E, "Read AndX" },
17283         { 0x2F, "Write AndX" },
17284
17285         /*
17286          * To quote
17287          *
17288          *    http://msdn.microsoft.com/en-us/library/ee442127.aspx
17289          *
17290          * "This command was reserved but not implemented. It was also never
17291          * defined. It is listed in [SNIA], but it is not defined in that
17292          * document and does not appear in any other references.
17293          *
17294          * Clients SHOULD NOT send requests using this command code, and
17295          * servers receiving requests with this command code SHOULD return
17296          * STATUS_NOT_IMPLEMENTED (ERRDOC/ERRbadfunc)."
17297          */
17298         { 0x30, "New File Size (reserved)" },
17299
17300         { 0x31, "Close And Tree Disconnect" },
17301         { 0x32, "Trans2" },
17302         { 0x33, "Trans2 Secondary" },
17303         { 0x34, "Find Close2" },
17304         { 0x35, "Find Notify Close" },
17305         { 0x70, "Tree Connect" },
17306         { 0x71, "Tree Disconnect" },
17307         { 0x72, "Negotiate Protocol" },
17308         { 0x73, "Session Setup AndX" },
17309         { 0x74, "Logoff AndX" },
17310         { 0x75, "Tree Connect AndX" },
17311         { 0x80, "Query Information Disk" },
17312         { 0x81, "Search" },
17313         { 0x82, "Find" },
17314         { 0x83, "Find Unique" },
17315         { 0x84, "Find Close" },
17316         { 0xA0, "NT Trans" },
17317         { 0xA1, "NT Trans Secondary" },
17318         { 0xA2, "NT Create AndX" },
17319         { 0xA3, "unknown-0xA3" },
17320         { 0xA4, "NT Cancel" },
17321         { 0xA5, "NT Rename" },
17322         { 0xC0, "Open Print File" },
17323         { 0xC1, "Write Print File" },
17324         { 0xC2, "Close Print File" },
17325         { 0xC3, "Get Print Queue" },
17326         { 0xD0, "Send Single Block Message" },
17327         { 0xD1, "Send Broadcast Message" },
17328         { 0xD2, "Forward User Name" },
17329         { 0xD3, "Cancel Forward" },
17330         { 0xD4, "Get Machine Name" },
17331         { 0xD5, "Send Start of Multi-block Message" },
17332         { 0xD6, "Send End of Multi-block Message" },
17333         { 0xD7, "Send Text of Multi-block Message" },
17334         { 0xD8, "SMBreadbulk" },
17335         { 0xD9, "SMBwritebulk" },
17336         { 0xDA, "SMBwritebulkdata" },
17337         { 0xFE, "SMBinvalid" },
17338         { 0x00, NULL },
17339 };
17340 value_string_ext smb_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb_cmd_vals);
17341
17342
17343 static void
17344 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
17345 {
17346         conv_tables_t *ct = (conv_tables_t *)ctarg;
17347
17348         if (ct->unmatched)
17349                 g_hash_table_destroy(ct->unmatched);
17350         if (ct->matched)
17351                 g_hash_table_destroy(ct->matched);
17352         if (ct->primaries)
17353                 g_hash_table_destroy(ct->primaries);
17354         if (ct->tid_service)
17355                 g_hash_table_destroy(ct->tid_service);
17356         if (ct->GSL_fid_info)
17357                 g_slist_free(ct->GSL_fid_info);
17358         g_free(ct);
17359 }
17360
17361 static void
17362 smb_init_protocol(void)
17363 {
17364         /*
17365          * Free the hash tables attached to the conversation table
17366          * structures, and then free the list of conversation table
17367          * data structures.
17368          */
17369         if (conv_tables) {
17370                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
17371                 g_slist_free(conv_tables);
17372                 conv_tables = NULL;
17373         }
17374 }
17375
17376 static const value_string errcls_types[] = {
17377         { SMB_SUCCESS, "Success"},
17378         { SMB_ERRDOS,  "DOS Error"},
17379         { SMB_ERRSRV,  "Server Error"},
17380         { SMB_ERRHRD,  "Hardware Error"},
17381         { SMB_ERRCMD,  "Command Error - Not an SMB format command"},
17382         { 0, NULL }
17383 };
17384
17385 /* Error codes for the ERRSRV class */
17386
17387 #define SRV_errors_VALUE_STRING_LIST(XXX) \
17388     XXX( SMBE_SRV_error,          1, "Non specific error code") \
17389     XXX( SMBE_SRV_badpw,          2, "Bad password") \
17390     XXX( SMBE_SRV_badtype,        3, "Reserved") \
17391     XXX( SMBE_SRV_access,         4, "No permissions to perform the requested operation") \
17392     XXX( SMBE_SRV_invnid,         5, "TID invalid") \
17393     XXX( SMBE_SRV_invnetname,     6, "Invalid network name. Service not found") \
17394     XXX( SMBE_SRV_invdevice,      7, "Invalid device") \
17395     XXX( SMBE_SRV_unknownsmb,    22, "Unknown SMB, from NT 3.5 response") \
17396     XXX( SMBE_SRV_qfull,         49, "Print queue full") \
17397     XXX( SMBE_SRV_qtoobig,       50, "Queued item too big") \
17398     XXX( SMBE_SRV_qeof,          51, "EOF in print queue dump") \
17399     XXX( SMBE_SRV_invpfid,       52, "Invalid print file in smb_fid") \
17400     XXX( SMBE_SRV_smbcmd,        64, "Unrecognised command") \
17401     XXX( SMBE_SRV_srverror,      65, "SMB server internal error") \
17402     XXX( SMBE_SRV_filespecs,     67, "Fid and pathname invalid combination") \
17403     XXX( SMBE_SRV_badlink,       68, "Bad link in request ???") \
17404     XXX( SMBE_SRV_badpermits,    69, "Access specified for a file is not valid") \
17405     XXX( SMBE_SRV_badpid,        70, "Bad process id in request") \
17406     XXX( SMBE_SRV_setattrmode,   71, "Attribute mode invalid") \
17407     XXX( SMBE_SRV_paused,        81, "Message server paused") \
17408     XXX( SMBE_SRV_msgoff,        82, "Not receiving messages") \
17409     XXX( SMBE_SRV_noroom,        83, "No room for message") \
17410     XXX( SMBE_SRV_rmuns,         87, "Too many remote usernames") \
17411     XXX( SMBE_SRV_timeout,       88, "Operation timed out") \
17412     XXX( SMBE_SRV_noresource,    89, "No resources currently available for request.") \
17413     XXX( SMBE_SRV_toomanyuids,   90, "Too many userids") \
17414     XXX( SMBE_SRV_baduid,        91, "Bad userid") \
17415     XXX( SMBE_SRV_useMPX,       250, "Temporarily unable to use raw mode, use MPX mode") \
17416     XXX( SMBE_SRV_useSTD,       251, "Temporarily unable to use raw mode, use standard mode") \
17417     XXX( SMBE_SRV_contMPX,      252, "Resume MPX mode") \
17418     XXX( SMBE_SRV_badPW,        253, "Bad Password???") \
17419     XXX( SMBE_SRV_nosupport, 0xFFFF, "Operation not supported")
17420
17421 #if 0 /* Values not needed */
17422 VALUE_STRING_ENUM(SRV_errors);
17423 #endif
17424 VALUE_STRING_ARRAY(SRV_errors);
17425 static value_string_ext SRV_errors_ext = VALUE_STRING_EXT_INIT(SRV_errors);
17426
17427
17428 /* Error codes for the ERRHRD class */
17429
17430 #define HRD_errors_VALUE_STRING_LIST(XXX) \
17431     XXX( SMBE_HRD_nowrite,     19, "Read only media") \
17432     XXX( SMBE_HRD_badunit,     20, "Unknown device") \
17433     XXX( SMBE_HRD_notready,    21, "Drive not ready") \
17434     XXX( SMBE_HRD_badcmd,      22, "Unknown command") \
17435     XXX( SMBE_HRD_data,        23, "Data (CRC) error") \
17436     XXX( SMBE_HRD_badreq,      24, "Bad request structure length") \
17437     XXX( SMBE_HRD_seek,        25, "Seek error") \
17438     XXX( SMBE_HRD_badmedia,    26, "Unknown media type") \
17439     XXX( SMBE_HRD_badsector,   27, "Sector not found") \
17440     XXX( SMBE_HRD_nopaper,     28, "Printer out of paper") \
17441     XXX( SMBE_HRD_write,       29, "Write fault") \
17442     XXX( SMBE_HRD_read,        30, "Read fault") \
17443     XXX( SMBE_HRD_general,     31, "General failure") \
17444 /* -- (really part of ERRDOS class ??) -- */ \
17445     XXX( SMBE_HRD_badshare,    32, "An open conflicts with an existing open") \
17446     XXX( SMBE_HRD_lock,        33, "Lock conflict/invalid mode, or unlock of another process's lock") \
17447 /* -- --*/ \
17448     XXX( SMBE_HRD_wrongdisk,   34, "The wrong disk was found in a drive") \
17449     XXX( SMBE_HRD_FCBunavail,  35, "No FCBs are available to process request") \
17450     XXX( SMBE_HRD_sharebufexc, 36, "A sharing buffer has been exceeded") \
17451     XXX( SMBE_HRD_diskfull,    39, "Disk full???")
17452
17453 #if 0 /* Values not needed */
17454 VALUE_STRING_ENUM(HRD_errors);
17455 #endif
17456 VALUE_STRING_ARRAY(HRD_errors);
17457 static value_string_ext HRD_errors_ext = VALUE_STRING_EXT_INIT(HRD_errors);
17458
17459 static const char *decode_smb_error(guint8 errcls, guint16 errcode)
17460 {
17461
17462         switch (errcls) {
17463
17464         case SMB_SUCCESS:
17465
17466                 return("No Error");   /* No error ??? */
17467
17468         case SMB_ERRDOS:
17469
17470                 return(val_to_str_ext(errcode, &DOS_errors_ext, "Unknown DOS error (%x)"));
17471
17472         case SMB_ERRSRV:
17473
17474                 return(val_to_str_ext(errcode, &SRV_errors_ext, "Unknown SRV error (%x)"));
17475
17476         case SMB_ERRHRD:
17477
17478                 return(val_to_str_ext(errcode, &HRD_errors_ext, "Unknown HRD error (%x)"));
17479
17480         default:
17481
17482                 return("Unknown error class!");
17483
17484         }
17485
17486 }
17487
17488 static const true_false_string tfs_smb_flags_lock = {
17489         "Lock&Read, Write&Unlock are supported",
17490         "Lock&Read, Write&Unlock are not supported"
17491 };
17492 static const true_false_string tfs_smb_flags_receive_buffer = {
17493         "Receive buffer has been posted",
17494         "Receive buffer has not been posted"
17495 };
17496 static const true_false_string tfs_smb_flags_caseless = {
17497         "Path names are caseless",
17498         "Path names are case sensitive"
17499 };
17500 static const true_false_string tfs_smb_flags_canon = {
17501         "Pathnames are canonicalized",
17502         "Pathnames are not canonicalized"
17503 };
17504 static const true_false_string tfs_smb_flags_oplock = {
17505         "OpLock requested/granted",
17506         "OpLock not requested/granted"
17507 };
17508 static const true_false_string tfs_smb_flags_notify = {
17509         "Notify client on all modifications",
17510         "Notify client only on open"
17511 };
17512 static const true_false_string tfs_smb_flags_response = {
17513         "Message is a response to the client/redirector",
17514         "Message is a request to the server"
17515 };
17516
17517 static int
17518 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
17519 {
17520         guint8      mask;
17521         proto_item *item;
17522         proto_tree *tree;
17523
17524         mask = tvb_get_guint8(tvb, offset);
17525
17526         if (parent_tree) {
17527                 item = proto_tree_add_item(parent_tree, hf_smb_flags, tvb, offset, 1, ENC_NA);
17528                 tree = proto_item_add_subtree(item, ett_smb_flags);
17529
17530                 proto_tree_add_boolean(tree, hf_smb_flags_response,
17531                         tvb, offset, 1, mask);
17532                 proto_tree_add_boolean(tree, hf_smb_flags_notify,
17533                         tvb, offset, 1, mask);
17534                 proto_tree_add_boolean(tree, hf_smb_flags_oplock,
17535                         tvb, offset, 1, mask);
17536                 proto_tree_add_boolean(tree, hf_smb_flags_canon,
17537                         tvb, offset, 1, mask);
17538                 proto_tree_add_boolean(tree, hf_smb_flags_caseless,
17539                         tvb, offset, 1, mask);
17540                 proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
17541                         tvb, offset, 1, mask);
17542                 proto_tree_add_boolean(tree, hf_smb_flags_lock,
17543                         tvb, offset, 1, mask);
17544         }
17545
17546         offset += 1;
17547         return offset;
17548 }
17549
17550
17551
17552 static const true_false_string tfs_smb_flags2_long_names_allowed = {
17553         "Long file names are allowed in the response",
17554         "Long file names are not allowed in the response"
17555 };
17556 static const true_false_string tfs_smb_flags2_ea = {
17557         "Extended attributes are supported",
17558         "Extended attributes are not supported"
17559 };
17560 static const true_false_string tfs_smb_flags2_sec_sig = {
17561         "Security signatures are supported",
17562         "Security signatures are not supported"
17563 };
17564 static const true_false_string tfs_smb_flags2_compressed = {
17565         "Compression is requested",
17566         "Compression is not requested"
17567 };
17568 static const true_false_string tfs_smb_flags2_sec_sig_required = {
17569         "Security signatures are required",
17570         "Security signatures are not required"
17571 };
17572 static const true_false_string tfs_smb_flags2_long_names_used = {
17573         "Path names in request are long file names",
17574         "Path names in request are not long file names"
17575 };
17576 static const true_false_string tfs_smb_flags2_reparse_path = {
17577         "The request uses a @GMT reparse path",
17578         "The request does not use a @GMT reparse path"
17579 };
17580 static const true_false_string tfs_smb_flags2_esn = {
17581         "Extended security negotiation is supported",
17582         "Extended security negotiation is not supported"
17583 };
17584 static const true_false_string tfs_smb_flags2_dfs = {
17585         "Resolve pathnames with Dfs",
17586         "Don't resolve pathnames with Dfs"
17587 };
17588 static const true_false_string tfs_smb_flags2_roe = {
17589         "Permit reads if execute-only",
17590         "Don't permit reads if execute-only"
17591 };
17592 static const true_false_string tfs_smb_flags2_nt_error = {
17593         "Error codes are NT error codes",
17594         "Error codes are DOS error codes"
17595 };
17596 static const true_false_string tfs_smb_flags2_string = {
17597         "Strings are Unicode",
17598         "Strings are ASCII"
17599 };
17600 static int
17601 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
17602 {
17603         guint16     mask;
17604         proto_item *item;
17605         proto_tree *tree;
17606
17607         mask = tvb_get_letohs(tvb, offset);
17608
17609         if (parent_tree) {
17610                 item = proto_tree_add_item(parent_tree, hf_smb_flags2, tvb, offset, 2, ENC_LITTLE_ENDIAN);
17611                 tree = proto_item_add_subtree(item, ett_smb_flags2);
17612
17613                 proto_tree_add_boolean(tree, hf_smb_flags2_string,
17614                         tvb, offset, 2, mask);
17615                 proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
17616                         tvb, offset, 2, mask);
17617                 proto_tree_add_boolean(tree, hf_smb_flags2_roe,
17618                         tvb, offset, 2, mask);
17619                 proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
17620                         tvb, offset, 2, mask);
17621                 proto_tree_add_boolean(tree, hf_smb_flags2_esn,
17622                         tvb, offset, 2, mask);
17623                 proto_tree_add_boolean(tree, hf_smb_flags2_reparse_path,
17624                         tvb, offset, 2, mask);
17625                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
17626                         tvb, offset, 2, mask);
17627                 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig_required,
17628                         tvb, offset, 2, mask);
17629                 proto_tree_add_boolean(tree, hf_smb_flags2_compressed,
17630                         tvb, offset, 2, mask);
17631                 proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
17632                         tvb, offset, 2, mask);
17633                 proto_tree_add_boolean(tree, hf_smb_flags2_ea,
17634                         tvb, offset, 2, mask);
17635                 proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
17636                         tvb, offset, 2, mask);
17637         }
17638         offset += 2;
17639         return offset;
17640 }
17641
17642
17643
17644 #define SMB_FLAGS_DIRN 0x80
17645
17646
17647 static void
17648 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
17649 {
17650         int                   offset   = 0;
17651         proto_item           *item     = NULL, *hitem = NULL;
17652         proto_tree           *tree     = NULL, *htree = NULL;
17653         proto_item           *tmp_item = NULL;
17654         guint8                flags;
17655         guint16               flags2;
17656         smb_info_t           *si;
17657         smb_saved_info_t     *sip      = NULL;
17658         smb_saved_info_key_t  key;
17659         smb_saved_info_key_t *new_key;
17660         guint8                errclass = 0;
17661         guint16               errcode  = 0;
17662         guint32               pid_mid;
17663         conversation_t       *conversation;
17664         nstime_t              t, deltat;
17665
17666         si = wmem_new0(wmem_packet_scope(), smb_info_t);
17667
17668         top_tree_global = parent_tree;
17669
17670         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
17671         col_clear(pinfo->cinfo, COL_INFO);
17672
17673         /* start off using the local variable, we will allocate a new one if we
17674            need to*/
17675         si->cmd = tvb_get_guint8(tvb, offset+4);
17676         flags = tvb_get_guint8(tvb, offset+9);
17677         /*
17678          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
17679          * the direction flag appears never to be set, even for what appear
17680          * to be replies.  Do some SMB servers fail to set that flag,
17681          * under the assumption that the client knows it's a reply because
17682          * it received it?
17683          */
17684         si->request = !(flags&SMB_FLAGS_DIRN);
17685         flags2 = tvb_get_letohs(tvb, offset+10);
17686         if (flags2 & 0x8000) {
17687                 si->unicode = TRUE; /* Mark them as Unicode */
17688         } else {
17689                 si->unicode = FALSE;
17690         }
17691         si->tid = tvb_get_letohs(tvb, offset+24);
17692         si->pid = tvb_get_letohs(tvb, offset+26);
17693         si->uid = tvb_get_letohs(tvb, offset+28);
17694         si->mid = tvb_get_letohs(tvb, offset+30);
17695         pid_mid = (si->pid << 16) | si->mid;
17696         si->info_level = -1;
17697         si->info_count = -1;
17698
17699         if (parent_tree) {
17700                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
17701                         -1, ENC_NA);
17702                 tree = proto_item_add_subtree(item, ett_smb);
17703
17704                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
17705                         "SMB Header");
17706
17707                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
17708         }
17709
17710         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
17711         offset += 4;  /* Skip the marker */
17712
17713         /* find which conversation we are part of and get the tables for that
17714            conversation*/
17715         conversation = find_or_create_conversation(pinfo);
17716         /* see if we already have the smb data for this conversation */
17717         si->ct = (conv_tables_t *)conversation_get_proto_data(conversation, proto_smb);
17718         if (!si->ct) {
17719                 /* No, not yet. create it and attach it to the conversation */
17720                 si->ct = (conv_tables_t *)g_malloc(sizeof(conv_tables_t));
17721
17722                 conv_tables = g_slist_prepend(conv_tables, si->ct);
17723                 si->ct->matched = g_hash_table_new(smb_saved_info_hash_matched,
17724                         smb_saved_info_equal_matched);
17725                 si->ct->unmatched = g_hash_table_new(smb_saved_info_hash_unmatched,
17726                         smb_saved_info_equal_unmatched);
17727                 /* We used the same key format as the unmatched entries */
17728                 si->ct->primaries = g_hash_table_new(
17729                         smb_saved_info_hash_unmatched,
17730                         smb_saved_info_equal_unmatched);
17731                 si->ct->tid_service = g_hash_table_new(
17732                         smb_saved_info_hash_unmatched,
17733                         smb_saved_info_equal_unmatched);
17734                 si->ct->raw_ntlmssp = 0;
17735
17736                 si->ct->fid_tree = wmem_tree_new(wmem_file_scope());
17737                 si->ct->tid_tree = wmem_tree_new(wmem_file_scope());
17738                 si->ct->uid_tree = wmem_tree_new(wmem_file_scope());
17739                 /* Initialize the GSL_fid_info for this ct */
17740                 si->ct->GSL_fid_info = NULL;
17741                 conversation_add_proto_data(conversation, proto_smb, si->ct);
17742         }
17743
17744         if ( (si->request)
17745             &&  (si->mid == 0)
17746             &&  (si->uid == 0)
17747             &&  (si->pid == 0)
17748             &&  (si->tid == 0) ) {
17749                 /* this is a broadcast SMB packet, there will not be a reply.
17750                    We dont need to do anything
17751                 */
17752                 si->unidir = TRUE;
17753         } else if ( (si->cmd == SMB_COM_NT_CANCEL)                  /* NT Cancel */
17754                    || (si->cmd == SMB_COM_TRANSACTION_SECONDARY)    /* Transaction Secondary */
17755                    || (si->cmd == SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
17756                    || (si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)) { /* NT Transaction Secondary */
17757                 /* Ok, we got a special request type. This request is either
17758                    an NT Cancel or a continuation relative to a real request
17759                    in an earlier packet.  In either case, we don't expect any
17760                    responses to this packet.  For continuations, any later
17761                    responses we see really just belong to the original request.
17762                    Anyway, we want to remember this packet somehow and
17763                    remember which original request it is associated with so
17764                    we can say nice things such as "This is a Cancellation to
17765                    the request in frame x", but we don't want the
17766                    request/response matching to get messed up.
17767
17768                    The only thing we do in this case is trying to find which original
17769                    request we match with and insert an entry for this "special"
17770                    request for later reference. We continue to reference the original
17771                    requests smb_saved_info_t but we dont touch it or change anything
17772                    in it.
17773                 */
17774
17775                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
17776
17777                 if (!pinfo->fd->flags.visited) {
17778                         /* try to find which original call we match and if we
17779                            find it add us to the matched table. Dont touch
17780                            anything else since we dont want this one to mess
17781                            up the request/response matching. We still consider
17782                            the initial call the real request and this is only
17783                            some sort of continuation.
17784                         */
17785                         /* we only check the unmatched table and assume that the
17786                            last seen MID matching ours is the right one.
17787                            This can fail but is better than nothing
17788                         */
17789                         sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17790                         if (sip != NULL) {
17791                                 new_key = (smb_saved_info_key_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_key_t));
17792                                 new_key->frame = pinfo->fd->num;
17793                                 new_key->pid_mid = pid_mid;
17794                                 g_hash_table_insert(si->ct->matched, new_key,
17795                                     sip);
17796                         } else {
17797                                 if ((si->cmd == SMB_COM_TRANSACTION_SECONDARY)  ||
17798                                     (si->cmd == SMB_COM_TRANSACTION2_SECONDARY) ||
17799                                     (si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)) {
17800                                         sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
17801                                 }
17802                         }
17803                 } else {
17804                         /* we have seen this packet before; check the
17805                            matching table
17806                         */
17807                         key.frame = pinfo->fd->num;
17808                         key.pid_mid = pid_mid;
17809                         sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->matched, &key);
17810                         if (sip == NULL) {
17811                         /*
17812                           We didn't find it.
17813                           Too bad, unfortunately there is not really much we can
17814                           do now since this means that we never saw the initial
17815                           request.
17816                          */
17817                         }
17818                 }
17819
17820
17821                 if (sip && sip->frame_req) {
17822                         switch(si->cmd) {
17823                         case SMB_COM_NT_CANCEL:
17824                                 tmp_item = proto_tree_add_uint(htree, hf_smb_cancel_to,
17825                                                     tvb, 0, 0, sip->frame_req);
17826                                 PROTO_ITEM_SET_GENERATED(tmp_item);
17827                                 break;
17828                         case SMB_COM_TRANSACTION_SECONDARY:
17829                         case SMB_COM_TRANSACTION2_SECONDARY:
17830                         case SMB_COM_NT_TRANSACT_SECONDARY:
17831                                 tmp_item = proto_tree_add_uint(htree, hf_smb_continuation_to,
17832                                                     tvb, 0, 0, sip->frame_req);
17833                                 PROTO_ITEM_SET_GENERATED(tmp_item);
17834                                 break;
17835                         }
17836                 } else {
17837                         switch(si->cmd) {
17838                         case SMB_COM_NT_CANCEL:
17839                                 proto_tree_add_text(htree, tvb, 0, 0,
17840                                                     "Cancellation to: <unknown frame>");
17841                                 break;
17842                         case SMB_COM_TRANSACTION_SECONDARY:
17843                         case SMB_COM_TRANSACTION2_SECONDARY:
17844                         case SMB_COM_NT_TRANSACT_SECONDARY:
17845                                 proto_tree_add_text(htree, tvb, 0, 0,
17846                                                     "Continuation to: <unknown frame>");
17847                                 break;
17848                         }
17849                 }
17850         } else { /* normal bidirectional request or response */
17851                 si->unidir = FALSE;
17852
17853                 if (!pinfo->fd->flags.visited) {
17854                         /* first see if we find an unmatched smb "equal" to
17855                            the current one
17856                         */
17857                         sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17858                         if (sip != NULL) {
17859                                 gboolean cmd_match = FALSE;
17860
17861                                 /*
17862                                  * Make sure the SMB we found was the
17863                                  * same command, or a different command
17864                                  * that's another valid type of reply
17865                                  * to that command.
17866                                  */
17867                                 if (si->cmd == sip->cmd) {
17868                                         cmd_match = TRUE;
17869                                 }
17870                                 else if (si->cmd == SMB_COM_NT_CANCEL) {
17871                                         cmd_match = TRUE;
17872                                 }
17873                                 else if ((si->cmd == SMB_COM_TRANSACTION_SECONDARY)
17874                                      && (sip->cmd == SMB_COM_TRANSACTION)) {
17875                                         cmd_match = TRUE;
17876                                 }
17877                                 else if ((si->cmd == SMB_COM_TRANSACTION2_SECONDARY)
17878                                      && (sip->cmd == SMB_COM_TRANSACTION2)) {
17879                                         cmd_match = TRUE;
17880                                 }
17881                                 else if ((si->cmd == SMB_COM_NT_TRANSACT_SECONDARY)
17882                                      && (sip->cmd == SMB_COM_NT_TRANSACT)) {
17883                                         cmd_match = TRUE;
17884                                 }
17885
17886                                 if ( (si->request) || (!cmd_match) ) {
17887                                         /* We are processing an SMB request but there was already
17888                                            another "identical" smb request we had not matched yet.
17889                                            This must mean that either we have a retransmission or that the
17890                                            response to the previous one was lost and the client has reused
17891                                            the MID for this conversation. In either case it's not much more
17892                                            we can do than forget the old request and concentrate on the
17893                                            present one instead.
17894
17895                                            We also do this cleanup if we see that the cmd in the original
17896                                            request in sip->cmd is not compatible with the current cmd.
17897                                            This is to prevent matching errors such as if there were two
17898                                            SMBs of different cmds but with identical MID and PID values and
17899                                            if wireshark lost the first reply and the second request.
17900                                         */
17901                                         g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17902                                         sip = NULL; /* XXX should free it as well */
17903                                 } else {
17904                                         /* we have found a response to some
17905                                            request we have seen earlier.
17906                                            What we do now depends on whether
17907                                            this is the first response to that
17908                                            request we see (id frame_res == 0) or
17909                                            if it's a response to a request
17910                                            for which we've seen an earlier
17911                                            response that's continued.
17912                                         */
17913                                         if ((sip->frame_res == 0) ||
17914                                             (sip->flags & SMB_SIF_IS_CONTINUED)) {
17915                                                 /* OK, it is the first response
17916                                                    we have seen to this packet,
17917                                                    or it's a continuation of
17918                                                    a response we've seen. */
17919                                                 sip->frame_res = pinfo->fd->num;
17920                                                 new_key = (smb_saved_info_key_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_key_t));
17921                                                 new_key->frame = sip->frame_res;
17922                                                 new_key->pid_mid = pid_mid;
17923                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
17924                                                 /* We remove the entry for unmatched since we have found a match.
17925                                                  * We have to do this since the MID value wraps so quickly (effective only 10 bits)
17926                                                  * and if there is packetloss in the trace (maybe due to large holes
17927                                                  * created by a sniffer device not being able to keep up
17928                                                  * with the line rate.
17929                                                  * There is a real possibility that the following would occur which is painful :
17930                                                  * 1, -> Request  MID:5
17931                                                  * 2, <- Response MID:5
17932                                                  * 3, -> Request  MID:5 (missing from capture)
17933                                                  * 4, <- Response MID:5
17934                                                  * We DONT want #4 to be presented as a response to #1
17935                                                  */
17936                                                 g_hash_table_remove(si->ct->unmatched, GUINT_TO_POINTER(pid_mid));
17937                                         } else {
17938                                                 /* We have already seen another response to this MID.
17939                                                    Since the MID in reality is only something like 10 bits
17940                                                    this probably means that we just have a MID that is being
17941                                                    reused due to the small MID space and that this is a new
17942                                                    command we did not see the original request for.
17943                                                 */
17944                                                 sip = NULL;
17945                                         }
17946                                 }
17947                         } else {
17948                                 if ((si->cmd == SMB_COM_TRANSACTION)  ||
17949                                     (si->cmd == SMB_COM_TRANSACTION2) ||
17950                                     (si->cmd == SMB_COM_NT_TRANSACT)) {
17951                                         sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
17952                                 }
17953                         }
17954                         if (si->request) {
17955                                 sip = (smb_saved_info_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_t));
17956                                 sip->frame_req = pinfo->fd->num;
17957                                 sip->frame_res = 0;
17958                                 sip->req_time = pinfo->fd->abs_ts;
17959                                 sip->flags = 0;
17960                                 if (g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))
17961                                     == (void *)TID_IPC) {
17962                                         sip->flags |= SMB_SIF_TID_IS_IPC;
17963                                 }
17964                                 sip->cmd = si->cmd;
17965                                 sip->extra_info = NULL;
17966                                 sip->extra_info_type = SMB_EI_NONE;
17967                                 sip->fid = 0;
17968                                 sip->fid_seen_in_request = 0;
17969                                 g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
17970                                 new_key = (smb_saved_info_key_t *)wmem_alloc(wmem_file_scope(), sizeof(smb_saved_info_key_t));
17971                                 new_key->frame = sip->frame_req;
17972                                 new_key->pid_mid = pid_mid;
17973                                 g_hash_table_insert(si->ct->matched, new_key, sip);
17974
17975                                 /* If it is a TRANSACT cmd, insert in hash */
17976                                 if ((si->cmd == SMB_COM_TRANSACTION)  ||
17977                                     (si->cmd == SMB_COM_TRANSACTION2) ||
17978                                     (si->cmd == SMB_COM_NT_TRANSACT)) {
17979                                         g_hash_table_insert(si->ct->primaries, GUINT_TO_POINTER(pid_mid), sip);
17980                                 }
17981                         }
17982                 } else {
17983                         /* we have seen this packet before; check the
17984                            matching table.
17985                            If we haven't yet seen the reply, we won't
17986                            find the info for it; we don't need it, as
17987                            we only use it to save information, and, as
17988                            we've seen this packet before, we've already
17989                            saved the information.
17990                         */
17991                         key.frame = pinfo->fd->num;
17992                         key.pid_mid = pid_mid;
17993                         sip = (smb_saved_info_t *)g_hash_table_lookup(si->ct->matched, &key);
17994                 }
17995         }
17996
17997         /*
17998          * Pass the "sip" on to subdissectors through "si".
17999          */
18000         si->sip = sip;
18001
18002         if (sip != NULL) {
18003                 /*
18004                  * Put in fields for the frame number of the frame to which
18005                  * this is a response or the frame with the response to this
18006                  * frame - if we know the frame number (i.e., it's not 0).
18007                  */
18008                 if (si->request) {
18009                         if (sip->frame_res != 0) {
18010                                 tmp_item = proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
18011                                 PROTO_ITEM_SET_GENERATED(tmp_item);
18012                         }
18013                 } else {
18014                         if (sip->frame_req != 0) {
18015                                 tmp_item = proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
18016                                 PROTO_ITEM_SET_GENERATED(tmp_item);
18017                                 t = pinfo->fd->abs_ts;
18018                                 nstime_delta(&deltat, &t, &sip->req_time);
18019                                 tmp_item = proto_tree_add_time(htree, hf_smb_time, tvb,
18020                                     0, 0, &deltat);
18021                                 PROTO_ITEM_SET_GENERATED(tmp_item);
18022                         }
18023                 }
18024         }
18025
18026         /* smb command */
18027         proto_tree_add_uint(htree, hf_smb_cmd, tvb, offset, 1, si->cmd);
18028         offset += 1;
18029
18030         if (flags2 & 0x4000) {
18031                 /* handle NT 32 bit error code */
18032
18033                 si->nt_status = tvb_get_letohl(tvb, offset);
18034
18035                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
18036                         ENC_LITTLE_ENDIAN);
18037                 offset += 4;
18038
18039         } else {
18040                 /* handle DOS error code & class */
18041                 errclass = tvb_get_guint8(tvb, offset);
18042                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
18043                         errclass);
18044                 offset += 1;
18045
18046                 /* reserved byte */
18047                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, ENC_NA);
18048                 offset += 1;
18049
18050                 /* error code */
18051                 /* XXX - the type of this field depends on the value of
18052                  * "errcls", so there is isn't a single value_string array
18053                  * fo it, so there can't be a single field for it.
18054                  */
18055                 errcode = tvb_get_letohs(tvb, offset);
18056                 proto_tree_add_uint_format_value(htree, hf_smb_error_code, tvb,
18057                         offset, 2, errcode, "%s",
18058                         decode_smb_error(errclass, errcode));
18059                 offset += 2;
18060         }
18061
18062         /* flags */
18063         offset = dissect_smb_flags(tvb, htree, offset);
18064
18065         /* flags2 */
18066         offset = dissect_smb_flags2(tvb, htree, offset);
18067
18068         /*
18069          * The document at
18070          *
18071          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
18072          *
18073          * (a text version of "Microsoft Networks SMB FILE SHARING
18074          * PROTOCOL, Document Version 6.0p") says that:
18075          *
18076          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
18077          *      the "High Part of PID";
18078          *
18079          *      the next four bytes are reserved;
18080          *
18081          *      the next four bytes are, for SMB-over-IPX (with no
18082          *      NetBIOS involved) two bytes of Session ID and two bytes
18083          *      of SequenceNumber.
18084          *
18085          * Network Monitor 2.x dissects the four bytes before the Session ID
18086          * as a "Key", and the two bytes after the SequenceNumber as
18087          * a "Group ID".
18088          *
18089          * The "High Part of PID" has been seen in calls other than NT
18090          * Create and X, although most of them appear to be I/O on DCE RPC
18091          * pipes opened with the NT Create and X in question.
18092          */
18093         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, ENC_LITTLE_ENDIAN);
18094         offset += 2;
18095
18096         if ((pinfo->ptype == PT_IPX) &&
18097             ((pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_SERVER) ||
18098              (pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_REDIR)  ||
18099              (pinfo->match_uint == IPX_SOCKET_NWLINK_SMB_MESSENGER))) {
18100                 /*
18101                  * This is SMB-over-IPX.
18102                  * XXX - do we have to worry about "sequenced commands",
18103                  * as per the Samba document?  They say that for
18104                  * "unsequenced commands" (with a sequence number of 0),
18105                  * the Mid must be unique, but perhaps the Mid doesn't
18106                  * have to be unique for sequenced commands.  In at least
18107                  * one capture with SMB-over-IPX, however, the Mids
18108                  * are unique even for sequenced commands.
18109                  */
18110                 /* Key */
18111                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
18112                     ENC_LITTLE_ENDIAN);
18113                 offset += 4;
18114
18115                 /* Session ID */
18116                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
18117                     ENC_LITTLE_ENDIAN);
18118                 offset += 2;
18119
18120                 /* Sequence number */
18121                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
18122                     ENC_LITTLE_ENDIAN);
18123                 offset += 2;
18124
18125                 /* Group ID */
18126                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
18127                     ENC_LITTLE_ENDIAN);
18128                 offset += 2;
18129         } else {
18130                 /*
18131                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
18132                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
18133                  * bytes after the "High part of PID" are an 8-byte
18134                  * signature ...
18135                  */
18136                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, ENC_NA);
18137                 offset += 8;
18138
18139                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, ENC_NA);
18140                 offset += 2;
18141         }
18142
18143         /* TID
18144          * TreeConnectAndX(0x75) is special, here it is the mere fact of
18145          * having a response that means that the share was mapped and we
18146          * need to track it
18147          */
18148         if (!pinfo->fd->flags.visited && (si->cmd == 0x75) && !si->request) {
18149                 offset = dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE, si);
18150         } else {
18151                 offset = dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE, si);
18152         }
18153
18154         /* PID */
18155         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
18156         offset += 2;
18157
18158         /* UID */
18159         offset = dissect_smb_uid(tvb, htree, offset, si);
18160
18161         /* MID */
18162         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
18163         offset += 2;
18164
18165         /* tap the packet before the dissectors are called so we still get
18166            the tap listener called even if there is an exception.
18167         */
18168         tap_queue_packet(smb_tap, pinfo, si);
18169         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE, si);
18170
18171         /* Append error info from this packet to info string. */
18172         if (!si->request) {
18173                 if (flags2 & 0x4000) {
18174                         /*
18175                          * The status is an NT status code; was there
18176                          * an error?
18177                          */
18178                         if ((si->nt_status & 0xC0000000) == 0xC0000000) {
18179                                 /*
18180                                  * Yes.
18181                                  */
18182                                 col_append_fstr(
18183                                         pinfo->cinfo, COL_INFO, ", Error: %s",
18184                                         val_to_str_ext(si->nt_status, &NT_errors_ext,
18185                                             "Unknown (0x%08X)"));
18186                         }
18187                 } else {
18188                         /*
18189                          * The status is a DOS error class and code; was
18190                          * there an error?
18191                          */
18192                         if (errclass != SMB_SUCCESS) {
18193                                 /*
18194                                  * Yes.
18195                                  */
18196                                 col_append_fstr(
18197                                         pinfo->cinfo, COL_INFO, ", Error: %s",
18198                                         decode_smb_error(errclass, errcode));
18199                         }
18200                 }
18201         }
18202 }
18203
18204 static gboolean
18205 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
18206 {
18207         /* must check that this really is a smb packet */
18208         if (tvb_length(tvb) < 4)
18209                 return FALSE;
18210
18211         if ( (tvb_get_guint8(tvb, 0) != 0xff)
18212             || (tvb_get_guint8(tvb, 1) != 'S')
18213             || (tvb_get_guint8(tvb, 2) != 'M')
18214             || (tvb_get_guint8(tvb, 3) != 'B') ) {
18215                 return FALSE;
18216         }
18217
18218         dissect_smb(tvb, pinfo, parent_tree);
18219         return TRUE;
18220 }
18221
18222 void
18223 proto_register_smb(void)
18224 {
18225         static hf_register_info hf[] = {
18226         { &hf_smb_cmd,
18227                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
18228                 &smb_cmd_vals_ext, 0x0, NULL, HFILL }},
18229
18230         { &hf_smb_andxcmd,
18231                 { "AndXCommand", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
18232                 &smb_cmd_vals_ext, 0x0, NULL, HFILL }},
18233
18234         { &hf_smb_trans2_subcmd,
18235                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
18236                 &trans2_cmd_vals_ext, 0, "Subcommand for TRANSACTION2", HFILL }},
18237
18238         { &hf_smb_nt_trans_subcmd,
18239                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
18240                 &nt_cmd_vals_ext, 0, "Function for NT Transaction", HFILL }},
18241
18242         { &hf_smb_word_count,
18243                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
18244                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
18245
18246         { &hf_smb_byte_count,
18247                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
18248                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
18249
18250         { &hf_smb_response_to,
18251                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
18252                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
18253
18254         { &hf_smb_time,
18255                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
18256                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
18257
18258         { &hf_smb_response_in,
18259                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
18260                 NULL, 0, "The response to this packet is in this packet", HFILL }},
18261
18262         { &hf_smb_continuation_to,
18263                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
18264                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
18265
18266         { &hf_smb_nt_status,
18267                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
18268                 &NT_errors_ext, 0, "NT Status code", HFILL }},
18269
18270         { &hf_smb_error_class,
18271                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
18272                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
18273
18274         { &hf_smb_error_code,
18275                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
18276                 NULL, 0, "DOS Error Code", HFILL }},
18277
18278         { &hf_smb_reserved,
18279                 { "Reserved", "smb.reserved", FT_BYTES, BASE_NONE,
18280                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
18281
18282         { &hf_smb_sig,
18283                 { "Signature", "smb.signature", FT_BYTES, BASE_NONE,
18284                 NULL, 0, "Signature bytes", HFILL }},
18285
18286         { &hf_smb_key,
18287                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
18288                 NULL, 0, "SMB-over-IPX Key", HFILL }},
18289
18290         { &hf_smb_session_id,
18291                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
18292                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
18293
18294         { &hf_smb_sequence_num,
18295                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
18296                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
18297
18298         { &hf_smb_group_id,
18299                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
18300                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
18301
18302         { &hf_smb_pid,
18303                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
18304                 NULL, 0, NULL, HFILL }},
18305
18306         { &hf_smb_pid_high,
18307                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
18308                 NULL, 0, "Process ID High Bytes", HFILL }},
18309
18310         { &hf_smb_tid,
18311                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
18312                 NULL, 0, NULL, HFILL }},
18313
18314         { &hf_smb_uid,
18315                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
18316                 NULL, 0, NULL, HFILL }},
18317
18318         { &hf_smb_mid,
18319                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
18320                 NULL, 0, NULL, HFILL }},
18321
18322         { &hf_smb_flags,
18323                 { "Flags", "smb.flags", FT_UINT8, BASE_HEX,
18324                 NULL, 0x0, NULL, HFILL }},
18325
18326         { &hf_smb_flags_lock,
18327                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
18328                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
18329
18330         { &hf_smb_flags_receive_buffer,
18331                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
18332                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
18333
18334         { &hf_smb_flags_caseless,
18335                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
18336                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
18337
18338         { &hf_smb_flags_canon,
18339                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
18340                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
18341
18342         { &hf_smb_flags_oplock,
18343                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
18344                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
18345
18346         { &hf_smb_flags_notify,
18347                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
18348                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
18349
18350         { &hf_smb_flags_response,
18351                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
18352                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
18353
18354         { &hf_smb_flags2,
18355                 { "Flags2", "smb.flags2", FT_UINT16, BASE_HEX,
18356                 NULL, 0x0, NULL, HFILL }},
18357
18358         { &hf_smb_flags2_long_names_allowed,
18359                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
18360                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
18361
18362         { &hf_smb_flags2_ea,
18363                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
18364                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
18365
18366         { &hf_smb_flags2_sec_sig,
18367                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
18368                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
18369
18370         { &hf_smb_flags2_compressed,
18371                 { "Compressed", "smb.flags2.compressed", FT_BOOLEAN, 16,
18372                 TFS(&tfs_smb_flags2_compressed), 0x0008, "Is compression requested?", HFILL }},
18373
18374         { &hf_smb_flags2_sec_sig_required,
18375                 { "Security Signatures Required", "smb.flags2.sec_sig_required", FT_BOOLEAN, 16,
18376                 TFS(&tfs_smb_flags2_sec_sig_required), 0x0010, "Are security signatures required?", HFILL }},
18377
18378         { &hf_smb_flags2_long_names_used,
18379                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
18380                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
18381
18382         { &hf_smb_flags2_reparse_path,
18383                 { "Reparse Path", "smb.flags2.reparse_path", FT_BOOLEAN, 16,
18384                 TFS(&tfs_smb_flags2_reparse_path), 0x0400, "The request uses a @GMT reparse path", HFILL }},
18385
18386         { &hf_smb_flags2_esn,
18387                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
18388                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
18389
18390         { &hf_smb_flags2_dfs,
18391                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
18392                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
18393
18394         { &hf_smb_flags2_roe,
18395                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
18396                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
18397
18398         { &hf_smb_flags2_nt_error,
18399                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
18400                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
18401
18402         { &hf_smb_flags2_string,
18403                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
18404                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
18405
18406         { &hf_smb_buffer_format,
18407                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
18408                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
18409
18410         { &hf_smb_dialect,
18411                 { "Dialect", "smb.dialect", FT_STRING, BASE_NONE,
18412                 NULL, 0x0, NULL, HFILL }},
18413
18414         { &hf_smb_dialect_name,
18415                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
18416                 NULL, 0, "Name of dialect", HFILL }},
18417
18418         { &hf_smb_dialect_index,
18419                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
18420                 NULL, 0, "Index of selected dialect", HFILL }},
18421
18422         { &hf_smb_max_trans_buf_size,
18423                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
18424                 NULL, 0, "Maximum transmit buffer size", HFILL }},
18425
18426         { &hf_smb_max_mpx_count,
18427                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
18428                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
18429
18430         { &hf_smb_max_vcs_num,
18431                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
18432                 NULL, 0, "Maximum VCs between client and server", HFILL }},
18433
18434         { &hf_smb_session_key,
18435                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
18436                 NULL, 0, "Unique token identifying this session", HFILL }},
18437
18438         { &hf_smb_server_timezone,
18439                 { "Server Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
18440                 NULL, 0, "Current timezone at server.", HFILL }},
18441
18442         { &hf_smb_encryption_key_length,
18443                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
18444                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
18445
18446         { &hf_smb_encryption_key,
18447                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_NONE,
18448                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
18449
18450         { &hf_smb_primary_domain,
18451                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
18452                 NULL, 0, "The server's primary domain", HFILL }},
18453
18454         { &hf_smb_server,
18455                 { "Server", "smb.server", FT_STRING, BASE_NONE,
18456                 NULL, 0, "The name of the DC/server", HFILL }},
18457
18458         { &hf_smb_max_raw_buf_size,
18459                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
18460                 NULL, 0, "Maximum raw buffer size", HFILL }},
18461
18462         { &hf_smb_server_guid,
18463                 { "Server GUID", "smb.server_guid", FT_GUID, BASE_NONE,
18464                 NULL, 0, "Globally unique identifier for this server", HFILL }},
18465
18466         { &hf_smb_volume_guid,
18467                 { "Volume GUID", "smb.volume_guid", FT_GUID, BASE_NONE,
18468                 NULL, 0, "Globally unique identifer for this volume", HFILL }},
18469
18470         { &hf_smb_security_blob_len,
18471                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
18472                 NULL, 0, NULL, HFILL }},
18473
18474         { &hf_smb_security_blob,
18475                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_NONE,
18476                 NULL, 0, NULL, HFILL }},
18477
18478         { &hf_smb_sm16,
18479                 { "Security Mode", "smb.sm", FT_UINT16, BASE_HEX,
18480                 NULL, 0x0, NULL, HFILL }},
18481
18482         { &hf_smb_sm_mode16,
18483                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
18484                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
18485
18486         { &hf_smb_sm_password16,
18487                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
18488                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
18489
18490         { &hf_smb_sm,
18491                 { "Security Mode", "smb.sm", FT_UINT8, BASE_HEX,
18492                 NULL, 0x0, NULL, HFILL }},
18493
18494         { &hf_smb_sm_mode,
18495                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
18496                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
18497
18498         { &hf_smb_sm_password,
18499                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
18500                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
18501
18502         { &hf_smb_sm_signatures,
18503                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
18504                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
18505
18506         { &hf_smb_sm_sig_required,
18507                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
18508                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
18509
18510         { &hf_smb_rm,
18511                 { "Raw Mode", "smb.rm", FT_UINT16, BASE_HEX,
18512                 NULL, 0x0, NULL, HFILL }},
18513
18514         { &hf_smb_rm_read,
18515                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
18516                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
18517
18518         { &hf_smb_rm_write,
18519                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
18520                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
18521
18522         { &hf_smb_server_date_time,
18523                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18524                 NULL, 0, "Current date and time at server", HFILL }},
18525
18526         { &hf_smb_server_smb_date,
18527                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
18528                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
18529
18530         { &hf_smb_server_smb_time,
18531                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
18532                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
18533
18534         { &hf_smb_server_cap,
18535                 { "Capabilities", "smb.server_cap", FT_UINT32, BASE_HEX,
18536                 NULL, 0x0, NULL, HFILL }},
18537
18538         { &hf_smb_server_cap_raw_mode,
18539                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
18540                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
18541
18542         { &hf_smb_server_cap_mpx_mode,
18543                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
18544                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
18545
18546         { &hf_smb_server_cap_unicode,
18547                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
18548                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
18549
18550         { &hf_smb_server_cap_large_files,
18551                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
18552                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
18553
18554         { &hf_smb_server_cap_nt_smbs,
18555                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
18556                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
18557
18558         { &hf_smb_server_cap_rpc_remote_apis,
18559                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
18560                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
18561
18562         { &hf_smb_server_cap_nt_status,
18563                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
18564                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
18565
18566         { &hf_smb_server_cap_level_ii_oplocks,
18567                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
18568                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
18569
18570         { &hf_smb_server_cap_lock_and_read,
18571                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
18572                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
18573
18574         { &hf_smb_server_cap_nt_find,
18575                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
18576                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
18577
18578         { &hf_smb_server_cap_dfs,
18579                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
18580                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
18581
18582         { &hf_smb_server_cap_infolevel_passthru,
18583                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
18584                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
18585
18586         { &hf_smb_server_cap_large_readx,
18587                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
18588                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
18589
18590         { &hf_smb_server_cap_large_writex,
18591                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
18592                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
18593
18594         { &hf_smb_server_cap_lwio,
18595                 { "LWIO", "smb.server_cap.lwio", FT_BOOLEAN, 32,
18596                 TFS(&tfs_server_cap_lwio), SERVER_CAP_LWIO,
18597                 "Is IOCTL/FSCTL supported", HFILL }},
18598
18599         { &hf_smb_server_cap_unix,
18600                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
18601                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
18602
18603         { &hf_smb_server_cap_compressed_data,
18604                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
18605                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
18606
18607         { &hf_smb_server_cap_dynamic_reauth,
18608                 { "Dynamic Reauth", "smb.server_cap.dynamic_reauth", FT_BOOLEAN, 32,
18609                 TFS(&tfs_server_cap_dynamic_reauth), SERVER_CAP_DYNAMIC_REAUTH,
18610                 "Is dynamic reauth supported?", HFILL }},
18611
18612         { &hf_smb_server_cap_extended_security,
18613                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
18614                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
18615
18616         { &hf_smb_system_time,
18617                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18618                 NULL, 0, NULL, HFILL }},
18619
18620         { &hf_smb_unknown,
18621                 { "Unknown Data", "smb.unknown_data", FT_BYTES, BASE_NONE,
18622                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
18623
18624         { &hf_smb_dir_name,
18625                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
18626                 NULL, 0, "SMB Directory Name", HFILL }},
18627
18628         { &hf_smb_echo_count,
18629                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
18630                 NULL, 0, "Number of times to echo data back", HFILL }},
18631
18632         { &hf_smb_echo_data,
18633                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_NONE,
18634                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
18635
18636         { &hf_smb_echo_seq_num,
18637                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
18638                 NULL, 0, "Sequence number for this echo response", HFILL }},
18639
18640         { &hf_smb_max_buf_size,
18641                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
18642                 NULL, 0, "Max client buffer size", HFILL }},
18643
18644         { &hf_smb_path,
18645                 { "Path", "smb.path", FT_STRING, BASE_NONE,
18646                 NULL, 0, "Path. Server name and share name", HFILL }},
18647
18648         { &hf_smb_service,
18649                 { "Service", "smb.service", FT_STRING, BASE_NONE,
18650                 NULL, 0, "Service name", HFILL }},
18651
18652         { &hf_smb_password,
18653                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
18654                 NULL, 0, NULL, HFILL }},
18655
18656         { &hf_smb_ansi_password,
18657                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
18658                 NULL, 0, NULL, HFILL }},
18659
18660         { &hf_smb_unicode_password,
18661                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
18662                 NULL, 0, NULL, HFILL }},
18663
18664         { &hf_smb_move_flags,
18665                 { "Flags", "smb.move.flags", FT_UINT16, BASE_HEX,
18666                 NULL, 0x0, NULL, HFILL }},
18667
18668         { &hf_smb_move_flags_file,
18669                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
18670                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
18671
18672         { &hf_smb_move_flags_dir,
18673                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
18674                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
18675
18676         { &hf_smb_move_flags_verify,
18677                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
18678                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
18679
18680         { &hf_smb_files_moved,
18681                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
18682                 NULL, 0, "Number of files moved", HFILL }},
18683
18684         { &hf_smb_copy_flags,
18685                 { "Flags", "smb.copy.flags", FT_UINT16, BASE_HEX,
18686                 NULL, 0x0, NULL, HFILL }},
18687
18688         { &hf_smb_copy_flags_file,
18689                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
18690                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
18691
18692         { &hf_smb_copy_flags_dir,
18693                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
18694                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
18695
18696         { &hf_smb_copy_flags_dest_mode,
18697                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
18698                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
18699
18700         { &hf_smb_copy_flags_source_mode,
18701                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
18702                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
18703
18704         { &hf_smb_copy_flags_verify,
18705                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
18706                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
18707
18708         { &hf_smb_copy_flags_tree_copy,
18709                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
18710                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
18711
18712         { &hf_smb_copy_flags_ea_action,
18713                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
18714                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
18715
18716         { &hf_smb_count,
18717                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
18718                 NULL, 0, "Count number of items/bytes", HFILL }},
18719
18720         { &hf_smb_count_low,
18721                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
18722                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
18723
18724         { &hf_smb_count_high,
18725                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
18726                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
18727
18728         { &hf_smb_file_name,
18729                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
18730                 NULL, 0, NULL, HFILL }},
18731
18732         { &hf_smb_open_function,
18733                 { "Open Function", "smb.open.function", FT_UINT16, BASE_HEX,
18734                 NULL, 0x0, NULL, HFILL }},
18735
18736         { &hf_smb_open_function_create,
18737                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
18738                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
18739
18740         { &hf_smb_open_function_open,
18741                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
18742                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
18743
18744         { &hf_smb_fid,
18745                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
18746                 NULL, 0, "FID: File ID", HFILL }},
18747
18748         { &hf_smb_file_attr_16bit,
18749                 { "File Attributes", "smb.file_attribute", FT_UINT16, BASE_HEX,
18750                 NULL, 0x0, NULL, HFILL }},
18751
18752         { &hf_smb_file_attr_8bit,
18753                 { "File Attributes", "smb.file_attribute", FT_UINT8, BASE_HEX,
18754                 NULL, 0x0, NULL, HFILL }},
18755
18756         { &hf_smb_file_attr_read_only_16bit,
18757                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
18758                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18759
18760         { &hf_smb_file_attr_read_only_8bit,
18761                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
18762                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18763
18764         { &hf_smb_file_attr_hidden_16bit,
18765                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
18766                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18767
18768         { &hf_smb_file_attr_hidden_8bit,
18769                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
18770                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18771
18772         { &hf_smb_file_attr_system_16bit,
18773                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
18774                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18775
18776         { &hf_smb_file_attr_system_8bit,
18777                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
18778                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18779
18780         { &hf_smb_file_attr_volume_16bit,
18781                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
18782                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18783
18784         { &hf_smb_file_attr_volume_8bit,
18785                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
18786                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
18787
18788         { &hf_smb_file_attr_directory_16bit,
18789                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
18790                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18791
18792         { &hf_smb_file_attr_directory_8bit,
18793                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
18794                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18795
18796         { &hf_smb_file_attr_archive_16bit,
18797                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
18798                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18799
18800         { &hf_smb_file_attr_archive_8bit,
18801                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
18802                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18803
18804 #if 0
18805         { &hf_smb_file_attr_device,
18806                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
18807                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18808
18809         { &hf_smb_file_attr_normal,
18810                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
18811                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18812
18813         { &hf_smb_file_attr_temporary,
18814                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
18815                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18816
18817         { &hf_smb_file_attr_sparse,
18818                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
18819                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18820
18821         { &hf_smb_file_attr_reparse,
18822                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
18823                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18824
18825         { &hf_smb_file_attr_compressed,
18826                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
18827                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18828
18829         { &hf_smb_file_attr_offline,
18830                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
18831                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18832
18833         { &hf_smb_file_attr_not_content_indexed,
18834                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
18835                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18836
18837         { &hf_smb_file_attr_encrypted,
18838                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
18839                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18840 #endif
18841
18842         { &hf_smb_file_size,
18843                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
18844                 NULL, 0, NULL, HFILL }},
18845
18846         { &hf_smb_search_attribute,
18847                 { "Search Attributes", "smb.search.attribute", FT_UINT16, BASE_HEX,
18848                 NULL, 0x0, NULL, HFILL }},
18849
18850         { &hf_smb_search_attribute_read_only,
18851                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
18852                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
18853
18854         { &hf_smb_search_attribute_hidden,
18855                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
18856                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
18857
18858         { &hf_smb_search_attribute_system,
18859                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
18860                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
18861
18862         { &hf_smb_search_attribute_volume,
18863                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
18864                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
18865
18866         { &hf_smb_search_attribute_directory,
18867                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
18868                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
18869
18870         { &hf_smb_search_attribute_archive,
18871                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
18872                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
18873
18874         { &hf_smb_access_mode,
18875                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
18876                 VALS(da_access_vals), 0x0007, NULL, HFILL }},
18877
18878         { &hf_smb_access_sharing,
18879                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
18880                 VALS(da_sharing_vals), 0x0070, NULL, HFILL }},
18881
18882         { &hf_smb_access_locality,
18883                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
18884                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
18885
18886         { &hf_smb_access_caching,
18887                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
18888                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
18889
18890         { &hf_smb_access_writetru,
18891                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
18892                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
18893
18894         { &hf_smb_create_time,
18895                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18896                 NULL, 0, "Creation Time", HFILL }},
18897
18898         { &hf_smb_modify_time,
18899                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18900                   NULL, 0, "Modification Time", HFILL }},
18901
18902         { &hf_smb_backup_time,
18903                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18904                   NULL, 0, "Backup time", HFILL}},
18905
18906         { &hf_smb_mac_alloc_block_count,
18907                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
18908                   NULL, 0, NULL, HFILL}},
18909
18910         { &hf_smb_mac_alloc_block_size,
18911                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
18912                   NULL, 0, "Allocation Block Size", HFILL}},
18913
18914         { &hf_smb_mac_free_block_count,
18915                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
18916                   NULL, 0, NULL, HFILL}},
18917
18918         { &hf_smb_mac_root_file_count,
18919                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
18920                 NULL, 0, NULL, HFILL}},
18921
18922         { &hf_smb_mac_root_dir_count,
18923           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
18924             NULL, 0, NULL, HFILL}},
18925
18926         { &hf_smb_mac_file_count,
18927           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
18928             NULL, 0, "File Count", HFILL}},
18929
18930         { &hf_smb_mac_dir_count,
18931           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
18932             NULL, 0, "Directory Count", HFILL}},
18933
18934         { &hf_smb_mac_sup,
18935           { "Mac Support Flags", "smb.mac", FT_UINT32, BASE_HEX,
18936             NULL, 0x0, NULL, HFILL }},
18937
18938         { &hf_smb_mac_sup_access_ctrl,
18939           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
18940             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
18941
18942         { &hf_smb_mac_sup_getset_comments,
18943           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
18944             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
18945
18946         { &hf_smb_mac_sup_desktopdb_calls,
18947           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
18948             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
18949
18950         { &hf_smb_mac_sup_unique_ids,
18951           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
18952             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
18953
18954         { &hf_smb_mac_sup_streams,
18955           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
18956             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
18957
18958         { &hf_smb_create_dos_date,
18959                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
18960                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
18961
18962         { &hf_smb_create_dos_time,
18963                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
18964                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
18965
18966         { &hf_smb_last_write_time,
18967                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
18968                 NULL, 0, "Time this file was last written to", HFILL }},
18969
18970         { &hf_smb_last_write_dos_date,
18971                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
18972                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
18973
18974         { &hf_smb_last_write_dos_time,
18975                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
18976                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
18977
18978         { &hf_smb_old_file_name,
18979                 { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
18980                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
18981
18982         { &hf_smb_offset,
18983                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
18984                 NULL, 0, "Offset in file", HFILL }},
18985
18986         { &hf_smb_remaining,
18987                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
18988                 NULL, 0, "Remaining number of bytes", HFILL }},
18989
18990         { &hf_smb_padding,
18991                 { "Padding", "smb.padding", FT_BYTES, BASE_NONE,
18992                 NULL, 0, "Padding or unknown data", HFILL }},
18993
18994         { &hf_smb_file_data,
18995                 { "File Data", "smb.file_data", FT_BYTES, BASE_NONE,
18996                 NULL, 0, "Data read/written to the file", HFILL }},
18997
18998 #if 0
18999         { &hf_smb_raw_ea_data,
19000                 { "EA Data", "smb.ea_data", FT_BYTES, BASE_NONE,
19001                 NULL, 0, "Data in EA list", HFILL }},
19002 #endif
19003
19004         { &hf_smb_mac_fndrinfo,
19005                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_NONE,
19006                   NULL, 0, NULL, HFILL}},
19007
19008         { &hf_smb_total_data_len,
19009                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
19010                 NULL, 0, "Total length of data", HFILL }},
19011
19012         { &hf_smb_data_len,
19013                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
19014                 NULL, 0, "Length of data", HFILL }},
19015
19016         { &hf_smb_data_len_low,
19017                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
19018                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
19019
19020         { &hf_smb_data_len_high,
19021                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
19022                 NULL, 0, "Length of data, High 16 bits", HFILL }},
19023
19024         { &hf_smb_seek_mode,
19025                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
19026                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
19027
19028         { &hf_smb_access_time,
19029                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19030                 NULL, 0, "Last Access Time", HFILL }},
19031
19032         { &hf_smb_access_dos_date,
19033                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
19034                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
19035
19036         { &hf_smb_access_dos_time,
19037                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
19038                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
19039
19040         { &hf_smb_data_size,
19041                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
19042                 NULL, 0, NULL, HFILL }},
19043
19044         { &hf_smb_alloc_size,
19045                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
19046                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
19047
19048         { &hf_smb_max_count,
19049                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
19050                 NULL, 0, "Maximum Count", HFILL }},
19051
19052         { &hf_smb_max_count_low,
19053                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
19054                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
19055
19056         { &hf_smb_max_count_high,
19057                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
19058                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
19059
19060         { &hf_smb_min_count,
19061                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
19062                 NULL, 0, "Minimum Count", HFILL }},
19063
19064         { &hf_smb_timeout,
19065                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
19066                 NULL, 0, "Timeout in milliseconds", HFILL }},
19067
19068         { &hf_smb_high_offset,
19069                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
19070                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
19071
19072         { &hf_smb_units,
19073                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
19074                 NULL, 0, "Total number of units at server", HFILL }},
19075
19076         { &hf_smb_bpu,
19077                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
19078                 NULL, 0, "Blocks per unit at server", HFILL }},
19079
19080         { &hf_smb_blocksize,
19081                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
19082                 NULL, 0, "Block size (in bytes) at server", HFILL }},
19083
19084         { &hf_smb_freeunits,
19085                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
19086                 NULL, 0, "Number of free units at server", HFILL }},
19087
19088         { &hf_smb_data_offset,
19089                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
19090                 NULL, 0, NULL, HFILL }},
19091
19092         { &hf_smb_dcm,
19093                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
19094                 NULL, 0, NULL, HFILL }},
19095
19096         { &hf_smb_request_mask,
19097                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
19098                 NULL, 0, "Connectionless mode mask", HFILL }},
19099
19100         { &hf_smb_response_mask,
19101                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
19102                 NULL, 0, "Connectionless mode mask", HFILL }},
19103
19104         { &hf_smb_search_id,
19105                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
19106                 NULL, 0, "Search ID, handle for find operations", HFILL }},
19107
19108         { &hf_smb_write_mode,
19109                 { "Write Mode", "smb.write.mode", FT_UINT16, BASE_HEX,
19110                 NULL, 0x0, NULL, HFILL }},
19111
19112         { &hf_smb_write_mode_write_through,
19113                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
19114                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
19115
19116         { &hf_smb_write_mode_return_remaining,
19117                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
19118                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
19119
19120         { &hf_smb_write_mode_raw,
19121                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
19122                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
19123
19124         { &hf_smb_write_mode_message_start,
19125                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
19126                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
19127
19128         { &hf_smb_write_mode_connectionless,
19129                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
19130                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
19131
19132         { &hf_smb_resume_key_len,
19133                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
19134                 NULL, 0, NULL, HFILL }},
19135
19136         { &hf_smb_resume_find_id,
19137                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
19138                 NULL, 0, "Handle for Find operation", HFILL }},
19139
19140         { &hf_smb_resume_server_cookie,
19141                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_NONE,
19142                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
19143
19144         { &hf_smb_resume_client_cookie,
19145                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_NONE,
19146                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
19147
19148         { &hf_smb_andxoffset,
19149                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
19150                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
19151
19152         { &hf_smb_lock_type,
19153                 { "Lock Type", "smb.lock.type", FT_UINT8, BASE_HEX,
19154                 NULL, 0x0, NULL, HFILL }},
19155
19156         { &hf_smb_lock_type_large,
19157                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
19158                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
19159
19160         { &hf_smb_lock_type_cancel,
19161                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
19162                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
19163
19164         { &hf_smb_lock_type_change,
19165                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
19166                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
19167
19168         { &hf_smb_lock_type_oplock,
19169                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
19170                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
19171
19172         { &hf_smb_lock_type_shared,
19173                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
19174                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
19175
19176         { &hf_smb_locking_ol,
19177                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
19178                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
19179
19180         { &hf_smb_number_of_locks,
19181                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
19182                 NULL, 0, "Number of lock requests in this request", HFILL }},
19183
19184         { &hf_smb_number_of_unlocks,
19185                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
19186                 NULL, 0, "Number of unlock requests in this request", HFILL }},
19187
19188         { &hf_smb_lock_long_length,
19189                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
19190                 NULL, 0, "Length of lock/unlock region", HFILL }},
19191
19192         { &hf_smb_lock_long_offset,
19193                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
19194                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
19195
19196         { &hf_smb_file_type,
19197                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
19198                 VALS(filetype_vals), 0, "Type of file", HFILL }},
19199
19200         { &hf_smb_ipc_state,
19201                 { "IPC State", "smb.ipc_state", FT_UINT16, BASE_HEX,
19202                 NULL, 0x0, NULL, HFILL }},
19203
19204         { &hf_smb_ipc_state_nonblocking,
19205                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
19206                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
19207
19208         { &hf_smb_ipc_state_endpoint,
19209                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
19210                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
19211
19212         { &hf_smb_ipc_state_pipe_type,
19213                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
19214                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
19215
19216         { &hf_smb_ipc_state_read_mode,
19217                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
19218                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
19219
19220         { &hf_smb_ipc_state_icount,
19221                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
19222                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
19223
19224         { &hf_smb_server_fid,
19225                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
19226                 NULL, 0, "Server unique File ID", HFILL }},
19227
19228         { &hf_smb_open_flags,
19229                 { "Flags", "smb.open.flags", FT_UINT16, BASE_HEX,
19230                 NULL, 0x0, NULL, HFILL }},
19231
19232         { &hf_smb_open_flags_add_info,
19233                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
19234                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
19235
19236         { &hf_smb_open_flags_ex_oplock,
19237                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
19238                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
19239
19240         { &hf_smb_open_flags_batch_oplock,
19241                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
19242                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
19243
19244         { &hf_smb_open_flags_ealen,
19245                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
19246                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
19247
19248         { &hf_smb_open_action,
19249                 { "Action", "smb.open.action", FT_UINT16, BASE_HEX,
19250                 NULL, 0x0, NULL, HFILL }},
19251
19252         { &hf_smb_open_action_open,
19253                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
19254                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
19255
19256         { &hf_smb_open_action_lock,
19257                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
19258                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
19259
19260         { &hf_smb_vc_num,
19261                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
19262                 NULL, 0, NULL, HFILL }},
19263
19264         { &hf_smb_password_len,
19265                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
19266                 NULL, 0, "Length of password", HFILL }},
19267
19268         { &hf_smb_ansi_password_len,
19269                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
19270                 NULL, 0, "Length of ANSI password", HFILL }},
19271
19272         { &hf_smb_unicode_password_len,
19273                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
19274                 NULL, 0, "Length of Unicode password", HFILL }},
19275
19276         { &hf_smb_account,
19277                 { "Account", "smb.account", FT_STRING, BASE_NONE,
19278                 NULL, 0, "Account, username", HFILL }},
19279
19280         { &hf_smb_os,
19281                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
19282                 NULL, 0, "Which OS we are running", HFILL }},
19283
19284         { &hf_smb_lanman,
19285                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
19286                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
19287
19288         { &hf_smb_setup_action,
19289                 { "Action", "smb.setup.action", FT_UINT16, BASE_HEX,
19290                 NULL, 0x0, NULL, HFILL }},
19291
19292         { &hf_smb_setup_action_guest,
19293                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
19294                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
19295
19296         { &hf_smb_fs,
19297                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
19298                 NULL, 0, NULL, HFILL }},
19299
19300         { &hf_smb_connect_flags,
19301                 { "Flags", "smb.connect.flags", FT_UINT16, BASE_HEX,
19302                 NULL, 0x0, NULL, HFILL }},
19303
19304         { &hf_smb_connect_flags_dtid,
19305                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
19306                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
19307
19308         { &hf_smb_connect_flags_ext_sig,
19309                 { "Extended Signature", "smb.connect.flags.extendedsig", FT_BOOLEAN, 16,
19310                 TFS(&tfs_extended_signature), 0x0004, "Extended signature?", HFILL }},
19311
19312         { &hf_smb_connect_flags_ext_resp,
19313                 { "Extended Response", "smb.connect.flags.extendedresp", FT_BOOLEAN, 16,
19314                 TFS(&tfs_extended_response), 0x0008, "Extended response?", HFILL }},
19315
19316         { &hf_smb_connect_support,
19317                 { "Optional Support", "smb.connect.support", FT_UINT16, BASE_HEX,
19318                 NULL, 0x0, NULL, HFILL }},
19319
19320         { &hf_smb_connect_support_search,
19321                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
19322                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
19323
19324         { &hf_smb_connect_support_in_dfs,
19325                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
19326                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
19327
19328         { &hf_smb_connect_support_csc_mask_vals,
19329                 { "CSC Mask", "smb.connect.support.cscmask", FT_UINT16, BASE_DEC,
19330                 VALS(connect_support_csc_mask_vals), 0x000c, "CSC mask?", HFILL }},
19331
19332         { &hf_smb_connect_support_uniquefilename,
19333                 { "Unique File Name", "smb.connect.support.uniqfilename", FT_BOOLEAN, 16,
19334                 TFS(&tfs_connect_support_uniquefilename), 0x0010, "Unique file name supported?", HFILL }},
19335
19336         { &hf_smb_connect_support_extended_signature,
19337                 { "Extended Signatures", "smb.connect.support.extendedsig", FT_BOOLEAN, 16,
19338                 TFS(&tfs_connect_support_extended_signature), 0x0020, "Extended signatures?", HFILL }},
19339
19340         { &hf_smb_max_setup_count,
19341                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
19342                 NULL, 0, "Maximum number of setup words to return", HFILL }},
19343
19344         { &hf_smb_total_param_count,
19345                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
19346                 NULL, 0, "Total number of parameter bytes", HFILL }},
19347
19348         { &hf_smb_total_data_count,
19349                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
19350                 NULL, 0, "Total number of data bytes", HFILL }},
19351
19352         { &hf_smb_max_param_count,
19353                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
19354                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
19355
19356         { &hf_smb_max_data_count,
19357                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
19358                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
19359
19360         { &hf_smb_param_disp16,
19361                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
19362                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
19363
19364         { &hf_smb_param_count16,
19365                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
19366                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
19367
19368         { &hf_smb_param_offset16,
19369                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
19370                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
19371
19372         { &hf_smb_param_disp32,
19373                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
19374                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
19375
19376         { &hf_smb_param_count32,
19377                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
19378                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
19379
19380         { &hf_smb_param_offset32,
19381                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
19382                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
19383
19384         { &hf_smb_data_count16,
19385                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
19386                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
19387
19388         { &hf_smb_data_disp16,
19389                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
19390                 NULL, 0, NULL, HFILL }},
19391
19392         { &hf_smb_data_offset16,
19393                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
19394                 NULL, 0, NULL, HFILL }},
19395
19396         { &hf_smb_data_count32,
19397                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
19398                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
19399
19400         { &hf_smb_data_disp32,
19401                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
19402                 NULL, 0, NULL, HFILL }},
19403
19404         { &hf_smb_data_offset32,
19405                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
19406                 NULL, 0, NULL, HFILL }},
19407
19408         { &hf_smb_setup_count,
19409                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
19410                 NULL, 0, "Number of setup words in this buffer", HFILL }},
19411
19412         { &hf_smb_nt_ioctl_isfsctl,
19413                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
19414                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
19415
19416         { &hf_smb_nt_ioctl_flags_completion_filter,
19417                 { "Completion Filter", "smb.nt.ioctl.completion_filter", FT_UINT8, BASE_HEX,
19418                 NULL, 0x0, NULL, HFILL }},
19419
19420         { &hf_smb_nt_ioctl_flags_root_handle,
19421                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
19422                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
19423
19424         { &hf_smb_nt_notify_action,
19425                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
19426                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
19427
19428         { &hf_smb_nt_notify_watch_tree,
19429                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
19430                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
19431
19432
19433         { &hf_smb_nt_notify_completion_filter,
19434                 { "Completion Filter", "smb.nt.notify.completion_filter", FT_UINT32, BASE_HEX,
19435                 NULL, 0x0, NULL, HFILL }},
19436         { &hf_smb_nt_notify_file_name,
19437                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
19438                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
19439
19440         { &hf_smb_nt_notify_dir_name,
19441                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
19442                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
19443
19444         { &hf_smb_nt_notify_attributes,
19445                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
19446                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
19447
19448         { &hf_smb_nt_notify_size,
19449                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
19450                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
19451
19452         { &hf_smb_nt_notify_last_write,
19453                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
19454                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
19455
19456         { &hf_smb_nt_notify_last_access,
19457                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
19458                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
19459
19460         { &hf_smb_nt_notify_creation,
19461                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
19462                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
19463
19464         { &hf_smb_nt_notify_ea,
19465                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
19466                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
19467
19468         { &hf_smb_nt_notify_security,
19469                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
19470                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
19471
19472         { &hf_smb_nt_notify_stream_name,
19473                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
19474                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
19475
19476         { &hf_smb_nt_notify_stream_size,
19477                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
19478                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
19479
19480         { &hf_smb_nt_notify_stream_write,
19481                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
19482                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
19483
19484
19485         { &hf_smb_root_dir_fid,
19486                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
19487                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
19488
19489         { &hf_smb_alloc_size64,
19490                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
19491                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
19492
19493         { &hf_smb_nt_create_disposition,
19494                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
19495                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
19496
19497         { &hf_smb_sd_length,
19498                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
19499                 NULL, 0, "Total length of security descriptor", HFILL }},
19500
19501         { &hf_smb_ea_list_length,
19502                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
19503                 NULL, 0, "Total length of extended attributes", HFILL }},
19504
19505         { &hf_smb_ea_flags,
19506                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
19507                 NULL, 0, NULL, HFILL }},
19508
19509         { &hf_smb_ea_name_length,
19510                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
19511                 NULL, 0, NULL, HFILL }},
19512
19513         { &hf_smb_ea_data_length,
19514                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
19515                 NULL, 0, NULL, HFILL }},
19516
19517         { &hf_smb_ea_name,
19518                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
19519                 NULL, 0, NULL, HFILL }},
19520
19521         { &hf_smb_ea_data,
19522                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
19523                 NULL, 0, NULL, HFILL }},
19524
19525         { &hf_smb_file_name_len,
19526                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
19527                 NULL, 0, "Length of File Name", HFILL }},
19528
19529         { &hf_smb_nt_impersonation_level,
19530                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
19531                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
19532
19533         { &hf_smb_nt_security_flags,
19534                 { "Security Flags", "smb.security.flags", FT_UINT8, BASE_HEX,
19535                 NULL, 0x0, NULL, HFILL }},
19536
19537         { &hf_smb_nt_security_flags_context_tracking,
19538                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
19539                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
19540
19541         { &hf_smb_nt_security_flags_effective_only,
19542                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
19543                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
19544
19545         { &hf_smb_nt_access_mask_generic_read,
19546                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
19547                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
19548
19549         { &hf_smb_nt_access_mask_generic_write,
19550                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
19551                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
19552
19553         { &hf_smb_nt_access_mask_generic_execute,
19554                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
19555                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
19556
19557         { &hf_smb_nt_access_mask_generic_all,
19558                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
19559                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
19560
19561         { &hf_smb_nt_access_mask_maximum_allowed,
19562                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
19563                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
19564
19565         { &hf_smb_nt_access_mask_system_security,
19566                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
19567                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
19568
19569         { &hf_smb_nt_access_mask_synchronize,
19570                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
19571                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
19572
19573         { &hf_smb_nt_access_mask_write_owner,
19574                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
19575                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
19576
19577         { &hf_smb_nt_access_mask_write_dac,
19578                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
19579                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
19580
19581         { &hf_smb_nt_access_mask_read_control,
19582                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
19583                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
19584
19585         { &hf_smb_nt_access_mask_delete,
19586                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
19587                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
19588
19589         { &hf_smb_nt_access_mask_write_attributes,
19590                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
19591                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
19592
19593         { &hf_smb_nt_access_mask_read_attributes,
19594                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
19595                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
19596
19597         { &hf_smb_nt_access_mask_delete_child,
19598                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
19599                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
19600
19601         /*
19602          * "Execute" for files, "traverse" for directories.
19603          */
19604         { &hf_smb_nt_access_mask_execute,
19605                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
19606                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
19607
19608         { &hf_smb_nt_access_mask_write_ea,
19609                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
19610                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
19611
19612         { &hf_smb_nt_access_mask_read_ea,
19613                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
19614                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
19615
19616         /*
19617          * "Append data" for files, "add subdirectory" for directories,
19618          * "create pipe instance" for named pipes.
19619          */
19620         { &hf_smb_nt_access_mask_append,
19621                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
19622                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
19623
19624         /*
19625          * "Write data" for files and pipes, "add file" for directory.
19626          */
19627         { &hf_smb_nt_access_mask_write,
19628                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
19629                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
19630
19631         /*
19632          * "Read data" for files and pipes, "list directory" for directory.
19633          */
19634         { &hf_smb_nt_access_mask_read,
19635                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
19636                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
19637
19638         { &hf_smb_nt_create_bits_oplock,
19639                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
19640                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
19641
19642         { &hf_smb_nt_create_bits_boplock,
19643                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
19644                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
19645
19646         { &hf_smb_nt_create_bits_dir,
19647                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
19648                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
19649
19650         { &hf_smb_nt_create_bits_ext_resp,
19651           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
19652             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
19653
19654         { &hf_smb_nt_create_options_directory_file,
19655                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
19656                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
19657
19658         { &hf_smb_nt_create_options_write_through,
19659                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
19660                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
19661
19662         { &hf_smb_nt_create_options_sequential_only,
19663                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
19664                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will access to this file only be sequential?", HFILL }},
19665
19666         { &hf_smb_nt_create_options_no_intermediate_buffering,
19667                 { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
19668                 TFS(&tfs_nt_create_options_no_intermediate_buffering), 0x00000008, "Is intermediate buffering allowed?", HFILL }},
19669
19670         { &hf_smb_nt_create_options_sync_io_alert,
19671                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
19672                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
19673
19674         { &hf_smb_nt_create_options_sync_io_nonalert,
19675                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
19676                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
19677
19678         { &hf_smb_nt_create_options_non_directory_file,
19679                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
19680                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
19681
19682         { &hf_smb_nt_create_options_create_tree_connection,
19683                 { "Create Tree Connection", "smb.nt.create_options.create_tree_connection", FT_BOOLEAN, 32,
19684                 TFS(&tfs_nt_create_options_create_tree_connection), 0x00000080, "Create Tree Connection flag", HFILL }},
19685
19686         { &hf_smb_nt_create_options_complete_if_oplocked,
19687                 { "Complete If Oplocked", "smb.nt.create_options.complete_if_oplocked", FT_BOOLEAN, 32,
19688                 TFS(&tfs_nt_create_options_complete_if_oplocked), 0x00000100, "Complete if oplocked flag", HFILL }},
19689
19690         { &hf_smb_nt_create_options_no_ea_knowledge,
19691                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
19692                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
19693
19694         { &hf_smb_nt_create_options_eight_dot_three_only,
19695                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
19696                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
19697
19698         { &hf_smb_nt_create_options_random_access,
19699                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
19700                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
19701
19702         { &hf_smb_nt_create_options_delete_on_close,
19703                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
19704                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
19705         { &hf_smb_nt_create_options_open_by_fileid,
19706                 { "Open By FileID", "smb.nt.create_options.open_by_fileid", FT_BOOLEAN, 32,
19707                 TFS(&tfs_nt_create_options_open_by_fileid), 0x00002000, "Open file by inode", HFILL }},
19708
19709         { &hf_smb_nt_create_options_backup_intent,
19710                 { "Backup Intent", "smb.nt.create_options.backup_intent", FT_BOOLEAN, 32,
19711                 TFS(&tfs_nt_create_options_backup_intent), 0x00004000, "Is this opened by BACKUP ADMIN for backup intent?", HFILL }},
19712
19713         { &hf_smb_nt_create_options_no_compression,
19714                 { "No Compression", "smb.nt.create_options.no_compression", FT_BOOLEAN, 32,
19715                 TFS(&tfs_nt_create_options_no_compression), 0x00008000, "Is compression allowed?", HFILL }},
19716
19717         { &hf_smb_nt_create_options_reserve_opfilter,
19718                 { "Reserve Opfilter", "smb.nt.create_options.reserve_opfilter", FT_BOOLEAN, 32,
19719                 TFS(&tfs_nt_create_options_reserve_opfilter), 0x00100000, "Reserve Opfilter flag", HFILL }},
19720
19721         { &hf_smb_nt_create_options_open_reparse_point,
19722                 { "Open Reparse Point", "smb.nt.create_options.open_reparse_point", FT_BOOLEAN, 32,
19723                 TFS(&tfs_nt_create_options_open_reparse_point), 0x00200000, "Is this an open of a reparse point or of the normal file?", HFILL }},
19724
19725         { &hf_smb_nt_create_options_open_no_recall,
19726                 { "Open No Recall", "smb.nt.create_options.open_no_recall", FT_BOOLEAN, 32,
19727                 TFS(&tfs_nt_create_options_open_no_recall), 0x00400000, "Open no recall flag", HFILL }},
19728
19729         { &hf_smb_nt_create_options_open_for_free_space_query,
19730                 { "Open For Free Space query", "smb.nt.create_options.open_for_free_space_query", FT_BOOLEAN, 32,
19731                 TFS(&tfs_nt_create_options_open_for_free_space_query), 0x00800000, "Open For Free Space Query flag", HFILL }},
19732
19733         { &hf_smb_nt_share_access_read,
19734                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
19735                 TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
19736
19737         { &hf_smb_nt_share_access_write,
19738                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
19739                 TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
19740
19741         { &hf_smb_nt_share_access_delete,
19742                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
19743                 TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, NULL, HFILL }},
19744
19745         { &hf_smb_file_eattr,
19746                 { "File Attributes", "smb.file_attribute", FT_UINT32, BASE_HEX,
19747                 NULL, 0x0, NULL, HFILL }},
19748
19749         { &hf_smb_file_eattr_read_only,
19750                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
19751                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
19752
19753         { &hf_smb_file_eattr_hidden,
19754                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
19755                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
19756
19757         { &hf_smb_file_eattr_system,
19758                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
19759                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
19760
19761         { &hf_smb_file_eattr_volume,
19762                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
19763                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
19764
19765         { &hf_smb_file_eattr_directory,
19766                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
19767                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
19768
19769         { &hf_smb_file_eattr_archive,
19770                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
19771                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
19772
19773         { &hf_smb_file_eattr_device,
19774                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
19775                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
19776
19777         { &hf_smb_file_eattr_normal,
19778                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
19779                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
19780
19781         { &hf_smb_file_eattr_temporary,
19782                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
19783                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
19784
19785         { &hf_smb_file_eattr_sparse,
19786                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
19787                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
19788
19789         { &hf_smb_file_eattr_reparse,
19790                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
19791                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
19792
19793         { &hf_smb_file_eattr_compressed,
19794                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
19795                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
19796
19797         { &hf_smb_file_eattr_offline,
19798                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
19799                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
19800
19801         { &hf_smb_file_eattr_not_content_indexed,
19802                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
19803                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
19804
19805         { &hf_smb_file_eattr_encrypted,
19806                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
19807                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
19808
19809         { &hf_smb_size_returned_quota_data,
19810                 { "Size of returned Quota data", "smb.size_returned_quota_data", FT_UINT32, BASE_DEC,
19811                 NULL, 0x0, NULL, HFILL }},
19812
19813         { &hf_smb_sec_desc_len,
19814                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
19815                 NULL, 0, "Security Descriptor Length", HFILL }},
19816
19817         { &hf_smb_nt_qsd,
19818                 { "Security Information", "smb.nt_qsd", FT_UINT32, BASE_HEX,
19819                 NULL, 0x0, NULL, HFILL }},
19820
19821         { &hf_smb_nt_qsd_owner,
19822                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
19823                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security information being queried?", HFILL }},
19824
19825         { &hf_smb_nt_qsd_group,
19826                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
19827                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security information being queried?", HFILL }},
19828
19829         { &hf_smb_nt_qsd_dacl,
19830                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
19831                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security information being queried?", HFILL }},
19832
19833         { &hf_smb_nt_qsd_sacl,
19834                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
19835                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security information being queried?", HFILL }},
19836
19837         { &hf_smb_extended_attributes,
19838                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_NONE,
19839                 NULL, 0, NULL, HFILL }},
19840
19841         { &hf_smb_oplock_level,
19842                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
19843                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
19844
19845         { &hf_smb_create_action,
19846                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
19847                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
19848
19849         { &hf_smb_file_id,
19850                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
19851                 NULL, 0, NULL, HFILL }},
19852
19853         { &hf_smb_file_id_64bit,
19854                 { "Server unique 64-bit file ID", "smb.create.file_id_64b", FT_UINT64, BASE_HEX,
19855                 NULL, 0, NULL, HFILL }},
19856
19857         { &hf_smb_ea_error_offset,
19858                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
19859                 NULL, 0, "Offset into EA list if EA error", HFILL }},
19860
19861         { &hf_smb_end_of_file,
19862                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
19863                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
19864
19865         { &hf_smb_replace,
19866                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
19867                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
19868
19869         { &hf_smb_root_dir_handle,
19870                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
19871                 NULL, 0, NULL, HFILL }},
19872
19873         { &hf_smb_target_name_len,
19874                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
19875                 NULL, 0, "Length of target file name", HFILL }},
19876
19877         { &hf_smb_target_name,
19878                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
19879                 NULL, 0, "Target file name", HFILL }},
19880
19881         { &hf_smb_device_type,
19882                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
19883                 &device_type_vals_ext, 0, "Type of device", HFILL }},
19884
19885         { &hf_smb_is_directory,
19886                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
19887                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
19888
19889         { &hf_smb_next_entry_offset,
19890                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
19891                 NULL, 0, "Offset to next entry", HFILL }},
19892
19893         { &hf_smb_change_time,
19894                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19895                 NULL, 0, "Last Change Time", HFILL }},
19896
19897         { &hf_smb_setup_len,
19898                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
19899                 NULL, 0, "Length of printer setup data", HFILL }},
19900
19901         { &hf_smb_print_mode,
19902                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
19903                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
19904
19905         { &hf_smb_print_identifier,
19906                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
19907                 NULL, 0, "Identifier string for this print job", HFILL }},
19908
19909         { &hf_smb_restart_index,
19910                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
19911                 NULL, 0, "Index of entry after last returned", HFILL }},
19912
19913         { &hf_smb_print_queue_date,
19914                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
19915                 NULL, 0, "Date when this entry was queued", HFILL }},
19916
19917         { &hf_smb_print_queue_dos_date,
19918                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
19919                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
19920
19921         { &hf_smb_print_queue_dos_time,
19922                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
19923                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
19924
19925         { &hf_smb_print_status,
19926                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
19927                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
19928
19929         { &hf_smb_print_spool_file_number,
19930                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
19931                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
19932
19933         { &hf_smb_print_spool_file_size,
19934                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
19935                 NULL, 0, "Number of bytes in spool file", HFILL }},
19936
19937         { &hf_smb_print_spool_file_name,
19938                 { "Name", "smb.print.spool.name", FT_STRINGZ, BASE_NONE,
19939                 NULL, 0, "Name of client that submitted this job", HFILL }},
19940
19941         { &hf_smb_start_index,
19942                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
19943                 NULL, 0, "First queue entry to return", HFILL }},
19944
19945         { &hf_smb_originator_name,
19946                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
19947                 NULL, 0, "Name of sender of message", HFILL }},
19948
19949         { &hf_smb_destination_name,
19950                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
19951                 NULL, 0, "Name of recipient of message", HFILL }},
19952
19953         { &hf_smb_message_len,
19954                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
19955                 NULL, 0, "Length of message", HFILL }},
19956
19957         { &hf_smb_message,
19958                 { "Message", "smb.message", FT_STRING, BASE_NONE,
19959                 NULL, 0, "Message text", HFILL }},
19960
19961         { &hf_smb_mgid,
19962                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
19963                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
19964
19965         { &hf_smb_forwarded_name,
19966                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
19967                 NULL, 0, "Recipient name being forwarded", HFILL }},
19968
19969         { &hf_smb_machine_name,
19970                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
19971                 NULL, 0, "Name of target machine", HFILL }},
19972
19973         { &hf_smb_cancel_to,
19974                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
19975                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
19976
19977         { &hf_smb_trans_name,
19978                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
19979                 NULL, 0, "Name of transaction", HFILL }},
19980
19981         { &hf_smb_transaction_flags,
19982                 { "Flags", "smb.transaction.flags", FT_UINT16, BASE_HEX,
19983                 NULL, 0x0, NULL, HFILL }},
19984
19985         { &hf_smb_transaction_flags_dtid,
19986                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
19987                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
19988
19989         { &hf_smb_transaction_flags_owt,
19990                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
19991                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
19992
19993         { &hf_smb_search_count,
19994                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
19995                 NULL, 0, "Maximum number of search entries to return", HFILL }},
19996
19997         { &hf_smb_search_pattern,
19998                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
19999                 NULL, 0, NULL, HFILL }},
20000
20001         { &hf_smb_ff2,
20002                 { "Flags", "smb.find_first2.flags", FT_UINT16, BASE_HEX,
20003                 NULL, 0x0, NULL, HFILL }},
20004
20005         { &hf_smb_ff2_backup,
20006                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
20007                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
20008
20009         { &hf_smb_ff2_continue,
20010                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
20011                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
20012
20013         { &hf_smb_ff2_resume,
20014                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
20015                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
20016
20017         { &hf_smb_ff2_close_eos,
20018                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
20019                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
20020
20021         { &hf_smb_ff2_close,
20022                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
20023                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
20024
20025         { &hf_smb_ff2_information_level,
20026                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
20027                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
20028
20029         { &hf_smb_qpi_loi,
20030                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
20031                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
20032
20033         { &hf_smb_spi_loi,
20034                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
20035                 &spi_loi_vals_ext, 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
20036
20037 #if 0
20038         { &hf_smb_sfi_writetru,
20039                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
20040                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
20041
20042         { &hf_smb_sfi_caching,
20043                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
20044                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
20045 #endif
20046
20047         { &hf_smb_storage_type,
20048                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
20049                 NULL, 0, "Type of storage", HFILL }},
20050
20051         { &hf_smb_resume,
20052                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
20053                 NULL, 0, NULL, HFILL }},
20054
20055         { &hf_smb_max_referral_level,
20056                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
20057                 NULL, 0, "Latest referral version number understood", HFILL }},
20058
20059         { &hf_smb_qfsi_information_level,
20060                 { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX | BASE_EXT_STRING,
20061                 &qfsi_vals_ext, 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
20062
20063         { &hf_smb_sfsi_information_level,
20064                 { "Level of Interest", "smb.sfsi_loi", FT_UINT16, BASE_HEX,
20065                 VALS(sfsi_vals), 0, "Level of interest for SET_FS_INFORMATION2 command", HFILL }},
20066
20067         { &hf_smb_nt_rename_level,
20068                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
20069                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
20070
20071         { &hf_smb_cluster_count,
20072                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
20073                 NULL, 0, "Number of clusters", HFILL }},
20074
20075         { &hf_smb_number_of_links,
20076                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
20077                 NULL, 0, "Number of hard links to the file", HFILL }},
20078
20079         { &hf_smb_delete_pending,
20080                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
20081                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
20082
20083         { &hf_smb_index_number,
20084                 { "Index Number", "smb.index_number", FT_UINT64, BASE_HEX,
20085                 NULL, 0, "File system unique identifier", HFILL }},
20086
20087         { &hf_smb_position,
20088                 { "Position", "smb.position", FT_UINT64, BASE_DEC,
20089                 NULL, 0, "File position", HFILL }},
20090
20091 #if 0
20092         { &hf_smb_current_offset,
20093                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
20094                 NULL, 0, "Current offset in the file", HFILL }},
20095 #endif
20096
20097         { &hf_smb_t2_alignment,
20098                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
20099                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
20100
20101         { &hf_smb_t2_stream_name_length,
20102                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
20103                 NULL, 0, "Length of stream name", HFILL }},
20104
20105         { &hf_smb_t2_stream_size,
20106                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
20107                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
20108
20109         { &hf_smb_t2_stream_name,
20110                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
20111                 NULL, 0, "Name of the stream", HFILL }},
20112
20113         { &hf_smb_t2_compressed_file_size,
20114                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
20115                 NULL, 0, "Size of the compressed file", HFILL }},
20116
20117         { &hf_smb_t2_compressed_format,
20118                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
20119                 NULL, 0, "Compression algorithm used", HFILL }},
20120
20121         { &hf_smb_t2_compressed_unit_shift,
20122                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
20123                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
20124
20125         { &hf_smb_t2_compressed_chunk_shift,
20126                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
20127                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
20128
20129         { &hf_smb_t2_compressed_cluster_shift,
20130                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
20131                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
20132
20133         { &hf_smb_t2_marked_for_deletion,
20134                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
20135                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
20136
20137         { &hf_smb_dfs_path_consumed,
20138                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
20139                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
20140
20141         { &hf_smb_dfs_num_referrals,
20142                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
20143                 NULL, 0, "Number of referrals in this pdu", HFILL }},
20144
20145         { &hf_smb_get_dfs_flags,
20146                 { "Flags", "smb.dfs.flags", FT_UINT16, BASE_HEX,
20147                 NULL, 0x0, NULL, HFILL }},
20148
20149         { &hf_smb_get_dfs_server_hold_storage,
20150                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
20151                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
20152
20153         { &hf_smb_get_dfs_fielding,
20154                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
20155                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
20156
20157         { &hf_smb_dfs_referral_version,
20158                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
20159                 NULL, 0, "Version of referral element", HFILL }},
20160
20161         { &hf_smb_dfs_referral_size,
20162                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
20163                 NULL, 0, "Size of referral element", HFILL }},
20164
20165         { &hf_smb_dfs_referral_server_type,
20166                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
20167                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
20168
20169         { &hf_smb_dfs_referral_flags,
20170                 { "Flags", "smb.dfs.referral.flags", FT_UINT16, BASE_HEX,
20171                 NULL, 0x0, NULL, HFILL }},
20172
20173         { &hf_smb_dfs_referral_flags_name_list_referral,
20174                 { "NameListReferral", "smb.dfs.referral.flags.name_list_referral", FT_BOOLEAN, 16,
20175                 TFS(&tfs_dfs_referral_flags_name_list_referral), REFENT_FLAGS_NAME_LIST_REFERRAL, "Is a domain/DC referral response?", HFILL }},
20176
20177         { &hf_smb_dfs_referral_flags_target_set_boundary,
20178                 { "TargetSetBoundary", "smb.dfs.referral.flags.target_set_boundary", FT_BOOLEAN, 16,
20179                 TFS(&tfs_dfs_referral_flags_target_set_boundary), REFENT_FLAGS_TARGET_SET_BOUNDARY, "Is this a first target in the target set?", HFILL }},
20180
20181         { &hf_smb_dfs_referral_node_offset,
20182                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
20183                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
20184
20185         { &hf_smb_dfs_referral_node,
20186                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
20187                 NULL, 0, "Name of entity to visit next", HFILL }},
20188
20189         { &hf_smb_dfs_referral_proximity,
20190                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT32, BASE_DEC,
20191                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
20192
20193         { &hf_smb_dfs_referral_ttl,
20194                 { "TTL", "smb.dfs.referral.ttl", FT_UINT32, BASE_DEC,
20195                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
20196
20197         { &hf_smb_dfs_referral_path_offset,
20198                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
20199                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20200
20201         { &hf_smb_dfs_referral_path,
20202                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
20203                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
20204
20205         { &hf_smb_dfs_referral_alt_path_offset,
20206                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
20207                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
20208
20209         { &hf_smb_dfs_referral_alt_path,
20210                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
20211                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
20212
20213         { &hf_smb_dfs_referral_domain_offset,
20214                 { "Domain Offset", "smb.dfs.referral.domain_offset", FT_UINT16, BASE_DEC,
20215                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20216
20217         { &hf_smb_dfs_referral_number_of_expnames,
20218                 { "Number of Expanded Names", "smb.dfs.referral.number_of_expnames", FT_UINT16, BASE_DEC,
20219                 NULL, 0, NULL, HFILL }},
20220
20221         { &hf_smb_dfs_referral_expnames_offset,
20222                 { "Expanded Names Offset", "smb.dfs.referral.expnames_offset", FT_UINT16, BASE_DEC,
20223                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
20224
20225         { &hf_smb_dfs_referral_domain_name,
20226                 { "Domain Name", "smb.dfs.referral.domain_name", FT_STRING, BASE_NONE,
20227                 NULL, 0, "Dfs referral domain name", HFILL }},
20228
20229         { &hf_smb_dfs_referral_expname,
20230                 { "Expanded Name", "smb.dfs.referral.expname", FT_STRING, BASE_NONE,
20231                 NULL, 0, "Dfs expanded name", HFILL }},
20232
20233         { &hf_smb_dfs_referral_server_guid,
20234                 { "Server GUID", "smb.dfs.referral.server_guid", FT_GUID, BASE_NONE,
20235                 NULL, 0, "Globally unique identifier for this server", HFILL }},
20236
20237         { &hf_smb_end_of_search,
20238                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
20239                 NULL, 0, "Was last entry returned?", HFILL }},
20240
20241         { &hf_smb_last_name_offset,
20242                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
20243                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
20244
20245         { &hf_smb_fn_information_level,
20246                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
20247                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
20248
20249         { &hf_smb_monitor_handle,
20250                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
20251                 NULL, 0, "Handle for Find Notify operations", HFILL }},
20252
20253         { &hf_smb_change_count,
20254                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
20255                 NULL, 0, "Number of changes to wait for", HFILL }},
20256
20257         { &hf_smb_file_index,
20258                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
20259                 NULL, 0, NULL, HFILL }},
20260
20261         { &hf_smb_short_file_name,
20262                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
20263                 NULL, 0, "Short (8.3) File Name", HFILL }},
20264
20265         { &hf_smb_short_file_name_len,
20266                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
20267                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
20268
20269         { &hf_smb_fs_id,
20270                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
20271                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
20272
20273         { &hf_smb_sector_unit,
20274                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
20275                 NULL, 0, "Sectors per allocation unit", HFILL }},
20276
20277         { &hf_smb_fs_units,
20278                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
20279                 NULL, 0, "Total number of units on this filesystem", HFILL }},
20280
20281         { &hf_smb_fs_sector,
20282                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
20283                 NULL, 0, NULL, HFILL }},
20284
20285         { &hf_smb_avail_units,
20286                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
20287                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
20288
20289         { &hf_smb_volume_serial_num,
20290                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
20291                 NULL, 0, NULL, HFILL }},
20292
20293         { &hf_smb_volume_label_len,
20294                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
20295                 NULL, 0, "Length of volume label", HFILL }},
20296
20297         { &hf_smb_volume_label,
20298                 { "Label", "smb.volume.label", FT_STRING, BASE_NONE,
20299                 NULL, 0, "Volume label", HFILL }},
20300
20301         { &hf_smb_free_alloc_units64,
20302                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
20303                 NULL, 0, "Number of free allocation units", HFILL }},
20304
20305         { &hf_smb_caller_free_alloc_units64,
20306                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
20307                 NULL, 0, "Number of caller free allocation units", HFILL }},
20308
20309         { &hf_smb_actual_free_alloc_units64,
20310                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
20311                 NULL, 0, "Number of actual free allocation units", HFILL }},
20312
20313         { &hf_smb_soft_quota_limit,
20314                 { "(Soft) Quota Threshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
20315                 NULL, 0, "Soft Quota threshold", HFILL }},
20316
20317         { &hf_smb_hard_quota_limit,
20318                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
20319                 NULL, 0, "Hard Quota limit", HFILL }},
20320
20321         { &hf_smb_user_quota_used,
20322                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
20323                 NULL, 0, "How much Quota is used by this user", HFILL }},
20324
20325         { &hf_smb_max_name_len,
20326                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
20327                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
20328
20329         { &hf_smb_fs_name_len,
20330                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
20331                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
20332
20333         { &hf_smb_fs_name,
20334                 { "FS Name", "smb.fs_name", FT_STRING, BASE_NONE,
20335                 NULL, 0, "Name of filesystem", HFILL }},
20336
20337         { &hf_smb_device_char,
20338                 { "Device Characteristics", "smb.device", FT_UINT32, BASE_HEX,
20339                 NULL, 0x0, NULL, HFILL }},
20340
20341         { &hf_smb_device_char_removable,
20342                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
20343                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
20344
20345         { &hf_smb_device_char_read_only,
20346                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
20347                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
20348
20349         { &hf_smb_device_char_floppy,
20350                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
20351                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
20352
20353         { &hf_smb_device_char_write_once,
20354                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
20355                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
20356
20357         { &hf_smb_device_char_remote,
20358                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
20359                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
20360
20361         { &hf_smb_device_char_mounted,
20362                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
20363                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
20364
20365         { &hf_smb_device_char_virtual,
20366                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
20367                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
20368
20369         { &hf_smb_fs_attr,
20370                 { "FS Attributes", "smb.fs_attr", FT_UINT32, BASE_HEX,
20371                 NULL, 0x0, NULL, HFILL }},
20372
20373         { &hf_smb_fs_attr_css,
20374                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
20375                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
20376
20377         { &hf_smb_fs_attr_cpn,
20378                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
20379                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
20380
20381         { &hf_smb_fs_attr_uod,
20382                 { "Unicode On Disk", "smb.fs_attr.uod", FT_BOOLEAN, 32,
20383                 TFS(&tfs_fs_attr_uod), 0x00000004, "Does this FS support Unicode On Disk?", HFILL }},
20384
20385         { &hf_smb_fs_attr_pacls,
20386                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
20387                 TFS(&tfs_fs_attr_pacls), 0x00000008, "Does this FS support Persistent ACLs?", HFILL }},
20388
20389         { &hf_smb_fs_attr_fc,
20390                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
20391                 TFS(&tfs_fs_attr_fc), 0x00000010, "Does this FS support File Compression?", HFILL }},
20392
20393         { &hf_smb_fs_attr_vq,
20394                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
20395                 TFS(&tfs_fs_attr_vq), 0x00000020, "Does this FS support Volume Quotas?", HFILL }},
20396
20397         { &hf_smb_fs_attr_ssf,
20398                 { "Sparse Files", "smb.fs_attr.ssf", FT_BOOLEAN, 32,
20399                 TFS(&tfs_fs_attr_ssf), 0x00000040, "Does this FS support SPARSE FILES?", HFILL }},
20400
20401         { &hf_smb_fs_attr_srp,
20402                 { "Reparse Points", "smb.fs_attr.srp", FT_BOOLEAN, 32,
20403                 TFS(&tfs_fs_attr_srp), 0x00000080, "Does this FS support REPARSE POINTS?", HFILL }},
20404
20405         { &hf_smb_fs_attr_srs,
20406                 { "Remote Storage", "smb.fs_attr.srs", FT_BOOLEAN, 32,
20407                 TFS(&tfs_fs_attr_srs), 0x00000100, "Does this FS support REMOTE STORAGE?", HFILL }},
20408
20409         { &hf_smb_fs_attr_sla,
20410                 { "LFN APIs", "smb.fs_attr.sla", FT_BOOLEAN, 32,
20411                 TFS(&tfs_fs_attr_sla), 0x00004000, "Does this FS support LFN APIs?", HFILL }},
20412
20413         { &hf_smb_fs_attr_vic,
20414                 { "Volume Is Compressed", "smb.fs_attr.vis", FT_BOOLEAN, 32,
20415                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS on a compressed volume?", HFILL }},
20416
20417         { &hf_smb_fs_attr_soids,
20418                 { "Supports OIDs", "smb.fs_attr.soids", FT_BOOLEAN, 32,
20419                 TFS(&tfs_fs_attr_soids), 0x00010000, "Does this FS support OIDs?", HFILL }},
20420
20421         { &hf_smb_fs_attr_se,
20422                 { "Supports Encryption", "smb.fs_attr.se", FT_BOOLEAN, 32,
20423                 TFS(&tfs_fs_attr_se), 0x00020000, "Does this FS support encryption?", HFILL }},
20424
20425         { &hf_smb_fs_attr_ns,
20426                 { "Named Streams", "smb.fs_attr.ns", FT_BOOLEAN, 32,
20427                 TFS(&tfs_fs_attr_ns), 0x00040000, "Does this FS support named streams?", HFILL }},
20428
20429         { &hf_smb_fs_attr_rov,
20430                 { "Read Only Volume", "smb.fs_attr.rov", FT_BOOLEAN, 32,
20431                 TFS(&tfs_fs_attr_rov), 0x00080000, "Is this FS on a read only volume?", HFILL }},
20432
20433         { &hf_smb_length_of_sid,
20434                 { "Length of SID", "smb.length_of_sid", FT_UINT32, BASE_DEC,
20435                 NULL, 0x0, NULL, HFILL }},
20436
20437         { &hf_smb_user_quota_offset,
20438                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
20439                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
20440
20441         { &hf_smb_pipe_write_len,
20442                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
20443                 NULL, 0, "Number of bytes written to pipe", HFILL }},
20444
20445         { &hf_smb_quota_flags_deny_disk,
20446                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
20447                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
20448
20449         { &hf_smb_quota_flags_log_limit,
20450                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
20451                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
20452
20453         { &hf_smb_quota_flags_log_warning,
20454                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
20455                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
20456
20457         { &hf_smb_quota_flags_enabled,
20458                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
20459                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
20460
20461         { &hf_smb_segment_overlap,
20462                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20463                         "Fragment overlaps with other fragments", HFILL }},
20464
20465         { &hf_smb_segment_overlap_conflict,
20466                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20467                         "Overlapping fragments contained conflicting data", HFILL }},
20468
20469         { &hf_smb_segment_multiple_tails,
20470                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20471                         "Several tails were found when defragmenting the packet", HFILL }},
20472
20473         { &hf_smb_segment_too_long_fragment,
20474                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
20475                         "Fragment contained data past end of packet", HFILL }},
20476
20477         { &hf_smb_segment_error,
20478                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20479                         "Defragmentation error due to illegal fragments", HFILL }},
20480
20481         { &hf_smb_segment_count,
20482                 { "Fragment count", "smb.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
20483                         NULL, HFILL }},
20484
20485         { &hf_smb_reassembled_length,
20486                 { "Reassembled SMB length", "smb.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
20487                         "The total length of the reassembled payload", HFILL }},
20488
20489         { &hf_smb_opened_in,
20490                 { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20491                         "The frame this fid was opened", HFILL }},
20492
20493         { &hf_smb_closed_in,
20494                 { "Closed in", "smb.fid.closed_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20495                         "The frame this fid was closed", HFILL }},
20496
20497         { &hf_smb_mapped_in,
20498                 { "Mapped in", "smb.fid.mapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20499                         "The frame this share was mapped", HFILL }},
20500
20501         { &hf_smb_unmapped_in,
20502                 { "Unmapped in", "smb.fid.unmapped_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20503                         "The frame this share was unmapped", HFILL }},
20504
20505         { &hf_smb_segment,
20506                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
20507                         NULL, HFILL }},
20508
20509         { &hf_smb_segments,
20510                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
20511                         NULL, HFILL }},
20512
20513         { &hf_smb_unix_major_version,
20514           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
20515             NULL, 0, "UNIX Major Version", HFILL }},
20516
20517         { &hf_smb_unix_minor_version,
20518           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
20519             NULL, 0, "UNIX Minor Version", HFILL }},
20520
20521         { &hf_smb_unix_capability,
20522                 { "Capabilities", "smb.unix.capability", FT_UINT64, BASE_HEX,
20523                 NULL, 0x0, NULL, HFILL }},
20524
20525         { &hf_smb_unix_capability_fcntl,
20526           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
20527                 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20528
20529         { &hf_smb_unix_capability_posix_acl,
20530           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
20531                 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20532
20533         { &hf_smb_unix_capability_xattr,
20534           { "EA Capability", "smb.unix.capability.ea", FT_BOOLEAN, 32,
20535                 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20536
20537         { &hf_smb_unix_capability_attr,
20538           { "Additional Attributes Capability", "smb.unix.capability.attr", FT_BOOLEAN, 32,
20539                 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20540
20541         { &hf_smb_unix_capability_posix_paths,
20542           { "POSIX Pathnames Capability", "smb.unix.capability.posix_paths", FT_BOOLEAN, 32,
20543                 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20544
20545         { &hf_smb_unix_capability_posix_path_ops,
20546           { "POSIX Path Operations Capability", "smb.unix.capability.posix_path_ops", FT_BOOLEAN, 32,
20547                 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20548
20549         { &hf_smb_unix_capability_large_read,
20550           { "Large Read Capability", "smb.unix.capability.large_read", FT_BOOLEAN, 32,
20551                 TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
20552
20553         { &hf_smb_unix_capability_large_write,
20554           { "Large Write Capability", "smb.unix.capability.large_write", FT_BOOLEAN, 32,
20555                 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20556
20557         { &hf_smb_unix_capability_encrpytion,
20558           { "Encryption Capability", "smb.unix.capability.encrpytion", FT_BOOLEAN, 32,
20559                 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20560
20561         { &hf_smb_unix_capability_mandatory_crypto,
20562           { "Mandatory Encryption Capability", "smb.unix.capability.mandatory_crypto", FT_BOOLEAN, 32,
20563                 TFS(&tfs_set_notset), 0x00000200, NULL, HFILL }},
20564
20565         { &hf_smb_unix_capability_proxy,
20566           { "Proxy Capability", "smb.unix.capability.proxy", FT_BOOLEAN, 32,
20567                 TFS(&tfs_set_notset), 0x00000400, NULL, HFILL }},
20568
20569         { &hf_smb_file_access_mask_read_data,
20570           { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
20571                 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20572
20573         { &hf_smb_file_access_mask_write_data,
20574           { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
20575                 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20576
20577         { &hf_smb_file_access_mask_append_data,
20578           { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
20579                 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20580
20581         { &hf_smb_file_access_mask_read_ea,
20582           { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
20583                 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20584
20585         { &hf_smb_file_access_mask_write_ea,
20586           { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
20587                 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20588
20589         { &hf_smb_file_access_mask_execute,
20590           { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
20591                 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20592
20593         { &hf_smb_file_access_mask_read_attribute,
20594           { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
20595                 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20596
20597         { &hf_smb_file_access_mask_write_attribute,
20598           { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
20599                 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20600
20601         { &hf_smb_dir_access_mask_list,
20602           { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
20603                 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
20604
20605         { &hf_smb_dir_access_mask_add_file,
20606           { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
20607                 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
20608
20609         { &hf_smb_dir_access_mask_add_subdir,
20610           { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
20611                 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
20612
20613         { &hf_smb_dir_access_mask_read_ea,
20614           { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
20615                 TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
20616
20617         { &hf_smb_dir_access_mask_write_ea,
20618           { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
20619                 TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
20620
20621         { &hf_smb_dir_access_mask_traverse,
20622           { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
20623                 TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
20624
20625         { &hf_smb_dir_access_mask_delete_child,
20626           { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
20627                 TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
20628
20629         { &hf_smb_dir_access_mask_read_attribute,
20630           { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
20631                 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
20632
20633         { &hf_smb_dir_access_mask_write_attribute,
20634           { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
20635                 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
20636
20637         { &hf_smb_unix_file_link_dest,
20638           { "Link destination", "smb.unix.file.link_dest", FT_STRING,
20639             BASE_NONE, NULL, 0, NULL, HFILL }},
20640
20641         { &hf_smb_unix_file_size,
20642           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
20643             NULL, 0, NULL, HFILL }},
20644
20645         { &hf_smb_unix_file_num_bytes,
20646           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
20647             NULL, 0, "Number of bytes used to store the file", HFILL }},
20648
20649         { &hf_smb_unix_file_last_status,
20650           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20651             NULL, 0, NULL, HFILL }},
20652
20653         { &hf_smb_unix_file_last_access,
20654           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20655             NULL, 0, NULL, HFILL }},
20656
20657         { &hf_smb_unix_file_last_change,
20658           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20659             NULL, 0, NULL, HFILL }},
20660
20661         { &hf_smb_unix_file_creation_time,
20662           { "Creation time", "smb.unix.file.crtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
20663             NULL, 0, NULL, HFILL }},
20664
20665         { &hf_smb_unix_file_uid,
20666           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
20667             NULL, 0, NULL, HFILL }},
20668
20669         { &hf_smb_unix_file_gid,
20670           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
20671             NULL, 0, NULL, HFILL }},
20672
20673         { &hf_smb_unix_file_type,
20674           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
20675             VALS(unix_file_type_vals), 0, NULL, HFILL }},
20676
20677         { &hf_smb_unix_file_dev_major,
20678           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
20679             NULL, 0, NULL, HFILL }},
20680
20681         { &hf_smb_unix_file_dev_minor,
20682           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
20683             NULL, 0, NULL, HFILL }},
20684
20685         { &hf_smb_unix_file_unique_id,
20686           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
20687             NULL, 0, NULL, HFILL }},
20688
20689         { &hf_smb_unix_file_permissions,
20690           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
20691             NULL, 0, NULL, HFILL }},
20692
20693         { &hf_smb_unix_file_nlinks,
20694           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
20695             NULL, 0, NULL, HFILL }},
20696
20697         { &hf_smb_unix_info2_file_flags,
20698           { "Flags", "smb.unix_info2.file.flags", FT_UINT32, BASE_HEX,
20699              NULL, 0, NULL, HFILL }},
20700
20701         { &hf_smb_unix_info2_file_flags_mask,
20702           { "Flags mask", "smb.unix_info2.file.flags_mask", FT_UINT32, BASE_HEX,
20703              NULL, 0, NULL, HFILL }},
20704
20705         { &hf_smb_unix_info2_file_flags_secure_delete,
20706           { "Secure delete", "smb.unix_info2.file.flags.secure_delete", FT_BOOLEAN, 32,
20707              NULL, 0x00000001, NULL, HFILL }},
20708
20709         { &hf_smb_unix_info2_file_flags_enable_undelete,
20710           { "Enable undelete", "smb.unix_info2.file.flags.enable_undelete", FT_BOOLEAN, 32,
20711              NULL, 0x00000002, NULL, HFILL }},
20712
20713         { &hf_smb_unix_info2_file_flags_synchronous,
20714           { "Synchronous", "smb.unix_info2.file.flags.synchronous", FT_BOOLEAN, 32,
20715              NULL, 0x00000004, NULL, HFILL }},
20716
20717         { &hf_smb_unix_info2_file_flags_immutable,
20718           { "Immutable", "smb.unix_info2.file.flags.immutable", FT_BOOLEAN, 32,
20719              NULL, 0x00000008, NULL, HFILL }},
20720
20721         { &hf_smb_unix_info2_file_flags_append_only,
20722           { "Append-only", "smb.unix_info2.file.flags.append_only", FT_BOOLEAN, 32,
20723              NULL, 0x00000010, NULL, HFILL }},
20724
20725         { &hf_smb_unix_info2_file_flags_do_not_backup,
20726           { "Do not backup", "smb.unix_info2.file.flags.do_not_backup", FT_BOOLEAN, 32,
20727              NULL, 0x00000020, NULL, HFILL }},
20728
20729         { &hf_smb_unix_info2_file_flags_no_update_atime,
20730           { "Don't update atime", "smb.unix_info2.file.flags.no_update_atime", FT_BOOLEAN, 32,
20731              NULL, 0x00000040, NULL, HFILL }},
20732
20733         { &hf_smb_unix_info2_file_flags_hidden,
20734           { "Hidden", "smb.unix_info2.file.flags.hidden", FT_BOOLEAN, 32,
20735              NULL, 0x00000080, NULL, HFILL }},
20736
20737         { &hf_smb_unix_file_name_length,
20738           { "File name length", "smb.unix.file.name_length", FT_UINT32, BASE_DEC,
20739              NULL, 0, NULL, HFILL }},
20740
20741         { &hf_smb_unix_file_name,
20742           { "File name", "smb.unix.file.name", FT_STRING,
20743             BASE_NONE, NULL, 0, NULL, HFILL }},
20744
20745         { &hf_smb_unix_find_file_nextoffset,
20746           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
20747             NULL, 0, NULL, HFILL }},
20748
20749         { &hf_smb_unix_find_file_resumekey,
20750           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
20751             NULL, 0, NULL, HFILL }},
20752
20753         { &hf_smb_unix_whoami_mapflags,
20754           { "UNIX whoami mapping flags", "smb.unix.whoami.mapflags", FT_UINT32, BASE_DEC,
20755             NULL, 0, NULL, HFILL }},
20756
20757         { &hf_smb_unix_whoami_mapflags_mask,
20758           { "UNIX whoami mapping flags mask", "smb.unix.whoami.mapflags_mask", FT_UINT32, BASE_DEC,
20759             NULL, 0, NULL, HFILL }},
20760
20761         { &hf_smb_unix_whoami_num_supl_gids,
20762           { "Number of supplementary UNIX GIDs", "smb.unix.whoami.num_gids", FT_UINT32, BASE_DEC,
20763             NULL, 0, NULL, HFILL }},
20764
20765         { &hf_smb_unix_whoami_num_supl_sids,
20766           { "Number of supplementary SIDs", "smb.unix.whoami.num_sids", FT_UINT32, BASE_DEC,
20767             NULL, 0, NULL, HFILL }},
20768
20769         { &hf_smb_unix_whoami_sids_buflen,
20770           { "Supplementary SIDs buffer length", "smb.unix.whoami.sids_buflen", FT_UINT32, BASE_DEC,
20771             NULL, 0, NULL, HFILL }},
20772
20773         { &hf_smb_create_flags,
20774           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
20775             NULL, 0, NULL, HFILL }},
20776
20777         { &hf_smb_create_options,
20778           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
20779             NULL, 0, NULL, HFILL }},
20780
20781         { &hf_smb_share_access,
20782           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
20783             NULL, 0, NULL, HFILL }},
20784
20785         { &hf_smb_access_mask,
20786           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
20787             NULL, 0, NULL, HFILL }},
20788
20789         { &hf_smb_mode,
20790           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
20791             NULL, 0, NULL, HFILL }},
20792
20793         { &hf_smb_attribute,
20794           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
20795             NULL, 0, NULL, HFILL }},
20796
20797         { &hf_smb_reparse_tag,
20798           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
20799             NULL, 0, NULL, HFILL }},
20800
20801         { &hf_smb_disposition_delete_on_close,
20802           { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
20803             TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
20804
20805         { &hf_smb_pipe_info_flag,
20806           { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
20807             TFS(&tfs_pipe_info_flag), 0x01, NULL, HFILL }},
20808
20809         { &hf_smb_logged_in,
20810           { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_NONE,
20811             NULL, 0, NULL, HFILL }},
20812
20813         { &hf_smb_logged_out,
20814           { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_NONE,
20815             NULL, 0, NULL, HFILL }},
20816
20817         { &hf_smb_file_rw_offset,
20818           { "File Offset", "smb.file.rw.offset", FT_UINT64, BASE_DEC,
20819             NULL, 0, NULL, HFILL }},
20820
20821         { &hf_smb_file_rw_length,
20822           { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
20823             NULL, 0, NULL, HFILL }},
20824
20825         { &hf_smb_posix_acl_version,
20826           { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
20827             NULL, 0, NULL, HFILL }},
20828
20829         { &hf_smb_posix_num_file_aces,
20830           { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
20831             NULL, 0, NULL, HFILL }},
20832
20833         { &hf_smb_posix_num_def_aces,
20834           { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
20835             NULL, 0, NULL, HFILL }},
20836
20837         { &hf_smb_posix_ace_type,
20838           { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
20839             VALS(ace_type_vals), 0, NULL, HFILL }},
20840
20841         { &hf_smb_posix_ace_flags,
20842           { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
20843             NULL, 0, NULL, HFILL }},
20844
20845         { &hf_smb_posix_ace_perm_read,
20846           {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
20847            NULL, 0x04, NULL, HFILL}},
20848
20849         { &hf_smb_posix_ace_perm_write,
20850           {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
20851            NULL, 0x02, NULL, HFILL}},
20852
20853         { &hf_smb_posix_ace_perm_execute,
20854           {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
20855            NULL, 0x01, NULL, HFILL}},
20856
20857         { &hf_smb_posix_ace_perm_owner_uid,
20858           { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
20859             NULL, 0, NULL, HFILL }},
20860
20861         { &hf_smb_posix_ace_perm_owner_gid,
20862           { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
20863             NULL, 0, NULL, HFILL }},
20864
20865         { &hf_smb_posix_ace_perm_uid,
20866           { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
20867             NULL, 0, NULL, HFILL }},
20868
20869         { &hf_smb_posix_ace_perm_gid,
20870           { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
20871             NULL, 0, NULL, HFILL }},
20872
20873         { &hf_smb_trans_data_setup_word,
20874                 { "Setup Word", "smb.trans_data.setup_word", FT_UINT16, BASE_HEX,
20875                 NULL, 0x0, NULL, HFILL }},
20876
20877         { &hf_smb_trans_data_parameters,
20878                 { "Parameters", "smb.trans_data.parameters", FT_BYTES, BASE_NONE,
20879                 NULL, 0x0, NULL, HFILL }},
20880
20881         { &hf_smb_trans_data,
20882                 { "Data", "smb.trans_data", FT_BYTES, BASE_NONE,
20883                 NULL, 0x0, NULL, HFILL }},
20884         };
20885
20886         static gint *ett[] = {
20887                 &ett_smb,
20888                 &ett_smb_fid,
20889                 &ett_smb_tid,
20890                 &ett_smb_uid,
20891                 &ett_smb_hdr,
20892                 &ett_smb_command,
20893                 &ett_smb_fileattributes,
20894                 &ett_smb_capabilities,
20895                 &ett_smb_aflags,
20896                 &ett_smb_dialect,
20897                 &ett_smb_dialects,
20898                 &ett_smb_mode,
20899                 &ett_smb_rawmode,
20900                 &ett_smb_flags,
20901                 &ett_smb_flags2,
20902                 &ett_smb_desiredaccess,
20903                 &ett_smb_search,
20904                 &ett_smb_file,
20905                 &ett_smb_openfunction,
20906                 &ett_smb_filetype,
20907                 &ett_smb_openaction,
20908                 &ett_smb_writemode,
20909                 &ett_smb_lock_type,
20910                 &ett_smb_ssetupandxaction,
20911                 &ett_smb_optionsup,
20912                 &ett_smb_time_date,
20913                 &ett_smb_move_copy_flags,
20914                 &ett_smb_file_attributes,
20915                 &ett_smb_search_resume_key,
20916                 &ett_smb_search_dir_info,
20917                 &ett_smb_unlocks,
20918                 &ett_smb_unlock,
20919                 &ett_smb_locks,
20920                 &ett_smb_lock,
20921                 &ett_smb_open_flags,
20922                 &ett_smb_ipc_state,
20923                 &ett_smb_open_action,
20924                 &ett_smb_setup_action,
20925                 &ett_smb_connect_flags,
20926                 &ett_smb_connect_support_bits,
20927                 &ett_smb_nt_access_mask,
20928                 &ett_smb_nt_create_bits,
20929                 &ett_smb_nt_create_options,
20930                 &ett_smb_nt_share_access,
20931                 &ett_smb_nt_security_flags,
20932                 &ett_smb_nt_trans_setup,
20933                 &ett_smb_nt_trans_data,
20934                 &ett_smb_nt_trans_param,
20935                 &ett_smb_nt_notify_completion_filter,
20936                 &ett_smb_nt_ioctl_flags,
20937                 &ett_smb_security_information_mask,
20938                 &ett_smb_print_queue_entry,
20939                 &ett_smb_transaction_flags,
20940                 &ett_smb_transaction_params,
20941                 &ett_smb_find_first2_flags,
20942 #if 0
20943                 &ett_smb_ioflag,
20944 #endif
20945                 &ett_smb_transaction_data,
20946                 &ett_smb_stream_info,
20947                 &ett_smb_dfs_referrals,
20948                 &ett_smb_dfs_referral,
20949                 &ett_smb_dfs_referral_flags,
20950                 &ett_smb_dfs_referral_expnames,
20951                 &ett_smb_get_dfs_flags,
20952                 &ett_smb_ff2_data,
20953                 &ett_smb_device_characteristics,
20954                 &ett_smb_fs_attributes,
20955                 &ett_smb_segments,
20956                 &ett_smb_segment,
20957                 &ett_smb_quotaflags,
20958                 &ett_smb_secblob,
20959                 &ett_smb_mac_support_flags,
20960                 &ett_smb_unicode_password,
20961                 &ett_smb_ea,
20962                 &ett_smb_unix_capabilities,
20963                 &ett_smb_unix_whoami_gids,
20964                 &ett_smb_unix_whoami_sids,
20965                 &ett_smb_posix_ace,
20966                 &ett_smb_posix_ace_perms,
20967                 &ett_smb_info2_file_flags
20968         };
20969
20970         static ei_register_info ei[] = {
20971                 { &ei_smb_mal_information_level, { "smb.information_level.malformed", PI_MALFORMED, PI_ERROR, "Information level structure goes past the end of the transation data.", EXPFILL }},
20972                 { &ei_smb_not_implemented, { "smb.not_implemented", PI_UNDECODED, PI_WARN, "Not Implemented yet", EXPFILL }},
20973         };
20974
20975         module_t *smb_module;
20976         expert_module_t* expert_smb;
20977
20978         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
20979             "SMB", "smb");
20980         proto_register_subtree_array(ett, array_length(ett));
20981         proto_register_field_array(proto_smb, hf, array_length(hf));
20982         expert_smb = expert_register_protocol(proto_smb);
20983         expert_register_field_array(expert_smb, ei, array_length(ei));
20984
20985         proto_do_register_windows_common(proto_smb);
20986
20987         register_init_routine(&smb_init_protocol);
20988         smb_module = prefs_register_protocol(proto_smb, NULL);
20989         prefs_register_bool_preference(smb_module, "trans_reassembly",
20990                 "Reassemble SMB Transaction payload",
20991                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
20992                 &smb_trans_reassembly);
20993         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
20994                 "Reassemble DCERPC over SMB",
20995                 "Whether the dissector should reassemble DCERPC over SMB commands",
20996                 &smb_dcerpc_reassembly);
20997         prefs_register_bool_preference(smb_module, "sid_name_snooping",
20998                 "Snoop SID to Name mappings",
20999                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
21000                 &sid_name_snooping);
21001
21002         /* For display of SIDs and RIDs in Hex option */
21003         prefs_register_bool_preference(smb_module, "sid_display_hex",
21004                 "Display SIDs in Hex",
21005                 "Whether the dissector should display SIDs and RIDs in hexadecimal rather than decimal",
21006                 &sid_display_hex);
21007
21008         /* Will Export Object take name as fid ? */
21009         prefs_register_bool_preference(smb_module, "eosmb_take_name_as_fid",
21010                 "Use the full file name as File ID when exporting an SMB object",
21011                 "Whether the export object functionality will take the full path file name as file identifier",
21012                 &eosmb_take_name_as_fid);
21013
21014         register_init_routine(smb_trans_reassembly_init);
21015         smb_tap = register_tap("smb");
21016
21017         /* Register the tap for the "Export Object" function */
21018         smb_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
21019
21020         register_dissector("smb", dissect_smb, proto_smb);
21021 }
21022
21023 void
21024 proto_reg_handoff_smb(void)
21025 {
21026         dissector_handle_t smb_handle;
21027
21028         gssapi_handle  = find_dissector("gssapi");
21029         ntlmssp_handle = find_dissector("ntlmssp");
21030
21031         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
21032         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
21033         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
21034
21035         smb_handle = find_dissector("smb");
21036         dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
21037         dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
21038         dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER, smb_handle);
21039         dissector_add_uint("spp.socket", IDP_SOCKET_SMB, smb_handle);
21040 }
21041
21042 /*
21043  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
21044  *
21045  * Local variables:
21046  * c-basic-offset: 8
21047  * tab-width: 8
21048  * indent-tabs-mode: t
21049  * End:
21050  *
21051  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
21052  * :indentSize=8:tabSize=8:noTabs=false:
21053  */